feat: implement main window view models

This commit is contained in:
yyc12345 committed 2026-10-22 21:19:02 +08:00
1 parent 34a588864f
commit 996c0a9515
7 files changed
+1121 -6

No files matched your search

+163
View File
@@ -0,0 +1,163 @@
using System.IO;
using SongTidy.Models;
using SongTidy.ViewModels;
namespace SongTidy.Tests;
/// <summary>
/// Contains tests for <see cref="SongEntryViewModel"/>.
/// </summary>
[TestClass]
public sealed class SongEntryViewModelTests {
#region Preview
/// <summary>
/// Verifies the initial fields and target preview.
/// </summary>
[TestMethod]
public void InitializesFieldsAndTargetPreview() {
SongEntryViewModel entry = CreateEntry();
Assert.AreEqual("Artist", entry.Artist);
Assert.AreEqual("Title", entry.Title);
Assert.AreEqual("Live", entry.Comment);
Assert.AreEqual(RenameFormat.ArtistFirst, entry.Format);
Assert.AreEqual("A.mp3", entry.OriginalFileName);
Assert.AreEqual("Artist - Title (Live).mp3", entry.TargetFileName);
}
/// <summary>
/// Verifies that changing a field immediately updates the target preview.
/// </summary>
[TestMethod]
public void UpdatesTargetPreviewWhenFieldChanges() {
SongEntryViewModel entry = CreateEntry();
entry.Artist = "New Artist";
Assert.AreEqual("New Artist - Title (Live).mp3", entry.TargetFileName);
}
/// <summary>
/// Verifies that changing the format updates the target preview.
/// </summary>
[TestMethod]
public void UpdatesTargetPreviewWhenFormatChanges() {
SongEntryViewModel entry = CreateEntry();
entry.Format = RenameFormat.TitleFirst;
Assert.AreEqual("Title (Live) - Artist.mp3", entry.TargetFileName);
}
/// <summary>
/// Verifies that the original extension is preserved for other file types.
/// </summary>
[TestMethod]
public void PreservesOriginalExtension() {
SongEntryViewModel entry = new(
Path.Combine("Music", "A.flac"),
string.Empty,
"Title",
string.Empty,
RenameFormat.ArtistFirst);
Assert.AreEqual("Title.flac", entry.TargetFileName);
}
#endregion
#region Dirty notifications
/// <summary>
/// Verifies that editing any field raises the edited event.
/// </summary>
[TestMethod]
public void RaisesEditedWhenFieldChanges() {
SongEntryViewModel entry = CreateEntry();
int editCount = 0;
entry.Edited += (_, _) => editCount++;
entry.Artist = "New Artist";
entry.Title = "New Title";
entry.Comment = "New Comment";
Assert.AreEqual(3, editCount);
}
/// <summary>
/// Verifies that assigning the current value does not raise the edited event.
/// </summary>
[TestMethod]
public void DoesNotRaiseEditedWhenFieldValueIsUnchanged() {
SongEntryViewModel entry = CreateEntry();
int editCount = 0;
entry.Edited += (_, _) => editCount++;
entry.Artist = entry.Artist;
Assert.AreEqual(0, editCount);
}
/// <summary>
/// Verifies that changing the format does not itself count as a field edit.
/// </summary>
[TestMethod]
public void ChangingFormatDoesNotRaiseEdited() {
SongEntryViewModel entry = CreateEntry();
int editCount = 0;
entry.Edited += (_, _) => editCount++;
entry.Format = RenameFormat.TitleFirst;
Assert.AreEqual(0, editCount);
}
#endregion
#region Swap
/// <summary>
/// Verifies that swapping exchanges the artist and title values.
/// </summary>
[TestMethod]
public void SwapsArtistAndTitle() {
SongEntryViewModel entry = CreateEntry();
entry.SwapArtistAndTitle();
Assert.AreEqual("Title", entry.Artist);
Assert.AreEqual("Artist", entry.Title);
Assert.AreEqual("Title - Artist (Live).mp3", entry.TargetFileName);
}
/// <summary>
/// Verifies that swapping raises edited notifications for both changed fields.
/// </summary>
[TestMethod]
public void SwapRaisesEditedForBothFields() {
SongEntryViewModel entry = CreateEntry();
int editCount = 0;
entry.Edited += (_, _) => editCount++;
entry.SwapArtistAndTitle();
Assert.AreEqual(2, editCount);
}
#endregion
/// <summary>
/// Creates a standard test entry.
/// </summary>
/// <returns>The created entry.</returns>
private static SongEntryViewModel CreateEntry() {
return new SongEntryViewModel(
Path.Combine("Music", "A.mp3"),
"Artist",
"Title",
"Live",
RenameFormat.ArtistFirst);
}
}