diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 053b51d..566a674 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -21,6 +21,9 @@ jobs: - name: Check formatting working-directory: sof-js run: bun run check-fmt + - name: Validate JSON tests + working-directory: sof-js + run: bun run validate - name: Run tests working-directory: sof-js run: bun test diff --git a/sof-js/package.json b/sof-js/package.json index dcae61b..8b37528 100644 --- a/sof-js/package.json +++ b/sof-js/package.json @@ -6,7 +6,8 @@ "type": "module", "scripts": { "fmt": "prettier -w ../tests", - "check-fmt": "prettier -c ../tests" + "check-fmt": "prettier -c ../tests", + "validate": "ajv -s ../tests.schema.json -d \"../tests/*.json\"" }, "author": "niquola,jmandel", "license": "ISC", diff --git a/sof-js/tests/validation.test.js b/sof-js/tests/validation.test.js index 5d7b299..1f6a810 100644 --- a/sof-js/tests/validation.test.js +++ b/sof-js/tests/validation.test.js @@ -1,61 +1,65 @@ -import { describe } from "bun:test"; -import { start_case, end_case, invalid_view, debug, add_throwing_test } from './test_helpers.js' - +import { describe } from 'bun:test' +import { add_throwing_test, end_case, invalid_view, start_case } from './test_helpers.js' let resources = [ { resourceType: 'Patient', - name: [ - { family: 'F1.1' }, - ], - id: 'pt1' + name: [{ family: 'F1.1' }], + id: 'pt1', }, { resourceType: 'Patient', - id: 'pt2' + id: 'pt2', }, ] start_case('validate', 'TBD', resources) -describe("validate", () => { - +describe('validate', () => { invalid_view({ title: 'empty', view: {}, - expectError: true - }); + expectError: true, + }) + + invalid_view({ + title: 'missing resource', + view: { + select: [{ column: [{ name: 'id', path: 'id' }] }], + }, + expectError: true, + }) invalid_view({ title: 'wrong fhirpath', view: { resource: 'Patient', status: 'active', - select: [{forEach: '@@'}] + select: [{ forEach: '@@' }], }, - expectError: true - }); + expectError: true, + }) invalid_view({ title: 'wrong type in forEach', view: { resource: 'Patient', status: 'active', - select: [{forEach: 1}] + select: [{ forEach: 1 }], }, - expectError: true - }); + expectError: true, + }) add_throwing_test({ title: 'where with path resolving to not boolean', view: { resource: 'Patient', status: 'active', - select: [{column: [{name: 'id', path: 'id'}]}], - where: [{path: "name.family"}] + select: [{ column: [{ name: 'id', path: 'id' }] }], + where: [{ path: 'name.family' }], }, - expectError: true - }); + expectError: true, + }) end_case() -}); +}) diff --git a/tests.schema.json b/tests.schema.json new file mode 100644 index 0000000..4549bf8 --- /dev/null +++ b/tests.schema.json @@ -0,0 +1,109 @@ +{ + "$id": "http://hl7.org/fhir/uv/sql-on-fhir/tests", + "title": "SQL on FHIR tests schema", + "description": "Standard format for JSON test definitions used to validate SQL on FHIR view runner implementations.", + "type": "object", + "required": [ + "title", + "resources", + "tests" + ], + "properties": { + "title": { + "type": "string", + "description": "The name of the test suite." + }, + "description": { + "type": "string", + "description": "A description of the test suite." + }, + "allowExtendedFhirpath": { + "type": "boolean", + "description": "If true, the test runner should allow the use of FHIRPath functions outside of the restricted subset defined in the specification." + }, + "authors": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The authors of the test suite." + }, + "generated": { + "type": "boolean", + "description": "If true, the test suite was generated by a tool and should not be edited directly." + }, + "resources": { + "type": "array", + "items": { + "type": "object" + }, + "description": "A list of FHIR resources that are used in the tests. There can be multiple different resource types in the list. Each should be a valid FHIR resource." + }, + "tests": { + "type": "array", + "description": "A list of tests to run against the view.", + "minItems": 1, + "items": { + "type": "object", + "required": [ + "title", + "view" + ], + "oneOf": [ + { + "required": [ + "expect" + ] + }, + { + "required": [ + "expectCount" + ] + }, + { + "required": [ + "expectError" + ] + } + ], + "properties": { + "title": { + "type": "string", + "description": "The name of the test." + }, + "description": { + "type": "string", + "description": "A description of the test." + }, + "view": { + "type": "object", + "description": "The view to run the test against." + }, + "expect": { + "type": "array", + "description": "The expected result of the test. Each object within the array represents a row in the result set, with column names as keys.", + "items": { + "type": "object" + } + }, + "expectCount": { + "type": "number", + "description": "The expected number of rows in the result." + }, + "expectError": { + "type": "boolean", + "description": "If true, the test is expected to throw an error." + }, + "expectColumns": { + "type": "array", + "description": "The expected columns in the result set.", + "items": { + "type": "string" + }, + "minItems": 1 + } + } + } + } + } +} diff --git a/tests/validate.json b/tests/validate.json index f4030fa..e8af79f 100644 --- a/tests/validate.json +++ b/tests/validate.json @@ -22,6 +22,22 @@ "view": {}, "expectError": true }, + { + "title": "missing resource", + "view": { + "select": [ + { + "column": [ + { + "name": "id", + "path": "id" + } + ] + } + ] + }, + "expectError": true + }, { "title": "wrong fhirpath", "view": {