MASViewConstraintSpec.m 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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.h"
  10. @interface MASViewConstraint ()
  11. @property (nonatomic, strong) NSLayoutConstraint *layoutConstraint;
  12. @property (nonatomic, assign) NSLayoutRelation layoutRelation;
  13. @property (nonatomic, assign) UILayoutPriority layoutPriority;
  14. @property (nonatomic, assign) CGFloat layoutMultiplier;
  15. @property (nonatomic, assign) CGFloat layoutConstant;
  16. @property (nonatomic, assign) BOOL hasLayoutRelation;
  17. @end
  18. SpecBegin(MASViewConstraint)
  19. __block UIView *superview;
  20. __block MASViewConstraint *constraint;
  21. __block id<MASConstraintDelegate> delegate;
  22. __block MASViewAttribute *secondViewAttribute;
  23. beforeEach(^{
  24. superview = mock(UIView.class);
  25. UIView *secondView = mock(UIView.class);
  26. [given(secondView.superview) willReturn:superview];
  27. secondViewAttribute = [[MASViewAttribute alloc] initWithView:secondView layoutAttribute:NSLayoutAttributeHeight];
  28. delegate = mockProtocol(@protocol(MASConstraintDelegate));
  29. UIView *firstView = mock(UIView.class);
  30. [given(firstView.superview) willReturn:superview];
  31. MASViewAttribute *firstViewAttribute = [[MASViewAttribute alloc] initWithView:firstView layoutAttribute:NSLayoutAttributeWidth];
  32. constraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:firstViewAttribute];
  33. constraint.delegate = delegate;
  34. });
  35. describe(@"equality chaining", ^{
  36. it(@"should return same constraint when encountering equal for first time", ^{
  37. MASViewConstraint *newConstraint = constraint.equal(secondViewAttribute);
  38. [verify(delegate) addConstraint:(id)constraint];
  39. expect(newConstraint).to.beIdenticalTo(constraint);
  40. expect(constraint.secondViewAttribute).to.beIdenticalTo(secondViewAttribute);
  41. expect(constraint.layoutRelation).to.ex_equal(NSLayoutRelationEqual);
  42. });
  43. it(@"should start new constraint when encountering equal subsequently", ^{
  44. constraint.greaterThanOrEqual(secondViewAttribute);
  45. MASViewConstraint *newConstraint = constraint.equal(secondViewAttribute);
  46. [verify(delegate) addConstraint:(id)constraint];
  47. [verify(delegate) addConstraint:(id)newConstraint];
  48. expect(newConstraint).notTo.beIdenticalTo(constraint);
  49. });
  50. it(@"should return same constraint when encountering greaterThanOrEqual for first time", ^{
  51. MASViewConstraint *newConstraint = constraint.greaterThanOrEqual(secondViewAttribute);
  52. [verify(delegate) addConstraint:(id)constraint];
  53. expect(newConstraint).to.beIdenticalTo(constraint);
  54. expect(constraint.secondViewAttribute).to.beIdenticalTo(secondViewAttribute);
  55. expect(constraint.layoutRelation).to.ex_equal(NSLayoutRelationGreaterThanOrEqual);
  56. });
  57. it(@"should start new constraint when encountering greaterThanOrEqual subsequently", ^{
  58. constraint.lessThanOrEqual(secondViewAttribute);
  59. MASViewConstraint *newConstraint = constraint.greaterThanOrEqual(secondViewAttribute);
  60. [verify(delegate) addConstraint:(id)constraint];
  61. [verify(delegate) addConstraint:(id)newConstraint];
  62. expect(newConstraint).notTo.beIdenticalTo(constraint);
  63. });
  64. it(@"should return same constraint when encountering lessThanOrEqual for first time", ^{
  65. MASViewConstraint *newConstraint = constraint.lessThanOrEqual(secondViewAttribute);
  66. [verify(delegate) addConstraint:(id)constraint];
  67. expect(newConstraint).to.beIdenticalTo(constraint);
  68. expect(constraint.secondViewAttribute).to.beIdenticalTo(secondViewAttribute);
  69. expect(constraint.layoutRelation).to.ex_equal(NSLayoutRelationLessThanOrEqual);
  70. });
  71. it(@"should start new constraint when encountering lessThanOrEqual subsequently", ^{
  72. constraint.equal(secondViewAttribute);
  73. MASViewConstraint *newConstraint = constraint.lessThanOrEqual(secondViewAttribute);
  74. [verify(delegate) addConstraint:(id)constraint];
  75. [verify(delegate) addConstraint:(id)newConstraint];
  76. expect(newConstraint).notTo.beIdenticalTo(constraint);
  77. });
  78. it(@"should not allow update of equal once layoutconstraint is created", ^{
  79. [constraint commit];
  80. expect(^{
  81. constraint.equal(secondViewAttribute);
  82. }).to.raise(@"NSInternalInconsistencyException");
  83. });
  84. it(@"should not allow update of lessThanOrEqual once layoutconstraint is created", ^{
  85. [constraint commit];
  86. expect(^{
  87. constraint.lessThanOrEqual(secondViewAttribute);
  88. }).to.raise(@"NSInternalInconsistencyException");
  89. });
  90. it(@"should not allow update of greaterThanOrEqual once layoutconstraint is created", ^{
  91. [constraint commit];
  92. expect(^{
  93. constraint.greaterThanOrEqual(secondViewAttribute);
  94. }).to.raise(@"NSInternalInconsistencyException");
  95. });
  96. xit(@"should create composite when passed array of views", ^{
  97. });
  98. });
  99. describe(@"multiplier & constant", ^{
  100. it(@"should not allow update of multiplier after layoutconstraint is created", ^{
  101. [constraint commit];
  102. expect(^{
  103. constraint.percent(0.9);
  104. }).to.raise(@"NSInternalInconsistencyException");
  105. });
  106. it(@"should allow update of constant after layoutconstraint is created", ^{
  107. [constraint commit];
  108. constraint.offset(10);
  109. expect(constraint.layoutConstant).to.ex_equal(10);
  110. expect(constraint.layoutConstraint.constant).to.ex_equal(10);
  111. });
  112. xit(@"should update sides only", ^{});
  113. xit(@"should update center only", ^{});
  114. xit(@"should update size only", ^{});
  115. });
  116. describe(@"commit", ^{
  117. it(@"should create layout constraint", ^{
  118. constraint.equal(secondViewAttribute);
  119. constraint.percent(0.5);
  120. constraint.offset(10);
  121. constraint.priority(345);
  122. [constraint commit];
  123. expect(constraint.layoutConstraint.firstAttribute).to.ex_equal(NSLayoutAttributeWidth);
  124. expect(constraint.layoutConstraint.secondAttribute).to.ex_equal(NSLayoutAttributeHeight);
  125. expect(constraint.layoutConstraint.firstItem).to.beIdenticalTo(constraint.firstViewAttribute.view);
  126. expect(constraint.layoutConstraint.secondItem).to.beIdenticalTo(constraint.secondViewAttribute.view);
  127. expect(constraint.layoutConstraint.relation).to.ex_equal(NSLayoutRelationEqual);
  128. expect(constraint.layoutConstraint.constant).to.ex_equal(10);
  129. expect(constraint.layoutConstraint.priority).to.ex_equal(345);
  130. expect(constraint.layoutConstraint.multiplier).to.ex_equal(0.5);
  131. [verify(superview) addConstraint:constraint.layoutConstraint];
  132. });
  133. });
  134. SpecEnd