Skip to content

Commit b1d38c7

Browse files
authored
Implement 'gt', 'gt', 'lt', 'le', 'defined', 'undefined', 'iterable', 'mapping', 'number', 'sequence' and 'string' testers (#23)
1 parent d9674cd commit b1d38c7

File tree

3 files changed

+234
-3
lines changed

3 files changed

+234
-3
lines changed

src/expression_parser.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ ExpressionEvaluatorPtr<Expression> ExpressionParser::ParseLogicalCompare(LexScan
136136

137137
if (lexer.NextToken() == '(')
138138
params = ParseCallParams(lexer, valid);
139+
else
140+
lexer.ReturnToken();
139141

140142
if (!valid)
141143
return ExpressionEvaluatorPtr<Expression>();

src/testers.cpp

Lines changed: 121 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,130 @@ bool StartsWith::Test(const InternalValue& baseVal, RenderContext& context)
100100

101101
ValueTester::ValueTester(TesterParams params, ValueTester::Mode mode)
102102
: m_mode(mode)
103-
{}
103+
{
104+
switch (m_mode)
105+
{
106+
case IsDefinedMode:
107+
break;
108+
case IsEvenMode:
109+
break;
110+
case IsInMode:
111+
break;
112+
case IsIterableMode:
113+
break;
114+
case IsLowerMode:
115+
break;
116+
case IsMappingMode:
117+
break;
118+
case IsNumberMode:
119+
break;
120+
case IsOddMode:
121+
break;
122+
case IsSequenceMode:
123+
break;
124+
case IsStringMode:
125+
break;
126+
case IsUndefinedMode:
127+
break;
128+
case IsUpperMode:
129+
break;
130+
131+
}
132+
}
133+
134+
enum class ValueKind
135+
{
136+
Empty,
137+
Boolean,
138+
String,
139+
Integer,
140+
Double,
141+
List,
142+
Map,
143+
KVPair,
144+
Callable
145+
};
146+
147+
struct ValueKindGetter : visitors::BaseVisitor<ValueKind>
148+
{
149+
using visitors::BaseVisitor<ValueKind>::operator ();
150+
151+
ValueKind operator()(const EmptyValue&) const
152+
{
153+
return ValueKind::Empty;
154+
}
155+
ValueKind operator()(bool) const
156+
{
157+
return ValueKind::Boolean;
158+
}
159+
template<typename CharT>
160+
ValueKind operator()(const std::basic_string<CharT>&) const
161+
{
162+
return ValueKind::String;
163+
}
164+
ValueKind operator()(int64_t) const
165+
{
166+
return ValueKind::Integer;
167+
}
168+
ValueKind operator()(double) const
169+
{
170+
return ValueKind::Double;
171+
}
172+
ValueKind operator()(const ListAdapter&) const
173+
{
174+
return ValueKind::List;
175+
}
176+
ValueKind operator()(const MapAdapter&) const
177+
{
178+
return ValueKind::Map;
179+
}
180+
ValueKind operator()(const KeyValuePair&) const
181+
{
182+
return ValueKind::KVPair;
183+
}
184+
};
104185

105186
bool ValueTester::Test(const InternalValue& baseVal, RenderContext& context)
106187
{
107-
return false;
108-
}
188+
bool result = false;
189+
auto valKind = Apply<ValueKindGetter>(baseVal);
109190

191+
switch (m_mode)
192+
{
193+
case IsIterableMode:
194+
result = valKind == ValueKind::List || valKind == ValueKind::Map;
195+
break;
196+
case IsMappingMode:
197+
result = valKind == ValueKind::KVPair || valKind == ValueKind::Map;
198+
break;
199+
case IsNumberMode:
200+
result = valKind == ValueKind::Integer || valKind == ValueKind::Double;
201+
break;
202+
case IsSequenceMode:
203+
result = valKind == ValueKind::List;
204+
break;
205+
case IsStringMode:
206+
result = valKind == ValueKind::String;
207+
break;
208+
case IsDefinedMode:
209+
result = valKind != ValueKind::Empty;
210+
break;
211+
case IsUndefinedMode:
212+
result = valKind == ValueKind::Empty;
213+
break;
214+
case IsInMode:
215+
break;
216+
case IsEvenMode:
217+
break;
218+
case IsOddMode:
219+
break;
220+
case IsLowerMode:
221+
break;
222+
case IsUpperMode:
223+
break;
224+
225+
}
226+
return result;
227+
}
110228
}
111229
}

test/testers_test.cpp

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,114 @@ INSTANTIATE_TEST_CASE_P(LtTest, TestersGenericTest, ::testing::Values(
134134
InputOutputPair{"intAsDoubleList[0] is lt(intList[1])", "false"},
135135
InputOutputPair{"intAsDoubleList[1] is lt(intList[0])", "true"}
136136
));
137+
138+
INSTANTIATE_TEST_CASE_P(DefinedTest, TestersGenericTest, ::testing::Values(
139+
InputOutputPair{"antList is defined", "false"},
140+
InputOutputPair{"intList is defined", "true"}
141+
));
142+
143+
INSTANTIATE_TEST_CASE_P(UndefinedTest, TestersGenericTest, ::testing::Values(
144+
InputOutputPair{"antList is undefined", "true"},
145+
InputOutputPair{"intList is undefined", "false"}
146+
));
147+
148+
INSTANTIATE_TEST_CASE_P(IterableTest, TestersGenericTest, ::testing::Values(
149+
InputOutputPair{"0 is iterable", "false"},
150+
InputOutputPair{"'intList' is iterable", "false"},
151+
InputOutputPair{"false is iterable", "false"},
152+
InputOutputPair{"0.2 is iterable", "false"},
153+
InputOutputPair{"intValue is iterable", "false"},
154+
InputOutputPair{"stringValue is iterable", "false"},
155+
InputOutputPair{"doubleValue is iterable", "false"},
156+
InputOutputPair{"boolFalseValue is iterable", "false"},
157+
InputOutputPair{"boolTrueValue is iterable", "false"},
158+
InputOutputPair{"[0, 1, 2] is iterable", "true"},
159+
InputOutputPair{"(0, 1, 2) is iterable", "true"},
160+
InputOutputPair{"{'name'='itemName', 'val'='itemValue'} is iterable", "true"},
161+
InputOutputPair{"mapValue is iterable", "true"},
162+
// InputOutputPair{"mapValue | first is iterable", "false"},
163+
InputOutputPair{"intList is iterable", "true"},
164+
InputOutputPair{"reflectedVal is iterable", "true"},
165+
InputOutputPair{"reflectedList is iterable", "true"}
166+
));
167+
168+
INSTANTIATE_TEST_CASE_P(MappingTest, TestersGenericTest, ::testing::Values(
169+
InputOutputPair{"0 is mapping", "false"},
170+
InputOutputPair{"'intList' is mapping", "false"},
171+
InputOutputPair{"false is mapping", "false"},
172+
InputOutputPair{"0.2 is mapping", "false"},
173+
InputOutputPair{"intValue is mapping", "false"},
174+
InputOutputPair{"stringValue is mapping", "false"},
175+
InputOutputPair{"doubleValue is mapping", "false"},
176+
InputOutputPair{"boolFalseValue is mapping", "false"},
177+
InputOutputPair{"boolTrueValue is mapping", "false"},
178+
InputOutputPair{"[0, 1, 2] is mapping", "false"},
179+
InputOutputPair{"(0, 1, 2) is mapping", "false"},
180+
InputOutputPair{"{'name'='itemName', 'val'='itemValue'} is mapping", "true"},
181+
InputOutputPair{"mapValue is mapping", "true"},
182+
// InputOutputPair{"mapValue | first is mapping", "true"}, ???
183+
InputOutputPair{"intList is mapping", "false"},
184+
InputOutputPair{"reflectedVal is mapping", "true"},
185+
InputOutputPair{"reflectedList is mapping", "false"}
186+
));
187+
188+
INSTANTIATE_TEST_CASE_P(NumberTest, TestersGenericTest, ::testing::Values(
189+
InputOutputPair{"0 is number", "true"},
190+
InputOutputPair{"'intList' is number", "false"},
191+
InputOutputPair{"false is number", "false"},
192+
InputOutputPair{"0.2 is number", "true"},
193+
InputOutputPair{"intValue is number", "true"},
194+
InputOutputPair{"stringValue is number", "false"},
195+
InputOutputPair{"doubleValue is number", "true"},
196+
InputOutputPair{"boolFalseValue is number", "false"},
197+
InputOutputPair{"boolTrueValue is number", "false"},
198+
InputOutputPair{"[0, 1, 2] is number", "false"},
199+
InputOutputPair{"(0, 1, 2) is number", "false"},
200+
InputOutputPair{"{'name'='itemName', 'val'='itemValue'} is number", "false"},
201+
InputOutputPair{"mapValue is number", "false"},
202+
// InputOutputPair{"mapValue | first is number", "true"}, ???
203+
InputOutputPair{"intList is number", "false"},
204+
InputOutputPair{"reflectedVal is number", "false"},
205+
InputOutputPair{"reflectedList is number", "false"}
206+
));
207+
208+
INSTANTIATE_TEST_CASE_P(SequenceTest, TestersGenericTest, ::testing::Values(
209+
InputOutputPair{"0 is sequence", "false"},
210+
InputOutputPair{"'intList' is sequence", "false"},
211+
InputOutputPair{"false is sequence", "false"},
212+
InputOutputPair{"0.2 is sequence", "false"},
213+
InputOutputPair{"intValue is sequence", "false"},
214+
InputOutputPair{"stringValue is sequence", "false"},
215+
InputOutputPair{"doubleValue is sequence", "false"},
216+
InputOutputPair{"boolFalseValue is sequence", "false"},
217+
InputOutputPair{"boolTrueValue is sequence", "false"},
218+
InputOutputPair{"[0, 1, 2] is sequence", "true"},
219+
InputOutputPair{"(0, 1, 2) is sequence", "true"},
220+
InputOutputPair{"{'name'='itemName', 'val'='itemValue'} is sequence", "false"},
221+
InputOutputPair{"mapValue is sequence", "false"},
222+
// InputOutputPair{"mapValue | first is sequence", "true"}, ???
223+
InputOutputPair{"intList is sequence", "true"},
224+
InputOutputPair{"reflectedVal is sequence", "false"},
225+
InputOutputPair{"reflectedList is sequence", "true"}
226+
));
227+
228+
229+
INSTANTIATE_TEST_CASE_P(StringTest, TestersGenericTest, ::testing::Values(
230+
InputOutputPair{"0 is string", "false"},
231+
InputOutputPair{"'intList' is string", "true"},
232+
InputOutputPair{"false is string", "false"},
233+
InputOutputPair{"0.2 is string", "false"},
234+
InputOutputPair{"intValue is string", "false"},
235+
InputOutputPair{"stringValue is string", "true"},
236+
InputOutputPair{"doubleValue is string", "false"},
237+
InputOutputPair{"boolFalseValue is string", "false"},
238+
InputOutputPair{"boolTrueValue is string", "false"},
239+
InputOutputPair{"[0, 1, 2] is string", "false"},
240+
InputOutputPair{"(0, 1, 2) is string", "false"},
241+
InputOutputPair{"{'name'='itemName', 'val'='itemValue'} is string", "false"},
242+
InputOutputPair{"mapValue is string", "false"},
243+
// InputOutputPair{"mapValue | first is string", "true"}, ???
244+
InputOutputPair{"intList is string", "false"},
245+
InputOutputPair{"reflectedVal is string", "false"},
246+
InputOutputPair{"reflectedList is string", "false"}
247+
));

0 commit comments

Comments
 (0)