Selkie.git | xt/snapshots/ | 47-border-padding-collapse.raku


use lib 'lib';
use Selkie::Test::Snapshot;
use Selkie::Widget;
use Selkie::Container;
use Selkie::Widget::Border;
use Selkie::BorderStyle;
use Selkie::Layout::HBox;
use Selkie::Sizing;

# The padding-collapse bleed guard.
#
# Reaching the failure needs two layout passes: the content widget must
# already own a plane at a comfortable size before padding squeezes its
# box to nothing. Pass one gives the left pane 20 columns and no
# padding, so its content plane is created 18 wide. Pass two shrinks
# the pane to 8 columns and pads it by 3 — inner-rect is then 0x0.
#
# ncplane_resize_simple refuses a zero row or column count, so the naive
# "just resize the content" path leaves an 18-column plane sitting
# inside an 8-column frame, painting eleven columns of stale ASCII
# frame straight across the right-hand pane. Border parks the content
# instead, and this golden is the proof: the left frame is empty, and
# nothing appears between it and the right pane's own border.
#
# If this snapshot ever grows '+---' debris to the right of column 7,
# the guard in Selkie::Widget::Border.render has regressed.

class ReflowRoot does Selkie::Container {
    has &.between is required;

    method render() {
        my $kid = self.children[0];
        $kid.init-plane(self.plane, y => 0, x => 0,
                        rows => self.rows, cols => self.cols)
            unless $kid.plane;
        $kid.set-viewport(abs-y => self.abs-y, abs-x => self.abs-x,
                          rows => self.rows, cols => self.cols);
        $kid.mark-dirty;
        $kid.render;

        &!between();

        $kid.mark-dirty;
        $kid.render;
        self.clear-dirty;
    }
}

my $left = Selkie::Widget::Border.new(
    border-style => BorderRounded,
    sizing       => Sizing.fixed(20),
);
$left.set-content(Selkie::Widget::Border.new(
    border-style => BorderAscii,
    sizing       => Sizing.flex,
));

my $right = Selkie::Widget::Border.new(
    title        => 'Intact',
    border-style => BorderRounded,
    sizing       => Sizing.flex,
);

my $row = Selkie::Layout::HBox.new(sizing => Sizing.flex);
$row.add: $left;
$row.add: $right;

my $root = ReflowRoot.new(
    sizing  => Sizing.flex,
    between => {
        $left.set-sizing(Sizing.fixed(8));
        $left.set-padding(3);
    },
);
$root.add: $row;

print render-to-string($root, rows => 6, cols => 30);