Website Summary Files Commits Branches @commit @diff @stats
path: root / JSImpl
diff options
context:
space:
mode:
Commite89ae67ea4d71912caef286d3b4dcc3a5a64d134 (patch)
Author
 Dimitar Trendafilov <dimitar@coherent-labs.com>
2018-10-28 18:47:12 +0200
Committer
 Dimitar Trendafilov <dimitar@coherent-labs.com>
2018-10-28 18:47:12 +0200
Files51bc62f8df96e4df48934ece5502855cb448f2d2 /JSImpl
IPL-e89ae67ea4d71912caef286d3b4dcc3a5a64d134.tar
IPL-e89ae67ea4d71912caef286d3b4dcc3a5a64d134.tar.gz
IPL-e89ae67ea4d71912caef286d3b4dcc3a5a64d134.zip
Parent2bb25db66a044f8c489ab6449386a32f31de1256 (diff)
Moved lexer and parser tests to the test app
5 files changed, 247 insertions, 243 deletions
-rw-r--r--JSImpl/solution/genie.lua12
-rw-r--r--JSImpl/src/Tests/main.cpp240
-rw-r--r--JSImpl/test/LexerTests.cpp213
-rw-r--r--JSImpl/test/ParserTests.cpp22
-rw-r--r--JSImpl/test/genie.lua3
diff --git a/JSImpl/solution/genie.lua b/JSImpl/solution/genie.lua
index 5806154..ced7ec1 100644
--- a/JSImpl/solution/genie.lua
+++ b/JSImpl/solution/genie.lua
@@ -17,11 +17,19 @@ solution 'IPL'
objdir(root .. 'obj/release')
configuration '*'
+ project 'JSLib'
+ kind 'StaticLib'
+ language 'C++'
+ uuid(os.uuid('JSLib'))
+ files '../src/*.cpp'
+ removefiles '../src/main.cpp'
+ files '../src/*.h'
+
project 'JSImpl'
kind 'ConsoleApp'
language 'C++'
uuid(os.uuid('JSImpl'))
- files '../src/*.cpp'
- files '../src/*.h'
+ files '../src/main.cpp'
+ links 'JSLib'
include '../test'
diff --git a/JSImpl/src/Tests/main.cpp b/JSImpl/src/Tests/main.cpp
index f92144a..a46866d 100644
--- a/JSImpl/src/Tests/main.cpp
+++ b/JSImpl/src/Tests/main.cpp
@@ -1,244 +1,4 @@
-#include "Lexer.h"
-#include "Parser.h"
-#include "ASTPrinter.h"
-#include "ASTInterpreter.h"
-#include <iostream>
-#define LOG(msg) std::cout << msg << std::endl
-#define EXECUTE_TEST(test) std::cout << #test << " "; test();
-
-#define CHECK(cond) if (cond) {LOG("PASS");} else {LOG(#cond " FAIL");}
-
-// Lexer Tests
-void TestLess()
-{
- IPLVector<Token> tokens;
- Tokenize("<", tokens);
-
- CHECK(tokens.size() == 2 && tokens[0].Type == TokenType::Less);
-}
-
-void TestNumber()
-{
- IPLVector<Token> tokens;
- Tokenize("213434.24", tokens);
-
- CHECK(tokens.size() == 2 && tokens[0].Type == TokenType::Number && tokens[0].Number == 213434.24);
-}
-
-void TestNumberStartWithNine()
-{
- IPLVector<Token> tokens;
- Tokenize("999", tokens);
- CHECK(tokens.size() == 2 && tokens[0].Type == TokenType::Number && tokens[0].Number == 999);
-}
-
-void TestNumberStartWithZero()
-{
- IPLVector<Token> tokens;
- Tokenize("0999", tokens);
- CHECK(tokens.size() == 2 && tokens[0].Type == TokenType::Number && tokens[0].Number == 999);
-}
-
-void TestSpaceNewLineSpace()
-{
- IPLVector<Token> tokens;
- Tokenize(" \n var a = 4; ", tokens);
- CHECK(tokens.size() == 6 && tokens[0].Type == TokenType::Var &&
- tokens[1].Type == TokenType::Identifier &&
- tokens[2].Type == TokenType::Equal &&
- tokens[3].Type == TokenType::Number &&
- tokens[4].Type == TokenType::Semicolon);
-}
-
-void TestString()
-{
- IPLVector<Token> tokens;
- Tokenize("\"alabala\"", tokens);
- CHECK(tokens.size() == 2 && tokens[0].Type == TokenType::String && tokens[0].Lexeme == "\"alabala\"");
-}
-
-void TestStringSingleQuotedStrings()
-{
- IPLVector<Token> tokens;
- Tokenize("'alabala'", tokens);
- CHECK(tokens.size() == 2 && tokens[0].Type == TokenType::String && tokens[0].Lexeme == "'alabala'");
-}
-
-void TestKeyWord()
-{
- IPLVector<Token> tokens;
- Tokenize("for", tokens);
- CHECK(tokens.size() == 2 && tokens[0].Type == TokenType::For);
-}
-
-void TestVariableDeclaration()
-{
- IPLVector<Token> tokens;
- Tokenize("var pesho = 10", tokens);
-
- CHECK(tokens.size() == 5 && tokens[0].Type == TokenType::Var
- && tokens[1].Type == TokenType::Identifier
- && tokens[2].Type == TokenType::Equal
- && tokens[3].Type == TokenType::Number
- && tokens[4].Type == TokenType::Eof);
-}
-
-void TestStringError()
-{
- IPLVector<Token> tokens;
- const auto& res = Tokenize("\" aaaa", tokens);
- CHECK(!res.IsSuccessful && res.Error.Row == 0 && res.Error.Column == 6);
-}
-
-void TestWhiteSpaceTokens()
-{
- IPLVector<Token> tokens;
- const auto& res = Tokenize(" 1\n2 abc\n \n", tokens, { true, false });
- CHECK(res.IsSuccessful
- && tokens.size() == 8
- && tokens[0].Type == TokenType::Whitespace
- && tokens[0].Lexeme == " "
- && tokens[1].Type == TokenType::Number
- && tokens[1].Number == 1
- && tokens[2].Type == TokenType::Whitespace
- && tokens[2].Lexeme == "\n"
- && tokens[3].Type == TokenType::Number
- && tokens[3].Number == 2
- && tokens[4].Type == TokenType::Whitespace
- && tokens[4].Lexeme == " "
- && tokens[5].Type == TokenType::Identifier
- && tokens[5].Lexeme == "abc"
- && tokens[6].Type == TokenType::Whitespace
- && tokens[6].Lexeme == "\n \n"
- && tokens[7].Type == TokenType::Eof);
-}
-
-void TestSimpleComment()
-{
- IPLVector<Token> tokens;
- const auto& res = Tokenize("//comment", tokens, { false, true });
- CHECK(res.IsSuccessful
- && tokens.size() == 2
- && tokens[0].Type == TokenType::Comment
- && tokens[0].Lexeme == "//comment"
- && tokens[1].Type == TokenType::Eof);
-}
-
-void TestSimpleMultiLineComment()
-{
- IPLVector<Token> tokens;
- const auto& res = Tokenize("/*comment\ncomment*/", tokens, { false, true });
- CHECK(res.IsSuccessful
- && tokens.size() == 2
- && tokens[0].Type == TokenType::Comment
- && tokens[0].Lexeme == "/*comment\ncomment*/"
- && tokens[1].Type == TokenType::Eof);
-}
-
-void TestConsecutiveMultiLineComment()
-{
- IPLVector<Token> tokens;
- const auto& res = Tokenize("/*comment1\ncomment1*//*comment2\ncomment2*/", tokens, { false, true });
- CHECK(res.IsSuccessful
- && tokens.size() == 3
- && tokens[0].Type == TokenType::Comment
- && tokens[0].Lexeme == "/*comment1\ncomment1*/"
- && tokens[1].Type == TokenType::Comment
- && tokens[1].Lexeme == "/*comment2\ncomment2*/"
- && tokens[2].Type == TokenType::Eof);
-}
-
-void TestConsecutiveMultiLineCommentWithSpace()
-{
- IPLVector<Token> tokens;
- const auto& res = Tokenize("/*comment1\ncomment1*/\n\n\n/*comment2\ncomment2*/", tokens, { false, true });
- CHECK(res.IsSuccessful
- && tokens.size() == 3
- && tokens[0].Type == TokenType::Comment
- && tokens[0].Lexeme == "/*comment1\ncomment1*/"
- && tokens[1].Type == TokenType::Comment
- && tokens[1].Lexeme == "/*comment2\ncomment2*/"
- && tokens[2].Type == TokenType::Eof);
-}
-
-void TestConsecutiveMultiLineCommentWithSpaceWithTokens()
-{
- IPLVector<Token> tokens;
- const auto& res = Tokenize("//comment1\n/*comment2\ncomment2*/\n\n\n/*comment3\ncomment3*/", tokens, { true, true });
- CHECK(res.IsSuccessful
- && tokens.size() == 6
- && tokens[0].Type == TokenType::Comment
- && tokens[0].Lexeme == "//comment1"
- && tokens[1].Type == TokenType::Whitespace
- && tokens[1].Lexeme == "\n"
- && tokens[2].Type == TokenType::Comment
- && tokens[2].Lexeme == "/*comment2\ncomment2*/"
- && tokens[3].Type == TokenType::Whitespace
- && tokens[3].Lexeme == "\n\n\n"
- && tokens[4].Type == TokenType::Comment
- && tokens[4].Lexeme == "/*comment3\ncomment3*/"
- && tokens[5].Type == TokenType::Eof);
-}
-
-void TestCommentError()
-{
- IPLVector<Token> tokens;
- const auto& res = Tokenize(" aa\n /*", tokens);
- CHECK(!res.IsSuccessful && res.Error.Row == 1 && res.Error.Column == 3);
-}
-
-// Parser Tests
-void TestParseUnaryExpr()
-{
- IPLVector<Token> tokens;
- Tokenize("function pesho() { var a = 0; return a; } var a = \"3\";", tokens);
-
- // TODO make actual test :D
- auto expr = Parse(tokens);
- ASTPrinter p(std::cout);
- expr->Accept(p);
- std::cout << "\n";
-}
-
-void TestHexNumber()
-{
- IPLVector<Token> tokens;
- const auto& res = Tokenize("0x10", tokens);
-
- CHECK(res.IsSuccessful && tokens[0].Type == TokenType::Number && tokens[0].Number == 16);
-}
-
-void TestScientificNotationNumber()
-{
- IPLVector<Token> tokens;
- const auto& res = Tokenize("1e2", tokens);
-
- CHECK(res.IsSuccessful && tokens[0].Type == TokenType::Number && tokens[0].Number == 100);
-}
-
int main()
{
- EXECUTE_TEST(TestLess);
- EXECUTE_TEST(TestNumber);
- EXECUTE_TEST(TestNumberStartWithNine);
- EXECUTE_TEST(TestNumberStartWithZero);
- EXECUTE_TEST(TestString);
- EXECUTE_TEST(TestSpaceNewLineSpace);
- EXECUTE_TEST(TestStringSingleQuotedStrings);
- EXECUTE_TEST(TestKeyWord);
- EXECUTE_TEST(TestVariableDeclaration);
- EXECUTE_TEST(TestWhiteSpaceTokens);
- EXECUTE_TEST(TestSimpleComment);
- EXECUTE_TEST(TestSimpleMultiLineComment);
- EXECUTE_TEST(TestConsecutiveMultiLineComment);
- EXECUTE_TEST(TestConsecutiveMultiLineCommentWithSpace);
- EXECUTE_TEST(TestConsecutiveMultiLineCommentWithSpaceWithTokens);
- EXECUTE_TEST(TestCommentError);
- EXECUTE_TEST(TestHexNumber);
- EXECUTE_TEST(TestScientificNotationNumber);
-
-#if defined(_WIN32)
- std::system("pause");
-#endif
return 0;
}
diff --git a/JSImpl/test/LexerTests.cpp b/JSImpl/test/LexerTests.cpp
new file mode 100644
index 0000000..b24d7a2
--- /dev/null
+++ b/JSImpl/test/LexerTests.cpp
@@ -0,0 +1,213 @@
+#include <src/Lexer.h>
+#include <src/CommonTypes.h>
+
+#include <gtest/gtest.h>
+
+TEST(Lexer, Less)
+{
+ IPLVector<Token> tokens;
+ Tokenize("<", tokens);
+
+ ASSERT_EQ(tokens.size(), 2u);
+ ASSERT_EQ(tokens[0].Type, TokenType::Less);
+}
+
+TEST(Lexer, Number)
+{
+ IPLVector<Token> tokens;
+ Tokenize("213434.24", tokens);
+
+ ASSERT_EQ(tokens.size(), 2u);
+ ASSERT_EQ(tokens[0].Type, TokenType::Number);
+ ASSERT_EQ(tokens[0].Number, 213434.24);
+}
+
+
+TEST(Lexer, HexNumber)
+{
+ IPLVector<Token> tokens;
+ const auto& res = Tokenize("0x10", tokens);
+
+ ASSERT_EQ(tokens.size(), 2u);
+ ASSERT_EQ(tokens[0].Type, TokenType::Number);
+ ASSERT_EQ(tokens[0].Number, 16);
+}
+
+TEST(Lexer, ScientificNotationNumber)
+{
+ IPLVector<Token> tokens;
+ const auto& res = Tokenize("1e2", tokens);
+
+ ASSERT_EQ(tokens.size(), 2u);
+ ASSERT_EQ(tokens[0].Type, TokenType::Number);
+ ASSERT_EQ(tokens[0].Number, 100);
+}
+
+TEST(Lexer, NumberStartWithNine)
+{
+ IPLVector<Token> tokens;
+ Tokenize("999", tokens);
+ ASSERT_EQ(tokens.size(), 2u);
+ ASSERT_EQ(tokens[0].Type, TokenType::Number);
+ ASSERT_EQ(tokens[0].Number, 999);
+}
+
+TEST(Lexer, NumberStartWithZero)
+{
+ IPLVector<Token> tokens;
+ Tokenize("0999", tokens);
+ ASSERT_EQ(tokens.size(), 2u);
+ ASSERT_EQ(tokens[0].Type, TokenType::Number);
+ ASSERT_EQ(tokens[0].Number, 999);
+}
+
+TEST(Lexer, SpaceNewLineSpace)
+{
+ IPLVector<Token> tokens;
+ Tokenize(" \n var a = 4; ", tokens);
+ ASSERT_TRUE(tokens.size() == 6 && tokens[0].Type == TokenType::Var &&
+ tokens[1].Type == TokenType::Identifier &&
+ tokens[2].Type == TokenType::Equal &&
+ tokens[3].Type == TokenType::Number &&
+ tokens[4].Type == TokenType::Semicolon);
+}
+
+TEST(Lexer, String)
+{
+ IPLVector<Token> tokens;
+ Tokenize("\"alabala\"", tokens);
+ ASSERT_TRUE(tokens.size() == 2 && tokens[0].Type == TokenType::String
+ && tokens[0].Lexeme == "\"alabala\"");
+}
+
+TEST(Lexer, StringSingleQuotedStrings)
+{
+ IPLVector<Token> tokens;
+ Tokenize("'alabala'", tokens);
+ ASSERT_TRUE(tokens.size() == 2 && tokens[0].Type == TokenType::String && tokens[0].Lexeme == "'alabala'");
+}
+
+TEST(Lexer, KeyWord)
+{
+ IPLVector<Token> tokens;
+ Tokenize("for", tokens);
+ ASSERT_TRUE(tokens.size() == 2 && tokens[0].Type == TokenType::For);
+}
+
+TEST(Lexer, VariableDeclaration)
+{
+ IPLVector<Token> tokens;
+ Tokenize("var pesho = 10", tokens);
+
+ ASSERT_TRUE(tokens.size() == 5 && tokens[0].Type == TokenType::Var
+ && tokens[1].Type == TokenType::Identifier
+ && tokens[2].Type == TokenType::Equal
+ && tokens[3].Type == TokenType::Number
+ && tokens[4].Type == TokenType::Eof);
+}
+
+TEST(Lexer, StringError)
+{
+ IPLVector<Token> tokens;
+ const auto& res = Tokenize("\" aaaa", tokens);
+ ASSERT_TRUE(!res.IsSuccessful && res.Error.Row == 0 && res.Error.Column == 6);
+}
+
+TEST(Lexer, TestWhiteSpaceTokens)
+{
+ IPLVector<Token> tokens;
+ const auto& res = Tokenize(" 1\n2 abc\n \n", tokens, { true, false });
+ ASSERT_TRUE(res.IsSuccessful
+ && tokens.size() == 8
+ && tokens[0].Type == TokenType::Whitespace
+ && tokens[0].Lexeme == " "
+ && tokens[1].Type == TokenType::Number
+ && tokens[1].Number == 1
+ && tokens[2].Type == TokenType::Whitespace
+ && tokens[2].Lexeme == "\n"
+ && tokens[3].Type == TokenType::Number
+ && tokens[3].Number == 2
+ && tokens[4].Type == TokenType::Whitespace
+ && tokens[4].Lexeme == " "
+ && tokens[5].Type == TokenType::Identifier
+ && tokens[5].Lexeme == "abc"
+ && tokens[6].Type == TokenType::Whitespace
+ && tokens[6].Lexeme == "\n \n"
+ && tokens[7].Type == TokenType::Eof);
+}
+
+TEST(Lexer, SimpleComment)
+{
+ IPLVector<Token> tokens;
+ const auto& res = Tokenize("//comment", tokens, { false, true });
+ ASSERT_TRUE(res.IsSuccessful
+ && tokens.size() == 2
+ && tokens[0].Type == TokenType::Comment
+ && tokens[0].Lexeme == "//comment"
+ && tokens[1].Type == TokenType::Eof);
+}
+
+TEST(Lexer, SimpleMultiLineComment)
+{
+ IPLVector<Token> tokens;
+ const auto& res = Tokenize("/*comment\ncomment*/", tokens, { false, true });
+ ASSERT_TRUE(res.IsSuccessful
+ && tokens.size() == 2
+ && tokens[0].Type == TokenType::Comment
+ && tokens[0].Lexeme == "/*comment\ncomment*/"
+ && tokens[1].Type == TokenType::Eof);
+}
+
+TEST(Lexer, ConsecutiveMultiLineComment)
+{
+ IPLVector<Token> tokens;
+ const auto& res = Tokenize("/*comment1\ncomment1*//*comment2\ncomment2*/", tokens, { false, true });
+ ASSERT_TRUE(res.IsSuccessful
+ && tokens.size() == 3
+ && tokens[0].Type == TokenType::Comment
+ && tokens[0].Lexeme == "/*comment1\ncomment1*/"
+ && tokens[1].Type == TokenType::Comment
+ && tokens[1].Lexeme == "/*comment2\ncomment2*/"
+ && tokens[2].Type == TokenType::Eof);
+}
+
+TEST(Lexer, ConsecutiveMultiLineCommentWithSpace)
+{
+ IPLVector<Token> tokens;
+ const auto& res = Tokenize("/*comment1\ncomment1*/\n\n\n/*comment2\ncomment2*/", tokens, { false, true });
+ ASSERT_TRUE(res.IsSuccessful
+ && tokens.size() == 3
+ && tokens[0].Type == TokenType::Comment
+ && tokens[0].Lexeme == "/*comment1\ncomment1*/"
+ && tokens[1].Type == TokenType::Comment
+ && tokens[1].Lexeme == "/*comment2\ncomment2*/"
+ && tokens[2].Type == TokenType::Eof);
+}
+
+TEST(Lexer, ConsecutiveMultiLineCommentWithSpaceWithTokens)
+{
+ IPLVector<Token> tokens;
+ const auto& res = Tokenize("//comment1\n/*comment2\ncomment2*/\n\n\n/*comment3\ncomment3*/", tokens, { true, true });
+ ASSERT_TRUE(res.IsSuccessful
+ && tokens.size() == 6
+ && tokens[0].Type == TokenType::Comment
+ && tokens[0].Lexeme == "//comment1"
+ && tokens[1].Type == TokenType::Whitespace
+ && tokens[1].Lexeme == "\n"
+ && tokens[2].Type == TokenType::Comment
+ && tokens[2].Lexeme == "/*comment2\ncomment2*/"
+ && tokens[3].Type == TokenType::Whitespace
+ && tokens[3].Lexeme == "\n\n\n"
+ && tokens[4].Type == TokenType::Comment
+ && tokens[4].Lexeme == "/*comment3\ncomment3*/"
+ && tokens[5].Type == TokenType::Eof);
+}
+
+TEST(Lexer, CommentError)
+{
+ IPLVector<Token> tokens;
+ const auto& res = Tokenize(" aa\n /*", tokens);
+ ASSERT_TRUE(!res.IsSuccessful && res.Error.Row == 1 &&
+ res.Error.Column == 3);
+}
+
diff --git a/JSImpl/test/ParserTests.cpp b/JSImpl/test/ParserTests.cpp
new file mode 100644
index 0000000..a884f37
--- /dev/null
+++ b/JSImpl/test/ParserTests.cpp
@@ -0,0 +1,22 @@
+#include <src/CommonTypes.h>
+#include <src/Lexer.h>
+#include <src/Parser.h>
+#include <src/ASTPrinter.h>
+
+#include <gtest/gtest.h>
+
+#include <sstream>
+
+TEST(Parser, ParseUnaryExpr)
+{
+ IPLVector<Token> tokens;
+ Tokenize("function pesho() { var a = 0; return a; } var a = \"3\";", tokens);
+
+ // TODO make actual test :D
+ auto expr = Parse(tokens);
+ std::ostringstream output;
+ ASTPrinter p(output);
+ expr->Accept(p);
+ ASSERT_TRUE(!output.str().empty());
+}
+
diff --git a/JSImpl/test/genie.lua b/JSImpl/test/genie.lua
index c46b4a8..3bf1a4c 100644
--- a/JSImpl/test/genie.lua
+++ b/JSImpl/test/genie.lua
@@ -8,9 +8,10 @@ project 'Test'
includedirs {
'googletest/googletest/include',
'googletest/googlemock/include',
- '../JSImpl/googlemock/include',
+ '..',
}
links {
+ 'JSLib',
'gtest',
'gmock',
'gtest_main',