Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 41 additions & 2 deletions src/CommunityToolkit.Maui.UnitTests/Layouts/StateContainerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -514,10 +514,27 @@ public void StateContainer_CreatesControllerWithLayout()
}

[Fact]
public void Controller_ReturnsErrorLabelOnInvalidState()
public void Controller_ThrowsStateContainerExceptionInvalidStateKey()
{
Assert.Throws<StateContainerException>(() => controller.SwitchToState("InvalidStateKey"));
}

[Fact]
public void Controller_ThrowsStateContainerExceptionOnDuplicateStateKey()
{
// Arrange
var stackLayout = new StackLayout();
var label = new Label();
var button = new Button();

StateView.SetStateKey(label, StateKey.Anything);
StateView.SetStateKey(button, StateKey.Anything);
StateContainer.SetStateViews(stackLayout, [label, button]);

// Assert
var exception = Assert.Throws<StateContainerException>(() => StateContainer.SetCurrentState(stackLayout, StateKey.Anything));
exception.Message.Should().Contain("multiple");
}

[Fact]
public void Controller_SwitchesToStateFromContentSuccess()
Expand Down Expand Up @@ -594,12 +611,34 @@ public void EnsureDefaults()
var stackLayout = new StackLayout();

// Act Assert
Assert.Equal(StateContainerDefaults.StateViews, StateContainer.GetStateViews(stackLayout));
Assert.Equal([], StateContainer.GetStateViews(stackLayout));
Assert.Empty(StateContainer.GetStateViews(stackLayout));
Assert.Equal(StateContainerDefaults.CurrentState, StateContainer.GetCurrentState(stackLayout));
Assert.Equal(StateContainerDefaults.CanStateChange, StateContainer.GetCanStateChange(stackLayout));
Assert.Equal(StateViewDefaults.StateKey, StateView.GetStateKey(stackLayout));
}

[Fact]
public void EnsureLayoutControllerIsUniquePerLayout()
{
// Arrange
var grid1 = new Grid();
var grid2 = new Grid();

// Act
var grid1StateViews = StateContainer.GetStateViews(grid1);
var grid2StateViews = StateContainer.GetStateViews(grid2);
grid1StateViews.Add(new Label
{
Text = "Test",
});

// Assert
Assert.NotSame(grid1StateViews, grid2StateViews);
Assert.Single(grid1StateViews);
Assert.Empty(grid2StateViews);
}

sealed class ViewModel : INotifyPropertyChanged
{
public bool CanChangeState
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ static void ValidateCanStateChange(in BindableObject bindable)
}
}

static IList<View> CreateDefaultStateViewsProperty(BindableObject bindable) => StateContainerDefaults.StateViews;
static IList<View> CreateDefaultStateViewsProperty(BindableObject bindable) => [];
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,21 @@
/// <summary>
/// StateContainer Controller
/// </summary>
sealed class StateContainerController
/// <remarks>
/// Initialize <see cref="StateContainerController"/> with a <see cref="Layout"/>
/// </remarks>
/// <param name="layout"></param>
Comment thread
TheCodeTraveler marked this conversation as resolved.
Outdated
sealed class StateContainerController(Layout layout)
{
readonly WeakReference<Layout> layoutWeakReference;
readonly WeakReference<Layout> layoutWeakReference = new(layout);

string? previousState;
List<IView> originalContent = Enumerable.Empty<IView>().ToList();

/// <summary>
/// Initialize <see cref="StateContainerController"/> with a <see cref="Layout"/>
/// </summary>
/// <param name="layout"></param>
public StateContainerController(Layout layout) => layoutWeakReference = new WeakReference<Layout>(layout);

/// <summary>
/// The StateViews defined in the StateContainer.
/// </summary>
public required IList<View> StateViews { get; set; }
public required IList<View> StateViews { get; init; }

/// <summary>
/// Display the default content.
Expand Down Expand Up @@ -84,7 +82,14 @@

View GetViewForState(string state)
{
var view = StateViews.FirstOrDefault(x => StateView.GetStateKey(x) == state);
return view ?? throw new StateContainerException($"View for {state} not defined.");
try
{
var view = StateViews.SingleOrDefault(x => StateView.GetStateKey(x) == state);
return view ?? throw new StateContainerException($"{nameof(StateView)} for {state} not defined.");
}
catch (InvalidOperationException e)

Check warning on line 90 in src/CommunityToolkit.Maui/Layouts/StateContainer/StateContainerController.shared.cs

View workflow job for this annotation

GitHub Actions / Build Library (windows-latest)

The variable 'e' is declared but never used

Check warning on line 90 in src/CommunityToolkit.Maui/Layouts/StateContainer/StateContainerController.shared.cs

View workflow job for this annotation

GitHub Actions / Build Library (windows-latest)

The variable 'e' is declared but never used

Check warning on line 90 in src/CommunityToolkit.Maui/Layouts/StateContainer/StateContainerController.shared.cs

View workflow job for this annotation

GitHub Actions / Build Library (windows-latest)

The variable 'e' is declared but never used

Check warning on line 90 in src/CommunityToolkit.Maui/Layouts/StateContainer/StateContainerController.shared.cs

View workflow job for this annotation

GitHub Actions / Build Library (windows-latest)

The variable 'e' is declared but never used

Check warning on line 90 in src/CommunityToolkit.Maui/Layouts/StateContainer/StateContainerController.shared.cs

View workflow job for this annotation

GitHub Actions / Build Library (windows-latest)

The variable 'e' is declared but never used

Check warning on line 90 in src/CommunityToolkit.Maui/Layouts/StateContainer/StateContainerController.shared.cs

View workflow job for this annotation

GitHub Actions / Build Library (windows-latest)

The variable 'e' is declared but never used

Check warning on line 90 in src/CommunityToolkit.Maui/Layouts/StateContainer/StateContainerController.shared.cs

View workflow job for this annotation

GitHub Actions / Build Library (macos-26)

The variable 'e' is declared but never used

Check warning on line 90 in src/CommunityToolkit.Maui/Layouts/StateContainer/StateContainerController.shared.cs

View workflow job for this annotation

GitHub Actions / Build Library (macos-26)

The variable 'e' is declared but never used

Check warning on line 90 in src/CommunityToolkit.Maui/Layouts/StateContainer/StateContainerController.shared.cs

View workflow job for this annotation

GitHub Actions / Build Library (macos-26)

The variable 'e' is declared but never used

Check warning on line 90 in src/CommunityToolkit.Maui/Layouts/StateContainer/StateContainerController.shared.cs

View workflow job for this annotation

GitHub Actions / Build Library (macos-26)

The variable 'e' is declared but never used

Check warning on line 90 in src/CommunityToolkit.Maui/Layouts/StateContainer/StateContainerController.shared.cs

View workflow job for this annotation

GitHub Actions / Build Library (macos-26)

The variable 'e' is declared but never used

Check warning on line 90 in src/CommunityToolkit.Maui/Layouts/StateContainer/StateContainerController.shared.cs

View workflow job for this annotation

GitHub Actions / Build Library (macos-26)

The variable 'e' is declared but never used

Check warning on line 90 in src/CommunityToolkit.Maui/Layouts/StateContainer/StateContainerController.shared.cs

View workflow job for this annotation

GitHub Actions / Build Library (macos-26)

The variable 'e' is declared but never used

Check warning on line 90 in src/CommunityToolkit.Maui/Layouts/StateContainer/StateContainerController.shared.cs

View workflow job for this annotation

GitHub Actions / Build Library (macos-26)

The variable 'e' is declared but never used

Check warning on line 90 in src/CommunityToolkit.Maui/Layouts/StateContainer/StateContainerController.shared.cs

View workflow job for this annotation

GitHub Actions / Run Benchmarks

The variable 'e' is declared but never used
Comment thread
TheCodeTraveler marked this conversation as resolved.
{
throw new StateContainerException($"Unable to determine {nameof(StateView)} for State: {state}. This State has been assigned to multiple {nameof(StateView)}s. Ensure each {nameof(StateView)} has a unique StateKey");
Comment thread
TheCodeTraveler marked this conversation as resolved.
Outdated
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ static class StateContainerDefaults
{
public const string? CurrentState = null;
public const bool CanStateChange = true;
public static IList<View> StateViews { get; } = [];
}
Loading