Skip to content

Commit

Permalink
Merge pull request #19 from sylac/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
sylac authored Jan 20, 2025
2 parents b59fd3d + b1384f1 commit 7c2398d
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ namespace Sylac.Mvvm.Navigation.Abstractions
{
public interface IPlatformNavigation
{
SynchronizationContext SynchronizationContext { get; }

void RegisterPage<TPage>() where TPage : INavigationablePage;
IObservable<Unit> GoTo(string route);
IObservable<Unit> GoTo(string route, IDictionary<string, object> parameters);
IObservable<Unit> GoBack();
}
}
5 changes: 4 additions & 1 deletion Sylac.Mvvm.Core/Navigation/NavigationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public IObservable<Unit> NavigateTo<TViewModel, TParams>(TParams parameters)
where TParams : IViewModelParameters
{
return Observable.Return(ViewModelsRegistry.GetValueOrDefault(typeof(TViewModel)))
.SubscribeOn(_platformNavigation.SynchronizationContext)
.Where(result => result != default)
.SelectMany(result =>
// is type check needed? Is it possible to pass a different type?
Expand All @@ -54,6 +55,8 @@ public IObservable<Unit> NavigateTo<TViewModel, TParams>(TParams parameters)
: Observable.Return(Unit.Default));
}

public IObservable<Unit> NavigateBack() => _platformNavigation.GoTo("..");
public IObservable<Unit> NavigateBack() => Observable.Return(Unit.Default)
.SubscribeOn(_platformNavigation.SynchronizationContext)
.SelectMany(_ => _platformNavigation.GoBack());
}

2 changes: 1 addition & 1 deletion Sylac.Mvvm.Core/Sylac.Mvvm.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<IsPackable>true</IsPackable>
<PackageId>Sylac.Mvvm.Core</PackageId>
<RootNamespace>Sylac.Mvvm</RootNamespace>
<Version>0.3.0</Version>
<Version>0.3.1</Version>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Authors>Sylwester Łach</Authors>
<RepositoryUrl>https://github.com/sylac/Sylac.Mvvm</RepositoryUrl>
Expand Down
19 changes: 19 additions & 0 deletions Sylac.Mvvm.Maui/Navigation/MauiNavigation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@ namespace Sylac.Mvvm.Maui.Navigation
{
public class MauiNavigation : IPlatformNavigation
{
public SynchronizationContext SynchronizationContext
{
get
{
try
{
return MainThread.GetMainThreadSynchronizationContextAsync().GetAwaiter().GetResult();
}
catch (Exception ex)
{
throw new InvalidOperationException("Failed to get the main thread synchronization context.", ex);
}
}
}

public void RegisterPage<TPage>() where TPage : INavigationablePage
=> Routing.RegisterRoute(typeof(TPage).Name, typeof(TPage));

Expand All @@ -16,5 +31,9 @@ public IObservable<Unit> GoTo(string route) => Shell.Current
public IObservable<Unit> GoTo(string route, IDictionary<string, object> parameters) => Shell.Current
.GoToAsync(route, parameters)
.ToObservable();

public IObservable<Unit> GoBack() => Shell.Current
.GoToAsync("..")
.ToObservable();
}
}
2 changes: 1 addition & 1 deletion Sylac.Mvvm.Maui/Sylac.Mvvm.Maui.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<!-- NUGET PACKAGE SETTINGS -->
<IsPackable>true</IsPackable>
<PackageId>Sylac.Mvvm.Maui</PackageId>
<Version>0.3.0</Version>
<Version>0.3.1</Version>
<Authors>Sylwester Łach</Authors>
<RepositoryUrl>https://github.com/sylac/Sylac.Mvvm</RepositoryUrl>
<RepositoryType>git</RepositoryType>
Expand Down
23 changes: 16 additions & 7 deletions Tests/Sylac.Mvvm.UnitTests/NavigationServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,17 @@ public async Task NavigateTo_ShouldNavigateToPage()
var navigationService = new NavigationService(shellWrapper);
navigationService.RegisterNavigationView<TestPage, TestViewModel, TestViewModelParameters>();

_ = shellWrapper.SynchronizationContext.Returns(SynchronizationContext.Current);

// Act
var result = await navigationService
.NavigateTo<TestViewModel, TestViewModelParameters>(new("TestString"))
.ToTask();

// Assert
Assert.Equal(Unit.Default, result);
await shellWrapper
.Received()
_ = await shellWrapper
.Received(1)
.GoTo(nameof(TestPage), Arg.Any<Dictionary<string, object>>())
.ToTask();

Expand All @@ -76,8 +78,10 @@ public async Task NavigateTo_ShouldThrowArgumentException_WhenViewModelIsNotRegi
var shellWrapper = Substitute.For<IPlatformNavigation>();
var navigationService = new NavigationService(shellWrapper);

_ = shellWrapper.SynchronizationContext.Returns(SynchronizationContext.Current);

// Act & Assert
await Assert.ThrowsAsync<ArgumentException>(() => navigationService
_ = await Assert.ThrowsAsync<ArgumentException>(() => navigationService
.NavigateTo<TestViewModel2, TestViewModelParameters2>(new("TestString"))
.ToTask());

Expand All @@ -96,8 +100,10 @@ public async Task NavigateTo_ShouldThrowArgumentException_IfParametersTypeIsInva
Assert.Fail("Failed to add TestViewModel to ViewModelsRegistry");
}

_ = shellWrapper.SynchronizationContext.Returns(SynchronizationContext.Current);

// Act & Assert
await Assert.ThrowsAsync<ArgumentException>(() => navigationService
_ = await Assert.ThrowsAsync<ArgumentException>(() => navigationService
.NavigateTo<TestViewModel, TestViewModelParameters>(new("TestString"))
.ToTask());

Expand All @@ -111,11 +117,12 @@ public async Task NavigateTo_ShouldThrowArgumentException_IfNavigationFails()
var navigationService = new NavigationService(shellWrapper);
navigationService.RegisterNavigationView<TestPage, TestViewModel, TestViewModelParameters>();

shellWrapper.GoTo(nameof(TestPage), Arg.Any<Dictionary<string, object>>())
_ = shellWrapper.SynchronizationContext.Returns(SynchronizationContext.Current);
_ = shellWrapper.GoTo(nameof(TestPage), Arg.Any<Dictionary<string, object>>())
.Returns(Observable.Throw<Unit>(new Exception("Error navigating to page")));

// Act & Assert
await Assert.ThrowsAsync<Exception>(() => navigationService
_ = await Assert.ThrowsAsync<Exception>(() => navigationService
.NavigateTo<TestViewModel, TestViewModelParameters>(new("TestString"))
.ToTask());

Expand All @@ -129,12 +136,14 @@ public async Task NavigateBack_ShouldNavigateBack()
var shellWrapper = Substitute.For<IPlatformNavigation>();
var navigationService = new NavigationService(shellWrapper);

_ = shellWrapper.SynchronizationContext.Returns(SynchronizationContext.Current);

// Act
var result = await navigationService.NavigateBack().ToTask();

// Assert
Assert.Equal(Unit.Default, result);
await shellWrapper.Received().GoTo("..").ToTask();
_ = await shellWrapper.Received(1).GoBack().ToTask();
}

private record TestViewModelParameters(string TestString) : IViewModelParameters;
Expand Down

0 comments on commit 7c2398d

Please sign in to comment.