├── .gitignore ├── LICENSE ├── PATENTS ├── README.md ├── absolute_position_test.go ├── align_content_test.go ├── align_items_test.go ├── align_self_test.go ├── aspect_ratio_test.go ├── baseline_func_test.go ├── border_test.go ├── compute_margin_test.go ├── compute_padding_test.go ├── default_values_test.go ├── dimension_test.go ├── dirty_marking_test.go ├── display_test.go ├── edge_test.go ├── enums.go ├── flex_direction_test.go ├── flex_test.go ├── flex_wrap_test.go ├── had_overflow_test.go ├── issue5_test.go ├── justify_content_test.go ├── margin_test.go ├── math.go ├── math_test.go ├── measure_cache_test.go ├── measure_mode_test.go ├── measure_test.go ├── min_max_dimension_test.go ├── node_child_test.go ├── padding_test.go ├── percentage_test.go ├── print.go ├── relayout_test.go ├── rounding_function_test.go ├── rounding_measure_func_test.go ├── rounding_test.go ├── size_overflow_test.go ├── style_test.go ├── yoga.go ├── yoga_h.go └── yoga_props.go /.gitignore: -------------------------------------------------------------------------------- 1 | debug 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD License 2 | 3 | For yoga software 4 | 5 | Copyright (c) 2014-present, Facebook, Inc. All rights reserved. 6 | Copyright (c) 2017-present, Krzysztof Kowalczyk. All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without modification, 9 | are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name Facebook nor the names of its contributors may be used to 19 | endorse or promote products derived from this software without specific 20 | prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 26 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 29 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /PATENTS: -------------------------------------------------------------------------------- 1 | Additional Grant of Patent Rights Version 2 2 | 3 | "Software" means the yoga software distributed by Facebook, Inc. 4 | 5 | Facebook, Inc. (“Facebook”) hereby grants to each recipient of the Software 6 | (“you”) a perpetual, worldwide, royalty-free, non-exclusive, irrevocable 7 | (subject to the termination provision below) license under any Necessary 8 | Claims, to make, have made, use, sell, offer to sell, import, and otherwise 9 | transfer the Software. For avoidance of doubt, no license is granted under 10 | Facebook's rights in any patent claims that are infringed by (i) modifications 11 | to the Software made by you or any third party or (ii) the Software in 12 | combination with any software or other technology. 13 | 14 | The license granted hereunder will terminate, automatically and without notice, 15 | if you (or any of your subsidiaries, corporate affiliates or agents) initiate 16 | directly or indirectly, or take a direct financial interest in, any Patent 17 | Assertion: (i) against Facebook or any of its subsidiaries or corporate 18 | affiliates, (ii) against any party if such Patent Assertion arises in whole or 19 | in part from any software, technology, product or service of Facebook or any of 20 | its subsidiaries or corporate affiliates, or (iii) against any party relating 21 | to the Software. Notwithstanding the foregoing, if Facebook or any of its 22 | subsidiaries or corporate affiliates files a lawsuit alleging patent 23 | infringement against you in the first instance, and you respond by filing a 24 | patent infringement counterclaim in that lawsuit against that party that is 25 | unrelated to the Software, the license granted hereunder will not terminate 26 | under section (i) of this paragraph due to such counterclaim. 27 | 28 | A "Necessary Claim" is a claim of a patent owned by Facebook that is 29 | necessarily infringed by the Software standing alone. 30 | 31 | A "Patent Assertion" is any lawsuit or other action alleging direct, indirect, 32 | or contributory infringement or inducement to infringe any patent, including a 33 | cross-claim or counterclaim. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flex - CSS flexbox layout implementation in Go 2 | 3 | Go implementation of [flexbox CSS](https://www.w3.org/TR/css-flexbox-1/) layout algorithm. 4 | 5 | A pure Go port of [Facebook's Yoga](https://github.com/facebook/yoga). 6 | 7 | ## How to use 8 | 9 | Read [tutorial](https://blog.kowalczyk.info/article/9/tutorial-on-using-github.comkjkflex-go-package.html) or look at `_test.go` files. 10 | 11 | ## Status 12 | 13 | The port is finished. The code works and passess all Yoga tests. 14 | 15 | The API is awkward by Go standards but it's the best I could do given that I want to stay close to C version. 16 | 17 | Logic is currently synced up to https://github.com/facebook/yoga/commit/f45059e1e696727c1282742b89d2c8bf06345254 18 | 19 | ## How the port was made 20 | 21 | You can read a [detailed story](https://blog.kowalczyk.info/article/wN9R/experience-porting-4.5k-loc-of-c-to-go-facebooks-css-flexbox-implementation-yoga.html). 22 | 23 | In short: 24 | 25 | * manually ported [C code](https://github.com/facebook/yoga/tree/master/yoga) to Go, line-by-line 26 | * manually ported [tests](https://github.com/facebook/yoga/tree/master/tests) to Go 27 | * tweak the API from C style to be more Go like. The structure and logic still is very close to C code (this makes porting future C changes easy) 28 | -------------------------------------------------------------------------------- /align_self_test.go: -------------------------------------------------------------------------------- 1 | package flex 2 | 3 | import "testing" 4 | 5 | func TestAlign_self_center(t *testing.T) { 6 | config := NewConfig() 7 | 8 | root := NewNodeWithConfig(config) 9 | root.StyleSetWidth(100) 10 | root.StyleSetHeight(100) 11 | 12 | rootChild0 := NewNodeWithConfig(config) 13 | rootChild0.StyleSetAlignSelf(AlignCenter) 14 | rootChild0.StyleSetWidth(10) 15 | rootChild0.StyleSetHeight(10) 16 | root.InsertChild(rootChild0, 0) 17 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 18 | 19 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 20 | assertFloatEqual(t, 0, root.LayoutGetTop()) 21 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 22 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 23 | 24 | assertFloatEqual(t, 45, rootChild0.LayoutGetLeft()) 25 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 26 | assertFloatEqual(t, 10, rootChild0.LayoutGetWidth()) 27 | assertFloatEqual(t, 10, rootChild0.LayoutGetHeight()) 28 | 29 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 30 | 31 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 32 | assertFloatEqual(t, 0, root.LayoutGetTop()) 33 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 34 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 35 | 36 | assertFloatEqual(t, 45, rootChild0.LayoutGetLeft()) 37 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 38 | assertFloatEqual(t, 10, rootChild0.LayoutGetWidth()) 39 | assertFloatEqual(t, 10, rootChild0.LayoutGetHeight()) 40 | } 41 | 42 | func TestAlign_self_flex_end(t *testing.T) { 43 | config := NewConfig() 44 | 45 | root := NewNodeWithConfig(config) 46 | root.StyleSetWidth(100) 47 | root.StyleSetHeight(100) 48 | 49 | rootChild0 := NewNodeWithConfig(config) 50 | rootChild0.StyleSetAlignSelf(AlignFlexEnd) 51 | rootChild0.StyleSetWidth(10) 52 | rootChild0.StyleSetHeight(10) 53 | root.InsertChild(rootChild0, 0) 54 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 55 | 56 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 57 | assertFloatEqual(t, 0, root.LayoutGetTop()) 58 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 59 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 60 | 61 | assertFloatEqual(t, 90, rootChild0.LayoutGetLeft()) 62 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 63 | assertFloatEqual(t, 10, rootChild0.LayoutGetWidth()) 64 | assertFloatEqual(t, 10, rootChild0.LayoutGetHeight()) 65 | 66 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 67 | 68 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 69 | assertFloatEqual(t, 0, root.LayoutGetTop()) 70 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 71 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 72 | 73 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 74 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 75 | assertFloatEqual(t, 10, rootChild0.LayoutGetWidth()) 76 | assertFloatEqual(t, 10, rootChild0.LayoutGetHeight()) 77 | } 78 | 79 | func TestAlign_self_flex_start(t *testing.T) { 80 | config := NewConfig() 81 | 82 | root := NewNodeWithConfig(config) 83 | root.StyleSetWidth(100) 84 | root.StyleSetHeight(100) 85 | 86 | rootChild0 := NewNodeWithConfig(config) 87 | rootChild0.StyleSetAlignSelf(AlignFlexStart) 88 | rootChild0.StyleSetWidth(10) 89 | rootChild0.StyleSetHeight(10) 90 | root.InsertChild(rootChild0, 0) 91 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 92 | 93 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 94 | assertFloatEqual(t, 0, root.LayoutGetTop()) 95 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 96 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 97 | 98 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 99 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 100 | assertFloatEqual(t, 10, rootChild0.LayoutGetWidth()) 101 | assertFloatEqual(t, 10, rootChild0.LayoutGetHeight()) 102 | 103 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 104 | 105 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 106 | assertFloatEqual(t, 0, root.LayoutGetTop()) 107 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 108 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 109 | 110 | assertFloatEqual(t, 90, rootChild0.LayoutGetLeft()) 111 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 112 | assertFloatEqual(t, 10, rootChild0.LayoutGetWidth()) 113 | assertFloatEqual(t, 10, rootChild0.LayoutGetHeight()) 114 | } 115 | 116 | func TestAlign_self_flex_end_override_flex_start(t *testing.T) { 117 | config := NewConfig() 118 | 119 | root := NewNodeWithConfig(config) 120 | root.StyleSetAlignItems(AlignFlexStart) 121 | root.StyleSetWidth(100) 122 | root.StyleSetHeight(100) 123 | 124 | rootChild0 := NewNodeWithConfig(config) 125 | rootChild0.StyleSetAlignSelf(AlignFlexEnd) 126 | rootChild0.StyleSetWidth(10) 127 | rootChild0.StyleSetHeight(10) 128 | root.InsertChild(rootChild0, 0) 129 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 130 | 131 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 132 | assertFloatEqual(t, 0, root.LayoutGetTop()) 133 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 134 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 135 | 136 | assertFloatEqual(t, 90, rootChild0.LayoutGetLeft()) 137 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 138 | assertFloatEqual(t, 10, rootChild0.LayoutGetWidth()) 139 | assertFloatEqual(t, 10, rootChild0.LayoutGetHeight()) 140 | 141 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 142 | 143 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 144 | assertFloatEqual(t, 0, root.LayoutGetTop()) 145 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 146 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 147 | 148 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 149 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 150 | assertFloatEqual(t, 10, rootChild0.LayoutGetWidth()) 151 | assertFloatEqual(t, 10, rootChild0.LayoutGetHeight()) 152 | } 153 | 154 | func TestAlign_self_baseline(t *testing.T) { 155 | config := NewConfig() 156 | 157 | root := NewNodeWithConfig(config) 158 | root.StyleSetFlexDirection(FlexDirectionRow) 159 | root.StyleSetWidth(100) 160 | root.StyleSetHeight(100) 161 | 162 | rootChild0 := NewNodeWithConfig(config) 163 | rootChild0.StyleSetAlignSelf(AlignBaseline) 164 | rootChild0.StyleSetWidth(50) 165 | rootChild0.StyleSetHeight(50) 166 | root.InsertChild(rootChild0, 0) 167 | 168 | rootChild1 := NewNodeWithConfig(config) 169 | rootChild1.StyleSetAlignSelf(AlignBaseline) 170 | rootChild1.StyleSetWidth(50) 171 | rootChild1.StyleSetHeight(20) 172 | root.InsertChild(rootChild1, 1) 173 | 174 | rootChild1child0 := NewNodeWithConfig(config) 175 | rootChild1child0.StyleSetWidth(50) 176 | rootChild1child0.StyleSetHeight(10) 177 | rootChild1.InsertChild(rootChild1child0, 0) 178 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 179 | 180 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 181 | assertFloatEqual(t, 0, root.LayoutGetTop()) 182 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 183 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 184 | 185 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 186 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 187 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 188 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 189 | 190 | assertFloatEqual(t, 50, rootChild1.LayoutGetLeft()) 191 | assertFloatEqual(t, 40, rootChild1.LayoutGetTop()) 192 | assertFloatEqual(t, 50, rootChild1.LayoutGetWidth()) 193 | assertFloatEqual(t, 20, rootChild1.LayoutGetHeight()) 194 | 195 | assertFloatEqual(t, 0, rootChild1child0.LayoutGetLeft()) 196 | assertFloatEqual(t, 0, rootChild1child0.LayoutGetTop()) 197 | assertFloatEqual(t, 50, rootChild1child0.LayoutGetWidth()) 198 | assertFloatEqual(t, 10, rootChild1child0.LayoutGetHeight()) 199 | 200 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 201 | 202 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 203 | assertFloatEqual(t, 0, root.LayoutGetTop()) 204 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 205 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 206 | 207 | assertFloatEqual(t, 50, rootChild0.LayoutGetLeft()) 208 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 209 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 210 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 211 | 212 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 213 | assertFloatEqual(t, 40, rootChild1.LayoutGetTop()) 214 | assertFloatEqual(t, 50, rootChild1.LayoutGetWidth()) 215 | assertFloatEqual(t, 20, rootChild1.LayoutGetHeight()) 216 | 217 | assertFloatEqual(t, 0, rootChild1child0.LayoutGetLeft()) 218 | assertFloatEqual(t, 0, rootChild1child0.LayoutGetTop()) 219 | assertFloatEqual(t, 50, rootChild1child0.LayoutGetWidth()) 220 | assertFloatEqual(t, 10, rootChild1child0.LayoutGetHeight()) 221 | } 222 | -------------------------------------------------------------------------------- /aspect_ratio_test.go: -------------------------------------------------------------------------------- 1 | package flex 2 | 3 | import "testing" 4 | 5 | func _measure(node *Node, width float32, widthMode MeasureMode, 6 | height float32, heightMode MeasureMode) Size { 7 | 8 | if widthMode != MeasureModeExactly { 9 | width = 50 10 | } 11 | if heightMode != MeasureModeExactly { 12 | height = 50 13 | } 14 | return Size{ 15 | Width: width, 16 | Height: height, 17 | } 18 | } 19 | 20 | func TestAspect_ratio_cross_defined(t *testing.T) { 21 | root := NewNode() 22 | root.StyleSetAlignItems(AlignFlexStart) 23 | root.StyleSetWidth(100) 24 | root.StyleSetHeight(100) 25 | 26 | rootChild0 := NewNode() 27 | rootChild0.StyleSetWidth(50) 28 | rootChild0.StyleSetAspectRatio(1) 29 | root.InsertChild(rootChild0, 0) 30 | 31 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 32 | 33 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 34 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 35 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 36 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 37 | } 38 | 39 | func TestAspect_ratio_main_defined(t *testing.T) { 40 | root := NewNode() 41 | root.StyleSetAlignItems(AlignFlexStart) 42 | root.StyleSetWidth(100) 43 | root.StyleSetHeight(100) 44 | 45 | rootChild0 := NewNode() 46 | rootChild0.StyleSetHeight(50) 47 | rootChild0.StyleSetAspectRatio(1) 48 | root.InsertChild(rootChild0, 0) 49 | 50 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 51 | 52 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 53 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 54 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 55 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 56 | } 57 | 58 | func TestAspect_ratio_both_dimensions_defined_row(t *testing.T) { 59 | root := NewNode() 60 | root.StyleSetFlexDirection(FlexDirectionRow) 61 | root.StyleSetAlignItems(AlignFlexStart) 62 | root.StyleSetWidth(100) 63 | root.StyleSetHeight(100) 64 | 65 | rootChild0 := NewNode() 66 | rootChild0.StyleSetWidth(100) 67 | rootChild0.StyleSetHeight(50) 68 | rootChild0.StyleSetAspectRatio(1) 69 | root.InsertChild(rootChild0, 0) 70 | 71 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 72 | 73 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 74 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 75 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 76 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 77 | } 78 | 79 | func TestAspect_ratio_both_dimensions_defined_column(t *testing.T) { 80 | root := NewNode() 81 | root.StyleSetAlignItems(AlignFlexStart) 82 | root.StyleSetWidth(100) 83 | root.StyleSetHeight(100) 84 | 85 | rootChild0 := NewNode() 86 | rootChild0.StyleSetWidth(100) 87 | rootChild0.StyleSetHeight(50) 88 | rootChild0.StyleSetAspectRatio(1) 89 | root.InsertChild(rootChild0, 0) 90 | 91 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 92 | 93 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 94 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 95 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 96 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 97 | } 98 | 99 | func TestAspect_ratio_align_stretch(t *testing.T) { 100 | root := NewNode() 101 | root.StyleSetWidth(100) 102 | root.StyleSetHeight(100) 103 | 104 | rootChild0 := NewNode() 105 | rootChild0.StyleSetAspectRatio(1) 106 | root.InsertChild(rootChild0, 0) 107 | 108 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 109 | 110 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 111 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 112 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 113 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 114 | } 115 | 116 | func TestAspect_ratio_flex_grow(t *testing.T) { 117 | root := NewNode() 118 | root.StyleSetAlignItems(AlignFlexStart) 119 | root.StyleSetWidth(100) 120 | root.StyleSetHeight(100) 121 | 122 | rootChild0 := NewNode() 123 | rootChild0.StyleSetHeight(50) 124 | rootChild0.StyleSetFlexGrow(1) 125 | rootChild0.StyleSetAspectRatio(1) 126 | root.InsertChild(rootChild0, 0) 127 | 128 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 129 | 130 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 131 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 132 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 133 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 134 | } 135 | 136 | func TestAspect_ratio_flex_shrink(t *testing.T) { 137 | root := NewNode() 138 | root.StyleSetAlignItems(AlignFlexStart) 139 | root.StyleSetWidth(100) 140 | root.StyleSetHeight(100) 141 | 142 | rootChild0 := NewNode() 143 | rootChild0.StyleSetHeight(150) 144 | rootChild0.StyleSetFlexShrink(1) 145 | rootChild0.StyleSetAspectRatio(1) 146 | root.InsertChild(rootChild0, 0) 147 | 148 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 149 | 150 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 151 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 152 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 153 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 154 | } 155 | 156 | func TestAspect_ratio_basis(t *testing.T) { 157 | root := NewNode() 158 | root.StyleSetAlignItems(AlignFlexStart) 159 | root.StyleSetWidth(100) 160 | root.StyleSetHeight(100) 161 | 162 | rootChild0 := NewNode() 163 | rootChild0.StyleSetFlexBasis(50) 164 | rootChild0.StyleSetAspectRatio(1) 165 | root.InsertChild(rootChild0, 0) 166 | 167 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 168 | 169 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 170 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 171 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 172 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 173 | } 174 | 175 | func TestAspect_ratio_absolute_layout_width_defined(t *testing.T) { 176 | root := NewNode() 177 | root.StyleSetWidth(100) 178 | root.StyleSetHeight(100) 179 | 180 | rootChild0 := NewNode() 181 | rootChild0.StyleSetPositionType(PositionTypeAbsolute) 182 | rootChild0.StyleSetPosition(EdgeLeft, 0) 183 | rootChild0.StyleSetPosition(EdgeTop, 0) 184 | rootChild0.StyleSetWidth(50) 185 | rootChild0.StyleSetAspectRatio(1) 186 | root.InsertChild(rootChild0, 0) 187 | 188 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 189 | 190 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 191 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 192 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 193 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 194 | } 195 | 196 | func TestAspect_ratio_absolute_layout_height_defined(t *testing.T) { 197 | root := NewNode() 198 | root.StyleSetWidth(100) 199 | root.StyleSetHeight(100) 200 | 201 | rootChild0 := NewNode() 202 | rootChild0.StyleSetPositionType(PositionTypeAbsolute) 203 | rootChild0.StyleSetPosition(EdgeLeft, 0) 204 | rootChild0.StyleSetPosition(EdgeTop, 0) 205 | rootChild0.StyleSetHeight(50) 206 | rootChild0.StyleSetAspectRatio(1) 207 | root.InsertChild(rootChild0, 0) 208 | 209 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 210 | 211 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 212 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 213 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 214 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 215 | } 216 | 217 | func TestAspect_ratio_with_max_cross_defined(t *testing.T) { 218 | root := NewNode() 219 | root.StyleSetAlignItems(AlignFlexStart) 220 | root.StyleSetWidth(100) 221 | root.StyleSetHeight(100) 222 | 223 | rootChild0 := NewNode() 224 | rootChild0.StyleSetHeight(50) 225 | rootChild0.StyleSetMaxWidth(40) 226 | rootChild0.StyleSetAspectRatio(1) 227 | root.InsertChild(rootChild0, 0) 228 | 229 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 230 | 231 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 232 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 233 | assertFloatEqual(t, 40, rootChild0.LayoutGetWidth()) 234 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 235 | } 236 | 237 | func TestAspect_ratio_with_max_main_defined(t *testing.T) { 238 | root := NewNode() 239 | root.StyleSetAlignItems(AlignFlexStart) 240 | root.StyleSetWidth(100) 241 | root.StyleSetHeight(100) 242 | 243 | rootChild0 := NewNode() 244 | rootChild0.StyleSetWidth(50) 245 | rootChild0.StyleSetMaxHeight(40) 246 | rootChild0.StyleSetAspectRatio(1) 247 | root.InsertChild(rootChild0, 0) 248 | 249 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 250 | 251 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 252 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 253 | assertFloatEqual(t, 40, rootChild0.LayoutGetWidth()) 254 | assertFloatEqual(t, 40, rootChild0.LayoutGetHeight()) 255 | } 256 | 257 | func TestAspect_ratio_with_min_cross_defined(t *testing.T) { 258 | root := NewNode() 259 | root.StyleSetAlignItems(AlignFlexStart) 260 | root.StyleSetWidth(100) 261 | root.StyleSetHeight(100) 262 | 263 | rootChild0 := NewNode() 264 | rootChild0.StyleSetHeight(30) 265 | rootChild0.StyleSetMinWidth(40) 266 | rootChild0.StyleSetAspectRatio(1) 267 | root.InsertChild(rootChild0, 0) 268 | 269 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 270 | 271 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 272 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 273 | assertFloatEqual(t, 40, rootChild0.LayoutGetWidth()) 274 | assertFloatEqual(t, 30, rootChild0.LayoutGetHeight()) 275 | } 276 | 277 | func TestAspect_ratio_with_min_main_defined(t *testing.T) { 278 | root := NewNode() 279 | root.StyleSetAlignItems(AlignFlexStart) 280 | root.StyleSetWidth(100) 281 | root.StyleSetHeight(100) 282 | 283 | rootChild0 := NewNode() 284 | rootChild0.StyleSetWidth(30) 285 | rootChild0.StyleSetMinHeight(40) 286 | rootChild0.StyleSetAspectRatio(1) 287 | root.InsertChild(rootChild0, 0) 288 | 289 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 290 | 291 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 292 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 293 | assertFloatEqual(t, 40, rootChild0.LayoutGetWidth()) 294 | assertFloatEqual(t, 40, rootChild0.LayoutGetHeight()) 295 | } 296 | 297 | func TestAspect_ratio_double_cross(t *testing.T) { 298 | root := NewNode() 299 | root.StyleSetAlignItems(AlignFlexStart) 300 | root.StyleSetWidth(100) 301 | root.StyleSetHeight(100) 302 | 303 | rootChild0 := NewNode() 304 | rootChild0.StyleSetHeight(50) 305 | rootChild0.StyleSetAspectRatio(2) 306 | root.InsertChild(rootChild0, 0) 307 | 308 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 309 | 310 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 311 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 312 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 313 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 314 | } 315 | 316 | func TestAspect_ratio_half_cross(t *testing.T) { 317 | root := NewNode() 318 | root.StyleSetAlignItems(AlignFlexStart) 319 | root.StyleSetWidth(100) 320 | root.StyleSetHeight(100) 321 | 322 | rootChild0 := NewNode() 323 | rootChild0.StyleSetHeight(100) 324 | rootChild0.StyleSetAspectRatio(0.5) 325 | root.InsertChild(rootChild0, 0) 326 | 327 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 328 | 329 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 330 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 331 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 332 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 333 | } 334 | 335 | func TestAspect_ratio_double_main(t *testing.T) { 336 | root := NewNode() 337 | root.StyleSetAlignItems(AlignFlexStart) 338 | root.StyleSetWidth(100) 339 | root.StyleSetHeight(100) 340 | 341 | rootChild0 := NewNode() 342 | rootChild0.StyleSetWidth(50) 343 | rootChild0.StyleSetAspectRatio(0.5) 344 | root.InsertChild(rootChild0, 0) 345 | 346 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 347 | 348 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 349 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 350 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 351 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 352 | } 353 | 354 | func TestAspect_ratio_half_main(t *testing.T) { 355 | root := NewNode() 356 | root.StyleSetAlignItems(AlignFlexStart) 357 | root.StyleSetWidth(100) 358 | root.StyleSetHeight(100) 359 | 360 | rootChild0 := NewNode() 361 | rootChild0.StyleSetWidth(100) 362 | rootChild0.StyleSetAspectRatio(2) 363 | root.InsertChild(rootChild0, 0) 364 | 365 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 366 | 367 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 368 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 369 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 370 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 371 | } 372 | 373 | func TestAspect_ratio_with_measure_func(t *testing.T) { 374 | root := NewNode() 375 | root.StyleSetAlignItems(AlignFlexStart) 376 | root.StyleSetWidth(100) 377 | root.StyleSetHeight(100) 378 | 379 | rootChild0 := NewNode() 380 | rootChild0.SetMeasureFunc(_measure) 381 | rootChild0.StyleSetAspectRatio(1) 382 | root.InsertChild(rootChild0, 0) 383 | 384 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 385 | 386 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 387 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 388 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 389 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 390 | } 391 | 392 | func TestAspect_ratio_width_height_flex_grow_row(t *testing.T) { 393 | root := NewNode() 394 | root.StyleSetFlexDirection(FlexDirectionRow) 395 | root.StyleSetAlignItems(AlignFlexStart) 396 | root.StyleSetWidth(100) 397 | root.StyleSetHeight(200) 398 | 399 | rootChild0 := NewNode() 400 | rootChild0.StyleSetWidth(50) 401 | rootChild0.StyleSetHeight(50) 402 | rootChild0.StyleSetFlexGrow(1) 403 | rootChild0.StyleSetAspectRatio(1) 404 | root.InsertChild(rootChild0, 0) 405 | 406 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 407 | 408 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 409 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 410 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 411 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 412 | } 413 | 414 | func TestAspect_ratio_width_height_flex_grow_column(t *testing.T) { 415 | root := NewNode() 416 | root.StyleSetAlignItems(AlignFlexStart) 417 | root.StyleSetWidth(200) 418 | root.StyleSetHeight(100) 419 | 420 | rootChild0 := NewNode() 421 | rootChild0.StyleSetWidth(50) 422 | rootChild0.StyleSetHeight(50) 423 | rootChild0.StyleSetFlexGrow(1) 424 | rootChild0.StyleSetAspectRatio(1) 425 | root.InsertChild(rootChild0, 0) 426 | 427 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 428 | 429 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 430 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 431 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 432 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 433 | } 434 | 435 | func TestAspect_ratio_height_as_flex_basis(t *testing.T) { 436 | root := NewNode() 437 | root.StyleSetAlignItems(AlignFlexStart) 438 | root.StyleSetFlexDirection(FlexDirectionRow) 439 | root.StyleSetWidth(200) 440 | root.StyleSetHeight(200) 441 | 442 | rootChild0 := NewNode() 443 | rootChild0.StyleSetHeight(50) 444 | rootChild0.StyleSetFlexGrow(1) 445 | rootChild0.StyleSetAspectRatio(1) 446 | root.InsertChild(rootChild0, 0) 447 | 448 | rootChild1 := NewNode() 449 | rootChild1.StyleSetHeight(100) 450 | rootChild1.StyleSetFlexGrow(1) 451 | rootChild1.StyleSetAspectRatio(1) 452 | root.InsertChild(rootChild1, 1) 453 | 454 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 455 | 456 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 457 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 458 | assertFloatEqual(t, 75, rootChild0.LayoutGetWidth()) 459 | assertFloatEqual(t, 75, rootChild0.LayoutGetHeight()) 460 | 461 | assertFloatEqual(t, 75, rootChild1.LayoutGetLeft()) 462 | assertFloatEqual(t, 0, rootChild1.LayoutGetTop()) 463 | assertFloatEqual(t, 125, rootChild1.LayoutGetWidth()) 464 | assertFloatEqual(t, 125, rootChild1.LayoutGetHeight()) 465 | } 466 | 467 | func TestAspect_ratio_width_as_flex_basis(t *testing.T) { 468 | root := NewNode() 469 | root.StyleSetAlignItems(AlignFlexStart) 470 | root.StyleSetWidth(200) 471 | root.StyleSetHeight(200) 472 | 473 | rootChild0 := NewNode() 474 | rootChild0.StyleSetWidth(50) 475 | rootChild0.StyleSetFlexGrow(1) 476 | rootChild0.StyleSetAspectRatio(1) 477 | root.InsertChild(rootChild0, 0) 478 | 479 | rootChild1 := NewNode() 480 | rootChild1.StyleSetWidth(100) 481 | rootChild1.StyleSetFlexGrow(1) 482 | rootChild1.StyleSetAspectRatio(1) 483 | root.InsertChild(rootChild1, 1) 484 | 485 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 486 | 487 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 488 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 489 | assertFloatEqual(t, 75, rootChild0.LayoutGetWidth()) 490 | assertFloatEqual(t, 75, rootChild0.LayoutGetHeight()) 491 | 492 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 493 | assertFloatEqual(t, 75, rootChild1.LayoutGetTop()) 494 | assertFloatEqual(t, 125, rootChild1.LayoutGetWidth()) 495 | assertFloatEqual(t, 125, rootChild1.LayoutGetHeight()) 496 | } 497 | 498 | func TestAspect_ratio_overrides_flex_grow_row(t *testing.T) { 499 | root := NewNode() 500 | root.StyleSetAlignItems(AlignFlexStart) 501 | root.StyleSetFlexDirection(FlexDirectionRow) 502 | root.StyleSetWidth(100) 503 | root.StyleSetHeight(100) 504 | 505 | rootChild0 := NewNode() 506 | rootChild0.StyleSetWidth(50) 507 | rootChild0.StyleSetFlexGrow(1) 508 | rootChild0.StyleSetAspectRatio(0.5) 509 | root.InsertChild(rootChild0, 0) 510 | 511 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 512 | 513 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 514 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 515 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 516 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 517 | } 518 | 519 | func TestAspect_ratio_overrides_flex_grow_column(t *testing.T) { 520 | root := NewNode() 521 | root.StyleSetAlignItems(AlignFlexStart) 522 | root.StyleSetWidth(100) 523 | root.StyleSetHeight(100) 524 | 525 | rootChild0 := NewNode() 526 | rootChild0.StyleSetHeight(50) 527 | rootChild0.StyleSetFlexGrow(1) 528 | rootChild0.StyleSetAspectRatio(2) 529 | root.InsertChild(rootChild0, 0) 530 | 531 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 532 | 533 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 534 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 535 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 536 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 537 | } 538 | 539 | func TestAspect_ratio_left_right_absolute(t *testing.T) { 540 | root := NewNode() 541 | root.StyleSetWidth(100) 542 | root.StyleSetHeight(100) 543 | 544 | rootChild0 := NewNode() 545 | rootChild0.StyleSetPositionType(PositionTypeAbsolute) 546 | rootChild0.StyleSetPosition(EdgeLeft, 10) 547 | rootChild0.StyleSetPosition(EdgeTop, 10) 548 | rootChild0.StyleSetPosition(EdgeRight, 10) 549 | rootChild0.StyleSetAspectRatio(1) 550 | root.InsertChild(rootChild0, 0) 551 | 552 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 553 | 554 | assertFloatEqual(t, 10, rootChild0.LayoutGetLeft()) 555 | assertFloatEqual(t, 10, rootChild0.LayoutGetTop()) 556 | assertFloatEqual(t, 80, rootChild0.LayoutGetWidth()) 557 | assertFloatEqual(t, 80, rootChild0.LayoutGetHeight()) 558 | } 559 | 560 | func TestAspect_ratio_top_bottom_absolute(t *testing.T) { 561 | root := NewNode() 562 | root.StyleSetWidth(100) 563 | root.StyleSetHeight(100) 564 | 565 | rootChild0 := NewNode() 566 | rootChild0.StyleSetPositionType(PositionTypeAbsolute) 567 | rootChild0.StyleSetPosition(EdgeLeft, 10) 568 | rootChild0.StyleSetPosition(EdgeTop, 10) 569 | rootChild0.StyleSetPosition(EdgeBottom, 10) 570 | rootChild0.StyleSetAspectRatio(1) 571 | root.InsertChild(rootChild0, 0) 572 | 573 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 574 | 575 | assertFloatEqual(t, 10, rootChild0.LayoutGetLeft()) 576 | assertFloatEqual(t, 10, rootChild0.LayoutGetTop()) 577 | assertFloatEqual(t, 80, rootChild0.LayoutGetWidth()) 578 | assertFloatEqual(t, 80, rootChild0.LayoutGetHeight()) 579 | } 580 | 581 | func TestAspect_ratio_width_overrides_align_stretch_row(t *testing.T) { 582 | root := NewNode() 583 | root.StyleSetFlexDirection(FlexDirectionRow) 584 | root.StyleSetWidth(100) 585 | root.StyleSetHeight(100) 586 | 587 | rootChild0 := NewNode() 588 | rootChild0.StyleSetWidth(50) 589 | rootChild0.StyleSetAspectRatio(1) 590 | root.InsertChild(rootChild0, 0) 591 | 592 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 593 | 594 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 595 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 596 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 597 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 598 | } 599 | 600 | func TestAspect_ratio_height_overrides_align_stretch_column(t *testing.T) { 601 | root := NewNode() 602 | root.StyleSetWidth(100) 603 | root.StyleSetHeight(100) 604 | 605 | rootChild0 := NewNode() 606 | rootChild0.StyleSetHeight(50) 607 | rootChild0.StyleSetAspectRatio(1) 608 | root.InsertChild(rootChild0, 0) 609 | 610 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 611 | 612 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 613 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 614 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 615 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 616 | } 617 | 618 | func TestAspect_ratio_allow_child_overflow_parent_size(t *testing.T) { 619 | root := NewNode() 620 | root.StyleSetAlignItems(AlignFlexStart) 621 | root.StyleSetWidth(100) 622 | 623 | rootChild0 := NewNode() 624 | rootChild0.StyleSetHeight(50) 625 | rootChild0.StyleSetAspectRatio(4) 626 | root.InsertChild(rootChild0, 0) 627 | 628 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 629 | 630 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 631 | assertFloatEqual(t, 50, root.LayoutGetHeight()) 632 | 633 | assertFloatEqual(t, 200, rootChild0.LayoutGetWidth()) 634 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 635 | } 636 | 637 | func TestAspect_ratio_defined_main_with_margin(t *testing.T) { 638 | root := NewNode() 639 | root.StyleSetAlignItems(AlignCenter) 640 | root.StyleSetJustifyContent(JustifyCenter) 641 | root.StyleSetWidth(100) 642 | root.StyleSetHeight(100) 643 | 644 | rootChild0 := NewNode() 645 | rootChild0.StyleSetHeight(50) 646 | rootChild0.StyleSetAspectRatio(1) 647 | rootChild0.StyleSetMargin(EdgeLeft, 10) 648 | rootChild0.StyleSetMargin(EdgeRight, 10) 649 | root.InsertChild(rootChild0, 0) 650 | 651 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 652 | 653 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 654 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 655 | 656 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 657 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 658 | } 659 | 660 | func TestAspect_ratio_defined_cross_with_margin(t *testing.T) { 661 | root := NewNode() 662 | root.StyleSetAlignItems(AlignCenter) 663 | root.StyleSetJustifyContent(JustifyCenter) 664 | root.StyleSetWidth(100) 665 | root.StyleSetHeight(100) 666 | 667 | rootChild0 := NewNode() 668 | rootChild0.StyleSetWidth(50) 669 | rootChild0.StyleSetAspectRatio(1) 670 | rootChild0.StyleSetMargin(EdgeLeft, 10) 671 | rootChild0.StyleSetMargin(EdgeRight, 10) 672 | root.InsertChild(rootChild0, 0) 673 | 674 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 675 | 676 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 677 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 678 | 679 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 680 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 681 | } 682 | -------------------------------------------------------------------------------- /baseline_func_test.go: -------------------------------------------------------------------------------- 1 | package flex 2 | 3 | import "testing" 4 | 5 | func baselineFunc(node *Node, width float32, height float32) float32 { 6 | baseline := node.Context.(float32) 7 | return baseline 8 | } 9 | 10 | func TestAlign_baseline_customer_func(t *testing.T) { 11 | root := NewNode() 12 | root.StyleSetFlexDirection(FlexDirectionRow) 13 | root.StyleSetAlignItems(AlignBaseline) 14 | root.StyleSetWidth(100) 15 | root.StyleSetHeight(100) 16 | 17 | rootChild0 := NewNode() 18 | rootChild0.StyleSetWidth(50) 19 | rootChild0.StyleSetHeight(50) 20 | root.InsertChild(rootChild0, 0) 21 | 22 | rootChild1 := NewNode() 23 | rootChild1.StyleSetWidth(50) 24 | rootChild1.StyleSetHeight(20) 25 | root.InsertChild(rootChild1, 1) 26 | 27 | var baselineValue float32 = 10 28 | rootChild1child0 := NewNode() 29 | rootChild1child0.Context = baselineValue 30 | rootChild1child0.StyleSetWidth(50) 31 | rootChild1child0.Baseline = baselineFunc 32 | rootChild1child0.StyleSetHeight(20) 33 | rootChild1.InsertChild(rootChild1child0, 0) 34 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 35 | 36 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 37 | assertFloatEqual(t, 0, root.LayoutGetTop()) 38 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 39 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 40 | 41 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 42 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 43 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 44 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 45 | 46 | assertFloatEqual(t, 50, rootChild1.LayoutGetLeft()) 47 | assertFloatEqual(t, 40, rootChild1.LayoutGetTop()) 48 | assertFloatEqual(t, 50, rootChild1.LayoutGetWidth()) 49 | assertFloatEqual(t, 20, rootChild1.LayoutGetHeight()) 50 | 51 | assertFloatEqual(t, 0, rootChild1child0.LayoutGetLeft()) 52 | assertFloatEqual(t, 0, rootChild1child0.LayoutGetTop()) 53 | assertFloatEqual(t, 50, rootChild1child0.LayoutGetWidth()) 54 | assertFloatEqual(t, 20, rootChild1child0.LayoutGetHeight()) 55 | } 56 | -------------------------------------------------------------------------------- /border_test.go: -------------------------------------------------------------------------------- 1 | package flex 2 | 3 | import "testing" 4 | 5 | func TestBorder_no_size(t *testing.T) { 6 | config := NewConfig() 7 | 8 | root := NewNodeWithConfig(config) 9 | root.StyleSetBorder(EdgeLeft, 10) 10 | root.StyleSetBorder(EdgeTop, 10) 11 | root.StyleSetBorder(EdgeRight, 10) 12 | root.StyleSetBorder(EdgeBottom, 10) 13 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 14 | 15 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 16 | assertFloatEqual(t, 0, root.LayoutGetTop()) 17 | assertFloatEqual(t, 20, root.LayoutGetWidth()) 18 | assertFloatEqual(t, 20, root.LayoutGetHeight()) 19 | 20 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 21 | 22 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 23 | assertFloatEqual(t, 0, root.LayoutGetTop()) 24 | assertFloatEqual(t, 20, root.LayoutGetWidth()) 25 | assertFloatEqual(t, 20, root.LayoutGetHeight()) 26 | } 27 | 28 | func TestBorder_container_match_child(t *testing.T) { 29 | config := NewConfig() 30 | 31 | root := NewNodeWithConfig(config) 32 | root.StyleSetBorder(EdgeLeft, 10) 33 | root.StyleSetBorder(EdgeTop, 10) 34 | root.StyleSetBorder(EdgeRight, 10) 35 | root.StyleSetBorder(EdgeBottom, 10) 36 | 37 | rootChild0 := NewNodeWithConfig(config) 38 | rootChild0.StyleSetWidth(10) 39 | rootChild0.StyleSetHeight(10) 40 | root.InsertChild(rootChild0, 0) 41 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 42 | 43 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 44 | assertFloatEqual(t, 0, root.LayoutGetTop()) 45 | assertFloatEqual(t, 30, root.LayoutGetWidth()) 46 | assertFloatEqual(t, 30, root.LayoutGetHeight()) 47 | 48 | assertFloatEqual(t, 10, rootChild0.LayoutGetLeft()) 49 | assertFloatEqual(t, 10, rootChild0.LayoutGetTop()) 50 | assertFloatEqual(t, 10, rootChild0.LayoutGetWidth()) 51 | assertFloatEqual(t, 10, rootChild0.LayoutGetHeight()) 52 | 53 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 54 | 55 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 56 | assertFloatEqual(t, 0, root.LayoutGetTop()) 57 | assertFloatEqual(t, 30, root.LayoutGetWidth()) 58 | assertFloatEqual(t, 30, root.LayoutGetHeight()) 59 | 60 | assertFloatEqual(t, 10, rootChild0.LayoutGetLeft()) 61 | assertFloatEqual(t, 10, rootChild0.LayoutGetTop()) 62 | assertFloatEqual(t, 10, rootChild0.LayoutGetWidth()) 63 | assertFloatEqual(t, 10, rootChild0.LayoutGetHeight()) 64 | } 65 | 66 | func TestBorder_flex_child(t *testing.T) { 67 | config := NewConfig() 68 | 69 | root := NewNodeWithConfig(config) 70 | root.StyleSetBorder(EdgeLeft, 10) 71 | root.StyleSetBorder(EdgeTop, 10) 72 | root.StyleSetBorder(EdgeRight, 10) 73 | root.StyleSetBorder(EdgeBottom, 10) 74 | root.StyleSetWidth(100) 75 | root.StyleSetHeight(100) 76 | 77 | rootChild0 := NewNodeWithConfig(config) 78 | rootChild0.StyleSetFlexGrow(1) 79 | rootChild0.StyleSetWidth(10) 80 | root.InsertChild(rootChild0, 0) 81 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 82 | 83 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 84 | assertFloatEqual(t, 0, root.LayoutGetTop()) 85 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 86 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 87 | 88 | assertFloatEqual(t, 10, rootChild0.LayoutGetLeft()) 89 | assertFloatEqual(t, 10, rootChild0.LayoutGetTop()) 90 | assertFloatEqual(t, 10, rootChild0.LayoutGetWidth()) 91 | assertFloatEqual(t, 80, rootChild0.LayoutGetHeight()) 92 | 93 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 94 | 95 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 96 | assertFloatEqual(t, 0, root.LayoutGetTop()) 97 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 98 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 99 | 100 | assertFloatEqual(t, 80, rootChild0.LayoutGetLeft()) 101 | assertFloatEqual(t, 10, rootChild0.LayoutGetTop()) 102 | assertFloatEqual(t, 10, rootChild0.LayoutGetWidth()) 103 | assertFloatEqual(t, 80, rootChild0.LayoutGetHeight()) 104 | } 105 | 106 | func TestBorder_stretch_child(t *testing.T) { 107 | config := NewConfig() 108 | 109 | root := NewNodeWithConfig(config) 110 | root.StyleSetBorder(EdgeLeft, 10) 111 | root.StyleSetBorder(EdgeTop, 10) 112 | root.StyleSetBorder(EdgeRight, 10) 113 | root.StyleSetBorder(EdgeBottom, 10) 114 | root.StyleSetWidth(100) 115 | root.StyleSetHeight(100) 116 | 117 | rootChild0 := NewNodeWithConfig(config) 118 | rootChild0.StyleSetHeight(10) 119 | root.InsertChild(rootChild0, 0) 120 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 121 | 122 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 123 | assertFloatEqual(t, 0, root.LayoutGetTop()) 124 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 125 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 126 | 127 | assertFloatEqual(t, 10, rootChild0.LayoutGetLeft()) 128 | assertFloatEqual(t, 10, rootChild0.LayoutGetTop()) 129 | assertFloatEqual(t, 80, rootChild0.LayoutGetWidth()) 130 | assertFloatEqual(t, 10, rootChild0.LayoutGetHeight()) 131 | 132 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 133 | 134 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 135 | assertFloatEqual(t, 0, root.LayoutGetTop()) 136 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 137 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 138 | 139 | assertFloatEqual(t, 10, rootChild0.LayoutGetLeft()) 140 | assertFloatEqual(t, 10, rootChild0.LayoutGetTop()) 141 | assertFloatEqual(t, 80, rootChild0.LayoutGetWidth()) 142 | assertFloatEqual(t, 10, rootChild0.LayoutGetHeight()) 143 | } 144 | 145 | func TestBorder_center_child(t *testing.T) { 146 | config := NewConfig() 147 | 148 | root := NewNodeWithConfig(config) 149 | root.StyleSetJustifyContent(JustifyCenter) 150 | root.StyleSetAlignItems(AlignCenter) 151 | root.StyleSetBorder(EdgeStart, 10) 152 | root.StyleSetBorder(EdgeEnd, 20) 153 | root.StyleSetBorder(EdgeBottom, 20) 154 | root.StyleSetWidth(100) 155 | root.StyleSetHeight(100) 156 | 157 | rootChild0 := NewNodeWithConfig(config) 158 | rootChild0.StyleSetWidth(10) 159 | rootChild0.StyleSetHeight(10) 160 | root.InsertChild(rootChild0, 0) 161 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 162 | 163 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 164 | assertFloatEqual(t, 0, root.LayoutGetTop()) 165 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 166 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 167 | 168 | assertFloatEqual(t, 40, rootChild0.LayoutGetLeft()) 169 | assertFloatEqual(t, 35, rootChild0.LayoutGetTop()) 170 | assertFloatEqual(t, 10, rootChild0.LayoutGetWidth()) 171 | assertFloatEqual(t, 10, rootChild0.LayoutGetHeight()) 172 | 173 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 174 | 175 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 176 | assertFloatEqual(t, 0, root.LayoutGetTop()) 177 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 178 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 179 | 180 | assertFloatEqual(t, 50, rootChild0.LayoutGetLeft()) 181 | assertFloatEqual(t, 35, rootChild0.LayoutGetTop()) 182 | assertFloatEqual(t, 10, rootChild0.LayoutGetWidth()) 183 | assertFloatEqual(t, 10, rootChild0.LayoutGetHeight()) 184 | } 185 | -------------------------------------------------------------------------------- /compute_margin_test.go: -------------------------------------------------------------------------------- 1 | package flex 2 | 3 | import "testing" 4 | 5 | func TestComputed_layout_margin(t *testing.T) { 6 | root := NewNode() 7 | root.StyleSetWidth(100) 8 | root.StyleSetHeight(100) 9 | root.StyleSetMarginPercent(EdgeStart, 10) 10 | 11 | CalculateLayout(root, 100, 100, DirectionLTR) 12 | 13 | assertFloatEqual(t, 10, root.LayoutGetMargin(EdgeLeft)) 14 | assertFloatEqual(t, 0, root.LayoutGetMargin(EdgeRight)) 15 | 16 | CalculateLayout(root, 100, 100, DirectionRTL) 17 | 18 | assertFloatEqual(t, 0, root.LayoutGetMargin(EdgeLeft)) 19 | assertFloatEqual(t, 10, root.LayoutGetMargin(EdgeRight)) 20 | } 21 | -------------------------------------------------------------------------------- /compute_padding_test.go: -------------------------------------------------------------------------------- 1 | package flex 2 | 3 | import "testing" 4 | 5 | func TestComputed_layout_padding(t *testing.T) { 6 | root := NewNode() 7 | root.StyleSetWidth(100) 8 | root.StyleSetHeight(100) 9 | root.StyleSetPaddingPercent(EdgeStart, 10) 10 | 11 | CalculateLayout(root, 100, 100, DirectionLTR) 12 | 13 | assertFloatEqual(t, 10, root.LayoutGetPadding(EdgeLeft)) 14 | assertFloatEqual(t, 0, root.LayoutGetPadding(EdgeRight)) 15 | 16 | CalculateLayout(root, 100, 100, DirectionRTL) 17 | 18 | assertFloatEqual(t, 0, root.LayoutGetPadding(EdgeLeft)) 19 | assertFloatEqual(t, 10, root.LayoutGetPadding(EdgeRight)) 20 | } 21 | -------------------------------------------------------------------------------- /default_values_test.go: -------------------------------------------------------------------------------- 1 | package flex 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestAssert_default_values(t *testing.T) { 10 | root := NewNode() 11 | 12 | assert.Equal(t, 0, len(root.Children)) 13 | var nilNode *Node 14 | assert.Equal(t, nilNode, root.GetChild(1)) 15 | assert.Equal(t, nilNode, root.GetChild(0)) 16 | 17 | assert.Equal(t, DirectionInherit, root.Style.Direction) 18 | assert.Equal(t, FlexDirectionColumn, root.Style.FlexDirection) 19 | assert.Equal(t, JustifyFlexStart, root.Style.JustifyContent) 20 | assert.Equal(t, AlignFlexStart, root.Style.AlignContent) 21 | assert.Equal(t, AlignStretch, root.Style.AlignItems) 22 | assert.Equal(t, AlignAuto, root.Style.AlignSelf) 23 | assert.Equal(t, PositionTypeRelative, root.Style.PositionType) 24 | assert.Equal(t, WrapNoWrap, root.Style.FlexWrap) 25 | assert.Equal(t, OverflowVisible, root.Style.Overflow) 26 | assertFloatEqual(t, 0, root.StyleGetFlexGrow()) 27 | assertFloatEqual(t, 0, root.StyleGetFlexShrink()) 28 | assert.Equal(t, root.Style.FlexBasis.Unit, UnitAuto) 29 | 30 | assert.Equal(t, root.StyleGetPosition(EdgeLeft).Unit, UnitUndefined) 31 | assert.Equal(t, root.StyleGetPosition(EdgeTop).Unit, UnitUndefined) 32 | assert.Equal(t, root.StyleGetPosition(EdgeRight).Unit, UnitUndefined) 33 | assert.Equal(t, root.StyleGetPosition(EdgeBottom).Unit, UnitUndefined) 34 | assert.Equal(t, root.StyleGetPosition(EdgeStart).Unit, UnitUndefined) 35 | assert.Equal(t, root.StyleGetPosition(EdgeEnd).Unit, UnitUndefined) 36 | 37 | assert.Equal(t, root.StyleGetMargin(EdgeLeft).Unit, UnitUndefined) 38 | assert.Equal(t, root.StyleGetMargin(EdgeTop).Unit, UnitUndefined) 39 | assert.Equal(t, root.StyleGetMargin(EdgeRight).Unit, UnitUndefined) 40 | assert.Equal(t, root.StyleGetMargin(EdgeBottom).Unit, UnitUndefined) 41 | assert.Equal(t, root.StyleGetMargin(EdgeStart).Unit, UnitUndefined) 42 | assert.Equal(t, root.StyleGetMargin(EdgeEnd).Unit, UnitUndefined) 43 | 44 | assert.Equal(t, root.StyleGetPadding(EdgeLeft).Unit, UnitUndefined) 45 | assert.Equal(t, root.StyleGetPadding(EdgeTop).Unit, UnitUndefined) 46 | assert.Equal(t, root.StyleGetPadding(EdgeRight).Unit, UnitUndefined) 47 | assert.Equal(t, root.StyleGetPadding(EdgeBottom).Unit, UnitUndefined) 48 | assert.Equal(t, root.StyleGetPadding(EdgeStart).Unit, UnitUndefined) 49 | assert.Equal(t, root.StyleGetPadding(EdgeEnd).Unit, UnitUndefined) 50 | 51 | assert.True(t, FloatIsUndefined(root.StyleGetBorder(EdgeLeft))) 52 | assert.True(t, FloatIsUndefined(root.StyleGetBorder(EdgeTop))) 53 | assert.True(t, FloatIsUndefined(root.StyleGetBorder(EdgeRight))) 54 | assert.True(t, FloatIsUndefined(root.StyleGetBorder(EdgeBottom))) 55 | assert.True(t, FloatIsUndefined(root.StyleGetBorder(EdgeStart))) 56 | assert.True(t, FloatIsUndefined(root.StyleGetBorder(EdgeEnd))) 57 | 58 | assert.Equal(t, root.StyleGetWidth().Unit, UnitAuto) 59 | assert.Equal(t, root.StyleGetHeight().Unit, UnitAuto) 60 | assert.Equal(t, root.StyleGetMinWidth().Unit, UnitUndefined) 61 | assert.Equal(t, root.StyleGetMinHeight().Unit, UnitUndefined) 62 | assert.Equal(t, root.StyleGetMaxWidth().Unit, UnitUndefined) 63 | assert.Equal(t, root.StyleGetMaxHeight().Unit, UnitUndefined) 64 | 65 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 66 | assertFloatEqual(t, 0, root.LayoutGetTop()) 67 | assertFloatEqual(t, 0, root.LayoutGetRight()) 68 | assertFloatEqual(t, 0, root.LayoutGetBottom()) 69 | 70 | assertFloatEqual(t, 0, root.LayoutGetMargin(EdgeLeft)) 71 | assertFloatEqual(t, 0, root.LayoutGetMargin(EdgeTop)) 72 | assertFloatEqual(t, 0, root.LayoutGetMargin(EdgeRight)) 73 | assertFloatEqual(t, 0, root.LayoutGetMargin(EdgeBottom)) 74 | 75 | assertFloatEqual(t, 0, root.LayoutGetPadding(EdgeLeft)) 76 | assertFloatEqual(t, 0, root.LayoutGetPadding(EdgeTop)) 77 | assertFloatEqual(t, 0, root.LayoutGetPadding(EdgeRight)) 78 | assertFloatEqual(t, 0, root.LayoutGetPadding(EdgeBottom)) 79 | 80 | assertFloatEqual(t, 0, root.LayoutGetBorder(EdgeLeft)) 81 | assertFloatEqual(t, 0, root.LayoutGetBorder(EdgeTop)) 82 | assertFloatEqual(t, 0, root.LayoutGetBorder(EdgeRight)) 83 | assertFloatEqual(t, 0, root.LayoutGetBorder(EdgeBottom)) 84 | 85 | assert.True(t, FloatIsUndefined(root.LayoutGetWidth())) 86 | assert.True(t, FloatIsUndefined(root.LayoutGetHeight())) 87 | assert.Equal(t, DirectionInherit, root.Layout.Direction) 88 | 89 | } 90 | 91 | func TestAssert_webdefault_values(t *testing.T) { 92 | config := NewConfig() 93 | config.UseWebDefaults = true 94 | root := NewNodeWithConfig(config) 95 | 96 | assert.Equal(t, FlexDirectionRow, root.Style.FlexDirection) 97 | assert.Equal(t, AlignStretch, root.Style.AlignContent) 98 | assertFloatEqual(t, 1, root.StyleGetFlexShrink()) 99 | 100 | } 101 | 102 | func TestAssert_webdefault_values_reset(t *testing.T) { 103 | config := NewConfig() 104 | config.UseWebDefaults = true 105 | root := NewNodeWithConfig(config) 106 | root.Reset() 107 | 108 | assert.Equal(t, FlexDirectionRow, root.Style.FlexDirection) 109 | assert.Equal(t, AlignStretch, root.Style.AlignContent) 110 | assertFloatEqual(t, 1, root.StyleGetFlexShrink()) 111 | 112 | } 113 | -------------------------------------------------------------------------------- /dimension_test.go: -------------------------------------------------------------------------------- 1 | package flex 2 | 3 | import "testing" 4 | 5 | func TestWrap_child(t *testing.T) { 6 | config := NewConfig() 7 | root := NewNodeWithConfig(config) 8 | 9 | rootChild0 := NewNodeWithConfig(config) 10 | rootChild0.StyleSetWidth(100) 11 | rootChild0.StyleSetHeight(100) 12 | root.InsertChild(rootChild0, 0) 13 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 14 | 15 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 16 | assertFloatEqual(t, 0, root.LayoutGetTop()) 17 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 18 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 19 | 20 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 21 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 22 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 23 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 24 | 25 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 26 | 27 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 28 | assertFloatEqual(t, 0, root.LayoutGetTop()) 29 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 30 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 31 | 32 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 33 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 34 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 35 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 36 | } 37 | 38 | func TestWrap_grandchild(t *testing.T) { 39 | config := NewConfig() 40 | 41 | root := NewNodeWithConfig(config) 42 | 43 | rootChild0 := NewNodeWithConfig(config) 44 | root.InsertChild(rootChild0, 0) 45 | 46 | rootChild0Child0 := NewNodeWithConfig(config) 47 | rootChild0Child0.StyleSetWidth(100) 48 | rootChild0Child0.StyleSetHeight(100) 49 | rootChild0.InsertChild(rootChild0Child0, 0) 50 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 51 | 52 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 53 | assertFloatEqual(t, 0, root.LayoutGetTop()) 54 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 55 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 56 | 57 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 58 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 59 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 60 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 61 | 62 | assertFloatEqual(t, 0, rootChild0Child0.LayoutGetLeft()) 63 | assertFloatEqual(t, 0, rootChild0Child0.LayoutGetTop()) 64 | assertFloatEqual(t, 100, rootChild0Child0.LayoutGetWidth()) 65 | assertFloatEqual(t, 100, rootChild0Child0.LayoutGetHeight()) 66 | 67 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 68 | 69 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 70 | assertFloatEqual(t, 0, root.LayoutGetTop()) 71 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 72 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 73 | 74 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 75 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 76 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 77 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 78 | 79 | assertFloatEqual(t, 0, rootChild0Child0.LayoutGetLeft()) 80 | assertFloatEqual(t, 0, rootChild0Child0.LayoutGetTop()) 81 | assertFloatEqual(t, 100, rootChild0Child0.LayoutGetWidth()) 82 | assertFloatEqual(t, 100, rootChild0Child0.LayoutGetHeight()) 83 | } 84 | -------------------------------------------------------------------------------- /dirty_marking_test.go: -------------------------------------------------------------------------------- 1 | package flex 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestDirty_propagation(t *testing.T) { 10 | root := NewNode() 11 | root.StyleSetAlignItems(AlignFlexStart) 12 | root.StyleSetWidth(100) 13 | root.StyleSetHeight(100) 14 | 15 | rootChild0 := NewNode() 16 | rootChild0.StyleSetWidth(50) 17 | rootChild0.StyleSetHeight(20) 18 | root.InsertChild(rootChild0, 0) 19 | 20 | rootChild1 := NewNode() 21 | rootChild1.StyleSetWidth(50) 22 | rootChild1.StyleSetHeight(20) 23 | root.InsertChild(rootChild1, 1) 24 | 25 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 26 | 27 | rootChild0.StyleSetWidth(20) 28 | 29 | assert.True(t, rootChild0.IsDirty) 30 | assert.False(t, rootChild1.IsDirty) 31 | assert.True(t, root.IsDirty) 32 | 33 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 34 | 35 | assert.False(t, rootChild0.IsDirty) 36 | assert.False(t, rootChild1.IsDirty) 37 | assert.False(t, root.IsDirty) 38 | 39 | } 40 | 41 | func TestDirty_propagation_only_if_prop_changed(t *testing.T) { 42 | root := NewNode() 43 | root.StyleSetAlignItems(AlignFlexStart) 44 | root.StyleSetWidth(100) 45 | root.StyleSetHeight(100) 46 | 47 | rootChild0 := NewNode() 48 | rootChild0.StyleSetWidth(50) 49 | rootChild0.StyleSetHeight(20) 50 | root.InsertChild(rootChild0, 0) 51 | 52 | rootChild1 := NewNode() 53 | rootChild1.StyleSetWidth(50) 54 | rootChild1.StyleSetHeight(20) 55 | root.InsertChild(rootChild1, 1) 56 | 57 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 58 | 59 | rootChild0.StyleSetWidth(50) 60 | 61 | assert.False(t, rootChild0.IsDirty) 62 | assert.False(t, rootChild1.IsDirty) 63 | assert.False(t, root.IsDirty) 64 | 65 | } 66 | 67 | func TestDirty_mark_all_children_as_dirty_when_display_changes(t *testing.T) { 68 | root := NewNode() 69 | root.StyleSetFlexDirection(FlexDirectionRow) 70 | root.StyleSetHeight(100) 71 | 72 | child0 := NewNode() 73 | child0.StyleSetFlexGrow(1) 74 | child1 := NewNode() 75 | child1.StyleSetFlexGrow(1) 76 | 77 | child1Child0 := NewNode() 78 | child1Child0Child0 := NewNode() 79 | child1Child0Child0.StyleSetWidth(8) 80 | child1Child0Child0.StyleSetHeight(16) 81 | 82 | child1Child0.InsertChild(child1Child0Child0, 0) 83 | 84 | child1.InsertChild(child1Child0, 0) 85 | root.InsertChild(child0, 0) 86 | root.InsertChild(child1, 0) 87 | 88 | child0.StyleSetDisplay(DisplayFlex) 89 | child1.StyleSetDisplay(DisplayNone) 90 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 91 | assertFloatEqual(t, 0, child1Child0Child0.LayoutGetWidth()) 92 | assertFloatEqual(t, 0, child1Child0Child0.LayoutGetHeight()) 93 | 94 | child0.StyleSetDisplay(DisplayNone) 95 | child1.StyleSetDisplay(DisplayFlex) 96 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 97 | assertFloatEqual(t, 8, child1Child0Child0.LayoutGetWidth()) 98 | assertFloatEqual(t, 16, child1Child0Child0.LayoutGetHeight()) 99 | 100 | child0.StyleSetDisplay(DisplayFlex) 101 | child1.StyleSetDisplay(DisplayNone) 102 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 103 | assertFloatEqual(t, 0, child1Child0Child0.LayoutGetWidth()) 104 | assertFloatEqual(t, 0, child1Child0Child0.LayoutGetHeight()) 105 | 106 | child0.StyleSetDisplay(DisplayNone) 107 | child1.StyleSetDisplay(DisplayFlex) 108 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 109 | assertFloatEqual(t, 8, child1Child0Child0.LayoutGetWidth()) 110 | assertFloatEqual(t, 16, child1Child0Child0.LayoutGetHeight()) 111 | } 112 | 113 | func TestDirty_node_only_if_children_are_actually_removed(t *testing.T) { 114 | root := NewNode() 115 | root.StyleSetAlignItems(AlignFlexStart) 116 | root.StyleSetWidth(50) 117 | root.StyleSetHeight(50) 118 | 119 | child0 := NewNode() 120 | child0.StyleSetWidth(50) 121 | child0.StyleSetHeight(25) 122 | root.InsertChild(child0, 0) 123 | 124 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 125 | 126 | child1 := NewNode() 127 | root.RemoveChild(child1) 128 | assert.False(t, root.IsDirty) 129 | 130 | root.RemoveChild(child0) 131 | assert.True(t, root.IsDirty) 132 | } 133 | -------------------------------------------------------------------------------- /display_test.go: -------------------------------------------------------------------------------- 1 | package flex 2 | 3 | import "testing" 4 | 5 | func TestDisplay_none(t *testing.T) { 6 | config := NewConfig() 7 | 8 | root := NewNodeWithConfig(config) 9 | root.StyleSetFlexDirection(FlexDirectionRow) 10 | root.StyleSetWidth(100) 11 | root.StyleSetHeight(100) 12 | 13 | rootChild0 := NewNodeWithConfig(config) 14 | rootChild0.StyleSetFlexGrow(1) 15 | root.InsertChild(rootChild0, 0) 16 | 17 | rootChild1 := NewNodeWithConfig(config) 18 | rootChild1.StyleSetFlexGrow(1) 19 | rootChild1.StyleSetDisplay(DisplayNone) 20 | root.InsertChild(rootChild1, 1) 21 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 22 | 23 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 24 | assertFloatEqual(t, 0, root.LayoutGetTop()) 25 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 26 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 27 | 28 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 29 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 30 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 31 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 32 | 33 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 34 | assertFloatEqual(t, 0, rootChild1.LayoutGetTop()) 35 | assertFloatEqual(t, 0, rootChild1.LayoutGetWidth()) 36 | assertFloatEqual(t, 0, rootChild1.LayoutGetHeight()) 37 | 38 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 39 | 40 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 41 | assertFloatEqual(t, 0, root.LayoutGetTop()) 42 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 43 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 44 | 45 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 46 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 47 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 48 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 49 | 50 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 51 | assertFloatEqual(t, 0, rootChild1.LayoutGetTop()) 52 | assertFloatEqual(t, 0, rootChild1.LayoutGetWidth()) 53 | assertFloatEqual(t, 0, rootChild1.LayoutGetHeight()) 54 | } 55 | 56 | func TestDisplay_none_fixed_size(t *testing.T) { 57 | config := NewConfig() 58 | 59 | root := NewNodeWithConfig(config) 60 | root.StyleSetFlexDirection(FlexDirectionRow) 61 | root.StyleSetWidth(100) 62 | root.StyleSetHeight(100) 63 | 64 | rootChild0 := NewNodeWithConfig(config) 65 | rootChild0.StyleSetFlexGrow(1) 66 | root.InsertChild(rootChild0, 0) 67 | 68 | rootChild1 := NewNodeWithConfig(config) 69 | rootChild1.StyleSetWidth(20) 70 | rootChild1.StyleSetHeight(20) 71 | rootChild1.StyleSetDisplay(DisplayNone) 72 | root.InsertChild(rootChild1, 1) 73 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 74 | 75 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 76 | assertFloatEqual(t, 0, root.LayoutGetTop()) 77 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 78 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 79 | 80 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 81 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 82 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 83 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 84 | 85 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 86 | assertFloatEqual(t, 0, rootChild1.LayoutGetTop()) 87 | assertFloatEqual(t, 0, rootChild1.LayoutGetWidth()) 88 | assertFloatEqual(t, 0, rootChild1.LayoutGetHeight()) 89 | 90 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 91 | 92 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 93 | assertFloatEqual(t, 0, root.LayoutGetTop()) 94 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 95 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 96 | 97 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 98 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 99 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 100 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 101 | 102 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 103 | assertFloatEqual(t, 0, rootChild1.LayoutGetTop()) 104 | assertFloatEqual(t, 0, rootChild1.LayoutGetWidth()) 105 | assertFloatEqual(t, 0, rootChild1.LayoutGetHeight()) 106 | } 107 | 108 | func TestDisplay_none_with_margin(t *testing.T) { 109 | config := NewConfig() 110 | 111 | root := NewNodeWithConfig(config) 112 | root.StyleSetFlexDirection(FlexDirectionRow) 113 | root.StyleSetWidth(100) 114 | root.StyleSetHeight(100) 115 | 116 | rootChild0 := NewNodeWithConfig(config) 117 | rootChild0.StyleSetMargin(EdgeLeft, 10) 118 | rootChild0.StyleSetMargin(EdgeTop, 10) 119 | rootChild0.StyleSetMargin(EdgeRight, 10) 120 | rootChild0.StyleSetMargin(EdgeBottom, 10) 121 | rootChild0.StyleSetWidth(20) 122 | rootChild0.StyleSetHeight(20) 123 | rootChild0.StyleSetDisplay(DisplayNone) 124 | root.InsertChild(rootChild0, 0) 125 | 126 | rootChild1 := NewNodeWithConfig(config) 127 | rootChild1.StyleSetFlexGrow(1) 128 | root.InsertChild(rootChild1, 1) 129 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 130 | 131 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 132 | assertFloatEqual(t, 0, root.LayoutGetTop()) 133 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 134 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 135 | 136 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 137 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 138 | assertFloatEqual(t, 0, rootChild0.LayoutGetWidth()) 139 | assertFloatEqual(t, 0, rootChild0.LayoutGetHeight()) 140 | 141 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 142 | assertFloatEqual(t, 0, rootChild1.LayoutGetTop()) 143 | assertFloatEqual(t, 100, rootChild1.LayoutGetWidth()) 144 | assertFloatEqual(t, 100, rootChild1.LayoutGetHeight()) 145 | 146 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 147 | 148 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 149 | assertFloatEqual(t, 0, root.LayoutGetTop()) 150 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 151 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 152 | 153 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 154 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 155 | assertFloatEqual(t, 0, rootChild0.LayoutGetWidth()) 156 | assertFloatEqual(t, 0, rootChild0.LayoutGetHeight()) 157 | 158 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 159 | assertFloatEqual(t, 0, rootChild1.LayoutGetTop()) 160 | assertFloatEqual(t, 100, rootChild1.LayoutGetWidth()) 161 | assertFloatEqual(t, 100, rootChild1.LayoutGetHeight()) 162 | } 163 | 164 | func TestDisplay_none_with_child(t *testing.T) { 165 | config := NewConfig() 166 | 167 | root := NewNodeWithConfig(config) 168 | root.StyleSetFlexDirection(FlexDirectionRow) 169 | root.StyleSetWidth(100) 170 | root.StyleSetHeight(100) 171 | 172 | rootChild0 := NewNodeWithConfig(config) 173 | rootChild0.StyleSetFlexGrow(1) 174 | rootChild0.StyleSetFlexShrink(1) 175 | rootChild0.StyleSetFlexBasisPercent(0) 176 | root.InsertChild(rootChild0, 0) 177 | 178 | rootChild1 := NewNodeWithConfig(config) 179 | rootChild1.StyleSetFlexGrow(1) 180 | rootChild1.StyleSetFlexShrink(1) 181 | rootChild1.StyleSetFlexBasisPercent(0) 182 | rootChild1.StyleSetDisplay(DisplayNone) 183 | root.InsertChild(rootChild1, 1) 184 | 185 | rootChild1child0 := NewNodeWithConfig(config) 186 | rootChild1child0.StyleSetFlexGrow(1) 187 | rootChild1child0.StyleSetFlexShrink(1) 188 | rootChild1child0.StyleSetFlexBasisPercent(0) 189 | rootChild1child0.StyleSetWidth(20) 190 | rootChild1child0.StyleSetMinWidth(0) 191 | rootChild1child0.StyleSetMinHeight(0) 192 | rootChild1.InsertChild(rootChild1child0, 0) 193 | 194 | rootChild2 := NewNodeWithConfig(config) 195 | rootChild2.StyleSetFlexGrow(1) 196 | rootChild2.StyleSetFlexShrink(1) 197 | rootChild2.StyleSetFlexBasisPercent(0) 198 | root.InsertChild(rootChild2, 2) 199 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 200 | 201 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 202 | assertFloatEqual(t, 0, root.LayoutGetTop()) 203 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 204 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 205 | 206 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 207 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 208 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 209 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 210 | 211 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 212 | assertFloatEqual(t, 0, rootChild1.LayoutGetTop()) 213 | assertFloatEqual(t, 0, rootChild1.LayoutGetWidth()) 214 | assertFloatEqual(t, 0, rootChild1.LayoutGetHeight()) 215 | 216 | assertFloatEqual(t, 0, rootChild1child0.LayoutGetLeft()) 217 | assertFloatEqual(t, 0, rootChild1child0.LayoutGetTop()) 218 | assertFloatEqual(t, 0, rootChild1child0.LayoutGetWidth()) 219 | assertFloatEqual(t, 0, rootChild1child0.LayoutGetHeight()) 220 | 221 | assertFloatEqual(t, 50, rootChild2.LayoutGetLeft()) 222 | assertFloatEqual(t, 0, rootChild2.LayoutGetTop()) 223 | assertFloatEqual(t, 50, rootChild2.LayoutGetWidth()) 224 | assertFloatEqual(t, 100, rootChild2.LayoutGetHeight()) 225 | 226 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 227 | 228 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 229 | assertFloatEqual(t, 0, root.LayoutGetTop()) 230 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 231 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 232 | 233 | assertFloatEqual(t, 50, rootChild0.LayoutGetLeft()) 234 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 235 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 236 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 237 | 238 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 239 | assertFloatEqual(t, 0, rootChild1.LayoutGetTop()) 240 | assertFloatEqual(t, 0, rootChild1.LayoutGetWidth()) 241 | assertFloatEqual(t, 0, rootChild1.LayoutGetHeight()) 242 | 243 | assertFloatEqual(t, 0, rootChild1child0.LayoutGetLeft()) 244 | assertFloatEqual(t, 0, rootChild1child0.LayoutGetTop()) 245 | assertFloatEqual(t, 0, rootChild1child0.LayoutGetWidth()) 246 | assertFloatEqual(t, 0, rootChild1child0.LayoutGetHeight()) 247 | 248 | assertFloatEqual(t, 0, rootChild2.LayoutGetLeft()) 249 | assertFloatEqual(t, 0, rootChild2.LayoutGetTop()) 250 | assertFloatEqual(t, 50, rootChild2.LayoutGetWidth()) 251 | assertFloatEqual(t, 100, rootChild2.LayoutGetHeight()) 252 | } 253 | 254 | func TestDisplay_none_with_position(t *testing.T) { 255 | config := NewConfig() 256 | 257 | root := NewNodeWithConfig(config) 258 | root.StyleSetFlexDirection(FlexDirectionRow) 259 | root.StyleSetWidth(100) 260 | root.StyleSetHeight(100) 261 | 262 | rootChild0 := NewNodeWithConfig(config) 263 | rootChild0.StyleSetFlexGrow(1) 264 | root.InsertChild(rootChild0, 0) 265 | 266 | rootChild1 := NewNodeWithConfig(config) 267 | rootChild1.StyleSetFlexGrow(1) 268 | rootChild1.StyleSetPosition(EdgeTop, 10) 269 | rootChild1.StyleSetDisplay(DisplayNone) 270 | root.InsertChild(rootChild1, 1) 271 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 272 | 273 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 274 | assertFloatEqual(t, 0, root.LayoutGetTop()) 275 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 276 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 277 | 278 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 279 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 280 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 281 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 282 | 283 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 284 | assertFloatEqual(t, 0, rootChild1.LayoutGetTop()) 285 | assertFloatEqual(t, 0, rootChild1.LayoutGetWidth()) 286 | assertFloatEqual(t, 0, rootChild1.LayoutGetHeight()) 287 | 288 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 289 | 290 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 291 | assertFloatEqual(t, 0, root.LayoutGetTop()) 292 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 293 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 294 | 295 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 296 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 297 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 298 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 299 | 300 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 301 | assertFloatEqual(t, 0, rootChild1.LayoutGetTop()) 302 | assertFloatEqual(t, 0, rootChild1.LayoutGetWidth()) 303 | assertFloatEqual(t, 0, rootChild1.LayoutGetHeight()) 304 | } 305 | -------------------------------------------------------------------------------- /edge_test.go: -------------------------------------------------------------------------------- 1 | package flex 2 | 3 | import "testing" 4 | 5 | func TestStart_overrides(t *testing.T) { 6 | root := NewNode() 7 | root.StyleSetFlexDirection(FlexDirectionRow) 8 | root.StyleSetWidth(100) 9 | root.StyleSetHeight(100) 10 | 11 | rootChild0 := NewNode() 12 | rootChild0.StyleSetFlexGrow(1) 13 | rootChild0.StyleSetMargin(EdgeStart, 10) 14 | rootChild0.StyleSetMargin(EdgeLeft, 20) 15 | rootChild0.StyleSetMargin(EdgeRight, 20) 16 | root.InsertChild(rootChild0, 0) 17 | 18 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 19 | assertFloatEqual(t, 10, rootChild0.LayoutGetLeft()) 20 | assertFloatEqual(t, 20, rootChild0.LayoutGetRight()) 21 | 22 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 23 | assertFloatEqual(t, 20, rootChild0.LayoutGetLeft()) 24 | assertFloatEqual(t, 10, rootChild0.LayoutGetRight()) 25 | } 26 | 27 | func TestEnd_overrides(t *testing.T) { 28 | root := NewNode() 29 | root.StyleSetFlexDirection(FlexDirectionRow) 30 | root.StyleSetWidth(100) 31 | root.StyleSetHeight(100) 32 | 33 | rootChild0 := NewNode() 34 | rootChild0.StyleSetFlexGrow(1) 35 | rootChild0.StyleSetMargin(EdgeEnd, 10) 36 | rootChild0.StyleSetMargin(EdgeLeft, 20) 37 | rootChild0.StyleSetMargin(EdgeRight, 20) 38 | root.InsertChild(rootChild0, 0) 39 | 40 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 41 | assertFloatEqual(t, 20, rootChild0.LayoutGetLeft()) 42 | assertFloatEqual(t, 10, rootChild0.LayoutGetRight()) 43 | 44 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 45 | assertFloatEqual(t, 10, rootChild0.LayoutGetLeft()) 46 | assertFloatEqual(t, 20, rootChild0.LayoutGetRight()) 47 | } 48 | 49 | func TestHorizontal_overridden(t *testing.T) { 50 | root := NewNode() 51 | root.StyleSetFlexDirection(FlexDirectionRow) 52 | root.StyleSetWidth(100) 53 | root.StyleSetHeight(100) 54 | 55 | rootChild0 := NewNode() 56 | rootChild0.StyleSetFlexGrow(1) 57 | rootChild0.StyleSetMargin(EdgeHorizontal, 10) 58 | rootChild0.StyleSetMargin(EdgeLeft, 20) 59 | root.InsertChild(rootChild0, 0) 60 | 61 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 62 | assertFloatEqual(t, 20, rootChild0.LayoutGetLeft()) 63 | assertFloatEqual(t, 10, rootChild0.LayoutGetRight()) 64 | } 65 | 66 | func TestVertical_overridden(t *testing.T) { 67 | root := NewNode() 68 | root.StyleSetFlexDirection(FlexDirectionColumn) 69 | root.StyleSetWidth(100) 70 | root.StyleSetHeight(100) 71 | 72 | rootChild0 := NewNode() 73 | rootChild0.StyleSetFlexGrow(1) 74 | rootChild0.StyleSetMargin(EdgeVertical, 10) 75 | rootChild0.StyleSetMargin(EdgeTop, 20) 76 | root.InsertChild(rootChild0, 0) 77 | 78 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 79 | assertFloatEqual(t, 20, rootChild0.LayoutGetTop()) 80 | assertFloatEqual(t, 10, rootChild0.LayoutGetBottom()) 81 | } 82 | 83 | func TestHorizontal_overrides_all(t *testing.T) { 84 | root := NewNode() 85 | root.StyleSetFlexDirection(FlexDirectionColumn) 86 | root.StyleSetWidth(100) 87 | root.StyleSetHeight(100) 88 | 89 | rootChild0 := NewNode() 90 | rootChild0.StyleSetFlexGrow(1) 91 | rootChild0.StyleSetMargin(EdgeHorizontal, 10) 92 | rootChild0.StyleSetMargin(EdgeAll, 20) 93 | root.InsertChild(rootChild0, 0) 94 | 95 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 96 | assertFloatEqual(t, 10, rootChild0.LayoutGetLeft()) 97 | assertFloatEqual(t, 20, rootChild0.LayoutGetTop()) 98 | assertFloatEqual(t, 10, rootChild0.LayoutGetRight()) 99 | assertFloatEqual(t, 20, rootChild0.LayoutGetBottom()) 100 | } 101 | 102 | func TestVertical_overrides_all(t *testing.T) { 103 | root := NewNode() 104 | root.StyleSetFlexDirection(FlexDirectionColumn) 105 | root.StyleSetWidth(100) 106 | root.StyleSetHeight(100) 107 | 108 | rootChild0 := NewNode() 109 | rootChild0.StyleSetFlexGrow(1) 110 | rootChild0.StyleSetMargin(EdgeVertical, 10) 111 | rootChild0.StyleSetMargin(EdgeAll, 20) 112 | root.InsertChild(rootChild0, 0) 113 | 114 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 115 | assertFloatEqual(t, 20, rootChild0.LayoutGetLeft()) 116 | assertFloatEqual(t, 10, rootChild0.LayoutGetTop()) 117 | assertFloatEqual(t, 20, rootChild0.LayoutGetRight()) 118 | assertFloatEqual(t, 10, rootChild0.LayoutGetBottom()) 119 | } 120 | 121 | func TestAll_overridden(t *testing.T) { 122 | root := NewNode() 123 | root.StyleSetFlexDirection(FlexDirectionColumn) 124 | root.StyleSetWidth(100) 125 | root.StyleSetHeight(100) 126 | 127 | rootChild0 := NewNode() 128 | rootChild0.StyleSetFlexGrow(1) 129 | rootChild0.StyleSetMargin(EdgeLeft, 10) 130 | rootChild0.StyleSetMargin(EdgeTop, 10) 131 | rootChild0.StyleSetMargin(EdgeRight, 10) 132 | rootChild0.StyleSetMargin(EdgeBottom, 10) 133 | rootChild0.StyleSetMargin(EdgeAll, 20) 134 | root.InsertChild(rootChild0, 0) 135 | 136 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 137 | assertFloatEqual(t, 10, rootChild0.LayoutGetLeft()) 138 | assertFloatEqual(t, 10, rootChild0.LayoutGetTop()) 139 | assertFloatEqual(t, 10, rootChild0.LayoutGetRight()) 140 | assertFloatEqual(t, 10, rootChild0.LayoutGetBottom()) 141 | } 142 | -------------------------------------------------------------------------------- /enums.go: -------------------------------------------------------------------------------- 1 | package flex 2 | 3 | // port of YGEnums.h 4 | 5 | // Align describes align flex attribute 6 | type Align int 7 | 8 | const ( 9 | // AlignAuto is "auto" 10 | AlignAuto Align = iota 11 | // AlignFlexStart is "flex-start" 12 | AlignFlexStart 13 | // AlignCenter if "center" 14 | AlignCenter 15 | // AlignFlexEnd is "flex-end" 16 | AlignFlexEnd 17 | // AlignStretch is "strech" 18 | AlignStretch 19 | // AlignBaseline is "baseline" 20 | AlignBaseline 21 | // AlignSpaceBetween is "space-between" 22 | AlignSpaceBetween 23 | // AlignSpaceAround is "space-around" 24 | AlignSpaceAround 25 | ) 26 | 27 | // Dimension represents dimention 28 | type Dimension int 29 | 30 | const ( 31 | // DimensionWidth is width 32 | DimensionWidth Dimension = iota 33 | // DimensionHeight is height 34 | DimensionHeight 35 | ) 36 | 37 | // Direction represents right-to-left or left-to-right direction 38 | type Direction int 39 | 40 | const ( 41 | // DirectionInherit is "inherit" 42 | DirectionInherit Direction = iota 43 | // DirectionLTR is "ltr" 44 | DirectionLTR 45 | // DirectionRTL is "rtl" 46 | DirectionRTL 47 | ) 48 | 49 | // Display is "display" property 50 | type Display int 51 | 52 | const ( 53 | // DisplayFlex is "flex" 54 | DisplayFlex Display = iota 55 | // DisplayNone is "none" 56 | DisplayNone 57 | ) 58 | 59 | // Edge represents an edge 60 | type Edge int 61 | 62 | const ( 63 | // EdgeLeft is left edge 64 | EdgeLeft Edge = iota 65 | // EdgeTop is top edge 66 | EdgeTop 67 | // EdgeRight is right edge 68 | EdgeRight 69 | // EdgeBottom is bottom edge 70 | EdgeBottom 71 | // EdgeStart is start edge 72 | EdgeStart 73 | // EdgeEnd is end edge 74 | EdgeEnd 75 | // EdgeHorizontal is horizontal edge 76 | EdgeHorizontal 77 | // EdgeVertical is vertical edge 78 | EdgeVertical 79 | // EdgeAll is all edge 80 | EdgeAll 81 | ) 82 | 83 | const ( 84 | // EdgeCount is count of edges 85 | EdgeCount = 9 86 | ) 87 | 88 | // ExperimentalFeature defines experimental features 89 | type ExperimentalFeature int 90 | 91 | const ( 92 | // ExperimentalFeatureWebFlexBasis is web flex basis 93 | ExperimentalFeatureWebFlexBasis ExperimentalFeature = iota 94 | ) 95 | 96 | const ( 97 | experimentalFeatureCount = 1 98 | ) 99 | 100 | // FlexDirection describes "flex-direction" property 101 | type FlexDirection int 102 | 103 | const ( 104 | // FlexDirectionColumn is "column" 105 | FlexDirectionColumn FlexDirection = iota 106 | // FlexDirectionColumnReverse is "column-reverse" 107 | FlexDirectionColumnReverse 108 | // FlexDirectionRow is "row" 109 | FlexDirectionRow 110 | // FlexDirectionRowReverse is "row-reverse" 111 | FlexDirectionRowReverse 112 | ) 113 | 114 | // Justify is "justify" property 115 | type Justify int 116 | 117 | const ( 118 | // JustifyFlexStart is "flex-start" 119 | JustifyFlexStart Justify = iota 120 | // JustifyCenter is "center" 121 | JustifyCenter 122 | // JustifyFlexEnd is "flex-end" 123 | JustifyFlexEnd 124 | // JustifySpaceBetween is "space-between" 125 | JustifySpaceBetween 126 | // JustifySpaceAround is "space-around" 127 | JustifySpaceAround 128 | ) 129 | 130 | // LogLevel represents log level 131 | type LogLevel int 132 | 133 | const ( 134 | LogLevelError LogLevel = iota 135 | LogLevelWarn 136 | LogLevelInfo 137 | LogLevelDebug 138 | LogLevelVerbose 139 | LogLevelFatal 140 | ) 141 | 142 | // MeasureMode defines measurement mode 143 | type MeasureMode int 144 | 145 | const ( 146 | // MeasureModeUndefined is undefined 147 | MeasureModeUndefined MeasureMode = iota 148 | // MeasureModeExactly is exactly 149 | MeasureModeExactly 150 | // MeasureModeAtMost is at-most 151 | MeasureModeAtMost 152 | ) 153 | 154 | const ( 155 | measureModeCount = 3 156 | ) 157 | 158 | // NodeType defines node type 159 | type NodeType int 160 | 161 | const ( 162 | // NodeTypeDefault is default node 163 | NodeTypeDefault NodeType = iota 164 | // NodeTypeText is text node 165 | NodeTypeText 166 | ) 167 | 168 | // Overflow describes "overflow" property 169 | type Overflow int 170 | 171 | const ( 172 | // OverflowVisible is "visible" 173 | OverflowVisible Overflow = iota 174 | // OverflowHidden is "hidden" 175 | OverflowHidden 176 | // OverflowScroll is "scroll" 177 | OverflowScroll 178 | ) 179 | 180 | // PositionType is "position" property 181 | type PositionType int 182 | 183 | const ( 184 | // PositionTypeRelative is "relative" 185 | PositionTypeRelative PositionType = iota 186 | // PositionTypeAbsolute is "absolute" 187 | PositionTypeAbsolute 188 | ) 189 | 190 | type PrintOptions int 191 | 192 | const ( 193 | PrintOptionsLayout PrintOptions = 1 << iota 194 | PrintOptionsStyle 195 | PrintOptionsChildren 196 | ) 197 | 198 | // Unit is "unit" property 199 | type Unit int 200 | 201 | const ( 202 | // UnitUndefined is "undefined" 203 | UnitUndefined Unit = iota 204 | // UnitPoint is "point" 205 | UnitPoint 206 | // UnitPercent is "percent" 207 | UnitPercent 208 | // UnitAuto is "auto" 209 | UnitAuto 210 | ) 211 | 212 | // Wrap is "wrap" property 213 | type Wrap int 214 | 215 | const ( 216 | // WrapNoWrap is "no-wrap" 217 | WrapNoWrap Wrap = iota 218 | // WrapWrap is "wrap" 219 | WrapWrap 220 | // WrapWrapReverse is "reverse" 221 | WrapWrapReverse 222 | ) 223 | 224 | // AlignToString returns string version of Align enum 225 | func AlignToString(value Align) string { 226 | switch value { 227 | case AlignAuto: 228 | return "auto" 229 | case AlignFlexStart: 230 | return "flex-start" 231 | case AlignCenter: 232 | return "center" 233 | case AlignFlexEnd: 234 | return "flex-end" 235 | case AlignStretch: 236 | return "stretch" 237 | case AlignBaseline: 238 | return "baseline" 239 | case AlignSpaceBetween: 240 | return "space-between" 241 | case AlignSpaceAround: 242 | return "space-around" 243 | } 244 | return "unknown" 245 | } 246 | 247 | // DimensionToString returns string version of Dimension enum 248 | func DimensionToString(value Dimension) string { 249 | switch value { 250 | case DimensionWidth: 251 | return "width" 252 | case DimensionHeight: 253 | return "height" 254 | } 255 | return "unknown" 256 | } 257 | 258 | // DirectionToString returns string version of Direction enum 259 | func DirectionToString(value Direction) string { 260 | switch value { 261 | case DirectionInherit: 262 | return "inherit" 263 | case DirectionLTR: 264 | return "ltr" 265 | case DirectionRTL: 266 | return "rtl" 267 | } 268 | return "unknown" 269 | } 270 | 271 | // DisplayToString returns string version of Display enum 272 | func DisplayToString(value Display) string { 273 | switch value { 274 | case DisplayFlex: 275 | return "flex" 276 | case DisplayNone: 277 | return "none" 278 | } 279 | return "unknown" 280 | } 281 | 282 | // EdgeToString returns string version of Edge enum 283 | func EdgeToString(value Edge) string { 284 | switch value { 285 | case EdgeLeft: 286 | return "left" 287 | case EdgeTop: 288 | return "top" 289 | case EdgeRight: 290 | return "right" 291 | case EdgeBottom: 292 | return "bottom" 293 | case EdgeStart: 294 | return "start" 295 | case EdgeEnd: 296 | return "end" 297 | case EdgeHorizontal: 298 | return "horizontal" 299 | case EdgeVertical: 300 | return "vertical" 301 | case EdgeAll: 302 | return "all" 303 | } 304 | return "unknown" 305 | } 306 | 307 | // ExperimentalFeatureToString returns string version of ExperimentalFeature enum 308 | func ExperimentalFeatureToString(value ExperimentalFeature) string { 309 | switch value { 310 | case ExperimentalFeatureWebFlexBasis: 311 | return "web-flex-basis" 312 | } 313 | return "unknown" 314 | } 315 | 316 | // FlexDirectionToString returns string version of FlexDirection enum 317 | func FlexDirectionToString(value FlexDirection) string { 318 | switch value { 319 | case FlexDirectionColumn: 320 | return "column" 321 | case FlexDirectionColumnReverse: 322 | return "column-reverse" 323 | case FlexDirectionRow: 324 | return "row" 325 | case FlexDirectionRowReverse: 326 | return "row-reverse" 327 | } 328 | return "unknown" 329 | } 330 | 331 | // JustifyToString returns string version of Justify enum 332 | func JustifyToString(value Justify) string { 333 | switch value { 334 | case JustifyFlexStart: 335 | return "flex-start" 336 | case JustifyCenter: 337 | return "center" 338 | case JustifyFlexEnd: 339 | return "flex-end" 340 | case JustifySpaceBetween: 341 | return "space-between" 342 | case JustifySpaceAround: 343 | return "space-around" 344 | } 345 | return "unknown" 346 | } 347 | 348 | // LogLevelToString returns string version of LogLevel enum 349 | func LogLevelToString(value LogLevel) string { 350 | switch value { 351 | case LogLevelError: 352 | return "error" 353 | case LogLevelWarn: 354 | return "warn" 355 | case LogLevelInfo: 356 | return "info" 357 | case LogLevelDebug: 358 | return "debug" 359 | case LogLevelVerbose: 360 | return "verbose" 361 | case LogLevelFatal: 362 | return "fatal" 363 | } 364 | return "unknown" 365 | } 366 | 367 | // MeasureModeToString returns string version of MeasureMode enum 368 | func MeasureModeToString(value MeasureMode) string { 369 | switch value { 370 | case MeasureModeUndefined: 371 | return "undefined" 372 | case MeasureModeExactly: 373 | return "exactly" 374 | case MeasureModeAtMost: 375 | return "at-most" 376 | } 377 | return "unknown" 378 | } 379 | 380 | // NodeTypeToString returns string version of NodeType enum 381 | func NodeTypeToString(value NodeType) string { 382 | switch value { 383 | case NodeTypeDefault: 384 | return "default" 385 | case NodeTypeText: 386 | return "text" 387 | } 388 | return "unknown" 389 | } 390 | 391 | // OverflowToString returns string version of Overflow enum 392 | func OverflowToString(value Overflow) string { 393 | switch value { 394 | case OverflowVisible: 395 | return "visible" 396 | case OverflowHidden: 397 | return "hidden" 398 | case OverflowScroll: 399 | return "scroll" 400 | } 401 | return "unknown" 402 | } 403 | 404 | // PositionTypeToString returns string version of PositionType enum 405 | func PositionTypeToString(value PositionType) string { 406 | switch value { 407 | case PositionTypeRelative: 408 | return "relative" 409 | case PositionTypeAbsolute: 410 | return "absolute" 411 | } 412 | return "unknown" 413 | } 414 | 415 | // PrintOptionsToString returns string version of PrintOptions enum 416 | func PrintOptionsToString(value PrintOptions) string { 417 | switch value { 418 | case PrintOptionsLayout: 419 | return "layout" 420 | case PrintOptionsStyle: 421 | return "style" 422 | case PrintOptionsChildren: 423 | return "children" 424 | } 425 | return "unknown" 426 | } 427 | 428 | // UnitToString returns string version of Unit enum 429 | func UnitToString(value Unit) string { 430 | switch value { 431 | case UnitUndefined: 432 | return "undefined" 433 | case UnitPoint: 434 | return "point" 435 | case UnitPercent: 436 | return "percent" 437 | case UnitAuto: 438 | return "auto" 439 | } 440 | return "unknown" 441 | } 442 | 443 | // WrapToString returns string version of Wrap enum 444 | func WrapToString(value Wrap) string { 445 | switch value { 446 | case WrapNoWrap: 447 | return "no-wrap" 448 | case WrapWrap: 449 | return "wrap" 450 | case WrapWrapReverse: 451 | return "wrap-reverse" 452 | } 453 | return "unknown" 454 | } 455 | -------------------------------------------------------------------------------- /flex_direction_test.go: -------------------------------------------------------------------------------- 1 | package flex 2 | 3 | import "testing" 4 | 5 | func TestFlex_direction_column_no_height(t *testing.T) { 6 | config := NewConfig() 7 | root := NewNodeWithConfig(config) 8 | root.StyleSetWidth(100) 9 | 10 | rootChild0 := NewNodeWithConfig(config) 11 | rootChild0.StyleSetHeight(10) 12 | root.InsertChild(rootChild0, 0) 13 | 14 | rootChild1 := NewNodeWithConfig(config) 15 | rootChild1.StyleSetHeight(10) 16 | root.InsertChild(rootChild1, 1) 17 | 18 | rootChild2 := NewNodeWithConfig(config) 19 | rootChild2.StyleSetHeight(10) 20 | root.InsertChild(rootChild2, 2) 21 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 22 | 23 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 24 | assertFloatEqual(t, 0, root.LayoutGetTop()) 25 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 26 | assertFloatEqual(t, 30, root.LayoutGetHeight()) 27 | 28 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 29 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 30 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 31 | assertFloatEqual(t, 10, rootChild0.LayoutGetHeight()) 32 | 33 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 34 | assertFloatEqual(t, 10, rootChild1.LayoutGetTop()) 35 | assertFloatEqual(t, 100, rootChild1.LayoutGetWidth()) 36 | assertFloatEqual(t, 10, rootChild1.LayoutGetHeight()) 37 | 38 | assertFloatEqual(t, 0, rootChild2.LayoutGetLeft()) 39 | assertFloatEqual(t, 20, rootChild2.LayoutGetTop()) 40 | assertFloatEqual(t, 100, rootChild2.LayoutGetWidth()) 41 | assertFloatEqual(t, 10, rootChild2.LayoutGetHeight()) 42 | 43 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 44 | 45 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 46 | assertFloatEqual(t, 0, root.LayoutGetTop()) 47 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 48 | assertFloatEqual(t, 30, root.LayoutGetHeight()) 49 | 50 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 51 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 52 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 53 | assertFloatEqual(t, 10, rootChild0.LayoutGetHeight()) 54 | 55 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 56 | assertFloatEqual(t, 10, rootChild1.LayoutGetTop()) 57 | assertFloatEqual(t, 100, rootChild1.LayoutGetWidth()) 58 | assertFloatEqual(t, 10, rootChild1.LayoutGetHeight()) 59 | 60 | assertFloatEqual(t, 0, rootChild2.LayoutGetLeft()) 61 | assertFloatEqual(t, 20, rootChild2.LayoutGetTop()) 62 | assertFloatEqual(t, 100, rootChild2.LayoutGetWidth()) 63 | assertFloatEqual(t, 10, rootChild2.LayoutGetHeight()) 64 | } 65 | 66 | func TestFlex_direction_row_no_width(t *testing.T) { 67 | config := NewConfig() 68 | 69 | root := NewNodeWithConfig(config) 70 | root.StyleSetFlexDirection(FlexDirectionRow) 71 | root.StyleSetHeight(100) 72 | 73 | rootChild0 := NewNodeWithConfig(config) 74 | rootChild0.StyleSetWidth(10) 75 | root.InsertChild(rootChild0, 0) 76 | 77 | rootChild1 := NewNodeWithConfig(config) 78 | rootChild1.StyleSetWidth(10) 79 | root.InsertChild(rootChild1, 1) 80 | 81 | rootChild2 := NewNodeWithConfig(config) 82 | rootChild2.StyleSetWidth(10) 83 | root.InsertChild(rootChild2, 2) 84 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 85 | 86 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 87 | assertFloatEqual(t, 0, root.LayoutGetTop()) 88 | assertFloatEqual(t, 30, root.LayoutGetWidth()) 89 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 90 | 91 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 92 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 93 | assertFloatEqual(t, 10, rootChild0.LayoutGetWidth()) 94 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 95 | 96 | assertFloatEqual(t, 10, rootChild1.LayoutGetLeft()) 97 | assertFloatEqual(t, 0, rootChild1.LayoutGetTop()) 98 | assertFloatEqual(t, 10, rootChild1.LayoutGetWidth()) 99 | assertFloatEqual(t, 100, rootChild1.LayoutGetHeight()) 100 | 101 | assertFloatEqual(t, 20, rootChild2.LayoutGetLeft()) 102 | assertFloatEqual(t, 0, rootChild2.LayoutGetTop()) 103 | assertFloatEqual(t, 10, rootChild2.LayoutGetWidth()) 104 | assertFloatEqual(t, 100, rootChild2.LayoutGetHeight()) 105 | 106 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 107 | 108 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 109 | assertFloatEqual(t, 0, root.LayoutGetTop()) 110 | assertFloatEqual(t, 30, root.LayoutGetWidth()) 111 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 112 | 113 | assertFloatEqual(t, 20, rootChild0.LayoutGetLeft()) 114 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 115 | assertFloatEqual(t, 10, rootChild0.LayoutGetWidth()) 116 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 117 | 118 | assertFloatEqual(t, 10, rootChild1.LayoutGetLeft()) 119 | assertFloatEqual(t, 0, rootChild1.LayoutGetTop()) 120 | assertFloatEqual(t, 10, rootChild1.LayoutGetWidth()) 121 | assertFloatEqual(t, 100, rootChild1.LayoutGetHeight()) 122 | 123 | assertFloatEqual(t, 0, rootChild2.LayoutGetLeft()) 124 | assertFloatEqual(t, 0, rootChild2.LayoutGetTop()) 125 | assertFloatEqual(t, 10, rootChild2.LayoutGetWidth()) 126 | assertFloatEqual(t, 100, rootChild2.LayoutGetHeight()) 127 | } 128 | 129 | func TestFlex_direction_column(t *testing.T) { 130 | config := NewConfig() 131 | 132 | root := NewNodeWithConfig(config) 133 | root.StyleSetWidth(100) 134 | root.StyleSetHeight(100) 135 | 136 | rootChild0 := NewNodeWithConfig(config) 137 | rootChild0.StyleSetHeight(10) 138 | root.InsertChild(rootChild0, 0) 139 | 140 | rootChild1 := NewNodeWithConfig(config) 141 | rootChild1.StyleSetHeight(10) 142 | root.InsertChild(rootChild1, 1) 143 | 144 | rootChild2 := NewNodeWithConfig(config) 145 | rootChild2.StyleSetHeight(10) 146 | root.InsertChild(rootChild2, 2) 147 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 148 | 149 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 150 | assertFloatEqual(t, 0, root.LayoutGetTop()) 151 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 152 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 153 | 154 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 155 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 156 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 157 | assertFloatEqual(t, 10, rootChild0.LayoutGetHeight()) 158 | 159 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 160 | assertFloatEqual(t, 10, rootChild1.LayoutGetTop()) 161 | assertFloatEqual(t, 100, rootChild1.LayoutGetWidth()) 162 | assertFloatEqual(t, 10, rootChild1.LayoutGetHeight()) 163 | 164 | assertFloatEqual(t, 0, rootChild2.LayoutGetLeft()) 165 | assertFloatEqual(t, 20, rootChild2.LayoutGetTop()) 166 | assertFloatEqual(t, 100, rootChild2.LayoutGetWidth()) 167 | assertFloatEqual(t, 10, rootChild2.LayoutGetHeight()) 168 | 169 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 170 | 171 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 172 | assertFloatEqual(t, 0, root.LayoutGetTop()) 173 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 174 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 175 | 176 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 177 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 178 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 179 | assertFloatEqual(t, 10, rootChild0.LayoutGetHeight()) 180 | 181 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 182 | assertFloatEqual(t, 10, rootChild1.LayoutGetTop()) 183 | assertFloatEqual(t, 100, rootChild1.LayoutGetWidth()) 184 | assertFloatEqual(t, 10, rootChild1.LayoutGetHeight()) 185 | 186 | assertFloatEqual(t, 0, rootChild2.LayoutGetLeft()) 187 | assertFloatEqual(t, 20, rootChild2.LayoutGetTop()) 188 | assertFloatEqual(t, 100, rootChild2.LayoutGetWidth()) 189 | assertFloatEqual(t, 10, rootChild2.LayoutGetHeight()) 190 | } 191 | 192 | func TestFlex_direction_row(t *testing.T) { 193 | config := NewConfig() 194 | 195 | root := NewNodeWithConfig(config) 196 | root.StyleSetFlexDirection(FlexDirectionRow) 197 | root.StyleSetWidth(100) 198 | root.StyleSetHeight(100) 199 | 200 | rootChild0 := NewNodeWithConfig(config) 201 | rootChild0.StyleSetWidth(10) 202 | root.InsertChild(rootChild0, 0) 203 | 204 | rootChild1 := NewNodeWithConfig(config) 205 | rootChild1.StyleSetWidth(10) 206 | root.InsertChild(rootChild1, 1) 207 | 208 | rootChild2 := NewNodeWithConfig(config) 209 | rootChild2.StyleSetWidth(10) 210 | root.InsertChild(rootChild2, 2) 211 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 212 | 213 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 214 | assertFloatEqual(t, 0, root.LayoutGetTop()) 215 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 216 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 217 | 218 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 219 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 220 | assertFloatEqual(t, 10, rootChild0.LayoutGetWidth()) 221 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 222 | 223 | assertFloatEqual(t, 10, rootChild1.LayoutGetLeft()) 224 | assertFloatEqual(t, 0, rootChild1.LayoutGetTop()) 225 | assertFloatEqual(t, 10, rootChild1.LayoutGetWidth()) 226 | assertFloatEqual(t, 100, rootChild1.LayoutGetHeight()) 227 | 228 | assertFloatEqual(t, 20, rootChild2.LayoutGetLeft()) 229 | assertFloatEqual(t, 0, rootChild2.LayoutGetTop()) 230 | assertFloatEqual(t, 10, rootChild2.LayoutGetWidth()) 231 | assertFloatEqual(t, 100, rootChild2.LayoutGetHeight()) 232 | 233 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 234 | 235 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 236 | assertFloatEqual(t, 0, root.LayoutGetTop()) 237 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 238 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 239 | 240 | assertFloatEqual(t, 90, rootChild0.LayoutGetLeft()) 241 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 242 | assertFloatEqual(t, 10, rootChild0.LayoutGetWidth()) 243 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 244 | 245 | assertFloatEqual(t, 80, rootChild1.LayoutGetLeft()) 246 | assertFloatEqual(t, 0, rootChild1.LayoutGetTop()) 247 | assertFloatEqual(t, 10, rootChild1.LayoutGetWidth()) 248 | assertFloatEqual(t, 100, rootChild1.LayoutGetHeight()) 249 | 250 | assertFloatEqual(t, 70, rootChild2.LayoutGetLeft()) 251 | assertFloatEqual(t, 0, rootChild2.LayoutGetTop()) 252 | assertFloatEqual(t, 10, rootChild2.LayoutGetWidth()) 253 | assertFloatEqual(t, 100, rootChild2.LayoutGetHeight()) 254 | } 255 | 256 | func TestFlex_direction_column_reverse(t *testing.T) { 257 | config := NewConfig() 258 | 259 | root := NewNodeWithConfig(config) 260 | root.StyleSetFlexDirection(FlexDirectionColumnReverse) 261 | root.StyleSetWidth(100) 262 | root.StyleSetHeight(100) 263 | 264 | rootChild0 := NewNodeWithConfig(config) 265 | rootChild0.StyleSetHeight(10) 266 | root.InsertChild(rootChild0, 0) 267 | 268 | rootChild1 := NewNodeWithConfig(config) 269 | rootChild1.StyleSetHeight(10) 270 | root.InsertChild(rootChild1, 1) 271 | 272 | rootChild2 := NewNodeWithConfig(config) 273 | rootChild2.StyleSetHeight(10) 274 | root.InsertChild(rootChild2, 2) 275 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 276 | 277 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 278 | assertFloatEqual(t, 0, root.LayoutGetTop()) 279 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 280 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 281 | 282 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 283 | assertFloatEqual(t, 90, rootChild0.LayoutGetTop()) 284 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 285 | assertFloatEqual(t, 10, rootChild0.LayoutGetHeight()) 286 | 287 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 288 | assertFloatEqual(t, 80, rootChild1.LayoutGetTop()) 289 | assertFloatEqual(t, 100, rootChild1.LayoutGetWidth()) 290 | assertFloatEqual(t, 10, rootChild1.LayoutGetHeight()) 291 | 292 | assertFloatEqual(t, 0, rootChild2.LayoutGetLeft()) 293 | assertFloatEqual(t, 70, rootChild2.LayoutGetTop()) 294 | assertFloatEqual(t, 100, rootChild2.LayoutGetWidth()) 295 | assertFloatEqual(t, 10, rootChild2.LayoutGetHeight()) 296 | 297 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 298 | 299 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 300 | assertFloatEqual(t, 0, root.LayoutGetTop()) 301 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 302 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 303 | 304 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 305 | assertFloatEqual(t, 90, rootChild0.LayoutGetTop()) 306 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 307 | assertFloatEqual(t, 10, rootChild0.LayoutGetHeight()) 308 | 309 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 310 | assertFloatEqual(t, 80, rootChild1.LayoutGetTop()) 311 | assertFloatEqual(t, 100, rootChild1.LayoutGetWidth()) 312 | assertFloatEqual(t, 10, rootChild1.LayoutGetHeight()) 313 | 314 | assertFloatEqual(t, 0, rootChild2.LayoutGetLeft()) 315 | assertFloatEqual(t, 70, rootChild2.LayoutGetTop()) 316 | assertFloatEqual(t, 100, rootChild2.LayoutGetWidth()) 317 | assertFloatEqual(t, 10, rootChild2.LayoutGetHeight()) 318 | } 319 | 320 | func TestFlex_direction_row_reverse(t *testing.T) { 321 | config := NewConfig() 322 | 323 | root := NewNodeWithConfig(config) 324 | root.StyleSetFlexDirection(FlexDirectionRowReverse) 325 | root.StyleSetWidth(100) 326 | root.StyleSetHeight(100) 327 | 328 | rootChild0 := NewNodeWithConfig(config) 329 | rootChild0.StyleSetWidth(10) 330 | root.InsertChild(rootChild0, 0) 331 | 332 | rootChild1 := NewNodeWithConfig(config) 333 | rootChild1.StyleSetWidth(10) 334 | root.InsertChild(rootChild1, 1) 335 | 336 | rootChild2 := NewNodeWithConfig(config) 337 | rootChild2.StyleSetWidth(10) 338 | root.InsertChild(rootChild2, 2) 339 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 340 | 341 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 342 | assertFloatEqual(t, 0, root.LayoutGetTop()) 343 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 344 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 345 | 346 | assertFloatEqual(t, 90, rootChild0.LayoutGetLeft()) 347 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 348 | assertFloatEqual(t, 10, rootChild0.LayoutGetWidth()) 349 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 350 | 351 | assertFloatEqual(t, 80, rootChild1.LayoutGetLeft()) 352 | assertFloatEqual(t, 0, rootChild1.LayoutGetTop()) 353 | assertFloatEqual(t, 10, rootChild1.LayoutGetWidth()) 354 | assertFloatEqual(t, 100, rootChild1.LayoutGetHeight()) 355 | 356 | assertFloatEqual(t, 70, rootChild2.LayoutGetLeft()) 357 | assertFloatEqual(t, 0, rootChild2.LayoutGetTop()) 358 | assertFloatEqual(t, 10, rootChild2.LayoutGetWidth()) 359 | assertFloatEqual(t, 100, rootChild2.LayoutGetHeight()) 360 | 361 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 362 | 363 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 364 | assertFloatEqual(t, 0, root.LayoutGetTop()) 365 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 366 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 367 | 368 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 369 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 370 | assertFloatEqual(t, 10, rootChild0.LayoutGetWidth()) 371 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 372 | 373 | assertFloatEqual(t, 10, rootChild1.LayoutGetLeft()) 374 | assertFloatEqual(t, 0, rootChild1.LayoutGetTop()) 375 | assertFloatEqual(t, 10, rootChild1.LayoutGetWidth()) 376 | assertFloatEqual(t, 100, rootChild1.LayoutGetHeight()) 377 | 378 | assertFloatEqual(t, 20, rootChild2.LayoutGetLeft()) 379 | assertFloatEqual(t, 0, rootChild2.LayoutGetTop()) 380 | assertFloatEqual(t, 10, rootChild2.LayoutGetWidth()) 381 | assertFloatEqual(t, 100, rootChild2.LayoutGetHeight()) 382 | } 383 | -------------------------------------------------------------------------------- /flex_test.go: -------------------------------------------------------------------------------- 1 | package flex 2 | 3 | import "testing" 4 | 5 | func TestFlex_basis_flex_grow_column(t *testing.T) { 6 | config := NewConfig() 7 | 8 | root := NewNodeWithConfig(config) 9 | root.StyleSetWidth(100) 10 | root.StyleSetHeight(100) 11 | 12 | rootChild0 := NewNodeWithConfig(config) 13 | rootChild0.StyleSetFlexGrow(1) 14 | rootChild0.StyleSetFlexBasis(50) 15 | root.InsertChild(rootChild0, 0) 16 | 17 | rootChild1 := NewNodeWithConfig(config) 18 | rootChild1.StyleSetFlexGrow(1) 19 | root.InsertChild(rootChild1, 1) 20 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 21 | 22 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 23 | assertFloatEqual(t, 0, root.LayoutGetTop()) 24 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 25 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 26 | 27 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 28 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 29 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 30 | assertFloatEqual(t, 75, rootChild0.LayoutGetHeight()) 31 | 32 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 33 | assertFloatEqual(t, 75, rootChild1.LayoutGetTop()) 34 | assertFloatEqual(t, 100, rootChild1.LayoutGetWidth()) 35 | assertFloatEqual(t, 25, rootChild1.LayoutGetHeight()) 36 | 37 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 38 | 39 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 40 | assertFloatEqual(t, 0, root.LayoutGetTop()) 41 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 42 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 43 | 44 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 45 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 46 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 47 | assertFloatEqual(t, 75, rootChild0.LayoutGetHeight()) 48 | 49 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 50 | assertFloatEqual(t, 75, rootChild1.LayoutGetTop()) 51 | assertFloatEqual(t, 100, rootChild1.LayoutGetWidth()) 52 | assertFloatEqual(t, 25, rootChild1.LayoutGetHeight()) 53 | } 54 | 55 | func TestFlex_basis_flex_grow_row(t *testing.T) { 56 | config := NewConfig() 57 | 58 | root := NewNodeWithConfig(config) 59 | root.StyleSetFlexDirection(FlexDirectionRow) 60 | root.StyleSetWidth(100) 61 | root.StyleSetHeight(100) 62 | 63 | rootChild0 := NewNodeWithConfig(config) 64 | rootChild0.StyleSetFlexGrow(1) 65 | rootChild0.StyleSetFlexBasis(50) 66 | root.InsertChild(rootChild0, 0) 67 | 68 | rootChild1 := NewNodeWithConfig(config) 69 | rootChild1.StyleSetFlexGrow(1) 70 | root.InsertChild(rootChild1, 1) 71 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 72 | 73 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 74 | assertFloatEqual(t, 0, root.LayoutGetTop()) 75 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 76 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 77 | 78 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 79 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 80 | assertFloatEqual(t, 75, rootChild0.LayoutGetWidth()) 81 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 82 | 83 | assertFloatEqual(t, 75, rootChild1.LayoutGetLeft()) 84 | assertFloatEqual(t, 0, rootChild1.LayoutGetTop()) 85 | assertFloatEqual(t, 25, rootChild1.LayoutGetWidth()) 86 | assertFloatEqual(t, 100, rootChild1.LayoutGetHeight()) 87 | 88 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 89 | 90 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 91 | assertFloatEqual(t, 0, root.LayoutGetTop()) 92 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 93 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 94 | 95 | assertFloatEqual(t, 25, rootChild0.LayoutGetLeft()) 96 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 97 | assertFloatEqual(t, 75, rootChild0.LayoutGetWidth()) 98 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 99 | 100 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 101 | assertFloatEqual(t, 0, rootChild1.LayoutGetTop()) 102 | assertFloatEqual(t, 25, rootChild1.LayoutGetWidth()) 103 | assertFloatEqual(t, 100, rootChild1.LayoutGetHeight()) 104 | } 105 | 106 | func TestFlex_basis_flex_shrink_column(t *testing.T) { 107 | config := NewConfig() 108 | 109 | root := NewNodeWithConfig(config) 110 | root.StyleSetWidth(100) 111 | root.StyleSetHeight(100) 112 | 113 | rootChild0 := NewNodeWithConfig(config) 114 | rootChild0.StyleSetFlexShrink(1) 115 | rootChild0.StyleSetFlexBasis(100) 116 | root.InsertChild(rootChild0, 0) 117 | 118 | rootChild1 := NewNodeWithConfig(config) 119 | rootChild1.StyleSetFlexBasis(50) 120 | root.InsertChild(rootChild1, 1) 121 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 122 | 123 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 124 | assertFloatEqual(t, 0, root.LayoutGetTop()) 125 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 126 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 127 | 128 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 129 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 130 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 131 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 132 | 133 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 134 | assertFloatEqual(t, 50, rootChild1.LayoutGetTop()) 135 | assertFloatEqual(t, 100, rootChild1.LayoutGetWidth()) 136 | assertFloatEqual(t, 50, rootChild1.LayoutGetHeight()) 137 | 138 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 139 | 140 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 141 | assertFloatEqual(t, 0, root.LayoutGetTop()) 142 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 143 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 144 | 145 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 146 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 147 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 148 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 149 | 150 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 151 | assertFloatEqual(t, 50, rootChild1.LayoutGetTop()) 152 | assertFloatEqual(t, 100, rootChild1.LayoutGetWidth()) 153 | assertFloatEqual(t, 50, rootChild1.LayoutGetHeight()) 154 | } 155 | 156 | func TestFlex_basis_flex_shrink_row(t *testing.T) { 157 | config := NewConfig() 158 | 159 | root := NewNodeWithConfig(config) 160 | root.StyleSetFlexDirection(FlexDirectionRow) 161 | root.StyleSetWidth(100) 162 | root.StyleSetHeight(100) 163 | 164 | rootChild0 := NewNodeWithConfig(config) 165 | rootChild0.StyleSetFlexShrink(1) 166 | rootChild0.StyleSetFlexBasis(100) 167 | root.InsertChild(rootChild0, 0) 168 | 169 | rootChild1 := NewNodeWithConfig(config) 170 | rootChild1.StyleSetFlexBasis(50) 171 | root.InsertChild(rootChild1, 1) 172 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 173 | 174 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 175 | assertFloatEqual(t, 0, root.LayoutGetTop()) 176 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 177 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 178 | 179 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 180 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 181 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 182 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 183 | 184 | assertFloatEqual(t, 50, rootChild1.LayoutGetLeft()) 185 | assertFloatEqual(t, 0, rootChild1.LayoutGetTop()) 186 | assertFloatEqual(t, 50, rootChild1.LayoutGetWidth()) 187 | assertFloatEqual(t, 100, rootChild1.LayoutGetHeight()) 188 | 189 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 190 | 191 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 192 | assertFloatEqual(t, 0, root.LayoutGetTop()) 193 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 194 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 195 | 196 | assertFloatEqual(t, 50, rootChild0.LayoutGetLeft()) 197 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 198 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 199 | assertFloatEqual(t, 100, rootChild0.LayoutGetHeight()) 200 | 201 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 202 | assertFloatEqual(t, 0, rootChild1.LayoutGetTop()) 203 | assertFloatEqual(t, 50, rootChild1.LayoutGetWidth()) 204 | assertFloatEqual(t, 100, rootChild1.LayoutGetHeight()) 205 | } 206 | 207 | func TestFlex_shrink_to_zero(t *testing.T) { 208 | config := NewConfig() 209 | 210 | root := NewNodeWithConfig(config) 211 | root.StyleSetHeight(75) 212 | 213 | rootChild0 := NewNodeWithConfig(config) 214 | rootChild0.StyleSetWidth(50) 215 | rootChild0.StyleSetHeight(50) 216 | root.InsertChild(rootChild0, 0) 217 | 218 | rootChild1 := NewNodeWithConfig(config) 219 | rootChild1.StyleSetFlexShrink(1) 220 | rootChild1.StyleSetWidth(50) 221 | rootChild1.StyleSetHeight(50) 222 | root.InsertChild(rootChild1, 1) 223 | 224 | rootChild2 := NewNodeWithConfig(config) 225 | rootChild2.StyleSetWidth(50) 226 | rootChild2.StyleSetHeight(50) 227 | root.InsertChild(rootChild2, 2) 228 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 229 | 230 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 231 | assertFloatEqual(t, 0, root.LayoutGetTop()) 232 | assertFloatEqual(t, 50, root.LayoutGetWidth()) 233 | assertFloatEqual(t, 75, root.LayoutGetHeight()) 234 | 235 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 236 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 237 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 238 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 239 | 240 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 241 | assertFloatEqual(t, 50, rootChild1.LayoutGetTop()) 242 | assertFloatEqual(t, 50, rootChild1.LayoutGetWidth()) 243 | assertFloatEqual(t, 0, rootChild1.LayoutGetHeight()) 244 | 245 | assertFloatEqual(t, 0, rootChild2.LayoutGetLeft()) 246 | assertFloatEqual(t, 50, rootChild2.LayoutGetTop()) 247 | assertFloatEqual(t, 50, rootChild2.LayoutGetWidth()) 248 | assertFloatEqual(t, 50, rootChild2.LayoutGetHeight()) 249 | 250 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 251 | 252 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 253 | assertFloatEqual(t, 0, root.LayoutGetTop()) 254 | assertFloatEqual(t, 50, root.LayoutGetWidth()) 255 | assertFloatEqual(t, 75, root.LayoutGetHeight()) 256 | 257 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 258 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 259 | assertFloatEqual(t, 50, rootChild0.LayoutGetWidth()) 260 | assertFloatEqual(t, 50, rootChild0.LayoutGetHeight()) 261 | 262 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 263 | assertFloatEqual(t, 50, rootChild1.LayoutGetTop()) 264 | assertFloatEqual(t, 50, rootChild1.LayoutGetWidth()) 265 | assertFloatEqual(t, 0, rootChild1.LayoutGetHeight()) 266 | 267 | assertFloatEqual(t, 0, rootChild2.LayoutGetLeft()) 268 | assertFloatEqual(t, 50, rootChild2.LayoutGetTop()) 269 | assertFloatEqual(t, 50, rootChild2.LayoutGetWidth()) 270 | assertFloatEqual(t, 50, rootChild2.LayoutGetHeight()) 271 | } 272 | 273 | func TestFlex_basis_overrides_main_size(t *testing.T) { 274 | config := NewConfig() 275 | 276 | root := NewNodeWithConfig(config) 277 | root.StyleSetWidth(100) 278 | root.StyleSetHeight(100) 279 | 280 | rootChild0 := NewNodeWithConfig(config) 281 | rootChild0.StyleSetFlexGrow(1) 282 | rootChild0.StyleSetFlexBasis(50) 283 | rootChild0.StyleSetHeight(20) 284 | root.InsertChild(rootChild0, 0) 285 | 286 | rootChild1 := NewNodeWithConfig(config) 287 | rootChild1.StyleSetFlexGrow(1) 288 | rootChild1.StyleSetHeight(10) 289 | root.InsertChild(rootChild1, 1) 290 | 291 | rootChild2 := NewNodeWithConfig(config) 292 | rootChild2.StyleSetFlexGrow(1) 293 | rootChild2.StyleSetHeight(10) 294 | root.InsertChild(rootChild2, 2) 295 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 296 | 297 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 298 | assertFloatEqual(t, 0, root.LayoutGetTop()) 299 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 300 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 301 | 302 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 303 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 304 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 305 | assertFloatEqual(t, 60, rootChild0.LayoutGetHeight()) 306 | 307 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 308 | assertFloatEqual(t, 60, rootChild1.LayoutGetTop()) 309 | assertFloatEqual(t, 100, rootChild1.LayoutGetWidth()) 310 | assertFloatEqual(t, 20, rootChild1.LayoutGetHeight()) 311 | 312 | assertFloatEqual(t, 0, rootChild2.LayoutGetLeft()) 313 | assertFloatEqual(t, 80, rootChild2.LayoutGetTop()) 314 | assertFloatEqual(t, 100, rootChild2.LayoutGetWidth()) 315 | assertFloatEqual(t, 20, rootChild2.LayoutGetHeight()) 316 | 317 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 318 | 319 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 320 | assertFloatEqual(t, 0, root.LayoutGetTop()) 321 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 322 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 323 | 324 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 325 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 326 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 327 | assertFloatEqual(t, 60, rootChild0.LayoutGetHeight()) 328 | 329 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 330 | assertFloatEqual(t, 60, rootChild1.LayoutGetTop()) 331 | assertFloatEqual(t, 100, rootChild1.LayoutGetWidth()) 332 | assertFloatEqual(t, 20, rootChild1.LayoutGetHeight()) 333 | 334 | assertFloatEqual(t, 0, rootChild2.LayoutGetLeft()) 335 | assertFloatEqual(t, 80, rootChild2.LayoutGetTop()) 336 | assertFloatEqual(t, 100, rootChild2.LayoutGetWidth()) 337 | assertFloatEqual(t, 20, rootChild2.LayoutGetHeight()) 338 | } 339 | 340 | func TestFlex_grow_shrink_at_most(t *testing.T) { 341 | config := NewConfig() 342 | 343 | root := NewNodeWithConfig(config) 344 | root.StyleSetWidth(100) 345 | root.StyleSetHeight(100) 346 | 347 | rootChild0 := NewNodeWithConfig(config) 348 | root.InsertChild(rootChild0, 0) 349 | 350 | rootChild0Child0 := NewNodeWithConfig(config) 351 | rootChild0Child0.StyleSetFlexGrow(1) 352 | rootChild0Child0.StyleSetFlexShrink(1) 353 | rootChild0.InsertChild(rootChild0Child0, 0) 354 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 355 | 356 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 357 | assertFloatEqual(t, 0, root.LayoutGetTop()) 358 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 359 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 360 | 361 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 362 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 363 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 364 | assertFloatEqual(t, 0, rootChild0.LayoutGetHeight()) 365 | 366 | assertFloatEqual(t, 0, rootChild0Child0.LayoutGetLeft()) 367 | assertFloatEqual(t, 0, rootChild0Child0.LayoutGetTop()) 368 | assertFloatEqual(t, 100, rootChild0Child0.LayoutGetWidth()) 369 | assertFloatEqual(t, 0, rootChild0Child0.LayoutGetHeight()) 370 | 371 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 372 | 373 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 374 | assertFloatEqual(t, 0, root.LayoutGetTop()) 375 | assertFloatEqual(t, 100, root.LayoutGetWidth()) 376 | assertFloatEqual(t, 100, root.LayoutGetHeight()) 377 | 378 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 379 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 380 | assertFloatEqual(t, 100, rootChild0.LayoutGetWidth()) 381 | assertFloatEqual(t, 0, rootChild0.LayoutGetHeight()) 382 | 383 | assertFloatEqual(t, 0, rootChild0Child0.LayoutGetLeft()) 384 | assertFloatEqual(t, 0, rootChild0Child0.LayoutGetTop()) 385 | assertFloatEqual(t, 100, rootChild0Child0.LayoutGetWidth()) 386 | assertFloatEqual(t, 0, rootChild0Child0.LayoutGetHeight()) 387 | } 388 | 389 | func TestFlex_grow_less_than_factor_one(t *testing.T) { 390 | config := NewConfig() 391 | 392 | root := NewNodeWithConfig(config) 393 | root.StyleSetWidth(200) 394 | root.StyleSetHeight(500) 395 | 396 | rootChild0 := NewNodeWithConfig(config) 397 | rootChild0.StyleSetFlexGrow(0.2) 398 | rootChild0.StyleSetFlexBasis(40) 399 | root.InsertChild(rootChild0, 0) 400 | 401 | rootChild1 := NewNodeWithConfig(config) 402 | rootChild1.StyleSetFlexGrow(0.2) 403 | root.InsertChild(rootChild1, 1) 404 | 405 | rootChild2 := NewNodeWithConfig(config) 406 | rootChild2.StyleSetFlexGrow(0.4) 407 | root.InsertChild(rootChild2, 2) 408 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 409 | 410 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 411 | assertFloatEqual(t, 0, root.LayoutGetTop()) 412 | assertFloatEqual(t, 200, root.LayoutGetWidth()) 413 | assertFloatEqual(t, 500, root.LayoutGetHeight()) 414 | 415 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 416 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 417 | assertFloatEqual(t, 200, rootChild0.LayoutGetWidth()) 418 | assertFloatEqual(t, 132, rootChild0.LayoutGetHeight()) 419 | 420 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 421 | assertFloatEqual(t, 132, rootChild1.LayoutGetTop()) 422 | assertFloatEqual(t, 200, rootChild1.LayoutGetWidth()) 423 | assertFloatEqual(t, 92, rootChild1.LayoutGetHeight()) 424 | 425 | assertFloatEqual(t, 0, rootChild2.LayoutGetLeft()) 426 | assertFloatEqual(t, 224, rootChild2.LayoutGetTop()) 427 | assertFloatEqual(t, 200, rootChild2.LayoutGetWidth()) 428 | assertFloatEqual(t, 184, rootChild2.LayoutGetHeight()) 429 | 430 | CalculateLayout(root, Undefined, Undefined, DirectionRTL) 431 | 432 | assertFloatEqual(t, 0, root.LayoutGetLeft()) 433 | assertFloatEqual(t, 0, root.LayoutGetTop()) 434 | assertFloatEqual(t, 200, root.LayoutGetWidth()) 435 | assertFloatEqual(t, 500, root.LayoutGetHeight()) 436 | 437 | assertFloatEqual(t, 0, rootChild0.LayoutGetLeft()) 438 | assertFloatEqual(t, 0, rootChild0.LayoutGetTop()) 439 | assertFloatEqual(t, 200, rootChild0.LayoutGetWidth()) 440 | assertFloatEqual(t, 132, rootChild0.LayoutGetHeight()) 441 | 442 | assertFloatEqual(t, 0, rootChild1.LayoutGetLeft()) 443 | assertFloatEqual(t, 132, rootChild1.LayoutGetTop()) 444 | assertFloatEqual(t, 200, rootChild1.LayoutGetWidth()) 445 | assertFloatEqual(t, 92, rootChild1.LayoutGetHeight()) 446 | 447 | assertFloatEqual(t, 0, rootChild2.LayoutGetLeft()) 448 | assertFloatEqual(t, 224, rootChild2.LayoutGetTop()) 449 | assertFloatEqual(t, 200, rootChild2.LayoutGetWidth()) 450 | assertFloatEqual(t, 184, rootChild2.LayoutGetHeight()) 451 | } 452 | -------------------------------------------------------------------------------- /had_overflow_test.go: -------------------------------------------------------------------------------- 1 | package flex 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func newHadOverflowTests() (*Config, *Node) { 10 | config := NewConfig() 11 | root := NewNodeWithConfig(config) 12 | root.StyleSetWidth(200) 13 | root.StyleSetHeight(100) 14 | root.StyleSetFlexDirection(FlexDirectionColumn) 15 | root.StyleSetFlexWrap(WrapNoWrap) 16 | return config, root 17 | } 18 | 19 | func TestChildren_overflow_no_wrap_and_no_flex_children(t *testing.T) { 20 | config, root := newHadOverflowTests() 21 | child0 := NewNodeWithConfig(config) 22 | child0.StyleSetWidth(80) 23 | child0.StyleSetHeight(40) 24 | child0.StyleSetMargin(EdgeTop, 10) 25 | child0.StyleSetMargin(EdgeBottom, 15) 26 | root.InsertChild(child0, 0) 27 | child1 := NewNodeWithConfig(config) 28 | child1.StyleSetWidth(80) 29 | child1.StyleSetHeight(40) 30 | child1.StyleSetMargin(EdgeBottom, 5) 31 | root.InsertChild(child1, 1) 32 | 33 | CalculateLayout(root, 200, 100, DirectionLTR) 34 | 35 | assert.True(t, root.Layout.HadOverflow) 36 | } 37 | 38 | func TestSpacing_overflow_no_wrap_and_no_flex_children(t *testing.T) { 39 | config, root := newHadOverflowTests() 40 | child0 := NewNodeWithConfig(config) 41 | child0.StyleSetWidth(80) 42 | child0.StyleSetHeight(40) 43 | child0.StyleSetMargin(EdgeTop, 10) 44 | child0.StyleSetMargin(EdgeBottom, 10) 45 | root.InsertChild(child0, 0) 46 | child1 := NewNodeWithConfig(config) 47 | child1.StyleSetWidth(80) 48 | child1.StyleSetHeight(40) 49 | child1.StyleSetMargin(EdgeBottom, 5) 50 | root.InsertChild(child1, 1) 51 | 52 | CalculateLayout(root, 200, 100, DirectionLTR) 53 | 54 | assert.True(t, root.Layout.HadOverflow) 55 | } 56 | 57 | func TestNo_overflow_no_wrap_and_flex_children(t *testing.T) { 58 | config, root := newHadOverflowTests() 59 | child0 := NewNodeWithConfig(config) 60 | child0.StyleSetWidth(80) 61 | child0.StyleSetHeight(40) 62 | child0.StyleSetMargin(EdgeTop, 10) 63 | child0.StyleSetMargin(EdgeBottom, 10) 64 | root.InsertChild(child0, 0) 65 | child1 := NewNodeWithConfig(config) 66 | child1.StyleSetWidth(80) 67 | child1.StyleSetHeight(40) 68 | child1.StyleSetMargin(EdgeBottom, 5) 69 | child1.StyleSetFlexShrink(1) 70 | root.InsertChild(child1, 1) 71 | 72 | CalculateLayout(root, 200, 100, DirectionLTR) 73 | 74 | assert.False(t, root.Layout.HadOverflow) 75 | } 76 | 77 | func TestHadOverflow_gets_reset_if_not_logger_valid(t *testing.T) { 78 | config, root := newHadOverflowTests() 79 | child0 := NewNodeWithConfig(config) 80 | child0.StyleSetWidth(80) 81 | child0.StyleSetHeight(40) 82 | child0.StyleSetMargin(EdgeTop, 10) 83 | child0.StyleSetMargin(EdgeBottom, 10) 84 | root.InsertChild(child0, 0) 85 | child1 := NewNodeWithConfig(config) 86 | child1.StyleSetWidth(80) 87 | child1.StyleSetHeight(40) 88 | child1.StyleSetMargin(EdgeBottom, 5) 89 | root.InsertChild(child1, 1) 90 | 91 | CalculateLayout(root, 200, 100, DirectionLTR) 92 | 93 | assert.True(t, root.Layout.HadOverflow) 94 | 95 | child1.StyleSetFlexShrink(1) 96 | 97 | CalculateLayout(root, 200, 100, DirectionLTR) 98 | 99 | assert.False(t, root.Layout.HadOverflow) 100 | } 101 | 102 | func TestSpacing_overflow_in_nested_nodes(t *testing.T) { 103 | config, root := newHadOverflowTests() 104 | child0 := NewNodeWithConfig(config) 105 | child0.StyleSetWidth(80) 106 | child0.StyleSetHeight(40) 107 | child0.StyleSetMargin(EdgeTop, 10) 108 | child0.StyleSetMargin(EdgeBottom, 10) 109 | root.InsertChild(child0, 0) 110 | child1 := NewNodeWithConfig(config) 111 | child1.StyleSetWidth(80) 112 | child1.StyleSetHeight(40) 113 | root.InsertChild(child1, 1) 114 | child1_1 := NewNodeWithConfig(config) 115 | child1_1.StyleSetWidth(80) 116 | child1_1.StyleSetHeight(40) 117 | child1_1.StyleSetMargin(EdgeBottom, 5) 118 | child1.InsertChild(child1_1, 0) 119 | 120 | CalculateLayout(root, 200, 100, DirectionLTR) 121 | 122 | assert.True(t, root.Layout.HadOverflow) 123 | } 124 | -------------------------------------------------------------------------------- /issue5_test.go: -------------------------------------------------------------------------------- 1 | package flex 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestIssue5(t *testing.T) { 11 | config := NewConfig() 12 | config.Context = "test" 13 | 14 | // check that "padding" set with EdgeAll is printed out 15 | root := NewNodeWithConfig(config) 16 | root.StyleSetFlexDirection(FlexDirectionColumn) 17 | root.StyleSetHeightPercent(100) 18 | 19 | child := NewNodeWithConfig(config) 20 | child.StyleSetPadding(EdgeAll, 20) 21 | root.InsertChild(child, 0) 22 | 23 | CalculateLayout(root, Undefined, Undefined, DirectionLTR) 24 | 25 | w := &bytes.Buffer{} 26 | printer := NewNodePrinter(w, PrintOptionsLayout|PrintOptionsStyle|PrintOptionsChildren) 27 | printer.Print(root) 28 | got := w.String() 29 | exp := `