Authored by Jonas Budelmann

added ability to remove constraint. refactored child constraints

@@ -76,8 +76,10 @@ @@ -76,8 +76,10 @@
76 76
77 #pragma mark - MASConstraintDelegate 77 #pragma mark - MASConstraintDelegate
78 78
79 -- (void)addConstraint:(id<MASConstraint>)constraint {  
80 - [self.delegate addConstraint:constraint]; 79 +- (void)constraint:(id<MASConstraint>)constraint shouldBeReplacedWithConstraint:(id<MASConstraint>)replacementConstraint {
  80 + int index = [self.childConstraints indexOfObject:constraint];
  81 + NSAssert(index != NSNotFound, @"Could not find constraint %@", constraint);
  82 + [self.childConstraints replaceObjectAtIndex:index withObject:replacementConstraint];
81 } 83 }
82 84
83 #pragma mark - NSLayoutConstraint constant proxies 85 #pragma mark - NSLayoutConstraint constant proxies
@@ -165,7 +167,7 @@ @@ -165,7 +167,7 @@
165 167
166 - (id<MASConstraint> (^)(id))equalTo { 168 - (id<MASConstraint> (^)(id))equalTo {
167 return ^id(id attr) { 169 return ^id(id attr) {
168 - for (id<MASConstraint> constraint in self.childConstraints) { 170 + for (id<MASConstraint> constraint in self.childConstraints.copy) {
169 constraint.equalTo(attr); 171 constraint.equalTo(attr);
170 } 172 }
171 return self; 173 return self;
@@ -174,7 +176,7 @@ @@ -174,7 +176,7 @@
174 176
175 - (id<MASConstraint> (^)(id))greaterThanOrEqualTo { 177 - (id<MASConstraint> (^)(id))greaterThanOrEqualTo {
176 return ^id(id attr) { 178 return ^id(id attr) {
177 - for (id<MASConstraint> constraint in self.childConstraints) { 179 + for (id<MASConstraint> constraint in self.childConstraints.copy) {
178 constraint.greaterThanOrEqualTo(attr); 180 constraint.greaterThanOrEqualTo(attr);
179 } 181 }
180 return self; 182 return self;
@@ -183,7 +185,7 @@ @@ -183,7 +185,7 @@
183 185
184 - (id<MASConstraint> (^)(id))lessThanOrEqualTo { 186 - (id<MASConstraint> (^)(id))lessThanOrEqualTo {
185 return ^id(id attr) { 187 return ^id(id attr) {
186 - for (id<MASConstraint> constraint in self.childConstraints) { 188 + for (id<MASConstraint> constraint in self.childConstraints.copy) {
187 constraint.lessThanOrEqualTo(attr); 189 constraint.lessThanOrEqualTo(attr);
188 } 190 }
189 return self; 191 return self;
@@ -211,7 +213,16 @@ @@ -211,7 +213,16 @@
211 213
212 #pragma mark - MASConstraint 214 #pragma mark - MASConstraint
213 215
214 -- (void)commit { 216 +- (void)installConstraint {
  217 + for (id<MASConstraint> constraint in self.childConstraints) {
  218 + [constraint installConstraint];
  219 + }
  220 +}
  221 +
  222 +- (void)uninstallConstraint {
  223 + for (id<MASConstraint> constraint in self.childConstraints) {
  224 + [constraint uninstallConstraint];
  225 + }
215 } 226 }
216 227
217 @end 228 @end
@@ -111,19 +111,23 @@ typedef float MASLayoutPriority; @@ -111,19 +111,23 @@ typedef float MASLayoutPriority;
111 @property (nonatomic, copy, readonly) id<MASConstraint> (^key)(id key); 111 @property (nonatomic, copy, readonly) id<MASConstraint> (^key)(id key);
112 112
113 /** 113 /**
114 - * Creates a NSLayoutConstraint. The constraint is added to the first view or the or the closest common superview of the first and second view. 114 + * Creates a NSLayoutConstraint. The constraint is installed to the first view or the or the closest common superview of the first and second view.
115 */ 115 */
116 -- (void)commit; 116 +- (void)installConstraint;
  117 +
  118 +/**
  119 + * Removes previously installed NSLayoutConstraint
  120 + */
  121 +- (void)uninstallConstraint;
117 122
118 @end 123 @end
119 124
120 @protocol MASConstraintDelegate <NSObject> 125 @protocol MASConstraintDelegate <NSObject>
121 126
122 /** 127 /**
123 - * Notifies the delegate when the constraint is has the minimum set of properties.  
124 - *  
125 - * @param constraint a constraint that has at least a NSLayoutRelation and view 128 + * Notifies the delegate when the constraint needs to be replaced with another constraint. For example
  129 + * A MASViewConstraint may turn into a MASCompositeConstraint when an array is passed to one of the equality blocks
126 */ 130 */
127 -- (void)addConstraint:(id<MASConstraint>)constraint; 131 +- (void)constraint:(id<MASConstraint>)constraint shouldBeReplacedWithConstraint:(id<MASConstraint>)replacementConstraint;
128 132
129 @end 133 @end
@@ -32,15 +32,17 @@ @@ -32,15 +32,17 @@
32 32
33 - (void)commit { 33 - (void)commit {
34 for (id<MASConstraint> constraint in self.constraints) { 34 for (id<MASConstraint> constraint in self.constraints) {
35 - [constraint commit]; 35 + [constraint installConstraint];
36 } 36 }
37 [self.constraints removeAllObjects]; 37 [self.constraints removeAllObjects];
38 } 38 }
39 39
40 #pragma mark - MASConstraintDelegate 40 #pragma mark - MASConstraintDelegate
41 41
42 -- (void)addConstraint:(id<MASConstraint>)constraint {  
43 - [self.constraints addObject:constraint]; 42 +- (void)constraint:(id<MASConstraint>)constraint shouldBeReplacedWithConstraint:(id<MASConstraint>)replacementConstraint {
  43 + int index = [self.constraints indexOfObject:constraint];
  44 + NSAssert(index != NSNotFound, @"Could not find constraint %@", constraint);
  45 + [self.constraints replaceObjectAtIndex:index withObject:replacementConstraint];
44 } 46 }
45 47
46 #pragma mark - constraint properties 48 #pragma mark - constraint properties
@@ -49,6 +51,7 @@ @@ -49,6 +51,7 @@
49 MASViewAttribute *viewAttribute = [[MASViewAttribute alloc] initWithView:self.view layoutAttribute:layoutAttribute]; 51 MASViewAttribute *viewAttribute = [[MASViewAttribute alloc] initWithView:self.view layoutAttribute:layoutAttribute];
50 MASViewConstraint *constraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:viewAttribute]; 52 MASViewConstraint *constraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:viewAttribute];
51 constraint.delegate = self; 53 constraint.delegate = self;
  54 + [self.constraints addObject:constraint];
52 return constraint; 55 return constraint;
53 } 56 }
54 57
@@ -104,18 +107,21 @@ @@ -104,18 +107,21 @@
104 - (id<MASConstraint>)edges { 107 - (id<MASConstraint>)edges {
105 MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithView:self.view type:MASCompositeConstraintTypeEdges]; 108 MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithView:self.view type:MASCompositeConstraintTypeEdges];
106 constraint.delegate = self; 109 constraint.delegate = self;
  110 + [self.constraints addObject:constraint];
107 return constraint; 111 return constraint;
108 } 112 }
109 113
110 - (id<MASConstraint>)size { 114 - (id<MASConstraint>)size {
111 MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithView:self.view type:MASCompositeConstraintTypeSize]; 115 MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithView:self.view type:MASCompositeConstraintTypeSize];
112 constraint.delegate = self; 116 constraint.delegate = self;
  117 + [self.constraints addObject:constraint];
113 return constraint; 118 return constraint;
114 } 119 }
115 120
116 - (id<MASConstraint>)center { 121 - (id<MASConstraint>)center {
117 MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithView:self.view type:MASCompositeConstraintTypeCenter]; 122 MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithView:self.view type:MASCompositeConstraintTypeCenter];
118 constraint.delegate = self; 123 constraint.delegate = self;
  124 + [self.constraints addObject:constraint];
119 return constraint; 125 return constraint;
120 } 126 }
121 @end 127 @end
@@ -14,6 +14,7 @@ @@ -14,6 +14,7 @@
14 14
15 @property (nonatomic, strong, readwrite) MASViewAttribute *secondViewAttribute; 15 @property (nonatomic, strong, readwrite) MASViewAttribute *secondViewAttribute;
16 @property (nonatomic, strong, readwrite) MASLayoutConstraint *layoutConstraint; 16 @property (nonatomic, strong, readwrite) MASLayoutConstraint *layoutConstraint;
  17 +@property (nonatomic, weak) UIView *installedView;
17 @property (nonatomic, assign) NSLayoutRelation layoutRelation; 18 @property (nonatomic, assign) NSLayoutRelation layoutRelation;
18 @property (nonatomic, assign) MASLayoutPriority layoutPriority; 19 @property (nonatomic, assign) MASLayoutPriority layoutPriority;
19 @property (nonatomic, assign) CGFloat layoutMultiplier; 20 @property (nonatomic, assign) CGFloat layoutMultiplier;
@@ -60,7 +61,7 @@ @@ -60,7 +61,7 @@
60 self.hasLayoutRelation = YES; 61 self.hasLayoutRelation = YES;
61 } 62 }
62 63
63 -- (BOOL)hasBeenCommitted { 64 +- (BOOL)hasBeenInstalled {
64 return self.layoutConstraint != nil; 65 return self.layoutConstraint != nil;
65 } 66 }
66 67
@@ -146,8 +147,8 @@ @@ -146,8 +147,8 @@
146 147
147 - (id<MASConstraint> (^)(CGFloat))percent { 148 - (id<MASConstraint> (^)(CGFloat))percent {
148 return ^id(CGFloat percent) { 149 return ^id(CGFloat percent) {
149 - NSAssert(!self.hasBeenCommitted,  
150 - @"Cannot modify constraint percent after it has been committed"); 150 + NSAssert(!self.hasBeenInstalled,
  151 + @"Cannot modify constraint percent after it has been installed");
151 152
152 self.layoutMultiplier = percent; 153 self.layoutMultiplier = percent;
153 return self; 154 return self;
@@ -158,8 +159,8 @@ @@ -158,8 +159,8 @@
158 159
159 - (id<MASConstraint> (^)(MASLayoutPriority))priority { 160 - (id<MASConstraint> (^)(MASLayoutPriority))priority {
160 return ^id(MASLayoutPriority priority) { 161 return ^id(MASLayoutPriority priority) {
161 - NSAssert(!self.hasBeenCommitted,  
162 - @"Cannot modify constraint priority after it has been committed"); 162 + NSAssert(!self.hasBeenInstalled,
  163 + @"Cannot modify constraint priority after it has been installed");
163 164
164 self.layoutPriority = priority; 165 self.layoutPriority = priority;
165 return self; 166 return self;
@@ -197,16 +198,15 @@ @@ -197,16 +198,15 @@
197 for (id attr in attribute) { 198 for (id attr in attribute) {
198 MASViewConstraint *viewConstraint = [self copy]; 199 MASViewConstraint *viewConstraint = [self copy];
199 viewConstraint.secondViewAttribute = attr; 200 viewConstraint.secondViewAttribute = attr;
200 - [viewConstraint.delegate addConstraint:viewConstraint];  
201 [children addObject:viewConstraint]; 201 [children addObject:viewConstraint];
202 } 202 }
203 MASCompositeConstraint *compositeConstraint = [[MASCompositeConstraint alloc] initWithView:self.firstViewAttribute.view children:children]; 203 MASCompositeConstraint *compositeConstraint = [[MASCompositeConstraint alloc] initWithView:self.firstViewAttribute.view children:children];
204 compositeConstraint.delegate = self.delegate; 204 compositeConstraint.delegate = self.delegate;
  205 + [self.delegate constraint:self shouldBeReplacedWithConstraint:compositeConstraint];
205 return compositeConstraint; 206 return compositeConstraint;
206 } else { 207 } else {
207 self.layoutRelation = relation; 208 self.layoutRelation = relation;
208 self.secondViewAttribute = attribute; 209 self.secondViewAttribute = attribute;
209 - [self.delegate addConstraint:self];  
210 return self; 210 return self;
211 } 211 }
212 }; 212 };
@@ -241,8 +241,8 @@ @@ -241,8 +241,8 @@
241 241
242 #pragma mark - MASConstraint 242 #pragma mark - MASConstraint
243 243
244 -- (void)commit {  
245 - NSAssert(!self.hasBeenCommitted, @"Cannot commit constraint more than once"); 244 +- (void)installConstraint {
  245 + NSAssert(!self.hasBeenInstalled, @"Cannot install constraint more than once");
246 246
247 UIView *firstLayoutItem = self.firstViewAttribute.view; 247 UIView *firstLayoutItem = self.firstViewAttribute.view;
248 NSLayoutAttribute firstLayoutAttribute = self.firstViewAttribute.layoutAttribute; 248 NSLayoutAttribute firstLayoutAttribute = self.firstViewAttribute.layoutAttribute;
@@ -283,11 +283,18 @@ @@ -283,11 +283,18 @@
283 @"couldn't find a common superview for %@ and %@", 283 @"couldn't find a common superview for %@ and %@",
284 firstLayoutItem, 284 firstLayoutItem,
285 secondLayoutItem); 285 secondLayoutItem);
  286 + self.installedView = closestCommonSuperview;
286 [closestCommonSuperview addConstraint:self.layoutConstraint]; 287 [closestCommonSuperview addConstraint:self.layoutConstraint];
287 } else { 288 } else {
288 - 289 + self.installedView = firstLayoutItem;
289 [firstLayoutItem addConstraint:self.layoutConstraint]; 290 [firstLayoutItem addConstraint:self.layoutConstraint];
290 } 291 }
291 } 292 }
292 293
  294 +- (void)uninstallConstraint {
  295 + [self.installedView removeConstraint:self.layoutConstraint];
  296 + self.layoutConstraint = nil;
  297 + self.installedView = nil;
  298 +}
  299 +
293 @end 300 @end
@@ -116,7 +116,7 @@ it(@"should complete children", ^{ @@ -116,7 +116,7 @@ it(@"should complete children", ^{
116 expect(viewConstraint.layoutPriority).to.equal(MASLayoutPriorityDefaultLow); 116 expect(viewConstraint.layoutPriority).to.equal(MASLayoutPriorityDefaultLow);
117 }); 117 });
118 118
119 -it(@"should not remove on commit", ^{ 119 +it(@"should not remove on install", ^{
120 composite = [[MASCompositeConstraint alloc] initWithView:view type:MASCompositeConstraintTypeSize]; 120 composite = [[MASCompositeConstraint alloc] initWithView:view type:MASCompositeConstraintTypeSize];
121 composite.delegate = delegate; 121 composite.delegate = delegate;
122 UIView *newView = UIView.new; 122 UIView *newView = UIView.new;
@@ -125,11 +125,22 @@ it(@"should not remove on commit", ^{ @@ -125,11 +125,22 @@ it(@"should not remove on commit", ^{
125 //first equality statement 125 //first equality statement
126 composite.equalTo(newView).sizeOffset(CGSizeMake(90, 30)); 126 composite.equalTo(newView).sizeOffset(CGSizeMake(90, 30));
127 127
128 - [composite commit]; 128 + [composite installConstraint];
129 129
130 expect(composite.childConstraints).to.haveCountOf(2); 130 expect(composite.childConstraints).to.haveCountOf(2);
131 - expect(delegate.constraints).to.contain(composite.childConstraints[0]);  
132 - expect(delegate.constraints).to.contain(composite.childConstraints[1]); 131 +});
  132 +
  133 +it(@"should spawn child composite constraints", ^{
  134 + composite = [[MASCompositeConstraint alloc] initWithView:view type:MASCompositeConstraintTypeSize];
  135 + composite.delegate = delegate;
  136 +
  137 + UIView *otherView = UIView.new;
  138 + [superview addSubview:otherView];
  139 + composite.lessThanOrEqualTo(@[@2, otherView]);
  140 +
  141 + expect(composite.childConstraints).to.haveCountOf(2);
  142 + expect(composite.childConstraints[0]).to.beKindOf(MASCompositeConstraint.class);
  143 + expect(composite.childConstraints[1]).to.beKindOf(MASCompositeConstraint.class);
133 }); 144 });
134 145
135 SpecEnd 146 SpecEnd
@@ -19,8 +19,8 @@ @@ -19,8 +19,8 @@
19 return self; 19 return self;
20 } 20 }
21 21
22 -- (void)addConstraint:(id<MASConstraint>)constraint {  
23 - [self.constraints addObject:constraint]; 22 +- (void)constraint:(id<MASConstraint>)constraint shouldBeReplacedWithConstraint:(id<MASConstraint>)replacementConstraint {
  23 + [self.constraints replaceObjectAtIndex:[self.constraints indexOfObject:constraint] withObject:replacementConstraint];
24 } 24 }
25 25
26 @end 26 @end
@@ -10,6 +10,7 @@ @@ -10,6 +10,7 @@
10 #import "MASConstraint.h" 10 #import "MASConstraint.h"
11 #import "UIView+MASAdditions.h" 11 #import "UIView+MASAdditions.h"
12 #import "MASConstraintDelegateMock.h" 12 #import "MASConstraintDelegateMock.h"
  13 +#import "MASCompositeConstraint.h"
13 14
14 @interface MASViewConstraint () 15 @interface MASViewConstraint ()
15 16
@@ -21,6 +22,12 @@ @@ -21,6 +22,12 @@
21 22
22 @end 23 @end
23 24
  25 +@interface MASCompositeConstraint () <MASConstraintDelegate>
  26 +
  27 +@property (nonatomic, strong) NSMutableArray *childConstraints;
  28 +
  29 +@end
  30 +
24 SpecBegin(MASViewConstraint) 31 SpecBegin(MASViewConstraint)
25 32
26 __block MASConstraintDelegateMock *delegate; 33 __block MASConstraintDelegateMock *delegate;
@@ -49,7 +56,6 @@ describe(@"create equality constraint", ^{ @@ -49,7 +56,6 @@ describe(@"create equality constraint", ^{
49 MASViewAttribute *secondViewAttribute = otherView.mas_top; 56 MASViewAttribute *secondViewAttribute = otherView.mas_top;
50 MASViewConstraint *newConstraint = (id)constraint.equalTo(secondViewAttribute); 57 MASViewConstraint *newConstraint = (id)constraint.equalTo(secondViewAttribute);
51 58
52 - expect(delegate.constraints).to.contain(constraint);  
53 expect(newConstraint).to.beIdenticalTo(constraint); 59 expect(newConstraint).to.beIdenticalTo(constraint);
54 expect(constraint.secondViewAttribute).to.beIdenticalTo(secondViewAttribute); 60 expect(constraint.secondViewAttribute).to.beIdenticalTo(secondViewAttribute);
55 expect(constraint.layoutRelation).to.equal(NSLayoutRelationEqual); 61 expect(constraint.layoutRelation).to.equal(NSLayoutRelationEqual);
@@ -59,7 +65,6 @@ describe(@"create equality constraint", ^{ @@ -59,7 +65,6 @@ describe(@"create equality constraint", ^{
59 MASViewAttribute *secondViewAttribute = otherView.mas_top; 65 MASViewAttribute *secondViewAttribute = otherView.mas_top;
60 MASViewConstraint *newConstraint = (id)constraint.greaterThanOrEqualTo(secondViewAttribute); 66 MASViewConstraint *newConstraint = (id)constraint.greaterThanOrEqualTo(secondViewAttribute);
61 67
62 - expect(delegate.constraints).to.contain(constraint);  
63 expect(newConstraint).to.beIdenticalTo(constraint); 68 expect(newConstraint).to.beIdenticalTo(constraint);
64 expect(constraint.secondViewAttribute).to.beIdenticalTo(secondViewAttribute); 69 expect(constraint.secondViewAttribute).to.beIdenticalTo(secondViewAttribute);
65 expect(constraint.layoutRelation).to.equal(NSLayoutRelationGreaterThanOrEqual); 70 expect(constraint.layoutRelation).to.equal(NSLayoutRelationGreaterThanOrEqual);
@@ -69,7 +74,6 @@ describe(@"create equality constraint", ^{ @@ -69,7 +74,6 @@ describe(@"create equality constraint", ^{
69 MASViewAttribute *secondViewAttribute = otherView.mas_top; 74 MASViewAttribute *secondViewAttribute = otherView.mas_top;
70 MASViewConstraint *newConstraint = (id)constraint.lessThanOrEqualTo(secondViewAttribute); 75 MASViewConstraint *newConstraint = (id)constraint.lessThanOrEqualTo(secondViewAttribute);
71 76
72 - expect(delegate.constraints).to.contain(constraint);  
73 expect(newConstraint).to.beIdenticalTo(constraint); 77 expect(newConstraint).to.beIdenticalTo(constraint);
74 expect(constraint.secondViewAttribute).to.beIdenticalTo(secondViewAttribute); 78 expect(constraint.secondViewAttribute).to.beIdenticalTo(secondViewAttribute);
75 expect(constraint.layoutRelation).to.equal(NSLayoutRelationLessThanOrEqual); 79 expect(constraint.layoutRelation).to.equal(NSLayoutRelationLessThanOrEqual);
@@ -112,11 +116,14 @@ describe(@"create equality constraint", ^{ @@ -112,11 +116,14 @@ describe(@"create equality constraint", ^{
112 116
113 it(@"should create composite when passed array of views", ^{ 117 it(@"should create composite when passed array of views", ^{
114 NSArray *views = @[UIView.new, UIView.new, UIView.new]; 118 NSArray *views = @[UIView.new, UIView.new, UIView.new];
115 - constraint.equalTo(views).priorityMedium().offset(-10); 119 + [delegate.constraints addObject:constraint];
  120 +
  121 + MASCompositeConstraint *composite = (id)constraint.equalTo(views).priorityMedium().offset(-10);
116 122
117 - expect(delegate.constraints).to.haveCountOf(3);  
118 - for (MASViewConstraint *constraint in delegate.constraints) {  
119 - int index = [delegate.constraints indexOfObject:constraint]; 123 + expect(delegate.constraints).to.haveCountOf(1);
  124 + expect(delegate.constraints[0]).to.beKindOf(MASCompositeConstraint.class);
  125 + for (MASViewConstraint *constraint in composite.childConstraints) {
  126 + int index = [composite.childConstraints indexOfObject:constraint];
120 expect(constraint.secondViewAttribute.view).to.beIdenticalTo(views[index]); 127 expect(constraint.secondViewAttribute.view).to.beIdenticalTo(views[index]);
121 expect(constraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeWidth); 128 expect(constraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeWidth);
122 expect(constraint.secondViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeWidth); 129 expect(constraint.secondViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeWidth);
@@ -127,11 +134,14 @@ describe(@"create equality constraint", ^{ @@ -127,11 +134,14 @@ describe(@"create equality constraint", ^{
127 134
128 it(@"should create composite when passed array of attributes", ^{ 135 it(@"should create composite when passed array of attributes", ^{
129 NSArray *viewAttributes = @[UIView.new.mas_height, UIView.new.mas_left]; 136 NSArray *viewAttributes = @[UIView.new.mas_height, UIView.new.mas_left];
130 - constraint.equalTo(viewAttributes).priority(60).offset(10); 137 + [delegate.constraints addObject:constraint];
  138 +
  139 + MASCompositeConstraint *composite = (id)constraint.equalTo(viewAttributes).priority(60).offset(10);
131 140
132 - expect(delegate.constraints).to.haveCountOf(2);  
133 - for (MASViewConstraint *constraint in delegate.constraints) {  
134 - int index = [delegate.constraints indexOfObject:constraint]; 141 + expect(delegate.constraints).to.haveCountOf(1);
  142 + expect(delegate.constraints[0]).to.beKindOf(MASCompositeConstraint.class);
  143 + for (MASViewConstraint *constraint in composite.childConstraints) {
  144 + int index = [composite.childConstraints indexOfObject:constraint];
135 expect(constraint.secondViewAttribute.view).to.beIdenticalTo([viewAttributes[index] view]); 145 expect(constraint.secondViewAttribute.view).to.beIdenticalTo([viewAttributes[index] view]);
136 expect(constraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeWidth); 146 expect(constraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeWidth);
137 expect(constraint.secondViewAttribute.layoutAttribute).to.equal([viewAttributes[index] layoutAttribute]); 147 expect(constraint.secondViewAttribute.layoutAttribute).to.equal([viewAttributes[index] layoutAttribute]);
@@ -144,7 +154,7 @@ describe(@"create equality constraint", ^{ @@ -144,7 +154,7 @@ describe(@"create equality constraint", ^{
144 describe(@"multiplier & constant", ^{ 154 describe(@"multiplier & constant", ^{
145 155
146 it(@"should not allow update of multiplier after layoutconstraint is created", ^{ 156 it(@"should not allow update of multiplier after layoutconstraint is created", ^{
147 - [constraint commit]; 157 + [constraint installConstraint];
148 158
149 expect(^{ 159 expect(^{
150 constraint.percent(0.9); 160 constraint.percent(0.9);
@@ -152,7 +162,7 @@ describe(@"multiplier & constant", ^{ @@ -152,7 +162,7 @@ describe(@"multiplier & constant", ^{
152 }); 162 });
153 163
154 it(@"should allow update of constant after layoutconstraint is created", ^{ 164 it(@"should allow update of constant after layoutconstraint is created", ^{
155 - [constraint commit]; 165 + [constraint installConstraint];
156 constraint.offset(10); 166 constraint.offset(10);
157 167
158 expect(constraint.layoutConstant).to.equal(10); 168 expect(constraint.layoutConstant).to.equal(10);
@@ -210,7 +220,7 @@ describe(@"multiplier & constant", ^{ @@ -210,7 +220,7 @@ describe(@"multiplier & constant", ^{
210 }); 220 });
211 }); 221 });
212 222
213 -describe(@"commit", ^{ 223 +describe(@"install", ^{
214 224
215 it(@"should create layout constraint on commit", ^{ 225 it(@"should create layout constraint on commit", ^{
216 MASViewAttribute *secondViewAttribute = otherView.mas_height; 226 MASViewAttribute *secondViewAttribute = otherView.mas_height;
@@ -218,7 +228,7 @@ describe(@"commit", ^{ @@ -218,7 +228,7 @@ describe(@"commit", ^{
218 constraint.percent(0.5); 228 constraint.percent(0.5);
219 constraint.offset(10); 229 constraint.offset(10);
220 constraint.priority(345); 230 constraint.priority(345);
221 - [constraint commit]; 231 + [constraint installConstraint];
222 232
223 expect(constraint.layoutConstraint.firstAttribute).to.equal(NSLayoutAttributeWidth); 233 expect(constraint.layoutConstraint.firstAttribute).to.equal(NSLayoutAttributeWidth);
224 expect(constraint.layoutConstraint.secondAttribute).to.equal(NSLayoutAttributeHeight); 234 expect(constraint.layoutConstraint.secondAttribute).to.equal(NSLayoutAttributeHeight);
@@ -232,6 +242,18 @@ describe(@"commit", ^{ @@ -232,6 +242,18 @@ describe(@"commit", ^{
232 expect(superview.constraints[0]).to.beIdenticalTo(constraint.layoutConstraint); 242 expect(superview.constraints[0]).to.beIdenticalTo(constraint.layoutConstraint);
233 }); 243 });
234 244
  245 + it(@"should uninstall constraint", ^{
  246 + MASViewAttribute *secondViewAttribute = otherView.mas_height;
  247 + constraint.equalTo(secondViewAttribute);
  248 + [constraint installConstraint];
  249 +
  250 + expect(superview.constraints).to.haveCountOf(1);
  251 + expect(superview.constraints[0]).to.equal(constraint.layoutConstraint);
  252 +
  253 + [constraint uninstallConstraint];
  254 + expect(superview.constraints).to.haveCountOf(0);
  255 + });
  256 +
235 }); 257 });
236 258
237 SpecEnd 259 SpecEnd