diff options
-rw-r--r-- | src/core/common/VariantReader.cpp | 12 | ||||
-rw-r--r-- | test/core/common/VariantReaderTest.cpp | 152 |
2 files changed, 161 insertions, 3 deletions
diff --git a/src/core/common/VariantReader.cpp b/src/core/common/VariantReader.cpp index 7320973..c0368f1 100644 --- a/src/core/common/VariantReader.cpp +++ b/src/core/common/VariantReader.cpp @@ -559,6 +559,7 @@ std::pair<bool, Variant::cardinalityType> VariantReader::parseCardinality( switch (c) { case '}': case ',': + card.merge({start}); reader.resetPeek(); break; case '-': { @@ -569,6 +570,7 @@ std::pair<bool, Variant::cardinalityType> VariantReader::parseCardinality( error(reader, logger, ERR_UNEXPECTED_END, Variant::cardinalityType{}); } + reader.resetPeek(); Number n2; if (!n2.parse(reader, logger, cardDelims) || !n2.isInt() || n2.intValue() < 0) { @@ -576,8 +578,16 @@ std::pair<bool, Variant::cardinalityType> VariantReader::parseCardinality( "Invalid number for cardinality!", Variant::cardinalityType{}); } - unsigned int end = (unsigned int)n2.intValue(); + if (end <= start) { + return error(reader, logger, + std::string("The start of the range (") + + std::to_string(start) + + ") was bigger (or equal) to the end " + "of the range (" + + std::to_string(end) + ")!", + Variant::cardinalityType{}); + } card.merge({start, end}); break; } diff --git a/test/core/common/VariantReaderTest.cpp b/test/core/common/VariantReaderTest.cpp index 241aa56..14442e9 100644 --- a/test/core/common/VariantReaderTest.cpp +++ b/test/core/common/VariantReaderTest.cpp @@ -25,7 +25,7 @@ namespace ousia { static TerminalLogger logger{std::cerr, true}; -//static Logger logger; +// static Logger logger; TEST(VariantReader, readString) { @@ -576,6 +576,153 @@ TEST(VariantReader, parseObject) } } +TEST(VariantReader, parseCardinality) +{ + Logger logger; + // Primitive cardinality. + { + CharReader reader(" { 5 } "); + auto res = VariantReader::parseCardinality(reader, logger); + ASSERT_TRUE(res.first); + + Variant::cardinalityType card{}; + card.merge({5}); + ASSERT_EQ(card, res.second); + } + // Range cardinality + { + CharReader reader(" { 5-10 } "); + auto res = VariantReader::parseCardinality(reader, logger); + ASSERT_TRUE(res.first); + + Variant::cardinalityType card{}; + card.merge({5, 10}); + ASSERT_EQ(card, res.second); + } + // Larger than + { + CharReader reader(" { >9 } "); + auto res = VariantReader::parseCardinality(reader, logger); + ASSERT_TRUE(res.first); + + Variant::cardinalityType card{}; + card.merge(Variant::rangeType::typeRangeFrom(10)); + ASSERT_EQ(card, res.second); + } + // Smaller than + { + CharReader reader(" { <9 } "); + auto res = VariantReader::parseCardinality(reader, logger); + ASSERT_TRUE(res.first); + + Variant::cardinalityType card{}; + card.merge(Variant::rangeType::typeRangeUntil(8)); + ASSERT_EQ(card, res.second); + } + // Kleene-Star + { + CharReader reader(" { * } "); + auto res = VariantReader::parseCardinality(reader, logger); + ASSERT_TRUE(res.first); + + Variant::cardinalityType card{}; + card.merge(Variant::rangeType::typeRange()); + ASSERT_EQ(card, res.second); + } + // More complex parse + { + CharReader reader(" { 1 , 4- 6 ,>8 } some other text"); + auto res = VariantReader::parseCardinality(reader, logger); + ASSERT_TRUE(res.first); + + Variant::cardinalityType card{}; + card.merge({1}); + card.merge({4, 6}); + card.merge(Variant::rangeType::typeRangeFrom(9)); + ASSERT_EQ(card, res.second); + } + // More complex parses that are equivalent. + { + Variant::cardinalityType card{}; + card.merge(Variant::rangeType::typeRange()); + { + CharReader reader(" { * } "); + auto res = VariantReader::parseCardinality(reader, logger); + ASSERT_TRUE(res.first); + ASSERT_EQ(card, res.second); + } + { + CharReader reader = CharReader(" { 1-4, 8, 9-12, 10, * } "); + auto res = VariantReader::parseCardinality(reader, logger); + ASSERT_TRUE(res.first); + ASSERT_EQ(card, res.second); + } + { + CharReader reader = CharReader(" { 0, >0 } "); + auto res = VariantReader::parseCardinality(reader, logger); + ASSERT_TRUE(res.first); + ASSERT_EQ(card, res.second); + } + { + CharReader reader = CharReader(" { <10, 10, >10 } "); + auto res = VariantReader::parseCardinality(reader, logger); + ASSERT_TRUE(res.first); + ASSERT_EQ(card, res.second); + } + { + CharReader reader = CharReader(" { 0,1-2, 3-4, >4 } "); + auto res = VariantReader::parseCardinality(reader, logger); + ASSERT_TRUE(res.first); + ASSERT_EQ(card, res.second); + } + } + // Invalid cardinalities. + { + CharReader reader(" 5 } "); + ASSERT_FALSE(VariantReader::parseCardinality(reader, logger).first); + } + { + CharReader reader(" { 5 , } "); + ASSERT_FALSE(VariantReader::parseCardinality(reader, logger).first); + } + { + CharReader reader(" { 5- } "); + ASSERT_FALSE(VariantReader::parseCardinality(reader, logger).first); + } + { + CharReader reader(" { -3 } "); + ASSERT_FALSE(VariantReader::parseCardinality(reader, logger).first); + } + { + CharReader reader(" { 5-3 } "); + ASSERT_FALSE(VariantReader::parseCardinality(reader, logger).first); + } + { + CharReader reader(" { 3-3 } "); + ASSERT_FALSE(VariantReader::parseCardinality(reader, logger).first); + } + { + CharReader reader(" { > } "); + ASSERT_FALSE(VariantReader::parseCardinality(reader, logger).first); + } + { + CharReader reader(" { < } "); + ASSERT_FALSE(VariantReader::parseCardinality(reader, logger).first); + } + { + CharReader reader(" { , } "); + ASSERT_FALSE(VariantReader::parseCardinality(reader, logger).first); + } + { + CharReader reader(" { 4 "); + ASSERT_FALSE(VariantReader::parseCardinality(reader, logger).first); + } + { + CharReader reader(" { m } "); + ASSERT_FALSE(VariantReader::parseCardinality(reader, logger).first); + } +} + TEST(VariantReader, parseGenericToken) { // Simple case, unescaped string @@ -614,7 +761,8 @@ TEST(VariantReader, parseGenericToken) // String with whitespaces at the beginning. { CharReader reader(" \' test\'"); - auto res = VariantReader::parseGenericToken(reader, logger, {';'}, true); + auto res = + VariantReader::parseGenericToken(reader, logger, {';'}, true); ASSERT_EQ(" test", res.second); } |