/** * Copyright (c) 2021 OceanBase * OceanBase CE is licensed under Mulan PubL v2. * You can use this software according to the terms and conditions of the Mulan PubL v2. * You may obtain a copy of Mulan PubL v2 at: * http://license.coscl.org.cn/MulanPubL-2.0 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PubL v2 for more details. */ #include #include "lib/string/ob_sql_string.h" #define private public #include "lib/json_type/ob_json_path.h" #include "lib/json_type/ob_json_bin.h" #undef private using namespace oceanbase::common; class TestJsonPath : public ::testing::Test { public: TestJsonPath() {} ~TestJsonPath() {} virtual void SetUp() {} virtual void TearDown() {} static void SetUpTestCase() {} static void TearDownTestCase() {} private: // disallow copy DISALLOW_COPY_AND_ASSIGN(TestJsonPath); }; TEST_F(TestJsonPath, test_get_cnt) { ObJsonPath path(NULL); ASSERT_EQ(0, path.path_node_cnt()); } TEST_F(TestJsonPath, test_is_terminator) { char ch[] = "[. *ibc%^&"; for(int i = 0; i < sizeof(ch); ++i) { if (i <= 3) { ASSERT_EQ(true, ObJsonPathUtil::is_terminator(ch[i])); } else { ASSERT_EQ(false, ObJsonPathUtil::is_terminator(ch[i])); } } } // 测试 basicNode的构造函数 TEST_F(TestJsonPath, test_create_basic_node) { // ** ObJsonPathBasicNode temp1; ASSERT_EQ(0, temp1.init(JPN_ELLIPSIS)); ASSERT_EQ(JPN_ELLIPSIS, temp1.get_node_type()); ASSERT_EQ(true, temp1.get_node_content().is_had_wildcard_); // .* ObJsonPathBasicNode temp2; ASSERT_EQ(0, temp2.init(JPN_MEMBER_WILDCARD)); ASSERT_EQ(JPN_MEMBER_WILDCARD, temp2.get_node_type()); ASSERT_EQ(true, temp2.get_node_content().is_had_wildcard_); // [*] ObJsonPathBasicNode temp3; ASSERT_EQ(0, temp3.init(JPN_ARRAY_CELL_WILDCARD)); ASSERT_EQ(JPN_ARRAY_CELL_WILDCARD, temp3.get_node_type()); ASSERT_EQ(true, temp3.get_node_content().is_had_wildcard_); // [1] ObJsonPathBasicNode temp4(1,false); ASSERT_EQ(JPN_ARRAY_CELL, temp4.get_node_type()); ASSERT_EQ(1, temp4.get_node_content().array_cell_.index_); ASSERT_EQ(false, temp4.get_node_content().array_cell_.is_index_from_end_); // [last-3 to 6] ObJsonPathBasicNode temp5(3, true, 6, false); ASSERT_EQ(JPN_ARRAY_RANGE, temp5.get_node_type()); ASSERT_EQ(3, temp5.get_node_content().array_range_.first_index_); ASSERT_EQ(true, temp5.get_node_content().array_range_.is_first_index_from_end_); ASSERT_EQ(6, temp5.get_node_content().array_range_.last_index_); ASSERT_EQ(false, temp5.get_node_content().array_range_.is_last_index_from_end_); // .keyname ObString kn("keyname"); ObJsonPathBasicNode temp6(kn); ASSERT_EQ(JPN_MEMBER, temp6.get_node_type()); std::cout< (fa1))->get_node_type()); ASSERT_EQ(true, fa1->get_node_content().is_had_wildcard_); } // 测试 append函数 TEST_F(TestJsonPath, test_append) { // append ** int ret = OB_SUCCESS; ObArenaAllocator allocator(ObModIds::TEST); ObJsonPath test_path(&allocator); ObJsonPathBasicNode temp1; ASSERT_EQ(0, temp1.init(JPN_ELLIPSIS)); ObJsonPathNode *fa1 = &temp1; ret = test_path.append(fa1); ASSERT_EQ(OB_SUCCESS,ret); ASSERT_EQ(JPN_ELLIPSIS, test_path.path_nodes_[0]->get_node_type()); ASSERT_EQ(true, test_path.path_nodes_[0]->get_node_content().is_had_wildcard_); // append .* ObJsonPathBasicNode temp2; ASSERT_EQ(0, temp2.init(JPN_MEMBER_WILDCARD)); ObJsonPathNode *fa2 = &temp2; ret = test_path.append(fa2); ASSERT_EQ(OB_SUCCESS,ret); ASSERT_EQ(JPN_MEMBER_WILDCARD, test_path.path_nodes_[1]->get_node_type()); ASSERT_EQ(true, test_path.path_nodes_[1]->get_node_content().is_had_wildcard_); // append [*] ObJsonPathBasicNode temp3; ASSERT_EQ(0, temp3.init(JPN_ARRAY_CELL_WILDCARD)); ObJsonPathNode *fa3 = &temp3; ret = test_path.append(fa3); ASSERT_EQ(OB_SUCCESS,ret); ASSERT_EQ(JPN_ARRAY_CELL_WILDCARD, test_path.path_nodes_[2]->get_node_type()); ASSERT_EQ(true, test_path.path_nodes_[2]->get_node_content().is_had_wildcard_); // append array_cell ObJsonPathBasicNode temp4(1,false); ObJsonPathNode *fa4 = &temp4; ret = test_path.append(fa4); ASSERT_EQ(OB_SUCCESS,ret); ASSERT_EQ(JPN_ARRAY_CELL, test_path.path_nodes_[3]->get_node_type()); ASSERT_EQ(1, test_path.path_nodes_[3]->get_node_content().array_cell_.index_); ASSERT_EQ(false, test_path.path_nodes_[3]->get_node_content().array_cell_.is_index_from_end_); // [last-3 to 6] ObJsonPathBasicNode temp5(3, true, 6, false); ObJsonPathNode *fa5 = &temp5; ret = test_path.append(fa5); ASSERT_EQ(OB_SUCCESS,ret); ASSERT_EQ(JPN_ARRAY_RANGE, test_path.path_nodes_[4]->get_node_type()); ASSERT_EQ(3, test_path.path_nodes_[4]->get_node_content().array_range_.first_index_); ASSERT_EQ(true, test_path.path_nodes_[4]->get_node_content().array_range_.is_first_index_from_end_); ASSERT_EQ(6, test_path.path_nodes_[4]->get_node_content().array_range_.last_index_); ASSERT_EQ(false, test_path.path_nodes_[4]->get_node_content().array_range_.is_last_index_from_end_); // .keyname ObString kn("keyname"); ObJsonPathBasicNode temp6(kn); ObJsonPathNode *fa6 = &temp6; ret = test_path.append(fa6); ASSERT_EQ(OB_SUCCESS,ret); ASSERT_EQ(JPN_MEMBER, test_path.path_nodes_[5]->get_node_type()); std::cout<<"6: "<get_node_content().member_.object_name_<node_type); //ASSERT_EQ(10, test_path1.path_nodes_[0]->path_node_content_.array_cell_.index_); //ASSERT_EQ(false, test_path1.path_nodes_[0]->path_node_content_.array_cell_.index_); } // 测试能否正确解析array_cell_node TEST_F(TestJsonPath, test_array_cell_node) { int ret = OB_SUCCESS; ObArenaAllocator allocator(ObModIds::TEST); ObJsonPath test_path("$[10]", &allocator); ret = test_path.parse_path(); ASSERT_EQ(OB_SUCCESS, ret); // 只有一个节点 ASSERT_EQ(1, test_path.path_node_cnt()); ASSERT_EQ(JPN_ARRAY_CELL,test_path.path_nodes_[0]->get_node_type()); ASSERT_EQ(10,test_path.path_nodes_[0]->get_node_content().array_cell_.index_); ASSERT_EQ(false,test_path.path_nodes_[0]->get_node_content().array_cell_.is_index_from_end_); } // 测试能否正确解析array_range_node TEST_F(TestJsonPath, test_array_range_node) { int ret = OB_SUCCESS; ObArenaAllocator allocator(ObModIds::TEST); ObJsonPath test_path("$[1 to 10]", &allocator); ret = test_path.parse_path(); ASSERT_EQ(OB_SUCCESS, ret); // 只有一个节点 ASSERT_EQ(1, test_path.path_node_cnt()); ASSERT_EQ(JPN_ARRAY_RANGE,test_path.path_nodes_[0]->get_node_type()); ASSERT_EQ(1,test_path.path_nodes_[0]->get_node_content().array_range_.first_index_); ASSERT_EQ(false,test_path.path_nodes_[0]->get_node_content().array_range_.is_first_index_from_end_); ASSERT_EQ(10,test_path.path_nodes_[0]->get_node_content().array_range_.last_index_); ASSERT_EQ(false,test_path.path_nodes_[0]->get_node_content().array_range_.is_last_index_from_end_); } // 测试能否正确解析array_range_wildcard_node TEST_F(TestJsonPath, test_array_wildcard_node) { int ret = OB_SUCCESS; ObArenaAllocator allocator(ObModIds::TEST); ObJsonPath test_path("$[*]", &allocator); ret = test_path.parse_path(); ASSERT_EQ(OB_SUCCESS, ret); // 只有一个节点 ASSERT_EQ(1, test_path.path_node_cnt()); ASSERT_EQ(JPN_ARRAY_CELL_WILDCARD,test_path.path_nodes_[0]->get_node_type()); } // 测试能否正确解析member_wildcard_node TEST_F(TestJsonPath, test_member_wildcard_node) { int ret = OB_SUCCESS; ObArenaAllocator allocator(ObModIds::TEST); ObJsonPath test_path("$.*", &allocator); ret = test_path.parse_path(); ASSERT_EQ(OB_SUCCESS, ret); // 只有一个节点 ASSERT_EQ(1, test_path.path_node_cnt()); ASSERT_EQ(JPN_MEMBER_WILDCARD,test_path.path_nodes_[0]->get_node_type()); } // 测试能否正确解析member_node TEST_F(TestJsonPath, test_member_node) { int ret = OB_SUCCESS; ObString str_orgin("$.name"); ObArenaAllocator allocator(ObModIds::TEST); ObJsonPath test_path(str_orgin, &allocator); ret = test_path.parse_path(); ASSERT_EQ(OB_SUCCESS, ret); std::cout<<"test"<get_node_type()); ObString str(test_path.path_nodes_[0]->get_node_content().member_.object_name_); ASSERT_TRUE(str.case_compare("name") == 0); std::cout<get_node_content().member_.object_name_<get_node_type()); ASSERT_EQ(JPN_ARRAY_CELL,test_path.path_nodes_[1]->get_node_type()); ASSERT_EQ(10,test_path.path_nodes_[1]->get_node_content().array_cell_.index_); ASSERT_EQ(false,test_path.path_nodes_[1]->get_node_content().array_cell_.is_index_from_end_); } // 测试能否成功解析path表达式 TEST_F(TestJsonPath, test_parse_path) { int ret = OB_SUCCESS; ObArenaAllocator allocator(ObModIds::TEST); ObJsonPath test_path("$[last-10 to last-1]", &allocator); ret = test_path.parse_path(); ASSERT_EQ(OB_SUCCESS, ret); // 只有一个节点 ASSERT_EQ(1, test_path.path_node_cnt()); if (OB_SUCC(ret)) { for(int i=0; inode_type); std::cout<node_type); /* ASSERT_EQ(JPN_MEMBER,test_path.path_nodes_[i]->node_type); std::cout<get_node_content().member_.object_name_<node_type); ASSERT_EQ(10,test_path.path_nodes_[i]->get_node_content().array_cell_.index_); ASSERT_EQ(true,test_path.path_nodes_[i]->get_node_content().array_cell_.is_index_from_end_); */ ASSERT_EQ(10,test_path.path_nodes_[i]->get_node_content().array_range_.first_index_); ASSERT_EQ(true,test_path.path_nodes_[i]->get_node_content().array_range_.is_first_index_from_end_); ASSERT_EQ(1,test_path.path_nodes_[i]->get_node_content().array_range_.last_index_); ASSERT_EQ(true,test_path.path_nodes_[i]->get_node_content().array_range_.is_last_index_from_end_); } } } else { std::cout<<"fail\n"; } } // test tostring // test array_cell node to string TEST_F(TestJsonPath, test_array_cell_node_to_string) { ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer str(&allocator); ObJsonPathBasicNode node(10, true); node.node_to_string(str); std::cout<get_node_type()<get_node_content().member_.object_name_<get_node_content().array_cell_.index_<get_node_content().array_cell_.is_index_from_end_<get_path_string().ptr(), read_ok_path1->get_path_string().ptr()); // cache stratety works, iff the path string unchanged, the path needn't parse again ret = path_cache.find_and_add_cache(json_path, ok_path1, ok_path1_idx); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(json_path, read_ok_path1); ObString ok_path2 = " $.\" abc d \" "; // some spaces do not has any effect upon the path cache ret = path_cache.find_and_add_cache(json_path, ok_path2, ok_path1_idx); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(json_path, read_ok_path1); ObJsonPath* read_ok_path2 = path_cache.path_at(ok_path1_idx); ASSERT_EQ(read_ok_path2, read_ok_path1); } TEST_F(TestJsonPath, test_pathcache_exprire) { int ret = OB_SUCCESS; ObArenaAllocator allocator(ObModIds::TEST); ObJsonPathCache path_cache(&allocator); ObString ok_path1 = "$.\"abc d\""; // test a nornal json path ObJsonPath* json_path = NULL; int ok_path1_idx = path_cache.size(); // parse a normal path ret = path_cache.find_and_add_cache(json_path, ok_path1, ok_path1_idx); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(path_cache.path_stat_at(ok_path1_idx), ObPathParseStat::OK_NOT_NULL); ObJsonPath* read_ok_path1 = path_cache.path_at(ok_path1_idx); ObString ok_path2 = " $.\"efs d \""; // some spaces do not has any effect upon the path cache ret = path_cache.find_and_add_cache(json_path, ok_path2, ok_path1_idx); ASSERT_EQ(ret, OB_SUCCESS); // json path string differs, cache invalid ASSERT_NE(json_path, read_ok_path1); ObJsonPath* read_ok_path2 = path_cache.path_at(ok_path1_idx); ASSERT_EQ(read_ok_path2, json_path); } TEST_F(TestJsonPath, test_pathcache_reset) { int ret = OB_SUCCESS; ObArenaAllocator allocator(ObModIds::TEST); ObJsonPathCache path_cache(&allocator); ObString ok_path1 = "$.\"abc d\""; // test a nornal json path ObJsonPath* json_path = NULL; int ok_path1_idx = path_cache.size(); // parse a normal path ret = path_cache.find_and_add_cache(json_path, ok_path1, ok_path1_idx); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(path_cache.path_stat_at(ok_path1_idx), ObPathParseStat::OK_NOT_NULL); path_cache.reset(); ASSERT_EQ(path_cache.path_stat_at(ok_path1_idx), ObPathParseStat::UNINITIALIZED); ASSERT_EQ(path_cache.size(), 0); } int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); /* system("rm -f test_json_path.log"); OB_LOGGER.set_file_name("test_json_path.log"); OB_LOGGER.set_log_level("INFO"); */ return RUN_ALL_TESTS(); }