Skip to content

Commit 3d5bac3

Browse files
authored
Merge pull request #3987 from slavapestov/objc-failing-designated-init-tests
Add tests for failable and throwing designated initializers in @objc classes
2 parents a0fca3a + 992b68b commit 3d5bac3

File tree

4 files changed

+561
-0
lines changed

4 files changed

+561
-0
lines changed

test/Interpreter/Inputs/ObjCClasses/ObjCClasses.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ NS_ASSUME_NONNULL_BEGIN
9494
- (id) initWithArray: (NSArray<T>*) array;
9595
@end
9696

97+
@interface NSLifetimeTracked : NSObject
98+
+ (unsigned) count;
99+
@end
100+
97101
NS_ASSUME_NONNULL_END
98102

99103
#endif

test/Interpreter/Inputs/ObjCClasses/ObjCClasses.m

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,22 @@ - (NSInteger) count {
132132
return _objects.count;
133133
}
134134
@end
135+
136+
static unsigned counter = 0;
137+
138+
@implementation NSLifetimeTracked
139+
140+
+ (id) allocWithZone:(NSZone *)zone {
141+
counter++;
142+
return [super allocWithZone:zone];
143+
}
144+
145+
- (void) dealloc {
146+
counter--;
147+
}
148+
149+
+ (unsigned) count {
150+
return counter;
151+
}
152+
153+
@end
Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
// RUN: rm -rf %t
2+
// RUN: mkdir -p %t
3+
//
4+
// RUN: %target-clang -fobjc-arc %S/Inputs/ObjCClasses/ObjCClasses.m -c -o %t/ObjCClasses.o
5+
// RUN: %target-build-swift -I %S/Inputs/ObjCClasses/ -Xlinker %t/ObjCClasses.o %s -o %t/a.out
6+
// RUN: %target-run %t/a.out
7+
8+
// REQUIRES: executable_test
9+
// REQUIRES: objc_interop
10+
11+
import Foundation
12+
import ObjCClasses
13+
import StdlibUnittest
14+
15+
var FailableInitTestSuite = TestSuite("FailableInitObjC")
16+
17+
class Bear : NSLifetimeTracked {
18+
let x: LifetimeTracked
19+
20+
/* Designated */
21+
init(n: Int) {
22+
x = LifetimeTracked(0)
23+
}
24+
25+
init?(n: Int, before: Bool) {
26+
if before {
27+
return nil
28+
}
29+
self.x = LifetimeTracked(0)
30+
}
31+
32+
init?(n: Int, after: Bool) {
33+
self.x = LifetimeTracked(0)
34+
if after {
35+
return nil
36+
}
37+
}
38+
39+
init?(n: Int, before: Bool, after: Bool) {
40+
if before {
41+
return nil
42+
}
43+
self.x = LifetimeTracked(0)
44+
if after {
45+
return nil
46+
}
47+
}
48+
49+
/* Convenience */
50+
convenience init?(before: Bool) {
51+
if before {
52+
return nil
53+
}
54+
self.init(n: 0)
55+
}
56+
57+
convenience init?(during: Bool) {
58+
self.init(n: 0, after: during)
59+
}
60+
61+
convenience init?(before: Bool, during: Bool) {
62+
if before {
63+
return nil
64+
}
65+
self.init(n: 0, after: during)
66+
}
67+
68+
convenience init?(after: Bool) {
69+
self.init(n: 0)
70+
if after {
71+
return nil
72+
}
73+
}
74+
75+
convenience init?(before: Bool, after: Bool) {
76+
if before {
77+
return nil
78+
}
79+
self.init(n: 0)
80+
if after {
81+
return nil
82+
}
83+
}
84+
85+
convenience init?(during: Bool, after: Bool) {
86+
self.init(n: 0, after: during)
87+
if after {
88+
return nil
89+
}
90+
}
91+
92+
convenience init?(before: Bool, during: Bool, after: Bool) {
93+
if before {
94+
return nil
95+
}
96+
self.init(n: 0, after: during)
97+
if after {
98+
return nil
99+
}
100+
}
101+
102+
/* Exotic */
103+
convenience init!(IUO: Bool) {
104+
self.init(before: IUO)
105+
}
106+
107+
convenience init(force: Bool) {
108+
self.init(before: force)!
109+
}
110+
}
111+
112+
class PolarBear : Bear {
113+
let y: LifetimeTracked
114+
115+
/* Designated */
116+
override init(n: Int) {
117+
self.y = LifetimeTracked(0)
118+
super.init(n: n)
119+
}
120+
121+
override init?(n: Int, before: Bool) {
122+
if before {
123+
return nil
124+
}
125+
self.y = LifetimeTracked(0)
126+
super.init(n: n)
127+
}
128+
129+
init?(n: Int, during: Bool) {
130+
self.y = LifetimeTracked(0)
131+
super.init(n: n, before: during)
132+
}
133+
134+
init?(n: Int, before: Bool, during: Bool) {
135+
self.y = LifetimeTracked(0)
136+
if before {
137+
return nil
138+
}
139+
super.init(n: n, before: during)
140+
}
141+
142+
override init?(n: Int, after: Bool) {
143+
self.y = LifetimeTracked(0)
144+
super.init(n: n)
145+
if after {
146+
return nil
147+
}
148+
}
149+
150+
init?(n: Int, during: Bool, after: Bool) {
151+
self.y = LifetimeTracked(0)
152+
super.init(n: n, before: during)
153+
if after {
154+
return nil
155+
}
156+
}
157+
158+
override init?(n: Int, before: Bool, after: Bool) {
159+
if before {
160+
return nil
161+
}
162+
self.y = LifetimeTracked(0)
163+
super.init(n: n)
164+
if after {
165+
return nil
166+
}
167+
}
168+
169+
init?(n: Int, before: Bool, during: Bool, after: Bool) {
170+
if before {
171+
return nil
172+
}
173+
self.y = LifetimeTracked(0)
174+
super.init(n: n, before: during)
175+
if after {
176+
return nil
177+
}
178+
}
179+
}
180+
181+
class GuineaPig<T> : Bear {
182+
let y: LifetimeTracked
183+
let t: T
184+
185+
init?(t: T, during: Bool) {
186+
self.y = LifetimeTracked(0)
187+
self.t = t
188+
super.init(n: 0, before: during)
189+
}
190+
}
191+
192+
func mustFail<T>(f: () -> T?) {
193+
if f() != nil {
194+
preconditionFailure("Didn't fail")
195+
}
196+
}
197+
198+
FailableInitTestSuite.test("FailableInitFailure_Root") {
199+
mustFail { Bear(n: 0, before: true) }
200+
mustFail { Bear(n: 0, after: true) }
201+
mustFail { Bear(n: 0, before: true, after: false) }
202+
mustFail { Bear(n: 0, before: false, after: true) }
203+
expectEqual(NSLifetimeTracked.count(), 0)
204+
}
205+
206+
FailableInitTestSuite.test("FailableInitFailure_Derived") {
207+
mustFail { PolarBear(n: 0, before: true) }
208+
mustFail { PolarBear(n: 0, during: true) }
209+
mustFail { PolarBear(n: 0, before: true, during: false) }
210+
mustFail { PolarBear(n: 0, before: false, during: true) }
211+
mustFail { PolarBear(n: 0, after: true) }
212+
mustFail { PolarBear(n: 0, during: true, after: false) }
213+
mustFail { PolarBear(n: 0, during: false, after: true) }
214+
mustFail { PolarBear(n: 0, before: true, after: false) }
215+
mustFail { PolarBear(n: 0, before: false, after: true) }
216+
mustFail { PolarBear(n: 0, before: true, during: false, after: false) }
217+
mustFail { PolarBear(n: 0, before: false, during: true, after: false) }
218+
mustFail { PolarBear(n: 0, before: false, during: false, after: true) }
219+
expectEqual(NSLifetimeTracked.count(), 0)
220+
}
221+
222+
FailableInitTestSuite.test("DesignatedInitFailure_DerivedGeneric") {
223+
mustFail { GuineaPig<LifetimeTracked>(t: LifetimeTracked(0), during: true) }
224+
expectEqual(NSLifetimeTracked.count(), 0)
225+
}
226+
227+
FailableInitTestSuite.test("ConvenienceInitFailure_Root") {
228+
mustFail { Bear(before: true) }
229+
mustFail { Bear(during: true) }
230+
mustFail { Bear(before: true, during: false) }
231+
mustFail { Bear(before: false, during: true) }
232+
mustFail { Bear(after: true) }
233+
mustFail { Bear(before: true, after: false) }
234+
mustFail { Bear(before: false, after: true) }
235+
mustFail { Bear(during: true, after: false) }
236+
mustFail { Bear(during: false, after: true) }
237+
mustFail { Bear(before: true, during: false, after: false) }
238+
mustFail { Bear(before: false, during: true, after: false) }
239+
mustFail { Bear(before: false, during: false, after: true) }
240+
241+
_ = Bear(IUO: false)
242+
_ = Bear(force: false)
243+
244+
expectEqual(NSLifetimeTracked.count(), 0)
245+
}
246+
247+
FailableInitTestSuite.test("ConvenienceInitFailure_Derived") {
248+
mustFail { PolarBear(before: true) }
249+
mustFail { PolarBear(during: true) }
250+
mustFail { PolarBear(before: true, during: false) }
251+
mustFail { PolarBear(before: false, during: true) }
252+
mustFail { PolarBear(after: true) }
253+
mustFail { PolarBear(before: true, after: false) }
254+
mustFail { PolarBear(before: false, after: true) }
255+
mustFail { PolarBear(during: true, after: false) }
256+
mustFail { PolarBear(during: false, after: true) }
257+
mustFail { PolarBear(before: true, during: false, after: false) }
258+
mustFail { PolarBear(before: false, during: true, after: false) }
259+
mustFail { PolarBear(before: false, during: false, after: true) }
260+
expectEqual(NSLifetimeTracked.count(), 0)
261+
}
262+
263+
runAllTests()

0 commit comments

Comments
 (0)