scoped_objc_class_swizzler_unittest.mm 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // Copyright 2014 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. #import "base/mac/scoped_objc_class_swizzler.h"
  5. #import "base/mac/scoped_nsobject.h"
  6. #include "testing/gtest/include/gtest/gtest.h"
  7. @interface ObjCClassSwizzlerTestOne : NSObject
  8. + (NSInteger)function;
  9. - (NSInteger)method;
  10. - (NSInteger)modifier;
  11. @end
  12. @interface ObjCClassSwizzlerTestTwo : NSObject
  13. + (NSInteger)function;
  14. - (NSInteger)method;
  15. - (NSInteger)modifier;
  16. @end
  17. @implementation ObjCClassSwizzlerTestOne : NSObject
  18. + (NSInteger)function {
  19. return 10;
  20. }
  21. - (NSInteger)method {
  22. // Multiply by a modifier to ensure |self| in a swizzled implementation
  23. // refers to the original object.
  24. return 1 * [self modifier];
  25. }
  26. - (NSInteger)modifier {
  27. return 3;
  28. }
  29. @end
  30. @implementation ObjCClassSwizzlerTestTwo : NSObject
  31. + (NSInteger)function {
  32. return 20;
  33. }
  34. - (NSInteger)method {
  35. return 2 * [self modifier];
  36. }
  37. - (NSInteger)modifier {
  38. return 7;
  39. }
  40. @end
  41. @interface ObjCClassSwizzlerTestOne (AlternateCategory)
  42. - (NSInteger)alternate;
  43. @end
  44. @implementation ObjCClassSwizzlerTestOne (AlternateCategory)
  45. - (NSInteger)alternate {
  46. return 3 * [self modifier];
  47. }
  48. @end
  49. @interface ObjCClassSwizzlerTestOneChild : ObjCClassSwizzlerTestOne
  50. - (NSInteger)childAlternate;
  51. @end
  52. @implementation ObjCClassSwizzlerTestOneChild
  53. - (NSInteger)childAlternate {
  54. return 5 * [self modifier];
  55. }
  56. @end
  57. namespace base::mac {
  58. TEST(ObjCClassSwizzlerTest, SwizzleInstanceMethods) {
  59. base::scoped_nsobject<ObjCClassSwizzlerTestOne> object_one(
  60. [[ObjCClassSwizzlerTestOne alloc] init]);
  61. base::scoped_nsobject<ObjCClassSwizzlerTestTwo> object_two(
  62. [[ObjCClassSwizzlerTestTwo alloc] init]);
  63. EXPECT_EQ(3, [object_one method]);
  64. EXPECT_EQ(14, [object_two method]);
  65. {
  66. base::mac::ScopedObjCClassSwizzler swizzler(
  67. [ObjCClassSwizzlerTestOne class],
  68. [ObjCClassSwizzlerTestTwo class],
  69. @selector(method));
  70. EXPECT_EQ(6, [object_one method]);
  71. EXPECT_EQ(7, [object_two method]);
  72. EXPECT_EQ(3, swizzler.InvokeOriginal<int>(object_one, @selector(method)));
  73. }
  74. EXPECT_EQ(3, [object_one method]);
  75. EXPECT_EQ(14, [object_two method]);
  76. }
  77. TEST(ObjCClassSwizzlerTest, SwizzleClassMethods) {
  78. EXPECT_EQ(10, [ObjCClassSwizzlerTestOne function]);
  79. EXPECT_EQ(20, [ObjCClassSwizzlerTestTwo function]);
  80. {
  81. base::mac::ScopedObjCClassSwizzler swizzler(
  82. [ObjCClassSwizzlerTestOne class],
  83. [ObjCClassSwizzlerTestTwo class],
  84. @selector(function));
  85. EXPECT_EQ(20, [ObjCClassSwizzlerTestOne function]);
  86. EXPECT_EQ(10, [ObjCClassSwizzlerTestTwo function]);
  87. EXPECT_EQ(10, swizzler.InvokeOriginal<int>([ObjCClassSwizzlerTestOne class],
  88. @selector(function)));
  89. }
  90. EXPECT_EQ(10, [ObjCClassSwizzlerTestOne function]);
  91. EXPECT_EQ(20, [ObjCClassSwizzlerTestTwo function]);
  92. }
  93. TEST(ObjCClassSwizzlerTest, SwizzleViaCategory) {
  94. base::scoped_nsobject<ObjCClassSwizzlerTestOne> object_one(
  95. [[ObjCClassSwizzlerTestOne alloc] init]);
  96. EXPECT_EQ(3, [object_one method]);
  97. {
  98. base::mac::ScopedObjCClassSwizzler swizzler(
  99. [ObjCClassSwizzlerTestOne class],
  100. @selector(method),
  101. @selector(alternate));
  102. EXPECT_EQ(9, [object_one method]);
  103. EXPECT_EQ(3, swizzler.InvokeOriginal<int>(object_one, @selector(method)));
  104. }
  105. EXPECT_EQ(3, [object_one method]);
  106. }
  107. TEST(ObjCClassSwizzlerTest, SwizzleViaInheritance) {
  108. base::scoped_nsobject<ObjCClassSwizzlerTestOneChild> child(
  109. [[ObjCClassSwizzlerTestOneChild alloc] init]);
  110. EXPECT_EQ(3, [child method]);
  111. {
  112. base::mac::ScopedObjCClassSwizzler swizzler(
  113. [ObjCClassSwizzlerTestOneChild class],
  114. @selector(method),
  115. @selector(childAlternate));
  116. EXPECT_EQ(15, [child method]);
  117. EXPECT_EQ(3, swizzler.InvokeOriginal<int>(child, @selector(method)));
  118. }
  119. EXPECT_EQ(3, [child method]);
  120. }
  121. } // namespace base::mac