blob: a95649916328ab649bd2732de21aee4f57da3d44 [file] [log] [blame]
// Copyright 2018 The Goma 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 "cpp_macro_expander_cbv.h"
#include "cpp_tokenizer.h"
#include "gtest/gtest.h"
namespace devtools_goma {
TEST(CppMacroExpanderCBVTest, GetMacroArguments) {
ArrayTokenList tokens;
ASSERT_TRUE(CppTokenizer::TokenizeAll(
"macro(a1, a2(b1, b2), a3, a4(c1(d))) + 1", false, &tokens));
ArrayTokenList::const_iterator it = tokens.cbegin();
CppMacroExpanderCBV::ArgRangeVector args;
EXPECT_TRUE(CppMacroExpanderCBV::GetMacroArguments(
tokens.cbegin(), tokens.cend(), 4, &it, &args));
ASSERT_EQ(4U, args.size());
// args[0] is a1
ArrayTokenList args0(args[0].first, args[0].second);
ArrayTokenList args0_expected;
ASSERT_TRUE(CppTokenizer::TokenizeAll("a1", false, &args0_expected));
EXPECT_EQ(args0_expected, args0);
// args[1] is a2(b1, b2)
ArrayTokenList args1(args[1].first, args[1].second);
ArrayTokenList args1_expected;
ASSERT_TRUE(CppTokenizer::TokenizeAll("a2(b1, b2)", false, &args1_expected));
EXPECT_EQ(args1_expected, args1);
// args[2] is a3
ArrayTokenList args2(args[2].first, args[2].second);
ArrayTokenList args2_expected;
ASSERT_TRUE(CppTokenizer::TokenizeAll("a3", false, &args2_expected));
EXPECT_EQ(args2_expected, args2);
// args[3] is a4(c1(d))
ArrayTokenList args3(args[3].first, args[3].second);
ArrayTokenList args3_expected;
ASSERT_TRUE(CppTokenizer::TokenizeAll("a4(c1(d))", false, &args3_expected));
EXPECT_EQ(args3_expected, args3);
// *it must be on ')'.
EXPECT_EQ(CppToken(CppToken::PUNCTUATOR, ')'), *it);
}
TEST(CppMacroExpanderCBVTest, GetMacroArgumentsEmptyArg) {
ArrayTokenList tokens;
ASSERT_TRUE(CppTokenizer::TokenizeAll("macro(a1,)", false, &tokens));
ArrayTokenList::const_iterator it = tokens.cbegin();
CppMacroExpanderCBV::ArgRangeVector args;
EXPECT_TRUE(CppMacroExpanderCBV::GetMacroArguments(
tokens.cbegin(), tokens.cend(), 2, &it, &args));
ASSERT_EQ(2U, args.size());
// args[0] is a1
ArrayTokenList args0(args[0].first, args[0].second);
ArrayTokenList args0_expected;
ASSERT_TRUE(CppTokenizer::TokenizeAll("a1", false, &args0_expected));
EXPECT_EQ(args0_expected, args0);
// args[1] is empty
ArrayTokenList args1(args[1].first, args[1].second);
ArrayTokenList args1_expected;
ASSERT_TRUE(CppTokenizer::TokenizeAll("", false, &args1_expected));
EXPECT_EQ(args1_expected, args1);
// *it must be on ')'.
EXPECT_EQ(CppToken(CppToken::PUNCTUATOR, ')'), *it);
}
TEST(CppMacroExpanderCBVTest, GetMacroArgumentsPlentyOrShort) {
ArrayTokenList tokens;
ASSERT_TRUE(CppTokenizer::TokenizeAll(
"macro(a1, a2(b1, b2), a3, a4(c1(d))) + 1", false, &tokens));
{
ArrayTokenList::const_iterator it = tokens.cbegin();
CppMacroExpanderCBV::ArgRangeVector args;
EXPECT_FALSE(CppMacroExpanderCBV::GetMacroArguments(
tokens.cbegin(), tokens.cend(), 5, &it, &args));
}
{
ArrayTokenList::const_iterator it = tokens.cbegin();
CppMacroExpanderCBV::ArgRangeVector args;
EXPECT_FALSE(CppMacroExpanderCBV::GetMacroArguments(
tokens.cbegin(), tokens.cend(), 3, &it, &args));
}
}
TEST(CppMacroExpanderCBVTest, GetMacroArgumentsEmpty) {
ArrayTokenList tokens;
ASSERT_TRUE(CppTokenizer::TokenizeAll("macro() + 1", false, &tokens));
{
ArrayTokenList::const_iterator it = tokens.cbegin();
CppMacroExpanderCBV::ArgRangeVector args;
EXPECT_TRUE(CppMacroExpanderCBV::GetMacroArguments(
tokens.cbegin(), tokens.cend(), 0, &it, &args));
EXPECT_EQ(0U, args.size());
// *it must be on ')'.
EXPECT_EQ(CppToken(CppToken::PUNCTUATOR, ')'), *it);
}
// Use n=1 instead.
{
ArrayTokenList::const_iterator it = tokens.cbegin();
CppMacroExpanderCBV::ArgRangeVector args;
EXPECT_FALSE(CppMacroExpanderCBV::GetMacroArguments(
tokens.cbegin(), tokens.cend(), 1, &it, &args));
}
}
TEST(CppMacroExpanderCBVTest, GetMacroArgumentsFail) {
{
ArrayTokenList tokens;
ASSERT_TRUE(CppTokenizer::TokenizeAll("macro(", false, &tokens));
ArrayTokenList::const_iterator it = tokens.cbegin();
CppMacroExpanderCBV::ArgRangeVector args;
EXPECT_FALSE(CppMacroExpanderCBV::GetMacroArguments(
tokens.cbegin(), tokens.cend(), 2, &it, &args));
}
{
ArrayTokenList tokens;
ASSERT_TRUE(CppTokenizer::TokenizeAll("macro((1, 2), ", false, &tokens));
ArrayTokenList::const_iterator it = tokens.cbegin();
CppMacroExpanderCBV::ArgRangeVector args;
EXPECT_FALSE(CppMacroExpanderCBV::GetMacroArguments(
tokens.cbegin(), tokens.cend(), 2, &it, &args));
}
{
ArrayTokenList tokens;
ASSERT_TRUE(CppTokenizer::TokenizeAll("macro)", false, &tokens));
ArrayTokenList::const_iterator it = tokens.cbegin();
CppMacroExpanderCBV::ArgRangeVector args;
EXPECT_FALSE(CppMacroExpanderCBV::GetMacroArguments(
tokens.cbegin(), tokens.cend(), 2, &it, &args));
}
}
} // namespace devtools_goma