updates for FHIRPath test corrections
This commit is contained in:
parent
ebd07775a7
commit
7b8b5df67c
|
@ -24,6 +24,7 @@ package org.hl7.fhir.r4.model;
|
|||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -138,6 +139,14 @@ private Map<String, Object> userData;
|
|||
return null;
|
||||
}
|
||||
|
||||
public boolean isDateTime() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Date dateTimeValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract String fhirType() ;
|
||||
|
||||
public boolean hasType(String... name) {
|
||||
|
|
|
@ -846,4 +846,15 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDateTime() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date dateTimeValue() {
|
||||
return getValue();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -234,4 +234,9 @@ public class DateTimeType extends BaseDateTimeType {
|
|||
return r.substring(0, i)+r.substring(i+1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDateTime() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -203,4 +203,9 @@ public class DateType extends BaseDateTimeType {
|
|||
public String fhirType() {
|
||||
return "date";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDateTime() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ import org.hl7.fhir.utilities.Utilities;
|
|||
public class ExpressionNode {
|
||||
|
||||
public enum Kind {
|
||||
Name, Function, Constant, Group
|
||||
Name, Function, Constant, Group, Unary
|
||||
}
|
||||
public static class SourceLocation {
|
||||
private int line;
|
||||
|
@ -61,7 +61,8 @@ public class ExpressionNode {
|
|||
|
||||
Empty, Not, Exists, SubsetOf, SupersetOf, IsDistinct, Distinct, Count, Where, Select, All, Repeat, Aggregate, Item /*implicit from name[]*/, As, Is, Single,
|
||||
First, Last, Tail, Skip, Take, Union, Combine, Intersect, Exclude, Iif, Upper, Lower, ToChars, Substring, StartsWith, EndsWith, Matches, ReplaceMatches, Contains, Replace, Length,
|
||||
Children, Descendants, MemberOf, Trace, Today, Now, Resolve, Extension, HasValue, AliasAs, Alias, HtmlChecks, OfType, Type,
|
||||
Children, Descendants, MemberOf, Trace, Today, Now, Resolve, Extension, AllFalse, AnyFalse, AllTrue, AnyTrue,
|
||||
HasValue, AliasAs, Alias, HtmlChecks, OfType, Type,
|
||||
ConvertsToBoolean, ConvertsToInteger, ConvertsToString, ConvertsToDecimal, ConvertsToQuantity, ConvertsToDateTime, ConvertsToTime, ToBoolean, ToInteger, ToString, ToDecimal, ToQuantity, ToDateTime, ToTime, ConformsTo;
|
||||
|
||||
public static Function fromCode(String name) {
|
||||
|
@ -111,6 +112,10 @@ public class ExpressionNode {
|
|||
if (name.equals("now")) return Function.Now;
|
||||
if (name.equals("resolve")) return Function.Resolve;
|
||||
if (name.equals("extension")) return Function.Extension;
|
||||
if (name.equals("allFalse")) return Function.AllFalse;
|
||||
if (name.equals("anyFalse")) return Function.AnyFalse;
|
||||
if (name.equals("allTrue")) return Function.AllTrue;
|
||||
if (name.equals("anyTrue")) return Function.AnyTrue;
|
||||
if (name.equals("hasValue")) return Function.HasValue;
|
||||
if (name.equals("alias")) return Function.Alias;
|
||||
if (name.equals("aliasAs")) return Function.AliasAs;
|
||||
|
@ -182,6 +187,10 @@ public class ExpressionNode {
|
|||
case Now : return "now";
|
||||
case Resolve : return "resolve";
|
||||
case Extension : return "extension";
|
||||
case AllFalse : return "allFalse";
|
||||
case AnyFalse : return "anyFalse";
|
||||
case AllTrue : return "allTrue";
|
||||
case AnyTrue : return "anyTrue";
|
||||
case HasValue : return "hasValue";
|
||||
case Alias : return "alias";
|
||||
case AliasAs : return "aliasAs";
|
||||
|
@ -209,7 +218,7 @@ public class ExpressionNode {
|
|||
}
|
||||
|
||||
public enum Operation {
|
||||
Equals, Equivalent, NotEquals, NotEquivalent, LessThen, Greater, LessOrEqual, GreaterOrEqual, Is, As, Union, Or, And, Xor, Implies,
|
||||
Equals, Equivalent, NotEquals, NotEquivalent, LessThan, Greater, LessOrEqual, GreaterOrEqual, Is, As, Union, Or, And, Xor, Implies,
|
||||
Times, DivideBy, Plus, Minus, Concatenate, Div, Mod, In, Contains, MemberOf;
|
||||
|
||||
public static Operation fromCode(String name) {
|
||||
|
@ -226,7 +235,7 @@ public class ExpressionNode {
|
|||
if (name.equals(">"))
|
||||
return Operation.Greater;
|
||||
if (name.equals("<"))
|
||||
return Operation.LessThen;
|
||||
return Operation.LessThan;
|
||||
if (name.equals(">="))
|
||||
return Operation.GreaterOrEqual;
|
||||
if (name.equals("<="))
|
||||
|
@ -275,7 +284,7 @@ public class ExpressionNode {
|
|||
case NotEquals : return "!=";
|
||||
case NotEquivalent : return "!~";
|
||||
case Greater : return ">";
|
||||
case LessThen : return "<";
|
||||
case LessThan : return "<";
|
||||
case GreaterOrEqual : return ">=";
|
||||
case LessOrEqual : return "<=";
|
||||
case Union : return "|";
|
||||
|
@ -579,6 +588,8 @@ public class ExpressionNode {
|
|||
|
||||
break;
|
||||
|
||||
case Unary:
|
||||
break;
|
||||
case Constant:
|
||||
if (constant == null)
|
||||
return "No Constant provided @ "+location();
|
||||
|
|
|
@ -90,7 +90,7 @@ public class FHIRLexer {
|
|||
}
|
||||
|
||||
public boolean isStringConstant() {
|
||||
return current.charAt(0) == '\'' || current.charAt(0) == '"';
|
||||
return current.charAt(0) == '\'' || current.charAt(0) == '"' || current.charAt(0) == '`';
|
||||
}
|
||||
|
||||
public String take() throws FHIRLexerException {
|
||||
|
@ -185,9 +185,9 @@ public class FHIRLexer {
|
|||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '%') {
|
||||
cursor++;
|
||||
if (cursor < source.length() && (source.charAt(cursor) == '"')) {
|
||||
if (cursor < source.length() && (source.charAt(cursor) == '`')) {
|
||||
cursor++;
|
||||
while (cursor < source.length() && (source.charAt(cursor) != '"'))
|
||||
while (cursor < source.length() && (source.charAt(cursor) != '`'))
|
||||
cursor++;
|
||||
cursor++;
|
||||
} else
|
||||
|
@ -228,6 +228,20 @@ public class FHIRLexer {
|
|||
throw error("Unterminated string");
|
||||
cursor++;
|
||||
current = "\""+source.substring(currentStart+1, cursor-1)+"\"";
|
||||
} else if (ch == '`') {
|
||||
cursor++;
|
||||
boolean escape = false;
|
||||
while (cursor < source.length() && (escape || source.charAt(cursor) != '`')) {
|
||||
if (escape)
|
||||
escape = false;
|
||||
else
|
||||
escape = (source.charAt(cursor) == '\\');
|
||||
cursor++;
|
||||
}
|
||||
if (cursor == source.length())
|
||||
throw error("Unterminated string");
|
||||
cursor++;
|
||||
current = "`"+source.substring(currentStart+1, cursor-1)+"`";
|
||||
} else if (ch == '\''){
|
||||
cursor++;
|
||||
char ech = ch;
|
||||
|
@ -358,6 +372,9 @@ public class FHIRLexer {
|
|||
case '"':
|
||||
b.append('"');
|
||||
break;
|
||||
case '`':
|
||||
b.append('`');
|
||||
break;
|
||||
case '\\':
|
||||
b.append('\\');
|
||||
break;
|
||||
|
|
|
@ -72,6 +72,7 @@ import org.hl7.fhir.utilities.Utilities;
|
|||
|
||||
//import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
||||
import ca.uhn.fhir.util.ElementUtil;
|
||||
import net.sf.saxon.om.Item;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -655,30 +656,13 @@ public class FHIRPathEngine {
|
|||
return b.toString();
|
||||
}
|
||||
|
||||
private String convertToString(Base item) {
|
||||
public String convertToString(Base item) {
|
||||
if (item.isPrimitive())
|
||||
return item.primitiveValue();
|
||||
else if (item instanceof Quantity) {
|
||||
Quantity q = (Quantity) item;
|
||||
if (q.getSystem().equals("http://unitsofmeasure.org")) {
|
||||
String u = "'"+q.getCode()+"'";
|
||||
boolean plural = !q.getValue().toPlainString().equals("1");
|
||||
if ("a".equals(q.getCode()))
|
||||
u = plural ? "years" : "year";
|
||||
else if ("mo".equals(q.getCode()))
|
||||
u = plural ? "months" : "month";
|
||||
else if ("wk".equals(q.getCode()))
|
||||
u = plural ? "weeks" : "week";
|
||||
else if ("d".equals(q.getCode()))
|
||||
u = plural ? "days" : "day";
|
||||
else if ("h".equals(q.getCode()))
|
||||
u = plural ? "hours" : "hour";
|
||||
else if ("min".equals(q.getCode()))
|
||||
u = plural ? "minutes" : "minute";
|
||||
else if ("s".equals(q.getCode()))
|
||||
u = plural ? "seconds" : "seconds";
|
||||
else if ("ms".equals(q.getCode()))
|
||||
u = plural ? "milliseconds" : "milliseconds";
|
||||
return q.getValue().toPlainString()+" "+u;
|
||||
}
|
||||
else
|
||||
|
@ -795,19 +779,31 @@ public class FHIRPathEngine {
|
|||
|
||||
private ExpressionNode parseExpression(FHIRLexer lexer, boolean proximal) throws FHIRLexerException {
|
||||
ExpressionNode result = new ExpressionNode(lexer.nextId());
|
||||
ExpressionNode wrapper = null;
|
||||
SourceLocation c = lexer.getCurrentStartLocation();
|
||||
result.setStart(lexer.getCurrentLocation());
|
||||
// special:
|
||||
if (lexer.getCurrent().equals("-")) {
|
||||
lexer.take();
|
||||
lexer.setCurrent("-"+lexer.getCurrent());
|
||||
}
|
||||
if (lexer.getCurrent().equals("+")) {
|
||||
lexer.take();
|
||||
lexer.setCurrent("+"+lexer.getCurrent());
|
||||
// special: +/- represents a unary operation at this point, but cannot be a feature of the lexer, since that's not always true.
|
||||
// so we back correct for both +/- and as part of a numeric constant below.
|
||||
|
||||
// special: +/- represents a unary operation at this point, but cannot be a feature of the lexer, since that's not always true.
|
||||
// so we back correct for both +/- and as part of a numeric constant below.
|
||||
if (Utilities.existsInList(lexer.getCurrent(), "-", "+")) {
|
||||
wrapper = new ExpressionNode(lexer.nextId());
|
||||
wrapper.setKind(Kind.Unary);
|
||||
wrapper.setOperation(ExpressionNode.Operation.fromCode(lexer.take()));
|
||||
wrapper.setProximal(proximal);
|
||||
}
|
||||
|
||||
if (lexer.isConstant()) {
|
||||
boolean isString = lexer.isStringConstant();
|
||||
if (!isString && (lexer.getCurrent().startsWith("-") || lexer.getCurrent().startsWith("+"))) {
|
||||
// the grammar says that this is a unary operation; it affects the correct processing order of the inner operations
|
||||
wrapper = new ExpressionNode(lexer.nextId());
|
||||
wrapper.setKind(Kind.Unary);
|
||||
wrapper.setOperation(ExpressionNode.Operation.fromCode(lexer.getCurrent().substring(0, 1)));
|
||||
wrapper.setProximal(proximal);
|
||||
lexer.setCurrent(lexer.getCurrent().substring(1));
|
||||
}
|
||||
result.setConstant(processConstant(lexer));
|
||||
result.setKind(Kind.Constant);
|
||||
if (!isString && !lexer.done() && (result.getConstant() instanceof IntegerType || result.getConstant() instanceof DecimalType) && (lexer.isStringConstant() || lexer.hasToken("year", "years", "month", "months", "week", "weeks", "day", "days", "hour", "hours", "minute", "minutes", "second", "seconds", "millisecond", "milliseconds"))) {
|
||||
|
@ -909,6 +905,11 @@ public class FHIRPathEngine {
|
|||
}
|
||||
result = organisePrecedence(lexer, result);
|
||||
}
|
||||
if (wrapper != null) {
|
||||
wrapper.setOpNext(result);
|
||||
result.setProximal(false);
|
||||
result = wrapper;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -916,7 +917,7 @@ public class FHIRPathEngine {
|
|||
node = gatherPrecedence(lexer, node, EnumSet.of(Operation.Times, Operation.DivideBy, Operation.Div, Operation.Mod));
|
||||
node = gatherPrecedence(lexer, node, EnumSet.of(Operation.Plus, Operation.Minus, Operation.Concatenate));
|
||||
node = gatherPrecedence(lexer, node, EnumSet.of(Operation.Union));
|
||||
node = gatherPrecedence(lexer, node, EnumSet.of(Operation.LessThen, Operation.Greater, Operation.LessOrEqual, Operation.GreaterOrEqual));
|
||||
node = gatherPrecedence(lexer, node, EnumSet.of(Operation.LessThan, Operation.Greater, Operation.LessOrEqual, Operation.GreaterOrEqual));
|
||||
node = gatherPrecedence(lexer, node, EnumSet.of(Operation.Is));
|
||||
node = gatherPrecedence(lexer, node, EnumSet.of(Operation.Equals, Operation.Equivalent, Operation.NotEquals, Operation.NotEquivalent));
|
||||
node = gatherPrecedence(lexer, node, EnumSet.of(Operation.And));
|
||||
|
@ -1093,6 +1094,10 @@ public class FHIRPathEngine {
|
|||
case Now: return checkParamCount(lexer, location, exp, 0);
|
||||
case Resolve: return checkParamCount(lexer, location, exp, 0);
|
||||
case Extension: return checkParamCount(lexer, location, exp, 1);
|
||||
case AllFalse: return checkParamCount(lexer, location, exp, 0);
|
||||
case AnyFalse: return checkParamCount(lexer, location, exp, 0);
|
||||
case AllTrue: return checkParamCount(lexer, location, exp, 0);
|
||||
case AnyTrue: return checkParamCount(lexer, location, exp, 0);
|
||||
case HasValue: return checkParamCount(lexer, location, exp, 0);
|
||||
case Alias: return checkParamCount(lexer, location, exp, 1);
|
||||
case AliasAs: return checkParamCount(lexer, location, exp, 1);
|
||||
|
@ -1121,6 +1126,9 @@ public class FHIRPathEngine {
|
|||
// System.out.println("Evaluate {'"+exp.toString()+"'} on "+focus.toString());
|
||||
List<Base> work = new ArrayList<Base>();
|
||||
switch (exp.getKind()) {
|
||||
case Unary:
|
||||
work.add(new IntegerType(0));
|
||||
break;
|
||||
case Name:
|
||||
if (atEntry && exp.getName().equals("$this"))
|
||||
work.add(context.getThisItem());
|
||||
|
@ -1176,12 +1184,17 @@ public class FHIRPathEngine {
|
|||
|
||||
private List<Base> executeTypeName(ExecutionContext context, List<Base> focus, ExpressionNode next, boolean atEntry) {
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
result.add(new StringType(next.getName()));
|
||||
if (next.getInner() != null)
|
||||
result.add(new StringType(next.getName()+"."+next.getInner().getName()));
|
||||
else
|
||||
result.add(new StringType(next.getName()));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private List<Base> preOperate(List<Base> left, Operation operation) {
|
||||
if (left.size() == 0)
|
||||
return null;
|
||||
switch (operation) {
|
||||
case And:
|
||||
return isBoolean(left, false) ? makeBoolean(false) : null;
|
||||
|
@ -1225,6 +1238,9 @@ public class FHIRPathEngine {
|
|||
case Function:
|
||||
result.update(evaluateFunctionType(context, focus, exp));
|
||||
break;
|
||||
case Unary:
|
||||
result.addType("integer");
|
||||
break;
|
||||
case Constant:
|
||||
result.update(resolveConstantType(context, exp.getConstant()));
|
||||
break;
|
||||
|
@ -1301,11 +1317,11 @@ public class FHIRPathEngine {
|
|||
return context.context;
|
||||
} else if (s.equals("%us-zip"))
|
||||
return new StringType("[0-9]{5}(-[0-9]{4}){0,1}").noExtensions();
|
||||
else if (s.startsWith("%\"vs-"))
|
||||
else if (s.startsWith("%`vs-"))
|
||||
return new StringType("http://hl7.org/fhir/ValueSet/"+s.substring(5, s.length()-1)+"").noExtensions();
|
||||
else if (s.startsWith("%\"cs-"))
|
||||
else if (s.startsWith("%`cs-"))
|
||||
return new StringType("http://hl7.org/fhir/"+s.substring(5, s.length()-1)+"").noExtensions();
|
||||
else if (s.startsWith("%\"ext-"))
|
||||
else if (s.startsWith("%`ext-"))
|
||||
return new StringType("http://hl7.org/fhir/StructureDefinition/"+s.substring(6, s.length()-1)).noExtensions();
|
||||
else if (hostServices == null)
|
||||
throw new PathEngineException("Unknown fixed constant '"+s+"'");
|
||||
|
@ -1340,6 +1356,9 @@ public class FHIRPathEngine {
|
|||
case '"':
|
||||
b.append('"');
|
||||
break;
|
||||
case '`':
|
||||
b.append('`');
|
||||
break;
|
||||
case '\\':
|
||||
b.append('\\');
|
||||
break;
|
||||
|
@ -1371,7 +1390,7 @@ public class FHIRPathEngine {
|
|||
case Equivalent: return opEquivalent(left, right);
|
||||
case NotEquals: return opNotEquals(left, right);
|
||||
case NotEquivalent: return opNotEquivalent(left, right);
|
||||
case LessThen: return opLessThen(left, right);
|
||||
case LessThan: return opLessThan(left, right);
|
||||
case Greater: return opGreater(left, right);
|
||||
case LessOrEqual: return opLessOrEqual(left, right);
|
||||
case GreaterOrEqual: return opGreaterOrEqual(left, right);
|
||||
|
@ -1419,7 +1438,7 @@ public class FHIRPathEngine {
|
|||
if (left.get(0) instanceof org.hl7.fhir.r4.elementmodel.Element)
|
||||
result.add(new BooleanType(left.get(0).hasType(tn)).noExtensions());
|
||||
else if ((left.get(0) instanceof Element) && ((Element) left.get(0)).isDisallowExtensions())
|
||||
result.add(new BooleanType(Utilities.capitalize(left.get(0).fhirType()).equals(tn)).noExtensions());
|
||||
result.add(new BooleanType(Utilities.capitalize(left.get(0).fhirType()).equals(tn) || ("System."+Utilities.capitalize(left.get(0).fhirType())).equals(tn)).noExtensions());
|
||||
else
|
||||
result.add(new BooleanType(left.get(0).hasType(tn)).noExtensions());
|
||||
}
|
||||
|
@ -1433,7 +1452,7 @@ public class FHIRPathEngine {
|
|||
case Equivalent: return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
|
||||
case NotEquals: return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
|
||||
case NotEquivalent: return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
|
||||
case LessThen: return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
|
||||
case LessThan: return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
|
||||
case Greater: return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
|
||||
case LessOrEqual: return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
|
||||
case GreaterOrEqual: return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
|
||||
|
@ -1495,6 +1514,9 @@ public class FHIRPathEngine {
|
|||
|
||||
|
||||
private List<Base> opEquals(List<Base> left, List<Base> right) {
|
||||
if (left.size() == 0 || right.size() == 0)
|
||||
return new ArrayList<Base>();
|
||||
|
||||
if (left.size() != right.size())
|
||||
return makeBoolean(false);
|
||||
|
||||
|
@ -1509,6 +1531,9 @@ public class FHIRPathEngine {
|
|||
}
|
||||
|
||||
private List<Base> opNotEquals(List<Base> left, List<Base> right) {
|
||||
if (left.size() == 0 || right.size() == 0)
|
||||
return new ArrayList<Base>();
|
||||
|
||||
if (left.size() != right.size())
|
||||
return makeBoolean(true);
|
||||
|
||||
|
@ -1522,9 +1547,38 @@ public class FHIRPathEngine {
|
|||
return makeBoolean(!res);
|
||||
}
|
||||
|
||||
private String removeTrailingZeros(String s) {
|
||||
if (Utilities.noString(s))
|
||||
return "";
|
||||
int i = s.length()-1;
|
||||
boolean done = false;
|
||||
boolean dot = false;
|
||||
while (i > 0 && !done) {
|
||||
if (s.charAt(i) == '.') {
|
||||
i--;
|
||||
dot = true;
|
||||
}
|
||||
else if (!dot && s.charAt(i) == '0')
|
||||
i--;
|
||||
else
|
||||
done = true;
|
||||
}
|
||||
return s.substring(0, i+1);
|
||||
}
|
||||
|
||||
private boolean decEqual(String left, String right) {
|
||||
left = removeTrailingZeros(left);
|
||||
right = removeTrailingZeros(right);
|
||||
return left.equals(right);
|
||||
}
|
||||
|
||||
private boolean doEquals(Base left, Base right) {
|
||||
if (left instanceof Quantity && right instanceof Quantity)
|
||||
return qtyEqual((Quantity) left, (Quantity) right);
|
||||
else if (left.isDateTime() && right.isDateTime())
|
||||
return left.dateTimeValue().equals(right.dateTimeValue());
|
||||
else if (left instanceof DecimalType || right instanceof DecimalType)
|
||||
return decEqual(left.primitiveValue(), right.primitiveValue());
|
||||
else if (left.isPrimitive() && right.isPrimitive())
|
||||
return Base.equals(left.primitiveValue(), right.primitiveValue());
|
||||
else
|
||||
|
@ -1543,7 +1597,7 @@ public class FHIRPathEngine {
|
|||
return Utilities.equivalentNumber(left.primitiveValue(), right.primitiveValue());
|
||||
if (left.hasType("date", "dateTime", "time", "instant") && right.hasType("date", "dateTime", "time", "instant"))
|
||||
return compareDateTimeElements(left, right, true) == 0;
|
||||
if (left.hasType("string", "id", "code", "uri") && right.hasType("string", "id", "code", "uri"))
|
||||
if (left.hasType(FHIR_TYPES_STRING) && right.hasType(FHIR_TYPES_STRING))
|
||||
return Utilities.equivalent(convertToString(left), convertToString(right));
|
||||
|
||||
throw new PathEngineException(String.format("Unable to determine equivalence between %s and %s", left.fhirType(), right.fhirType()));
|
||||
|
@ -1600,6 +1654,8 @@ public class FHIRPathEngine {
|
|||
|
||||
|
||||
private List<Base> opEquivalent(List<Base> left, List<Base> right) throws PathEngineException {
|
||||
if (left.size() == 0 || right.size() == 0)
|
||||
return new ArrayList<Base>();
|
||||
if (left.size() != right.size())
|
||||
return makeBoolean(false);
|
||||
|
||||
|
@ -1621,6 +1677,8 @@ public class FHIRPathEngine {
|
|||
}
|
||||
|
||||
private List<Base> opNotEquivalent(List<Base> left, List<Base> right) throws PathEngineException {
|
||||
if (left.size() == 0 || right.size() == 0)
|
||||
return new ArrayList<Base>();
|
||||
if (left.size() != right.size())
|
||||
return makeBoolean(true);
|
||||
|
||||
|
@ -1641,11 +1699,16 @@ public class FHIRPathEngine {
|
|||
return makeBoolean(!res);
|
||||
}
|
||||
|
||||
private List<Base> opLessThen(List<Base> left, List<Base> right) throws FHIRException {
|
||||
private final static String[] FHIR_TYPES_STRING = new String[] {"string", "uri", "code", "oid", "id", "uuid", "sid", "markdown", "base64Binary"};
|
||||
|
||||
private List<Base> opLessThan(List<Base> left, List<Base> right) throws FHIRException {
|
||||
if (left.size() == 0 || right.size() == 0)
|
||||
return new ArrayList<Base>();
|
||||
|
||||
if (left.size() == 1 && right.size() == 1 && left.get(0).isPrimitive() && right.get(0).isPrimitive()) {
|
||||
Base l = left.get(0);
|
||||
Base r = right.get(0);
|
||||
if (l.hasType("string") && r.hasType("string"))
|
||||
if (l.hasType(FHIR_TYPES_STRING) && r.hasType(FHIR_TYPES_STRING))
|
||||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) < 0);
|
||||
else if ((l.hasType("integer") || l.hasType("decimal")) && (r.hasType("integer") || r.hasType("decimal")))
|
||||
return makeBoolean(new Double(l.primitiveValue()) < new Double(r.primitiveValue()));
|
||||
|
@ -1653,11 +1716,13 @@ public class FHIRPathEngine {
|
|||
return makeBoolean(compareDateTimeElements(l, r, false) < 0);
|
||||
else if ((l.hasType("time")) && (r.hasType("time")))
|
||||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) < 0);
|
||||
else
|
||||
throw new PathEngineException("Unable to compare values of type "+l.fhirType()+" and "+r.fhirType());
|
||||
} else if (left.size() == 1 && right.size() == 1 && left.get(0).fhirType().equals("Quantity") && right.get(0).fhirType().equals("Quantity") ) {
|
||||
List<Base> lUnit = left.get(0).listChildrenByName("code");
|
||||
List<Base> rUnit = right.get(0).listChildrenByName("code");
|
||||
if (Base.compareDeep(lUnit, rUnit, true)) {
|
||||
return opLessThen(left.get(0).listChildrenByName("value"), right.get(0).listChildrenByName("value"));
|
||||
return opLessThan(left.get(0).listChildrenByName("value"), right.get(0).listChildrenByName("value"));
|
||||
} else {
|
||||
if (worker.getUcumService() == null)
|
||||
return makeBoolean(false);
|
||||
|
@ -1666,7 +1731,7 @@ public class FHIRPathEngine {
|
|||
dl.add(qtyToCanonical((Quantity) left.get(0)));
|
||||
List<Base> dr = new ArrayList<Base>();
|
||||
dr.add(qtyToCanonical((Quantity) right.get(0)));
|
||||
return opLessThen(dl, dr);
|
||||
return opLessThan(dl, dr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1674,10 +1739,12 @@ public class FHIRPathEngine {
|
|||
}
|
||||
|
||||
private List<Base> opGreater(List<Base> left, List<Base> right) throws FHIRException {
|
||||
if (left.size() == 0 || right.size() == 0)
|
||||
return new ArrayList<Base>();
|
||||
if (left.size() == 1 && right.size() == 1 && left.get(0).isPrimitive() && right.get(0).isPrimitive()) {
|
||||
Base l = left.get(0);
|
||||
Base r = right.get(0);
|
||||
if (l.hasType("string") && r.hasType("string"))
|
||||
if (l.hasType(FHIR_TYPES_STRING) && r.hasType(FHIR_TYPES_STRING))
|
||||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) > 0);
|
||||
else if ((l.hasType("integer", "decimal", "unsignedInt", "positiveInt")) && (r.hasType("integer", "decimal", "unsignedInt", "positiveInt")))
|
||||
return makeBoolean(new Double(l.primitiveValue()) > new Double(r.primitiveValue()));
|
||||
|
@ -1685,6 +1752,8 @@ public class FHIRPathEngine {
|
|||
return makeBoolean(compareDateTimeElements(l, r, false) > 0);
|
||||
else if ((l.hasType("time")) && (r.hasType("time")))
|
||||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) > 0);
|
||||
else
|
||||
throw new PathEngineException("Unable to compare values of type "+l.fhirType()+" and "+r.fhirType());
|
||||
} else if (left.size() == 1 && right.size() == 1 && left.get(0).fhirType().equals("Quantity") && right.get(0).fhirType().equals("Quantity") ) {
|
||||
List<Base> lUnit = left.get(0).listChildrenByName("unit");
|
||||
List<Base> rUnit = right.get(0).listChildrenByName("unit");
|
||||
|
@ -1706,10 +1775,12 @@ public class FHIRPathEngine {
|
|||
}
|
||||
|
||||
private List<Base> opLessOrEqual(List<Base> left, List<Base> right) throws FHIRException {
|
||||
if (left.size() == 0 || right.size() == 0)
|
||||
return new ArrayList<Base>();
|
||||
if (left.size() == 1 && right.size() == 1 && left.get(0).isPrimitive() && right.get(0).isPrimitive()) {
|
||||
Base l = left.get(0);
|
||||
Base r = right.get(0);
|
||||
if (l.hasType("string") && r.hasType("string"))
|
||||
if (l.hasType(FHIR_TYPES_STRING) && r.hasType(FHIR_TYPES_STRING))
|
||||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) <= 0);
|
||||
else if ((l.hasType("integer", "decimal", "unsignedInt", "positiveInt")) && (r.hasType("integer", "decimal", "unsignedInt", "positiveInt")))
|
||||
return makeBoolean(new Double(l.primitiveValue()) <= new Double(r.primitiveValue()));
|
||||
|
@ -1717,6 +1788,8 @@ public class FHIRPathEngine {
|
|||
return makeBoolean(compareDateTimeElements(l, r, false) <= 0);
|
||||
else if ((l.hasType("time")) && (r.hasType("time")))
|
||||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) <= 0);
|
||||
else
|
||||
throw new PathEngineException("Unable to compare values of type "+l.fhirType()+" and "+r.fhirType());
|
||||
} else if (left.size() == 1 && right.size() == 1 && left.get(0).fhirType().equals("Quantity") && right.get(0).fhirType().equals("Quantity") ) {
|
||||
List<Base> lUnits = left.get(0).listChildrenByName("unit");
|
||||
String lunit = lUnits.size() == 1 ? lUnits.get(0).primitiveValue() : null;
|
||||
|
@ -1740,10 +1813,12 @@ public class FHIRPathEngine {
|
|||
}
|
||||
|
||||
private List<Base> opGreaterOrEqual(List<Base> left, List<Base> right) throws FHIRException {
|
||||
if (left.size() == 0 || right.size() == 0)
|
||||
return new ArrayList<Base>();
|
||||
if (left.size() == 1 && right.size() == 1 && left.get(0).isPrimitive() && right.get(0).isPrimitive()) {
|
||||
Base l = left.get(0);
|
||||
Base r = right.get(0);
|
||||
if (l.hasType("string") && r.hasType("string"))
|
||||
if (l.hasType(FHIR_TYPES_STRING) && r.hasType(FHIR_TYPES_STRING))
|
||||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) >= 0);
|
||||
else if ((l.hasType("integer", "decimal", "unsignedInt", "positiveInt")) && (r.hasType("integer", "decimal", "unsignedInt", "positiveInt")))
|
||||
return makeBoolean(new Double(l.primitiveValue()) >= new Double(r.primitiveValue()));
|
||||
|
@ -1751,6 +1826,8 @@ public class FHIRPathEngine {
|
|||
return makeBoolean(compareDateTimeElements(l, r, false) >= 0);
|
||||
else if ((l.hasType("time")) && (r.hasType("time")))
|
||||
return makeBoolean(l.primitiveValue().compareTo(r.primitiveValue()) >= 0);
|
||||
else
|
||||
throw new PathEngineException("Unable to compare values of type "+l.fhirType()+" and "+r.fhirType());
|
||||
} else if (left.size() == 1 && right.size() == 1 && left.get(0).fhirType().equals("Quantity") && right.get(0).fhirType().equals("Quantity") ) {
|
||||
List<Base> lUnit = left.get(0).listChildrenByName("unit");
|
||||
List<Base> rUnit = right.get(0).listChildrenByName("unit");
|
||||
|
@ -1792,6 +1869,8 @@ public class FHIRPathEngine {
|
|||
}
|
||||
|
||||
private List<Base> opIn(List<Base> left, List<Base> right) throws FHIRException {
|
||||
if (left.size() == 0 || right.size() == 0)
|
||||
return new ArrayList<Base>();
|
||||
boolean ans = true;
|
||||
for (Base l : left) {
|
||||
boolean f = false;
|
||||
|
@ -1809,6 +1888,8 @@ public class FHIRPathEngine {
|
|||
}
|
||||
|
||||
private List<Base> opContains(List<Base> left, List<Base> right) {
|
||||
if (left.size() == 0 || right.size() == 0)
|
||||
return new ArrayList<Base>();
|
||||
boolean ans = true;
|
||||
for (Base r : right) {
|
||||
boolean f = false;
|
||||
|
@ -1826,14 +1907,12 @@ public class FHIRPathEngine {
|
|||
}
|
||||
|
||||
private List<Base> opPlus(List<Base> left, List<Base> right) throws PathEngineException {
|
||||
if (left.size() == 0)
|
||||
throw new PathEngineException("Error performing +: left operand has no value");
|
||||
if (left.size() == 0 || right.size() == 0)
|
||||
return new ArrayList<Base>();
|
||||
if (left.size() > 1)
|
||||
throw new PathEngineException("Error performing +: left operand has more than one value");
|
||||
if (!left.get(0).isPrimitive())
|
||||
throw new PathEngineException(String.format("Error performing +: left operand has the wrong type (%s)", left.get(0).fhirType()));
|
||||
if (right.size() == 0)
|
||||
throw new PathEngineException("Error performing +: right operand has no value");
|
||||
if (right.size() > 1)
|
||||
throw new PathEngineException("Error performing +: right operand has more than one value");
|
||||
if (!right.get(0).isPrimitive())
|
||||
|
@ -1842,7 +1921,7 @@ public class FHIRPathEngine {
|
|||
List<Base> result = new ArrayList<Base>();
|
||||
Base l = left.get(0);
|
||||
Base r = right.get(0);
|
||||
if (l.hasType("string", "id", "code", "uri") && r.hasType("string", "id", "code", "uri"))
|
||||
if (l.hasType(FHIR_TYPES_STRING) && r.hasType(FHIR_TYPES_STRING))
|
||||
result.add(new StringType(l.primitiveValue() + r.primitiveValue()));
|
||||
else if (l.hasType("integer") && r.hasType("integer"))
|
||||
result.add(new IntegerType(Integer.parseInt(l.primitiveValue()) + Integer.parseInt(r.primitiveValue())));
|
||||
|
@ -1854,14 +1933,12 @@ public class FHIRPathEngine {
|
|||
}
|
||||
|
||||
private List<Base> opTimes(List<Base> left, List<Base> right) throws PathEngineException {
|
||||
if (left.size() == 0)
|
||||
throw new PathEngineException("Error performing *: left operand has no value");
|
||||
if (left.size() == 0 || right.size() == 0)
|
||||
return new ArrayList<Base>();
|
||||
if (left.size() > 1)
|
||||
throw new PathEngineException("Error performing *: left operand has more than one value");
|
||||
if (!left.get(0).isPrimitive() && !(left.get(0) instanceof Quantity))
|
||||
throw new PathEngineException(String.format("Error performing +: left operand has the wrong type (%s)", left.get(0).fhirType()));
|
||||
if (right.size() == 0)
|
||||
throw new PathEngineException("Error performing *: right operand has no value");
|
||||
if (right.size() > 1)
|
||||
throw new PathEngineException("Error performing *: right operand has more than one value");
|
||||
if (!right.get(0).isPrimitive() && !(right.get(0) instanceof Quantity))
|
||||
|
@ -1891,9 +1968,22 @@ public class FHIRPathEngine {
|
|||
}
|
||||
|
||||
|
||||
private List<Base> opConcatenate(List<Base> left, List<Base> right) {
|
||||
private List<Base> opConcatenate(List<Base> left, List<Base> right) throws PathEngineException {
|
||||
if (left.size() == 0 || right.size() == 0)
|
||||
return new ArrayList<Base>();
|
||||
if (left.size() > 1)
|
||||
throw new PathEngineException("Error performing &: left operand has more than one value");
|
||||
if (!left.get(0).hasType(FHIR_TYPES_STRING))
|
||||
throw new PathEngineException(String.format("Error performing &: left operand has the wrong type (%s)", left.get(0).fhirType()));
|
||||
if (right.size() > 1)
|
||||
throw new PathEngineException("Error performing &: right operand has more than one value");
|
||||
if (!right.get(0).hasType(FHIR_TYPES_STRING))
|
||||
throw new PathEngineException(String.format("Error performing &: right operand has the wrong type (%s)", right.get(0).fhirType()));
|
||||
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
result.add(new StringType(convertToString(left) + convertToString((right))));
|
||||
Base l = left.get(0);
|
||||
Base r = right.get(0);
|
||||
result.add(new StringType(l.primitiveValue() + r.primitiveValue()));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1954,7 +2044,9 @@ public class FHIRPathEngine {
|
|||
}
|
||||
|
||||
private List<Base> opImplies(List<Base> left, List<Base> right) {
|
||||
if (!convertToBoolean(left))
|
||||
if (left.size() == 0)
|
||||
return new ArrayList<Base>();
|
||||
else if (!convertToBoolean(left))
|
||||
return makeBoolean(true);
|
||||
else if (right.size() == 0)
|
||||
return new ArrayList<Base>();
|
||||
|
@ -1964,14 +2056,12 @@ public class FHIRPathEngine {
|
|||
|
||||
|
||||
private List<Base> opMinus(List<Base> left, List<Base> right) throws PathEngineException {
|
||||
if (left.size() == 0)
|
||||
throw new PathEngineException("Error performing -: left operand has no value");
|
||||
if (left.size() == 0 || right.size() == 0)
|
||||
return new ArrayList<Base>();
|
||||
if (left.size() > 1)
|
||||
throw new PathEngineException("Error performing -: left operand has more than one value");
|
||||
if (!left.get(0).isPrimitive())
|
||||
throw new PathEngineException(String.format("Error performing -: left operand has the wrong type (%s)", left.get(0).fhirType()));
|
||||
if (right.size() == 0)
|
||||
throw new PathEngineException("Error performing -: right operand has no value");
|
||||
if (right.size() > 1)
|
||||
throw new PathEngineException("Error performing -: right operand has more than one value");
|
||||
if (!right.get(0).isPrimitive())
|
||||
|
@ -1991,14 +2081,12 @@ public class FHIRPathEngine {
|
|||
}
|
||||
|
||||
private List<Base> opDivideBy(List<Base> left, List<Base> right) throws PathEngineException {
|
||||
if (left.size() == 0)
|
||||
throw new PathEngineException("Error performing /: left operand has no value");
|
||||
if (left.size() == 0 || right.size() == 0)
|
||||
return new ArrayList<Base>();
|
||||
if (left.size() > 1)
|
||||
throw new PathEngineException("Error performing /: left operand has more than one value");
|
||||
if (!left.get(0).isPrimitive() && !(left.get(0) instanceof Quantity))
|
||||
throw new PathEngineException(String.format("Error performing -: left operand has the wrong type (%s)", left.get(0).fhirType()));
|
||||
if (right.size() == 0)
|
||||
throw new PathEngineException("Error performing /: right operand has no value");
|
||||
if (right.size() > 1)
|
||||
throw new PathEngineException("Error performing /: right operand has more than one value");
|
||||
if (!right.get(0).isPrimitive() && !(right.get(0) instanceof Quantity))
|
||||
|
@ -2033,14 +2121,12 @@ public class FHIRPathEngine {
|
|||
}
|
||||
|
||||
private List<Base> opDiv(List<Base> left, List<Base> right) throws PathEngineException {
|
||||
if (left.size() == 0)
|
||||
throw new PathEngineException("Error performing div: left operand has no value");
|
||||
if (left.size() == 0 || right.size() == 0)
|
||||
return new ArrayList<Base>();
|
||||
if (left.size() > 1)
|
||||
throw new PathEngineException("Error performing div: left operand has more than one value");
|
||||
if (!left.get(0).isPrimitive() && !(left.get(0) instanceof Quantity))
|
||||
throw new PathEngineException(String.format("Error performing div: left operand has the wrong type (%s)", left.get(0).fhirType()));
|
||||
if (right.size() == 0)
|
||||
throw new PathEngineException("Error performing div: right operand has no value");
|
||||
if (right.size() > 1)
|
||||
throw new PathEngineException("Error performing div: right operand has more than one value");
|
||||
if (!right.get(0).isPrimitive() && !(right.get(0) instanceof Quantity))
|
||||
|
@ -2068,14 +2154,12 @@ public class FHIRPathEngine {
|
|||
}
|
||||
|
||||
private List<Base> opMod(List<Base> left, List<Base> right) throws PathEngineException {
|
||||
if (left.size() == 0)
|
||||
throw new PathEngineException("Error performing mod: left operand has no value");
|
||||
if (left.size() == 0 || right.size() == 0)
|
||||
return new ArrayList<Base>();
|
||||
if (left.size() > 1)
|
||||
throw new PathEngineException("Error performing mod: left operand has more than one value");
|
||||
if (!left.get(0).isPrimitive())
|
||||
throw new PathEngineException(String.format("Error performing mod: left operand has the wrong type (%s)", left.get(0).fhirType()));
|
||||
if (right.size() == 0)
|
||||
throw new PathEngineException("Error performing mod: right operand has no value");
|
||||
if (right.size() > 1)
|
||||
throw new PathEngineException("Error performing mod: right operand has more than one value");
|
||||
if (!right.get(0).isPrimitive())
|
||||
|
@ -2140,11 +2224,11 @@ public class FHIRPathEngine {
|
|||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String);
|
||||
else if (s.equals("%us-zip"))
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String);
|
||||
else if (s.startsWith("%\"vs-"))
|
||||
else if (s.startsWith("%`vs-"))
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String);
|
||||
else if (s.startsWith("%\"cs-"))
|
||||
else if (s.startsWith("%`cs-"))
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String);
|
||||
else if (s.startsWith("%\"ext-"))
|
||||
else if (s.startsWith("%`ext-"))
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String);
|
||||
else if (hostServices == null)
|
||||
throw new PathEngineException("Unknown fixed constant type for '"+s+"'");
|
||||
|
@ -2201,7 +2285,7 @@ public class FHIRPathEngine {
|
|||
@SuppressWarnings("unchecked")
|
||||
private TypeDetails evaluateFunctionType(ExecutionTypeContext context, TypeDetails focus, ExpressionNode exp) throws PathEngineException, DefinitionException {
|
||||
List<TypeDetails> paramTypes = new ArrayList<TypeDetails>();
|
||||
if (exp.getFunction() == Function.Is || exp.getFunction() == Function.As)
|
||||
if (exp.getFunction() == Function.Is || exp.getFunction() == Function.As || exp.getFunction() == Function.OfType)
|
||||
paramTypes.add(new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String));
|
||||
else
|
||||
for (ExpressionNode expr : exp.getParameters()) {
|
||||
|
@ -2391,6 +2475,14 @@ public class FHIRPathEngine {
|
|||
checkParamTypes(exp.getFunction().toCode(), paramTypes, new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String));
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, "Extension");
|
||||
}
|
||||
case AnyTrue:
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
|
||||
case AllTrue:
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
|
||||
case AnyFalse:
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
|
||||
case AllFalse:
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
|
||||
case HasValue :
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
|
||||
case HtmlChecks :
|
||||
|
@ -2567,6 +2659,10 @@ public class FHIRPathEngine {
|
|||
case Now : return funcNow(context, focus, exp);
|
||||
case Resolve : return funcResolve(context, focus, exp);
|
||||
case Extension : return funcExtension(context, focus, exp);
|
||||
case AnyFalse: return funcAnyFalse(context, focus, exp);
|
||||
case AllFalse: return funcAllFalse(context, focus, exp);
|
||||
case AnyTrue: return funcAnyTrue(context, focus, exp);
|
||||
case AllTrue: return funcAllTrue(context, focus, exp);
|
||||
case HasValue : return funcHasValue(context, focus, exp);
|
||||
case AliasAs : return funcAliasAs(context, focus, exp);
|
||||
case Alias : return funcAlias(context, focus, exp);
|
||||
|
@ -2759,10 +2855,16 @@ public class FHIRPathEngine {
|
|||
List<Base> result = new ArrayList<Base>();
|
||||
String sw = convertToString(execute(context, focus, exp.getParameters().get(0), true));
|
||||
|
||||
if (focus.size() == 1 && !Utilities.noString(sw))
|
||||
result.add(new BooleanType(convertToString(focus.get(0)).endsWith(sw)).noExtensions());
|
||||
else
|
||||
if (focus.size() == 0)
|
||||
result.add(new BooleanType(false).noExtensions());
|
||||
else if (Utilities.noString(sw))
|
||||
result.add(new BooleanType(true).noExtensions());
|
||||
else {
|
||||
if (focus.size() == 1 && !Utilities.noString(sw))
|
||||
result.add(new BooleanType(convertToString(focus.get(0)).endsWith(sw)).noExtensions());
|
||||
else
|
||||
result.add(new BooleanType(false).noExtensions());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2778,12 +2880,21 @@ public class FHIRPathEngine {
|
|||
if (focus.size() == 1) {
|
||||
if (focus.get(0) instanceof BooleanType)
|
||||
result.add(focus.get(0));
|
||||
else if (focus.get(0) instanceof IntegerType)
|
||||
result.add(new BooleanType(!focus.get(0).primitiveValue().equals("0")).noExtensions());
|
||||
else if (focus.get(0) instanceof StringType) {
|
||||
if ("true".equals(focus.get(0).primitiveValue()))
|
||||
else if (focus.get(0) instanceof IntegerType) {
|
||||
int i = Integer.parseInt(focus.get(0).primitiveValue());
|
||||
if (i == 0)
|
||||
result.add(new BooleanType(false).noExtensions());
|
||||
else if (i == 1)
|
||||
result.add(new BooleanType(true).noExtensions());
|
||||
else if ("false".equals(focus.get(0).primitiveValue()))
|
||||
} else if (focus.get(0) instanceof DecimalType) {
|
||||
if (((DecimalType) focus.get(0)).getValue().compareTo(BigDecimal.ZERO) == 0)
|
||||
result.add(new BooleanType(false).noExtensions());
|
||||
else if (((DecimalType) focus.get(0)).getValue().compareTo(BigDecimal.ONE) == 0)
|
||||
result.add(new BooleanType(true).noExtensions());
|
||||
} else if (focus.get(0) instanceof StringType) {
|
||||
if ("true".equalsIgnoreCase(focus.get(0).primitiveValue()))
|
||||
result.add(new BooleanType(true).noExtensions());
|
||||
else if ("false".equalsIgnoreCase(focus.get(0).primitiveValue()))
|
||||
result.add(new BooleanType(false).noExtensions());
|
||||
}
|
||||
}
|
||||
|
@ -2900,7 +3011,7 @@ public class FHIRPathEngine {
|
|||
List<Base> other = execute(context, focus, exp.getParameters().get(0), true);
|
||||
|
||||
for (Base item : focus) {
|
||||
if (!doContains(result, item) && !doContains(other, item))
|
||||
if (!doContains(other, item))
|
||||
result.add(item);
|
||||
}
|
||||
return result;
|
||||
|
@ -2936,6 +3047,8 @@ public class FHIRPathEngine {
|
|||
n = texp.getName();
|
||||
}
|
||||
if (ns.equals("System")) {
|
||||
if (focus.get(0) instanceof Resource)
|
||||
return makeBoolean(false);
|
||||
if (!(focus.get(0) instanceof Element) || ((Element) focus.get(0)).isDisallowExtensions())
|
||||
return makeBoolean(n.equals(Utilities.capitalize(focus.get(0).fhirType())));
|
||||
else
|
||||
|
@ -2950,10 +3063,21 @@ public class FHIRPathEngine {
|
|||
|
||||
private List<Base> funcAs(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
String tn = exp.getParameters().get(0).getName();
|
||||
for (Base b : focus)
|
||||
if (b.hasType(tn))
|
||||
result.add(b);
|
||||
String tn;
|
||||
if (exp.getParameters().get(0).getInner() != null)
|
||||
tn = exp.getParameters().get(0).getName()+"."+exp.getParameters().get(0).getInner().getName();
|
||||
else
|
||||
tn = "FHIR."+exp.getParameters().get(0).getName();
|
||||
for (Base b : focus) {
|
||||
if (tn.startsWith("System.")) {
|
||||
if (b instanceof Element &&((Element) b).isDisallowExtensions())
|
||||
if (b.hasType(tn.substring(7)))
|
||||
result.add(b);
|
||||
} else if (tn.startsWith("FHIR.")) {
|
||||
if (b.hasType(tn.substring(5)))
|
||||
result.add(b);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -3132,6 +3256,138 @@ public class FHIRPathEngine {
|
|||
return result;
|
||||
}
|
||||
|
||||
private List<Base> funcAllFalse(ExecutionContext context, List<Base> focus, ExpressionNode exp) throws FHIRException {
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
if (exp.getParameters().size() == 1) {
|
||||
boolean all = true;
|
||||
List<Base> pc = new ArrayList<Base>();
|
||||
for (Base item : focus) {
|
||||
pc.clear();
|
||||
pc.add(item);
|
||||
List<Base> res = execute(context, pc, exp.getParameters().get(0), true);
|
||||
if (convertToBoolean(res)) {
|
||||
all = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
result.add(new BooleanType(all).noExtensions());
|
||||
} else {
|
||||
boolean all = true;
|
||||
for (Base item : focus) {
|
||||
boolean v;
|
||||
if (item instanceof BooleanType)
|
||||
v = ((BooleanType) item).booleanValue();
|
||||
else
|
||||
v = item != null;
|
||||
if (v) {
|
||||
all = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
result.add(new BooleanType(all).noExtensions());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Base> funcAnyFalse(ExecutionContext context, List<Base> focus, ExpressionNode exp) throws FHIRException {
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
if (exp.getParameters().size() == 1) {
|
||||
boolean any = false;
|
||||
List<Base> pc = new ArrayList<Base>();
|
||||
for (Base item : focus) {
|
||||
pc.clear();
|
||||
pc.add(item);
|
||||
List<Base> res = execute(context, pc, exp.getParameters().get(0), true);
|
||||
if (!convertToBoolean(res)) {
|
||||
any = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
result.add(new BooleanType(any).noExtensions());
|
||||
} else {
|
||||
boolean any = false;
|
||||
for (Base item : focus) {
|
||||
boolean v;
|
||||
if (item instanceof BooleanType)
|
||||
v = ((BooleanType) item).booleanValue();
|
||||
else
|
||||
v = item != null;
|
||||
if (!v) {
|
||||
any = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
result.add(new BooleanType(any).noExtensions());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Base> funcAllTrue(ExecutionContext context, List<Base> focus, ExpressionNode exp) throws FHIRException {
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
if (exp.getParameters().size() == 1) {
|
||||
boolean all = true;
|
||||
List<Base> pc = new ArrayList<Base>();
|
||||
for (Base item : focus) {
|
||||
pc.clear();
|
||||
pc.add(item);
|
||||
List<Base> res = execute(context, pc, exp.getParameters().get(0), true);
|
||||
if (!convertToBoolean(res)) {
|
||||
all = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
result.add(new BooleanType(all).noExtensions());
|
||||
} else {
|
||||
boolean all = true;
|
||||
for (Base item : focus) {
|
||||
boolean v;
|
||||
if (item instanceof BooleanType)
|
||||
v = ((BooleanType) item).booleanValue();
|
||||
else
|
||||
v = item != null;
|
||||
if (!v) {
|
||||
all = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
result.add(new BooleanType(all).noExtensions());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Base> funcAnyTrue(ExecutionContext context, List<Base> focus, ExpressionNode exp) throws FHIRException {
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
if (exp.getParameters().size() == 1) {
|
||||
boolean any = false;
|
||||
List<Base> pc = new ArrayList<Base>();
|
||||
for (Base item : focus) {
|
||||
pc.clear();
|
||||
pc.add(item);
|
||||
List<Base> res = execute(context, pc, exp.getParameters().get(0), true);
|
||||
if (convertToBoolean(res)) {
|
||||
any = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
result.add(new BooleanType(any).noExtensions());
|
||||
} else {
|
||||
boolean any = false;
|
||||
for (Base item : focus) {
|
||||
boolean v;
|
||||
if (item instanceof BooleanType)
|
||||
v = ((BooleanType) item).booleanValue();
|
||||
else
|
||||
v = item != null;
|
||||
if (v) {
|
||||
any = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
result.add(new BooleanType(any).noExtensions());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Base> funcTrace(ExecutionContext context, List<Base> focus, ExpressionNode exp) throws FHIRException {
|
||||
List<Base> nl = execute(context, focus, exp.getParameters().get(0), true);
|
||||
String name = nl.get(0).primitiveValue();
|
||||
|
@ -3181,14 +3437,17 @@ public class FHIRPathEngine {
|
|||
List<Base> result = new ArrayList<Base>();
|
||||
String sw = convertToString(execute(context, focus, exp.getParameters().get(0), true));
|
||||
|
||||
if (focus.size() == 1 && !Utilities.noString(sw)) {
|
||||
if (focus.size() != 1) {
|
||||
result.add(new BooleanType(false).noExtensions());
|
||||
} else if (Utilities.noString(sw)) {
|
||||
result.add(new BooleanType(true).noExtensions());
|
||||
} else {
|
||||
String st = convertToString(focus.get(0));
|
||||
if (Utilities.noString(st))
|
||||
result.add(new BooleanType(false).noExtensions());
|
||||
else
|
||||
result.add(new BooleanType(st.contains(sw)).noExtensions());
|
||||
} else
|
||||
result.add(new BooleanType(false).noExtensions());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -3214,15 +3473,17 @@ public class FHIRPathEngine {
|
|||
List<Base> result = new ArrayList<Base>();
|
||||
String sw = convertToString(execute(context, focus, exp.getParameters().get(0), true));
|
||||
|
||||
if (focus.size() == 1 && !Utilities.noString(sw)) {
|
||||
if (focus.size() == 0) {
|
||||
result.add(new BooleanType(false).noExtensions());
|
||||
} else if (Utilities.noString(sw)) {
|
||||
result.add(new BooleanType(true).noExtensions());
|
||||
} else {
|
||||
String s = convertToString(focus.get(0));
|
||||
if (s == null)
|
||||
result.add(new BooleanType(false).noExtensions());
|
||||
else
|
||||
result.add(new BooleanType(s.startsWith(sw)).noExtensions());
|
||||
}
|
||||
else
|
||||
result.add(new BooleanType(false).noExtensions());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -3312,12 +3573,14 @@ public class FHIRPathEngine {
|
|||
List<Base> result = new ArrayList<Base>();
|
||||
if (focus.size() != 1)
|
||||
result.add(new BooleanType(false).noExtensions());
|
||||
else if (focus.get(0) instanceof IntegerType && ((IntegerType) focus.get(0)).getValue() >= 0)
|
||||
result.add(new BooleanType(true).noExtensions());
|
||||
else if (focus.get(0) instanceof IntegerType)
|
||||
result.add(new BooleanType(((IntegerType) focus.get(0)).getValue() >= 0 && ((IntegerType) focus.get(0)).getValue() <= 1).noExtensions());
|
||||
else if (focus.get(0) instanceof DecimalType)
|
||||
result.add(new BooleanType(((DecimalType) focus.get(0)).getValue().compareTo(BigDecimal.ZERO) == 0 || ((DecimalType) focus.get(0)).getValue().compareTo(BigDecimal.ONE) == 0).noExtensions());
|
||||
else if (focus.get(0) instanceof BooleanType)
|
||||
result.add(new BooleanType(true).noExtensions());
|
||||
else if (focus.get(0) instanceof StringType)
|
||||
result.add(new BooleanType(Utilities.existsInList(convertToString(focus.get(0)), "true", "false")).noExtensions());
|
||||
result.add(new BooleanType(Utilities.existsInList(convertToString(focus.get(0)).toLowerCase(), "true", "false")).noExtensions());
|
||||
else
|
||||
result.add(new BooleanType(false).noExtensions());
|
||||
return result;
|
||||
|
@ -3385,6 +3648,8 @@ public class FHIRPathEngine {
|
|||
result.add(new BooleanType(true).noExtensions());
|
||||
else if (focus.get(0) instanceof Quantity)
|
||||
result.add(new BooleanType(true).noExtensions());
|
||||
else if (focus.get(0) instanceof BooleanType)
|
||||
result.add(new BooleanType(true).noExtensions());
|
||||
else if (focus.get(0) instanceof StringType) {
|
||||
Quantity q = parseQuantityString(focus.get(0).primitiveValue());
|
||||
result.add(new BooleanType(q != null).noExtensions());
|
||||
|
|
|
@ -149,7 +149,7 @@ public class FHIRPathTests {
|
|||
fp.setHostServices(new FHIRPathTestEvaluationServices());
|
||||
String input = test.getAttribute("inputfile");
|
||||
String expression = XMLUtil.getNamedChild(test, "expression").getTextContent();
|
||||
boolean fail = "true".equals(XMLUtil.getNamedChild(test, "expression").getAttribute("invalid"));
|
||||
boolean fail = Utilities.existsInList(XMLUtil.getNamedChild(test, "expression").getAttribute("invalid"), "true", "semantic");
|
||||
Resource res = null;
|
||||
|
||||
List<Base> outcome = new ArrayList<Base>();
|
||||
|
@ -182,20 +182,38 @@ public class FHIRPathTests {
|
|||
|
||||
List<Element> expected = new ArrayList<Element>();
|
||||
XMLUtil.getNamedChildren(test, "output", expected);
|
||||
Assert.assertTrue(String.format("Expected %d objects but found %d", expected.size(), outcome.size()), outcome.size() == expected.size());
|
||||
for (int i = 0; i < Math.min(outcome.size(), expected.size()); i++) {
|
||||
String tn = expected.get(i).getAttribute("type");
|
||||
if (!Utilities.noString(tn)) {
|
||||
Assert.assertTrue(String.format("Outcome %d: Type should be %s but was %s", i, tn, outcome.get(i).fhirType()), tn.equals(outcome.get(i).fhirType()));
|
||||
Assert.assertTrue(String.format("Expected %d objects but found %d for expression %s", expected.size(), outcome.size(), expression), outcome.size() == expected.size());
|
||||
if ("false".equals(test.getAttribute("ordered"))) {
|
||||
for (int i = 0; i < Math.min(outcome.size(), expected.size()); i++) {
|
||||
String tn = outcome.get(i).fhirType();
|
||||
String s;
|
||||
if (outcome.get(i) instanceof Quantity)
|
||||
s = fp.convertToString(outcome.get(i));
|
||||
else
|
||||
s = ((PrimitiveType) outcome.get(i)).asStringValue();
|
||||
boolean found = false;
|
||||
for (Element e : expected) {
|
||||
if ((Utilities.noString(e.getAttribute("type")) || e.getAttribute("type").equals(tn)) &&
|
||||
(Utilities.noString(e.getTextContent()) || e.getTextContent().equals(s)))
|
||||
found = true;
|
||||
}
|
||||
Assert.assertTrue(String.format("Outcome %d: Value %s of type %s not expected for %s", i, s, tn, expression), found);
|
||||
}
|
||||
String v = expected.get(i).getTextContent();
|
||||
if (!Utilities.noString(v)) {
|
||||
if (outcome.get(i) instanceof Quantity) {
|
||||
Quantity q = fp.parseQuantityString(v);
|
||||
Assert.assertTrue(String.format("Outcome %d: Value should be %s but was %s", i, v, outcome.get(i).toString()), outcome.get(i).equalsDeep(q));
|
||||
} else {
|
||||
Assert.assertTrue(String.format("Outcome %d: Value should be a primitive type but was %s", i, outcome.get(i).fhirType()), outcome.get(i) instanceof PrimitiveType);
|
||||
Assert.assertTrue(String.format("Outcome %d: Value should be %s but was %s", i, v, outcome.get(i).toString()), v.equals(((PrimitiveType)outcome.get(i)).asStringValue()));
|
||||
} else {
|
||||
for (int i = 0; i < Math.min(outcome.size(), expected.size()); i++) {
|
||||
String tn = expected.get(i).getAttribute("type");
|
||||
if (!Utilities.noString(tn)) {
|
||||
Assert.assertTrue(String.format("Outcome %d: Type should be %s but was %s", i, tn, outcome.get(i).fhirType()), tn.equals(outcome.get(i).fhirType()));
|
||||
}
|
||||
String v = expected.get(i).getTextContent();
|
||||
if (!Utilities.noString(v)) {
|
||||
if (outcome.get(i) instanceof Quantity) {
|
||||
Quantity q = fp.parseQuantityString(v);
|
||||
Assert.assertTrue(String.format("Outcome %d: Value should be %s but was %s", i, v, outcome.get(i).toString()), outcome.get(i).equalsDeep(q));
|
||||
} else {
|
||||
Assert.assertTrue(String.format("Outcome %d: Value should be a primitive type but was %s", i, outcome.get(i).fhirType()), outcome.get(i) instanceof PrimitiveType);
|
||||
Assert.assertTrue(String.format("Outcome %d: Value should be %s but was %s for expression %s", i, v, outcome.get(i).toString(), expression), v.equals(((PrimitiveType)outcome.get(i)).asStringValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,10 +46,18 @@
|
|||
<output type="string">Peter</output>
|
||||
<output type="string">James</output>
|
||||
</test>
|
||||
<test name="testSimpleBackTick1" inputfile="patient-example.xml">
|
||||
<expression>`Patient`.name.`given`</expression>
|
||||
<output type="string">Peter</output>
|
||||
<output type="string">James</output>
|
||||
<output type="string">Jim</output>
|
||||
<output type="string">Peter</output>
|
||||
<output type="string">James</output>
|
||||
</test>
|
||||
|
||||
<!-- testWrong(patient(), "name.given1"); -->
|
||||
<test name="testSimpleFail" inputfile="patient-example.xml">
|
||||
<expression invalid="true">name.given1</expression>
|
||||
<test name="testSimpleFail" inputfile="patient-example.xml" mode="strict">
|
||||
<expression invalid="semantic">name.given1</expression>
|
||||
</test>
|
||||
|
||||
<!-- test(patient(), "Patient.name.given", 3, "string"); -->
|
||||
|
@ -63,8 +71,8 @@
|
|||
</test>
|
||||
|
||||
<!-- testWrong(patient(), "Encounter.name.given"); -->
|
||||
<test name="testSimpleWithWrongContext" inputfile="patient-example.xml">
|
||||
<expression invalid="true">Encounter.name.given</expression>
|
||||
<test name="testSimpleWithWrongContext" inputfile="patient-example.xml" mode="strict">
|
||||
<expression invalid="semantic">Encounter.name.given</expression>
|
||||
</test>
|
||||
</group>
|
||||
|
||||
|
@ -72,12 +80,12 @@
|
|||
<!-- test(observation(), "Observation.value.unit", 1, "string"); -->
|
||||
<test name="testPolymorphismA" inputfile="observation-example.xml">
|
||||
<expression>Observation.value.unit</expression>
|
||||
<output type="string"></output>
|
||||
<output type="string">lbs</output>
|
||||
</test>
|
||||
|
||||
<!-- testWrong(observation(), "Observation.valueQuantity.unit"); -->
|
||||
<test name="testPolymorphismB" inputfile="observation-example.xml">
|
||||
<expression invalid="true">Observation.valueQuantity.unit</expression>
|
||||
<test name="testPolymorphismB" inputfile="observation-example.xml" mode="strict">
|
||||
<expression invalid="semantic">Observation.valueQuantity.unit</expression>
|
||||
</test>
|
||||
|
||||
<!-- testBoolean(observation(), "Observation.value.is(Quantity)", true); -->
|
||||
|
@ -109,8 +117,8 @@
|
|||
</test>
|
||||
|
||||
<!-- testWrong(observation(), "(Observation.value as Period).unit"); -->
|
||||
<test name="testPolymorphismAsB" inputfile="observation-example.xml">
|
||||
<expression invalid="true">(Observation.value as Period).unit</expression>
|
||||
<test name="testPolymorphismAsB" inputfile="observation-example.xml" mode="strict">
|
||||
<expression invalid="semantic">(Observation.value as Period).unit</expression>
|
||||
</test>
|
||||
|
||||
<!-- test(observation(), "Observation.value.as(Period).start", 0); -->
|
||||
|
@ -146,8 +154,8 @@
|
|||
</test>
|
||||
|
||||
<!-- testWrong(patient(), "Patient.children().skip(1)"); -->
|
||||
<test name="testDollarOrderNotAllowed" inputfile="patient-example.xml">
|
||||
<expression invalid="true">Patient.children().skip(1)</expression>
|
||||
<test name="testDollarOrderNotAllowed" inputfile="patient-example.xml" mode="strict">
|
||||
<expression invalid="semantic">Patient.children().skip(1)</expression>
|
||||
</test>
|
||||
</group>
|
||||
|
||||
|
@ -172,12 +180,12 @@
|
|||
|
||||
<test name="testLiteralInteger" inputfile="patient-example.xml"><expression>1.convertsToInteger()</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralInteger" inputfile="patient-example.xml"><expression>0.convertsToInteger()</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralInteger" inputfile="patient-example.xml"><expression>-1.convertsToInteger()</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralInteger" inputfile="patient-example.xml"><expression>-1.convertsToInteger()</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralInteger" inputfile="patient-example.xml"><expression>(-1).convertsToInteger()</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralInteger" inputfile="patient-example.xml"><expression invalid="true">-1.convertsToInteger()</expression></test>
|
||||
<test name="testLiteralInteger" inputfile="patient-example.xml"><expression>2147483647.convertsToInteger()</expression><output type="boolean">true</output></test>
|
||||
|
||||
<test name="testLiteralString" inputfile="patient-example.xml"><expression>'test'.convertsToString()</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralString" inputfile="patient-example.xml"><expression>'\\\/\f\r\n\t\"\"\'\u002a'.convertsToString()</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralString" inputfile="patient-example.xml"><expression>'\\\/\f\r\n\t\"\`\'\u002a'.convertsToString()</expression><output type="boolean">true</output></test>
|
||||
|
||||
<test name="testLiteralBoolean" inputfile="patient-example.xml"><expression>true.convertsToBoolean()</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralBoolean" inputfile="patient-example.xml"><expression>false.convertsToBoolean()</expression><output type="boolean">true</output></test>
|
||||
|
@ -185,7 +193,8 @@
|
|||
<test name="testLiteralDecimal" inputfile="patient-example.xml"><expression>1.0.convertsToDecimal()</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralDecimal" inputfile="patient-example.xml"><expression>0.1.convertsToDecimal()</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralDecimal" inputfile="patient-example.xml"><expression>0.0.convertsToDecimal()</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralDecimal" inputfile="patient-example.xml"><expression>-0.1.convertsToDecimal()</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralDecimal" inputfile="patient-example.xml"><expression>(-0.1).convertsToDecimal()</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralDecimal" inputfile="patient-example.xml"><expression invalid="true">-0.1.convertsToDecimal()</expression></test>
|
||||
<test name="testLiteralDecimal" inputfile="patient-example.xml"><expression>1234567890987654321.0.convertsToDecimal()</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralDecimal" inputfile="patient-example.xml"><expression>0.000000000000000000000000000001.convertsToDecimal()</expression><output type="boolean">true</output></test>
|
||||
|
||||
|
@ -206,6 +215,7 @@
|
|||
|
||||
<test name="testLiteralInteger" inputfile="patient-example.xml"><expression>-3 != 3</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralInteger" inputfile="patient-example.xml"><expression>Patient.name.given.count() = 5</expression><output type="boolean">true</output></test>
|
||||
<test name="testPolarityPrecedence" inputfile="patient-example.xml"><expression>-Patient.name.given.count() = -5</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralInteger" inputfile="patient-example.xml"><expression>Patient.name.given.count() > -3</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralInteger" inputfile="patient-example.xml"><expression>Patient.name.given.count() != 0</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralInteger" inputfile="patient-example.xml"><expression>1 < 2</expression><output type="boolean">true</output></test>
|
||||
|
@ -217,7 +227,7 @@
|
|||
<test name="testLiteralDecimal" inputfile="observation-example.xml"><expression>Observation.value.value > 0.0</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralDecimal" inputfile="observation-example.xml"><expression>Observation.value.value > 0</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralDecimal" inputfile="observation-example.xml"><expression>Observation.value.value < 190</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralDecimal" inputfile="observation-example.xml"><expression>Observation.value.value < 'test'</expression><!-- no output - empty set --></test>
|
||||
<test name="testLiteralDecimal" inputfile="observation-example.xml"><expression invalid="semantic">Observation.value.value < 'test'</expression><!-- no output - empty set --></test>
|
||||
|
||||
<test name="testLiteralDate" inputfile="patient-example.xml"><expression>Patient.birthDate = @1974-12-25</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralDate" inputfile="patient-example.xml"><expression>Patient.birthDate != @1974-12-25T12:34:00</expression><output type="boolean">true</output></test>
|
||||
|
@ -232,18 +242,19 @@
|
|||
<test name="testLiteralDateTZ" inputfile="patient-example.xml"><expression>@2017-11-05T01:30:00.0-04:00 > @2017-11-05T01:15:00.0-05:00</expression><output type="boolean">false</output></test>
|
||||
<test name="testLiteralDateTZ" inputfile="patient-example.xml"><expression>@2017-11-05T01:30:00.0-04:00 < @2017-11-05T01:15:00.0-05:00</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralDateTZ" inputfile="patient-example.xml"><expression>@2017-11-05T01:30:00.0-04:00 = @2017-11-05T01:15:00.0-05:00</expression><output type="boolean">false</output></test>
|
||||
<test name="testLiteralDateTZ" inputfile="patient-example.xml"><expression>@2017-11-05T01:30:00.0-04:00 = @2017-11-05T00:30:00.0-05:00</expression><output type="boolean">false</output></test>
|
||||
<test name="testLiteralDateTZ" inputfile="patient-example.xml"><expression>@2017-11-05T01:30:00.0-04:00 = @2017-11-05T00:30:00.0-05:00</expression><output type="boolean">true</output></test>
|
||||
|
||||
<test name="testLiteralUnicode" inputfile="patient-example.xml"><expression>Patient.name.given.first() = 'P\u0065ter'</expression><output type="boolean">true</output></test>
|
||||
|
||||
<test name="testLiteralEmptyCollection" inputfile="patient-example.xml"><expression>Patient.name.given != {}</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralEmptyCollection" inputfile="patient-example.xml"><expression>Patient.name.given.empty().not()</expression><output type="boolean">true</output></test>
|
||||
<test name="testLiteralEmptyCollection" inputfile="patient-example.xml"><expression>Patient.name.given != {}</expression></test>
|
||||
|
||||
<test name="testExpressions" inputfile="patient-example.xml"><expression>Patient.name.select(given | family).distinct()</expression>
|
||||
<output type="string"></output>
|
||||
<output type="string"></output>
|
||||
<output type="string"></output>
|
||||
<output type="string"></output>
|
||||
<output type="string"></output>
|
||||
<test name="testExpressions" inputfile="patient-example.xml" ordered="false"><expression>Patient.name.select(given | family).distinct()</expression>
|
||||
<output type="string">Peter</output>
|
||||
<output type="string">James</output>
|
||||
<output type="string">Chalmers</output>
|
||||
<output type="string">Jim</output>
|
||||
<output type="string">Windsor</output>
|
||||
</test>
|
||||
<test name="testExpressions" inputfile="patient-example.xml"><expression>Patient.name.given.count() = 1 + 4</expression><output type="boolean">true</output></test>
|
||||
|
||||
|
@ -271,7 +282,8 @@
|
|||
|
||||
<test name="test" inputfile="patient-example.xml"><expression>1.toInteger() = 1</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>'1'.toInteger() = 1</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>'1.1'.toInteger() = {}</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>'1.1'.toInteger() = {}</expression></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>'1.1'.toInteger().empty()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>true.toInteger() = 1</expression><output type="boolean">true</output></test>
|
||||
|
||||
<test name="test" inputfile="patient-example.xml"><expression>1.convertsToDecimal()</expression><output type="boolean">true</output></test>
|
||||
|
@ -286,7 +298,7 @@
|
|||
<test name="test" inputfile="patient-example.xml"><expression>true.convertsToDecimal()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>true.is(Decimal).not()</expression><output type="boolean">true</output></test>
|
||||
|
||||
<test name="test" inputfile="patient-example.xml"><expression>1.toDecimal() != 1.0</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>1.toDecimal() = 1.0</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>1.toDecimal() ~ 1.0</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>1.0.toDecimal() = 1.0</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>'1.1'.toDecimal() = 1.1</expression><output type="boolean">true</output></test>
|
||||
|
@ -304,7 +316,7 @@
|
|||
<test name="test" inputfile="patient-example.xml"><expression>'1.a'.convertsToQuantity().not()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>'1.0'.convertsToQuantity()</expression><output type="boolean">true</output></test>
|
||||
<!-- <test name="test" inputfile="patient-example.xml"><expression>'1.0'.is(System.Quantity).not()</expression><output type="boolean">true</output></test> -->
|
||||
<test name="test" inputfile="patient-example.xml"><expression>true.convertsToQuantity()</expression><output type="boolean">false</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>true.convertsToQuantity()</expression><output type="boolean">true</output></test>
|
||||
<!-- <test name="test" inputfile="patient-example.xml"><expression>true.is(System.Quantity).not()</expression><output type="boolean">true</output></test> -->
|
||||
|
||||
<test name="test" inputfile="patient-example.xml"><expression>1.toQuantity() = 1 '1'</expression><output type="boolean">true</output></test>
|
||||
|
@ -316,41 +328,45 @@
|
|||
<test name="test" inputfile="patient-example.xml"><expression>'1.0'.toQuantity() ~ 1 '1'</expression><output type="boolean">true</output></test>
|
||||
|
||||
<test name="test" inputfile="patient-example.xml"><expression>1.convertsToBoolean()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>2.convertsToBoolean()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>-1.convertsToBoolean().not()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>2.convertsToBoolean()</expression><output type="boolean">false</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>(-1).convertsToBoolean()</expression><output type="boolean">false</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>0.convertsToBoolean()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>1.0.convertsToBoolean().not()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>1.0.convertsToBoolean()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>'true'.convertsToBoolean()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>'false'.convertsToBoolean()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>'False'.convertsToBoolean().not()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>'False'.convertsToBoolean()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>true.convertsToBoolean()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>false.convertsToBoolean()</expression><output type="boolean">true</output></test>
|
||||
|
||||
<test name="test" inputfile="patient-example.xml"><expression>1.toBoolean()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>2.toBoolean()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>2.toBoolean()</expression><!-- empty --></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>0.toBoolean()</expression><output type="boolean">false</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>'true'.toBoolean()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>'false'.toBoolean()</expression><output type="boolean">false</output></test>
|
||||
|
||||
<test name="test" inputfile="patient-example.xml"><expression>1.convertsToString()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>1.is(String).not()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>-1.convertsToString()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>(-1).convertsToString()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>1.0.convertsToString()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>'true'.convertsToString()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>true.convertsToString()</expression><output type="boolean">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>1 'wk'.convertsToString()</expression><output type="boolean">true</output></test>
|
||||
|
||||
<test name="test" inputfile="patient-example.xml"><expression>1.toString()</expression><output type="string">1</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>-1.toString()</expression><output type="string">-1</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>(-1).toString()</expression><output type="string">-1</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>1.0.toString()</expression><output type="string">1.0</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>'true'.toString()</expression><output type="string">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>true.toString()</expression><output type="string">true</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>1 'wk'.toString()</expression><output type="string">1 week</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>1 'wk'.toString()</expression><output type="string">1 'wk'</output></test>
|
||||
<test name="test" inputfile="patient-example.xml"><expression>1 week.toString()</expression><output type="string">1 'wk'</output></test>
|
||||
|
||||
</group>
|
||||
|
||||
<group name="testAll">
|
||||
<test inputfile="patient-example.xml"><expression>Patient.name.select(given.exists()).all()</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>Patient.name.select(family.exists()).all()</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>Patient.name.select(given.exists()).allTrue()</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>Patient.name.select(period.exists()).allTrue()</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>Patient.name.all(given.exists())</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>Patient.name.all(period.exists())</expression><output type="boolean">false</output></test>
|
||||
</group>
|
||||
|
||||
<group name="testSubSetOf">
|
||||
|
@ -382,6 +398,8 @@
|
|||
<test inputfile="patient-example.xml"><expression>iif({}, true, false)</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>iif(true, true, false)</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>iif({} | true, true, false)</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>iif(true, true, 1/0)</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>iif(false, 1/0, true)</expression><output type="boolean">true</output></test>
|
||||
</group>
|
||||
|
||||
|
||||
|
@ -398,23 +416,13 @@
|
|||
</test>
|
||||
|
||||
<test inputfile="questionnaire-example.xml">
|
||||
<expression>Questionnaire.descendants().linkId.distinct()</expression>
|
||||
<output type="string"></output>
|
||||
<output type="string"></output>
|
||||
<output type="string"></output>
|
||||
<output type="string"></output>
|
||||
<output type="string"></output>
|
||||
<output type="string"></output>
|
||||
<output type="string"></output>
|
||||
<output type="string"></output>
|
||||
<output type="string"></output>
|
||||
<output type="string"></output>
|
||||
<expression>Questionnaire.descendants().linkId.distinct().count()</expression>
|
||||
<output type="integer">10</output>
|
||||
</test>
|
||||
|
||||
<test inputfile="questionnaire-example.xml">
|
||||
<expression>Questionnaire.descendants().linkId.select(substring(0,1)).distinct()</expression>
|
||||
<output type="string"></output>
|
||||
<output type="string"></output>
|
||||
<expression>Questionnaire.descendants().linkId.select(substring(0,1)).distinct().count()</expression>
|
||||
<output type="integer">2</output>
|
||||
</test>
|
||||
</group>
|
||||
|
||||
|
@ -458,7 +466,7 @@
|
|||
|
||||
<group name="testSingle">
|
||||
<test inputfile="patient-example.xml"><expression>Patient.name.first().single().exists()</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression invalid="true">Patient.name.single().exists()</expression></test>
|
||||
<test inputfile="patient-example.xml"><expression invalid="semantic">Patient.name.single().exists()</expression></test>
|
||||
</group>
|
||||
|
||||
<group name="testFirstLast">
|
||||
|
@ -543,7 +551,7 @@
|
|||
<test inputfile="patient-example.xml"><expression>'12345'.startsWith('13') = false</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'12345'.startsWith('12345') = true</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'12345'.startsWith('123456') = false</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'12345'.startsWith('') = false</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'12345'.startsWith('') = true</expression><output type="boolean">true</output></test>
|
||||
</group>
|
||||
|
||||
<group name="testEndsWith">
|
||||
|
@ -553,7 +561,7 @@
|
|||
<test inputfile="patient-example.xml"><expression>'12345'.endsWith('35') = false</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'12345'.endsWith('12345') = true</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'12345'.endsWith('012345') = false</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'12345'.endsWith('') = false</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'12345'.endsWith('') = true</expression><output type="boolean">true</output></test>
|
||||
</group>
|
||||
|
||||
<group name="testContainsString">
|
||||
|
@ -563,7 +571,7 @@
|
|||
<test inputfile="patient-example.xml"><expression>'12345'.contains('35') = false</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'12345'.contains('12345') = true</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'12345'.contains('012345') = false</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'12345'.contains('') = false</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'12345'.contains('') = true</expression><output type="boolean">true</output></test>
|
||||
</group>
|
||||
|
||||
<group name="testLength">
|
||||
|
@ -591,46 +599,49 @@
|
|||
|
||||
<group name="testEquality">
|
||||
<test inputfile="patient-example.xml"><expression>1 = 1</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>{} = {}</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>{} = {}</expression></test>
|
||||
<test inputfile="patient-example.xml"><expression>true = {}</expression></test>
|
||||
<test inputfile="patient-example.xml"><expression>1 = 2</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'a' = 'a'</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'a' = 'A'</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'a' = 'b'</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>1.1 = 1.1</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>1.1 = 1.2</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>1.10 = 1.1</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>1.10 = 1.1</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>0 = 0</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>0.0 = 0</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>0.0 = 0</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>@2012-04-15 = @2012-04-15</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>@2012-04-15 = @2012-04-16</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>@2012-04-15 = @2012-04-15T10:00:00</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>name = name</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>name.take(2) = name.take(2).first() | name.take(2).last()</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>name.take(2) = name.take(2).last() | name.take(2).first()</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="observation-example.xml"><expression>Observation.value = 185 '[lb_av]'</expression><output type="boolean">true</output></test>
|
||||
</group>
|
||||
|
||||
<group name="testNEquality">
|
||||
<test inputfile="patient-example.xml"><expression>1 != 1</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>{} != {}</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>{} != {}</expression></test>
|
||||
<test inputfile="patient-example.xml"><expression>1 != 2</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'a' != 'a'</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'a' != 'b'</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>1.1 != 1.1</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>1.1 != 1.2</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>1.10 != 1.1</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>1.10 != 1.1</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>0 != 0</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>0.0 != 0</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>0.0 != 0</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>@2012-04-15 != @2012-04-15</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>@2012-04-15 != @2012-04-16</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>@2012-04-15 != @2012-04-15T10:00:00</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>name != name</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>name.take(2) != name.take(2).first() | name.take(2).last()</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>name.take(2) != name.take(2).last() | name.take(2).first()</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="observation-example.xml"><expression>Observation.value != 185 'kg'</expression><output type="boolean">true</output></test>
|
||||
</group>
|
||||
|
||||
<group name="testEquivalent">
|
||||
<test inputfile="patient-example.xml"><expression>1 ~ 1</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>{} ~ {}</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>{} ~ {}</expression></test>
|
||||
<test inputfile="patient-example.xml"><expression>1 ~ 2</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'a' ~ 'a'</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'a' ~ 'A'</expression><output type="boolean">true</output></test>
|
||||
|
@ -646,11 +657,12 @@
|
|||
<!-- <test inputfile="patient-example.xml"><expression>name ~ name</expression><output type="boolean">true</output></test> -->
|
||||
<test inputfile="patient-example.xml"><expression>name.take(2).given ~ name.take(2).first().given | name.take(2).last().given</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>name.take(2).given ~ name.take(2).last().given | name.take(2).first().given</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="observation-example.xml"><expression>Observation.value ~ 185 '[lb_av]'</expression><output type="boolean">true</output></test>
|
||||
</group>
|
||||
|
||||
<group name="testNotEquivalent">
|
||||
<test inputfile="patient-example.xml"><expression>1 !~ 1</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>{} !~ {}</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>{} !~ {}</expression></test>
|
||||
<test inputfile="patient-example.xml"><expression>1 !~ 2</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'a' !~ 'a'</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'a' !~ 'A'</expression><output type="boolean">false</output></test>
|
||||
|
@ -666,6 +678,8 @@
|
|||
<!-- <test inputfile="patient-example.xml"><expression>name !~ name</expression><output type="boolean">true</output></test> -->
|
||||
<test inputfile="patient-example.xml"><expression>name.take(2).given !~ name.take(2).first().given | name.take(2).last().given</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>name.take(2).given !~ name.take(2).last().given | name.take(2).first().given</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="observation-example.xml"><expression>Observation.value !~ 185 'kg'</expression><output type="boolean">true</output></test>
|
||||
|
||||
</group>
|
||||
|
||||
<group name="testLessThan">
|
||||
|
@ -692,6 +706,8 @@
|
|||
<test inputfile="patient-example.xml"><expression>@2014-12-13 < @2014-12-12</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>@2014-12-13T12:00:01 < @2014-12-13T12:00:00</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>@T12:00:01 < @T12:00:00</expression><output type="boolean">false</output></test>
|
||||
|
||||
<test inputfile="observation-example.xml"><expression>Observation.value < 200 '[lb_av]'</expression><output type="boolean">true</output></test>
|
||||
</group>
|
||||
|
||||
<group name="testLessOrEqual">
|
||||
|
@ -718,6 +734,7 @@
|
|||
<test inputfile="patient-example.xml"><expression>@2014-12-13 <= @2014-12-12</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>@2014-12-13T12:00:01 <= @2014-12-13T12:00:00</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>@T12:00:01 <= @T12:00:00</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="observation-example.xml"><expression>Observation.value <= 200 '[lb_av]'</expression><output type="boolean">true</output></test>
|
||||
</group>
|
||||
|
||||
<group name="testGreatorOrEqual">
|
||||
|
@ -744,9 +761,11 @@
|
|||
<test inputfile="patient-example.xml"><expression>@2014-12-13 >= @2014-12-12</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>@2014-12-13T12:00:01 >= @2014-12-13T12:00:00</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>@T12:00:01 >= @T12:00:00</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="observation-example.xml"><expression>Observation.value >= 100 '[lb_av]'</expression><output type="boolean">true</output></test>
|
||||
|
||||
</group>
|
||||
|
||||
<group name="testGreatorThan">
|
||||
<group name="testGreaterThan">
|
||||
<test inputfile="patient-example.xml"><expression>1 > 2</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>1.0 > 1.2</expression><output type="boolean">false</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'a' > 'b'</expression><output type="boolean">false</output></test>
|
||||
|
@ -770,6 +789,7 @@
|
|||
<test inputfile="patient-example.xml"><expression>@2014-12-13 > @2014-12-12</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>@2014-12-13T12:00:01 > @2014-12-13T12:00:00</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>@T12:00:01 > @T12:00:00</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="observation-example.xml"><expression>Observation.value > 100 '[lb_av]'</expression><output type="boolean">true</output></test>
|
||||
</group>
|
||||
|
||||
<group name="testUnion">
|
||||
|
@ -785,8 +805,8 @@
|
|||
|
||||
<group name="testIntersect">
|
||||
<test inputfile="patient-example.xml"><expression>(1 | 2 | 3).intersect(2 | 4) = 2</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(1 | 2).intersect(4) = {}</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(1 | 2).intersect({}) = {}</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(1 | 2).intersect(4).empty()</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(1 | 2).intersect({}).empty()</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>1.combine(1).intersect(1).count() = 1</expression><output type="boolean">true</output></test> <!-- do not merge duplicates -->
|
||||
</group>
|
||||
|
||||
|
@ -794,7 +814,7 @@
|
|||
<test inputfile="patient-example.xml"><expression>(1 | 2 | 3).exclude(2 | 4) = 1 | 3</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(1 | 2).exclude(4) = 1 | 2</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(1 | 2).exclude({}) = 1 | 2</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>1.combine(1).exclude(2).count() = 1</expression><output type="boolean">true</output></test> <!-- do not merge duplicates -->
|
||||
<test inputfile="patient-example.xml"><expression>1.combine(1).exclude(2).count() = 2</expression><output type="boolean">true</output></test> <!-- do not merge duplicates -->
|
||||
</group>
|
||||
|
||||
<group name="testIn">
|
||||
|
@ -814,15 +834,15 @@
|
|||
<group name="testBooleanLogicAnd">
|
||||
<test inputfile="patient-example.xml"><expression>(true and true) = true</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(true and false) = false</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(true and {}) = {}</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(true and {}).empty()</expression><output type="boolean">true</output></test>
|
||||
|
||||
<test inputfile="patient-example.xml"><expression>(false and true) = false</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(false and false) = false</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(false and {}) = false</expression><output type="boolean">true</output></test>
|
||||
|
||||
<test inputfile="patient-example.xml"><expression>({} and true) = {}</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>({} and true).empty()</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>({} and false) = false</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>({} and {}) = {}</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>({} and {}).empty()</expression><output type="boolean">true</output></test>
|
||||
</group>
|
||||
|
||||
<group name="testBooleanLogicOr">
|
||||
|
@ -832,39 +852,39 @@
|
|||
|
||||
<test inputfile="patient-example.xml"><expression>(false or true) = true</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(false or false) = false</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(false or {}) = {}</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(false or {}).empty()</expression><output type="boolean">true</output></test>
|
||||
|
||||
<test inputfile="patient-example.xml"><expression>({} or true) = true</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>({} or false) = {}</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>({} or {}) = {}</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>({} or false).empty()</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>({} or {}).empty()</expression><output type="boolean">true</output></test>
|
||||
</group>
|
||||
|
||||
<group name="testBooleanLogicXOr">
|
||||
<test inputfile="patient-example.xml"><expression>(true xor true) = false</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(true xor false) = true</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(true xor {}) = {}</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(true xor {}).empty()</expression><output type="boolean">true</output></test>
|
||||
|
||||
<test inputfile="patient-example.xml"><expression>(false xor true) = true</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(false xor false) = false</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(false xor {}) = {}</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(false xor {}).empty()</expression><output type="boolean">true</output></test>
|
||||
|
||||
<test inputfile="patient-example.xml"><expression>({} xor true) = {}</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>({} xor false) = {}</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>({} xor {}) = {}</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>({} xor true).empty()</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>({} xor false).empty()</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>({} xor {}).empty()</expression><output type="boolean">true</output></test>
|
||||
</group>
|
||||
|
||||
<group name="testBooleanImplies">
|
||||
<test inputfile="patient-example.xml"><expression>(true implies true) = true</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(true implies false) = false</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(true implies {}) = {}</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(true implies {}).empty()</expression><output type="boolean">true</output></test>
|
||||
|
||||
<test inputfile="patient-example.xml"><expression>(false implies true) = true</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(false implies false) = true</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(false implies {}) = true</expression><output type="boolean">true</output></test>
|
||||
|
||||
<test inputfile="patient-example.xml"><expression>({} implies true) = true</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>({} implies false) = true</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>({} implies {}) = true</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>({} implies true).empty()</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>({} implies false).empty()</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>({} implies {}).empty()</expression><output type="boolean">true</output></test>
|
||||
</group>
|
||||
|
||||
<group name="testPlus">
|
||||
|
@ -875,18 +895,17 @@
|
|||
</group>
|
||||
|
||||
<group name="testConcatenate">
|
||||
<test inputfile="patient-example.xml"><expression>1 & 1 = '11'</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>1 & 'a' = '1a'</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>{} & 'b' = 'b'</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>(1 | 2 | 3) & 'b' = '1,2,3b'</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'a'&'b' = 'ab'</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>'a' & 'b' = 'ab'</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>('1' & {}).empty()</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>({} & 'b').empty()</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression invalid="semantic">(1 | 2 | 3) & 'b' = '1,2,3b'</expression></test>
|
||||
</group>
|
||||
|
||||
<group name="testMinus">
|
||||
<test inputfile="patient-example.xml"><expression>1 - 1 = 0</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>1 - 0 = 1</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>1.8 - 1.2 = 0.6</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression invalid="true">'a'-'b' = 'ab'</expression></test>
|
||||
<test inputfile="patient-example.xml"><expression invalid="semantic">'a'-'b' = 'ab'</expression></test>
|
||||
</group>
|
||||
|
||||
<group name="testMultiply">
|
||||
|
@ -919,6 +938,11 @@
|
|||
</group>
|
||||
|
||||
<group name="testPrecedence">
|
||||
<test name="testUnaryPrecedence" inputfile="patient-example.xml">
|
||||
<expression invalid="semantic">-1.convertsToInteger()</expression>
|
||||
<!-- should error because unary does not work on boolean: -(1.convertsToInteger()) -->
|
||||
</test>
|
||||
|
||||
<test inputfile="patient-example.xml"><expression>1+2*3+4 = 11</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>1 > 2 is Boolean</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>1 | 1 is Integer</expression><output type="boolean">true</output></test>
|
||||
|
@ -928,12 +952,12 @@
|
|||
<test inputfile="patient-example.xml"><expression>%sct = 'http://snomed.info/sct'</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>%loinc = 'http://loinc.org'</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>%ucum = 'http://unitsofmeasure.org'</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>%"vs-administrative-gender" = 'http://hl7.org/fhir/ValueSet/administrative-gender'</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>%`vs-administrative-gender` = 'http://hl7.org/fhir/ValueSet/administrative-gender'</expression><output type="boolean">true</output></test>
|
||||
</group>
|
||||
|
||||
<group name="testExtension">
|
||||
<test inputfile="patient-example.xml"><expression>Patient.birthDate.extension('http://hl7.org/fhir/StructureDefinition/patient-birthTime').exists()</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>Patient.birthDate.extension(%"ext-patient-birthTime").exists()</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>Patient.birthDate.extension(%`ext-patient-birthTime`).exists()</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>Patient.birthDate.extension('http://hl7.org/fhir/StructureDefinition/patient-birthTime1').empty()</expression><output type="boolean">true</output></test>
|
||||
</group>
|
||||
|
||||
|
@ -944,6 +968,8 @@
|
|||
<test inputfile="patient-example.xml"><expression>true.type().name = 'Boolean'</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>true.is(Boolean)</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>true.is(System.Boolean)</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>true is Boolean</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>true is System.Boolean</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>Patient.active.type().namespace = 'FHIR'</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>Patient.active.type().name = 'boolean'</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>Patient.active.is(boolean)</expression><output type="boolean">true</output></test>
|
||||
|
@ -954,6 +980,11 @@
|
|||
<test inputfile="patient-example.xml"><expression>Patient.type().name = 'Patient'</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>Patient.is(Patient)</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>Patient.is(FHIR.Patient)</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>Patient.is(FHIR.`Patient`)</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>Patient.ofType(Patient).type().name</expression><output type="string">Patient</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>Patient.ofType(FHIR.Patient).type().name</expression><output type="string">Patient</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>Patient.is(System.Patient).not()</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression>Patient.ofType(FHIR.`Patient`).type().name</expression><output type="string">Patient</output></test>
|
||||
</group>
|
||||
|
||||
<group name="testConformsTo">
|
||||
|
@ -962,12 +993,5 @@
|
|||
<test inputfile="patient-example.xml"><expression invalid="true">conformsTo('http://trash')</expression></test>
|
||||
</group>
|
||||
|
||||
<!--
|
||||
<group name="testDollarResource">
|
||||
testBoolean(patient(), patient().getManagingOrganization(), "Reference", "reference.startsWith('#').not() or (reference.substring(1).trace('url') in %resource.contained.id.trace('ids'))</expression><output type="boolean">true</output></test>
|
||||
testBoolean(patient(), patient(), "Patient", "contained.select(('#'+id in %resource.descendants().reference).not()).empty()</expression><output type="boolean">true</output></test>
|
||||
<test inputfile="patient-example.xml"><expression invalid="true">contained.select(('#'+id in %resource.descendants().reference).not()).empty()");
|
||||
</group>
|
||||
-->
|
||||
</tests>
|
||||
|
||||
|
|
Loading…
Reference in New Issue