From 37a002577e7f4949e0634dca7e828b5333d2ccc5 Mon Sep 17 00:00:00 2001 From: Benjamin Paassen Date: Sun, 25 Jan 2015 13:19:48 +0100 Subject: Bugfixes in VariantReader for cardinality reading and extensive cardinality reading tests. --- test/core/common/VariantReaderTest.cpp | 152 ++++++++++++++++++++++++++++++++- 1 file changed, 150 insertions(+), 2 deletions(-) (limited to 'test') 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); } -- cgit v1.2.3 From eab6577b066319aab7ebaf514e6bb7aab9590624 Mon Sep 17 00:00:00 2001 From: Benjamin Paassen Date: Sun, 25 Jan 2015 15:50:52 +0100 Subject: removed cardinality type definition from Domain.hpp and made everything compatible with the Variant cardinality. --- src/core/model/Document.cpp | 8 ++++++-- src/core/model/Domain.cpp | 17 +++++++++++------ src/core/model/Domain.hpp | 15 +++++++-------- test/core/model/DocumentTest.cpp | 2 +- test/core/model/DomainTest.cpp | 8 ++++---- test/core/model/TestAdvanced.hpp | 6 +++--- test/core/model/TestDomain.hpp | 6 +++--- 7 files changed, 35 insertions(+), 27 deletions(-) (limited to 'test') diff --git a/src/core/model/Document.cpp b/src/core/model/Document.cpp index 61c384d..42192a2 100644 --- a/src/core/model/Document.cpp +++ b/src/core/model/Document.cpp @@ -147,6 +147,10 @@ bool DocumentEntity::doValidate(Logger &logger) const // a constructor we can not check anything else. return false; } + // if we have an invalid descriptor we can not proceed either. + if(!descriptor->validate(logger)){ + return false; + } // check the attribute primitive content. bool valid; if (descriptor->getAttributesDescriptor() == nullptr) { @@ -218,7 +222,7 @@ bool DocumentEntity::doValidate(Logger &logger) const * cardinality. */ for (auto &ac : fieldDescs[f]->getChildren()) { - const size_t min = ac->getCardinality().min(); + const size_t min = ac->getCardinality().asCardinality().min(); if (min > 0) { logger.error( std::string("Field \"") + fieldDescs[f]->getName() + @@ -305,7 +309,7 @@ bool DocumentEntity::doValidate(Logger &logger) const if (n != nums.end()) { num = n->second; } - if (!ac->getCardinality().contains(num)) { + if (!ac->getCardinality().asCardinality().contains(num)) { logger.error( std::string("Field \"") + fieldDescs[f]->getName() + "\" had " + std::to_string(num) + " elements of class \"" + diff --git a/src/core/model/Domain.cpp b/src/core/model/Domain.cpp index c7afd22..635fc50 100644 --- a/src/core/model/Domain.cpp +++ b/src/core/model/Domain.cpp @@ -306,13 +306,12 @@ Rooted Descriptor::createFieldDescriptor( /* Class StructuredClass */ StructuredClass::StructuredClass(Manager &mgr, std::string name, - Handle domain, - const Cardinality &cardinality, + Handle domain, Variant cardinality, Handle attributesDescriptor, Handle superclass, bool transparent, bool root) : Descriptor(mgr, std::move(name), domain, attributesDescriptor), - cardinality(cardinality), + cardinality(std::move(cardinality)), superclass(acquire(superclass)), subclasses(this), transparent(transparent), @@ -338,6 +337,11 @@ bool StructuredClass::doValidate(Logger &logger) const valid = false; } } + // check the cardinality. + if(!cardinality.isCardinality()){ + logger.error(cardinality.toString() + " is not a cardinality!"); + valid = false; + } // check the validity of this superclass. if (superclass != nullptr) { valid = valid & superclass->validate(logger); @@ -496,13 +500,14 @@ bool Domain::removeStructuredClass(Handle s) } Rooted Domain::createStructuredClass( - std::string name, const Cardinality &cardinality, + std::string name, Variant cardinality, Handle attributesDescriptor, Handle superclass, bool transparent, bool root) { return Rooted{new StructuredClass( - getManager(), std::move(name), this, cardinality, attributesDescriptor, - superclass, std::move(transparent), std::move(root))}; + getManager(), std::move(name), this, std::move(cardinality), + attributesDescriptor, superclass, std::move(transparent), + std::move(root))}; } void Domain::addAnnotationClass(Handle a) diff --git a/src/core/model/Domain.hpp b/src/core/model/Domain.hpp index e40a9f3..ef228b1 100644 --- a/src/core/model/Domain.hpp +++ b/src/core/model/Domain.hpp @@ -618,20 +618,19 @@ public: * cardinalities independent of context? Should we not have at least have the * possibility to define it context-dependently? */ -typedef RangeSet Cardinality; /** * This is the default cardinality. */ -static Cardinality createAny() +static Variant::cardinalityType createAny() { - Cardinality any; + Variant::cardinalityType any; any.merge(Range::typeRangeFrom(0)); return std::move(any); } -static const Cardinality AnyCardinality = createAny(); +static const Variant AnyCardinality = createAny(); /** * A StructuredClass specifies nodes in the StructureTree of a document that @@ -710,7 +709,7 @@ class StructuredClass : public Descriptor { friend Domain; private: - const Cardinality cardinality; + const Variant cardinality; Owned superclass; NodeVector subclasses; bool transparent; @@ -758,7 +757,7 @@ public: */ StructuredClass(Manager &mgr, std::string name = "", Handle domain = nullptr, - const Cardinality &cardinality = AnyCardinality, + Variant cardinality = AnyCardinality, Handle attributesDescriptor = nullptr, Handle superclass = nullptr, bool transparent = false, bool root = false); @@ -768,7 +767,7 @@ public: * * @return the Cardinality of this StructuredClass (as a RangeSet). */ - const Cardinality &getCardinality() const { return cardinality; } + const Variant &getCardinality() const { return cardinality; } /** * Returns the superclass of this StructuredClass. This is not the same as @@ -1016,7 +1015,7 @@ public: * @return the newly created StructuredClass. */ Rooted createStructuredClass( - std::string name, const Cardinality &cardinality = AnyCardinality, + std::string name, Variant cardinality = AnyCardinality, Handle attributesDescriptor = nullptr, Handle superclass = nullptr, bool transparent = false, bool root = false); diff --git a/test/core/model/DocumentTest.cpp b/test/core/model/DocumentTest.cpp index e07deb8..1d8457c 100644 --- a/test/core/model/DocumentTest.cpp +++ b/test/core/model/DocumentTest.cpp @@ -117,7 +117,7 @@ TEST(Document, validate) Manager mgr{1}; Rooted sys{new SystemTypesystem(mgr)}; Rooted domain{new Domain(mgr, sys, "trivial")}; - Cardinality single; + Variant::cardinalityType single; single.merge({1}); // Set up the "root" StructuredClass. Rooted rootClass{new StructuredClass( diff --git a/test/core/model/DomainTest.cpp b/test/core/model/DomainTest.cpp index c00b122..54fd86a 100644 --- a/test/core/model/DomainTest.cpp +++ b/test/core/model/DomainTest.cpp @@ -152,8 +152,8 @@ TEST(Descriptor, pathToAdvanced) Rooted sys{new SystemTypesystem(mgr)}; // Construct the domain Rooted domain{new Domain(mgr, sys, "nasty")}; - Cardinality any; - any.merge(Range::typeRangeFrom(0)); + Variant::cardinalityType any; + any.merge(Range::typeRange()); // Let's create the classes that we need first Rooted A{new StructuredClass( @@ -225,8 +225,8 @@ TEST(StructuredClass, isSubclassOf) Manager mgr{1}; Rooted sys{new SystemTypesystem(mgr)}; Rooted domain{new Domain(mgr, sys, "inheritance")}; - Cardinality any; - any.merge(Range::typeRangeFrom(0)); + Variant::cardinalityType any; + any.merge(Range::typeRange()); Rooted A{new StructuredClass( mgr, "A", domain, any, {nullptr}, {nullptr}, false, true)}; // first branch diff --git a/test/core/model/TestAdvanced.hpp b/test/core/model/TestAdvanced.hpp index f8585d1..6f8ca33 100644 --- a/test/core/model/TestAdvanced.hpp +++ b/test/core/model/TestAdvanced.hpp @@ -53,7 +53,7 @@ static Rooted constructHeadingDomain(Manager &mgr, // set up domain node. Rooted domain{new Domain(mgr, sys, "headings")}; // set up cardinality (every section may have at most one heading). - Cardinality card; + Variant::cardinalityType card; card.merge({0, 1}); // set up heading StructuredClass. Rooted heading{new StructuredClass( @@ -84,8 +84,8 @@ static Rooted constructListDomain(Manager &mgr, // set up domain node. Rooted domain{new Domain(mgr, sys, "list")}; // set up cardinality - Cardinality any; - any.merge(Range::typeRangeFrom(0)); + Variant::cardinalityType any; + any.merge(Range::typeRange()); // get book.paragraph Rooted p = resolveDescriptor(bookDomain, "paragraph"); // set up item StructuredClass; diff --git a/test/core/model/TestDomain.hpp b/test/core/model/TestDomain.hpp index f6b8805..ec63216 100644 --- a/test/core/model/TestDomain.hpp +++ b/test/core/model/TestDomain.hpp @@ -36,10 +36,10 @@ static Rooted constructBookDomain(Manager &mgr, // Start with the Domain itself. Rooted domain{new Domain(mgr, sys, "book")}; // Set up the cardinalities we'll need. - Cardinality single; + Variant::cardinalityType single; single.merge({1}); - Cardinality any; - any.merge(Range::typeRangeFrom(0)); + Variant::cardinalityType any; + any.merge(Range::typeRange()); // Set up the "book" node. Rooted book{new StructuredClass( -- cgit v1.2.3