blob: 75d8dd9d9d1231f509d1e20c9bc42451ac0b366f [file] [log] [blame]
/*
* 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>
);