diff --git a/sof-js/src/index.js b/sof-js/src/index.js index 8c5772e..0b8106e 100644 --- a/sof-js/src/index.js +++ b/sof-js/src/index.js @@ -113,7 +113,9 @@ function select(select_expr, node, def) { assert(select_expr.select, 'select') if(select_expr.where) { let include = select_expr.where.every((w)=>{ - return fhirpath_evaluate(node, w.path, def.constant)[0] + const val = fhirpath_evaluate(node, w.path, def.constant)[0] + assert(typeof val === "boolean", "'where' expression path should return 'boolean'") + return val }) if(!include) { return []} } diff --git a/sof-js/tests/1_basic.test.js b/sof-js/tests/1_basic.test.js index e5e643d..2745369 100644 --- a/sof-js/tests/1_basic.test.js +++ b/sof-js/tests/1_basic.test.js @@ -153,7 +153,7 @@ describe("basics", () => { resource: 'Patient', status: 'active', select: [{column: [{name: 'id', path: 'id'}]}], - where: [{path: 'active = true'}] + where: [{path: 'active.exists() and active = true'}] }, expect: [{id: 'pt1'}] }) @@ -164,13 +164,13 @@ describe("basics", () => { resource: 'Patient', status: 'active', select: [{column: [{name: 'id', path: 'id'}]}], - where: [{path: 'active = false'}] + where: [{path: 'active.exists() and active = false'}] }, expect: [{id: 'pt2'}] }) - add_test({ - title: 'where as element', + add_throwing_test({ + title: 'where returns non-boolean for some cases', view: { resource: 'Patient', status: 'active', @@ -186,7 +186,7 @@ describe("basics", () => { resource: 'Patient', status: 'active', select: [{column: [{name: 'id', path: 'id'}]}], - where: [{path: "name.family = 'F2'"}] + where: [{path: "name.family.exists() and name.family = 'F2'"}] }, expect: [{id: 'pt2'}] }) @@ -197,7 +197,7 @@ describe("basics", () => { resource: 'Patient', status: 'active', select: [{column: [{name: 'id', path: 'id'}]}], - where: [{path: "name.family = 'F1'"}] + where: [{path: "name.family.exists() and name.family = 'F1'"}] }, expect: [{id: 'pt1'}] }) diff --git a/sof-js/tests/5_constants.test.js b/sof-js/tests/5_constants.test.js index 9d1237c..9a4d847 100644 --- a/sof-js/tests/5_constants.test.js +++ b/sof-js/tests/5_constants.test.js @@ -94,7 +94,7 @@ describe("constant", () => { column: [{ name: "id", path: "id" }] } ], - where: [{ path: "name.where(use = %name_use)" }] + where: [{ path: "name.where(use = %name_use).exists()" }] }, expect: [{ id: "pt1" }] }); @@ -168,7 +168,7 @@ describe("constant", () => { column: [{ name: "id", path: "id" }] } ], - where: [{ path: "deceased.ofType(boolean) = %is_deceased" }] + where: [{ path: "deceased.ofType(boolean).exists() and deceased.ofType(boolean) = %is_deceased" }] }, expect: [{ id: "pt2" }] }); diff --git a/sof-js/tests/validation.test.js b/sof-js/tests/validation.test.js index 41fe22e..5d7b299 100644 --- a/sof-js/tests/validation.test.js +++ b/sof-js/tests/validation.test.js @@ -1,10 +1,13 @@ import { describe } from "bun:test"; -import { start_case, end_case, invalid_view, debug } from './test_helpers.js' +import { start_case, end_case, invalid_view, debug, add_throwing_test } from './test_helpers.js' let resources = [ { resourceType: 'Patient', + name: [ + { family: 'F1.1' }, + ], id: 'pt1' }, { diff --git a/tests/basic.json b/tests/basic.json index caf877c..866093a 100644 --- a/tests/basic.json +++ b/tests/basic.json @@ -182,7 +182,7 @@ ], "where": [ { - "path": "active = true" + "path": "active.exists() and active = true" } ] }, @@ -209,7 +209,7 @@ ], "where": [ { - "path": "active = false" + "path": "active.exists() and active = false" } ] }, @@ -220,7 +220,7 @@ ] }, { - "title": "where as element", + "title": "where returns non-boolean for some cases", "view": { "resource": "Patient", "status": "active", @@ -263,7 +263,7 @@ ], "where": [ { - "path": "name.family = 'F2'" + "path": "name.family.exists() and name.family = 'F2'" } ] }, @@ -290,7 +290,7 @@ ], "where": [ { - "path": "name.family = 'F1'" + "path": "name.family.exists() and name.family = 'F1'" } ] }, diff --git a/tests/constant.json b/tests/constant.json index ef19fce..bc16729 100644 --- a/tests/constant.json +++ b/tests/constant.json @@ -122,7 +122,7 @@ ], "where": [ { - "path": "name.where(use = %name_use)" + "path": "name.where(use = %name_use).exists()" } ] }, @@ -244,7 +244,7 @@ ], "where": [ { - "path": "deceased.ofType(boolean) = %is_deceased" + "path": "deceased.ofType(boolean).exists() and deceased.ofType(boolean) = %is_deceased" } ] }, diff --git a/tests/validate.json b/tests/validate.json index 141523c..f4030fa 100644 --- a/tests/validate.json +++ b/tests/validate.json @@ -4,6 +4,11 @@ "resources": [ { "resourceType": "Patient", + "name": [ + { + "family": "F1.1" + } + ], "id": "pt1" }, { @@ -15,7 +20,7 @@ { "title": "empty", "view": {}, - "error": "structure" + "expectError": true }, { "title": "wrong fhirpath", @@ -28,10 +33,10 @@ } ] }, - "error": "fhirpath" + "expectError": true }, { - "title": "wrong type", + "title": "wrong type in forEach", "view": { "resource": "Patient", "status": "active", @@ -41,7 +46,30 @@ } ] }, - "error": "structure" + "expectError": true + }, + { + "title": "where with path resolving to not boolean", + "view": { + "resource": "Patient", + "status": "active", + "select": [ + { + "column": [ + { + "name": "id", + "path": "id" + } + ] + } + ], + "where": [ + { + "path": "name.family" + } + ] + }, + "expectError": true } ] }