Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nullability and Generics #107

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Example/BonMot/NSDictionary+BONEquality.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@

@import Foundation;

#import "BONCompatibility.h"

@import CoreGraphics.CGBase;

OBJC_EXTERN const CGFloat kBONCGFloatEpsilon;
OBJC_EXTERN BOOL BONCGFloatsCloseEnough(CGFloat float1, CGFloat float2);

@interface NSDictionary (BONEquality)
@interface BONGenericDict (BONEquality)

- (BOOL)bon_isCloseEnoughEqualToDictionary:(NSDictionary *)dictionary;
- (BOOL)bon_isCloseEnoughEqualToDictionary:(BONNullable BONGenericDict *)dictionary;

@end
4 changes: 2 additions & 2 deletions Example/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
PODS:
- BonMot (2.1.1)
- BonMot (2.3)

DEPENDENCIES:
- BonMot (from `../`)
Expand All @@ -9,6 +9,6 @@ EXTERNAL SOURCES:
:path: "../"

SPEC CHECKSUMS:
BonMot: 52c1f4026036a8a03081a12402fc3e796f56e28e
BonMot: 6fbd53628aca43c70db2a0e778fa847384a7d858

COCOAPODS: 0.39.0
1 change: 1 addition & 0 deletions Example/Pods/Headers/Private/BonMot/BONCompatibility.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Example/Pods/Local Podspecs/BonMot.podspec.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Example/Pods/Manifest.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

272 changes: 138 additions & 134 deletions Example/Pods/Pods.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

36 changes: 12 additions & 24 deletions Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/BonMot.xcscheme

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Example/Pods/Target Support Files/BonMot/BonMot-umbrella.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Example/Pods/Target Support Files/BonMot/Info.plist

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 8 additions & 7 deletions Example/Tests/BONBaseTestCase.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
@import XCTest;
#import "NSDictionary+BONEquality.h"
#import "DummyAssetClass.h"
#import "BONCompatibility.h"

OBJC_EXTERN NSValue *BONValueFromRange(NSUInteger location, NSUInteger length);

Expand Down Expand Up @@ -41,13 +42,13 @@ OBJC_EXTERN NSValue *BONValueFromRange(NSUInteger location, NSUInteger length);
* @param attributedString The attributed string to validate.
* @param controlAttributes A dictionary whose keys are @c NSValue objects containing @c NSRange structs, and whose values are attributes dictionaries.
*/
#define BONAssertAttributedStringHasAttributes(attributedString, controlAttributes) \
NSMutableDictionary *mutableControlAttributes = controlAttributes.mutableCopy; \
[attributedString enumerateAttributesInRange:NSMakeRange(0, attributedString.length) options:0 usingBlock:^(NSDictionary * attrs, NSRange range, BOOL * stop) { \
NSValue *testRangeValue = [NSValue valueWithRange:range]; \
NSDictionary *controlAttrs = controlAttributes[testRangeValue]; \
XCTAssertNotNil(controlAttrs, @"Attributed String had attributes that were not accounted for at %@: %@", NSStringFromRange(range), attrs); \
BONAssertEqualDictionaries(attrs, controlAttrs); \
#define BONAssertAttributedStringHasAttributes(attributedString, controlAttributes) \
NSMutableDictionary *mutableControlAttributes = controlAttributes.mutableCopy; \
[attributedString enumerateAttributesInRange:NSMakeRange(0, attributedString.length) options:0 usingBlock:^(BONStringDict * BONCNonnull attrs, NSRange range, BOOL * BONCNonnull stop) { \
NSValue *testRangeValue = [NSValue valueWithRange:range]; \
NSDictionary *controlAttrs = controlAttributes[testRangeValue]; \
XCTAssertNotNil(controlAttrs, @"Attributed String had attributes that were not accounted for at %@: %@", NSStringFromRange(range), attrs); \
BONAssertEqualDictionaries(attrs, controlAttrs); \
[mutableControlAttributes removeObjectForKey:testRangeValue]; }]; \
XCTAssertEqual(mutableControlAttributes.count, 0, @"Some attributes not found in string: %@", mutableControlAttributes);

Expand Down
5 changes: 3 additions & 2 deletions Example/Tests/BONTextAlignmentTestCase.m
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,9 @@ - (void)testParagraphStyle
// Test behavior when using both `headIndent` and `indentSpacer`
- (void)testHeadIndentWithIndentSpacer
{
UIImage *robotImage = [UIImage imageNamed:@"robot" inBundle:[NSBundle bundleForClass:self.class] compatibleWithTraitCollection:nil];
BONChain *chain = BONChain.new
.image([UIImage imageNamed:@"robot" inBundle:[NSBundle bundleForClass:self.class] compatibleWithTraitCollection:nil])
.image(robotImage)
.headIndent(1.23)
.indentSpacer(4.0);
[chain appendLink:chain.string(@"test")];
Expand All @@ -133,7 +134,7 @@ - (void)testHeadIndentWithIndentSpacer
// The `indentSpacer` doesn't overwrite the `headIndent` value
XCTAssertEqualWithAccuracy(testParagraphStyle.headIndent, 1.23, kBONCGFloatEpsilon);

[testAttributedString enumerateAttributesInRange:NSMakeRange(0, testAttributedString.length) options:0 usingBlock:^(NSDictionary<NSString *, id> *_Nonnull attrs, NSRange range, BOOL *_Nonnull stop) {
[testAttributedString enumerateAttributesInRange:NSMakeRange(0, testAttributedString.length) options:0 usingBlock:^(BONStringDict *BONCNonnull attrs, NSRange range, BOOL *BONCNonnull stop) {
NSParagraphStyle *paragraphStyle = attrs[NSParagraphStyleAttributeName];
if (paragraphStyle != nil) {
NSString *substring = [testAttributedString.string substringWithRange:range];
Expand Down
2 changes: 1 addition & 1 deletion Pod/BonMot.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// BonMot.h
// Pods
// BonMot
//
// Created by Zev Eisenberg on 7/13/15.
//
Expand Down
65 changes: 35 additions & 30 deletions Pod/Classes/BONChain.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// BONChain.h
// Pods
// BonMot
//
// Created by Zev Eisenberg on 4/24/15.
//
Expand All @@ -9,41 +9,44 @@
@import Foundation;

#import "BONText.h"
#import "BONCompatibility.h"

BON_ASSUME_NONNULL_BEGIN

@class BONChain;

typedef BONChain * (^BONChainFontNameAndSize)(NSString *fontName, CGFloat fontSize);
typedef BONChain * (^BONChainFont)(UIFont *font);
typedef BONChain * (^BONChainColor)(UIColor *color);
typedef BONChain * (^BONChainAdobeTracking)(NSInteger adobeTracking);
typedef BONChain * (^BONChainPointTracking)(CGFloat pointTracking);
typedef BONChain * (^BONChainFirstLineHeadIndent)(CGFloat firstLineHeadIndent);
typedef BONChain * (^BONChainHeadIndent)(CGFloat headIndent);
typedef BONChain * (^BONChainTailIndent)(CGFloat tailIndent);
typedef BONChain * (^BONChainLineHeight)(CGFloat lineHeightMultiple);
typedef BONChain * (^BONChainMaximumLineHeight)(CGFloat maximumLineHeight);
typedef BONChain * (^BONChainMinimumLineHeight)(CGFloat minimumLineHeight);
typedef BONChain * (^BONChainLineSpacing)(CGFloat lineSpacing);
typedef BONChain * (^BONChainParagraphSpacingAfter)(CGFloat paragraphSpacing);
typedef BONChain * (^BONChainParagraphSpacingBefore)(CGFloat paragraphSpacingBefore);
typedef BONChain * (^BONChainBaselineOffset)(CGFloat baselineOffset);
typedef BONChain * (^BONChainAlignment)(NSTextAlignment alignment);
typedef BONChain * (^BONChainFigureCase)(BONFigureCase figureCase);
typedef BONChain * (^BONChainFigureSpacing)(BONFigureSpacing figureSpacing);
typedef BONChain * (^BONChainIndentSpacer)(CGFloat indentSpacer);
typedef BONChain * (^BONChainString)(NSString *string);
typedef BONChain * (^BONChainImage)(UIImage *image);

typedef BONChain * (^BONChainUnderlineStyle)(NSUnderlineStyle style);
typedef BONChain * (^BONChainUnderlineColor)(UIColor *color);

typedef BONChain * (^BONChainStrikethroughStyle)(NSUnderlineStyle style);
typedef BONChain * (^BONChainStrikethroughColor)(UIColor *color);
typedef BONChain *BONCNonnull (^BONChainFontNameAndSize)(NSString *BONCNonnull fontName, CGFloat fontSize);
typedef BONChain *BONCNonnull (^BONChainFont)(UIFont *BONCNullable font);
typedef BONChain *BONCNonnull (^BONChainColor)(UIColor *BONCNullable color);
typedef BONChain *BONCNonnull (^BONChainAdobeTracking)(NSInteger adobeTracking);
typedef BONChain *BONCNonnull (^BONChainPointTracking)(CGFloat pointTracking);
typedef BONChain *BONCNonnull (^BONChainFirstLineHeadIndent)(CGFloat firstLineHeadIndent);
typedef BONChain *BONCNonnull (^BONChainHeadIndent)(CGFloat headIndent);
typedef BONChain *BONCNonnull (^BONChainTailIndent)(CGFloat tailIndent);
typedef BONChain *BONCNonnull (^BONChainLineHeight)(CGFloat lineHeightMultiple);
typedef BONChain *BONCNonnull (^BONChainMaximumLineHeight)(CGFloat maximumLineHeight);
typedef BONChain *BONCNonnull (^BONChainMinimumLineHeight)(CGFloat minimumLineHeight);
typedef BONChain *BONCNonnull (^BONChainLineSpacing)(CGFloat lineSpacing);
typedef BONChain *BONCNonnull (^BONChainParagraphSpacingAfter)(CGFloat paragraphSpacing);
typedef BONChain *BONCNonnull (^BONChainParagraphSpacingBefore)(CGFloat paragraphSpacingBefore);
typedef BONChain *BONCNonnull (^BONChainBaselineOffset)(CGFloat baselineOffset);
typedef BONChain *BONCNonnull (^BONChainAlignment)(NSTextAlignment alignment);
typedef BONChain *BONCNonnull (^BONChainFigureCase)(BONFigureCase figureCase);
typedef BONChain *BONCNonnull (^BONChainFigureSpacing)(BONFigureSpacing figureSpacing);
typedef BONChain *BONCNonnull (^BONChainIndentSpacer)(CGFloat indentSpacer);
typedef BONChain *BONCNonnull (^BONChainString)(NSString *BONCNullable string);
typedef BONChain *BONCNonnull (^BONChainImage)(UIImage *BONCNullable image);

typedef BONChain *BONCNonnull (^BONChainUnderlineStyle)(NSUnderlineStyle style);
typedef BONChain *BONCNonnull (^BONChainUnderlineColor)(UIColor *BONCNullable color);

typedef BONChain *BONCNonnull (^BONChainStrikethroughStyle)(NSUnderlineStyle style);
typedef BONChain *BONCNonnull (^BONChainStrikethroughColor)(UIColor *BONCNullable color);

@interface BONChain : NSObject <NSCopying, BONChainable>

@property (copy, nonatomic, readonly) NSAttributedString *attributedString;
@property (copy, nonatomic, readonly) NSDictionary *attributes;
@property (copy, nonatomic, readonly) BONStringDict *attributes;

// fontNameAndSize and font are mutually exclusive: setting one will unset the other
@property (copy, nonatomic, readonly) BONChainFontNameAndSize fontNameAndSize;
Expand Down Expand Up @@ -91,6 +94,8 @@ typedef BONChain * (^BONChainStrikethroughColor)(UIColor *color);

// concatenation
- (void)appendLink:(id<BONChainable>)link;
- (void)appendLink:(id<BONChainable>)link separator:(NSString *)separator;
- (void)appendLink:(id<BONChainable>)link separator:(BONNullable NSString *)separator;

@end

BON_ASSUME_NONNULL_END
2 changes: 1 addition & 1 deletion Pod/Classes/BONChain.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// BONChain.m
// Pods
// BonMot
//
// Created by Zev Eisenberg on 4/24/15.
//
Expand Down
8 changes: 7 additions & 1 deletion Pod/Classes/BONChainable.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
//
// BONChainable.h
// Pods
// BonMot
//
// Created by Zev Eisenberg on 10/9/15.
//
//

@import Foundation;

#import "BONCompatibility.h"

@class BONText;

BON_ASSUME_NONNULL_BEGIN

/**
* Objects conforming to this protocol can be used in BonMot chaining operations.
*/
Expand All @@ -18,3 +22,5 @@
@property (strong, nonatomic, readonly) BONText *text;

@end

BON_ASSUME_NONNULL_END
46 changes: 46 additions & 0 deletions Pod/Classes/BONCompatibility.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// BONCompatibility.h
// BonMot
//
// Created by Zev Eisenberg on 3/4/15.
//

//
// Nullability annotation compatibility.
//

// clang-format off
#if __has_feature(nullability)
# define BONNonnull nonnull
# define BONNullable nullable
# define BONCNonnull __nonnull
# define BONCNullable __nullable
# define BON_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
# define BON_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END
#else
# define BONNonnull
# define BONNullable
# define BONCNonnull
# define BONCNullable
# define BON_ASSUME_NONNULL_BEGIN
# define BON_ASSUME_NONNULL_END
#endif

//
// Lightweight generics compatibility.
//

#if __has_feature(objc_generics)
# define BONGeneric(class, ...) class<__VA_ARGS__>
# define BONGenericType(type) type
#else
# define BONGeneric(class, ...) class
# define BONGenericType(type) id
#endif


#define BONStringDict BONGeneric(NSDictionary, NSString *, id)
#define BONStringMutableDict BONGeneric(NSMutableDictionary, NSString *, id)
#define BONGenericDict BONGeneric(NSDictionary, KeyType, ObjectType)

// clang-format on
Loading