scoped_block_swizzler_unittest.mm 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ios/testing/scoped_block_swizzler.h"
  5. #include "base/mac/foundation_util.h"
  6. #include "testing/gtest/include/gtest/gtest.h"
  7. #import "testing/gtest_mac.h"
  8. #include "testing/platform_test.h"
  9. #if !defined(__has_feature) || !__has_feature(objc_arc)
  10. #error "This file requires ARC support."
  11. #endif
  12. // Class containing two methods that will be swizzled by the unittests.
  13. @interface ScopedBlockSwizzlerTestClass : NSObject
  14. // An NSString property that will be accessed by one of the swizzled methods.
  15. @property(nonatomic, copy) NSString* value;
  16. + (NSString*)classMethodToSwizzle;
  17. - (NSString*)instanceMethodToSwizzle;
  18. @end
  19. namespace {
  20. NSString* const kOriginalClassValue = @"Bar";
  21. NSString* const kSwizzledClassValue = @"Foo";
  22. NSString* const kOriginalInstanceValue = @"Bizz";
  23. NSString* const kSwizzledInstanceValue = @"Buzz";
  24. using ScopedBlockSwizzlerTest = PlatformTest;
  25. // Tests that swizzling a class method works properly.
  26. TEST_F(ScopedBlockSwizzlerTest, SwizzlingClassMethods) {
  27. EXPECT_NSEQ(kOriginalClassValue,
  28. [ScopedBlockSwizzlerTestClass classMethodToSwizzle]);
  29. {
  30. id block = ^NSString*(id self) { return kSwizzledClassValue; };
  31. ScopedBlockSwizzler swizzler([ScopedBlockSwizzlerTestClass class],
  32. @selector(classMethodToSwizzle), block);
  33. EXPECT_NSEQ(kSwizzledClassValue,
  34. [ScopedBlockSwizzlerTestClass classMethodToSwizzle]);
  35. }
  36. EXPECT_NSEQ(kOriginalClassValue,
  37. [ScopedBlockSwizzlerTestClass classMethodToSwizzle]);
  38. }
  39. // Tests that swizzling an instance method works properly.
  40. TEST_F(ScopedBlockSwizzlerTest, SwizzlingInstanceMethod) {
  41. ScopedBlockSwizzlerTestClass* target =
  42. [[ScopedBlockSwizzlerTestClass alloc] init];
  43. target.value = kSwizzledInstanceValue;
  44. EXPECT_NSEQ(kOriginalInstanceValue, [target instanceMethodToSwizzle]);
  45. EXPECT_FALSE([[target instanceMethodToSwizzle]
  46. isEqualToString:kSwizzledInstanceValue]);
  47. {
  48. id block = ^NSString*(id self) {
  49. return base::mac::ObjCCastStrict<ScopedBlockSwizzlerTestClass>(self)
  50. .value;
  51. };
  52. ScopedBlockSwizzler swizzler([ScopedBlockSwizzlerTestClass class],
  53. @selector(instanceMethodToSwizzle), block);
  54. EXPECT_NSEQ(kSwizzledInstanceValue, [target instanceMethodToSwizzle]);
  55. }
  56. EXPECT_NSEQ(kOriginalInstanceValue, [target instanceMethodToSwizzle]);
  57. }
  58. // Tests that calling |ScopedBlockSwizzler::reset()| properly unswizzles the
  59. // method.
  60. TEST_F(ScopedBlockSwizzlerTest, TestReset) {
  61. EXPECT_NSEQ(kOriginalClassValue,
  62. [ScopedBlockSwizzlerTestClass classMethodToSwizzle]);
  63. id block = ^NSString*(id self) { return kSwizzledClassValue; };
  64. std::unique_ptr<ScopedBlockSwizzler> swizzler(
  65. new ScopedBlockSwizzler([ScopedBlockSwizzlerTestClass class],
  66. @selector(classMethodToSwizzle), block));
  67. EXPECT_NSEQ(kSwizzledClassValue,
  68. [ScopedBlockSwizzlerTestClass classMethodToSwizzle]);
  69. swizzler.reset();
  70. EXPECT_NSEQ(kOriginalClassValue,
  71. [ScopedBlockSwizzlerTestClass classMethodToSwizzle]);
  72. }
  73. } // namespace
  74. #pragma mark - ScopedBlockSwizzlerTestClass
  75. @implementation ScopedBlockSwizzlerTestClass
  76. @synthesize value = _value;
  77. + (NSString*)classMethodToSwizzle {
  78. return kOriginalClassValue;
  79. }
  80. - (NSString*)instanceMethodToSwizzle {
  81. return kOriginalInstanceValue;
  82. }
  83. @end