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 @@
'preprocessor_tests/number_test.cpp',
'preprocessor_tests/operator_test.cpp',
'preprocessor_tests/pragma_test.cpp',
'preprocessor_tests/PreprocessorTest.h',
'preprocessor_tests/space_test.cpp',
'preprocessor_tests/token_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 @@
#include <algorithm>
#include <climits>
#include "gtest/gtest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "PreprocessorTest.h"
#include "Token.h"
#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)
const char* cstr = str.c_str();
int length = 1;
MockDiagnostics diagnostics;
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
// Note that we pass the length param as well because the invalid
// 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;
std::string expectedValue;
......@@ -89,12 +83,12 @@ TEST_P(CharTest, Identified)
{
// Everything else is invalid.
using testing::_;
EXPECT_CALL(diagnostics,
EXPECT_CALL(mDiagnostics,
print(pp::Diagnostics::INVALID_CHARACTER, _, str));
}
pp::Token token;
preprocessor.lex(&token);
mPreprocessor.lex(&token);
EXPECT_EQ(expectedType, token.type);
EXPECT_EQ(expectedValue, token.value);
};
......
......@@ -4,14 +4,13 @@
// found in the LICENSE file.
//
#include "gtest/gtest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "PreprocessorTest.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)
{
const char* str = GetParam();
MockDiagnostics diagnostics;
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
ASSERT_TRUE(preprocessor.init(1, &str, 0));
ASSERT_TRUE(mPreprocessor.init(1, &str, 0));
pp::Token token;
preprocessor.lex(&token);
mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::LAST, token.type);
}
......@@ -44,34 +40,34 @@ INSTANTIATE_TEST_CASE_P(BlockComment, CommentTest,
"/***/", // With lone '*'.
"/*\"*/")); // Invalid character.
TEST(BlockComment, CommentReplacedWithSpace)
#endif // GTEST_HAS_PARAM_TEST
class BlockCommentTest : public PreprocessorTest
{
};
TEST_F(BlockCommentTest, CommentReplacedWithSpace)
{
const char* str = "/*foo*/bar";
MockDiagnostics diagnostics;
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
ASSERT_TRUE(preprocessor.init(1, &str, 0));
ASSERT_TRUE(mPreprocessor.init(1, &str, 0));
pp::Token token;
preprocessor.lex(&token);
mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ("bar", token.value);
EXPECT_TRUE(token.hasLeadingSpace());
}
TEST(BlockComment, UnterminatedComment)
TEST_F(BlockCommentTest, UnterminatedComment)
{
const char* str = "/*foo";
MockDiagnostics diagnostics;
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
ASSERT_TRUE(preprocessor.init(1, &str, 0));
ASSERT_TRUE(mPreprocessor.init(1, &str, 0));
using testing::_;
EXPECT_CALL(diagnostics, print(pp::Diagnostics::EOF_IN_COMMENT, _, _));
EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::EOF_IN_COMMENT, _, _));
pp::Token token;
preprocessor.lex(&token);
mPreprocessor.lex(&token);
}
......@@ -4,48 +4,38 @@
// found in the LICENSE file.
//
#include "gtest/gtest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "PreprocessorTest.h"
#include "Token.h"
class ErrorTest : public testing::Test
class ErrorTest : public PreprocessorTest
{
protected:
ErrorTest() : mPreprocessor(&mDiagnostics, &mDirectiveHandler) { }
void lex()
void preprocess(const char* str)
{
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
pp::Token token;
mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::LAST, token.type);
EXPECT_EQ("", token.value);
}
MockDiagnostics mDiagnostics;
MockDirectiveHandler mDirectiveHandler;
pp::Preprocessor mPreprocessor;
};
TEST_F(ErrorTest, Empty)
{
const char* str = "#error\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_;
EXPECT_CALL(mDirectiveHandler, handleError(pp::SourceLocation(0, 1), ""));
// No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
lex();
preprocess(str);
}
TEST_F(ErrorTest, OneTokenMessage)
{
const char* str = "#error foo\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_;
EXPECT_CALL(mDirectiveHandler,
......@@ -53,13 +43,12 @@ TEST_F(ErrorTest, OneTokenMessage)
// No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
lex();
preprocess(str);
}
TEST_F(ErrorTest, TwoTokenMessage)
{
const char* str = "#error foo bar\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_;
EXPECT_CALL(mDirectiveHandler,
......@@ -67,7 +56,7 @@ TEST_F(ErrorTest, TwoTokenMessage)
// No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
lex();
preprocess(str);
}
TEST_F(ErrorTest, Comments)
......@@ -83,7 +72,6 @@ TEST_F(ErrorTest, Comments)
"/*foo*/"
"//foo"
"\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_;
EXPECT_CALL(mDirectiveHandler,
......@@ -91,13 +79,12 @@ TEST_F(ErrorTest, Comments)
// No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
lex();
preprocess(str);
}
TEST_F(ErrorTest, MissingNewline)
{
const char* str = "#error foo";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_;
// Directive successfully parsed.
......@@ -106,5 +93,5 @@ TEST_F(ErrorTest, MissingNewline)
// Error reported about EOF.
EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::EOF_IN_DIRECTIVE, _, _));
lex();
preprocess(str);
}
......@@ -4,35 +4,26 @@
// found in the LICENSE file.
//
#include "gtest/gtest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "PreprocessorTest.h"
#include "Token.h"
class ExtensionTest : public testing::Test
class ExtensionTest : public PreprocessorTest
{
protected:
ExtensionTest() : mPreprocessor(&mDiagnostics, &mDirectiveHandler) { }
void lex()
void preprocess(const char* str)
{
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
pp::Token token;
mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::LAST, token.type);
EXPECT_EQ("", token.value);
}
MockDiagnostics mDiagnostics;
MockDirectiveHandler mDirectiveHandler;
pp::Preprocessor mPreprocessor;
};
TEST_F(ExtensionTest, Valid)
{
const char* str = "#extension foo : bar\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_;
EXPECT_CALL(mDirectiveHandler,
......@@ -40,7 +31,7 @@ TEST_F(ExtensionTest, Valid)
// No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
lex();
preprocess(str);
}
TEST_F(ExtensionTest, Comments)
......@@ -58,7 +49,6 @@ TEST_F(ExtensionTest, Comments)
"/*foo*/"
"//foo"
"\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_;
EXPECT_CALL(mDirectiveHandler,
......@@ -66,13 +56,12 @@ TEST_F(ExtensionTest, Comments)
// No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
lex();
preprocess(str);
}
TEST_F(ExtensionTest, MissingNewline)
{
const char* str = "#extension foo : bar";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_;
// Directive successfully parsed.
......@@ -81,9 +70,11 @@ TEST_F(ExtensionTest, MissingNewline)
// Error reported about EOF.
EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::EOF_IN_DIRECTIVE, _, _));
lex();
preprocess(str);
}
#if GTEST_HAS_PARAM_TEST
struct ExtensionTestParam
{
const char* str;
......@@ -99,7 +90,6 @@ class InvalidExtensionTest : public ExtensionTest,
TEST_P(InvalidExtensionTest, Identified)
{
ExtensionTestParam param = GetParam();
ASSERT_TRUE(mPreprocessor.init(1, &param.str, NULL));
using testing::_;
// No handleExtension call.
......@@ -107,7 +97,7 @@ TEST_P(InvalidExtensionTest, Identified)
// Invalid extension directive call.
EXPECT_CALL(mDiagnostics, print(param.id, pp::SourceLocation(0, 1), _));
lex();
preprocess(param.str);
}
static const ExtensionTestParam kParams[] = {
......@@ -119,3 +109,5 @@ static const ExtensionTestParam kParams[] = {
{"#extension foo : bar baz\n", pp::Diagnostics::UNEXPECTED_TOKEN}
};
INSTANTIATE_TEST_CASE_P(All, InvalidExtensionTest, testing::ValuesIn(kParams));
#endif // GTEST_HAS_PARAM_TEST
\ No newline at end of file
......@@ -4,132 +4,145 @@
// found in the LICENSE file.
//
#include "gtest/gtest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "PreprocessorTest.h"
#include "Token.h"
static void PreprocessAndVerifyIdentifier(const char* str)
class IdentifierTest : public PreprocessorTest
{
MockDiagnostics diagnostics;
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
ASSERT_TRUE(preprocessor.init(1, &str, 0));
pp::Token token;
preprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ(str, token.value);
}
protected:
void preprocess(const std::string& str)
{
const char* cstr = str.c_str();
ASSERT_TRUE(mPreprocessor.init(1, &cstr, 0));
pp::Token token;
mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ(str, token.value);
}
};
#if GTEST_HAS_COMBINE
#if GTEST_HAS_PARAM_TEST
typedef std::tr1::tuple<char, char> IdentifierParams;
class IdentifierTest : public testing::TestWithParam<IdentifierParams>
#define CLOSED_RANGE(x, y) testing::Range(x, static_cast<char>((y) + 1))
class SingleLetterIdentifierTest : public IdentifierTest,
public testing::WithParamInterface<char>
{
};
// This test covers identifier names of form [_a-zA-Z][_a-zA-Z0-9]?.
TEST_P(IdentifierTest, IdentifierIdentified)
// This test covers identifier names of form [_a-zA-Z].
TEST_P(SingleLetterIdentifierTest, Identified)
{
std::string str(1, std::tr1::get<0>(GetParam()));
char c = std::tr1::get<1>(GetParam());
if (c != '\0') str.push_back(c);
PreprocessAndVerifyIdentifier(str.c_str());
std::string str(1, GetParam());
preprocess(str);
}
#define CLOSED_RANGE(x, y) testing::Range(x, static_cast<char>((y) + 1))
// Test string: '_'
INSTANTIATE_TEST_CASE_P(SingleLetter_Underscore,
IdentifierTest,
testing::Combine(testing::Values('_'),
testing::Values('\0')));
INSTANTIATE_TEST_CASE_P(Underscore,
SingleLetterIdentifierTest,
testing::Values('_'));
// Test string: [a-z]
INSTANTIATE_TEST_CASE_P(SingleLetter_a_z,
IdentifierTest,
testing::Combine(CLOSED_RANGE('a', 'z'),
testing::Values('\0')));
INSTANTIATE_TEST_CASE_P(a_z,
SingleLetterIdentifierTest,
CLOSED_RANGE('a', 'z'));
// Test string: [A-Z]
INSTANTIATE_TEST_CASE_P(SingleLetter_A_Z,
IdentifierTest,
testing::Combine(CLOSED_RANGE('A', 'Z'),
testing::Values('\0')));
INSTANTIATE_TEST_CASE_P(A_Z,
SingleLetterIdentifierTest,
CLOSED_RANGE('A', 'Z'));
#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: "__"
INSTANTIATE_TEST_CASE_P(DoubleLetter_Underscore_Underscore,
IdentifierTest,
INSTANTIATE_TEST_CASE_P(Underscore_Underscore,
DoubleLetterIdentifierTest,
testing::Combine(testing::Values('_'),
testing::Values('_')));
// Test string: "_"[a-z]
INSTANTIATE_TEST_CASE_P(DoubleLetter_Underscore_a_z,
IdentifierTest,
INSTANTIATE_TEST_CASE_P(Underscore_a_z,
DoubleLetterIdentifierTest,
testing::Combine(testing::Values('_'),
CLOSED_RANGE('a', 'z')));
// Test string: "_"[A-Z]
INSTANTIATE_TEST_CASE_P(DoubleLetter_Underscore_A_Z,
IdentifierTest,
INSTANTIATE_TEST_CASE_P(Underscore_A_Z,
DoubleLetterIdentifierTest,
testing::Combine(testing::Values('_'),
CLOSED_RANGE('A', 'Z')));
// Test string: "_"[0-9]
INSTANTIATE_TEST_CASE_P(DoubleLetter_Underscore_0_9,
IdentifierTest,
INSTANTIATE_TEST_CASE_P(Underscore_0_9,
DoubleLetterIdentifierTest,
testing::Combine(testing::Values('_'),
CLOSED_RANGE('0', '9')));
// Test string: [a-z]"_"
INSTANTIATE_TEST_CASE_P(DoubleLetter_a_z_Underscore,
IdentifierTest,
INSTANTIATE_TEST_CASE_P(a_z_Underscore,
DoubleLetterIdentifierTest,
testing::Combine(CLOSED_RANGE('a', 'z'),
testing::Values('_')));
// Test string: [a-z][a-z]
INSTANTIATE_TEST_CASE_P(DoubleLetter_a_z_a_z,
IdentifierTest,
INSTANTIATE_TEST_CASE_P(a_z_a_z,
DoubleLetterIdentifierTest,
testing::Combine(CLOSED_RANGE('a', 'z'),
CLOSED_RANGE('a', 'z')));
// Test string: [a-z][A-Z]
INSTANTIATE_TEST_CASE_P(DoubleLetter_a_z_A_Z,
IdentifierTest,
INSTANTIATE_TEST_CASE_P(a_z_A_Z,
DoubleLetterIdentifierTest,
testing::Combine(CLOSED_RANGE('a', 'z'),
CLOSED_RANGE('A', 'Z')));
// Test string: [a-z][0-9]
INSTANTIATE_TEST_CASE_P(DoubleLetter_a_z_0_9,
IdentifierTest,
INSTANTIATE_TEST_CASE_P(a_z_0_9,
DoubleLetterIdentifierTest,
testing::Combine(CLOSED_RANGE('a', 'z'),
CLOSED_RANGE('0', '9')));
// Test string: [A-Z]"_"
INSTANTIATE_TEST_CASE_P(DoubleLetter_A_Z_Underscore,
IdentifierTest,
INSTANTIATE_TEST_CASE_P(A_Z_Underscore,
DoubleLetterIdentifierTest,
testing::Combine(CLOSED_RANGE('A', 'Z'),
testing::Values('_')));
// Test string: [A-Z][a-z]
INSTANTIATE_TEST_CASE_P(DoubleLetter_A_Z_a_z,
IdentifierTest,
INSTANTIATE_TEST_CASE_P(A_Z_a_z,
DoubleLetterIdentifierTest,
testing::Combine(CLOSED_RANGE('A', 'Z'),
CLOSED_RANGE('a', 'z')));
// Test string: [A-Z][A-Z]
INSTANTIATE_TEST_CASE_P(DoubleLetter_A_Z_A_Z,
IdentifierTest,
INSTANTIATE_TEST_CASE_P(A_Z_A_Z,
DoubleLetterIdentifierTest,
testing::Combine(CLOSED_RANGE('A', 'Z'),
CLOSED_RANGE('A', 'Z')));
// Test string: [A-Z][0-9]
INSTANTIATE_TEST_CASE_P(DoubleLetter_A_Z_0_9,
IdentifierTest,
INSTANTIATE_TEST_CASE_P(A_Z_0_9,
DoubleLetterIdentifierTest,
testing::Combine(CLOSED_RANGE('A', 'Z'),
CLOSED_RANGE('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
// identifier names. This test covers all characters in a single string.
TEST(IdentifierTestAllCharacters, IdentifierIdentified)
TEST_F(IdentifierTest, AllLetters)
{
std::string str;
for (int c = 'a'; c <= 'z'; ++c)
......@@ -153,5 +166,5 @@ TEST(IdentifierTestAllCharacters, IdentifierIdentified)
for (int c = '0'; c <= '9'; ++c)
str.push_back(c);
PreprocessAndVerifyIdentifier(str.c_str());
preprocess(str);
}
......@@ -4,39 +4,30 @@
// found in the LICENSE file.
//
#include "gtest/gtest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "PreprocessorTest.h"
#include "Token.h"
TEST(InputTest, NegativeCount)
class InitTest : public PreprocessorTest
{
};
TEST_F(InitTest, NegativeCount)
{
MockDiagnostics diagnostics;
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
EXPECT_FALSE(preprocessor.init(-1, NULL, NULL));
EXPECT_FALSE(mPreprocessor.init(-1, NULL, NULL));
}
TEST(InputTest, ZeroCount)
TEST_F(InitTest, ZeroCount)
{
MockDiagnostics diagnostics;
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
EXPECT_TRUE(preprocessor.init(0, NULL, NULL));
EXPECT_TRUE(mPreprocessor.init(0, NULL, NULL));
pp::Token token;
preprocessor.lex(&token);
mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::LAST, token.type);
}
TEST(InputTest, NullString)
TEST_F(InitTest, NullString)
{
MockDiagnostics diagnostics;
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
EXPECT_FALSE(preprocessor.init(1, NULL, NULL));
EXPECT_FALSE(mPreprocessor.init(1, NULL, NULL));
}
TEST(InputTest, DefaultConstructor)
......
......@@ -4,33 +4,30 @@
// found in the LICENSE file.
//
#include "gtest/gtest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "PreprocessorTest.h"
#include "Token.h"
static void PreprocessAndVerifyLocation(int count,
const char* const string[],
const int length[],
const pp::SourceLocation& location)
class LocationTest : public PreprocessorTest
{
MockDiagnostics diagnostics;
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
ASSERT_TRUE(preprocessor.init(count, string, length));
pp::Token token;
preprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ("foo", token.value);
EXPECT_EQ(location.file, token.location.file);
EXPECT_EQ(location.line, token.location.line);
}
TEST(LocationTest, String0_Line1)
protected:
void preprocess(int count,
const char* const string[],
const int length[],
const pp::SourceLocation& location)
{
ASSERT_TRUE(mPreprocessor.init(count, string, length));
pp::Token token;
mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ("foo", token.value);
EXPECT_EQ(location.file, token.location.file);
EXPECT_EQ(location.line, token.location.line);
}
};
TEST_F(LocationTest, String0_Line1)
{
const char* str = "foo";
pp::SourceLocation loc;
......@@ -38,10 +35,10 @@ TEST(LocationTest, String0_Line1)
loc.line = 1;
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";
pp::SourceLocation loc;
......@@ -49,10 +46,10 @@ TEST(LocationTest, String0_Line2)
loc.line = 2;
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"};
pp::SourceLocation loc;
......@@ -60,10 +57,10 @@ TEST(LocationTest, String1_Line1)
loc.line = 1;
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"};
pp::SourceLocation loc;
......@@ -71,10 +68,10 @@ TEST(LocationTest, String1_Line2)
loc.line = 2;
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";
pp::SourceLocation loc;
......@@ -82,30 +79,26 @@ TEST(LocationTest, NewlineInsideCommentCounted)
loc.line = 3;
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*/@";
MockDiagnostics diagnostics;
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
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, "@"));
ASSERT_TRUE(mPreprocessor.init(1, &str, 0));
EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::INVALID_CHARACTER,
pp::SourceLocation(0, 3),
"@"));
pp::Token token;
preprocessor.lex(&token);
mPreprocessor.lex(&token);
}
// The location of a token straddling two or more strings is that of the
// first character of the token.
TEST(LocationTest, TokenStraddlingTwoStrings)
TEST_F(LocationTest, TokenStraddlingTwoStrings)
{
const char* const str[] = {"f", "oo"};
pp::SourceLocation loc;
......@@ -113,10 +106,10 @@ TEST(LocationTest, TokenStraddlingTwoStrings)
loc.line = 1;
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"};
pp::SourceLocation loc;
......@@ -124,7 +117,7 @@ TEST(LocationTest, TokenStraddlingThreeStrings)
loc.line = 1;
SCOPED_TRACE("TokenStraddlingThreeStrings");
PreprocessAndVerifyLocation(3, str, 0, loc);
preprocess(3, str, 0, loc);
}
// TODO(alokp): Add tests for #line directives.
......@@ -4,33 +4,26 @@
// found in the LICENSE file.
//
#include "gtest/gtest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "PreprocessorTest.h"
#include "Token.h"
#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)
{
const char* str = GetParam();
MockDiagnostics diagnostics;
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
ASSERT_TRUE(preprocessor.init(1, &str, 0));
ASSERT_TRUE(mPreprocessor.init(1, &str, 0));
using testing::_;
EXPECT_CALL(diagnostics, print(pp::Diagnostics::INVALID_NUMBER, _, str));
EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::INVALID_NUMBER, _, str));
pp::Token token;
preprocessor.lex(&token);
mPreprocessor.lex(&token);
}
INSTANTIATE_TEST_CASE_P(InvalidIntegers, InvalidNumberTest,
......@@ -45,23 +38,21 @@ INSTANTIATE_TEST_CASE_P(InvalidFloats, InvalidNumberTest,
#if GTEST_HAS_COMBINE
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.
str.push_back(std::tr1::get<1>(GetParam())); // digit.
const char* cstr = str.c_str();
MockDiagnostics diagnostics;
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
ASSERT_TRUE(preprocessor.init(1, &cstr, 0));
ASSERT_TRUE(mPreprocessor.init(1, &cstr, 0));
pp::Token token;
preprocessor.lex(&token);
mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::CONST_INT, token.type);
EXPECT_EQ(str, token.value);
}
......@@ -93,21 +84,25 @@ INSTANTIATE_TEST_CASE_P(HexadecimalInteger_A_F,
testing::Combine(testing::Values("0x"),
CLOSED_RANGE('A', 'F')));
static void PreprocessAndVerifyFloat(const char* str)
class FloatTest : public PreprocessorTest
{
MockDiagnostics diagnostics;
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
ASSERT_TRUE(preprocessor.init(1, &str, 0));
pp::Token token;
preprocessor.lex(&token);
EXPECT_EQ(pp::Token::CONST_FLOAT, token.type);
EXPECT_EQ(str, token.value);
}
protected:
void preprocess(const std::string& str)
{
const char* cstr = str.c_str();
ASSERT_TRUE(mPreprocessor.init(1, &cstr, 0));
pp::Token token;
mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::CONST_FLOAT, token.type);
EXPECT_EQ(str, token.value);
}
};
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)
str.push_back(std::tr1::get<3>(GetParam())); // exponent [0-9].
SCOPED_TRACE("FloatScientificTest");
PreprocessAndVerifyFloat(str.c_str());
preprocess(str);
}
INSTANTIATE_TEST_CASE_P(FloatScientific,
......@@ -132,7 +127,9 @@ INSTANTIATE_TEST_CASE_P(FloatScientific,
CLOSED_RANGE('0', '9')));
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)
str.push_back(fraction);
SCOPED_TRACE("FloatFractionTest");
PreprocessAndVerifyFloat(str.c_str());
preprocess(str);
}
INSTANTIATE_TEST_CASE_P(FloatFraction_X_X,
......@@ -174,9 +171,8 @@ INSTANTIATE_TEST_CASE_P(FloatFraction_X_0,
// In the tests above we have tested individual parts of a float separately.
// This test has all parts of a float.
TEST(FloatFractionScientificTest, FloatIdentified)
TEST_F(FloatTest, FractionScientific)
{
SCOPED_TRACE("FloatFractionScientificTest");
PreprocessAndVerifyFloat("0.1e+2");
SCOPED_TRACE("FractionScientific");
preprocess("0.1e+2");
}
......@@ -4,11 +4,7 @@
// found in the LICENSE file.
//
#include "gtest/gtest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "PreprocessorTest.h"
#include "Token.h"
#if GTEST_HAS_PARAM_TEST
......@@ -19,7 +15,8 @@ struct OperatorTestParam
int op;
};
class OperatorTest : public testing::TestWithParam<OperatorTestParam>
class OperatorTest : public PreprocessorTest,
public testing::WithParamInterface<OperatorTestParam>
{
};
......@@ -27,13 +24,10 @@ TEST_P(OperatorTest, Identified)
{
OperatorTestParam param = GetParam();
MockDiagnostics diagnostics;
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
ASSERT_TRUE(preprocessor.init(1, &param.str, 0));
ASSERT_TRUE(mPreprocessor.init(1, &param.str, 0));
pp::Token token;
preprocessor.lex(&token);
mPreprocessor.lex(&token);
EXPECT_EQ(param.op, token.type);
EXPECT_EQ(param.str, token.value);
}
......
......@@ -4,35 +4,26 @@
// found in the LICENSE file.
//
#include "gtest/gtest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "PreprocessorTest.h"
#include "Token.h"
class PragmaTest : public testing::Test
class PragmaTest : public PreprocessorTest
{
protected:
PragmaTest() : mPreprocessor(&mDiagnostics, &mDirectiveHandler) { }
void lex()
void preprocess(const char* str)
{
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
pp::Token token;
mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::LAST, token.type);
EXPECT_EQ("", token.value);
}
MockDiagnostics mDiagnostics;
MockDirectiveHandler mDirectiveHandler;
pp::Preprocessor mPreprocessor;
};
TEST_F(PragmaTest, EmptyName)
{
const char* str = "#pragma\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_;
// No handlePragma calls.
......@@ -40,13 +31,12 @@ TEST_F(PragmaTest, EmptyName)
// No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
lex();
preprocess(str);
}
TEST_F(PragmaTest, EmptyValue)
{
const char* str = "#pragma foo\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_;
EXPECT_CALL(mDirectiveHandler,
......@@ -54,13 +44,12 @@ TEST_F(PragmaTest, EmptyValue)
// No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
lex();
preprocess(str);
}
TEST_F(PragmaTest, NameValue)
{
const char* str = "#pragma foo(bar)\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_;
EXPECT_CALL(mDirectiveHandler,
......@@ -68,7 +57,7 @@ TEST_F(PragmaTest, NameValue)
// No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
lex();
preprocess(str);
}
TEST_F(PragmaTest, Comments)
......@@ -88,7 +77,6 @@ TEST_F(PragmaTest, Comments)
"/*foo*/"
"//foo"
"\n";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_;
EXPECT_CALL(mDirectiveHandler,
......@@ -96,13 +84,12 @@ TEST_F(PragmaTest, Comments)
// No error or warning.
EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
lex();
preprocess(str);
}
TEST_F(PragmaTest, MissingNewline)
{
const char* str = "#pragma foo(bar)";
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_;
// Pragma successfully parsed.
......@@ -111,9 +98,11 @@ TEST_F(PragmaTest, MissingNewline)
// Error reported about EOF.
EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::EOF_IN_DIRECTIVE, _, _));
lex();
preprocess(str);
}
#if GTEST_HAS_PARAM_TEST
class InvalidPragmaTest : public PragmaTest,
public testing::WithParamInterface<const char*>
{
......@@ -122,7 +111,6 @@ class InvalidPragmaTest : public PragmaTest,
TEST_P(InvalidPragmaTest, Identified)
{
const char* str = GetParam();
ASSERT_TRUE(mPreprocessor.init(1, &str, NULL));
using testing::_;
// No handlePragma calls.
......@@ -132,7 +120,7 @@ TEST_P(InvalidPragmaTest, Identified)
print(pp::Diagnostics::UNRECOGNIZED_PRAGMA,
pp::SourceLocation(0, 1), _));
lex();
preprocess(str);
}
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 parens.
"#pragma foo(bar) baz\n")); // Extra tokens.
#endif // GTEST_HAS_PARAM_TEST
\ No newline at end of file
......@@ -4,13 +4,27 @@
// found in the LICENSE file.
//
#include "gtest/gtest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "PreprocessorTest.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.
// Note that newline characters (\n) will be tested separately.
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.
// All tests in this fixture are ran with all possible whitespace character
// allowed in GLSL.
class SpaceCharTest : public testing::TestWithParam<char>
class SpaceCharTest : public SpaceTest,
public testing::WithParamInterface<char>
{
};
TEST_P(SpaceCharTest, SpaceIgnored)
{
// Construct test string with the whitespace char before "foo".
const char* identifier = "foo";
std::string str(1, GetParam());
str.append(identifier);
const char* cstr = str.c_str();
MockDiagnostics diagnostics;
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());
str.append("foo");
preprocess(str);
}
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
// combinations of whitespace characters allowed in GLSL.
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)
{
// Construct test string with the whitespace char before "foo".
const char* identifier = "foo";
std::string str(1, std::tr1::get<0>(GetParam()));
std::string str;
str.push_back(std::tr1::get<0>(GetParam()));
str.push_back(std::tr1::get<1>(GetParam()));
str.push_back(std::tr1::get<2>(GetParam()));
str.append(identifier);
const char* cstr = str.c_str();
str.append("foo");
MockDiagnostics diagnostics;
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());
preprocess(str);
}
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
// next token. This test makes sure that a token is not incorrectly marked
// to have leading space.
TEST(SpaceTest, LeadingSpace)
TEST_F(SpaceTest, LeadingSpace)
{
const char* str = " foo+ -bar";
ASSERT_TRUE(mPreprocessor.init(1, &str, 0));
pp::Token token;
MockDiagnostics diagnostics;
MockDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor(&diagnostics, &directiveHandler);
ASSERT_TRUE(preprocessor.init(1, &str, 0));
preprocessor.lex(&token);
mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ("foo", token.value);
EXPECT_TRUE(token.hasLeadingSpace());
preprocessor.lex(&token);
mPreprocessor.lex(&token);
EXPECT_EQ('+', token.type);
EXPECT_FALSE(token.hasLeadingSpace());
preprocessor.lex(&token);
mPreprocessor.lex(&token);
EXPECT_EQ('-', token.type);
EXPECT_TRUE(token.hasLeadingSpace());
preprocessor.lex(&token);
mPreprocessor.lex(&token);
EXPECT_EQ(pp::Token::IDENTIFIER, token.type);
EXPECT_EQ("bar", token.value);
EXPECT_FALSE(token.hasLeadingSpace());
......
......@@ -4,18 +4,12 @@
// found in the LICENSE file.
//
#include "gtest/gtest.h"
#include "MockDiagnostics.h"
#include "MockDirectiveHandler.h"
#include "Preprocessor.h"
#include "PreprocessorTest.h"
#include "Token.h"
class VersionTest : public testing::Test
class VersionTest : public PreprocessorTest
{
protected:
VersionTest() : mPreprocessor(&mDiagnostics, &mDirectiveHandler) { }
protected:
void lex()
{
pp::Token token;
......@@ -23,10 +17,6 @@ protected:
EXPECT_EQ(pp::Token::LAST, token.type);
EXPECT_EQ("", token.value);
}
MockDiagnostics mDiagnostics;
MockDirectiveHandler mDirectiveHandler;
pp::Preprocessor mPreprocessor;
};
TEST_F(VersionTest, Valid)
......@@ -80,6 +70,8 @@ TEST_F(VersionTest, MissingNewline)
lex();
}
#if GTEST_HAS_PARAM_TEST
struct VersionTestParam
{
const char* str;
......@@ -112,3 +104,5 @@ static const VersionTestParam 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