summaryrefslogtreecommitdiff
path: root/test/core/common/VariantReaderTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/core/common/VariantReaderTest.cpp')
-rw-r--r--test/core/common/VariantReaderTest.cpp345
1 files changed, 345 insertions, 0 deletions
diff --git a/test/core/common/VariantReaderTest.cpp b/test/core/common/VariantReaderTest.cpp
new file mode 100644
index 0000000..d9bb74e
--- /dev/null
+++ b/test/core/common/VariantReaderTest.cpp
@@ -0,0 +1,345 @@
+/*
+ Ousía
+ Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <iostream>
+#include <gtest/gtest.h>
+
+#include <core/common/VariantReader.hpp>
+
+namespace ousia {
+namespace variant {
+
+//static TerminalLogger logger{std::cerr, true};
+static Logger logger;
+
+TEST(Reader, readString)
+{
+ // Simple, double quoted string
+ {
+ CharReader reader("\"hello world\"");
+ auto res = VariantReader::parseString(reader, logger);
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ("hello world", res.second);
+ }
+
+ // Simple, double quoted string with whitespace
+ {
+ CharReader reader(" \"hello world\" ");
+ auto res = VariantReader::parseString(reader, logger);
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ("hello world", res.second);
+ }
+
+ // Simple, single quoted string
+ {
+ CharReader reader("'hello world'");
+ auto res = VariantReader::parseString(reader, logger);
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ("hello world", res.second);
+ }
+
+ // Escape characters
+ {
+ CharReader reader("'\\'\\\"\\b\\f\\n\\r\\t\\v'");
+ auto res = VariantReader::parseString(reader, logger);
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ("'\"\b\f\n\r\t\v", res.second);
+ }
+}
+
+TEST(Reader, parseUnescapedString)
+{
+ // Simple case
+ {
+ CharReader reader("hello world;");
+ auto res = VariantReader::parseUnescapedString(reader, logger, {';'});
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ("hello world", res.second);
+ }
+
+ // Simple case with whitespace
+ {
+ CharReader reader(" hello world ; ");
+ auto res = VariantReader::parseUnescapedString(reader, logger, {';'});
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ("hello world", res.second);
+ }
+
+ // Linebreaks
+ {
+ CharReader reader(" hello\nworld ; ");
+ auto res = VariantReader::parseUnescapedString(reader, logger, {';'});
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ("hello\nworld", res.second);
+ }
+
+ // End of stream
+ {
+ CharReader reader(" hello world ");
+ auto res = VariantReader::parseUnescapedString(reader, logger, {';'});
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ("hello world", res.second);
+ }
+}
+
+static const std::unordered_set<char> noDelim;
+
+TEST(Reader, parseInteger)
+{
+ // Valid integers
+ {
+ CharReader reader("0 ");
+ auto res = VariantReader::parseInteger(reader, logger, noDelim);
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ(0, res.second);
+ }
+
+ {
+ CharReader reader("42 ");
+ auto res = VariantReader::parseInteger(reader, logger, noDelim);
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ(42, res.second);
+ }
+
+ {
+ CharReader reader("-42");
+ auto res = VariantReader::parseInteger(reader, logger, noDelim);
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ(-42, res.second);
+ }
+
+ {
+ CharReader reader(" -0x4A2 ");
+ auto res = VariantReader::parseInteger(reader, logger, noDelim);
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ(-0x4A2, res.second);
+ }
+
+ {
+ CharReader reader(" 0Xaffe");
+ auto res = VariantReader::parseInteger(reader, logger, noDelim);
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ(0xAFFE, res.second);
+ }
+
+ {
+ CharReader reader("0x7FFFFFFFFFFFFFFF");
+ auto res = VariantReader::parseInteger(reader, logger, noDelim);
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ(0x7FFFFFFFFFFFFFFFL, res.second);
+ }
+
+ {
+ CharReader reader("-0x7FFFFFFFFFFFFFFF");
+ auto res = VariantReader::parseInteger(reader, logger, noDelim);
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ(-0x7FFFFFFFFFFFFFFFL, res.second);
+ }
+
+ // Invalid integers
+ {
+ CharReader reader("-");
+ auto res = VariantReader::parseInteger(reader, logger, noDelim);
+ ASSERT_FALSE(res.first);
+ }
+
+ {
+ CharReader reader("0a");
+ auto res = VariantReader::parseInteger(reader, logger, noDelim);
+ ASSERT_FALSE(res.first);
+ }
+
+ {
+ CharReader reader("-0xag");
+ auto res = VariantReader::parseInteger(reader, logger, noDelim);
+ ASSERT_FALSE(res.first);
+ }
+
+ {
+ CharReader reader("0x8000000000000000");
+ auto res = VariantReader::parseInteger(reader, logger, noDelim);
+ ASSERT_FALSE(res.first);
+ }
+}
+
+TEST(Reader, parseDouble)
+{
+ // Valid doubles
+ {
+ CharReader reader("1.25");
+ auto res = VariantReader::parseDouble(reader, logger, noDelim);
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ(1.25, res.second);
+ }
+
+ {
+ CharReader reader(".25");
+ auto res = VariantReader::parseDouble(reader, logger, noDelim);
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ(.25, res.second);
+ }
+
+ {
+ CharReader reader(".25e1");
+ auto res = VariantReader::parseDouble(reader, logger, noDelim);
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ(2.5, res.second);
+ }
+
+ {
+ CharReader reader("-2.5e-1");
+ auto res = VariantReader::parseDouble(reader, logger, noDelim);
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ(-0.25, res.second);
+ }
+
+ {
+ CharReader reader("-50e-2");
+ auto res = VariantReader::parseDouble(reader, logger, noDelim);
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ(-0.5, res.second);
+ }
+
+ {
+ CharReader reader("-1.");
+ auto res = VariantReader::parseDouble(reader, logger, noDelim);
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ(-1., res.second);
+ }
+
+ {
+ CharReader reader("-50.e-2");
+ auto res = VariantReader::parseDouble(reader, logger, {'.'});
+ ASSERT_TRUE(res.first);
+ ASSERT_EQ(-50, res.second);
+ }
+
+ // Invalid doubles
+ {
+ CharReader reader(".e1");
+ auto res = VariantReader::parseDouble(reader, logger, noDelim);
+ ASSERT_FALSE(res.first);
+ }
+
+ {
+ CharReader reader("0e100000");
+ auto res = VariantReader::parseDouble(reader, logger, noDelim);
+ ASSERT_FALSE(res.first);
+ }
+}
+
+TEST(Reader, parseArray)
+{
+ // Simple case (only primitive data types)
+ {
+ CharReader reader("[\"Hello, World\", unescaped\n string ,\n"
+ "1234, 0.56, true, false, null]");
+ auto res = VariantReader::parseArray(reader, logger);
+ ASSERT_TRUE(res.first);
+
+ // Make sure array has the correct size
+ ASSERT_EQ(7U, res.second.size());
+
+ // Check the types
+ ASSERT_TRUE(res.second[0].isString());
+ ASSERT_TRUE(res.second[1].isString());
+ ASSERT_TRUE(res.second[2].isInt());
+ ASSERT_TRUE(res.second[3].isDouble());
+ ASSERT_TRUE(res.second[4].isBool());
+ ASSERT_TRUE(res.second[5].isBool());
+ ASSERT_TRUE(res.second[6].isNull());
+
+ // Check the values
+ ASSERT_EQ("Hello, World", res.second[0].asString());
+ ASSERT_EQ("unescaped\n string", res.second[1].asString());
+ ASSERT_EQ(1234, res.second[2].asInt());
+ ASSERT_EQ(0.56, res.second[3].asDouble());
+ ASSERT_TRUE(res.second[4].asBool());
+ ASSERT_FALSE(res.second[5].asBool());
+ }
+
+ // Ending with comma
+ {
+ CharReader reader("[ 'test' ,]");
+ auto res = VariantReader::parseArray(reader, logger);
+ ASSERT_TRUE(res.first);
+
+ // Make sure the array has the correct size
+ ASSERT_EQ(1U, res.second.size());
+
+ // Check the types
+ ASSERT_TRUE(res.second[0].isString());
+
+ // Check the values
+ ASSERT_EQ("test", res.second[0].asString());
+ }
+
+ // Recovery from invalid values
+ {
+ CharReader reader("[ 0invalidNumber, str, 1invalid]");
+ auto res = VariantReader::parseArray(reader, logger);
+ ASSERT_TRUE(res.first);
+
+ // Make sure the array has the correct size
+ ASSERT_EQ(3U, res.second.size());
+
+ // Check the types (all must be strings since the numbers are invalid)
+ ASSERT_TRUE(res.second[0].isString());
+ ASSERT_TRUE(res.second[1].isString());
+ ASSERT_TRUE(res.second[2].isString());
+
+ // Check the values
+ ASSERT_EQ("0invalidNumber", res.second[0].asString());
+ ASSERT_EQ("str", res.second[1].asString());
+ ASSERT_EQ("1invalid", res.second[2].asString());
+ }
+}
+
+TEST(Reader, parseGeneric)
+{
+ // Simple case, unescaped string
+ {
+ CharReader reader("hello world");
+ auto res = VariantReader::parseGeneric(reader, logger, {';'});
+ ASSERT_TRUE(res.first);
+ ASSERT_TRUE(res.second.isString());
+ ASSERT_EQ("hello world", res.second.asString());
+ }
+
+ // Simple case, double quoted string
+ {
+ CharReader reader(" \"hello world\" ");
+ auto res = VariantReader::parseGeneric(reader, logger, {';'});
+ ASSERT_TRUE(res.first);
+ ASSERT_TRUE(res.second.isString());
+ ASSERT_EQ("hello world", res.second.asString());
+ }
+
+ // Simple case, single quoted string
+ {
+ CharReader reader(" 'hello world' ");
+ auto res = VariantReader::parseGeneric(reader, logger, {';'});
+ ASSERT_TRUE(res.first);
+ ASSERT_TRUE(res.second.isString());
+ ASSERT_EQ("hello world", res.second.asString());
+ }
+}
+
+}
+}
+