okami.mom/ultraviolet
git clone https://git.nkp.pet/okami.mom/ultraviolet
227cc8b
upstream
1package layout 2 3import ( 4"fmt" 5"reflect" 6"strings" 7"testing" 8 9 uv"github.com/charmbracelet/ultraviolet" 10"github.com/charmbracelet/ultraviolet/screen" 11) 12 13func BenchmarkLayout_Split (b * testing.B ) { 14layout := Vertical (Len (2 ),Fill (1 ),Ratio {1 ,5 },Percent (10 )) 15 16area := uv .Rect (123 ,123 ,1000 ,2000 ) 17 18b .Run ("without cache" ,func (b * testing.B ) { 19for b .Loop () { 20_ ,_ ,err := layout .split (area ) 21if err != nil { 22b .Fatal (err ) 23 } 24 } 25 }) 26 27b .Run ("with cache" ,func (b * testing.B ) { 28for b .Loop () { 29_ ,_ ,err := layout .splitCached (area ) 30if err != nil { 31b .Fatal (err ) 32 } 33 } 34 }) 35} 36 37func TestPriorityIsValid (t * testing.T ) { 38t .Parallel () 39 40assert := func (ok bool ) { 41t .Helper () 42 43if ! ok { 44t .Error ("invalid priority" ) 45 } 46 } 47 48// Ensures that the constants are defined in the correct order of priority. 49 50assert (spacerSizeEq > maxSizeLTE ) 51assert (maxSizeLTE > maxSizeEq ) 52assert (minSizeGTE == maxSizeLTE ) 53assert (maxSizeLTE > lengthSizeEq ) 54assert (lengthSizeEq > percentSizeEq ) 55assert (percentSizeEq > ratioSizeEq ) 56assert (ratioSizeEq > maxSizeEq ) 57assert (minSizeGTE > fillGrow ) 58assert (fillGrow > grow ) 59assert (grow > spaceGrow ) 60assert (spaceGrow > allSegmentGrow ) 61} 62 63type LayoutSplitTestCase struct { 64Flex Flex 65Width int 66Constraints []Constraint 67Want string 68} 69 70func (tc LayoutSplitTestCase )Name ()string { 71return fmt .Sprintf ("Flex(%s) Width(%d) Constraints(%s)" ,tc .Flex ,tc .Width ,tc .Constraints ) 72} 73 74func (tc LayoutSplitTestCase )Test (t * testing.T ) { 75t .Helper () 76 77t .Parallel () 78 79letters (t ,tc .Flex ,tc .Constraints ,tc .Width ,tc .Want ) 80} 81 82func TestLength (t * testing.T ) { 83t .Parallel () 84 85testCases := []LayoutSplitTestCase { 86 {FlexLegacy ,1 , []Constraint {Len (0 )},"a" }, 87 {FlexLegacy ,1 , []Constraint {Len (1 )},"a" }, 88 {FlexLegacy ,1 , []Constraint {Len (2 )},"a" }, 89 {FlexLegacy ,2 , []Constraint {Len (0 )},"aa" }, 90 {FlexLegacy ,2 , []Constraint {Len (1 )},"aa" }, 91 {FlexLegacy ,2 , []Constraint {Len (2 )},"aa" }, 92 {FlexLegacy ,2 , []Constraint {Len (3 )},"aa" }, 93 {FlexLegacy ,1 , []Constraint {Len (0 ),Len (0 )},"b" }, 94 {FlexLegacy ,1 , []Constraint {Len (0 ),Len (1 )},"b" }, 95 {FlexLegacy ,1 , []Constraint {Len (0 ),Len (2 )},"b" }, 96 {FlexLegacy ,1 , []Constraint {Len (1 ),Len (0 )},"a" }, 97 {FlexLegacy ,1 , []Constraint {Len (1 ),Len (1 )},"a" }, 98 {FlexLegacy ,1 , []Constraint {Len (1 ),Len (2 )},"a" }, 99 {FlexLegacy ,1 , []Constraint {Len (2 ),Len (0 )},"a" }, 100 {FlexLegacy ,1 , []Constraint {Len (2 ),Len (1 )},"a" }, 101 {FlexLegacy ,1 , []Constraint {Len (2 ),Len (2 )},"a" }, 102 {FlexLegacy ,2 , []Constraint {Len (0 ),Len (0 )},"bb" }, 103 {FlexLegacy ,2 , []Constraint {Len (0 ),Len (1 )},"bb" }, 104 {FlexLegacy ,2 , []Constraint {Len (0 ),Len (2 )},"bb" }, 105 {FlexLegacy ,2 , []Constraint {Len (0 ),Len (3 )},"bb" }, 106 {FlexLegacy ,2 , []Constraint {Len (1 ),Len (0 )},"ab" }, 107 {FlexLegacy ,2 , []Constraint {Len (1 ),Len (1 )},"ab" }, 108 {FlexLegacy ,2 , []Constraint {Len (1 ),Len (2 )},"ab" }, 109 {FlexLegacy ,2 , []Constraint {Len (1 ),Len (3 )},"ab" }, 110 {FlexLegacy ,2 , []Constraint {Len (2 ),Len (0 )},"aa" }, 111 {FlexLegacy ,2 , []Constraint {Len (2 ),Len (1 )},"aa" }, 112 {FlexLegacy ,2 , []Constraint {Len (2 ),Len (2 )},"aa" }, 113 {FlexLegacy ,2 , []Constraint {Len (2 ),Len (3 )},"aa" }, 114 {FlexLegacy ,2 , []Constraint {Len (3 ),Len (0 )},"aa" }, 115 {FlexLegacy ,2 , []Constraint {Len (3 ),Len (1 )},"aa" }, 116 {FlexLegacy ,2 , []Constraint {Len (3 ),Len (2 )},"aa" }, 117 {FlexLegacy ,2 , []Constraint {Len (3 ),Len (3 )},"aa" }, 118 {FlexLegacy ,3 , []Constraint {Len (2 ),Len (2 )},"aab" }, 119 } 120 121for _ ,tc := range testCases { 122t .Run (tc .Name (),tc .Test ) 123 } 124} 125 126func TestMax (t * testing.T ) { 127t .Parallel () 128 129testCases := []LayoutSplitTestCase { 130 {FlexLegacy ,1 , []Constraint {Max (0 )},"a" }, 131 {FlexLegacy ,1 , []Constraint {Max (1 )},"a" }, 132 {FlexLegacy ,1 , []Constraint {Max (2 )},"a" }, 133 {FlexLegacy ,2 , []Constraint {Max (0 )},"aa" }, 134 {FlexLegacy ,2 , []Constraint {Max (1 )},"aa" }, 135 {FlexLegacy ,2 , []Constraint {Max (2 )},"aa" }, 136 {FlexLegacy ,2 , []Constraint {Max (3 )},"aa" }, 137 {FlexLegacy ,1 , []Constraint {Max (0 ),Max (0 )},"b" }, 138 {FlexLegacy ,1 , []Constraint {Max (0 ),Max (1 )},"b" }, 139 {FlexLegacy ,1 , []Constraint {Max (0 ),Max (2 )},"b" }, 140 {FlexLegacy ,1 , []Constraint {Max (1 ),Max (0 )},"a" }, 141 {FlexLegacy ,1 , []Constraint {Max (1 ),Max (1 )},"a" }, 142 {FlexLegacy ,1 , []Constraint {Max (1 ),Max (2 )},"a" }, 143 {FlexLegacy ,1 , []Constraint {Max (2 ),Max (0 )},"a" }, 144 {FlexLegacy ,1 , []Constraint {Max (2 ),Max (1 )},"a" }, 145 {FlexLegacy ,1 , []Constraint {Max (2 ),Max (2 )},"a" }, 146 {FlexLegacy ,2 , []Constraint {Max (0 ),Max (0 )},"bb" }, 147 {FlexLegacy ,2 , []Constraint {Max (0 ),Max (1 )},"bb" }, 148 {FlexLegacy ,2 , []Constraint {Max (0 ),Max (2 )},"bb" }, 149 {FlexLegacy ,2 , []Constraint {Max (0 ),Max (3 )},"bb" }, 150 {FlexLegacy ,2 , []Constraint {Max (1 ),Max (0 )},"ab" }, 151 {FlexLegacy ,2 , []Constraint {Max (1 ),Max (1 )},"ab" }, 152 {FlexLegacy ,2 , []Constraint {Max (1 ),Max (2 )},"ab" }, 153 {FlexLegacy ,2 , []Constraint {Max (1 ),Max (3 )},"ab" }, 154 {FlexLegacy ,2 , []Constraint {Max (2 ),Max (0 )},"aa" }, 155 {FlexLegacy ,2 , []Constraint {Max (2 ),Max (1 )},"aa" }, 156 {FlexLegacy ,2 , []Constraint {Max (2 ),Max (2 )},"aa" }, 157 {FlexLegacy ,2 , []Constraint {Max (2 ),Max (3 )},"aa" }, 158 {FlexLegacy ,2 , []Constraint {Max (3 ),Max (0 )},"aa" }, 159 {FlexLegacy ,2 , []Constraint {Max (3 ),Max (1 )},"aa" }, 160 {FlexLegacy ,2 , []Constraint {Max (3 ),Max (2 )},"aa" }, 161 {FlexLegacy ,2 , []Constraint {Max (3 ),Max (3 )},"aa" }, 162 {FlexLegacy ,3 , []Constraint {Max (2 ),Max (2 )},"aab" }, 163 } 164 165for _ ,tc := range testCases { 166t .Run (tc .Name (),tc .Test ) 167 } 168} 169 170func TestMin (t * testing.T ) { 171t .Parallel () 172 173testCases := []LayoutSplitTestCase { 174 {FlexLegacy ,1 , []Constraint {Min (0 ),Min (0 )},"b" }, 175 {FlexLegacy ,1 , []Constraint {Min (0 ),Min (1 )},"b" }, 176 {FlexLegacy ,1 , []Constraint {Min (0 ),Min (2 )},"b" }, 177 {FlexLegacy ,1 , []Constraint {Min (1 ),Min (0 )},"a" }, 178 {FlexLegacy ,1 , []Constraint {Min (1 ),Min (1 )},"a" }, 179 {FlexLegacy ,1 , []Constraint {Min (1 ),Min (2 )},"a" }, 180 {FlexLegacy ,1 , []Constraint {Min (2 ),Min (0 )},"a" }, 181 {FlexLegacy ,1 , []Constraint {Min (2 ),Min (1 )},"a" }, 182 {FlexLegacy ,1 , []Constraint {Min (2 ),Min (2 )},"a" }, 183 {FlexLegacy ,2 , []Constraint {Min (0 ),Min (0 )},"bb" }, 184 {FlexLegacy ,2 , []Constraint {Min (0 ),Min (1 )},"bb" }, 185 {FlexLegacy ,2 , []Constraint {Min (0 ),Min (2 )},"bb" }, 186 {FlexLegacy ,2 , []Constraint {Min (0 ),Min (3 )},"bb" }, 187 {FlexLegacy ,2 , []Constraint {Min (1 ),Min (0 )},"ab" }, 188 {FlexLegacy ,2 , []Constraint {Min (1 ),Min (1 )},"ab" }, 189 {FlexLegacy ,2 , []Constraint {Min (1 ),Min (2 )},"ab" }, 190 {FlexLegacy ,2 , []Constraint {Min (1 ),Min (3 )},"ab" }, 191 {FlexLegacy ,2 , []Constraint {Min (2 ),Min (0 )},"aa" }, 192 {FlexLegacy ,2 , []Constraint {Min (2 ),Min (1 )},"aa" }, 193 {FlexLegacy ,2 , []Constraint {Min (2 ),Min (2 )},"aa" }, 194 {FlexLegacy ,2 , []Constraint {Min (2 ),Min (3 )},"aa" }, 195 {FlexLegacy ,2 , []Constraint {Min (3 ),Min (0 )},"aa" }, 196 {FlexLegacy ,2 , []Constraint {Min (3 ),Min (1 )},"aa" }, 197 {FlexLegacy ,2 , []Constraint {Min (3 ),Min (2 )},"aa" }, 198 {FlexLegacy ,2 , []Constraint {Min (3 ),Min (3 )},"aa" }, 199 {FlexLegacy ,3 , []Constraint {Min (2 ),Min (2 )},"aab" }, 200 } 201 202for _ ,tc := range testCases { 203t .Run (tc .Name (),tc .Test ) 204 } 205} 206 207func TestPercent (t * testing.T ) { 208t .Parallel () 209 210testCases := []LayoutSplitTestCase { 211 {FlexStart ,10 , []Constraint {Percent (0 ),Percent (0 )}," " }, 212 {FlexStart ,10 , []Constraint {Percent (0 ),Percent (25 )},"bbb " }, 213 {FlexStart ,10 , []Constraint {Percent (0 ),Percent (50 )},"bbbbb " }, 214 {FlexStart ,10 , []Constraint {Percent (0 ),Percent (100 )},"bbbbbbbbbb" }, 215 {FlexStart ,10 , []Constraint {Percent (0 ),Percent (200 )},"bbbbbbbbbb" }, 216 {FlexStart ,10 , []Constraint {Percent (10 ),Percent (0 )},"a " }, 217 {FlexStart ,10 , []Constraint {Percent (10 ),Percent (25 )},"abbb " }, 218 {FlexStart ,10 , []Constraint {Percent (10 ),Percent (50 )},"abbbbb " }, 219 {FlexStart ,10 , []Constraint {Percent (10 ),Percent (100 )},"abbbbbbbbb" }, 220 {FlexStart ,10 , []Constraint {Percent (10 ),Percent (200 )},"abbbbbbbbb" }, 221 {FlexStart ,10 , []Constraint {Percent (25 ),Percent (0 )},"aaa " }, 222 {FlexStart ,10 , []Constraint {Percent (25 ),Percent (25 )},"aaabb " }, 223 {FlexStart ,10 , []Constraint {Percent (25 ),Percent (50 )},"aaabbbbb " }, 224 {FlexStart ,10 , []Constraint {Percent (25 ),Percent (100 )},"aaabbbbbbb" }, 225 {FlexStart ,10 , []Constraint {Percent (25 ),Percent (200 )},"aaabbbbbbb" }, 226 {FlexStart ,10 , []Constraint {Percent (33 ),Percent (0 )},"aaa " }, 227 {FlexStart ,10 , []Constraint {Percent (33 ),Percent (25 )},"aaabbb " }, 228 {FlexStart ,10 , []Constraint {Percent (33 ),Percent (50 )},"aaabbbbb " }, 229 {FlexStart ,10 , []Constraint {Percent (33 ),Percent (100 )},"aaabbbbbbb" }, 230 {FlexStart ,10 , []Constraint {Percent (33 ),Percent (200 )},"aaabbbbbbb" }, 231 {FlexStart ,10 , []Constraint {Percent (50 ),Percent (0 )},"aaaaa " }, 232 {FlexStart ,10 , []Constraint {Percent (50 ),Percent (50 )},"aaaaabbbbb" }, 233 {FlexStart ,10 , []Constraint {Percent (50 ),Percent (100 )},"aaaaabbbbb" }, 234 {FlexStart ,10 , []Constraint {Percent (100 ),Percent (0 )},"aaaaaaaaaa" }, 235 {FlexStart ,10 , []Constraint {Percent (100 ),Percent (50 )},"aaaaabbbbb" }, 236 {FlexStart ,10 , []Constraint {Percent (100 ),Percent (100 )},"aaaaabbbbb" }, 237 {FlexStart ,10 , []Constraint {Percent (100 ),Percent (200 )},"aaaaabbbbb" }, 238 {FlexSpaceBetween ,10 , []Constraint {Percent (0 ),Percent (0 )}," " }, 239 {FlexSpaceBetween ,10 , []Constraint {Percent (0 ),Percent (25 )}," bb" }, 240 {FlexSpaceBetween ,10 , []Constraint {Percent (0 ),Percent (50 )}," bbbbb" }, 241 {FlexSpaceBetween ,10 , []Constraint {Percent (0 ),Percent (100 )},"bbbbbbbbbb" }, 242 {FlexSpaceBetween ,10 , []Constraint {Percent (0 ),Percent (200 )},"bbbbbbbbbb" }, 243 {FlexSpaceBetween ,10 , []Constraint {Percent (10 ),Percent (0 )},"a " }, 244 {FlexSpaceBetween ,10 , []Constraint {Percent (10 ),Percent (25 )},"a bb" }, 245 {FlexSpaceBetween ,10 , []Constraint {Percent (10 ),Percent (50 )},"a bbbbb" }, 246 {FlexSpaceBetween ,10 , []Constraint {Percent (10 ),Percent (100 )},"abbbbbbbbb" }, 247 {FlexSpaceBetween ,10 , []Constraint {Percent (10 ),Percent (200 )},"abbbbbbbbb" }, 248 {FlexSpaceBetween ,10 , []Constraint {Percent (25 ),Percent (0 )},"aaa " }, 249 {FlexSpaceBetween ,10 , []Constraint {Percent (25 ),Percent (25 )},"aaa bb" }, 250 {FlexSpaceBetween ,10 , []Constraint {Percent (25 ),Percent (50 )},"aaa bbbbb" }, 251 {FlexSpaceBetween ,10 , []Constraint {Percent (25 ),Percent (100 )},"aaabbbbbbb" }, 252 {FlexLegacy ,10 , []Constraint {Percent (25 ),Percent (200 )},"aaabbbbbbb" }, 253 {FlexSpaceBetween ,10 , []Constraint {Percent (33 ),Percent (0 )},"aaa " }, 254 {FlexSpaceBetween ,10 , []Constraint {Percent (33 ),Percent (25 )},"aaa bb" }, 255 {FlexSpaceBetween ,10 , []Constraint {Percent (33 ),Percent (50 )},"aaa bbbbb" }, 256 {FlexSpaceBetween ,10 , []Constraint {Percent (33 ),Percent (100 )},"aaabbbbbbb" }, 257 {FlexSpaceBetween ,10 , []Constraint {Percent (33 ),Percent (200 )},"aaabbbbbbb" }, 258 {FlexSpaceBetween ,10 , []Constraint {Percent (50 ),Percent (0 )},"aaaaa " }, 259 {FlexSpaceBetween ,10 , []Constraint {Percent (50 ),Percent (50 )},"aaaaabbbbb" }, 260 {FlexSpaceBetween ,10 , []Constraint {Percent (50 ),Percent (100 )},"aaaaabbbbb" }, 261 {FlexSpaceBetween ,10 , []Constraint {Percent (100 ),Percent (0 )},"aaaaaaaaaa" }, 262 {FlexSpaceBetween ,10 , []Constraint {Percent (100 ),Percent (50 )},"aaaaabbbbb" }, 263 {FlexSpaceBetween ,10 , []Constraint {Percent (100 ),Percent (100 )},"aaaaabbbbb" }, 264 {FlexSpaceBetween ,10 , []Constraint {Percent (100 ),Percent (200 )},"aaaaabbbbb" }, 265 } 266 267for _ ,tc := range testCases { 268t .Run (tc .Name (),tc .Test ) 269 } 270} 271 272func TestRatio (t * testing.T ) { 273t .Parallel () 274 275testCases := []LayoutSplitTestCase { 276 {FlexLegacy ,1 , []Constraint {Ratio {0 ,1 }},"a" }, 277 {FlexLegacy ,1 , []Constraint {Ratio {0 ,1 }},"a" }, 278 {FlexLegacy ,2 , []Constraint {Ratio {0 ,1 }},"aa" }, 279 {FlexLegacy ,10 , []Constraint {Ratio {0 ,1 },Ratio {0 ,1 }},"bbbbbbbbbb" }, 280 {FlexLegacy ,10 , []Constraint {Ratio {0 ,1 },Ratio {1 ,4 }},"bbbbbbbbbb" }, 281 {FlexLegacy ,10 , []Constraint {Ratio {0 ,1 },Ratio {1 ,2 }},"bbbbbbbbbb" }, 282 {FlexLegacy ,10 , []Constraint {Ratio {0 ,1 },Ratio {1 ,1 }},"bbbbbbbbbb" }, 283 {FlexLegacy ,10 , []Constraint {Ratio {0 ,1 },Ratio {2 ,1 }},"bbbbbbbbbb" }, 284 {FlexLegacy ,10 , []Constraint {Ratio {1 ,10 },Ratio {0 ,1 }},"abbbbbbbbb" }, 285 {FlexLegacy ,10 , []Constraint {Ratio {1 ,10 },Ratio {1 ,4 }},"abbbbbbbbb" }, 286 {FlexLegacy ,10 , []Constraint {Ratio {1 ,10 },Ratio {1 ,2 }},"abbbbbbbbb" }, 287 {FlexLegacy ,10 , []Constraint {Ratio {1 ,10 },Ratio {1 ,1 }},"abbbbbbbbb" }, 288 {FlexLegacy ,10 , []Constraint {Ratio {1 ,10 },Ratio {2 ,1 }},"abbbbbbbbb" }, 289 {FlexLegacy ,10 , []Constraint {Ratio {1 ,4 },Ratio {0 ,1 }},"aaabbbbbbb" }, 290 {FlexLegacy ,10 , []Constraint {Ratio {1 ,4 },Ratio {1 ,4 }},"aaabbbbbbb" }, 291 {FlexLegacy ,10 , []Constraint {Ratio {1 ,4 },Ratio {1 ,2 }},"aaabbbbbbb" }, 292 {FlexLegacy ,10 , []Constraint {Ratio {1 ,4 },Ratio {1 ,1 }},"aaabbbbbbb" }, 293 {FlexLegacy ,10 , []Constraint {Ratio {1 ,4 },Ratio {2 ,1 }},"aaabbbbbbb" }, 294 {FlexLegacy ,10 , []Constraint {Ratio {1 ,3 },Ratio {0 ,1 }},"aaabbbbbbb" }, 295 {FlexLegacy ,10 , []Constraint {Ratio {1 ,3 },Ratio {1 ,4 }},"aaabbbbbbb" }, 296 {FlexLegacy ,10 , []Constraint {Ratio {1 ,3 },Ratio {1 ,2 }},"aaabbbbbbb" }, 297 {FlexLegacy ,10 , []Constraint {Ratio {1 ,3 },Ratio {1 ,1 }},"aaabbbbbbb" }, 298 {FlexLegacy ,10 , []Constraint {Ratio {1 ,3 },Ratio {2 ,1 }},"aaabbbbbbb" }, 299 {FlexLegacy ,10 , []Constraint {Ratio {1 ,2 },Ratio {0 ,1 }},"aaaaabbbbb" }, 300 {FlexLegacy ,10 , []Constraint {Ratio {1 ,2 },Ratio {1 ,2 }},"aaaaabbbbb" }, 301 {FlexLegacy ,10 , []Constraint {Ratio {1 ,2 },Ratio {1 ,1 }},"aaaaabbbbb" }, 302 {FlexLegacy ,10 , []Constraint {Ratio {1 ,1 },Ratio {0 ,1 }},"aaaaaaaaaa" }, 303 {FlexLegacy ,10 , []Constraint {Ratio {1 ,1 },Ratio {1 ,2 }},"aaaaaaaaaa" }, 304 {FlexLegacy ,10 , []Constraint {Ratio {1 ,1 },Ratio {1 ,1 }},"aaaaaaaaaa" }, 305 {FlexStart ,10 , []Constraint {Ratio {0 ,1 },Ratio {0 ,1 }}," " }, 306 {FlexStart ,10 , []Constraint {Ratio {0 ,1 },Ratio {1 ,4 }},"bbb " }, 307 {FlexStart ,10 , []Constraint {Ratio {0 ,1 },Ratio {1 ,2 }},"bbbbb " }, 308 {FlexStart ,10 , []Constraint {Ratio {0 ,1 },Ratio {1 ,1 }},"bbbbbbbbbb" }, 309 {FlexStart ,10 , []Constraint {Ratio {0 ,1 },Ratio {2 ,1 }},"bbbbbbbbbb" }, 310 {FlexStart ,10 , []Constraint {Ratio {1 ,10 },Ratio {0 ,1 }},"a " }, 311 {FlexStart ,10 , []Constraint {Ratio {1 ,10 },Ratio {1 ,4 }},"abbb " }, 312 {FlexStart ,10 , []Constraint {Ratio {1 ,10 },Ratio {1 ,2 }},"abbbbb " }, 313 {FlexStart ,10 , []Constraint {Ratio {1 ,10 },Ratio {1 ,1 }},"abbbbbbbbb" }, 314 {FlexStart ,10 , []Constraint {Ratio {1 ,10 },Ratio {2 ,1 }},"abbbbbbbbb" }, 315 {FlexStart ,10 , []Constraint {Ratio {1 ,4 },Ratio {0 ,1 }},"aaa " }, 316 {FlexStart ,10 , []Constraint {Ratio {1 ,4 },Ratio {1 ,4 }},"aaabb " }, 317 {FlexStart ,10 , []Constraint {Ratio {1 ,4 },Ratio {1 ,2 }},"aaabbbbb " }, 318 {FlexStart ,10 , []Constraint {Ratio {1 ,4 },Ratio {1 ,1 }},"aaabbbbbbb" }, 319 {FlexStart ,10 , []Constraint {Ratio {1 ,4 },Ratio {2 ,1 }},"aaabbbbbbb" }, 320 {FlexStart ,10 , []Constraint {Ratio {1 ,3 },Ratio {0 ,1 }},"aaa " }, 321 {FlexStart ,10 , []Constraint {Ratio {1 ,3 },Ratio {1 ,4 }},"aaabbb " }, 322 {FlexStart ,10 , []Constraint {Ratio {1 ,3 },Ratio {1 ,2 }},"aaabbbbb " }, 323 {FlexStart ,10 , []Constraint {Ratio {1 ,3 },Ratio {1 ,1 }},"aaabbbbbbb" }, 324 {FlexStart ,10 , []Constraint {Ratio {1 ,3 },Ratio {2 ,1 }},"aaabbbbbbb" }, 325 {FlexStart ,10 , []Constraint {Ratio {1 ,2 },Ratio {0 ,1 }},"aaaaa " }, 326 {FlexStart ,10 , []Constraint {Ratio {1 ,2 },Ratio {1 ,2 }},"aaaaabbbbb" }, 327 {FlexStart ,10 , []Constraint {Ratio {1 ,2 },Ratio {1 ,1 }},"aaaaabbbbb" }, 328 {FlexStart ,10 , []Constraint {Ratio {1 ,1 },Ratio {0 ,1 }},"aaaaaaaaaa" }, 329 {FlexStart ,10 , []Constraint {Ratio {1 ,1 },Ratio {1 ,2 }},"aaaaabbbbb" }, 330 {FlexStart ,10 , []Constraint {Ratio {1 ,1 },Ratio {1 ,1 }},"aaaaabbbbb" }, 331 {FlexStart ,10 , []Constraint {Ratio {1 ,1 },Ratio {2 ,1 }},"aaaaabbbbb" }, 332 {FlexSpaceBetween ,10 , []Constraint {Ratio {0 ,1 },Ratio {0 ,1 }}," " }, 333 {FlexSpaceBetween ,10 , []Constraint {Ratio {0 ,1 },Ratio {1 ,4 }}," bb" }, 334 {FlexSpaceBetween ,10 , []Constraint {Ratio {0 ,1 },Ratio {1 ,2 }}," bbbbb" }, 335 {FlexSpaceBetween ,10 , []Constraint {Ratio {0 ,1 },Ratio {1 ,1 }},"bbbbbbbbbb" }, 336 {FlexSpaceBetween ,10 , []Constraint {Ratio {0 ,1 },Ratio {2 ,1 }},"bbbbbbbbbb" }, 337 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,10 },Ratio {0 ,1 }},"a " }, 338 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,10 },Ratio {1 ,4 }},"a bb" }, 339 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,10 },Ratio {1 ,2 }},"a bbbbb" }, 340 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,10 },Ratio {1 ,1 }},"abbbbbbbbb" }, 341 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,10 },Ratio {2 ,1 }},"abbbbbbbbb" }, 342 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,4 },Ratio {0 ,1 }},"aaa " }, 343 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,4 },Ratio {1 ,4 }},"aaa bb" }, 344 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,4 },Ratio {1 ,2 }},"aaa bbbbb" }, 345 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,4 },Ratio {1 ,1 }},"aaabbbbbbb" }, 346 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,4 },Ratio {2 ,1 }},"aaabbbbbbb" }, 347 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,3 },Ratio {0 ,1 }},"aaa " }, 348 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,3 },Ratio {1 ,4 }},"aaa bb" }, 349 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,3 },Ratio {1 ,2 }},"aaa bbbbb" }, 350 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,3 },Ratio {1 ,1 }},"aaabbbbbbb" }, 351 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,3 },Ratio {2 ,1 }},"aaabbbbbbb" }, 352 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,2 },Ratio {0 ,1 }},"aaaaa " }, 353 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,2 },Ratio {1 ,2 }},"aaaaabbbbb" }, 354 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,2 },Ratio {1 ,1 }},"aaaaabbbbb" }, 355 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,1 },Ratio {0 ,1 }},"aaaaaaaaaa" }, 356 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,1 },Ratio {1 ,2 }},"aaaaabbbbb" }, 357 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,1 },Ratio {1 ,1 }},"aaaaabbbbb" }, 358 {FlexSpaceBetween ,10 , []Constraint {Ratio {1 ,1 },Ratio {2 ,1 }},"aaaaabbbbb" }, 359 } 360 361for _ ,tc := range testCases { 362t .Run (tc .Name (),tc .Test ) 363 } 364} 365 366type Rect = uv.Rectangle 367 368func TestEdgeCases (t * testing.T ) { 369t .Parallel () 370 371testCases := []struct { 372name string 373constraints []Constraint 374direction Direction 375split Rect 376want Splitted 377 }{ 378 { 379name :"50% 50% min(0) stretches into last" , 380constraints : []Constraint { 381Percent (50 ), 382Percent (50 ), 383Min (0 ), 384 }, 385direction :DirectionVertical , 386split :uv .Rect (0 ,0 ,1 ,1 ), 387want : []Rect { 388uv .Rect (0 ,0 ,1 ,1 ), 389uv .Rect (0 ,1 ,1 ,0 ), 390uv .Rect (0 ,1 ,1 ,0 ), 391 }, 392 }, 393 { 394name :"max(1) 99% min(0) stretches into last" , 395constraints : []Constraint { 396Max (1 ), 397Percent (99 ), 398Min (0 ), 399 }, 400direction :DirectionVertical , 401split :uv .Rect (0 ,0 ,1 ,1 ), 402want : []Rect { 403uv .Rect (0 ,0 ,1 ,0 ), 404uv .Rect (0 ,0 ,1 ,1 ), 405uv .Rect (0 ,1 ,1 ,0 ), 406 }, 407 }, 408 { 409name :"min(1) length(0) min(1)" , 410constraints : []Constraint { 411Min (1 ), 412Len (0 ), 413Min (1 ), 414 }, 415direction :DirectionHorizontal , 416split :uv .Rect (0 ,0 ,1 ,1 ), 417want : []Rect { 418uv .Rect (0 ,0 ,1 ,1 ), 419uv .Rect (1 ,0 ,0 ,1 ), 420uv .Rect (1 ,0 ,0 ,1 ), 421 }, 422 }, 423 { 424name :"stretches the 2nd last length instead of the last min based on ranking" , 425constraints : []Constraint { 426Len (3 ), 427Min (4 ), 428Len (1 ), 429Min (4 ), 430 }, 431direction :DirectionHorizontal , 432split :uv .Rect (0 ,0 ,7 ,1 ), 433want : []Rect { 434uv .Rect (0 ,0 ,0 ,1 ), 435uv .Rect (0 ,0 ,4 ,1 ), 436uv .Rect (4 ,0 ,0 ,1 ), 437uv .Rect (4 ,0 ,3 ,1 ), 438 }, 439 }, 440 } 441 442for _ ,tc := range testCases { 443t .Run (tc .name ,func (t * testing.T ) { 444t .Parallel () 445 446layout := Layout { 447Constraints :tc .constraints , 448Direction :tc .direction , 449 }.Split (tc .split ) 450 451if ! reflect .DeepEqual (tc .want ,layout ) { 452t .Fatalf ("not equal: want %#+v, got %#+v" ,tc .want ,layout ) 453 } 454 }) 455 } 456} 457 458func TestFlexConstraint (t * testing.T ) { 459t .Parallel () 460 461testCases := []struct { 462name string 463constraints []Constraint 464want [][]int 465flex Flex 466 }{ 467 { 468name :"length legacy" , 469constraints : []Constraint { 470Len (50 ), 471 }, 472want : [][]int {{0 ,100 }}, 473flex :FlexLegacy , 474 }, 475 { 476name :"length start" , 477constraints : []Constraint { 478Len (50 ), 479 }, 480want : [][]int {{0 ,50 }}, 481flex :FlexStart , 482 }, 483 { 484name :"length end" , 485constraints : []Constraint { 486Len (50 ), 487 }, 488want : [][]int {{50 ,100 }}, 489flex :FlexEnd , 490 }, 491 { 492name :"length end" , 493constraints : []Constraint { 494Len (50 ), 495 }, 496want : [][]int {{25 ,75 }}, 497flex :FlexCenter , 498 }, 499 { 500name :"ratio legacy" , 501constraints : []Constraint { 502Ratio {1 ,2 }, 503 }, 504want : [][]int {{0 ,100 }}, 505flex :FlexLegacy , 506 }, 507 { 508name :"ratio start" , 509constraints : []Constraint { 510Ratio {1 ,2 }, 511 }, 512want : [][]int {{0 ,50 }}, 513flex :FlexStart , 514 }, 515 { 516name :"ratio end" , 517constraints : []Constraint { 518Ratio {1 ,2 }, 519 }, 520want : [][]int {{50 ,100 }}, 521flex :FlexEnd , 522 }, 523 { 524name :"ratio center" , 525constraints : []Constraint { 526Ratio {1 ,2 }, 527 }, 528want : [][]int {{25 ,75 }}, 529flex :FlexCenter , 530 }, 531 { 532name :"percent legacy" , 533constraints : []Constraint { 534Percent (50 ), 535 }, 536want : [][]int {{0 ,100 }}, 537flex :FlexLegacy , 538 }, 539 { 540name :"percent start" , 541constraints : []Constraint { 542Percent (50 ), 543 }, 544want : [][]int {{0 ,50 }}, 545flex :FlexStart , 546 }, 547 { 548name :"percent end" , 549constraints : []Constraint { 550Percent (50 ), 551 }, 552want : [][]int {{50 ,100 }}, 553flex :FlexEnd , 554 }, 555 { 556name :"percent center" , 557constraints : []Constraint { 558Percent (50 ), 559 }, 560want : [][]int {{25 ,75 }}, 561flex :FlexCenter , 562 }, 563 { 564name :"min legacy" , 565constraints : []Constraint { 566Min (50 ), 567 }, 568want : [][]int {{0 ,100 }}, 569flex :FlexLegacy , 570 }, 571 { 572name :"min start" , 573constraints : []Constraint { 574Min (50 ), 575 }, 576want : [][]int {{0 ,100 }}, 577flex :FlexStart , 578 }, 579 { 580name :"min end" , 581constraints : []Constraint { 582Min (50 ), 583 }, 584want : [][]int {{0 ,100 }}, 585flex :FlexEnd , 586 }, 587 { 588name :"min center" , 589constraints : []Constraint { 590Min (50 ), 591 }, 592want : [][]int {{0 ,100 }}, 593flex :FlexCenter , 594 }, 595 { 596name :"min legacy" , 597constraints : []Constraint { 598Min (50 ), 599 }, 600want : [][]int {{0 ,100 }}, 601flex :FlexLegacy , 602 }, 603 { 604name :"max legacy" , 605constraints : []Constraint { 606Max (50 ), 607 }, 608want : [][]int {{0 ,100 }}, 609flex :FlexLegacy , 610 }, 611 { 612name :"max start" , 613constraints : []Constraint { 614Max (50 ), 615 }, 616want : [][]int {{0 ,50 }}, 617flex :FlexStart , 618 }, 619 { 620name :"max end" , 621constraints : []Constraint { 622Max (50 ), 623 }, 624want : [][]int {{50 ,100 }}, 625flex :FlexEnd , 626 }, 627 { 628name :"max center" , 629constraints : []Constraint { 630Max (50 ), 631 }, 632want : [][]int {{25 ,75 }}, 633flex :FlexCenter , 634 }, 635 { 636name :"space between becomes stretch" , 637constraints : []Constraint { 638Min (1 ), 639 }, 640want : [][]int {{0 ,100 }}, 641flex :FlexSpaceBetween , 642 }, 643 { 644name :"space between becomes stretch" , 645constraints : []Constraint { 646Max (20 ), 647 }, 648want : [][]int {{0 ,100 }}, 649flex :FlexSpaceBetween , 650 }, 651 { 652name :"space between becomes stretch" , 653constraints : []Constraint { 654Len (20 ), 655 }, 656want : [][]int {{0 ,100 }}, 657flex :FlexSpaceBetween , 658 }, 659 { 660name :"len legacy 2" , 661constraints : []Constraint { 662Len (25 ),Len (25 ), 663 }, 664want : [][]int {{0 ,25 }, {25 ,100 }}, 665flex :FlexLegacy , 666 }, 667 { 668name :"len start 2" , 669constraints : []Constraint { 670Len (25 ),Len (25 ), 671 }, 672want : [][]int {{0 ,25 }, {25 ,50 }}, 673flex :FlexStart , 674 }, 675 { 676name :"len center 2" , 677constraints : []Constraint { 678Len (25 ),Len (25 ), 679 }, 680want : [][]int {{25 ,50 }, {50 ,75 }}, 681flex :FlexCenter , 682 }, 683 { 684name :"len end 2" , 685constraints : []Constraint { 686Len (25 ),Len (25 ), 687 }, 688want : [][]int {{50 ,75 }, {75 ,100 }}, 689flex :FlexEnd , 690 }, 691 { 692name :"len space between" , 693constraints : []Constraint { 694Len (25 ),Len (25 ), 695 }, 696want : [][]int {{0 ,25 }, {75 ,100 }}, 697flex :FlexSpaceBetween , 698 }, 699 { 700name :"len space evenly" , 701constraints : []Constraint { 702Len (25 ),Len (25 ), 703 }, 704want : [][]int {{17 ,42 }, {58 ,83 }}, 705flex :FlexSpaceEvenly , 706 }, 707 { 708name :"len space around" , 709constraints : []Constraint { 710Len (25 ),Len (25 ), 711 }, 712want : [][]int {{13 ,38 }, {63 ,88 }}, 713flex :FlexSpaceAround , 714 }, 715 { 716name :"percentage around" , 717constraints : []Constraint { 718Percent (25 ),Percent (25 ), 719 }, 720want : [][]int {{0 ,25 }, {25 ,100 }}, 721flex :FlexLegacy , 722 }, 723 { 724name :"percentage start" , 725constraints : []Constraint { 726Percent (25 ),Percent (25 ), 727 }, 728want : [][]int {{0 ,25 }, {25 ,50 }}, 729flex :FlexStart , 730 }, 731 { 732name :"percentage center" , 733constraints : []Constraint { 734Percent (25 ),Percent (25 ), 735 }, 736want : [][]int {{25 ,50 }, {50 ,75 }}, 737flex :FlexCenter , 738 }, 739 { 740name :"percentage end" , 741constraints : []Constraint { 742Percent (25 ),Percent (25 ), 743 }, 744want : [][]int {{50 ,75 }, {75 ,100 }}, 745flex :FlexEnd , 746 }, 747 { 748name :"percentage space between" , 749constraints : []Constraint { 750Percent (25 ),Percent (25 ), 751 }, 752want : [][]int {{0 ,25 }, {75 ,100 }}, 753flex :FlexSpaceBetween , 754 }, 755 { 756name :"percentage space evenly" , 757constraints : []Constraint { 758Percent (25 ),Percent (25 ), 759 }, 760want : [][]int {{17 ,42 }, {58 ,83 }}, 761flex :FlexSpaceEvenly , 762 }, 763 { 764name :"percentage space around" , 765constraints : []Constraint { 766Percent (25 ),Percent (25 ), 767 }, 768want : [][]int {{13 ,38 }, {63 ,88 }}, 769flex :FlexSpaceAround , 770 }, 771 { 772name :"min legacy 2" , 773constraints : []Constraint { 774Min (25 ),Min (25 ), 775 }, 776want : [][]int {{0 ,25 }, {25 ,100 }}, 777flex :FlexLegacy , 778 }, 779 { 780name :"min start 2" , 781constraints : []Constraint { 782Min (25 ),Min (25 ), 783 }, 784want : [][]int {{0 ,50 }, {50 ,100 }}, 785flex :FlexStart , 786 }, 787 { 788name :"min center 2" , 789constraints : []Constraint { 790Min (25 ),Min (25 ), 791 }, 792want : [][]int {{0 ,50 }, {50 ,100 }}, 793flex :FlexCenter , 794 }, 795 { 796name :"min end 2" , 797constraints : []Constraint { 798Min (25 ),Min (25 ), 799 }, 800want : [][]int {{0 ,50 }, {50 ,100 }}, 801flex :FlexEnd , 802 }, 803 { 804name :"min space between" , 805constraints : []Constraint { 806Min (25 ),Min (25 ), 807 }, 808want : [][]int {{0 ,50 }, {50 ,100 }}, 809flex :FlexSpaceBetween , 810 }, 811 { 812name :"min space evenly" , 813constraints : []Constraint { 814Min (25 ),Min (25 ), 815 }, 816want : [][]int {{0 ,50 }, {50 ,100 }}, 817flex :FlexSpaceEvenly , 818 }, 819 { 820name :"min space around" , 821constraints : []Constraint { 822Min (25 ),Min (25 ), 823 }, 824want : [][]int {{0 ,50 }, {50 ,100 }}, 825flex :FlexSpaceAround , 826 }, 827 { 828name :"max legacy 2" , 829constraints : []Constraint { 830Max (25 ),Max (25 ), 831 }, 832want : [][]int {{0 ,25 }, {25 ,100 }}, 833flex :FlexLegacy , 834 }, 835 { 836name :"max start 2" , 837constraints : []Constraint { 838Max (25 ),Max (25 ), 839 }, 840want : [][]int {{0 ,25 }, {25 ,50 }}, 841flex :FlexStart , 842 }, 843 { 844name :"max center 2" , 845constraints : []Constraint { 846Max (25 ),Max (25 ), 847 }, 848want : [][]int {{25 ,50 }, {50 ,75 }}, 849flex :FlexCenter , 850 }, 851 { 852name :"max end 2" , 853constraints : []Constraint { 854Max (25 ),Max (25 ), 855 }, 856want : [][]int {{50 ,75 }, {75 ,100 }}, 857flex :FlexEnd , 858 }, 859 { 860name :"max space between" , 861constraints : []Constraint { 862Max (25 ),Max (25 ), 863 }, 864want : [][]int {{0 ,25 }, {75 ,100 }}, 865flex :FlexSpaceBetween , 866 }, 867 { 868name :"max space evenly" , 869constraints : []Constraint { 870Max (25 ),Max (25 ), 871 }, 872want : [][]int {{17 ,42 }, {58 ,83 }}, 873flex :FlexSpaceEvenly , 874 }, 875 { 876name :"max space around" , 877constraints : []Constraint { 878Max (25 ),Max (25 ), 879 }, 880want : [][]int {{13 ,38 }, {63 ,88 }}, 881flex :FlexSpaceAround , 882 }, 883 { 884name :"length spaced around" , 885constraints : []Constraint { 886Len (25 ),Len (25 ),Len (25 ), 887 }, 888want : [][]int {{0 ,25 }, {38 ,63 }, {75 ,100 }}, 889flex :FlexSpaceBetween , 890 }, 891 { 892name :"one segment legacy" , 893constraints : []Constraint { 894Len (50 ), 895 }, 896want : [][]int {{0 ,100 }}, 897flex :FlexLegacy , 898 }, 899 { 900name :"one segment start" , 901constraints : []Constraint { 902Len (50 ), 903 }, 904want : [][]int {{0 ,50 }}, 905flex :FlexStart , 906 }, 907 { 908name :"one segment end" , 909constraints : []Constraint { 910Len (50 ), 911 }, 912want : [][]int {{50 ,100 }}, 913flex :FlexEnd , 914 }, 915 { 916name :"one segment center" , 917constraints : []Constraint { 918Len (50 ), 919 }, 920want : [][]int {{25 ,75 }}, 921flex :FlexCenter , 922 }, 923 { 924name :"one segment space between" , 925constraints : []Constraint { 926Len (50 ), 927 }, 928want : [][]int {{0 ,100 }}, 929flex :FlexSpaceBetween , 930 }, 931 { 932name :"one segment space evenly" , 933constraints : []Constraint { 934Len (50 ), 935 }, 936want : [][]int {{25 ,75 }}, 937flex :FlexSpaceEvenly , 938 }, 939 { 940name :"one segment space around" , 941constraints : []Constraint { 942Len (50 ), 943 }, 944want : [][]int {{25 ,75 }}, 945flex :FlexSpaceAround , 946 }, 947 } 948 949for _ ,tc := range testCases { 950t .Run (tc .name ,func (t * testing.T ) { 951t .Parallel () 952 953rect := uv .Rect (0 ,0 ,100 ,1 ) 954 955rects := Horizontal (tc .constraints ... ).WithFlex (tc .flex ).Split (rect ) 956 957ranges := make ([][]int ,0 ,len (rects )) 958 959for _ ,r := range rects { 960ranges = append (ranges , []int {r .Min .X ,r .Max .X }) 961 } 962 963if ! reflect .DeepEqual (tc .want ,ranges ) { 964t .Fatalf ("not equal: want %#+v, got %#+v" ,tc .want ,ranges ) 965 } 966 }) 967 } 968} 969 970func TestFlexSpacing (t * testing.T ) { 971t .Parallel () 972 973testCases := []struct { 974name string 975want [][]int 976constraints []Constraint 977flex Flex 978spacing int 979 }{ 980 { 981name :"length zero spacing" , 982want : [][]int {{0 ,20 }, {20 ,20 }, {40 ,20 }}, 983constraints : []Constraint {Len (20 ),Len (20 ),Len (20 )}, 984flex :FlexStart , 985spacing :0 , 986 }, 987 { 988name :"length overlap 2" , 989want : [][]int {{0 ,20 }, {19 ,20 }, {38 ,20 }}, 990constraints : []Constraint {Len (20 ),Len (20 ),Len (20 )}, 991flex :FlexStart , 992spacing :- 1 , 993 }, 994 { 995name :"length overlap 3" , 996want : [][]int {{21 ,20 }, {40 ,20 }, {59 ,20 }}, 997constraints : []Constraint {Len (20 ),Len (20 ),Len (20 )}, 998flex :FlexCenter , 999spacing :- 1 , 1000 }, 1001 { 1002name :"length overlap 4" , 1003want : [][]int {{42 ,20 }, {61 ,20 }, {80 ,20 }}, 1004constraints : []Constraint {Len (20 ),Len (20 ),Len (20 )}, 1005flex :FlexEnd , 1006spacing :- 1 , 1007 }, 1008 { 1009name :"length overlap 5" , 1010want : [][]int {{0 ,20 }, {19 ,20 }, {38 ,62 }}, 1011constraints : []Constraint {Len (20 ),Len (20 ),Len (20 )}, 1012flex :FlexLegacy , 1013spacing :- 1 , 1014 }, 1015 { 1016name :"length overlap 6" , 1017want : [][]int {{0 ,20 }, {40 ,20 }, {80 ,20 }}, 1018constraints : []Constraint {Len (20 ),Len (20 ),Len (20 )}, 1019flex :FlexSpaceBetween , 1020spacing :- 1 , 1021 }, 1022 { 1023name :"length overlap 7" , 1024want : [][]int {{10 ,20 }, {40 ,20 }, {70 ,20 }}, 1025constraints : []Constraint {Len (20 ),Len (20 ),Len (20 )}, 1026flex :FlexSpaceEvenly , 1027spacing :- 1 , 1028 }, 1029 { 1030name :"length overlap 8" , 1031want : [][]int {{7 ,20 }, {40 ,20 }, {73 ,20 }}, 1032constraints : []Constraint {Len (20 ),Len (20 ),Len (20 )}, 1033flex :FlexSpaceAround , 1034spacing :- 1 , 1035 }, 1036 1037 { 1038name :"length spacing 1" , 1039want : [][]int {{0 ,20 }, {22 ,20 }, {44 ,20 }}, 1040constraints : []Constraint {Len (20 ),Len (20 ),Len (20 )}, 1041flex :FlexStart , 1042spacing :2 , 1043 }, 1044 { 1045name :"length spacing 2" , 1046want : [][]int {{18 ,20 }, {40 ,20 }, {62 ,20 }}, 1047constraints : []Constraint {Len (20 ),Len (20 ),Len (20 )}, 1048flex :FlexCenter , 1049spacing :2 , 1050 }, 1051 { 1052name :"length spacing 3" , 1053want : [][]int {{36 ,20 }, {58 ,20 }, {80 ,20 }}, 1054constraints : []Constraint {Len (20 ),Len (20 ),Len (20 )}, 1055flex :FlexEnd , 1056spacing :2 , 1057 }, 1058 { 1059name :"length spacing 4" , 1060want : [][]int {{0 ,20 }, {22 ,20 }, {44 ,56 }}, 1061constraints : []Constraint {Len (20 ),Len (20 ),Len (20 )}, 1062flex :FlexLegacy , 1063spacing :2 , 1064 }, 1065 { 1066name :"length spacing 5" , 1067want : [][]int {{0 ,20 }, {40 ,20 }, {80 ,20 }}, 1068constraints : []Constraint {Len (20 ),Len (20 ),Len (20 )}, 1069flex :FlexSpaceBetween , 1070spacing :2 , 1071 }, 1072 { 1073name :"length spacing 6" , 1074want : [][]int {{10 ,20 }, {40 ,20 }, {70 ,20 }}, 1075constraints : []Constraint {Len (20 ),Len (20 ),Len (20 )}, 1076flex :FlexSpaceEvenly , 1077spacing :2 , 1078 }, 1079 { 1080name :"length spacing 7" , 1081want : [][]int {{7 ,20 }, {40 ,20 }, {73 ,20 }}, 1082constraints : []Constraint {Len (20 ),Len (20 ),Len (20 )}, 1083flex :FlexSpaceAround , 1084spacing :2 , 1085 }, 1086 } 1087 1088for _ ,tc := range testCases { 1089t .Run (tc .name ,func (t * testing.T ) { 1090t .Parallel () 1091 1092rect := uv .Rect (0 ,0 ,100 ,1 ) 1093 1094splitted := Horizontal (tc .constraints ... ). 1095WithFlex (tc .flex ). 1096WithSpacing (tc .spacing ). 1097Split (rect ) 1098 1099got := make ([][]int ,0 ,len (splitted )) 1100 1101for _ ,r := range splitted { 1102got = append (got , []int {r .Min .X ,r .Dx ()}) 1103 } 1104 1105if ! reflect .DeepEqual (tc .want ,got ) { 1106t .Fatalf ("not equal: want %#+v, got %#+v" ,tc .want ,got ) 1107 } 1108 }) 1109 } 1110} 1111 1112func letters (t * testing.T ,flex Flex ,constraints []Constraint ,width int ,expected string ) { 1113t .Helper () 1114 1115area := uv .Rect (0 ,0 ,width ,1 ) 1116 1117layout := Layout { 1118Direction :DirectionHorizontal , 1119Constraints :constraints , 1120Flex :flex , 1121 }.Split (area ) 1122 1123got := uv .NewScreenBuffer (area .Dx (),area .Dy ()) 1124 1125latin := []rune ("abcdefghijklmnopqrstuvwxyz" ) 1126 1127for i := 0 ;i < min (len (constraints ),len (layout ));i ++ { 1128c := latin [i ] 1129area := layout [i ] 1130 1131s := strings .Repeat (string (c ),area .Dx ()) 1132 1133buffer := uv .NewScreenBuffer (area .Dx (),area .Dy ()) 1134 1135screen .NewContext (buffer ).WriteString (s ) 1136 1137buffer .Draw (got ,area ) 1138 } 1139 1140want := newBufferString (expected ) 1141 1142if ! reflect .DeepEqual (want ,got ) { 1143t .Fatalf ("not equal: want %#+v, got %#+v" ,want ,got ) 1144 } 1145} 1146 1147func newBufferString (s string ) uv.ScreenBuffer { 1148var width ,height int 1149 1150for line := range strings .Lines (s ) { 1151width = max (width ,len (line )) 1152height ++ 1153 } 1154 1155buf := uv .NewScreenBuffer (width ,height ) 1156 1157screen .NewContext (buf ).WriteString (s ) 1158 1159return buf 1160}