Skip to content

Commit

Permalink
[YAML] Add contains/excludes constraints to TestConstraints.yaml (#19042
Browse files Browse the repository at this point in the history
)

* Add contains/excludes constraints to TestConstraints.yaml

* Add support for contains/excludes to chip-tool for simple list

* Add support for contains/excludes to darwin-framework-tool for simple list

* Update chip-tool generated content

* Update darwin-framework-tool generated content
  • Loading branch information
vivien-apple authored Jun 3, 2022
1 parent 8dabae0 commit fd5e78d
Show file tree
Hide file tree
Showing 10 changed files with 503 additions and 159 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@

{{~#if (hasProperty expectedConstraints "maxValue")}}VerifyOrReturn(CheckConstraintMaxValue("{{asPropertyValue}}", {{asPropertyValue}}, {{asTypedLiteral expectedConstraints.maxValue type}}));{{/if}}

{{~#if (hasProperty expectedConstraints "contains")}}
{{#chip_tests_iterate_expected_list expectedConstraints.contains}}
VerifyOrReturn(CheckConstraintContains("{{asPropertyValue}}", {{asPropertyValue}}, {{asTypedLiteral value type}}));
{{/chip_tests_iterate_expected_list}}
{{/if}}

{{~#if (hasProperty expectedConstraints "excludes")}}
{{#chip_tests_iterate_expected_list expectedConstraints.excludes}}
VerifyOrReturn(CheckConstraintExcludes("{{asPropertyValue}}", {{asPropertyValue}}, {{asTypedLiteral value type}}));
{{/chip_tests_iterate_expected_list}}
{{/if}}

{{~#if (hasProperty expectedConstraints "notValue")}}
{{#if (isLiteralNull expectedConstraints.notValue)}}
VerifyOrReturn(CheckValueNonNull("{{asPropertyValue}}", {{asPropertyValue}}));
Expand Down
25 changes: 25 additions & 0 deletions examples/darwin-framework-tool/commands/tests/TestCommandBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,31 @@ class TestCommandBridge : public CHIPCommandBridge,
return ConstraintsChecker::CheckConstraintNotValue(itemName, currentValue, expectedValue);
}

template <typename T> bool CheckConstraintContains(const char * _Nonnull itemName, const NSArray * _Nonnull current, T expected)
{
for (id currentElement in current) {
if ([currentElement isEqualToNumber:@(expected)]) {
return true;
}
}

Exit(std::string(itemName) + " expect the value " + std::to_string(expected) + " but the list does not contains it.");
return false;
}

template <typename T> bool CheckConstraintExcludes(const char * _Nonnull itemName, const NSArray * _Nonnull current, T expected)
{
for (id currentElement in current) {
if ([currentElement isEqualToNumber:@(expected)]) {
Exit(std::string(itemName) + " does not expect the value " + std::to_string(expected)
+ " but the list contains it.");
return false;
}
}

return true;
}

bool CheckConstraintNotValue(const char * _Nonnull itemName, const NSData * _Nonnull current, const NSData * _Nonnull expected)
{
const chip::ByteSpan currentValue(static_cast<const uint8_t *>([current bytes]), [current length]);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{{#if hasExpectedConstraints}}
{{~#*inline "item"}}{{asLowerCamelCase name}}{{/inline}}
{{#if (hasProperty expectedConstraints "type")}}VerifyOrReturn(CheckConstraintType("{{>item}}", "", "{{expectedConstraints.type}}"));{{/if}}

{{~#if (hasProperty expectedConstraints "format")}}VerifyOrReturn(CheckConstraintFormat("{{>item}}", "", "{{expectedConstraints.format}}"));{{/if}}

{{~#if (hasProperty expectedConstraints "startsWith")}}VerifyOrReturn(CheckConstraintStartsWith("{{>item}}", {{>actualValue}}, "{{expectedConstraints.startsWith}}"));{{/if}}

{{~#if (hasProperty expectedConstraints "endsWith")}}VerifyOrReturn(CheckConstraintEndsWith("{{>item}}", {{>actualValue}}, "{{expectedConstraints.endsWith}}"));{{/if}}

{{~#if (hasProperty expectedConstraints "isUpperCase")}}VerifyOrReturn(CheckConstraintIsUpperCase("{{>item}}", {{>actualValue}}, {{expectedConstraints.isUpperCase}}));{{/if}}

{{~#if (hasProperty expectedConstraints "isLowerCase")}}VerifyOrReturn(CheckConstraintIsLowerCase("{{>item}}", {{>actualValue}}, {{expectedConstraints.isLowerCase}}));{{/if}}

{{~#if (hasProperty expectedConstraints "isHexString")}}VerifyOrReturn(CheckConstraintIsHexString("{{>item}}", {{>actualValue}}, {{expectedConstraints.isHexString}}));{{/if}}

{{~#if (hasProperty expectedConstraints "minLength")}}VerifyOrReturn(CheckConstraintMinLength("{{>item}}", [{{>actualValue}} length], {{expectedConstraints.minLength}}));{{/if}}

{{~#if (hasProperty expectedConstraints "maxLength")}}VerifyOrReturn(CheckConstraintMaxLength("{{>item}}", [{{>actualValue}} length], {{expectedConstraints.maxLength}}));{{/if}}

{{~#if (hasProperty expectedConstraints "minValue")}}
if ({{>actualValue}} != nil)
{
VerifyOrReturn(CheckConstraintMinValue<{{chipType}}>("{{>item}}", [{{>actualValue}} {{asObjectiveCNumberType "" type true}}Value], {{asTypedLiteral expectedConstraints.minValue type}}));
}
{{/if}}

{{~#if (hasProperty expectedConstraints "maxValue")}}
if ({{>actualValue}} != nil)
{
VerifyOrReturn(CheckConstraintMaxValue<{{chipType}}>("{{>item}}", [{{>actualValue}} {{asObjectiveCNumberType "" type true}}Value], {{asTypedLiteral expectedConstraints.maxValue type}}));
}
{{/if}}

{{~#if (hasProperty expectedConstraints "contains")}}
if ({{>actualValue}} != nil)
{
{{#chip_tests_iterate_expected_list expectedConstraints.contains}}
VerifyOrReturn(CheckConstraintContains("{{asLowerCamelCase name}}", {{>actualValue}}, {{asTypedLiteral value type}}));
{{/chip_tests_iterate_expected_list}}
}
{{/if}}

{{~#if (hasProperty expectedConstraints "excludes")}}
if ({{>actualValue}} != nil)
{
{{#chip_tests_iterate_expected_list expectedConstraints.excludes}}
VerifyOrReturn(CheckConstraintExcludes("{{asLowerCamelCase name}}", {{>actualValue}}, {{asTypedLiteral value type}}));
{{/chip_tests_iterate_expected_list}}
}
{{/if}}

{{~#if (hasProperty expectedConstraints "notValue")}}
{{#if (isLiteralNull expectedConstraints.notValue)}}
VerifyOrReturn(CheckValueNonNull("{{>item}}", {{>actualValue}}));
{{else}}
if ({{>actualValue}} != nil)
{
{{#if (isString type)}}
VerifyOrReturn(CheckConstraintNotValue("{{>item}}", {{>actualValue}}, {{asTypedLiteral expectedConstraints.notValue type}}));
{{else}}
VerifyOrReturn(CheckConstraintNotValue("{{>item}}", {{>actualValue}}, {{asTypedLiteral expectedConstraints.notValue type}}));
{{/if}}
}
{{/if}}
{{/if}}
{{/if}}
Original file line number Diff line number Diff line change
Expand Up @@ -209,47 +209,13 @@ class {{filename}}: public TestCommandBridge
{{>check_test_value actual="actualValue" expected=expectedValue cluster=../cluster}}
}
{{/if}}
{{#if hasExpectedConstraints}}
{{~#*inline "item"}}{{asLowerCamelCase name}}{{/inline}}
{{#if (hasProperty expectedConstraints "type")}}VerifyOrReturn(CheckConstraintType("{{>item}}", "", "{{expectedConstraints.type}}"));{{/if}}
{{~#if (hasProperty expectedConstraints "format")}}VerifyOrReturn(CheckConstraintFormat("{{>item}}", "", "{{expectedConstraints.format}}"));{{/if}}
{{~#if (hasProperty expectedConstraints "startsWith")}}VerifyOrReturn(CheckConstraintStartsWith("{{>item}}", {{>actualValue}}, "{{expectedConstraints.startsWith}}"));{{/if}}
{{~#if (hasProperty expectedConstraints "endsWith")}}VerifyOrReturn(CheckConstraintEndsWith("{{>item}}", {{>actualValue}}, "{{expectedConstraints.endsWith}}"));{{/if}}
{{~#if (hasProperty expectedConstraints "isUpperCase")}}VerifyOrReturn(CheckConstraintIsUpperCase("{{>item}}", {{>actualValue}}, {{expectedConstraints.isUpperCase}}));{{/if}}
{{~#if (hasProperty expectedConstraints "isLowerCase")}}VerifyOrReturn(CheckConstraintIsLowerCase("{{>item}}", {{>actualValue}}, {{expectedConstraints.isLowerCase}}));{{/if}}
{{~#if (hasProperty expectedConstraints "isHexString")}}VerifyOrReturn(CheckConstraintIsHexString("{{>item}}", {{>actualValue}}, {{expectedConstraints.isHexString}}));{{/if}}
{{~#if (hasProperty expectedConstraints "minLength")}}VerifyOrReturn(CheckConstraintMinLength("{{>item}}", [{{>actualValue}} length], {{expectedConstraints.minLength}}));{{/if}}
{{~#if (hasProperty expectedConstraints "maxLength")}}VerifyOrReturn(CheckConstraintMaxLength("{{>item}}", [{{>actualValue}} length], {{expectedConstraints.maxLength}}));{{/if}}
{{~#if (hasProperty expectedConstraints "minValue")}}
if ({{>actualValue}} != nil) {
VerifyOrReturn(CheckConstraintMinValue<{{chipType}}>("{{>item}}", [{{>actualValue}} {{asObjectiveCNumberType "" type true}}Value], {{asTypedLiteral expectedConstraints.minValue type}}));
}
{{/if}}
{{~#if (hasProperty expectedConstraints "maxValue")}}
if ({{>actualValue}} != nil) {
VerifyOrReturn(CheckConstraintMaxValue<{{chipType}}>("{{>item}}", [{{>actualValue}} {{asObjectiveCNumberType "" type true}}Value], {{asTypedLiteral expectedConstraints.maxValue type}}));
}
{{/if}}
{{~#if (hasProperty expectedConstraints "notValue")}}
{{#if (isLiteralNull expectedConstraints.notValue)}}
VerifyOrReturn(CheckValueNonNull("{{>item}}", {{>actualValue}}));
{{else}}
if ({{>actualValue}} != nil) {
{{#if (isString type)}}
VerifyOrReturn(CheckConstraintNotValue("{{>item}}", {{>actualValue}}, {{asTypedLiteral expectedConstraints.notValue type}}));
{{else}}
VerifyOrReturn(CheckConstraintNotValue("{{>item}}", {{>actualValue}}, {{asTypedLiteral expectedConstraints.notValue type}}));
{{/if}}
}
{{/if}}
{{>maybeCheckExpectedConstraints}}
{{#if saveAs}}
{
{{saveAs}} = {{>actualValue}};
}
{{/if}}
{{/if}}
{{#if saveAs}}
{
{{saveAs}} = {{>actualValue}};
}
{{/if}}
{{/chip_tests_item_response_parameters}}
{{/chip_tests_item_response_parameters}}

{{#unless async}}
NextTest();
Expand Down
4 changes: 4 additions & 0 deletions examples/darwin-framework-tool/templates/tests/templates.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@
{
"name": "check_test_value",
"path": "partials/check_test_value.zapt"
},
{
"name": "maybeCheckExpectedConstraints",
"path": "partials/checks/maybeCheckExpectedConstraints.zapt"
}
],
"templates": [
Expand Down
30 changes: 30 additions & 0 deletions src/app/tests/suites/TestConstraints.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,36 @@ tests:
- name: "nodeId"
value: nodeId

# Tests for List of INT8U attribute
- label: "Write attribute LIST With List of INT8U"
command: "writeAttribute"
attribute: "list_int8u"
arguments:
value: [1, 2, 3, 4]

- label:
"Read attribute LIST With Partial List of INT8U that should be in it"
command: "readAttribute"
attribute: "list_int8u"
response:
constraints:
contains: [2, 3, 4]

- label:
"Read attribute LIST With Partial List of INT8U that should not be
included"
command: "readAttribute"
attribute: "list_int8u"
response:
constraints:
excludes: [0, 5]

- label: "Write attribute LIST Back to Default Value"
command: "writeAttribute"
attribute: "list_int8u"
arguments:
value: []

# Tests for INT32U attribute

- label: "Write attribute INT32U Value"
Expand Down
42 changes: 42 additions & 0 deletions src/app/tests/suites/include/ConstraintsChecker.h
Original file line number Diff line number Diff line change
Expand Up @@ -419,4 +419,46 @@ class ConstraintsChecker
}
return false;
}

template <typename T, typename U>
bool CheckConstraintContains(const char * itemName, const chip::app::DataModel::DecodableList<T> & current, const U & expected)
{
auto iterValue = current.begin();
while (iterValue.Next())
{
auto currentValue = iterValue.GetValue();
if (currentValue == expected)
{
return true;
}
}

Exit(std::string(itemName) + " expect the value " + std::to_string(expected) + " but the list does not contains it.");
return false;
}

template <typename T, typename U>
bool CheckConstraintExcludes(const char * itemName, const chip::app::DataModel::DecodableList<T> & current, const U & expected)
{
auto iterValue = current.begin();
while (iterValue.Next())
{
auto currentValue = iterValue.GetValue();
if (currentValue == expected)
{
Exit(std::string(itemName) + " does not expect the value " + std::to_string(expected) +
" but the list contains it.");
return false;
}
}

CHIP_ERROR err = iterValue.GetStatus();
if (CHIP_NO_ERROR != err)
{
Exit(std::string(chip::ErrorStr(err)));
return false;
}

return true;
}
};
13 changes: 13 additions & 0 deletions src/app/zap-templates/common/ClusterTestGeneration.js
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,18 @@ async function chip_tests_only_cluster_response_parameters(options)
return asBlocks.call(this, Promise.resolve(this.arguments), options);
}

function chip_tests_iterate_expected_list(values, options)
{
values = values.map(value => {
return {
global: this.global, parent: this.parent, name: this.name, type: this.type, isArray: this.isArray,
isNullable: this.isNullable, value: value,
}
});

return asBlocks.call(this, Promise.resolve(values), options);
}

//
// Module exports
//
Expand Down Expand Up @@ -1028,3 +1040,4 @@ exports.chip_tests_only_cluster_response_parameters = chip_tests_only_cluster_re
exports.isHexString = isHexString;
exports.octetStringLengthFromHexString = octetStringLengthFromHexString;
exports.octetStringFromHexString = octetStringFromHexString;
exports.chip_tests_iterate_expected_list = chip_tests_iterate_expected_list;
Loading

0 comments on commit fd5e78d

Please sign in to comment.