Authored by Jonas Budelmann

better header comments, weak ref to views!

@@ -79,7 +79,6 @@ @@ -79,7 +79,6 @@
79 DD52F1E6179CAACA005CD195 /* UIView+MASAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+MASAdditions.m"; sourceTree = "<group>"; }; 79 DD52F1E6179CAACA005CD195 /* UIView+MASAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+MASAdditions.m"; sourceTree = "<group>"; };
80 DD52F1ED179CAAEE005CD195 /* Masonry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Masonry.h; sourceTree = "<group>"; }; 80 DD52F1ED179CAAEE005CD195 /* Masonry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Masonry.h; sourceTree = "<group>"; };
81 DDE2653D179D24E600D48565 /* UIView+MASShorthandAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+MASShorthandAdditions.h"; sourceTree = "<group>"; }; 81 DDE2653D179D24E600D48565 /* UIView+MASShorthandAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+MASShorthandAdditions.h"; sourceTree = "<group>"; };
82 - DDF3875D179E8A2900178773 /* SpecHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpecHelpers.h; sourceTree = "<group>"; };  
83 DE643A835A4447F4807FDBFA /* libPods-MasonryTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-MasonryTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 82 DE643A835A4447F4807FDBFA /* libPods-MasonryTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-MasonryTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
84 /* End PBXFileReference section */ 83 /* End PBXFileReference section */
85 84
@@ -179,7 +178,6 @@ @@ -179,7 +178,6 @@
179 DD52F1D7179CAA78005CD195 /* Specs */ = { 178 DD52F1D7179CAA78005CD195 /* Specs */ = {
180 isa = PBXGroup; 179 isa = PBXGroup;
181 children = ( 180 children = (
182 - DDF3875D179E8A2900178773 /* SpecHelpers.h */,  
183 DD52F1D8179CAA9C005CD195 /* MASCompositeConstraintSpec.m */, 181 DD52F1D8179CAA9C005CD195 /* MASCompositeConstraintSpec.m */,
184 DD52F1D9179CAA9C005CD195 /* MASViewConstraintSpec.m */, 182 DD52F1D9179CAA9C005CD195 /* MASViewConstraintSpec.m */,
185 ); 183 );
@@ -10,15 +10,15 @@ @@ -10,15 +10,15 @@
10 #import "MASConstraint.h" 10 #import "MASConstraint.h"
11 11
12 typedef NS_ENUM(NSInteger, MASCompositeViewConstraintType) { 12 typedef NS_ENUM(NSInteger, MASCompositeViewConstraintType) {
13 - MASCompositeViewConstraintTypeEdges,  
14 - MASCompositeViewConstraintTypeSize,  
15 - MASCompositeViewConstraintTypeCenter, 13 + MASCompositeViewConstraintTypeEdges, //top, left, bottom, right
  14 + MASCompositeViewConstraintTypeSize, //width, height
  15 + MASCompositeViewConstraintTypeCenter, //centerX, centerY
16 }; 16 };
17 17
18 @interface MASCompositeConstraint : NSObject <MASConstraint> 18 @interface MASCompositeConstraint : NSObject <MASConstraint>
19 19
20 @property (nonatomic, weak) id<MASConstraintDelegate> delegate; 20 @property (nonatomic, weak) id<MASConstraintDelegate> delegate;
21 -@property (nonatomic, strong, readonly) UIView *view; 21 +@property (nonatomic, weak, readonly) UIView *view;
22 @property (nonatomic, assign, readonly) MASCompositeViewConstraintType type; 22 @property (nonatomic, assign, readonly) MASCompositeViewConstraintType type;
23 23
24 - (id)initWithView:(UIView *)view type:(MASCompositeViewConstraintType)type; 24 - (id)initWithView:(UIView *)view type:(MASCompositeViewConstraintType)type;
@@ -69,7 +69,7 @@ @@ -69,7 +69,7 @@
69 [self.completedChildConstraints addObject:constraint]; 69 [self.completedChildConstraints addObject:constraint];
70 } 70 }
71 71
72 -#pragma mark - layout constant 72 +#pragma mark - NSLayoutConstraint constant proxies
73 73
74 - (id<MASConstraint> (^)(UIEdgeInsets))insets { 74 - (id<MASConstraint> (^)(UIEdgeInsets))insets {
75 return ^id(UIEdgeInsets insets) { 75 return ^id(UIEdgeInsets insets) {
@@ -107,7 +107,7 @@ @@ -107,7 +107,7 @@
107 }; 107 };
108 } 108 }
109 109
110 -#pragma mark - layout multiplier 110 +#pragma mark - NSLayoutConstraint multiplier proxies
111 111
112 - (id<MASConstraint> (^)(CGFloat))percent { 112 - (id<MASConstraint> (^)(CGFloat))percent {
113 return ^id(CGFloat percent) { 113 return ^id(CGFloat percent) {
@@ -118,7 +118,7 @@ @@ -118,7 +118,7 @@
118 }; 118 };
119 } 119 }
120 120
121 -#pragma mark - layout priority 121 +#pragma mark - MASLayoutPriority proxies
122 122
123 - (id<MASConstraint> (^)(MASLayoutPriority))priority { 123 - (id<MASConstraint> (^)(MASLayoutPriority))priority {
124 return ^id(MASLayoutPriority priority) { 124 return ^id(MASLayoutPriority priority) {
@@ -150,7 +150,7 @@ @@ -150,7 +150,7 @@
150 }; 150 };
151 } 151 }
152 152
153 -#pragma mark - layout relation 153 +#pragma mark - NSLayoutRelation proxies
154 154
155 - (id<MASConstraint> (^)(id))relationWithBlock:(id<MASConstraint> (^)(id<MASConstraint> constraint, id attr))block { 155 - (id<MASConstraint> (^)(id))relationWithBlock:(id<MASConstraint> (^)(id<MASConstraint> constraint, id attr))block {
156 return ^id(id attr) { 156 return ^id(id attr) {
@@ -199,6 +199,8 @@ @@ -199,6 +199,8 @@
199 for (id<MASConstraint> constraint in self.completedChildConstraints) { 199 for (id<MASConstraint> constraint in self.completedChildConstraints) {
200 [constraint commit]; 200 [constraint commit];
201 } 201 }
  202 + [self.currentChildConstraints removeAllObjects];
  203 + [self.completedChildConstraints removeAllObjects];
202 } 204 }
203 205
204 @end 206 @end
@@ -19,22 +19,22 @@ typedef float MASLayoutPriority; @@ -19,22 +19,22 @@ typedef float MASLayoutPriority;
19 19
20 @protocol MASConstraint <NSObject> 20 @protocol MASConstraint <NSObject>
21 21
22 -//layout constants 22 +//NSLayoutConstraint constant proxies
23 @property (nonatomic, copy, readonly) id<MASConstraint> (^insets)(UIEdgeInsets insets); 23 @property (nonatomic, copy, readonly) id<MASConstraint> (^insets)(UIEdgeInsets insets);
24 @property (nonatomic, copy, readonly) id<MASConstraint> (^sizeOffset)(CGSize offset); 24 @property (nonatomic, copy, readonly) id<MASConstraint> (^sizeOffset)(CGSize offset);
25 @property (nonatomic, copy, readonly) id<MASConstraint> (^centerOffset)(CGPoint offset); 25 @property (nonatomic, copy, readonly) id<MASConstraint> (^centerOffset)(CGPoint offset);
26 @property (nonatomic, copy, readonly) id<MASConstraint> (^offset)(CGFloat offset); 26 @property (nonatomic, copy, readonly) id<MASConstraint> (^offset)(CGFloat offset);
27 27
28 -//layout multipliers 28 +//NSLayoutConstraint multiplier proxies
29 @property (nonatomic, copy, readonly) id<MASConstraint> (^percent)(CGFloat percent); 29 @property (nonatomic, copy, readonly) id<MASConstraint> (^percent)(CGFloat percent);
30 30
31 -//layout priority  
32 -@property (nonatomic, copy, readonly) id<MASConstraint> (^priority)(UILayoutPriority priority); 31 +//MASLayoutPriority proxies
  32 +@property (nonatomic, copy, readonly) id<MASConstraint> (^priority)(MASLayoutPriority priority);
33 @property (nonatomic, copy, readonly) id<MASConstraint> (^priorityLow)(); 33 @property (nonatomic, copy, readonly) id<MASConstraint> (^priorityLow)();
34 @property (nonatomic, copy, readonly) id<MASConstraint> (^priorityMedium)(); 34 @property (nonatomic, copy, readonly) id<MASConstraint> (^priorityMedium)();
35 @property (nonatomic, copy, readonly) id<MASConstraint> (^priorityHigh)(); 35 @property (nonatomic, copy, readonly) id<MASConstraint> (^priorityHigh)();
36 36
37 -//layout relation 37 +//NSLayoutRelation proxies
38 @property (nonatomic, copy, readonly) id<MASConstraint> (^equalTo)(id attr); 38 @property (nonatomic, copy, readonly) id<MASConstraint> (^equalTo)(id attr);
39 @property (nonatomic, copy, readonly) id<MASConstraint> (^greaterThanOrEqualTo)(id attr); 39 @property (nonatomic, copy, readonly) id<MASConstraint> (^greaterThanOrEqualTo)(id attr);
40 @property (nonatomic, copy, readonly) id<MASConstraint> (^lessThanOrEqualTo)(id attr); 40 @property (nonatomic, copy, readonly) id<MASConstraint> (^lessThanOrEqualTo)(id attr);
@@ -42,12 +42,18 @@ typedef float MASLayoutPriority; @@ -42,12 +42,18 @@ typedef float MASLayoutPriority;
42 //semantic properties 42 //semantic properties
43 @property (nonatomic, copy, readonly) id<MASConstraint> with; 43 @property (nonatomic, copy, readonly) id<MASConstraint> with;
44 44
  45 +/**
  46 + Creates a NSLayoutConstraint. The constraint is added to the first view or the or the closest common superview of the first and second view.
  47 + */
45 - (void)commit; 48 - (void)commit;
46 49
47 @end 50 @end
48 51
49 @protocol MASConstraintDelegate <NSObject> 52 @protocol MASConstraintDelegate <NSObject>
50 53
  54 +/**
  55 + Notifies the delegate when the constraint is has the minimum set of properties, has a NSLayoutRelation and view
  56 + */
51 - (void)addConstraint:(id<MASConstraint>)constraint; 57 - (void)addConstraint:(id<MASConstraint>)constraint;
52 58
53 @end 59 @end
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 13
14 @interface MASConstraintMaker () <MASConstraintDelegate> 14 @interface MASConstraintMaker () <MASConstraintDelegate>
15 15
16 -@property (nonatomic, strong) UIView *view; 16 +@property (nonatomic, weak) UIView *view;
17 @property (nonatomic, strong) NSMutableArray *constraints; 17 @property (nonatomic, strong) NSMutableArray *constraints;
18 18
19 @end 19 @end
@@ -10,11 +10,16 @@ @@ -10,11 +10,16 @@
10 10
11 @interface MASViewAttribute : NSObject 11 @interface MASViewAttribute : NSObject
12 12
13 -@property (nonatomic, strong, readonly) UIView *view; 13 +@property (nonatomic, weak, readonly) UIView *view;
14 @property (nonatomic, assign, readonly) NSLayoutAttribute layoutAttribute; 14 @property (nonatomic, assign, readonly) NSLayoutAttribute layoutAttribute;
15 15
16 - (id)initWithView:(UIView *)view layoutAttribute:(NSLayoutAttribute)layoutAttribute; 16 - (id)initWithView:(UIView *)view layoutAttribute:(NSLayoutAttribute)layoutAttribute;
17 17
18 -- (BOOL)isAlignment; 18 +/**
  19 + Creates a MASConstraintMaker with the callee view. any constraints defined are added to the view or the appropriate superview once the block has finished executing
  20 +
  21 + @return YES if layoutAttribute is equal to NSLayoutAttributeWidth or NSLayoutAttributeHeight
  22 + */
  23 +- (BOOL)isSizeAttribute;
19 24
20 @end 25 @end
@@ -20,8 +20,8 @@ @@ -20,8 +20,8 @@
20 return self; 20 return self;
21 } 21 }
22 22
23 -- (BOOL)isAlignment {  
24 - return self.layoutAttribute != NSLayoutAttributeWidth && self.layoutAttribute != NSLayoutAttributeHeight; 23 +- (BOOL)isSizeAttribute {
  24 + return self.layoutAttribute == NSLayoutAttributeWidth || self.layoutAttribute == NSLayoutAttributeHeight;
25 } 25 }
26 26
27 @end 27 @end
@@ -61,7 +61,6 @@ @@ -61,7 +61,6 @@
61 } else { 61 } else {
62 NSAssert(YES, @"attempting to add unsupported attribute: %@", secondViewAttribute); 62 NSAssert(YES, @"attempting to add unsupported attribute: %@", secondViewAttribute);
63 } 63 }
64 - [self.delegate addConstraint:self];  
65 } 64 }
66 65
67 - (instancetype)cloneIfNeeded { 66 - (instancetype)cloneIfNeeded {
@@ -76,7 +75,7 @@ @@ -76,7 +75,7 @@
76 return self; 75 return self;
77 } 76 }
78 77
79 -#pragma mark - layout constant 78 +#pragma mark - NSLayoutConstraint constant proxies
80 79
81 - (id<MASConstraint> (^)(UIEdgeInsets))insets { 80 - (id<MASConstraint> (^)(UIEdgeInsets))insets {
82 return ^id(UIEdgeInsets insets){ 81 return ^id(UIEdgeInsets insets){
@@ -142,7 +141,7 @@ @@ -142,7 +141,7 @@
142 }; 141 };
143 } 142 }
144 143
145 -#pragma mark - layout multiplier 144 +#pragma mark - NSLayoutConstraint multiplier proxies
146 145
147 - (id<MASConstraint> (^)(CGFloat))percent { 146 - (id<MASConstraint> (^)(CGFloat))percent {
148 return ^id(CGFloat percent) { 147 return ^id(CGFloat percent) {
@@ -154,7 +153,7 @@ @@ -154,7 +153,7 @@
154 }; 153 };
155 } 154 }
156 155
157 -#pragma mark - layout priority 156 +#pragma mark - MASLayoutPriority proxies
158 157
159 - (id<MASConstraint> (^)(MASLayoutPriority))priority { 158 - (id<MASConstraint> (^)(MASLayoutPriority))priority {
160 return ^id(MASLayoutPriority priority) { 159 return ^id(MASLayoutPriority priority) {
@@ -187,7 +186,7 @@ @@ -187,7 +186,7 @@
187 }; 186 };
188 } 187 }
189 188
190 -#pragma mark - layout relation 189 +#pragma mark - NSLayoutRelation proxies
191 190
192 - (id<MASConstraint> (^)(id))equalTo { 191 - (id<MASConstraint> (^)(id))equalTo {
193 return ^id(id attr) { 192 return ^id(id attr) {
@@ -197,6 +196,7 @@ @@ -197,6 +196,7 @@
197 MASViewConstraint *viewConstraint = [self cloneIfNeeded]; 196 MASViewConstraint *viewConstraint = [self cloneIfNeeded];
198 viewConstraint.layoutRelation = NSLayoutRelationEqual; 197 viewConstraint.layoutRelation = NSLayoutRelationEqual;
199 viewConstraint.secondViewAttribute = attr; 198 viewConstraint.secondViewAttribute = attr;
  199 + [viewConstraint.delegate addConstraint:viewConstraint];
200 return viewConstraint; 200 return viewConstraint;
201 }; 201 };
202 } 202 }
@@ -209,6 +209,7 @@ @@ -209,6 +209,7 @@
209 MASViewConstraint *viewConstraint = [self cloneIfNeeded]; 209 MASViewConstraint *viewConstraint = [self cloneIfNeeded];
210 viewConstraint.layoutRelation = NSLayoutRelationGreaterThanOrEqual; 210 viewConstraint.layoutRelation = NSLayoutRelationGreaterThanOrEqual;
211 viewConstraint.secondViewAttribute = attr; 211 viewConstraint.secondViewAttribute = attr;
  212 + [viewConstraint.delegate addConstraint:viewConstraint];
212 return viewConstraint; 213 return viewConstraint;
213 }; 214 };
214 } 215 }
@@ -221,6 +222,7 @@ @@ -221,6 +222,7 @@
221 MASViewConstraint *viewConstraint = [self cloneIfNeeded]; 222 MASViewConstraint *viewConstraint = [self cloneIfNeeded];
222 viewConstraint.layoutRelation = NSLayoutRelationLessThanOrEqual; 223 viewConstraint.layoutRelation = NSLayoutRelationLessThanOrEqual;
223 viewConstraint.secondViewAttribute = attr; 224 viewConstraint.secondViewAttribute = attr;
  225 + [viewConstraint.delegate addConstraint:viewConstraint];
224 return viewConstraint; 226 return viewConstraint;
225 }; 227 };
226 } 228 }
@@ -240,7 +242,7 @@ @@ -240,7 +242,7 @@
240 NSLayoutAttribute firstLayoutAttribute = self.firstViewAttribute.layoutAttribute; 242 NSLayoutAttribute firstLayoutAttribute = self.firstViewAttribute.layoutAttribute;
241 UIView *secondLayoutItem = self.secondViewAttribute.view; 243 UIView *secondLayoutItem = self.secondViewAttribute.view;
242 NSLayoutAttribute secondLayoutAttribute = self.secondViewAttribute.layoutAttribute; 244 NSLayoutAttribute secondLayoutAttribute = self.secondViewAttribute.layoutAttribute;
243 - if (self.firstViewAttribute.isAlignment && !self.secondViewAttribute) { 245 + if (!self.firstViewAttribute.isSizeAttribute && !self.secondViewAttribute) {
244 secondLayoutItem = firstLayoutItem.superview; 246 secondLayoutItem = firstLayoutItem.superview;
245 secondLayoutAttribute = firstLayoutAttribute; 247 secondLayoutAttribute = firstLayoutAttribute;
246 } 248 }
@@ -12,6 +12,7 @@ @@ -12,6 +12,7 @@
12 12
13 @interface UIView (MASAdditions) 13 @interface UIView (MASAdditions)
14 14
  15 +// following properties return a new MASViewAttribute with current view and appropriate NSLayoutAttribute
15 @property (nonatomic, strong, readonly) MASViewAttribute *mas_left; 16 @property (nonatomic, strong, readonly) MASViewAttribute *mas_left;
16 @property (nonatomic, strong, readonly) MASViewAttribute *mas_top; 17 @property (nonatomic, strong, readonly) MASViewAttribute *mas_top;
17 @property (nonatomic, strong, readonly) MASViewAttribute *mas_right; 18 @property (nonatomic, strong, readonly) MASViewAttribute *mas_right;
@@ -24,6 +25,11 @@ @@ -24,6 +25,11 @@
24 @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerY; 25 @property (nonatomic, strong, readonly) MASViewAttribute *mas_centerY;
25 @property (nonatomic, strong, readonly) MASViewAttribute *mas_baseline; 26 @property (nonatomic, strong, readonly) MASViewAttribute *mas_baseline;
26 27
  28 +/**
  29 + Creates a MASConstraintMaker with the callee view. any constraints defined are added to the view or the appropriate superview once the block has finished executing
  30 +
  31 + @param block scope within which you can build up the constraints which you wish to apply to the view.
  32 + */
27 - (void)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block; 33 - (void)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block;
28 34
29 @end 35 @end
@@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
17 [constraintMaker commit]; 17 [constraintMaker commit];
18 } 18 }
19 19
20 -#pragma mark - attribute properties 20 +#pragma mark - NSLayoutAttribute properties
21 21
22 - (MASViewAttribute *)mas_left { 22 - (MASViewAttribute *)mas_left {
23 return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeft]; 23 return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeft];
@@ -8,7 +8,6 @@ @@ -8,7 +8,6 @@
8 8
9 #import "MASCompositeConstraint.h" 9 #import "MASCompositeConstraint.h"
10 #import "MASViewConstraint.h" 10 #import "MASViewConstraint.h"
11 -#import "SpecHelpers.h"  
12 11
13 @interface MASCompositeConstraint () <MASConstraintDelegate> 12 @interface MASCompositeConstraint () <MASConstraintDelegate>
14 13
@@ -26,8 +25,22 @@ @@ -26,8 +25,22 @@
26 25
27 SpecBegin(MASCompositeConstraint) 26 SpecBegin(MASCompositeConstraint)
28 27
  28 +__block id<MASConstraintDelegate> delegate;
  29 +__block UIView *superview;
  30 +__block UIView *view;
  31 +__block MASCompositeConstraint *composite;
  32 +
  33 +beforeEach(^{
  34 + composite = nil;
  35 + delegate = mockProtocol(@protocol(MASConstraintDelegate));
  36 + view = UIView.new;
  37 + superview = UIView.new;
  38 + [superview addSubview:view];
  39 +});
  40 +
29 it(@"should create centerY and centerX children", ^{ 41 it(@"should create centerY and centerX children", ^{
30 - MASCompositeConstraint *composite = createCompositeWithType(MASCompositeViewConstraintTypeCenter); 42 + composite = [[MASCompositeConstraint alloc] initWithView:view type:MASCompositeViewConstraintTypeCenter];
  43 +
31 expect(composite.currentChildConstraints).to.haveCountOf(2); 44 expect(composite.currentChildConstraints).to.haveCountOf(2);
32 45
33 MASViewConstraint *viewConstraint = composite.currentChildConstraints[0]; 46 MASViewConstraint *viewConstraint = composite.currentChildConstraints[0];
@@ -41,7 +54,7 @@ it(@"should create centerY and centerX children", ^{ @@ -41,7 +54,7 @@ it(@"should create centerY and centerX children", ^{
41 54
42 it(@"should create top, left, bottom, right children", ^{ 55 it(@"should create top, left, bottom, right children", ^{
43 UIView *newView = UIView.new; 56 UIView *newView = UIView.new;
44 - MASCompositeConstraint *composite = createCompositeWithType(MASCompositeViewConstraintTypeEdges); 57 + composite = [[MASCompositeConstraint alloc] initWithView:view type:MASCompositeViewConstraintTypeEdges];
45 composite.equalTo(newView); 58 composite.equalTo(newView);
46 59
47 expect(composite.completedChildConstraints).to.haveCountOf(4); 60 expect(composite.completedChildConstraints).to.haveCountOf(4);
@@ -68,7 +81,7 @@ it(@"should create top, left, bottom, right children", ^{ @@ -68,7 +81,7 @@ it(@"should create top, left, bottom, right children", ^{
68 }); 81 });
69 82
70 it(@"should create width and height children", ^{ 83 it(@"should create width and height children", ^{
71 - MASCompositeConstraint *composite = createCompositeWithType(MASCompositeViewConstraintTypeSize); 84 + composite = [[MASCompositeConstraint alloc] initWithView:view type:MASCompositeViewConstraintTypeSize];
72 expect(composite.currentChildConstraints).to.haveCountOf(2); 85 expect(composite.currentChildConstraints).to.haveCountOf(2);
73 86
74 MASViewConstraint *viewConstraint = composite.currentChildConstraints[0]; 87 MASViewConstraint *viewConstraint = composite.currentChildConstraints[0];
@@ -81,24 +94,25 @@ it(@"should create width and height children", ^{ @@ -81,24 +94,25 @@ it(@"should create width and height children", ^{
81 }); 94 });
82 95
83 it(@"should complete children", ^{ 96 it(@"should complete children", ^{
84 - UIView *view = UIView.new;  
85 - MASCompositeConstraint *composite = createCompositeWithType(MASCompositeViewConstraintTypeSize); 97 + composite = [[MASCompositeConstraint alloc] initWithView:view type:MASCompositeViewConstraintTypeSize];
  98 + composite.delegate = delegate;
  99 + UIView *newView = UIView.new;
86 100
87 //first equality statement 101 //first equality statement
88 - composite.equalTo(view).sizeOffset(CGSizeMake(90, 30)); 102 + composite.equalTo(newView).sizeOffset(CGSizeMake(90, 30));
89 103
90 - [verify(composite.delegate) addConstraint:(id)composite]; 104 + [verify(delegate) addConstraint:(id)composite];
91 105
92 expect(composite.completedChildConstraints).to.haveCountOf(2); 106 expect(composite.completedChildConstraints).to.haveCountOf(2);
93 expect(composite.currentChildConstraints).to.haveCountOf(2); 107 expect(composite.currentChildConstraints).to.haveCountOf(2);
94 108
95 MASViewConstraint *viewConstraint = composite.completedChildConstraints[0]; 109 MASViewConstraint *viewConstraint = composite.completedChildConstraints[0];
96 - expect(viewConstraint.secondViewAttribute.view).to.beIdenticalTo(view); 110 + expect(viewConstraint.secondViewAttribute.view).to.beIdenticalTo(newView);
97 expect(viewConstraint.secondViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeWidth); 111 expect(viewConstraint.secondViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeWidth);
98 expect(viewConstraint.layoutConstant).to.equal(90); 112 expect(viewConstraint.layoutConstant).to.equal(90);
99 113
100 viewConstraint = composite.completedChildConstraints[1]; 114 viewConstraint = composite.completedChildConstraints[1];
101 - expect(viewConstraint.secondViewAttribute.view).to.beIdenticalTo(view); 115 + expect(viewConstraint.secondViewAttribute.view).to.beIdenticalTo(newView);
102 expect(viewConstraint.secondViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeHeight); 116 expect(viewConstraint.secondViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeHeight);
103 expect(viewConstraint.layoutConstant).to.equal(30); 117 expect(viewConstraint.layoutConstant).to.equal(30);
104 118
@@ -127,4 +141,24 @@ it(@"should complete children", ^{ @@ -127,4 +141,24 @@ it(@"should complete children", ^{
127 expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeHeight); 141 expect(viewConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeHeight);
128 }); 142 });
129 143
  144 +it(@"should remove all on commit", ^{
  145 + composite = [[MASCompositeConstraint alloc] initWithView:view type:MASCompositeViewConstraintTypeSize];
  146 + composite.delegate = delegate;
  147 + UIView *newView = UIView.new;
  148 + [superview addSubview:newView];
  149 +
  150 + //first equality statement
  151 + composite.equalTo(newView).sizeOffset(CGSizeMake(90, 30));
  152 +
  153 + [verify(delegate) addConstraint:(id)composite];
  154 +
  155 + expect(composite.completedChildConstraints).to.haveCountOf(2);
  156 + expect(composite.currentChildConstraints).to.haveCountOf(2);
  157 +
  158 + [composite commit];
  159 +
  160 + expect(composite.completedChildConstraints).to.haveCountOf(0);
  161 + expect(composite.currentChildConstraints).to.haveCountOf(0);
  162 +});
  163 +
130 SpecEnd 164 SpecEnd
@@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
8 8
9 #import "MASViewConstraint.h" 9 #import "MASViewConstraint.h"
10 #import "MASConstraint.h" 10 #import "MASConstraint.h"
11 -#import "SpecHelpers.h" 11 +#import "UIView+MASAdditions.h"
12 12
13 @interface MASViewConstraint () 13 @interface MASViewConstraint ()
14 14
@@ -23,22 +23,30 @@ @@ -23,22 +23,30 @@
23 23
24 SpecBegin(MASViewConstraint) 24 SpecBegin(MASViewConstraint)
25 25
  26 +__block id<MASConstraintDelegate> delegate;
26 __block UIView *superview; 27 __block UIView *superview;
27 __block MASViewConstraint *constraint; 28 __block MASViewConstraint *constraint;
28 -__block MASViewAttribute *secondViewAttribute; 29 +__block UIView *otherView;
  30 +
29 31
30 beforeEach(^{ 32 beforeEach(^{
31 superview = UIView.new; 33 superview = UIView.new;
32 - constraint = createConstraintWithLayoutAttribute(NSLayoutAttributeWidth);  
33 - [superview addSubview:constraint.firstViewAttribute.view]; 34 + delegate = mockProtocol(@protocol(MASConstraintDelegate));
  35 +
  36 + UIView *view = UIView.new;
  37 + constraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:view.mas_width];
  38 + constraint.delegate = delegate;
  39 +
  40 + [superview addSubview:view];
34 41
35 - secondViewAttribute = createViewAttribute(NSLayoutAttributeHeight);  
36 - [superview addSubview:secondViewAttribute.view]; 42 + otherView = UIView.new;
  43 + [superview addSubview:otherView];
37 }); 44 });
38 45
39 describe(@"equality chaining", ^{ 46 describe(@"equality chaining", ^{
40 47
41 it(@"should return same constraint when encountering equal for first time", ^{ 48 it(@"should return same constraint when encountering equal for first time", ^{
  49 + MASViewAttribute *secondViewAttribute = otherView.mas_top;
42 MASViewConstraint *newConstraint = constraint.equalTo(secondViewAttribute); 50 MASViewConstraint *newConstraint = constraint.equalTo(secondViewAttribute);
43 51
44 [verify(constraint.delegate) addConstraint:(id)constraint]; 52 [verify(constraint.delegate) addConstraint:(id)constraint];
@@ -48,6 +56,7 @@ describe(@"equality chaining", ^{ @@ -48,6 +56,7 @@ describe(@"equality chaining", ^{
48 }); 56 });
49 57
50 it(@"should start new constraint when encountering equal subsequently", ^{ 58 it(@"should start new constraint when encountering equal subsequently", ^{
  59 + MASViewAttribute *secondViewAttribute = otherView.mas_top;
51 constraint.greaterThanOrEqualTo(secondViewAttribute); 60 constraint.greaterThanOrEqualTo(secondViewAttribute);
52 MASViewConstraint *newConstraint = constraint.equalTo(secondViewAttribute); 61 MASViewConstraint *newConstraint = constraint.equalTo(secondViewAttribute);
53 62
@@ -57,6 +66,7 @@ describe(@"equality chaining", ^{ @@ -57,6 +66,7 @@ describe(@"equality chaining", ^{
57 }); 66 });
58 67
59 it(@"should return same constraint when encountering greaterThanOrEqual for first time", ^{ 68 it(@"should return same constraint when encountering greaterThanOrEqual for first time", ^{
  69 + MASViewAttribute *secondViewAttribute = otherView.mas_top;
60 MASViewConstraint *newConstraint = constraint.greaterThanOrEqualTo(secondViewAttribute); 70 MASViewConstraint *newConstraint = constraint.greaterThanOrEqualTo(secondViewAttribute);
61 71
62 [verify(constraint.delegate) addConstraint:(id)constraint]; 72 [verify(constraint.delegate) addConstraint:(id)constraint];
@@ -66,6 +76,7 @@ describe(@"equality chaining", ^{ @@ -66,6 +76,7 @@ describe(@"equality chaining", ^{
66 }); 76 });
67 77
68 it(@"should start new constraint when encountering greaterThanOrEqual subsequently", ^{ 78 it(@"should start new constraint when encountering greaterThanOrEqual subsequently", ^{
  79 + MASViewAttribute *secondViewAttribute = otherView.mas_top;
69 constraint.lessThanOrEqualTo(secondViewAttribute); 80 constraint.lessThanOrEqualTo(secondViewAttribute);
70 MASViewConstraint *newConstraint = constraint.greaterThanOrEqualTo(secondViewAttribute); 81 MASViewConstraint *newConstraint = constraint.greaterThanOrEqualTo(secondViewAttribute);
71 82
@@ -75,6 +86,7 @@ describe(@"equality chaining", ^{ @@ -75,6 +86,7 @@ describe(@"equality chaining", ^{
75 }); 86 });
76 87
77 it(@"should return same constraint when encountering lessThanOrEqual for first time", ^{ 88 it(@"should return same constraint when encountering lessThanOrEqual for first time", ^{
  89 + MASViewAttribute *secondViewAttribute = otherView.mas_top;
78 MASViewConstraint *newConstraint = constraint.lessThanOrEqualTo(secondViewAttribute); 90 MASViewConstraint *newConstraint = constraint.lessThanOrEqualTo(secondViewAttribute);
79 91
80 [verify(constraint.delegate) addConstraint:(id)constraint]; 92 [verify(constraint.delegate) addConstraint:(id)constraint];
@@ -84,6 +96,7 @@ describe(@"equality chaining", ^{ @@ -84,6 +96,7 @@ describe(@"equality chaining", ^{
84 }); 96 });
85 97
86 it(@"should start new constraint when encountering lessThanOrEqual subsequently", ^{ 98 it(@"should start new constraint when encountering lessThanOrEqual subsequently", ^{
  99 + MASViewAttribute *secondViewAttribute = otherView.mas_top;
87 constraint.equalTo(secondViewAttribute); 100 constraint.equalTo(secondViewAttribute);
88 MASViewConstraint *newConstraint = constraint.lessThanOrEqualTo(secondViewAttribute); 101 MASViewConstraint *newConstraint = constraint.lessThanOrEqualTo(secondViewAttribute);
89 102
@@ -93,6 +106,7 @@ describe(@"equality chaining", ^{ @@ -93,6 +106,7 @@ describe(@"equality chaining", ^{
93 }); 106 });
94 107
95 it(@"should not allow update of equal once layoutconstraint is created", ^{ 108 it(@"should not allow update of equal once layoutconstraint is created", ^{
  109 + MASViewAttribute *secondViewAttribute = otherView.mas_top;
96 [constraint commit]; 110 [constraint commit];
97 111
98 expect(^{ 112 expect(^{
@@ -101,6 +115,7 @@ describe(@"equality chaining", ^{ @@ -101,6 +115,7 @@ describe(@"equality chaining", ^{
101 }); 115 });
102 116
103 it(@"should not allow update of lessThanOrEqual once layoutconstraint is created", ^{ 117 it(@"should not allow update of lessThanOrEqual once layoutconstraint is created", ^{
  118 + MASViewAttribute *secondViewAttribute = otherView.mas_top;
104 [constraint commit]; 119 [constraint commit];
105 120
106 expect(^{ 121 expect(^{
@@ -109,6 +124,7 @@ describe(@"equality chaining", ^{ @@ -109,6 +124,7 @@ describe(@"equality chaining", ^{
109 }); 124 });
110 125
111 it(@"should not allow update of greaterThanOrEqual once layoutconstraint is created", ^{ 126 it(@"should not allow update of greaterThanOrEqual once layoutconstraint is created", ^{
  127 + MASViewAttribute *secondViewAttribute = otherView.mas_top;
112 [constraint commit]; 128 [constraint commit];
113 129
114 expect(^{ 130 expect(^{
@@ -148,51 +164,51 @@ describe(@"multiplier & constant", ^{ @@ -148,51 +164,51 @@ describe(@"multiplier & constant", ^{
148 }); 164 });
149 165
150 it(@"should update sides offset only", ^{ 166 it(@"should update sides offset only", ^{
151 - MASViewConstraint *centerY = createConstraintWithLayoutAttribute(NSLayoutAttributeCenterY); 167 + MASViewConstraint *centerY = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerY];
152 centerY.insets(UIEdgeInsetsMake(10, 10, 10, 10)); 168 centerY.insets(UIEdgeInsetsMake(10, 10, 10, 10));
153 expect(centerY.layoutConstant).to.equal(0); 169 expect(centerY.layoutConstant).to.equal(0);
154 170
155 - MASViewConstraint *top = createConstraintWithLayoutAttribute(NSLayoutAttributeTop); 171 + MASViewConstraint *top = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_top];
156 top.insets(UIEdgeInsetsMake(15, 10, 10, 10)); 172 top.insets(UIEdgeInsetsMake(15, 10, 10, 10));
157 expect(top.layoutConstant).to.equal(15); 173 expect(top.layoutConstant).to.equal(15);
158 174
159 - MASViewConstraint *left = createConstraintWithLayoutAttribute(NSLayoutAttributeLeft); 175 + MASViewConstraint *left = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_left];
160 left.insets(UIEdgeInsetsMake(10, 15, 10, 10)); 176 left.insets(UIEdgeInsetsMake(10, 15, 10, 10));
161 expect(left.layoutConstant).to.equal(15); 177 expect(left.layoutConstant).to.equal(15);
162 178
163 - MASViewConstraint *bottom = createConstraintWithLayoutAttribute(NSLayoutAttributeBottom); 179 + MASViewConstraint *bottom = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_bottom];
164 bottom.insets(UIEdgeInsetsMake(10, 10, 15, 10)); 180 bottom.insets(UIEdgeInsetsMake(10, 10, 15, 10));
165 expect(bottom.layoutConstant).to.equal(-15); 181 expect(bottom.layoutConstant).to.equal(-15);
166 182
167 - MASViewConstraint *right = createConstraintWithLayoutAttribute(NSLayoutAttributeRight); 183 + MASViewConstraint *right = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_right];
168 right.insets(UIEdgeInsetsMake(10, 10, 10, 15)); 184 right.insets(UIEdgeInsetsMake(10, 10, 10, 15));
169 expect(right.layoutConstant).to.equal(-15); 185 expect(right.layoutConstant).to.equal(-15);
170 }); 186 });
171 187
172 it(@"should update center offset only", ^{ 188 it(@"should update center offset only", ^{
173 - MASViewConstraint *width = createConstraintWithLayoutAttribute(NSLayoutAttributeWidth); 189 + MASViewConstraint *width = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_width];
174 width.centerOffset(CGPointMake(-20, -10)); 190 width.centerOffset(CGPointMake(-20, -10));
175 expect(width.layoutConstant).to.equal(0); 191 expect(width.layoutConstant).to.equal(0);
176 192
177 - MASViewConstraint *centerX = createConstraintWithLayoutAttribute(NSLayoutAttributeCenterX); 193 + MASViewConstraint *centerX = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerX];
178 centerX.centerOffset(CGPointMake(-20, -10)); 194 centerX.centerOffset(CGPointMake(-20, -10));
179 expect(centerX.layoutConstant).to.equal(-20); 195 expect(centerX.layoutConstant).to.equal(-20);
180 196
181 - MASViewConstraint *centerY = createConstraintWithLayoutAttribute(NSLayoutAttributeCenterY); 197 + MASViewConstraint *centerY = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerY];
182 centerY.centerOffset(CGPointMake(-20, -10)); 198 centerY.centerOffset(CGPointMake(-20, -10));
183 expect(centerY.layoutConstant).to.equal(-10); 199 expect(centerY.layoutConstant).to.equal(-10);
184 }); 200 });
185 201
186 it(@"should update size offset only", ^{ 202 it(@"should update size offset only", ^{
187 - MASViewConstraint *bottom = createConstraintWithLayoutAttribute(NSLayoutAttributeBottom); 203 + MASViewConstraint *bottom = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_bottom];
188 bottom.sizeOffset(CGSizeMake(-40, 55)); 204 bottom.sizeOffset(CGSizeMake(-40, 55));
189 expect(bottom.layoutConstant).to.equal(0); 205 expect(bottom.layoutConstant).to.equal(0);
190 206
191 - MASViewConstraint *width = createConstraintWithLayoutAttribute(NSLayoutAttributeWidth); 207 + MASViewConstraint *width = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_width];
192 width.sizeOffset(CGSizeMake(-40, 55)); 208 width.sizeOffset(CGSizeMake(-40, 55));
193 expect(width.layoutConstant).to.equal(-40); 209 expect(width.layoutConstant).to.equal(-40);
194 210
195 - MASViewConstraint *height = createConstraintWithLayoutAttribute(NSLayoutAttributeHeight); 211 + MASViewConstraint *height = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_height];
196 height.sizeOffset(CGSizeMake(-40, 55)); 212 height.sizeOffset(CGSizeMake(-40, 55));
197 expect(height.layoutConstant).to.equal(55); 213 expect(height.layoutConstant).to.equal(55);
198 }); 214 });
@@ -200,7 +216,8 @@ describe(@"multiplier & constant", ^{ @@ -200,7 +216,8 @@ describe(@"multiplier & constant", ^{
200 216
201 describe(@"commit", ^{ 217 describe(@"commit", ^{
202 218
203 - it(@"should create layout constraint", ^{ 219 + it(@"should create layout constraint on commit", ^{
  220 + MASViewAttribute *secondViewAttribute = otherView.mas_height;
204 constraint.equalTo(secondViewAttribute); 221 constraint.equalTo(secondViewAttribute);
205 constraint.percent(0.5); 222 constraint.percent(0.5);
206 constraint.offset(10); 223 constraint.offset(10);
1 -//  
2 -// SpecHelpers.h  
3 -// Masonry  
4 -//  
5 -// Created by Jonas Budelmann on 23/07/13.  
6 -// Copyright (c) 2013 Jonas Budelmann. All rights reserved.  
7 -//  
8 -  
9 -#import "MASCompositeConstraint.h"  
10 -#import "MASViewAttribute.h"  
11 -#import "MASViewConstraint.h"  
12 -  
13 -static id (^createViewAttribute)(NSLayoutAttribute layoutAttribute) = ^id(NSLayoutAttribute layoutAttribute) {  
14 - UIView *view = UIView.new;  
15 - MASViewAttribute *viewAttribute = [[MASViewAttribute alloc] initWithView:view layoutAttribute:layoutAttribute];  
16 - return viewAttribute;  
17 -};  
18 -  
19 -static id (^createConstraintWithLayoutAttribute)(NSLayoutAttribute layoutAttribute) = ^id(NSLayoutAttribute layoutAttribute) {  
20 - id delegate = mockProtocol(@protocol(MASConstraintDelegate));  
21 - MASViewConstraint *constraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:createViewAttribute(layoutAttribute)];  
22 - constraint.delegate = delegate;  
23 - return constraint;  
24 -};  
25 -  
26 -static id(^createCompositeWithType)(MASCompositeViewConstraintType type) = ^id(MASCompositeViewConstraintType type){  
27 - id delegate = mockProtocol(@protocol(MASConstraintDelegate));  
28 - UIView *view = UIView.new;  
29 - MASCompositeConstraint *composite = [[MASCompositeConstraint alloc] initWithView:view type:type];  
30 - composite.delegate = delegate;  
31 - return composite;  
32 -};