changed settings saving (#3)
Reviewed-on: #3 Co-authored-by: Aleksandr Neychev <alexnejchev73@gmail.com>
This commit was merged in pull request #3.
This commit is contained in:
@@ -114,7 +114,7 @@ public sealed class ThemeServiceTests
|
||||
{
|
||||
using var service = new ThemeService(settings, static () => AppTheme.Dark);
|
||||
|
||||
settings.FontSize = 40;
|
||||
settings.Current.FontSize = 40;
|
||||
settings.Language = "ru";
|
||||
|
||||
Assert.Equal(AppTheme.Light, service.CurrentTheme);
|
||||
|
||||
@@ -43,7 +43,7 @@ public sealed class SettingsViewModelTests
|
||||
var localization = new FakeLocalizationService();
|
||||
using var viewModel = Create(settings, localization);
|
||||
|
||||
settings.FontSize = 30;
|
||||
settings.Current.FontSize = 30;
|
||||
|
||||
Assert.Equal("en", localization.CurrentLanguage);
|
||||
}
|
||||
@@ -59,6 +59,18 @@ public sealed class SettingsViewModelTests
|
||||
Assert.Equal(Enum.GetValues<ScreenPosition>(), viewModel.ScreenPositions.Select(option => option.Value));
|
||||
}
|
||||
|
||||
// Next to the caret the popup only goes beside it: above or below is where the next
|
||||
// line of the text is
|
||||
[Fact]
|
||||
public void The_caret_is_offered_two_sides_and_no_more()
|
||||
{
|
||||
using SettingsViewModel viewModel = Create();
|
||||
|
||||
Assert.Equal(
|
||||
[CaretSide.Left, CaretSide.Right],
|
||||
viewModel.CaretSides.Select(option => option.Value));
|
||||
}
|
||||
|
||||
// A caption key is built from the type name and the value
|
||||
[Fact]
|
||||
public void The_option_captions_come_from_the_resources()
|
||||
@@ -85,6 +97,7 @@ public sealed class SettingsViewModelTests
|
||||
Assert.Same(first, viewModel.Themes[0]);
|
||||
Assert.Equal("ru:AppTheme_System", first.Display);
|
||||
Assert.Equal("ru:AnchorSide_TopLeft", viewModel.AnchorSides[0].Display);
|
||||
Assert.Equal("ru:CaretSide_Left", viewModel.CaretSides[0].Display);
|
||||
Assert.Equal("ru:ScreenPosition_TopLeft", viewModel.ScreenPositions[0].Display);
|
||||
Assert.Equal("ru:PopupPlacementMode_AtCursor", viewModel.PlacementModes[0].Display);
|
||||
}
|
||||
@@ -114,8 +127,8 @@ public sealed class SettingsViewModelTests
|
||||
var settings = new AppSettings();
|
||||
using var viewModel = Create(settings);
|
||||
|
||||
Assert.Contains(settings.BackgroundColor, viewModel.BackgroundPalette);
|
||||
Assert.Contains(settings.ForegroundColor, viewModel.TextPalette);
|
||||
Assert.Contains(settings.Current.BackgroundColor, viewModel.BackgroundPalette);
|
||||
Assert.Contains(settings.Current.ForegroundColor, viewModel.TextPalette);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -124,7 +124,8 @@ public sealed class MainWindowTests
|
||||
{
|
||||
Sta.Run(() =>
|
||||
{
|
||||
var settings = new AppSettings { FontSize = 33 };
|
||||
var settings = new AppSettings();
|
||||
settings.Current.FontSize = 33;
|
||||
using SettingsViewModel viewModel = CreateViewModel(settings);
|
||||
|
||||
Open(viewModel, window =>
|
||||
@@ -133,6 +134,178 @@ public sealed class MainWindowTests
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The preview follows the mode: switching it shows the settings of the new one.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The look is bound through the current mode, so a switch has to reach the window.
|
||||
/// Bound to a mode by name, the sliders would keep showing the cursor mode whatever
|
||||
/// was chosen above them.
|
||||
/// </remarks>
|
||||
[Fact]
|
||||
public void A_switch_of_the_mode_shows_the_settings_of_that_mode()
|
||||
{
|
||||
Sta.Run(() =>
|
||||
{
|
||||
var settings = new AppSettings();
|
||||
settings.AtCursor.FontSize = 24;
|
||||
settings.FixedPoint.FontSize = 56;
|
||||
|
||||
using SettingsViewModel viewModel = CreateViewModel(settings);
|
||||
|
||||
Open(viewModel, window =>
|
||||
{
|
||||
Assert.Contains(FindAll<TextBlock>(window), text => Math.Abs(text.FontSize - 24) < 0.001);
|
||||
|
||||
settings.PlacementMode = PopupPlacementMode.FixedPoint;
|
||||
window.UpdateLayout();
|
||||
|
||||
Assert.Contains(FindAll<TextBlock>(window), text => Math.Abs(text.FontSize - 56) < 0.001);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// In the middle of the monitor the offset from the edge cannot be set, but it stays
|
||||
/// in place.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// There is no edge to stand off from there, so the setting goes grey. Taking the row
|
||||
/// out of the section instead would move everything below it on every switch of the
|
||||
/// place — the section is not to jump about.
|
||||
/// </remarks>
|
||||
[Fact]
|
||||
public void In_the_middle_of_the_monitor_the_offset_from_the_edge_goes_grey()
|
||||
{
|
||||
Sta.Run(() =>
|
||||
{
|
||||
var settings = new AppSettings { PlacementMode = PopupPlacementMode.FixedPoint };
|
||||
using SettingsViewModel viewModel = CreateViewModel(settings);
|
||||
|
||||
Open(viewModel, window =>
|
||||
{
|
||||
Slider offset = Assert.Single(FindSlidersBoundTo(window, "Settings.FixedPoint.Offset"));
|
||||
|
||||
Assert.True(offset.IsVisible);
|
||||
Assert.False(offset.IsEnabled);
|
||||
|
||||
// And it looks the part: the template draws from brushes that know
|
||||
// nothing of the state, so the style has to fade it
|
||||
Assert.True(offset.Opacity < 1);
|
||||
|
||||
settings.FixedPoint.Position = ScreenPosition.TopRight;
|
||||
window.UpdateLayout();
|
||||
|
||||
Assert.True(offset.IsVisible);
|
||||
Assert.True(offset.IsEnabled);
|
||||
Assert.Equal(1, offset.Opacity);
|
||||
|
||||
settings.FixedPoint.Position = ScreenPosition.Center;
|
||||
window.UpdateLayout();
|
||||
|
||||
Assert.True(offset.IsVisible);
|
||||
Assert.False(offset.IsEnabled);
|
||||
Assert.True(offset.Opacity < 1);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Another mode has no fixed point at all, and its offset has no place on screen
|
||||
[Fact]
|
||||
public void Away_from_the_fixed_point_its_offset_is_not_shown()
|
||||
{
|
||||
Sta.Run(() =>
|
||||
{
|
||||
var settings = new AppSettings { PlacementMode = PopupPlacementMode.AtCursor };
|
||||
using SettingsViewModel viewModel = CreateViewModel(settings);
|
||||
|
||||
Open(viewModel, window =>
|
||||
Assert.All(FindSlidersBoundTo(window, "Settings.FixedPoint.Offset"), slider =>
|
||||
Assert.False(slider.IsVisible)));
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// What the look belongs to is explained in a tooltip next to the mode.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The sliders of the look show other numbers after a switch of the mode, and that
|
||||
/// has to be explained. A line of text saying so would sit in the section forever,
|
||||
/// while the question is asked once.
|
||||
/// </remarks>
|
||||
[Fact]
|
||||
public void The_window_explains_that_the_look_belongs_to_the_mode()
|
||||
{
|
||||
Sta.Run(() =>
|
||||
{
|
||||
using SettingsViewModel viewModel = CreateViewModel();
|
||||
|
||||
Open(viewModel, window =>
|
||||
{
|
||||
// The text of a tooltip is bound but not computed until the tooltip is
|
||||
// shown, so what it is bound to is what gets checked
|
||||
List<TextBlock> hints =
|
||||
[
|
||||
.. FindAll<TextBlock>(window)
|
||||
.Where(text => text.ToolTip is ToolTip tip &&
|
||||
tip.Content is TextBlock content &&
|
||||
PathOf(content, TextBlock.TextProperty) == "Localization[PopupLookPerModeHint]"),
|
||||
];
|
||||
|
||||
TextBlock link = Assert.Single(hints);
|
||||
|
||||
Assert.Equal("en:MoreInfoLink", link.Text);
|
||||
Assert.True(link.IsVisible);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Beside the caret and nowhere else: the list offers the two sides it has
|
||||
[Fact]
|
||||
public void The_caret_is_offered_two_sides_in_the_window()
|
||||
{
|
||||
Sta.Run(() =>
|
||||
{
|
||||
var settings = new AppSettings { PlacementMode = PopupPlacementMode.AtCaret };
|
||||
using SettingsViewModel viewModel = CreateViewModel(settings);
|
||||
|
||||
Open(viewModel, window =>
|
||||
{
|
||||
ComboBox sides = Assert.Single(
|
||||
FindAll<ComboBox>(window),
|
||||
box => BindingOperations.GetBinding(box, Selector.SelectedValueProperty)?.Path.Path
|
||||
== "Settings.AtCaret.Side");
|
||||
|
||||
Assert.Equal(2, sides.Items.Count);
|
||||
|
||||
sides.SelectedValue = CaretSide.Left;
|
||||
|
||||
Assert.Equal(CaretSide.Left, settings.AtCaret.Side);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// The sliders of the look write into the mode chosen above them
|
||||
[Fact]
|
||||
public void The_look_is_edited_in_the_mode_that_is_chosen()
|
||||
{
|
||||
Sta.Run(() =>
|
||||
{
|
||||
var settings = new AppSettings { PlacementMode = PopupPlacementMode.AtCaret };
|
||||
using SettingsViewModel viewModel = CreateViewModel(settings);
|
||||
|
||||
Open(viewModel, window =>
|
||||
{
|
||||
Slider slider = Assert.Single(FindSlidersBoundTo(window, "Settings.Current.FontSize"));
|
||||
|
||||
slider.Value = 44;
|
||||
|
||||
Assert.Equal(44, settings.AtCaret.FontSize);
|
||||
Assert.Equal(20, settings.AtCursor.FontSize);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_tooltip_colours_are_shown_as_swatches()
|
||||
{
|
||||
@@ -144,7 +317,7 @@ public sealed class MainWindowTests
|
||||
// The chosen colour is shown as a swatch with a caption — in the
|
||||
// same notation the settings file uses
|
||||
System.Drawing.Color chosen = viewModel.BackgroundPalette[2];
|
||||
settings.BackgroundColor = chosen;
|
||||
settings.Current.BackgroundColor = chosen;
|
||||
|
||||
string expected = $"#{chosen.R:X2}{chosen.G:X2}{chosen.B:X2}";
|
||||
|
||||
@@ -359,6 +532,13 @@ public sealed class MainWindowTests
|
||||
FindAll<Button>(root).Where(button =>
|
||||
BindingOperations.GetBinding(button, ButtonBase.CommandProperty)?.Path.Path == path);
|
||||
|
||||
private static string? PathOf(DependencyObject element, DependencyProperty property) =>
|
||||
BindingOperations.GetBinding(element, property)?.Path.Path;
|
||||
|
||||
private static IEnumerable<Slider> FindSlidersBoundTo(DependencyObject root, string path) =>
|
||||
FindAll<Slider>(root).Where(slider =>
|
||||
BindingOperations.GetBinding(slider, RangeBase.ValueProperty)?.Path.Path == path);
|
||||
|
||||
private static IEnumerable<CheckBox> FindStartupCheckBoxes(DependencyObject root) =>
|
||||
FindCheckBoxesBoundTo(root, nameof(SettingsViewModel.RunAtStartup));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user