diff options
Diffstat (limited to 'test')
15 files changed, 1622 insertions, 587 deletions
diff --git a/test/core/RangeSetTest.cpp b/test/core/RangeSetTest.cpp index cbf8f59..446ee51 100644 --- a/test/core/RangeSetTest.cpp +++ b/test/core/RangeSetTest.cpp @@ -110,7 +110,7 @@ TEST(RangeSet, Merge)  	s.merge(Range<int>(40, 50));  	s.merge(Range<int>(60, 70));  	{ -		ASSERT_EQ(ranges.size(), 4); +		ASSERT_EQ(ranges.size(), 4U);  		auto it = ranges.begin();  		ASSERT_EQ((*it).start, 0); @@ -132,7 +132,7 @@ TEST(RangeSet, Merge)  	// Now insert an element which spans the second and third element  	s.merge(Range<int>(15, 55));  	{ -		ASSERT_EQ(ranges.size(), 3); +		ASSERT_EQ(ranges.size(), 3U);  		auto it = ranges.begin();  		ASSERT_EQ((*it).start, 0); @@ -150,7 +150,7 @@ TEST(RangeSet, Merge)  	// Now insert an element which expands the first element  	s.merge(Range<int>(-10, 11));  	{ -		ASSERT_EQ(ranges.size(), 3); +		ASSERT_EQ(ranges.size(), 3U);  		auto it = ranges.begin();  		ASSERT_EQ((*it).start, -10); @@ -168,7 +168,7 @@ TEST(RangeSet, Merge)  	// Now insert an element which merges the last two elements  	s.merge(Range<int>(13, 70));  	{ -		ASSERT_EQ(ranges.size(), 2); +		ASSERT_EQ(ranges.size(), 2U);  		auto it = ranges.begin();  		ASSERT_EQ((*it).start, -10); @@ -182,7 +182,7 @@ TEST(RangeSet, Merge)  	// Now insert an element which merges the remaining elements  	s.merge(Range<int>(-9, 12));  	{ -		ASSERT_EQ(ranges.size(), 1); +		ASSERT_EQ(ranges.size(), 1U);  		auto it = ranges.begin();  		ASSERT_EQ((*it).start, -10); diff --git a/test/core/StandaloneEnvironment.hpp b/test/core/StandaloneEnvironment.hpp index a9dcdce..790bad4 100644 --- a/test/core/StandaloneEnvironment.hpp +++ b/test/core/StandaloneEnvironment.hpp @@ -31,6 +31,10 @@  namespace ousia { +/** + * StandaloneEnvironment is a class used for quickly setting up an entire + * environment needed for running an Ousia instance. + */  struct StandaloneEnvironment {  	ConcreteLogger &logger;  	Manager manager; diff --git a/test/core/common/UtilsTest.cpp b/test/core/common/UtilsTest.cpp index 917f45c..7801296 100644 --- a/test/core/common/UtilsTest.cpp +++ b/test/core/common/UtilsTest.cpp @@ -24,22 +24,40 @@ namespace ousia {  TEST(Utils, isIdentifier)  { -	ASSERT_TRUE(Utils::isIdentifier("test")); -	ASSERT_TRUE(Utils::isIdentifier("t0-_est")); -	ASSERT_FALSE(Utils::isIdentifier("_t0-_EST")); -	ASSERT_FALSE(Utils::isIdentifier("-t0-_EST")); -	ASSERT_FALSE(Utils::isIdentifier("0t-_EST")); -	ASSERT_FALSE(Utils::isIdentifier("invalid key")); +	EXPECT_TRUE(Utils::isIdentifier("test")); +	EXPECT_TRUE(Utils::isIdentifier("t0-_est")); +	EXPECT_FALSE(Utils::isIdentifier("_t0-_EST")); +	EXPECT_FALSE(Utils::isIdentifier("-t0-_EST")); +	EXPECT_FALSE(Utils::isIdentifier("0t-_EST")); +	EXPECT_FALSE(Utils::isIdentifier("_A")); +	EXPECT_FALSE(Utils::isIdentifier("invalid key")); +	EXPECT_FALSE(Utils::isIdentifier(""));  } -TEST(Utils, trim) + +TEST(Utils, isNamespacedIdentifier)  { -	ASSERT_EQ("hello world", Utils::trim("\t hello world   \n\r\t")); -	ASSERT_EQ("hello world", Utils::trim("hello world   \n\r\t")); -	ASSERT_EQ("hello world", Utils::trim("   hello world")); -	ASSERT_EQ("hello world", Utils::trim("hello world")); +	EXPECT_TRUE(Utils::isNamespacedIdentifier("test")); +	EXPECT_TRUE(Utils::isNamespacedIdentifier("t0-_est")); +	EXPECT_FALSE(Utils::isNamespacedIdentifier("_t0-_EST")); +	EXPECT_FALSE(Utils::isNamespacedIdentifier("-t0-_EST")); +	EXPECT_FALSE(Utils::isNamespacedIdentifier("0t-_EST")); +	EXPECT_FALSE(Utils::isNamespacedIdentifier("invalid key")); +	EXPECT_FALSE(Utils::isNamespacedIdentifier("_A")); +	EXPECT_FALSE(Utils::isNamespacedIdentifier("")); +	EXPECT_FALSE(Utils::isNamespacedIdentifier(":")); +	EXPECT_TRUE(Utils::isNamespacedIdentifier("test:a")); +	EXPECT_TRUE(Utils::isNamespacedIdentifier("t0-_est:b")); +	EXPECT_TRUE(Utils::isNamespacedIdentifier("test:test")); +	EXPECT_TRUE(Utils::isNamespacedIdentifier("t0-_est:t0-_est")); +	EXPECT_FALSE(Utils::isNamespacedIdentifier("test:_A")); +	EXPECT_FALSE(Utils::isNamespacedIdentifier("test::a")); +	EXPECT_FALSE(Utils::isNamespacedIdentifier(":test")); +	EXPECT_FALSE(Utils::isNamespacedIdentifier("t0-_est:_t0-_EST")); +	EXPECT_FALSE(Utils::isNamespacedIdentifier("t0-_est: b"));  } +  TEST(Utils, split)  {  	ASSERT_EQ(std::vector<std::string>({"ab"}), Utils::split("ab", '.')); @@ -73,5 +91,23 @@ TEST(Utils, extractFileExtension)  	ASSERT_EQ("ext", Utils::extractFileExtension("foo.bar/test.EXT"));  } +TEST(Utils, startsWith) +{ +	ASSERT_TRUE(Utils::startsWith("foobar", "foo")); +	ASSERT_TRUE(Utils::startsWith("foo", "foo")); +	ASSERT_FALSE(Utils::startsWith("foo", "foobar")); +	ASSERT_FALSE(Utils::startsWith("foobar", "bar")); +	ASSERT_TRUE(Utils::startsWith("foo", "")); +} + +TEST(Utils, endsWith) +{ +	ASSERT_FALSE(Utils::endsWith("foobar", "foo")); +	ASSERT_TRUE(Utils::endsWith("foo", "foo")); +	ASSERT_FALSE(Utils::endsWith("foo", "foobar")); +	ASSERT_TRUE(Utils::endsWith("foobar", "bar")); +	ASSERT_TRUE(Utils::endsWith("foo", "")); +} +  } diff --git a/test/core/model/DomainTest.cpp b/test/core/model/DomainTest.cpp index 8fcbdf2..4cb4331 100644 --- a/test/core/model/DomainTest.cpp +++ b/test/core/model/DomainTest.cpp @@ -242,7 +242,7 @@ TEST(Descriptor, getDefaultFields)  	    A->createPrimitiveFieldDescriptor(sys->getStringType(), logger);  	// now we should find that.  	auto fields = A->getDefaultFields(); -	ASSERT_EQ(1, fields.size()); +	ASSERT_EQ(1U, fields.size());  	ASSERT_EQ(A_prim_field, fields[0]);  	// remove that field from A and add it to another class. @@ -258,7 +258,7 @@ TEST(Descriptor, getDefaultFields)  	// but we should find it again if we set B as superclass of A.  	A->setSuperclass(B, logger);  	fields = A->getDefaultFields(); -	ASSERT_EQ(1, fields.size()); +	ASSERT_EQ(1U, fields.size());  	ASSERT_EQ(A_prim_field, fields[0]);  	// and we should not be able to find it if we override the field. @@ -277,7 +277,7 @@ TEST(Descriptor, getDefaultFields)  	// now we should find that.  	fields = A->getDefaultFields(); -	ASSERT_EQ(1, fields.size()); +	ASSERT_EQ(1U, fields.size());  	ASSERT_EQ(C_field, fields[0]);  	// add another transparent child class to A with a daughter class that has @@ -296,7 +296,7 @@ TEST(Descriptor, getDefaultFields)  	// now we should find both primitive fields, but the C field first.  	fields = A->getDefaultFields(); -	ASSERT_EQ(2, fields.size()); +	ASSERT_EQ(2U, fields.size());  	ASSERT_EQ(C_field, fields[0]);  	ASSERT_EQ(F_field, fields[1]);  } @@ -321,7 +321,7 @@ TEST(Descriptor, getPermittedChildren)  	 * in between.  	 */  	NodeVector<StructuredClass> children = book->getPermittedChildren(); -	ASSERT_EQ(3, children.size()); +	ASSERT_EQ(3U, children.size());  	ASSERT_EQ(section, children[0]);  	ASSERT_EQ(paragraph, children[1]);  	ASSERT_EQ(text, children[2]); @@ -331,7 +331,7 @@ TEST(Descriptor, getPermittedChildren)  	    mgr, "Subclass", domain, Cardinality::any(), text, true, false)};  	// And that should be in the result list as well now.  	children = book->getPermittedChildren(); -	ASSERT_EQ(4, children.size()); +	ASSERT_EQ(4U, children.size());  	ASSERT_EQ(section, children[0]);  	ASSERT_EQ(paragraph, children[1]);  	ASSERT_EQ(text, children[2]); diff --git a/test/core/parser/ParserStackTest.cpp b/test/core/parser/ParserStackTest.cpp deleted file mode 100644 index 3a0decb..0000000 --- a/test/core/parser/ParserStackTest.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* -    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/parser/ParserStack.hpp> -#include <core/StandaloneEnvironment.hpp> - -namespace ousia { - -ConcreteLogger logger; - -static int startCount = 0; -static int endCount = 0; -static int dataCount = 0; - -class TestHandler : public Handler { -public: -	using Handler::Handler; - -	void start(Variant::mapType &args) override { startCount++; } - -	void end() override { endCount++; } - -	void data(const std::string &data, int field) override { dataCount++; } - -	static Handler *create(const HandlerData &data) -	{ -		return new TestHandler(data); -	} -}; - -namespace ParserStates { -static const ParserState Document = -    ParserStateBuilder().parent(&None).elementHandler(TestHandler::create); -static const ParserState Body = ParserStateBuilder() -                                    .parent(&Document) -                                    .elementHandler(TestHandler::create); -static const ParserState Empty = -    ParserStateBuilder().parent(&Document).elementHandler(TestHandler::create); -static const ParserState Special = -    ParserStateBuilder().parent(&All).elementHandler(TestHandler::create); -static const ParserState Arguments = -    ParserStateBuilder() -        .parent(&None) -        .elementHandler(TestHandler::create) -        .arguments({Argument::Int("a"), Argument::String("b")}); -static const ParserState BodyChildren = -    ParserStateBuilder() -        .parent(&Body) -        .elementHandler(TestHandler::create); - -static const std::multimap<std::string, const ParserState *> TestHandlers{ -    {"document", &Document}, -    {"body", &Body}, -    {"empty", &Empty}, -    {"special", &Special}, -    {"arguments", &Arguments}, -    {"*", &BodyChildren}}; -} - -TEST(ParserStack, simpleTest) -{ -	StandaloneEnvironment env(logger); -	ParserStack s{env.context, ParserStates::TestHandlers}; - -	startCount = 0; -	endCount = 0; -	dataCount = 0; - -	EXPECT_EQ("", s.currentCommandName()); -	EXPECT_EQ(&ParserStates::None, &s.currentState()); - -	s.start("document", {}); -	s.data("test1"); - -	EXPECT_EQ("document", s.currentCommandName()); -	EXPECT_EQ(&ParserStates::Document, &s.currentState()); -	EXPECT_EQ(1, startCount); -	EXPECT_EQ(1, dataCount); - -	s.start("body", {}); -	s.data("test2"); -	EXPECT_EQ("body", s.currentCommandName()); -	EXPECT_EQ(&ParserStates::Body, &s.currentState()); -	EXPECT_EQ(2, startCount); -	EXPECT_EQ(2, dataCount); - -	s.start("inner", {}); -	EXPECT_EQ("inner", s.currentCommandName()); -	EXPECT_EQ(&ParserStates::BodyChildren, &s.currentState()); -	s.end(); -	EXPECT_EQ(3, startCount); -	EXPECT_EQ(1, endCount); - -	s.end(); -	EXPECT_EQ(2, endCount); - -	EXPECT_EQ("document", s.currentCommandName()); -	EXPECT_EQ(&ParserStates::Document, &s.currentState()); - -	s.start("body", {}); -	s.data("test3"); -	EXPECT_EQ("body", s.currentCommandName()); -	EXPECT_EQ(&ParserStates::Body, &s.currentState()); -	s.end(); -	EXPECT_EQ(4, startCount); -	EXPECT_EQ(3, dataCount); -	EXPECT_EQ(3, endCount); - -	EXPECT_EQ("document", s.currentCommandName()); -	EXPECT_EQ(&ParserStates::Document, &s.currentState()); - -	s.end(); -	EXPECT_EQ(4, endCount); - -	EXPECT_EQ("", s.currentCommandName()); -	EXPECT_EQ(&ParserStates::None, &s.currentState()); -} - -TEST(ParserStack, errorHandling) -{ -	StandaloneEnvironment env(logger); -	ParserStack s{env.context, ParserStates::TestHandlers}; - -	EXPECT_THROW(s.start("body", {}), OusiaException); -	s.start("document", {}); -	EXPECT_THROW(s.start("document", {}), OusiaException); -	s.start("empty", {}); -	EXPECT_THROW(s.start("body", {}), OusiaException); -	s.start("special", {}); -	s.end(); -	s.end(); -	s.end(); -	EXPECT_EQ(&ParserStates::None, &s.currentState()); -	ASSERT_THROW(s.end(), OusiaException); -	ASSERT_THROW(s.data("test", 1), OusiaException); -} - -TEST(ParserStack, validation) -{ -	StandaloneEnvironment env(logger); -	ParserStack s{env.context, ParserStates::TestHandlers}; - -	logger.reset(); -	s.start("arguments", {}); -	EXPECT_TRUE(logger.hasError()); -	s.end(); - -	s.start("arguments", {{"a", 5}}); -	EXPECT_TRUE(logger.hasError()); -	s.end(); - -	logger.reset(); -	s.start("arguments", {{"a", 5}, {"b", "test"}}); -	EXPECT_FALSE(logger.hasError()); -	s.end(); -} -} - diff --git a/test/core/parser/ParserStateTest.cpp b/test/core/parser/ParserStateTest.cpp deleted file mode 100644 index 91d8dcd..0000000 --- a/test/core/parser/ParserStateTest.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* -    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 <gtest/gtest.h> - -#include <core/common/Rtti.hpp> -#include <core/parser/ParserState.hpp> - -namespace ousia { - -static const Rtti t1; -static const Rtti t2; -static const Rtti t3; -static const Rtti t4; -static const Rtti t5; - -static const ParserState s1 = ParserStateBuilder().createdNodeType(&t1); -static const ParserState s2a = -    ParserStateBuilder().parent(&s1).createdNodeType(&t2); -static const ParserState s2b = -    ParserStateBuilder().parent(&s1).createdNodeType(&t2); -static const ParserState s3 = -    ParserStateBuilder().parents({&s2a, &s1}).createdNodeType(&t3); -static const ParserState s4 = -    ParserStateBuilder().parent(&s3).createdNodeType(&t4); -static const ParserState s5 = -    ParserStateBuilder().parent(&s2b).createdNodeType(&t5); - -TEST(ParserStateDeductor, deduce) -{ -	using Result = std::vector<const ParserState *>; -	using Signature = std::vector<const Rtti *>; -	std::vector<const ParserState *> states{&s1, &s2a, &s2b, &s3, &s4, &s5}; - -	// Should not crash on empty signature -	ASSERT_EQ(Result{}, ParserStateDeductor(Signature{}, states).deduce()); - -	// Try repeating signature elements -	ASSERT_EQ(Result({&s1}), -	          ParserStateDeductor(Signature({&t1}), states).deduce()); -	ASSERT_EQ(Result({&s1}), -	          ParserStateDeductor(Signature({&t1, &t1}), states).deduce()); -	ASSERT_EQ(Result({&s1}), -	          ParserStateDeductor(Signature({&t1, &t1, &t1}), states).deduce()); - -	// Go to another state -	ASSERT_EQ(Result({&s2a, &s2b}), -	          ParserStateDeductor(Signature({&t1, &t1, &t2}), states).deduce()); -	ASSERT_EQ(Result({&s4}), -	          ParserStateDeductor(Signature({&t1, &t3, &t4}), states).deduce()); - -	// Skip one state -	ASSERT_EQ(Result({&s4}), -	          ParserStateDeductor(Signature({&t2, &t4}), states).deduce()); - -	// Impossible signature -	ASSERT_EQ(Result({}), -	          ParserStateDeductor(Signature({&t4, &t5}), states).deduce()); - -} -} - diff --git a/test/core/parser/stack/StackTest.cpp b/test/core/parser/stack/StackTest.cpp new file mode 100644 index 0000000..321d471 --- /dev/null +++ b/test/core/parser/stack/StackTest.cpp @@ -0,0 +1,666 @@ +/* +    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/frontend/TerminalLogger.hpp> +#include <core/parser/stack/Handler.hpp> +#include <core/parser/stack/Stack.hpp> +#include <core/parser/stack/State.hpp> + +#include <core/StandaloneEnvironment.hpp> + +namespace ousia { +namespace parser_stack { + +// Build an instance of the StandaloneEnvironment used for this unit test +static TerminalLogger logger(std::cerr, true); +// static ConcreteLogger logger; +static StandaloneEnvironment env(logger); + +namespace { + +struct Tracker { +	int startCount; +	int endCount; +	int fieldStartCount; +	int fieldEndCount; +	int annotationStartCount; +	int annotationEndCount; +	int dataCount; + +	Variant::mapType startArgs; +	bool fieldStartIsDefault; +	size_t fieldStartIdx; +	Variant annotationStartClassName; +	Variant::mapType annotationStartArgs; +	Variant annotationEndClassName; +	Variant annotationEndElementName; +	Variant dataData; + +	bool startResult; +	bool fieldStartSetIsDefault; +	bool fieldStartResult; +	bool annotationStartResult; +	bool annotationEndResult; +	bool dataResult; + +	Tracker() { reset(); } + +	void reset() +	{ +		startCount = 0; +		endCount = 0; +		fieldStartCount = 0; +		fieldEndCount = 0; +		annotationStartCount = 0; +		annotationEndCount = 0; +		dataCount = 0; + +		startArgs = Variant::mapType{}; +		fieldStartIsDefault = false; +		fieldStartIdx = 0; +		annotationStartClassName = Variant::fromString(std::string{}); +		annotationStartArgs = Variant::mapType{}; +		annotationEndClassName = Variant::fromString(std::string{}); +		annotationEndElementName = Variant::fromString(std::string{}); +		dataData = Variant::fromString(std::string{}); + +		startResult = true; +		fieldStartSetIsDefault = false; +		fieldStartResult = true; +		annotationStartResult = true; +		annotationEndResult = true; +		dataResult = true; +	} + +	void expect(int startCount, int endCount, int fieldStartCount, +	            int fieldEndCount, int annotationStartCount, +	            int annotationEndCount, int dataCount) +	{ +		EXPECT_EQ(startCount, this->startCount); +		EXPECT_EQ(endCount, this->endCount); +		EXPECT_EQ(fieldStartCount, this->fieldStartCount); +		EXPECT_EQ(fieldEndCount, this->fieldEndCount); +		EXPECT_EQ(annotationStartCount, this->annotationStartCount); +		EXPECT_EQ(annotationEndCount, this->annotationEndCount); +		EXPECT_EQ(dataCount, this->dataCount); +	} +}; + +static Tracker tracker; + +class TestHandler : public Handler { +private: +	TestHandler(const HandlerData &handlerData) : Handler(handlerData) {} + +public: +	bool start(Variant::mapType &args) override +	{ +		tracker.startCount++; +		tracker.startArgs = args; +		if (!tracker.startResult) { +			logger().error( +			    "The TestHandler was told not to allow a field start. So it " +			    "doesn't. The TestHandler always obeys its master."); +		} +		return tracker.startResult; +	} + +	void end() override { tracker.endCount++; } + +	bool fieldStart(bool &isDefault, size_t fieldIdx) override +	{ +		tracker.fieldStartCount++; +		tracker.fieldStartIsDefault = isDefault; +		tracker.fieldStartIdx = fieldIdx; +		if (tracker.fieldStartSetIsDefault) { +			isDefault = true; +		} +		return tracker.fieldStartResult; +	} + +	void fieldEnd() override { tracker.fieldEndCount++; } + +	bool annotationStart(const Variant &className, +	                     Variant::mapType &args) override +	{ +		tracker.annotationStartCount++; +		tracker.annotationStartClassName = className; +		tracker.annotationStartArgs = args; +		return tracker.annotationStartResult; +	} + +	bool annotationEnd(const Variant &className, +	                   const Variant &elementName) override +	{ +		tracker.annotationEndCount++; +		tracker.annotationEndClassName = className; +		tracker.annotationEndElementName = elementName; +		return tracker.annotationEndResult; +	} + +	bool data(Variant &data) override +	{ +		tracker.dataCount++; +		tracker.dataData = data; +		return tracker.dataResult; +	} + +	static Handler *create(const HandlerData &handlerData) +	{ +		return new TestHandler(handlerData); +	} +}; +} + +namespace States { +static const State Document = +    StateBuilder().parent(&None).elementHandler(TestHandler::create); +static const State Body = +    StateBuilder().parent(&Document).elementHandler(TestHandler::create); +static const State Empty = +    StateBuilder().parent(&Document).elementHandler(TestHandler::create); +static const State Special = +    StateBuilder().parent(&All).elementHandler(TestHandler::create); +static const State Arguments = +    StateBuilder().parent(&None).elementHandler(TestHandler::create).arguments( +        {Argument::Int("a"), Argument::String("b")}); +static const State BodyChildren = +    StateBuilder().parent(&Body).elementHandler(TestHandler::create); +static const State Any = +    StateBuilder().parents({&None, &Any}).elementHandler(TestHandler::create); + +static const std::multimap<std::string, const State *> TestHandlers{ +    {"document", &Document}, +    {"body", &Body}, +    {"empty", &Empty}, +    {"special", &Special}, +    {"arguments", &Arguments}, +    {"*", &BodyChildren}}; + +static const std::multimap<std::string, const State *> AnyHandlers{{"*", &Any}}; +} + +TEST(Stack, basicTest) +{ +	tracker.reset(); +	logger.reset(); +	{ +		Stack s{env.context, States::TestHandlers}; + +		EXPECT_EQ("", s.currentCommandName()); +		EXPECT_EQ(&States::None, &s.currentState()); + +		s.command("document", {}); +		s.fieldStart(true); +		s.data("test1"); + +		EXPECT_EQ("document", s.currentCommandName()); +		EXPECT_EQ(&States::Document, &s.currentState()); +		tracker.expect(1, 0, 1, 0, 0, 0, 1);  // sc, ec, fsc, fse, asc, aec, dc + +		s.command("body", {}); +		s.fieldStart(true); +		s.data("test2"); +		EXPECT_EQ("body", s.currentCommandName()); +		EXPECT_EQ(&States::Body, &s.currentState()); +		tracker.expect(2, 0, 2, 0, 0, 0, 2);  // sc, ec, fsc, fse, asc, aec, dc + +		s.command("inner", {}); +		s.fieldStart(true); +		EXPECT_EQ("inner", s.currentCommandName()); +		EXPECT_EQ(&States::BodyChildren, &s.currentState()); + +		s.fieldEnd(); +		tracker.expect(3, 1, 3, 1, 0, 0, 2);  // sc, ec, fsc, fse, asc, aec, dc + +		s.fieldEnd(); +		EXPECT_EQ("document", s.currentCommandName()); +		EXPECT_EQ(&States::Document, &s.currentState()); +		tracker.expect(3, 2, 3, 2, 0, 0, 2);  // sc, ec, fsc, fse, asc, aec, dc + +		s.command("body", {}); +		s.fieldStart(true); +		s.data("test3"); +		EXPECT_EQ("body", s.currentCommandName()); +		EXPECT_EQ(&States::Body, &s.currentState()); +		s.fieldEnd(); +		tracker.expect(4, 3, 4, 3, 0, 0, 3);  // sc, ec, fsc, fse, asc, aec, dc + +		EXPECT_EQ("document", s.currentCommandName()); +		EXPECT_EQ(&States::Document, &s.currentState()); + +		s.fieldEnd(); +		tracker.expect(4, 4, 4, 4, 0, 0, 3);  // sc, ec, fsc, fse, asc, aec, dc + +		EXPECT_EQ("", s.currentCommandName()); +		EXPECT_EQ(&States::None, &s.currentState()); +	} +	ASSERT_FALSE(logger.hasError()); +} + +TEST(Stack, errorInvalidCommands) +{ +	Stack s{env.context, States::TestHandlers}; +	tracker.reset(); +	EXPECT_THROW(s.command("body", {}), LoggableException); +	s.command("document", {}); +	s.fieldStart(true); +	EXPECT_THROW(s.command("document", {}), LoggableException); +	s.command("empty", {}); +	s.fieldStart(true); +	EXPECT_THROW(s.command("body", {}), LoggableException); +	s.command("special", {}); +	s.fieldStart(true); +	s.fieldEnd(); +	s.fieldEnd(); +	s.fieldEnd(); +	EXPECT_EQ(&States::None, &s.currentState()); +	ASSERT_THROW(s.fieldEnd(), LoggableException); +	ASSERT_THROW(s.data("test"), LoggableException); +} + +TEST(Stack, validation) +{ +	Stack s{env.context, States::TestHandlers}; +	tracker.reset(); +	logger.reset(); + +	s.command("arguments", {}); +	EXPECT_TRUE(logger.hasError()); +	s.fieldStart(true); +	s.fieldEnd(); + +	logger.reset(); +	s.command("arguments", {{"a", 5}}); +	EXPECT_TRUE(logger.hasError()); +	s.fieldStart(true); +	s.fieldEnd(); + +	logger.reset(); +	s.command("arguments", {{"a", 5}, {"b", "test"}}); +	EXPECT_FALSE(logger.hasError()); +	s.fieldStart(true); +	s.fieldEnd(); +} + +TEST(Stack, invalidCommandName) +{ +	Stack s{env.context, States::AnyHandlers}; +	tracker.reset(); +	logger.reset(); + +	s.command("a", {}); +	s.fieldStart(true); +	s.fieldEnd(); +	tracker.expect(1, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc + +	s.command("a_", {}); +	s.fieldStart(true); +	s.fieldEnd(); +	tracker.expect(2, 2, 2, 2, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc + +	s.command("a_:b", {}); +	s.fieldStart(true); +	s.fieldEnd(); +	tracker.expect(3, 3, 3, 3, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc + +	ASSERT_THROW(s.command("_a", {}), LoggableException); +	ASSERT_THROW(s.command("a:", {}), LoggableException); +	ASSERT_THROW(s.command("a:_b", {}), LoggableException); +	tracker.expect(3, 3, 3, 3, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +} + +TEST(Stack, multipleFields) +{ +	tracker.reset(); +	logger.reset(); +	{ +		Stack s{env.context, States::AnyHandlers}; + +		s.command("a", {{"a", false}}); +		tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +		EXPECT_EQ("a", s.currentCommandName()); +		EXPECT_EQ(Variant::mapType({{"a", false}}), tracker.startArgs); + +		s.fieldStart(false); +		tracker.expect(1, 0, 1, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +		EXPECT_FALSE(tracker.fieldStartIsDefault); +		EXPECT_EQ(0U, tracker.fieldStartIdx); + +		s.data("test"); +		tracker.expect(1, 0, 1, 0, 0, 0, 1);  // sc, ec, fsc, fse, asc, aec, dc +		EXPECT_EQ("test", tracker.dataData); + +		s.fieldEnd(); +		tracker.expect(1, 0, 1, 1, 0, 0, 1);  // sc, ec, fsc, fse, asc, aec, dc + +		s.fieldStart(false); +		tracker.expect(1, 0, 2, 1, 0, 0, 1);  // sc, ec, fsc, fse, asc, aec, dc +		EXPECT_FALSE(tracker.fieldStartIsDefault); +		EXPECT_EQ(1U, tracker.fieldStartIdx); + +		s.data("test2"); +		tracker.expect(1, 0, 2, 1, 0, 0, 2);  // sc, ec, fsc, fse, asc, aec, dc +		EXPECT_EQ("test2", tracker.dataData); + +		s.fieldEnd(); +		tracker.expect(1, 0, 2, 2, 0, 0, 2);  // sc, ec, fsc, fse, asc, aec, dc + +		s.fieldStart(true); +		tracker.expect(1, 0, 3, 2, 0, 0, 2);  // sc, ec, fsc, fse, asc, aec, dc +		EXPECT_TRUE(tracker.fieldStartIsDefault); +		EXPECT_EQ(2U, tracker.fieldStartIdx); + +		s.data("test3"); +		tracker.expect(1, 0, 3, 2, 0, 0, 3);  // sc, ec, fsc, fse, asc, aec, dc +		EXPECT_EQ("test3", tracker.dataData); + +		s.fieldEnd(); +		tracker.expect(1, 1, 3, 3, 0, 0, 3);  // sc, ec, fsc, fse, asc, aec, dc +	} +	ASSERT_FALSE(logger.hasError()); +} + +TEST(Stack, implicitDefaultFieldOnNewCommand) +{ +	tracker.reset(); +	logger.reset(); +	{ +		Stack s{env.context, States::AnyHandlers}; + +		s.command("a", {}); +		tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc + +		s.command("b", {}); +		tracker.expect(2, 0, 1, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	} +	tracker.expect(2, 2, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	ASSERT_FALSE(logger.hasError()); +} + +TEST(Stack, implicitDefaultFieldOnNewCommandWithExplicitDefaultField) +{ +	tracker.reset(); +	logger.reset(); +	{ +		Stack s{env.context, States::AnyHandlers}; + +		s.command("a", {}); +		tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +		ASSERT_EQ("a", s.currentCommandName()); + +		s.command("b", {}); +		tracker.expect(2, 0, 1, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +		ASSERT_EQ("b", s.currentCommandName()); +		s.fieldStart(true); +		s.fieldEnd(); +		tracker.expect(2, 1, 2, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +		ASSERT_EQ("a", s.currentCommandName()); +	} +	tracker.expect(2, 2, 2, 2, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	ASSERT_FALSE(logger.hasError()); +} + +TEST(Stack, noImplicitDefaultFieldOnIncompatibleCommand) +{ +	tracker.reset(); +	logger.reset(); +	{ +		Stack s{env.context, States::AnyHandlers}; + +		s.command("a", {}); +		tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +		ASSERT_EQ("a", s.currentCommandName()); + +		tracker.fieldStartResult = false; +		s.command("b", {}); +		tracker.expect(2, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +		ASSERT_EQ("b", s.currentCommandName()); +	} +	tracker.expect(2, 2, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	ASSERT_FALSE(logger.hasError()); +} + +TEST(Stack, noImplicitDefaultFieldIfDefaultFieldGiven) +{ +	tracker.reset(); +	logger.reset(); +	{ +		Stack s{env.context, States::AnyHandlers}; + +		s.command("a", {}); +		tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +		ASSERT_EQ("a", s.currentCommandName()); +		s.fieldStart(true); +		tracker.expect(1, 0, 1, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +		ASSERT_EQ("a", s.currentCommandName()); +		s.fieldEnd(); +		tracker.expect(1, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +		ASSERT_EQ("", s.currentCommandName()); + +		s.command("b", {}); +		tracker.expect(2, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +		ASSERT_EQ("b", s.currentCommandName()); +	} +	tracker.expect(2, 2, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	ASSERT_FALSE(logger.hasError()); +} + +TEST(Stack, noEndIfStartFails) +{ +	tracker.reset(); +	logger.reset(); +	{ +		Stack s{env.context, States::AnyHandlers}; + +		s.command("a", {}); +		tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +		ASSERT_EQ("a", s.currentCommandName()); + +		tracker.startResult = false; +		s.command("b", {}); +		tracker.expect(3, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +		ASSERT_EQ("b", s.currentCommandName()); +	} +	tracker.expect(3, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	ASSERT_TRUE(logger.hasError()); +} + +TEST(Stack, implicitDefaultFieldOnData) +{ +	tracker.reset(); +	logger.reset(); +	{ +		Stack s{env.context, States::AnyHandlers}; + +		s.command("a", {}); +		tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc + +		s.data("test"); +		tracker.expect(1, 0, 1, 0, 0, 0, 1);  // sc, ec, fsc, fse, asc, aec, dc +	} +	tracker.expect(1, 1, 1, 1, 0, 0, 1);  // sc, ec, fsc, fse, asc, aec, dc +	ASSERT_FALSE(logger.hasError()); +} + +TEST(Stack, autoFieldEnd) +{ +	tracker.reset(); +	logger.reset(); + +	{ +		Stack s{env.context, States::AnyHandlers}; +		s.command("a", {}); +		tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	} +	tracker.expect(1, 1, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	ASSERT_FALSE(logger.hasError()); +} + +TEST(Stack, autoImplicitFieldEnd) +{ +	tracker.reset(); +	logger.reset(); + +	{ +		Stack s{env.context, States::AnyHandlers}; +		s.command("a", {}); +		s.command("b", {}); +		s.command("c", {}); +		s.command("d", {}); +		s.command("e", {}); +		s.fieldStart(true); +		s.fieldEnd(); +		tracker.expect(5, 1, 5, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	} +	tracker.expect(5, 5, 5, 5, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	ASSERT_FALSE(logger.hasError()); +} + +TEST(Stack, invalidDefaultField) +{ +	tracker.reset(); +	logger.reset(); + +	{ +		Stack s{env.context, States::AnyHandlers}; +		s.command("a", {}); +		tracker.fieldStartResult = false; +		s.fieldStart(true); +		s.fieldEnd(); +		tracker.expect(1, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	} +	tracker.expect(1, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	ASSERT_FALSE(logger.hasError()); +} + +TEST(Stack, errorInvalidDefaultFieldData) +{ +	tracker.reset(); +	logger.reset(); + +	{ +		Stack s{env.context, States::AnyHandlers}; +		s.command("a", {}); +		tracker.fieldStartResult = false; +		s.fieldStart(true); +		ASSERT_FALSE(logger.hasError()); +		s.data("test"); +		ASSERT_TRUE(logger.hasError()); +		s.fieldEnd(); +		tracker.expect(1, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	} +	tracker.expect(1, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +} + +TEST(Stack, errorInvalidFieldData) +{ +	tracker.reset(); +	logger.reset(); + +	{ +		Stack s{env.context, States::AnyHandlers}; +		s.command("a", {}); +		tracker.fieldStartResult = false; +		ASSERT_FALSE(logger.hasError()); +		s.fieldStart(false); +		ASSERT_TRUE(logger.hasError()); +		s.data("test"); +		s.fieldEnd(); +		tracker.expect(1, 0, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	} +	tracker.expect(1, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +} + +TEST(Stack, errorFieldStartNoCommand) +{ +	tracker.reset(); +	logger.reset(); + +	Stack s{env.context, States::AnyHandlers}; +	ASSERT_THROW(s.fieldStart(false), LoggableException); +	ASSERT_THROW(s.fieldStart(true), LoggableException); +	tracker.expect(0, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +} + +TEST(Stack, errorMutlipleFieldStarts) +{ +	tracker.reset(); +	logger.reset(); + +	{ +		Stack s{env.context, States::AnyHandlers}; +		s.command("a", {}); +		tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc + +		s.fieldStart(false); +		ASSERT_FALSE(logger.hasError()); +		s.fieldStart(false); +		ASSERT_TRUE(logger.hasError()); +		tracker.expect(1, 0, 1, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc + +		s.fieldEnd(); +		tracker.expect(1, 0, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	} +	tracker.expect(1, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +} + +TEST(Stack, errorMutlipleFieldEnds) +{ +	tracker.reset(); +	logger.reset(); + +	{ +		Stack s{env.context, States::AnyHandlers}; +		s.command("a", {}); +		tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc + +		s.fieldStart(false); +		s.fieldEnd(); +		ASSERT_FALSE(logger.hasError()); +		tracker.expect(1, 0, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +		s.fieldEnd(); +		ASSERT_TRUE(logger.hasError()); +		tracker.expect(1, 0, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	} +	tracker.expect(1, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +} + +TEST(Stack, errorOpenField) +{ +	tracker.reset(); +	logger.reset(); + +	{ +		Stack s{env.context, States::AnyHandlers}; +		s.command("a", {}); +		tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc + +		s.fieldStart(false); +		ASSERT_FALSE(logger.hasError()); +	} +	ASSERT_TRUE(logger.hasError()); +	tracker.expect(1, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +} +} +} + diff --git a/test/core/parser/stack/StateTest.cpp b/test/core/parser/stack/StateTest.cpp new file mode 100644 index 0000000..e503d30 --- /dev/null +++ b/test/core/parser/stack/StateTest.cpp @@ -0,0 +1,79 @@ +/* +    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 <gtest/gtest.h> + +#include <core/common/Rtti.hpp> +#include <core/parser/stack/State.hpp> + +namespace ousia { +namespace parser_stack { + +static const Rtti t1; +static const Rtti t2; +static const Rtti t3; +static const Rtti t4; +static const Rtti t5; + +static const State s1 = StateBuilder().createdNodeType(&t1); +static const State s2a = +    StateBuilder().parent(&s1).createdNodeType(&t2); +static const State s2b = +    StateBuilder().parent(&s1).createdNodeType(&t2); +static const State s3 = +    StateBuilder().parents({&s2a, &s1}).createdNodeType(&t3); +static const State s4 = +    StateBuilder().parent(&s3).createdNodeType(&t4); +static const State s5 = +    StateBuilder().parent(&s2b).createdNodeType(&t5); + +TEST(StateDeductor, deduce) +{ +	using Result = std::vector<const State *>; +	using Signature = std::vector<const Rtti *>; +	std::vector<const State *> states{&s1, &s2a, &s2b, &s3, &s4, &s5}; + +	// Should not crash on empty signature +	ASSERT_EQ(Result{}, StateDeductor(Signature{}, states).deduce()); + +	// Try repeating signature elements +	ASSERT_EQ(Result({&s1}), +	          StateDeductor(Signature({&t1}), states).deduce()); +	ASSERT_EQ(Result({&s1}), +	          StateDeductor(Signature({&t1, &t1}), states).deduce()); +	ASSERT_EQ(Result({&s1}), +	          StateDeductor(Signature({&t1, &t1, &t1}), states).deduce()); + +	// Go to another state +	ASSERT_EQ(Result({&s2a, &s2b}), +	          StateDeductor(Signature({&t1, &t1, &t2}), states).deduce()); +	ASSERT_EQ(Result({&s4}), +	          StateDeductor(Signature({&t1, &t3, &t4}), states).deduce()); + +	// Skip one state +	ASSERT_EQ(Result({&s4}), +	          StateDeductor(Signature({&t2, &t4}), states).deduce()); + +	// Impossible signature +	ASSERT_EQ(Result({}), +	          StateDeductor(Signature({&t4, &t5}), states).deduce()); + +} +} +} + diff --git a/test/formats/osdm/TokenTrieTest.cpp b/test/core/parser/utils/TokenTrieTest.cpp index aacd6c0..087e6e6 100644 --- a/test/formats/osdm/TokenTrieTest.cpp +++ b/test/core/parser/utils/TokenTrieTest.cpp @@ -18,7 +18,7 @@  #include <gtest/gtest.h> -#include <formats/osdm/TokenTrie.hpp> +#include <core/parser/utils/TokenTrie.hpp>  namespace ousia { diff --git a/test/formats/osdm/DynamicTokenizerTest.cpp b/test/core/parser/utils/TokenizerTest.cpp index c1f8785..8565057 100644 --- a/test/formats/osdm/DynamicTokenizerTest.cpp +++ b/test/core/parser/utils/TokenizerTest.cpp @@ -19,13 +19,13 @@  #include <gtest/gtest.h>  #include <core/common/CharReader.hpp> -#include <formats/osdm/DynamicTokenizer.hpp> +#include <core/parser/utils/Tokenizer.hpp>  namespace ousia { -TEST(DynamicTokenizer, tokenRegistration) +TEST(Tokenizer, tokenRegistration)  { -	DynamicTokenizer tokenizer; +	Tokenizer tokenizer;  	ASSERT_EQ(EmptyToken, tokenizer.registerToken("")); @@ -50,15 +50,15 @@ TEST(DynamicTokenizer, tokenRegistration)  	ASSERT_EQ("d", tokenizer.getTokenString(1U));  } -TEST(DynamicTokenizer, textTokenPreserveWhitespace) +TEST(Tokenizer, textTokenPreserveWhitespace)  {  	{  		CharReader reader{" this \t is only a  \n\n test   text   "};  		//                 012345 6789012345678 9 0123456789012345  		//                 0          1           2         3 -		DynamicTokenizer tokenizer{WhitespaceMode::PRESERVE}; +		Tokenizer tokenizer{WhitespaceMode::PRESERVE}; -		DynamicToken token; +		Token token;  		ASSERT_TRUE(tokenizer.read(reader, token));  		ASSERT_EQ(TextToken, token.type);  		ASSERT_EQ(" this \t is only a  \n\n test   text   ", token.content); @@ -74,9 +74,9 @@ TEST(DynamicTokenizer, textTokenPreserveWhitespace)  		CharReader reader{"this \t is only a  \n\n test   text"};  		//                 01234 5678901234567 8 9012345678901  		//                 0          1           2         3 -		DynamicTokenizer tokenizer{WhitespaceMode::PRESERVE}; +		Tokenizer tokenizer{WhitespaceMode::PRESERVE}; -		DynamicToken token; +		Token token;  		ASSERT_TRUE(tokenizer.read(reader, token));  		ASSERT_EQ(TextToken, token.type);  		ASSERT_EQ("this \t is only a  \n\n test   text", token.content); @@ -89,15 +89,15 @@ TEST(DynamicTokenizer, textTokenPreserveWhitespace)  	}  } -TEST(DynamicTokenizer, textTokenTrimWhitespace) +TEST(Tokenizer, textTokenTrimWhitespace)  {  	{  		CharReader reader{" this \t is only a  \n\n test   text   "};  		//                 012345 6789012345678 9 0123456789012345  		//                 0          1           2         3 -		DynamicTokenizer tokenizer{WhitespaceMode::TRIM}; +		Tokenizer tokenizer{WhitespaceMode::TRIM}; -		DynamicToken token; +		Token token;  		ASSERT_TRUE(tokenizer.read(reader, token));  		ASSERT_EQ(TextToken, token.type);  		ASSERT_EQ("this \t is only a  \n\n test   text", token.content); @@ -113,9 +113,9 @@ TEST(DynamicTokenizer, textTokenTrimWhitespace)  		CharReader reader{"this \t is only a  \n\n test   text"};  		//                 01234 5678901234567 8 9012345678901  		//                 0          1           2         3 -		DynamicTokenizer tokenizer{WhitespaceMode::TRIM}; +		Tokenizer tokenizer{WhitespaceMode::TRIM}; -		DynamicToken token; +		Token token;  		ASSERT_TRUE(tokenizer.read(reader, token));  		ASSERT_EQ(TextToken, token.type);  		ASSERT_EQ("this \t is only a  \n\n test   text", token.content); @@ -128,15 +128,15 @@ TEST(DynamicTokenizer, textTokenTrimWhitespace)  	}  } -TEST(DynamicTokenizer, textTokenCollapseWhitespace) +TEST(Tokenizer, textTokenCollapseWhitespace)  {  	{  		CharReader reader{" this \t is only a  \n\n test   text   "};  		//                 012345 6789012345678 9 0123456789012345  		//                 0          1           2         3 -		DynamicTokenizer tokenizer{WhitespaceMode::COLLAPSE}; +		Tokenizer tokenizer{WhitespaceMode::COLLAPSE}; -		DynamicToken token; +		Token token;  		ASSERT_TRUE(tokenizer.read(reader, token));  		ASSERT_EQ(TextToken, token.type);  		ASSERT_EQ("this is only a test text", token.content); @@ -152,9 +152,9 @@ TEST(DynamicTokenizer, textTokenCollapseWhitespace)  		CharReader reader{"this \t is only a  \n\n test   text"};  		//                 01234 5678901234567 8 9012345678901  		//                 0          1           2         3 -		DynamicTokenizer tokenizer{WhitespaceMode::COLLAPSE}; +		Tokenizer tokenizer{WhitespaceMode::COLLAPSE}; -		DynamicToken token; +		Token token;  		ASSERT_TRUE(tokenizer.read(reader, token));  		ASSERT_EQ(TextToken, token.type);  		ASSERT_EQ("this is only a test text", token.content); @@ -167,16 +167,16 @@ TEST(DynamicTokenizer, textTokenCollapseWhitespace)  	}  } -TEST(DynamicTokenizer, simpleReadToken) +TEST(Tokenizer, simpleReadToken)  {  	CharReader reader{"test1:test2"}; -	DynamicTokenizer tokenizer; +	Tokenizer tokenizer;  	const TokenTypeId tid = tokenizer.registerToken(":");  	ASSERT_EQ(0U, tid);  	{ -		DynamicToken token; +		Token token;  		ASSERT_TRUE(tokenizer.read(reader, token));  		ASSERT_EQ(TextToken, token.type); @@ -192,7 +192,7 @@ TEST(DynamicTokenizer, simpleReadToken)  	}  	{ -		DynamicToken token; +		Token token;  		ASSERT_TRUE(tokenizer.read(reader, token));  		ASSERT_EQ(tid, token.type); @@ -208,7 +208,7 @@ TEST(DynamicTokenizer, simpleReadToken)  	}  	{ -		DynamicToken token; +		Token token;  		ASSERT_TRUE(tokenizer.read(reader, token));  		ASSERT_EQ(TextToken, token.type); @@ -223,16 +223,16 @@ TEST(DynamicTokenizer, simpleReadToken)  	}  } -TEST(DynamicTokenizer, simplePeekToken) +TEST(Tokenizer, simplePeekToken)  {  	CharReader reader{"test1:test2"}; -	DynamicTokenizer tokenizer; +	Tokenizer tokenizer;  	const TokenTypeId tid = tokenizer.registerToken(":");  	ASSERT_EQ(0U, tid);  	{ -		DynamicToken token; +		Token token;  		ASSERT_TRUE(tokenizer.peek(reader, token));  		ASSERT_EQ(TextToken, token.type); @@ -246,7 +246,7 @@ TEST(DynamicTokenizer, simplePeekToken)  	}  	{ -		DynamicToken token; +		Token token;  		ASSERT_TRUE(tokenizer.peek(reader, token));  		ASSERT_EQ(tid, token.type); @@ -260,7 +260,7 @@ TEST(DynamicTokenizer, simplePeekToken)  	}  	{ -		DynamicToken token; +		Token token;  		ASSERT_TRUE(tokenizer.peek(reader, token));  		ASSERT_EQ(TextToken, token.type); @@ -274,7 +274,7 @@ TEST(DynamicTokenizer, simplePeekToken)  	}  	{ -		DynamicToken token; +		Token token;  		ASSERT_TRUE(tokenizer.read(reader, token));  		ASSERT_EQ(TextToken, token.type); @@ -288,7 +288,7 @@ TEST(DynamicTokenizer, simplePeekToken)  	}  	{ -		DynamicToken token; +		Token token;  		ASSERT_TRUE(tokenizer.read(reader, token));  		ASSERT_EQ(tid, token.type); @@ -302,7 +302,7 @@ TEST(DynamicTokenizer, simplePeekToken)  	}  	{ -		DynamicToken token; +		Token token;  		ASSERT_TRUE(tokenizer.read(reader, token));  		ASSERT_EQ(TextToken, token.type); @@ -316,10 +316,10 @@ TEST(DynamicTokenizer, simplePeekToken)  	}  } -TEST(DynamicTokenizer, ambiguousTokens) +TEST(Tokenizer, ambiguousTokens)  {  	CharReader reader{"abc"}; -	DynamicTokenizer tokenizer; +	Tokenizer tokenizer;  	TokenTypeId t1 = tokenizer.registerToken("abd");  	TokenTypeId t2 = tokenizer.registerToken("bc"); @@ -327,7 +327,7 @@ TEST(DynamicTokenizer, ambiguousTokens)  	ASSERT_EQ(0U, t1);  	ASSERT_EQ(1U, t2); -	DynamicToken token; +	Token token;  	ASSERT_TRUE(tokenizer.read(reader, token));  	ASSERT_EQ(TextToken, token.type); @@ -349,18 +349,18 @@ TEST(DynamicTokenizer, ambiguousTokens)  	ASSERT_FALSE(tokenizer.read(reader, token));  } -TEST(DynamicTokenizer, commentTestWhitespacePreserve) +TEST(Tokenizer, commentTestWhitespacePreserve)  {  	CharReader reader{"Test/Test /* Block Comment */", 0};  	//                 012345678901234567890123456789  	//                 0        1         2 -	DynamicTokenizer tokenizer(WhitespaceMode::PRESERVE); +	Tokenizer tokenizer(WhitespaceMode::PRESERVE);  	const TokenTypeId t1 = tokenizer.registerToken("/");  	const TokenTypeId t2 = tokenizer.registerToken("/*");  	const TokenTypeId t3 = tokenizer.registerToken("*/"); -	std::vector<DynamicToken> expected = { +	std::vector<Token> expected = {  	    {TextToken, "Test", SourceLocation{0, 0, 4}},  	    {t1, "/", SourceLocation{0, 4, 5}},  	    {TextToken, "Test ", SourceLocation{0, 5, 10}}, @@ -368,7 +368,7 @@ TEST(DynamicTokenizer, commentTestWhitespacePreserve)  	    {TextToken, " Block Comment ", SourceLocation{0, 12, 27}},  	    {t3, "*/", SourceLocation{0, 27, 29}}}; -	DynamicToken t; +	Token t;  	for (auto &te : expected) {  		EXPECT_TRUE(tokenizer.read(reader, t));  		EXPECT_EQ(te.type, t.type); @@ -380,18 +380,18 @@ TEST(DynamicTokenizer, commentTestWhitespacePreserve)  	ASSERT_FALSE(tokenizer.read(reader, t));  } -TEST(DynamicTokenizer, commentTestWhitespaceCollapse) +TEST(Tokenizer, commentTestWhitespaceCollapse)  {  	CharReader reader{"Test/Test /* Block Comment */", 0};  	//                 012345678901234567890123456789  	//                 0        1         2 -	DynamicTokenizer tokenizer(WhitespaceMode::COLLAPSE); +	Tokenizer tokenizer(WhitespaceMode::COLLAPSE);  	const TokenTypeId t1 = tokenizer.registerToken("/");  	const TokenTypeId t2 = tokenizer.registerToken("/*");  	const TokenTypeId t3 = tokenizer.registerToken("*/"); -	std::vector<DynamicToken> expected = { +	std::vector<Token> expected = {  	    {TextToken, "Test", SourceLocation{0, 0, 4}},  	    {t1, "/", SourceLocation{0, 4, 5}},  	    {TextToken, "Test", SourceLocation{0, 5, 9}}, @@ -399,7 +399,7 @@ TEST(DynamicTokenizer, commentTestWhitespaceCollapse)  	    {TextToken, "Block Comment", SourceLocation{0, 13, 26}},  	    {t3, "*/", SourceLocation{0, 27, 29}}}; -	DynamicToken t; +	Token t;  	for (auto &te : expected) {  		EXPECT_TRUE(tokenizer.read(reader, t));  		EXPECT_EQ(te.type, t.type); @@ -410,6 +410,5 @@ TEST(DynamicTokenizer, commentTestWhitespaceCollapse)  	}  	ASSERT_FALSE(tokenizer.read(reader, t));  } -  } diff --git a/test/formats/osdm/OsdmStreamParserTest.cpp b/test/formats/osml/OsmlStreamParserTest.cpp index 46f4cf6..d52fa5b 100644 --- a/test/formats/osdm/OsdmStreamParserTest.cpp +++ b/test/formats/osml/OsmlStreamParserTest.cpp @@ -23,95 +23,205 @@  #include <core/common/CharReader.hpp>  #include <core/frontend/TerminalLogger.hpp> -#include <formats/osdm/OsdmStreamParser.hpp> +#include <formats/osml/OsmlStreamParser.hpp>  namespace ousia {  static TerminalLogger logger(std::cerr, true); +// static ConcreteLogger logger; -TEST(OsdmStreamParser, empty) +static void assertCommand(OsmlStreamParser &reader, const std::string &name, +                          SourceOffset start = InvalidSourceOffset, +                          SourceOffset end = InvalidSourceOffset) +{ +	ASSERT_EQ(OsmlStreamParser::State::COMMAND, reader.parse()); +	EXPECT_EQ(name, reader.getCommandName().asString()); +	if (start != InvalidSourceOffset) { +		EXPECT_EQ(start, reader.getCommandName().getLocation().getStart()); +		EXPECT_EQ(start, reader.getLocation().getStart()); +	} +	if (end != InvalidSourceOffset) { +		EXPECT_EQ(end, reader.getCommandName().getLocation().getEnd()); +		EXPECT_EQ(end, reader.getLocation().getEnd()); +	} +} + +static void assertCommand(OsmlStreamParser &reader, const std::string &name, +                          const Variant::mapType &args, +                          SourceOffset start = InvalidSourceOffset, +                          SourceOffset end = InvalidSourceOffset) +{ +	assertCommand(reader, name, start, end); +	EXPECT_EQ(args, reader.getCommandArguments()); +} + +static void assertData(OsmlStreamParser &reader, const std::string &data, +                       SourceOffset start = InvalidSourceOffset, +                       SourceOffset end = InvalidSourceOffset) +{ +	ASSERT_EQ(OsmlStreamParser::State::DATA, reader.parse()); +	EXPECT_EQ(data, reader.getData().asString()); +	if (start != InvalidSourceOffset) { +		EXPECT_EQ(start, reader.getData().getLocation().getStart()); +		EXPECT_EQ(start, reader.getLocation().getStart()); +	} +	if (end != InvalidSourceOffset) { +		EXPECT_EQ(end, reader.getData().getLocation().getEnd()); +		EXPECT_EQ(end, reader.getLocation().getEnd()); +	} +} + +static void assertFieldStart(OsmlStreamParser &reader, bool defaultField, +                             SourceOffset start = InvalidSourceOffset, +                             SourceOffset end = InvalidSourceOffset) +{ +	ASSERT_EQ(OsmlStreamParser::State::FIELD_START, reader.parse()); +	EXPECT_EQ(defaultField, reader.inDefaultField()); +	if (start != InvalidSourceOffset) { +		EXPECT_EQ(start, reader.getLocation().getStart()); +	} +	if (end != InvalidSourceOffset) { +		EXPECT_EQ(end, reader.getLocation().getEnd()); +	} +} + +static void assertFieldEnd(OsmlStreamParser &reader, +                           SourceOffset start = InvalidSourceOffset, +                           SourceOffset end = InvalidSourceOffset) +{ +	ASSERT_EQ(OsmlStreamParser::State::FIELD_END, reader.parse()); +	if (start != InvalidSourceOffset) { +		EXPECT_EQ(start, reader.getLocation().getStart()); +	} +	if (end != InvalidSourceOffset) { +		EXPECT_EQ(end, reader.getLocation().getEnd()); +	} +} + +static void assertAnnotationStart(OsmlStreamParser &reader, +                                  const std::string &name, +                                  SourceOffset start = InvalidSourceOffset, +                                  SourceOffset end = InvalidSourceOffset) +{ +	ASSERT_EQ(OsmlStreamParser::State::ANNOTATION_START, reader.parse()); +	EXPECT_EQ(name, reader.getCommandName().asString()); +	if (start != InvalidSourceOffset) { +		EXPECT_EQ(start, reader.getCommandName().getLocation().getStart()); +		EXPECT_EQ(start, reader.getLocation().getStart()); +	} +	if (end != InvalidSourceOffset) { +		EXPECT_EQ(end, reader.getCommandName().getLocation().getEnd()); +		EXPECT_EQ(end, reader.getLocation().getEnd()); +	} +} + +static void assertAnnotationStart(OsmlStreamParser &reader, +                                  const std::string &name, +                                  const Variant::mapType &args, +                                  SourceOffset start = InvalidSourceOffset, +                                  SourceOffset end = InvalidSourceOffset) +{ +	assertAnnotationStart(reader, name, start, end); +	EXPECT_EQ(args, reader.getCommandArguments()); +} + +static void assertAnnotationEnd(OsmlStreamParser &reader, +                                const std::string &name, +                                const std::string &elementName, +                                SourceOffset start = InvalidSourceOffset, +                                SourceOffset end = InvalidSourceOffset) +{ +	ASSERT_EQ(OsmlStreamParser::State::ANNOTATION_END, reader.parse()); +	ASSERT_EQ(name, reader.getCommandName().asString()); +	if (!elementName.empty()) { +		ASSERT_EQ(1U, reader.getCommandArguments().asMap().size()); +		ASSERT_EQ(1U, reader.getCommandArguments().asMap().count("name")); + +		auto it = reader.getCommandArguments().asMap().find("name"); +		ASSERT_EQ(elementName, it->second.asString()); +	} +	if (start != InvalidSourceOffset) { +		EXPECT_EQ(start, reader.getLocation().getStart()); +	} +	if (end != InvalidSourceOffset) { +		EXPECT_EQ(end, reader.getLocation().getEnd()); +	} +} + +static void assertEnd(OsmlStreamParser &reader, +                      SourceOffset start = InvalidSourceOffset, +                      SourceOffset end = InvalidSourceOffset) +{ +	ASSERT_EQ(OsmlStreamParser::State::END, reader.parse()); +	if (start != InvalidSourceOffset) { +		EXPECT_EQ(start, reader.getLocation().getStart()); +	} +	if (end != InvalidSourceOffset) { +		EXPECT_EQ(end, reader.getLocation().getEnd()); +	} +} + +TEST(OsmlStreamParser, empty)  {  	const char *testString = "";  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger); -	ASSERT_EQ(OsdmStreamParser::State::END, reader.parse()); +	ASSERT_EQ(OsmlStreamParser::State::END, reader.parse());  } -TEST(OsdmStreamParser, oneCharacter) +TEST(OsmlStreamParser, oneCharacter)  {  	const char *testString = "a";  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); - -	ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse()); -	ASSERT_EQ("a", reader.getData().asString()); +	OsmlStreamParser reader(charReader, logger); -	SourceLocation loc = reader.getData().getLocation(); -	ASSERT_EQ(0U, loc.getStart()); -	ASSERT_EQ(1U, loc.getEnd()); +	assertData(reader, "a", 0, 1);  } -TEST(OsdmStreamParser, whitespaceElimination) +TEST(OsmlStreamParser, whitespaceElimination)  {  	const char *testString = " hello \t world ";  	//                        0123456 78901234  	//                        0          1  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); - -	ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse()); -	ASSERT_EQ("hello world", reader.getData().asString()); +	OsmlStreamParser reader(charReader, logger); -	SourceLocation loc = reader.getData().getLocation(); -	ASSERT_EQ(1U, loc.getStart()); -	ASSERT_EQ(14U, loc.getEnd()); +	assertData(reader, "hello world", 1, 14);  } -TEST(OsdmStreamParser, whitespaceEliminationWithLinebreak) +TEST(OsmlStreamParser, whitespaceEliminationWithLinebreak)  {  	const char *testString = " hello \n world ";  	//                        0123456 78901234  	//                        0          1  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); - -	ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse()); -	ASSERT_EQ("hello world", reader.getData().asString()); +	OsmlStreamParser reader(charReader, logger); -	SourceLocation loc = reader.getData().getLocation(); -	ASSERT_EQ(1U, loc.getStart()); -	ASSERT_EQ(14U, loc.getEnd()); -	ASSERT_EQ(OsdmStreamParser::State::END, reader.parse()); +	assertData(reader, "hello world", 1, 14);  } -TEST(OsdmStreamParser, escapeWhitespace) +TEST(OsmlStreamParser, escapeWhitespace)  {  	const char *testString = " hello\\ \\ world ";  	//                        012345 67 89012345  	//                        0           1  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger); -	ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse()); -	ASSERT_EQ("hello  world", reader.getData().asString()); - -	SourceLocation loc = reader.getData().getLocation(); -	ASSERT_EQ(1U, loc.getStart()); -	ASSERT_EQ(15U, loc.getEnd()); -	ASSERT_EQ(OsdmStreamParser::State::END, reader.parse()); +	assertData(reader, "hello  world", 1, 15);  }  static void testEscapeSpecialCharacter(const std::string &c)  {  	CharReader charReader(std::string("\\") + c); -	OsdmStreamParser reader(charReader, logger); -	EXPECT_EQ(OsdmStreamParser::State::DATA, reader.parse()); +	OsmlStreamParser reader(charReader, logger); +	EXPECT_EQ(OsmlStreamParser::State::DATA, reader.parse());  	EXPECT_EQ(c, reader.getData().asString());  	SourceLocation loc = reader.getData().getLocation(); @@ -119,32 +229,30 @@ static void testEscapeSpecialCharacter(const std::string &c)  	EXPECT_EQ(1U + c.size(), loc.getEnd());  } -TEST(OsdmStreamParser, escapeSpecialCharacters) +TEST(OsmlStreamParser, escapeSpecialCharacters)  {  	testEscapeSpecialCharacter("\\");  	testEscapeSpecialCharacter("{");  	testEscapeSpecialCharacter("}"); -	testEscapeSpecialCharacter("<"); -	testEscapeSpecialCharacter(">");  } -TEST(OsdmStreamParser, simpleSingleLineComment) +TEST(OsmlStreamParser, simpleSingleLineComment)  {  	const char *testString = "% This is a single line comment";  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); -	ASSERT_EQ(OsdmStreamParser::State::END, reader.parse()); +	OsmlStreamParser reader(charReader, logger); +	ASSERT_EQ(OsmlStreamParser::State::END, reader.parse());  } -TEST(OsdmStreamParser, singleLineComment) +TEST(OsmlStreamParser, singleLineComment)  {  	const char *testString = "a% This is a single line comment\nb";  	//                        01234567890123456789012345678901 23  	//                        0         1         2         3  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	{ -		ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse()); +		ASSERT_EQ(OsmlStreamParser::State::DATA, reader.parse());  		ASSERT_EQ("a", reader.getData().asString());  		SourceLocation loc = reader.getData().getLocation();  		ASSERT_EQ(0U, loc.getStart()); @@ -152,25 +260,25 @@ TEST(OsdmStreamParser, singleLineComment)  	}  	{ -		ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse()); +		ASSERT_EQ(OsmlStreamParser::State::DATA, reader.parse());  		ASSERT_EQ("b", reader.getData().asString());  		SourceLocation loc = reader.getData().getLocation();  		ASSERT_EQ(33U, loc.getStart());  		ASSERT_EQ(34U, loc.getEnd());  	} -	ASSERT_EQ(OsdmStreamParser::State::END, reader.parse()); +	ASSERT_EQ(OsmlStreamParser::State::END, reader.parse());  } -TEST(OsdmStreamParser, multilineComment) +TEST(OsmlStreamParser, multilineComment)  {  	const char *testString = "a%{ This is a\n\n multiline line comment}%b";  	//                        0123456789012 3 456789012345678901234567890  	//                        0         1           2         3         4  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	{ -		ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse()); +		ASSERT_EQ(OsmlStreamParser::State::DATA, reader.parse());  		ASSERT_EQ("a", reader.getData().asString());  		SourceLocation loc = reader.getData().getLocation();  		ASSERT_EQ(0U, loc.getStart()); @@ -178,25 +286,25 @@ TEST(OsdmStreamParser, multilineComment)  	}  	{ -		ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse()); +		ASSERT_EQ(OsmlStreamParser::State::DATA, reader.parse());  		ASSERT_EQ("b", reader.getData().asString());  		SourceLocation loc = reader.getData().getLocation();  		ASSERT_EQ(40U, loc.getStart());  		ASSERT_EQ(41U, loc.getEnd());  	} -	ASSERT_EQ(OsdmStreamParser::State::END, reader.parse()); +	ASSERT_EQ(OsmlStreamParser::State::END, reader.parse());  } -TEST(OsdmStreamParser, nestedMultilineComment) +TEST(OsmlStreamParser, nestedMultilineComment)  {  	const char *testString = "a%{%{Another\n\n}%multiline line comment}%b";  	//                        0123456789012 3 456789012345678901234567890  	//                        0         1           2         3         4  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	{ -		ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse()); +		ASSERT_EQ(OsmlStreamParser::State::DATA, reader.parse());  		ASSERT_EQ("a", reader.getData().asString());  		SourceLocation loc = reader.getData().getLocation();  		ASSERT_EQ(0U, loc.getStart()); @@ -204,23 +312,23 @@ TEST(OsdmStreamParser, nestedMultilineComment)  	}  	{ -		ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse()); +		ASSERT_EQ(OsmlStreamParser::State::DATA, reader.parse());  		ASSERT_EQ("b", reader.getData().asString());  		SourceLocation loc = reader.getData().getLocation();  		ASSERT_EQ(40U, loc.getStart());  		ASSERT_EQ(41U, loc.getEnd());  	} -	ASSERT_EQ(OsdmStreamParser::State::END, reader.parse()); +	ASSERT_EQ(OsmlStreamParser::State::END, reader.parse());  } -TEST(OsdmStreamParser, simpleCommand) +TEST(OsmlStreamParser, simpleCommand)  {  	const char *testString = "\\test";  	//                        0 12345  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); -	ASSERT_EQ(OsdmStreamParser::State::COMMAND, reader.parse()); +	OsmlStreamParser reader(charReader, logger); +	ASSERT_EQ(OsmlStreamParser::State::COMMAND, reader.parse());  	Variant commandName = reader.getCommandName();  	ASSERT_EQ("test", commandName.asString()); @@ -230,16 +338,16 @@ TEST(OsdmStreamParser, simpleCommand)  	ASSERT_EQ(5U, loc.getEnd());  	ASSERT_EQ(0U, reader.getCommandArguments().asMap().size()); -	ASSERT_EQ(OsdmStreamParser::State::END, reader.parse()); +	ASSERT_EQ(OsmlStreamParser::State::END, reader.parse());  } -TEST(OsdmStreamParser, simpleCommandWithName) +TEST(OsmlStreamParser, simpleCommandWithName)  {  	const char *testString = "\\test#bla";  	//                        0 12345678  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); -	ASSERT_EQ(OsdmStreamParser::State::COMMAND, reader.parse()); +	OsmlStreamParser reader(charReader, logger); +	ASSERT_EQ(OsmlStreamParser::State::COMMAND, reader.parse());  	Variant commandName = reader.getCommandName();  	ASSERT_EQ("test", commandName.asString()); @@ -257,17 +365,17 @@ TEST(OsdmStreamParser, simpleCommandWithName)  	ASSERT_EQ(5U, loc.getStart());  	ASSERT_EQ(9U, loc.getEnd()); -	ASSERT_EQ(OsdmStreamParser::State::END, reader.parse()); +	ASSERT_EQ(OsmlStreamParser::State::END, reader.parse());  } -TEST(OsdmStreamParser, simpleCommandWithArguments) +TEST(OsmlStreamParser, simpleCommandWithArguments)  {  	const char *testString = "\\test[a=1,b=2,c=\"test\"]";  	//                        0 123456789012345 678901 2  	//                        0          1          2  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); -	ASSERT_EQ(OsdmStreamParser::State::COMMAND, reader.parse()); +	OsmlStreamParser reader(charReader, logger); +	ASSERT_EQ(OsmlStreamParser::State::COMMAND, reader.parse());  	Variant commandName = reader.getCommandName();  	ASSERT_EQ("test", commandName.asString()); @@ -297,17 +405,17 @@ TEST(OsdmStreamParser, simpleCommandWithArguments)  	ASSERT_EQ(16U, loc.getStart());  	ASSERT_EQ(22U, loc.getEnd()); -	ASSERT_EQ(OsdmStreamParser::State::END, reader.parse()); +	ASSERT_EQ(OsmlStreamParser::State::END, reader.parse());  } -TEST(OsdmStreamParser, simpleCommandWithArgumentsAndName) +TEST(OsmlStreamParser, simpleCommandWithArgumentsAndName)  {  	const char *testString = "\\test#bla[a=1,b=2,c=\"test\"]";  	//                        0 1234567890123456789 01234 56  	//                        0          1          2  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); -	ASSERT_EQ(OsdmStreamParser::State::COMMAND, reader.parse()); +	OsmlStreamParser reader(charReader, logger); +	ASSERT_EQ(OsmlStreamParser::State::COMMAND, reader.parse());  	Variant commandName = reader.getCommandName();  	ASSERT_EQ("test", commandName.asString()); @@ -343,126 +451,46 @@ TEST(OsdmStreamParser, simpleCommandWithArgumentsAndName)  	ASSERT_EQ(5U, loc.getStart());  	ASSERT_EQ(9U, loc.getEnd()); -	ASSERT_EQ(OsdmStreamParser::State::END, reader.parse()); +	ASSERT_EQ(OsmlStreamParser::State::END, reader.parse());  } -static void assertCommand(OsdmStreamParser &reader, const std::string &name, -                          SourceOffset start = InvalidSourceOffset, -                          SourceOffset end = InvalidSourceOffset) -{ -	ASSERT_EQ(OsdmStreamParser::State::COMMAND, reader.parse()); -	EXPECT_EQ(name, reader.getCommandName().asString()); -	if (start != InvalidSourceOffset) { -		EXPECT_EQ(start, reader.getCommandName().getLocation().getStart()); -		EXPECT_EQ(start, reader.getLocation().getStart()); -	} -	if (end != InvalidSourceOffset) { -		EXPECT_EQ(end, reader.getCommandName().getLocation().getEnd()); -		EXPECT_EQ(end, reader.getLocation().getEnd()); -	} -} - -static void assertCommand(OsdmStreamParser &reader, const std::string &name, -                          const Variant::mapType &args, -                          SourceOffset start = InvalidSourceOffset, -                          SourceOffset end = InvalidSourceOffset) -{ -	assertCommand(reader, name, start, end); -	EXPECT_EQ(args, reader.getCommandArguments()); -} - -static void assertData(OsdmStreamParser &reader, const std::string &data, -                       SourceOffset start = InvalidSourceOffset, -                       SourceOffset end = InvalidSourceOffset) -{ -	ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse()); -	EXPECT_EQ(data, reader.getData().asString()); -	if (start != InvalidSourceOffset) { -		EXPECT_EQ(start, reader.getData().getLocation().getStart()); -		EXPECT_EQ(start, reader.getLocation().getStart()); -	} -	if (end != InvalidSourceOffset) { -		EXPECT_EQ(end, reader.getData().getLocation().getEnd()); -		EXPECT_EQ(end, reader.getLocation().getEnd()); -	} -} - -static void assertFieldStart(OsdmStreamParser &reader, -                             SourceOffset start = InvalidSourceOffset, -                             SourceOffset end = InvalidSourceOffset) -{ -	ASSERT_EQ(OsdmStreamParser::State::FIELD_START, reader.parse()); -	if (start != InvalidSourceOffset) { -		EXPECT_EQ(start, reader.getLocation().getStart()); -	} -	if (end != InvalidSourceOffset) { -		EXPECT_EQ(end, reader.getLocation().getEnd()); -	} -} - -static void assertFieldEnd(OsdmStreamParser &reader, -                           SourceOffset start = InvalidSourceOffset, -                           SourceOffset end = InvalidSourceOffset) -{ -	ASSERT_EQ(OsdmStreamParser::State::FIELD_END, reader.parse()); -	if (start != InvalidSourceOffset) { -		EXPECT_EQ(start, reader.getLocation().getStart()); -	} -	if (end != InvalidSourceOffset) { -		EXPECT_EQ(end, reader.getLocation().getEnd()); -	} -} - -static void assertEnd(OsdmStreamParser &reader, -                      SourceOffset start = InvalidSourceOffset, -                      SourceOffset end = InvalidSourceOffset) -{ -	ASSERT_EQ(OsdmStreamParser::State::END, reader.parse()); -	if (start != InvalidSourceOffset) { -		EXPECT_EQ(start, reader.getLocation().getStart()); -	} -	if (end != InvalidSourceOffset) { -		EXPECT_EQ(end, reader.getLocation().getEnd()); -	} -} - -TEST(OsdmStreamParser, fields) +TEST(OsmlStreamParser, fields)  {  	const char *testString = "\\test{a}{b}{c}";  	//                         01234567890123  	//                         0         1  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	assertCommand(reader, "test", 0, 5); -	assertFieldStart(reader, 5, 6); +	assertFieldStart(reader, false, 5, 6);  	assertData(reader, "a", 6, 7);  	assertFieldEnd(reader, 7, 8); -	assertFieldStart(reader, 8, 9); +	assertFieldStart(reader, false, 8, 9);  	assertData(reader, "b", 9, 10);  	assertFieldEnd(reader, 10, 11); -	assertFieldStart(reader, 11, 12); +	assertFieldStart(reader, false, 11, 12);  	assertData(reader, "c", 12, 13);  	assertFieldEnd(reader, 13, 14);  	assertEnd(reader, 14, 14);  } -TEST(OsdmStreamParser, dataOutsideField) +TEST(OsmlStreamParser, dataOutsideField)  {  	const char *testString = "\\test{a}{b} c";  	//                         0123456789012  	//                         0         1  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	assertCommand(reader, "test", 0, 5); -	assertFieldStart(reader, 5, 6); +	assertFieldStart(reader, false, 5, 6);  	assertData(reader, "a", 6, 7);  	assertFieldEnd(reader, 7, 8); -	assertFieldStart(reader, 8, 9); +	assertFieldStart(reader, false, 8, 9);  	assertData(reader, "b", 9, 10);  	assertFieldEnd(reader, 10, 11); @@ -470,24 +498,24 @@ TEST(OsdmStreamParser, dataOutsideField)  	assertEnd(reader, 13, 13);  } -TEST(OsdmStreamParser, nestedCommand) +TEST(OsmlStreamParser, nestedCommand)  {  	const char *testString = "\\test{a}{\\test2{b} c} d";  	//                         012345678 90123456789012  	//                         0          1         2  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	assertCommand(reader, "test", 0, 5); -	assertFieldStart(reader, 5, 6); +	assertFieldStart(reader, false, 5, 6);  	assertData(reader, "a", 6, 7);  	assertFieldEnd(reader, 7, 8); -	assertFieldStart(reader, 8, 9); +	assertFieldStart(reader, false, 8, 9);  	{  		assertCommand(reader, "test2", 9, 15); -		assertFieldStart(reader, 15, 16); +		assertFieldStart(reader, false, 15, 16);  		assertData(reader, "b", 16, 17);  		assertFieldEnd(reader, 17, 18);  	} @@ -497,19 +525,19 @@ TEST(OsdmStreamParser, nestedCommand)  	assertEnd(reader, 23, 23);  } -TEST(OsdmStreamParser, nestedCommandImmediateEnd) +TEST(OsmlStreamParser, nestedCommandImmediateEnd)  {  	const char *testString = "\\test{\\test2{b}} d";  	//                         012345 678901234567  	//                         0          1  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	assertCommand(reader, "test", 0, 5); -	assertFieldStart(reader, 5, 6); +	assertFieldStart(reader, false, 5, 6);  	{  		assertCommand(reader, "test2", 6, 12); -		assertFieldStart(reader, 12, 13); +		assertFieldStart(reader, false, 12, 13);  		assertData(reader, "b", 13, 14);  		assertFieldEnd(reader, 14, 15);  	} @@ -518,27 +546,27 @@ TEST(OsdmStreamParser, nestedCommandImmediateEnd)  	assertEnd(reader, 18, 18);  } -TEST(OsdmStreamParser, nestedCommandNoData) +TEST(OsmlStreamParser, nestedCommandNoData)  {  	const char *testString = "\\test{\\test2}";  	//                         012345 6789012  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	assertCommand(reader, "test", 0, 5); -	assertFieldStart(reader, 5, 6); +	assertFieldStart(reader, false, 5, 6);  	assertCommand(reader, "test2", 6, 12);  	assertFieldEnd(reader, 12, 13);  	assertEnd(reader, 13, 13);  } -TEST(OsdmStreamParser, multipleCommands) +TEST(OsmlStreamParser, multipleCommands)  {  	const char *testString = "\\a \\b \\c \\d";  	//                         012 345 678 90  	//                         0            1  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	assertCommand(reader, "a", 0, 2);  	assertCommand(reader, "b", 3, 5); @@ -547,33 +575,33 @@ TEST(OsdmStreamParser, multipleCommands)  	assertEnd(reader, 11, 11);  } -TEST(OsdmStreamParser, fieldsWithSpaces) +TEST(OsmlStreamParser, fieldsWithSpaces)  {  	const char *testString = "\\a {\\b \\c}   \n\n {\\d}";  	//                         0123 456 789012 3 456 789  	//                         0           1  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	assertCommand(reader, "a", 0, 2); -	assertFieldStart(reader, 3, 4); +	assertFieldStart(reader, false, 3, 4);  	assertCommand(reader, "b", 4, 6);  	assertCommand(reader, "c", 7, 9);  	assertFieldEnd(reader, 9, 10); -	assertFieldStart(reader, 16, 17); +	assertFieldStart(reader, false, 16, 17);  	assertCommand(reader, "d", 17, 19);  	assertFieldEnd(reader, 19, 20);  	assertEnd(reader, 20, 20);  } -TEST(OsdmStreamParser, errorNoFieldToStart) +TEST(OsmlStreamParser, errorNoFieldToStart)  {  	const char *testString = "\\a b {";  	//                         012345  	//                         0  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	logger.reset();  	assertCommand(reader, "a", 0, 2); @@ -583,14 +611,14 @@ TEST(OsdmStreamParser, errorNoFieldToStart)  	ASSERT_TRUE(logger.hasError());  } -TEST(OsdmStreamParser, errorNoFieldToEnd) +TEST(OsmlStreamParser, errorNoFieldToEnd)  {  	const char *testString = "\\a b }";  	//                         012345  	//                         0  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	logger.reset();  	assertCommand(reader, "a", 0, 2); @@ -600,20 +628,20 @@ TEST(OsdmStreamParser, errorNoFieldToEnd)  	ASSERT_TRUE(logger.hasError());  } -TEST(OsdmStreamParser, errorNoFieldEndNested) +TEST(OsmlStreamParser, errorNoFieldEndNested)  {  	const char *testString = "\\test{\\test2{}}}";  	//                         012345 6789012345  	//                         0          1  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	logger.reset();  	assertCommand(reader, "test", 0, 5); -	assertFieldStart(reader, 5, 6); +	assertFieldStart(reader, false, 5, 6);  	assertCommand(reader, "test2", 6, 12); -	assertFieldStart(reader, 12, 13); +	assertFieldStart(reader, false, 12, 13);  	assertFieldEnd(reader, 13, 14);  	assertFieldEnd(reader, 14, 15);  	ASSERT_FALSE(logger.hasError()); @@ -621,20 +649,20 @@ TEST(OsdmStreamParser, errorNoFieldEndNested)  	ASSERT_TRUE(logger.hasError());  } -TEST(OsdmStreamParser, errorNoFieldEndNestedData) +TEST(OsmlStreamParser, errorNoFieldEndNestedData)  {  	const char *testString = "\\test{\\test2{}}a}";  	//                         012345 67890123456  	//                         0          1  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	logger.reset();  	assertCommand(reader, "test", 0, 5); -	assertFieldStart(reader, 5, 6); +	assertFieldStart(reader, false, 5, 6);  	assertCommand(reader, "test2", 6, 12); -	assertFieldStart(reader, 12, 13); +	assertFieldStart(reader, false, 12, 13);  	assertFieldEnd(reader, 13, 14);  	assertFieldEnd(reader, 14, 15);  	assertData(reader, "a", 15, 16); @@ -643,53 +671,53 @@ TEST(OsdmStreamParser, errorNoFieldEndNestedData)  	ASSERT_TRUE(logger.hasError());  } -TEST(OsdmStreamParser, beginEnd) +TEST(OsmlStreamParser, beginEnd)  {  	const char *testString = "\\begin{book}\\end{book}";  	//                         012345678901 2345678901  	//                         0         1          2  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	assertCommand(reader, "book", 7, 11); -	assertFieldStart(reader, 12, 13); +	assertFieldStart(reader, true, 12, 13);  	assertFieldEnd(reader, 17, 21);  	assertEnd(reader, 22, 22);  } -TEST(OsdmStreamParser, beginEndWithName) +TEST(OsmlStreamParser, beginEndWithName)  {  	const char *testString = "\\begin{book#a}\\end{book}";  	//                         01234567890123 4567890123  	//                         0         1          2  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	assertCommand(reader, "book", {{"name", "a"}}, 7, 11); -	assertFieldStart(reader, 14, 15); +	assertFieldStart(reader, true, 14, 15);  	assertFieldEnd(reader, 19, 23);  	assertEnd(reader, 24, 24);  } -TEST(OsdmStreamParser, beginEndWithNameAndArgs) +TEST(OsmlStreamParser, beginEndWithNameAndArgs)  {  	const char *testString = "\\begin{book#a}[a=1,b=2,c=\"test\"]\\end{book}";  	//                         0123456789012345678901234 56789 01 2345678901  	//                         0         1         2           3          4  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	assertCommand(reader, "book",  	              {{"name", "a"}, {"a", 1}, {"b", 2}, {"c", "test"}}, 7, 11); -	assertFieldStart(reader, 32, 33); +	assertFieldStart(reader, true, 32, 33);  	assertFieldEnd(reader, 37, 41);  	assertEnd(reader, 42, 42);  } -TEST(OsdmStreamParser, beginEndWithNameAndArgsMultipleFields) +TEST(OsmlStreamParser, beginEndWithNameAndArgsMultipleFields)  {  	const char *testString =  	    "\\begin{book#a}[a=1,b=2,c=\"test\"]{a \\test}{b \\test{}}\\end{book}"; @@ -697,67 +725,100 @@ TEST(OsdmStreamParser, beginEndWithNameAndArgsMultipleFields)  	//    0         1         2           3          4          5          6  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	assertCommand(reader, "book",  	              {{"name", "a"}, {"a", 1}, {"b", 2}, {"c", "test"}}, 7, 11); -	assertFieldStart(reader, 32, 33); +	assertFieldStart(reader, false, 32, 33);  	assertData(reader, "a", 33, 34);  	assertCommand(reader, "test", Variant::mapType{}, 35, 40);  	assertFieldEnd(reader, 40, 41); -	assertFieldStart(reader, 41, 42); +	assertFieldStart(reader, false, 41, 42);  	assertData(reader, "b", 42, 43);  	assertCommand(reader, "test", Variant::mapType{}, 44, 49); -	assertFieldStart(reader, 49, 50); +	assertFieldStart(reader, false, 49, 50);  	assertFieldEnd(reader, 50, 51);  	assertFieldEnd(reader, 51, 52); -	assertFieldStart(reader, 52, 53); +	assertFieldStart(reader, true, 52, 53);  	assertFieldEnd(reader, 57, 61);  	assertEnd(reader, 62, 62);  } -TEST(OsdmStreamParser, beginEndWithData) +TEST(OsmlStreamParser, beginEndWithData)  {  	const char *testString = "\\begin{book}a\\end{book}";  	//                         0123456789012 3456789012  	//                         0         1          2  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	assertCommand(reader, "book", 7, 11); -	assertFieldStart(reader, 12, 13); +	assertFieldStart(reader, true, 12, 13);  	assertData(reader, "a", 12, 13);  	assertFieldEnd(reader, 18, 22);  	assertEnd(reader, 23, 23);  } -TEST(OsdmStreamParser, beginEndWithCommand) +TEST(OsmlStreamParser, beginEndNested) +{ +	const char *testString = +	    "\\begin{a}{b} c \\begin{d}{e}{f} \\g{h} \\end{d}\\end{a}"; +	//    012345678901234 5678901234567890 123456 7890123 4567890 +	//    0         1          2         3           4          5 +	CharReader charReader(testString); + +	OsmlStreamParser reader(charReader, logger); + +	assertCommand(reader, "a", 7, 8); +	assertFieldStart(reader, false, 9, 10); +	assertData(reader, "b", 10, 11); +	assertFieldEnd(reader, 11, 12); +	assertFieldStart(reader, true, 13, 14); +	assertData(reader, "c", 13, 14); +	assertCommand(reader, "d", 22, 23); +	assertFieldStart(reader, false, 24, 25); +	assertData(reader, "e", 25, 26); +	assertFieldEnd(reader, 26, 27); +	assertFieldStart(reader, false, 27, 28); +	assertData(reader, "f", 28, 29); +	assertFieldEnd(reader, 29, 30); +	assertFieldStart(reader, true, 31, 32); +	assertCommand(reader, "g", 31, 33); +	assertFieldStart(reader, false, 33, 34); +	assertData(reader, "h", 34, 35); +	assertFieldEnd(reader, 35, 36); +	assertFieldEnd(reader, 42, 43); +	assertFieldEnd(reader, 49, 50); +	assertEnd(reader, 51, 51); +} + +TEST(OsmlStreamParser, beginEndWithCommand)  {  	const char *testString = "\\begin{book}\\a{test}\\end{book}";  	//                         012345678901 23456789 0123456789  	//                         0         1           2  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	assertCommand(reader, "book", 7, 11); -	assertFieldStart(reader, 12, 13); +	assertFieldStart(reader, true, 12, 13);  	assertCommand(reader, "a", 12, 14); -	assertFieldStart(reader, 14, 15); +	assertFieldStart(reader, false, 14, 15);  	assertData(reader, "test", 15, 19);  	assertFieldEnd(reader, 19, 20);  	assertFieldEnd(reader, 25, 29);  	assertEnd(reader, 30, 30);  } -TEST(OsdmStreamParser, errorBeginNoBraceOpen) +TEST(OsmlStreamParser, errorBeginNoBraceOpen)  {  	const char *testString = "\\begin a";  	//                         01234567  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	logger.reset();  	ASSERT_FALSE(logger.hasError()); @@ -765,12 +826,12 @@ TEST(OsdmStreamParser, errorBeginNoBraceOpen)  	ASSERT_TRUE(logger.hasError());  } -TEST(OsdmStreamParser, errorBeginNoIdentifier) +TEST(OsmlStreamParser, errorBeginNoIdentifier)  {  	const char *testString = "\\begin{!";  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	logger.reset();  	ASSERT_FALSE(logger.hasError()); @@ -778,12 +839,12 @@ TEST(OsdmStreamParser, errorBeginNoIdentifier)  	ASSERT_TRUE(logger.hasError());  } -TEST(OsdmStreamParser, errorBeginNoBraceClose) +TEST(OsmlStreamParser, errorBeginNoBraceClose)  {  	const char *testString = "\\begin{a";  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	logger.reset();  	ASSERT_FALSE(logger.hasError()); @@ -791,12 +852,12 @@ TEST(OsdmStreamParser, errorBeginNoBraceClose)  	ASSERT_TRUE(logger.hasError());  } -TEST(OsdmStreamParser, errorBeginNoName) +TEST(OsmlStreamParser, errorBeginNoName)  {  	const char *testString = "\\begin{a#}";  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	logger.reset();  	ASSERT_FALSE(logger.hasError()); @@ -808,13 +869,13 @@ TEST(OsdmStreamParser, errorBeginNoName)  	ASSERT_TRUE(logger.hasError());  } -TEST(OsdmStreamParser, errorEndNoBraceOpen) +TEST(OsmlStreamParser, errorEndNoBraceOpen)  {  	const char *testString = "\\end a";  	//                         012345  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	logger.reset();  	ASSERT_FALSE(logger.hasError()); @@ -822,12 +883,12 @@ TEST(OsdmStreamParser, errorEndNoBraceOpen)  	ASSERT_TRUE(logger.hasError());  } -TEST(OsdmStreamParser, errorEndNoIdentifier) +TEST(OsmlStreamParser, errorEndNoIdentifier)  {  	const char *testString = "\\end{!";  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	logger.reset();  	ASSERT_FALSE(logger.hasError()); @@ -835,12 +896,12 @@ TEST(OsdmStreamParser, errorEndNoIdentifier)  	ASSERT_TRUE(logger.hasError());  } -TEST(OsdmStreamParser, errorEndNoBraceClose) +TEST(OsmlStreamParser, errorEndNoBraceClose)  {  	const char *testString = "\\end{a";  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	logger.reset();  	ASSERT_FALSE(logger.hasError()); @@ -848,12 +909,12 @@ TEST(OsdmStreamParser, errorEndNoBraceClose)  	ASSERT_TRUE(logger.hasError());  } -TEST(OsdmStreamParser, errorEndNoBegin) +TEST(OsmlStreamParser, errorEndNoBegin)  {  	const char *testString = "\\end{a}";  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	logger.reset();  	ASSERT_FALSE(logger.hasError()); @@ -861,91 +922,91 @@ TEST(OsdmStreamParser, errorEndNoBegin)  	ASSERT_TRUE(logger.hasError());  } -TEST(OsdmStreamParser, errorBeginEndMismatch) +TEST(OsmlStreamParser, errorBeginEndMismatch)  {  	const char *testString = "\\begin{a} \\begin{b} test \\end{a}";  	//                         0123456789 012345678901234 5678901  	//                         0          1         2          3  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	logger.reset();  	assertCommand(reader, "a", 7, 8); -	assertFieldStart(reader, 10, 11); +	assertFieldStart(reader, true, 10, 11);  	assertCommand(reader, "b", 17, 18); -	assertFieldStart(reader, 20, 24); +	assertFieldStart(reader, true, 20, 24);  	assertData(reader, "test", 20, 24);  	ASSERT_FALSE(logger.hasError());  	ASSERT_THROW(reader.parse(), LoggableException);  	ASSERT_TRUE(logger.hasError());  } -TEST(OsdmStreamParser, commandWithNSSep) +TEST(OsmlStreamParser, commandWithNSSep)  {  	const char *testString = "\\test1:test2";  	//                         012345678901  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	assertCommand(reader, "test1:test2", 0, 12);  	assertEnd(reader, 12, 12);  } -TEST(OsdmStreamParser, beginEndWithNSSep) +TEST(OsmlStreamParser, beginEndWithNSSep)  {  	const char *testString = "\\begin{test1:test2}\\end{test1:test2}";  	//                         0123456789012345678 90123456789012345  	//                         0         1          2         3  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	assertCommand(reader, "test1:test2", 7, 18); -	assertFieldStart(reader, 19, 20); +	assertFieldStart(reader, true, 19, 20);  	assertFieldEnd(reader, 24, 35);  	assertEnd(reader, 36, 36);  } -TEST(OsdmStreamParser, errorBeginNSSep) +TEST(OsmlStreamParser, errorBeginNSSep)  {  	const char *testString = "\\begin:test{blub}\\end{blub}";  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	logger.reset();  	ASSERT_FALSE(logger.hasError());  	assertCommand(reader, "blub");  	ASSERT_TRUE(logger.hasError()); -	assertFieldStart(reader); +	assertFieldStart(reader, true);  	assertFieldEnd(reader);  	assertEnd(reader);  } -TEST(OsdmStreamParser, errorEndNSSep) +TEST(OsmlStreamParser, errorEndNSSep)  {  	const char *testString = "\\begin{blub}\\end:test{blub}";  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	logger.reset();  	assertCommand(reader, "blub"); -	assertFieldStart(reader); +	assertFieldStart(reader, true);  	ASSERT_FALSE(logger.hasError());  	assertFieldEnd(reader);  	ASSERT_TRUE(logger.hasError());  	assertEnd(reader);  } -TEST(OsdmStreamParser, errorEmptyNs) +TEST(OsmlStreamParser, errorEmptyNs)  {  	const char *testString = "\\test:";  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	logger.reset();  	ASSERT_FALSE(logger.hasError()); @@ -955,12 +1016,12 @@ TEST(OsdmStreamParser, errorEmptyNs)  	assertEnd(reader);  } -TEST(OsdmStreamParser, errorRepeatedNs) +TEST(OsmlStreamParser, errorRepeatedNs)  {  	const char *testString = "\\test::";  	CharReader charReader(testString); -	OsdmStreamParser reader(charReader, logger); +	OsmlStreamParser reader(charReader, logger);  	logger.reset();  	ASSERT_FALSE(logger.hasError()); @@ -969,5 +1030,232 @@ TEST(OsdmStreamParser, errorRepeatedNs)  	assertData(reader, "::");  	assertEnd(reader);  } + +TEST(OsmlStreamParser, explicitDefaultField) +{ +	const char *testString = "\\a{!b}c"; +	//                         01234567 +	CharReader charReader(testString); + +	OsmlStreamParser reader(charReader, logger); + +	assertCommand(reader, "a", 0, 2); +	assertFieldStart(reader, true, 2, 4); +	assertData(reader, "b", 4, 5); +	assertFieldEnd(reader, 5, 6); +	assertData(reader, "c", 6, 7); +	assertEnd(reader, 7, 7); +} + +TEST(OsmlStreamParser, explicitDefaultFieldWithCommand) +{ +	const char *testString = "\\a{!\\b}c"; +	//                         0123 4567 +	CharReader charReader(testString); + +	OsmlStreamParser reader(charReader, logger); + +	assertCommand(reader, "a", 0, 2); +	assertFieldStart(reader, true, 2, 4); +	assertCommand(reader, "b", 4, 6); +	assertFieldEnd(reader, 6, 7); +	assertData(reader, "c", 7, 8); +	assertEnd(reader, 8, 8); +} + +TEST(OsmlStreamParser, errorFieldAfterExplicitDefaultField) +{ +	const char *testString = "\\a{!\\b}{c}"; +	//                         0123 456789 +	CharReader charReader(testString); + +	OsmlStreamParser reader(charReader, logger); + +	logger.reset(); +	assertCommand(reader, "a", 0, 2); +	assertFieldStart(reader, true, 2, 4); +	assertCommand(reader, "b", 4, 6); +	assertFieldEnd(reader, 6, 7); +	ASSERT_FALSE(logger.hasError()); +	assertData(reader, "c", 8, 9); +	ASSERT_TRUE(logger.hasError()); +	assertEnd(reader, 10, 10); +} + +TEST(OsmlStreamParser, annotationStart) +{ +	const char *testString = "<\\a"; +	//                        0 12 + +	CharReader charReader(testString); + +	OsmlStreamParser reader(charReader, logger); + +	assertAnnotationStart(reader, "a", Variant::mapType{}, 0, 3); +	assertEnd(reader, 3, 3); +} + +TEST(OsmlStreamParser, annotationStartWithName) +{ +	const char *testString = "<\\annotationWithName#aName"; +	//                        0 1234567890123456789012345 +	//                        0          1         2 + +	CharReader charReader(testString); + +	OsmlStreamParser reader(charReader, logger); + +	assertAnnotationStart(reader, "annotationWithName", +	                      Variant::mapType{{"name", "aName"}}, 0, 20); +	assertEnd(reader, 26, 26); +} + +TEST(OsmlStreamParser, annotationStartWithArguments) +{ +	const char *testString = "<\\annotationWithName#aName[a=1,b=2]"; +	//                        0 1234567890123456789012345678901234 +	//                        0          1         2         3 + +	CharReader charReader(testString); + +	OsmlStreamParser reader(charReader, logger); + +	assertAnnotationStart( +	    reader, "annotationWithName", +	    Variant::mapType{{"name", "aName"}, {"a", 1}, {"b", 2}}, 0, 20); +	assertEnd(reader, 35, 35); +} + +TEST(OsmlStreamParser, simpleAnnotationStartBeginEnd) +{ +	const char *testString = "<\\begin{ab#name}[a=1,b=2] a \\end{ab}\\>"; +	//                        0 123456789012345678901234567 89012345 67 +	//                        0          1         2          3 + +	CharReader charReader(testString); + +	OsmlStreamParser reader(charReader, logger); + +	assertAnnotationStart( +	    reader, "ab", Variant::mapType{{"name", "name"}, {"a", 1}, {"b", 2}}, 8, +	    10); +	assertFieldStart(reader, true, 26, 27); +	assertData(reader, "a", 26, 27); +	assertFieldEnd(reader, 33, 35); +	assertAnnotationEnd(reader, "", "", 36, 38); +	assertEnd(reader, 38, 38); +} + +TEST(OsmlStreamParser, annotationEnd) +{ +	const char *testString = "\\a>"; +	//                         012 + +	CharReader charReader(testString); + +	OsmlStreamParser reader(charReader, logger); + +	assertAnnotationEnd(reader, "a", "", 0, 2); +	assertEnd(reader, 3, 3); +} + +TEST(OsmlStreamParser, annotationEndWithName) +{ +	const char *testString = "\\a#name>"; +	//                         01234567 + +	CharReader charReader(testString); + +	OsmlStreamParser reader(charReader, logger); + +	assertAnnotationEnd(reader, "a", "name", 0, 2); +	assertEnd(reader, 8, 8); +} + +TEST(OsmlStreamParser, annotationEndWithNameAsArgs) +{ +	const char *testString = "\\a[name=name]>"; +	//                         01234567890123 + +	CharReader charReader(testString); + +	OsmlStreamParser reader(charReader, logger); + +	assertAnnotationEnd(reader, "a", "name", 0, 2); +	assertEnd(reader, 14, 14); +} + +TEST(OsmlStreamParser, errorAnnotationEndWithArguments) +{ +	const char *testString = "\\a[foo=bar]>"; +	//                         012345678901 +	//                         0         1 + +	CharReader charReader(testString); + +	OsmlStreamParser reader(charReader, logger); + +	logger.reset(); +	ASSERT_FALSE(logger.hasError()); +	assertCommand(reader, "a", Variant::mapType{{"foo", "bar"}}, 0, 2); +	ASSERT_TRUE(logger.hasError()); +	assertData(reader, ">", 11, 12); +	assertEnd(reader, 12, 12); +} + +TEST(OsmlStreamParser, closingAnnotation) +{ +	const char *testString = "<\\a>"; +	//                        0 123 + +	CharReader charReader(testString); + +	OsmlStreamParser reader(charReader, logger); + +	assertAnnotationStart(reader, "a", Variant::mapType{}, 0, 3); +	assertData(reader, ">", 3, 4); +	assertEnd(reader, 4, 4); +} + +TEST(OsmlStreamParser, annotationWithFields) +{ +	const char *testString = "a <\\b{c}{d}{!e} f \\> g"; +	//                        012 345678901234567 8901 +	//                        0          1          2 + +	CharReader charReader(testString); + +	OsmlStreamParser reader(charReader, logger); + +	assertData(reader, "a", 0, 1); +	assertAnnotationStart(reader, "b", Variant::mapType{}, 2, 5); +	assertFieldStart(reader, false, 5, 6); +	assertData(reader, "c", 6, 7); +	assertFieldEnd(reader, 7, 8); +	assertFieldStart(reader, false, 8, 9); +	assertData(reader, "d", 9, 10); +	assertFieldEnd(reader, 10, 11); +	assertFieldStart(reader, true, 11, 13); +	assertData(reader, "e", 13, 14); +	assertFieldEnd(reader, 14, 15); +	assertData(reader, "f", 16, 17); +	assertAnnotationEnd(reader, "", "", 18, 20); +	assertData(reader, "g", 21, 22); +	assertEnd(reader, 22, 22); +} + +TEST(OsmlStreamParser, annotationStartEscape) +{ +	const char *testString = "<\\%test"; +	//                        0 123456 +	//                        0 + +	CharReader charReader(testString); + +	OsmlStreamParser reader(charReader, logger); + +	assertData(reader, "<%test", 0, 7); +	assertEnd(reader, 7, 7); +}  } diff --git a/test/formats/osxml/OsxmlEventParserTest.cpp b/test/formats/osxml/OsxmlEventParserTest.cpp new file mode 100644 index 0000000..3293370 --- /dev/null +++ b/test/formats/osxml/OsxmlEventParserTest.cpp @@ -0,0 +1,217 @@ +/* +    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 <gtest/gtest.h> + +#include <core/frontend/TerminalLogger.hpp> +#include <core/common/CharReader.hpp> +#include <core/common/Variant.hpp> + +#include <formats/osxml/OsxmlEventParser.hpp> + +namespace ousia { + +static TerminalLogger logger(std::cerr, true); +// static ConcreteLogger logger; + +namespace { +enum class OsxmlEvent { +	COMMAND, +	ANNOTATION_START, +	ANNOTATION_END, +	FIELD_END, +	DATA +}; + +class TestOsxmlEventListener : public OsxmlEvents { +public: +	std::vector<std::pair<OsxmlEvent, Variant>> events; + +	void command(const Variant &name, const Variant::mapType &args) override +	{ +		events.emplace_back(OsxmlEvent::COMMAND, +		                    Variant::arrayType{name, args}); +	} + +	void annotationStart(const Variant &className, +	                     const Variant::mapType &args) override +	{ +		events.emplace_back(OsxmlEvent::ANNOTATION_START, +		                    Variant::arrayType{className, args}); +	} + +	void annotationEnd(const Variant &className, +	                   const Variant &elementName) override +	{ +		events.emplace_back(OsxmlEvent::ANNOTATION_END, +		                    Variant::arrayType{className, elementName}); +	} + +	void fieldEnd() override +	{ +		events.emplace_back(OsxmlEvent::FIELD_END, Variant::arrayType{}); +	} + +	void data(const Variant &data) override +	{ +		events.emplace_back(OsxmlEvent::DATA, Variant::arrayType{data}); +	} +}; + +static std::vector<std::pair<OsxmlEvent, Variant>> parseXml( +    const char *testString, +    WhitespaceMode whitespaceMode = WhitespaceMode::TRIM) +{ +	TestOsxmlEventListener listener; +	CharReader reader(testString); +	OsxmlEventParser parser(reader, listener, logger); +	parser.setWhitespaceMode(whitespaceMode); +	parser.parse(); +	return listener.events; +} +} + +TEST(OsxmlEventParser, simpleCommandWithArgs) +{ +	const char *testString = "<a name=\"test\" a=\"1\" b=\"2\" c=\"blub\"/>"; +	//                        01234567 89012 3456 78 9012 34 5678 90123 456 +	//                        0          1            2            3 + +	std::vector<std::pair<OsxmlEvent, Variant>> expectedEvents{ +	    {OsxmlEvent::COMMAND, +	     Variant::arrayType{ +	         "a", Variant::mapType{ +	                  {"name", "test"}, {"a", 1}, {"b", 2}, {"c", "blub"}}}}, +	    {OsxmlEvent::FIELD_END, Variant::arrayType{}}}; + +	auto events = parseXml(testString); +	ASSERT_EQ(expectedEvents, events); + +	// Check the locations (I'll do this one time and then just assume it works) +	ASSERT_EQ(1U, events[0].second.asArray()[0].getLocation().getStart()); +	ASSERT_EQ(2U, events[0].second.asArray()[0].getLocation().getEnd()); +	ASSERT_EQ( +	    9U, +	    events[0].second.asArray()[1].asMap()["name"].getLocation().getStart()); +	ASSERT_EQ( +	    13U, +	    events[0].second.asArray()[1].asMap()["name"].getLocation().getEnd()); +	ASSERT_EQ( +	    18U, +	    events[0].second.asArray()[1].asMap()["a"].getLocation().getStart()); +	ASSERT_EQ( +	    19U, events[0].second.asArray()[1].asMap()["a"].getLocation().getEnd()); +	ASSERT_EQ( +	    24U, +	    events[0].second.asArray()[1].asMap()["b"].getLocation().getStart()); +	ASSERT_EQ( +	    25U, events[0].second.asArray()[1].asMap()["b"].getLocation().getEnd()); +	ASSERT_EQ( +	    30U, +	    events[0].second.asArray()[1].asMap()["c"].getLocation().getStart()); +	ASSERT_EQ( +	    34U, events[0].second.asArray()[1].asMap()["c"].getLocation().getEnd()); +} + +TEST(OsxmlEventParser, magicTopLevelTag) +{ +	const char *testString = "<ousia><a/><b/></ousia>"; + +	std::vector<std::pair<OsxmlEvent, Variant>> expectedEvents{ +	    {OsxmlEvent::COMMAND, Variant::arrayType{{"a", Variant::mapType{}}}}, +	    {OsxmlEvent::FIELD_END, Variant::arrayType{}}, +	    {OsxmlEvent::COMMAND, Variant::arrayType{{"b", Variant::mapType{}}}}, +	    {OsxmlEvent::FIELD_END, Variant::arrayType{}}}; + +	auto events = parseXml(testString); +	ASSERT_EQ(expectedEvents, events); +} + +TEST(OsxmlEventParser, magicTopLevelTagInside) +{ +	const char *testString = "<a><ousia/></a>"; + +	std::vector<std::pair<OsxmlEvent, Variant>> expectedEvents{ +	    {OsxmlEvent::COMMAND, Variant::arrayType{{"a", Variant::mapType{}}}}, +	    {OsxmlEvent::COMMAND, +	     Variant::arrayType{{"ousia", Variant::mapType{}}}}, +	    {OsxmlEvent::FIELD_END, Variant::arrayType{}}, +	    {OsxmlEvent::FIELD_END, Variant::arrayType{}}}; + +	auto events = parseXml(testString); +	ASSERT_EQ(expectedEvents, events); +} + +TEST(OsxmlEventParser, commandWithDataPreserveWhitespace) +{ +	const char *testString = "<a>  hello  \n world </a>"; +	//                        012345678901 234567890123 +	//                        0         1          2 + +	std::vector<std::pair<OsxmlEvent, Variant>> expectedEvents{ +	    {OsxmlEvent::COMMAND, Variant::arrayType{"a", Variant::mapType{}}}, +	    {OsxmlEvent::DATA, Variant::arrayType{"  hello  \n world "}}, +	    {OsxmlEvent::FIELD_END, Variant::arrayType{}}}; + +	auto events = parseXml(testString, WhitespaceMode::PRESERVE); +	ASSERT_EQ(expectedEvents, events); + +	// Check the location of the text +	ASSERT_EQ(3U, events[1].second.asArray()[0].getLocation().getStart()); +	ASSERT_EQ(20U, events[1].second.asArray()[0].getLocation().getEnd()); +} + +TEST(OsxmlEventParser, commandWithDataTrimWhitespace) +{ +	const char *testString = "<a>  hello  \n world </a>"; +	//                        012345678901 234567890123 +	//                        0         1          2 + +	std::vector<std::pair<OsxmlEvent, Variant>> expectedEvents{ +	    {OsxmlEvent::COMMAND, Variant::arrayType{"a", Variant::mapType{}}}, +	    {OsxmlEvent::DATA, Variant::arrayType{"hello  \n world"}}, +	    {OsxmlEvent::FIELD_END, Variant::arrayType{}}}; + +	auto events = parseXml(testString, WhitespaceMode::TRIM); +	ASSERT_EQ(expectedEvents, events); + +	// Check the location of the text +	ASSERT_EQ(5U, events[1].second.asArray()[0].getLocation().getStart()); +	ASSERT_EQ(19U, events[1].second.asArray()[0].getLocation().getEnd()); +} + +TEST(OsxmlEventParser, commandWithDataCollapseWhitespace) +{ +	const char *testString = "<a>  hello  \n world </a>"; +	//                        012345678901 234567890123 +	//                        0         1          2 + +	std::vector<std::pair<OsxmlEvent, Variant>> expectedEvents{ +	    {OsxmlEvent::COMMAND, Variant::arrayType{"a", Variant::mapType{}}}, +	    {OsxmlEvent::DATA, Variant::arrayType{"hello world"}}, +	    {OsxmlEvent::FIELD_END, Variant::arrayType{}}}; + +	auto events = parseXml(testString, WhitespaceMode::COLLAPSE); +	ASSERT_EQ(expectedEvents, events); + +	// Check the location of the text +	ASSERT_EQ(5U, events[1].second.asArray()[0].getLocation().getStart()); +	ASSERT_EQ(19U, events[1].second.asArray()[0].getLocation().getEnd()); +} +} + diff --git a/test/plugins/xml/XmlParserTest.cpp b/test/formats/osxml/OsxmlParserTest.cpp index fdae779..fe8ed34 100644 --- a/test/plugins/xml/XmlParserTest.cpp +++ b/test/formats/osxml/OsxmlParserTest.cpp @@ -30,7 +30,7 @@  #include <core/StandaloneEnvironment.hpp>  #include <plugins/filesystem/FileLocator.hpp> -#include <plugins/xml/XmlParser.hpp> +#include <formats/osxml/OsxmlParser.hpp>  namespace ousia { @@ -41,7 +41,7 @@ extern const Rtti Typesystem;  }  struct XmlStandaloneEnvironment : public StandaloneEnvironment { -	XmlParser xmlParser; +	OsxmlParser parser;  	FileLocator fileLocator;  	XmlStandaloneEnvironment(ConcreteLogger &logger) @@ -52,21 +52,21 @@ struct XmlStandaloneEnvironment : public StandaloneEnvironment {  		registry.registerDefaultExtensions();  		registry.registerParser({"text/vnd.ousia.oxm", "text/vnd.ousia.oxd"}, -		                        {&RttiTypes::Node}, &xmlParser); +		                        {&RttiTypes::Node}, &parser);  		registry.registerResourceLocator(&fileLocator);  	}  };  static TerminalLogger logger(std::cerr, true); -TEST(XmlParser, mismatchedTag) +TEST(OsxmlParser, mismatchedTag)  {  	XmlStandaloneEnvironment env(logger);  	env.parse("mismatchedTag.oxm", "", "", RttiSet{&RttiTypes::Document});  	ASSERT_TRUE(logger.hasError());  } -TEST(XmlParser, generic) +TEST(OsxmlParser, generic)  {  	XmlStandaloneEnvironment env(logger);  	env.parse("generic.oxm", "", "", RttiSet{&RttiTypes::Node}); @@ -186,7 +186,7 @@ static void checkFieldDescriptor(      Handle<Type> primitiveType = nullptr, bool optional = false)  {  	auto res = desc->resolve(&RttiTypes::FieldDescriptor, name); -	ASSERT_EQ(1, res.size()); +	ASSERT_EQ(1U, res.size());  	checkFieldDescriptor(res[0].node, name, parent, children, type,  	                     primitiveType, optional);  } @@ -201,7 +201,7 @@ static void checkFieldDescriptor(  	                     optional);  } -TEST(XmlParser, domainParsing) +TEST(OsxmlParser, domainParsing)  {  	XmlStandaloneEnvironment env(logger);  	Rooted<Node> book_domain_node = @@ -332,10 +332,10 @@ static void checkText(Handle<Node> p, Handle<Node> expectedParent,  {  	checkStructuredEntity(p, expectedParent, doc, "paragraph");  	Rooted<StructuredEntity> par = p.cast<StructuredEntity>(); -	ASSERT_EQ(1, par->getField().size()); +	ASSERT_EQ(1U, par->getField().size());  	checkStructuredEntity(par->getField()[0], par, doc, "text");  	Rooted<StructuredEntity> text = par->getField()[0].cast<StructuredEntity>(); -	ASSERT_EQ(1, text->getField().size()); +	ASSERT_EQ(1U, text->getField().size());  	Handle<StructureNode> d = text->getField()[0];  	ASSERT_FALSE(d == nullptr); @@ -345,7 +345,7 @@ static void checkText(Handle<Node> p, Handle<Node> expectedParent,  	ASSERT_EQ(expected, prim->getContent());  } -TEST(XmlParser, documentParsing) +TEST(OsxmlParser, documentParsing)  {  	XmlStandaloneEnvironment env(logger);  	Rooted<Node> book_document_node = @@ -357,7 +357,7 @@ TEST(XmlParser, documentParsing)  	checkStructuredEntity(doc->getRoot(), doc, doc, "book");  	{  		Rooted<StructuredEntity> book = doc->getRoot(); -		ASSERT_EQ(2, book->getField().size()); +		ASSERT_EQ(2U, book->getField().size());  		checkText(book->getField()[0], book, doc,  		          "This might be some introductory text or a dedication.");  		checkStructuredEntity(book->getField()[1], book, doc, "chapter", @@ -365,7 +365,7 @@ TEST(XmlParser, documentParsing)  		{  			Rooted<StructuredEntity> chapter =  			    book->getField()[1].cast<StructuredEntity>(); -			ASSERT_EQ(3, chapter->getField().size()); +			ASSERT_EQ(3U, chapter->getField().size());  			checkText(chapter->getField()[0], chapter, doc,  			          "Here we might have an introduction to the chapter.");  			checkStructuredEntity(chapter->getField()[1], chapter, doc, @@ -374,7 +374,7 @@ TEST(XmlParser, documentParsing)  			{  				Rooted<StructuredEntity> section =  				    chapter->getField()[1].cast<StructuredEntity>(); -				ASSERT_EQ(1, section->getField().size()); +				ASSERT_EQ(1U, section->getField().size());  				checkText(section->getField()[0], section, doc,  				          "Here we might find the actual section content.");  			} @@ -384,7 +384,7 @@ TEST(XmlParser, documentParsing)  			{  				Rooted<StructuredEntity> section =  				    chapter->getField()[2].cast<StructuredEntity>(); -				ASSERT_EQ(1, section->getField().size()); +				ASSERT_EQ(1U, section->getField().size());  				checkText(section->getField()[0], section, doc,  				          "Here we might find the actual section content.");  			} diff --git a/test/core/CodeTokenizerTest.cpp b/test/plugins/css/CodeTokenizerTest.cpp index 2d4d5a7..2d4d5a7 100644 --- a/test/core/CodeTokenizerTest.cpp +++ b/test/plugins/css/CodeTokenizerTest.cpp diff --git a/test/core/TokenizerTest.cpp b/test/plugins/css/TokenizerTest.cpp index c53f93d..c53f93d 100644 --- a/test/core/TokenizerTest.cpp +++ b/test/plugins/css/TokenizerTest.cpp  | 
