gui-cs / Terminal.Gui

Cross Platform Terminal UI toolkit for .NET
MIT License
9.4k stars 675 forks source link

Finish `Dim.Auto (Content)` #3499

Open tig opened 1 month ago

tig commented 1 month ago

This puppy is not really finished:

DimAutoStyle.Content sorta works. Needs moar. This issue is to track.

BDisp commented 1 month ago

@tig I added these two DimAutoStyle.Auto unit tests to give an opinion on how the behavior is verified using ContentSize and Text. Only the test that uses Text fails if the maximum value is defined as Fill(). In my opinion, just like using ContentSize, the value returned from Fill() is what should be considered.

    [Fact]
    public void Dim_Auto_ContentSize_Min_Max ()
    {
        var size = new Size (5, 5);
        var view1 = new View { Width = Auto (DimAutoStyle.Auto, 10), Height = Auto (DimAutoStyle.Auto, 10) };
        view1.SetContentSize (size);
        var view2 = new View { Width = Auto (DimAutoStyle.Auto, 10, 30), Height = Auto (DimAutoStyle.Auto, 10, 30) };
        view2.SetContentSize (size);
        var view3 = new View { Width = Auto (DimAutoStyle.Auto, 10, Fill ()), Height = Auto (DimAutoStyle.Auto, 10, Fill ()) };
        view3.SetContentSize (size);
        var top = new View { Width = 20, Height = 20 };
        top.Add (view1, view2, view3);

        top.LayoutSubviews ();
        Assert.Equal (new (0, 0, 10, 10), view1.Frame);
        Assert.Equal (new (0, 0, 10, 10), view2.Frame);
        Assert.Equal (new (0, 0, 10, 10), view3.Frame);

        size = new (35, 35);
        view1.SetContentSize (size);
        view2.SetContentSize (size);
        view3.SetContentSize (size);
        top.Width = 40;
        top.Height = 40;
        top.LayoutSubviews ();
        Assert.Equal (size, view1.GetContentSize ());
        Assert.Equal (size, view2.GetContentSize ());
        Assert.Equal (size, view3.GetContentSize ());
        Assert.Equal (new (0, 0, 35, 35), view1.Frame);
        Assert.Equal (new (0, 0, 30, 30), view2.Frame);
        Assert.Equal (new (0, 0, 35, 35), view3.Frame);

        size = new (50, 50);
        view1.SetContentSize (size);
        view2.SetContentSize (size);
        view3.SetContentSize (size);
        top.LayoutSubviews ();
        Assert.Equal (size, view1.GetContentSize ());
        Assert.Equal (size, view2.GetContentSize ());
        Assert.Equal (size, view3.GetContentSize ());
        Assert.Equal (new (0, 0, 50, 50), view1.Frame);
        Assert.Equal (new (0, 0, 30, 30), view2.Frame);
        Assert.Equal (new (0, 0, 40, 40), view3.Frame);
    }

    [Fact]
    public void Dim_Auto_Text_Min_Max ()
    {
        var length = 5;
        var view1 = new View { Width = Auto (DimAutoStyle.Auto, 10), Height = Auto (DimAutoStyle.Auto, 10) };
        view1.Text = new ('x', length);
        var view2 = new View { Width = Auto (DimAutoStyle.Auto, 10, 30), Height = Auto (DimAutoStyle.Auto, 10, 30) };
        view2.TextDirection = TextDirection.TopBottom_LeftRight;
        view2.Text = new ('x', length);
        var view3 = new View { Width = Auto (DimAutoStyle.Auto, 10, Fill ()), Height = Auto (DimAutoStyle.Auto, 10, Fill ()) };
        view3.Text = new ('x', length);
        var top = new View { Width = 20, Height = 20 };
        top.Add (view1, view2, view3);

        top.LayoutSubviews ();
        Assert.Equal (new (0, 0, 10, 10), view1.Frame);
        Assert.Equal (new (0, 0, 10, 10), view2.Frame);
        Assert.Equal (new (0, 0, 10, 10), view3.Frame);

        length = 35;
        view1.Text = new ('x', length);
        view2.Text = new ('x', length);
        view3.Text = new ('x', length);
        top.Width = 40;
        top.Height = 40;
        top.LayoutSubviews ();
        Assert.Equal (length, view1.Text.Length);
        Assert.Equal (length, view2.Text.Length);
        Assert.Equal (length, view3.Text.Length);
        Assert.Equal (new (0, 0, 35, 10), view1.Frame);
        Assert.Equal (new (0, 0, 10, 30), view2.Frame);
        // This gives {X = 0 Y = 0 Width = 35 Height = 10}
        // but I think the Fill should be respected
        Assert.Equal (new (0, 0, 40, 10), view3.Frame);

        length = 50;
        view1.Text = new ('x', length);
        view2.Text = new ('x', length);
        view3.Text = new ('x', length);
        top.LayoutSubviews ();
        Assert.Equal (length, view1.Text.Length);
        Assert.Equal (length, view2.Text.Length);
        Assert.Equal (length, view3.Text.Length);
        Assert.Equal (new (0, 0, 50, 10), view1.Frame);
        Assert.Equal (new (0, 0, 10, 30), view2.Frame);
        Assert.Equal (new (0, 0, 40, 10), view3.Frame);
    }
tig commented 1 month ago

I appreciate you doing this, but there is a LOT going on in those tests. Is there any way you can simplify them down to more precise cases? If not, that's ok... but it would make my life a lot easier.

BDisp commented 1 month ago

Basically in each test, using DimAutoStyle.Auto, I am testing 3 views, where the first does not use the maximum value, the second uses an absolute value and the third uses Fill. In the first test I am using ContentSize and in the second I am using Text, where view2.TextDirection = TextDirection.TopBottom_LeftRight. Practically the tests pass as expected and the only exception is in the second test, using Text, in the view that is using Fill, it does not respect the width of the superview (40), returning Text.Length (35). I didn't want to use Theory to avoid complicating things and making it simpler.