@@ -3,70 +3,120 @@ import XCTest
33
44fileprivate class ExampleClass : NSObject {
55 @objc dynamic func doSomething( ) { }
6+ @objc dynamic var intValue = 1
67}
78
89fileprivate class ExampleSubclass : ExampleClass { }
910
1011final class ClassHookTests : InterposeKitTestCase {
1112
12- func testSuccess_applyHook ( ) throws {
13+ func testLifecycle_applyHook ( ) throws {
1314 let hook = try Interpose . applyHook (
1415 on: ExampleClass . self,
15- for: #selector( ExampleClass . doSomething ) ,
16- methodSignature: ( @convention( c) ( NSObject, Selector) - > Void ) . self,
17- hookSignature: ( @convention( block) ( NSObject) - > Void ) . self
16+ for: #selector( getter: ExampleClass . intValue ) ,
17+ methodSignature: ( @convention( c) ( NSObject, Selector) - > Int ) . self,
18+ hookSignature: ( @convention( block) ( NSObject) - > Int ) . self
1819 ) { hook in
19- return { `self` in }
20+ return { `self` in
21+ 1 + hook. original ( self , hook. selector)
22+ }
2023 }
2124
25+ XCTAssertEqual ( ExampleClass ( ) . intValue, 2 )
2226 XCTAssertEqual ( hook. state, . active)
2327 XCTAssertMatchesRegex (
2428 hook. debugDescription,
25- #"^Active hook for -\[ExampleClass doSomething \] \(originalIMP: 0x[0-9a-fA-F]+\)$"#
29+ #"^Active hook for -\[ExampleClass intValue \] \(originalIMP: 0x[0-9a-fA-F]+\)$"#
2630 )
2731
2832 try hook. revert ( )
2933
34+ XCTAssertEqual ( ExampleClass ( ) . intValue, 1 )
3035 XCTAssertEqual ( hook. state, . pending)
3136 XCTAssertMatchesRegex (
3237 hook. debugDescription,
33- #"^Pending hook for -\[ExampleClass doSomething \]$"#
38+ #"^Pending hook for -\[ExampleClass intValue \]$"#
3439 )
3540 }
3641
37- func testSuccess_prepareHook ( ) throws {
42+ func testLifecycle_prepareHook ( ) throws {
3843 let hook = try Interpose . prepareHook (
3944 on: ExampleClass . self,
40- for: #selector( ExampleClass . doSomething ) ,
41- methodSignature: ( @convention( c) ( NSObject, Selector) - > Void ) . self,
42- hookSignature: ( @convention( block) ( NSObject) - > Void ) . self
45+ for: #selector( getter: ExampleClass . intValue ) ,
46+ methodSignature: ( @convention( c) ( NSObject, Selector) - > Int ) . self,
47+ hookSignature: ( @convention( block) ( NSObject) - > Int ) . self
4348 ) { hook in
44- return { `self` in }
49+ return { `self` in
50+ 1 + hook. original ( self , hook. selector)
51+ }
4552 }
4653
54+ XCTAssertEqual ( ExampleClass ( ) . intValue, 1 )
4755 XCTAssertEqual ( hook. state, . pending)
4856 XCTAssertMatchesRegex (
4957 hook. debugDescription,
50- #"^Pending hook for -\[ExampleClass doSomething \]$"#
58+ #"^Pending hook for -\[ExampleClass intValue \]$"#
5159 )
5260
5361 try hook. apply ( )
5462
63+ XCTAssertEqual ( ExampleClass ( ) . intValue, 2 )
5564 XCTAssertEqual ( hook. state, . active)
5665 XCTAssertMatchesRegex (
5766 hook. debugDescription,
58- #"^Active hook for -\[ExampleClass doSomething \] \(originalIMP: 0x[0-9a-fA-F]+\)$"#
67+ #"^Active hook for -\[ExampleClass intValue \] \(originalIMP: 0x[0-9a-fA-F]+\)$"#
5968 )
6069
6170 try hook. revert ( )
6271
72+ XCTAssertEqual ( ExampleClass ( ) . intValue, 1 )
6373 XCTAssertEqual ( hook. state, . pending)
6474 XCTAssertMatchesRegex (
6575 hook. debugDescription,
66- #"^Pending hook for -\[ExampleClass doSomething \]$"#
76+ #"^Pending hook for -\[ExampleClass intValue \]$"#
6777 )
6878 }
6979
80+ func testLifecycle_idempotentApplyAndRevert( ) throws {
81+ let object = ExampleClass ( )
82+
83+ let hook = try Interpose . prepareHook (
84+ on: ExampleClass . self,
85+ for: #selector( getter: ExampleClass . intValue) ,
86+ methodSignature: ( @convention( c) ( NSObject, Selector) - > Int) . self,
87+ hookSignature: ( @convention( block) ( NSObject) - > Int) . self
88+ ) { hook in
89+ return { `self` in
90+ 1 + hook. original ( self , hook. selector)
91+ }
92+ }
93+
94+ XCTAssertEqual ( object. intValue, 1 )
95+ XCTAssertEqual ( hook. state, . pending)
96+
97+ try hook. apply ( )
98+ try hook. apply ( ) // noop
99+
100+ XCTAssertEqual ( object. intValue, 2 )
101+ XCTAssertEqual ( hook. state, . active)
102+
103+ try hook. revert ( )
104+ try hook. revert ( ) // noop
105+
106+ XCTAssertEqual ( object. intValue, 1 )
107+ XCTAssertEqual ( hook. state, . pending)
108+
109+ try hook. apply ( )
110+
111+ XCTAssertEqual ( object. intValue, 2 )
112+ XCTAssertEqual ( hook. state, . active)
113+
114+ try hook. revert ( )
115+
116+ XCTAssertEqual ( object. intValue, 1 )
117+ XCTAssertEqual ( hook. state, . pending)
118+ }
119+
70120 func testValidationFailure_methodNotFound( ) throws {
71121 XCTAssertThrowsError (
72122 try Interpose . prepareHook (
0 commit comments