| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "ignite/client/table/qualified_name.h" |
| #include "ignite/common/ignite_error.h" |
| |
| #include <gmock/gmock-matchers.h> |
| #include <gtest/gtest.h> |
| |
| using namespace ignite; |
| using namespace detail; |
| |
| namespace { |
| |
| template<typename T> |
| std::string PrintTestIndex(const testing::TestParamInfo<typename T::ParamType>& info) { |
| return "_" + std::to_string(info.index); |
| } |
| |
| } |
| |
| TEST(client_qualified_name, create_empty_schema_empty_name_throws) { |
| EXPECT_THROW( |
| { |
| try { |
| (void)qualified_name::create({}, {}); |
| } catch (const ignite_error &e) { |
| EXPECT_EQ(e.get_status_code(), error::code::ILLEGAL_ARGUMENT); |
| EXPECT_THAT(e.what_str(), testing::HasSubstr("Object name can not be empty")); |
| throw; |
| } |
| }, |
| ignite_error); |
| } |
| |
| TEST(client_qualified_name, create_empty_name_throws) { |
| EXPECT_THROW( |
| { |
| try { |
| (void)qualified_name::create("TEST", {}); |
| } catch (const ignite_error &e) { |
| EXPECT_EQ(e.get_status_code(), error::code::ILLEGAL_ARGUMENT); |
| EXPECT_THAT(e.what_str(), testing::HasSubstr("Object name can not be empty")); |
| throw; |
| } |
| }, |
| ignite_error); |
| } |
| |
| TEST(client_qualified_name, parse_empty_name_throws) { |
| EXPECT_THROW( |
| { |
| try { |
| (void)qualified_name::parse({}); |
| } catch (const ignite_error &e) { |
| EXPECT_EQ(e.get_status_code(), error::code::ILLEGAL_ARGUMENT); |
| EXPECT_THAT(e.what_str(), testing::HasSubstr("Object name can not be empty")); |
| throw; |
| } |
| }, |
| ignite_error); |
| } |
| |
| TEST(client_qualified_name, create_empty_schema_default) { |
| auto name = qualified_name::create({}, "TEST"); |
| EXPECT_EQ(name.get_schema_name(), qualified_name::DEFAULT_SCHEMA_NAME); |
| } |
| |
| TEST(client_qualified_name, parse_implicit_schema_default) { |
| auto name = qualified_name::parse("TEST"); |
| EXPECT_EQ(name.get_schema_name(), qualified_name::DEFAULT_SCHEMA_NAME); |
| } |
| |
| class canonical_values_fixture : public ::testing::TestWithParam<std::string> {}; |
| |
| TEST_P(canonical_values_fixture, canonical_name_parse) { |
| auto canonical_name = GetParam(); |
| |
| EXPECT_EQ(canonical_name, qualified_name::parse(canonical_name).get_canonical_name()); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P( |
| client_qualified_name, canonical_values_fixture, |
| ::testing::Values( |
| "FOO.FOO", |
| "_FOO._FOO", |
| "_._", |
| "A\xCC\x80.A\xC2\xB7", |
| R"("foo"."bar")", |
| "\"\xF0\x9F\x98\x85\".\"\xC2\xB7\"" |
| ), |
| PrintTestIndex<canonical_values_fixture> |
| ); |
| |
| class valid_simple_names_fixture : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {}; |
| |
| TEST_P(valid_simple_names_fixture, valid_simple_name) { |
| auto [to_parse, expected] = GetParam(); |
| |
| auto parsed = qualified_name::parse(to_parse).get_object_name(); |
| auto created = qualified_name::create({}, to_parse).get_object_name(); |
| |
| EXPECT_EQ(expected, parsed); |
| EXPECT_EQ(expected, created); |
| |
| EXPECT_EQ(parsed, created); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P( |
| client_qualified_name, valid_simple_names_fixture, |
| ::testing::Values( |
| std::make_tuple("foo", "FOO"), |
| std::make_tuple("fOo", "FOO"), |
| std::make_tuple("FOO", "FOO"), |
| std::make_tuple("f23", "F23"), |
| std::make_tuple("\"23f\"", "23f"), |
| std::make_tuple("foo_", "FOO_"), |
| std::make_tuple("foo_1", "FOO_1"), |
| std::make_tuple("_foo", "_FOO"), |
| std::make_tuple("__foo", "__FOO"), |
| std::make_tuple("\"FOO\"", "FOO"), |
| std::make_tuple("\"foo\"", "foo"), |
| std::make_tuple("\"fOo\"", "fOo"), |
| std::make_tuple("\"_foo\"", "_foo"), |
| std::make_tuple("\"$foo\"", "$foo"), |
| std::make_tuple("\"%foo\"", "%foo"), |
| std::make_tuple("\"foo_\"", "foo_"), |
| std::make_tuple("\"foo$\"", "foo$"), |
| std::make_tuple("\"foo%\"", "foo%"), |
| std::make_tuple("\"@#$\"", "@#$"), |
| std::make_tuple("\"f.f\"", "f.f"), |
| std::make_tuple("\" \"", " "), |
| std::make_tuple("\"\xF0\x9F\x98\x85\"", "\xF0\x9F\x98\x85"), |
| std::make_tuple("\"f\"\"f\"", "f\"f"), |
| std::make_tuple("\"f\"\"\"\"f\"", "f\"\"f"), |
| std::make_tuple("\"\"\"bar\"\"\"", "\"bar\""), |
| std::make_tuple("\"\"\"\"\"bar\"\"\"", "\"\"bar\"") |
| ), |
| PrintTestIndex<valid_simple_names_fixture> |
| ); |
| |
| class malformed_simple_name_fixture : public ::testing::TestWithParam<std::string> {}; |
| |
| TEST_P(malformed_simple_name_fixture, malformed_simple_name) { |
| auto malformed = GetParam(); |
| |
| EXPECT_THROW( |
| { |
| try { |
| (void) qualified_name::create({}, malformed); |
| } catch (const ignite_error &e) { |
| EXPECT_EQ(e.get_status_code(), error::code::ILLEGAL_ARGUMENT); |
| throw; |
| } |
| }, |
| ignite_error); |
| } |
| |
| TEST_P(malformed_simple_name_fixture, malformed_schema_name) { |
| auto malformed = GetParam(); |
| |
| EXPECT_THROW( |
| { |
| try { |
| (void) qualified_name::create(malformed, {}); |
| } catch (const ignite_error &e) { |
| EXPECT_EQ(e.get_status_code(), error::code::ILLEGAL_ARGUMENT); |
| throw; |
| } |
| }, |
| ignite_error); |
| } |
| |
| TEST_P(malformed_simple_name_fixture, malformed_parse) { |
| auto malformed = GetParam(); |
| |
| EXPECT_THROW( |
| { |
| try { |
| (void) qualified_name::parse(malformed); |
| } catch (const ignite_error &e) { |
| EXPECT_EQ(e.get_status_code(), error::code::ILLEGAL_ARGUMENT); |
| throw; |
| } |
| }, |
| ignite_error); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P( |
| client_qualified_name, malformed_simple_name_fixture, |
| ::testing::Values( |
| "", |
| " ", |
| ".f", |
| "f.", |
| ".", |
| "f f", |
| "1o0", |
| "@#$", |
| "foo$", |
| "foo%", |
| "foo&", |
| "f😅", |
| "😅f", |
| "f\"f", |
| "f\"\"f", |
| "\"foo", |
| "\"fo\"o\"" |
| ), |
| PrintTestIndex<malformed_simple_name_fixture> |
| ); |
| |
| class malformed_canonical_name_fixture : public ::testing::TestWithParam<std::string> {}; |
| |
| TEST_P(malformed_canonical_name_fixture, malformed_parse) { |
| auto malformed = GetParam(); |
| |
| EXPECT_THROW( |
| { |
| try { |
| (void) qualified_name::parse(malformed); |
| } catch (const ignite_error &e) { |
| EXPECT_EQ(e.get_status_code(), error::code::ILLEGAL_ARGUMENT); |
| throw; |
| } |
| }, |
| ignite_error); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P( |
| client_qualified_name, malformed_canonical_name_fixture, |
| ::testing::Values( |
| "foo.", |
| ".bar", |
| ".", |
| "foo..bar", |
| "foo.bar.", |
| "foo..", |
| "@#$.bar", |
| "foo.@#$", |
| "@#$", |
| "1oo.bar", |
| "foo.1ar", |
| "1oo" |
| ), |
| PrintTestIndex<malformed_canonical_name_fixture> |
| ); |
| |
| class valid_simple_name_fixture : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {}; |
| |
| TEST_P(valid_simple_name_fixture, valid_simple_name) { |
| auto [to_parse, expected] = GetParam(); |
| |
| auto parsed = qualified_name::parse(to_parse).get_object_name(); |
| auto created = qualified_name::create({}, to_parse).get_object_name(); |
| |
| EXPECT_EQ(expected, parsed); |
| EXPECT_EQ(expected, created); |
| |
| EXPECT_EQ(parsed, created); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P( |
| client_qualified_name, valid_simple_name_fixture, |
| ::testing::Values( |
| std::make_tuple("foo", "FOO"), |
| std::make_tuple("fOo", "FOO"), |
| std::make_tuple("FOO", "FOO"), |
| std::make_tuple("f23", "F23"), |
| std::make_tuple("\"23f\"", "23f"), |
| std::make_tuple("foo_", "FOO_"), |
| std::make_tuple("foo_1", "FOO_1"), |
| std::make_tuple("_foo", "_FOO"), |
| std::make_tuple("__foo", "__FOO"), |
| std::make_tuple("\"FOO\"", "FOO"), |
| std::make_tuple("\"foo\"", "foo"), |
| std::make_tuple("\"fOo\"", "fOo"), |
| std::make_tuple("\"_foo\"", "_foo"), |
| std::make_tuple("\"$foo\"", "$foo"), |
| std::make_tuple("\"%foo\"", "%foo"), |
| std::make_tuple("\"foo_\"", "foo_"), |
| std::make_tuple("\"foo$\"", "foo$"), |
| std::make_tuple("\"foo%\"", "foo%"), |
| std::make_tuple("\"@#$\"", "@#$"), |
| std::make_tuple("\"f.f\"", "f.f"), |
| std::make_tuple("\" \"", " "), |
| std::make_tuple("\"\xF0\x9F\x98\x85\"", "\xF0\x9F\x98\x85"), |
| std::make_tuple("\"f\"\"f\"", "f\"f"), |
| std::make_tuple("\"f\"\"\"\"f\"", "f\"\"f"), |
| std::make_tuple("\"\"\"bar\"\"\"", "\"bar\""), |
| std::make_tuple("\"\"\"\"\"bar\"\"\"", "\"\"bar\"") |
| ), |
| PrintTestIndex<valid_simple_name_fixture> |
| ); |
| |
| class valid_canonical_name_fixture : public ::testing::TestWithParam<std::tuple<std::string, std::string, std::string>> {}; |
| |
| TEST_P(valid_canonical_name_fixture, valid_canonical_name) { |
| auto [full, schema, object] = GetParam(); |
| |
| auto parsed = qualified_name::parse(full); |
| |
| EXPECT_EQ(schema, parsed.get_schema_name()); |
| EXPECT_EQ(object, parsed.get_object_name()); |
| |
| auto parsed2 = qualified_name::parse(parsed.get_canonical_name()); |
| |
| EXPECT_EQ(schema, parsed2.get_schema_name()); |
| EXPECT_EQ(object, parsed2.get_object_name()); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P( |
| client_qualified_name, valid_canonical_name_fixture, |
| ::testing::Values( |
| std::make_tuple("\"foo.bar\".baz", "foo.bar", "BAZ"), |
| std::make_tuple("foo.\"bar.baz\"", "FOO", "bar.baz"), |
| std::make_tuple("\"foo.\"\"bar\"\"\".baz", "foo.\"bar\"", "BAZ"), |
| std::make_tuple("foo.\"bar.\"\"baz\"", "FOO", "bar.\"baz"), |
| std::make_tuple("_foo.bar", "_FOO", "BAR"), |
| std::make_tuple("foo._bar", "FOO", "_BAR") |
| ), |
| PrintTestIndex<valid_canonical_name_fixture> |
| ); |
| |
| class parsing_error_fixture : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {}; |
| |
| TEST_P(parsing_error_fixture, parsing_error) { |
| auto [name, exception] = GetParam(); |
| |
| EXPECT_THROW( |
| { |
| try { |
| (void) qualified_name::parse(name); |
| } catch (const ignite_error &e) { |
| EXPECT_EQ(e.get_status_code(), error::code::ILLEGAL_ARGUMENT); |
| EXPECT_THAT(e.what_str(), testing::HasSubstr(exception)); |
| throw; |
| } |
| }, |
| ignite_error); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P( |
| client_qualified_name, parsing_error_fixture, |
| ::testing::Values( |
| std::make_tuple("x.", "Object part of the canonical name can not be empty"), |
| std::make_tuple(".x", "Invalid identifier start '46' : .x. Unquoted identifiers must begin with a letter or an underscore."), |
| std::make_tuple("\"x", "Missing closing quote: '\"x"), |
| std::make_tuple("y.\"x", "Missing closing quote: 'y.\"x"), |
| std::make_tuple("\"xx\"yy\"", "Unexpected character '121' after quote: '\"xx\"yy\"'"), |
| std::make_tuple("123", "Invalid identifier start '49' : 123. Unquoted identifiers must begin with a letter or an underscore."), |
| std::make_tuple("x.y.z", "Canonical name should have at most two parts: 'x.y.z'") |
| ), |
| PrintTestIndex<parsing_error_fixture> |
| ); |