first commit
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Bunit;
|
||||
using SufiChain.SufiBlazor.Components.Layout;
|
||||
using Xunit;
|
||||
|
||||
namespace SufiChain.SufiBlazor.Tests.Components.Layout;
|
||||
|
||||
public class SbContainerTests : BunitContext
|
||||
{
|
||||
private IRenderedComponent<SbContainer> RenderContainer(
|
||||
Action<ComponentParameterCollectionBuilder<SbContainer>>? configure = null)
|
||||
{
|
||||
return Render<SbContainer>(p => configure?.Invoke(p));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RendersContainerStructure()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderContainer();
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-container");
|
||||
Assert.NotNull(div);
|
||||
Assert.Equal("div", div.TagName.ToLowerInvariant());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RendersChildContent()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderContainer(p => p.AddChildContent("<p>Content</p>"));
|
||||
|
||||
// Assert
|
||||
Assert.Contains("Content", cut.Markup);
|
||||
Assert.NotNull(cut.Find("p"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UsesLgMaxWidthByDefault()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderContainer();
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-container");
|
||||
Assert.Contains("sb-container--lg", div.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesMaxWidthClass()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderContainer(p => p.Add(x => x.MaxWidth, SbContainerMaxWidth.Sm));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-container");
|
||||
Assert.Contains("sb-container--sm", div.ClassList);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(SbContainerMaxWidth.Sm, "sm")]
|
||||
[InlineData(SbContainerMaxWidth.Md, "md")]
|
||||
[InlineData(SbContainerMaxWidth.Lg, "lg")]
|
||||
[InlineData(SbContainerMaxWidth.Xl, "xl")]
|
||||
[InlineData(SbContainerMaxWidth.Xxl, "xxl")]
|
||||
[InlineData(SbContainerMaxWidth.Fluid, "fluid")]
|
||||
public void AppliesCorrectMaxWidthClassForEachPreset(SbContainerMaxWidth preset, string expectedClass)
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderContainer(p => p.Add(x => x.MaxWidth, preset));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-container");
|
||||
Assert.Contains($"sb-container--{expectedClass}", div.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddsNoGuttersClassWhenDisableGuttersTrue()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderContainer(p => p.Add(x => x.DisableGutters, true));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-container");
|
||||
Assert.Contains("sb-container--no-gutters", div.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DoesNotAddNoGuttersClassWhenDisableGuttersFalse()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderContainer(p => p.Add(x => x.DisableGutters, false));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-container");
|
||||
Assert.DoesNotContain("sb-container--no-gutters", div.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesClassParameter()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderContainer(p => p.Add(x => x.Class, "my-container"));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-container");
|
||||
Assert.Contains("my-container", div.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesStyleParameter()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderContainer(p => p.Add(x => x.Style, "padding-top: 20px;"));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-container");
|
||||
Assert.Contains("padding-top: 20px", div.GetAttribute("style"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesAdditionalAttributes()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderContainer(p => p.Add(x => x.AdditionalAttributes, new Dictionary<string, object>
|
||||
{
|
||||
{ "data-testid", "main-container" },
|
||||
{ "role", "main" }
|
||||
}));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-container");
|
||||
Assert.Equal("main-container", div.GetAttribute("data-testid"));
|
||||
Assert.Equal("main", div.GetAttribute("role"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,357 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Bunit;
|
||||
using SufiChain.SufiBlazor.Components.Layout;
|
||||
using Xunit;
|
||||
|
||||
namespace SufiChain.SufiBlazor.Tests.Components.Layout;
|
||||
|
||||
public class SbGridTests : BunitContext
|
||||
{
|
||||
private IRenderedComponent<SbGrid> RenderGrid(
|
||||
Action<ComponentParameterCollectionBuilder<SbGrid>>? configure = null)
|
||||
{
|
||||
return Render<SbGrid>(p => configure?.Invoke(p));
|
||||
}
|
||||
|
||||
private IRenderedComponent<SbGridItem> RenderGridItem(
|
||||
Action<ComponentParameterCollectionBuilder<SbGridItem>>? configure = null)
|
||||
{
|
||||
return Render<SbGridItem>(p => configure?.Invoke(p));
|
||||
}
|
||||
|
||||
// --- SbGrid tests ---
|
||||
|
||||
[Fact]
|
||||
public void RendersGridStructure()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGrid();
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-grid");
|
||||
Assert.NotNull(div);
|
||||
Assert.Equal("div", div.TagName.ToLowerInvariant());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RendersChildContent()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGrid(p => p.AddChildContent("<span>Grid content</span>"));
|
||||
|
||||
// Assert
|
||||
Assert.Contains("Grid content", cut.Markup);
|
||||
Assert.NotNull(cut.Find("span"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetsDefaultColumnsInStyle()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGrid();
|
||||
|
||||
// Assert - default Columns is 12
|
||||
var div = cut.Find(".sb-grid");
|
||||
var style = div.GetAttribute("style");
|
||||
Assert.Contains("--sb-grid-columns: 12", style);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesCustomColumns()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGrid(p => p.Add(x => x.Columns, 6));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-grid");
|
||||
var style = div.GetAttribute("style");
|
||||
Assert.Contains("--sb-grid-columns: 6", style);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesResponsiveColumnClasses()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGrid(p => p
|
||||
.Add(x => x.ColumnsSm, 6)
|
||||
.Add(x => x.ColumnsMd, 8)
|
||||
.Add(x => x.ColumnsLg, 10)
|
||||
.Add(x => x.ColumnsXl, 12));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-grid");
|
||||
Assert.Contains("sb-grid--sm-6", div.ClassList);
|
||||
Assert.Contains("sb-grid--md-8", div.ClassList);
|
||||
Assert.Contains("sb-grid--lg-10", div.ClassList);
|
||||
Assert.Contains("sb-grid--xl-12", div.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DoesNotAddResponsiveClassWhenNull()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGrid(p => p.Add(x => x.ColumnsSm, 6));
|
||||
|
||||
// Assert - only sm, not md/lg/xl
|
||||
var div = cut.Find(".sb-grid");
|
||||
Assert.Contains("sb-grid--sm-6", div.ClassList);
|
||||
Assert.DoesNotContain("sb-grid--md-", div.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetsDefaultGapInStyle()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGrid();
|
||||
|
||||
// Assert - default Gap is 4
|
||||
var div = cut.Find(".sb-grid");
|
||||
var style = div.GetAttribute("style");
|
||||
Assert.Contains("gap: var(--sb-space-4)", style);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesCustomGap()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGrid(p => p.Add(x => x.Gap, 8));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-grid");
|
||||
var style = div.GetAttribute("style");
|
||||
Assert.Contains("gap: var(--sb-space-8)", style);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UsesRowGapAndColumnGapWhenProvided()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGrid(p => p
|
||||
.Add(x => x.RowGap, 2)
|
||||
.Add(x => x.ColumnGap, 6));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-grid");
|
||||
var style = div.GetAttribute("style");
|
||||
Assert.Contains("row-gap: var(--sb-space-2)", style);
|
||||
Assert.Contains("column-gap: var(--sb-space-6)", style);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UsesGapAsFallbackWhenOnlyRowGapSet()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGrid(p => p.Add(x => x.RowGap, 2));
|
||||
|
||||
// Assert - column-gap falls back to Gap (4)
|
||||
var div = cut.Find(".sb-grid");
|
||||
var style = div.GetAttribute("style");
|
||||
Assert.Contains("row-gap: var(--sb-space-2)", style);
|
||||
Assert.Contains("column-gap: var(--sb-space-4)", style);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesClassParameter()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGrid(p => p.Add(x => x.Class, "my-grid"));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-grid");
|
||||
Assert.Contains("my-grid", div.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesStyleParameter()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGrid(p => p.Add(x => x.Style, "min-height: 100px;"));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-grid");
|
||||
var style = div.GetAttribute("style");
|
||||
Assert.Contains("min-height: 100px", style);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesAdditionalAttributes()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGrid(p => p.Add(x => x.AdditionalAttributes, new Dictionary<string, object>
|
||||
{
|
||||
{ "data-testid", "layout-grid" },
|
||||
{ "role", "presentation" }
|
||||
}));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-grid");
|
||||
Assert.Equal("layout-grid", div.GetAttribute("data-testid"));
|
||||
Assert.Equal("presentation", div.GetAttribute("role"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RendersGridItemChildren()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = Render<SbGrid>(p => p.AddChildContent(b =>
|
||||
{
|
||||
b.OpenComponent<SbGridItem>(0);
|
||||
b.AddAttribute(1, "Span", 4);
|
||||
b.AddAttribute(2, "ChildContent", (RenderFragment)(c => c.AddMarkupContent(0, "Item 1")));
|
||||
b.CloseComponent();
|
||||
b.OpenComponent<SbGridItem>(3);
|
||||
b.AddAttribute(4, "Span", 8);
|
||||
b.AddAttribute(5, "ChildContent", (RenderFragment)(c => c.AddMarkupContent(0, "Item 2")));
|
||||
b.CloseComponent();
|
||||
}));
|
||||
|
||||
// Assert
|
||||
var grid = cut.Find(".sb-grid");
|
||||
Assert.NotNull(grid);
|
||||
var items = cut.FindAll(".sb-grid-item");
|
||||
Assert.Equal(2, items.Count);
|
||||
Assert.Contains("Item 1", cut.Markup);
|
||||
Assert.Contains("Item 2", cut.Markup);
|
||||
}
|
||||
|
||||
// --- SbGridItem tests ---
|
||||
|
||||
[Fact]
|
||||
public void GridItem_RendersStructure()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGridItem();
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-grid-item");
|
||||
Assert.NotNull(div);
|
||||
Assert.Equal("div", div.TagName.ToLowerInvariant());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GridItem_RendersChildContent()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGridItem(p => p.AddChildContent("<p>Item content</p>"));
|
||||
|
||||
// Assert
|
||||
Assert.Contains("Item content", cut.Markup);
|
||||
Assert.NotNull(cut.Find("p"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GridItem_SetsDefaultSpanInStyle()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGridItem();
|
||||
|
||||
// Assert - default Span is 1
|
||||
var div = cut.Find(".sb-grid-item");
|
||||
var style = div.GetAttribute("style");
|
||||
Assert.Contains("--sb-grid-span: 1", style);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GridItem_AppliesSpanInStyle()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGridItem(p => p.Add(x => x.Span, 6));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-grid-item");
|
||||
var style = div.GetAttribute("style");
|
||||
Assert.Contains("--sb-grid-span: 6", style);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GridItem_AppliesResponsiveSpanClasses()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGridItem(p => p
|
||||
.Add(x => x.SpanSm, 2)
|
||||
.Add(x => x.SpanMd, 4)
|
||||
.Add(x => x.SpanLg, 6)
|
||||
.Add(x => x.SpanXl, 8));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-grid-item");
|
||||
Assert.Contains("sb-grid-item--sm-2", div.ClassList);
|
||||
Assert.Contains("sb-grid-item--md-4", div.ClassList);
|
||||
Assert.Contains("sb-grid-item--lg-6", div.ClassList);
|
||||
Assert.Contains("sb-grid-item--xl-8", div.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GridItem_DoesNotAddResponsiveClassWhenNull()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGridItem(p => p.Add(x => x.SpanMd, 6));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-grid-item");
|
||||
Assert.Contains("sb-grid-item--md-6", div.ClassList);
|
||||
Assert.DoesNotContain("sb-grid-item--sm-", div.ClassList);
|
||||
Assert.DoesNotContain("sb-grid-item--lg-", div.ClassList);
|
||||
Assert.DoesNotContain("sb-grid-item--xl-", div.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GridItem_AppliesClassParameter()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGridItem(p => p.Add(x => x.Class, "sidebar"));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-grid-item");
|
||||
Assert.Contains("sidebar", div.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GridItem_AppliesStyleParameter()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGridItem(p => p.Add(x => x.Style, "background: white;"));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-grid-item");
|
||||
var style = div.GetAttribute("style");
|
||||
Assert.Contains("background: white", style);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GridItem_AppliesAdditionalAttributes()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderGridItem(p => p.Add(x => x.AdditionalAttributes, new Dictionary<string, object>
|
||||
{
|
||||
{ "data-testid", "grid-cell" },
|
||||
{ "aria-label", "Main content" }
|
||||
}));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-grid-item");
|
||||
Assert.Equal("grid-cell", div.GetAttribute("data-testid"));
|
||||
Assert.Equal("Main content", div.GetAttribute("aria-label"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GridItem_WorksInsideSbGrid()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = Render<SbGrid>(p => p.AddChildContent(b =>
|
||||
{
|
||||
b.OpenComponent<SbGridItem>(0);
|
||||
b.AddAttribute(1, "Span", 12);
|
||||
b.AddAttribute(2, "ChildContent", (RenderFragment)(c => c.AddMarkupContent(0, "Full width")));
|
||||
b.CloseComponent();
|
||||
}));
|
||||
|
||||
// Assert
|
||||
var grid = cut.Find(".sb-grid");
|
||||
var item = cut.Find(".sb-grid-item");
|
||||
Assert.NotNull(grid);
|
||||
Assert.NotNull(item);
|
||||
Assert.Contains("Full width", cut.Markup);
|
||||
Assert.Contains("--sb-grid-span: 12", item.GetAttribute("style"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Bunit;
|
||||
using SufiChain.SufiBlazor.Components.Layout;
|
||||
using Xunit;
|
||||
|
||||
namespace SufiChain.SufiBlazor.Tests.Components.Layout;
|
||||
|
||||
public class SbSpacerTests : BunitContext
|
||||
{
|
||||
private IRenderedComponent<SbSpacer> RenderSpacer(
|
||||
Action<ComponentParameterCollectionBuilder<SbSpacer>>? configure = null)
|
||||
{
|
||||
return Render<SbSpacer>(p => configure?.Invoke(p));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RendersSpacerStructure()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderSpacer();
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-spacer");
|
||||
Assert.NotNull(div);
|
||||
Assert.Equal("div", div.TagName.ToLowerInvariant());
|
||||
Assert.Equal("true", div.GetAttribute("aria-hidden"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UsesMediumHeightByDefault()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderSpacer();
|
||||
|
||||
// Assert - Medium = 1rem
|
||||
var div = cut.Find(".sb-spacer");
|
||||
var style = div.GetAttribute("style");
|
||||
Assert.Contains("height: 1rem", style);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(SbSpacerSize.ExtraSmall, "0.25rem")]
|
||||
[InlineData(SbSpacerSize.Small, "0.5rem")]
|
||||
[InlineData(SbSpacerSize.Medium, "1rem")]
|
||||
[InlineData(SbSpacerSize.Large, "1.5rem")]
|
||||
[InlineData(SbSpacerSize.ExtraLarge, "2rem")]
|
||||
public void AppliesCorrectHeightForEachSize(SbSpacerSize size, string expectedHeight)
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderSpacer(p => p.Add(x => x.Size, size));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-spacer");
|
||||
var style = div.GetAttribute("style");
|
||||
Assert.Contains($"height: {expectedHeight}", style);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HeightOverridesSize()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderSpacer(p => p
|
||||
.Add(x => x.Size, SbSpacerSize.Large)
|
||||
.Add(x => x.Height, "3rem"));
|
||||
|
||||
// Assert - custom Height overrides Size
|
||||
var div = cut.Find(".sb-spacer");
|
||||
var style = div.GetAttribute("style");
|
||||
Assert.Contains("height: 3rem", style);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesWidthWhenProvided()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderSpacer(p => p.Add(x => x.Width, "2rem"));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-spacer");
|
||||
var style = div.GetAttribute("style");
|
||||
Assert.Contains("width: 2rem", style);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesFlexGrowWhenGrowTrue()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderSpacer(p => p.Add(x => x.Grow, true));
|
||||
|
||||
// Assert - Grow takes precedence, no height
|
||||
var div = cut.Find(".sb-spacer");
|
||||
var style = div.GetAttribute("style");
|
||||
Assert.Contains("flex-grow: 1", style);
|
||||
Assert.DoesNotContain("height:", style);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GrowWithWidthAppliesBoth()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderSpacer(p => p
|
||||
.Add(x => x.Grow, true)
|
||||
.Add(x => x.Width, "1rem"));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-spacer");
|
||||
var style = div.GetAttribute("style");
|
||||
Assert.Contains("flex-grow: 1", style);
|
||||
Assert.Contains("width: 1rem", style);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesClassParameter()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderSpacer(p => p.Add(x => x.Class, "my-spacer"));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-spacer");
|
||||
Assert.Contains("my-spacer", div.ClassList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
using Bunit;
|
||||
using SufiChain.SufiBlazor.Components.Layout;
|
||||
using Xunit;
|
||||
|
||||
namespace SufiChain.SufiBlazor.Tests.Components.Layout;
|
||||
|
||||
public class SbStackTests : BunitContext
|
||||
{
|
||||
private IRenderedComponent<SbStack> RenderStack(
|
||||
Action<ComponentParameterCollectionBuilder<SbStack>>? configure = null)
|
||||
{
|
||||
return Render<SbStack>(p => configure?.Invoke(p));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RendersStackStructure()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderStack();
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-stack");
|
||||
Assert.NotNull(div);
|
||||
Assert.Equal("div", div.TagName.ToLowerInvariant());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RendersChildContent()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderStack(p => p.AddChildContent("<span>Stack content</span>"));
|
||||
|
||||
// Assert
|
||||
Assert.Contains("Stack content", cut.Markup);
|
||||
Assert.NotNull(cut.Find("span"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UsesColumnDirectionByDefault()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderStack();
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-stack");
|
||||
Assert.Contains("sb-stack--column", div.ClassList);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(SbStackDirection.Row, "row")]
|
||||
[InlineData(SbStackDirection.Column, "column")]
|
||||
public void AppliesDirectionClass(SbStackDirection direction, string expectedClass)
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderStack(p => p.Add(x => x.Direction, direction));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-stack");
|
||||
Assert.Contains($"sb-stack--{expectedClass}", div.ClassList);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(SbStackDirection.Row, "sb-stack--sm-row")]
|
||||
[InlineData(SbStackDirection.Column, "sb-stack--sm-column")]
|
||||
public void AppliesDirectionSmClass_WhenSet(SbStackDirection directionSm, string expectedClass)
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderStack(p => p.Add(x => x.DirectionSm, directionSm));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-stack");
|
||||
Assert.Contains(expectedClass, div.ClassList);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(SbStackDirection.Row, "sb-stack--md-row")]
|
||||
[InlineData(SbStackDirection.Column, "sb-stack--md-column")]
|
||||
public void AppliesDirectionMdClass_WhenSet(SbStackDirection directionMd, string expectedClass)
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderStack(p => p.Add(x => x.DirectionMd, directionMd));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-stack");
|
||||
Assert.Contains(expectedClass, div.ClassList);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(SbStackDirection.Row, "sb-stack--lg-row")]
|
||||
[InlineData(SbStackDirection.Column, "sb-stack--lg-column")]
|
||||
public void AppliesDirectionLgClass_WhenSet(SbStackDirection directionLg, string expectedClass)
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderStack(p => p.Add(x => x.DirectionLg, directionLg));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-stack");
|
||||
Assert.Contains(expectedClass, div.ClassList);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(SbStackDirection.Row, "sb-stack--xl-row")]
|
||||
[InlineData(SbStackDirection.Column, "sb-stack--xl-column")]
|
||||
public void AppliesDirectionXlClass_WhenSet(SbStackDirection directionXl, string expectedClass)
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderStack(p => p.Add(x => x.DirectionXl, directionXl));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-stack");
|
||||
Assert.Contains(expectedClass, div.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesMultipleResponsiveDirectionClasses_WhenMultipleBreakpointsSet()
|
||||
{
|
||||
// Arrange & Act - Column on mobile, Row at sm, Column at md (e.g. for tablet), Row at lg+
|
||||
var cut = RenderStack(p => p
|
||||
.Add(x => x.Direction, SbStackDirection.Column)
|
||||
.Add(x => x.DirectionSm, SbStackDirection.Row)
|
||||
.Add(x => x.DirectionMd, SbStackDirection.Column)
|
||||
.Add(x => x.DirectionLg, SbStackDirection.Row));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-stack");
|
||||
Assert.Contains("sb-stack--column", div.ClassList);
|
||||
Assert.Contains("sb-stack--sm-row", div.ClassList);
|
||||
Assert.Contains("sb-stack--md-column", div.ClassList);
|
||||
Assert.Contains("sb-stack--lg-row", div.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UsesDefaultGapInStyle()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderStack();
|
||||
|
||||
// Assert - default Gap is 2
|
||||
var div = cut.Find(".sb-stack");
|
||||
var style = div.GetAttribute("style");
|
||||
Assert.Contains("gap: var(--sb-space-2)", style);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0, "0")]
|
||||
[InlineData(4, "4")]
|
||||
[InlineData(8, "8")]
|
||||
[InlineData(16, "16")]
|
||||
public void AppliesGapInStyle(int gap, string expectedGap)
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderStack(p => p.Add(x => x.Gap, gap));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-stack");
|
||||
var style = div.GetAttribute("style");
|
||||
Assert.Contains($"gap: var(--sb-space-{expectedGap})", style);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(SbAlign.Start, "start")]
|
||||
[InlineData(SbAlign.Center, "center")]
|
||||
[InlineData(SbAlign.End, "end")]
|
||||
[InlineData(SbAlign.Stretch, "stretch")]
|
||||
[InlineData(SbAlign.Baseline, "baseline")]
|
||||
public void AppliesAlignClass(SbAlign align, string expectedClass)
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderStack(p => p.Add(x => x.Align, align));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-stack");
|
||||
Assert.Contains($"sb-stack--align-{expectedClass}", div.ClassList);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(SbAlign.Start, "sb-stack--sm-align-start")]
|
||||
[InlineData(SbAlign.Center, "sb-stack--sm-align-center")]
|
||||
[InlineData(SbAlign.End, "sb-stack--sm-align-end")]
|
||||
[InlineData(SbAlign.Stretch, "sb-stack--sm-align-stretch")]
|
||||
[InlineData(SbAlign.Baseline, "sb-stack--sm-align-baseline")]
|
||||
public void AppliesAlignSmClass_WhenSet(SbAlign alignSm, string expectedClass)
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderStack(p => p.Add(x => x.AlignSm, alignSm));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-stack");
|
||||
Assert.Contains(expectedClass, div.ClassList);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(SbAlign.Center, "sb-stack--md-align-center")]
|
||||
public void AppliesAlignMdClass_WhenSet(SbAlign alignMd, string expectedClass)
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderStack(p => p.Add(x => x.AlignMd, alignMd));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-stack");
|
||||
Assert.Contains(expectedClass, div.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesMultipleResponsiveAlignClasses_WhenMultipleBreakpointsSet()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderStack(p => p
|
||||
.Add(x => x.Align, SbAlign.Stretch)
|
||||
.Add(x => x.AlignSm, SbAlign.Center)
|
||||
.Add(x => x.AlignMd, SbAlign.Start)
|
||||
.Add(x => x.AlignLg, SbAlign.Center));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-stack");
|
||||
Assert.Contains("sb-stack--align-stretch", div.ClassList);
|
||||
Assert.Contains("sb-stack--sm-align-center", div.ClassList);
|
||||
Assert.Contains("sb-stack--md-align-start", div.ClassList);
|
||||
Assert.Contains("sb-stack--lg-align-center", div.ClassList);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(SbJustify.Start, "start")]
|
||||
[InlineData(SbJustify.Center, "center")]
|
||||
[InlineData(SbJustify.End, "end")]
|
||||
[InlineData(SbJustify.SpaceBetween, "between")]
|
||||
[InlineData(SbJustify.SpaceAround, "around")]
|
||||
[InlineData(SbJustify.SpaceEvenly, "evenly")]
|
||||
public void AppliesJustifyClass(SbJustify justify, string expectedClass)
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderStack(p => p.Add(x => x.Justify, justify));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-stack");
|
||||
Assert.Contains($"sb-stack--justify-{expectedClass}", div.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddsWrapClassWhenWrapTrue()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderStack(p => p.Add(x => x.Wrap, true));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-stack");
|
||||
Assert.Contains("sb-stack--wrap", div.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DoesNotAddWrapClassWhenWrapFalse()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderStack(p => p.Add(x => x.Wrap, false));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-stack");
|
||||
Assert.DoesNotContain("sb-stack--wrap", div.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesClassParameter()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderStack(p => p.Add(x => x.Class, "my-stack"));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-stack");
|
||||
Assert.Contains("my-stack", div.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesStyleParameter()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderStack(p => p.Add(x => x.Style, "min-width: 200px;"));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-stack");
|
||||
var style = div.GetAttribute("style");
|
||||
Assert.Contains("gap: var(--sb-space-2)", style);
|
||||
Assert.Contains("min-width: 200px", style);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PassesAdditionalAttributes()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderStack(p => p.Add(x => x.AdditionalAttributes, new Dictionary<string, object>
|
||||
{
|
||||
{ "data-testid", "stack-root" }
|
||||
}));
|
||||
|
||||
// Assert
|
||||
var div = cut.Find(".sb-stack");
|
||||
Assert.Equal("stack-root", div.GetAttribute("data-testid"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user