* Copyright (c) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as path from 'path'
import { camelCaseToLowerSnakeCase, ETSLanguageWriter, PeerLibrary } from '@idlizer/core'
import { cStyleCopyright } from '@idlizer/libohos'
import { LibaceInstall } from '../ArkoalaInstall.js'
import { AceTypesTs, Fixture, Import } from './AceTypes.js'
import { Enum } from './E2ESuitesCreator.js'
import { createEtsWriter, makeTsImports, printEtsResource, quoted1 } from './PrinterUtils.js'
export enum Target { ETS, ARK_TS_1_2 }
export function printTsFixtures(
aceTypes: AceTypesTs, enums: readonly Enum[], peerLibrary: PeerLibrary, libace: LibaceInstall, target: Target
): void {
const testFixturesEnumsEts = createEtsWriter(peerLibrary)
testFixturesEnumsEts.writeLines(cStyleCopyright)
const folders = libace.endToEndTest()
const testEnums = makeFixturesEnums(enums, target, peerLibrary)
testFixturesEnumsEts.concat(testEnums)
testFixturesEnumsEts.printTo(path.join(folders.fixtures, "TestFixturesEnums.ets"))
const testFixturesEts = createEtsWriter(peerLibrary)
testFixturesEts.writeLines(cStyleCopyright)
const testData = makeFixtures(aceTypes.getFixturesTs(), aceTypes.imports, target, peerLibrary)
testFixturesEts.concat(testData.fixtures)
testFixturesEts.printTo(path.join(folders.fixtures, "TestFixtures.ets"))
printEtsResource(folders.element, "color.json", testData.color.json)
printEtsResource(folders.element, "float.json", testData.float.json)
printEtsResource(folders.element, "string.json", testData.string.json)
}
function makeFixturesEnums(enums: readonly Enum[], target: Target, peerLibrary: PeerLibrary): ETSLanguageWriter {
const testPlans = createEtsWriter(peerLibrary)
const prefix = "testFixtureEnum"
const enumTypes = new Set<string>()
for (const en of enums) {
enumTypes.add(en.name)
testPlans.print(`export const ${prefix}${en.name}ValidInputs: ${en.name}[] = [`)
testPlans.pushIndent()
en.values.forEach(value => testPlans.print(`${en.name}.${value},`))
testPlans.popIndent()
testPlans.print("]")
testPlans.print("")
testPlans.print(`export const ${prefix}${en.name}ValidExpects: string[] = [`)
testPlans.pushIndent()
en.values.forEach(value => testPlans.print(`'${en.name}.${value}',`))
testPlans.popIndent()
testPlans.print("]")
testPlans.print("")
testPlans.print(`export const ${prefix}${en.name}InvalidInputs: ${en.name}[] = [`)
if (target !== Target.ARK_TS_1_2) {
testPlans.pushIndent()
if (en.isString) {
testPlans.print(`'' as ${en.name}, 'INVALID_ENUM' as ${en.name}`)
} else {
testPlans.print(`-1 as ${en.name}, 0x7FFFFFFF as ${en.name}`)
}
testPlans.popIndent()
}
testPlans.print("]")
testPlans.print("")
}
const body = createEtsWriter(peerLibrary)
if (target === Target.ARK_TS_1_2) {
body.concat(makeTsImports(enumTypes, "@ohos.arkui.component", peerLibrary))
body.print("")
}
body.concat(testPlans)
return body
}
function makeFixtures(fixtures: readonly Fixture[], imports: Import[], target: Target, peerLibrary: PeerLibrary): {
fixtures: ETSLanguageWriter
color: ColorJson
float: FloatJson
string: StringJson
} {
const testPlans = createEtsWriter(peerLibrary)
const resColor = new ColorJson()
const resFloat = new FloatJson()
const resString = new StringJson()
const fixtureTypes = new Set<string>(["$r"])
for (const fixture of fixtures) {
const makeInputValue: (value: string, index: number) => string|undefined =
fixture.type === "Resource" ? (value, index) => {
const file: JsonFile = fixture.resType === "COLOR" ? resColor
: fixture.resType === "FLOAT" ? resFloat
: fixture.resType === "STRING" ? resString
: new JsonFileStub()
if (file instanceof JsonFileStub) return undefined
const jsonValue = {
name: `${camelCaseToLowerSnakeCase(fixture.name)}_${index}`,
value: value,
}
file.add(jsonValue)
return `\$r('${file.path}${jsonValue.name}')`
}
: (fixture.type === "string" && fixture.quoted !== false) || fixture.quoted === true
? value => quoted1(value) : value => value
const printFixtureValues = (
values: string[], label: "Valid"|"Invalid", variant: "Inputs"|"Expects", type: string
): void => {
const types = type.split("|")
if (types.length > 1) {
type = `(${type})`
}
types.filter(t => t.at(0) === (t.at(0)?.toUpperCase() ?? "")).forEach(t => fixtureTypes.add(t))
testPlans.print(`export const testFixture${fixture.name}${label}${variant}: ${type}[] = [`)
testPlans.pushIndent()
values.forEach(value => testPlans.print(value + ","))
testPlans.popIndent()
testPlans.print("]")
testPlans.print("")
}
testPlans.print(`// Fixture '${fixture.name}' for type '${fixture.type}'`)
if (fixture.validValues) {
const inputs = new Array<string>()
const expects = new Array<string>()
fixture.validValues.forEach((validValue, index) => {
const input = makeInputValue(validValue[0], index)
if (input !== undefined) {
inputs.push(input)
expects.push(quoted1(validValue[1]))
}
})
printFixtureValues(inputs, "Valid", "Inputs", fixture.type)
printFixtureValues(expects, "Valid", "Expects", "string")
}
if (fixture.invalidValues) {
const inputs = new Array<string>()
const indexStart = fixture.validValues?.length ?? 0
fixture.invalidValues.forEach((invalidValue, index) => {
const input = makeInputValue(invalidValue, index + indexStart)
if (input !== undefined) {
inputs.push(input)
}
})
printFixtureValues(inputs, "Invalid", "Inputs", fixture.type)
}
}
const body = createEtsWriter(peerLibrary)
body.concat(makeFixtureImports(imports, fixtureTypes, target, peerLibrary))
body.print("export * from './TestFixturesEnums'")
body.print("")
body.concat(testPlans)
return {
fixtures: body,
color: resColor,
float: resFloat,
string: resString,
}
}
function makeFixtureImports(
imports: readonly Import[], fixtureTypes: Set<string>, target: Target, peerLibrary: PeerLibrary
): ETSLanguageWriter {
const importList = new Map<string, Set<string>>()
if (target === Target.ARK_TS_1_2) {
importList.set("@ohos.arkui.component", fixtureTypes)
} else {
importList.set("../types", new Set(["int, long, double"]))
}
for (const item of imports) {
let importItems = importList.get(item.from)
if (importItems === undefined) {
importItems = new Set<string>()
importList.set(item.from, importItems)
}
importItems.add(item.name)
if (target === Target.ARK_TS_1_2) {
fixtureTypes.delete(item.name)
}
}
const importsWriter = createEtsWriter(peerLibrary)
importList.forEach((names, from) => importsWriter.concat(makeTsImports(names, from, peerLibrary)))
importsWriter.print("")
return importsWriter
}
interface JsonValue {
name: string
value: string
}
interface JsonFile {
add(value: JsonValue): void
readonly path: string
}
class ColorJson implements JsonFile {
color: JsonValue[] = [{
name: "start_window_background",
value: "#FFFFFF"
}]
add(value: JsonValue): void {
this.color.push(value)
}
readonly path = "app.color."
get json() {
return {
color: this.color
}
}
}
class FloatJson implements JsonFile {
float: JsonValue[] = [{
name: "page_text_font_size",
value: "50fp"
}]
add(value: JsonValue): void {
this.float.push(value)
}
readonly path = "app.float."
get json() {
return {
float: this.float
}
}
}
class StringJson implements JsonFile {
string: JsonValue[] = [{
name: "module_desc",
value: "E2E"
}, {
name: "EntryAbility_desc",
value: "C-API end to end"
}, {
name: "EntryAbility_label",
value: "E2E"
}]
add(value: JsonValue): void {
this.string.push(value)
}
readonly path = "app.string."
get json() {
return {
string: this.string
}
}
}
class JsonFileStub implements JsonFile {
add(): void {}
readonly path = ""
}