Skip to content

Commit a504d57

Browse files
committed
Add library evolution tests for constructor, computed property, subscript default implementations
1 parent 194c170 commit a504d57

File tree

2 files changed

+232
-6
lines changed

2 files changed

+232
-6
lines changed

validation-test/Evolution/Inputs/protocol_add_requirements.swift

Lines changed: 129 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ public func getVersion() -> Int {
77
#endif
88
}
99

10+
1011
public protocol ElementProtocol : Equatable {
1112
func increment() -> Self
1213
}
1314

14-
public protocol AddRequirementsProtocol {
15+
public protocol AddMethodsProtocol {
1516
associatedtype Element : ElementProtocol
1617

1718
func importantOperation() -> Element
@@ -22,7 +23,7 @@ public protocol AddRequirementsProtocol {
2223
#endif
2324
}
2425

25-
extension AddRequirementsProtocol {
26+
extension AddMethodsProtocol {
2627
public func unimportantOperation() -> Element {
2728
return importantOperation().increment()
2829
}
@@ -34,7 +35,7 @@ extension AddRequirementsProtocol {
3435
#endif
3536
}
3637

37-
public func doSomething<T : AddRequirementsProtocol>(t: T) -> [T.Element] {
38+
public func doSomething<T : AddMethodsProtocol>(t: T) -> [T.Element] {
3839
#if BEFORE
3940
return [
4041
t.importantOperation(),
@@ -49,3 +50,128 @@ public func doSomething<T : AddRequirementsProtocol>(t: T) -> [T.Element] {
4950
]
5051
#endif
5152
}
53+
54+
55+
public protocol AddConstructorsProtocol {
56+
init(name: String)
57+
58+
#if AFTER
59+
init?(nickname: String)
60+
#endif
61+
}
62+
63+
extension AddConstructorsProtocol {
64+
public init?(nickname: String) {
65+
if nickname == "" {
66+
return nil
67+
}
68+
self.init(name: nickname + "ster")
69+
}
70+
}
71+
72+
public func testConstructorProtocol<T : AddConstructorsProtocol>(t: T.Type) -> [T?] {
73+
#if BEFORE
74+
return [t.init(name: "Puff")]
75+
#else
76+
return [t.init(name: "Meow meow"),
77+
t.init(nickname: ""),
78+
t.init(nickname: "Robster the Lob")]
79+
#endif
80+
}
81+
82+
83+
public protocol AddPropertiesProtocol {
84+
var topSpeed: Int { get nonmutating set }
85+
var maxRPM: Int { get set }
86+
87+
#if AFTER
88+
var maxSafeSpeed: Int { get set }
89+
var minSafeSpeed: Int { get nonmutating set }
90+
var redLine: Int { mutating get set }
91+
#endif
92+
}
93+
94+
extension AddPropertiesProtocol {
95+
#if AFTER
96+
public var maxSafeSpeed: Int {
97+
get {
98+
return topSpeed / 2
99+
}
100+
set {
101+
topSpeed = newValue * 2
102+
}
103+
}
104+
105+
public var minSafeSpeed: Int {
106+
get {
107+
return topSpeed / 4
108+
}
109+
nonmutating set {
110+
topSpeed = newValue * 4
111+
}
112+
}
113+
114+
public var redLine: Int {
115+
get {
116+
return maxRPM - 2000
117+
}
118+
set {
119+
maxRPM = newValue + 2000
120+
}
121+
}
122+
#endif
123+
}
124+
125+
public func getProperties<T : AddPropertiesProtocol>(t: inout T) -> [Int] {
126+
#if BEFORE
127+
return [t.topSpeed, t.maxRPM]
128+
#else
129+
return [t.topSpeed, t.maxRPM, t.maxSafeSpeed, t.minSafeSpeed, t.redLine]
130+
#endif
131+
}
132+
133+
func increment(x: inout Int, by: Int) {
134+
x += by
135+
}
136+
137+
public func setProperties<T : AddPropertiesProtocol>(t: inout T) {
138+
#if AFTER
139+
t.minSafeSpeed = t.maxSafeSpeed
140+
increment(&t.redLine, by: 7000)
141+
#else
142+
increment(&t.topSpeed, by: t.topSpeed)
143+
increment(&t.maxRPM, by: 7000)
144+
#endif
145+
}
146+
147+
148+
public protocol AddSubscriptProtocol {
149+
associatedtype Key
150+
associatedtype Value
151+
152+
func get(key key: Key) -> Value
153+
mutating func set(key key: Key, value: Value)
154+
155+
#if AFTER
156+
subscript(key: Key) -> Value { get set }
157+
#endif
158+
}
159+
160+
extension AddSubscriptProtocol {
161+
public subscript(key: Key) -> Value {
162+
get {
163+
return get(key: key)
164+
}
165+
set {
166+
set(key: key, value: newValue)
167+
}
168+
}
169+
}
170+
171+
public func doSomething<T : AddSubscriptProtocol>(t: inout T, k1: T.Key, k2: T.Key) {
172+
#if BEFORE
173+
t.set(key: k1, value: t.get(key: k2))
174+
#else
175+
t[k1] = t[k2]
176+
#endif
177+
}

validation-test/Evolution/test_protocol_add_requirements.swift

Lines changed: 103 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func ==(h1: Halogen, h2: Halogen) -> Bool {
2727
return h1.x == h2.x
2828
}
2929

30-
struct ConformingType : AddRequirementsProtocol {
30+
struct AddMethods : AddMethodsProtocol {
3131
func importantOperation() -> Halogen {
3232
return Halogen(x: 0)
3333
}
@@ -39,8 +39,8 @@ struct ConformingType : AddRequirementsProtocol {
3939
#endif
4040
}
4141

42-
ProtocolAddRequirementsTest.test("AddRequirements") {
43-
let result = doSomething(ConformingType())
42+
ProtocolAddRequirementsTest.test("AddMethodRequirements") {
43+
let result = doSomething(AddMethods())
4444

4545
#if BEFORE
4646
let expected = [0, 1, 2].map(Halogen.init)
@@ -51,5 +51,105 @@ ProtocolAddRequirementsTest.test("AddRequirements") {
5151
expectEqual(result, expected)
5252
}
5353

54+
55+
struct AddConstructors : AddConstructorsProtocol, Equatable {
56+
var name: String
57+
58+
init(name: String) {
59+
self.name = name
60+
}
61+
}
62+
63+
func ==(a1: AddConstructors, a2: AddConstructors) -> Bool {
64+
return a1.name == a2.name
65+
}
66+
67+
ProtocolAddRequirementsTest.test("AddConstructorsProtocol") {
68+
// Would be nice if [T?] was Equatable...
69+
if getVersion() == 0 {
70+
let result = testConstructorProtocol(AddConstructors.self)
71+
expectEqual(result.count, 1)
72+
expectEqual(result[0], AddConstructors(name: "Puff"))
73+
} else {
74+
let result = testConstructorProtocol(AddConstructors.self)
75+
expectEqual(result.count, 3)
76+
expectEqual(result[0], AddConstructors(name: "Meow meow"))
77+
expectEqual(result[1], nil)
78+
expectEqual(result[2], AddConstructors(name: "Robster the Lobster"))
79+
}
80+
}
81+
82+
83+
class Box<T> {
84+
var value: T
85+
86+
init(value: T) {
87+
self.value = value
88+
}
89+
}
90+
91+
struct AddProperties : AddPropertiesProtocol {
92+
var speedBox: Box<Int> = Box<Int>(value: 160)
93+
var gearBox: Box<Int> = Box<Int>(value: 8000)
94+
95+
var topSpeed: Int {
96+
get {
97+
return speedBox.value
98+
}
99+
nonmutating set {
100+
speedBox.value = newValue
101+
}
102+
}
103+
104+
var maxRPM: Int {
105+
get {
106+
return gearBox.value
107+
}
108+
set {
109+
gearBox.value = newValue
110+
}
111+
}
112+
}
113+
114+
ProtocolAddRequirementsTest.test("AddPropertyRequirements") {
115+
var x = AddProperties()
116+
117+
do {
118+
let expected = (getVersion() == 0
119+
? [160, 8000]
120+
: [160, 8000, 80, 40, 6000])
121+
expectEqual(getProperties(&x), expected)
122+
}
123+
124+
setProperties(&x)
125+
126+
do {
127+
let expected = (getVersion() == 0
128+
? [320, 15000]
129+
: [320, 15000, 160, 80, 13000])
130+
expectEqual(getProperties(&x), expected)
131+
}
132+
}
133+
134+
135+
struct AddSubscript<Key : Hashable, Value> : AddSubscriptProtocol {
136+
var dict: [Key : Value] = [:]
137+
138+
func get(key key: Key) -> Value {
139+
return dict[key]!
140+
}
141+
142+
mutating func set(key key: Key, value: Value) {
143+
dict[key] = value
144+
}
145+
}
146+
147+
ProtocolAddRequirementsTest.test("AddPropertyRequirements") {
148+
var t = AddSubscript<String, Int>()
149+
t.set(key: "B", value: 20)
150+
doSomething(&t, k1: "A", k2: "B")
151+
expectEqual(t.get(key: "A"), 20)
152+
}
153+
54154
runAllTests()
55155

0 commit comments

Comments
 (0)