[ASStackLayoutSpec] Fix interitem spacing not being reset on new lines and add snapshot tests #trivial (#491)

* Add snapshot tests for interitem and interline spacings of stack spec

* Improve comment

* Make sure item spacings are properly considered and reset on new lines, snapshot tests included
This commit is contained in:
Huy Nguyen 2017-08-06 13:20:33 +01:00 committed by GitHub
parent 10efa31abd
commit 69a915356d
15 changed files with 120 additions and 6 deletions

View File

@ -485,7 +485,8 @@ static CGFloat computeItemsStackDimensionSum(const std::vector<ASStackLayoutSpec
});
// Sum up the childrens' dimensions (including spacing) in the stack direction.
const CGFloat childStackDimensionSum = std::accumulate(items.begin(), items.end(), childSpacingSum,
const CGFloat childStackDimensionSum = std::accumulate(items.begin(), items.end(),
childSpacingSum,
[&](CGFloat x, const ASStackLayoutSpecItem &l) {
return x + stackDimension(style.direction, l.layout.size);
});
@ -647,22 +648,25 @@ static std::vector<ASStackUnpositionedLine> collectChildrenIntoLines(const std::
std::vector<ASStackUnpositionedLine> lines;
std::vector<ASStackLayoutSpecItem> lineItems;
CGFloat lineStackDimensionSum = 0;
CGFloat interitemSpacing = 0;
for(auto it = items.begin(); it != items.end(); ++it) {
const auto &item = *it;
const CGFloat itemStackDimension = stackDimension(style.direction, item.layout.size);
const CGFloat itemAndSpacingStackDimension = (lineItems.empty() ? 0.0 : style.spacing) + item.child.style.spacingBefore + itemStackDimension + item.child.style.spacingAfter;
const BOOL negativeViolationIfAddItem = (ASStackUnpositionedLayout::computeStackViolation(lineStackDimensionSum + itemAndSpacingStackDimension, style, sizeRange) < 0);
const CGFloat itemAndSpacingStackDimension = item.child.style.spacingBefore + itemStackDimension + item.child.style.spacingAfter;
const BOOL negativeViolationIfAddItem = (ASStackUnpositionedLayout::computeStackViolation(lineStackDimensionSum + interitemSpacing + itemAndSpacingStackDimension, style, sizeRange) < 0);
const BOOL breakCurrentLine = negativeViolationIfAddItem && !lineItems.empty();
if (breakCurrentLine) {
lines.push_back({.items = std::vector<ASStackLayoutSpecItem> (lineItems)});
lineItems.clear();
lineStackDimensionSum = 0;
interitemSpacing = 0;
}
lineItems.push_back(std::move(item));
lineStackDimensionSum += itemAndSpacingStackDimension;
lineStackDimensionSum += interitemSpacing + itemAndSpacingStackDimension;
interitemSpacing = style.spacing;
}
// Handle last line

View File

@ -110,6 +110,7 @@ static NSArray<ASTextNode*> *defaultTextNodes()
alignItems:style.alignItems
flexWrap:style.flexWrap
alignContent:style.alignContent
lineSpacing:style.lineSpacing
children:children];
[self testStackLayoutSpec:stackLayoutSpec sizeRange:sizeRange subnodes:subnodes identifier:identifier];
@ -163,6 +164,7 @@ static NSArray<ASTextNode*> *defaultTextNodes()
}
- (void)testStackLayoutSpecWithAlignContent:(ASStackLayoutAlignContent)alignContent
lineSpacing:(CGFloat)lineSpacing
sizeRange:(ASSizeRange)sizeRange
identifier:(NSString *)identifier
{
@ -170,8 +172,9 @@ static NSArray<ASTextNode*> *defaultTextNodes()
.direction = ASStackLayoutDirectionHorizontal,
.flexWrap = ASStackLayoutFlexWrapWrap,
.alignContent = alignContent,
.lineSpacing = lineSpacing,
};
CGSize subnodeSize = {50, 50};
NSArray<ASDisplayNode *> *subnodes = @[
ASDisplayNodeWithBackgroundColor([UIColor redColor], subnodeSize),
@ -181,10 +184,17 @@ static NSArray<ASTextNode*> *defaultTextNodes()
ASDisplayNodeWithBackgroundColor([UIColor greenColor], subnodeSize),
ASDisplayNodeWithBackgroundColor([UIColor cyanColor], subnodeSize),
];
[self testStackLayoutSpecWithStyle:style sizeRange:sizeRange subnodes:subnodes identifier:identifier];
}
- (void)testStackLayoutSpecWithAlignContent:(ASStackLayoutAlignContent)alignContent
sizeRange:(ASSizeRange)sizeRange
identifier:(NSString *)identifier
{
[self testStackLayoutSpecWithAlignContent:alignContent lineSpacing:0.0 sizeRange:sizeRange identifier:identifier];
}
#pragma mark -
- (void)testDefaultStackLayoutElementFlexProperties
@ -1209,6 +1219,77 @@ static NSArray<ASTextNode*> *defaultTextNodes()
[self testStackLayoutSpec:stackLayoutSpec sizeRange:kSize subnodes:children identifier:nil];
}
#pragma mark - Flex wrap and item spacings test
- (void)testFlexWrapWithItemSpacings
{
ASStackLayoutSpecStyle style = {
.spacing = 50,
.direction = ASStackLayoutDirectionHorizontal,
.flexWrap = ASStackLayoutFlexWrapWrap,
.alignContent = ASStackLayoutAlignContentStart,
.lineSpacing = 5,
};
CGSize subnodeSize = {50, 50};
NSArray<ASDisplayNode *> *subnodes = @[
ASDisplayNodeWithBackgroundColor([UIColor redColor], subnodeSize),
ASDisplayNodeWithBackgroundColor([UIColor yellowColor], subnodeSize),
ASDisplayNodeWithBackgroundColor([UIColor blueColor], subnodeSize),
];
for (ASDisplayNode *subnode in subnodes) {
subnode.style.spacingBefore = 5;
subnode.style.spacingAfter = 5;
}
// 3 items, each item has a size of {50, 50}
// width is 230px, enough to fit all items without taking all spacings into account
// Test that all spacings are included and therefore the last item is pushed to a second line.
// See: https://github.com/TextureGroup/Texture/pull/472
static ASSizeRange kSize = {{230, 300}, {230, 300}};
[self testStackLayoutSpecWithStyle:style sizeRange:kSize subnodes:subnodes identifier:nil];
}
- (void)testFlexWrapWithItemSpacingsBeingResetOnNewLines
{
ASStackLayoutSpecStyle style = {
.spacing = 5,
.direction = ASStackLayoutDirectionHorizontal,
.flexWrap = ASStackLayoutFlexWrapWrap,
.alignContent = ASStackLayoutAlignContentStart,
.lineSpacing = 5,
};
CGSize subnodeSize = {50, 50};
NSArray<ASDisplayNode *> *subnodes = @[
// 1st line
ASDisplayNodeWithBackgroundColor([UIColor redColor], subnodeSize),
ASDisplayNodeWithBackgroundColor([UIColor yellowColor], subnodeSize),
ASDisplayNodeWithBackgroundColor([UIColor blueColor], subnodeSize),
// 2nd line
ASDisplayNodeWithBackgroundColor([UIColor magentaColor], subnodeSize),
ASDisplayNodeWithBackgroundColor([UIColor greenColor], subnodeSize),
ASDisplayNodeWithBackgroundColor([UIColor cyanColor], subnodeSize),
// 3rd line
ASDisplayNodeWithBackgroundColor([UIColor brownColor], subnodeSize),
ASDisplayNodeWithBackgroundColor([UIColor orangeColor], subnodeSize),
ASDisplayNodeWithBackgroundColor([UIColor purpleColor], subnodeSize),
];
for (ASDisplayNode *subnode in subnodes) {
subnode.style.spacingBefore = 5;
subnode.style.spacingAfter = 5;
}
// 3 lines, each line has 3 items, each item has a size of {50, 50}
// width is 190px, enough to fit 3 items into a line
// Test that interitem spacing is reset on new lines. Otherwise, lines after the 1st line would have only 2 items.
// See: https://github.com/TextureGroup/Texture/pull/472
static ASSizeRange kSize = {{190, 300}, {190, 300}};
[self testStackLayoutSpecWithStyle:style sizeRange:kSize subnodes:subnodes identifier:nil];
}
#pragma mark - Content alignment tests
- (void)testAlignContentUnderflow
@ -1282,4 +1363,33 @@ static NSArray<ASTextNode*> *defaultTextNodes()
[self testStackLayoutSpecWithStyle:style sizeRange:kSize subnodes:subnodes identifier:nil];
}
#pragma mark - Line spacing tests
- (void)testAlignContentAndLineSpacingUnderflow
{
// 3 lines, each line has 2 items, each item has a size of {50, 50}
// 10px between lines
// width is 110px. It's 10px bigger than the required width of each line (110px vs 100px) to test that items are still correctly collected into lines
static ASSizeRange kSize = {{110, 320}, {110, 320}};
[self testStackLayoutSpecWithAlignContent:ASStackLayoutAlignContentStart lineSpacing:10 sizeRange:kSize identifier:@"alignContentStart"];
[self testStackLayoutSpecWithAlignContent:ASStackLayoutAlignContentCenter lineSpacing:10 sizeRange:kSize identifier:@"alignContentCenter"];
[self testStackLayoutSpecWithAlignContent:ASStackLayoutAlignContentEnd lineSpacing:10 sizeRange:kSize identifier:@"alignContentEnd"];
[self testStackLayoutSpecWithAlignContent:ASStackLayoutAlignContentSpaceBetween lineSpacing:10 sizeRange:kSize identifier:@"alignContentSpaceBetween"];
[self testStackLayoutSpecWithAlignContent:ASStackLayoutAlignContentSpaceAround lineSpacing:10 sizeRange:kSize identifier:@"alignContentSpaceAround"];
[self testStackLayoutSpecWithAlignContent:ASStackLayoutAlignContentStretch lineSpacing:10 sizeRange:kSize identifier:@"alignContentStretch"];
}
- (void)testAlignContentAndLineSpacingOverflow
{
// 6 lines, each line has 1 item, each item has a size of {50, 50}
// 10px between lines
// width is 40px. It's 10px smaller than the width of each item (40px vs 50px) to test that items are still correctly collected into lines
static ASSizeRange kSize = {{40, 310}, {40, 310}};
[self testStackLayoutSpecWithAlignContent:ASStackLayoutAlignContentStart lineSpacing:10 sizeRange:kSize identifier:@"alignContentStart"];
[self testStackLayoutSpecWithAlignContent:ASStackLayoutAlignContentCenter lineSpacing:10 sizeRange:kSize identifier:@"alignContentCenter"];
[self testStackLayoutSpecWithAlignContent:ASStackLayoutAlignContentEnd lineSpacing:10 sizeRange:kSize identifier:@"alignContentEnd"];
[self testStackLayoutSpecWithAlignContent:ASStackLayoutAlignContentSpaceBetween lineSpacing:10 sizeRange:kSize identifier:@"alignContentSpaceBetween"];
[self testStackLayoutSpecWithAlignContent:ASStackLayoutAlignContentSpaceAround lineSpacing:10 sizeRange:kSize identifier:@"alignContentSpaceAround"];
}
@end

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB