diff --git a/client/ios/DivKit/Extensions/DivContainer/DivContainerSizeModifier.swift b/client/ios/DivKit/Extensions/DivContainer/DivContainerSizeModifier.swift index ebe7320af..27d941d5b 100644 --- a/client/ios/DivKit/Extensions/DivContainer/DivContainerSizeModifier.swift +++ b/client/ios/DivKit/Extensions/DivContainer/DivContainerSizeModifier.swift @@ -13,6 +13,11 @@ struct DivContainerSizeModifier: DivSizeModifier { orientation: DivContainer.Orientation ) { let items = container.nonNilItems + if items.isEmpty { + shouldOverrideWidth = false + shouldOverrideHeight = false + return + } let isWrapContentWidth = container.getTransformedWidth(context).isIntrinsic switch orientation { diff --git a/client/ios/DivKitTests/Extensions/DivContainerExtensionsTests.swift b/client/ios/DivKitTests/Extensions/DivContainerExtensionsTests.swift index ec59d4c58..eeb9af111 100644 --- a/client/ios/DivKitTests/Extensions/DivContainerExtensionsTests.swift +++ b/client/ios/DivKitTests/Extensions/DivContainerExtensionsTests.swift @@ -42,6 +42,29 @@ final class DivContainerExtensionsTests: XCTestCase { assertEqual(block, expectedBlock) } + func test_EmptyItems_WrapContent() throws { + let block = makeBlock( + divContainer( + items: [], + width: wrapContentSize() + ) + ) + + let expectedBlock = try StateBlock( + child: DecoratingBlock( + child: ContainerBlock( + layoutDirection: .vertical, + widthTrait: .intrinsic, + children: [] + ), + accessibilityElement: .default + ), + ids: [] + ) + + assertEqual(block, expectedBlock) + } + func test_WithItems() throws { let block = makeBlock( divContainer( @@ -316,6 +339,58 @@ final class DivContainerExtensionsTests: XCTestCase { assertEqual(block, expectedBlock) } + func test_WrapContent_MatchParentItem() throws { + let context = DivBlockModelingContext() + let block = makeBlock( + divContainer( + items: [ + divText( + text: "Hello!", + width: matchParentSize() + ), + ], + width: wrapContentSize() + ), + context: context, + ignoreErrors: true + ) + + let expectedBlock = try StateBlock( + child: DecoratingBlock( + child: ContainerBlock( + layoutDirection: .vertical, + widthTrait: .intrinsic, + children: [ + DecoratingBlock( + child: textBlock( + widthTrait: .intrinsic( + constrained: true, + minSize: 0, + maxSize: .infinity + ), + text: "Hello!" + ), + accessibilityElement: accessibility( + traits: .staticText, + label: "Hello!" + ) + ), + ] + ), + accessibilityElement: .default + ), + ids: [] + ) + + assertEqual(block, expectedBlock) + + assertEqual(context.errorsStorage.errors.count, 1) + assertEqual( + context.errorsStorage.errors.first?.message, + "All items in DivContainer with wrap_content width has match_parent width" + ) + } + func test_AddsIndexedParentPathToItems() throws { let block = try makeBlock( fromFile: "item_with_action" diff --git a/client/ios/DivKitTests/Utils/BlockModelingUtils.swift b/client/ios/DivKitTests/Utils/BlockModelingUtils.swift index fbefd560f..478709ccb 100644 --- a/client/ios/DivKitTests/Utils/BlockModelingUtils.swift +++ b/client/ios/DivKitTests/Utils/BlockModelingUtils.swift @@ -1,15 +1,19 @@ @testable import DivKit -@testable import LayoutKit - import Foundation - +@testable import LayoutKit import VGSL +import XCTest func makeBlock( _ div: Div, - context: DivBlockModelingContext = DivBlockModelingContext() + context: DivBlockModelingContext = DivBlockModelingContext(), + ignoreErrors: Bool = false ) -> StateBlock { - try! divData(div).makeBlock(context: context) as! StateBlock + let block = try! divData(div).makeBlock(context: context) as! StateBlock + if !ignoreErrors, let error = context.errorsStorage.errors.first { + XCTFail(error.message) + } + return block } func separatorBlock() -> Block { @@ -18,9 +22,12 @@ func separatorBlock() -> Block { ) } -func textBlock(text: String) -> Block { +func textBlock( + widthTrait: LayoutTrait = .resizable, + text: String +) -> Block { TextBlock( - widthTrait: .resizable, + widthTrait: widthTrait, text: text.withTypo(), verticalAlignment: .leading, accessibilityElement: nil diff --git a/client/ios/DivKitTests/Utils/DivBuilders.swift b/client/ios/DivKitTests/Utils/DivBuilders.swift index 2d1846750..c3957c2f5 100644 --- a/client/ios/DivKitTests/Utils/DivBuilders.swift +++ b/client/ios/DivKitTests/Utils/DivBuilders.swift @@ -481,6 +481,10 @@ func fixedSize(_ value: Int) -> DivSize { .divFixedSize(DivFixedSize(value: .value(value))) } +func matchParentSize() -> DivSize { + .divMatchParentSize(DivMatchParentSize()) +} + func wrapContentSize() -> DivSize { .divWrapContentSize(DivWrapContentSize()) } diff --git a/client/ios/LayoutKit/LayoutKit/Blocks/Container/ContainerBlock.swift b/client/ios/LayoutKit/LayoutKit/Blocks/Container/ContainerBlock.swift index d1a891836..d5478e997 100644 --- a/client/ios/LayoutKit/LayoutKit/Blocks/Container/ContainerBlock.swift +++ b/client/ios/LayoutKit/LayoutKit/Blocks/Container/ContainerBlock.swift @@ -156,7 +156,9 @@ public final class ContainerBlock: BlockWithLayout { self.clipContent = clipContent self.accessibilityElement = accessibilityElement - try validateLayoutTraits() + if !children.isEmpty { + try validateLayoutTraits() + } } public func ascent(forWidth width: CGFloat) -> CGFloat? {