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