Skip to content

Commit bb35aa5

Browse files
committed
Initial take on signature tests
1 parent 8dee337 commit bb35aa5

3 files changed

Lines changed: 209 additions & 299 deletions

File tree

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
import InterposeKit
2+
import XCTest
3+
4+
fileprivate class ExampleClass: NSObject {
5+
6+
@objc dynamic func passthroughInt(_ input: Int) -> Int { input }
7+
@objc dynamic func passthroughDouble(_ input: Double) -> Double { input }
8+
@objc dynamic func passthroughPoint(_ input: CGPoint) -> CGPoint { input }
9+
@objc dynamic func passthroughRect(_ input: CGRect) -> CGRect { input }
10+
@objc dynamic func passthroughTransform3D(_ input: CATransform3D) -> CATransform3D { input }
11+
@objc dynamic func passthroughString(_ input: String) -> String { input }
12+
@objc dynamic func passthroughObject(_ input: NSObject) -> NSObject { input }
13+
14+
@objc dynamic func sum3(var1: Int, var2: Int, var3: Int) -> Int {
15+
var1 + var2 + var3
16+
}
17+
18+
@objc dynamic func sum6(var1: Int, var2: Int, var3: Int, var4: Int, var5: Int, var6: Int) -> Int {
19+
var1 + var2 + var3 + var4 + var5 + var6
20+
}
21+
22+
}
23+
24+
final class SignatureTests: XCTestCase {
25+
26+
override func setUpWithError() throws {
27+
Interpose.isLoggingEnabled = true
28+
}
29+
30+
func testPassthroughInt() throws {
31+
let object = ExampleClass()
32+
33+
let hook = try object.applyHook(
34+
for: #selector(ExampleClass.passthroughInt(_:)),
35+
methodSignature: (@convention(c) (NSObject, Selector, Int) -> Int).self,
36+
hookSignature: (@convention(block) (NSObject, Int) -> Int).self
37+
) { hook in
38+
return { `self`, input in
39+
hook.original(self, hook.selector, input) + 1
40+
}
41+
}
42+
XCTAssertEqual(object.passthroughInt(42), 43)
43+
44+
try hook.revert()
45+
XCTAssertEqual(object.passthroughInt(42), 42)
46+
}
47+
48+
func testPassthroughDouble() throws {
49+
let object = ExampleClass()
50+
51+
let hook = try object.applyHook(
52+
for: #selector(ExampleClass.passthroughDouble(_:)),
53+
methodSignature: (@convention(c) (NSObject, Selector, Double) -> Double).self,
54+
hookSignature: (@convention(block) (NSObject, Double) -> Double).self
55+
) { hook in
56+
return { `self`, input in
57+
hook.original(self, hook.selector, input) + 0.5
58+
}
59+
}
60+
XCTAssertEqual(object.passthroughDouble(1.5), 2.0)
61+
62+
try hook.revert()
63+
XCTAssertEqual(object.passthroughDouble(1.5), 1.5)
64+
}
65+
66+
func testPassthroughPoint() throws {
67+
let object = ExampleClass()
68+
69+
let hook = try object.applyHook(
70+
for: #selector(ExampleClass.passthroughPoint(_:)),
71+
methodSignature: (@convention(c) (NSObject, Selector, CGPoint) -> CGPoint).self,
72+
hookSignature: (@convention(block) (NSObject, CGPoint) -> CGPoint).self
73+
) { hook in
74+
return { `self`, input in
75+
var point = hook.original(self, hook.selector, input)
76+
point.x += 1
77+
point.y += 1
78+
return point
79+
}
80+
}
81+
XCTAssertEqual(object.passthroughPoint(CGPoint(x: 1, y: 2)), CGPoint(x: 2, y: 3))
82+
83+
try hook.revert()
84+
XCTAssertEqual(object.passthroughPoint(CGPoint(x: 1, y: 2)), CGPoint(x: 1, y: 2))
85+
}
86+
87+
func testPassthroughRect() throws {
88+
let object = ExampleClass()
89+
90+
let hook = try object.applyHook(
91+
for: #selector(ExampleClass.passthroughRect(_:)),
92+
methodSignature: (@convention(c) (NSObject, Selector, CGRect) -> CGRect).self,
93+
hookSignature: (@convention(block) (NSObject, CGRect) -> CGRect).self
94+
) { hook in
95+
{ `self`, rect in
96+
var rect = hook.original(self, hook.selector, rect)
97+
rect.origin.x += 1
98+
rect.size.width += 1
99+
return rect
100+
}
101+
}
102+
XCTAssertEqual(
103+
object.passthroughRect(CGRect(x: 1, y: 1, width: 10, height: 10)),
104+
CGRect(x: 2, y: 1, width: 11, height: 10)
105+
)
106+
107+
try hook.revert()
108+
XCTAssertEqual(
109+
object.passthroughRect(CGRect(x: 1, y: 2, width: 10, height: 10)),
110+
CGRect(x: 1, y: 2, width: 10, height: 10)
111+
)
112+
}
113+
114+
func testPassthroughTransform3D() throws {
115+
let object = ExampleClass()
116+
let input = CATransform3DMakeTranslation(1, 2, 3)
117+
118+
let hook = try object.applyHook(
119+
for: #selector(ExampleClass.passthroughTransform3D(_:)),
120+
methodSignature: (@convention(c) (NSObject, Selector, CATransform3D) -> CATransform3D).self,
121+
hookSignature: (@convention(block) (NSObject, CATransform3D) -> CATransform3D).self
122+
) { hook in
123+
{ `self`, transform in
124+
var modified = hook.original(self, hook.selector, transform)
125+
modified.m44 += 1
126+
return modified
127+
}
128+
}
129+
130+
var expected = input
131+
expected.m44 += 1
132+
XCTAssertTrue(CATransform3DEqualToTransform(object.passthroughTransform3D(input), expected))
133+
134+
try hook.revert()
135+
XCTAssertTrue(CATransform3DEqualToTransform(object.passthroughTransform3D(input), input))
136+
}
137+
138+
func testPassthroughString() throws {
139+
let object = ExampleClass()
140+
141+
let hook = try object.applyHook(
142+
for: #selector(ExampleClass.passthroughString(_:)),
143+
methodSignature: (@convention(c) (NSObject, Selector, String) -> String).self,
144+
hookSignature: (@convention(block) (NSObject, String) -> String).self
145+
) { hook in
146+
{ `self`, input in hook.original(self, hook.selector, input) + "!" }
147+
}
148+
XCTAssertEqual(object.passthroughString("Test"), "Test!")
149+
150+
try hook.revert()
151+
XCTAssertEqual(object.passthroughString("Test"), "Test")
152+
}
153+
154+
func testPassthroughObject() throws {
155+
let object = ExampleClass()
156+
let input = NSObject()
157+
158+
let hook = try object.applyHook(
159+
for: #selector(ExampleClass.passthroughObject(_:)),
160+
methodSignature: (@convention(c) (NSObject, Selector, NSObject) -> NSObject).self,
161+
hookSignature: (@convention(block) (NSObject, NSObject) -> NSObject).self
162+
) { hook in
163+
{ `self`, _ in NSObject() }
164+
}
165+
XCTAssertTrue(object.passthroughObject(input) !== input)
166+
167+
try hook.revert()
168+
XCTAssertTrue(object.passthroughObject(input) === input)
169+
}
170+
171+
func testSum3Ints() throws {
172+
let object = ExampleClass()
173+
174+
let hook = try object.applyHook(
175+
for: #selector(ExampleClass.sum3(var1:var2:var3:)),
176+
methodSignature: (@convention(c) (NSObject, Selector, Int, Int, Int) -> Int).self,
177+
hookSignature: (@convention(block) (NSObject, Int, Int, Int) -> Int).self
178+
) { hook in
179+
{ `self`, var1, var2, var3 in
180+
hook.original(self, hook.selector, var1, var2, var3) + 1
181+
}
182+
}
183+
184+
XCTAssertEqual(object.sum3(var1: 1, var2: 2, var3: 3), 7)
185+
186+
try hook.revert()
187+
XCTAssertEqual(object.sum3(var1: 1, var2: 2, var3: 3), 6)
188+
}
189+
190+
func testSum6Ints() throws {
191+
let object = ExampleClass()
192+
193+
let hook = try object.applyHook(
194+
for: #selector(ExampleClass.sum6(var1:var2:var3:var4:var5:var6:)),
195+
methodSignature: (@convention(c) (NSObject, Selector, Int, Int, Int, Int, Int, Int) -> Int).self,
196+
hookSignature: (@convention(block) (NSObject, Int, Int, Int, Int, Int, Int) -> Int).self
197+
) { hook in
198+
{ `self`, var1, var2, var3, var4, var5, var6 in
199+
hook.original(self, hook.selector, var1, var2, var3, var4, var5, var6) + 1
200+
}
201+
}
202+
203+
XCTAssertEqual(object.sum6(var1: 1, var2: 1, var3: 1, var4: 1, var5: 1, var6: 1), 7)
204+
205+
try hook.revert()
206+
XCTAssertEqual(object.sum6(var1: 1, var2: 1, var3: 1, var4: 1, var5: 1, var6: 1), 6)
207+
}
208+
209+
}

0 commit comments

Comments
 (0)