1 /******************************************************************************
3 * Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
5 * This program is free software; you can redistribute it and/or *
6 * modify it under the terms of the GNU General Public License *
7 * as published by the Free Software Foundation; either version 2 *
8 * of the License, or (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the Free Software Foundation *
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ******************************************************************************/
20 #include "config/configcompiler.hpp"
21 #include "base/exception.hpp"
22 #include <BoostTestTargetConfig.h>
24 using namespace icinga;
26 BOOST_AUTO_TEST_SUITE(config_ops)
28 BOOST_AUTO_TEST_CASE(simple)
30 ScriptFrame frame(true);
31 std::unique_ptr<Expression> expr;
34 expr = ConfigCompiler::CompileText("<test>", "");
35 BOOST_CHECK(expr->Evaluate(frame).GetValue() == Empty);
37 expr = ConfigCompiler::CompileText("<test>", "\n3");
38 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
40 expr = ConfigCompiler::CompileText("<test>", "{ 3\n\n5 }");
41 BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
43 expr = ConfigCompiler::CompileText("<test>", "1 + 3");
44 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 4);
46 expr = ConfigCompiler::CompileText("<test>", "3 - 1");
47 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 2);
49 expr = ConfigCompiler::CompileText("<test>", "5m * 10");
50 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3000);
52 expr = ConfigCompiler::CompileText("<test>", "5m / 5");
53 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 60);
55 expr = ConfigCompiler::CompileText("<test>", "7 & 3");
56 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
58 expr = ConfigCompiler::CompileText("<test>", "2 | 3");
59 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
61 expr = ConfigCompiler::CompileText("<test>", "true && false");
62 BOOST_CHECK(!expr->Evaluate(frame).GetValue());
64 expr = ConfigCompiler::CompileText("<test>", "true || false");
65 BOOST_CHECK(expr->Evaluate(frame).GetValue());
67 expr = ConfigCompiler::CompileText("<test>", "3 < 5");
68 BOOST_CHECK(expr->Evaluate(frame).GetValue());
70 expr = ConfigCompiler::CompileText("<test>", "3 > 5");
71 BOOST_CHECK(!expr->Evaluate(frame).GetValue());
73 expr = ConfigCompiler::CompileText("<test>", "3 <= 3");
74 BOOST_CHECK(expr->Evaluate(frame).GetValue());
76 expr = ConfigCompiler::CompileText("<test>", "3 >= 3");
77 BOOST_CHECK(expr->Evaluate(frame).GetValue());
79 expr = ConfigCompiler::CompileText("<test>", "2 + 3 * 4");
80 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 14);
82 expr = ConfigCompiler::CompileText("<test>", "(2 + 3) * 4");
83 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 20);
85 expr = ConfigCompiler::CompileText("<test>", "2 * - 3");
86 BOOST_CHECK(expr->Evaluate(frame).GetValue() == -6);
88 expr = ConfigCompiler::CompileText("<test>", "-(2 + 3)");
89 BOOST_CHECK(expr->Evaluate(frame).GetValue() == -5);
91 expr = ConfigCompiler::CompileText("<test>", "- 2 * 2 - 2 * 3 - 4 * - 5");
92 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 10);
94 expr = ConfigCompiler::CompileText("<test>", "!0 == true");
95 BOOST_CHECK(expr->Evaluate(frame).GetValue());
97 expr = ConfigCompiler::CompileText("<test>", "~0");
98 BOOST_CHECK(expr->Evaluate(frame).GetValue() == (double)~(long)0);
100 expr = ConfigCompiler::CompileText("<test>", "4 << 8");
101 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 1024);
103 expr = ConfigCompiler::CompileText("<test>", "1024 >> 4");
104 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 64);
106 expr = ConfigCompiler::CompileText("<test>", "2 << 3 << 4");
107 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 256);
109 expr = ConfigCompiler::CompileText("<test>", "256 >> 4 >> 3");
110 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 2);
112 expr = ConfigCompiler::CompileText("<test>", R"("hello" == "hello")");
113 BOOST_CHECK(expr->Evaluate(frame).GetValue());
115 expr = ConfigCompiler::CompileText("<test>", R"("hello" != "hello")");
116 BOOST_CHECK(!expr->Evaluate(frame).GetValue());
118 expr = ConfigCompiler::CompileText("<test>", R"("foo" in [ "foo", "bar" ])");
119 BOOST_CHECK(expr->Evaluate(frame).GetValue());
121 expr = ConfigCompiler::CompileText("<test>", R"("foo" in [ "bar", "baz" ])");
122 BOOST_CHECK(!expr->Evaluate(frame).GetValue());
124 expr = ConfigCompiler::CompileText("<test>", "\"foo\" in null");
125 BOOST_CHECK(!expr->Evaluate(frame).GetValue());
127 expr = ConfigCompiler::CompileText("<test>", R"("foo" in "bar")");
128 BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
130 expr = ConfigCompiler::CompileText("<test>", R"("foo" !in [ "bar", "baz" ])");
131 BOOST_CHECK(expr->Evaluate(frame).GetValue());
133 expr = ConfigCompiler::CompileText("<test>", R"("foo" !in [ "foo", "bar" ])");
134 BOOST_CHECK(!expr->Evaluate(frame).GetValue());
136 expr = ConfigCompiler::CompileText("<test>", "\"foo\" !in null");
137 BOOST_CHECK(expr->Evaluate(frame).GetValue());
139 expr = ConfigCompiler::CompileText("<test>", R"("foo" !in "bar")");
140 BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
142 expr = ConfigCompiler::CompileText("<test>", "{ a += 3 }");
143 dict = expr->Evaluate(frame).GetValue();
144 BOOST_CHECK(dict->GetLength() == 1);
145 BOOST_CHECK(dict->Get("a") == 3);
147 expr = ConfigCompiler::CompileText("<test>", "test");
148 BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
150 expr = ConfigCompiler::CompileText("<test>", "null + 3");
151 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
153 expr = ConfigCompiler::CompileText("<test>", "3 + null");
154 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
156 expr = ConfigCompiler::CompileText("<test>", "\"test\" + 3");
157 BOOST_CHECK(expr->Evaluate(frame).GetValue() == "test3");
159 expr = ConfigCompiler::CompileText("<test>", R"("\"te\\st")");
160 BOOST_CHECK(expr->Evaluate(frame).GetValue() == "\"te\\st");
162 expr = ConfigCompiler::CompileText("<test>", R"("\'test")");
163 BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
165 expr = ConfigCompiler::CompileText("<test>", "({ a = 3\nb = 3 })");
166 BOOST_CHECK(expr->Evaluate(frame).GetValue().IsObjectType<Dictionary>());
169 BOOST_AUTO_TEST_CASE(advanced)
171 ScriptFrame frame(true);
172 std::unique_ptr<Expression> expr;
175 expr = ConfigCompiler::CompileText("<test>", R"(regex("^Hello", "Hello World"))");
176 BOOST_CHECK(expr->Evaluate(frame).GetValue());
178 expr = ConfigCompiler::CompileText("<test>", "__boost_test()");
179 BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
181 Object::Ptr self = new Object();
182 ScriptFrame frame2(true, self);
183 expr = ConfigCompiler::CompileText("<test>", "this");
184 BOOST_CHECK(expr->Evaluate(frame2).GetValue() == Value(self));
186 expr = ConfigCompiler::CompileText("<test>", "var v = 7; v");
187 BOOST_CHECK(expr->Evaluate(frame).GetValue());
189 expr = ConfigCompiler::CompileText("<test>", "{ a = 3 }.a");
190 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
192 expr = ConfigCompiler::CompileText("<test>", "[ 2, 3 ][1]");
193 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
195 expr = ConfigCompiler::CompileText("<test>", "var v = { a = 3}; v.a");
196 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
198 expr = ConfigCompiler::CompileText("<test>", "a = 3 b = 3");
199 BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
201 expr = ConfigCompiler::CompileText("<test>", "function() { 3 }()");
202 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
204 expr = ConfigCompiler::CompileText("<test>", "function() { return 3, 5 }()");
205 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
207 expr = ConfigCompiler::CompileText("<test>", "typeof([]) == Array");
208 BOOST_CHECK(expr->Evaluate(frame).GetValue());
210 expr = ConfigCompiler::CompileText("<test>", "typeof({}) == Dictionary");
211 BOOST_CHECK(expr->Evaluate(frame).GetValue());
213 expr = ConfigCompiler::CompileText("<test>", "typeof(3) == Number");
214 BOOST_CHECK(expr->Evaluate(frame).GetValue());
216 expr = ConfigCompiler::CompileText("<test>", "typeof(\"test\") == String");
217 BOOST_CHECK(expr->Evaluate(frame).GetValue());
219 expr = ConfigCompiler::CompileText("<test>", "(7 | 8) == 15");
220 BOOST_CHECK(expr->Evaluate(frame).GetValue());
222 expr = ConfigCompiler::CompileText("<test>", "(7 ^ 8) == 15");
223 BOOST_CHECK(expr->Evaluate(frame).GetValue());
225 expr = ConfigCompiler::CompileText("<test>", "(7 & 15) == 7");
226 BOOST_CHECK(expr->Evaluate(frame).GetValue());
228 expr = ConfigCompiler::CompileText("<test>", "7 in [7] == true");
229 BOOST_CHECK(expr->Evaluate(frame).GetValue());
231 expr = ConfigCompiler::CompileText("<test>", "7 !in [7] == false");
232 BOOST_CHECK(expr->Evaluate(frame).GetValue());
234 expr = ConfigCompiler::CompileText("<test>", "(7 | 8) > 14");
235 BOOST_CHECK(expr->Evaluate(frame).GetValue());
237 expr = ConfigCompiler::CompileText("<test>", "(7 ^ 8) > 14");
238 BOOST_CHECK(expr->Evaluate(frame).GetValue());
240 expr = ConfigCompiler::CompileText("<test>", "(7 & 15) > 6");
241 BOOST_CHECK(expr->Evaluate(frame).GetValue());
243 expr = ConfigCompiler::CompileText("<test>", "\"a\" = 3");
244 BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
246 expr = ConfigCompiler::CompileText("<test>", "3 = 3");
247 BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
249 expr = ConfigCompiler::CompileText("<test>", "var e; e");
250 BOOST_CHECK(expr->Evaluate(frame).GetValue().IsEmpty());
252 expr = ConfigCompiler::CompileText("<test>", "var e = 3; e");
253 BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
255 expr = ConfigCompiler::CompileText("<test>", "Array.x");
256 BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
258 expr = ConfigCompiler::CompileText("<test>", "{{ 3 }}");
259 func = expr->Evaluate(frame).GetValue();
260 BOOST_CHECK(func->Invoke() == 3);
263 BOOST_AUTO_TEST_SUITE_END()