diff --git a/src/did/+did/query.m b/src/did/+did/query.m index 0da67bf..22cde46 100644 --- a/src/did/+did/query.m +++ b/src/did/+did/query.m @@ -113,8 +113,13 @@ query_struct = did.datastructures.emptystruct('field','operation','param1','param2'); elseif nargin == 1 if isstruct(field) - % check arguments - if ~did.datastructures.eqlen(sort(fieldnames(field)),sort({'field','operation','param1','param2'})) + % Validate fieldnames against the expected set. + % fieldnames() returns a 4x1 cell, so build the + % literal as a column too — did.datastructures.eqlen + % checks shape strictly, and a 1x4 vs 4x1 mismatch + % otherwise rejects every well-formed struct input. + if ~did.datastructures.eqlen(sort(fieldnames(field)), ... + sort({'field';'operation';'param1';'param2'})) error('Field names of search structure do not match expected fields.'); end query_struct = field; diff --git a/tests/+did/+unittest/test_query.m b/tests/+did/+unittest/test_query.m index c5ee84c..e0a9073 100644 --- a/tests/+did/+unittest/test_query.m +++ b/tests/+did/+unittest/test_query.m @@ -40,5 +40,27 @@ function test_or_query(testCase) testCase.verifyEqual(q_or.searchstructure.param2(1).operation, 'greaterthan'); testCase.verifyEqual(q_or.searchstructure.param2(1).param1, 30); end + + function test_struct_input_accepted(testCase) + % did.query accepts a pre-built searchstructure as a + % one-arg input. Regression test for the shape-strict + % eqlen check that previously rejected every struct + % input because sort(fieldnames(...)) returns a 4x1 + % cell and the validator compared it against a 1x4 + % cell literal. + ss = struct('field', 'base.name', 'operation', 'exact_string', ... + 'param1', 'myname', 'param2', ''); + q = did.query(ss); + testCase.verifyEqual(q.searchstructure.field, 'base.name'); + testCase.verifyEqual(q.searchstructure.operation, 'exact_string'); + testCase.verifyEqual(q.searchstructure.param1, 'myname'); + end + + function test_struct_input_rejects_unknown_fields(testCase) + % The shape fix must NOT loosen the field-set check. + ss = struct('field', 'base.name', 'operation', 'exact_string', ... + 'param1', 'myname', 'extra', 'X'); + testCase.verifyError(@() did.query(ss), ''); + end end end