1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/profile_resetter/jtl_interpreter.h"
7 #include "base/strings/string_util.h"
8 #include "base/test/values_test_util.h"
9 #include "chrome/browser/profile_resetter/jtl_foundation.h"
10 #include "chrome/browser/profile_resetter/jtl_instructions.h"
11 #include "crypto/hmac.h"
12 #include "testing/gtest/include/gtest/gtest.h"
16 const char seed[] = "foobar";
18 #define KEY_HASH_1 GetHash("KEY_HASH_1")
19 #define KEY_HASH_2 GetHash("KEY_HASH_2")
20 #define KEY_HASH_3 GetHash("KEY_HASH_3")
21 #define KEY_HASH_4 GetHash("KEY_HASH_4")
23 #define VALUE_HASH_1 GetHash("VALUE_HASH_1")
24 #define VALUE_HASH_2 GetHash("VALUE_HASH_2")
26 #define VAR_HASH_1 "01234567890123456789012345678901"
27 #define VAR_HASH_2 "12345678901234567890123456789012"
29 std::string GetHash(const std::string& input) {
30 return jtl_foundation::Hasher(seed).GetHash(input);
33 // escaped_json_param may contain ' characters that are replaced with ". This
34 // makes the code more readable because we need less escaping.
35 #define INIT_INTERPRETER(program_param, escaped_json_param) \
36 const char* escaped_json = escaped_json_param; \
38 ReplaceChars(escaped_json, "'", "\"", &json); \
39 scoped_ptr<Value> json_value(ParseJson(json)); \
40 JtlInterpreter interpreter( \
43 static_cast<const DictionaryValue*>(json_value.get())); \
46 using base::test::ParseJson;
48 TEST(JtlInterpreter, Store) {
50 OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
51 "{ 'KEY_HASH_1': 'VALUE_HASH_1' }");
52 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
53 base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
56 TEST(JtlInterpreter, NavigateAndStore) {
58 OP_NAVIGATE(KEY_HASH_1) +
59 OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
60 "{ 'KEY_HASH_1': 'VALUE_HASH_1' }");
61 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
62 base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
65 TEST(JtlInterpreter, FailNavigate) {
67 OP_NAVIGATE(KEY_HASH_2) +
68 OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
69 "{ 'KEY_HASH_1': 'VALUE_HASH_1' }");
70 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
71 EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
74 TEST(JtlInterpreter, ConsecutiveNavigate) {
76 OP_NAVIGATE(KEY_HASH_1) +
77 OP_NAVIGATE(KEY_HASH_2) +
78 OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
79 "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
80 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
81 base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
84 TEST(JtlInterpreter, FailConsecutiveNavigate) {
86 OP_NAVIGATE(KEY_HASH_1) +
87 OP_NAVIGATE(KEY_HASH_2) +
88 OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
89 "{ 'KEY_HASH_1': 'foo' }");
90 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
91 EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
94 TEST(JtlInterpreter, NavigateAnyInDictionary) {
96 OP_NAVIGATE(KEY_HASH_1) +
98 OP_NAVIGATE(KEY_HASH_4) +
99 OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
101 " { 'KEY_HASH_2': {'KEY_HASH_3': 'VALUE_HASH_1' },"
102 " 'KEY_HASH_3': {'KEY_HASH_4': 'VALUE_HASH_1' }"
104 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
105 base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
108 TEST(JtlInterpreter, NavigateAnyInList) {
110 OP_NAVIGATE(KEY_HASH_1) +
112 OP_NAVIGATE(KEY_HASH_4) +
113 OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
115 " [ {'KEY_HASH_3': 'VALUE_HASH_1' },"
116 " {'KEY_HASH_4': 'VALUE_HASH_1' }"
118 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
119 base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
122 TEST(JtlInterpreter, NavigateBack) {
124 OP_NAVIGATE(KEY_HASH_1) +
125 OP_NAVIGATE(KEY_HASH_2) +
127 OP_NAVIGATE(KEY_HASH_3) +
128 OP_NAVIGATE(KEY_HASH_4) +
129 OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
131 " { 'KEY_HASH_2': {'KEY_HASH_3': 'VALUE_HASH_1' },"
132 " 'KEY_HASH_3': {'KEY_HASH_4': 'VALUE_HASH_1' }"
134 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
135 base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
138 TEST(JtlInterpreter, StoreTwoValues) {
140 OP_NAVIGATE(KEY_HASH_1) +
141 OP_NAVIGATE(KEY_HASH_2) +
142 OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE) +
143 OP_STORE_HASH(VAR_HASH_2, VALUE_HASH_1),
144 "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
145 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
146 base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
147 base::ExpectDictStringValue(VALUE_HASH_1, *interpreter.working_memory(),
151 TEST(JtlInterpreter, CompareStoredMatch) {
153 OP_NAVIGATE(KEY_HASH_1) +
154 OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE) +
155 OP_NAVIGATE(KEY_HASH_2) +
156 OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_TRUE, VALUE_FALSE) +
157 OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
158 "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
159 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
160 base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
161 base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_2);
164 TEST(JtlInterpreter, CompareStoredMismatch) {
166 OP_NAVIGATE(KEY_HASH_1) +
167 OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE) +
168 OP_NAVIGATE(KEY_HASH_2) +
169 OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_FALSE, VALUE_TRUE) +
170 OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
171 "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
172 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
173 base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
174 EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
177 TEST(JtlInterpreter, CompareStoredNoValueMatchingDefault) {
179 OP_NAVIGATE(KEY_HASH_1) +
180 OP_NAVIGATE(KEY_HASH_2) +
181 OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_TRUE, VALUE_TRUE) +
182 OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
183 "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
184 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
185 base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_2);
188 TEST(JtlInterpreter, CompareStoredNoValueMismatchingDefault) {
190 OP_NAVIGATE(KEY_HASH_1) +
191 OP_NAVIGATE(KEY_HASH_2) +
192 OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_TRUE, VALUE_FALSE) +
193 OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
194 "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
195 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
196 EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
199 TEST(JtlInterpreter, CompareBool) {
201 std::string expected_value;
203 bool expected_success;
205 { VALUE_TRUE, "{ 'KEY_HASH_1': true }", true },
206 { VALUE_FALSE, "{ 'KEY_HASH_1': false }", true },
207 { VALUE_TRUE, "{ 'KEY_HASH_1': false }", false },
208 { VALUE_TRUE, "{ 'KEY_HASH_1': 'abc' }", false },
209 { VALUE_TRUE, "{ 'KEY_HASH_1': 1 }", false },
210 { VALUE_TRUE, "{ 'KEY_HASH_1': 1.2 }", false },
211 { VALUE_TRUE, "{ 'KEY_HASH_1': [1] }", false },
212 { VALUE_TRUE, "{ 'KEY_HASH_1': {'a': 'b'} }", false },
215 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
216 SCOPED_TRACE(testing::Message() << "Iteration " << i);
218 OP_NAVIGATE(KEY_HASH_1) +
219 OP_COMPARE_NODE_BOOL(cases[i].expected_value) +
220 OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
222 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
223 if (cases[i].expected_success) {
224 base::ExpectDictBooleanValue(
225 true, *interpreter.working_memory(), VAR_HASH_1);
227 EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
232 TEST(JtlInterpreter, CompareHashString) {
234 std::string expected_value;
236 bool expected_success;
238 { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", true },
239 { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_2' }", false },
240 { VALUE_HASH_1, "{ 'KEY_HASH_1': true }", false },
241 { VALUE_HASH_1, "{ 'KEY_HASH_1': 1 }", false },
242 { VALUE_HASH_1, "{ 'KEY_HASH_1': 1.1 }", false },
243 { VALUE_HASH_1, "{ 'KEY_HASH_1': [1] }", false },
244 { VALUE_HASH_1, "{ 'KEY_HASH_1': {'a': 'b'} }", false },
246 { GetHash("1.2"), "{ 'KEY_HASH_1': 1.2 }", true },
247 { GetHash("1.2"), "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false },
248 { GetHash("1.2"), "{ 'KEY_HASH_1': true }", false },
249 { GetHash("1.2"), "{ 'KEY_HASH_1': 1 }", false },
250 { GetHash("1.2"), "{ 'KEY_HASH_1': 1.3 }", false },
251 { GetHash("1.2"), "{ 'KEY_HASH_1': [1] }", false },
252 { GetHash("1.2"), "{ 'KEY_HASH_1': {'a': 'b'} }", false },
254 { GetHash("1"), "{ 'KEY_HASH_1': 1 }", true },
255 { GetHash("1"), "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false },
256 { GetHash("1"), "{ 'KEY_HASH_1': true }", false },
257 { GetHash("1"), "{ 'KEY_HASH_1': 2 }", false },
258 { GetHash("1"), "{ 'KEY_HASH_1': 1.1 }", false },
259 { GetHash("1"), "{ 'KEY_HASH_1': [1] }", false },
260 { GetHash("1"), "{ 'KEY_HASH_1': {'a': 'b'} }", false },
263 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
264 SCOPED_TRACE(testing::Message() << "Iteration " << i);
266 OP_NAVIGATE(KEY_HASH_1) +
267 OP_COMPARE_NODE_HASH(cases[i].expected_value) +
268 OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
270 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
271 if (cases[i].expected_success) {
272 base::ExpectDictBooleanValue(
273 true, *interpreter.working_memory(), VAR_HASH_1);
275 EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
279 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
280 SCOPED_TRACE(testing::Message() << "Negated, Iteration " << i);
282 OP_NAVIGATE(KEY_HASH_1) +
283 OP_COMPARE_NODE_HASH_NOT(cases[i].expected_value) +
284 OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
286 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
287 if (!cases[i].expected_success) {
288 base::ExpectDictBooleanValue(
289 true, *interpreter.working_memory(), VAR_HASH_1);
291 EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
296 TEST(JtlInterpreter, StoreNodeBool) {
300 bool expected_success;
302 { true, "{ 'KEY_HASH_1': true }", true },
303 { false, "{ 'KEY_HASH_1': false }", true },
304 { false, "{ 'KEY_HASH_1': 'abc' }", false },
305 { false, "{ 'KEY_HASH_1': 1 }", false },
306 { false, "{ 'KEY_HASH_1': 1.2 }", false },
307 { false, "{ 'KEY_HASH_1': [1] }", false },
308 { false, "{ 'KEY_HASH_1': {'a': 'b'} }", false },
311 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
312 SCOPED_TRACE(testing::Message() << "Iteration " << i);
314 OP_NAVIGATE(KEY_HASH_1) +
315 OP_STORE_NODE_BOOL(VAR_HASH_1) +
316 OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
318 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
319 if (cases[i].expected_success) {
320 base::ExpectDictBooleanValue(
321 cases[i].expected_value, *interpreter.working_memory(), VAR_HASH_1);
322 base::ExpectDictBooleanValue(
323 true, *interpreter.working_memory(), VAR_HASH_2);
325 EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
326 EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
331 TEST(JtlInterpreter, CompareNodeToStoredBool) {
333 std::string stored_value;
335 bool expected_success;
337 { VALUE_TRUE, "{ 'KEY_HASH_1': true }", true },
338 { VALUE_FALSE, "{ 'KEY_HASH_1': false }", true },
339 { VALUE_FALSE, "{ 'KEY_HASH_1': true }", false },
340 { std::string(), "{ 'KEY_HASH_1': true }", false },
342 { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false },
343 { GetHash("1"), "{ 'KEY_HASH_1': 1 }", false },
344 { GetHash("1.2"), "{ 'KEY_HASH_1': 1.2 }", false },
346 { VALUE_HASH_1, "{ 'KEY_HASH_1': true }", false },
347 { GetHash("1"), "{ 'KEY_HASH_1': true }", false },
348 { GetHash("1.2"), "{ 'KEY_HASH_1': true }", false },
350 { VALUE_TRUE, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false },
351 { VALUE_TRUE, "{ 'KEY_HASH_1': 1 }", false },
352 { VALUE_TRUE, "{ 'KEY_HASH_1': 1.2 }", false },
353 { VALUE_TRUE, "{ 'KEY_HASH_1': [1] }", false },
354 { VALUE_TRUE, "{ 'KEY_HASH_1': {'a': 'b'} }", false },
357 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
358 SCOPED_TRACE(testing::Message() << "Iteration " << i);
359 std::string store_op;
360 if (cases[i].stored_value == VALUE_TRUE ||
361 cases[i].stored_value == VALUE_FALSE)
362 store_op = OP_STORE_BOOL(VAR_HASH_1, cases[i].stored_value);
363 else if (!cases[i].stored_value.empty())
364 store_op = OP_STORE_HASH(VAR_HASH_1, cases[i].stored_value);
367 OP_NAVIGATE(KEY_HASH_1) +
368 OP_COMPARE_NODE_TO_STORED_BOOL(VAR_HASH_1) +
369 OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
371 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
372 if (cases[i].expected_success) {
373 base::ExpectDictBooleanValue(
374 true, *interpreter.working_memory(), VAR_HASH_2);
376 EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
381 TEST(JtlInterpreter, StoreNodeHash) {
383 std::string expected_value;
385 bool expected_success;
387 { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", true },
388 { VALUE_HASH_2, "{ 'KEY_HASH_1': 'VALUE_HASH_2' }", true },
389 { GetHash("1"), "{ 'KEY_HASH_1': 1 }", true },
390 { GetHash("1.2"), "{ 'KEY_HASH_1': 1.2 }", true },
391 { std::string(), "{ 'KEY_HASH_1': true }", false },
392 { std::string(), "{ 'KEY_HASH_1': [1] }", false },
393 { std::string(), "{ 'KEY_HASH_1': {'a': 'b'} }", false },
396 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
397 SCOPED_TRACE(testing::Message() << "Iteration " << i);
399 OP_NAVIGATE(KEY_HASH_1) +
400 OP_STORE_NODE_HASH(VAR_HASH_1) +
401 OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
403 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
404 if (cases[i].expected_success) {
405 base::ExpectDictStringValue(
406 cases[i].expected_value, *interpreter.working_memory(), VAR_HASH_1);
407 base::ExpectDictBooleanValue(
408 true, *interpreter.working_memory(), VAR_HASH_2);
410 EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
411 EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
416 TEST(JtlInterpreter, CompareNodeToStoredHash) {
418 std::string stored_value;
420 bool expected_success;
422 { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", true },
423 { VALUE_HASH_2, "{ 'KEY_HASH_1': 'VALUE_HASH_2' }", true },
424 { std::string(), "{ 'KEY_HASH_1': 'VALUE_HASH_2' }", false },
425 { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_2' }", false },
426 { VALUE_HASH_1, "{ 'KEY_HASH_1': true }", false },
427 { VALUE_HASH_1, "{ 'KEY_HASH_1': 1 }", false },
428 { VALUE_HASH_1, "{ 'KEY_HASH_1': 1.1 }", false },
429 { VALUE_HASH_1, "{ 'KEY_HASH_1': [1] }", false },
430 { VALUE_HASH_1, "{ 'KEY_HASH_1': {'a': 'b'} }", false },
432 { GetHash("1.2"), "{ 'KEY_HASH_1': 1.2 }", true },
433 { GetHash("1.3"), "{ 'KEY_HASH_1': 1.3 }", true },
434 { std::string(), "{ 'KEY_HASH_1': 1.2 }", false },
435 { GetHash("1.2"), "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false },
436 { GetHash("1.2"), "{ 'KEY_HASH_1': true }", false },
437 { GetHash("1.2"), "{ 'KEY_HASH_1': 1 }", false },
438 { GetHash("1.2"), "{ 'KEY_HASH_1': 1.3 }", false },
439 { GetHash("1.2"), "{ 'KEY_HASH_1': [1] }", false },
440 { GetHash("1.2"), "{ 'KEY_HASH_1': {'a': 'b'} }", false },
442 { GetHash("1"), "{ 'KEY_HASH_1': 1 }", true },
443 { GetHash("2"), "{ 'KEY_HASH_1': 2 }", true },
444 { std::string(), "{ 'KEY_HASH_1': 2 }", false },
445 { GetHash("1"), "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false },
446 { GetHash("1"), "{ 'KEY_HASH_1': true }", false },
447 { GetHash("1"), "{ 'KEY_HASH_1': 2 }", false },
448 { GetHash("1"), "{ 'KEY_HASH_1': 1.1 }", false },
449 { GetHash("1"), "{ 'KEY_HASH_1': [1] }", false },
450 { GetHash("1"), "{ 'KEY_HASH_1': {'a': 'b'} }", false },
452 { VALUE_TRUE, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false },
453 { VALUE_TRUE, "{ 'KEY_HASH_1': 1 }", false },
454 { VALUE_TRUE, "{ 'KEY_HASH_1': 1.3 }", false },
455 { VALUE_TRUE, "{ 'KEY_HASH_1': [1] }", false },
456 { VALUE_TRUE, "{ 'KEY_HASH_1': {'a': 'b'} }", false },
458 { VALUE_TRUE, "{ 'KEY_HASH_1': true }", false },
459 { VALUE_FALSE, "{ 'KEY_HASH_1': false }", false },
462 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
463 SCOPED_TRACE(testing::Message() << "Iteration " << i);
464 std::string store_op;
465 if (cases[i].stored_value == VALUE_TRUE ||
466 cases[i].stored_value == VALUE_FALSE)
467 store_op = OP_STORE_BOOL(VAR_HASH_1, cases[i].stored_value);
468 else if (!cases[i].stored_value.empty())
469 store_op = OP_STORE_HASH(VAR_HASH_1, cases[i].stored_value);
472 OP_NAVIGATE(KEY_HASH_1) +
473 OP_COMPARE_NODE_TO_STORED_HASH(VAR_HASH_1) +
474 OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
476 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
477 if (cases[i].expected_success) {
478 base::ExpectDictBooleanValue(
479 true, *interpreter.working_memory(), VAR_HASH_2);
481 EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
486 TEST(JtlInterpreter, Stop) {
488 OP_NAVIGATE(KEY_HASH_1) +
489 OP_NAVIGATE(KEY_HASH_2) +
490 OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE) +
491 OP_STOP_EXECUTING_SENTENCE +
492 OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
493 "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
494 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
495 base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
496 EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
499 TEST(JtlInterpreter, EndOfSentence) {
501 OP_NAVIGATE(KEY_HASH_1) +
502 OP_NAVIGATE(KEY_HASH_2) +
503 OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE) +
505 OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
506 "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
507 EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
508 base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
509 base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_2);
512 TEST(JtlInterpreter, InvalidBack) {
514 OP_NAVIGATE(KEY_HASH_1) +
517 "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
518 EXPECT_EQ(JtlInterpreter::RUNTIME_ERROR, interpreter.result());
521 TEST(JtlInterpreter, IncorrectPrograms) {
522 std::string missing_hash;
523 std::string missing_bool;
524 std::string invalid_hash("123");
525 std::string invalid_bool("\x02", 1);
526 std::string invalid_operation("\x99", 1);
527 std::string programs[] = {
528 OP_NAVIGATE(missing_hash),
529 OP_NAVIGATE(invalid_hash),
530 OP_STORE_BOOL(VAR_HASH_1, invalid_bool),
531 OP_STORE_BOOL(missing_hash, VALUE_TRUE),
532 OP_STORE_BOOL(invalid_hash, VALUE_TRUE),
533 OP_COMPARE_STORED_BOOL(invalid_hash, VALUE_TRUE, VALUE_TRUE),
534 OP_COMPARE_STORED_BOOL(VAR_HASH_1, invalid_bool, VALUE_TRUE),
535 OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_TRUE, invalid_bool),
536 OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_TRUE, missing_bool),
537 OP_STORE_NODE_BOOL(missing_hash),
538 OP_STORE_NODE_BOOL(invalid_hash),
539 OP_STORE_NODE_HASH(missing_hash),
540 OP_STORE_NODE_HASH(invalid_hash),
541 OP_COMPARE_NODE_BOOL(missing_bool),
542 OP_COMPARE_NODE_BOOL(invalid_bool),
543 OP_COMPARE_NODE_HASH(missing_hash),
544 OP_COMPARE_NODE_HASH(invalid_hash),
545 OP_COMPARE_NODE_TO_STORED_BOOL(missing_hash),
546 OP_COMPARE_NODE_TO_STORED_BOOL(invalid_hash),
547 OP_COMPARE_NODE_TO_STORED_HASH(missing_hash),
548 OP_COMPARE_NODE_TO_STORED_HASH(invalid_hash),
551 for (size_t i = 0; i < arraysize(programs); ++i) {
552 SCOPED_TRACE(testing::Message() << "Iteration " << i);
553 INIT_INTERPRETER(programs[i],
554 "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
555 EXPECT_EQ(JtlInterpreter::PARSE_ERROR, interpreter.result());
559 TEST(JtlInterpreter, GetOutput) {
561 OP_STORE_BOOL(GetHash("output1"), VALUE_TRUE) +
562 OP_STORE_HASH(GetHash("output2"), VALUE_HASH_1),
564 bool output1 = false;
566 EXPECT_TRUE(interpreter.GetOutputBoolean("output1", &output1));
567 EXPECT_EQ(true, output1);
568 EXPECT_TRUE(interpreter.GetOutputString("output2", &output2));
569 EXPECT_EQ(VALUE_HASH_1, output2);
570 EXPECT_FALSE(interpreter.GetOutputBoolean("outputxx", &output1));
571 EXPECT_FALSE(interpreter.GetOutputString("outputxx", &output2));