Selkie.git | t/ | 05-sizing.rakutest


use Test;
use lib 'lib';

use Selkie::Sizing;
use Selkie::Widget;
use Selkie::Layout::Allocate;

plan 8;

subtest "fixed sizing" => {
    plan 2;
    my $s = Sizing.fixed(10);
    is $s.mode, SizeFixed, "mode is fixed";
    is $s.value, 10, "value is 10";
};

subtest "percent sizing" => {
    plan 2;
    my $s = Sizing.percent(50);
    is $s.mode, SizePercent, "mode is percent";
    is $s.value, 50, "value is 50";
};

subtest "flex sizing with weight" => {
    plan 2;
    my $s = Sizing.flex(2);
    is $s.mode, SizeFlex, "mode is flex";
    is $s.value, 2, "weight is 2";
};

subtest "flex sizing default weight" => {
    plan 2;
    my $s = Sizing.flex;
    is $s.mode, SizeFlex, "mode is flex";
    is $s.value, 1, "default weight is 1";
};

subtest "percent with decimal" => {
    plan 1;
    my $s = Sizing.percent(33.3);
    is-approx $s.value, 33.3, "fractional percent";
};

subtest "fixed zero" => {
    plan 1;
    my $s = Sizing.fixed(0);
    is $s.value, 0, "zero is valid";
};

# --- Sizing on the cross axis -------------------------------------
#
# `Widget.cross-sizing` reuses this exact type for the axis a box does
# *not* stack on. The model itself is unchanged — the same immutable
# Sizing object is legal on both axes at once — but flex means
# something slightly different there: with no siblings to share
# leftovers with, it resolves to the whole extent. See
# t/91-cross-align for the full resolution table.

class CrossKid does Selkie::Widget {
    method render() { self.clear-dirty }
}

subtest "one Sizing object can drive both axes" => {
    plan 4;
    my $s = Sizing.fixed(6);
    my $k = CrossKid.new(sizing => $s, cross-sizing => $s);
    ok $k.sizing === $k.cross-sizing, "the same instance serves both axes";
    is resolve-cross-extent($k, 40), 6, "…resolving to 6 on the cross axis";
    is $k.sizing.mode, SizeFixed, "the shared object is not mutated by resolution";
    is $k.sizing.value, 6, "…in mode or value";
};

subtest "flex on the cross axis means fill, not a share" => {
    plan 3;
    # On the main axis flex(1) beside flex(1) gets half. On the cross
    # axis there is nothing to divide, so it fills — the same answer an
    # undefined cross-sizing gives.
    is resolve-cross-extent(CrossKid.new(cross-sizing => Sizing.flex), 30), 30,
        "flex fills the cross extent";
    is resolve-cross-extent(CrossKid.new(cross-sizing => Sizing.flex(2)), 30), 30,
        "the flex factor is irrelevant there";
    is resolve-cross-extent(CrossKid.new, 30), 30,
        "…matching the undefined default";
};