11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2011 The Chromium Authors. All rights reserved.
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file.
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/profile_resetter/jtl_interpreter.h"
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <numeric>
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/string_util.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/test/values_test_util.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/profile_resetter/jtl_foundation.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/profile_resetter/jtl_instructions.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "crypto/hmac.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "testing/gtest/include/gtest/gtest.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace {
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst char seed[] = "foobar";
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define KEY_HASH_1 GetHash("KEY_HASH_1")
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define KEY_HASH_2 GetHash("KEY_HASH_2")
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define KEY_HASH_3 GetHash("KEY_HASH_3")
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define KEY_HASH_4 GetHash("KEY_HASH_4")
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define VALUE_HASH_1 GetHash("VALUE_HASH_1")
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define VALUE_HASH_2 GetHash("VALUE_HASH_2")
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define VAR_HASH_1 "01234567890123456789012345678901"
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define VAR_HASH_2 "12345678901234567890123456789012"
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistd::string GetHash(const std::string& input) {
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return jtl_foundation::Hasher(seed).GetHash(input);
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistd::string EncodeUint32(uint32 value) {
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string bytecode;
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (int i = 0; i < 4; ++i) {
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bytecode.push_back(static_cast<char>(value & 0xFFu));
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    value >>= 8;
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return bytecode;
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// escaped_json_param may contain ' characters that are replaced with ". This
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// makes the code more readable because we need less escaping.
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define INIT_INTERPRETER(program_param, escaped_json_param) \
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* escaped_json = escaped_json_param; \
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::string json; \
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::ReplaceChars(escaped_json, "'", "\"", &json); \
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<base::Value> json_value(ParseJson(json)); \
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    JtlInterpreter interpreter( \
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        seed, \
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        program_param, \
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        static_cast<const base::DictionaryValue*>(json_value.get())); \
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    interpreter.Execute()
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing base::test::ParseJson;
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, Store) {
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  INIT_INTERPRETER(
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "{ 'KEY_HASH_1': 'VALUE_HASH_1' }");
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, NavigateAndStore) {
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  INIT_INTERPRETER(
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_1) +
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "{ 'KEY_HASH_1': 'VALUE_HASH_1' }");
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, FailNavigate) {
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  INIT_INTERPRETER(
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_2) +
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "{ 'KEY_HASH_1': 'VALUE_HASH_1' }");
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, ConsecutiveNavigate) {
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  INIT_INTERPRETER(
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_1) +
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_2) +
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, FailConsecutiveNavigate) {
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  INIT_INTERPRETER(
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_1) +
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_2) +
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "{ 'KEY_HASH_1': 'foo' }");
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, NavigateAnyInDictionary) {
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  INIT_INTERPRETER(
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_1) +
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE_ANY +
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_4) +
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          "{ 'KEY_HASH_1':"
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          "  { 'KEY_HASH_2': {'KEY_HASH_3': 'VALUE_HASH_1' },"
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          "    'KEY_HASH_3': {'KEY_HASH_4': 'VALUE_HASH_1' }"
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          "  } }");
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, NavigateAnyInList) {
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  INIT_INTERPRETER(
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_1) +
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE_ANY +
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_4) +
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          "{ 'KEY_HASH_1':"
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          "  [ {'KEY_HASH_3': 'VALUE_HASH_1' },"
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          "    {'KEY_HASH_4': 'VALUE_HASH_1' }"
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          "  ] }");
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, NavigateBack) {
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  INIT_INTERPRETER(
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_1) +
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_2) +
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE_BACK +
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_3) +
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_4) +
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          "{ 'KEY_HASH_1':"
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          "  { 'KEY_HASH_2': {'KEY_HASH_3': 'VALUE_HASH_1' },"
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          "    'KEY_HASH_3': {'KEY_HASH_4': 'VALUE_HASH_1' }"
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          "  } }");
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, StoreTwoValues) {
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  INIT_INTERPRETER(
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_1) +
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_2) +
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE) +
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_HASH(VAR_HASH_2, VALUE_HASH_1),
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::ExpectDictStringValue(VALUE_HASH_1, *interpreter.working_memory(),
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              VAR_HASH_2);
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, CompareStoredMatch) {
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  INIT_INTERPRETER(
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_1) +
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE) +
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_2) +
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_TRUE, VALUE_FALSE) +
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_2);
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, CompareStoredMismatch) {
1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  INIT_INTERPRETER(
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_1) +
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE) +
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_2) +
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_FALSE, VALUE_TRUE) +
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, CompareStoredNoValueMatchingDefault) {
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  INIT_INTERPRETER(
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_1) +
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_2) +
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_TRUE, VALUE_TRUE) +
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_2);
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, CompareStoredNoValueMismatchingDefault) {
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  INIT_INTERPRETER(
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_1) +
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_2) +
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_TRUE, VALUE_FALSE) +
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, CompareBool) {
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct TestCase {
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::string expected_value;
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* json;
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool expected_success;
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } cases[] = {
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_TRUE, "{ 'KEY_HASH_1': true }", true },
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_FALSE, "{ 'KEY_HASH_1': false }", true },
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_TRUE, "{ 'KEY_HASH_1': false }", false },
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_TRUE, "{ 'KEY_HASH_1': 'abc' }", false },
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_TRUE, "{ 'KEY_HASH_1': 1 }", false },
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_TRUE, "{ 'KEY_HASH_1': 1.2 }", false },
2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_TRUE, "{ 'KEY_HASH_1': [1] }", false },
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_TRUE, "{ 'KEY_HASH_1': {'a': 'b'} }", false },
2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(testing::Message() << "Iteration " << i);
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    INIT_INTERPRETER(
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_NAVIGATE(KEY_HASH_1) +
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_COMPARE_NODE_BOOL(cases[i].expected_value) +
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        cases[i].json);
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (cases[i].expected_success) {
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::ExpectDictBooleanValue(
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          true, *interpreter.working_memory(), VAR_HASH_1);
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, CompareHashString) {
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct TestCase {
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::string expected_value;
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* json;
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool expected_success;
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } cases[] = {
2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", true },
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_2' }", false },
2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': true }", false },
2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': 1 }", false },
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': 1.1 }", false },
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': [1] }", false },
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': {'a': 'b'} }", false },
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1.2"), "{ 'KEY_HASH_1': 1.2 }", true },
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1.2"), "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false },
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1.2"), "{ 'KEY_HASH_1': true }", false },
2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1.2"), "{ 'KEY_HASH_1': 1 }", false },
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1.2"), "{ 'KEY_HASH_1': 1.3 }", false },
2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1.2"), "{ 'KEY_HASH_1': [1] }", false },
2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1.2"), "{ 'KEY_HASH_1': {'a': 'b'} }", false },
2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1"), "{ 'KEY_HASH_1': 1 }", true },
2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1"), "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false },
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1"), "{ 'KEY_HASH_1': true }", false },
2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1"), "{ 'KEY_HASH_1': 2 }", false },
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1"), "{ 'KEY_HASH_1': 1.1 }", false },
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1"), "{ 'KEY_HASH_1': [1] }", false },
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1"), "{ 'KEY_HASH_1': {'a': 'b'} }", false },
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(testing::Message() << "Iteration " << i);
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    INIT_INTERPRETER(
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_NAVIGATE(KEY_HASH_1) +
2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_COMPARE_NODE_HASH(cases[i].expected_value) +
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        cases[i].json);
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (cases[i].expected_success) {
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::ExpectDictBooleanValue(
2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          true, *interpreter.working_memory(), VAR_HASH_1);
2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(testing::Message() << "Negated, Iteration " << i);
2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    INIT_INTERPRETER(
2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_NAVIGATE(KEY_HASH_1) +
2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_COMPARE_NODE_HASH_NOT(cases[i].expected_value) +
2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        cases[i].json);
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!cases[i].expected_success) {
2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::ExpectDictBooleanValue(
3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          true, *interpreter.working_memory(), VAR_HASH_1);
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, StoreNodeBool) {
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct TestCase {
3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool expected_value;
3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* json;
3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool expected_success;
3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } cases[] = {
3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { true, "{ 'KEY_HASH_1': true }", true },
3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { false, "{ 'KEY_HASH_1': false }", true },
3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { false, "{ 'KEY_HASH_1': 'abc' }", false },
3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { false, "{ 'KEY_HASH_1': 1 }", false },
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { false, "{ 'KEY_HASH_1': 1.2 }", false },
3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { false, "{ 'KEY_HASH_1': [1] }", false },
3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { false, "{ 'KEY_HASH_1': {'a': 'b'} }", false },
3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(testing::Message() << "Iteration " << i);
3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    INIT_INTERPRETER(
3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_NAVIGATE(KEY_HASH_1) +
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_STORE_NODE_BOOL(VAR_HASH_1) +
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        cases[i].json);
3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (cases[i].expected_success) {
3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::ExpectDictBooleanValue(
3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          cases[i].expected_value, *interpreter.working_memory(), VAR_HASH_1);
3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::ExpectDictBooleanValue(
3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          true, *interpreter.working_memory(), VAR_HASH_2);
3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, CompareNodeToStoredBool) {
3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct TestCase {
3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::string stored_value;
3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* json;
3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool expected_success;
3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } cases[] = {
3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_TRUE, "{ 'KEY_HASH_1': true }", true },
3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_FALSE, "{ 'KEY_HASH_1': false }", true },
3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_FALSE, "{ 'KEY_HASH_1': true }", false },
3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { std::string(), "{ 'KEY_HASH_1': true }", false },
3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false },
3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1"), "{ 'KEY_HASH_1': 1 }", false },
3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1.2"), "{ 'KEY_HASH_1': 1.2 }", false },
3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': true }", false },
3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1"), "{ 'KEY_HASH_1': true }", false },
3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1.2"), "{ 'KEY_HASH_1': true }", false },
3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_TRUE, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false },
3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_TRUE, "{ 'KEY_HASH_1': 1 }", false },
3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_TRUE, "{ 'KEY_HASH_1': 1.2 }", false },
3641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_TRUE, "{ 'KEY_HASH_1': [1] }", false },
3651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_TRUE, "{ 'KEY_HASH_1': {'a': 'b'} }", false },
3661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
3671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
3691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(testing::Message() << "Iteration " << i);
3701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::string store_op;
3711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (cases[i].stored_value == VALUE_TRUE ||
3721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        cases[i].stored_value == VALUE_FALSE)
3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      store_op = OP_STORE_BOOL(VAR_HASH_1, cases[i].stored_value);
3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    else if (!cases[i].stored_value.empty())
3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      store_op = OP_STORE_HASH(VAR_HASH_1, cases[i].stored_value);
3761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    INIT_INTERPRETER(
3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        store_op +
3781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_NAVIGATE(KEY_HASH_1) +
3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_COMPARE_NODE_TO_STORED_BOOL(VAR_HASH_1) +
3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        cases[i].json);
3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (cases[i].expected_success) {
3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::ExpectDictBooleanValue(
3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          true, *interpreter.working_memory(), VAR_HASH_2);
3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, StoreNodeHash) {
3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct TestCase {
3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::string expected_value;
3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* json;
3961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool expected_success;
3971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } cases[] = {
3981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", true },
3991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_2, "{ 'KEY_HASH_1': 'VALUE_HASH_2' }", true },
4001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1"), "{ 'KEY_HASH_1': 1 }", true },
4011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1.2"), "{ 'KEY_HASH_1': 1.2 }", true },
4021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { std::string(), "{ 'KEY_HASH_1': true }", false },
4031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { std::string(), "{ 'KEY_HASH_1': [1] }", false },
4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { std::string(), "{ 'KEY_HASH_1': {'a': 'b'} }", false },
4051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
4061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
4081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(testing::Message() << "Iteration " << i);
4091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    INIT_INTERPRETER(
4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_NAVIGATE(KEY_HASH_1) +
4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_STORE_NODE_HASH(VAR_HASH_1) +
4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        cases[i].json);
4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (cases[i].expected_success) {
4161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::ExpectDictStringValue(
4171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          cases[i].expected_value, *interpreter.working_memory(), VAR_HASH_1);
4181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::ExpectDictBooleanValue(
4191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          true, *interpreter.working_memory(), VAR_HASH_2);
4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
4211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
4221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, CompareNodeToStoredHash) {
4281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct TestCase {
4291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::string stored_value;
4301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* json;
4311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool expected_success;
4321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } cases[] = {
4331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", true },
4341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_2, "{ 'KEY_HASH_1': 'VALUE_HASH_2' }", true },
4351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { std::string(), "{ 'KEY_HASH_1': 'VALUE_HASH_2' }", false },
4361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_2' }", false },
4371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': true }", false },
4381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': 1 }", false },
4391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': 1.1 }", false },
4401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': [1] }", false },
4411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': {'a': 'b'} }", false },
4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1.2"), "{ 'KEY_HASH_1': 1.2 }", true },
4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1.3"), "{ 'KEY_HASH_1': 1.3 }", true },
4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { std::string(), "{ 'KEY_HASH_1': 1.2 }", false },
4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1.2"), "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false },
4471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1.2"), "{ 'KEY_HASH_1': true }", false },
4481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1.2"), "{ 'KEY_HASH_1': 1 }", false },
4491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1.2"), "{ 'KEY_HASH_1': 1.3 }", false },
4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1.2"), "{ 'KEY_HASH_1': [1] }", false },
4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1.2"), "{ 'KEY_HASH_1': {'a': 'b'} }", false },
4521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1"), "{ 'KEY_HASH_1': 1 }", true },
4541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("2"), "{ 'KEY_HASH_1': 2 }", true },
4551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { std::string(), "{ 'KEY_HASH_1': 2 }", false },
4561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1"), "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false },
4571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1"), "{ 'KEY_HASH_1': true }", false },
4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1"), "{ 'KEY_HASH_1': 2 }", false },
4591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1"), "{ 'KEY_HASH_1': 1.1 }", false },
4601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1"), "{ 'KEY_HASH_1': [1] }", false },
4611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("1"), "{ 'KEY_HASH_1': {'a': 'b'} }", false },
4621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_TRUE, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false },
4641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_TRUE, "{ 'KEY_HASH_1': 1 }", false },
4651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_TRUE, "{ 'KEY_HASH_1': 1.3 }", false },
4661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_TRUE, "{ 'KEY_HASH_1': [1] }", false },
4671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_TRUE, "{ 'KEY_HASH_1': {'a': 'b'} }", false },
4681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_TRUE, "{ 'KEY_HASH_1': true }", false },
4701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_FALSE, "{ 'KEY_HASH_1': false }", false },
4711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
4721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
4741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(testing::Message() << "Iteration " << i);
4751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::string store_op;
4761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (cases[i].stored_value == VALUE_TRUE ||
4771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        cases[i].stored_value == VALUE_FALSE)
4781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      store_op = OP_STORE_BOOL(VAR_HASH_1, cases[i].stored_value);
4791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    else if (!cases[i].stored_value.empty())
4801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      store_op = OP_STORE_HASH(VAR_HASH_1, cases[i].stored_value);
4811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    INIT_INTERPRETER(
4821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        store_op +
4831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_NAVIGATE(KEY_HASH_1) +
4841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_COMPARE_NODE_TO_STORED_HASH(VAR_HASH_1) +
4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
4861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        cases[i].json);
4871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
4881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (cases[i].expected_success) {
4891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::ExpectDictBooleanValue(
4901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          true, *interpreter.working_memory(), VAR_HASH_2);
4911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
4921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
4931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
4941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, CompareSubstring) {
4981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct TestCase {
4991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::string pattern;
5001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* json;
5011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool expected_success;
5021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } cases[] = {
5031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { "abc", "{ 'KEY_HASH_1': 'abcdefghijklmnopqrstuvwxyz' }", true },
5041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { "xyz", "{ 'KEY_HASH_1': 'abcdefghijklmnopqrstuvwxyz' }", true },
5051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { "m", "{ 'KEY_HASH_1': 'abcdefghijklmnopqrstuvwxyz' }", true },
5061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { "abc", "{ 'KEY_HASH_1': 'abc' }", true },
5071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { "cba", "{ 'KEY_HASH_1': 'abcdefghijklmnopqrstuvwxyz' }", false },
5081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { "acd", "{ 'KEY_HASH_1': 'abcdefghijklmnopqrstuvwxyz' }", false },
5091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { "waaaaaaay_too_long", "{ 'KEY_HASH_1': 'abc' }", false },
5101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': true }", false },
5121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': 1 }", false },
5131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': 1.1 }", false },
5141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': [1] }", false },
5151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { VALUE_HASH_1, "{ 'KEY_HASH_1': {'a': 'b'} }", false },
5161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
5171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
5191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(testing::Message() << "Iteration " << i);
5201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::string pattern = cases[i].pattern;
5211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uint32 pattern_sum = std::accumulate(
5221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        pattern.begin(), pattern.end(), static_cast<uint32>(0u));
5231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    INIT_INTERPRETER(
5241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_NAVIGATE(KEY_HASH_1) +
5251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_COMPARE_NODE_SUBSTRING(GetHash(pattern),
5261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  EncodeUint32(pattern.size()),
5271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  EncodeUint32(pattern_sum)) +
5281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
5291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        cases[i].json);
5301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
5311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (cases[i].expected_success) {
5321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::ExpectDictBooleanValue(
5331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          true, *interpreter.working_memory(), VAR_HASH_1);
5341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
5351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
5361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
5371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
5381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
5391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, StoreNodeRegisterableDomainHash) {
5411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct TestCase {
5421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::string expected_value;
5431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* json;
5441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool expected_success;
5451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } cases[] = {
5461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("google"), "{ 'KEY_HASH_1': 'http://google.com/path' }", true },
5471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("google"), "{ 'KEY_HASH_1': 'http://mail.google.com/' }", true },
5481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("google"), "{ 'KEY_HASH_1': 'http://google.co.uk/' }", true },
5491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("google"), "{ 'KEY_HASH_1': 'http://google.com./' }", true },
5501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("google"), "{ 'KEY_HASH_1': 'http://..google.com/' }", true },
5511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("foo"), "{ 'KEY_HASH_1': 'http://foo.bar/path' }", true },
5531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("foo"), "{ 'KEY_HASH_1': 'http://sub.foo.bar' }", true },
5541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("foo"), "{ 'KEY_HASH_1': 'http://foo.appspot.com/' }", true },
5551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { GetHash("foo"), "{ 'KEY_HASH_1': 'http://sub.foo.appspot.com' }", true },
5561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { std::string(), "{ 'KEY_HASH_1': 'http://google.com../' }", false },
5581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { std::string(), "{ 'KEY_HASH_1': 'http://bar/path' }", false },
5601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { std::string(), "{ 'KEY_HASH_1': 'http://co.uk/path' }", false },
5611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { std::string(), "{ 'KEY_HASH_1': 'http://appspot.com/path' }", false },
5621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { std::string(), "{ 'KEY_HASH_1': 'http://127.0.0.1/path' }", false },
5631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { std::string(), "{ 'KEY_HASH_1': 'file:///C:/bar.html' }", false },
5641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { std::string(), "{ 'KEY_HASH_1': 1 }", false },
5661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { std::string(), "{ 'KEY_HASH_1': 1.2 }", false },
5671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { std::string(), "{ 'KEY_HASH_1': true }", false },
5681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { std::string(), "{ 'KEY_HASH_1': [1] }", false },
5691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    { std::string(), "{ 'KEY_HASH_1': {'a': 'b'} }", false },
5701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
5711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
5731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(testing::Message() << "Iteration " << i);
5741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    INIT_INTERPRETER(
5751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_NAVIGATE(KEY_HASH_1) +
5761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_STORE_NODE_REGISTERABLE_DOMAIN_HASH(VAR_HASH_1) +
5771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
5781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        cases[i].json);
5791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
5801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (cases[i].expected_success) {
5811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::ExpectDictStringValue(
5821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          cases[i].expected_value, *interpreter.working_memory(), VAR_HASH_1);
5831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::ExpectDictBooleanValue(
5841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          true, *interpreter.working_memory(), VAR_HASH_2);
5851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
5861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
5871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
5881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
5891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
5901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
5911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, Stop) {
5931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  INIT_INTERPRETER(
5941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_1) +
5951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_2) +
5961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE) +
5971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STOP_EXECUTING_SENTENCE +
5981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
5991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
6001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
6011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
6021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
6031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
6041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, EndOfSentence) {
6061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  INIT_INTERPRETER(
6071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_1) +
6081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_2) +
6091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE) +
6101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_END_OF_SENTENCE +
6111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
6121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
6131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
6141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
6151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_2);
6161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
6171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, InvalidBack) {
6191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  INIT_INTERPRETER(
6201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE(KEY_HASH_1) +
6211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE_BACK +
6221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_NAVIGATE_BACK,
6231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
6241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(JtlInterpreter::RUNTIME_ERROR, interpreter.result());
6251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
6261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, IncorrectPrograms) {
6281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string missing_hash;
6291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string missing_bool;
6301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string invalid_hash("123");
6311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string invalid_bool("\x02", 1);
6321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string invalid_operation("\x99", 1);
6331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string programs[] = {
6341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OP_NAVIGATE(missing_hash),
6351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OP_NAVIGATE(invalid_hash),
6361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OP_STORE_BOOL(VAR_HASH_1, invalid_bool),
6371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OP_STORE_BOOL(missing_hash, VALUE_TRUE),
6381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OP_STORE_BOOL(invalid_hash, VALUE_TRUE),
6391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OP_COMPARE_STORED_BOOL(invalid_hash, VALUE_TRUE, VALUE_TRUE),
6401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OP_COMPARE_STORED_BOOL(VAR_HASH_1, invalid_bool, VALUE_TRUE),
6411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_TRUE, invalid_bool),
6421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_TRUE, missing_bool),
6431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OP_STORE_NODE_BOOL(missing_hash),
6441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OP_STORE_NODE_BOOL(invalid_hash),
6451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OP_STORE_NODE_HASH(missing_hash),
6461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OP_STORE_NODE_HASH(invalid_hash),
6471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OP_COMPARE_NODE_BOOL(missing_bool),
6481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OP_COMPARE_NODE_BOOL(invalid_bool),
6491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OP_COMPARE_NODE_HASH(missing_hash),
6501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OP_COMPARE_NODE_HASH(invalid_hash),
6511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OP_COMPARE_NODE_TO_STORED_BOOL(missing_hash),
6521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OP_COMPARE_NODE_TO_STORED_BOOL(invalid_hash),
6531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OP_COMPARE_NODE_TO_STORED_HASH(missing_hash),
6541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OP_COMPARE_NODE_TO_STORED_HASH(invalid_hash),
6551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    invalid_operation,
6561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
6571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < arraysize(programs); ++i) {
6581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(testing::Message() << "Iteration " << i);
6591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    INIT_INTERPRETER(programs[i],
6601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
6611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(JtlInterpreter::PARSE_ERROR, interpreter.result());
6621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
6631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
6641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, GetOutput) {
6661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  INIT_INTERPRETER(
6671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_BOOL(GetHash("output1"), VALUE_TRUE) +
6681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OP_STORE_HASH(GetHash("output2"), VALUE_HASH_1),
6691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "{}");
6701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool output1 = false;
6711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string output2;
6721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(interpreter.GetOutputBoolean("output1", &output1));
6731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(true, output1);
6741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(interpreter.GetOutputString("output2", &output2));
6751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(VALUE_HASH_1, output2);
6761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(interpreter.GetOutputBoolean("outputxx", &output1));
6771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(interpreter.GetOutputString("outputxx", &output2));
6781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
6791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(JtlInterpreter, CalculateProgramChecksum) {
6811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const char kTestSeed[] = "Irrelevant seed value.";
6821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const char kTestProgram[] = "The quick brown fox jumps over the lazy dog.";
6831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // This program is invalid, but we are not actually executing it.
6841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::DictionaryValue input;
6851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  JtlInterpreter interpreter(kTestSeed, kTestProgram, &input);
6861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0xef537f, interpreter.CalculateProgramChecksum());
6871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
6881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace
690