From 993d9ef7dc98f33fbae1c244b2ec23154b61615d Mon Sep 17 00:00:00 2001 From: Bryant Austin Date: Fri, 31 Jul 2026 09:34:48 -0600 Subject: [PATCH] Handle tests that provide a full CQL and a named (e.g. the overload-matching test in cql-tests PR #61). --- src/commands/build-cql-command.ts | 6 ++++++ src/models/test-types.ts | 14 +++++++++++++- src/shared/results-shared.ts | 27 ++++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/commands/build-cql-command.ts b/src/commands/build-cql-command.ts index 1210d98..a23a8e4 100644 --- a/src/commands/build-cql-command.ts +++ b/src/commands/build-cql-command.ts @@ -43,6 +43,12 @@ export class BuildCommand { testsName = r.testsName; } + // Library-style tests carry their own complete CQL library and are evaluated inline + // (via the $cql `content` parameter), so they are not wrapped as a define here. + if (r.library !== undefined) { + continue; + } + if (r.invalid !== 'semantic') { const defineVal = `define "${r.groupName}.${r.testName}": ${r.expression}`; const key = `${r.testsName}-${r.groupName}-${r.testName}`; diff --git a/src/models/test-types.ts b/src/models/test-types.ts index d5b907b..8c9fc74 100644 --- a/src/models/test-types.ts +++ b/src/models/test-types.ts @@ -3,8 +3,15 @@ export interface TestExpression { invalid: 'false' | 'true' | 'semantic'; } +export interface TestLibrary { + text: string; + invalid: 'false' | 'true' | 'semantic'; +} + export interface TestOutput { text: string; + // For library-style tests, the name of the define whose result this output describes. + name?: string; type?: | 'boolean' | 'code' @@ -29,7 +36,9 @@ export interface Test { mode?: 'strict' | 'loose'; ordered?: boolean; checkOrderedFunctions?: boolean; - expression: string | TestExpression; + // A test provides EITHER an expression OR a full CQL library (mutually exclusive; see testSchema.xsd). + expression?: string | TestExpression; + library?: string | TestLibrary; capability: CapabilityKV[]; output?: string | TestOutput | string[] | TestOutput[]; } @@ -79,6 +88,9 @@ export interface InternalTestResult { testVersionTo?: string; invalid?: 'false' | 'true' | 'semantic' | 'undefined'; expression: string; + // For library-style tests: the full CQL library source that is evaluated inline. + // (For these tests, `expression` holds the name of the define whose result is compared.) + library?: string; capability?: CapabilityKV[]; SkipMessage?: string; } diff --git a/src/shared/results-shared.ts b/src/shared/results-shared.ts index b910d55..0ffc9a5 100644 --- a/src/shared/results-shared.ts +++ b/src/shared/results-shared.ts @@ -19,6 +19,7 @@ export class Result implements InternalTestResult { testVersionTo?: string; invalid: 'false' | 'true' | 'semantic' | 'undefined'; expression: string; + library?: string; capability: CapabilityKV[] = []; constructor(testsName: string, groupName: string, test: Test) { @@ -28,7 +29,23 @@ export class Result implements InternalTestResult { this.testVersion = test.version; this.testVersionTo = test.versionTo; - if (typeof test.expression !== 'string') { + if (test.library !== undefined) { + // Library-style test: the whole CQL library is evaluated inline. The value sent as + // `expression` is the name of the define to evaluate, taken from the output's `name` + // attribute (defaults to 'output'). + if (typeof test.library === 'string') { + this.invalid = 'false'; + this.library = test.library; + } else { + this.invalid = test.library.invalid; + this.library = test.library.text; + } + const out = test.output; + this.expression = + out !== undefined && typeof out !== 'string' && !Array.isArray(out) && out.name + ? out.name + : 'output'; + } else if (typeof test.expression !== 'string') { if (test.expression === undefined) { this.invalid = 'undefined'; this.expression = 'undefined'; @@ -117,6 +134,14 @@ export function generateParametersResource( }, ], }; + // Library-style tests: pass the full CQL library inline via the `content` parameter. + // `expression` then names the define within that library to evaluate. + if (result.library !== undefined) { + data.parameter!.push({ + name: 'content', + valueString: result.library, + }); + } } else if (cqlEndpoint === '$evaluate') { data = { resourceType: 'Parameters',