SDUtilsTests.m 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * This file is part of the SDWebImage package.
  3. * (c) Olivier Poitrey <rs@dailymotion.com>
  4. * (c) Matt Galloway
  5. *
  6. * For the full copyright and license information, please view the LICENSE
  7. * file that was distributed with this source code.
  8. */
  9. #import "SDTestCase.h"
  10. #import "SDWeakProxy.h"
  11. #import "SDDisplayLink.h"
  12. #import "SDInternalMacros.h"
  13. #import "SDFileAttributeHelper.h"
  14. #import "UIColor+SDHexString.h"
  15. @interface SDUtilsTests : SDTestCase
  16. @end
  17. @implementation SDUtilsTests
  18. - (void)testSDWeakProxy {
  19. NSObject *object = [NSObject new];
  20. SDWeakProxy *proxy = [SDWeakProxy proxyWithTarget:object];
  21. SEL sel = @selector(hash);
  22. NSMethodSignature *signature = [proxy methodSignatureForSelector:sel];
  23. NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
  24. [proxy forwardInvocation:invocation];
  25. void *returnValue;
  26. [invocation getReturnValue:&returnValue];
  27. expect(returnValue).beNil();
  28. expect([((NSObject *)proxy) forwardingTargetForSelector:sel]).equal(object);
  29. expect(proxy.isProxy).beTruthy();
  30. expect([proxy respondsToSelector:sel]).equal([object respondsToSelector:sel]);
  31. expect([proxy isEqual:object]).beTruthy();
  32. expect(proxy.hash).equal(object.hash);
  33. expect(proxy.superclass).equal(object.superclass);
  34. expect(proxy.class).equal(object.class);
  35. expect([proxy isKindOfClass:NSObject.class]).equal([object isKindOfClass:NSObject.class]);
  36. expect([proxy isMemberOfClass:NSObject.class]).equal([object isMemberOfClass:NSObject.class]);
  37. expect([proxy conformsToProtocol:@protocol(NSObject)]).equal([object conformsToProtocol:@protocol(NSObject)]);
  38. expect([proxy.description isEqualToString:object.description]).beTruthy();
  39. expect([proxy.debugDescription isEqualToString:object.debugDescription]).beTruthy();
  40. }
  41. - (void)testSDDisplayLink {
  42. XCTestExpectation *expectation1 = [self expectationWithDescription:@"Display Link Stop"];
  43. XCTestExpectation *expectation2 = [self expectationWithDescription:@"Display Link Start"];
  44. SDDisplayLink *displayLink = [SDDisplayLink displayLinkWithTarget:self selector:@selector(displayLinkDidRefresh:)];
  45. NSTimeInterval duration = displayLink.duration; // Initial value
  46. expect(duration).equal(1.0 / 60);
  47. [displayLink addToRunLoop:NSRunLoop.mainRunLoop forMode:NSRunLoopCommonModes];
  48. [displayLink start];
  49. expect(displayLink.isRunning).beTruthy();
  50. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  51. expect(displayLink.isRunning).beTruthy();
  52. [displayLink stop];
  53. });
  54. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  55. expect(displayLink.isRunning).beFalsy();
  56. [displayLink start];
  57. [expectation1 fulfill];
  58. });
  59. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  60. expect(displayLink.isRunning).beTruthy();
  61. [displayLink stop];
  62. [expectation2 fulfill];
  63. });
  64. [self waitForExpectationsWithCommonTimeout];
  65. }
  66. - (void)displayLinkDidRefresh:(SDDisplayLink *)displayLink {
  67. NSTimeInterval duration = displayLink.duration; // Running value
  68. expect(duration).beGreaterThan(0.01);
  69. expect(duration).beLessThan(0.02);
  70. }
  71. - (void)testSDFileAttributeHelper {
  72. NSData *fileData = [@"File Data" dataUsingEncoding:NSUTF8StringEncoding];
  73. NSData *extendedData = [@"Extended Data" dataUsingEncoding:NSUTF8StringEncoding];
  74. NSString *filePath = @"/tmp/file.dat";
  75. [NSFileManager.defaultManager removeItemAtPath:filePath error:nil];
  76. [fileData writeToFile:filePath atomically:YES];
  77. BOOL exist = [NSFileManager.defaultManager fileExistsAtPath:filePath];
  78. expect(exist).beTruthy();
  79. NSArray *names = [SDFileAttributeHelper extendedAttributeNamesAtPath:filePath traverseLink:NO error:nil];
  80. expect(names.count).equal(0);
  81. NSString *attr = @"com.hackemist.test";
  82. [SDFileAttributeHelper setExtendedAttribute:attr value:extendedData atPath:filePath traverseLink:NO overwrite:YES error:nil];
  83. BOOL hasAttr =[SDFileAttributeHelper hasExtendedAttribute:attr atPath:filePath traverseLink:NO error:nil];
  84. expect(hasAttr).beTruthy();
  85. names = [SDFileAttributeHelper extendedAttributeNamesAtPath:filePath traverseLink:NO error:nil];
  86. expect(names.count).equal(1);
  87. expect(names.firstObject).equal(attr);
  88. NSData *queriedData = [SDFileAttributeHelper extendedAttribute:attr atPath:filePath traverseLink:NO error:nil];
  89. expect(extendedData).equal(queriedData);
  90. BOOL removed = [SDFileAttributeHelper removeExtendedAttribute:attr atPath:filePath traverseLink:NO error:nil];
  91. expect(removed).beTruthy();
  92. hasAttr = [SDFileAttributeHelper hasExtendedAttribute:attr atPath:filePath traverseLink:NO error:nil];
  93. expect(hasAttr).beFalsy();
  94. }
  95. - (void)testSDGraphicsImageRenderer {
  96. // Main Screen
  97. SDGraphicsImageRendererFormat *format = SDGraphicsImageRendererFormat.preferredFormat;
  98. #if SD_UIKIT
  99. CGFloat screenScale = [UIScreen mainScreen].scale;
  100. #elif SD_MAC
  101. CGFloat screenScale = [NSScreen mainScreen].backingScaleFactor;
  102. #endif
  103. expect(format.scale).equal(screenScale);
  104. expect(format.opaque).beFalsy();
  105. #if SD_UIKIT
  106. expect(format.preferredRange).equal(SDGraphicsImageRendererFormatRangeAutomatic);
  107. #elif SD_MAC
  108. expect(format.preferredRange).equal(SDGraphicsImageRendererFormatRangeStandard);
  109. #endif
  110. CGSize size = CGSizeMake(100, 100);
  111. SDGraphicsImageRenderer *renderer = [[SDGraphicsImageRenderer alloc] initWithSize:size format:format];
  112. UIColor *color = UIColor.redColor;
  113. UIImage *image = [renderer imageWithActions:^(CGContextRef _Nonnull context) {
  114. [color setFill];
  115. CGContextFillRect(context, CGRectMake(0, 0, size.width, size.height));
  116. }];
  117. expect(image.scale).equal(format.scale);
  118. expect([[image sd_colorAtPoint:CGPointMake(50, 50)].sd_hexString isEqualToString:color.sd_hexString]).beTruthy();
  119. }
  120. - (void)testSDScaledImageForKey {
  121. // Test nil
  122. expect(SDScaledImageForKey(nil, nil)).beNil();
  123. // Test @2x
  124. NSData *data = [NSData dataWithContentsOfFile:[self testGIFPath]];
  125. UIImage * image = [UIImage sd_imageWithGIFData:data];
  126. expect(image.sd_isAnimated).beTruthy();
  127. expect(image.scale).equal(1);
  128. UIImage *scaledImage = SDScaledImageForKey(@"test@2x.gif", image);
  129. expect(scaledImage.scale).equal(2);
  130. }
  131. - (void)testInternalMacro {
  132. @weakify(self);
  133. @onExit {
  134. @strongify(self);
  135. expect(self).notTo.beNil();
  136. };
  137. }
  138. #pragma mark - Helper
  139. - (NSString *)testJPEGPath {
  140. NSBundle *testBundle = [NSBundle bundleForClass:[self class]];
  141. return [testBundle pathForResource:@"TestImage" ofType:@"jpg"];
  142. }
  143. - (NSString *)testGIFPath {
  144. NSBundle *testBundle = [NSBundle bundleForClass:[self class]];
  145. return [testBundle pathForResource:@"TestImage" ofType:@"gif"];
  146. }
  147. @end