diff --git a/src/expression_parser.cpp b/src/expression_parser.cpp index 892a5d5a..8ca1cfd4 100644 --- a/src/expression_parser.cpp +++ b/src/expression_parser.cpp @@ -136,6 +136,8 @@ ExpressionEvaluatorPtr ExpressionParser::ParseLogicalCompare(LexScan if (lexer.NextToken() == '(') params = ParseCallParams(lexer, valid); + else + lexer.ReturnToken(); if (!valid) return ExpressionEvaluatorPtr(); diff --git a/src/testers.cpp b/src/testers.cpp index c9a6e6e2..0dbc9fa4 100644 --- a/src/testers.cpp +++ b/src/testers.cpp @@ -100,12 +100,130 @@ bool StartsWith::Test(const InternalValue& baseVal, RenderContext& context) ValueTester::ValueTester(TesterParams params, ValueTester::Mode mode) : m_mode(mode) -{} +{ + switch (m_mode) + { + case IsDefinedMode: + break; + case IsEvenMode: + break; + case IsInMode: + break; + case IsIterableMode: + break; + case IsLowerMode: + break; + case IsMappingMode: + break; + case IsNumberMode: + break; + case IsOddMode: + break; + case IsSequenceMode: + break; + case IsStringMode: + break; + case IsUndefinedMode: + break; + case IsUpperMode: + break; + + } +} + +enum class ValueKind +{ + Empty, + Boolean, + String, + Integer, + Double, + List, + Map, + KVPair, + Callable +}; + +struct ValueKindGetter : visitors::BaseVisitor +{ + using visitors::BaseVisitor::operator (); + + ValueKind operator()(const EmptyValue&) const + { + return ValueKind::Empty; + } + ValueKind operator()(bool) const + { + return ValueKind::Boolean; + } + template + ValueKind operator()(const std::basic_string&) const + { + return ValueKind::String; + } + ValueKind operator()(int64_t) const + { + return ValueKind::Integer; + } + ValueKind operator()(double) const + { + return ValueKind::Double; + } + ValueKind operator()(const ListAdapter&) const + { + return ValueKind::List; + } + ValueKind operator()(const MapAdapter&) const + { + return ValueKind::Map; + } + ValueKind operator()(const KeyValuePair&) const + { + return ValueKind::KVPair; + } +}; bool ValueTester::Test(const InternalValue& baseVal, RenderContext& context) { - return false; -} + bool result = false; + auto valKind = Apply(baseVal); + switch (m_mode) + { + case IsIterableMode: + result = valKind == ValueKind::List || valKind == ValueKind::Map; + break; + case IsMappingMode: + result = valKind == ValueKind::KVPair || valKind == ValueKind::Map; + break; + case IsNumberMode: + result = valKind == ValueKind::Integer || valKind == ValueKind::Double; + break; + case IsSequenceMode: + result = valKind == ValueKind::List; + break; + case IsStringMode: + result = valKind == ValueKind::String; + break; + case IsDefinedMode: + result = valKind != ValueKind::Empty; + break; + case IsUndefinedMode: + result = valKind == ValueKind::Empty; + break; + case IsInMode: + break; + case IsEvenMode: + break; + case IsOddMode: + break; + case IsLowerMode: + break; + case IsUpperMode: + break; + + } + return result; +} } } diff --git a/test/testers_test.cpp b/test/testers_test.cpp index 28aba7dd..72b28ad4 100644 --- a/test/testers_test.cpp +++ b/test/testers_test.cpp @@ -134,3 +134,114 @@ INSTANTIATE_TEST_CASE_P(LtTest, TestersGenericTest, ::testing::Values( InputOutputPair{"intAsDoubleList[0] is lt(intList[1])", "false"}, InputOutputPair{"intAsDoubleList[1] is lt(intList[0])", "true"} )); + +INSTANTIATE_TEST_CASE_P(DefinedTest, TestersGenericTest, ::testing::Values( + InputOutputPair{"antList is defined", "false"}, + InputOutputPair{"intList is defined", "true"} + )); + +INSTANTIATE_TEST_CASE_P(UndefinedTest, TestersGenericTest, ::testing::Values( + InputOutputPair{"antList is undefined", "true"}, + InputOutputPair{"intList is undefined", "false"} + )); + +INSTANTIATE_TEST_CASE_P(IterableTest, TestersGenericTest, ::testing::Values( + InputOutputPair{"0 is iterable", "false"}, + InputOutputPair{"'intList' is iterable", "false"}, + InputOutputPair{"false is iterable", "false"}, + InputOutputPair{"0.2 is iterable", "false"}, + InputOutputPair{"intValue is iterable", "false"}, + InputOutputPair{"stringValue is iterable", "false"}, + InputOutputPair{"doubleValue is iterable", "false"}, + InputOutputPair{"boolFalseValue is iterable", "false"}, + InputOutputPair{"boolTrueValue is iterable", "false"}, + InputOutputPair{"[0, 1, 2] is iterable", "true"}, + InputOutputPair{"(0, 1, 2) is iterable", "true"}, + InputOutputPair{"{'name'='itemName', 'val'='itemValue'} is iterable", "true"}, + InputOutputPair{"mapValue is iterable", "true"}, + // InputOutputPair{"mapValue | first is iterable", "false"}, + InputOutputPair{"intList is iterable", "true"}, + InputOutputPair{"reflectedVal is iterable", "true"}, + InputOutputPair{"reflectedList is iterable", "true"} + )); + +INSTANTIATE_TEST_CASE_P(MappingTest, TestersGenericTest, ::testing::Values( + InputOutputPair{"0 is mapping", "false"}, + InputOutputPair{"'intList' is mapping", "false"}, + InputOutputPair{"false is mapping", "false"}, + InputOutputPair{"0.2 is mapping", "false"}, + InputOutputPair{"intValue is mapping", "false"}, + InputOutputPair{"stringValue is mapping", "false"}, + InputOutputPair{"doubleValue is mapping", "false"}, + InputOutputPair{"boolFalseValue is mapping", "false"}, + InputOutputPair{"boolTrueValue is mapping", "false"}, + InputOutputPair{"[0, 1, 2] is mapping", "false"}, + InputOutputPair{"(0, 1, 2) is mapping", "false"}, + InputOutputPair{"{'name'='itemName', 'val'='itemValue'} is mapping", "true"}, + InputOutputPair{"mapValue is mapping", "true"}, + // InputOutputPair{"mapValue | first is mapping", "true"}, ??? + InputOutputPair{"intList is mapping", "false"}, + InputOutputPair{"reflectedVal is mapping", "true"}, + InputOutputPair{"reflectedList is mapping", "false"} + )); + +INSTANTIATE_TEST_CASE_P(NumberTest, TestersGenericTest, ::testing::Values( + InputOutputPair{"0 is number", "true"}, + InputOutputPair{"'intList' is number", "false"}, + InputOutputPair{"false is number", "false"}, + InputOutputPair{"0.2 is number", "true"}, + InputOutputPair{"intValue is number", "true"}, + InputOutputPair{"stringValue is number", "false"}, + InputOutputPair{"doubleValue is number", "true"}, + InputOutputPair{"boolFalseValue is number", "false"}, + InputOutputPair{"boolTrueValue is number", "false"}, + InputOutputPair{"[0, 1, 2] is number", "false"}, + InputOutputPair{"(0, 1, 2) is number", "false"}, + InputOutputPair{"{'name'='itemName', 'val'='itemValue'} is number", "false"}, + InputOutputPair{"mapValue is number", "false"}, + // InputOutputPair{"mapValue | first is number", "true"}, ??? + InputOutputPair{"intList is number", "false"}, + InputOutputPair{"reflectedVal is number", "false"}, + InputOutputPair{"reflectedList is number", "false"} + )); + +INSTANTIATE_TEST_CASE_P(SequenceTest, TestersGenericTest, ::testing::Values( + InputOutputPair{"0 is sequence", "false"}, + InputOutputPair{"'intList' is sequence", "false"}, + InputOutputPair{"false is sequence", "false"}, + InputOutputPair{"0.2 is sequence", "false"}, + InputOutputPair{"intValue is sequence", "false"}, + InputOutputPair{"stringValue is sequence", "false"}, + InputOutputPair{"doubleValue is sequence", "false"}, + InputOutputPair{"boolFalseValue is sequence", "false"}, + InputOutputPair{"boolTrueValue is sequence", "false"}, + InputOutputPair{"[0, 1, 2] is sequence", "true"}, + InputOutputPair{"(0, 1, 2) is sequence", "true"}, + InputOutputPair{"{'name'='itemName', 'val'='itemValue'} is sequence", "false"}, + InputOutputPair{"mapValue is sequence", "false"}, + // InputOutputPair{"mapValue | first is sequence", "true"}, ??? + InputOutputPair{"intList is sequence", "true"}, + InputOutputPair{"reflectedVal is sequence", "false"}, + InputOutputPair{"reflectedList is sequence", "true"} + )); + + +INSTANTIATE_TEST_CASE_P(StringTest, TestersGenericTest, ::testing::Values( + InputOutputPair{"0 is string", "false"}, + InputOutputPair{"'intList' is string", "true"}, + InputOutputPair{"false is string", "false"}, + InputOutputPair{"0.2 is string", "false"}, + InputOutputPair{"intValue is string", "false"}, + InputOutputPair{"stringValue is string", "true"}, + InputOutputPair{"doubleValue is string", "false"}, + InputOutputPair{"boolFalseValue is string", "false"}, + InputOutputPair{"boolTrueValue is string", "false"}, + InputOutputPair{"[0, 1, 2] is string", "false"}, + InputOutputPair{"(0, 1, 2) is string", "false"}, + InputOutputPair{"{'name'='itemName', 'val'='itemValue'} is string", "false"}, + InputOutputPair{"mapValue is string", "false"}, + // InputOutputPair{"mapValue | first is string", "true"}, ??? + InputOutputPair{"intList is string", "false"}, + InputOutputPair{"reflectedVal is string", "false"}, + InputOutputPair{"reflectedList is string", "false"} + ));