first commit

This commit is contained in:
2026-05-18 15:53:59 +03:30
commit 2c100028a1
534 changed files with 94240 additions and 0 deletions
+137
View File
@@ -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"));
}
}
+357
View File
@@ -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"));
}
}
+122
View File
@@ -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);
}
}
+298
View File
@@ -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"));
}
}