#include <gtest/gtest.h>
#include <utils/common/StringTokenizer.h>
#include <utils/common/UtilExceptions.h>

using namespace std;

/*
Tests StringTokenizer class from <SUMO>/src/utils/common
*/

/* Tests the behaviour with a StringTokenizer::WHITECHAR for splitting a string.*/
TEST(StringTokenizer, test_split_with_whitechar) {
	StringTokenizer *strTok = new StringTokenizer("Hello  World", StringTokenizer::WHITECHARS);
	EXPECT_TRUE(strTok->hasNext()) << "There must be more tokens available.";
	EXPECT_EQ("Hello",strTok->next());
	EXPECT_EQ("World",strTok->next());
	EXPECT_FALSE(strTok->hasNext()) << "No tokens should be available.";
}

/* Tests the behaviour with a StringTokenizer::NEWLINE for splitting a string.*/
TEST(StringTokenizer, test_split_with_newline) {
	StringTokenizer *strTok = new StringTokenizer("Hello\nWorld", StringTokenizer::NEWLINE);
	EXPECT_TRUE(strTok->hasNext()) << "There must be more tokens available.";
	EXPECT_EQ("Hello",strTok->next());
	EXPECT_EQ("World",strTok->next());
	EXPECT_FALSE(strTok->hasNext()) << "No tokens should be available.";
}

/* Tests the behaviour with any tokens for splitting a string.*/
TEST(StringTokenizer, test_split_with_x) {
	StringTokenizer *strTok = new StringTokenizer("HelloxxWorld", "x");
	EXPECT_TRUE(strTok->hasNext()) << "There must be more tokens available.";
	EXPECT_EQ("Hello",strTok->next());
	EXPECT_EQ("",strTok->next());
	EXPECT_EQ("World",strTok->next());
	EXPECT_FALSE(strTok->hasNext()) << "No tokens should be available.";
}

/* Tests the behaviour with any tokens for splitting a string with the option splitAtAllChars=true*/
TEST(StringTokenizer, test_split_any_char) {
	StringTokenizer *strTok = new StringTokenizer("HelloxWyorld", "xy", true);
	EXPECT_TRUE(strTok->hasNext()) << "There must be more tokens available.";
	EXPECT_EQ("Hello",strTok->next());
	EXPECT_EQ("W",strTok->next());
	EXPECT_EQ("orld",strTok->next());
	EXPECT_FALSE(strTok->hasNext()) << "No tokens should be available.";
}

/* Tests the method reinit*/
TEST(StringTokenizer, test_method_reinit) {
	StringTokenizer *strTok = new StringTokenizer("Hello");
	strTok->next();
	EXPECT_FALSE(strTok->hasNext()) << "No tokens should be available.";
	strTok->reinit();
	EXPECT_TRUE(strTok->hasNext()) << "There must be more tokens available.";
}

/* Tests the method size*/
TEST(StringTokenizer, test_method_size) {
	StringTokenizer *strTok = new StringTokenizer("Hello little World");
	EXPECT_EQ(3,strTok->size()) << "The number of the token is not right.";
	StringTokenizer *strTok2 = new StringTokenizer("");
	EXPECT_EQ(0,strTok2->size()) << "The number of the token is not right.";
}

/* Tests the method front*/
TEST(StringTokenizer, test_method_front) {
	StringTokenizer *strTok = new StringTokenizer("Hello World");
	EXPECT_EQ("Hello",strTok->front()) << "The first token is not right.";
	strTok->next();
	EXPECT_EQ("Hello",strTok->front()) << "The first token is not right.";
}

/* Tests the method get*/
TEST(StringTokenizer, test_method_get) {
	StringTokenizer *strTok = new StringTokenizer("Hello World");
	EXPECT_EQ("Hello",strTok->get(0)) << "The first token is not right.";
	EXPECT_EQ("World",strTok->get(1)) << "The second token is not right.";
	ASSERT_THROW(strTok->get(2),OutOfBoundsException) << "Expect an OutOfBoundsException exception.";
}

/* Tests the method get with empty data*/
TEST(StringTokenizer, test_method_get_with_empty_data) {
	StringTokenizer *strTok = new StringTokenizer();
	ASSERT_THROW(strTok->get(0),OutOfBoundsException) << "Expect an OutOfBoundsException exception.";
}

/* Tests the method getVector*/
TEST(StringTokenizer, test_method_getVector) {
	StringTokenizer *strTok = new StringTokenizer("Hello World");
	vector<string> strVek = strTok->getVector();
	EXPECT_EQ("World",strVek.back());
	EXPECT_EQ("Hello",strVek.front());
}





