diff --git a/examples/chip-tool/templates/helper.js b/examples/chip-tool/templates/helper.js deleted file mode 100644 index 6fdc65cc32090d..00000000000000 --- a/examples/chip-tool/templates/helper.js +++ /dev/null @@ -1,153 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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 helpers from zap core -const zapPath = '../../../third_party/zap/repo/dist/src-electron/'; -const templateUtil = require(zapPath + 'generator/template-util.js'); -const zclHelper = require(zapPath + 'generator/helper-zcl.js'); -const zclQuery = require(zapPath + 'db/query-zcl.js'); - -const ChipTypesHelper = require('../../../src/app/zap-templates/common/ChipTypesHelper.js'); - -function asDelimitedCommand(name) -{ - return name.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); -} - -function asTypeMinValue(type) -{ - function fn(pkgId) - { - const options = { 'hash' : {} }; - this.isArray = false; - return zclHelper.asUnderlyingZclType.call(this, type, options).then(zclType => { - const basicType = ChipTypesHelper.asBasicType(zclType); - switch (basicType) { - case 'bool': - return '0'; - case 'int8_t': - case 'int16_t': - case 'int32_t': - case 'int64_t': - return 'INT' + parseInt(basicType.slice(3)) + '_MIN'; - case 'uint8_t': - case 'uint16_t': - case 'uint32_t': - case 'uint64_t': - return '0'; - case 'float': - case 'double': - return `-std::numeric_limits<${basicType}>::infinity()`; - default: - error = 'asTypeMinValue: Unhandled underlying type ' + zclType + ' for original type ' + type; - throw error; - } - }) - } - - const promise = templateUtil.ensureZclPackageId(this).then(fn.bind(this)).catch(err => { - console.log(err); - throw err; - }); - return templateUtil.templatePromise(this.global, promise); -} - -function asTypeMaxValue(type) -{ - function fn(pkgId) - { - const options = { 'hash' : {} }; - return zclHelper.asUnderlyingZclType.call(this, type, options).then(zclType => { - const basicType = ChipTypesHelper.asBasicType(zclType); - switch (basicType) { - case 'bool': - return '1'; - case 'int8_t': - case 'int16_t': - case 'int32_t': - case 'int64_t': - return 'INT' + parseInt(basicType.slice(3)) + '_MAX'; - case 'uint8_t': - case 'uint16_t': - case 'uint32_t': - case 'uint64_t': - return 'UINT' + parseInt(basicType.slice(4)) + '_MAX'; - case 'float': - case 'double': - return `std::numeric_limits<${basicType}>::infinity()`; - default: - return 'err'; - error = 'asTypeMaxValue: Unhandled underlying type ' + zclType + ' for original type ' + type; - throw error; - } - }) - } - - const promise = templateUtil.ensureZclPackageId(this).then(fn.bind(this)).catch(err => { - console.log(err); - throw err; - }); - return templateUtil.templatePromise(this.global, promise); -} - -async function structs_with_cluster_name(options) -{ - const packageId = await templateUtil.ensureZclPackageId(this); - - const structs = await zclQuery.selectAllStructsWithItems(this.global.db, packageId); - - let blocks = []; - for (const s of structs) { - if (s.struct_cluster_count == 0) { - continue; - } - - if (s.struct_cluster_count == 1) { - const clusters = await zclQuery.selectStructClusters(this.global.db, s.id); - blocks.push( - { id : s.id, name : s.name, struct_fabric_idx_field : s.struct_fabric_idx_field, clusterName : clusters[0].name }); - } - - if (s.struct_cluster_count > 1) { - blocks.push({ id : s.id, name : s.name, struct_fabric_idx_field : s.struct_fabric_idx_field, clusterName : "detail" }); - } - } - - return templateUtil.collectBlocks(blocks, options, this); -} - -async function assertSameTestType(current, expected) -{ - if (current == expected) { - return ''; - } - - const filename = this.parent.parent.parent.filename; - const testName = this.parent.parent.parent.testName; - const error = `\nFile: ${filename}\nTest: ${testName}\nCluster ${this.parent.cluster} Attribute: ${this.name}: Constraint type "${ - expected}" does not match the current type "${current}".`; - throw error; -} - -// -// Module exports -// -exports.asDelimitedCommand = asDelimitedCommand; -exports.asTypeMinValue = asTypeMinValue; -exports.asTypeMaxValue = asTypeMaxValue; -exports.structs_with_cluster_name = structs_with_cluster_name; -exports.assertSameTestType = assertSameTestType; diff --git a/examples/chip-tool/templates/templates.json b/examples/chip-tool/templates/templates.json index e61ce2120942d7..1552ab8566bfa6 100644 --- a/examples/chip-tool/templates/templates.json +++ b/examples/chip-tool/templates/templates.json @@ -2,11 +2,11 @@ "name": "CHIP Tool templates", "version": "chip-v1", "helpers": [ - "../../../src/app/zap-templates/partials/helper.js", - "../../../src/app/zap-templates/common/StringHelper.js", - "../../../src/app/zap-templates/templates/app/helper.js", - "../../../src/app/zap-templates/templates/chip/helper.js", - "helper.js" + "partials/helper.js", + "common/StringHelper.js", + "templates/app/helper.js", + "templates/chip/helper.js", + "chip-tool/templates/helper.js" ], "override": "../../../src/app/zap-templates/common/override.js", "partials": [ diff --git a/examples/chip-tool/templates/tests/commands.zapt b/examples/chip-tool/templates/tests/commands.zapt index 4c73a5675ac12c..b960267359fa0d 100644 --- a/examples/chip-tool/templates/tests/commands.zapt +++ b/examples/chip-tool/templates/tests/commands.zapt @@ -17,7 +17,7 @@ public: TestList() : Command("list") {}; CHIP_ERROR Run() override { - {{#chip_tests (getTests)}}printf("{{filename}}\n");{{/chip_tests}} + {{#chip_tests "../../../../src/app/tests/suites/ciTests.json"}}printf("{{filename}}\n");{{/chip_tests}} return CHIP_NO_ERROR; } @@ -29,14 +29,14 @@ public: ManualTestList() : Command("list-manual") {}; CHIP_ERROR Run() override { - {{#chip_tests (getManualTests)}}printf("{{filename}}\n");{{/chip_tests}} + {{#chip_tests "../../../../src/app/tests/suites/manualTests.json"}}printf("{{filename}}\n");{{/chip_tests}} return CHIP_NO_ERROR; } }; -{{>test_cluster tests=(getTests) credsIssuerConfigArg=true needsWaitDuration=true}} -{{>test_cluster tests=(getManualTests) credsIssuerConfigArg=true needsWaitDuration=true}} +{{>test_cluster tests="../../../../src/app/tests/suites/ciTests.json" credsIssuerConfigArg=true needsWaitDuration=true}} +{{>test_cluster tests="../../../../src/app/tests/suites/manualTests.json" credsIssuerConfigArg=true needsWaitDuration=true}} #endif // CONFIG_ENABLE_YAML_TESTS @@ -48,10 +48,10 @@ void registerCommandsTests(Commands & commands, CredentialIssuerCommands * creds #if CONFIG_ENABLE_YAML_TESTS make_unique(), make_unique(), - {{#chip_tests (getTests)}} + {{#chip_tests "../../../../src/app/tests/suites/ciTests.json"}} make_unique<{{filename}}Suite>(credsIssuerConfig), {{/chip_tests}} - {{#chip_tests (getManualTests)}} + {{#chip_tests "../../../../src/app/tests/suites/manualTests.json"}} make_unique<{{filename}}Suite>(credsIssuerConfig), {{/chip_tests}} #endif // CONFIG_ENABLE_YAML_TESTS diff --git a/examples/chip-tool/templates/tests/helper.js b/examples/chip-tool/templates/tests/helper.js deleted file mode 100644 index d50912ca9f5703..00000000000000 --- a/examples/chip-tool/templates/tests/helper.js +++ /dev/null @@ -1,109 +0,0 @@ -/* - * - * Copyright (c) 2022 Project CHIP Authors - * - * 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. - */ - -const { zapTypeToDecodableClusterObjectType, zapTypeToEncodableClusterObjectType, asUpperCamelCase, asLowerCamelCase } -= require('../../../../src/app/zap-templates/templates/app/helper.js'); -const { isTestOnlyCluster } = require('../../../../src/app/zap-templates/common/simulated-clusters/SimulatedClusters.js'); - -function utf8StringLength(str) -{ - return new TextEncoder().encode(str).length -} - -/* - * Returns the name to use for accessing a given property of - * a decodable type. - * - */ -function asPropertyValue(options) -{ - let rootObject = 'value'; - - let context = options.hash.context || this; - - // The decodable type for commands is a struct by default, even if the - // command just returns a single value. - if (context.parent.isCommand) { - rootObject += '.' + asLowerCamelCase(context.name); - } - - if (context.isOptional && !options.hash.dontUnwrapValue) { - rootObject += '.Value()'; - } - - return rootObject; -} - -async function asEncodableType() -{ - // Copy some properties needed by zapTypeToEncodableClusterObjectType - let target = { global : this.global, entryType : this.entryType }; - - let type; - if ('commandObject' in this) { - type = this.commandObject.name; - } else if ('attributeObject' in this) { - type = this.attributeObject.type; - target.isArray = this.attributeObject.isArray; - target.isOptional = this.attributeObject.isOptional; - target.isNullable = this.attributeObject.isNullable; - } else { - throw new Error("Unsupported encodable type"); - } - - if (isTestOnlyCluster(this.cluster) || 'commandObject' in this) { - return `chip::app::Clusters::${asUpperCamelCase(this.cluster)}::Commands::${asUpperCamelCase(type)}::Type`; - } - - const options = { 'hash' : { ns : this.cluster } }; - return await zapTypeToEncodableClusterObjectType.call(target, type, options); -} - -async function asDecodableType() -{ - // Copy some properties needed by zapTypeToDecodableClusterObjectType - let target = { global : this.global, entryType : this.entryType }; - - let type; - if ('commandObject' in this) { - type = this.commandObject.responseName; - } else if ('attributeObject' in this) { - type = this.attributeObject.type; - target.isArray = this.attributeObject.isArray; - target.isOptional = this.attributeObject.isOptional; - target.isNullable = this.attributeObject.isNullable; - } else if ('eventObject' in this) { - type = this.event; - } else { - throw new Error("Unsupported decodable type"); - } - - if (isTestOnlyCluster(this.cluster) || 'commandObject' in this) { - return `chip::app::Clusters::${asUpperCamelCase(this.cluster)}::Commands::${asUpperCamelCase(type)}::DecodableType`; - } - - const options = { 'hash' : { ns : this.cluster } }; - return await zapTypeToDecodableClusterObjectType.call(target, type, options); -} - -// -// Module exports -// -exports.utf8StringLength = utf8StringLength; -exports.asPropertyValue = asPropertyValue; -exports.asDecodableType = asDecodableType; -exports.asEncodableType = asEncodableType; diff --git a/examples/chip-tool/templates/tests/templates.json b/examples/chip-tool/templates/tests/templates.json index 45152c4b2a0fab..93505fe7a1fce4 100644 --- a/examples/chip-tool/templates/tests/templates.json +++ b/examples/chip-tool/templates/tests/templates.json @@ -2,15 +2,19 @@ "name": "CHIP Tool Tests templates", "version": "chip-v1", "helpers": [ - "../../../../src/app/zap-templates/partials/helper.js", - "../../../../src/app/zap-templates/common/StringHelper.js", - "../../../../src/app/zap-templates/templates/app/helper.js", - "../../../../src/app/zap-templates/templates/chip/helper.js", - "../../../../src/app/zap-templates/common/ClusterTestGeneration.js", - "../helper.js", - "helper.js", - "tests.js" + "partials/helper.js", + "common/StringHelper.js", + "templates/app/helper.js", + "templates/chip/helper.js", + "common/ClusterTestGeneration.js", + "chip-tool/templates/helper.js", + "chip-tool/templates/tests/helper.js" ], + "resources": { + "pics-metafile": "../../../../src/app/tests/suites/certification/PICS.yaml", + "certification-metadir": "../../../../src/app/tests/suites/certification", + "test-metadir": "../../../../src/app/tests/suites" + }, "override": "../../../../src/app/zap-templates/common/override.js", "partials": [ { diff --git a/examples/chip-tool/templates/tests/tests.js b/examples/chip-tool/templates/tests/tests.js deleted file mode 100644 index 2f4df96281d27b..00000000000000 --- a/examples/chip-tool/templates/tests/tests.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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. - */ - -const testPath = '../../../../src/app/tests/suites/'; -const TestSuite = require(testPath + 'tests.js'); - -function getManualTests() -{ - return TestSuite.getManualTests(); -} - -function getTests() -{ - return TestSuite.getTests(); -} - -// -// Module exports -// -exports.getTests = getTests; -exports.getManualTests = getManualTests; diff --git a/examples/darwin-framework-tool/templates/helper.js b/examples/darwin-framework-tool/templates/helper.js deleted file mode 100644 index 16197e409ac13c..00000000000000 --- a/examples/darwin-framework-tool/templates/helper.js +++ /dev/null @@ -1,26 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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. - */ - -function hasArguments() -{ - return !!this.arguments.length -} - -// -// Module exports -// -exports.hasArguments = hasArguments; diff --git a/examples/darwin-framework-tool/templates/templates.json b/examples/darwin-framework-tool/templates/templates.json index 1535bf06327870..a571ccb860cf48 100644 --- a/examples/darwin-framework-tool/templates/templates.json +++ b/examples/darwin-framework-tool/templates/templates.json @@ -2,14 +2,19 @@ "name": "CHIP Tool Darwin templates", "version": "chip-v1", "helpers": [ - "../../../examples/chip-tool/templates/helper.js", - "../../../src/app/zap-templates/common/StringHelper.js", - "../../../src/app/zap-templates/partials/helper.js", - "../../../src/app/zap-templates/templates/app/helper.js", - "../../../src/app/zap-templates/templates/chip/helper.js", - "../../../src/app/zap-templates/common/ClusterTestGeneration.js", - "../../../src/darwin/Framework/CHIP/templates/helper.js" + "chip-tool/templates/helper.js", + "common/StringHelper.js", + "partials/helper.js", + "templates/app/helper.js", + "templates/chip/helper.js", + "common/ClusterTestGeneration.js", + "darwin/Framework/CHIP/templates/helper.js" ], + "resources": { + "pics-metafile": "../../../src/app/tests/suites/certification/PICS.yaml", + "certification-metadir": "../../../src/app/tests/suites/certification", + "test-metadir": "../../../src/app/tests/suites" + }, "override": "../../../src/app/zap-templates/common/override.js", "partials": [ { diff --git a/examples/darwin-framework-tool/templates/tests/ciTests.json b/examples/darwin-framework-tool/templates/tests/ciTests.json new file mode 100644 index 00000000000000..5be170ac3d8bba --- /dev/null +++ b/examples/darwin-framework-tool/templates/tests/ciTests.json @@ -0,0 +1,23 @@ +{ + "include": "../../../../src/app/tests/suites/ciTests.json", + "disable": [ + "Test_TC_SC_4_2", + "TestClusterComplexTypes", + "TestEvents", + "TestDiscovery", + "TestGroupMessaging", + "Test_TC_DGTHREAD_2_1", + "Test_TC_DGTHREAD_2_2", + "Test_TC_DGTHREAD_2_3", + "Test_TC_DGTHREAD_2_4", + "Test_TC_CC_7_2", + "Test_TC_CC_6_2", + "Test_TC_CC_6_3", + "Test_TC_CC_8_1", + "Test_TC_APPLAUNCHER_3_7", + "Test_TC_APPLAUNCHER_3_8", + "Test_TC_APPLAUNCHER_3_9", + "Test_TC_BINFO_2_1", + "Test_TC_SWTCH_2_1" + ] +} diff --git a/examples/darwin-framework-tool/templates/tests/commands.zapt b/examples/darwin-framework-tool/templates/tests/commands.zapt index 5a3f1c07707024..2d1f547489bc4c 100644 --- a/examples/darwin-framework-tool/templates/tests/commands.zapt +++ b/examples/darwin-framework-tool/templates/tests/commands.zapt @@ -16,7 +16,7 @@ public: TestList() : Command("list") {}; CHIP_ERROR Run() override { - {{#chip_tests (getTests)}}printf("{{filename}}\n");{{/chip_tests}} + {{#chip_tests "ciTests.json"}}printf("{{filename}}\n");{{/chip_tests}} return CHIP_NO_ERROR; } @@ -28,14 +28,14 @@ public: ManualTestList() : Command("list-manual") {}; CHIP_ERROR Run() override { - {{#chip_tests (getManualTests)}}printf("{{filename}}\n");{{/chip_tests}} + {{#chip_tests "manualTests.json"}}printf("{{filename}}\n");{{/chip_tests}} return CHIP_NO_ERROR; } }; -{{>test_cluster tests=(getTests) credsIssuerConfigArg=false}} -{{>test_cluster tests=(getManualTests) credsIssuerConfigArg=false}} +{{>test_cluster tests="ciTests.json" credsIssuerConfigArg=false}} +{{>test_cluster tests="manualTests.json" credsIssuerConfigArg=false}} #endif // CONFIG_ENABLE_YAML_TESTS @@ -47,10 +47,10 @@ void registerCommandsTests(Commands & commands) #if CONFIG_ENABLE_YAML_TESTS make_unique(), make_unique(), - {{#chip_tests (getTests)}} + {{#chip_tests "ciTests.json"}} make_unique<{{filename}}>(), {{/chip_tests}} - {{#chip_tests (getManualTests)}} + {{#chip_tests "manualTests.json"}} make_unique<{{filename}}>(), {{/chip_tests}} #endif // CONFIG_ENABLE_YAML_TESTS diff --git a/examples/darwin-framework-tool/templates/tests/manualTests.json b/examples/darwin-framework-tool/templates/tests/manualTests.json new file mode 100644 index 00000000000000..167f6d2a59e00c --- /dev/null +++ b/examples/darwin-framework-tool/templates/tests/manualTests.json @@ -0,0 +1,3 @@ +{ + "collection": [] +} diff --git a/examples/darwin-framework-tool/templates/tests/templates.json b/examples/darwin-framework-tool/templates/tests/templates.json index 6f46ea7e9aaf65..9ca4d2e533c183 100644 --- a/examples/darwin-framework-tool/templates/tests/templates.json +++ b/examples/darwin-framework-tool/templates/tests/templates.json @@ -2,17 +2,21 @@ "name": "CHIP Tool Tests templates", "version": "chip-v1", "helpers": [ - "../../../../examples/chip-tool/templates/helper.js", - "../../../../examples/chip-tool/templates/tests/helper.js", - "../../../../src/app/zap-templates/partials/helper.js", - "../../../../src/app/zap-templates/common/StringHelper.js", - "../../../../src/app/zap-templates/templates/app/helper.js", - "../../../../src/app/zap-templates/templates/chip/helper.js", - "../../../../src/app/zap-templates/common/ClusterTestGeneration.js", - "../../../../src/darwin/Framework/CHIP/templates/helper.js", - "../helper.js", - "tests.js" + "chip-tool/templates/helper.js", + "chip-tool/templates/tests/helper.js", + "partials/helper.js", + "common/StringHelper.js", + "templates/app/helper.js", + "templates/chip/helper.js", + "common/ClusterTestGeneration.js", + "darwin/Framework/CHIP/templates/helper.js", + "darwin-framework-tool/templates/helper.js" ], + "resources": { + "pics-metafile": "../../../../src/app/tests/suites/certification/PICS.yaml", + "certification-metadir": "../../../../src/app/tests/suites/certification", + "test-metadir": "../../../../src/app/tests/suites" + }, "override": "../../../../src/app/zap-templates/common/override.js", "partials": [ { diff --git a/examples/darwin-framework-tool/templates/tests/tests.js b/examples/darwin-framework-tool/templates/tests/tests.js deleted file mode 100644 index 13c3a062d1c9ab..00000000000000 --- a/examples/darwin-framework-tool/templates/tests/tests.js +++ /dev/null @@ -1,107 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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. - */ - -const testPath = '../../../../src/app/tests/suites/'; -const TestSuite = require(testPath + 'tests.js'); - -function getManualTests() -{ - return []; -} - -// clang-format off - -function getTests() { - - let tests = TestSuite.getTests(); - - // TODO: This test needs FindCommissionable - tests.disable('Test_TC_SC_4_2'); - - // TestClusterComplexTypes requires representing nullable optionals in ways - // that can differentiate missing and null, which Darwin can't right now. - tests.disable('TestClusterComplexTypes'); - - // TODO: TestEvents not supported in the codegen yet. - tests.disable('TestEvents'); - - // TODO: TestDiscovery needs FindCommissionable - tests.disable('TestDiscovery'); - - // TODO: TestGroupMessaging does not work on Darwin for now. - tests.disable('TestGroupMessaging'); - - // TODO: Test_TC_DIAG_TH_NW_2_1 does not work on Darwin for now. - tests.disable('Test_TC_DGTHREAD_2_1'); - - // TODO: Test_TC_DIAG_TH_NW_2_2 does not work on Darwin for now. - tests.disable('Test_TC_DGTHREAD_2_2'); - - // TODO: Test_TC_DIAG_TH_NW_2_3 does not work on Darwin for now. - tests.disable('Test_TC_DGTHREAD_2_3'); - - // TODO: Test_TC_DIAG_TH_NW_2_4 does not work on Darwin for now. - tests.disable('Test_TC_DGTHREAD_2_4'); - - // TODO: Test_TC_CC_7_2 seems to rely on pretty tight timing that seem to not - // work right in the darwin tests. - tests.disable('Test_TC_CC_7_2'); - - // TODO: Test_TC_CC_6_2 does not work on Darwin(no ble asan) for now. - tests.disable('Test_TC_CC_6_2'); - - // TODO: Test_TC_CC_6_3 does not work on Darwin(no ble asan) for now. - tests.disable('Test_TC_CC_6_3'); - - // TODO: Test_TC_CC_8_1 does not work on Darwin(no ble asan) for now. - tests.disable('Test_TC_CC_8_1'); - - // TODO: Test_TC_CC_9_1 does not work on Darwin for now. - // But is disabled in CI, so we can't disable it here. - //tests.disable('Test_TC_CC_9_1'); - - // TODO: Test_TC_CC_9_2 does not work on Darwin for now. - // But is disabled in CI, so we can't disable it here. - //tests.disable('Test_TC_CC_9_2'); - - // TODO: Test_TC_CC_9_3 does not work on Darwin for now. - // But is disabled in CI, so we can't disable it here. - //tests.disable('Test_TC_CC_9_3'); - - // TODO: Test_TC_MC_3_7 does not work on Darwin for now. - tests.disable('Test_TC_APPLAUNCHER_3_7'); - - // TODO: Test_TC_MC_3_8 does not work on Darwin for now. - tests.disable('Test_TC_APPLAUNCHER_3_8'); - - // TODO: Test_TC_MC_3_9 does not work on Darwin for now. - tests.disable('Test_TC_APPLAUNCHER_3_9'); - - // TODO: Test_TC_BINFO_2_1 does not work on Darwin for now. - tests.disable('Test_TC_BINFO_2_1'); - - // TODO: Test_TC_SWTCH_2_1 does not work on Darwin for now. - tests.disable('Test_TC_SWTCH_2_1'); - - return tests; -} - -// -// Module exports -// -exports.getTests = getTests; -exports.getManualTests = getManualTests; diff --git a/examples/placeholder/linux/apps/app1/ciTests.json b/examples/placeholder/linux/apps/app1/ciTests.json new file mode 100644 index 00000000000000..7d3af1e9b509ba --- /dev/null +++ b/examples/placeholder/linux/apps/app1/ciTests.json @@ -0,0 +1,4 @@ +{ + "Test": ["Test_TC_BINFO_2_3_Simulated"], + "collection": ["Test"] +} diff --git a/examples/placeholder/linux/apps/app1/tests.js b/examples/placeholder/linux/apps/app1/tests.js deleted file mode 100644 index 134085e4c85367..00000000000000 --- a/examples/placeholder/linux/apps/app1/tests.js +++ /dev/null @@ -1,30 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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. - */ - -function getTests() -{ - const tests = [ - "Test_TC_BINFO_2_3_Simulated", - ]; - - return tests.join(', '); -} - -// -// Module exports -// -exports.getTests = getTests; diff --git a/examples/placeholder/templates/helper.js b/examples/placeholder/templates/helper.js deleted file mode 100644 index 01fc3dad95fec5..00000000000000 --- a/examples/placeholder/templates/helper.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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. - */ - -function getTests() -{ - try { - const appTest = require('../linux/apps/app1/tests.js'); - return appTest.getTests(); - } catch (e) { - console.info("No tests configuration has been found."); - return ''; - } -} - -// -// Module exports -// -exports.getTests = getTests; diff --git a/examples/placeholder/templates/templates.json b/examples/placeholder/templates/templates.json index 8efe91f4650a47..5b4ee12daebc49 100644 --- a/examples/placeholder/templates/templates.json +++ b/examples/placeholder/templates/templates.json @@ -2,15 +2,19 @@ "name": "Placeholder templates", "version": "chip-v1", "helpers": [ - "../../../src/app/zap-templates/partials/helper.js", - "../../../src/app/zap-templates/common/StringHelper.js", - "../../../src/app/zap-templates/templates/app/helper.js", - "../../../src/app/zap-templates/templates/chip/helper.js", - "../../../src/app/zap-templates/common/ClusterTestGeneration.js", - "../../../examples/chip-tool/templates/helper.js", - "../../../examples/chip-tool/templates/tests/helper.js", - "helper.js" + "partials/helper.js", + "common/StringHelper.js", + "templates/app/helper.js", + "templates/chip/helper.js", + "common/ClusterTestGeneration.js", + "chip-tool/templates/helper.js", + "chip-tool/templates/tests/helper.js" ], + "resources": { + "pics-metafile": "../../../src/app/tests/suites/certification/PICS.yaml", + "certification-metadir": "../../../src/app/tests/suites/certification", + "test-metadir": "../../../src/app/tests/suites" + }, "override": "../../../src/app/zap-templates/common/override.js", "partials": [ { diff --git a/examples/placeholder/templates/tests-commands.zapt b/examples/placeholder/templates/tests-commands.zapt index 3c4f7a11776f72..f7bcbe375e802a 100644 --- a/examples/placeholder/templates/tests-commands.zapt +++ b/examples/placeholder/templates/tests-commands.zapt @@ -6,28 +6,23 @@ #include -{{#if (getTests)}} -{{>test_cluster tests=(getTests) credsIssuerConfigArg=false needsWaitDuration=false}} -{{/if}} +{{>test_cluster tests="../linux/apps/app1/ciTests.json" credsIssuerConfigArg=false needsWaitDuration=false}} std::unique_ptrGetTestCommand(std::string testName) { - {{#if (getTests)}} - {{#chip_tests (getTests)}} + {{#chip_tests "../linux/apps/app1/ciTests.json"}} if (testName == "{{filename}}") { return std::unique_ptr<{{filename}}Suite>(new {{filename}}Suite()); } {{/chip_tests}} - {{/if}} return nullptr; } void PrintTestCommands() { - {{#if (getTests)}} - {{#chip_tests (getTests)}} + {{#chip_tests "../linux/apps/app1/ciTests.json"}} {{#first}} ChipLogError(chipTool, "Supported commands:"); {{/first}} @@ -35,5 +30,4 @@ void PrintTestCommands() {{else}} ChipLogError("\t No available commands."); {{/chip_tests}} - {{/if}} } diff --git a/scripts/tools/sdk.json b/scripts/tools/sdk.json new file mode 100644 index 00000000000000..a464c0bf8c495e --- /dev/null +++ b/scripts/tools/sdk.json @@ -0,0 +1,290 @@ +{ + "meta": { + "sdkRoot": "../..", + "description": "Matter SDK", + "requiredFeatureLevel": 77 + }, + "zcl": { + "main": "src/app/zap-templates/zcl/zcl.json", + "main_ext": "src/app/zap-templates/zcl/zcl-with-test-extensions.json" + }, + "templates": { + "app-zap": "src/app/zap-templates/app-templates.json", + "placeholder": "examples/placeholder/templates/templates.json", + "chip-tool-test": "examples/chip-tool/templates/tests/templates.json", + "darwin-test": "examples/darwin-framework-tool/templates/tests/templates.json", + "app-common": "src/app/common/templates/templates.json", + "app-test": "src/app/tests/suites/templates/templates.json", + "chip-tool": "examples/chip-tool/templates/templates.json", + "darwin": "examples/darwin-framework-tool/templates/templates.json", + "python": "src/controller/python/templates/templates.json", + "darwin-chip": "src/darwin/Framework/CHIP/templates/templates.json", + "java": "src/controller/java/templates/templates.json" + }, + "zapFiles": { + "thermostat": "examples/thermostat/thermostat-common/thermostat.zap", + "bridge-app": "examples/bridge-app/bridge-common/bridge-app.zap", + "log-source-app": "examples/log-source-app/log-source-common/log-source-app.zap", + "lock-app": "examples/lock-app/lock-common/lock-app.zap", + "lighting-app": "examples/lighting-app/lighting-common/lighting-app.zap", + "all-clusters-minimal-app": "examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap", + "temperature-measurement": "examples/temperature-measurement-app/esp32/main/temperature-measurement.zap", + "all-clusters-app": "examples/all-clusters-app/all-clusters-common/all-clusters-app.zap", + "pump-controller-app": "examples/pump-controller-app/pump-controller-common/pump-controller-app.zap", + "tv-app": "examples/tv-app/tv-common/tv-app.zap", + "light-switch-app": "examples/light-switch-app/light-switch-common/light-switch-app.zap", + "ota-provider-app": "examples/ota-provider-app/ota-provider-common/ota-provider-app.zap", + "pump-app": "examples/pump-app/pump-common/pump-app.zap", + "ota-requestor-app": "examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap", + "tv-casting-app": "examples/tv-casting-app/tv-casting-common/tv-casting-app.zap", + "window-app": "examples/window-app/common/window-app.zap", + "app2": "examples/placeholder/linux/apps/app2/config.zap", + "app1": "examples/placeholder/linux/apps/app1/config.zap", + "chef_dimmablelight": "examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.zap", + "chef_contactsensor": "examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.zap", + "chef_humiditysensor": "examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.zap", + "chef_speaker": "examples/chef/devices/rootnode_speaker_RpzeXdimqA.zap", + "chef_temperaturesensor": "examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.zap", + "chef_flowsensor": "examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.zap", + "chef_thermostat": "examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.zap", + "chef_onofflightswitch": "examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.zap", + "chef_heatingcoolingunit": "examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.zap", + "chef_occupancysensor": "examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.zap", + "chef_onofflight": "examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.zap", + "chef_pressuresensor": "examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.zap", + "chef_windowcovering": "examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.zap", + "chef_onoffpluginunit": "examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.zap", + "chef_lightsensor": "examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.zap", + "controller": "src/controller/data_model/controller-clusters.zap" + }, + "generation": [ + { + "zapFile": "all-clusters-app", + "output": "zzz_generated/all-clusters-app/zap-generated", + "zcl": "main_ext", + "template": "app-zap" + }, + { + "zapFile": "all-clusters-minimal-app", + "output": "zzz_generated/all-clusters-minimal-app/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "app1", + "output": "zzz_generated/placeholder/app1/zap-generated", + "zcl": "main", + "template": ["app-zap", "placeholder"] + }, + { + "zapFile": "app2", + "output": "zzz_generated/placeholder/app2/zap-generated", + "zcl": "main", + "template": ["app-zap", "placeholder"] + }, + { + "zapFile": "bridge-app", + "output": "zzz_generated/bridge-app/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "chef_contactsensor", + "output": "zzz_generated/chef-rootnode_contactsensor_lFAGG1bfRO/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "chef_dimmablelight", + "output": "zzz_generated/chef-rootnode_dimmablelight_bCwGYSDpoe/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "chef_flowsensor", + "output": "zzz_generated/chef-rootnode_flowsensor_1zVxHedlaV/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "chef_heatingcoolingunit", + "output": "zzz_generated/chef-rootnode_heatingcoolingunit_ncdGai1E5a/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "chef_humiditysensor", + "output": "zzz_generated/chef-rootnode_humiditysensor_Xyj4gda6Hb/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "chef_lightsensor", + "output": "zzz_generated/chef-rootnode_lightsensor_lZQycTFcJK/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "chef_occupancysensor", + "output": "zzz_generated/chef-rootnode_occupancysensor_iHyVgifZuo/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "chef_onofflight", + "output": "zzz_generated/chef-rootnode_onofflight_bbs1b7IaOV/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "chef_onofflightswitch", + "output": "zzz_generated/chef-rootnode_onofflightswitch_FsPlMr090Q/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "chef_onoffpluginunit", + "output": "zzz_generated/chef-rootnode_onoffpluginunit_Wtf8ss5EBY/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "chef_pressuresensor", + "output": "zzz_generated/chef-rootnode_pressuresensor_s0qC9wLH4k/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "chef_speaker", + "output": "zzz_generated/chef-rootnode_speaker_RpzeXdimqA/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "chef_temperaturesensor", + "output": "zzz_generated/chef-rootnode_temperaturesensor_Qy1zkNW7c3/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "chef_thermostat", + "output": "zzz_generated/chef-rootnode_thermostat_bm3fb8dhYi/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "chef_windowcovering", + "output": "zzz_generated/chef-rootnode_windowcovering_RLCxaGi9Yx/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "controller", + "output": "", + "zcl": "main", + "template": ["python", "darwin-chip", "java"] + }, + { + "zapFile": "controller", + "output": "zzz_generated/app-common/app-common/zap-generated", + "zcl": "main", + "template": ["app-common", "app-test"] + }, + { + "zapFile": "controller", + "output": "zzz_generated/chip-tool/zap-generated", + "zcl": "main", + "template": ["chip-tool-test", "chip-tool"] + }, + { + "zapFile": "controller", + "output": "zzz_generated/controller-clusters/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "controller", + "output": "zzz_generated/darwin-framework-tool/zap-generated", + "zcl": "main", + "template": ["darwin-test", "darwin"] + }, + { + "zapFile": "light-switch-app", + "output": "zzz_generated/light-switch-app/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "lighting-app", + "output": "zzz_generated/lighting-app/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "lock-app", + "output": "zzz_generated/lock-app/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "log-source-app", + "output": "zzz_generated/log-source-app/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "ota-provider-app", + "output": "zzz_generated/ota-provider-app/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "ota-requestor-app", + "output": "zzz_generated/ota-requestor-app/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "pump-app", + "output": "zzz_generated/pump-app/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "pump-controller-app", + "output": "zzz_generated/pump-controller-app/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "temperature-measurement", + "output": "zzz_generated/temperature-measurement-app/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "thermostat", + "output": "zzz_generated/thermostat/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "tv-app", + "output": "zzz_generated/tv-app/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "tv-casting-app", + "output": "zzz_generated/tv-casting-app/zap-generated", + "zcl": "main", + "template": "app-zap" + }, + { + "zapFile": "window-app", + "output": "zzz_generated/window-app/zap-generated", + "zcl": "main", + "template": "app-zap" + } + ] +} diff --git a/scripts/tools/zap/generate.py b/scripts/tools/zap/generate.py index 72b63a1c7fbb6c..5034390e373cd7 100755 --- a/scripts/tools/zap/generate.py +++ b/scripts/tools/zap/generate.py @@ -136,7 +136,7 @@ def extractGeneratedIdl(output_dir, zap_config_path): def runGeneration(zap_file, zcl_file, templates_file, output_dir): - generator_dir = getDirPath('third_party/zap/repo') + generator_dir = os.getenv('ZAP_PATH', getDirPath('third_party/zap/repo')) os.chdir(generator_dir) subprocess.check_call(['node', './src-script/zap-generate.js', '-z', zcl_file, '-g', templates_file, '-i', zap_file, '-o', output_dir]) diff --git a/src/app/common/templates/templates.json b/src/app/common/templates/templates.json index 2e1ba3043bc24b..23838583aea61b 100644 --- a/src/app/common/templates/templates.json +++ b/src/app/common/templates/templates.json @@ -2,11 +2,11 @@ "name": "CHIP Application Common templates", "version": "chip-v1", "helpers": [ - "../../zap-templates/partials/helper.js", - "../../zap-templates/common/StringHelper.js", - "../../zap-templates/common/attributes/Accessors.js", - "../../zap-templates/templates/app/helper.js", - "../../zap-templates/templates/chip/helper.js" + "partials/helper.js", + "common/StringHelper.js", + "common/attributes/Accessors.js", + "templates/app/helper.js", + "templates/chip/helper.js" ], "override": "../../zap-templates/common/override.js", "partials": [ diff --git a/src/app/tests/suites/ciTests.json b/src/app/tests/suites/ciTests.json new file mode 100644 index 00000000000000..0e862676eb601b --- /dev/null +++ b/src/app/tests/suites/ciTests.json @@ -0,0 +1,277 @@ +{ + "AccessControl": [ + "TestAccessControlCluster", + "Test_TC_ACL_1_1", + "Test_TC_ACL_2_1", + "Test_TC_ACL_2_2" + ], + "BooleanState": ["Test_TC_BOOL_1_1", "Test_TC_BOOL_2_1"], + "Binding": ["Test_TC_BIND_1_1"], + "Actions": ["Test_TC_ACT_1_1"], + "ColorControl": [ + "Test_TC_CC_1_1", + "Test_TC_CC_2_1", + "Test_TC_CC_3_2", + "Test_TC_CC_3_3", + "Test_TC_CC_4_1", + "Test_TC_CC_4_2", + "Test_TC_CC_4_3", + "Test_TC_CC_4_4", + "Test_TC_CC_5_1", + "Test_TC_CC_5_2", + "Test_TC_CC_5_3", + "Test_TC_CC_6_1", + "Test_TC_CC_6_2", + "Test_TC_CC_6_3", + "Test_TC_CC_7_2", + "Test_TC_CC_7_3", + "Test_TC_CC_7_4", + "Test_TC_CC_8_1" + ], + "DeviceManagement": [ + "Test_TC_BINFO_1_1", + "Test_TC_BINFO_2_1", + "Test_TC_CNET_1_3" + ], + "Descriptor": ["Test_TC_DESC_1_1"], + "EthernetNetworkDiagnostics": [ + "Test_TC_DGETH_1_1", + "Test_TC_DGETH_2_1", + "Test_TC_DGETH_2_2" + ], + "FlowMeasurement": ["Test_TC_FLW_1_1", "Test_TC_FLW_2_1"], + "GeneralCommissioning": ["Test_TC_CGEN_1_1", "Test_TC_CGEN_2_1"], + "GeneralDiagnostics": ["Test_TC_DGGEN_1_1", "Test_TC_DGGEN_2_1"], + "Identify": [ + "Test_TC_I_1_1", + "Test_TC_I_2_1", + "Test_TC_I_2_2", + "Test_TC_I_2_3" + ], + "IlluminanceMeasurement": ["Test_TC_ILL_1_1", "Test_TC_ILL_2_1"], + "OccupancySensing": ["Test_TC_OCC_1_1", "Test_TC_OCC_2_1"], + "LevelControl": [ + "Test_TC_LVL_1_1", + "Test_TC_LVL_2_1", + "Test_TC_LVL_2_2", + "Test_TC_LVL_3_1", + "Test_TC_LVL_4_1", + "Test_TC_LVL_5_1", + "Test_TC_LVL_6_1" + ], + "UserLabel": [ + "Test_TC_ULABEL_1_1", + "Test_TC_ULABEL_2_2", + "Test_TC_ULABEL_2_3", + "Test_TC_ULABEL_2_4" + ], + "MediaControl": [ + "Test_TC_LOWPOWER_1_1", + "Test_TC_KEYPADINPUT_1_2", + "Test_TC_APPLAUNCHER_1_3", + "Test_TC_MEDIAINPUT_1_4", + "Test_TC_WAKEONLAN_1_5", + "Test_TC_CHANNEL_1_6", + "Test_TC_MEDIAPLAYBACK_1_7", + "Test_TC_AUDIOOUTPUT_1_8", + "Test_TC_TGTNAV_1_9", + "Test_TC_TGTNAV_8_2", + "Test_TC_APBSC_1_10", + "Test_TC_CONTENTLAUNCHER_1_11", + "Test_TC_ALOGIN_1_12", + "Test_TC_LOWPOWER_2_1", + "Test_TC_KEYPADINPUT_3_2", + "Test_TC_KEYPADINPUT_3_3", + "Test_TC_APPLAUNCHER_3_5", + "Test_TC_APPLAUNCHER_3_6", + "Test_TC_APPLAUNCHER_3_7", + "Test_TC_APPLAUNCHER_3_8", + "Test_TC_APPLAUNCHER_3_9", + "Test_TC_MEDIAINPUT_3_10", + "Test_TC_MEDIAINPUT_3_11", + "Test_TC_MEDIAINPUT_3_12", + "Test_TC_MEDIAINPUT_3_13", + "Test_TC_CHANNEL_5_1", + "Test_TC_CHANNEL_5_2", + "Test_TC_CHANNEL_5_3", + "Test_TC_MEDIAPLAYBACK_6_1", + "Test_TC_MEDIAPLAYBACK_6_2", + "Test_TC_MEDIAPLAYBACK_6_3", + "Test_TC_MEDIAPLAYBACK_6_4", + "Test_TC_AUDIOOUTPUT_7_1", + "Test_TC_AUDIOOUTPUT_7_2", + "Test_TC_TGTNAV_8_1", + "Test_TC_APBSC_9_1", + "Test_TC_CONTENTLAUNCHER_10_1" + ], + "ModeSelect": ["Test_TC_MOD_1_1"], + "MultipleFabrics": [], + "OTASoftwareUpdate": ["OTA_SuccessfulTransfer"], + "OnOff": [ + "Test_TC_OO_1_1", + "Test_TC_OO_2_1", + "Test_TC_OO_2_2", + "Test_TC_OO_2_4" + ], + "PowerSource": ["Test_TC_PS_1_1", "Test_TC_PS_2_1"], + "PressureMeasurement": ["Test_TC_PRS_1_1", "Test_TC_PRS_2_1"], + "PumpConfigurationControl": [ + "Test_TC_PCC_1_1", + "Test_TC_PCC_2_1", + "Test_TC_PCC_2_2", + "Test_TC_PCC_2_3", + "Test_TC_PCC_2_4" + ], + "PowerSourceConfiguration": ["Test_TC_PSCFG_1_1"], + "RelativeHumidityMeasurement": ["Test_TC_RH_1_1", "Test_TC_RH_2_1"], + "SecureChannel": ["Test_TC_SC_4_2"], + "Switch": ["Test_TC_SWTCH_1_1", "Test_TC_SWTCH_2_1"], + "TemperatureMeasurement": ["Test_TC_TMP_1_1", "Test_TC_TMP_2_1"], + "Thermostat": [ + "Test_TC_TSTAT_1_1", + "Test_TC_TSTAT_2_1", + "Test_TC_TSTAT_2_2" + ], + "ThermostatUserConfiguration": [ + "Test_TC_TSUIC_1_1", + "Test_TC_TSUIC_2_1", + "Test_TC_TSUIC_2_2" + ], + "ThreadNetworkDiagnostics": [ + "Test_TC_DGTHREAD_1_1", + "Test_TC_DGTHREAD_2_1", + "Test_TC_DGTHREAD_2_2", + "Test_TC_DGTHREAD_2_3", + "Test_TC_DGTHREAD_2_4" + ], + "WiFiNetworkDiagnostics": ["Test_TC_DGWIFI_2_1", "Test_TC_DGWIFI_2_3"], + "WindowCovering": [ + "Test_TC_WNCV_1_1", + "Test_TC_WNCV_2_1", + "Test_TC_WNCV_2_2", + "Test_TC_WNCV_2_3", + "Test_TC_WNCV_2_4", + "Test_TC_WNCV_2_5", + "Test_TC_WNCV_3_1", + "Test_TC_WNCV_3_2", + "Test_TC_WNCV_3_3", + "Test_TC_WNCV_3_4", + "Test_TC_WNCV_3_5", + "Test_TC_WNCV_4_1", + "Test_TC_WNCV_4_2", + "Test_TC_WNCV_4_3", + "Test_TC_WNCV_4_4", + "Test_TC_WNCV_4_5" + ], + "TV": [ + "TV_TargetNavigatorCluster", + "TV_AudioOutputCluster", + "TV_ApplicationLauncherCluster", + "TV_KeypadInputCluster", + "TV_AccountLoginCluster", + "TV_WakeOnLanCluster", + "TV_ApplicationBasicCluster", + "TV_MediaPlaybackCluster", + "TV_ChannelCluster", + "TV_LowPowerCluster", + "TV_ContentLauncherCluster", + "TV_MediaInputCluster" + ], + "Others": [ + "TestCASERecovery", + "TestCluster", + "TestClusterComplexTypes", + "TestConstraints", + "TestDelayCommands", + "TestEvents", + "TestDiscovery", + "TestLogCommands", + "TestSaveAs", + "TestConfigVariables", + "TestDescriptorCluster", + "TestBasicInformation", + "TestFabricRemovalWhileSubscribed", + "TestGeneralCommissioning", + "TestIdentifyCluster", + "TestOperationalCredentialsCluster", + "TestModeSelectCluster", + "TestSelfFabricRemoval", + "TestSystemCommands", + "TestBinding", + "TestUserLabelCluster", + "TestUserLabelClusterConstraints", + "TestArmFailSafe", + "TestFanControl", + "TestAccessControlConstraints", + "TestLevelControlWithOnOffDependency", + "TestCommissioningWindow" + ], + "MultiAdmin": ["TestMultiAdmin"], + "SoftwareDiagnostics": [ + "Test_TC_DGSW_1_1", + "Test_TC_DGSW_2_1", + "Test_TC_DGSW_2_2", + "Test_TC_DGSW_2_3" + ], + "Subscriptions": ["TestSubscribe_OnOff"], + "DoorLock": [ + "DL_UsersAndCredentials", + "DL_LockUnlock", + "DL_Schedules", + "Test_TC_DRLK_1_1", + "Test_TC_DRLK_2_2", + "Test_TC_DRLK_2_3", + "Test_TC_DRLK_2_4", + "Test_TC_DRLK_2_5", + "Test_TC_DRLK_2_7", + "Test_TC_DRLK_2_9" + ], + "Groups": [ + "TestGroupMessaging", + "TestGroupsCluster", + "TestGroupKeyManagementCluster" + ], + "collection": [ + "AccessControl", + "BooleanState", + "Actions", + "Binding", + "ColorControl", + "DeviceManagement", + "Descriptor", + "EthernetNetworkDiagnostics", + "FlowMeasurement", + "GeneralCommissioning", + "GeneralDiagnostics", + "Identify", + "IlluminanceMeasurement", + "LevelControl", + "MediaControl", + "ModeSelect", + "MultipleFabrics", + "OTASoftwareUpdate", + "OccupancySensing", + "OnOff", + "PowerSource", + "PressureMeasurement", + "PumpConfigurationControl", + "PowerSourceConfiguration", + "RelativeHumidityMeasurement", + "SecureChannel", + "Switch", + "TemperatureMeasurement", + "Thermostat", + "ThermostatUserConfiguration", + "ThreadNetworkDiagnostics", + "UserLabel", + "WiFiNetworkDiagnostics", + "WindowCovering", + "TV", + "Others", + "MultiAdmin", + "SoftwareDiagnostics", + "Subscriptions", + "DoorLock", + "Groups" + ] +} diff --git a/src/app/tests/suites/examples/TestGenExample.zapt b/src/app/tests/suites/examples/TestGenExample.zapt index c6db5d473bf558..89709513b96298 100644 --- a/src/app/tests/suites/examples/TestGenExample.zapt +++ b/src/app/tests/suites/examples/TestGenExample.zapt @@ -1,4 +1,4 @@ -{{#chip_tests (getTests)}} +{{#chip_tests "ciTests.json"}} {{#chip_tests_config}} "Argument Name {{name}}" "Argument Type {{type}}" diff --git a/src/app/tests/suites/examples/ciTests.json b/src/app/tests/suites/examples/ciTests.json new file mode 100644 index 00000000000000..6936377dd7885e --- /dev/null +++ b/src/app/tests/suites/examples/ciTests.json @@ -0,0 +1,8 @@ +{ + "TestExample": [ + "examples/Test_Example_1", + "examples/Test_Example_2", + "examples/Test_Example_3" + ], + "collection": ["TestExample"] +} diff --git a/src/app/tests/suites/examples/manualTests.json b/src/app/tests/suites/examples/manualTests.json new file mode 100644 index 00000000000000..c685c849dacb22 --- /dev/null +++ b/src/app/tests/suites/examples/manualTests.json @@ -0,0 +1,4 @@ +{ + "ExampleManualCataCategory": ["examples/Test_Example"], + "collection": ["ExampleManualCataCategory"] +} diff --git a/src/app/tests/suites/examples/templates/templates.json b/src/app/tests/suites/examples/templates/templates.json index 6c7f81544b1e89..2552115d92f13b 100644 --- a/src/app/tests/suites/examples/templates/templates.json +++ b/src/app/tests/suites/examples/templates/templates.json @@ -1,11 +1,12 @@ { "name": "CHIP README Templates", "version": "chip-v1", - "helpers": [ - "../../../../zap-templates/common/ClusterTestGeneration.js", - "tests.js" - ], - + "helpers": ["common/ClusterTestGeneration.js"], + "resources": { + "pics-metafile": "../../../../app/tests/suites/certification/PICS.yaml", + "certification-metadir": "../../../../app/tests/suites/certification", + "test-metadir": "../../../../app/tests/suites" + }, "templates": [ { "path": "../TestGenExample.zapt", diff --git a/src/app/tests/suites/examples/templates/tests.js b/src/app/tests/suites/examples/templates/tests.js deleted file mode 100644 index 2328879f061283..00000000000000 --- a/src/app/tests/suites/examples/templates/tests.js +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * Copyright (c) 2022 Project CHIP Authors - * - * 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. - */ - -function getManualTests() -{ - const ExampleManualCataCategory = [ - 'examples/Test_Example', - ]; - - const tests = [ - ExampleManualCataCategory, // - - ]; - return tests.flat(1); -} - -function getTests() -{ - const TestExample = [ - 'examples/Test_Example_1', - 'examples/Test_Example_2', - 'examples/Test_Example_3', - ]; - - const tests = [ - TestExample, // - ]; - return tests.flat(1); -} - -// -// Module exports -// -exports.getTests = getTests; -exports.getManualTests = getManualTests; diff --git a/src/app/tests/suites/manualTests.json b/src/app/tests/suites/manualTests.json new file mode 100644 index 00000000000000..19f48bc4586852 --- /dev/null +++ b/src/app/tests/suites/manualTests.json @@ -0,0 +1,406 @@ +{ + "DeviceDiscovery": [ + "Test_TC_DD_1_5", + "Test_TC_DD_1_6", + "Test_TC_DD_1_7", + "Test_TC_DD_1_8", + "Test_TC_DD_1_9", + "Test_TC_DD_1_10", + "Test_TC_DD_1_11", + "Test_TC_DD_1_12", + "Test_TC_DD_1_13", + "Test_TC_DD_1_14", + "Test_TC_DD_1_15", + "Test_TC_DD_2_1", + "Test_TC_DD_2_2", + "Test_TC_DD_3_1", + "Test_TC_DD_3_2", + "Test_TC_DD_3_3", + "Test_TC_DD_3_4", + "Test_TC_DD_3_5", + "Test_TC_DD_3_6", + "Test_TC_DD_3_7", + "Test_TC_DD_3_8", + "Test_TC_DD_3_9", + "Test_TC_DD_3_10", + "Test_TC_DD_3_11", + "Test_TC_DD_3_12", + "Test_TC_DD_3_13", + "Test_TC_DD_3_14", + "Test_TC_DD_3_15", + "Test_TC_DD_3_16", + "Test_TC_DD_3_17", + "Test_TC_DD_3_18", + "Test_TC_DD_3_19", + "Test_TC_DD_3_20", + "Test_TC_DD_3_21" + ], + "Groups": [ + "TestGroupDemoCommand", + "TestGroupDemoConfig", + "Test_TC_G_1_1", + "Test_TC_G_2_1", + "Test_TC_G_2_2", + "Test_TC_G_2_3", + "Test_TC_G_3_1", + "Test_TC_G_3_2" + ], + "BulkDataExchangeProtocol": [ + "Test_TC_BDX_1_1", + "Test_TC_BDX_1_2", + "Test_TC_BDX_1_3", + "Test_TC_BDX_1_4", + "Test_TC_BDX_1_5", + "Test_TC_BDX_1_6", + "Test_TC_BDX_2_1", + "Test_TC_BDX_2_2", + "Test_TC_BDX_2_3", + "Test_TC_BDX_2_4", + "Test_TC_BDX_2_5" + ], + "bridge": ["Test_TC_BR_1", "Test_TC_BR_2", "Test_TC_BR_3", "Test_TC_BR_4"], + "DeviceAttestation": [ + "Test_TC_DA_1_1", + "Test_TC_DA_1_2", + "Test_TC_DA_1_3", + "Test_TC_DA_1_4", + "Test_TC_DA_1_5", + "Test_TC_DA_1_6", + "Test_TC_DA_1_7" + ], + "DeviceManagement": [ + "Test_TC_OPCREDS_1_2", + "Test_TC_BINFO_2_2", + "Test_TC_BINFO_2_4", + "Test_TC_OPCREDS_3_1", + "Test_TC_OPCREDS_3_2", + "Test_TC_OPCREDS_3_3", + "Test_TC_OPCREDS_3_4", + "Test_TC_CNET_4_1", + "Test_TC_CNET_4_2", + "Test_TC_CNET_4_3", + "Test_TC_CNET_4_4", + "Test_TC_CNET_4_5", + "Test_TC_CNET_4_6", + "Test_TC_CNET_4_9", + "Test_TC_CNET_4_10", + "Test_TC_CNET_4_11", + "Test_TC_CNET_4_12", + "Test_TC_CNET_4_13", + "Test_TC_CNET_4_14", + "Test_TC_CNET_4_15", + "Test_TC_CNET_4_16", + "Test_TC_CNET_4_17", + "Test_TC_CNET_4_18", + "Test_TC_CNET_4_19", + "Test_TC_CNET_4_20", + "Test_TC_CNET_4_21", + "Test_TC_CNET_4_22" + ], + "DiagnosticsLogs": [ + "Test_TC_DLOG_1_1", + "Test_TC_DLOG_2_1", + "Test_TC_DLOG_2_2", + "Test_TC_DLOG_3_1" + ], + "Descriptor": ["Test_TC_DESC_2_1", "Test_TC_DESC_2_2"], + "EthernetNetworkDiagnostics": ["Test_TC_DGETH_3_1", "Test_TC_DGETH_3_2"], + "GeneralCommissioning": ["Test_TC_CGEN_2_2", "Test_TC_CGEN_2_4"], + "GeneralDiagnostics": [ + "Test_TC_DGGEN_2_2", + "Test_TC_DGGEN_2_3", + "Test_TC_DGGEN_3_1" + ], + "Identify": ["Test_TC_I_3_1", "Test_TC_I_3_2"], + "IlluminanceMeasurement": ["Test_TC_ILL_2_2", "Test_TC_ILL_3_1"], + "InteractionDataModel": [ + "Test_TC_IDM_1_1", + "Test_TC_IDM_1_2", + "Test_TC_IDM_2_1", + "Test_TC_IDM_2_2", + "Test_TC_IDM_3_1", + "Test_TC_IDM_3_2", + "Test_TC_IDM_4_1", + "Test_TC_IDM_4_2", + "Test_TC_IDM_4_3", + "Test_TC_IDM_5_1", + "Test_TC_IDM_5_2", + "Test_TC_IDM_6_1", + "Test_TC_IDM_6_2", + "Test_TC_IDM_6_3", + "Test_TC_IDM_6_4", + "Test_TC_IDM_7_1", + "Test_TC_IDM_8_1" + ], + "MediaControl": [ + "Test_TC_LOWPOWER_2_2", + "Test_TC_APPLAUNCHER_3_7_1", + "Test_TC_APPLAUNCHER_3_8_1", + "Test_TC_APPLAUNCHER_3_9_1", + "Test_TC_MEDIAINPUT_3_14", + "Test_TC_MEDIAINPUT_3_15", + "Test_TC_MEDIAINPUT_3_16", + "Test_TC_MEDIAINPUT_3_17", + "Test_TC_WAKEONLAN_4_1", + "Test_TC_CHANNEL_5_4", + "Test_TC_CHANNEL_5_5", + "Test_TC_CHANNEL_5_6", + "Test_TC_KEYPADINPUT_3_1", + "Test_TC_MEDIAPLAYBACK_6_5", + "Test_TC_MEDIAPLAYBACK_6_7", + "Test_TC_AUDIOOUTPUT_7_3", + "Test_TC_AUDIOOUTPUT_7_4", + "Test_TC_CONTENTLAUNCHER_10_3", + "Test_TC_CONTENTLAUNCHER_10_4", + "Test_TC_CONTENTLAUNCHER_10_5", + "Test_TC_CONTENTLAUNCHER_10_7", + "Test_TC_MC_11_1", + "Test_TC_MC_11_2", + "Test_TC_ALOGIN_12_1", + "Test_TC_ALOGIN_12_2" + ], + "MultipleFabrics": [ + "Test_TC_CADMIN_1_1", + "Test_TC_CADMIN_1_2", + "Test_TC_CADMIN_1_7", + "Test_TC_CADMIN_1_8", + "Test_TC_CADMIN_1_11", + "Test_TC_CADMIN_1_12", + "Test_TC_CADMIN_1_14", + "Test_TC_CADMIN_1_15", + "Test_TC_CADMIN_1_16", + "Test_TC_CADMIN_1_17", + "Test_TC_CADMIN_1_18", + "Test_TC_CADMIN_1_19", + "Test_TC_CADMIN_1_20", + "Test_TC_CADMIN_1_21", + "Test_TC_CADMIN_1_22", + "Test_TC_CADMIN_1_3", + "Test_TC_CADMIN_1_4", + "Test_TC_CADMIN_1_5", + "Test_TC_CADMIN_1_6", + "Test_TC_CADMIN_1_9", + "Test_TC_CADMIN_1_10", + "Test_TC_CADMIN_1_13", + "Test_TC_CADMIN_1_23", + "Test_TC_CADMIN_1_24" + ], + "ModeSelect": [ + "Test_TC_MOD_1_2", + "Test_TC_MOD_1_3", + "Test_TC_MOD_2_1", + "Test_TC_MOD_2_2", + "Test_TC_MOD_3_1", + "Test_TC_MOD_3_2", + "Test_TC_MOD_3_3", + "Test_TC_MOD_3_4" + ], + "OTASoftwareUpdate": [ + "Test_TC_SU_1_1", + "Test_TC_SU_2_1", + "Test_TC_SU_2_2", + "Test_TC_SU_2_3", + "Test_TC_SU_2_4", + "Test_TC_SU_2_5", + "Test_TC_SU_2_6", + "Test_TC_SU_2_7", + "Test_TC_SU_2_8", + "Test_TC_SU_3_1", + "Test_TC_SU_3_2", + "Test_TC_SU_3_3", + "Test_TC_SU_3_4", + "Test_TC_SU_4_1", + "Test_TC_SU_4_2" + ], + "PowerSourceConfiguration": [ + "Test_TC_PSCFG_2_1", + "Test_TC_PSCFG_2_2", + "Test_TC_PSCFG_3_1" + ], + "SecureChannel": [ + "Test_TC_SC_1_1", + "Test_TC_SC_1_2", + "Test_TC_SC_1_3", + "Test_TC_SC_1_4", + "Test_TC_SC_2_1", + "Test_TC_SC_2_2", + "Test_TC_SC_2_3", + "Test_TC_SC_2_4", + "Test_TC_SC_3_1", + "Test_TC_SC_3_2", + "Test_TC_SC_3_3", + "Test_TC_SC_3_4", + "Test_TC_SC_3_6", + "Test_TC_SC_4_1", + "Test_TC_SC_4_3", + "Test_TC_SC_4_4", + "Test_TC_SC_4_5", + "Test_TC_SC_4_6", + "Test_TC_SC_4_7", + "Test_TC_SC_4_8", + "Test_TC_SC_4_9", + "Test_TC_SC_4_10" + ], + "SoftwareDiagnostics": ["Test_TC_DGSW_3_1", "Test_TC_DGSW_3_2"], + "WiFiNetworkDiagnostics": [ + "Test_TC_DGWIFI_1_1", + "Test_TC_DGWIFI_2_2", + "Test_TC_DGWIFI_3_1", + "Test_TC_DGWIFI_3_2" + ], + "WindowCovering": ["Test_TC_WNCV_6_1", "Test_TC_WNCV_7_1"], + "FlowMeasurement": ["Test_TC_FLW_2_2", "Test_TC_FLW_3_1"], + "OccupancySensing": [ + "Test_TC_OCC_2_2", + "Test_TC_OCC_2_3", + "Test_TC_OCC_2_4", + "Test_TC_OCC_3_1", + "Test_TC_OCC_3_2" + ], + "PressureMeasurement": ["Test_TC_PRS_2_2", "Test_TC_PRS_3_1"], + "PowerSource": ["Test_TC_PS_2_2", "Test_TC_PS_3_1"], + "BooleanState": ["Test_TC_BOOL_2_2", "Test_TC_BOOL_3_1"], + "ColorControl": [ + "Test_TC_CC_2_2", + "Test_TC_CC_3_4", + "Test_TC_CC_4_5", + "Test_TC_CC_5_4", + "Test_TC_CC_6_4", + "Test_TC_CC_7_5", + "Test_TC_CC_9_4", + "Test_TC_CC_3_1", + "Test_TC_CC_7_1", + "Test_TC_CC_9_1", + "Test_TC_CC_9_2", + "Test_TC_CC_9_3" + ], + "DoorLock": [ + "Test_TC_DRLK_2_1", + "Test_TC_DRLK_2_6", + "Test_TC_DRLK_2_8", + "Test_TC_DRLK_2_10", + "Test_TC_DRLK_3_1", + "Test_TC_DRLK_3_2", + "Test_TC_DRLK_3_3" + ], + "LocalizationConfiguration": [ + "Test_TC_LCFG_1_1", + "Test_TC_LCFG_2_1", + "Test_TC_LCFG_3_1" + ], + "LevelControl": ["Test_TC_LVL_2_3", "Test_TC_LVL_7_1", "Test_TC_LVL_8_1"], + "OnOff": ["Test_TC_OO_2_3", "Test_TC_OO_3_1", "Test_TC_OO_3_2"], + "RelativeHumidityMeasurement": ["Test_TC_RH_2_2", "Test_TC_RH_3_1"], + "Switch": ["Test_TC_SWTCH_2_2", "Test_TC_SWTCH_3_1", "Test_TC_SWTCH_3_2"], + "TemperatureMeasurement": ["Test_TC_TMP_2_2", "Test_TC_TMP_3_1"], + "Thermostat": ["Test_TC_TSTAT_3_1", "Test_TC_TSTAT_3_2"], + "ThermostatUserConfiguration": ["Test_TC_TSUIC_3_1"], + "ThreadNetworkDiagnostics": [ + "Test_TC_DGTHREAD_2_5", + "Test_TC_DGTHREAD_3_1", + "Test_TC_DGTHREAD_3_2", + "Test_TC_DGTHREAD_3_3", + "Test_TC_DGTHREAD_3_4", + "Test_TC_DGTHREAD_3_5" + ], + "Actions": [ + "Test_TC_ACT_2_1", + "Test_TC_ACT_2_2", + "Test_TC_ACT_3_1", + "Test_TC_ACT_3_2" + ], + "TimeFormatLocalization": [ + "Test_TC_LTIME_1_1", + "Test_TC_LTIME_1_2", + "Test_TC_LTIME_2_1", + "Test_TC_LTIME_3_1" + ], + "UnitLocalization": [ + "Test_TC_LUNIT_1_1", + "Test_TC_LUNIT_1_2", + "Test_TC_LUNIT_2_1", + "Test_TC_LUNIT_3_1" + ], + "FixedLabel": [ + "Test_TC_FLABEL_1_1", + "Test_TC_FLABEL_2_1", + "Test_TC_FLABEL_3_1" + ], + "Binding": ["Test_TC_BIND_2_1", "Test_TC_BIND_2_2", "Test_TC_BIND_2_3"], + "Scenes": [ + "Test_TC_S_1_1", + "Test_TC_S_2_1", + "Test_TC_S_2_2", + "Test_TC_S_2_3", + "Test_TC_S_3_1" + ], + "PumpConfigurationControl": ["Test_TC_PCC_3_1"], + "AccessControl": [ + "Test_TC_ACL_2_3", + "Test_TC_ACL_2_4", + "Test_TC_ACL_2_5", + "Test_TC_ACL_2_6", + "Test_TC_ACL_2_7", + "Test_TC_ACL_2_8", + "Test_TC_ACL_2_9", + "Test_TC_ACL_2_10" + ], + "UserLabel": ["Test_TC_ULABEL_2_1", "Test_TC_ULABEL_3_1"], + "BridgedDeviceBasicInformation": [ + "Test_TC_BRBINFO_1_1", + "Test_TC_BRBINFO_2_1", + "Test_TC_BRBINFO_2_2", + "Test_TC_BRBINFO_2_3" + ], + "collection": [ + "DeviceDiscovery", + "Groups", + "BulkDataExchangeProtocol", + "bridge", + "DeviceAttestation", + "DeviceManagement", + "DiagnosticsLogs", + "Descriptor", + "EthernetNetworkDiagnostics", + "GeneralCommissioning", + "GeneralDiagnostics", + "Identify", + "IlluminanceMeasurement", + "InteractionDataModel", + "MediaControl", + "MultipleFabrics", + "ModeSelect", + "OTASoftwareUpdate", + "PowerSourceConfiguration", + "SecureChannel", + "SoftwareDiagnostics", + "WiFiNetworkDiagnostics", + "WindowCovering", + "FlowMeasurement", + "OccupancySensing", + "PressureMeasurement", + "PowerSource", + "BooleanState", + "ColorControl", + "DoorLock", + "LocalizationConfiguration", + "LevelControl", + "OnOff", + "RelativeHumidityMeasurement", + "Switch", + "TemperatureMeasurement", + "Thermostat", + "ThermostatUserConfiguration", + "ThreadNetworkDiagnostics", + "Actions", + "TimeFormatLocalization", + "UnitLocalization", + "FixedLabel", + "Binding", + "Scenes", + "PumpConfigurationControl", + "AccessControl", + "UserLabel", + "BridgedDeviceBasicInformation" + ] +} diff --git a/src/app/tests/suites/templates/templates.json b/src/app/tests/suites/templates/templates.json index ec7d113bb14a9e..2a174671c2763b 100644 --- a/src/app/tests/suites/templates/templates.json +++ b/src/app/tests/suites/templates/templates.json @@ -2,11 +2,16 @@ "name": "CHIP Tests templates", "version": "chip-v1", "helpers": [ - "../../../zap-templates/common/StringHelper.js", - "../../../zap-templates/templates/app/helper.js", - "../../../zap-templates/templates/chip/helper.js", - "../../../zap-templates/common/ClusterTestGeneration.js" + "common/StringHelper.js", + "templates/app/helper.js", + "templates/chip/helper.js", + "common/ClusterTestGeneration.js" ], + "resources": { + "pics-metafile": "../../../tests/suites/certification/PICS.yaml", + "certification-metadir": "../../../tests/suites/certification", + "test-metadir": "../../../tests/suites" + }, "override": "../../../zap-templates/common/override.js", "partials": [ { diff --git a/src/app/tests/suites/tests.js b/src/app/tests/suites/tests.js deleted file mode 100644 index 86799a1415e135..00000000000000 --- a/src/app/tests/suites/tests.js +++ /dev/null @@ -1,945 +0,0 @@ -/* - * - * Copyright (c) 2021-2022 Project CHIP Authors - * - * 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. - */ - -function disable(testName) -{ - const index = this.indexOf(testName); - if (index == -1) { - const errStr = `Test ${testName} does not exists.`; - throw new Error(errStr); - } - - this.splice(index, 1); -} - -// clang-format off - -function getManualTests() { - const DeviceDiscovery = [ - "Test_TC_DD_1_5", - "Test_TC_DD_1_6", - "Test_TC_DD_1_7", - "Test_TC_DD_1_8", - "Test_TC_DD_1_9", - "Test_TC_DD_1_10", - "Test_TC_DD_1_11", - "Test_TC_DD_1_12", - "Test_TC_DD_1_13", - "Test_TC_DD_1_14", - "Test_TC_DD_1_15", - "Test_TC_DD_2_1", - "Test_TC_DD_2_2", - "Test_TC_DD_3_1", - "Test_TC_DD_3_2", - "Test_TC_DD_3_3", - "Test_TC_DD_3_4", - "Test_TC_DD_3_5", - "Test_TC_DD_3_6", - "Test_TC_DD_3_7", - "Test_TC_DD_3_8", - "Test_TC_DD_3_9", - "Test_TC_DD_3_10", - "Test_TC_DD_3_11", - "Test_TC_DD_3_12", - "Test_TC_DD_3_13", - "Test_TC_DD_3_14", - "Test_TC_DD_3_15", - "Test_TC_DD_3_16", - "Test_TC_DD_3_17", - "Test_TC_DD_3_18", - "Test_TC_DD_3_19", - "Test_TC_DD_3_20", - "Test_TC_DD_3_21", - ]; - - const Groups = [ - "TestGroupDemoCommand", - "TestGroupDemoConfig", - "Test_TC_G_1_1", - "Test_TC_G_2_1", - "Test_TC_G_2_2", - "Test_TC_G_2_3", - "Test_TC_G_3_1", - "Test_TC_G_3_2", - ]; - - const BulkDataExchangeProtocol = [ - "Test_TC_BDX_1_1", - "Test_TC_BDX_1_2", - "Test_TC_BDX_1_3", - "Test_TC_BDX_1_4", - "Test_TC_BDX_1_5", - "Test_TC_BDX_1_6", - "Test_TC_BDX_2_1", - "Test_TC_BDX_2_2", - "Test_TC_BDX_2_3", - "Test_TC_BDX_2_4", - "Test_TC_BDX_2_5", - ]; - - const bridge = [ - "Test_TC_BR_1", - "Test_TC_BR_2", - "Test_TC_BR_3", - "Test_TC_BR_4", - ]; - - const DeviceAttestation = [ - "Test_TC_DA_1_1", - "Test_TC_DA_1_2", - "Test_TC_DA_1_3", - "Test_TC_DA_1_4", - "Test_TC_DA_1_5", - "Test_TC_DA_1_6", - "Test_TC_DA_1_7", - ]; - - const DeviceManagement = [ - "Test_TC_OPCREDS_1_2", - "Test_TC_BINFO_2_2", - "Test_TC_BINFO_2_4", - "Test_TC_OPCREDS_3_1", - "Test_TC_OPCREDS_3_2", - "Test_TC_OPCREDS_3_3", - "Test_TC_OPCREDS_3_4", - "Test_TC_CNET_4_1", - "Test_TC_CNET_4_2", - "Test_TC_CNET_4_3", - "Test_TC_CNET_4_4", - "Test_TC_CNET_4_5", - "Test_TC_CNET_4_6", - "Test_TC_CNET_4_9", - "Test_TC_CNET_4_10", - "Test_TC_CNET_4_11", - "Test_TC_CNET_4_12", - "Test_TC_CNET_4_13", - "Test_TC_CNET_4_14", - "Test_TC_CNET_4_15", - "Test_TC_CNET_4_16", - "Test_TC_CNET_4_17", - "Test_TC_CNET_4_18", - "Test_TC_CNET_4_19", - "Test_TC_CNET_4_20", - "Test_TC_CNET_4_21", - "Test_TC_CNET_4_22", - ]; - - const DiagnosticsLogs = [ - "Test_TC_DLOG_1_1", - "Test_TC_DLOG_2_1", - "Test_TC_DLOG_2_2", - "Test_TC_DLOG_3_1", - ]; - - const Descriptor = [ - "Test_TC_DESC_2_1", - "Test_TC_DESC_2_2", - ]; - - const EthernetNetworkDiagnostics = [ - "Test_TC_DGETH_3_1", - "Test_TC_DGETH_3_2", - ]; - - const GeneralCommissioning = [ - "Test_TC_CGEN_2_2", - "Test_TC_CGEN_2_4", - ]; - - const GeneralDiagnostics = [ - "Test_TC_DGGEN_2_2", - "Test_TC_DGGEN_2_3", - "Test_TC_DGGEN_3_1", - ]; - - const Identify = [ - "Test_TC_I_3_1", - "Test_TC_I_3_2", - ]; - - const IlluminanceMeasurement = [ - "Test_TC_ILL_2_2", - "Test_TC_ILL_3_1", - ]; - - const InteractionDataModel = [ - "Test_TC_IDM_1_1", - "Test_TC_IDM_1_2", - "Test_TC_IDM_2_1", - "Test_TC_IDM_2_2", - "Test_TC_IDM_3_1", - "Test_TC_IDM_3_2", - "Test_TC_IDM_4_1", - "Test_TC_IDM_4_2", - "Test_TC_IDM_4_3", - "Test_TC_IDM_5_1", - "Test_TC_IDM_5_2", - "Test_TC_IDM_6_1", - "Test_TC_IDM_6_2", - "Test_TC_IDM_6_3", - "Test_TC_IDM_6_4", - "Test_TC_IDM_7_1", - "Test_TC_IDM_8_1", - ]; - - const MediaControl = [ - "Test_TC_LOWPOWER_2_2", - "Test_TC_APPLAUNCHER_3_7_1", - "Test_TC_APPLAUNCHER_3_8_1", - "Test_TC_APPLAUNCHER_3_9_1", - "Test_TC_MEDIAINPUT_3_14", - "Test_TC_MEDIAINPUT_3_15", - "Test_TC_MEDIAINPUT_3_16", - "Test_TC_MEDIAINPUT_3_17", - "Test_TC_WAKEONLAN_4_1", - "Test_TC_CHANNEL_5_4", - "Test_TC_CHANNEL_5_5", - "Test_TC_CHANNEL_5_6", - "Test_TC_KEYPADINPUT_3_1", - "Test_TC_MEDIAPLAYBACK_6_5", - "Test_TC_MEDIAPLAYBACK_6_7", - "Test_TC_AUDIOOUTPUT_7_3", - "Test_TC_AUDIOOUTPUT_7_4", - "Test_TC_CONTENTLAUNCHER_10_3", - "Test_TC_CONTENTLAUNCHER_10_4", - "Test_TC_CONTENTLAUNCHER_10_5", - "Test_TC_CONTENTLAUNCHER_10_7", - "Test_TC_MC_11_1", - "Test_TC_MC_11_2", - "Test_TC_ALOGIN_12_1", - "Test_TC_ALOGIN_12_2", - ]; - - const MultipleFabrics = [ - "Test_TC_CADMIN_1_1", - "Test_TC_CADMIN_1_2", - "Test_TC_CADMIN_1_7", - "Test_TC_CADMIN_1_8", - "Test_TC_CADMIN_1_11", - "Test_TC_CADMIN_1_12", - "Test_TC_CADMIN_1_14", - "Test_TC_CADMIN_1_15", - "Test_TC_CADMIN_1_16", - "Test_TC_CADMIN_1_17", - "Test_TC_CADMIN_1_18", - "Test_TC_CADMIN_1_19", - "Test_TC_CADMIN_1_20", - "Test_TC_CADMIN_1_21", - "Test_TC_CADMIN_1_22", - // Slow tests that should not run in CI because they take many minutes each - "Test_TC_CADMIN_1_3", - "Test_TC_CADMIN_1_4", - "Test_TC_CADMIN_1_5", - "Test_TC_CADMIN_1_6", - "Test_TC_CADMIN_1_9", - "Test_TC_CADMIN_1_10", - "Test_TC_CADMIN_1_13", - "Test_TC_CADMIN_1_23", - "Test_TC_CADMIN_1_24", - ]; - - const ModeSelect = [ - "Test_TC_MOD_1_2", - "Test_TC_MOD_1_3", - "Test_TC_MOD_2_1", - "Test_TC_MOD_2_2", - "Test_TC_MOD_3_1", - "Test_TC_MOD_3_2", - "Test_TC_MOD_3_3", - "Test_TC_MOD_3_4", - ]; - - const OTASoftwareUpdate = [ - "Test_TC_SU_1_1", - "Test_TC_SU_2_1", - "Test_TC_SU_2_2", - "Test_TC_SU_2_3", - "Test_TC_SU_2_4", - "Test_TC_SU_2_5", - "Test_TC_SU_2_6", - "Test_TC_SU_2_7", - "Test_TC_SU_2_8", - "Test_TC_SU_3_1", - "Test_TC_SU_3_2", - "Test_TC_SU_3_3", - "Test_TC_SU_3_4", - "Test_TC_SU_4_1", - "Test_TC_SU_4_2", - ]; - - const PowerSourceConfiguration = [ - "Test_TC_PSCFG_2_1", - "Test_TC_PSCFG_2_2", - "Test_TC_PSCFG_3_1", - ]; - - const SecureChannel = [ - "Test_TC_SC_1_1", - "Test_TC_SC_1_2", - "Test_TC_SC_1_3", - "Test_TC_SC_1_4", - "Test_TC_SC_2_1", - "Test_TC_SC_2_2", - "Test_TC_SC_2_3", - "Test_TC_SC_2_4", - "Test_TC_SC_3_1", - "Test_TC_SC_3_2", - "Test_TC_SC_3_3", - "Test_TC_SC_3_4", - "Test_TC_SC_3_6", - "Test_TC_SC_4_1", - "Test_TC_SC_4_3", - "Test_TC_SC_4_4", - "Test_TC_SC_4_5", - "Test_TC_SC_4_6", - "Test_TC_SC_4_7", - "Test_TC_SC_4_8", - "Test_TC_SC_4_9", - "Test_TC_SC_4_10", - ]; - - const SoftwareDiagnostics = [ - "Test_TC_DGSW_3_1", - "Test_TC_DGSW_3_2", - ]; - - const WiFiNetworkDiagnostics = [ - "Test_TC_DGWIFI_1_1", - "Test_TC_DGWIFI_2_2", - "Test_TC_DGWIFI_3_1", - "Test_TC_DGWIFI_3_2", - ]; - - const WindowCovering = [ - "Test_TC_WNCV_6_1", - "Test_TC_WNCV_7_1", - ]; - - const FlowMeasurement = [ - "Test_TC_FLW_2_2", - "Test_TC_FLW_3_1", - ]; - - const OccupancySensing = [ - "Test_TC_OCC_2_2", - "Test_TC_OCC_2_3", - "Test_TC_OCC_2_4", - "Test_TC_OCC_3_1", - "Test_TC_OCC_3_2", - ]; - - const PressureMeasurement = [ - "Test_TC_PRS_2_2", - "Test_TC_PRS_3_1", - ]; - - const PowerSource = [ - "Test_TC_PS_2_2", - "Test_TC_PS_3_1", - ]; - - const BooleanState = [ - "Test_TC_BOOL_2_2", - "Test_TC_BOOL_3_1", - ]; - - const ColorControl = [ - "Test_TC_CC_2_2", - "Test_TC_CC_3_4", - "Test_TC_CC_4_5", - "Test_TC_CC_5_4", - "Test_TC_CC_6_4", - "Test_TC_CC_7_5", - "Test_TC_CC_9_4", - // Slow tests that should not run in CI because they take many minutes each - "Test_TC_CC_3_1", - "Test_TC_CC_7_1", - "Test_TC_CC_9_1", - "Test_TC_CC_9_2", - "Test_TC_CC_9_3", - ]; - - const DoorLock = [ - "Test_TC_DRLK_2_1", - "Test_TC_DRLK_2_6", - "Test_TC_DRLK_2_8", - "Test_TC_DRLK_2_10", - "Test_TC_DRLK_3_1", - "Test_TC_DRLK_3_2", - "Test_TC_DRLK_3_3", - ]; - - const LocalizationConfiguration = [ - "Test_TC_LCFG_1_1", - "Test_TC_LCFG_2_1", - "Test_TC_LCFG_3_1", - ]; - - const LevelControl = [ - "Test_TC_LVL_2_3", - "Test_TC_LVL_7_1", - "Test_TC_LVL_8_1", - ]; - - const OnOff = [ - "Test_TC_OO_2_3", - "Test_TC_OO_3_1", - "Test_TC_OO_3_2", - ]; - - const RelativeHumidityMeasurement = [ - "Test_TC_RH_2_2", - "Test_TC_RH_3_1", - ]; - - const Switch = [ - "Test_TC_SWTCH_2_2", - "Test_TC_SWTCH_3_1", - "Test_TC_SWTCH_3_2", - ]; - - const TemperatureMeasurement = [ - "Test_TC_TMP_2_2", - "Test_TC_TMP_3_1", - ]; - - const Thermostat = [ - "Test_TC_TSTAT_3_1", - "Test_TC_TSTAT_3_2", - ]; - - const ThermostatUserConfiguration = [ - "Test_TC_TSUIC_3_1", - ]; - - const ThreadNetworkDiagnostics = [ - "Test_TC_DGTHREAD_2_5", - "Test_TC_DGTHREAD_3_1", - "Test_TC_DGTHREAD_3_2", - "Test_TC_DGTHREAD_3_3", - "Test_TC_DGTHREAD_3_4", - "Test_TC_DGTHREAD_3_5", - ]; - - const Actions = [ - "Test_TC_ACT_2_1", - "Test_TC_ACT_2_2", - "Test_TC_ACT_3_1", - "Test_TC_ACT_3_2", - ]; - - const TimeFormatLocalization = [ - "Test_TC_LTIME_1_1", - "Test_TC_LTIME_1_2", - "Test_TC_LTIME_2_1", - "Test_TC_LTIME_3_1", - ]; - - const UnitLocalization = [ - "Test_TC_LUNIT_1_1", - "Test_TC_LUNIT_1_2", - "Test_TC_LUNIT_2_1", - "Test_TC_LUNIT_3_1", - ]; - - const FixedLabel = [ - "Test_TC_FLABEL_1_1", - "Test_TC_FLABEL_2_1", - "Test_TC_FLABEL_3_1", - ]; - - const Binding = [ - "Test_TC_BIND_2_1", - "Test_TC_BIND_2_2", - "Test_TC_BIND_2_3", - ]; - - const Scenes = [ - "Test_TC_S_1_1", - "Test_TC_S_2_1", - "Test_TC_S_2_2", - "Test_TC_S_2_3", - "Test_TC_S_3_1", - ]; - - const PumpConfigurationControl = [ - "Test_TC_PCC_3_1", - ]; - - const AccessControl = [ - "Test_TC_ACL_2_3", - "Test_TC_ACL_2_4", - "Test_TC_ACL_2_5", - "Test_TC_ACL_2_6", - "Test_TC_ACL_2_7", - "Test_TC_ACL_2_8", - "Test_TC_ACL_2_9", - "Test_TC_ACL_2_10", - ]; - - const UserLabel = [ - "Test_TC_ULABEL_2_1", - "Test_TC_ULABEL_3_1", - ]; - - const BridgedDeviceBasicInformation = [ - "Test_TC_BRBINFO_1_1", - "Test_TC_BRBINFO_2_1", - "Test_TC_BRBINFO_2_2", - "Test_TC_BRBINFO_2_3", - ]; - - const tests = [ - DeviceDiscovery, - Groups, - BulkDataExchangeProtocol, - bridge, - DeviceAttestation, - DeviceManagement, - DiagnosticsLogs, - Descriptor, - EthernetNetworkDiagnostics, - GeneralCommissioning, - GeneralDiagnostics, - Identify, - IlluminanceMeasurement, - InteractionDataModel, - MediaControl, - MultipleFabrics, - ModeSelect, - OTASoftwareUpdate, - PowerSourceConfiguration, - SecureChannel, - SoftwareDiagnostics, - WiFiNetworkDiagnostics, - WindowCovering, - FlowMeasurement, - OccupancySensing, - PressureMeasurement, - PowerSource, - BooleanState, - ColorControl, - DoorLock, - LocalizationConfiguration, - LevelControl, - OnOff, - RelativeHumidityMeasurement, - Switch, - TemperatureMeasurement, - Thermostat, - ThermostatUserConfiguration, - ThreadNetworkDiagnostics, - Actions, - TimeFormatLocalization, - UnitLocalization, - FixedLabel, - Binding, - Scenes, - PumpConfigurationControl, - AccessControl, - UserLabel, - BridgedDeviceBasicInformation, - ].flat(1); - - tests.disable = disable.bind(tests); - return tests; -} - -function getTests() { - const AccessControl = [ - "TestAccessControlCluster", - "Test_TC_ACL_1_1", - "Test_TC_ACL_2_1", - "Test_TC_ACL_2_2", - ]; - - const BooleanState = [ - "Test_TC_BOOL_1_1", - "Test_TC_BOOL_2_1", - ]; - - const Actions = [ - "Test_TC_ACT_1_1", - ]; - - const Binding = [ - "Test_TC_BIND_1_1", - ] - - const ColorControl = [ - "Test_TC_CC_1_1", - "Test_TC_CC_2_1", - "Test_TC_CC_3_2", - "Test_TC_CC_3_3", - "Test_TC_CC_4_1", - "Test_TC_CC_4_2", - "Test_TC_CC_4_3", - "Test_TC_CC_4_4", - "Test_TC_CC_5_1", - "Test_TC_CC_5_2", - "Test_TC_CC_5_3", - "Test_TC_CC_6_1", - "Test_TC_CC_6_2", - "Test_TC_CC_6_3", - "Test_TC_CC_7_2", - "Test_TC_CC_7_3", - "Test_TC_CC_7_4", - "Test_TC_CC_8_1", - ]; - - const DeviceManagement = [ - "Test_TC_BINFO_1_1", - "Test_TC_BINFO_2_1", - "Test_TC_CNET_1_3", - ]; - - const Descriptor = [ - "Test_TC_DESC_1_1", - ]; - - const EthernetNetworkDiagnostics = [ - "Test_TC_DGETH_1_1", - "Test_TC_DGETH_2_1", - "Test_TC_DGETH_2_2", - ]; - - const FlowMeasurement = [ - "Test_TC_FLW_1_1", - "Test_TC_FLW_2_1", - ]; - - const GeneralCommissioning = [ - "Test_TC_CGEN_1_1", - "Test_TC_CGEN_2_1", - ]; - - const GeneralDiagnostics = [ - "Test_TC_DGGEN_1_1", - "Test_TC_DGGEN_2_1", - ]; - - const Identify = [ - "Test_TC_I_1_1", - "Test_TC_I_2_1", - "Test_TC_I_2_2", - "Test_TC_I_2_3", - ]; - - const IlluminanceMeasurement = [ - "Test_TC_ILL_1_1", - "Test_TC_ILL_2_1", - ]; - - const OccupancySensing = [ - "Test_TC_OCC_1_1", - "Test_TC_OCC_2_1", - ]; - - const LevelControl = [ - "Test_TC_LVL_1_1", - "Test_TC_LVL_2_1", - "Test_TC_LVL_2_2", - "Test_TC_LVL_3_1", - "Test_TC_LVL_4_1", - "Test_TC_LVL_5_1", - "Test_TC_LVL_6_1", - ]; - - const UserLabel = [ - "Test_TC_ULABEL_1_1", - "Test_TC_ULABEL_2_2", - "Test_TC_ULABEL_2_3", - "Test_TC_ULABEL_2_4", - ]; - - const MediaControl = [ - "Test_TC_LOWPOWER_1_1", - "Test_TC_KEYPADINPUT_1_2", - "Test_TC_APPLAUNCHER_1_3", - "Test_TC_MEDIAINPUT_1_4", - "Test_TC_WAKEONLAN_1_5", - "Test_TC_CHANNEL_1_6", - "Test_TC_MEDIAPLAYBACK_1_7", - "Test_TC_AUDIOOUTPUT_1_8", - "Test_TC_TGTNAV_1_9", - "Test_TC_TGTNAV_8_2", - "Test_TC_APBSC_1_10", - "Test_TC_CONTENTLAUNCHER_1_11", - "Test_TC_ALOGIN_1_12", - "Test_TC_LOWPOWER_2_1", - "Test_TC_KEYPADINPUT_3_2", - "Test_TC_KEYPADINPUT_3_3", - "Test_TC_APPLAUNCHER_3_5", - "Test_TC_APPLAUNCHER_3_6", - "Test_TC_APPLAUNCHER_3_7", - "Test_TC_APPLAUNCHER_3_8", - "Test_TC_APPLAUNCHER_3_9", - "Test_TC_MEDIAINPUT_3_10", - "Test_TC_MEDIAINPUT_3_11", - "Test_TC_MEDIAINPUT_3_12", - "Test_TC_MEDIAINPUT_3_13", - "Test_TC_CHANNEL_5_1", - "Test_TC_CHANNEL_5_2", - "Test_TC_CHANNEL_5_3", - "Test_TC_MEDIAPLAYBACK_6_1", - "Test_TC_MEDIAPLAYBACK_6_2", - "Test_TC_MEDIAPLAYBACK_6_3", - "Test_TC_MEDIAPLAYBACK_6_4", - "Test_TC_AUDIOOUTPUT_7_1", - "Test_TC_AUDIOOUTPUT_7_2", - "Test_TC_TGTNAV_8_1", - "Test_TC_APBSC_9_1", - "Test_TC_CONTENTLAUNCHER_10_1", - ]; - - const ModeSelect = [ - "Test_TC_MOD_1_1", - ]; - - const MultipleFabrics = [ - ]; - - const OTASoftwareUpdate = [ - "OTA_SuccessfulTransfer", - ]; - - const OnOff = [ - "Test_TC_OO_1_1", - "Test_TC_OO_2_1", - "Test_TC_OO_2_2", - "Test_TC_OO_2_4", - ]; - - const PowerSource = [ - "Test_TC_PS_1_1", - "Test_TC_PS_2_1", - ]; - - const PressureMeasurement = [ - "Test_TC_PRS_1_1", - "Test_TC_PRS_2_1", - ]; - - const PumpConfigurationControl = [ - "Test_TC_PCC_1_1", - "Test_TC_PCC_2_1", - "Test_TC_PCC_2_2", - "Test_TC_PCC_2_3", - "Test_TC_PCC_2_4", - ]; - - const PowerSourceConfiguration = [ - "Test_TC_PSCFG_1_1", - ]; - - const RelativeHumidityMeasurement = [ - "Test_TC_RH_1_1", - "Test_TC_RH_2_1", - ]; - - const SecureChannel = [ - "Test_TC_SC_4_2", - ]; - - const Switch = [ - "Test_TC_SWTCH_1_1", - "Test_TC_SWTCH_2_1", - ]; - - const TemperatureMeasurement = [ - "Test_TC_TMP_1_1", - "Test_TC_TMP_2_1", - ]; - - const Thermostat = [ - "Test_TC_TSTAT_1_1", - "Test_TC_TSTAT_2_1", - "Test_TC_TSTAT_2_2", - ]; - - const ThermostatUserConfiguration = [ - "Test_TC_TSUIC_1_1", - "Test_TC_TSUIC_2_1", - "Test_TC_TSUIC_2_2", - ]; - - const ThreadNetworkDiagnostics = [ - "Test_TC_DGTHREAD_1_1", - "Test_TC_DGTHREAD_2_1", - "Test_TC_DGTHREAD_2_2", - "Test_TC_DGTHREAD_2_3", - "Test_TC_DGTHREAD_2_4", - ]; - - const WiFiNetworkDiagnostics = [ - "Test_TC_DGWIFI_2_1", - "Test_TC_DGWIFI_2_3", - ]; - - const WindowCovering = [ - "Test_TC_WNCV_1_1", - "Test_TC_WNCV_2_1", - "Test_TC_WNCV_2_2", - "Test_TC_WNCV_2_3", - "Test_TC_WNCV_2_4", - "Test_TC_WNCV_2_5", - "Test_TC_WNCV_3_1", - "Test_TC_WNCV_3_2", - "Test_TC_WNCV_3_3", - "Test_TC_WNCV_3_4", - "Test_TC_WNCV_3_5", - "Test_TC_WNCV_4_1", - "Test_TC_WNCV_4_2", - "Test_TC_WNCV_4_3", - "Test_TC_WNCV_4_4", - "Test_TC_WNCV_4_5", - ]; - - const TV = [ - "TV_TargetNavigatorCluster", - "TV_AudioOutputCluster", - "TV_ApplicationLauncherCluster", - "TV_KeypadInputCluster", - "TV_AccountLoginCluster", - "TV_WakeOnLanCluster", - "TV_ApplicationBasicCluster", - "TV_MediaPlaybackCluster", - "TV_ChannelCluster", - "TV_LowPowerCluster", - "TV_ContentLauncherCluster", - "TV_MediaInputCluster", - ]; - - const Others = [ - "TestCASERecovery", - "TestCluster", - "TestClusterComplexTypes", - "TestConstraints", - "TestDelayCommands", - "TestEvents", - "TestDiscovery", - "TestLogCommands", - "TestSaveAs", - "TestConfigVariables", - "TestDescriptorCluster", - "TestBasicInformation", - "TestFabricRemovalWhileSubscribed", - "TestGeneralCommissioning", - "TestIdentifyCluster", - "TestOperationalCredentialsCluster", - "TestModeSelectCluster", - "TestSelfFabricRemoval", - "TestSystemCommands", - "TestBinding", - "TestUserLabelCluster", - "TestUserLabelClusterConstraints", - "TestArmFailSafe", - "TestFanControl", - "TestAccessControlConstraints", - "TestLevelControlWithOnOffDependency", - "TestCommissioningWindow", - ]; - - const MultiAdmin = [ - "TestMultiAdmin", - ]; - - const SoftwareDiagnostics = [ - "Test_TC_DGSW_1_1", - "Test_TC_DGSW_2_1", - "Test_TC_DGSW_2_2", - "Test_TC_DGSW_2_3", - ]; - - const Subscriptions = [ - "TestSubscribe_OnOff", - ]; - - const DoorLock = [ - "DL_UsersAndCredentials", - "DL_LockUnlock", - "DL_Schedules", - "Test_TC_DRLK_1_1", - "Test_TC_DRLK_2_2", - "Test_TC_DRLK_2_3", - "Test_TC_DRLK_2_4", - "Test_TC_DRLK_2_5", - "Test_TC_DRLK_2_7", - "Test_TC_DRLK_2_9", - ]; - - const Groups = [ - "TestGroupMessaging", - "TestGroupsCluster", - "TestGroupKeyManagementCluster", - ]; - - const tests = [ - AccessControl, - BooleanState, - Actions, - Binding, - ColorControl, - DeviceManagement, - Descriptor, - EthernetNetworkDiagnostics, - FlowMeasurement, - GeneralCommissioning, - GeneralDiagnostics, - Identify, - IlluminanceMeasurement, - LevelControl, - MediaControl, - ModeSelect, - MultipleFabrics, - OTASoftwareUpdate, - OccupancySensing, - OnOff, - PowerSource, - PressureMeasurement, - PumpConfigurationControl, - PowerSourceConfiguration, - RelativeHumidityMeasurement, - SecureChannel, - Switch, - TemperatureMeasurement, - Thermostat, - ThermostatUserConfiguration, - ThreadNetworkDiagnostics, - UserLabel, - WiFiNetworkDiagnostics, - WindowCovering, - TV, - Others, - MultiAdmin, - SoftwareDiagnostics, - Subscriptions, - DoorLock, - Groups, - ].flat(1); - - tests.disable = disable.bind(tests); - return tests; -} - -// clang-format on - -// -// Module exports -// -exports.getTests = getTests; -exports.getManualTests = getManualTests; diff --git a/src/app/zap-templates/common/ChipTypesHelper.js b/src/app/zap-templates/common/ChipTypesHelper.js deleted file mode 100644 index e82c599c6d8783..00000000000000 --- a/src/app/zap-templates/common/ChipTypesHelper.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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. - */ - -function asBasicType(type) -{ - switch (type) { - case 'chip::ActionId': - case 'chip::FabricIndex': - case 'chip::Percent': - return 'uint8_t'; - case 'chip::EndpointId': - case 'chip::GroupId': - case 'chip::VendorId': - case 'chip::Percent100ths': - case 'chip::Protocols::InteractionModel::Status': - return 'uint16_t'; - case 'chip::ClusterId': - case 'chip::AttributeId': - case 'chip::FieldId': - case 'chip::EventId': - case 'chip::CommandId': - case 'chip::TransactionId': - case 'chip::DeviceTypeId': - case 'chip::StatusCode': - case 'chip::DataVersion': - return 'uint32_t'; - case 'chip::EventNumber': - case 'chip::FabricId': - case 'chip::NodeId': - return 'uint64_t'; - default: - return type; - } -} - -// -// Module exports -// -exports.asBasicType = asBasicType; diff --git a/src/app/zap-templates/common/ClusterTestGeneration.js b/src/app/zap-templates/common/ClusterTestGeneration.js deleted file mode 100644 index 88b15d029d6e29..00000000000000 --- a/src/app/zap-templates/common/ClusterTestGeneration.js +++ /dev/null @@ -1,1087 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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. - */ - -const basePath = '../../../../'; -const testPath = 'src/app/tests/suites/'; -const certificationPath = 'src/app/tests/suites/certification/'; -const zapPath = basePath + 'third_party/zap/repo/'; -const YAML = require(zapPath + 'node_modules/yaml'); -const fs = require('fs'); -const path = require('path'); - -// Import helpers from zap core -const templateUtil = require(zapPath + 'dist/src-electron/generator/template-util.js') -const zclHelper = require(zapPath + 'dist/src-electron/generator/helper-zcl.js'); -const queryEnum = require(zapPath + 'dist/src-electron/db/query-enum'); -const queryBitmap = require(zapPath + 'dist/src-electron/db/query-bitmap'); - -const { getClusters, getCommands, getAttributes, getEvents, isTestOnlyCluster } -= require('./simulated-clusters/SimulatedClusters.js'); -const { asBlocks, ensureClusters } = require('./ClustersHelper.js'); -const { Variables } = require('./variables/Variables.js'); - -const kIdentityName = 'identity'; -const kClusterName = 'cluster'; -const kEndpointName = 'endpoint'; -const kGroupId = 'groupId'; -const kCommandName = 'command'; -const kWaitCommandName = 'wait'; -const kIndexName = 'index'; -const kValuesName = 'values'; -const kConstraintsName = 'constraints'; -const kArgumentsName = 'arguments'; -const kResponseName = 'response'; -const kDisabledName = 'disabled'; -const kResponseErrorName = 'error'; -const kPICSName = 'PICS'; -const kSaveAsName = 'saveAs'; -const kFabricFiltered = 'fabricFiltered'; - -const kHexPrefix = 'hex:'; - -class NullObject { - toString() - { - return "YOU SHOULD HAVE CHECKED (isLiteralNull definedValue)" - } -}; - -function throwError(test, errorStr) -{ - console.error('Error in: ' + test.filename + '.yaml for test with label: "' + test.label + '"\n'); - console.error(errorStr); - throw new Error(); -} - -function setDefault(test, name, defaultValue) -{ - if (!(name in test)) { - if (defaultValue == null) { - const errorStr = 'Test does not have any "' + name + '" defined.'; - throwError(test, errorStr); - } - - test[name] = defaultValue; - } -} - -function setDefaultType(test) -{ - if (kWaitCommandName in test) { - setDefaultTypeForWaitCommand(test); - } else { - setDefaultTypeForCommand(test); - } -} - -function setDefaultTypeForWaitCommand(test) -{ - const type = test[kWaitCommandName]; - switch (type) { - case 'readEvent': - test.commandName = 'WaitEvent'; - test.isEvent = true; - test.isReadEvent = true; - break; - case 'subscribeEvent': - test.commandName = 'WaitEvent'; - test.isEvent = true; - test.isSubscribe = true; - test.isSubscribeEvent = true; - break; - case 'readAttribute': - test.commandName = 'WaitAttribute'; - test.isAttribute = true; - test.isReadAttribute = true; - break; - case 'writeAttribute': - test.commandName = 'WaitAttribute'; - test.isAttribute = true; - test.isWriteAttribute = true; - break; - case 'subscribeAttribute': - test.commandName = 'WaitAttribute'; - test.isAttribute = true; - test.isSubscribe = true; - test.isSubscribeAttribute = true; - break; - default: - test.commandName = 'WaitCommand'; - test.isCommand = true; - test.command = test.wait - break; - } - - test.isWait = true; -} - -function setDefaultTypeForCommand(test) -{ - const type = test[kCommandName]; - switch (type) { - case 'readEvent': - test.commandName = 'ReadEvent'; - test.isEvent = true; - test.isReadEvent = true; - break; - - case 'subscribeEvent': - test.commandName = 'SubscribeEvent'; - test.isEvent = true; - test.isSubscribe = true; - test.isSubscribeEvent = true; - break; - - case 'readAttribute': - test.commandName = 'ReadAttribute'; - test.isAttribute = true; - test.isReadAttribute = true; - if (!(kFabricFiltered in test)) { - test[kFabricFiltered] = true; - } - break; - - case 'writeAttribute': - test.commandName = 'WriteAttribute'; - test.isAttribute = true; - test.isWriteAttribute = true; - if ((kGroupId in test)) { - test.isGroupCommand = true; - test.isWriteGroupAttribute = true; - test.commandName = 'WriteGroupAttribute'; - test.groupId = parseInt(test[kGroupId], 10); - } - break; - - case 'subscribeAttribute': - test.commandName = 'SubscribeAttribute'; - test.isAttribute = true; - test.isSubscribe = true; - test.isSubscribeAttribute = true; - if (!(kFabricFiltered in test)) { - test[kFabricFiltered] = true; - } - break; - - case 'waitForReport': - test.commandName = 'WaitForReport'; - if ('attribute' in test) { - test.isAttribute = true; - } else if ('event' in test) { - test.isEvent = true; - } - test.isWaitForReport = true; - break; - - default: - test.commandName = isTestOnlyCluster(test.cluster) ? test.command : 'SendCommand'; - test.isCommand = true; - if ((kGroupId in test)) { - test.isGroupCommand = true; - test.commandName = 'SendGroupCommand'; - test.groupId = parseInt(test[kGroupId], 10); - } - break; - } - - // Sanity Check for GroupId usage - // Only two types of actions can be send to Group : Write attribute, and Commands - // Spec : Action 8.2.4 - if ((kGroupId in test) && !test.isGroupCommand) { - printErrorAndExit(this, 'Wrong Yaml configuration. Action : ' + test.commandName + " can't be sent to group " + test[kGroupId]); - } - - test.isWait = false; -} - -function setDefaultPICS(test) -{ - const defaultPICS = ''; - setDefault(test, kPICSName, defaultPICS); - - if (test[kPICSName] == '') { - return; - } - - const items = test[kPICSName].split(/[&|() !]+/g).filter(item => item.length); - items.forEach(key => { - if (!PICS.has(key)) { - const errorStr = 'PICS database does not contains any defined value for: ' + key; - throwError(test, errorStr); - } - }) -} - -function setDefaultArguments(test) -{ - const defaultArguments = {}; - setDefault(test, kArgumentsName, defaultArguments); - - const defaultArgumentsValues = []; - setDefault(test[kArgumentsName], kValuesName, defaultArgumentsValues); - - if (!test.isWriteAttribute) { - return; - } - - if (!('value' in test[kArgumentsName])) { - const errorStr = 'Test does not have a "value" defined.'; - throwError(test, errorStr); - } - - test[kArgumentsName].values.push({ name : test.attribute, value : test[kArgumentsName].value }); - delete test[kArgumentsName].value; -} - -function ensureValidError(response, errorName) -{ - if (isNaN(response[errorName])) { - response[errorName] = "EMBER_ZCL_STATUS_" + response[errorName]; - } -} - -function setDefaultResponse(test, useSynthesizeWaitForReport) -{ - // Some of the tests does not have any command defined. - if (!test.command || test.isWait) { - setDefault(test, kResponseName, []); - return; - } - - test.expectMultipleResponses = test.isEvent; - - const defaultResponse = test.expectMultipleResponses ? [] : {}; - setDefault(test, kResponseName, defaultResponse); - - // There is different syntax for expressing the expected response, but in the - // end it needs to be converted to an array of responses. - if (kResponseName in test && !Array.isArray(test[kResponseName])) { - let testValues = {}; - - const response = test[kResponseName]; - - if (kValuesName in response) { - testValues[kValuesName] = response[kValuesName]; - } else if ('value' in response || kConstraintsName in response || kSaveAsName in response) { - let obj = {}; - if ('value' in response) { - obj['value'] = response['value']; - } - - if (kConstraintsName in response) { - obj[kConstraintsName] = response[kConstraintsName]; - } - - if (kSaveAsName in response) { - obj[kSaveAsName] = response[kSaveAsName]; - } - - testValues[kValuesName] = [ obj ]; - } else { - testValues[kValuesName] = []; - } - - if (kResponseErrorName in response) { - testValues[kResponseErrorName] = response[kResponseErrorName]; - } - - if ('clusterError' in response) { - testValues['clusterError'] = response['clusterError']; - } - - test[kResponseName] = [ testValues ]; - } - - // Ensure only valid keywords are used for response values. - test[kResponseName].forEach(response => { - const values = response[kValuesName]; - for (let i = 0; i < values.length; i++) { - for (let key in values[i]) { - if (key == "name" || key == "value" || key == kConstraintsName || key == kSaveAsName) { - continue; - } - - const errorStr = `Unknown key "${key}" in "${JSON.stringify(values)}"`; - throwError(test, errorStr); - } - } - }); - - let responseType = ''; - if (test.isCommand) { - responseType = 'command'; - } else if (test.isAttribute) { - responseType = 'attribute'; - } else if (test.isEvent) { - responseType = 'event'; - } else { - const errorStr = 'Unknown response type'; - throwError(response, errorStr); - } - - const defaultName = test[responseType]; - - test[kResponseName].forEach(response => { - const hasResponseError = (kResponseErrorName in response); - - const defaultResponseError = 0; - setDefault(response, kResponseErrorName, defaultResponseError); - ensureValidError(response, kResponseErrorName); - - const values = response[kValuesName]; - values.forEach(expectedValue => { - const hasResponseValue = 'value' in expectedValue; - const hasResponseConstraints = (kConstraintsName in expectedValue) && !!Object.keys(expectedValue.constraints).length; - const hasResponseSaveAs = (kSaveAsName in expectedValue); - - if (test.isWriteAttribute || (useSynthesizeWaitForReport && test.isSubscribe)) { - if (hasResponseValue || hasResponseConstraints) { - const errorStr = 'Test has a "value" or a "constraints" defined.'; - throwError(test, errorStr); - } - } - - if (test.isCommand && !('name' in expectedValue)) { - const errorStr = 'Test value does not have a named argument.\n' + - '\n' + - 'Command should explicitly use the response argument name. Example: \n' + - '- label: "Send Test Specific Command"\n' + - ' command: "testSpecific"\n' + - ' response: \n' + - ' values: \n' + - ' - name: "returnValue"\n' + - ' - value: 7\n'; - throwError(test, errorStr); - } - - setDefault(expectedValue, 'name', defaultName); - }); - - setDefault(response, kCommandName, test.command); - setDefault(response, responseType, test[responseType]); - setDefault(response, kClusterName, test.cluster); - setDefault(response, 'optional', test.optional || false); - setDefault(response, 'async', test.async || false); - setDefaultType(response); - }); -} - -function setDefaults(test, defaultConfig, useSynthesizeWaitForReport) -{ - const defaultIdentityName = kIdentityName in defaultConfig ? defaultConfig[kIdentityName] : "alpha"; - const defaultClusterName = defaultConfig[kClusterName] || null; - const defaultEndpointId = kEndpointName in defaultConfig ? defaultConfig[kEndpointName] : null; - const defaultDisabled = false; - - setDefault(test, kIdentityName, defaultIdentityName); - setDefault(test, kClusterName, defaultClusterName); - setDefault(test, kEndpointName, defaultEndpointId); - setDefault(test, kDisabledName, defaultDisabled); - setDefaultType(test); - setDefaultPICS(test); - setDefaultArguments(test); - setDefaultResponse(test, useSynthesizeWaitForReport); -} - -function parse(filename, useSynthesizeWaitForReport) -{ - let filepath; - const isCertificationTest = filename.startsWith('Test_TC_'); - if (isCertificationTest) { - filepath = path.resolve(__dirname, basePath + certificationPath + filename + '.yaml'); - } else { - filepath = path.resolve(__dirname, basePath + testPath + filename + '.yaml'); - } - - const data = fs.readFileSync(filepath, { encoding : 'utf8', flag : 'r' }); - const yaml = YAML.parse(data); - - if (useSynthesizeWaitForReport) { - // "subscribeAttribute" command expects a report to be acked before - // it got a success response. - // In order to validate that the report has been received with the proper value - // a "subscribeAttribute" command can have a response configured into the test step - // definition. In this case, a new async "waitForReport" test step will be synthesized - // and added to the list of tests. - yaml.tests.forEach((test, index) => { - if (test.command == "subscribeAttribute" && test.response) { - // Create a new report test where the expected response is the response argument - // for the "subscribeAttributeTest" - const reportTest = { - label : "Report: " + test.label, - command : "waitForReport", - attribute : test.attribute, - response : test.response, - async : true, - allocateSubscribeDataCallback : true, - }; - delete test.response; - - // insert the new report test into the tests list - yaml.tests.splice(index, 0, reportTest); - - // Associate the "subscribeAttribute" test with the synthesized report test - test.hasWaitForReport = true; - test.waitForReport = reportTest; - test.allocateSubscribeDataCallback = !test.hasWaitForReport; - } - }); - } - - const defaultConfig = yaml.config || []; - yaml.tests.forEach(test => { - test.filename = filename; - test.testName = yaml.name; - setDefaults(test, defaultConfig, useSynthesizeWaitForReport); - }); - - // Filter disabled tests - yaml.tests = yaml.tests.filter(test => !test.disabled); - - yaml.tests.forEach((test, index) => { - setDefault(test, kIndexName, index); - }); - - yaml.filename = filename; - yaml.totalTests = yaml.tests.length; - - return yaml; -} - -function printErrorAndExit(context, msg) -{ - console.log("\nERROR:\n", context.testName, ': ', context.label); - console.log(msg); - process.exit(1); -} - -function assertCommandOrAttributeOrEvent(context) -{ - const clusterName = context.cluster; - return getClusters(context).then(clusters => { - if (!clusters.find(cluster => cluster.name == clusterName)) { - const names = clusters.map(item => item.name); - printErrorAndExit(context, 'Missing cluster "' + clusterName + '" in: \n\t* ' + names.join('\n\t* ')); - } - - let filterName; - let items; - - if (context.isCommand) { - filterName = context.command; - items = getCommands(context, clusterName); - } else if (context.isAttribute) { - filterName = context.attribute; - items = getAttributes(context, clusterName); - } else if (context.isEvent) { - filterName = context.event; - items = getEvents(context, clusterName); - } else { - printErrorAndExit(context, 'Unsupported command type: ', context); - } - - return items.then(items => { - const filter = item => item.name.toLowerCase() == filterName.toLowerCase(); - const item = items.find(filter); - const itemType = (context.isCommand ? 'Command' : context.isAttribute ? 'Attribute' : 'Event'); - - // If the command/attribute/event is not found, it could be because of a typo in the test - // description, or an attribute/event name not matching the spec, or a wrongly configured zap - // file. - if (!item) { - const names = items.map(item => item.name); - printErrorAndExit(context, 'Missing ' + itemType + ' "' + filterName + '" in: \n\t* ' + names.join('\n\t* ')); - } - - // If the command/attribute/event has been found but the response can not be found, it could be - // because of a wrongly configured cluster definition. - if (!item.response) { - printErrorAndExit(context, 'Missing ' + itemType + ' "' + filterName + '" response'); - } - - return item; - }); - }); -} - -const PICS = (() => { - let filepath = path.resolve(__dirname, basePath + certificationPath + 'PICS.yaml'); - const data = fs.readFileSync(filepath, { encoding : 'utf8', flag : 'r' }); - const yaml = YAML.parse(data); - - const getAll = () => yaml.PICS; - const get = (id) => has(id) ? yaml.PICS.filter(pics => pics.id == id)[0] : null; - const has = (id) => !!(yaml.PICS.filter(pics => pics.id == id)).length; - - const PICS = { - getAll : getAll, - get : get, - has : has, - }; - return PICS; -})(); - -// -// Templates -// -function chip_tests_pics(options) -{ - return templateUtil.collectBlocks(PICS.getAll(), options, this); -} - -async function configureTestItem(item) -{ - if (item.isCommand) { - let command = await assertCommandOrAttributeOrEvent(item); - item.commandObject = command; - item.hasSpecificArguments = true; - item.hasSpecificResponse = command.hasSpecificResponse || false; - } else if (item.isAttribute) { - let attr = await assertCommandOrAttributeOrEvent(item); - item.attributeObject = attr; - item.hasSpecificArguments = item.isWriteAttribute || false; - item.hasSpecificResponse = item.isReadAttribute || item.isSubscribeAttribute || item.isWaitForReport || false; - } else if (item.isEvent) { - let evt = await assertCommandOrAttributeOrEvent(item); - item.eventObject = evt; - item.hasSpecificArguments = false; - item.hasSpecificResponse = true; - } -} - -async function chip_tests(list, options) -{ - // Set a global on our items so assertCommandOrAttributeOrEvent can work. - let global = this.global; - const items = Array.isArray(list) ? list : list.split(','); - const names = items.map(name => name.trim()); - let tests = names.map(item => parse(item, options.hash.useSynthesizeWaitForReport)); - - const context = this; - tests = await Promise.all(tests.map(async function(test) { - test.tests = await Promise.all(test.tests.map(async function(item) { - item.global = global; - await configureTestItem(item); - - if (kResponseName in item) { - await Promise.all(item[kResponseName].map(response => configureTestItem(response))); - } - - return item; - })); - - const variables = await Variables(context, test); - test.variables = { - config : variables.config, - tests : variables.tests, - }; - return test; - })); - return templateUtil.collectBlocks(tests, options, this); -} - -function chip_tests_items(options) -{ - return templateUtil.collectBlocks(this.tests, options, this); -} - -function getVariable(context, key, name) -{ - if (!(typeof name == "string" || (typeof name == "object" && (name instanceof String)))) { - // Non-string key; don't try to look it up. Could end up looking like a - // variable name by accident when stringified. - return null; - } - - while (!('variables' in context) && context.parent) { - context = context.parent; - } - - if (typeof context === 'undefined' || !('variables' in context)) { - return null; - } - - return context.variables[key].find(variable => variable.name == name); -} - -function getVariableOrThrow(context, key, name) -{ - const variable = getVariable(context, key, name); - if (variable == null) { - throw new Error(`Variable ${name} can not be found`); - } - return variable; -} - -function chip_tests_variables(options) -{ - return templateUtil.collectBlocks(this.variables.tests, options, this); -} - -function chip_tests_variables_has(name, options) -{ - const variable = getVariable(this, 'tests', name); - return !!variable; -} - -function chip_tests_variables_get_type(name, options) -{ - const variable = getVariableOrThrow(this, 'tests', name); - return variable.type; -} - -function chip_tests_variables_is_nullable(name, options) -{ - const variable = getVariableOrThrow(this, 'tests', name); - return variable.isNullable; -} - -function chip_tests_config(options) -{ - return templateUtil.collectBlocks(this.variables.config, options, this); -} - -function chip_tests_config_has(name, options) -{ - const variable = getVariable(this, 'config', name); - return !!variable; -} - -function chip_tests_config_get_default_value(name, options) -{ - const variable = getVariableOrThrow(this, 'config', name); - return variable.defaultValue; -} - -function chip_tests_config_get_type(name, options) -{ - const variable = getVariableOrThrow(this, 'config', name); - return variable.type; -} - -// test_cluster_command_value and test_cluster_value-equals are recursive partials using #each. At some point the |global| -// context is lost and it fails. Make sure to attach the global context as a property of the | value | -// that is evaluated. -// -// errorContext should have "thisVal" and "name" properties that will be used -// for error reporting via printErrorAndExit. -function attachGlobal(global, value, errorContext) -{ - if (Array.isArray(value)) { - value = value.map(v => attachGlobal(global, v, errorContext)); - } else if (value instanceof Object) { - for (key in value) { - if (key == "global") { - continue; - } - value[key] = attachGlobal(global, value[key], errorContext); - } - } else if (value === null) { - value = new NullObject(); - } else { - switch (typeof value) { - case 'number': - checkNumberSanity(value, errorContext); - value = new Number(value); - break; - case 'string': - value = new String(value); - break; - case 'boolean': - value = new Boolean(value); - break; - default: - throw new Error('Unsupported value: ' + JSON.stringify(value)); - } - } - - value.global = global; - return value; -} - -/** - * Ensure the given value is not a possibly-corrupted-by-going-through-double - * integer. If it is, tell the user (using that errorContext.name to describe - * it) and die. - */ -function checkNumberSanity(value, errorContext) -{ - // Number.isInteger is false for non-Numbers. - if (Number.isInteger(value) && !Number.isSafeInteger(value)) { - printErrorAndExit(errorContext.thisVal, - `${errorContext.name} value ${ - value} is too large to represent exactly as an integer in YAML. Put quotes around it to treat it as a string.\n\n`); - } -} - -function chip_tests_item_parameters(options) -{ - if (this.isWait) { - return asBlocks.call(this, Promise.resolve([]), options); - } - - const commandValues = this.arguments.values; - - const promise = assertCommandOrAttributeOrEvent(this).then(item => { - if ((this.isAttribute || this.isEvent) && !this.isWriteAttribute) { - if (this.isSubscribe) { - const minInterval = { name : 'minInterval', type : 'int16u', chipType : 'uint16_t', definedValue : this.minInterval }; - const maxInterval = { name : 'maxInterval', type : 'int16u', chipType : 'uint16_t', definedValue : this.maxInterval }; - return [ minInterval, maxInterval ]; - } - return []; - } - - const commandArgs = item.arguments; - const commands = commandArgs.map(commandArg => { - commandArg = JSON.parse(JSON.stringify(commandArg)); - - const expected = commandValues.find(value => value.name.toLowerCase() == commandArg.name.toLowerCase()); - if (!expected) { - if (commandArg.isOptional) { - return undefined; - } - printErrorAndExit(this, - 'Missing "' + commandArg.name + '" in arguments list: \n\t* ' - + commandValues.map(command => command.name).join('\n\t* ')); - } - - commandArg.definedValue = attachGlobal(this.global, expected.value, { thisVal : this, name : commandArg.name }); - - return commandArg; - }); - - return commands.filter(item => item !== undefined); - }); - - return asBlocks.call(this, promise, options); -} - -function chip_tests_item_responses(options) -{ - return templateUtil.collectBlocks(this[kResponseName], options, this); -} - -function chip_tests_item_response_parameters(options) -{ - const responseValues = this.values.slice(); - - const promise = assertCommandOrAttributeOrEvent(this).then(item => { - if (this.isWriteAttribute) { - return []; - } - const responseArgs = item.response.arguments; - - const responses = responseArgs.map(responseArg => { - responseArg = JSON.parse(JSON.stringify(responseArg)); - - const expectedIndex = responseValues.findIndex(value => value.name.toLowerCase() == responseArg.name.toLowerCase()); - if (expectedIndex != -1) { - const expected = responseValues.splice(expectedIndex, 1)[0]; - if ('value' in expected) { - responseArg.hasExpectedValue = true; - responseArg.expectedValue = attachGlobal(this.global, expected.value, { thisVal : this, name : responseArg.name }); - } - - if ('constraints' in expected) { - responseArg.hasExpectedConstraints = true; - responseArg.expectedConstraints - = attachGlobal(this.global, expected.constraints, { thisVal : this, name : responseArg.name }); - } - - if ('saveAs' in expected) { - responseArg.saveAs = expected.saveAs; - } - } - - return responseArg; - }); - - const unusedResponseValues = responseValues.filter(response => 'value' in response); - unusedResponseValues.forEach(unusedResponseValue => { - printErrorAndExit(this, - 'Missing "' + unusedResponseValue.name + '" in response arguments list:\n\t* ' - + responseArgs.map(response => response.name).join('\n\t* ')); - }); - - return responses; - }); - - return asBlocks.call(this, promise, options); -} - -function isLiteralNull(value, options) -{ - // Literal null might look different depending on whether it went through - // attachGlobal or not. - return (value === null) || (value instanceof NullObject); -} - -function isHexString(value) -{ - return value && value.startsWith(kHexPrefix); -} - -function octetStringFromHexString(value) -{ - const hexString = value.substring(kHexPrefix.length); - - if (hexString.length % 2) { - throw new Error("The provided hexadecimal string contains an even number of characters"); - } - - if (!(/^[0-9a-fA-F]+$/.test(hexString))) { - throw new Error("The provided hexadecimal string contains invalid hexadecimal character."); - } - - const bytes = hexString.match(/(..)/g); - return bytes.map(byte => '\\x' + byte).join(''); -} - -function octetStringLengthFromHexString(value) -{ - const hexString = value.substring(kHexPrefix.length); - return (hexString.length / 2); -} - -function octetStringEscapedForCLiteral(value) -{ - // Escape control characters, things outside the ASCII range, and single - // quotes (because that's our string terminator). - return value.replace(/\p{Control}|\P{ASCII}|"/gu, ch => { - var code = ch.charCodeAt(0).toString(8) - return "\\" + - "0".repeat(3 - code.length) + code; - }); -} - -// Structs may not always provide values for optional members. -function if_include_struct_item_value(structValue, name, options) -{ - let hasValue = (name in structValue); - if (hasValue) { - return options.fn(this); - } - - if (!this.isOptional) { - throw new Error(`Value not provided for ${name} where one is expected in ` + JSON.stringify(structValue)); - } - - return options.inverse(this); -} - -// To be used to verify that things are actually arrays before trying to use -// #each with them, since that silently treats non-arrays as empty arrays. -function ensureIsArray(value, options) -{ - if (!(value instanceof Array)) { - printErrorAndExit(this, `Expected array but instead got ${typeof value}: ${JSON.stringify(value)}\n`); - } -} - -function checkIsInsideTestOnlyClusterBlock(conditions, name) -{ - conditions.forEach(condition => { - if (condition == undefined) { - const errorStr = `Not inside a ({#${name}}} block.`; - console.error(errorStr); - throw new Error(errorStr); - } - }); -} - -/** - * Creates block iterator over the simulated clusters. - * - * @param {*} options - */ -async function chip_tests_only_clusters(options) -{ - const clusters = await getClusters(this); - const testOnlyClusters = clusters.filter(cluster => isTestOnlyCluster(cluster.name)); - return asBlocks.call(this, Promise.resolve(testOnlyClusters), options); -} - -/** - * Creates block iterator over the cluster commands for a given simulated cluster. - * - * This function is meant to be used inside a {{#chip_tests_only_clusters}} - * block. It will throw otherwise. - * - * @param {*} options - */ -async function chip_tests_only_cluster_commands(options) -{ - const conditions = [ isTestOnlyCluster(this.name) ]; - checkIsInsideTestOnlyClusterBlock(conditions, 'chip_tests_only_clusters'); - - const commands = await getCommands(this, this.name); - return asBlocks.call(this, Promise.resolve(commands), options); -} - -/** - * Creates block iterator over the command arguments for a given simulated cluster command. - * - * This function is meant to be used inside a {{#chip_tests_only_cluster_commands}} - * block. It will throw otherwise. - * - * @param {*} options - */ -async function chip_tests_only_cluster_command_parameters(options) -{ - const conditions = [ isTestOnlyCluster(this.parent.name), this.arguments, this.response ]; - checkIsInsideTestOnlyClusterBlock(conditions, 'chip_tests_only_cluster_commands'); - - return asBlocks.call(this, Promise.resolve(this.arguments), options); -} - -/** - * Creates block iterator over the cluster responses for a given simulated cluster. - * - * This function is meant to be used inside a {{#chip_tests_only_clusters}} - * block. It will throw otherwise. - * - * @param {*} options - */ -async function chip_tests_only_cluster_responses(options) -{ - const conditions = [ isTestOnlyCluster(this.name) ]; - checkIsInsideTestOnlyClusterBlock(conditions, 'chip_tests_only_clusters'); - - const commands = await getCommands(this, this.name); - const responses = []; - commands.forEach(command => { - if (!command.response.arguments) { - return; - } - - if (!('responseName' in command)) { - return; - } - - const alreadyExists = responses.some(item => item.responseName == command.responseName); - if (alreadyExists) { - return; - } - - command.response.responseName = command.responseName; - responses.push(command.response); - }); - - return asBlocks.call(this, Promise.resolve(responses), options); -} - -/** - * Creates block iterator over the response arguments for a given simulated cluster response. - * - * This function is meant to be used inside a {{#chip_tests_only_cluster_responses}} - * block. It will throw otherwise. - * - * @param {*} options - */ -async function chip_tests_only_cluster_response_parameters(options) -{ - const conditions = [ isTestOnlyCluster(this.parent.name), this.arguments, this.responseName ]; - checkIsInsideTestOnlyClusterBlock(conditions, 'chip_tests_only_cluster_responses'); - - return asBlocks.call(this, Promise.resolve(this.arguments), options); -} - -function chip_tests_iterate_expected_list(values, options) -{ - let context = options.hash.context || this; - values = values.map(value => { - return { - global: context.global, parent: context.parent, name: context.name, type: context.type, isArray: false, isNullable: false, - value: value, - } - }); - - return asBlocks.call(this, Promise.resolve(values), options); -} - -function chip_tests_iterate_constraints(constraints, options) -{ - let values = []; - for (let key of Object.keys(constraints)) { - // Skip "global", because that's not an actual constraint. - if (key == "global") { - continue; - } - values.push({ global : this.global, constraint : key, value : constraints[key] }) - } - - return asBlocks.call(this, Promise.resolve(values), options) -} - -async function asTestType(type, isList) -{ - if (isList) { - return 'list'; - } - - const pkgId = await templateUtil.ensureZclPackageId(this); - const db = this.global.db; - - const isEnum = await zclHelper.isEnum(db, type, pkgId); - if (isEnum != 'unknown') { - const enumObj = await queryEnum.selectEnumByName(db, type, pkgId); - return 'enum' + (8 * enumObj.size); - } - - const isBitmap = await zclHelper.isBitmap(db, type, pkgId); - if (isBitmap != 'unknown') { - const bitmapObj = await queryBitmap.selectBitmapByName(db, pkgId, type); - return 'bitmap' + (8 * bitmapObj.size); - } - - return type; -} - -// -// Module exports -// -exports.chip_tests = chip_tests; -exports.chip_tests_items = chip_tests_items; -exports.chip_tests_item_parameters = chip_tests_item_parameters; -exports.chip_tests_item_responses = chip_tests_item_responses; -exports.chip_tests_item_response_parameters = chip_tests_item_response_parameters; -exports.chip_tests_pics = chip_tests_pics; -exports.chip_tests_config = chip_tests_config; -exports.chip_tests_config_has = chip_tests_config_has; -exports.chip_tests_config_get_default_value = chip_tests_config_get_default_value; -exports.chip_tests_config_get_type = chip_tests_config_get_type; -exports.chip_tests_variables = chip_tests_variables; -exports.chip_tests_variables_has = chip_tests_variables_has; -exports.chip_tests_variables_get_type = chip_tests_variables_get_type; -exports.chip_tests_variables_is_nullable = chip_tests_variables_is_nullable; -exports.isTestOnlyCluster = isTestOnlyCluster; -exports.isLiteralNull = isLiteralNull; -exports.octetStringEscapedForCLiteral = octetStringEscapedForCLiteral; -exports.if_include_struct_item_value = if_include_struct_item_value; -exports.ensureIsArray = ensureIsArray; -exports.chip_tests_only_clusters = chip_tests_only_clusters; -exports.chip_tests_only_cluster_commands = chip_tests_only_cluster_commands; -exports.chip_tests_only_cluster_command_parameters = chip_tests_only_cluster_command_parameters; -exports.chip_tests_only_cluster_responses = chip_tests_only_cluster_responses; -exports.chip_tests_only_cluster_response_parameters = chip_tests_only_cluster_response_parameters; -exports.isHexString = isHexString; -exports.octetStringLengthFromHexString = octetStringLengthFromHexString; -exports.octetStringFromHexString = octetStringFromHexString; -exports.chip_tests_iterate_expected_list = chip_tests_iterate_expected_list; -exports.chip_tests_iterate_constraints = chip_tests_iterate_constraints; -exports.asTestType = asTestType; diff --git a/src/app/zap-templates/common/ClustersHelper.js b/src/app/zap-templates/common/ClustersHelper.js deleted file mode 100644 index 320478ff0c4b0b..00000000000000 --- a/src/app/zap-templates/common/ClustersHelper.js +++ /dev/null @@ -1,941 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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 helpers from zap core -const zapPath = '../../../../third_party/zap/repo/dist/src-electron/'; -const queryConfig = require(zapPath + 'db/query-config.js') -const queryCommand = require(zapPath + 'db/query-command.js') -const queryEndpoint = require(zapPath + 'db/query-endpoint.js') -const queryEndpointType = require(zapPath + 'db/query-endpoint-type.js') -const queryEvent = require(zapPath + 'db/query-event.js') -const templateUtil = require(zapPath + 'generator/template-util.js') -const zclHelper = require(zapPath + 'generator/helper-zcl.js') -const zclQuery = require(zapPath + 'db/query-zcl.js') - -const { Deferred } = require('./Deferred.js'); -const ListHelper = require('./ListHelper.js'); -const StringHelper = require('./StringHelper.js'); -const ChipTypesHelper = require('./ChipTypesHelper.js'); - -// Helper for better error reporting. -function ensureState(condition, error) -{ - if (!condition) { - let err = new Error(error); - console.log(`${error}: ` + err.stack); - throw err; - } -} - -// -// Load Step 1 -// -function loadAtomics(packageId) -{ - const { db, sessionId } = this.global; - const options = { 'hash' : {} }; - - const resolveZclTypes = atomics => Promise.all(atomics.map(atomic => { - return zclHelper.asUnderlyingZclType.call(this, atomic.name, options).then(zclType => { - atomic.chipType = zclType; - return atomic; - }); - })); - - return zclQuery.selectAllAtomics(db, packageId).then(resolveZclTypes); -} - -function loadBitmaps(packageId) -{ - const { db, sessionId } = this.global; - return zclQuery.selectAllBitmaps(db, packageId); -} - -function loadEnums(packageId) -{ - const { db, sessionId } = this.global; - return zclQuery.selectAllEnums(db, packageId); -} - -function loadStructItems(struct, packageId) -{ - const { db, sessionId } = this.global; - return zclQuery.selectAllStructItemsById(db, struct.id).then(structItems => { - struct.items = structItems; - return struct; - }); -} - -function loadStructs(packageId) -{ - const { db, sessionId } = this.global; - return zclQuery.selectAllStructsWithItemCount(db, packageId) - .then(structs => Promise.all(structs.map(struct => loadStructItems.call(this, struct, packageId)))); -} - -/** - * Loads endpoint data, specifically what endpoints are available and what clusters - * are defined within those endpoints. - */ -async function loadEndpoints() -{ - let result = []; - - const { db, sessionId } = this.global; - - const endpoints = await queryEndpoint.selectAllEndpoints(db, sessionId); - - // Selection is one by one since existing API does not seem to provide - // linkage between cluster and what endpoint it belongs to. - // - // TODO: there should be a better way - for (const endpoint of endpoints) { - const endpointClusters - = await queryEndpointType.selectAllClustersDetailsFromEndpointTypes(db, [ { endpointTypeId : endpoint.endpointTypeRef } ]); - result.push({...endpoint, clusters : endpointClusters.filter(c => c.enabled == 1) }); - } - - return result; -} - -async function loadAllClusters(packageId) -{ - const { db, sessionId } = this.global; - - let allClusters = await zclQuery.selectAllClusters(db, packageId); - // To match what loadClusters does, sort by cluster name (not cluster code). - allClusters.sort((a, b) => { - if (a.name < b.name) { - return -1; - } - if (a.name == b.name) { - return 0; - } - return 1; - }); - let serverClusters = allClusters.map(cluster => ({...cluster, side : 'server', enabled : true })); - let clientClusters = allClusters.map(cluster => ({...cluster, side : 'client', enabled : true })); - return serverClusters.concat(clientClusters); -} - -async function loadClusters() -{ - const { db, sessionId } = this.global; - - const endpointTypes = await queryEndpointType.selectEndpointTypeIds(db, sessionId); - const clusters = await queryEndpointType.selectAllClustersDetailsFromEndpointTypes(db, endpointTypes); - - return clusters.filter(cluster => cluster.enabled == 1); -} - -function loadCommandResponse(command, packageId) -{ - const { db, sessionId } = this.global; - return queryCommand.selectCommandById(db, command.id, packageId).then(commandDetails => { - if (commandDetails.responseRef == null) { - command.response = null; - return command; - } - - return queryCommand.selectCommandById(db, commandDetails.responseRef, packageId).then(response => { - command.response = response; - return command; - }); - }); -} - -function loadCommandArguments(command, packageId) -{ - const { db, sessionId } = this.global; - return queryCommand.selectCommandArgumentsByCommandId(db, command.id, packageId).then(commandArguments => { - command.arguments = commandArguments; - return command; - }); -} - -async function loadAllCommands(packageId) -{ - const { db, sessionId } = this.global; - let cmds = await queryCommand.selectAllCommandsWithClusterInfo(db, [ packageId ]); - // For each command, include it twice: once as outgoing for its source, once - // as incoming for its destination. - let outgoing = cmds.map(cmd => ({...cmd, incoming : false, outgoing : true, clusterSide : cmd.source })); - let incoming = cmds.map( - cmd => ({...cmd, incoming : true, outgoing : false, clusterSide : (cmd.source == 'server' ? 'client' : 'server') })); - let commands = Promise.resolve(outgoing.concat(incoming)); - return loadCommandsCommon.call(this, packageId, commands); -} - -function loadCommands(packageId) -{ - const { db, sessionId } = this.global; - let cmds = queryEndpointType.selectEndpointTypeIds(db, sessionId) - .then(endpointTypes => queryEndpointType.selectClustersAndEndpointDetailsFromEndpointTypes(db, endpointTypes)) - .then(endpointTypesAndClusters => queryCommand.selectCommandDetailsFromAllEndpointTypesAndClusters( - db, endpointTypesAndClusters, true)); - - return loadCommandsCommon.call(this, packageId, cmds); -} - -// commandsPromise is a promise for an array of commands. -function loadCommandsCommon(packageId, commandsPromise) -{ - return commandsPromise.then(commands => Promise.all(commands.map(command => loadCommandResponse.call(this, command, packageId)))) - .then(commands => Promise.all(commands.map(command => loadCommandArguments.call(this, command, packageId)))); -} - -async function loadAllAttributes(packageId) -{ - // The 'server' side is enforced here, because the list of attributes is used to generate client global - // commands to retrieve server side attributes. - const { db, sessionId } = this.global; - let attrs = await zclQuery.selectAllAttributesBySide(db, 'server', [ packageId ]); - const globalAttrs = attrs.filter(attr => attr.clusterRef == null); - // Exclude global attributes for now, since we will add them ourselves for - // all clusters. - attrs = attrs.filter(attr => attr.clusterRef != null); - // selectAllAttributesBySide sets clusterRef, not clusterId, so manually - // set the latter here. - attrs.forEach(attr => attr.clusterId = attr.clusterRef); - - const clusters = await zclQuery.selectAllClusters(db, packageId); - for (let cluster of clusters) { - for (let globalAttr of globalAttrs) { - attrs.push({...globalAttr, clusterId : cluster.id }); - } - } - // selectAllAttributesBySide includes optionality information, which we - // don't want here, because the types of the attributes are not in fact - // optionals for our purposes. - attrs.forEach(attr => delete attr.isOptional); - // Treat all attributes that could be reportable as reportable. - attrs.forEach(attr => { - if (attr.isReportable) { - attr.includedReportable = true; - } - }); - return attrs.sort((a, b) => a.code - b.code); -} - -function loadAttributes(packageId) -{ - // The 'server' side is enforced here, because the list of attributes is used to generate client global - // commands to retrieve server side attributes. - const { db, sessionId } = this.global; - return queryEndpointType.selectEndpointTypeIds(db, sessionId) - .then(endpointTypes => Promise.all( - endpointTypes.map(({ endpointTypeId }) => queryEndpoint.selectEndpointClusters(db, endpointTypeId)))) - .then(clusters => clusters.flat()) - .then(clusters => Promise.all( - clusters.map(({ clusterId, side, endpointTypeId }) => queryEndpoint.selectEndpointClusterAttributes( - db, clusterId, 'server', endpointTypeId)))) - .then(attributes => attributes.flat()) - .then(attributes => attributes.filter(attribute => attribute.isIncluded)) - .then(attributes => attributes.sort((a, b) => a.code - b.code)); - //.then(attributes => Promise.all(attributes.map(attribute => types.typeSizeAttribute(db, packageId, attribute)) -} - -async function loadAllEvents(packageId) -{ - const { db, sessionId } = this.global; - let clusters = await zclQuery.selectAllClusters(db, packageId); - return loadEventsCommon.call(this, packageId, clusters); -} - -async function loadEvents(packageId) -{ - const { db, sessionId } = this.global; - let clusters = await queryEndpointType.selectEndpointTypeIds(db, sessionId) - .then(endpointTypes => Promise.all( - endpointTypes.map(({ endpointTypeId }) => queryEndpoint.selectEndpointClusters(db, endpointTypeId)))) - .then(clusters => clusters.flat(3)); - return loadEventsCommon.call(this, packageId, clusters); -} - -// clusters is an array of clusters (not a promise). -function loadEventsCommon(packageId, clusters) -{ - const { db, sessionId } = this.global; - return queryEvent.selectAllEvents(db, packageId).then(events => { - events.forEach(event => { - const cluster = clusters.find(cluster => cluster.code == event.clusterCode); - if (cluster) { - event.clusterId = cluster.clusterId; - event.clusterName = cluster.name; - } - }); - return events.filter(event => clusters.find(cluster => cluster.code == event.clusterCode)); - }); -} - -function loadGlobalAttributes(packageId) -{ - const { db, sessionId } = this.global; - return zclQuery.selectAllAttributes(db, packageId) - .then(attributes => attributes.filter(attribute => attribute.clusterRef == null)) - .then(attributes => attributes.map(attribute => attribute.code)); -} - -// -// Load step 2 -// - -function asChipCallback(item) -{ - if (StringHelper.isOctetString(item.type)) { - return { name : 'OctetString', type : 'const chip::ByteSpan' }; - } - - if (StringHelper.isCharString(item.type)) { - return { name : 'CharString', type : 'const chip::CharSpan' }; - } - - if (item.isArray) { - return { name : 'List', type : null }; - } - - const basicType = ChipTypesHelper.asBasicType(item.chipType); - switch (basicType) { - case 'int8_t': - case 'int16_t': - case 'int32_t': - case 'int64_t': - return { name : 'Int' + basicType.replace(/[^0-9]/g, '') + 's', type : basicType }; - case 'uint8_t': - case 'uint16_t': - case 'uint32_t': - case 'uint64_t': - return { name : 'Int' + basicType.replace(/[^0-9]/g, '') + 'u', type : basicType }; - case 'bool': - return { name : 'Boolean', type : 'bool' }; - case 'float': - return { name : 'Float', type : 'float' }; - case 'double': - return { name : 'Double', type : 'double' }; - default: - return { name : 'Unsupported', type : null }; - } -} - -function getAtomic(atomics, type) -{ - return atomics.find(atomic => atomic.name == type.toLowerCase()); -} - -function getBitmap(bitmaps, type) -{ - return bitmaps.find(bitmap => bitmap.label == type); -} - -function getEnum(enums, type) -{ - return enums.find(enumItem => enumItem.label == type); -} - -function getStruct(structs, type) -{ - return structs.find(struct => struct.label == type); -} - -function handleString(item, [ atomics, enums, bitmaps, structs ]) -{ - if (!StringHelper.isString(item.type)) { - return false; - } - - const atomic = getAtomic(atomics, item.type); - if (!atomic) { - return false; - } - - const kLengthSizeInBytes = 2; - - item.atomicTypeId = atomic.atomicId; - if (StringHelper.isOctetString(item.type)) { - item.chipType = 'chip::ByteSpan'; - } else { - item.chipType = 'chip::CharSpan'; - } - item.size = kLengthSizeInBytes + item.maxLength; - item.name = item.name || item.label; - return true; -} - -function handleList(item, [ atomics, enums, bitmaps, structs ]) -{ - if (!ListHelper.isList(item.type)) { - return false; - } - - const entryType = item.entryType; - if (!entryType) { - console.log(item); - throw new Error(item.label, 'List[T] is missing type "T" information'); - } - - item.isArray = true; - item.type = entryType; - enhancedItem(item, [ atomics, enums, bitmaps, structs ]); - - return true; -} - -function handleStruct(item, [ atomics, enums, bitmaps, structs ]) -{ - const struct = getStruct(structs, item.type); - if (!struct) { - return false; - } - - // Add a leading `_` before the name of struct to match what is done in the af-structs.zapt template. - // For instance structs are declared as "typedef struct _{{asType label}}". - item.chipType = '_' + item.type; - item.isStruct = true; - - struct.items.map(structItem => enhancedItem(structItem, [ atomics, enums, bitmaps, structs ])); - item.items = struct.items; - item.size = struct.items.map(type => type.size).reduce((accumulator, currentValue) => accumulator + currentValue, 0); - return true; -} - -function handleBasic(item, [ atomics, enums, bitmaps, structs ]) -{ - let itemType = item.type; - - const enumItem = getEnum(enums, itemType); - if (enumItem) { - item.isEnum = true; - itemType = 'enum' + enumItem.size * 8; - } - - const bitmap = getBitmap(bitmaps, itemType); - if (bitmap) { - item.isBitmap = true; - itemType = 'bitmap' + bitmap.size * 8; - } - - const atomic = getAtomic(atomics, itemType); - if (atomic) { - item.name = item.name || item.label; - item.isStruct = false; - item.atomicTypeId = atomic.atomicId; - item.size = atomic.size; - item.chipType = atomic.chipType; - return true; - } - - return false; -} - -function enhancedItem(item, types) -{ - if (handleString(item, types)) { - return; - } - - if (handleList(item, types)) { - return; - } - - if (handleStruct(item, types)) { - return; - } - - if (handleBasic(item, types)) { - return; - } - - console.log(item); - throw new Error(item.type + ' not found.'); -} - -function inlineStructItems(args) -{ - const arguments = []; - args.forEach(argument => { - if (!argument.isStruct) { - arguments.push(argument); - return; - } - - argument.items.forEach(item => { - arguments.push(item); - }); - }); - - return arguments; -} - -function enhancedCommands(commands, types) -{ - commands.forEach(command => { - command.arguments.forEach(argument => { - enhancedItem(argument, types); - argument.isComplex = argument.isList || argument.isStruct || argument.isArray; - }); - }); - - commands.forEach(command => { - // Flag things ending in "Response" so we can filter out unused responses, - // but don't stomp on a true isResponse value if it's set already because - // some other command had this one as its response. - command.isResponse = command.isResponse || command.name.includes('Response'); - command.isManufacturerSpecificCommand = !!this.mfgCode; - - command.hasSpecificResponse = !!command.response; - if (command.response) { - const responseName = command.response.name; - command.responseName = responseName; - // The 'response' property contains the response returned by the `selectCommandById` - // helper. But this one does not contains all the metadata informations added by - // `enhancedItem`, so instead of using the one from ZAP, retrieve the enhanced version. - command.response = commands.find(command => command.name == responseName); - // We might have failed to find a response if our configuration is weird - // in some way. - if (command.response) { - command.response.isResponse = true; - } - } else { - command.responseName = 'DefaultSuccess'; - command.response = { arguments : [] }; - } - }); - - // Filter unused responses - commands = commands.filter(command => { - if (!command.isResponse) { - return true; - } - - const responseName = command.name; - return commands.find(command => command.responseName == responseName); - }); - - // At this stage, 'command.arguments' may contains 'struct'. But some controllers does not know (yet) how - // to handle them. So those needs to be inlined. - commands.forEach(command => { - if (command.isResponse) { - return; - } - - command.expandedArguments = inlineStructItems(command.arguments); - }); - - return commands; -} - -function enhancedEvents(events, types) -{ - events.forEach(event => { - const argument = { - name : event.name, - type : event.name, - isArray : false, - isEvent : true, - isNullable : false, - label : event.name, - }; - event.response = { arguments : [ argument ] }; - }); - return events; -} - -function enhancedAttributes(attributes, globalAttributes, types) -{ - attributes.forEach(attribute => { - enhancedItem(attribute, types); - attribute.isGlobalAttribute = globalAttributes.includes(attribute.code); - attribute.isWritableAttribute = !!attribute.isWritable; - attribute.isReportableAttribute = !!attribute.includedReportable; - attribute.chipCallback = asChipCallback(attribute); - attribute.isComplex = attribute.isList || attribute.isStruct || attribute.isArray; - }); - - attributes.forEach(attribute => { - const argument = { - name : attribute.name, - type : attribute.type, - size : attribute.size, - isArray : attribute.isArray, - isEvent : false, - isNullable : attribute.isNullable, - chipType : attribute.chipType, - chipCallback : attribute.chipCallback, - label : attribute.name, - }; - attribute.arguments = [ argument ]; - attribute.response = { arguments : [ argument ] }; - }); - - // At this stage, the 'attributes' array contains all attributes enabled for all endpoints. It means - // that a lot of attributes are duplicated if a cluster is enabled on multiple endpoints but that's - // not what the templates expect. So let's deduplicate them. - const compare = (a, b) => (a.name == b.name && a.clusterId == b.clusterId && a.side == b.side); - return attributes.filter((att, index) => attributes.findIndex(att2 => compare(att, att2)) == index); -} - -const Clusters = { - ready : new Deferred(), - post_processing_ready : new Deferred() -}; - -class ClusterStructUsage { - constructor() - { - this.usedStructures = new Map(); // Structure label -> structure - this.clustersForStructure = new Map(); // Structure label -> Set(Cluster name) - this.structuresForCluster = new Map(); // Cluster name -> Set(Structure label) - } - - addUsedStructure(clusterName, structure) - { - // Record that generally this structure is used - this.usedStructures.set(structure.label, structure); - - // Record that this structure is used by a - // particular cluster name - let clusterSet = this.clustersForStructure.get(structure.label); - if (!clusterSet) { - clusterSet = new Set(); - this.clustersForStructure.set(structure.label, clusterSet); - } - clusterSet.add(clusterName); - - let structureLabelSet = this.structuresForCluster.get(clusterName); - if (!structureLabelSet) { - structureLabelSet = new Set(); - this.structuresForCluster.set(clusterName, structureLabelSet); - } - structureLabelSet.add(structure.label); - } - - /** - * Finds structures that are specific to one cluster: - * - they belong to the cluster - * - only that cluster ever uses it - */ - structuresSpecificToCluster(clusterName) - { - let clusterStructures = this.structuresForCluster.get(clusterName); - if (!clusterStructures) { - return []; - } - - return Array.from(clusterStructures) - .filter(name => this.clustersForStructure.get(name).size == 1) - .map(name => this.usedStructures.get(name)); - } - - structuresUsedByMultipleClusters() - { - return Array.from(this.usedStructures.values()).filter(s => this.clustersForStructure.get(s.label).size > 1); - } -} - -Clusters._addUsedStructureNames = async function(clusterName, startType, allKnownStructs) { - const struct = getStruct(allKnownStructs, startType.type); - if (!struct) { - return; - } - - this._cluster_structures.addUsedStructure(clusterName, struct); - - for (const item of struct.items) { - this._addUsedStructureNames(clusterName, item, allKnownStructs); - } -} - -Clusters._computeUsedStructureNames = async function(structs) { - // NOTE: this MUST be called only after attribute promise is resolved - // as iteration of `get*ByClusterName` needs that data. - for (const cluster of this._clusters) { - const attributes = await this.getAttributesByClusterName(cluster.name); - for (const attribute of attributes) { - if (attribute.isStruct) { - this._addUsedStructureNames(cluster.name, attribute, structs); - } - } - - const commands = await this.getCommandsByClusterName(cluster.name); - for (const command of commands) { - for (const argument of command.arguments) { - this._addUsedStructureNames(cluster.name, argument, structs); - } - } - - const responses = await this.getResponsesByClusterName(cluster.name); - for (const response of responses) { - for (const argument of response.arguments) { - this._addUsedStructureNames(cluster.name, argument, structs); - } - } - } - - this._used_structure_names = new Set(this._cluster_structures.usedStructures.keys()) -} - -/** - * If includeAll is true, all events/commands/attributes will be included, not - * just the ones enabled in the ZAP configuration. - */ -Clusters.init = async function(context, includeAll) { - if (this.ready.running) - { - return this.ready; - } - this.ready.running = true; - - let packageId = await templateUtil.ensureZclPackageId(context).catch(err => { console.log(err); throw err; }); - - const loadTypes = [ - loadAtomics.call(context, packageId), - loadEnums.call(context, packageId), - loadBitmaps.call(context, packageId), - loadStructs.call(context, packageId), - ]; - - const promises = [ - Promise.all(loadTypes), - loadEndpoints.call(context), - // For now just always use loadClusters, because we have a bunch of things - // defined in our XML that are not actually part of Matter. - (includeAll ? loadClusters : loadClusters).call(context, packageId), - (includeAll ? loadAllCommands : loadCommands).call(context, packageId), - (includeAll ? loadAllAttributes : loadAttributes).call(context, packageId), - loadGlobalAttributes.call(context, packageId), - (includeAll ? loadAllEvents : loadEvents).call(context, packageId), - ]; - - let [types, endpoints, clusters, commands, attributes, globalAttributes, events] = await Promise.all(promises); - - this._endpoints = endpoints; - this._clusters = clusters; - this._commands = enhancedCommands(commands, types); - this._attributes = enhancedAttributes(attributes, globalAttributes, types); - this._events = enhancedEvents(events, types); - this._cluster_structures = new ClusterStructUsage(); - - // data is ready, but not full post - processing - this.ready.resolve(); - - await this._computeUsedStructureNames(types[3]); - - return this.post_processing_ready.resolve(); -} - - -// -// Helpers: All -// -function asBlocks(promise, options) -{ - return promise.then(data => templateUtil.collectBlocks(data, options, this)) -} - -function ensureClusters(context, includeAll = false) -{ - // Kick off Clusters initialization. This is async, but that's fine: all the - // getters on Clusters wait on that initialziation to complete. - ensureState(context, "Don't have a context"); - - Clusters.init(context, includeAll); - return Clusters; -} - -// -// Helpers: Get all clusters/commands/responses/attributes. -// -const kResponseFilter = (isResponse, item) => isResponse == item.isResponse; - -Clusters.ensureReady = function() -{ - ensureState(this.ready.running); - return this.ready; -} - -Clusters.ensurePostProcessingDone = function() -{ - ensureState(this.ready.running); - return this.post_processing_ready; -} - -Clusters.getClusters = function() -{ - return this.ensureReady().then(() => this._clusters); -} - -Clusters.getEndPoints = function() -{ - return this.ensureReady().then(() => this._endpoints); -} - -Clusters.getCommands = function() -{ - return this.ensureReady().then(() => this._commands.filter(kResponseFilter.bind(null, false))); -} - -Clusters.getResponses = function() -{ - return this.ensureReady().then(() => this._commands.filter(kResponseFilter.bind(null, true))); -} - -Clusters.getAttributes = function() -{ - return this.ensureReady().then(() => this._attributes); -} - -Clusters.getEvents = function() -{ - return this.ensureReady().then(() => this._events); -} - -// -// Helpers: Get by Cluster Name -// -const kNameFilter = (name, item) => name.toLowerCase() == (item.clusterName || item.name).toLowerCase(); - -Clusters.getCommandsByClusterName = function(name) -{ - return this.getCommands().then(items => items.filter(kNameFilter.bind(null, name))); -} - -Clusters.getResponsesByClusterName = function(name) -{ - return this.getResponses().then(items => items.filter(kNameFilter.bind(null, name))); -} - -Clusters.getAttributesByClusterName = function(name) -{ - return this.ensureReady().then(() => { - const clusterId = this._clusters.find(kNameFilter.bind(null, name)).id; - const filter = attribute => attribute.clusterId == clusterId; - return this.getAttributes().then(items => items.filter(filter)); - }); -} - -Clusters.getEventsByClusterName = function(name) -{ - return this.getEvents().then(items => items.filter(kNameFilter.bind(null, name))); -} - -// -// Helpers: Get by Cluster Side -// -const kSideFilter = (side, item) => item.source ? ((item.source == side && item.outgoing) || (item.source != side && item.incoming)) - : item.side == side; - -Clusters.getCommandsByClusterSide = function(side) -{ - return this.getCommands().then(items => items.filter(kSideFilter.bind(null, side))); -} - -Clusters.getResponsesByClusterSide = function(side) -{ - return this.getResponses().then(items => items.filter(kSideFilter.bind(null, side))); -} - -Clusters.getAttributesByClusterSide = function(side) -{ - return this.getAttributes().then(items => items.filter(kSideFilter.bind(null, side))); -} - -Clusters.getEventsByClusterSide = function(side) -{ - return this.getEvents().then(items => items.filter(kSideFilter.bind(null, side))); -} - - -// -// Helpers: Client -// -const kClientSideFilter = kSideFilter.bind(null, 'client'); - -Clusters.getClientClusters = function() -{ - return this.getClusters().then(items => items.filter(kClientSideFilter)); -} - -Clusters.getClientCommands = function(name) -{ - return this.getCommandsByClusterName(name).then(items => items.filter(kClientSideFilter)); -} - -Clusters.getClientResponses = function(name) -{ - return this.getResponsesByClusterName(name).then(items => items.filter(kClientSideFilter)); -} - -Clusters.getClientAttributes = function(name) -{ - return this.getAttributesByClusterName(name).then(items => items.filter(kClientSideFilter)); -} - -Clusters.getClientEvents = function(name) -{ - return this.getEventsByClusterName(name).then(items => items.filter(kClientSideFilter)); -} - -// -// Helpers: Server -// -const kServerSideFilter = kSideFilter.bind(null, 'server'); - -Clusters.getServerClusters = function() -{ - return this.getClusters().then(items => items.filter(kServerSideFilter)); -} - -Clusters.getServerCommands = function(name) -{ - return this.getCommandsByClusterName(name).then(items => items.filter(kServerSideFilter)); -} - -Clusters.getServerResponses = function(name) -{ - return this.getResponsesByClusterName(name).then(items => items.filter(kServerSideFilter)); -} - -Clusters.getServerAttributes = function(name) -{ - return this.getAttributesByClusterName(name).then(items => items.filter(kServerSideFilter)); -} - -Clusters.getUsedStructureNames = function() -{ - return this.ensurePostProcessingDone().then(() => this._used_structure_names); -} - -Clusters.getStructuresByClusterName = function(name) -{ - return this.ensurePostProcessingDone().then(() => this._cluster_structures.structuresSpecificToCluster(name)); -} - -Clusters.getSharedStructs = function() -{ - return this.ensurePostProcessingDone().then(() => this._cluster_structures.structuresUsedByMultipleClusters()); -} - -Clusters.getServerEvents = function(name) -{ - return this.getEventsByClusterName(name).then(items => items.filter(kServerSideFilter)); -} - -// -// Module exports -// -exports.asBlocks = asBlocks; -exports.ensureClusters = ensureClusters; diff --git a/src/app/zap-templates/common/Deferred.js b/src/app/zap-templates/common/Deferred.js deleted file mode 100644 index fa6da232c0a75d..00000000000000 --- a/src/app/zap-templates/common/Deferred.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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. - */ - -function Deferred() -{ - let resolve, reject; - - let promise = new Promise((_resolve, _reject) => { - resolve = _resolve; - reject = _reject; - }); - - promise.resolve = resolve; - promise.reject = reject; - return promise; -} - -// -// Module exports -// -exports.Deferred = Deferred; diff --git a/src/app/zap-templates/common/ListHelper.js b/src/app/zap-templates/common/ListHelper.js deleted file mode 100644 index 4e6011adfa5f95..00000000000000 --- a/src/app/zap-templates/common/ListHelper.js +++ /dev/null @@ -1,28 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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. - */ - -const listType = 'ARRAY'; - -function isList(type) -{ - return type.toUpperCase() == listType; -} - -// -// Module exports -// -exports.isList = isList; diff --git a/src/app/zap-templates/common/StringHelper.js b/src/app/zap-templates/common/StringHelper.js deleted file mode 100644 index b3bc6f57a1d6a3..00000000000000 --- a/src/app/zap-templates/common/StringHelper.js +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * - * 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. - */ - -const characterStringTypes = [ 'CHAR_STRING', 'LONG_CHAR_STRING' ]; -const octetStringTypes = [ 'OCTET_STRING', 'LONG_OCTET_STRING' ]; -const stringShortTypes = [ 'CHAR_STRING', 'OCTET_STRING' ]; -const stringLongTypes = [ 'LONG_CHAR_STRING', 'LONG_OCTET_STRING' ]; - -function isString(type) -{ - return isCharString(type) || isOctetString(type); -} - -function isCharString(type) -{ - return characterStringTypes.includes(type.toUpperCase()); -} - -function isOctetString(type) -{ - return octetStringTypes.includes(type.toUpperCase()); -} - -function isShortString(type) -{ - return stringShortTypes.includes(type.toUpperCase()); -} - -function isLongString(type) -{ - return stringLongTypes.includes(type.toUpperCase()); -} - -// -// Module exports -// -exports.isString = isString; -exports.isCharString = isCharString; -exports.isOctetString = isOctetString; -exports.isShortString = isShortString; -exports.isLongString = isLongString; diff --git a/src/app/zap-templates/common/attributes/Accessors.js b/src/app/zap-templates/common/attributes/Accessors.js deleted file mode 100644 index 29c20fb313a37e..00000000000000 --- a/src/app/zap-templates/common/attributes/Accessors.js +++ /dev/null @@ -1,107 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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. - */ - -const zapPath = '../../../../../third_party/zap/repo/dist/src-electron/'; -const ListHelper = require('../../common/ListHelper.js'); -const StringHelper = require('../../common/StringHelper.js'); -const appHelper = require('../../templates/app/helper.js'); -const cHelper = require(zapPath + 'generator/helper-c.js') -const zclHelper = require(zapPath + 'generator/helper-zcl.js') -const templateUtil = require(zapPath + 'generator/template-util.js') -const zclUtil = require(zapPath + 'util/zcl-util.js') - -// Not sure what to do with EUI64 yet. -const unsupportedTypes = [ 'EUI64' ]; -function isUnsupportedType(type) -{ - return unsupportedTypes.includes(type.toUpperCase()); -} - -function canHaveSimpleAccessors(attr) -{ - if (attr.isArray) { - return false; - } - - if (ListHelper.isList(attr.type)) { - return false; - } - - // We can't check for being a struct synchronously, so that's handled manually - // in the template. - if (isUnsupportedType(attr.type)) { - return false; - } - - return true; -} - -async function accessorGetterType(attr) -{ - let type; - let mayNeedPointer = false; - if (StringHelper.isCharString(attr.type)) { - type = "chip::MutableCharSpan"; - } else if (StringHelper.isOctetString(attr.type)) { - type = "chip::MutableByteSpan"; - } else { - mayNeedPointer = true; - const options = { 'hash' : { forceNotNullable : true, forceNotOptional : true, ns : this.parent.name } }; - type = await appHelper.zapTypeToEncodableClusterObjectType.call(this, attr.type, options); - } - - if (attr.isNullable) { - type = `DataModel::Nullable<${type}> &`; - } else if (mayNeedPointer) { - type = `${type} *`; - } - - return type; -} - -async function accessorTraitType(type) -{ - let temp = type.toLowerCase(); - let matches = temp.match(/^int([0-9]+)(s?)/i); - if (matches) { - let signed = matches[2] != ""; - let size = parseInt(matches[1]) / 8; - - if (size != 1 && size != 2 && size != 4 && size != 8) { - return `OddSizedInteger<${size}, ${signed}>`; - } - } - - const options = { 'hash' : { forceNotNullable : true, forceNotOptional : true, ns : this.parent.name } }; - return appHelper.zapTypeToEncodableClusterObjectType.call(this, type, options); -} - -async function typeAsDelimitedMacro(type) -{ - const { db } = this.global; - const pkgId = await templateUtil.ensureZclPackageId(this); - const typeInfo = await zclUtil.determineType(db, type, pkgId); - return cHelper.asDelimitedMacro.call(this, typeInfo.atomicType); -} - -// -// Module exports -// -exports.canHaveSimpleAccessors = canHaveSimpleAccessors; -exports.accessorGetterType = accessorGetterType; -exports.accessorTraitType = accessorTraitType; -exports.typeAsDelimitedMacro = typeAsDelimitedMacro; diff --git a/src/app/zap-templates/common/simulated-clusters/SimulatedClusters.js b/src/app/zap-templates/common/simulated-clusters/SimulatedClusters.js deleted file mode 100644 index e135c0dc020f77..00000000000000 --- a/src/app/zap-templates/common/simulated-clusters/SimulatedClusters.js +++ /dev/null @@ -1,96 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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. - */ - -const { ensureClusters } = require('../ClustersHelper.js'); - -const fs = require('fs'); -const path = require('path'); - -let SimulatedClusters = []; -(async () => { - const simulatedClustersPath = path.join(__dirname, 'clusters'); - const simulatedClustersFiles = await fs.promises.readdir(simulatedClustersPath); - SimulatedClusters = simulatedClustersFiles.map(filename => { - let cluster = (require(path.join(simulatedClustersPath, filename))).cluster; - cluster.commands.forEach(command => { - if (!('name' in command)) { - console.error('Error in: ' + filename + '. Missing command name.'); - throw new Error(); - } - - if (!('arguments' in command)) { - command.arguments = []; - } - - if (!('response' in command)) { - command.response = { arguments : [] }; - } - - if (command.arguments.length) { - command.hasSpecificArguments = true; - } - - if (command.response.arguments.length) { - command.hasSpecificResponse = true; - } - }); - return cluster; - }); - return SimulatedClusters; -})(); - -function getSimulatedCluster(clusterName) -{ - return SimulatedClusters.find(cluster => cluster.name == clusterName); -} - -function getClusters(context) -{ - return ensureClusters(context, true).getClusters().then(clusters => clusters.concat(SimulatedClusters).flat(1)); -} - -function getCommands(context, clusterName) -{ - const cluster = getSimulatedCluster(clusterName); - return cluster ? Promise.resolve(cluster.commands) : ensureClusters(context).getClientCommands(clusterName); -} - -function getAttributes(context, clusterName) -{ - const cluster = getSimulatedCluster(clusterName); - return cluster ? Promise.resolve(cluster.attributes) : ensureClusters(context).getServerAttributes(clusterName); -} - -function getEvents(context, clusterName) -{ - const cluster = getSimulatedCluster(clusterName); - return cluster ? Promise.resolve(cluster.events) : ensureClusters(context).getServerEvents(clusterName); -} - -function isTestOnlyCluster(clusterName) -{ - return !!getSimulatedCluster(clusterName); -} - -// -// Module exports -// -exports.getClusters = getClusters; -exports.getCommands = getCommands; -exports.getAttributes = getAttributes; -exports.getEvents = getEvents; -exports.isTestOnlyCluster = isTestOnlyCluster; diff --git a/src/app/zap-templates/common/simulated-clusters/clusters/CommissionerCommands.js b/src/app/zap-templates/common/simulated-clusters/clusters/CommissionerCommands.js deleted file mode 100644 index 3acbcb890d5923..00000000000000 --- a/src/app/zap-templates/common/simulated-clusters/clusters/CommissionerCommands.js +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * Copyright (c) 2022 Project CHIP Authors - * - * 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. - */ - -/* - * This file declare test suites utilities methods for commissioner commands. - * - * Each method declared in this file needs to be implemented on a per-language - * basis and permits to exposes methods to the test suites that are not part - * of the regular cluster set of APIs. - * - */ - -const PairWithCode = { - name : 'PairWithCode', - arguments : [ { type : 'NODE_ID', name : 'nodeId' }, { type : 'CHAR_STRING', name : 'payload' } ], -}; - -const Unpair = { - name : 'Unpair', - arguments : [ { type : 'NODE_ID', name : 'nodeId' } ], -}; - -const name = 'CommissionerCommands'; -const commands = [ PairWithCode, Unpair ]; - -const CommissionerCommands = { - name, - commands -}; - -// -// Module exports -// -exports.cluster = CommissionerCommands; diff --git a/src/app/zap-templates/common/simulated-clusters/clusters/DelayCommands.js b/src/app/zap-templates/common/simulated-clusters/clusters/DelayCommands.js deleted file mode 100644 index 23da2c0e1b64ee..00000000000000 --- a/src/app/zap-templates/common/simulated-clusters/clusters/DelayCommands.js +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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. - */ - -/* - * This file declare test suites utilities methods for delayed commands. - * - * Each method declared in this file needs to be implemented on a per-language - * basis and permits to exposes methods to the test suites that are not part - * of the regular cluster set of APIs. - * - */ - -const WaitForMs = { - name : 'WaitForMs', - arguments : [ { type : 'INT32U', name : 'ms' } ], -}; - -const WaitForCommissioning = { - name : 'WaitForCommissioning', -}; - -const WaitForCommissionee = { - name : 'WaitForCommissionee', - arguments : [ { type : 'NODE_ID', name : 'nodeId' }, { type : 'BOOLEAN', name : 'expireExistingSession', isOptional : true } ], -}; - -const WaitForMessage = { - name : 'WaitForMessage', - arguments : [ { type : 'CHAR_STRING', name : 'registerKey', isOptional : true }, { type : 'CHAR_STRING', name : 'message' } ], -}; - -const name = 'DelayCommands'; -const commands = [ WaitForMs, WaitForCommissioning, WaitForCommissionee, WaitForMessage ]; - -const DelayCommands = { - name, - commands -}; - -// -// Module exports -// -exports.cluster = DelayCommands; diff --git a/src/app/zap-templates/common/simulated-clusters/clusters/DiscoveryCommands.js b/src/app/zap-templates/common/simulated-clusters/clusters/DiscoveryCommands.js deleted file mode 100644 index 7579b69d176f20..00000000000000 --- a/src/app/zap-templates/common/simulated-clusters/clusters/DiscoveryCommands.js +++ /dev/null @@ -1,170 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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. - */ - -/* - * This file declares test suite utility methods for discovery. - * - * Each method declared in this file needs to be implemented on a per-language - * basis and allows exposing methods to the test suites that are not part - * of the regular cluster set of APIs. - * - */ - -const kTypeArgument = { - name : 'type', - type : 'CHAR_STRING', -}; - -const kNumberValueArgument = { - name : 'value', - type : 'INT64U', -}; - -const kStringValueArgument = { - name : 'value', - type : 'CHAR_STRING', -}; - -const kDefaultResponse = { - arguments : [ - { name : 'hostName', type : 'CHAR_STRING', chipType : 'chip::CharSpan' }, // - { name : 'instanceName', type : 'CHAR_STRING', chipType : 'chip::CharSpan' }, // - { name : 'longDiscriminator', type : 'INT16U', chipType : 'uint16_t' }, // - { name : 'shortDiscriminator', type : 'INT8U', chipType : 'uint8_t' }, // - { name : 'vendorId', type : 'INT16U', chipType : 'uint16_t' }, // - { name : 'productId', type : 'INT16U', chipType : 'uint16_t' }, // - { name : 'commissioningMode', type : 'INT8U', chipType : 'uint8_t' }, // - { name : 'deviceType', type : 'INT16U', chipType : 'uint16_t' }, // - { name : 'deviceName', type : 'CHAR_STRING' }, // - { name : 'rotatingId', type : 'OCTET_STRING', chipType : 'chip::ByteSpan' }, // - { name : 'rotatingIdLen', type : 'INT64U', chipType : 'uint64_t' }, // - { name : 'pairingHint', type : 'INT16U', chipType : 'uint16_t' }, // - { name : 'pairingInstruction', type : 'CHAR_STRING' }, // - { name : 'supportsTcp', type : 'BOOLEAN', chipType : 'bool' }, // - { name : 'numIPs', type : 'INT8U', chipType : 'uint8_t' }, // - { name : 'port', type : 'INT16U', chipType : 'uint16_t' }, // - { name : 'mrpRetryIntervalIdle', type : 'INT32U', chipType : 'uint32_t', isOptional : true }, // - { name : 'mrpRetryIntervalActive', type : 'INT32U', chipType : 'uint32_t', isOptional : true }, // - ] -}; - -// -// Commissionable -// - -const FindCommissionable = { - name : 'FindCommissionable', - responseName : 'DiscoveryCommandResponse', - response : kDefaultResponse -}; - -const FindCommissionableByShortDiscriminator = { - name : 'FindCommissionableByShortDiscriminator', - arguments : [ kNumberValueArgument ], - responseName : 'DiscoveryCommandResponse', - response : kDefaultResponse -}; - -const FindCommissionableByLongDiscriminator = { - name : 'FindCommissionableByLongDiscriminator', - arguments : [ kNumberValueArgument ], - responseName : 'DiscoveryCommandResponse', - response : kDefaultResponse -}; - -const FindCommissionableByCompressedFabricId = { - name : 'FindOperationalByCompressedFabricId', - arguments : [ kNumberValueArgument ], - responseName : 'DiscoveryCommandResponse', - response : kDefaultResponse -}; - -const FindCommissionableByCommissioningMode = { - name : 'FindCommissionableByCommissioningMode', - responseName : 'DiscoveryCommandResponse', - response : kDefaultResponse -}; - -const FindCommissionableByVendorId = { - name : 'FindCommissionableByVendorId', - arguments : [ kNumberValueArgument ], - responseName : 'DiscoveryCommandResponse', - response : kDefaultResponse -}; - -const FindCommissionableByDeviceType = { - name : 'FindCommissionableByDeviceType', - arguments : [ kNumberValueArgument ], - responseName : 'DiscoveryCommandResponse', - response : kDefaultResponse -}; - -const FindCommissionableByName = { - name : 'FindCommissionableByName', - arguments : [ kStringValueArgument ], - responseName : 'DiscoveryCommandResponse', - response : kDefaultResponse -}; - -// -// Commissioner -// - -const FindCommissioner = { - name : 'FindCommissioner', - responseName : 'DiscoveryCommandResponse', - response : kDefaultResponse -}; - -const FindCommissionerByVendorId = { - name : 'FindCommissionerByVendorId', - arguments : [ kNumberValueArgument ], - responseName : 'DiscoveryCommandResponse', - response : kDefaultResponse -}; - -const FindCommissionerByDeviceType = { - name : 'FindCommissionerByDeviceType', - arguments : [ kNumberValueArgument ], - responseName : 'DiscoveryCommandResponse', - response : kDefaultResponse -}; - -const commands = [ - // Commissionable - FindCommissionable, - FindCommissionableByShortDiscriminator, - FindCommissionableByLongDiscriminator, - FindCommissionableByCommissioningMode, - FindCommissionableByVendorId, - FindCommissionableByDeviceType, - FindCommissionableByName, - // Commissioner - FindCommissioner, - FindCommissionerByVendorId, - FindCommissionerByDeviceType, -]; - -const DiscoveryCommands = { - name : 'DiscoveryCommands', - commands : commands, -}; - -// -// Module exports -// -exports.cluster = DiscoveryCommands; diff --git a/src/app/zap-templates/common/simulated-clusters/clusters/LogCommands.js b/src/app/zap-templates/common/simulated-clusters/clusters/LogCommands.js deleted file mode 100644 index 3be33a01651a6b..00000000000000 --- a/src/app/zap-templates/common/simulated-clusters/clusters/LogCommands.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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. - */ - -/* - * This file declares test suite utility methods for logging. - * - * Each method declared in this file needs to be implemented on a per-language - * basis and allows exposing methods to the test suites that are not part - * of the regular cluster set of APIs. - * - */ - -const Log = { - name : 'Log', - arguments : [ { type : 'CHAR_STRING', name : 'message' } ], -}; - -const UserPrompt = { - name : 'UserPrompt', - arguments : [ { type : 'CHAR_STRING', name : 'message' }, { type : 'CHAR_STRING', name : 'expectedValue', isOptional : true } ], -}; - -const LogCommands = { - name : 'LogCommands', - commands : [ Log, UserPrompt ], -}; - -// -// Module exports -// -exports.cluster = LogCommands; diff --git a/src/app/zap-templates/common/simulated-clusters/clusters/SystemCommands.js b/src/app/zap-templates/common/simulated-clusters/clusters/SystemCommands.js deleted file mode 100644 index b59f9c9fc925a0..00000000000000 --- a/src/app/zap-templates/common/simulated-clusters/clusters/SystemCommands.js +++ /dev/null @@ -1,77 +0,0 @@ -/* - * - * Copyright (c) 2022 Project CHIP Authors - * - * 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. - */ - -/* - * This file declares test suite utility methods for system commands. - * - * Each method declared in this file needs to be implemented on a per-language - * basis and allows exposing methods to the test suites that are not part - * of the regular cluster set of APIs. - * - */ - -const Start = { - name : 'Start', - arguments : [ - { 'name' : 'registerKey', type : 'CHAR_STRING', isOptional : true }, - { 'name' : 'discriminator', type : 'INT16U', isOptional : true }, { 'name' : 'port', type : 'INT16U', isOptional : true }, - { 'name' : 'kvs', type : 'CHAR_STRING', isOptional : true }, - { 'name' : 'minCommissioningTimeout', type : 'INT16U', isOptional : true }, - // OTA provider specific arguments - { 'name' : 'filepath', type : 'CHAR_STRING', isOptional : true }, - // OTA requestor specific arguments - { 'name' : 'otaDownloadPath', type : 'CHAR_STRING', isOptional : true } - ], -}; - -const Stop = { - name : 'Stop', - arguments : [ { 'name' : 'registerKey', type : 'CHAR_STRING', isOptional : true } ], -}; - -const Reboot = { - name : 'Reboot', - arguments : [ { 'name' : 'registerKey', type : 'CHAR_STRING', isOptional : true } ], -}; - -const FactoryReset = { - name : 'FactoryReset', - arguments : [ { 'name' : 'registerKey', type : 'CHAR_STRING', isOptional : true } ], -}; - -const CreateOtaImage = { - name : 'CreateOtaImage', - arguments : [ - { 'name' : 'otaImageFilePath', type : 'CHAR_STRING' }, { 'name' : 'rawImageFilePath', type : 'CHAR_STRING' }, - { 'name' : 'rawImageContent', type : 'CHAR_STRING' } - ], -}; - -const CompareFiles = { - name : 'CompareFiles', - arguments : [ { 'name' : 'file1', type : 'CHAR_STRING' }, { 'name' : 'file2', type : 'CHAR_STRING' } ], -}; - -const SystemCommands = { - name : 'SystemCommands', - commands : [ Start, Stop, Reboot, FactoryReset, CreateOtaImage, CompareFiles ], -}; - -// -// Module exports -// -exports.cluster = SystemCommands; diff --git a/src/app/zap-templates/common/variables/Variables.js b/src/app/zap-templates/common/variables/Variables.js deleted file mode 100644 index 31a9eb27caacf2..00000000000000 --- a/src/app/zap-templates/common/variables/Variables.js +++ /dev/null @@ -1,150 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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. - */ - -/* - * This file contains code for supporting variables into the YAML tests suites. - */ - -// Import helpers from zap core -const zapPath = '../../../../../third_party/zap/repo/dist/src-electron/'; -const zclHelper = require(zapPath + 'generator/helper-zcl.js') -const templateUtil = require(zapPath + 'generator/template-util.js') - -const { getCommands, getAttributes } = require('../simulated-clusters/SimulatedClusters.js'); - -const knownVariables = { - 'nodeId' : { type : 'NODE_ID', defaultValue : 0x12345, isNullable : false }, - 'endpoint' : { type : 'ENDPOINT_NO', defaultValue : '', isNullable : false }, - 'cluster' : { type : 'CHAR_STRING', defaultValue : '', isNullable : false }, - 'timeout' : { type : 'INT16U', defaultValue : "kTimeoutInSeconds", isNullable : false }, -}; - -function throwError(test, errorStr) -{ - console.error('Error in: ' + test.filename + '.yaml for test with label: "' + test.label + '"\n'); - console.error(errorStr); - throw new Error(); -} - -async function getItems(test, promise, itemName) -{ - return promise.then(items => { - const item = items.find(item => item.name.toLowerCase() == itemName.toLowerCase()); - if (!item) { - const names = items.map(item => item.name); - throwError(test, 'Missing ' + itemName + '" in: \n\t* ' + names.join('\n\t* ')); - } - - return item; - }); -} - -async function getCommandInformationsFor(context, test, argumentName) -{ - const command = await getItems(test, getCommands(context, test.cluster), test.command); - const argument = command.response.arguments.find(item => item.name.toLowerCase() == argumentName.toLowerCase()); - return { type : argument.type, chipType : argument.chipType, isNullable : argument.isNullable }; -} - -async function getAttributeInformationsFor(context, test, attributeName) -{ - const attribute = await getItems(test, getAttributes(context, test.cluster), attributeName); - return { type : attribute.type, chipType : attribute.chipType, isNullable : attribute.isNullable }; -} - -async function extractVariablesFromConfig(context, suite) -{ - let variables = []; - - // Ensure that timeout is always set in the config, to enable command-line - // control over it. - if (!("timeout" in suite.config)) { - // Set to the defaultValue, because below for the isKnownVariable case we will use - // the actual value as the default value... - suite.config.timeout = knownVariables.timeout.defaultValue; - } - - for (const key in suite.config) { - let value = {}; - - const isKnownVariable = key in knownVariables; - - const target = isKnownVariable ? knownVariables[key] : suite.config[key]; - for (const prop in target) { - value[prop] = target[prop]; - } - - if (!isKnownVariable && !('defaultValue' in target)) { - throw new Error(`${suite.filename}: No default value defined for config '${key}'`); - } - - value.defaultValue = isKnownVariable ? suite.config[key] : suite.config[key].defaultValue; - if (Number.isInteger(value.defaultValue) && !Number.isSafeInteger(value.defaultValue)) { - throw new Error(`${suite.filename}: Default value defined for config '${ - key}' is too large to represent exactly as an integer in YAML. Put quotes around it to treat it as a string.`); - } - value.chipType = await zclHelper.asUnderlyingZclType.call(context, value.type, { 'hash' : {} }); - value.name = key; - variables.push(value); - } - - return variables; -} - -async function extractVariablesFromTests(context, suite) -{ - let variables = {}; - suite.tests.forEach(test => { - test.response.forEach(response => { - response.values.filter(value => value.saveAs).forEach(saveAsValue => { - const key = saveAsValue.saveAs; - if (key in variables) { - throwError(test, `Variable with name: ${key} is already registered.`); - } - - if (!test.isCommand && !test.isAttribute) { - throwError(test, `Variable support for step ${test} is not supported. Only commands and attributes are supported.`); - } - - variables[key] = { test, name : saveAsValue.name }; - }); - }); - }); - - const rv = []; - for (const [key, { test, name }] of Object.entries(variables)) { - let variable = await ( - test.isCommand ? getCommandInformationsFor(context, test, name) : getAttributeInformationsFor(context, test, name)); - variable.name = key; - rv.push(variable); - } - - return rv; -} - -async function Variables(context, suite) -{ - return { - config : await extractVariablesFromConfig(context, suite), - tests : await extractVariablesFromTests(context, suite), - }; -} - -// -// Module exports -// -exports.Variables = Variables; diff --git a/src/app/zap-templates/partials/helper.js b/src/app/zap-templates/partials/helper.js deleted file mode 100644 index 78f61cffccce43..00000000000000 --- a/src/app/zap-templates/partials/helper.js +++ /dev/null @@ -1,43 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * - * 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. - */ - -function pad(label, len, ch = ' ') -{ - return label.padEnd(len, ch); -} - -function concat() -{ - let str = '' - // Last argument is our hash argument. - for (let arg = 0; arg < arguments.length - 1; ++arg) - { - if (typeof arguments[arg] != 'object' || arguments[arg] instanceof String) { - str += arguments[arg]; - } else { - throw new TypeError( - `Unexpected object in concat: ${arg}:${Object.prototype.toString.call(arguments[arg])}, ${JSON.stringify(arguments)}`); - } - } - return str -} - -// -// Module exports -// -exports.pad = pad; -exports.concat = concat; diff --git a/src/app/zap-templates/templates/app/helper.js b/src/app/zap-templates/templates/app/helper.js deleted file mode 100644 index 66033f0100de5f..00000000000000 --- a/src/app/zap-templates/templates/app/helper.js +++ /dev/null @@ -1,876 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * - * 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 helpers from zap core -const zapPath = '../../../../../third_party/zap/repo/dist/src-electron/'; -const templateUtil = require(zapPath + 'generator/template-util.js') -const zclHelper = require(zapPath + 'generator/helper-zcl.js') -const queryCommand = require(zapPath + 'db/query-command.js') -const zclQuery = require(zapPath + 'db/query-zcl.js') -const queryEvents = require(zapPath + 'db/query-event.js') -const cHelper = require(zapPath + 'generator/helper-c.js') -const string = require(zapPath + 'util/string.js') -const dbEnum = require(zapPath + '../src-shared/db-enum.js') - -const StringHelper = require('../../common/StringHelper.js'); -const ChipTypesHelper = require('../../common/ChipTypesHelper.js'); -const TestHelper = require('../../common/ClusterTestGeneration.js'); - -zclHelper['isEvent'] = function (db, event_name, packageId) { - return queryEvents - .selectAllEvents(db, packageId) - .then(events => events.find(event => event.name == event_name)) - .then(events => events ? 'event' : dbEnum.zclType.unknown); -} - -// This list of attributes is taken from section '11.2. Global Attributes' of the -// Data Model specification. -const kGlobalAttributes = [ - 0xfff8, // GeneratedCommandList - 0xfff9, // AcceptedCommandList - 0xfffb, // AttributeList - 0xfffc, // ClusterRevision - 0xfffd, // FeatureMap -]; - -// Endpoint-config specific helpers -// these helpers are a Hot fix for the "GENERATED_FUNCTIONS" problem -// They should be removed or replace once issue #4369 is resolved -// These helpers only works within the endpoint_config iterator - -// List of all cluster with generated functions -var endpointClusterWithInit = [ - 'Basic', - 'Color Control', - 'Groups', - 'Identify', - 'Level Control', - 'Localization Configuration', - 'Occupancy Sensing', - 'On/Off', - 'Pump Configuration and Control', - 'Scenes', - 'Time Format Localization', - 'Thermostat', - 'Mode Select', -]; -var endpointClusterWithAttributeChanged = [ - 'Bridged Device Basic', - 'Door Lock', - 'Identify', - 'Pump Configuration and Control', - 'Window Covering', - 'Fan Control', -]; -var endpointClusterWithPreAttribute = [ - 'Door Lock', - 'Pump Configuration and Control', - 'Thermostat User Interface Configuration', - 'Time Format Localization', - 'Localization Configuration', - 'Mode Select', - 'Fan Control', - 'Thermostat', -]; - -/** - * Populate the GENERATED_FUNCTIONS field - */ -function chip_endpoint_generated_functions() -{ - let alreadySetCluster = []; - let ret = '\\\n'; - this.clusterList.forEach((c) => { - let clusterName = c.clusterName; - let functionList = ''; - if (alreadySetCluster.includes(clusterName)) { - // Only one array of Generated functions per cluster across all endpoints - return - } - if (c.comment.includes('server')) { - let hasFunctionArray = false - if (endpointClusterWithInit.includes(clusterName)) - { - hasFunctionArray = true - functionList = functionList.concat( - ` (EmberAfGenericClusterFunction) emberAf${cHelper.asCamelCased(clusterName, false)}ClusterServerInitCallback,\\\n`) - } - - if (endpointClusterWithAttributeChanged.includes(clusterName)) { - functionList = functionList.concat(` (EmberAfGenericClusterFunction) Matter${ - cHelper.asCamelCased(clusterName, false)}ClusterServerAttributeChangedCallback,\\\n`) - hasFunctionArray = true - } - - if (endpointClusterWithPreAttribute.includes(clusterName)) { - functionList = functionList.concat(` (EmberAfGenericClusterFunction) Matter${ - cHelper.asCamelCased(clusterName, false)}ClusterServerPreAttributeChangedCallback,\\\n`) - hasFunctionArray = true - } - - if (hasFunctionArray) { - ret = ret.concat( - `const EmberAfGenericClusterFunction chipFuncArray${cHelper.asCamelCased(clusterName, false)}Server[] = {\\\n`) - ret = ret.concat(functionList) - ret = ret.concat(`};\\\n`) - alreadySetCluster.push(clusterName) - } - } - }) - return ret.concat('\n'); -} - -function chip_endpoint_generated_commands_list(options) -{ - let ret = []; - let index = 0; - this.clusterList.forEach((c) => { - let acceptedCommands = []; - let generatedCommands = []; - - c.commands.forEach((cmd) => { - if (cmd.mask.includes('incoming_server')) { - acceptedCommands.push(`${cmd.commandId} /* ${cmd.name} */`); - if (cmd.responseId !== null) { - generatedCommands.push(`${cmd.responseId} /* ${cmd.responseName} */`); - } - } - }); - - generatedCommands = [...new Set(generatedCommands) ].sort(); - - if (acceptedCommands.length > 0 || generatedCommands.length > 0) { - ret.push({ text : ` /* ${c.comment} */\\` }); - } - if (acceptedCommands.length > 0) { - acceptedCommands.push('chip::kInvalidCommandId /* end of list */') - ret.push({ text : ` /* AcceptedCommandList (index=${index}) */ \\\n ${acceptedCommands.join(', \\\n ')}, \\` }); - index += acceptedCommands.length; - } - if (generatedCommands.length > 0) { - generatedCommands.push('chip::kInvalidCommandId /* end of list */') - ret.push({ text : ` /* GeneratedCommandList (index=${index})*/ \\\n ${generatedCommands.join(', \\\n ')}, \\` }); - index += generatedCommands.length; - } - }) - return templateUtil.collectBlocks(ret, options, this); -} - -/** - * Return endpoint config GENERATED_CLUSTER MACRO - * To be used as a replacement of endpoint_cluster_list since this one - * includes the GENERATED_FUNCTIONS array - */ -function chip_endpoint_cluster_list() -{ - let ret = '{ \\\n'; - let totalCommands = 0; - this.clusterList.forEach((c) => { - let mask = ''; - let functionArray = c.functions; - let clusterName = c.clusterName; - - if (c.comment.includes('server')) { - let hasFunctionArray = false; - if (endpointClusterWithInit.includes(clusterName)) { - c.mask.push('INIT_FUNCTION') - hasFunctionArray = true - } - - if (endpointClusterWithAttributeChanged.includes(clusterName)) { - c.mask.push('ATTRIBUTE_CHANGED_FUNCTION') - hasFunctionArray = true - } - - if (endpointClusterWithPreAttribute.includes(clusterName)) { - c.mask.push('PRE_ATTRIBUTE_CHANGED_FUNCTION') - hasFunctionArray = true - } - - if (hasFunctionArray) { - functionArray = 'chipFuncArray' + cHelper.asCamelCased(clusterName, false) + 'Server' - } - } - - if (c.mask.length == 0) { - mask = '0' - } else { - mask = c.mask.map((m) => `ZAP_CLUSTER_MASK(${m.toUpperCase()})`).join(' | ') - } - - let acceptedCommands = 0; - let generatedCommandList = []; - c.commands.forEach((cmd) => { - if (cmd.mask.includes('incoming_server')) { - acceptedCommands++; - if (cmd.responseId !== null) { - generatedCommandList.push(cmd.responseId); - } - } - }); - let generatedCommands = new Set(generatedCommandList).size; - - let acceptedCommandsListVal = "nullptr"; - let generatedCommandsListVal = "nullptr"; - - if (acceptedCommands > 0) { - acceptedCommands++; // Leaves space for the terminator - acceptedCommandsListVal = `ZAP_GENERATED_COMMANDS_INDEX( ${totalCommands} )`; - } - - if (generatedCommands > 0) { - generatedCommands++; // Leaves space for the terminator - generatedCommandsListVal = `ZAP_GENERATED_COMMANDS_INDEX( ${totalCommands + acceptedCommands} )`; - } - - ret = ret.concat(` { \\ - /* ${c.comment} */ \\ - .clusterId = ${c.clusterId}, \\ - .attributes = ZAP_ATTRIBUTE_INDEX(${c.attributeIndex}), \\ - .attributeCount = ${c.attributeCount}, \\ - .clusterSize = ${c.attributeSize}, \\ - .mask = ${mask}, \\ - .functions = ${functionArray}, \\ - .acceptedCommandList = ${acceptedCommandsListVal} ,\\ - .generatedCommandList = ${generatedCommandsListVal} ,\\ - },\\\n`) - - totalCommands = totalCommands + acceptedCommands + generatedCommands; - }) - return ret.concat('}\n'); -} - -/** - * Return the number of data versions we need for our fixed endpoints. - * - * This is just the count of server clusters on those endpoints. - */ -function chip_endpoint_data_version_count() -{ - let serverCount = 0; - for (const ep of this.endpoints) { - let epType = this.endpointTypes.find(type => type.id == ep.endpointTypeRef); - for (const cluster of epType.clusters) { - if (cluster.side == "server") { - ++serverCount; - } - } - } - return serverCount; -} - -// End of Endpoint-config specific helpers - -async function asNativeType(type) -{ - function fn(pkgId) - { - const options = { 'hash' : {} }; - return zclHelper.asUnderlyingZclType.call(this, type, options).then(zclType => { - return ChipTypesHelper.asBasicType(zclType); - }) - } - - const promise = templateUtil.ensureZclPackageId(this).then(fn.bind(this)).catch(err => { - console.log(err); - throw err; - }); - return templateUtil.templatePromise(this.global, promise) -} - -async function asTypedExpression(value, type) -{ - const valueIsANumber = !isNaN(value); - if (!value || valueIsANumber) { - return asTypedLiteral.call(this, value, type); - } - - const tokens = value.split(' '); - if (tokens.length < 2) { - return asTypedLiteral.call(this, value, type); - } - - value = tokens - .map(token => { - if (!TestHelper.chip_tests_variables_has.call(this, token)) { - return token; - } - - if (!TestHelper.chip_tests_variables_is_nullable.call(this, token)) { - return token; - } - - return `${token}.Value()`; - }) - .join(' '); - - const resultType = await asNativeType.call(this, type); - return `static_cast<${resultType}>(${value})`; -} - -async function asTypedLiteral(value, type, cookie) -{ - const valueIsANumber = !isNaN(value); - if (!valueIsANumber) { - return value; - } - - const basicType = await asNativeType.call(this, type); - switch (basicType) { - case 'int32_t': - return value + 'L'; - case 'int64_t': - return value + 'LL'; - case 'uint8_t': - case 'uint16_t': - return value + 'U'; - case 'uint32_t': - return value + 'UL'; - case 'uint64_t': - return value + 'ULL'; - case 'float': - if (value == Infinity || value == -Infinity) { - return `${(value < 0) ? '-' : ''}INFINITY` - } - // If the number looks like an integer, append ".0" to the end; - // otherwise adding an "f" suffix makes compilers complain. - value = value.toString(); - if (value.match(/^-?[0-9]+$/)) { - value = value + ".0"; - } - return value + 'f'; - default: - if (value == Infinity || value == -Infinity) { - return `${(value < 0) ? '-' : ''}INFINITY` - } - return value; - } -} - -function hasSpecificAttributes(options) -{ - return this.count > kGlobalAttributes.length; -} - -function asLowerCamelCase(label) -{ - let str = string.toCamelCase(label, true); - // Check for the case when we're: - // 1. A single word (that's the regexp at the beginning, which matches the - // word-splitting regexp in string.toCamelCase). - // 2. Starting with multiple capital letters in a row. - // 3. But not _all_ capital letters (which we purposefully - // convert to all-lowercase). - // - // and if all those conditions hold, preserve the leading capital letters by - // uppercasing the first one, which got lowercased. - if (!/ |_|-|\//.test(label) && label.length > 1 && label.substring(0, 2).toUpperCase() == label.substring(0, 2) - && label.toUpperCase() != label) { - str = str[0].toUpperCase() + str.substring(1); - } - return str.replace(/[^A-Za-z0-9_]/g, ''); -} - -function asUpperCamelCase(label) -{ - let str = string.toCamelCase(label, false); - return str.replace(/[^A-Za-z0-9_]/g, ''); -} - -function chip_friendly_endpoint_type_name(options) -{ - var name = this.endpointTypeName; - if (name.startsWith("MA-")) { - // prefix likely for "Matter" and is redundant - name = name.substring(3); - } - - return asLowerCamelCase(name); -} - -function asMEI(prefix, suffix) -{ - return cHelper.asHex((prefix << 16) + suffix, 8); -} - -// Not to be exported. -function nsValueToNamespace(ns) -{ - if (ns == "detail") { - return ns; - } - - return asUpperCamelCase(ns); -} - -/* - * @brief - * - * This function converts a given ZAP type to a Cluster Object - * type used by the Matter SDK. - * - * Args: - * - * type: ZAP type specified in the XML - * isDecodable: Whether to emit an Encodable or Decodable cluster - * object type. - * - * These types can be found in src/app/data-model/. - * - */ -async function zapTypeToClusterObjectType(type, isDecodable, options) -{ - // Use the entryType as a type - if (type == 'array' && this.entryType) { - type = this.entryType; - } - - let passByReference = false; - async function fn(pkgId) - { - const ns = options.hash.ns ? ('chip::app::Clusters::' + nsValueToNamespace(options.hash.ns) + '::') : ''; - const typeChecker = async (method) => zclHelper[method](this.global.db, type, pkgId).then(zclType => zclType != 'unknown'); - - const types = { - isEnum : await typeChecker('isEnum'), - isBitmap : await typeChecker('isBitmap'), - isEvent : await typeChecker('isEvent'), - isStruct : await typeChecker('isStruct'), - }; - - const typesCount = Object.values(types).filter(isType => isType).length; - if (typesCount > 1) { - let error = type + ' is ambiguous: \n'; - Object.entries(types).forEach(([ key, value ]) => { - if (value) { - error += '\t' + key + ': ' + value + '\n'; - } - }); - throw error; - } - - if (types.isEnum) { - // Catching baseline enums and converting them into 'uint[size]_t' - let s = type.toLowerCase().match(/^enum(\d+)$/); - if (s) { - return 'uint' + s[1] + '_t'; - } - return ns + type; - } - - if (types.isBitmap) { - // Catching baseline bitmaps and converting them into 'uint[size]_t' - let s = type.toLowerCase().match(/^bitmap(\d+)$/); - if (s) { - return 'uint' + s[1] + '_t'; - } - return 'chip::BitMask<' + ns + type + '>'; - } - - if (types.isStruct) { - passByReference = true; - return ns + 'Structs::' + type + '::' + (isDecodable ? 'DecodableType' : 'Type'); - } - - if (types.isEvent) { - passByReference = true; - return ns + 'Events::' + type + '::' + (isDecodable ? 'DecodableType' : 'Type'); - } - - return zclHelper.asUnderlyingZclType.call({ global : this.global }, type, options); - } - - let typeStr = await templateUtil.ensureZclPackageId(this).then(fn.bind(this)); - if ((this.isArray || this.entryType) && !options.hash.forceNotList) { - passByReference = true; - // If we did not have a namespace provided, we can assume we're inside - // chip::app. - let listNamespace = options.hash.ns ? "chip::app::" : "" - if (isDecodable) - { - typeStr = `${listNamespace}DataModel::DecodableList<${typeStr}>`; - } - else - { - // Use const ${typeStr} so that consumers don't have to create non-const - // data to encode. - typeStr = `${listNamespace}DataModel::List`; - } - } - if (this.isNullable && !options.hash.forceNotNullable) { - passByReference = true; - // If we did not have a namespace provided, we can assume we're inside - // chip::app::. - let ns = options.hash.ns ? "chip::app::" : "" - typeStr = `${ns}DataModel::Nullable<${typeStr}>`; - } - if (this.isOptional && !options.hash.forceNotOptional) { - passByReference = true; - // If we did not have a namespace provided, we can assume we're inside - // chip::. - let ns = options.hash.ns ? "chip::" : "" - typeStr = `${ns}Optional<${typeStr}>`; - } - if (options.hash.isArgument && passByReference) { - typeStr = `const ${typeStr} &`; - } - return templateUtil.templatePromise(this.global, Promise.resolve(typeStr)) -} - -function zapTypeToEncodableClusterObjectType(type, options) -{ - return zapTypeToClusterObjectType.call(this, type, false, options) -} - -function zapTypeToDecodableClusterObjectType(type, options) -{ - return zapTypeToClusterObjectType.call(this, type, true, options) -} - -async function _zapTypeToPythonClusterObjectType(type, options) -{ - async function fn(pkgId) - { - const ns = options.hash.ns; - const typeChecker = async (method) => zclHelper[method](this.global.db, type, pkgId).then(zclType => zclType != 'unknown'); - - if (await typeChecker('isEnum')) { - // Catching baseline enums and converting them into 'uint' - if (type.toLowerCase().match(/^enum\d+$/g)) { - return 'uint'; - } - return ns + '.Enums.' + type; - } - - if (await typeChecker('isBitmap')) { - return 'uint'; - } - - if (await typeChecker('isStruct')) { - return ns + '.Structs.' + type; - } - - if (StringHelper.isCharString(type)) { - return 'str'; - } - - if (StringHelper.isOctetString(type)) { - return 'bytes'; - } - - if (type.toLowerCase() == 'single') { - return 'float32'; - } - - if (type.toLowerCase() == 'double') { - return 'float'; - } - - if (type.toLowerCase() == 'boolean') { - return 'bool' - } - - // #10748: asUnderlyingZclType will emit wrong types for int{48|56|64}(u), so we process all int values here. - if (type.toLowerCase().match(/^int\d+$/)) { - return 'int' - } - - if (type.toLowerCase().match(/^int\d+u$/)) { - return 'uint' - } - - resolvedType = await zclHelper.asUnderlyingZclType.call({ global : this.global }, type, options); - { - basicType = ChipTypesHelper.asBasicType(resolvedType); - if (basicType.match(/^int\d+_t$/)) { - return 'int' - } - if (basicType.match(/^uint\d+_t$/)) { - return 'uint' - } - } - } - - let promise = templateUtil.ensureZclPackageId(this).then(fn.bind(this)); - if ((this.isArray || this.entryType) && !options.hash.forceNotList) { - promise = promise.then(typeStr => `typing.List[${typeStr}]`); - } - - const isNull = (this.isNullable && !options.hash.forceNotNullable); - const isOptional = (this.isOptional && !options.hash.forceNotOptional); - - if (isNull && isOptional) { - promise = promise.then(typeStr => `typing.Union[None, Nullable, ${typeStr}]`); - } else if (isNull) { - promise = promise.then(typeStr => `typing.Union[Nullable, ${typeStr}]`); - } else if (isOptional) { - promise = promise.then(typeStr => `typing.Optional[${typeStr}]`); - } - - return templateUtil.templatePromise(this.global, promise) -} - -function zapTypeToPythonClusterObjectType(type, options) -{ - return _zapTypeToPythonClusterObjectType.call(this, type, options) -} - -async function _getPythonFieldDefault(type, options) -{ - async function fn(pkgId) - { - const ns = options.hash.ns; - const typeChecker = async (method) => zclHelper[method](this.global.db, type, pkgId).then(zclType => zclType != 'unknown'); - - if (await typeChecker('isEnum')) { - return '0'; - } - - if (await typeChecker('isBitmap')) { - return '0'; - } - - if (await typeChecker('isStruct')) { - return 'field(default_factory=lambda: ' + ns + '.Structs.' + type + '())'; - } - - if (StringHelper.isCharString(type)) { - return '""'; - } - - if (StringHelper.isOctetString(type)) { - return 'b""'; - } - - if ([ 'single', 'double' ].includes(type.toLowerCase())) { - return '0.0'; - } - - if (type.toLowerCase() == 'boolean') { - return 'False' - } - - // #10748: asUnderlyingZclType will emit wrong types for int{48|56|64}(u), so we process all int values here. - if (type.toLowerCase().match(/^int\d+$/)) { - return '0' - } - - if (type.toLowerCase().match(/^int\d+u$/)) { - return '0' - } - - resolvedType = await zclHelper.asUnderlyingZclType.call({ global : this.global }, type, options); - { - basicType = ChipTypesHelper.asBasicType(resolvedType); - if (basicType.match(/^int\d+_t$/)) { - return '0' - } - if (basicType.match(/^uint\d+_t$/)) { - return '0' - } - } - } - - let promise = templateUtil.ensureZclPackageId(this).then(fn.bind(this)); - if ((this.isArray || this.entryType) && !options.hash.forceNotList) { - promise = promise.then(typeStr => `field(default_factory=lambda: [])`); - } - - const isNull = (this.isNullable && !options.hash.forceNotNullable); - const isOptional = (this.isOptional && !options.hash.forceNotOptional); - - if (isNull && isOptional) { - promise = promise.then(typeStr => `None`); - } else if (isNull) { - promise = promise.then(typeStr => `NullValue`); - } else if (isOptional) { - promise = promise.then(typeStr => `None`); - } - - return templateUtil.templatePromise(this.global, promise) -} - -function getPythonFieldDefault(type, options) -{ - return _getPythonFieldDefault.call(this, type, options) -} - -// Allow-list of enums that we generate as enums, not enum classes. The goal is -// to drive this down to 0. -function isWeaklyTypedEnum(label) -{ - return [ - "AttributeWritePermission", - "BarrierControlBarrierPosition", - "BarrierControlMovingState", - "ColorControlOptions", - "ColorLoopAction", - "ColorLoopDirection", - "ColorMode", - "ContentLaunchStatus", - "ContentLaunchStreamingType", - "EnhancedColorMode", - "HardwareFaultType", - "HueDirection", - "HueMoveMode", - "HueStepMode", - "IdentifyEffectIdentifier", - "IdentifyEffectVariant", - "IdentifyIdentifyType", - "InterfaceType", - "KeypadLockout", - "LevelControlOptions", - "MoveMode", - "NetworkFaultType", - "OnOffDelayedAllOffEffectVariant", - "OnOffDyingLightEffectVariant", - "OnOffEffectIdentifier", - "PHYRateType", - "RadioFaultType", - "RoutingRole", - "SaturationMoveMode", - "SaturationStepMode", - "SecurityType", - "SetpointAdjustMode", - "StartUpOnOffValue", - "StatusCode", - "StepMode", - "TemperatureDisplayMode", - "WiFiVersionType", - ].includes(label); -} - -function incrementDepth(depth) -{ - return depth + 1; -} - -function hasProperty(obj, prop) -{ - return prop in obj; -} - -async function zcl_events_fields_by_event_name(name, options) -{ - const { db, sessionId } = this.global; - const packageId = await templateUtil.ensureZclPackageId(this) - - const promise = queryEvents.selectAllEvents(db, packageId) - .then(events => events.find(event => event.name == name)) - .then(evt => queryEvents.selectEventFieldsByEventId(db, evt.id)) - .then(fields => fields.map(field => { - field.label = field.name; - return field; - })) - .then(fields => templateUtil.collectBlocks(fields, options, this)) - return templateUtil.templatePromise(this.global, promise) -} - -// Must be used inside zcl_clusters -async function zcl_commands_that_need_timed_invoke(options) -{ - const { db } = this.global; - let packageId = await templateUtil.ensureZclPackageId(this); - let commands = await queryCommand.selectCommandsByClusterId(db, this.id, packageId); - commands = commands.filter(cmd => cmd.mustUseTimedInvoke); - return templateUtil.collectBlocks(commands, options, this); -} - -// Allows conditioning generation on whether the given type is a fabric-scoped -// struct. -async function if_is_fabric_scoped_struct(type, options) -{ - let packageId = await templateUtil.ensureZclPackageId(this); - let st = await zclQuery.selectStructByName(this.global.db, type, packageId); - - if (st) { - // TODO: Should know whether a struct is fabric-scoped without sniffing its - // members. - let fields = await zclQuery.selectAllStructItemsById(this.global.db, st.id); - if (fields.find((i) => i.type.toLowerCase() == "fabric_idx")) { - return options.fn(this); - } - } - - return options.inverse(this); -} - -// check if a value is numerically 0 for the purpose of default value -// interpretation. Note that this does NOT check for data type, so assumes -// a string of 'false' is 0 because boolean false is 0. -function isNonZeroValue(value) -{ - if (!value) { - return false; - } - - if (value === '0') { - return false; - } - - // Hex value usage is inconsistent in XML. It looks we have - // all of 0x0, 0x00, 0x0000 so support all here. - if (value.match(/^0x0+$/)) { - return false; - } - - // boolean 0 is false. We do not do a type check here - // so if anyone defaults a string to 'false' this will be wrong. - if (value === 'false') { - return false; - } - - return true; -} - -// Check if the default value is non-zero -// Generally does string checks for empty strings, numeric or hex zeroes or -// boolean values. -async function if_is_non_zero_default(value, options) -{ - if (isNonZeroValue(value)) { - return options.fn(this); - } else { - return options.inverse(this); - } -} - -// -// Module exports -// -exports.chip_endpoint_generated_functions = chip_endpoint_generated_functions -exports.chip_endpoint_cluster_list = chip_endpoint_cluster_list -exports.chip_endpoint_data_version_count = chip_endpoint_data_version_count; -exports.chip_endpoint_generated_commands_list = chip_endpoint_generated_commands_list -exports.asTypedExpression = asTypedExpression; -exports.asTypedLiteral = asTypedLiteral; -exports.asLowerCamelCase = asLowerCamelCase; -exports.asUpperCamelCase = asUpperCamelCase; -exports.chip_friendly_endpoint_type_name = chip_friendly_endpoint_type_name; -exports.hasProperty = hasProperty; -exports.hasSpecificAttributes = hasSpecificAttributes; -exports.asMEI = asMEI; -exports.zapTypeToEncodableClusterObjectType = zapTypeToEncodableClusterObjectType; -exports.zapTypeToDecodableClusterObjectType = zapTypeToDecodableClusterObjectType; -exports.zapTypeToPythonClusterObjectType = zapTypeToPythonClusterObjectType; -exports.isWeaklyTypedEnum = isWeaklyTypedEnum; -exports.getPythonFieldDefault = getPythonFieldDefault; -exports.incrementDepth = incrementDepth; -exports.zcl_events_fields_by_event_name = zcl_events_fields_by_event_name; -exports.zcl_commands_that_need_timed_invoke = zcl_commands_that_need_timed_invoke; -exports.if_is_fabric_scoped_struct = if_is_fabric_scoped_struct; -exports.if_is_non_zero_default = if_is_non_zero_default; diff --git a/src/app/zap-templates/templates/chip/ListHelper.js b/src/app/zap-templates/templates/chip/ListHelper.js deleted file mode 100644 index 0713e5d667310b..00000000000000 --- a/src/app/zap-templates/templates/chip/ListHelper.js +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Copyright (c) 2020-2021 Project CHIP Authors - * - * 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. - */ - -const kListAttributeAtomicTypeId = 0x48; - -/** - * Returns the calculated length of the given attribute list - * - * This function is meant to be used inside a {{#chip_server_cluster_attributes}} block. - * It will throws otherwise. - * - * @param {*} options - */ -function asListEntryLength(options) -{ - return this.size; - if (this.atomicTypeId == undefined) { - const error = 'asListEntryLength: missing atomic type.'; - console.log(error); - throw error; - } - - if (this.atomicTypeId != kListAttributeAtomicTypeId) { - const error = 'asListEntryLength: Not a list.'; - console.log(error); - throw error; - } - - const entryType = this.entryType; - return entryType.size || entryType.map(type => type.size).reduce((accumulator, currentValue) => accumulator + currentValue, 0); -} - -// -// Module exports -// -exports.asListEntryLength = asListEntryLength; diff --git a/src/app/zap-templates/templates/chip/helper.js b/src/app/zap-templates/templates/chip/helper.js deleted file mode 100644 index ccb6164df4df85..00000000000000 --- a/src/app/zap-templates/templates/chip/helper.js +++ /dev/null @@ -1,675 +0,0 @@ -/* - * - * Copyright (c) 2020-2021 Project CHIP Authors - * - * 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 helpers from zap core -const zapPath = '../../../../../third_party/zap/repo/dist/src-electron/'; -const templateUtil = require(zapPath + 'generator/template-util.js'); -const zclHelper = require(zapPath + 'generator/helper-zcl.js'); -const iteratorUtil = require(zapPath + 'util/iterator-util.js'); -const queryAccess = require(zapPath + 'db/query-access') -const queryZcl = require(zapPath + 'db/query-zcl'); - -const { asBlocks, ensureClusters } = require('../../common/ClustersHelper.js'); -const StringHelper = require('../../common/StringHelper.js'); -const ChipTypesHelper = require('../../common/ChipTypesHelper.js'); - -function throwErrorIfUndefined(item, errorMsg, conditions) -{ - conditions.forEach(condition => { - if (condition == undefined) { - console.log(item); - console.log(errorMsg); - throw error; - } - }); -} - -function checkIsInsideClusterBlock(context, name) -{ - const clusterName = context.name ? context.name : context.clusterName; - const clusterSide = context.side ? context.side : context.clusterSide; - const errorMsg = name + ': Not inside a ({#chip_server_clusters}} block.'; - throwErrorIfUndefined(context, errorMsg, [ clusterName, clusterSide ]); - - return { clusterName, clusterSide }; -} - -function checkIsInsideCommandBlock(context, name) -{ - const clusterName = context.clusterName; - const clusterSide = context.clusterSide; - const commandId = context.id; - const errorMsg = name + ': Not inside a ({#chip_cluster_commands}} block.'; - - throwErrorIfUndefined(context, errorMsg, [ commandId, clusterName, clusterSide ]); - - return commandId; -} - -function checkIsInsideAttributeBlock(context, name) -{ - const code = context.code; - const errorMsg = name + ': Not inside a ({#chip_server_attributes}} block.'; - - throwErrorIfUndefined(context, errorMsg, [ code ]); -} - -function checkIsChipType(context, name) -{ - const type = context.chipType; - const errorMsg = name + ': Could not find chipType'; - - throwErrorIfUndefined(context, errorMsg, [ type ]); - - return type; -} - -function getCommands(methodName) -{ - const { clusterName, clusterSide } = checkIsInsideClusterBlock(this, methodName); - return clusterSide == 'client' ? ensureClusters(this).getClientCommands(clusterName) - : ensureClusters(this).getServerCommands(clusterName); -} - -function getAttributes(methodName) -{ - const { clusterName, clusterSide } = checkIsInsideClusterBlock(this, methodName); - return ensureClusters(this).getAttributesByClusterName(clusterName); -} - -function getResponses(methodName) -{ - const { clusterName, clusterSide } = checkIsInsideClusterBlock(this, methodName); - return clusterSide == 'client' ? ensureClusters(this).getClientResponses(clusterName) - : ensureClusters(this).getServerResponses(clusterName); -} - -/** - * Creates block iterator over the enabled server side clusters - * - * @param {*} options - */ -function chip_server_clusters(options) -{ - return asBlocks.call(this, ensureClusters(this, options.hash.includeAll).getServerClusters(), options); -} - -/** - * Check if there is any enabled server clusters - * - */ -function chip_has_server_clusters(options) -{ - return ensureClusters(this).getServerClusters().then(clusters => !!clusters.length); -} - -/** - * Creates block iterator over client side enabled clusters - * - * @param {*} options - */ -function chip_client_clusters(options) -{ - return asBlocks.call(this, ensureClusters(this, options.hash.includeAll).getClientClusters(), options); -} - -/** - * Check if there is any enabled client clusters - * - */ -function chip_has_client_clusters(options) -{ - return ensureClusters(this).getClientClusters().then(clusters => !!clusters.length); -} - -/** - * Creates block iterator over enabled clusters - * - * @param {*} options - */ -function chip_clusters(options) -{ - return asBlocks.call(this, ensureClusters(this, options.hash.includeAll).getClusters(), options); -} - -/** - * Check if there is any enabled clusters - * - */ -function chip_has_clusters(options) -{ - return ensureClusters(this).getClusters().then(clusters => !!clusters.length); -} - -/** - * Creates block iterator over the server global responses - * - * @param {*} options - */ -function chip_server_global_responses(options) -{ - return asBlocks.call(this, getServerGlobalAttributeResponses(this), options); -} - -async function if_basic_global_response(options) -{ - const attribute = this.response.arguments[0]; - const globalResponses = await getServerGlobalAttributeResponses(this); - const complexType = attribute.isNullable || attribute.isOptional || attribute.isStruct || attribute.isArray; - const responseTypeExists = globalResponses.find(item => item.chipType == attribute.chipType); - - if (!complexType && responseTypeExists) { - return options.fn(this); - } else { - return options.inverse(this); - } -} - -function getServerGlobalAttributeResponses(context) -{ - const sorter = (a, b) => a.chipCallback.name.localeCompare(b.chipCallback.name, 'en', { numeric : true }); - - const reducer = (unique, item) => { - const { type, size, isArray, isOptional, isNullable, chipCallback, chipType } = item.response.arguments[0]; - - // List-typed elements have a dedicated callback - if (isArray) { - return unique; - } - - if (unique.find(item => item.chipCallback.name == chipCallback.name)) { - return unique; - } - - return [...unique, { chipCallback, chipType, size, isOptional, isNullable } ]; - }; - - const filter = attributes => attributes.reduce(reducer, []).sort(sorter); - return ensureClusters(context).getAttributesByClusterSide('server').then(filter); -} - -/** - * Creates block iterator over the cluster commands for a given cluster/side. - * - * This function is meant to be used inside a {{#chip_*_clusters}} - * block. It will throw otherwise. - * - * @param {*} options - */ -function chip_cluster_commands(options) -{ - const commands = getCommands.call(this, 'chip_cluster_commands'); - - return asBlocks.call(this, commands, options); -} - -/** - * Creates block iterator over the cluster responses for a given cluster/side. - * - * This function is meant to be used inside a {{#chip_*_clusters}} - * block. It will throw otherwise. - * - * @param {*} options - */ -function chip_cluster_responses(options) -{ - const responses = getResponses.call(this, 'chip_cluster_responses'); - - return asBlocks.call(this, responses, options); -} - -/** - * Creates block iterator over the current command arguments for a given cluster/side. - * - * This function is meant to be used inside a {{#chip_cluster_commands}} - * block. It will throw otherwise. - * - * @param {*} options - */ -function chip_cluster_command_arguments(options) -{ - const commandId = checkIsInsideCommandBlock(this, 'chip_cluster_command_arguments'); - const commands = getCommands.call(this.parent, 'chip_cluster_commands_argments'); - - const filter = command => command.id == commandId; - return asBlocks.call(this, commands.then(items => items.find(filter).arguments), options); -} - -/** - * Creates block iterator over the current command arguments for a given cluster/side. - * - * This function is meant to be used inside a {{#chip_cluster_commands}} - * block. It will throw otherwise. - * - * The arguments list built by this function differs from {{chip_cluster_command_arguments}}. - * For example, if a command contains a single struct argument "SomeStruct", with the following type: - * - * struct SomeStruct { - * uint8_t a; - * uint16_t b; - * uint32_t c; - * } - * - * then that argument will be expanded into 3 arguments (uint8_t a, uint16_t b, uint32_t c). - * - * @param {*} options - */ -function chip_cluster_command_arguments_with_structs_expanded(options) -{ - const commandId = checkIsInsideCommandBlock(this, 'chip_cluster_command_arguments'); - const commands = getCommands.call(this.parent, 'chip_cluster_command_arguments_with_structs_expanded'); - - const filter = command => command.id == commandId; - return asBlocks.call(this, commands.then(items => { - const item = items.find(filter); - if (item === undefined) { - return []; - } - return item.expandedArguments || item.arguments; - }), - options); -} - -/** - * Creates block iterator over the current response arguments for a given cluster/side. - * - * This function is meant to be used inside a {{#chip_cluster_responses}} - * block. It will throw otherwise. - * - * @param {*} options - */ -function chip_cluster_response_arguments(options) -{ - const commandId = checkIsInsideCommandBlock(this, 'chip_cluster_response_arguments'); - const responses = getResponses.call(this.parent, 'chip_cluster_responses_argments'); - - const filter = command => command.id == commandId; - return asBlocks.call(this, responses.then(items => items.find(filter).arguments), options); -} - -/** - * Returns if a given server cluster has any attributes of type List[T] - * - * This function is meant to be used inside a {{#chip_server_clusters}} - * block. It will throw otherwise. - * - * @param {*} options - */ -function chip_server_has_list_attributes(options) -{ - const { clusterName } = checkIsInsideClusterBlock(this, 'chip_server_has_list_attributes'); - const attributes = ensureClusters(this).getServerAttributes(clusterName); - - const filter = attribute => attribute.isArray; - return attributes.then(items => items.find(filter)); -} - -/** - * Returns if a given client cluster has any attributes of type List[T] - * - * This function is meant to be used inside a {{#chip_client_clusters}} - * block. It will throw otherwise. - * - * @param {*} options - */ -function chip_client_has_list_attributes(options) -{ - const { clusterName } = checkIsInsideClusterBlock(this, 'chip_client_has_list_attributes'); - const attributes = ensureClusters(this).getClientAttributes(clusterName); - - const filter = attribute => attribute.isArray; - return attributes.then(items => items.find(filter)); -} - -/** - * Returns if a given server cluster has any reportable attribute - * - * This function is meant to be used inside a {{#chip_server_clusters}} - * block. It will throw otherwise. - * - * @param {*} options - */ -function chip_server_has_reportable_attributes(options) -{ - const { clusterName } = checkIsInsideClusterBlock(this, 'chip_server_has_reportable_attributes'); - const attributes = ensureClusters(this).getServerAttributes(clusterName); - - const filter = attribute => attribute.isReportableAttribute; - return attributes.then(items => items.find(filter)); -} - -/** - * Creates block iterator over the server side cluster attributes - * for a given cluster. - * - * This function is meant to be used inside a {{#chip_server_clusters}} - * block. It will throw otherwise. - * - * @param {*} options - */ -function chip_server_cluster_attributes(options) -{ - const { clusterName } = checkIsInsideClusterBlock(this, 'chip_server_cluster_attributes'); - const attributes = ensureClusters(this).getServerAttributes(clusterName); - - return asBlocks.call(this, attributes, options); -} - -/** - * Creates block iterator over the server side cluster attributes - * for a given cluster. - * - * This function is meant to be used inside a {{#chip_server_clusters}} - * block. It will throw otherwise. - * - * @param {*} options - */ -function chip_server_cluster_events(options) -{ - const { clusterName } = checkIsInsideClusterBlock(this, 'chip_server_cluster_events'); - const events = ensureClusters(this).getServerEvents(clusterName); - - return asBlocks.call(this, events, options); -} - -function chip_attribute_list_entryTypes(options) -{ - checkIsInsideAttributeBlock(this, 'chip_attribute_list_entry_types'); - return templateUtil.collectBlocks(this.items, options, this); -} - -/** - * Creates block iterator over commands for a given cluster that have the - * following properties: - * - * 1) Are not manufacturer-specific (to exclude MfgSpecificPing) - * 2) Are available in the isCommandAvailable sense. - */ -function chip_available_cluster_commands(options) -{ - const { clusterName, clusterSide } = checkIsInsideClusterBlock(this, 'chip_available_cluster_commands'); - let promise = iteratorUtil.all_user_cluster_commands_helper.call(this, options) - .then(endpointCommands => endpointCommands.filter(command => { - return command.clusterName == clusterName - && zclHelper.isCommandAvailable( - clusterSide, command.incoming, command.outgoing, command.commandSource, command.name) - && /* exclude MfgSpecificPing */ !command.mfgCode; - })) - .then(filteredCommands => templateUtil.collectBlocks(filteredCommands, options, this)); - return promise; -} - -/** - * Creates block iterator over structures belonging to the current cluster - */ -async function chip_cluster_specific_structs(options) -{ - const { clusterName, clusterSide } = checkIsInsideClusterBlock(this, 'chip_cluster_specific_structs'); - - const structs = await ensureClusters(this).getStructuresByClusterName(clusterName); - - return templateUtil.collectBlocks(structs, options, this); -} - -/** - * Creates block iterator over structures that are shared between clusters - */ -async function chip_shared_structs(options) -{ - const structs = await ensureClusters(this).getSharedStructs(); - return templateUtil.collectBlocks(structs, options, this); -} - -async function chip_endpoints(options) -{ - const endpoints = await ensureClusters(this).getEndPoints(); - return templateUtil.collectBlocks(endpoints, options, this); -} - -async function chip_endpoint_clusters(options) -{ - const clusters = this.clusters; - return templateUtil.collectBlocks(clusters, options, this); -} - -/** - * Helper checks if the type for the bitmap is BitFlags. This generally includes - * all bitmaps apart from - * bitmap8/16/32 (generally defined in types.xml) - * example: - * {{#if_is_strongly_typed_bitmap type}} - * strongly typed bitmap - * {{else}} - * not a strongly typed bitmap - * {{/if_is_strongly_typed_bitmap}} - * - * @param {*} type - * @returns Promise of content. - */ -async function if_is_strongly_typed_bitmap(type, options) -{ - let packageId = await templateUtil.ensureZclPackageId(this); - let bitmap; - if (type && typeof type === 'string') { - bitmap = await queryZcl.selectBitmapByName(this.global.db, packageId, type); - } else { - bitmap = await queryZcl.selectBitmapById(this.global.db, type); - } - - if (bitmap) { - let a = await queryZcl.selectAtomicType(this.global.db, packageId, bitmap.name); - if (a) { - // If this is an atomic type, it's a generic, weakly typed, bitmap. - return options.inverse(this); - } else { - return options.fn(this); - } - } - return options.inverse(this); -} - -/** - * Handlebar helper function which checks if an enum is a strongly typed enum or - * not. This generally includes all enums apart from - * enum8/16/32 (generally defined in types.xml) - * example for if_is_strongly_typed_chip_enum: - * {{#if_is_strongly_typed_chip_enum type}} - * strongly typed enum - * {{else}} - * not a strongly typed enum - * {{/if_is_strongly_typed_chip_enum}} - * - * @param {*} type - * @param {*} options - * @returns Promise of content. - */ -async function if_is_strongly_typed_chip_enum(type, options) -{ - // There are certain exceptions. - if (type.toLowerCase() == 'vendor_id') { - return options.fn(this); - } else { - let packageId = await templateUtil.ensureZclPackageId(this); - let enumRes; - // Retrieving the enum from the enum table - if (type && typeof type === 'string') { - enumRes = await queryZcl.selectEnumByName(this.global.db, type, packageId); - } else { - enumRes = await queryZcl.selectEnumById(this.global.db, type); - } - - // Checking if an enum is atomic. If an enum is not atomic then the enum - // is a strongly typed enum - if (enumRes) { - let a = await queryZcl.selectAtomicType(this.global.db, packageId, enumRes.name); - if (a) { - // if an enum has an atomic type that means it's a weakly-typed enum. - return options.inverse(this); - } else { - return options.fn(this); - } - } - return options.inverse(this); - } -} - -/** - * Checks whether a type is an enum for purposes of its chipType. That includes - * both spec-defined enum types and types that we map to enum types in our code. - */ -async function if_chip_enum(type, options) -{ - if (type.toLowerCase() == 'vendor_id') { - return options.fn(this); - } - - let pkgId = await templateUtil.ensureZclPackageId(this); - let checkResult = await zclHelper.isEnum(this.global.db, type, pkgId); - let result; - if (checkResult != 'unknown') { - result = options.fn(this); - } else { - result = options.inverse(this); - } - return templateUtil.templatePromise(this.global, result); -} - -async function if_chip_complex(options) -{ - // `zcl_command_arguments` has an `isArray` property and `type` - // contains the array element type. - if (this.isArray) { - return options.fn(this); - } - - // zcl_attributes iterators does not expose an `isArray` property - // and `entryType` contains the array element type, while `type` - // contains the atomic type, which is array in this case. - // https://github.com/project-chip/zap/issues/412 - if (this.type == 'array') { - return options.fn(this); - } - - let pkgId = await templateUtil.ensureZclPackageId(this); - let checkResult = await zclHelper.isStruct(this.global.db, this.type, pkgId); - let result; - if (checkResult != 'unknown') { - result = options.fn(this); - } else { - result = options.inverse(this); - } - return templateUtil.templatePromise(this.global, result); -} - -async function chip_access_elements(options) -{ - - // console.log(options); - let entityType = options.hash.entity - - if (entityType == null) - { - throw new Error('Access helper requires entityType, either from context, or from the entity="" option.') - } - - let accessList = null - - // Exaples of operations: - // { operation: null, role: null, accessModifier: 'fabric-scoped' }, - // { operation: 'read', role: 'administer', accessModifier: null }, - // { operation: 'write', role: 'administer', accessModifier: null } - // - // Note the existence of a null operation with a modifier of fabric-scoped - - // accessDefaults contains acceptable operations - // together with their default value - let accessDefaults = new Map(); - - switch (entityType) { - case 'attribute': - accessList = await queryAccess.selectAttributeAccess(this.global.db, this.id); - accessDefaults.set('read', 'view'); - accessDefaults.set('write', 'operate'); - break; - case 'command': - accessList = await queryAccess.selectCommandAccess(this.global.db, this.id); - accessDefaults.set('invoke', 'operate'); - break; - case 'event': - accessList = await queryAccess.selectEventAccess(this.global.db, this.id); - accessDefaults.set('read', 'view'); - break; - default: - throw new Error(`Entity type ${entityType} not supported. Requires: attribute/command/event.`) - } - - let accessEntries = []; - - for (element of accessList) { - if (!element.operation) { - continue; // not a valid operation (likely null) - } - - const operation = element.operation.toLowerCase(); - if (!accessDefaults.has(operation)) { - continue; // not a valid operation (may be a bug or non-matter operation) - } - - const role = element.role.toLowerCase(); - - if (role === accessDefaults.get(operation)) { - continue; // already set as a default - } - - accessEntries.push({ operation, role }) - } - - let p = templateUtil.collectBlocks(accessEntries, options, this) - return templateUtil.templatePromise(this.global, p) -} - -// -// Module exports -// -exports.chip_clusters = chip_clusters; -exports.chip_has_clusters = chip_has_clusters; -exports.chip_client_clusters = chip_client_clusters; -exports.chip_has_client_clusters = chip_has_client_clusters; -exports.chip_server_clusters = chip_server_clusters; -exports.chip_has_server_clusters = chip_has_server_clusters; -exports.chip_cluster_commands = chip_cluster_commands; -exports.chip_cluster_command_arguments = chip_cluster_command_arguments; -exports.chip_cluster_command_arguments_with_structs_expanded = chip_cluster_command_arguments_with_structs_expanded; -exports.chip_server_global_responses = chip_server_global_responses; -exports.chip_cluster_responses = chip_cluster_responses; -exports.chip_cluster_response_arguments = chip_cluster_response_arguments -exports.chip_attribute_list_entryTypes = chip_attribute_list_entryTypes; -exports.chip_server_cluster_attributes = chip_server_cluster_attributes; -exports.chip_server_cluster_events = chip_server_cluster_events; -exports.chip_server_has_list_attributes = chip_server_has_list_attributes; -exports.chip_server_has_reportable_attributes = chip_server_has_reportable_attributes; -exports.chip_available_cluster_commands = chip_available_cluster_commands; -exports.chip_endpoints = chip_endpoints; -exports.chip_endpoint_clusters = chip_endpoint_clusters; -exports.if_chip_enum = if_chip_enum; -exports.if_chip_complex = if_chip_complex; -exports.if_basic_global_response = if_basic_global_response; -exports.chip_cluster_specific_structs = chip_cluster_specific_structs; -exports.chip_shared_structs = chip_shared_structs; -exports.chip_access_elements = chip_access_elements -exports.if_is_strongly_typed_chip_enum = if_is_strongly_typed_chip_enum -exports.if_is_strongly_typed_bitmap = if_is_strongly_typed_bitmap diff --git a/src/controller/java/templates/helper.js b/src/controller/java/templates/helper.js deleted file mode 100644 index 53a77aad35dc8c..00000000000000 --- a/src/controller/java/templates/helper.js +++ /dev/null @@ -1,339 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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 helpers from zap core -const zapPath = '../../../../third_party/zap/repo/dist/src-electron/'; -const templateUtil = require(zapPath + 'generator/template-util.js') -const zclHelper = require(zapPath + 'generator/helper-zcl.js') - -const ChipTypesHelper = require('../../../../src/app/zap-templates/common/ChipTypesHelper.js'); -const StringHelper = require('../../../../src/app/zap-templates/common/StringHelper.js'); -const appHelper = require('../../../../src/app/zap-templates/templates/app/helper.js'); - -function convertBasicCTypeToJavaType(cType) -{ - switch (cType) { - case 'uint8_t': - case 'int8_t': - case 'uint16_t': - case 'int16_t': - return 'int'; - case 'uint32_t': - case 'int32_t': - // TODO(#8074): replace with BigInteger, or mark as unsigned. - case 'uint64_t': - case 'int64_t': - return 'long'; - case 'bool': - return 'boolean'; - case 'float': - return 'float'; - case 'double': - return 'double'; - default: - error = 'Unhandled type ' + cType; - throw error; - } -} - -function convertBasicCTypeToJniType(cType) -{ - switch (convertBasicCTypeToJavaType(cType)) { - case 'int': - return 'jint'; - case 'long': - return 'jlong'; - case 'boolean': - return 'jboolean'; - case 'float': - return 'jfloat'; - case 'double': - return 'jdouble'; - default: - error = 'Unhandled type ' + cType; - throw error; - } -} - -function convertBasicCTypeToJavaBoxedType(cType) -{ - switch (convertBasicCTypeToJavaType(cType)) { - case 'int': - return 'Integer'; - case 'long': - return 'Long'; - case 'boolean': - return 'Boolean'; - case 'float': - return 'Float'; - case 'double': - return 'Double'; - default: - error = 'Unhandled type ' + cType; - throw error; - } -} - -function asJavaBoxedType(type, zclType) -{ - if (StringHelper.isOctetString(type)) { - return 'byte[]'; - } else if (StringHelper.isCharString(type)) { - return 'String'; - } else { - try { - return convertBasicCTypeToJavaBoxedType(ChipTypesHelper.asBasicType(zclType)); - } catch (error) { - // Unknown type, default to Object. - return "Object"; - } - } -} - -function asJniBasicType(type, useBoxedTypes) -{ - if (this.isOptional) { - return 'jobject'; - } else if (StringHelper.isOctetString(type)) { - return 'jbyteArray'; - } else if (StringHelper.isCharString(type)) { - return 'jstring'; - } else { - if (useBoxedTypes) { - return 'jobject'; - } - return convertBasicCTypeToJniType(ChipTypesHelper.asBasicType(this.chipType)); - } -} - -function asJniSignatureBasic(type, useBoxedTypes) -{ - function fn(pkgId) - { - const options = { 'hash' : {} }; - return zclHelper.asUnderlyingZclType.call(this, type, options).then(zclType => { - return convertCTypeToJniSignature(ChipTypesHelper.asBasicType(zclType), useBoxedTypes); - }) - } - - const promise = templateUtil.ensureZclPackageId(this).then(fn.bind(this)).catch(err => { - console.log(err); - throw err; - }); - return templateUtil.templatePromise(this.global, promise) -} - -function convertCTypeToJniSignature(cType, useBoxedTypes) -{ - let javaType; - if (useBoxedTypes) { - javaType = convertBasicCTypeToJavaBoxedType(cType); - } else { - javaType = convertBasicCTypeToJavaType(cType); - } - - switch (javaType) { - case 'int': - return 'I'; - case 'long': - return 'J'; - case 'boolean': - return 'Z'; - case 'double': - return 'D'; - case 'float': - return 'F'; - case 'Boolean': - return 'Ljava/lang/Boolean;'; - case 'Integer': - return 'Ljava/lang/Integer;'; - case 'Long': - return 'Ljava/lang/Long;'; - case 'double': - return 'D'; - case 'Double': - return 'Ljava/lang/Double;'; - case 'float': - return 'F'; - case 'Float': - return 'Ljava/lang/Float;'; - default: - error = 'Unhandled Java type ' + javaType + ' for C type ' + cType; - throw error; - } -} - -function convertAttributeCallbackTypeToJavaName(cType) -{ - // These correspond to OctetStringAttributeCallback and CharStringAttributeCallback in ChipClusters-java.zapt. - if (StringHelper.isOctetString(this.type)) { - return 'OctetString'; - } else if (StringHelper.isCharString(this.type)) { - return 'CharString'; - } else { - return convertBasicCTypeToJavaBoxedType(cType); - } -} - -async function asUnderlyingBasicType(type) -{ - const options = { 'hash' : {} }; - let zclType = await zclHelper.asUnderlyingZclType.call(this, type, options); - return ChipTypesHelper.asBasicType(zclType); -} - -async function asJavaType(type, zclType, cluster, options) -{ - let pkgId = await templateUtil.ensureZclPackageId(this); - if (zclType == null) { - const options = { 'hash' : {} }; - zclType = await zclHelper.asUnderlyingZclType.call(this, type, options); - } - let isStruct = await zclHelper.isStruct(this.global.db, type, pkgId).then(zclType => zclType != 'unknown'); - - let classType = ""; - - if (StringHelper.isOctetString(type)) { - classType += 'byte[]'; - } else if (StringHelper.isCharString(type)) { - classType += 'String'; - } else if (isStruct) { - classType += `ChipStructs.${appHelper.asUpperCamelCase(cluster)}Cluster${appHelper.asUpperCamelCase(type)}`; - } else { - classType += asJavaBoxedType(type, zclType); - } - - if (!options.hash.underlyingType) { - if (!options.hash.forceNotList && (this.isArray || this.entryType)) { - if (!options.hash.removeGenericType) { - classType = 'ArrayList<' + classType + '>'; - } else { - classType = 'ArrayList'; - } - } - - if (this.isOptional) { - if (!options.hash.removeGenericType) { - classType = 'Optional<' + classType + '>'; - } else { - classType = 'Optional'; - } - } - - if (this.isNullable && options.hash.includeAnnotations) { - classType = '@Nullable ' + classType; - } - } - - return classType; -} - -async function asJniType(type, zclType, cluster, options) -{ - let types = await asJniHelper.call(this, type, zclType, cluster, options); - return types["jniType"]; -} - -async function asJniSignature(type, zclType, cluster, useBoxedTypes, options) -{ - let types = await asJniHelper.call(this, type, zclType, cluster, options); - return useBoxedTypes ? types["jniBoxedSignature"] : types["jniSignature"]; -} - -async function asJniClassName(type, zclType, cluster, options) -{ - let types = await asJniHelper.call(this, type, zclType, cluster, options); - return types["jniClassName"]; -} - -async function asJniHelper(type, zclType, cluster, options) -{ - let pkgId = await templateUtil.ensureZclPackageId(this); - if (zclType == null) { - zclType = await zclHelper.asUnderlyingZclType.call(this, type, options); - } - let isStruct = await zclHelper.isStruct(this.global.db, type, pkgId).then(zclType => zclType != 'unknown'); - - if (this.isOptional) { - const signature = "Ljava/util/Optional;" - return { jniType : "jobject", jniSignature : signature, jniBoxedSignature : signature }; - } - - if (this.isArray) { - const signature = "Ljava/util/ArrayList;" - return { jniType : "jobject", jniSignature : signature, jniBoxedSignature : signature }; - } - - if (StringHelper.isOctetString(type)) { - const signature = "[B"; - return { jniType : "jbyteArray", jniSignature : signature, jniBoxedSignature : signature }; - } - - if (StringHelper.isCharString(type)) { - const signature = "Ljava/lang/String;"; - return { jniType : "jstring", jniSignature : signature, jniBoxedSignature : signature }; - } - - if (isStruct) { - const signature - = `Lchip/devicecontroller/ChipStructs$${appHelper.asUpperCamelCase(cluster)}Cluster${appHelper.asUpperCamelCase(type)};`; - return { jniType : "jobject", jniSignature : signature, jniBoxedSignature : signature }; - } - - let jniBoxedSignature; - try { - jniBoxedSignature = await asJniSignatureBasic.call(this, type, true); - } catch (error) { - jniBoxedSignature = "Ljava/lang/Object;"; - } - let jniSignature; - try { - jniSignature = await asJniSignatureBasic.call(this, type, false); - } catch (error) { - jniSignature = "Ljava/lang/Object;"; - } - // Example: Ljava/lang/Integer; -> java/lang/Integer, needed for JNI class lookup - let jniClassName = jniBoxedSignature.substring(1, jniBoxedSignature.length - 1); - return { - jniType : asJniBasicType(type, true), - jniSignature : jniSignature, - jniBoxedSignature : jniBoxedSignature, - jniClassName : jniClassName - }; -} - -function incrementDepth(depth) -{ - return depth + 1; -} - -// -// Module exports -// -exports.asUnderlyingBasicType = asUnderlyingBasicType; -exports.asJavaType = asJavaType; -exports.asJavaBoxedType = asJavaBoxedType; -exports.asJniType = asJniType; -exports.asJniSignature = asJniSignature; -exports.asJniClassName = asJniClassName; -exports.asJniBasicType = asJniBasicType; -exports.asJniSignatureBasic = asJniSignatureBasic; -exports.convertBasicCTypeToJniType = convertBasicCTypeToJniType; -exports.convertCTypeToJniSignature = convertCTypeToJniSignature; -exports.convertBasicCTypeToJavaBoxedType = convertBasicCTypeToJavaBoxedType; -exports.convertAttributeCallbackTypeToJavaName = convertAttributeCallbackTypeToJavaName; -exports.incrementDepth = incrementDepth; diff --git a/src/controller/java/templates/templates.json b/src/controller/java/templates/templates.json index 7b1521f0865053..d839cc4f211a33 100644 --- a/src/controller/java/templates/templates.json +++ b/src/controller/java/templates/templates.json @@ -2,13 +2,13 @@ "name": "CHIP Android templates", "version": "chip-v1", "helpers": [ - "../../../app/zap-templates/common/ChipTypesHelper.js", - "../../../app/zap-templates/common/ListHelper.js", - "../../../app/zap-templates/common/StringHelper.js", - "../../../app/zap-templates/partials/helper.js", - "../../../app/zap-templates/templates/app/helper.js", - "../../../app/zap-templates/templates/chip/helper.js", - "helper.js" + "common/ChipTypesHelper.js", + "common/ListHelper.js", + "common/StringHelper.js", + "partials/helper.js", + "templates/app/helper.js", + "templates/chip/helper.js", + "controller/java/templates/helper.js" ], "override": "../../../app/zap-templates/common/override.js", "partials": [ diff --git a/src/controller/python/templates/helper.js b/src/controller/python/templates/helper.js deleted file mode 100644 index 874526cab70910..00000000000000 --- a/src/controller/python/templates/helper.js +++ /dev/null @@ -1,74 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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 helpers from zap core -const zapPath = '../../../../third_party/zap/repo/dist/src-electron/'; -const templateUtil = require(zapPath + 'generator/template-util.js') -const zclHelper = require(zapPath + 'generator/helper-zcl.js') - -const ChipTypesHelper = require('../../../../src/app/zap-templates/common/ChipTypesHelper.js'); - -function asPythonType(zclType) -{ - const type = ChipTypesHelper.asBasicType(zclType); - switch (type) { - case 'bool': - return 'bool'; - case 'int8_t': - case 'int16_t': - case 'int32_t': - case 'int64_t': - case 'uint8_t': - case 'uint16_t': - case 'uint32_t': - case 'uint64_t': - return 'int'; - case 'char *': - return 'str'; - case 'uint8_t *': - case 'chip::ByteSpan': - return 'bytes'; - case 'chip::CharSpan': - return 'str'; - } -} - -function asPythonCType(zclType) -{ - const type = ChipTypesHelper.asBasicType(zclType); - switch (type) { - case 'bool': - case 'int8_t': - case 'int16_t': - case 'int32_t': - case 'int64_t': - case 'uint8_t': - case 'uint16_t': - case 'uint32_t': - case 'uint64_t': - return 'c_' + type.replace('_t', ''); - case 'char *': - case 'uint8_t *': - return 'c_char_p'; - } -} - -// -// Module exports -// -exports.asPythonType = asPythonType; -exports.asPythonCType = asPythonCType; diff --git a/src/controller/python/templates/templates.json b/src/controller/python/templates/templates.json index 859c98ad22b619..e5d15198c5aac8 100644 --- a/src/controller/python/templates/templates.json +++ b/src/controller/python/templates/templates.json @@ -2,11 +2,11 @@ "name": "CHIP Python templates", "version": "chip-v1", "helpers": [ - "../../../../src/app/zap-templates/partials/helper.js", - "../../../../src/app/zap-templates/common/StringHelper.js", - "../../../../src/app/zap-templates/templates/app/helper.js", - "../../../../src/app/zap-templates/templates/chip/helper.js", - "helper.js" + "partials/helper.js", + "common/StringHelper.js", + "templates/app/helper.js", + "templates/chip/helper.js", + "controller/python/templates/helper.js" ], "override": "../../../../src/app/zap-templates/common/override.js", "partials": [ diff --git a/src/darwin/Framework/CHIP/templates/helper.js b/src/darwin/Framework/CHIP/templates/helper.js deleted file mode 100644 index d534312729001e..00000000000000 --- a/src/darwin/Framework/CHIP/templates/helper.js +++ /dev/null @@ -1,244 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * 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 helpers from zap core -const zapPath = '../../../../../third_party/zap/repo/dist/src-electron/'; -const string = require(zapPath + 'util/string.js') -const templateUtil = require(zapPath + 'generator/template-util.js') -const zclHelper = require(zapPath + 'generator/helper-zcl.js') - -const ChipTypesHelper = require('../../../../../src/app/zap-templates/common/ChipTypesHelper.js'); -const TestHelper = require('../../../../../src/app/zap-templates/common/ClusterTestGeneration.js'); -const StringHelper = require('../../../../../src/app/zap-templates/common/StringHelper.js'); -const appHelper = require('../../../../../src/app/zap-templates/templates/app/helper.js'); - -function asObjectiveCBasicType(type, options) -{ - if (StringHelper.isOctetString(type)) { - return options.hash.is_mutable ? 'NSMutableData *' : 'NSData *'; - } else if (StringHelper.isCharString(type)) { - return options.hash.is_mutable ? 'NSMutableString *' : 'NSString *'; - } else { - return ChipTypesHelper.asBasicType(this.chipType); - } -} - -/** - * Converts an expression involving possible variables whose types are objective C objects into an expression whose type is a C++ - * type - */ -async function asTypedExpressionFromObjectiveC(value, type) -{ - const valueIsANumber = !isNaN(value); - if (!value || valueIsANumber) { - return appHelper.asTypedLiteral.call(this, value, type); - } - - const tokens = value.split(' '); - if (tokens.length < 2) { - return appHelper.asTypedLiteral.call(this, value, type); - } - - let expr = []; - for (let i = 0; i < tokens.length; i++) { - const token = tokens[i]; - if ([ '+', '-', '/', '*', '%', '(', ')' ].includes(token)) { - expr[i] = token; - } else if (!isNaN(token.replace(/ULL$|UL$|U$|LL$|L$/i, ''))) { - expr[i] = await appHelper.asTypedLiteral.call(this, token, type); - } else { - const variableType = TestHelper.chip_tests_variables_get_type.call(this, token); - const asType = await asObjectiveCNumberType.call(this, token, variableType, true); - expr[i] = `[${token} ${asType}Value]`; - } - } - - return expr.join(' '); -} - -function asObjectiveCNumberType(label, type, asLowerCased) -{ - function fn(pkgId) - { - const options = { 'hash' : {} }; - return zclHelper.asUnderlyingZclType.call(this, type, options) - .then(zclType => { - const basicType = ChipTypesHelper.asBasicType(zclType); - switch (basicType) { - case 'bool': - return 'Bool'; - case 'uint8_t': - return 'UnsignedChar'; - case 'uint16_t': - return 'UnsignedShort'; - case 'uint32_t': - return 'UnsignedInt'; - case 'uint64_t': - return 'UnsignedLongLong'; - case 'int8_t': - return 'Char'; - case 'int16_t': - return 'Short'; - case 'int32_t': - return 'Int'; - case 'int64_t': - return 'LongLong'; - case 'float': - return 'Float'; - case 'double': - return 'Double'; - default: - error = label + ': Unhandled underlying type ' + zclType + ' for original type ' + type; - throw error; - } - }) - .then(typeName => asLowerCased ? (typeName[0].toLowerCase() + typeName.substring(1)) : typeName); - } - - const promise = templateUtil.ensureZclPackageId(this).then(fn.bind(this)).catch(err => console.log(err)); - return templateUtil.templatePromise(this.global, promise) -} - -async function asObjectiveCClass(type, cluster, options) -{ - let pkgId = await templateUtil.ensureZclPackageId(this); - let isStruct = await zclHelper.isStruct(this.global.db, type, pkgId).then(zclType => zclType != 'unknown'); - - if ((this.isArray || this.entryType || options.hash.forceList) && !options.hash.forceNotList) { - return 'NSArray'; - } - - if (StringHelper.isOctetString(type)) { - return 'NSData'; - } - - if (StringHelper.isCharString(type)) { - return 'NSString'; - } - - if (isStruct) { - return `MTR${appHelper.asUpperCamelCase(cluster)}Cluster${appHelper.asUpperCamelCase(type)}`; - } - - return 'NSNumber'; -} - -async function asObjectiveCType(type, cluster, options) -{ - let typeStr = await asObjectiveCClass.call(this, type, cluster, options); - if (this.isNullable || this.isOptional) { - typeStr = `${typeStr} * _Nullable`; - } else { - typeStr = `${typeStr} * _Nonnull`; - } - - return typeStr; -} - -function asStructPropertyName(prop) -{ - prop = appHelper.asLowerCamelCase(prop); - - // If prop is now "description", we need to rename it, because that's - // reserved. - if (prop == "description") { - return "descriptionString"; - } - - // If prop starts with a sequence of capital letters (which can happen for - // output of asLowerCamelCase if the original string started that way, - // lowercase all but the last one. - return prop.replace(/^([A-Z]+)([A-Z])/, (match, p1, p2) => { return p1.toLowerCase() + p2 }); -} - -function asGetterName(prop) -{ - let propName = asStructPropertyName(prop); - if (propName.match(/^new[A-Z]/) || propName == "count") { - return "get" + appHelper.asUpperCamelCase(prop); - } - return propName; -} - -function commandHasRequiredField(command) -{ - return command.arguments.some(arg => !arg.isOptional); -} - -/** - * Produce a reasonable name for an Objective C enum for the given cluster name - * and enum label. Because a lot of our enum labels already have the cluster - * name prefixed (e.g. NetworkCommissioning*, or the IdentifyIdentifyType that - * has it prefixed _twice_) just concatenating the two gives overly verbose - * names in a few cases (e.g. "IdentifyIdentifyIdentifyType"). - * - * This function strips out the redundant cluster names, and strips off trailing - * "Enum" bits on the enum names while we're here. - */ -function objCEnumName(clusterName, enumLabel) -{ - clusterName = appHelper.asUpperCamelCase(clusterName); - enumLabel = appHelper.asUpperCamelCase(enumLabel); - // Some enum names have one or more copies of the cluster name at the - // beginning. - while (enumLabel.startsWith(clusterName)) { - enumLabel = enumLabel.substring(clusterName.length); - } - - if (enumLabel.endsWith("Enum")) { - // Strip that off; it'll clearly be an enum anyway. - enumLabel = enumLabel.substring(0, enumLabel.length - "Enum".length); - } - - return "MTR" + clusterName + enumLabel; -} - -function objCEnumItemLabel(itemLabel) -{ - // Check for the case when we're: - // 1. A single word (that's the regexp at the beginning, which matches the - // word-splitting regexp in string.toCamelCase). - // 2. All upper-case. - // - // This will get converted to lowercase except the first letter by - // asUpperCamelCase, which is not really what we want. - if (!/ |_|-|\//.test(itemLabel) && itemLabel.toUpperCase() == itemLabel) { - return itemLabel.replace(/[\.:]/g, ''); - } - - return appHelper.asUpperCamelCase(itemLabel); -} - -function hasArguments() -{ - return !!this.arguments.length -} - -// -// Module exports -// -exports.asObjectiveCBasicType = asObjectiveCBasicType; -exports.asObjectiveCNumberType = asObjectiveCNumberType; -exports.asObjectiveCClass = asObjectiveCClass; -exports.asObjectiveCType = asObjectiveCType; -exports.asStructPropertyName = asStructPropertyName; -exports.asTypedExpressionFromObjectiveC = asTypedExpressionFromObjectiveC; -exports.asGetterName = asGetterName; -exports.commandHasRequiredField = commandHasRequiredField; -exports.objCEnumName = objCEnumName; -exports.objCEnumItemLabel = objCEnumItemLabel; -exports.hasArguments = hasArguments; diff --git a/src/darwin/Framework/CHIP/templates/templates.json b/src/darwin/Framework/CHIP/templates/templates.json index f91c8c3815bca8..aa441fe8b6756a 100644 --- a/src/darwin/Framework/CHIP/templates/templates.json +++ b/src/darwin/Framework/CHIP/templates/templates.json @@ -2,14 +2,19 @@ "name": "Framework templates", "version": "chip-v1", "helpers": [ - "../../../../../src/app/zap-templates/partials/helper.js", - "../../../../../src/app/zap-templates/common/ChipTypesHelper.js", - "../../../../../src/app/zap-templates/common/StringHelper.js", - "../../../../../src/app/zap-templates/templates/app/helper.js", - "../../../../../src/app/zap-templates/templates/chip/helper.js", - "../../../../../src/app/zap-templates/common/ClusterTestGeneration.js", - "helper.js" + "partials/helper.js", + "common/ChipTypesHelper.js", + "common/StringHelper.js", + "templates/app/helper.js", + "templates/chip/helper.js", + "common/ClusterTestGeneration.js", + "darwin/Framework/CHIP/templates/helper.js" ], + "resources": { + "pics-metafile": "../../../../app/tests/suites/certification/PICS.yaml", + "certification-metadir": "../../../../app/tests/suites/certification", + "test-metadir": "../../../../app/tests/suites" + }, "override": "../../../../../src/app/zap-templates/common/override.js", "partials": [ { diff --git a/third_party/zap/repo b/third_party/zap/repo index 1d4be6d96182fa..a94875d430d199 160000 --- a/third_party/zap/repo +++ b/third_party/zap/repo @@ -1 +1 @@ -Subproject commit 1d4be6d96182fac353107b9ffe8efb35ae060984 +Subproject commit a94875d430d199ece002ab5bd971fdb78305fd4e