1 #include "TokenTest.hpp"
6 CPPUNIT_TEST_SUITE_REGISTRATION(blank::test::TokenTest);
13 void TokenTest::setUp() {
17 void TokenTest::tearDown() {
22 void TokenTest::testTypeIO() {
23 AssertStreamOutput(Token::UNKNOWN, "UNKNOWN");
24 AssertStreamOutput(Token::ANGLE_BRACKET_OPEN, "ANGLE_BRACKET_OPEN");
25 AssertStreamOutput(Token::ANGLE_BRACKET_CLOSE, "ANGLE_BRACKET_CLOSE");
26 AssertStreamOutput(Token::CHEVRON_OPEN, "CHEVRON_OPEN");
27 AssertStreamOutput(Token::CHEVRON_CLOSE, "CHEVRON_CLOSE");
28 AssertStreamOutput(Token::BRACKET_OPEN, "BRACKET_OPEN");
29 AssertStreamOutput(Token::BRACKET_CLOSE, "BRACKET_CLOSE");
30 AssertStreamOutput(Token::PARENTHESIS_OPEN, "PARENTHESIS_OPEN");
31 AssertStreamOutput(Token::PARENTHESIS_CLOSE, "PARENTHESIS_CLOSE");
32 AssertStreamOutput(Token::COLON, "COLON");
33 AssertStreamOutput(Token::SEMICOLON, "SEMICOLON");
34 AssertStreamOutput(Token::COMMA, "COMMA");
35 AssertStreamOutput(Token::EQUALS, "EQUALS");
36 AssertStreamOutput(Token::NUMBER, "NUMBER");
37 AssertStreamOutput(Token::STRING, "STRING");
38 AssertStreamOutput(Token::IDENTIFIER, "IDENTIFIER");
39 AssertStreamOutput(Token::COMMENT, "COMMENT");
42 void TokenTest::testTokenIO() {
44 t.value = "why oh why";
45 AssertStreamOutput(t, "UNKNOWN(why oh why)");
46 t.type = Token::UNKNOWN;
47 t.value = "do I have no purpose";
48 AssertStreamOutput(t, "UNKNOWN(do I have no purpose)");
49 t.type = Token::ANGLE_BRACKET_OPEN;
50 AssertStreamOutput(t, "ANGLE_BRACKET_OPEN");
51 t.type = Token::ANGLE_BRACKET_CLOSE;
52 AssertStreamOutput(t, "ANGLE_BRACKET_CLOSE");
53 t.type = Token::CHEVRON_OPEN;
54 AssertStreamOutput(t, "CHEVRON_OPEN");
55 t.type = Token::CHEVRON_CLOSE;
56 AssertStreamOutput(t, "CHEVRON_CLOSE");
57 t.type = Token::BRACKET_OPEN;
58 AssertStreamOutput(t, "BRACKET_OPEN");
59 t.type = Token::BRACKET_CLOSE;
60 AssertStreamOutput(t, "BRACKET_CLOSE");
61 t.type = Token::PARENTHESIS_OPEN;
62 AssertStreamOutput(t, "PARENTHESIS_OPEN");
63 t.type = Token::PARENTHESIS_CLOSE;
64 AssertStreamOutput(t, "PARENTHESIS_CLOSE");
65 t.type = Token::COLON;
66 AssertStreamOutput(t, "COLON");
67 t.type = Token::SEMICOLON;
68 AssertStreamOutput(t, "SEMICOLON");
69 t.type = Token::COMMA;
70 AssertStreamOutput(t, "COMMA");
71 t.type = Token::EQUALS;
72 AssertStreamOutput(t, "EQUALS");
73 t.type = Token::NUMBER;
75 AssertStreamOutput(t, "NUMBER(15)");
76 t.type = Token::STRING;
77 t.value = "hello world";
78 AssertStreamOutput(t, "STRING(hello world)");
79 t.type = Token::IDENTIFIER;
81 AssertStreamOutput(t, "IDENTIFIER(foo)");
82 t.type = Token::COMMENT;
83 t.value = "WITHOUT ANY WARRANTY";
84 AssertStreamOutput(t, "COMMENT(WITHOUT ANY WARRANTY)");
87 void TokenTest::testTokenizer() {
89 stream << "[{0},<.5>+3=/**\n * test\n */ (-1.5); foo_bar.baz:\"hello\\r\\n\\t\\\"world\\\"\" ] // this line\n#that line";
93 Token token(in.Next());
94 AssertToken(token.type, token.value, in.Current());
95 AssertToken(Token::BRACKET_OPEN, token);
98 AssertToken(Token::ANGLE_BRACKET_OPEN, in.Next());
100 AssertToken(Token::NUMBER, "0", in.Next());
102 AssertToken(Token::ANGLE_BRACKET_CLOSE, in.Next());
104 AssertToken(Token::COMMA, in.Next());
106 AssertToken(Token::CHEVRON_OPEN, in.Next());
108 AssertToken(Token::NUMBER, ".5", in.Next());
110 AssertToken(Token::CHEVRON_CLOSE, in.Next());
112 AssertToken(Token::NUMBER, "+3", in.Next());
114 AssertToken(Token::EQUALS, in.Next());
116 AssertToken(Token::COMMENT, "*\n * test\n ", in.Next());
118 AssertToken(Token::PARENTHESIS_OPEN, in.Next());
120 AssertToken(Token::NUMBER, "-1.5", in.Next());
122 AssertToken(Token::PARENTHESIS_CLOSE, in.Next());
124 AssertToken(Token::SEMICOLON, in.Next());
126 AssertToken(Token::IDENTIFIER, "foo_bar.baz", in.Next());
128 AssertToken(Token::COLON, in.Next());
130 AssertToken(Token::STRING, "hello\r\n\t\"world\"", in.Next());
132 AssertToken(Token::BRACKET_CLOSE, in.Next());
134 AssertToken(Token::COMMENT, " this line", in.Next());
136 AssertToken(Token::COMMENT, "that line", in.Next());
137 CPPUNIT_ASSERT_MESSAGE("expected end of stream", !in.HasMore());
140 void TokenTest::testTokenizerBrokenComment() {
143 stream << "/* just one more thing…*";
144 Tokenizer in(stream);
146 CPPUNIT_ASSERT_THROW_MESSAGE(
147 "half-closed comment should throw",
148 in.Next(), std::runtime_error);
153 Tokenizer in(stream);
155 CPPUNIT_ASSERT_THROW_MESSAGE(
156 "sole '/' at end of stream should throw",
157 in.Next(), std::runtime_error);
162 Tokenizer in(stream);
164 CPPUNIT_ASSERT_THROW_MESSAGE(
165 "'/' followed by garbage should throw",
166 in.Next(), std::runtime_error);
171 void TokenTest::AssertStreamOutput(
177 CPPUNIT_ASSERT_EQUAL_MESSAGE(
178 "unexpected std::ostream << Token::Type result",
179 expected, conv.str());
182 void TokenTest::AssertStreamOutput(
188 CPPUNIT_ASSERT_EQUAL_MESSAGE(
189 "unexpected std::ostream << Token result",
190 expected, conv.str());
193 void TokenTest::AssertHasMore(Tokenizer &in) {
194 CPPUNIT_ASSERT_MESSAGE("unexpected end of stream", in.HasMore());
197 void TokenTest::AssertToken(
198 Token::Type expected_type,
199 const Token &actual_token
201 AssertToken(expected_type, "", actual_token);
204 void TokenTest::AssertToken(
205 Token::Type expected_type,
206 string expected_value,
207 const Token &actual_token
209 CPPUNIT_ASSERT_EQUAL_MESSAGE(
210 "unexpected token type",
211 expected_type, actual_token.type);
212 CPPUNIT_ASSERT_EQUAL_MESSAGE(
213 "unexpected token value",
214 expected_value, actual_token.value);