Skip to content

Commit

Permalink
Merge branch 'master' into bgomes/macRelease
Browse files Browse the repository at this point in the history
  • Loading branch information
Bruce committed Jan 28, 2024
2 parents eba78a6 + 0df1ac1 commit b496149
Show file tree
Hide file tree
Showing 10 changed files with 114 additions and 124 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/dotnet-desktop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ jobs:
- name: Build
run: dotnet build -p:ContinuousIntegrationBuild=True --configuration ${{ env.configuration }} --no-restore

- name: Test
run: dotnet test --no-build --configuration Release --verbosity normal

- name: Publish
run: dotnet publish --no-build --configuration ${{ env.configuration }}

Expand Down
4 changes: 2 additions & 2 deletions ColorKraken.Tests/ColorKraken.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
Expand All @@ -11,7 +11,7 @@
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="Moq.AutoMock" Version="3.5.0" />
<PackageReference Include="xunit" Version="2.6.5" />
<PackageReference Include="xunit" Version="2.6.6" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.6">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
Expand Down
80 changes: 0 additions & 80 deletions ColorKraken.Tests/EnumerableTests.cs

This file was deleted.

11 changes: 8 additions & 3 deletions ColorKraken.Tests/MainWindowViewModelTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public void OpenThemeFolderCommand_StartsExplorerProcess()
}

[Fact]
public void OnReceive_BrushUpdatedMessage_UpdatesTheme()
public async void OnReceive_BrushUpdatedMessage_UpdatesTheme()
{
//Arrange
AutoMocker mocker = new();
Expand All @@ -112,11 +112,16 @@ public void OnReceive_BrushUpdatedMessage_UpdatesTheme()

Mock<IThemeManager> themeManager = mocker.GetMock<IThemeManager>();
themeManager.Setup(x => x.SaveTheme(selectedTheme, It.IsAny<IEnumerable<ThemeCategory>>()));
themeManager.Setup(x => x.GetCategories(It.IsAny<Theme>())).ReturnsAsyncEnumerable();
EditorViewModel vm = mocker.CreateInstance<EditorViewModel>();

var categoriesSet = vm.WatchPropertyChanges<List<ThemeCategory>?>(nameof(EditorViewModel.ThemeCategories));
vm.SelectedTheme = selectedTheme;
var color = new ThemeColor("Testcolor", messenger) { Value = "new" };
var message = new BrushUpdated(color, "old" );

await categoriesSet.WaitForChange();

var color = new ThemeColor("TestColor", messenger) { Value = "new" };
var message = new BrushUpdated(color, "old");

//Act
messenger.Send(message);
Expand Down
87 changes: 87 additions & 0 deletions ColorKraken.Tests/PropertyChangedHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;

namespace ColorKraken.Tests;

/// <summary>
/// Based on https://intellitect.com/blog/making-unit-testing-easier/
/// </summary>
public static class PropertyChangedHelper
{
public static IPropertyChanges<T> WatchPropertyChanges<T>(this INotifyPropertyChanged propertyChanged, string propertyName)
{
if (propertyChanged == null) throw new ArgumentNullException(nameof(propertyChanged));
if (propertyName == null) throw new ArgumentNullException(nameof(propertyName));

return new PropertyChangedEnumerable<T>(propertyChanged, propertyName);
}

private class PropertyChangedEnumerable<T> : IPropertyChanges<T>
{
private readonly List<T> _values = [];
private readonly Func<T> _getPropertyValue;
private readonly string _propertyName;
private readonly List<(Func<T, bool>, TaskCompletionSource)> _waitHandles = [];

public PropertyChangedEnumerable(INotifyPropertyChanged propertyChanged, string propertyName)
{
_propertyName = propertyName;

const BindingFlags flags = BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.Public;
var propertyInfo = propertyChanged.GetType().GetProperty(propertyName, flags)
?? throw new ArgumentException($"Could not find public property getter for {propertyName} on {propertyChanged.GetType().FullName}");
var instance = Expression.Constant(propertyChanged);
var propertyExpression = Expression.Property(instance, propertyInfo);
_getPropertyValue = Expression.Lambda<Func<T>>(propertyExpression).Compile();

propertyChanged.PropertyChanged += OnPropertyChanged;
}

private void OnPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (string.Equals(_propertyName, e.PropertyName, StringComparison.Ordinal))
{
var value = _getPropertyValue();
_values.Add(value);
_waitHandles.ForEach(t =>
{
if (t.Item1(value)) t.Item2.SetResult();
});
}
}

public IEnumerator<T> GetEnumerator()
{
return _values.GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}

public Task WaitForChange(CancellationToken token)
{
return WaitFor(x => true, token);
}

public Task WaitFor(Func<T, bool> predicate, CancellationToken token)
{
TaskCompletionSource tcs = new();
_waitHandles.Add((predicate, tcs));
return tcs.Task;
}
}
}

public interface IPropertyChanges<out T> : IEnumerable<T>
{
Task WaitForChange(CancellationToken token = default);
Task WaitFor(Func<T, bool> predicate, CancellationToken token = default);
}
27 changes: 0 additions & 27 deletions ColorKraken.Tests/TaskTests.cs

This file was deleted.

2 changes: 1 addition & 1 deletion ColorKraken/ColorKraken.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
<ApplicationIcon>Icon.ico</ApplicationIcon>
Expand Down
15 changes: 10 additions & 5 deletions ColorKraken/Configuration/TolerantSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public bool TryGet(string key, out string? value)
}
}

public void Set(string key, string value)
public void Set(string key, string? value)
{
try
{
Expand Down Expand Up @@ -73,7 +73,7 @@ public void Load()
{ }
}

public IEnumerable<string> GetChildKeys(IEnumerable<string> earlierKeys, string parentPath)
public IEnumerable<string> GetChildKeys(IEnumerable<string> earlierKeys, string? parentPath)
{
try
{
Expand All @@ -82,7 +82,7 @@ public IEnumerable<string> GetChildKeys(IEnumerable<string> earlierKeys, string
}
catch (Exception)
{
return Array.Empty<string>();
return [];
}
}
}
Expand All @@ -95,9 +95,14 @@ private class EmptyChangeToken : IChangeToken

public bool ActiveChangeCallbacks => false;

public IDisposable? RegisterChangeCallback(Action<object> callback, object state)
public IDisposable RegisterChangeCallback(Action<object?> callback, object? state)
{
return null;
return new EmptyDisposable();
}
}

private sealed class EmptyDisposable : IDisposable
{
public void Dispose() { }
}
}
6 changes: 2 additions & 4 deletions ColorKraken/DownloadViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Security.Policy;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using System.Windows.Data;
Expand All @@ -16,10 +15,9 @@

namespace ColorKraken;

[ObservableObject]
public partial class DownloadViewModel
public partial class DownloadViewModel : ObservableObject
{
public ObservableCollection<ThemeItem> Items { get; } = new();
public ObservableCollection<ThemeItem> Items { get; } = [];

private HttpClient HttpClient { get; }
private IThemeManager ThemeManager { get; }
Expand Down
3 changes: 1 addition & 2 deletions ColorKraken/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@

namespace ColorKraken;

[ObservableObject]
public partial class MainWindowViewModel : IRecipient<ShowError>
public partial class MainWindowViewModel : ObservableObject, IRecipient<ShowError>
{
public ISnackbarMessageQueue MessageQueue { get; }

Expand Down

0 comments on commit b496149

Please sign in to comment.