blob: 6bc8a3fb2fd8537722703b1eeb5067426fa0e642 [file] [log] [blame]
Avi Drissmanea1be232022-09-14 23:29:061// Copyright 2013 The Chromium Authors
rohitrao4aaf45232016-12-05 16:02:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Gauthier Ambard999088c2022-09-13 08:36:575#import "ios/testing/scoped_block_swizzler.h"
Sylvain Defresne14176c9f2025-01-23 10:57:236
Avi Drissmaneac566b02023-08-18 02:56:217#import "base/apple/foundation_util.h"
Gauthier Ambard999088c2022-09-13 08:36:578#import "testing/gtest/include/gtest/gtest.h"
olivierrobin3c03c1c2016-12-29 17:35:199#import "testing/gtest_mac.h"
Gauthier Ambard999088c2022-09-13 08:36:5710#import "testing/platform_test.h"
rohitrao4aaf45232016-12-05 16:02:5511
12// Class containing two methods that will be swizzled by the unittests.
13@interface ScopedBlockSwizzlerTestClass : NSObject
14
15// An NSString property that will be accessed by one of the swizzled methods.
16@property(nonatomic, copy) NSString* value;
17
18+ (NSString*)classMethodToSwizzle;
19- (NSString*)instanceMethodToSwizzle;
20@end
21
22namespace {
23
24NSString* const kOriginalClassValue = @"Bar";
25NSString* const kSwizzledClassValue = @"Foo";
26NSString* const kOriginalInstanceValue = @"Bizz";
27NSString* const kSwizzledInstanceValue = @"Buzz";
28
Sylvain Defresne647780802017-10-09 14:59:2729using ScopedBlockSwizzlerTest = PlatformTest;
30
rohitrao4aaf45232016-12-05 16:02:5531// Tests that swizzling a class method works properly.
Sylvain Defresne647780802017-10-09 14:59:2732TEST_F(ScopedBlockSwizzlerTest, SwizzlingClassMethods) {
rohitrao4aaf45232016-12-05 16:02:5533 EXPECT_NSEQ(kOriginalClassValue,
34 [ScopedBlockSwizzlerTestClass classMethodToSwizzle]);
35
36 {
Sylvain Defresne14176c9f2025-01-23 10:57:2337 id block = ^NSString*(id self) {
38 return kSwizzledClassValue;
39 };
rohitrao4aaf45232016-12-05 16:02:5540 ScopedBlockSwizzler swizzler([ScopedBlockSwizzlerTestClass class],
41 @selector(classMethodToSwizzle), block);
42 EXPECT_NSEQ(kSwizzledClassValue,
43 [ScopedBlockSwizzlerTestClass classMethodToSwizzle]);
44 }
45
46 EXPECT_NSEQ(kOriginalClassValue,
47 [ScopedBlockSwizzlerTestClass classMethodToSwizzle]);
48}
49
50// Tests that swizzling an instance method works properly.
Sylvain Defresne647780802017-10-09 14:59:2751TEST_F(ScopedBlockSwizzlerTest, SwizzlingInstanceMethod) {
liaoyuke0d45a3e2017-05-17 16:25:1152 ScopedBlockSwizzlerTestClass* target =
53 [[ScopedBlockSwizzlerTestClass alloc] init];
54 target.value = kSwizzledInstanceValue;
rohitrao4aaf45232016-12-05 16:02:5555
56 EXPECT_NSEQ(kOriginalInstanceValue, [target instanceMethodToSwizzle]);
Federica Germinario6c19d4f2024-09-11 10:00:1957 EXPECT_NSNE([target instanceMethodToSwizzle], kSwizzledInstanceValue);
rohitrao4aaf45232016-12-05 16:02:5558
59 {
60 id block = ^NSString*(id self) {
Avi Drissmaneac566b02023-08-18 02:56:2161 return base::apple::ObjCCastStrict<ScopedBlockSwizzlerTestClass>(self)
rohitrao4aaf45232016-12-05 16:02:5562 .value;
63 };
64 ScopedBlockSwizzler swizzler([ScopedBlockSwizzlerTestClass class],
65 @selector(instanceMethodToSwizzle), block);
66 EXPECT_NSEQ(kSwizzledInstanceValue, [target instanceMethodToSwizzle]);
67 }
68
69 EXPECT_NSEQ(kOriginalInstanceValue, [target instanceMethodToSwizzle]);
70}
71
72// Tests that calling |ScopedBlockSwizzler::reset()| properly unswizzles the
73// method.
Sylvain Defresne647780802017-10-09 14:59:2774TEST_F(ScopedBlockSwizzlerTest, TestReset) {
rohitrao4aaf45232016-12-05 16:02:5575 EXPECT_NSEQ(kOriginalClassValue,
76 [ScopedBlockSwizzlerTestClass classMethodToSwizzle]);
77
Sylvain Defresne14176c9f2025-01-23 10:57:2378 id block = ^NSString*(id self) {
79 return kSwizzledClassValue;
80 };
rohitrao4aaf45232016-12-05 16:02:5581 std::unique_ptr<ScopedBlockSwizzler> swizzler(
82 new ScopedBlockSwizzler([ScopedBlockSwizzlerTestClass class],
83 @selector(classMethodToSwizzle), block));
84 EXPECT_NSEQ(kSwizzledClassValue,
85 [ScopedBlockSwizzlerTestClass classMethodToSwizzle]);
86
87 swizzler.reset();
88 EXPECT_NSEQ(kOriginalClassValue,
89 [ScopedBlockSwizzlerTestClass classMethodToSwizzle]);
90}
91
92} // namespace
93
94#pragma mark - ScopedBlockSwizzlerTestClass
95
96@implementation ScopedBlockSwizzlerTestClass
97
98@synthesize value = _value;
99
100+ (NSString*)classMethodToSwizzle {
101 return kOriginalClassValue;
102}
103
104- (NSString*)instanceMethodToSwizzle {
105 return kOriginalInstanceValue;
106}
107
108@end