1 //===-- ObjCMemberwiseInitializerTests.cpp ----------------------*- C++ -*-===//
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
9 #include "TestTU.h"
10 #include "TweakTesting.h"
11 #include "gmock/gmock-matchers.h"
12 #include "gmock/gmock.h"
13 #include "gtest/gtest.h"
14
15 namespace clang {
16 namespace clangd {
17 namespace {
18
19 TWEAK_TEST(ObjCMemberwiseInitializer);
20
TEST_F(ObjCMemberwiseInitializerTest,TestAvailability)21 TEST_F(ObjCMemberwiseInitializerTest, TestAvailability) {
22 FileName = "TestTU.m";
23
24 // Ensure the action can't be triggered since arc is disabled.
25 EXPECT_UNAVAILABLE(R"cpp(
26 @interface Fo^o
27 @end
28 )cpp");
29
30 ExtraArgs.push_back("-fobjc-runtime=macosx");
31 ExtraArgs.push_back("-fobjc-arc");
32
33 // Ensure the action can be initiated on the interface and implementation,
34 // but not on the forward declaration.
35 EXPECT_AVAILABLE(R"cpp(
36 @interface Fo^o
37 @end
38 )cpp");
39 EXPECT_AVAILABLE(R"cpp(
40 @interface Foo
41 @end
42
43 @implementation F^oo
44 @end
45 )cpp");
46 EXPECT_UNAVAILABLE("@class Fo^o;");
47
48 // Ensure that the action can be triggered on ivars and properties,
49 // including selecting both.
50 EXPECT_AVAILABLE(R"cpp(
51 @interface Foo {
52 id _fi^eld;
53 }
54 @end
55 )cpp");
56 EXPECT_AVAILABLE(R"cpp(
57 @interface Foo
58 @property(nonatomic) id fi^eld;
59 @end
60 )cpp");
61 EXPECT_AVAILABLE(R"cpp(
62 @interface Foo {
63 id _fi^eld;
64 }
65 @property(nonatomic) id pr^op;
66 @end
67 )cpp");
68
69 // Ensure that the action can't be triggered on property synthesis
70 // and methods.
71 EXPECT_UNAVAILABLE(R"cpp(
72 @interface Foo
73 @property(nonatomic) id prop;
74 @end
75
76 @implementation Foo
77 @dynamic pr^op;
78 @end
79 )cpp");
80 EXPECT_UNAVAILABLE(R"cpp(
81 @interface Foo
82 @end
83
84 @implementation Foo
85 - (void)fo^o {}
86 @end
87 )cpp");
88 }
89
TEST_F(ObjCMemberwiseInitializerTest,Test)90 TEST_F(ObjCMemberwiseInitializerTest, Test) {
91 FileName = "TestTU.m";
92 ExtraArgs.push_back("-fobjc-runtime=macosx");
93 ExtraArgs.push_back("-fobjc-arc");
94
95 const char *Input = R"cpp(
96 @interface Foo {
97 id [[_field;
98 }
99 @property(nonatomic) id prop]];
100 @property(nonatomic) id notSelected;
101 @end)cpp";
102 const char *Output = R"cpp(
103 @interface Foo {
104 id _field;
105 }
106 @property(nonatomic) id prop;
107 @property(nonatomic) id notSelected;
108 - (instancetype)initWithField:(id)field prop:(id)prop;
109
110 @end)cpp";
111 EXPECT_EQ(apply(Input), Output);
112
113 Input = R"cpp(
114 @interface Foo
115 @property(nonatomic, nullable) id somePrettyLongPropertyName;
116 @property(nonatomic, nonnull) id someReallyLongPropertyName;
117 @end
118
119 @implementation F^oo
120
121 - (instancetype)init {
122 return self;
123 }
124
125 @end)cpp";
126 Output = R"cpp(
127 @interface Foo
128 @property(nonatomic, nullable) id somePrettyLongPropertyName;
129 @property(nonatomic, nonnull) id someReallyLongPropertyName;
130 - (instancetype)initWithSomePrettyLongPropertyName:(nullable id)somePrettyLongPropertyName someReallyLongPropertyName:(nonnull id)someReallyLongPropertyName;
131
132 @end
133
134 @implementation Foo
135
136 - (instancetype)init {
137 return self;
138 }
139
140 - (instancetype)initWithSomePrettyLongPropertyName:(nullable id)somePrettyLongPropertyName someReallyLongPropertyName:(nonnull id)someReallyLongPropertyName {
141 self = [super init];
142 if (self) {
143 _somePrettyLongPropertyName = somePrettyLongPropertyName;
144 _someReallyLongPropertyName = someReallyLongPropertyName;
145 }
146 return self;
147 }
148
149 @end)cpp";
150 EXPECT_EQ(apply(Input), Output);
151 }
152
153 } // namespace
154 } // namespace clangd
155 } // namespace clang
156