MASViewConstraintSpec.m 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. //
  2. // MASViewConstraintSpec.m
  3. // Masonry
  4. //
  5. // Created by Jonas Budelmann on 21/07/13.
  6. // Copyright (c) 2013 cloudling. All rights reserved.
  7. //
  8. #import "MASViewConstraint.h"
  9. #import "MASConstraint+Private.h"
  10. #import "MASConstraint.h"
  11. #import "View+MASAdditions.h"
  12. #import "MASConstraintDelegateMock.h"
  13. #import "MASCompositeConstraint.h"
  14. @interface MASViewConstraint ()
  15. @property (nonatomic, weak) MASLayoutConstraint *layoutConstraint;
  16. @property (nonatomic, assign) NSLayoutRelation layoutRelation;
  17. @property (nonatomic, assign) MASLayoutPriority layoutPriority;
  18. @property (nonatomic, assign) CGFloat layoutMultiplier;
  19. @property (nonatomic, assign) CGFloat layoutConstant;
  20. @property (nonatomic, assign) BOOL hasLayoutRelation;
  21. @end
  22. @interface MASCompositeConstraint () <MASConstraintDelegate>
  23. @property (nonatomic, strong) NSMutableArray *childConstraints;
  24. @end
  25. SpecBegin(MASViewConstraint) {
  26. MASConstraintDelegateMock *delegate;
  27. MAS_VIEW *superview;
  28. MASViewConstraint *constraint;
  29. MAS_VIEW *otherView;
  30. }
  31. - (void)setUp {
  32. superview = MAS_VIEW.new;
  33. delegate = MASConstraintDelegateMock.new;
  34. MAS_VIEW *view = MAS_VIEW.new;
  35. constraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:view.mas_width];
  36. constraint.delegate = delegate;
  37. [superview addSubview:view];
  38. otherView = MAS_VIEW.new;
  39. [superview addSubview:otherView];
  40. }
  41. - (void)testRelationCreateEqualConstraint {
  42. MASViewAttribute *secondViewAttribute = otherView.mas_top;
  43. MASViewConstraint *newConstraint = (id)constraint.equalTo(secondViewAttribute);
  44. expect(newConstraint).to.beIdenticalTo(constraint);
  45. expect(constraint.secondViewAttribute).to.beIdenticalTo(secondViewAttribute);
  46. expect(constraint.layoutRelation).to.equal(NSLayoutRelationEqual);
  47. }
  48. - (void)testRelationCreateGreaterThanOrEqualConstraint {
  49. MASViewAttribute *secondViewAttribute = otherView.mas_top;
  50. MASViewConstraint *newConstraint = (id)constraint.greaterThanOrEqualTo(secondViewAttribute);
  51. expect(newConstraint).to.beIdenticalTo(constraint);
  52. expect(constraint.secondViewAttribute).to.beIdenticalTo(secondViewAttribute);
  53. expect(constraint.layoutRelation).to.equal(NSLayoutRelationGreaterThanOrEqual);
  54. }
  55. - (void)testRelationCreateLessThanOrEqualConstraint {
  56. MASViewAttribute *secondViewAttribute = otherView.mas_top;
  57. MASViewConstraint *newConstraint = (id)constraint.lessThanOrEqualTo(secondViewAttribute);
  58. expect(newConstraint).to.beIdenticalTo(constraint);
  59. expect(constraint.secondViewAttribute).to.beIdenticalTo(secondViewAttribute);
  60. expect(constraint.layoutRelation).to.equal(NSLayoutRelationLessThanOrEqual);
  61. }
  62. - (void)testRelationNotAllowUpdateOfEqual {
  63. MASViewAttribute *secondViewAttribute = otherView.mas_top;
  64. constraint.lessThanOrEqualTo(secondViewAttribute);
  65. expect(^{
  66. constraint.equalTo(secondViewAttribute);
  67. }).to.raise(@"NSInternalInconsistencyException");
  68. }
  69. - (void)testRelationNotAllowUpdateOfLessThanOrEqual{
  70. MASViewAttribute *secondViewAttribute = otherView.mas_top;
  71. constraint.equalTo(secondViewAttribute);
  72. expect(^{
  73. constraint.lessThanOrEqualTo(secondViewAttribute);
  74. }).to.raise(@"NSInternalInconsistencyException");
  75. }
  76. - (void)testRelationNotAllowUpdateOfGreaterThanOrEqual {
  77. MASViewAttribute *secondViewAttribute = otherView.mas_top;
  78. constraint.greaterThanOrEqualTo(secondViewAttribute);
  79. expect(^{
  80. constraint.greaterThanOrEqualTo(secondViewAttribute);
  81. }).to.raise(@"NSInternalInconsistencyException");
  82. }
  83. - (void)testRelationAcceptsView {
  84. MAS_VIEW *view = MAS_VIEW.new;
  85. constraint.equalTo(view);
  86. expect(constraint.secondViewAttribute.view).to.beIdenticalTo(view);
  87. expect(constraint.firstViewAttribute.layoutAttribute).to.equal(constraint.secondViewAttribute.layoutAttribute);
  88. }
  89. - (void)testRelationAcceptsNumber {
  90. constraint.equalTo(@42);
  91. expect(constraint.secondViewAttribute.view).to.beNil();
  92. expect(constraint.layoutConstant).to.equal(42);
  93. }
  94. - (void)testRelationAcceptsValueWithCGPoint {
  95. CGPoint point = CGPointMake(10, 20);
  96. NSValue *value = [NSValue value:&point withObjCType:@encode(CGPoint)];
  97. MASViewConstraint *centerX = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerX];
  98. centerX.equalTo(value);
  99. expect(centerX.layoutConstant).to.equal(10);
  100. MASViewConstraint *centerY = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerY];
  101. centerY.equalTo(value);
  102. expect(centerY.layoutConstant).to.equal(20);
  103. MASViewConstraint *width = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_width];
  104. width.equalTo(value);
  105. expect(width.layoutConstant).to.equal(0);
  106. }
  107. - (void)testRelationAcceptsValueWithCGSize {
  108. CGSize size = CGSizeMake(30, 40);
  109. NSValue *value = [NSValue value:&size withObjCType:@encode(CGSize)];
  110. MASViewConstraint *width = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_width];
  111. width.equalTo(value);
  112. expect(width.layoutConstant).to.equal(30);
  113. MASViewConstraint *height = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_height];
  114. height.equalTo(value);
  115. expect(height.layoutConstant).to.equal(40);
  116. MASViewConstraint *centerX = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerX];
  117. centerX.equalTo(value);
  118. expect(centerX.layoutConstant).to.equal(0);
  119. }
  120. - (void)testRelationAcceptsValueWithEdgeInsets {
  121. MASEdgeInsets insets = (MASEdgeInsets){10, 20, 30, 40};
  122. NSValue *value = [NSValue value:&insets withObjCType:@encode(MASEdgeInsets)];
  123. MASViewConstraint *top = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_top];
  124. top.equalTo(value);
  125. expect(top.layoutConstant).to.equal(10);
  126. MASViewConstraint *left = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_left];
  127. left.equalTo(value);
  128. expect(left.layoutConstant).to.equal(20);
  129. MASViewConstraint *leading = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_leading];
  130. leading.equalTo(value);
  131. expect(leading.layoutConstant).to.equal(20);
  132. MASViewConstraint *bottom = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_bottom];
  133. bottom.equalTo(value);
  134. expect(bottom.layoutConstant).to.equal(-30);
  135. MASViewConstraint *right = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_right];
  136. right.equalTo(value);
  137. expect(right.layoutConstant).to.equal(-40);
  138. MASViewConstraint *trailing = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_trailing];
  139. trailing.equalTo(value);
  140. expect(trailing.layoutConstant).to.equal(-40);
  141. MASViewConstraint *centerX = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerX];
  142. centerX.equalTo(value);
  143. expect(centerX.layoutConstant).to.equal(0);
  144. }
  145. - (void)testRelationCreatesCompositeWithArrayOfViews {
  146. NSArray *views = @[MAS_VIEW.new, MAS_VIEW.new, MAS_VIEW.new];
  147. [delegate.constraints addObject:constraint];
  148. MASCompositeConstraint *composite = (id)constraint.equalTo(views).priorityMedium().offset(-10);
  149. expect(delegate.constraints).to.haveCountOf(1);
  150. expect(delegate.constraints[0]).to.beKindOf(MASCompositeConstraint.class);
  151. for (MASViewConstraint *childConstraint in composite.childConstraints) {
  152. NSUInteger index = [composite.childConstraints indexOfObject:childConstraint];
  153. expect(childConstraint.secondViewAttribute.view).to.beIdenticalTo((MAS_VIEW *)views[index]);
  154. expect(childConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeWidth);
  155. expect(childConstraint.secondViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeWidth);
  156. expect(childConstraint.layoutPriority).to.equal(MASLayoutPriorityDefaultMedium);
  157. expect(childConstraint.layoutConstant).to.equal(-10);
  158. }
  159. }
  160. - (void)testRelationCreatesCompositeWithArrayOfAttributes {
  161. NSArray *viewAttributes = @[MAS_VIEW.new.mas_height, MAS_VIEW.new.mas_left];
  162. [delegate.constraints addObject:constraint];
  163. MASCompositeConstraint *composite = (id)constraint.equalTo(viewAttributes).priority(60).offset(10);
  164. expect(delegate.constraints).to.haveCountOf(1);
  165. expect(delegate.constraints[0]).to.beKindOf(MASCompositeConstraint.class);
  166. for (MASViewConstraint *childConstraint in composite.childConstraints) {
  167. NSUInteger index = [composite.childConstraints indexOfObject:childConstraint];
  168. expect(childConstraint.secondViewAttribute.view).to.beIdenticalTo([viewAttributes[index] view]);
  169. expect(childConstraint.firstViewAttribute.layoutAttribute).to.equal(NSLayoutAttributeWidth);
  170. expect(childConstraint.secondViewAttribute.layoutAttribute).to.equal([viewAttributes[index] layoutAttribute]);
  171. expect(childConstraint.layoutPriority).to.equal(60);
  172. expect(childConstraint.layoutConstant).to.equal(10);
  173. }
  174. }
  175. - (void)testRelationComplainsWithUnsupportedArgument {
  176. expect(^{
  177. constraint.equalTo(@{});
  178. }).to.raise(@"NSInternalInconsistencyException");
  179. }
  180. - (void)testRelationAcceptsAutoboxedScalar {
  181. constraint.mas_equalTo(42);
  182. expect(constraint.layoutConstant).to.equal(42);
  183. }
  184. - (void)testRelationAcceptsAutoboxedCGPoint {
  185. MASViewConstraint *centerX = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerX];
  186. centerX.mas_equalTo(CGPointMake(10, 20));
  187. expect(centerX.layoutConstant).to.equal(10);
  188. MASViewConstraint *centerY = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerY];
  189. centerY.mas_equalTo(CGPointMake(10, 20));
  190. expect(centerY.layoutConstant).to.equal(20);
  191. }
  192. - (void)testRelationAcceptsAutoboxedCGSize {
  193. MASViewConstraint *width = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_width];
  194. width.mas_equalTo(CGSizeMake(30, 40));
  195. expect(width.layoutConstant).to.equal(30);
  196. MASViewConstraint *height = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_height];
  197. height.mas_equalTo(CGSizeMake(30, 40));
  198. expect(height.layoutConstant).to.equal(40);
  199. }
  200. - (void)testRelationAcceptsAutoboxedEdgeInsets {
  201. MASEdgeInsets insets = (MASEdgeInsets){10, 20, 30, 40};
  202. MASViewConstraint *top = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_top];
  203. top.mas_equalTo(insets);
  204. expect(top.layoutConstant).to.equal(10);
  205. MASViewConstraint *left = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_left];
  206. left.mas_equalTo(insets);
  207. expect(left.layoutConstant).to.equal(20);
  208. MASViewConstraint *bottom = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_bottom];
  209. bottom.mas_equalTo(insets);
  210. expect(bottom.layoutConstant).to.equal(-30);
  211. MASViewConstraint *right = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_right];
  212. right.mas_equalTo(insets);
  213. expect(right.layoutConstant).to.equal(-40);
  214. }
  215. - (void)testRelationAutoboxingComplainsWithUnsupportedArgument {
  216. expect(^{
  217. constraint.mas_equalTo(@{});
  218. }).to.raise(@"NSInternalInconsistencyException");
  219. }
  220. - (void)testPriorityHigh {
  221. constraint.equalTo(otherView);
  222. constraint.with.priorityHigh();
  223. [constraint install];
  224. expect(constraint.layoutPriority).to.equal(MASLayoutPriorityDefaultHigh);
  225. expect(constraint.layoutConstraint.priority).to.equal(MASLayoutPriorityDefaultHigh);
  226. }
  227. - (void)testPriorityLow {
  228. constraint.equalTo(otherView);
  229. constraint.with.priorityLow();
  230. [constraint install];
  231. expect(constraint.layoutPriority).to.equal(MASLayoutPriorityDefaultLow);
  232. expect(constraint.layoutConstraint.priority).to.equal(MASLayoutPriorityDefaultLow);
  233. }
  234. - (void)testPriorityMedium {
  235. constraint.equalTo(otherView);
  236. constraint.with.priorityMedium();
  237. [constraint install];
  238. expect(constraint.layoutPriority).to.equal(MASLayoutPriorityDefaultMedium);
  239. expect(constraint.layoutConstraint.priority).to.equal(MASLayoutPriorityDefaultMedium);
  240. }
  241. - (void)testMultiplierNotUpdate {
  242. [constraint install];
  243. expect(^{
  244. constraint.multipliedBy(0.9);
  245. }).to.raise(@"NSInternalInconsistencyException");
  246. }
  247. - (void)testMultiplierWithMultipliedBy {
  248. constraint.equalTo(otherView);
  249. constraint.multipliedBy(5);
  250. [constraint install];
  251. expect(constraint.layoutMultiplier).to.equal(5);
  252. expect(constraint.layoutConstraint.multiplier).to.equal(5);
  253. }
  254. - (void)testMultiplierWithDividedBy {
  255. constraint.equalTo(otherView);
  256. constraint.dividedBy(10);
  257. [constraint install];
  258. expect(constraint.layoutMultiplier).to.equal(0.1);
  259. expect(constraint.layoutConstraint.multiplier).to.beCloseTo(0.1);
  260. }
  261. - (void)testConstantUpdateAfterConstraintCreated {
  262. [constraint install];
  263. constraint.offset(10);
  264. expect(constraint.layoutConstant).to.equal(10);
  265. expect(constraint.layoutConstraint.constant).to.equal(10);
  266. }
  267. - (void)testConstantUpdateSidesOffset {
  268. MASViewConstraint *centerY = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerY];
  269. centerY.with.insets((MASEdgeInsets){10, 10, 10, 10});
  270. expect(centerY.layoutConstant).to.equal(0);
  271. MASViewConstraint *top = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_top];
  272. top.insets((MASEdgeInsets){15, 10, 10, 10});
  273. expect(top.layoutConstant).to.equal(15);
  274. MASViewConstraint *left = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_left];
  275. left.insets((MASEdgeInsets){10, 15, 10, 10});
  276. expect(left.layoutConstant).to.equal(15);
  277. MASViewConstraint *bottom = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_bottom];
  278. bottom.insets((MASEdgeInsets){10, 10, 15, 10});
  279. expect(bottom.layoutConstant).to.equal(-15);
  280. MASViewConstraint *right = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_right];
  281. right.insets((MASEdgeInsets){10, 10, 10, 15});
  282. expect(right.layoutConstant).to.equal(-15);
  283. }
  284. - (void)testConstantUpdateCenterOffsetOnly {
  285. MASViewConstraint *width = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_width];
  286. width.centerOffset(CGPointMake(-20, -10));
  287. expect(width.layoutConstant).to.equal(0);
  288. MASViewConstraint *centerX = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerX];
  289. centerX.centerOffset(CGPointMake(-20, -10));
  290. expect(centerX.layoutConstant).to.equal(-20);
  291. MASViewConstraint *centerY = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerY];
  292. centerY.centerOffset(CGPointMake(-20, -10));
  293. expect(centerY.layoutConstant).to.equal(-10);
  294. }
  295. - (void)testConstantUpdateSizeOffsetOnly {
  296. MASViewConstraint *bottom = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_bottom];
  297. bottom.sizeOffset(CGSizeMake(-40, 55));
  298. expect(bottom.layoutConstant).to.equal(0);
  299. MASViewConstraint *width = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_width];
  300. width.sizeOffset(CGSizeMake(-40, 55));
  301. expect(width.layoutConstant).to.equal(-40);
  302. MASViewConstraint *height = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_height];
  303. height.sizeOffset(CGSizeMake(-40, 55));
  304. expect(height.layoutConstant).to.equal(55);
  305. }
  306. - (void)testAutoboxedConstantUpdateOffset {
  307. constraint.mas_offset(42);
  308. expect(constraint.layoutConstant).to.equal(42);
  309. }
  310. - (void)testAutoboxedConstantUpdateSidesOffset {
  311. MASEdgeInsets insets = (MASEdgeInsets){10, 20, 30, 40};
  312. MASViewConstraint *centerY = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerY];
  313. centerY.mas_offset(insets);
  314. expect(centerY.layoutConstant).to.equal(0);
  315. MASViewConstraint *top = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_top];
  316. top.mas_offset(insets);
  317. expect(top.layoutConstant).to.equal(10);
  318. MASViewConstraint *left = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_left];
  319. left.mas_offset(insets);
  320. expect(left.layoutConstant).to.equal(20);
  321. MASViewConstraint *bottom = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_bottom];
  322. bottom.mas_offset(insets);
  323. expect(bottom.layoutConstant).to.equal(-30);
  324. MASViewConstraint *right = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_right];
  325. right.mas_offset(insets);
  326. expect(right.layoutConstant).to.equal(-40);
  327. }
  328. - (void)testAutoboxedConstantUpdateCenterOffset {
  329. MASViewConstraint *centerX = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerX];
  330. centerX.mas_offset(CGPointMake(-20, -10));
  331. expect(centerX.layoutConstant).to.equal(-20);
  332. MASViewConstraint *centerY = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_centerY];
  333. centerY.mas_offset(CGPointMake(-20, -10));
  334. expect(centerY.layoutConstant).to.equal(-10);
  335. }
  336. - (void)testAutoboxedConstantUpdateSizeOffset {
  337. MASViewConstraint *width = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_width];
  338. width.mas_offset(CGSizeMake(-40, 55));
  339. expect(width.layoutConstant).to.equal(-40);
  340. MASViewConstraint *height = [[MASViewConstraint alloc] initWithFirstViewAttribute:otherView.mas_height];
  341. height.mas_offset(CGSizeMake(-40, 55));
  342. expect(height.layoutConstant).to.equal(55);
  343. }
  344. - (void)testInstallLayoutConstraintOnCommit {
  345. MASViewAttribute *secondViewAttribute = otherView.mas_height;
  346. constraint.equalTo(secondViewAttribute);
  347. constraint.multipliedBy(0.5);
  348. constraint.offset(10);
  349. constraint.priority(345);
  350. [constraint install];
  351. expect(constraint.layoutConstraint.firstAttribute).to.equal(NSLayoutAttributeWidth);
  352. expect(constraint.layoutConstraint.secondAttribute).to.equal(NSLayoutAttributeHeight);
  353. expect(constraint.layoutConstraint.firstItem).to.beIdenticalTo(constraint.firstViewAttribute.view);
  354. expect(constraint.layoutConstraint.secondItem).to.beIdenticalTo(constraint.secondViewAttribute.view);
  355. expect(constraint.layoutConstraint.relation).to.equal(NSLayoutRelationEqual);
  356. expect(constraint.layoutConstraint.constant).to.equal(10);
  357. expect(constraint.layoutConstraint.priority).to.equal(345);
  358. expect(constraint.layoutConstraint.multiplier).to.equal(0.5);
  359. expect(superview.constraints[0]).to.beIdenticalTo(constraint.layoutConstraint);
  360. }
  361. - (void)testInstallRelativeToSuperview {
  362. MAS_VIEW *view = MAS_VIEW.new;
  363. constraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:view.mas_baseline];
  364. constraint.delegate = delegate;
  365. [superview addSubview:view];
  366. constraint.equalTo(@10);
  367. [constraint install];
  368. expect(constraint.layoutConstraint.firstAttribute).to.equal(NSLayoutAttributeBaseline);
  369. expect(constraint.layoutConstraint.secondAttribute).to.equal(NSLayoutAttributeBaseline);
  370. expect(constraint.layoutConstraint.firstItem).to.beIdenticalTo(constraint.firstViewAttribute.view);
  371. expect(constraint.layoutConstraint.secondItem).to.beIdenticalTo(superview);
  372. expect(constraint.layoutConstraint.relation).to.equal(NSLayoutRelationEqual);
  373. expect(constraint.layoutConstraint.constant).to.equal(10);
  374. expect(superview.constraints[0]).to.beIdenticalTo(constraint.layoutConstraint);
  375. }
  376. - (void)testInstallWidthAsConstant {
  377. constraint.equalTo(@10);
  378. [constraint install];
  379. expect(constraint.layoutConstraint.firstAttribute).to.equal(NSLayoutAttributeWidth);
  380. expect(constraint.layoutConstraint.secondAttribute).to.equal(NSLayoutAttributeNotAnAttribute);
  381. expect(constraint.layoutConstraint.firstItem).to.beIdenticalTo(constraint.firstViewAttribute.view);
  382. expect(constraint.layoutConstraint.secondItem).to.beNil();
  383. expect(constraint.layoutConstraint.relation).to.equal(NSLayoutRelationEqual);
  384. expect(constraint.layoutConstraint.constant).to.equal(10);
  385. expect(constraint.firstViewAttribute.view.constraints[0]).to.beIdenticalTo(constraint.layoutConstraint);
  386. }
  387. - (void)testUninstallConstraint {
  388. MASViewAttribute *secondViewAttribute = otherView.mas_height;
  389. constraint.equalTo(secondViewAttribute);
  390. [constraint install];
  391. expect(superview.constraints).to.haveCountOf(1);
  392. expect(superview.constraints[0]).to.equal(constraint.layoutConstraint);
  393. [constraint uninstall];
  394. expect(superview.constraints).to.haveCountOf(0);
  395. }
  396. - (void)testAttributeChainingShouldNotHaveRelation {
  397. MASViewAttribute *secondViewAttribute = otherView.mas_top;
  398. constraint.lessThanOrEqualTo(secondViewAttribute);
  399. expect(^{
  400. __unused id result = constraint.bottom;
  401. }).to.raise(@"NSInternalInconsistencyException");
  402. }
  403. - (void)testAttributeChainingShouldCallDelegate {
  404. MASViewConstraint *result = (id)constraint.and.bottom;
  405. expect(result.firstViewAttribute.layoutAttribute).to.equal(@(NSLayoutAttributeBottom));
  406. expect(delegate.chainedConstraints).to.equal(@[constraint]);
  407. }
  408. SpecEnd