Commit fc8b7200 by alokp@chromium.org

Refactored all tests to derive from a common PreprocessorTest. This avoids some code duplication.

Review URL: https://codereview.appspot.com/6257048 git-svn-id: https://angleproject.googlecode.com/svn/trunk@1097 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent e5dfefad
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
'preprocessor_tests/number_test.cpp', 'preprocessor_tests/number_test.cpp',
'preprocessor_tests/operator_test.cpp', 'preprocessor_tests/operator_test.cpp',
'preprocessor_tests/pragma_test.cpp', 'preprocessor_tests/pragma_test.cpp',
'preprocessor_tests/PreprocessorTest.h',
'preprocessor_tests/space_test.cpp', 'preprocessor_tests/space_test.cpp',
'preprocessor_tests/token_test.cpp', 'preprocessor_tests/token_test.cpp',
'preprocessor_tests/version_test.cpp', 'preprocessor_tests/version_test.cpp',
......
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "gtest/gtest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#ifndef PREPROCESSOR_TESTS_PREPROCESSOR_TEST_H_
#define PREPROCESSOR_TESTS_PREPROCESSOR_TEST_H_
class PreprocessorTest : public testing::Test
{
protected:
PreprocessorTest() : mPreprocessor(&mDiagnostics, &mDirectiveHandler) { }
MockDiagnostics mDiagnostics;
MockDirectiveHandler mDirectiveHandler;
pp::Preprocessor mPreprocessor;
};
#endif // PREPROCESSOR_TESTS_PREPROCESSOR_TEST_H_
...@@ -7,16 +7,13 @@ ...@@ -7,16 +7,13 @@
#include <algorithm> #include <algorithm>
#include <climits> #include <climits>
#include "gtest/gtest.h" #include "PreprocessorTest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "Token.h" #include "Token.h"
#if GTEST_HAS_PARAM_TEST #if GTEST_HAS_PARAM_TEST
class CharTest : public testing::TestWithParam<int> class CharTest : public PreprocessorTest,
public testing::WithParamInterface<int>
{ {
}; };
...@@ -50,12 +47,9 @@ TEST_P(CharTest, Identified) ...@@ -50,12 +47,9 @@ TEST_P(CharTest, Identified)
const char* cstr = str.c_str(); const char* cstr = str.c_str();
int length = 1; int length = 1;
MockDiagnostics diagnostics;
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
// Note that we pass the length param as well because the invalid // Note that we pass the length param as well because the invalid
// string may contain the null character. // string may contain the null character.
ASSERT_TRUE(preprocessor.init(1, &cstr, &length)); ASSERT_TRUE(mPreprocessor.init(1, &cstr, &length));
int expectedType = pp::Token::LAST; int expectedType = pp::Token::LAST;
std::string expectedValue; std::string expectedValue;
...@@ -89,12 +83,12 @@ TEST_P(CharTest, Identified) ...@@ -89,12 +83,12 @@ TEST_P(CharTest, Identified)
{ {
// Everything else is invalid. // Everything else is invalid.
using testing::_; using testing::_;
EXPECT_CALL(diagnostics, EXPECT_CALL(mDiagnostics,
print(pp::Diagnostics::INVALID_CHARACTER, _, str)); print(pp::Diagnostics::INVALID_CHARACTER, _, str));
} }
pp::Token token; pp::Token token;
preprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(expectedType, token.type); EXPECT_EQ(expectedType, token.type);
EXPECT_EQ(expectedValue, token.value); EXPECT_EQ(expectedValue, token.value);
}; };
......
...@@ -4,14 +4,13 @@ ...@@ -4,14 +4,13 @@
// found in the LICENSE file. // found in the LICENSE file.
// //
#include "gtest/gtest.h" #include "PreprocessorTest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "Token.h" #include "Token.h"
class CommentTest : public testing::TestWithParam<const char*> #if GTEST_HAS_PARAM_TEST
class CommentTest : public PreprocessorTest,
public testing::WithParamInterface<const char*>
{ {
}; };
...@@ -19,13 +18,10 @@ TEST_P(CommentTest, CommentIgnored) ...@@ -19,13 +18,10 @@ TEST_P(CommentTest, CommentIgnored)
{ {
const char* str = GetParam(); const char* str = GetParam();
MockDiagnostics diagnostics; ASSERT_TRUE(mPreprocessor.init(1, &str, 0));
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
ASSERT_TRUE(preprocessor.init(1, &str, 0));
pp::Token token; pp::Token token;
preprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::LAST, token.type); EXPECT_EQ(pp::Token::LAST, token.type);
} }
...@@ -44,34 +40,34 @@ INSTANTIATE_TEST_CASE_P(BlockComment, CommentTest, ...@@ -44,34 +40,34 @@ INSTANTIATE_TEST_CASE_P(BlockComment, CommentTest,
"/***/", // With lone '*'. "/***/", // With lone '*'.
"/*\"*/")); // Invalid character. "/*\"*/")); // Invalid character.
TEST(BlockComment, CommentReplacedWithSpace) #endif // GTEST_HAS_PARAM_TEST
class BlockCommentTest : public PreprocessorTest
{
};
TEST_F(BlockCommentTest, CommentReplacedWithSpace)
{ {
const char* str = "/*foo*/bar"; const char* str = "/*foo*/bar";
MockDiagnostics diagnostics; ASSERT_TRUE(mPreprocessor.init(1, &str, 0));
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
ASSERT_TRUE(preprocessor.init(1, &str, 0));
pp::Token token; pp::Token token;
preprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type); EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ("bar", token.value); EXPECT_EQ("bar", token.value);
EXPECT_TRUE(token.hasLeadingSpace()); EXPECT_TRUE(token.hasLeadingSpace());
} }
TEST(BlockComment, UnterminatedComment) TEST_F(BlockCommentTest, UnterminatedComment)
{ {
const char* str = "/*foo"; const char* str = "/*foo";
MockDiagnostics diagnostics; ASSERT_TRUE(mPreprocessor.init(1, &str, 0));
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
ASSERT_TRUE(preprocessor.init(1, &str, 0));
using testing::_; using testing::_;
EXPECT_CALL(diagnostics, print(pp::Diagnostics::EOF_IN_COMMENT, _, _)); EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::EOF_IN_COMMENT, _, _));
pp::Token token; pp::Token token;
preprocessor.lex(&token); mPreprocessor.lex(&token);
} }
...@@ -4,48 +4,38 @@ ...@@ -4,48 +4,38 @@
// found in the LICENSE file. // found in the LICENSE file.
// //
#include "gtest/gtest.h" #include "PreprocessorTest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "Token.h" #include "Token.h"
class ErrorTest : public testing::Test class ErrorTest : public PreprocessorTest
{ {
protected: protected:
ErrorTest() : mPreprocessor(&mDiagnostics, &mDirectiveHandler) { } void preprocess(const char* str)
void lex()
{ {
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
pp::Token token; pp::Token token;
mPreprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::LAST, token.type); EXPECT_EQ(pp::Token::LAST, token.type);
EXPECT_EQ("", token.value); EXPECT_EQ("", token.value);
} }
MockDiagnostics mDiagnostics;
MockDirectiveHandler mDirectiveHandler;
pp::Preprocessor mPreprocessor;
}; };
TEST_F(ErrorTest, Empty) TEST_F(ErrorTest, Empty)
{ {
const char* str = "#error\n"; const char* str = "#error\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_; using testing::_;
EXPECT_CALL(mDirectiveHandler, handleError(pp::SourceLocation(0, 1), "")); EXPECT_CALL(mDirectiveHandler, handleError(pp::SourceLocation(0, 1), ""));
// No error or warning. // No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0); EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
lex(); preprocess(str);
} }
TEST_F(ErrorTest, OneTokenMessage) TEST_F(ErrorTest, OneTokenMessage)
{ {
const char* str = "#error foo\n"; const char* str = "#error foo\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_; using testing::_;
EXPECT_CALL(mDirectiveHandler, EXPECT_CALL(mDirectiveHandler,
...@@ -53,13 +43,12 @@ TEST_F(ErrorTest, OneTokenMessage) ...@@ -53,13 +43,12 @@ TEST_F(ErrorTest, OneTokenMessage)
// No error or warning. // No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0); EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
lex(); preprocess(str);
} }
TEST_F(ErrorTest, TwoTokenMessage) TEST_F(ErrorTest, TwoTokenMessage)
{ {
const char* str = "#error foo bar\n"; const char* str = "#error foo bar\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_; using testing::_;
EXPECT_CALL(mDirectiveHandler, EXPECT_CALL(mDirectiveHandler,
...@@ -67,7 +56,7 @@ TEST_F(ErrorTest, TwoTokenMessage) ...@@ -67,7 +56,7 @@ TEST_F(ErrorTest, TwoTokenMessage)
// No error or warning. // No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0); EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
lex(); preprocess(str);
} }
TEST_F(ErrorTest, Comments) TEST_F(ErrorTest, Comments)
...@@ -83,7 +72,6 @@ TEST_F(ErrorTest, Comments) ...@@ -83,7 +72,6 @@ TEST_F(ErrorTest, Comments)
"/*foo*/" "/*foo*/"
"//foo" "//foo"
"\n"; "\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_; using testing::_;
EXPECT_CALL(mDirectiveHandler, EXPECT_CALL(mDirectiveHandler,
...@@ -91,13 +79,12 @@ TEST_F(ErrorTest, Comments) ...@@ -91,13 +79,12 @@ TEST_F(ErrorTest, Comments)
// No error or warning. // No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0); EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
lex(); preprocess(str);
} }
TEST_F(ErrorTest, MissingNewline) TEST_F(ErrorTest, MissingNewline)
{ {
const char* str = "#error foo"; const char* str = "#error foo";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_; using testing::_;
// Directive successfully parsed. // Directive successfully parsed.
...@@ -106,5 +93,5 @@ TEST_F(ErrorTest, MissingNewline) ...@@ -106,5 +93,5 @@ TEST_F(ErrorTest, MissingNewline)
// Error reported about EOF. // Error reported about EOF.
EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::EOF_IN_DIRECTIVE, _, _)); EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::EOF_IN_DIRECTIVE, _, _));
lex(); preprocess(str);
} }
...@@ -4,35 +4,26 @@ ...@@ -4,35 +4,26 @@
// found in the LICENSE file. // found in the LICENSE file.
// //
#include "gtest/gtest.h" #include "PreprocessorTest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "Token.h" #include "Token.h"
class ExtensionTest : public testing::Test class ExtensionTest : public PreprocessorTest
{ {
protected: protected:
ExtensionTest() : mPreprocessor(&mDiagnostics, &mDirectiveHandler) { } void preprocess(const char* str)
void lex()
{ {
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
pp::Token token; pp::Token token;
mPreprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::LAST, token.type); EXPECT_EQ(pp::Token::LAST, token.type);
EXPECT_EQ("", token.value); EXPECT_EQ("", token.value);
} }
MockDiagnostics mDiagnostics;
MockDirectiveHandler mDirectiveHandler;
pp::Preprocessor mPreprocessor;
}; };
TEST_F(ExtensionTest, Valid) TEST_F(ExtensionTest, Valid)
{ {
const char* str = "#extension foo : bar\n"; const char* str = "#extension foo : bar\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_; using testing::_;
EXPECT_CALL(mDirectiveHandler, EXPECT_CALL(mDirectiveHandler,
...@@ -40,7 +31,7 @@ TEST_F(ExtensionTest, Valid) ...@@ -40,7 +31,7 @@ TEST_F(ExtensionTest, Valid)
// No error or warning. // No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0); EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
lex(); preprocess(str);
} }
TEST_F(ExtensionTest, Comments) TEST_F(ExtensionTest, Comments)
...@@ -58,7 +49,6 @@ TEST_F(ExtensionTest, Comments) ...@@ -58,7 +49,6 @@ TEST_F(ExtensionTest, Comments)
"/*foo*/" "/*foo*/"
"//foo" "//foo"
"\n"; "\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_; using testing::_;
EXPECT_CALL(mDirectiveHandler, EXPECT_CALL(mDirectiveHandler,
...@@ -66,13 +56,12 @@ TEST_F(ExtensionTest, Comments) ...@@ -66,13 +56,12 @@ TEST_F(ExtensionTest, Comments)
// No error or warning. // No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0); EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
lex(); preprocess(str);
} }
TEST_F(ExtensionTest, MissingNewline) TEST_F(ExtensionTest, MissingNewline)
{ {
const char* str = "#extension foo : bar"; const char* str = "#extension foo : bar";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_; using testing::_;
// Directive successfully parsed. // Directive successfully parsed.
...@@ -81,9 +70,11 @@ TEST_F(ExtensionTest, MissingNewline) ...@@ -81,9 +70,11 @@ TEST_F(ExtensionTest, MissingNewline)
// Error reported about EOF. // Error reported about EOF.
EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::EOF_IN_DIRECTIVE, _, _)); EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::EOF_IN_DIRECTIVE, _, _));
lex(); preprocess(str);
} }
#if GTEST_HAS_PARAM_TEST
struct ExtensionTestParam struct ExtensionTestParam
{ {
const char* str; const char* str;
...@@ -99,7 +90,6 @@ class InvalidExtensionTest : public ExtensionTest, ...@@ -99,7 +90,6 @@ class InvalidExtensionTest : public ExtensionTest,
TEST_P(InvalidExtensionTest, Identified) TEST_P(InvalidExtensionTest, Identified)
{ {
ExtensionTestParam param = GetParam(); ExtensionTestParam param = GetParam();
ASSERT_TRUE(mPreprocessor.init(1, &param.str, NULL));
using testing::_; using testing::_;
// No handleExtension call. // No handleExtension call.
...@@ -107,7 +97,7 @@ TEST_P(InvalidExtensionTest, Identified) ...@@ -107,7 +97,7 @@ TEST_P(InvalidExtensionTest, Identified)
// Invalid extension directive call. // Invalid extension directive call.
EXPECT_CALL(mDiagnostics, print(param.id, pp::SourceLocation(0, 1), _)); EXPECT_CALL(mDiagnostics, print(param.id, pp::SourceLocation(0, 1), _));
lex(); preprocess(param.str);
} }
static const ExtensionTestParam kParams[] = { static const ExtensionTestParam kParams[] = {
...@@ -119,3 +109,5 @@ static const ExtensionTestParam kParams[] = { ...@@ -119,3 +109,5 @@ static const ExtensionTestParam kParams[] = {
{"#extension foo : bar baz\n", pp::Diagnostics::UNEXPECTED_TOKEN} {"#extension foo : bar baz\n", pp::Diagnostics::UNEXPECTED_TOKEN}
}; };
INSTANTIATE_TEST_CASE_P(All, InvalidExtensionTest, testing::ValuesIn(kParams)); INSTANTIATE_TEST_CASE_P(All, InvalidExtensionTest, testing::ValuesIn(kParams));
#endif // GTEST_HAS_PARAM_TEST
\ No newline at end of file
...@@ -4,132 +4,145 @@ ...@@ -4,132 +4,145 @@
// found in the LICENSE file. // found in the LICENSE file.
// //
#include "gtest/gtest.h" #include "PreprocessorTest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "Token.h" #include "Token.h"
static void PreprocessAndVerifyIdentifier(const char* str) class IdentifierTest : public PreprocessorTest
{ {
MockDiagnostics diagnostics; protected:
MockDirectiveHandler directiveHandler; void preprocess(const std::string& str)
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler); {
ASSERT_TRUE(preprocessor.init(1, &str, 0)); const char* cstr = str.c_str();
ASSERT_TRUE(mPreprocessor.init(1, &cstr, 0));
pp::Token token; pp::Token token;
preprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type); EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ(str, token.value); EXPECT_EQ(str, token.value);
} }
};
#if GTEST_HAS_COMBINE #if GTEST_HAS_PARAM_TEST
typedef std::tr1::tuple<char, char> IdentifierParams; #define CLOSED_RANGE(x, y) testing::Range(x, static_cast<char>((y) + 1))
class IdentifierTest : public testing::TestWithParam<IdentifierParams>
class SingleLetterIdentifierTest : public IdentifierTest,
public testing::WithParamInterface<char>
{ {
}; };
// This test covers identifier names of form [_a-zA-Z][_a-zA-Z0-9]?. // This test covers identifier names of form [_a-zA-Z].
TEST_P(IdentifierTest, IdentifierIdentified) TEST_P(SingleLetterIdentifierTest, Identified)
{ {
std::string str(1, std::tr1::get<0>(GetParam())); std::string str(1, GetParam());
char c = std::tr1::get<1>(GetParam()); preprocess(str);
if (c != '\0') str.push_back(c);
PreprocessAndVerifyIdentifier(str.c_str());
} }
#define CLOSED_RANGE(x, y) testing::Range(x, static_cast<char>((y) + 1))
// Test string: '_' // Test string: '_'
INSTANTIATE_TEST_CASE_P(SingleLetter_Underscore, INSTANTIATE_TEST_CASE_P(Underscore,
IdentifierTest, SingleLetterIdentifierTest,
testing::Combine(testing::Values('_'), testing::Values('_'));
testing::Values('\0')));
// Test string: [a-z] // Test string: [a-z]
INSTANTIATE_TEST_CASE_P(SingleLetter_a_z, INSTANTIATE_TEST_CASE_P(a_z,
IdentifierTest, SingleLetterIdentifierTest,
testing::Combine(CLOSED_RANGE('a', 'z'), CLOSED_RANGE('a', 'z'));
testing::Values('\0')));
// Test string: [A-Z] // Test string: [A-Z]
INSTANTIATE_TEST_CASE_P(SingleLetter_A_Z, INSTANTIATE_TEST_CASE_P(A_Z,
IdentifierTest, SingleLetterIdentifierTest,
testing::Combine(CLOSED_RANGE('A', 'Z'), CLOSED_RANGE('A', 'Z'));
testing::Values('\0')));
#endif // GTEST_HAS_PARAM_TEST
#if GTEST_HAS_COMBINE
typedef std::tr1::tuple<char, char> IdentifierParams;
class DoubleLetterIdentifierTest :
public IdentifierTest,
public testing::WithParamInterface<IdentifierParams>
{
};
// This test covers identifier names of form [_a-zA-Z][_a-zA-Z0-9].
TEST_P(DoubleLetterIdentifierTest, Identified)
{
std::string str;
str.push_back(std::tr1::get<0>(GetParam()));
str.push_back(std::tr1::get<1>(GetParam()));
preprocess(str);
}
// Test string: "__" // Test string: "__"
INSTANTIATE_TEST_CASE_P(DoubleLetter_Underscore_Underscore, INSTANTIATE_TEST_CASE_P(Underscore_Underscore,
IdentifierTest, DoubleLetterIdentifierTest,
testing::Combine(testing::Values('_'), testing::Combine(testing::Values('_'),
testing::Values('_'))); testing::Values('_')));
// Test string: "_"[a-z] // Test string: "_"[a-z]
INSTANTIATE_TEST_CASE_P(DoubleLetter_Underscore_a_z, INSTANTIATE_TEST_CASE_P(Underscore_a_z,
IdentifierTest, DoubleLetterIdentifierTest,
testing::Combine(testing::Values('_'), testing::Combine(testing::Values('_'),
CLOSED_RANGE('a', 'z'))); CLOSED_RANGE('a', 'z')));
// Test string: "_"[A-Z] // Test string: "_"[A-Z]
INSTANTIATE_TEST_CASE_P(DoubleLetter_Underscore_A_Z, INSTANTIATE_TEST_CASE_P(Underscore_A_Z,
IdentifierTest, DoubleLetterIdentifierTest,
testing::Combine(testing::Values('_'), testing::Combine(testing::Values('_'),
CLOSED_RANGE('A', 'Z'))); CLOSED_RANGE('A', 'Z')));
// Test string: "_"[0-9] // Test string: "_"[0-9]
INSTANTIATE_TEST_CASE_P(DoubleLetter_Underscore_0_9, INSTANTIATE_TEST_CASE_P(Underscore_0_9,
IdentifierTest, DoubleLetterIdentifierTest,
testing::Combine(testing::Values('_'), testing::Combine(testing::Values('_'),
CLOSED_RANGE('0', '9'))); CLOSED_RANGE('0', '9')));
// Test string: [a-z]"_" // Test string: [a-z]"_"
INSTANTIATE_TEST_CASE_P(DoubleLetter_a_z_Underscore, INSTANTIATE_TEST_CASE_P(a_z_Underscore,
IdentifierTest, DoubleLetterIdentifierTest,
testing::Combine(CLOSED_RANGE('a', 'z'), testing::Combine(CLOSED_RANGE('a', 'z'),
testing::Values('_'))); testing::Values('_')));
// Test string: [a-z][a-z] // Test string: [a-z][a-z]
INSTANTIATE_TEST_CASE_P(DoubleLetter_a_z_a_z, INSTANTIATE_TEST_CASE_P(a_z_a_z,
IdentifierTest, DoubleLetterIdentifierTest,
testing::Combine(CLOSED_RANGE('a', 'z'), testing::Combine(CLOSED_RANGE('a', 'z'),
CLOSED_RANGE('a', 'z'))); CLOSED_RANGE('a', 'z')));
// Test string: [a-z][A-Z] // Test string: [a-z][A-Z]
INSTANTIATE_TEST_CASE_P(DoubleLetter_a_z_A_Z, INSTANTIATE_TEST_CASE_P(a_z_A_Z,
IdentifierTest, DoubleLetterIdentifierTest,
testing::Combine(CLOSED_RANGE('a', 'z'), testing::Combine(CLOSED_RANGE('a', 'z'),
CLOSED_RANGE('A', 'Z'))); CLOSED_RANGE('A', 'Z')));
// Test string: [a-z][0-9] // Test string: [a-z][0-9]
INSTANTIATE_TEST_CASE_P(DoubleLetter_a_z_0_9, INSTANTIATE_TEST_CASE_P(a_z_0_9,
IdentifierTest, DoubleLetterIdentifierTest,
testing::Combine(CLOSED_RANGE('a', 'z'), testing::Combine(CLOSED_RANGE('a', 'z'),
CLOSED_RANGE('0', '9'))); CLOSED_RANGE('0', '9')));
// Test string: [A-Z]"_" // Test string: [A-Z]"_"
INSTANTIATE_TEST_CASE_P(DoubleLetter_A_Z_Underscore, INSTANTIATE_TEST_CASE_P(A_Z_Underscore,
IdentifierTest, DoubleLetterIdentifierTest,
testing::Combine(CLOSED_RANGE('A', 'Z'), testing::Combine(CLOSED_RANGE('A', 'Z'),
testing::Values('_'))); testing::Values('_')));
// Test string: [A-Z][a-z] // Test string: [A-Z][a-z]
INSTANTIATE_TEST_CASE_P(DoubleLetter_A_Z_a_z, INSTANTIATE_TEST_CASE_P(A_Z_a_z,
IdentifierTest, DoubleLetterIdentifierTest,
testing::Combine(CLOSED_RANGE('A', 'Z'), testing::Combine(CLOSED_RANGE('A', 'Z'),
CLOSED_RANGE('a', 'z'))); CLOSED_RANGE('a', 'z')));
// Test string: [A-Z][A-Z] // Test string: [A-Z][A-Z]
INSTANTIATE_TEST_CASE_P(DoubleLetter_A_Z_A_Z, INSTANTIATE_TEST_CASE_P(A_Z_A_Z,
IdentifierTest, DoubleLetterIdentifierTest,
testing::Combine(CLOSED_RANGE('A', 'Z'), testing::Combine(CLOSED_RANGE('A', 'Z'),
CLOSED_RANGE('A', 'Z'))); CLOSED_RANGE('A', 'Z')));
// Test string: [A-Z][0-9] // Test string: [A-Z][0-9]
INSTANTIATE_TEST_CASE_P(DoubleLetter_A_Z_0_9, INSTANTIATE_TEST_CASE_P(A_Z_0_9,
IdentifierTest, DoubleLetterIdentifierTest,
testing::Combine(CLOSED_RANGE('A', 'Z'), testing::Combine(CLOSED_RANGE('A', 'Z'),
CLOSED_RANGE('0', '9'))); CLOSED_RANGE('0', '9')));
...@@ -137,7 +150,7 @@ INSTANTIATE_TEST_CASE_P(DoubleLetter_A_Z_0_9, ...@@ -137,7 +150,7 @@ INSTANTIATE_TEST_CASE_P(DoubleLetter_A_Z_0_9,
// The tests above cover one-letter and various combinations of two-letter // The tests above cover one-letter and various combinations of two-letter
// identifier names. This test covers all characters in a single string. // identifier names. This test covers all characters in a single string.
TEST(IdentifierTestAllCharacters, IdentifierIdentified) TEST_F(IdentifierTest, AllLetters)
{ {
std::string str; std::string str;
for (int c = 'a'; c <= 'z'; ++c) for (int c = 'a'; c <= 'z'; ++c)
...@@ -153,5 +166,5 @@ TEST(IdentifierTestAllCharacters, IdentifierIdentified) ...@@ -153,5 +166,5 @@ TEST(IdentifierTestAllCharacters, IdentifierIdentified)
for (int c = '0'; c <= '9'; ++c) for (int c = '0'; c <= '9'; ++c)
str.push_back(c); str.push_back(c);
PreprocessAndVerifyIdentifier(str.c_str()); preprocess(str);
} }
...@@ -4,39 +4,30 @@ ...@@ -4,39 +4,30 @@
// found in the LICENSE file. // found in the LICENSE file.
// //
#include "gtest/gtest.h" #include "PreprocessorTest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "Token.h" #include "Token.h"
TEST(InputTest, NegativeCount) class InitTest : public PreprocessorTest
{
};
TEST_F(InitTest, NegativeCount)
{ {
MockDiagnostics diagnostics; EXPECT_FALSE(mPreprocessor.init(-1, NULL, NULL));
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
EXPECT_FALSE(preprocessor.init(-1, NULL, NULL));
} }
TEST(InputTest, ZeroCount) TEST_F(InitTest, ZeroCount)
{ {
MockDiagnostics diagnostics; EXPECT_TRUE(mPreprocessor.init(0, NULL, NULL));
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
EXPECT_TRUE(preprocessor.init(0, NULL, NULL));
pp::Token token; pp::Token token;
preprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::LAST, token.type); EXPECT_EQ(pp::Token::LAST, token.type);
} }
TEST(InputTest, NullString) TEST_F(InitTest, NullString)
{ {
MockDiagnostics diagnostics; EXPECT_FALSE(mPreprocessor.init(1, NULL, NULL));
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
EXPECT_FALSE(preprocessor.init(1, NULL, NULL));
} }
TEST(InputTest, DefaultConstructor) TEST(InputTest, DefaultConstructor)
......
...@@ -4,33 +4,30 @@ ...@@ -4,33 +4,30 @@
// found in the LICENSE file. // found in the LICENSE file.
// //
#include "gtest/gtest.h" #include "PreprocessorTest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "Token.h" #include "Token.h"
static void PreprocessAndVerifyLocation(int count, class LocationTest : public PreprocessorTest
{
protected:
void preprocess(int count,
const char* const string[], const char* const string[],
const int length[], const int length[],
const pp::SourceLocation& location) const pp::SourceLocation& location)
{ {
MockDiagnostics diagnostics; ASSERT_TRUE(mPreprocessor.init(count, string, length));
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
ASSERT_TRUE(preprocessor.init(count, string, length));
pp::Token token; pp::Token token;
preprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type); EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ("foo", token.value); EXPECT_EQ("foo", token.value);
EXPECT_EQ(location.file, token.location.file); EXPECT_EQ(location.file, token.location.file);
EXPECT_EQ(location.line, token.location.line); EXPECT_EQ(location.line, token.location.line);
} }
};
TEST(LocationTest, String0_Line1) TEST_F(LocationTest, String0_Line1)
{ {
const char* str = "foo"; const char* str = "foo";
pp::SourceLocation loc; pp::SourceLocation loc;
...@@ -38,10 +35,10 @@ TEST(LocationTest, String0_Line1) ...@@ -38,10 +35,10 @@ TEST(LocationTest, String0_Line1)
loc.line = 1; loc.line = 1;
SCOPED_TRACE("String0_Line1"); SCOPED_TRACE("String0_Line1");
PreprocessAndVerifyLocation(1, &str, 0, loc); preprocess(1, &str, 0, loc);
} }
TEST(LocationTest, String0_Line2) TEST_F(LocationTest, String0_Line2)
{ {
const char* str = "\nfoo"; const char* str = "\nfoo";
pp::SourceLocation loc; pp::SourceLocation loc;
...@@ -49,10 +46,10 @@ TEST(LocationTest, String0_Line2) ...@@ -49,10 +46,10 @@ TEST(LocationTest, String0_Line2)
loc.line = 2; loc.line = 2;
SCOPED_TRACE("String0_Line2"); SCOPED_TRACE("String0_Line2");
PreprocessAndVerifyLocation(1, &str, 0, loc); preprocess(1, &str, 0, loc);
} }
TEST(LocationTest, String1_Line1) TEST_F(LocationTest, String1_Line1)
{ {
const char* const str[] = {"\n\n", "foo"}; const char* const str[] = {"\n\n", "foo"};
pp::SourceLocation loc; pp::SourceLocation loc;
...@@ -60,10 +57,10 @@ TEST(LocationTest, String1_Line1) ...@@ -60,10 +57,10 @@ TEST(LocationTest, String1_Line1)
loc.line = 1; loc.line = 1;
SCOPED_TRACE("String1_Line1"); SCOPED_TRACE("String1_Line1");
PreprocessAndVerifyLocation(2, str, 0, loc); preprocess(2, str, 0, loc);
} }
TEST(LocationTest, String1_Line2) TEST_F(LocationTest, String1_Line2)
{ {
const char* const str[] = {"\n\n", "\nfoo"}; const char* const str[] = {"\n\n", "\nfoo"};
pp::SourceLocation loc; pp::SourceLocation loc;
...@@ -71,10 +68,10 @@ TEST(LocationTest, String1_Line2) ...@@ -71,10 +68,10 @@ TEST(LocationTest, String1_Line2)
loc.line = 2; loc.line = 2;
SCOPED_TRACE("String1_Line2"); SCOPED_TRACE("String1_Line2");
PreprocessAndVerifyLocation(2, str, 0, loc); preprocess(2, str, 0, loc);
} }
TEST(LocationTest, NewlineInsideCommentCounted) TEST_F(LocationTest, NewlineInsideCommentCounted)
{ {
const char* str = "/*\n\n*/foo"; const char* str = "/*\n\n*/foo";
pp::SourceLocation loc; pp::SourceLocation loc;
...@@ -82,30 +79,26 @@ TEST(LocationTest, NewlineInsideCommentCounted) ...@@ -82,30 +79,26 @@ TEST(LocationTest, NewlineInsideCommentCounted)
loc.line = 3; loc.line = 3;
SCOPED_TRACE("NewlineInsideCommentCounted"); SCOPED_TRACE("NewlineInsideCommentCounted");
PreprocessAndVerifyLocation(1, &str, 0, loc); preprocess(1, &str, 0, loc);
} }
TEST(LocationTest, ErrorLocationAfterComment) TEST_F(LocationTest, ErrorLocationAfterComment)
{ {
const char* str = "/*\n\n*/@"; const char* str = "/*\n\n*/@";
MockDiagnostics diagnostics; ASSERT_TRUE(mPreprocessor.init(1, &str, 0));
MockDirectiveHandler directiveHandler; EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::INVALID_CHARACTER,
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler); pp::SourceLocation(0, 3),
ASSERT_TRUE(preprocessor.init(1, &str, 0)); "@"));
pp::Diagnostics::ID id(pp::Diagnostics::INVALID_CHARACTER);
pp::SourceLocation loc(0, 3);
EXPECT_CALL(diagnostics, print(id, loc, "@"));
pp::Token token; pp::Token token;
preprocessor.lex(&token); mPreprocessor.lex(&token);
} }
// The location of a token straddling two or more strings is that of the // The location of a token straddling two or more strings is that of the
// first character of the token. // first character of the token.
TEST(LocationTest, TokenStraddlingTwoStrings) TEST_F(LocationTest, TokenStraddlingTwoStrings)
{ {
const char* const str[] = {"f", "oo"}; const char* const str[] = {"f", "oo"};
pp::SourceLocation loc; pp::SourceLocation loc;
...@@ -113,10 +106,10 @@ TEST(LocationTest, TokenStraddlingTwoStrings) ...@@ -113,10 +106,10 @@ TEST(LocationTest, TokenStraddlingTwoStrings)
loc.line = 1; loc.line = 1;
SCOPED_TRACE("TokenStraddlingTwoStrings"); SCOPED_TRACE("TokenStraddlingTwoStrings");
PreprocessAndVerifyLocation(2, str, 0, loc); preprocess(2, str, 0, loc);
} }
TEST(LocationTest, TokenStraddlingThreeStrings) TEST_F(LocationTest, TokenStraddlingThreeStrings)
{ {
const char* const str[] = {"f", "o", "o"}; const char* const str[] = {"f", "o", "o"};
pp::SourceLocation loc; pp::SourceLocation loc;
...@@ -124,7 +117,7 @@ TEST(LocationTest, TokenStraddlingThreeStrings) ...@@ -124,7 +117,7 @@ TEST(LocationTest, TokenStraddlingThreeStrings)
loc.line = 1; loc.line = 1;
SCOPED_TRACE("TokenStraddlingThreeStrings"); SCOPED_TRACE("TokenStraddlingThreeStrings");
PreprocessAndVerifyLocation(3, str, 0, loc); preprocess(3, str, 0, loc);
} }
// TODO(alokp): Add tests for #line directives. // TODO(alokp): Add tests for #line directives.
...@@ -4,33 +4,26 @@ ...@@ -4,33 +4,26 @@
// found in the LICENSE file. // found in the LICENSE file.
// //
#include "gtest/gtest.h" #include "PreprocessorTest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "Token.h" #include "Token.h"
#if GTEST_HAS_PARAM_TEST #if GTEST_HAS_PARAM_TEST
class InvalidNumberTest : public testing::TestWithParam<const char*> class InvalidNumberTest : public PreprocessorTest,
public testing::WithParamInterface<const char*>
{ {
}; };
TEST_P(InvalidNumberTest, InvalidNumberIdentified) TEST_P(InvalidNumberTest, InvalidNumberIdentified)
{ {
const char* str = GetParam(); const char* str = GetParam();
ASSERT_TRUE(mPreprocessor.init(1, &str, 0));
MockDiagnostics diagnostics;
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
ASSERT_TRUE(preprocessor.init(1, &str, 0));
using testing::_; using testing::_;
EXPECT_CALL(diagnostics, print(pp::Diagnostics::INVALID_NUMBER, _, str)); EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::INVALID_NUMBER, _, str));
pp::Token token; pp::Token token;
preprocessor.lex(&token); mPreprocessor.lex(&token);
} }
INSTANTIATE_TEST_CASE_P(InvalidIntegers, InvalidNumberTest, INSTANTIATE_TEST_CASE_P(InvalidIntegers, InvalidNumberTest,
...@@ -45,23 +38,21 @@ INSTANTIATE_TEST_CASE_P(InvalidFloats, InvalidNumberTest, ...@@ -45,23 +38,21 @@ INSTANTIATE_TEST_CASE_P(InvalidFloats, InvalidNumberTest,
#if GTEST_HAS_COMBINE #if GTEST_HAS_COMBINE
typedef std::tr1::tuple<const char*, char> IntegerParams; typedef std::tr1::tuple<const char*, char> IntegerParams;
class IntegerTest : public testing::TestWithParam<IntegerParams> class IntegerTest : public PreprocessorTest,
public testing::WithParamInterface<IntegerParams>
{ {
}; };
TEST_P(IntegerTest, IntegerIdentified) TEST_P(IntegerTest, Identified)
{ {
std::string str(std::tr1::get<0>(GetParam())); // prefix. std::string str(std::tr1::get<0>(GetParam())); // prefix.
str.push_back(std::tr1::get<1>(GetParam())); // digit. str.push_back(std::tr1::get<1>(GetParam())); // digit.
const char* cstr = str.c_str(); const char* cstr = str.c_str();
MockDiagnostics diagnostics; ASSERT_TRUE(mPreprocessor.init(1, &cstr, 0));
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
ASSERT_TRUE(preprocessor.init(1, &cstr, 0));
pp::Token token; pp::Token token;
preprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::CONST_INT, token.type); EXPECT_EQ(pp::Token::CONST_INT, token.type);
EXPECT_EQ(str, token.value); EXPECT_EQ(str, token.value);
} }
...@@ -93,21 +84,25 @@ INSTANTIATE_TEST_CASE_P(HexadecimalInteger_A_F, ...@@ -93,21 +84,25 @@ INSTANTIATE_TEST_CASE_P(HexadecimalInteger_A_F,
testing::Combine(testing::Values("0x"), testing::Combine(testing::Values("0x"),
CLOSED_RANGE('A', 'F'))); CLOSED_RANGE('A', 'F')));
static void PreprocessAndVerifyFloat(const char* str) class FloatTest : public PreprocessorTest
{ {
MockDiagnostics diagnostics; protected:
MockDirectiveHandler directiveHandler; void preprocess(const std::string& str)
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler); {
ASSERT_TRUE(preprocessor.init(1, &str, 0)); const char* cstr = str.c_str();
ASSERT_TRUE(mPreprocessor.init(1, &cstr, 0));
pp::Token token; pp::Token token;
preprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::CONST_FLOAT, token.type); EXPECT_EQ(pp::Token::CONST_FLOAT, token.type);
EXPECT_EQ(str, token.value); EXPECT_EQ(str, token.value);
} }
};
typedef std::tr1::tuple<char, char, const char*, char> FloatScientificParams; typedef std::tr1::tuple<char, char, const char*, char> FloatScientificParams;
class FloatScientificTest : public testing::TestWithParam<FloatScientificParams> class FloatScientificTest :
public FloatTest,
public testing::WithParamInterface<FloatScientificParams>
{ {
}; };
...@@ -121,7 +116,7 @@ TEST_P(FloatScientificTest, FloatIdentified) ...@@ -121,7 +116,7 @@ TEST_P(FloatScientificTest, FloatIdentified)
str.push_back(std::tr1::get<3>(GetParam())); // exponent [0-9]. str.push_back(std::tr1::get<3>(GetParam())); // exponent [0-9].
SCOPED_TRACE("FloatScientificTest"); SCOPED_TRACE("FloatScientificTest");
PreprocessAndVerifyFloat(str.c_str()); preprocess(str);
} }
INSTANTIATE_TEST_CASE_P(FloatScientific, INSTANTIATE_TEST_CASE_P(FloatScientific,
...@@ -132,7 +127,9 @@ INSTANTIATE_TEST_CASE_P(FloatScientific, ...@@ -132,7 +127,9 @@ INSTANTIATE_TEST_CASE_P(FloatScientific,
CLOSED_RANGE('0', '9'))); CLOSED_RANGE('0', '9')));
typedef std::tr1::tuple<char, char> FloatFractionParams; typedef std::tr1::tuple<char, char> FloatFractionParams;
class FloatFractionTest : public testing::TestWithParam<FloatFractionParams> class FloatFractionTest :
public FloatTest,
public testing::WithParamInterface<FloatFractionParams>
{ {
}; };
...@@ -152,7 +149,7 @@ TEST_P(FloatFractionTest, FloatIdentified) ...@@ -152,7 +149,7 @@ TEST_P(FloatFractionTest, FloatIdentified)
str.push_back(fraction); str.push_back(fraction);
SCOPED_TRACE("FloatFractionTest"); SCOPED_TRACE("FloatFractionTest");
PreprocessAndVerifyFloat(str.c_str()); preprocess(str);
} }
INSTANTIATE_TEST_CASE_P(FloatFraction_X_X, INSTANTIATE_TEST_CASE_P(FloatFraction_X_X,
...@@ -174,9 +171,8 @@ INSTANTIATE_TEST_CASE_P(FloatFraction_X_0, ...@@ -174,9 +171,8 @@ INSTANTIATE_TEST_CASE_P(FloatFraction_X_0,
// In the tests above we have tested individual parts of a float separately. // In the tests above we have tested individual parts of a float separately.
// This test has all parts of a float. // This test has all parts of a float.
TEST_F(FloatTest, FractionScientific)
TEST(FloatFractionScientificTest, FloatIdentified)
{ {
SCOPED_TRACE("FloatFractionScientificTest"); SCOPED_TRACE("FractionScientific");
PreprocessAndVerifyFloat("0.1e+2"); preprocess("0.1e+2");
} }
...@@ -4,11 +4,7 @@ ...@@ -4,11 +4,7 @@
// found in the LICENSE file. // found in the LICENSE file.
// //
#include "gtest/gtest.h" #include "PreprocessorTest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "Token.h" #include "Token.h"
#if GTEST_HAS_PARAM_TEST #if GTEST_HAS_PARAM_TEST
...@@ -19,7 +15,8 @@ struct OperatorTestParam ...@@ -19,7 +15,8 @@ struct OperatorTestParam
int op; int op;
}; };
class OperatorTest : public testing::TestWithParam<OperatorTestParam> class OperatorTest : public PreprocessorTest,
public testing::WithParamInterface<OperatorTestParam>
{ {
}; };
...@@ -27,13 +24,10 @@ TEST_P(OperatorTest, Identified) ...@@ -27,13 +24,10 @@ TEST_P(OperatorTest, Identified)
{ {
OperatorTestParam param = GetParam(); OperatorTestParam param = GetParam();
MockDiagnostics diagnostics; ASSERT_TRUE(mPreprocessor.init(1, &param.str, 0));
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
ASSERT_TRUE(preprocessor.init(1, &param.str, 0));
pp::Token token; pp::Token token;
preprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(param.op, token.type); EXPECT_EQ(param.op, token.type);
EXPECT_EQ(param.str, token.value); EXPECT_EQ(param.str, token.value);
} }
......
...@@ -4,35 +4,26 @@ ...@@ -4,35 +4,26 @@
// found in the LICENSE file. // found in the LICENSE file.
// //
#include "gtest/gtest.h" #include "PreprocessorTest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "Token.h" #include "Token.h"
class PragmaTest : public testing::Test class PragmaTest : public PreprocessorTest
{ {
protected: protected:
PragmaTest() : mPreprocessor(&mDiagnostics, &mDirectiveHandler) { } void preprocess(const char* str)
void lex()
{ {
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
pp::Token token; pp::Token token;
mPreprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::LAST, token.type); EXPECT_EQ(pp::Token::LAST, token.type);
EXPECT_EQ("", token.value); EXPECT_EQ("", token.value);
} }
MockDiagnostics mDiagnostics;
MockDirectiveHandler mDirectiveHandler;
pp::Preprocessor mPreprocessor;
}; };
TEST_F(PragmaTest, EmptyName) TEST_F(PragmaTest, EmptyName)
{ {
const char* str = "#pragma\n"; const char* str = "#pragma\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_; using testing::_;
// No handlePragma calls. // No handlePragma calls.
...@@ -40,13 +31,12 @@ TEST_F(PragmaTest, EmptyName) ...@@ -40,13 +31,12 @@ TEST_F(PragmaTest, EmptyName)
// No error or warning. // No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0); EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
lex(); preprocess(str);
} }
TEST_F(PragmaTest, EmptyValue) TEST_F(PragmaTest, EmptyValue)
{ {
const char* str = "#pragma foo\n"; const char* str = "#pragma foo\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_; using testing::_;
EXPECT_CALL(mDirectiveHandler, EXPECT_CALL(mDirectiveHandler,
...@@ -54,13 +44,12 @@ TEST_F(PragmaTest, EmptyValue) ...@@ -54,13 +44,12 @@ TEST_F(PragmaTest, EmptyValue)
// No error or warning. // No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0); EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
lex(); preprocess(str);
} }
TEST_F(PragmaTest, NameValue) TEST_F(PragmaTest, NameValue)
{ {
const char* str = "#pragma foo(bar)\n"; const char* str = "#pragma foo(bar)\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_; using testing::_;
EXPECT_CALL(mDirectiveHandler, EXPECT_CALL(mDirectiveHandler,
...@@ -68,7 +57,7 @@ TEST_F(PragmaTest, NameValue) ...@@ -68,7 +57,7 @@ TEST_F(PragmaTest, NameValue)
// No error or warning. // No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0); EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
lex(); preprocess(str);
} }
TEST_F(PragmaTest, Comments) TEST_F(PragmaTest, Comments)
...@@ -88,7 +77,6 @@ TEST_F(PragmaTest, Comments) ...@@ -88,7 +77,6 @@ TEST_F(PragmaTest, Comments)
"/*foo*/" "/*foo*/"
"//foo" "//foo"
"\n"; "\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_; using testing::_;
EXPECT_CALL(mDirectiveHandler, EXPECT_CALL(mDirectiveHandler,
...@@ -96,13 +84,12 @@ TEST_F(PragmaTest, Comments) ...@@ -96,13 +84,12 @@ TEST_F(PragmaTest, Comments)
// No error or warning. // No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0); EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
lex(); preprocess(str);
} }
TEST_F(PragmaTest, MissingNewline) TEST_F(PragmaTest, MissingNewline)
{ {
const char* str = "#pragma foo(bar)"; const char* str = "#pragma foo(bar)";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_; using testing::_;
// Pragma successfully parsed. // Pragma successfully parsed.
...@@ -111,9 +98,11 @@ TEST_F(PragmaTest, MissingNewline) ...@@ -111,9 +98,11 @@ TEST_F(PragmaTest, MissingNewline)
// Error reported about EOF. // Error reported about EOF.
EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::EOF_IN_DIRECTIVE, _, _)); EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::EOF_IN_DIRECTIVE, _, _));
lex(); preprocess(str);
} }
#if GTEST_HAS_PARAM_TEST
class InvalidPragmaTest : public PragmaTest, class InvalidPragmaTest : public PragmaTest,
public testing::WithParamInterface<const char*> public testing::WithParamInterface<const char*>
{ {
...@@ -122,7 +111,6 @@ class InvalidPragmaTest : public PragmaTest, ...@@ -122,7 +111,6 @@ class InvalidPragmaTest : public PragmaTest,
TEST_P(InvalidPragmaTest, Identified) TEST_P(InvalidPragmaTest, Identified)
{ {
const char* str = GetParam(); const char* str = GetParam();
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_; using testing::_;
// No handlePragma calls. // No handlePragma calls.
...@@ -132,7 +120,7 @@ TEST_P(InvalidPragmaTest, Identified) ...@@ -132,7 +120,7 @@ TEST_P(InvalidPragmaTest, Identified)
print(pp::Diagnostics::UNRECOGNIZED_PRAGMA, print(pp::Diagnostics::UNRECOGNIZED_PRAGMA,
pp::SourceLocation(0, 1), _)); pp::SourceLocation(0, 1), _));
lex(); preprocess(str);
} }
INSTANTIATE_TEST_CASE_P(All, InvalidPragmaTest, testing::Values( INSTANTIATE_TEST_CASE_P(All, InvalidPragmaTest, testing::Values(
...@@ -142,3 +130,5 @@ INSTANTIATE_TEST_CASE_P(All, InvalidPragmaTest, testing::Values( ...@@ -142,3 +130,5 @@ INSTANTIATE_TEST_CASE_P(All, InvalidPragmaTest, testing::Values(
"#pragma foo(bar\n", // Missing right paren. "#pragma foo(bar\n", // Missing right paren.
"#pragma foo bar\n", // Missing parens. "#pragma foo bar\n", // Missing parens.
"#pragma foo(bar) baz\n")); // Extra tokens. "#pragma foo(bar) baz\n")); // Extra tokens.
#endif // GTEST_HAS_PARAM_TEST
\ No newline at end of file
...@@ -4,13 +4,27 @@ ...@@ -4,13 +4,27 @@
// found in the LICENSE file. // found in the LICENSE file.
// //
#include "gtest/gtest.h" #include "PreprocessorTest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "Token.h" #include "Token.h"
class SpaceTest : public PreprocessorTest
{
protected:
void preprocess(const std::string& str)
{
const char* cstr = str.c_str();
ASSERT_TRUE(mPreprocessor.init(1, &cstr, 0));
pp::Token token;
// "foo" is returned after ignoring the whitespace characters.
mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ("foo", token.value);
// The whitespace character is however recorded with the next token.
EXPECT_TRUE(token.hasLeadingSpace());
}
};
// Whitespace characters allowed in GLSL. // Whitespace characters allowed in GLSL.
// Note that newline characters (\n) will be tested separately. // Note that newline characters (\n) will be tested separately.
static const char kSpaceChars[] = {' ', '\t', '\v', '\f'}; static const char kSpaceChars[] = {' ', '\t', '\v', '\f'};
...@@ -20,30 +34,18 @@ static const char kSpaceChars[] = {' ', '\t', '\v', '\f'}; ...@@ -20,30 +34,18 @@ static const char kSpaceChars[] = {' ', '\t', '\v', '\f'};
// This test fixture tests the processing of a single whitespace character. // This test fixture tests the processing of a single whitespace character.
// All tests in this fixture are ran with all possible whitespace character // All tests in this fixture are ran with all possible whitespace character
// allowed in GLSL. // allowed in GLSL.
class SpaceCharTest : public testing::TestWithParam<char> class SpaceCharTest : public SpaceTest,
public testing::WithParamInterface<char>
{ {
}; };
TEST_P(SpaceCharTest, SpaceIgnored) TEST_P(SpaceCharTest, SpaceIgnored)
{ {
// Construct test string with the whitespace char before "foo". // Construct test string with the whitespace char before "foo".
const char* identifier = "foo";
std::string str(1, GetParam()); std::string str(1, GetParam());
str.append(identifier); str.append("foo");
const char* cstr = str.c_str();
MockDiagnostics diagnostics; preprocess(str);
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
ASSERT_TRUE(preprocessor.init(1, &cstr, 0));
pp::Token token;
// Identifier "foo" is returned after ignoring the whitespace characters.
preprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ(identifier, token.value);
// The whitespace character is however recorded with the next token.
EXPECT_TRUE(token.hasLeadingSpace());
} }
INSTANTIATE_TEST_CASE_P(SingleSpaceChar, INSTANTIATE_TEST_CASE_P(SingleSpaceChar,
...@@ -58,32 +60,21 @@ INSTANTIATE_TEST_CASE_P(SingleSpaceChar, ...@@ -58,32 +60,21 @@ INSTANTIATE_TEST_CASE_P(SingleSpaceChar,
// whitespace characters. All tests in this fixture are ran with all possible // whitespace characters. All tests in this fixture are ran with all possible
// combinations of whitespace characters allowed in GLSL. // combinations of whitespace characters allowed in GLSL.
typedef std::tr1::tuple<char, char, char> SpaceStringParams; typedef std::tr1::tuple<char, char, char> SpaceStringParams;
class SpaceStringTest : public testing::TestWithParam<SpaceStringParams> class SpaceStringTest : public SpaceTest,
public testing::WithParamInterface<SpaceStringParams>
{ {
}; };
TEST_P(SpaceStringTest, SpaceIgnored) TEST_P(SpaceStringTest, SpaceIgnored)
{ {
// Construct test string with the whitespace char before "foo". // Construct test string with the whitespace char before "foo".
const char* identifier = "foo"; std::string str;
std::string str(1, std::tr1::get<0>(GetParam())); str.push_back(std::tr1::get<0>(GetParam()));
str.push_back(std::tr1::get<1>(GetParam())); str.push_back(std::tr1::get<1>(GetParam()));
str.push_back(std::tr1::get<2>(GetParam())); str.push_back(std::tr1::get<2>(GetParam()));
str.append(identifier); str.append("foo");
const char* cstr = str.c_str();
MockDiagnostics diagnostics; preprocess(str);
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
ASSERT_TRUE(preprocessor.init(1, &cstr, 0));
pp::Token token;
preprocessor.lex(&token);
// Identifier "foo" is returned after ignoring the whitespace characters.
EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ(identifier, token.value);
// The whitespace character is however recorded with the next token.
EXPECT_TRUE(token.hasLeadingSpace());
} }
INSTANTIATE_TEST_CASE_P(SpaceCharCombination, INSTANTIATE_TEST_CASE_P(SpaceCharCombination,
...@@ -97,30 +88,26 @@ INSTANTIATE_TEST_CASE_P(SpaceCharCombination, ...@@ -97,30 +88,26 @@ INSTANTIATE_TEST_CASE_P(SpaceCharCombination,
// The tests above make sure that the space char is recorded in the // The tests above make sure that the space char is recorded in the
// next token. This test makes sure that a token is not incorrectly marked // next token. This test makes sure that a token is not incorrectly marked
// to have leading space. // to have leading space.
TEST(SpaceTest, LeadingSpace) TEST_F(SpaceTest, LeadingSpace)
{ {
const char* str = " foo+ -bar"; const char* str = " foo+ -bar";
ASSERT_TRUE(mPreprocessor.init(1, &str, 0));
pp::Token token; pp::Token token;
MockDiagnostics diagnostics; mPreprocessor.lex(&token);
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
ASSERT_TRUE(preprocessor.init(1, &str, 0));
preprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type); EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ("foo", token.value); EXPECT_EQ("foo", token.value);
EXPECT_TRUE(token.hasLeadingSpace()); EXPECT_TRUE(token.hasLeadingSpace());
preprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ('+', token.type); EXPECT_EQ('+', token.type);
EXPECT_FALSE(token.hasLeadingSpace()); EXPECT_FALSE(token.hasLeadingSpace());
preprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ('-', token.type); EXPECT_EQ('-', token.type);
EXPECT_TRUE(token.hasLeadingSpace()); EXPECT_TRUE(token.hasLeadingSpace());
preprocessor.lex(&token); mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type); EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ("bar", token.value); EXPECT_EQ("bar", token.value);
EXPECT_FALSE(token.hasLeadingSpace()); EXPECT_FALSE(token.hasLeadingSpace());
......
...@@ -4,18 +4,12 @@ ...@@ -4,18 +4,12 @@
// found in the LICENSE file. // found in the LICENSE file.
// //
#include "gtest/gtest.h" #include "PreprocessorTest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "Token.h" #include "Token.h"
class VersionTest : public testing::Test class VersionTest : public PreprocessorTest
{ {
protected: protected:
VersionTest() : mPreprocessor(&mDiagnostics, &mDirectiveHandler) { }
void lex() void lex()
{ {
pp::Token token; pp::Token token;
...@@ -23,10 +17,6 @@ protected: ...@@ -23,10 +17,6 @@ protected:
EXPECT_EQ(pp::Token::LAST, token.type); EXPECT_EQ(pp::Token::LAST, token.type);
EXPECT_EQ("", token.value); EXPECT_EQ("", token.value);
} }
MockDiagnostics mDiagnostics;
MockDirectiveHandler mDirectiveHandler;
pp::Preprocessor mPreprocessor;
}; };
TEST_F(VersionTest, Valid) TEST_F(VersionTest, Valid)
...@@ -80,6 +70,8 @@ TEST_F(VersionTest, MissingNewline) ...@@ -80,6 +70,8 @@ TEST_F(VersionTest, MissingNewline)
lex(); lex();
} }
#if GTEST_HAS_PARAM_TEST
struct VersionTestParam struct VersionTestParam
{ {
const char* str; const char* str;
...@@ -112,3 +104,5 @@ static const VersionTestParam kParams[] = { ...@@ -112,3 +104,5 @@ static const VersionTestParam kParams[] = {
}; };
INSTANTIATE_TEST_CASE_P(All, InvalidVersionTest, testing::ValuesIn(kParams)); INSTANTIATE_TEST_CASE_P(All, InvalidVersionTest, testing::ValuesIn(kParams));
#endif // GTEST_HAS_PARAM_TEST
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment