From cfdd1f93803ecffdb7c4f7aab619bc927f1db3a3 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Mon, 9 Sep 2024 17:48:46 +0800 Subject: [PATCH] Update SQL-On-FHIR implementation for latest cases, and clone test cases to general test care repository --- .../r5/renderers/utils/RenderingContext.java | 3 + .../org/hl7/fhir/r5/utils/sql/Runner.java | 65 ++++++--- .../hl7/fhir/r5/utils/sql/StorageJson.java | 17 +-- .../org/hl7/fhir/r5/utils/sql/Validator.java | 131 ++++++++++++------ .../org/hl7/fhir/r5/sql/SQLOnFhirTests.java | 29 ++-- 5 files changed, 157 insertions(+), 88 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/utils/RenderingContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/utils/RenderingContext.java index 572523a1e..687d7c672 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/utils/RenderingContext.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/utils/RenderingContext.java @@ -554,6 +554,9 @@ public class RenderingContext extends RenderingI18nContext { } public String fixReference(String ref) { + if (ref == null) { + return null; + } if (!Utilities.isAbsoluteUrl(ref)) { return (localPrefix == null ? "" : localPrefix)+ref; } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/sql/Runner.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/sql/Runner.java index 432fff492..aa5d8b4e1 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/sql/Runner.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/sql/Runner.java @@ -103,7 +103,7 @@ public class Runner implements IEvaluationContext { for (JsonObject w : vd.getJsonObjects("where")) { String expr = w.asString("path"); ExpressionNode node = fpe.parse(expr); - boolean pass = fpe.evaluateToBoolean(null, b, b, b, node); + boolean pass = fpe.evaluateToBoolean(vd, b, b, b, node); if (!pass) { ok = false; break; @@ -114,7 +114,7 @@ public class Runner implements IEvaluationContext { rows.add(new ArrayList()); for (JsonObject select : vd.getJsonObjects("select")) { - executeSelect(select, b, rows); + executeSelect(vd, select, b, rows); } for (List row : rows) { storage.addRow(store, row); @@ -124,14 +124,14 @@ public class Runner implements IEvaluationContext { storage.finish(store); } - private void executeSelect(JsonObject select, Base b, List> rows) { + private void executeSelect(JsonObject vd, JsonObject select, Base b, List> rows) { List focus = new ArrayList<>(); if (select.has("forEach")) { - focus.addAll(executeForEach(select, b)); + focus.addAll(executeForEach(vd, select, b)); } else if (select.has("forEachOrNull")) { - focus.addAll(executeForEachOrNull(select, b)); + focus.addAll(executeForEachOrNull(vd, select, b)); if (focus.isEmpty()) { List columns = (List) select.getUserData("columns"); for (List row : rows) { @@ -159,20 +159,20 @@ public class Runner implements IEvaluationContext { List> rowsToAdd = cloneRows(tempRows); for (JsonObject column : select.getJsonObjects("column")) { - executeColumn(column, f, rowsToAdd); + executeColumn(vd, column, f, rowsToAdd); } for (JsonObject sub : select.getJsonObjects("select")) { - executeSelect(sub, f, rowsToAdd); + executeSelect(vd, sub, f, rowsToAdd); } - executeUnionAll(select.getJsonObjects("unionAll"), f, rowsToAdd); + executeUnionAll(vd, select.getJsonObjects("unionAll"), f, rowsToAdd); rows.addAll(rowsToAdd); } } - private void executeUnionAll(List unionList, Base b, List> rows) { + private void executeUnionAll(JsonObject vd, List unionList, Base b, List> rows) { if (unionList.isEmpty()) { return; } @@ -183,7 +183,7 @@ public class Runner implements IEvaluationContext { for (JsonObject union : unionList) { List> tempRows = new ArrayList<>(); tempRows.addAll(sourceRows); - executeSelect(union, b, tempRows); + executeSelect(vd, union, b, tempRows); rows.addAll(tempRows); } } @@ -204,25 +204,25 @@ public class Runner implements IEvaluationContext { return list; } - private List executeForEach(JsonObject focus, Base b) { + private List executeForEach(JsonObject vd, JsonObject focus, Base b) { ExpressionNode n = (ExpressionNode) focus.getUserData("forEach"); List result = new ArrayList<>(); - result.addAll(fpe.evaluate(b, n)); + result.addAll(fpe.evaluate(vd, b, n)); return result; } - private List executeForEachOrNull(JsonObject focus, Base b) { + private List executeForEachOrNull(JsonObject vd, JsonObject focus, Base b) { ExpressionNode n = (ExpressionNode) focus.getUserData("forEachOrNull"); List result = new ArrayList<>(); - result.addAll(fpe.evaluate(b, n)); + result.addAll(fpe.evaluate(vd, b, n)); return result; } - private void executeColumn(JsonObject column, Base b, List> rows) { + private void executeColumn(JsonObject vd, JsonObject column, Base b, List> rows) { ExpressionNode n = (ExpressionNode) column.getUserData("path"); List bl2 = new ArrayList<>(); if (b != null) { - bl2.addAll(fpe.evaluate(b, n)); + bl2.addAll(fpe.evaluate(vd, b, n)); } Column col = (Column) column.getUserData("column"); if (col == null) { @@ -344,14 +344,43 @@ public class Runner implements IEvaluationContext { @Override public List resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException { - throw new Error("Not implemented yet: resolveConstant"); + List list = new ArrayList(); + if (explicitConstant) { + JsonObject vd = (JsonObject) appContext; + JsonObject constant = findConstant(vd, name); + if (constant != null) { + Base b = (Base) constant.getUserData("value"); + if (b != null) { + list.add(b); + } + } + } + return list; } @Override public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException { - throw new Error("Not implemented yet: resolveConstantType"); + if (explicitConstant) { + JsonObject vd = (JsonObject) appContext; + JsonObject constant = findConstant(vd, name.substring(1)); + if (constant != null) { + Base b = (Base) constant.getUserData("value"); + if (b != null) { + return new TypeDetails(CollectionStatus.SINGLETON, b.fhirType()); + } + } + } + return null; } + private JsonObject findConstant(JsonObject vd, String name) { + for (JsonObject o : vd.getJsonObjects("constant")) { + if (name.equals(o.asString("name"))) { + return o; + } + } + return null; + } @Override public boolean log(String argument, List focus) { throw new Error("Not implemented yet: log"); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/sql/StorageJson.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/sql/StorageJson.java index d0e3aaeed..d76404c03 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/sql/StorageJson.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/sql/StorageJson.java @@ -2,6 +2,7 @@ package org.hl7.fhir.r5.utils.sql; import java.util.List; +import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.r5.model.Base; import org.hl7.fhir.utilities.json.model.JsonArray; import org.hl7.fhir.utilities.json.model.JsonBoolean; @@ -33,16 +34,16 @@ public class StorageJson implements Storage { JsonObject row = new JsonObject(); rows.add(row); for (Cell cell : cells) { - if (cell.getValues().size() == 0) { - row.add(cell.getColumn().getName(), new JsonNull()); - } else if (cell.getValues().size() == 1) { - row.add(cell.getColumn().getName(), makeJsonNode(cell.getValues().get(0))); - } else { + if (cell.getColumn().isColl() || cell.getValues().size() > 1) { JsonArray arr = new JsonArray(); - row.add(cell.getColumn().getName(), arr); + row.add(cell.getColumn().getName(), arr); for (Value value : cell.getValues()) { arr.add(makeJsonNode(value)); - } + } + } else if (cell.getValues().size() == 0) { + row.add(cell.getColumn().getName(), new JsonNull()); + } else { + row.add(cell.getColumn().getName(), makeJsonNode(cell.getValues().get(0))); } } } @@ -87,7 +88,7 @@ public class StorageJson implements Storage { @Override public String getKeyForSourceResource(Base res) { - return res.getIdBase(); + return res.fhirType()+"/"+res.getIdBase(); } @Override diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/sql/Validator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/sql/Validator.java index 669fa32de..00c862b5d 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/sql/Validator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/sql/Validator.java @@ -11,6 +11,27 @@ import org.hl7.fhir.r5.context.IWorkerContext; import org.hl7.fhir.r5.fhirpath.ExpressionNode; import org.hl7.fhir.r5.fhirpath.FHIRPathEngine; import org.hl7.fhir.r5.fhirpath.TypeDetails; +import org.hl7.fhir.r5.formats.JsonParser; +import org.hl7.fhir.r5.model.Base64BinaryType; +import org.hl7.fhir.r5.model.BooleanType; +import org.hl7.fhir.r5.model.CanonicalType; +import org.hl7.fhir.r5.model.CodeType; +import org.hl7.fhir.r5.model.DateTimeType; +import org.hl7.fhir.r5.model.DateType; +import org.hl7.fhir.r5.model.DecimalType; +import org.hl7.fhir.r5.model.IdType; +import org.hl7.fhir.r5.model.InstantType; +import org.hl7.fhir.r5.model.Integer64Type; +import org.hl7.fhir.r5.model.IntegerType; +import org.hl7.fhir.r5.model.OidType; +import org.hl7.fhir.r5.model.PositiveIntType; +import org.hl7.fhir.r5.model.PrimitiveType; +import org.hl7.fhir.r5.model.StringType; +import org.hl7.fhir.r5.model.TimeType; +import org.hl7.fhir.r5.model.UnsignedIntType; +import org.hl7.fhir.r5.model.UriType; +import org.hl7.fhir.r5.model.UrlType; +import org.hl7.fhir.r5.model.UuidType; import org.hl7.fhir.r5.fhirpath.ExpressionNode.CollectionStatus; import org.hl7.fhir.r5.fhirpath.FHIRPathEngine.IssueMessage; import org.hl7.fhir.utilities.Utilities; @@ -99,7 +120,7 @@ public class Validator { i = 0; if (checkAllObjects(path, viewDefinition, "where")) { for (JsonObject where : viewDefinition.getJsonObjects("where")) { - checkWhere(path+".where["+i+"]", where); + checkWhere(viewDefinition, path+".where["+i+"]", where); i++; } } @@ -108,7 +129,7 @@ public class Validator { i = 0; if (checkAllObjects(path, viewDefinition, "select")) { for (JsonObject select : viewDefinition.getJsonObjects("select")) { - columns.addAll(checkSelect(path+".select["+i+"]", select, t)); + columns.addAll(checkSelect(viewDefinition, path+".select["+i+"]", select, t)); i++; } if (i == 0) { @@ -119,15 +140,15 @@ public class Validator { } } - private List checkSelect(String path, JsonObject select, TypeDetails t) { + private List checkSelect(JsonObject vd, String path, JsonObject select, TypeDetails t) { List columns = new ArrayList<>(); select.setUserData("columns", columns); checkProperties(select, path, "column", "select", "forEach", "forEachOrNull", "unionAll"); if (select.has("forEach")) { - t = checkForEach(path, select, select.get("forEach"), t); + t = checkForEach(vd, path, select, select.get("forEach"), t); } else if (select.has("forEachOrNull")) { - t = checkForEachOrNull(path, select, select.get("forEachOrNull"), t); + t = checkForEachOrNull(vd, path, select, select.get("forEachOrNull"), t); } if (t != null) { @@ -142,7 +163,7 @@ public class Validator { if (!(e instanceof JsonObject)) { error(path+".column["+i+"]", a, "column["+i+"] is a "+e.type().toName()+" not an object", IssueType.INVALID); } else { - columns.add(checkColumn(path+".column["+i+"]", (JsonObject) e, t)); + columns.add(checkColumn(vd, path+".column["+i+"]", (JsonObject) e, t)); } } } @@ -158,14 +179,14 @@ public class Validator { if (!(e instanceof JsonObject)) { error(path+".select["+i+"]", e, "select["+i+"] is not an object", IssueType.INVALID); } else { - columns.addAll(checkSelect(path+".select["+i+"]", (JsonObject) e, t)); + columns.addAll(checkSelect(vd, path+".select["+i+"]", (JsonObject) e, t)); } } } } if (select.has("unionAll")) { - columns.addAll(checkUnion(path, select, select.get("unionAll"), t)); + columns.addAll(checkUnion(vd, path, select, select.get("unionAll"), t)); } if (columns.isEmpty()) { error(path, select, "The select has no columns or selects", IssueType.REQUIRED); @@ -191,7 +212,7 @@ public class Validator { } } - private List checkUnion(String path, JsonObject focus, JsonElement expression, TypeDetails t) { + private List checkUnion(JsonObject vd, String path, JsonObject focus, JsonElement expression, TypeDetails t) { JsonElement a = focus.get("unionAll"); if (!(a instanceof JsonArray)) { error(path+".unionAll", a, "union is not an array", IssueType.INVALID); @@ -203,7 +224,7 @@ public class Validator { if (!(e instanceof JsonObject)) { error(path+".unionAll["+i+"]", e, "unionAll["+i+"] is not an object", IssueType.INVALID); } else { - unionColumns.add(checkSelect(path+".unionAll["+i+"]", (JsonObject) e, t)); + unionColumns.add(checkSelect(vd, path+".unionAll["+i+"]", (JsonObject) e, t)); } i++; } @@ -242,7 +263,7 @@ public class Validator { } } - private Column checkColumn(String path, JsonObject column, TypeDetails t) { + private Column checkColumn(JsonObject vd, String path, JsonObject column, TypeDetails t) { checkProperties(column, path, "path", "name", "description", "collection", "type", "tag"); if (!column.has("path")) { @@ -260,7 +281,7 @@ public class Validator { try { node = fpe.parse(expr); column.setUserData("path", node); - td = fpe.checkOnTypes(null, resourceName, t, node, warnings); + td = fpe.checkOnTypes(vd, resourceName, t, node, warnings); } catch (Exception e) { error(path, expression, e.getMessage(), IssueType.INVALID); } @@ -296,25 +317,31 @@ public class Validator { // ok, name is sorted! if (columnName != null) { column.setUserData("name", columnName); - boolean isColl = (td.getCollectionStatus() != CollectionStatus.SINGLETON); + boolean isColl = false; if (column.has("collection")) { JsonElement collectionJ = column.get("collection"); if (!(collectionJ instanceof JsonBoolean)) { error(path+".collection", collectionJ, "collection is not a boolean", IssueType.INVALID); } else { boolean collection = collectionJ.asJsonBoolean().asBoolean(); - if (!collection && isColl) { - isColl = false; - warning(path, column, "collection is false, but the path statement(s) might return multiple values for the column '"+columnName+"' some inputs"); + if (collection) { + isColl = true; } } } if (isColl) { + if (td.getCollectionStatus() == CollectionStatus.SINGLETON) { + hint(path, column, "collection is true, but the path statement(s) can only return single values for the column '"+columnName+"'"); + } + } else { if (arrays == null) { warning(path, expression, "The column '"+columnName+"' appears to be a collection based on it's path. Collections are not supported in all execution contexts"); } else if (!arrays) { warning(path, expression, "The column '"+columnName+"' appears to be a collection based on it's path, but this is not allowed in the current execution context"); } + if (td.getCollectionStatus() != CollectionStatus.SINGLETON) { + warning(path, column, "collection is not true, but the path statement(s) might return multiple values for the column '"+columnName+"' for some inputs"); + } } Set types = new HashSet<>(); if (node.isNullSet()) { @@ -330,7 +357,7 @@ public class Validator { if (typeJ instanceof JsonString) { String type = typeJ.asString(); if (!td.hasType(type)) { - error(path+".type", typeJ, "The path expression does not return a value of the type '"+type, IssueType.VALUE); + error(path+".type", typeJ, "The path expression does not return a value of the type '"+type+"' - found "+td.describe(), IssueType.VALUE); } else { types.clear(); types.add(simpleType(type)); @@ -377,6 +404,8 @@ public class Validator { case "integer": return ColumnKind.Integer; case "decimal": return ColumnKind.Decimal; case "string": return ColumnKind.String; + case "id": return ColumnKind.String; + case "code": return ColumnKind.String; case "base64Binary": return ColumnKind.Binary; case "time": return ColumnKind.Time; default: return ColumnKind.Complex; @@ -384,7 +413,7 @@ public class Validator { } private boolean isSimpleType(String type) { - return Utilities.existsInList(type, "dateTime", "boolean", "integer", "decimal", "string", "base64Binary"); + return Utilities.existsInList(type, "dateTime", "boolean", "integer", "decimal", "string", "base64Binary", "id", "code", "date", "time"); } private String simpleType(String type) { @@ -413,7 +442,7 @@ public class Validator { return type; } - private TypeDetails checkForEach(String path, JsonObject focus, JsonElement expression, TypeDetails t) { + private TypeDetails checkForEach(JsonObject vd, String path, JsonObject focus, JsonElement expression, TypeDetails t) { if (!(expression instanceof JsonString)) { error(path+".forEach", expression, "forEach is not a string", IssueType.INVALID); return null; @@ -425,7 +454,7 @@ public class Validator { try { ExpressionNode n = fpe.parse(expr); focus.setUserData("forEach", n); - td = fpe.checkOnTypes(null, resourceName, t, n, warnings); + td = fpe.checkOnTypes(vd, resourceName, t, n, warnings); } catch (Exception e) { error(path, expression, e.getMessage(), IssueType.INVALID); } @@ -438,7 +467,7 @@ public class Validator { } } - private TypeDetails checkForEachOrNull(String path, JsonObject focus, JsonElement expression, TypeDetails t) { + private TypeDetails checkForEachOrNull(JsonObject vd, String path, JsonObject focus, JsonElement expression, TypeDetails t) { if (!(expression instanceof JsonString)) { error(path+".forEachOrNull", expression, "forEachOrNull is not a string", IssueType.INVALID); return null; @@ -450,7 +479,7 @@ public class Validator { try { ExpressionNode n = fpe.parse(expr); focus.setUserData("forEachOrNull", n); - td = fpe.checkOnTypes(null, resourceName, t, n, warnings); + td = fpe.checkOnTypes(vd, resourceName, t, n, warnings); } catch (Exception e) { error(path, expression, e.getMessage(), IssueType.INVALID); } @@ -477,69 +506,79 @@ public class Validator { } } if (constant.has("valueBase64Binary")) { - checkIsString(path, constant, "valueBase64Binary"); + checkIsString(path, constant, "valueBase64Binary", new Base64BinaryType()); } else if (constant.has("valueBoolean")) { - checkIsBoolean(path, constant, "valueBoolean"); + checkIsBoolean(path, constant, "valueBoolean", new BooleanType()); } else if (constant.has("valueCanonical")) { - checkIsString(path, constant, "valueCanonical"); + checkIsString(path, constant, "valueCanonical", new CanonicalType()); } else if (constant.has("valueCode")) { - checkIsString(path, constant, "valueCode"); + checkIsString(path, constant, "valueCode", new CodeType()); } else if (constant.has("valueDate")) { - checkIsString(path, constant, "valueDate"); + checkIsString(path, constant, "valueDate", new DateType()); } else if (constant.has("valueDateTime")) { - checkIsString(path, constant, "valueDateTime"); + checkIsString(path, constant, "valueDateTime", new DateTimeType()); } else if (constant.has("valueDecimal")) { - checkIsNumber(path, constant, "valueDecimal"); + checkIsNumber(path, constant, "valueDecimal", new DecimalType()); } else if (constant.has("valueId")) { - checkIsString(path, constant, "valueId"); + checkIsString(path, constant, "valueId", new IdType()); } else if (constant.has("valueInstant")) { - checkIsString(path, constant, "valueInstant"); + checkIsString(path, constant, "valueInstant", new InstantType()); } else if (constant.has("valueInteger")) { - checkIsNumber(path, constant, "valueInteger"); + checkIsNumber(path, constant, "valueInteger", new IntegerType()); } else if (constant.has("valueInteger64")) { - checkIsNumber(path, constant, "valueInteger64"); + checkIsNumber(path, constant, "valueInteger64", new Integer64Type()); } else if (constant.has("valueOid")) { - checkIsString(path, constant, "valueOid"); + checkIsString(path, constant, "valueOid", new OidType()); } else if (constant.has("valueString")) { - checkIsString(path, constant, "valueString"); + checkIsString(path, constant, "valueString", new StringType()); } else if (constant.has("valuePositiveInt")) { - checkIsNumber(path, constant, "valuePositiveInt"); + checkIsNumber(path, constant, "valuePositiveInt", new PositiveIntType()); } else if (constant.has("valueTime")) { - checkIsString(path, constant, "valueTime"); + checkIsString(path, constant, "valueTime", new TimeType()); } else if (constant.has("valueUnsignedInt")) { - checkIsNumber(path, constant, "valueUnsignedInt"); + checkIsNumber(path, constant, "valueUnsignedInt", new UnsignedIntType()); } else if (constant.has("valueUri")) { - checkIsString(path, constant, "valueUri"); + checkIsString(path, constant, "valueUri", new UriType()); } else if (constant.has("valueUrl")) { - checkIsString(path, constant, "valueUrl"); + checkIsString(path, constant, "valueUrl", new UrlType()); } else if (constant.has("valueUuid")) { - checkIsString(path, constant, "valueUuid"); + checkIsString(path, constant, "valueUuid", new UuidType()); } else { error(path, constant, "No value found", IssueType.REQUIRED); } } - private void checkIsString(String path, JsonObject constant, String name) { + private void checkIsString(String path, JsonObject constant, String name, PrimitiveType value) { JsonElement j = constant.get(name); if (!(j instanceof JsonString)) { error(path+"."+name, j, name+" must be a string", IssueType.INVALID); + } else { + value.setValueAsString(j.asString()); + constant.setUserData("value", value); } } - private void checkIsBoolean(String path, JsonObject constant, String name) { + private void checkIsBoolean(String path, JsonObject constant, String name, PrimitiveType value) { JsonElement j = constant.get(name); if (!(j instanceof JsonBoolean)) { error(path+"."+name, j, name+" must be a boolean", IssueType.INVALID); + } else { + value.setValueAsString(j.asString()); + constant.setUserData("value", value); } } - private void checkIsNumber(String path, JsonObject constant, String name) { + private void checkIsNumber(String path, JsonObject constant, String name, PrimitiveType value) { JsonElement j = constant.get(name); if (!(j instanceof JsonNumber)) { error(path+"."+name, j, name+" must be a number", IssueType.INVALID); + } else { + value.setValueAsString(j.asString()); + constant.setUserData("value", value); } } - private void checkWhere(String path, JsonObject where) { + + private void checkWhere(JsonObject vd, String path, JsonObject where) { checkProperties(where, path, "path", "description"); String expr = where.asString("path"); @@ -553,7 +592,7 @@ public class Validator { try { ExpressionNode n = fpe.parse(expr); where.setUserData("path", n); - td = fpe.checkOnTypes(null, resourceName, types, n, warnings); + td = fpe.checkOnTypes(vd, resourceName, types, n, warnings); } catch (Exception e) { error(path, where.get("path"), e.getMessage(), IssueType.INVALID); } diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/sql/SQLOnFhirTests.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/sql/SQLOnFhirTests.java index 9dba811a8..d650980fb 100644 --- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/sql/SQLOnFhirTests.java +++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/sql/SQLOnFhirTests.java @@ -83,23 +83,21 @@ public class SQLOnFhirTests { this.resources = resources; this.testCase = testCase; } - } public static Stream data() throws ParserConfigurationException, SAXException, IOException { List objects = new ArrayList<>(); - File dir = ManagedFileAccess.file("/Users/grahamegrieve/work/sql-on-fhir-v2/tests/content"); - for (File f : dir.listFiles()) { - if (f.getName().endsWith(".json")) { - JsonObject json = JsonParser.parseObject(f); - String name1 = f.getName().replace(".json", ""); - List resources = json.getJsonObjects("resources"); - int i = 0; - for (JsonObject test : json.getJsonObjects("tests")) { - String name2 = test.asString("title"); - objects.add(Arguments.of(name1+":"+name2, new TestDetails(name1+":"+name2, "$.tests["+i+"]", resources, test))); - i++; - } + JsonArray testFiles = (JsonArray) JsonParser.parse(TestingUtilities.loadTestResourceStream("sql-on-fhir", "manifest.json")); + + for (String s : testFiles.asStrings()) { + JsonObject json = JsonParser.parseObject(TestingUtilities.loadTestResourceStream("sql-on-fhir", s)); + String name1 = s.replace(".json", ""); + List resources = json.getJsonObjects("resources"); + int i = 0; + for (JsonObject test : json.getJsonObjects("tests")) { + String name2 = test.asString("title"); + objects.add(Arguments.of(name1+":"+name2, new TestDetails(name1+":"+name2, "$.tests["+i+"]", resources, test))); + i++; } } return objects.stream(); @@ -110,7 +108,6 @@ public class SQLOnFhirTests { @SuppressWarnings("deprecation") @ParameterizedTest(name = "{index}: file {0}") @MethodSource("data") - @Disabled public void test(String name, TestDetails test) throws FileNotFoundException, IOException, FHIRException, org.hl7.fhir.exceptions.FHIRException, UcumException { this.details = test; Runner runner = new Runner(); @@ -137,8 +134,8 @@ public class SQLOnFhirTests { rows.add("rows", results); JsonObject exp = new JsonObject(); exp.add("rows", test.testCase.getJsonArray("expect")); - sortResults(exp); - sortResults(rows); +// sortResults(exp); +// sortResults(rows); String expS = JsonParser.compose(exp, true); String rowS = JsonParser.compose(rows, true); String c = CompareUtilities.checkJsonSrcIsSame(name, expS, rowS, null);