Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
50 changes: 49 additions & 1 deletion Fronter.NET.Tests/Models/ConfigurationTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
using Fronter.Models.Configuration;
using Avalonia.Data;
using commonItems;
using Fronter.Models.Configuration;
using Fronter.Models.Configuration.Options;
using Microsoft.Data.Sqlite;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Xunit;
Expand Down Expand Up @@ -87,6 +91,50 @@ public void EmptyStringCanBeUsedAsDateOptionValue() {
Assert.Equal(string.Empty, bookmarkDateOption.GetValue());
}

[Fact]
public void CheckBoxSelector_TracksSelectedValuesAndIds() {
var selector = new CheckBoxSelector(new BufferedReader(string.Empty));
selector.CheckBoxOptions.Add(new ToggleableOption(new BufferedReader("name = alpha default = true"), 1));
selector.CheckBoxOptions.Add(new ToggleableOption(new BufferedReader("name = beta default = false"), 2));

selector.SetSelectedValues(new HashSet<string>(new[] { "beta" }));

Assert.Equal(new HashSet<string> { "beta" }, selector.GetSelectedValues());
Assert.Equal(new HashSet<int> { 2 }, selector.GetSelectedIds());
}

[Fact]
public void TextSelector_ParsesEditableValueAndTooltip() {
var selector = new TextSelector(new BufferedReader("editable = false\nvalue = \"chosen-name\"\ntooltip = \"example tooltip\""));

Assert.False(selector.Editable);
Assert.Equal("chosen-name", selector.Value);
Assert.Equal("example tooltip", selector.Tooltip);
}

[Fact]
public void DateSelector_TextValue_AllowsValidDatesAndClearsEmptyValues() {
var selector = new DateSelector(new BufferedReader("editable = true\nvalue = \"2025.05.04\"\ntooltip = \"example date\""));

Assert.Equal("2025.5.4", selector.TextValue);

selector.TextValue = "2026.06.15";
Assert.Equal("2026.6.15", selector.TextValue);

selector.TextValue = string.Empty;
Assert.Null(selector.Value);
}

[Theory]
[InlineData("2025.13.01")]
[InlineData("2025.00.01")]
[InlineData("2025.12.32")]
public void DateSelector_TextValue_RejectsInvalidDates(string invalidDate) {
var selector = new DateSelector(new BufferedReader(string.Empty));

Assert.Throws<DataValidationException>(() => selector.TextValue = invalidDate);
}

[Fact]
public void AutoLocatePlaysets_DoesNotThrowWhenLauncherDbIsInvalid() {
var config = new Config();
Expand Down
36 changes: 36 additions & 0 deletions Fronter.NET.Tests/Services/MessageSlicerTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Fronter.Services;
using log4net.Core;
using System;
using Xunit;

namespace Fronter.Tests.Services;
Expand All @@ -14,4 +15,39 @@ public void MessageIsCorrectlySliced() {
Assert.Equal(Level.Alert, logLine.Level);
Assert.Equal("test message", logLine.Message);
}

[Theory]
[InlineData("2000-06-06 15:23:33 [DEBUG] debug message", "DEBUG", "debug message")]
[InlineData("2000-06-06 15:23:33 [INFO] info message", "INFO", "info message")]
[InlineData("2000-06-06 15:23:33 [WARN] warning message", "WARN", "warning message")]
[InlineData("2000-06-06 15:23:33 [NOTICE] notice message", "NOTICE", "notice message")]
[InlineData("2000-06-06 15:23:33 [ERROR] error message", "ERROR", "error message")]
[InlineData("2000-06-06 15:23:33 [FATAL] fatal message", "FATAL", "fatal message")]
[InlineData("2000-06-06 15:23:33 [PROGRESS] 25%", "PROGRESS", "25%")]
public void SliceMessage_ParsesKnownLevels(string message, string expectedLevelName, string expectedText) {
var logLine = MessageSlicer.SliceMessage(message);

Assert.NotNull(logLine.Level);
Assert.Equal(expectedLevelName, logLine.Level.Name);
Assert.Equal(expectedText, logLine.Message);
Assert.Equal("2000-06-06 15:23:33", logLine.Timestamp.ToString("yyyy-MM-dd HH:mm:ss"));
}

[Fact]
public void SliceMessage_WithoutTimestamp_StillParsesLevelAndMessage() {
var logLine = MessageSlicer.SliceMessage("[WARNING] keep going");

Assert.Equal(Level.Warn, logLine.Level);
Assert.Equal("keep going", logLine.Message);
Assert.True(logLine.Timestamp <= DateTime.Now);
}

[Fact]
public void SliceMessage_WithoutBracketedLevel_ReturnsOriginalText() {
var message = "plain log line without a level prefix";
var logLine = MessageSlicer.SliceMessage(message);

Assert.Null(logLine.Level);
Assert.Equal(message, logLine.Message);
}
}
45 changes: 45 additions & 0 deletions Fronter.NET.Tests/Services/TargetDbManagerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using Fronter.Services;
using System;
using System.IO;
using Xunit;

namespace Fronter.Tests.Services;

public class TargetDbManagerTests {
[Fact]
public void GetLastUpdatedLauncherDbPath_ReturnsNewestExistingLauncherDatabase() {
var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(tempDir);

try {
var olderPath = Path.Combine(tempDir, "launcher-v2.sqlite");
var newerPath = Path.Combine(tempDir, "launcher-v2_openbeta.sqlite");

File.WriteAllText(olderPath, "older");
File.WriteAllText(newerPath, "newer");

File.SetLastWriteTimeUtc(olderPath, new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc));
File.SetLastWriteTimeUtc(newerPath, new DateTime(2024, 1, 2, 0, 0, 0, DateTimeKind.Utc));

Assert.Equal(newerPath, TargetDbManager.GetLastUpdatedLauncherDbPath(tempDir));
} finally {
if (Directory.Exists(tempDir)) {
Directory.Delete(tempDir, recursive: true);
}
}
}

[Fact]
public void GetLastUpdatedLauncherDbPath_ReturnsNullWhenNoDatabaseExists() {
var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(tempDir);

try {
Assert.Null(TargetDbManager.GetLastUpdatedLauncherDbPath(tempDir));
} finally {
if (Directory.Exists(tempDir)) {
Directory.Delete(tempDir, recursive: true);
}
}
}
}
36 changes: 36 additions & 0 deletions Fronter.NET.Tests/ValueConverters/ValueConverterTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using Avalonia;
using Fronter.ValueConverters;
using System.Globalization;
using Xunit;

namespace Fronter.Tests.ValueConverters;

public class ValueConverterTests {
[Fact]
public void BooleanNegationConverter_InvertsBooleanValues() {
var converter = BooleanNegationConverter.Instance;

Assert.Equal(false, converter.Convert(true, typeof(bool), null, CultureInfo.InvariantCulture));
Assert.Equal(true, converter.Convert(false, typeof(bool), null, CultureInfo.InvariantCulture));
Assert.Same(AvaloniaProperty.UnsetValue, converter.Convert("not a bool", typeof(bool), null, CultureInfo.InvariantCulture));
Assert.Equal(false, converter.ConvertBack(true, typeof(bool), null, CultureInfo.InvariantCulture));
Assert.Equal(true, converter.ConvertBack(false, typeof(bool), null, CultureInfo.InvariantCulture));
Assert.Same(AvaloniaProperty.UnsetValue, converter.ConvertBack("not a bool", typeof(bool), null, CultureInfo.InvariantCulture));
}

[Fact]
public void EnumToBooleanConverter_UsesParameterForEqualityChecks() {
var converter = EnumToBooleanConverter.Instance;

Assert.Equal(true, converter.Convert(TestEnum.Second, typeof(bool), TestEnum.Second, CultureInfo.InvariantCulture));
Assert.Equal(false, converter.Convert(TestEnum.First, typeof(bool), TestEnum.Second, CultureInfo.InvariantCulture));
Assert.Same(AvaloniaProperty.UnsetValue, converter.Convert(null, typeof(bool), TestEnum.Second, CultureInfo.InvariantCulture));
Assert.Equal(TestEnum.Second, converter.ConvertBack(true, typeof(TestEnum), TestEnum.Second, CultureInfo.InvariantCulture));
Assert.Same(AvaloniaProperty.UnsetValue, converter.ConvertBack(false, typeof(TestEnum), TestEnum.Second, CultureInfo.InvariantCulture));
}

private enum TestEnum {
First,
Second,
}
}
Loading