Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[YAML] Add contains/excludes constraints to TestConstraints.yaml #19042

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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}}
vivien-apple marked this conversation as resolved.
Show resolved Hide resolved
{{#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
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;
vivien-apple marked this conversation as resolved.
Show resolved Hide resolved
}
};
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