KWBeWithinMatcher.m 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. //
  2. // Licensed under the terms in License.txt
  3. //
  4. // Copyright 2010 Allen Ding. All rights reserved.
  5. //
  6. #import "KWBeWithinMatcher.h"
  7. #import "KWFormatter.h"
  8. #import "KWObjCUtilities.h"
  9. #import "KWValue.h"
  10. @interface KWBeWithinMatcher()
  11. @property (nonatomic, readwrite, strong) id distance;
  12. @property (nonatomic, readwrite, strong) id otherValue;
  13. @end
  14. @implementation KWBeWithinMatcher
  15. #pragma mark - Getting Matcher Strings
  16. + (NSArray *)matcherStrings {
  17. return @[@"beWithin:of:", @"equal:withDelta:"];
  18. }
  19. #pragma mark - Matching
  20. // Evaluation is done by getting the underlying values as the widest data
  21. // types available.
  22. - (BOOL)evaluateForFloatingPoint {
  23. double firstValue = [self.subject doubleValue];
  24. double secondValue = [self.otherValue doubleValue];
  25. double theDistance = [self.distance doubleValue];
  26. double absoluteDifference = firstValue > secondValue ? firstValue - secondValue : secondValue - firstValue;
  27. return absoluteDifference <= theDistance;
  28. }
  29. - (BOOL)evaluateForUnsignedIntegral {
  30. unsigned long long firstValue = [self.subject unsignedLongLongValue];
  31. unsigned long long secondValue = [self.otherValue unsignedLongLongValue];
  32. unsigned long long theDistance = [self.distance unsignedLongLongValue];
  33. unsigned long long absoluteDifference = firstValue > secondValue ? firstValue - secondValue : secondValue - firstValue;
  34. return absoluteDifference <= theDistance;
  35. }
  36. - (BOOL)evaluateForSignedIntegral {
  37. long long firstValue = [self.subject longLongValue];
  38. long long secondValue = [self.otherValue longLongValue];
  39. long long theDistance = [self.distance longLongValue];
  40. long long absoluteDifference = firstValue > secondValue ? firstValue - secondValue : secondValue - firstValue;
  41. return absoluteDifference <= theDistance;
  42. }
  43. - (BOOL)evaluate {
  44. const char *objCType = [self.subject objCType];
  45. if (KWObjCTypeIsFloatingPoint(objCType))
  46. return [self evaluateForFloatingPoint];
  47. else if (KWObjCTypeIsUnsignedIntegral(objCType))
  48. return [self evaluateForUnsignedIntegral];
  49. else
  50. return [self evaluateForSignedIntegral];
  51. }
  52. #pragma mark - Getting Failure Messages
  53. - (NSString *)failureMessageForShould {
  54. return [NSString stringWithFormat:@"expected subject to be within %@ of %@, got %@",
  55. [KWFormatter formatObject:self.distance],
  56. [KWFormatter formatObject:self.otherValue],
  57. [KWFormatter formatObject:self.subject]];
  58. }
  59. - (NSString *)description {
  60. return [NSString stringWithFormat:@"be within %@ of %@", self.distance, self.otherValue];
  61. }
  62. #pragma mark - Configuring Matchers
  63. - (void)beWithin:(id)aDistance of:(id)aValue {
  64. self.distance = aDistance;
  65. self.otherValue = aValue;
  66. }
  67. - (void)equal:(double)aValue withDelta:(double)aDelta {
  68. [self beWithin:[KWValue valueWithDouble:aDelta] of:[KWValue valueWithDouble:aValue]];
  69. }
  70. @end