diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml new file mode 100644 index 00000000..dac1467d --- /dev/null +++ b/.github/workflows/ci-build.yml @@ -0,0 +1,134 @@ +name: Build + +on: + push: + branches: [ main ] + pull_request: + types: [opened, synchronize, reopened, closed] + branches: [ main ] + +env: + configuration: Release + productNamespacePrefix: "Sextant" + +jobs: + build: + runs-on: windows-latest + outputs: + nbgv: ${{ steps.nbgv.outputs.SemVer2 }} + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Install .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 3.1.x + + - name: Use Node.js + uses: actions/setup-node@v1 + with: + node-version: '12.x' + + - name: NuGet restore + run: dotnet restore + working-directory: src + + - name: NBGV + id: nbgv + uses: dotnet/nbgv@master + with: + setAllVars: true + + - name: Add MSBuild to PATH + uses: microsoft/setup-msbuild@v1 + + - name: Build + run: msbuild /t:build,pack /maxcpucount /p:NoPackageAnalysis=true /verbosity:minimal /p:Configuration=${{ env.configuration }} + working-directory: src + + - name: Run Unit Tests and Generate Coverage + uses: glennawatson/coverlet-msbuild@v1 + with: + project-files: '**/*Tests*.csproj' + no-build: true + exclude-filter: '[${{env.productNamespacePrefix}}*Tests.*]*' + include-filter: '[${{env.productNamespacePrefix}}*]*' + output-format: opencover + merge-with: '../../artifacts/coverage/coverage.json' + output: '../../artifacts/coverage/' + configuration: ${{ env.configuration }} + + - name: Combine Coverage Reports + shell: bash + run: | + dotnet tool install --global dotnet-reportgenerator-globaltool + reportgenerator -reports:artifacts/coverage/*.xml -targetdir:artifacts/finalcoverage -reporttypes:Cobertura + + - name: Upload Code Coverage + run: | + npm install -g codecov + codecov + working-directory: artifacts/finalcoverage + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + - name: Create NuGet Artifacts + uses: actions/upload-artifact@master + with: + name: nuget + path: '**/*.nupkg' + + release: + runs-on: ubuntu-latest + needs: build + if: contains(github.event.pull_request.labels.*.name, 'release') && github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Download NuGet Packages + uses: actions/download-artifact@v2 + with: + name: nuget + + - name: Save SignClient Configuration + run: 'echo "$SIGN_CLIENT_CONFIG" > SignPackages.json' + shell: bash + env: + SIGN_CLIENT_CONFIG: ${{secrets.SIGN_CLIENT_CONFIG}} + + - name: Sign NuGet Packages + uses: glennawatson/signclient@v1 + with: + input-files: '**/*.nupkg' + sign-client-secret: ${{ secrets.SIGN_CLIENT_SECRET }} + sign-client-user: ${{ secrets.SIGN_CLIENT_USER_ID }} + project-name: reactiveui + description: reactiveui + config-file: SignPackages.json + + - name: Changelog + uses: glennawatson/ChangeLog@v1 + id: changelog + + - name: Create Release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token + with: + tag_name: ${{ needs.build.outputs.nbgv }} + release_name: ${{ needs.build.outputs.nbgv }} + body: | + ${{ steps.changelog.outputs.commitLog }} + + - name: NuGet Push + env: + NUGET_AUTH_TOKEN: ${{ secrets.NUGET_API_KEY }} + SOURCE_URL: https://api.nuget.org/v3/index.json + run: | + dotnet nuget push -s ${{ env.SOURCE_URL }} -k ${{ env.NUGET_AUTH_TOKEN }} **/*.nupkg diff --git a/README.md b/README.md index 5127bb41..065f4d7b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## Sextant -[![NuGet Stats](https://img.shields.io/nuget/v/sextant.svg)](https://www.nuget.org/packages/sextant) [![Build Status](https://dev.azure.com/dotnet/ReactiveUI/_apis/build/status/Sextant-CI)](https://dev.azure.com/dotnet/ReactiveUI/_build/latest?definitionId=76) [![Code Coverage](https://codecov.io/gh/reactiveui/sextant/branch/main/graph/badge.svg)](https://codecov.io/gh/reactiveui/sextant) +[![NuGet Stats](https://img.shields.io/nuget/v/sextant.svg)](https://www.nuget.org/packages/sextant) ![Build](https://github.com/reactiveui/Sextant/workflows/Build/badge.svg) [![Code Coverage](https://codecov.io/gh/reactiveui/sextant/branch/main/graph/badge.svg)](https://codecov.io/gh/reactiveui/sextant)
diff --git a/azure-pipelines.yml b/azure-pipelines.yml deleted file mode 100644 index ebed7531..00000000 --- a/azure-pipelines.yml +++ /dev/null @@ -1,19 +0,0 @@ -trigger: -- main -- rel/* -- preview/* - -pr: -- main -- rel/* -- preview/* - -resources: - repositories: - - repository: templates - type: github - name: ReactiveUI/ReactiveUI.Cake.Recipe - endpoint: reactiveui - -jobs: -- template: Azure/azure-pipelines.yml@templates # Template reference diff --git a/build.cake b/build.cake deleted file mode 100644 index 9980dd39..00000000 --- a/build.cake +++ /dev/null @@ -1,30 +0,0 @@ -#load nuget:https://pkgs.dev.azure.com/dotnet/ReactiveUI/_packaging/ReactiveUI/nuget/v3/index.json?package=ReactiveUI.Cake.Recipe&prerelease - -Environment.SetVariableNames(); - -// Whitelisted Packages -var packageWhitelist = new[] -{ - MakeAbsolute(File("./src/Sextant/Sextant.csproj")), - MakeAbsolute(File("./src/Sextant.XamForms/Sextant.XamForms.csproj")), -}; - -var packageTestWhitelist = new[] -{ - MakeAbsolute(File("./src/Sextant.Tests/Sextant.Tests.csproj")), - MakeAbsolute(File("./src/Sextant.XamForms.Tests/Sextant.XamForms.Tests.csproj")), -}; - -BuildParameters.SetParameters(context: Context, - buildSystem: BuildSystem, - title: "Sextant", - whitelistPackages: packageWhitelist, - whitelistTestPackages: packageTestWhitelist, - artifactsDirectory: "./artifacts", - sourceDirectory: "./src"); - -var testCoverageExcludeFilters = new [] { string.Format("[{0}*Tests*]*", BuildParameters.Title), string.Format("[{0}*Mocks*]*", BuildParameters.Title) }; - -ToolSettings.SetToolSettings(context: Context, testCoverageExcludeFilters: testCoverageExcludeFilters); - -Build.Run(); diff --git a/build.cmd b/build.cmd deleted file mode 100644 index e5fa880c..00000000 --- a/build.cmd +++ /dev/null @@ -1,2 +0,0 @@ -@echo off -powershell -ExecutionPolicy Unrestricted ./build.ps1 %CAKE_ARGS% %* diff --git a/build.config b/build.config deleted file mode 100644 index 70326d4e..00000000 --- a/build.config +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -CAKE_VERSION=0.38.4 diff --git a/build.ps1 b/build.ps1 deleted file mode 100644 index 27395f38..00000000 --- a/build.ps1 +++ /dev/null @@ -1,112 +0,0 @@ -$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent - -[string] $CakeVersion = '' -foreach($line in Get-Content "$PSScriptRoot\build.config") -{ - if ($line -like 'CAKE_VERSION=*') { - $CakeVersion = $line.SubString(13) - } -} - - -if ([string]::IsNullOrEmpty($CakeVersion)) { - 'Failed to parse Cake Version' - exit 1 -} - -# Make sure tools folder exists -$ToolPath = Join-Path $PSScriptRoot "tools" -if (!(Test-Path $ToolPath)) { - Write-Verbose "Creating tools directory..." - New-Item -Path $ToolPath -Type Directory -Force | out-null -} - - -if ($PSVersionTable.PSEdition -ne 'Core') { - # Attempt to set highest encryption available for SecurityProtocol. - # PowerShell will not set this by default (until maybe .NET 4.6.x). This - # will typically produce a message for PowerShell v2 (just an info - # message though) - try { - # Set TLS 1.2 (3072), then TLS 1.1 (768), then TLS 1.0 (192), finally SSL 3.0 (48) - # Use integers because the enumeration values for TLS 1.2 and TLS 1.1 won't - # exist in .NET 4.0, even though they are addressable if .NET 4.5+ is - # installed (.NET 4.5 is an in-place upgrade). - [System.Net.ServicePointManager]::SecurityProtocol = 3072 -bor 768 -bor 192 -bor 48 - } catch { - Write-Output 'Unable to set PowerShell to use TLS 1.2 and TLS 1.1 due to old .NET Framework installed. If you see underlying connection closed or trust errors, you may need to upgrade to .NET Framework 4.5+ and PowerShell v3' - } -} - -########################################################################### -# INSTALL .NET CORE CLI -########################################################################### - -Function Remove-PathVariable([string]$VariableToRemove) -{ - $SplitChar = ';' - if ($IsMacOS -or $IsLinux) { - $SplitChar = ':' - } - - $path = [Environment]::GetEnvironmentVariable("PATH", "User") - if ($path -ne $null) - { - $newItems = $path.Split($SplitChar, [StringSplitOptions]::RemoveEmptyEntries) | Where-Object { "$($_)" -inotlike $VariableToRemove } - [Environment]::SetEnvironmentVariable("PATH", [System.String]::Join($SplitChar, $newItems), "User") - } - - $path = [Environment]::GetEnvironmentVariable("PATH", "Process") - if ($path -ne $null) - { - $newItems = $path.Split($SplitChar, [StringSplitOptions]::RemoveEmptyEntries) | Where-Object { "$($_)" -inotlike $VariableToRemove } - [Environment]::SetEnvironmentVariable("PATH", [System.String]::Join($SplitChar, $newItems), "Process") - } -} - -$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 -$env:DOTNET_CLI_TELEMETRY_OPTOUT=1 - -########################################################################### -# INSTALL CAKE -########################################################################### - -# Make sure Cake has been installed. -[string] $CakeExePath = '' -[string] $CakeInstalledVersion = Get-Command dotnet-cake -ErrorAction SilentlyContinue | % {&$_.Source --version} - -if ($CakeInstalledVersion -eq $CakeVersion) { - # Cake found locally - $CakeExePath = (Get-Command dotnet-cake).Source -} -else { - $CakePath = Join-Path $ToolPath ".store\cake.tool\$CakeVersion" - $CakeExePath = (Get-ChildItem -Path $ToolPath -Filter "dotnet-cake*" -File| ForEach-Object FullName | Select-Object -First 1) - - - if ((!(Test-Path -Path $CakePath -PathType Container)) -or (!(Test-Path $CakeExePath -PathType Leaf))) { - - if ((![string]::IsNullOrEmpty($CakeExePath)) -and (Test-Path $CakeExePath -PathType Leaf)) - { - & dotnet tool uninstall --tool-path $ToolPath Cake.Tool - } - - & dotnet tool install --tool-path $ToolPath --version $CakeVersion Cake.Tool - if ($LASTEXITCODE -ne 0) - { - 'Failed to install cake' - exit 1 - } - $CakeExePath = (Get-ChildItem -Path $ToolPath -Filter "dotnet-cake*" -File| ForEach-Object FullName | Select-Object -First 1) - } -} - -########################################################################### -# RUN BUILD SCRIPT -########################################################################### -& "$CakeExePath" ./build.cake --bootstrap -if ($LASTEXITCODE -eq 0) -{ - & "$CakeExePath" ./build.cake $args -} -exit $LASTEXITCODE diff --git a/build.sh b/build.sh deleted file mode 100755 index 8c2183fd..00000000 --- a/build.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env bash -# Define varibles -SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) -source $SCRIPT_DIR/build.config -TOOLS_DIR=$SCRIPT_DIR/tools -CAKE_EXE=$TOOLS_DIR/dotnet-cake -CAKE_PATH=$TOOLS_DIR/.store/cake.tool/$CAKE_VERSION - -# Make sure the tools folder exist. -if [ ! -d "$TOOLS_DIR" ]; then - mkdir "$TOOLS_DIR" -fi - -########################################################################### -# INSTALL CAKE -########################################################################### -export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 -export DOTNET_CLI_TELEMETRY_OPTOUT=1 -export DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER=0 - -CAKE_INSTALLED_VERSION=$(dotnet-cake --version 2>&1) - -if [ "$CAKE_VERSION" != "$CAKE_INSTALLED_VERSION" ]; then - if [ ! -f "$CAKE_EXE" ] || [ ! -d "$CAKE_PATH" ]; then - if [ -f "$CAKE_EXE" ]; then - dotnet tool uninstall --tool-path $TOOLS_DIR Cake.Tool - fi - - echo "Installing Cake $CAKE_VERSION..." - dotnet tool install --tool-path $TOOLS_DIR --version $CAKE_VERSION Cake.Tool - if [ $? -ne 0 ]; then - echo "An error occured while installing Cake." - exit 1 - fi - fi - - # Make sure that Cake has been installed. - if [ ! -f "$CAKE_EXE" ]; then - echo "Could not find Cake.exe at '$CAKE_EXE'." - exit 1 - fi -else - CAKE_EXE="dotnet-cake" -fi - -########################################################################### -# RUN BUILD SCRIPT -########################################################################### - -# Start Cake -(exec "$CAKE_EXE" --bootstrap) && (exec "$CAKE_EXE" "$@") \ No newline at end of file diff --git a/cake.config b/cake.config deleted file mode 100644 index c26865e6..00000000 --- a/cake.config +++ /dev/null @@ -1,7 +0,0 @@ -[Paths] -Tools=./tools -Addins=./tools/Addins -Modules=./tools/Modules - -[NuGet] -UseInProcessClient=true diff --git a/src/Directory.build.props b/src/Directory.build.props index ee4db622..ffd2a204 100644 --- a/src/Directory.build.props +++ b/src/Directory.build.props @@ -31,23 +31,29 @@ - + + - + + + all + runtime; build; native; contentfiles; analyzers + + - + - + - \ No newline at end of file + diff --git a/src/Sextant.Tests/API/ApiApprovalTests.SextantProject.netcoreapp2.2.approved.txt b/src/Sextant.Tests/API/ApiApprovalTests.SextantProject.netcoreapp3.1.approved.txt similarity index 99% rename from src/Sextant.Tests/API/ApiApprovalTests.SextantProject.netcoreapp2.2.approved.txt rename to src/Sextant.Tests/API/ApiApprovalTests.SextantProject.netcoreapp3.1.approved.txt index 78013499..30b5df48 100644 --- a/src/Sextant.Tests/API/ApiApprovalTests.SextantProject.netcoreapp2.2.approved.txt +++ b/src/Sextant.Tests/API/ApiApprovalTests.SextantProject.netcoreapp3.1.approved.txt @@ -131,6 +131,7 @@ namespace Sextant { public static Sextant.IViewModelFactory Current { get; } } + [System.Serializable] public class ViewModelFactoryNotFoundException : System.Exception { public ViewModelFactoryNotFoundException() { } diff --git a/src/Sextant.Tests/API/ApiApprovalTests.cs b/src/Sextant.Tests/API/ApiApprovalTests.cs index 39d5a929..34e0d289 100644 --- a/src/Sextant.Tests/API/ApiApprovalTests.cs +++ b/src/Sextant.Tests/API/ApiApprovalTests.cs @@ -10,8 +10,8 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Text.RegularExpressions; +using DiffEngine; using PublicApiGenerator; -using Shouldly; using Splat; using Xunit; @@ -60,7 +60,7 @@ private static void CheckApproval(Assembly assembly, [CallerMemberName]string me if (!string.Equals(receivedPublicApi, approvedPublicApi, StringComparison.InvariantCulture)) { File.WriteAllText(receivedFileName, receivedPublicApi); - ShouldlyConfiguration.DiffTools.GetDiffTool().Open(receivedFileName, approvedFileName, true); + DiffRunner.Launch(receivedFileName, approvedFileName); } Assert.Equal(approvedPublicApi, receivedPublicApi); diff --git a/src/Sextant.Tests/DependencyResolverMixinTests.cs b/src/Sextant.Tests/DependencyResolverMixinTests.cs index f45649ce..b8aa5c34 100644 --- a/src/Sextant.Tests/DependencyResolverMixinTests.cs +++ b/src/Sextant.Tests/DependencyResolverMixinTests.cs @@ -3,9 +3,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. +using FluentAssertions; using ReactiveUI; using Sextant.Mocks; -using Shouldly; using Splat; using Xunit; @@ -34,7 +34,7 @@ public void Should_Register_View_Model_Factory() var result = ViewModelFactory.Current; // Then - result.ShouldBeOfType(); + result.Should().BeOfType(); } /// @@ -51,7 +51,7 @@ public void Should_Register_View_Model_Factory_With_Factory() var result = ViewModelFactory.Current; // Then - result.ShouldBe(viewModelFactory); + result.Should().Be(viewModelFactory); } } @@ -73,7 +73,7 @@ public void Should_Register_View() var result = Locator.Current.GetService>(); // Then - result.ShouldBeOfType(); + result.Should().BeOfType(); } /// @@ -89,7 +89,7 @@ public void Should_Register_View_Factory() var result = Locator.Current.GetService>(); // Then - result.ShouldBeOfType(); + result.Should().BeOfType(); } } } diff --git a/src/Sextant.Tests/Navigation/DestructibleTests.cs b/src/Sextant.Tests/Navigation/DestructibleTests.cs index 6b61968d..722b7108 100644 --- a/src/Sextant.Tests/Navigation/DestructibleTests.cs +++ b/src/Sextant.Tests/Navigation/DestructibleTests.cs @@ -5,9 +5,9 @@ using System.Reactive.Linq; using System.Threading.Tasks; +using FluentAssertions; using NSubstitute; using Sextant.Mocks; -using Shouldly; using Xunit; namespace Sextant.Tests @@ -32,11 +32,11 @@ public void Should_Destroy() ParameterViewModel sut = new ParameterViewModel(); // When - sut.Disposable.IsDisposed.ShouldBeFalse(); + sut.Disposable.IsDisposed.Should().BeFalse(); sut.Destroy(); // Then - sut.Disposable.IsDisposed.ShouldBeTrue(); + sut.Disposable.IsDisposed.Should().BeTrue(); } /// diff --git a/src/Sextant.Tests/Navigation/NavigatedTests.cs b/src/Sextant.Tests/Navigation/NavigatedTests.cs index 43d0a88f..3633317c 100644 --- a/src/Sextant.Tests/Navigation/NavigatedTests.cs +++ b/src/Sextant.Tests/Navigation/NavigatedTests.cs @@ -5,8 +5,8 @@ using System; using System.Collections.Generic; +using FluentAssertions; using Sextant.Mocks; -using Shouldly; using Xunit; namespace Sextant.Tests @@ -34,8 +34,8 @@ public void Should_Unwrap_Parameters() sut.WhenNavigatedTo(new NavigationParameter { { "hello", "world" }, { "life", 42 } }).Subscribe(); // Then - sut.Text.ShouldBe("world"); - sut.Meaning.ShouldBe(42); + sut.Text.Should().Be("world"); + sut.Meaning.Should().Be(42); } /// @@ -51,7 +51,7 @@ public void Should_Return_Null_If_No_Values_Provided() sut.WhenNavigatedTo(new NavigationParameter()); // Then - sut.Text.ShouldBeNull(); + sut.Text.Should().BeNull(); } /// @@ -64,10 +64,10 @@ public void Should_Throw_If_Key_Not_Found() ParameterViewModel sut = new ParameterViewModel(); // When - var result = Should.Throw(() => sut.WhenNavigatedTo(new NavigationParameter { { "hello", "world" } }).Subscribe()); + var result = Record.Exception(() => sut.WhenNavigatedTo(new NavigationParameter { { "hello", "world" } }).Subscribe()); // Then - result.ShouldNotBeNull(); + result.Should().BeOfType(); } } @@ -89,8 +89,8 @@ public void Should_Unwrap_Parameters() sut.WhenNavigatedFrom(new NavigationParameter { { "hello", "world" }, { "life", 42 } }).Subscribe(); // Then - sut.Text.ShouldBe("world"); - sut.Meaning.ShouldBe(42); + sut.Text.Should().Be("world"); + sut.Meaning.Should().Be(42); } /// @@ -106,7 +106,7 @@ public void Should_Return_Null_If_No_Values_Provided() sut.WhenNavigatedFrom(new NavigationParameter()); // Then - sut.Text.ShouldBeNull(); + sut.Text.Should().BeNull(); } /// @@ -119,10 +119,10 @@ public void Should_Throw_If_Key_Not_Found() ParameterViewModel sut = new ParameterViewModel(); // When - var result = Should.Throw(() => sut.WhenNavigatedFrom(new NavigationParameter { { "hello", "world" } }).Subscribe()); + var result = Record.Exception(() => sut.WhenNavigatedFrom(new NavigationParameter { { "hello", "world" } }).Subscribe()); // Then - result.ShouldNotBeNull(); + result.Should().BeOfType(); } } } diff --git a/src/Sextant.Tests/Navigation/NavigatingTests.cs b/src/Sextant.Tests/Navigation/NavigatingTests.cs index 50147f6a..e4633820 100644 --- a/src/Sextant.Tests/Navigation/NavigatingTests.cs +++ b/src/Sextant.Tests/Navigation/NavigatingTests.cs @@ -5,8 +5,8 @@ using System; using System.Collections.Generic; +using FluentAssertions; using Sextant.Mocks; -using Shouldly; using Xunit; namespace Sextant.Tests @@ -34,8 +34,8 @@ public void Should_Unwrap_Parameters() sut.WhenNavigatingTo(new NavigationParameter { { "hello", "world" }, { "life", 42 } }).Subscribe(); // Then - sut.Text.ShouldBe("world"); - sut.Meaning.ShouldBe(42); + sut.Text.Should().Be("world"); + sut.Meaning.Should().Be(42); } /// @@ -51,7 +51,7 @@ public void Should_Return_Null_If_No_Values_Provided() sut.WhenNavigatingTo(new NavigationParameter()); // Then - sut.Text.ShouldBeNull(); + sut.Text.Should().BeNull(); } /// @@ -64,10 +64,10 @@ public void Should_Throw_If_Key_Not_Found() ParameterViewModel sut = new ParameterViewModel(); // When - var result = Should.Throw(() => sut.WhenNavigatingTo(new NavigationParameter { { "hello", "world" } }).Subscribe()); + var result = Record.Exception(() => sut.WhenNavigatingTo(new NavigationParameter { { "hello", "world" } }).Subscribe()); // Then - result.ShouldNotBeNull(); + result.Should().BeOfType(); } } } diff --git a/src/Sextant.Tests/Navigation/ParameterViewStackServiceTests.cs b/src/Sextant.Tests/Navigation/ParameterViewStackServiceTests.cs index adaba985..7db32986 100644 --- a/src/Sextant.Tests/Navigation/ParameterViewStackServiceTests.cs +++ b/src/Sextant.Tests/Navigation/ParameterViewStackServiceTests.cs @@ -7,9 +7,9 @@ using System.Reactive.Linq; using System.Reactive.Subjects; using System.Threading.Tasks; +using FluentAssertions; using NSubstitute; using Sextant.Mocks; -using Shouldly; using Splat; using Xunit; @@ -43,7 +43,7 @@ public void Should_Throw_If_View_Model_Factory_Current_Null() var result = Record.Exception(() => new ParameterViewStackServiceFixture().WithFactory(null)); // Then - result.ShouldBeOfType(); + result.Should().BeOfType(); } /// @@ -59,7 +59,7 @@ public void Should_Resolve_View_Model_Factory() var result = Record.Exception(() => new ParameterViewStackServiceFixture().WithFactory(null)); // Then - result.ShouldBeNull(); + result.Should().BeNull(); } } @@ -81,12 +81,11 @@ public async Task Should_Throw_If_View_Model_Null() // When var result = - await Should - .ThrowAsync(async () => await sut.PushPage(null, navigationParameter)) + await Record.ExceptionAsync(async () => await sut.PushPage(null, navigationParameter)) .ConfigureAwait(false); // Then - result.ParamName.ShouldBe("navigableViewModel"); + result.Should().BeOfType().Which.ParamName.Should().Be("navigableViewModel"); } /// @@ -102,12 +101,11 @@ public async Task Should_Throw_If_Parameter_Null() // When var result = - await Should - .ThrowAsync(async () => await sut.PushPage(viewModel, (INavigationParameter)null)) + await Record.ExceptionAsync(async () => await sut.PushPage(viewModel, (INavigationParameter)null)) .ConfigureAwait(false); // Then - result.ParamName.ShouldBe("parameter"); + result.Should().BeOfType().Which.ParamName.Should().Be("parameter"); } /// @@ -247,12 +245,11 @@ public async Task Should_Throw_If_View_Model_Null() // When var result = - await Should - .ThrowAsync(async () => await sut.PushPage(navigationParameter)) + await Record.ExceptionAsync(async () => await sut.PushPage(navigationParameter)) .ConfigureAwait(false); // Then - result.ParamName.ShouldBe("navigableViewModel"); + result.Should().BeOfType().Which.ParamName.Should().Be("navigableViewModel"); } /// @@ -267,12 +264,11 @@ public async Task Should_Throw_If_Parameter_Null() // When var result = - await Should - .ThrowAsync(async () => await sut.PushPage(null)) + await Record.ExceptionAsync(async () => await sut.PushPage(null)) .ConfigureAwait(false); // Then - result.ParamName.ShouldBe("parameter"); + result.Should().BeOfType().Which.ParamName.Should().Be("parameter"); } /// @@ -342,12 +338,11 @@ public async Task Should_Throw_If_View_Model_Null() // When var result = - await Should - .ThrowAsync(async () => await sut.PushModal(null, navigationParameter)) + await Record.ExceptionAsync(async () => await sut.PushModal(null, navigationParameter)) .ConfigureAwait(false); // Then - result.ParamName.ShouldBe("navigableModal"); + result.Should().BeOfType().Which.ParamName.Should().Be("navigableModal"); } /// @@ -363,12 +358,11 @@ public async Task Should_Throw_If_Parameter_Null() // When var result = - await Should - .ThrowAsync(async () => await sut.PushModal(viewModel, null)) + await Record.ExceptionAsync(async () => await sut.PushModal(viewModel, null)) .ConfigureAwait(false); // Then - result.ParamName.ShouldBe("parameter"); + result.Should().BeOfType().Which.ParamName.Should().Be("parameter"); } /// @@ -485,12 +479,11 @@ public async Task Should_Throw_If_View_Model_Null() // When var result = - await Should - .ThrowAsync(async () => await sut.PushModal(navigationParameter)) + await Record.ExceptionAsync(async () => await sut.PushModal(navigationParameter)) .ConfigureAwait(false); // Then - result.ParamName.ShouldBe("navigableModal"); + result.Should().BeOfType().Which.ParamName.Should().Be("navigableModal"); } /// @@ -505,12 +498,11 @@ public async Task Should_Throw_If_Parameter_Null() // When var result = - await Should - .ThrowAsync(async () => await sut.PushModal(null)) + await Record.ExceptionAsync(async () => await sut.PushModal(null)) .ConfigureAwait(false); // Then - result.ParamName.ShouldBe("parameter"); + result.Should().BeOfType().Which.ParamName.Should().Be("parameter"); } /// @@ -580,12 +572,11 @@ public async Task Should_Throw_If_Parameter_Null() // When var result = - await Should - .ThrowAsync(async () => await sut.PopPage(null)) + await Record.ExceptionAsync(async () => await sut.PopPage(null)) .ConfigureAwait(false); // Then - result.ParamName.ShouldBe("parameter"); + result.Should().BeOfType().Which.ParamName.Should().Be("parameter"); } /// diff --git a/src/Sextant.Tests/Navigation/ViewStackServiceTests.cs b/src/Sextant.Tests/Navigation/ViewStackServiceTests.cs index 7aeac914..8ab6a1ba 100644 --- a/src/Sextant.Tests/Navigation/ViewStackServiceTests.cs +++ b/src/Sextant.Tests/Navigation/ViewStackServiceTests.cs @@ -9,9 +9,9 @@ using System.Reactive.Linq; using System.Reactive.Subjects; using System.Threading.Tasks; +using FluentAssertions; using NSubstitute; using Sextant.Mocks; -using Shouldly; using Splat; using Xunit; @@ -45,7 +45,7 @@ public void Should_Throw_If_View_Model_Factory_Current_Null() var result = Record.Exception(() => (ViewStackService)new ViewStackServiceFixture().WithFactory(null)); // Then - result.ShouldBeOfType(); + result.Should().BeOfType(); } /// @@ -61,7 +61,7 @@ public void Should_Resolve_View_Model_Factory() var result = Record.Exception(() => (ViewStackService)new ViewStackServiceFixture().WithFactory(null)); // Then - result.ShouldBeNull(); + result.Should().BeNull(); } } @@ -80,7 +80,7 @@ public void Should_Return_Observable() ViewStackService sut = new ViewStackServiceFixture(); // Then - sut.PageStack.ShouldNotBeOfType>>(); + sut.PageStack.Should().NotBeOfType>>(); } /// @@ -93,7 +93,7 @@ public void Should_Not_Return_Behavior() ViewStackService sut = new ViewStackServiceFixture(); // Then - sut.PageStack.ShouldNotBeOfType>>(); + sut.PageStack.Should().NotBeOfType>>(); } } @@ -112,7 +112,7 @@ public void Should_Return_Observable() ViewStackService sut = new ViewStackServiceFixture(); // Then - sut.ModalStack.ShouldNotBeOfType>>(); + sut.ModalStack.Should().NotBeOfType>>(); } /// @@ -125,7 +125,7 @@ public void Should_Not_Return_Behavior() ViewStackService sut = new ViewStackServiceFixture(); // Then - sut.ModalStack.ShouldNotBeOfType>>(); + sut.ModalStack.Should().NotBeOfType>>(); } } @@ -147,12 +147,12 @@ public async Task Should_Pop_Modal() // When var item = await sut.ModalStack.FirstAsync(); - item.Count.ShouldBe(1); + item.Count.Should().Be(1); await sut.PopModal(); // Then item = await sut.ModalStack.FirstAsync(); - item.ShouldBeEmpty(); + item.Should().BeEmpty(); } /// @@ -188,7 +188,7 @@ public async Task Should_Return_Unit() var result = await sut.PopModal(); // Then - result.ShouldBeOfType(); + result.Should().BeOfType(); } /// @@ -205,8 +205,8 @@ public async Task Should_Throw_If_Stack_Empty() var result = await Record.ExceptionAsync(async () => await sut.PopModal()).ConfigureAwait(false); // Then - result.ShouldBeOfType(); - result?.Message.ShouldBe("Stack is empty."); + result.Should().BeOfType(); + result?.Message.Should().Be("Stack is empty."); } /// @@ -283,7 +283,7 @@ public async Task Should_Pop_Page() var result = await sut.PageStack.FirstAsync(); // Then - result.ShouldBeEmpty(); + result.Should().BeEmpty(); } /// @@ -319,7 +319,7 @@ public async Task Should_Return_Unit() var result = await sut.PopPage(); // Then - result.ShouldBeOfType(); + result.Should().BeOfType(); } /// @@ -395,10 +395,10 @@ public async Task Should_Throw_If_Stack_Empty() ViewStackService sut = new ViewStackServiceFixture(); // When - var result = await Should.ThrowAsync(async () => await sut.PopToRootPage()).ConfigureAwait(false); + var result = await Record.ExceptionAsync(async () => await sut.PopToRootPage()).ConfigureAwait(false); // Then - result.Message.ShouldBe("Stack is empty."); + result.Should().BeOfType().Which.Message.Should().Be("Stack is empty."); } /// @@ -417,7 +417,7 @@ public async Task Should_Clear_Navigation_Stack() var result = await sut.PageStack.FirstOrDefaultAsync(); // Then - result.ShouldHaveSingleItem(); + result.Should().ContainSingle(); } /// @@ -441,7 +441,7 @@ public async Task Should_Return_Single_Notification() await sut.PopToRootPage(); // Then - count.ShouldBe(1); + count.Should().Be(1); } /// @@ -460,7 +460,7 @@ public async Task Should_Have_One_Item_On_Stack() var result = await sut.PageStack.FirstOrDefaultAsync(); // Then - result.ShouldHaveSingleItem(); + result.Should().ContainSingle(); } /// @@ -511,14 +511,14 @@ public async Task Should_Push_And_Pop(int amount) // Given ViewStackService sut = new ViewStackServiceFixture(); await sut.PushModal(new NavigableViewModelMock(), "modal", amount); - sut.ModalStack.FirstAsync().Wait().Count.ShouldBe(amount); + sut.ModalStack.FirstAsync().Wait().Count.Should().Be(amount); await sut.PopModal(amount); // When var result = await sut.ModalStack.FirstAsync(); // Then - result.ShouldBeEmpty(); + result.Should().BeEmpty(); } /// @@ -536,8 +536,8 @@ public async Task Should_Push_Modal() var result = await sut.TopModal(); // Then - result.ShouldNotBeNull(); - result.ShouldBeOfType(); + result.Should().NotBeNull(); + result.Should().BeOfType(); } /// @@ -576,8 +576,8 @@ public async Task Should_Push_Page_On_Stack() var result = await sut.ModalStack.FirstAsync(); // Then - result.ShouldNotBeEmpty(); - result.Count.ShouldBe(1); + result.Should().NotBeEmpty(); + result.Count.Should().Be(1); } /// @@ -611,7 +611,7 @@ public async Task Should_Throw_If_View_Model_Null() var result = await Record.ExceptionAsync(async () => await sut.PushModal(null)).ConfigureAwait(false); // Then - result.ShouldBeOfType(); + result.Should().BeOfType(); } } @@ -642,12 +642,11 @@ public async Task Should_Throw_If_View_Model_Null() // When var result = - await Should - .ThrowAsync(async () => await sut.PushModal()) + await Record.ExceptionAsync(async () => await sut.PushModal()) .ConfigureAwait(false); // Then - result.ParamName.ShouldBe("modal"); + result.Should().BeOfType().Which.ParamName.Should().Be("modal"); } /// @@ -705,10 +704,10 @@ public async Task Should_Throw_If_View_Model_Null() ViewStackService sut = new ViewStackServiceFixture(); // When - var result = await Should.ThrowAsync(async () => await sut.PushPage(null)).ConfigureAwait(false); + var result = await Record.ExceptionAsync(async () => await sut.PushPage(null)).ConfigureAwait(false); // Then - result.ParamName.ShouldBe("viewModel"); + result.Should().BeOfType().Which.ParamName.Should().Be("viewModel"); } /// @@ -726,8 +725,8 @@ public async Task Should_Push_Page() var result = await sut.TopPage(); // Then - result.ShouldNotBeNull(); - result.ShouldBeOfType(); + result.Should().NotBeNull(); + result.Should().BeOfType(); } /// @@ -745,8 +744,8 @@ public async Task Should_Push_Page_On_Stack() var result = await sut.PageStack.FirstAsync(); // Then - result.ShouldNotBeEmpty(); - result.Count.ShouldBe(1); + result.Should().NotBeEmpty(); + result.Count.Should().Be(1); } /// @@ -782,7 +781,7 @@ public async Task Should_Clear_Navigation_Stack_If_Reset() var result = await sut.PageStack.FirstOrDefaultAsync(); // Then - result.ShouldHaveSingleItem(); + result.Should().ContainSingle(); } } @@ -812,12 +811,11 @@ public async Task Should_Throw_If_View_Model_Null() // When var result = - await Should - .ThrowAsync(async () => await sut.PushPage()) + await Record.ExceptionAsync(async () => await sut.PushPage()) .ConfigureAwait(false); // Then - result.ParamName.ShouldBe("viewModel"); + result.Should().BeOfType().Which.ParamName.Should().Be("viewModel"); } /// @@ -898,8 +896,8 @@ public async Task Should_Return_Last_Element() var result = await sut.TopModal(); // Then - result.ShouldBeOfType(); - result.Id.ShouldBe("2"); + result.Should().BeOfType(); + result.Id.Should().Be("2"); } /// @@ -913,10 +911,10 @@ public async Task Should_Throw_If_Stack_Empty() ViewStackService sut = new ViewStackServiceFixture(); // When - var result = await Should.ThrowAsync(async () => await sut.TopModal()).ConfigureAwait(false); + var result = await Record.ExceptionAsync(async () => await sut.TopModal()).ConfigureAwait(false); // Then - result.ParamName.ShouldBe("index"); + result.Should().BeOfType().Which.ParamName.Should().Be("index"); } } @@ -959,8 +957,8 @@ public async Task Should_Return_Last_Element() var result = await sut.TopPage(); // Then - result.ShouldBeOfType(); - result.Id.ShouldBe("2"); + result.Should().BeOfType(); + result.Id.Should().Be("2"); } /// @@ -974,10 +972,10 @@ public async Task Should_Throw_If_Stack_Empty() ViewStackService sut = new ViewStackServiceFixture(); // When - var result = await Should.ThrowAsync(async () => await sut.TopPage()).ConfigureAwait(false); + var result = await Record.ExceptionAsync(async () => await sut.TopPage()).ConfigureAwait(false); // Then - result.ParamName.ShouldBe("index"); + result.Should().BeOfType().Which.ParamName.Should().Be("index"); } } } diff --git a/src/Sextant.Tests/Sextant.Tests.csproj b/src/Sextant.Tests/Sextant.Tests.csproj index 4542f081..c18764a4 100644 --- a/src/Sextant.Tests/Sextant.Tests.csproj +++ b/src/Sextant.Tests/Sextant.Tests.csproj @@ -1,7 +1,6 @@  - netcoreapp2.2 - $(TargetFrameworks);net472 + netcoreapp3.1 $(NoWarn);1591;CA1707;SA1633;CA1034;CA2000 false latest diff --git a/src/Sextant.Tests/ViewModelFactoryTests.cs b/src/Sextant.Tests/ViewModelFactoryTests.cs index 849576de..7af7c2ad 100644 --- a/src/Sextant.Tests/ViewModelFactoryTests.cs +++ b/src/Sextant.Tests/ViewModelFactoryTests.cs @@ -3,7 +3,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -using Shouldly; +using FluentAssertions; using Splat; using Xunit; @@ -34,10 +34,10 @@ public CurrentPropertyTests() public void Should_Throw_If_Not_Registered() { // Given, When - var result = Should.Throw(() => ViewModelFactory.Current); + var result = Record.Exception(() => ViewModelFactory.Current); // Then - result.Message.ShouldBe("Could not find a default ViewModelFactory. This should never happen, your dependency resolver is broken"); + result.Should().BeOfType().Which.Message.Should().Be("Could not find a default ViewModelFactory. This should never happen, your dependency resolver is broken"); } /// @@ -51,8 +51,8 @@ public void Should_Return_View_Model_Factory() var viewModelFactory = ViewModelFactory.Current; // Then - viewModelFactory.ShouldBeAssignableTo(); - viewModelFactory.ShouldBeOfType(); + viewModelFactory.Should().BeAssignableTo(); + viewModelFactory.Should().BeOfType(); } } } diff --git a/src/Sextant.XamForms.Tests/API/ApiApprovalTests.SextantProject.netcoreapp2.2.approved.txt b/src/Sextant.XamForms.Tests/API/ApiApprovalTests.SextantProject.netcoreapp3.1.approved.txt similarity index 100% rename from src/Sextant.XamForms.Tests/API/ApiApprovalTests.SextantProject.netcoreapp2.2.approved.txt rename to src/Sextant.XamForms.Tests/API/ApiApprovalTests.SextantProject.netcoreapp3.1.approved.txt diff --git a/src/Sextant.XamForms.Tests/API/ApiApprovalTests.cs b/src/Sextant.XamForms.Tests/API/ApiApprovalTests.cs index 814455a6..d7975b19 100644 --- a/src/Sextant.XamForms.Tests/API/ApiApprovalTests.cs +++ b/src/Sextant.XamForms.Tests/API/ApiApprovalTests.cs @@ -10,8 +10,8 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Text.RegularExpressions; +using DiffEngine; using PublicApiGenerator; -using Shouldly; using Splat; using Xunit; @@ -60,7 +60,7 @@ private static void CheckApproval(Assembly assembly, [CallerMemberName]string me if (!string.Equals(receivedPublicApi, approvedPublicApi, StringComparison.InvariantCulture)) { File.WriteAllText(receivedFileName, receivedPublicApi); - ShouldlyConfiguration.DiffTools.GetDiffTool().Open(receivedFileName, approvedFileName, true); + DiffRunner.Launch(receivedFileName, approvedFileName); } Assert.Equal(approvedPublicApi, receivedPublicApi); diff --git a/src/Sextant.XamForms.Tests/DependencyResolverMixinTests.cs b/src/Sextant.XamForms.Tests/DependencyResolverMixinTests.cs index 7a5bc3ec..ba1a9766 100644 --- a/src/Sextant.XamForms.Tests/DependencyResolverMixinTests.cs +++ b/src/Sextant.XamForms.Tests/DependencyResolverMixinTests.cs @@ -3,9 +3,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. +using FluentAssertions; using ReactiveUI; using Sextant.Mocks; -using Shouldly; using Splat; using Xamarin.Forms; using Xunit; @@ -35,7 +35,7 @@ public void Should_Register_Navigation_View() var result = Locator.Current.GetService(DependencyResolverMixins.NavigationView); // Then - result.ShouldBeOfType(); + result.Should().BeOfType(); } /// @@ -51,7 +51,7 @@ public void Should_Register_Navigation_View_With_Schedulers() var result = Locator.Current.GetService(DependencyResolverMixins.NavigationView); // Then - result.ShouldBeOfType(); + result.Should().BeOfType(); } } @@ -74,7 +74,7 @@ public void Should_Register_Navigation_View() var result = Locator.Current.GetService(DependencyResolverMixins.NavigationView); // Then - result.ShouldBeOfType(); + result.Should().BeOfType(); } } @@ -109,7 +109,7 @@ public void Should_Register_View_Stack_Service() var result = Locator.Current.GetService(); // Then - result.ShouldBeOfType(); + result.Should().BeOfType(); } /// @@ -127,7 +127,7 @@ public void Should_Register_View_Stack_Service_With_View() var result = Locator.Current.GetService(); // Then - result.ShouldBeOfType(); + result.Should().BeOfType(); } /// @@ -145,7 +145,7 @@ public void Should_Register_View_Stack_Service_With_Factory() var result = Locator.Current.GetService(); // Then - result.ShouldBeOfType(); + result.Should().BeOfType(); } } @@ -167,7 +167,7 @@ public void Should_Register_View() var result = Locator.Current.GetService>(); // Then - result.ShouldBeOfType(); + result.Should().BeOfType(); } /// @@ -183,7 +183,7 @@ public void Should_Register_View_Factory() var result = Locator.Current.GetService>(); // Then - result.ShouldBeOfType(); + result.Should().BeOfType(); } } @@ -205,9 +205,9 @@ public void Should_Return_Navigation_View() var result = Locator.Current.GetNavigationView(); // Then - result.ShouldBeAssignableTo(); - result.ShouldBeAssignableTo(); - result.ShouldBeAssignableTo(); + result.Should().BeAssignableTo(); + result.Should().BeAssignableTo(); + result.Should().BeAssignableTo(); } } } diff --git a/src/Sextant.XamForms.Tests/Sextant.XamForms.Tests.csproj b/src/Sextant.XamForms.Tests/Sextant.XamForms.Tests.csproj index ff012af4..3b7157f0 100644 --- a/src/Sextant.XamForms.Tests/Sextant.XamForms.Tests.csproj +++ b/src/Sextant.XamForms.Tests/Sextant.XamForms.Tests.csproj @@ -1,7 +1,6 @@  - netcoreapp2.2 - $(TargetFrameworks);net472 + netcoreapp3.1 $(NoWarn);1591;CA1707;SA1633;CA1034 false diff --git a/src/Sextant.XamForms.Tests/SextantExtensionTests.cs b/src/Sextant.XamForms.Tests/SextantExtensionTests.cs index e8bd09f5..29acc600 100644 --- a/src/Sextant.XamForms.Tests/SextantExtensionTests.cs +++ b/src/Sextant.XamForms.Tests/SextantExtensionTests.cs @@ -3,7 +3,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -using Shouldly; +using FluentAssertions; using Splat; using Xunit; @@ -32,7 +32,7 @@ public void Should_Register_Navigation_View() var result = Locator.Current.GetService(nameof(NavigationView)); // Then - result.ShouldBeOfType(); + result.Should().BeOfType(); } /// @@ -48,7 +48,7 @@ public void Should_Register_View_Stack_Service() var result = Locator.Current.GetService(); // Then - result.ShouldBeOfType(); + result.Should().BeOfType(); } /// @@ -64,7 +64,7 @@ public void Should_Register_Default_View_Model_Factory() var result = ViewModelFactory.Current; // Then - result.ShouldBeAssignableTo(); + result.Should().BeAssignableTo(); } } } diff --git a/src/Sextant.XamForms/Sextant.XamForms.csproj b/src/Sextant.XamForms/Sextant.XamForms.csproj index 35cf5b41..243ac408 100644 --- a/src/Sextant.XamForms/Sextant.XamForms.csproj +++ b/src/Sextant.XamForms/Sextant.XamForms.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + netstandard2.0 Sextant.XamForms Sextant Sextant.XamForms diff --git a/src/Sextant.iOS.Runner/NavigationViewControllerFixture.cs b/src/Sextant.iOS.Runner/NavigationViewControllerFixture.cs index a46635b0..e874693f 100644 --- a/src/Sextant.iOS.Runner/NavigationViewControllerFixture.cs +++ b/src/Sextant.iOS.Runner/NavigationViewControllerFixture.cs @@ -23,7 +23,7 @@ public class NavigationViewControllerFixture /// The result of the conversion. /// public static implicit operator NavigationViewController(NavigationViewControllerFixture fixture) => - fixture.Build(); + fixture?.Build(); private NavigationViewController Build() => new NavigationViewController(new TestScheduler(), new TestScheduler(), new TestViewLocator()); diff --git a/src/Sextant.iOS.Runner/TestViewLocator.cs b/src/Sextant.iOS.Runner/TestViewLocator.cs index b89251ec..06e218b3 100644 --- a/src/Sextant.iOS.Runner/TestViewLocator.cs +++ b/src/Sextant.iOS.Runner/TestViewLocator.cs @@ -18,7 +18,6 @@ internal class TestViewLocator : IViewLocator { public IViewFor ResolveView(T viewModel, string contract = null) - where T : class { return new PageUiViewController(); } diff --git a/src/global.json b/src/global.json index 17032b75..f8f6c586 100644 --- a/src/global.json +++ b/src/global.json @@ -1,5 +1,5 @@ { "msbuild-sdks": { - "MSBuild.Sdk.Extras": "2.0.54" + "MSBuild.Sdk.Extras": "2.1.2" } }