Skip to content

Commit dc39d98

Browse files
committed
[lldb][NFCI] Add unittests for ObjCLanguage::MethodName
I have a patch to refactor this class and I'd like a unittest in place to make sure I don't break anything. Differential Revision: https://reviews.llvm.org/D149804
1 parent 5cba771 commit dc39d98

File tree

3 files changed

+121
-0
lines changed

3 files changed

+121
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
add_subdirectory(CPlusPlus)
22
add_subdirectory(CLanguages)
33
add_subdirectory(Highlighting)
4+
add_subdirectory(ObjC)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
add_lldb_unittest(LanguageObjCTests
2+
ObjCLanguageTest.cpp
3+
4+
LINK_LIBS
5+
lldbPluginObjCLanguage
6+
)
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
//===-- ObjCLanguageTest.cpp ----------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
#include "Plugins/Language/ObjC/ObjCLanguage.h"
9+
#include "lldb/lldb-enumerations.h"
10+
#include "gmock/gmock.h"
11+
#include "gtest/gtest.h"
12+
#include <optional>
13+
14+
#include "llvm/ADT/StringRef.h"
15+
16+
using namespace lldb_private;
17+
18+
TEST(ObjCLanguage, MethodNameParsing) {
19+
struct TestCase {
20+
llvm::StringRef input;
21+
llvm::StringRef full_name_sans_category;
22+
llvm::StringRef class_name;
23+
llvm::StringRef class_name_with_category;
24+
llvm::StringRef category;
25+
llvm::StringRef selector;
26+
};
27+
28+
TestCase strict_cases[] = {
29+
{"-[MyClass mySelector:]", "", "MyClass", "MyClass", "", "mySelector:"},
30+
{"+[MyClass mySelector:]", "", "MyClass", "MyClass", "", "mySelector:"},
31+
{"-[MyClass(my_category) mySelector:]", "-[MyClass mySelector:]",
32+
"MyClass", "MyClass(my_category)", "my_category", "mySelector:"},
33+
{"+[MyClass(my_category) mySelector:]", "+[MyClass mySelector:]",
34+
"MyClass", "MyClass(my_category)", "my_category", "mySelector:"},
35+
};
36+
37+
TestCase lax_cases[] = {
38+
{"[MyClass mySelector:]", "", "MyClass", "MyClass", "", "mySelector:"},
39+
{"[MyClass(my_category) mySelector:]", "[MyClass mySelector:]", "MyClass",
40+
"MyClass(my_category)", "my_category", "mySelector:"},
41+
};
42+
43+
// First, be strict
44+
for (const auto &test : strict_cases) {
45+
ObjCLanguage::MethodName method(test.input, /*strict = */ true);
46+
EXPECT_TRUE(method.IsValid(/*strict = */ true));
47+
EXPECT_EQ(
48+
test.full_name_sans_category,
49+
method.GetFullNameWithoutCategory(/*empty_if_no_category = */ true)
50+
.GetStringRef());
51+
EXPECT_EQ(test.class_name, method.GetClassName().GetStringRef());
52+
EXPECT_EQ(test.class_name_with_category,
53+
method.GetClassNameWithCategory().GetStringRef());
54+
EXPECT_EQ(test.category, method.GetCategory().GetStringRef());
55+
EXPECT_EQ(test.selector, method.GetSelector().GetStringRef());
56+
}
57+
58+
// We should make sure strict parsing does not accept lax cases
59+
for (const auto &test : lax_cases) {
60+
ObjCLanguage::MethodName method(test.input, /*strict = */ true);
61+
EXPECT_FALSE(method.IsValid(/*strict = */ true));
62+
}
63+
64+
// All strict cases should work when not lax
65+
for (const auto &test : strict_cases) {
66+
ObjCLanguage::MethodName method(test.input, /*strict = */ false);
67+
EXPECT_TRUE(method.IsValid(/*strict = */ false));
68+
EXPECT_EQ(
69+
test.full_name_sans_category,
70+
method.GetFullNameWithoutCategory(/*empty_if_no_category = */ true)
71+
.GetStringRef());
72+
EXPECT_EQ(test.class_name, method.GetClassName().GetStringRef());
73+
EXPECT_EQ(test.class_name_with_category,
74+
method.GetClassNameWithCategory().GetStringRef());
75+
EXPECT_EQ(test.category, method.GetCategory().GetStringRef());
76+
EXPECT_EQ(test.selector, method.GetSelector().GetStringRef());
77+
}
78+
79+
// Make sure non-strict parsing works
80+
for (const auto &test : lax_cases) {
81+
ObjCLanguage::MethodName method(test.input, /*strict = */ false);
82+
EXPECT_TRUE(method.IsValid(/*strict = */ false));
83+
EXPECT_EQ(
84+
test.full_name_sans_category,
85+
method.GetFullNameWithoutCategory(/*empty_if_no_category = */ true)
86+
.GetStringRef());
87+
EXPECT_EQ(test.class_name, method.GetClassName().GetStringRef());
88+
EXPECT_EQ(test.class_name_with_category,
89+
method.GetClassNameWithCategory().GetStringRef());
90+
EXPECT_EQ(test.category, method.GetCategory().GetStringRef());
91+
EXPECT_EQ(test.selector, method.GetSelector().GetStringRef());
92+
}
93+
}
94+
95+
TEST(CPlusPlusLanguage, InvalidMethodNameParsing) {
96+
// Tests that we correctly reject malformed function names
97+
98+
llvm::StringRef test_cases[] = {"+[Uh oh!",
99+
"-[Definitely not...",
100+
"[Nice try ] :)",
101+
"+MaybeIfYouSquintYourEyes]",
102+
"?[Tricky]",
103+
"+[]",
104+
"-[]",
105+
"[]"};
106+
107+
for (const auto &name : test_cases) {
108+
ObjCLanguage::MethodName strict_method(name, /*strict = */ true);
109+
EXPECT_FALSE(strict_method.IsValid(true));
110+
111+
ObjCLanguage::MethodName lax_method(name, /*strict = */ false);
112+
EXPECT_FALSE(lax_method.IsValid(true));
113+
}
114+
}

0 commit comments

Comments
 (0)