8000 Begin implementing testers · jinja2cpp/Jinja2Cpp@eb71299 · GitHub
[go: up one dir, main page]

Skip to content

Commit eb71299

Browse files
committed
Begin implementing testers
1 parent 3ed0930 commit eb71299

File tree

7 files changed

+181
-26
lines changed

7 files changed

+181
-26
lines changed

src/filters.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -90,20 +90,6 @@ extern FilterPtr CreateFilter(std::string filterName, CallParams params)
9090
namespace filters
9191
{
9292

93-
bool FilterBase::ParseParams(const std::initializer_list<ArgumentInfo>& argsInfo, const CallParams& params)
94-
{
95-
bool result = true;
96-
m_args = helpers::ParseCallParams(argsInfo, params, result);
97-
98-
return result;
99-
}
100-
101-
InternalValue FilterBase::GetArgumentValue(std::string argName, RenderContext& context, InternalValue defVal)
102-
{
103-
auto argExpr = m_args[argName];
104-
return argExpr ? argExpr->Evaluate(context) : std::move(defVal);
105-
}
106-
10793
Join::Join(FilterParams params)
10894
{
10995
ParseParams({{"d", false, std::string()}, {"attribute"}}, params);

src/filters.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define FILTERS_H
33

44
#include "expression_evaluator.h"
5+
#include "function_base.h"
56
#include "jinja2cpp/value.h"
67
#include "render_context.h"
78

@@ -17,15 +18,8 @@ extern FilterPtr CreateFilter(std::string filterName, CallParams params);
1718

1819
namespace filters
1920
{
20-
class FilterBase : public ExpressionFilter::IExpressionFilter
21+
class FilterBase : public FunctionBase, public ExpressionFilter::IExpressionFilter
2122
{
22-
public:
23-
protected:
24-
bool ParseParams(const std::initializer_list<ArgumentInfo>& argsInfo, const CallParams& params);
25-
InternalValue GetArgumentValue(std::string argName, RenderContext& context, InternalValue defVal = InternalValue());
26-
27-
protected:
28-
ParsedArguments m_args;
2923
};
3024

3125
class Attribute : public FilterBase

src/function_base.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#ifndef FUNCTION_BASE_H
2+
#define FUNCTION_BASE_H
3+
4+
#include "expression_evaluator.h"
5+
#include "internal_value.h"
6+
7+
namespace jinja2
8+
{
9+
class FunctionBase
10+
{
11+
public:
12+
protected:
13+
bool ParseParams(const std::initializer_list<ArgumentInfo>& argsInfo, const CallParams& params);
14+
InternalValue GetArgumentValue(std::string argName, RenderContext& context, InternalValue defVal = InternalValue());
15+
16+
protected:
17+
ParsedArguments m_args;
18+
};
19+
20+
21+
inline bool FunctionBase::ParseParams(const std::initializer_list<ArgumentInfo>& argsInfo, const CallParams& params)
22+
{
23+
bool result = true;
24+
m_args = helpers::ParseCallParams(argsInfo, params, result);
25+
26+
return result;
27+
}
28+
29+
inline InternalValue FunctionBase::GetArgumentValue(std::string argName, RenderContext& context, InternalValue defVal)
30+
{
31+
auto argExpr = m_args[argName];
32+
return argExpr ? argExpr->Evaluate(context) : std::move(defVal);
33+
}
34+
35+
} // jinja2
36+
37+
#endif // FUNCTION_BASE_H

src/testers.cpp

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,43 @@ struct TesterFactory
1111
{
1212
return std::make_shared<F>(std::move(params));
1313
}
14+
15+
template<typename ... Args>
16+
static IsExpression::TesterFactoryFn MakeCreator(Args&& ... args)
17+
{
18+
return [args...](TesterParams params) {return std::make_shared<F>(std::move(params), args...);};
19+
}
1420
};
1521

1622
std::unordered_map<std::string, IsExpression::TesterFactoryFn> s_testers = {
17-
{"defined", &TesterFactory<testers::Defined>::Create},
23+
{"defined", TesterFactory<testers::ValueTester>::MakeCreator(testers::ValueTester::IsDefinedMode)},
1824
{"startsWith", &TesterFactory<testers::StartsWith>::Create},
25+
{"eq", TesterFactory<testers::Comparator>::MakeCreator(BinaryExpression::LogicalEq)},
26+
{"==", TesterFactory<testers::Comparator>::MakeCreator(BinaryExpression::LogicalEq)},
27+
{"equalto", TesterFactory<testers::Comparator>::MakeCreator(BinaryExpression::LogicalEq)},
28+
{"even", TesterFactory<testers::ValueTester>::MakeCreator(testers::ValueTester::IsEvenMode)},
29+
{"ge", TesterFactory<testers::Comparator>::MakeCreator(BinaryExpression::LogicalGe)},
30+
{">=", TesterFactory<testers::Comparator>::MakeCreator(BinaryExpression::LogicalGe)},
31+
{"gt", TesterFactory<testers::Comparator>::MakeCreator(BinaryExpression::LogicalGt)},
32+
{">", TesterFactory<testers::Comparator>::MakeCreator(BinaryExpression::LogicalGt)},
33+
{"greaterthan", TesterFactory<testers::Comparator>::MakeCreator(BinaryExpression::LogicalGt)},
34+
{"in", TesterFactory<testers::ValueTester>::MakeCreator(testers::ValueTester::IsInMode)},
35+
{"iterable", TesterFactory<testers::ValueTester>::MakeCreator(testers::ValueTester::IsIterableMode)},
36+
{"le", TesterFactory<testers::Comparator>::MakeCreator(BinaryExpression::LogicalLe)},
37+
{"<=", TesterFactory<testers::Comparator>::MakeCreator(BinaryExpression::LogicalLe)},
38+
{"lower", TesterFactory<testers::ValueTester>::MakeCreator(testers::ValueTester::IsLowerMode)},
39+
{"lt", TesterFactory<testers::Comparator>::MakeCreator(BinaryExpression::LogicalLt)},
40+
{"<", TesterFactory<testers::Comparator>::MakeCreator(BinaryExpression::LogicalLt)},
41+
{"lessthan", TesterFactory<testers::Comparator>::MakeCreator(BinaryExpression::LogicalLt)},
42+
{"mapping", TesterFactory<testers::ValueTester>::MakeCreator(testers::ValueTester::IsMappingMode)},
43+
{"ne", TesterFactory<testers::Comparator>::MakeCreator(BinaryExpression::LogicalNe)},
44+
{"!=", TesterFactory<testers::Comparator>::MakeCreator(BinaryExpression::LogicalNe)},
45+
{"number", TesterFactory<testers::ValueTester>::MakeCreator(testers::ValueTester::IsNumberMode)},
46+
{"odd", TesterFactory<testers::ValueTester>::MakeCreator(testers::ValueTester::IsOddMode)},
47+
{"sequence", TesterFactory<testers::ValueTester>::MakeCreator(testers::ValueTester::IsSequenceMode)},
48+
{"string", TesterFactory<testers::ValueTester>::MakeCreator(testers::ValueTester::IsStringMode)},
49+
{"undefined", TesterFactory<testers::ValueTester>::MakeCreator(testers::ValueTester::IsUndefinedMode)},
50+
{"upper", TesterFactory<testers::ValueTester>::MakeCreator(testers::ValueTester::IsUpperMode)},
1951
};
2052

2153
TesterPtr CreateTester(std::string testerName, CallParams params)
@@ -30,10 +62,26 @@ TesterPtr CreateTester(std::string testerName, CallParams params)
3062
namespace testers
3163
{
3264

65+
Comparator::Comparator(TesterParams params, BinaryExpression::Operation op)
66+
: m_op(op)
67+
{
68+
ParseParams({{"b", true}}, params);
69+
}
70+
71+
bool Comparator::Test(const InternalValue& baseVal, RenderContext& context)
72+
{
73+
auto b = GetArgumentValue("b", context);
74+
75+
auto cmpRes = Apply2<visitors::BinaryMathOperation>(baseVal, b, m_op);
76+
return ConvertToBool(cmpRes);
77+
}
78+
79+
#if 0
3380
bool Defined::Test(const InternalValue& baseVal, RenderContext& /*context*/)
3481
{
3582
return boost::get<EmptyValue>(&baseVal) == nullptr;
3683
}
84+
#endif
3785

3886
StartsWith::StartsWith(TesterParams params)
3987
{
@@ -50,5 +98,14 @@ bool StartsWith::Test(const InternalValue& baseVal, RenderContext& context)
5098
return baseStr.find(str) == 0;
5199
}
52100

101+
ValueTester::ValueTester(TesterParams params, ValueTester::Mode mode)
102+
: m_mode(mode)
103+
{}
104+
105+
bool ValueTester::Test(const InternalValue& baseVal, RenderContext& context)
106+
{
107+
return false;
108+
}
109+
53110
}
54111
}

src/testers.h

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define TESTERS_H
33

44
#include "expression_evaluator.h"
5+
#include "function_base.h"
56
#include "jinja2cpp/value.h"
67
#include "render_context.h"
78

@@ -17,12 +18,19 @@ extern TesterPtr CreateTester(std::string testerName, CallParams params);
1718

1819
namespace testers
1920
{
20-
class Defined : public IsExpression::ITester
21+
22+
class TesterBase : public FunctionBase, public IsExpression::ITester
23+
{
24+
};
25+
26+
class Comparator : public TesterBase
2127
{
2228
public:
23-
Defined(TesterParams) {}
29+
Comparator(TesterParams params, BinaryExpression::Operation op);
2430

2531
bool Test(const InternalValue& baseVal, RenderContext& context) override;
32+
private:
33+
BinaryExpression::Operation m_op;
2634
};
2735

2836
class StartsWith : public IsExpression::ITester
@@ -36,6 +44,32 @@ class StartsWith : public IsExpression::ITester
3644
ExpressionEvaluatorPtr<> m_stringEval;
3745
};
3846

47+
class ValueTester : public TesterBase
48+
{
49+
public:
50+
enum Mode
51+
{
52+
IsDefinedMode,
53+
IsEvenMode,
54+
IsInMode,
55+
IsIterableMode,
56+
IsLowerMode,
57+
IsMappingMode,
58+
IsNumberMode,
59+
IsOddMode,
60+
IsSequenceMode,
61+
IsStringMode,
62+
IsUndefinedMode,
63+
IsUpperMode
64+
};
65+
66+
ValueTester(TesterParams params, Mode mode);
67+
68+
bool Test(const InternalValue& baseVal, RenderContext& context) override;
69+
private:
70+
Mode m_mode;
71+
};
72+
3973
} // testers
4074
} // jinja2
4175

test/expressions_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ Hello; world!!!
169169
TEST(ExpressionsTest, IfExpression)
170170
{
171171
std::string source = R"(
172-
{{ intValue if doubleValue is defined }}
172+
{{ intValue if intValue is eq(3) }}
173173
{{ stringValue if intValue < 3 else doubleValue }}
174174
)";
175175

test/testers_test.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include <iostream>
2+
#include <string>
3+
4+
#include "test_tools.h"
5+
#include "jinja2cpp/template.h"
6+
7+
using namespace jinja2;
8+
9+
struct TestersGenericTestTag;
10+
using TestersGenericTest = InputOutputPairTest<TestersGenericTestTag>;
11+
12+
13+
TEST_P(TestersGenericTest, Test)
14+
{
15+
auto& testParam = GetParam();
16+
std::string source = "{{ 'true' if " + testParam.tpl + " else 'false'}}";
17+
18+
Template tpl;
19+
ASSERT_TRUE(tpl.Load(source));
20+
21+
std::string result = tpl.RenderAsString(PrepareTestData());
22+
std::cout << result << std::endl;
23+
std::string expectedResult = testParam.result;
24+
EXPECT_EQ(expectedResult, result);
25+
}
26+
27+
INSTANTIATE_TEST_CASE_P(EqTest, TestersGenericTest, ::testing::Values(
28+
InputOutputPair{"0 is eq(0)", "true"},
29+
InputOutputPair{"0 is eq(1)", "false"},
30+
InputOutputPair{"0.5 is eq(0.5)", "true"},
31+
InputOutputPair{"0.5 is eq(1.5)", "false"},
32+
InputOutputPair{"'0.5' is eq('0.5')", "true"},
33+
InputOutputPair{"'0.5' is eq('1.5')", "false"},
34+
InputOutputPair{"'Hello World' is eq('hello world')", "false"},
35+
InputOutputPair{"0 is equalto(1)", "false"}
36+
));
37+
38+
39+
INSTANTIATE_TEST_CASE_P(NeTest, TestersGenericTest, ::testing::Values(
40+
InputOutputPair{"0 is ne(0)", "false"},
41+
InputOutputPair{"0 is ne(1)", "true"},
42+
InputOutputPair{"0.5 is ne(0.5)", "false"},
43+
InputOutputPair{"0.5 is ne(1.5)", "true"},
44+
InputOutputPair{"'0.5' is ne('0.5')", "false"},
45+
InputOutputPair{"'0.5' is ne('1.5')", "true"},
46+
InputOutputPair{"'Hello World' is ne('hello world')", "true"}
47+
));

0 commit comments

Comments
 (0)
0