From e225679bdbd8575ce485c13b53d009da46706581 Mon Sep 17 00:00:00 2001 From: natekford Date: Wed, 1 Jan 2025 03:14:14 -0800 Subject: [PATCH] Updated to .net 8.0 and using collection initializers/better auto properties. --- .editorconfig | 3 + Directory.Build.props | 2 +- .../Controls/DynamicFontSizeGrid.cs | 125 ---------------- .../Models/ObservableAnime.cs | 46 +++--- src/SongProcessor.UI/Models/ObservableSong.cs | 84 +++++------ src/SongProcessor.UI/SongProcessor.UI.csproj | 1 + .../SortedObservableCollection.cs | 2 +- src/SongProcessor.UI/UIUtils.cs | 2 +- .../ViewModels/AddViewModel.cs | 52 +++---- .../ViewModels/EditViewModel.cs | 138 ++++++++---------- .../ViewModels/MainViewModel.cs | 8 +- .../ViewModels/MessageBoxViewModel.cs | 52 +++---- .../ViewModels/SearchTerms.cs | 16 +- .../ViewModels/SongViewModel.cs | 52 +++---- .../ViewModels/SongVisibility.cs | 48 +++--- .../FFmpeg/ISourceInfoGatherer.cs | 6 +- src/SongProcessor/FFmpeg/Jobs/SongJob.cs | 2 +- src/SongProcessor/FFmpeg/ProgressBuilder.cs | 6 +- .../FFmpeg/SourceInfoGatherer.cs | 40 +++-- src/SongProcessor/Gatherers/GathererUtils.cs | 3 +- src/SongProcessor/Models/Anime.cs | 5 +- src/SongProcessor/SongProcessor.cs | 6 +- .../FFmpeg/Jobs/Mp3SongJob_Tests.cs | 30 ++-- .../FFmpeg/Jobs/VideoSongJob_Tests.cs | 22 +-- .../FFmpeg/SourceInfoGatherer_Tests.cs | 21 +-- tests/SongProcessor.Tests/SongLoader_Tests.cs | 6 +- .../SongProcessor_Tests.cs | 50 +++---- 27 files changed, 305 insertions(+), 523 deletions(-) delete mode 100644 src/SongProcessor.UI/Controls/DynamicFontSizeGrid.cs diff --git a/.editorconfig b/.editorconfig index ad4cb74..e58635f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,3 +8,6 @@ dotnet_diagnostic.RCS1021.severity = none # CA1822: Mark members as static dotnet_diagnostic.CA1822.severity = none + +# SYSLIB1096: Convert to 'GeneratedComInterface' +dotnet_diagnostic.SYSLIB1096.severity = none \ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props index f99daa2..1c1ef57 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - net6.0 + net8.0 preview enable enable diff --git a/src/SongProcessor.UI/Controls/DynamicFontSizeGrid.cs b/src/SongProcessor.UI/Controls/DynamicFontSizeGrid.cs deleted file mode 100644 index cdcdd6f..0000000 --- a/src/SongProcessor.UI/Controls/DynamicFontSizeGrid.cs +++ /dev/null @@ -1,125 +0,0 @@ -using Avalonia; -using Avalonia.Controls; -using Avalonia.Controls.Primitives; -using Avalonia.Data; - -using SongProcessor.UI.Converters; - -using System.Collections.Concurrent; - -namespace SongProcessor.UI.Controls; - -/// -/// Allows the font size of any inside this to be based on the window's height. -/// -public class DynamicFontSizeGrid : Grid -{ - public static readonly StyledProperty DynamicFontSizeProperty = - AvaloniaProperty.Register(nameof(DynamicFontSize)); - - public static readonly AttachedProperty OverrideDynamicFontSizeProperty = - AvaloniaProperty.RegisterAttached("OverrideDynamicFontSize"); - - private static readonly ConcurrentDictionary _Bindings - = new(); - - public double DynamicFontSize - { - get => GetValue(DynamicFontSizeProperty); - set - { - SetAllChildren(this, value); - SetValue(DynamicFontSizeProperty, value); - } - } - - public static double GetOverrideDynamicFontSize(Control obj) - => obj.GetValue(OverrideDynamicFontSizeProperty); - - public static void SetOverrideDynamicFontSize(Control obj, double value) - { - if (obj is Panel panel) - { - SetAllChildren(panel, value); - } - if (obj is TemplatedControl templatedControl) - { - SetChild(templatedControl, value); - } - obj?.SetValue(OverrideDynamicFontSizeProperty, value); - } - - public override void EndInit() - { - if (DynamicFontSize > 0) - { - SetAllChildren(this, DynamicFontSize); - } - base.EndInit(); - } - - private static void SetAllChildren(Panel parent, double value) - { - foreach (var child in parent.Children.OfType()) - { - var overrideValue = GetOverrideDynamicFontSize(child); - //Skip any children where they have explicitly stated not to set anything via NaN - if (double.IsNaN(overrideValue)) - { - continue; - } - SetChild(child, overrideValue > 0 ? overrideValue : value); - } - foreach (var child in parent.Children.OfType()) - { - var overrideValue = GetOverrideDynamicFontSize(child); - //If the override isn't set, and this is a dynamic font size grid, use its current value - if (overrideValue <= 0 && child is DynamicFontSizeGrid dynamicFontSizeGrid) - { - overrideValue = dynamicFontSizeGrid.DynamicFontSize; - } - if (double.IsNaN(overrideValue)) - { - continue; - } - if (child is not null) - { - SetAllChildren(child, overrideValue > 0 ? overrideValue : value); - } - } - } - - private static void SetChild(TemplatedControl obj, double value) - { - if (value < 0) - { - throw new ArgumentException("DynamicFontSize must be greater than or equal to 0."); - } - else if (value > 0) - { - //Set the font size to a percentage of the window size - var binding = new Binding - { - Path = nameof(Height), - RelativeSource = new() - { - Mode = RelativeSourceMode.FindAncestor, - AncestorType = typeof(Window), - }, - Converter = new FontResizeConverter(value), - }; - //If a binding already exists, remove it then add in the new one - var newBinding = obj.Bind(TemplatedControl.FontSizeProperty, binding); - _Bindings.AddOrUpdate(obj, newBinding, (_, v) => - { - v.Dispose(); - return newBinding; - }); - } - //If setting the value to 0, remove the binding - else if (_Bindings.TryGetValue(obj, out var stored)) - { - stored.Dispose(); - } - } -} \ No newline at end of file diff --git a/src/SongProcessor.UI/Models/ObservableAnime.cs b/src/SongProcessor.UI/Models/ObservableAnime.cs index 8dd4f2e..203d9b4 100644 --- a/src/SongProcessor.UI/Models/ObservableAnime.cs +++ b/src/SongProcessor.UI/Models/ObservableAnime.cs @@ -11,65 +11,55 @@ namespace SongProcessor.UI.Models; [DebuggerDisplay(ModelUtils.DEBUGGER_DISPLAY)] public sealed class ObservableAnime : ReactiveObject, IAnime { - private string _AbsoluteInfoPath = null!; - private int _Id; - private bool _IsExpanded; - private bool _IsExpanderVisible; - private bool _IsVisible = true; - private string _Name = null!; - private ObservableCollection _Songs = null!; - private VideoInfo? _VideoInfo; - private int _Year; - public string AbsoluteInfoPath { - get => _AbsoluteInfoPath; - set => this.RaiseAndSetIfChanged(ref _AbsoluteInfoPath, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public int Id { - get => _Id; - set => this.RaiseAndSetIfChanged(ref _Id, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public bool IsExpanded { - get => _IsExpanded; - set => this.RaiseAndSetIfChanged(ref _IsExpanded, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public bool IsExpanderVisible { - get => _IsExpanderVisible; - set => this.RaiseAndSetIfChanged(ref _IsExpanderVisible, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public bool IsVisible { - get => _IsVisible; - set => this.RaiseAndSetIfChanged(ref _IsVisible, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public string Name { - get => _Name; - set => this.RaiseAndSetIfChanged(ref _Name, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public ObservableCollection Songs { - get => _Songs; - set => this.RaiseAndSetIfChanged(ref _Songs, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public string? Source => this.GetRelativeOrAbsoluteSourceFile(); public VideoInfo? VideoInfo { - get => _VideoInfo; + get; set { - this.RaiseAndSetIfChanged(ref _VideoInfo, value); + this.RaiseAndSetIfChanged(ref field, value); this.RaisePropertyChanged(nameof(Source)); } } public int Year { - get => _Year; - set => this.RaiseAndSetIfChanged(ref _Year, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } IReadOnlyList IAnimeBase.Songs => Songs; private string DebuggerDisplay => Name; diff --git a/src/SongProcessor.UI/Models/ObservableSong.cs b/src/SongProcessor.UI/Models/ObservableSong.cs index d0fc2ce..62f0c73 100644 --- a/src/SongProcessor.UI/Models/ObservableSong.cs +++ b/src/SongProcessor.UI/Models/ObservableSong.cs @@ -9,97 +9,81 @@ namespace SongProcessor.UI.Models; [DebuggerDisplay(ModelUtils.DEBUGGER_DISPLAY)] public sealed class ObservableSong : ReactiveObject, ISong { - private HashSet _AlsoIn = null!; - private string _Artist = null!; - private string? _CleanPath; - private TimeSpan _End; - private int? _Episode; - private bool _IsVisible = true; - private string _Name = null!; - private AspectRatio? _OverrideAspectRatio; - private int _OverrideAudioTrack; - private int _OverrideVideoTrack; - private bool _ShouldIgnore; - private TimeSpan _Start; - private Status _Status; - private SongTypeAndPosition _Type; - private VolumeModifer? _VolumeModifier; - public HashSet AlsoIn { - get => _AlsoIn; - set => this.RaiseAndSetIfChanged(ref _AlsoIn, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = null!; public string Artist { - get => _Artist; - set => this.RaiseAndSetIfChanged(ref _Artist, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = null!; public string? CleanPath { - get => _CleanPath; - set => this.RaiseAndSetIfChanged(ref _CleanPath, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public TimeSpan End { - get => _End; - set => this.RaiseAndSetIfChanged(ref _End, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public int? Episode { - get => _Episode; - set => this.RaiseAndSetIfChanged(ref _Episode, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public bool IsVisible { - get => _IsVisible; - set => this.RaiseAndSetIfChanged(ref _IsVisible, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = true; public string Name { - get => _Name; - set => this.RaiseAndSetIfChanged(ref _Name, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = null!; public AspectRatio? OverrideAspectRatio { - get => _OverrideAspectRatio; - set => this.RaiseAndSetIfChanged(ref _OverrideAspectRatio, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public int OverrideAudioTrack { - get => _OverrideAudioTrack; - set => this.RaiseAndSetIfChanged(ref _OverrideAudioTrack, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public int OverrideVideoTrack { - get => _OverrideVideoTrack; - set => this.RaiseAndSetIfChanged(ref _OverrideVideoTrack, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public ObservableAnime Parent { get; } public bool ShouldIgnore { - get => _ShouldIgnore; - set => this.RaiseAndSetIfChanged(ref _ShouldIgnore, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public TimeSpan Start { - get => _Start; - set => this.RaiseAndSetIfChanged(ref _Start, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public Status Status { - get => _Status; - set => this.RaiseAndSetIfChanged(ref _Status, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public SongTypeAndPosition Type { - get => _Type; - set => this.RaiseAndSetIfChanged(ref _Type, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public VolumeModifer? VolumeModifier { - get => _VolumeModifier; - set => this.RaiseAndSetIfChanged(ref _VolumeModifier, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } IReadOnlySet ISong.AlsoIn => AlsoIn; private string DebuggerDisplay => this.GetFullName(); diff --git a/src/SongProcessor.UI/SongProcessor.UI.csproj b/src/SongProcessor.UI/SongProcessor.UI.csproj index 69d5578..cd6dad0 100644 --- a/src/SongProcessor.UI/SongProcessor.UI.csproj +++ b/src/SongProcessor.UI/SongProcessor.UI.csproj @@ -5,6 +5,7 @@ copyused true cirno_at_computer_pTB_icon.ico + true diff --git a/src/SongProcessor.UI/SortedObservableCollection.cs b/src/SongProcessor.UI/SortedObservableCollection.cs index 3fce2a6..d156dc9 100644 --- a/src/SongProcessor.UI/SortedObservableCollection.cs +++ b/src/SongProcessor.UI/SortedObservableCollection.cs @@ -5,7 +5,7 @@ namespace SongProcessor.UI; -public class SortedObservableCollection(IComparer comparer, IEnumerable? collection = null) : ObservableCollection(collection ?? Array.Empty()) +public class SortedObservableCollection(IComparer comparer, IEnumerable? collection = null) : ObservableCollection(collection ?? []) { public IComparer Comparer { get; } = comparer; diff --git a/src/SongProcessor.UI/UIUtils.cs b/src/SongProcessor.UI/UIUtils.cs index 34cc3ca..634db8f 100644 --- a/src/SongProcessor.UI/UIUtils.cs +++ b/src/SongProcessor.UI/UIUtils.cs @@ -11,7 +11,7 @@ public static class UIUtils public const string NO = "No"; public const string YES = "Yes"; - public static ImmutableArray YesNo { get; } = new[] { YES, NO }.ToImmutableArray(); + public static ImmutableArray YesNo { get; } = [YES, NO]; public static async Task ConfirmAsync( this IMessageBoxManager manager, diff --git a/src/SongProcessor.UI/ViewModels/AddViewModel.cs b/src/SongProcessor.UI/ViewModels/AddViewModel.cs index 334bc55..8351466 100644 --- a/src/SongProcessor.UI/ViewModels/AddViewModel.cs +++ b/src/SongProcessor.UI/ViewModels/AddViewModel.cs @@ -26,64 +26,56 @@ public sealed class AddViewModel : ReactiveObject, IRoutableViewModel private readonly IEnumerable _Gatherers; private readonly ISongLoader _Loader; private readonly IMessageBoxManager _MessageBoxManager; - private bool _AddEndings = true; - private bool _AddInserts = true; - private bool _AddOpenings = true; - private bool _AddSongs = true; - private string? _Directory; - private Exception? _Exception; - private int _Id = 1; - private string _SelectedGathererName; [DataMember] public bool AddEndings { - get => _AddEndings; - set => this.RaiseAndSetIfChanged(ref _AddEndings, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = true; [DataMember] public bool AddInserts { - get => _AddInserts; - set => this.RaiseAndSetIfChanged(ref _AddInserts, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = true; [DataMember] public bool AddOpenings { - get => _AddOpenings; - set => this.RaiseAndSetIfChanged(ref _AddOpenings, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = true; [DataMember] public bool AddSongs { - get => _AddSongs; - set => this.RaiseAndSetIfChanged(ref _AddSongs, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = true; public ObservableCollection Anime { get; } = []; [DataMember] public string? Directory { - get => _Directory; - set => this.RaiseAndSetIfChanged(ref _Directory, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public Exception? Exception { - get => _Exception; - set => this.RaiseAndSetIfChanged(ref _Exception, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public IEnumerable GathererNames { get; } public IScreen HostScreen { get; } [DataMember] public int Id { - get => _Id; - set => this.RaiseAndSetIfChanged(ref _Id, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = 1; [DataMember] public string SelectedGathererName { - get => _SelectedGathererName; - set => this.RaiseAndSetIfChanged(ref _SelectedGathererName, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public string UrlPathSegment => "/add"; @@ -103,7 +95,7 @@ public AddViewModel( _Loader = loader ?? throw new ArgumentNullException(nameof(loader)); _MessageBoxManager = messageBoxManager ?? throw new ArgumentNullException(nameof(messageBoxManager)); _Gatherers = gatherers ?? throw new ArgumentNullException(nameof(gatherers)); - _SelectedGathererName = _Gatherers.First().Name; + SelectedGathererName = _Gatherers.First().Name; GathererNames = _Gatherers.Select(x => x.Name); var canAdd = this.WhenAnyValue( diff --git a/src/SongProcessor.UI/ViewModels/EditViewModel.cs b/src/SongProcessor.UI/ViewModels/EditViewModel.cs index d5eab6c..8a21b13 100644 --- a/src/SongProcessor.UI/ViewModels/EditViewModel.cs +++ b/src/SongProcessor.UI/ViewModels/EditViewModel.cs @@ -22,130 +22,112 @@ public sealed class EditViewModel : ReactiveObject, IRoutableViewModel, IValidat private readonly ISongLoader _Loader; private readonly IMessageBoxManager _MessageBoxManager; private readonly ObservableSong _Song; - private string _Artist; - private AspectRatio _AspectRatio; - private int _AudioTrack; - private string _ButtonText = "Save"; - private string _CleanPath; - private string _End; - private int _Episode; - private bool _Has480p; - private bool _Has720p; - private bool _HasMp3; - private bool _IsSubmitted; - private string _Name; - private bool _ShouldIgnore; - private int _SongPosition; - private SongType _SongType; - private string _Start; - private int _VideoTrack; - private int _VolumeModifier; - public static IReadOnlyList AspectRatios { get; } = new[] - { + public static IReadOnlyList AspectRatios { get; } = + [ default, new AspectRatio(4, 3), new AspectRatio(16, 9), - }; - public static IReadOnlyList SongTypes { get; } = new[] - { + ]; + public static IReadOnlyList SongTypes { get; } = + [ SongType.Opening, SongType.Ending, SongType.Insert, - }; + ]; public string Artist { - get => _Artist; - set => this.RaiseAndSetIfChanged(ref _Artist, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public AspectRatio AspectRatio { - get => _AspectRatio; - set => this.RaiseAndSetIfChanged(ref _AspectRatio, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public int AudioTrack { - get => _AudioTrack; - set => this.RaiseAndSetIfChanged(ref _AudioTrack, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public string ButtonText { - get => _ButtonText; - set => this.RaiseAndSetIfChanged(ref _ButtonText, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = "Save"; public string CleanPath { - get => _CleanPath; - set => this.RaiseAndSetIfChanged(ref _CleanPath, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public string End { - get => _End; - set => this.RaiseAndSetIfChanged(ref _End, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public int Episode { - get => _Episode; - set => this.RaiseAndSetIfChanged(ref _Episode, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public bool Has480p { - get => _Has480p; - set => this.RaiseAndSetIfChanged(ref _Has480p, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public bool Has720p { - get => _Has720p; - set => this.RaiseAndSetIfChanged(ref _Has720p, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public bool HasMp3 { - get => _HasMp3; - set => this.RaiseAndSetIfChanged(ref _HasMp3, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public IScreen HostScreen { get; } public bool IsSubmitted { - get => _IsSubmitted; - set => this.RaiseAndSetIfChanged(ref _IsSubmitted, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public string Name { - get => _Name; - set => this.RaiseAndSetIfChanged(ref _Name, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public bool ShouldIgnore { - get => _ShouldIgnore; - set => this.RaiseAndSetIfChanged(ref _ShouldIgnore, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public int SongPosition { - get => _SongPosition; - set => this.RaiseAndSetIfChanged(ref _SongPosition, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public SongType SongType { - get => _SongType; - set => this.RaiseAndSetIfChanged(ref _SongType, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public string Start { - get => _Start; - set => this.RaiseAndSetIfChanged(ref _Start, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public string UrlPathSegment => "/edit"; public ValidationContext ValidationContext { get; } = new(); public int VideoTrack { - get => _VideoTrack; - set => this.RaiseAndSetIfChanged(ref _VideoTrack, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public int VolumeModifier { - get => _VolumeModifier; - set => this.RaiseAndSetIfChanged(ref _VolumeModifier, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } #region Commands @@ -165,23 +147,23 @@ public EditViewModel( _Loader = loader ?? throw new ArgumentNullException(nameof(loader)); _MessageBoxManager = messageBoxManager ?? throw new ArgumentNullException(nameof(messageBoxManager)); - _Artist = _Song.Artist; - _AspectRatio = _Song.OverrideAspectRatio ?? AspectRatios[0]; - _AudioTrack = _Song.OverrideAudioTrack; - _CleanPath = _Song.CleanPath!; - _End = _Song.End.ToString(); - _Episode = _Song.Episode ?? 0; - _Has480p = !song.IsMissing(Status.Res480); - _Has720p = !song.IsMissing(Status.Res720); - _HasMp3 = !song.IsMissing(Status.Mp3); - _IsSubmitted = song.Status != Status.NotSubmitted; - _Name = _Song.Name; - _ShouldIgnore = _Song.ShouldIgnore; - _SongPosition = _Song.Type.Position ?? 0; - _SongType = _Song.Type.Type; - _Start = _Song.Start.ToString(); - _VideoTrack = _Song.OverrideVideoTrack; - _VolumeModifier = (int)(_Song.VolumeModifier?.Value ?? 0); + Artist = _Song.Artist; + AspectRatio = _Song.OverrideAspectRatio ?? AspectRatios[0]; + AudioTrack = _Song.OverrideAudioTrack; + CleanPath = _Song.CleanPath!; + End = _Song.End.ToString(); + Episode = _Song.Episode ?? 0; + Has480p = !song.IsMissing(Status.Res480); + Has720p = !song.IsMissing(Status.Res720); + HasMp3 = !song.IsMissing(Status.Mp3); + IsSubmitted = song.Status != Status.NotSubmitted; + Name = _Song.Name; + ShouldIgnore = _Song.ShouldIgnore; + SongPosition = _Song.Type.Position ?? 0; + SongType = _Song.Type.Type; + Start = _Song.Start.ToString(); + VideoTrack = _Song.OverrideVideoTrack; + VolumeModifier = (int)(_Song.VolumeModifier?.Value ?? 0); this.ValidationRule( x => x.Artist, diff --git a/src/SongProcessor.UI/ViewModels/MainViewModel.cs b/src/SongProcessor.UI/ViewModels/MainViewModel.cs index 8e3350b..981db80 100644 --- a/src/SongProcessor.UI/ViewModels/MainViewModel.cs +++ b/src/SongProcessor.UI/ViewModels/MainViewModel.cs @@ -16,14 +16,12 @@ namespace SongProcessor.UI.ViewModels; [DataContract] public sealed class MainViewModel : ReactiveObject, IScreen { - private RoutingState _Router = new(); - [DataMember] public RoutingState Router { - get => _Router; - set => this.RaiseAndSetIfChanged(ref _Router, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = new(); #region Commands public ReactiveCommand Add { get; } diff --git a/src/SongProcessor.UI/ViewModels/MessageBoxViewModel.cs b/src/SongProcessor.UI/ViewModels/MessageBoxViewModel.cs index 85089c9..6552cc4 100644 --- a/src/SongProcessor.UI/ViewModels/MessageBoxViewModel.cs +++ b/src/SongProcessor.UI/ViewModels/MessageBoxViewModel.cs @@ -9,47 +9,37 @@ namespace SongProcessor.UI.ViewModels; public sealed class MessageBoxViewModel : ReactiveObject { - private string? _ButtonText = "Ok"; - private bool _CanResize; - private T? _CurrentOption; - private bool _HasOptions; - private int _Height = UIUtils.MESSAGE_BOX_HEIGHT; - private IEnumerable? _Options; - private string? _Text; - private string? _Title; - private int _Width = UIUtils.MESSAGE_BOX_WIDTH; - public string? ButtonText { - get => _ButtonText; - set => this.RaiseAndSetIfChanged(ref _ButtonText, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = "Ok"; public bool CanResize { - get => _CanResize; - set => this.RaiseAndSetIfChanged(ref _CanResize, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public T? CurrentOption { - get => _CurrentOption; - set => this.RaiseAndSetIfChanged(ref _CurrentOption, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public bool HasOptions { - get => _HasOptions; - private set => this.RaiseAndSetIfChanged(ref _HasOptions, value); + get; + private set => this.RaiseAndSetIfChanged(ref field, value); } public int Height { - get => _Height; - set => this.RaiseAndSetIfChanged(ref _Height, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = UIUtils.MESSAGE_BOX_HEIGHT; public IEnumerable? Options { - get => _Options; + get; set { - this.RaiseAndSetIfChanged(ref _Options, value); + this.RaiseAndSetIfChanged(ref field, value); CurrentOption = default!; HasOptions = value?.Any() ?? false; ButtonText = HasOptions ? "Confirm" : "Ok"; @@ -57,19 +47,19 @@ public IEnumerable? Options } public string? Text { - get => _Text; - set => this.RaiseAndSetIfChanged(ref _Text, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public string? Title { - get => _Title; - set => this.RaiseAndSetIfChanged(ref _Title, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public int Width { - get => _Width; - set => this.RaiseAndSetIfChanged(ref _Width, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = UIUtils.MESSAGE_BOX_WIDTH; #region Commands public ReactiveCommand Escape { get; } diff --git a/src/SongProcessor.UI/ViewModels/SearchTerms.cs b/src/SongProcessor.UI/ViewModels/SearchTerms.cs index 7b2fa11..67e0b7f 100644 --- a/src/SongProcessor.UI/ViewModels/SearchTerms.cs +++ b/src/SongProcessor.UI/ViewModels/SearchTerms.cs @@ -9,27 +9,23 @@ namespace SongProcessor.UI.ViewModels; [DataContract] public sealed class SearchTerms : ReactiveObject { - private string? _AnimeName; - private string? _ArtistName; - private string? _SongName; - [DataMember] public string? AnimeName { - get => _AnimeName; - set => this.RaiseAndSetIfChanged(ref _AnimeName, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } [DataMember] public string? ArtistName { - get => _ArtistName; - set => this.RaiseAndSetIfChanged(ref _ArtistName, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } [DataMember] public string? SongName { - get => _SongName; - set => this.RaiseAndSetIfChanged(ref _SongName, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public bool IsVisible(IAnime anime) diff --git a/src/SongProcessor.UI/ViewModels/SongViewModel.cs b/src/SongProcessor.UI/ViewModels/SongViewModel.cs index 0d771f5..6d20741 100644 --- a/src/SongProcessor.UI/ViewModels/SongViewModel.cs +++ b/src/SongProcessor.UI/ViewModels/SongViewModel.cs @@ -42,33 +42,25 @@ public sealed class SongViewModel : ReactiveObject, IRoutableViewModel, INavigat private readonly ISongProcessor _Processor; private readonly List _Subscriptions = []; private readonly IClipboard _SystemClipboard; - private Clipboard? _ClipboardSong; - private int _CurrentJob; - private string? _Directory; - private ProcessingData? _ProcessingData; - private int _QueuedJobs; - private SearchTerms _Search = new(); - private AvaloniaList _SelectedItems = []; - private SongVisibility _SongVisibility = new(); public ObservableCollection Anime { get; } = new SortedObservableCollection(AnimeComparer.Instance); public IObservable CanNavigate { get; } public Clipboard? ClipboardSong { - get => _ClipboardSong; - set => this.RaiseAndSetIfChanged(ref _ClipboardSong, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public int CurrentJob { - get => _CurrentJob; - set => this.RaiseAndSetIfChanged(ref _CurrentJob, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } [DataMember] public string? Directory { - get => _Directory; - set => this.RaiseAndSetIfChanged(ref _Directory, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public IScreen HostScreen { get; } public bool IsBusy => _IsBusy.Value; @@ -77,31 +69,31 @@ public string? Directory public bool OnlySongsSelected => _OnlySongsSelected.Value; public ProcessingData? ProcessingData { - get => _ProcessingData; - set => this.RaiseAndSetIfChanged(ref _ProcessingData, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } public int QueuedJobs { - get => _QueuedJobs; - set => this.RaiseAndSetIfChanged(ref _QueuedJobs, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } [DataMember] public SearchTerms Search { - get => _Search; - set => this.RaiseAndSetIfChanged(ref _Search, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = new(); public AvaloniaList SelectedItems { - get => _SelectedItems; - set => this.RaiseAndSetIfChanged(ref _SelectedItems, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = []; [DataMember] public SongVisibility SongVisibility { - get => _SongVisibility; - set => this.RaiseAndSetIfChanged(ref _SongVisibility, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = new(); public string UrlPathSegment => "/songs"; #region Commands @@ -359,7 +351,7 @@ private async Task GetVolumeInfoAsync(ObservableAnime anime) foreach (var path in paths) { - VolumeInfo info; + VolumeInfo? info; try { info = await _Gatherer.GetVolumeInfoAsync(path).ConfigureAwait(true); @@ -372,7 +364,9 @@ private async Task GetVolumeInfoAsync(ObservableAnime anime) continue; } - var text = $"Volume information for \"{Path.GetFileName(path)}\":" + + var text = info is null + ? $"Unable to get volume information for \"{Path.GetFileName(path)}\"." + : $"Volume information for \"{Path.GetFileName(path)}\":" + $"\nMean volume: {info.MeanVolume}dB" + $"\nMax volume: {info.MaxVolume}dB"; _ = Dispatcher.UIThread.InvokeAsync(() => diff --git a/src/SongProcessor.UI/ViewModels/SongVisibility.cs b/src/SongProcessor.UI/ViewModels/SongVisibility.cs index 35cf967..1779c93 100644 --- a/src/SongProcessor.UI/ViewModels/SongVisibility.cs +++ b/src/SongProcessor.UI/ViewModels/SongVisibility.cs @@ -9,56 +9,48 @@ namespace SongProcessor.UI.ViewModels; [DataContract] public sealed class SongVisibility : ReactiveObject { - private bool _IsExpanded; - private bool _ShowCompletedSongs = true; - private bool _ShowIgnoredSongs = true; - private bool _ShowMissing480pSongs = true; - private bool _ShowMissing720pSongs = true; - private bool _ShowMissingMp3Songs = true; - private bool _ShowUnsubmittedSongs = true; - [DataMember] public bool IsExpanded { - get => _IsExpanded; - set => this.RaiseAndSetIfChanged(ref _IsExpanded, value); + get; + set => this.RaiseAndSetIfChanged(ref field, value); } [DataMember] public bool ShowCompletedSongs { - get => _ShowCompletedSongs; - set => this.RaiseAndSetIfChanged(ref _ShowCompletedSongs, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = true; [DataMember] public bool ShowIgnoredSongs { - get => _ShowIgnoredSongs; - set => this.RaiseAndSetIfChanged(ref _ShowIgnoredSongs, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = true; [DataMember] public bool ShowMissing480pSongs { - get => _ShowMissing480pSongs; - set => this.RaiseAndSetIfChanged(ref _ShowMissing480pSongs, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = true; [DataMember] public bool ShowMissing720pSongs { - get => _ShowMissing720pSongs; - set => this.RaiseAndSetIfChanged(ref _ShowMissing720pSongs, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = true; [DataMember] public bool ShowMissingMp3Songs { - get => _ShowMissingMp3Songs; - set => this.RaiseAndSetIfChanged(ref _ShowMissingMp3Songs, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = true; [DataMember] public bool ShowUnsubmittedSongs { - get => _ShowUnsubmittedSongs; - set => this.RaiseAndSetIfChanged(ref _ShowUnsubmittedSongs, value); - } + get; + set => this.RaiseAndSetIfChanged(ref field, value); + } = true; public bool IsVisible(ISong song) { diff --git a/src/SongProcessor/FFmpeg/ISourceInfoGatherer.cs b/src/SongProcessor/FFmpeg/ISourceInfoGatherer.cs index 4afcd67..797d0d1 100644 --- a/src/SongProcessor/FFmpeg/ISourceInfoGatherer.cs +++ b/src/SongProcessor/FFmpeg/ISourceInfoGatherer.cs @@ -2,9 +2,9 @@ public interface ISourceInfoGatherer { - Task GetAudioInfoAsync(string file, int track = 0); + Task GetAudioInfoAsync(string file, int track = 0); - Task GetVideoInfoAsync(string file, int track = 0); + Task GetVideoInfoAsync(string file, int track = 0); - Task GetVolumeInfoAsync(string file, int track = 0); + Task GetVolumeInfoAsync(string file, int track = 0); } \ No newline at end of file diff --git a/src/SongProcessor/FFmpeg/Jobs/SongJob.cs b/src/SongProcessor/FFmpeg/Jobs/SongJob.cs index ec2c6fd..8734e1c 100644 --- a/src/SongProcessor/FFmpeg/Jobs/SongJob.cs +++ b/src/SongProcessor/FFmpeg/Jobs/SongJob.cs @@ -88,7 +88,7 @@ void KillProcess(object? sender, EventArgs? args) var runTask = process.RunAsync(OutputMode.Async); var tasks = token is null - ? new[] { runTask } + ? [runTask] : new[] { runTask, process.WaitForExitAsync(token.Value) }; var task = await Task.WhenAny(tasks).ConfigureAwait(false); diff --git a/src/SongProcessor/FFmpeg/ProgressBuilder.cs b/src/SongProcessor/FFmpeg/ProgressBuilder.cs index 74ed42a..47f7ac2 100644 --- a/src/SongProcessor/FFmpeg/ProgressBuilder.cs +++ b/src/SongProcessor/FFmpeg/ProgressBuilder.cs @@ -21,8 +21,8 @@ internal sealed class ProgressBuilder private Dictionary _Values = new(ValidKeys.Count); - public static ImmutableHashSet ValidKeys { get; } = ImmutableHashSet.Create(new[] - { + public static ImmutableHashSet ValidKeys { get; } = ImmutableHashSet.Create( + [ BITRATE, DROP_FRAMES, DUP_FRAMES, @@ -35,7 +35,7 @@ internal sealed class ProgressBuilder SPEED, STREAM00Q, TOTAL_SIZE, - }); + ]); public bool IsNextProgressReady(string kvp, [NotNullWhen(true)] out Progress? progress) { diff --git a/src/SongProcessor/FFmpeg/SourceInfoGatherer.cs b/src/SongProcessor/FFmpeg/SourceInfoGatherer.cs index cc2f6fb..183d56e 100644 --- a/src/SongProcessor/FFmpeg/SourceInfoGatherer.cs +++ b/src/SongProcessor/FFmpeg/SourceInfoGatherer.cs @@ -10,7 +10,7 @@ namespace SongProcessor.FFmpeg; -public sealed class SourceInfoGatherer : ISourceInfoGatherer +public sealed partial class SourceInfoGatherer : ISourceInfoGatherer { private const string PROPERTY = "property"; private const string VALUE = "value"; @@ -32,31 +32,29 @@ public sealed class SourceInfoGatherer : ISourceInfoGatherer { ["volumedetect"] = "", }; - private static readonly Regex VolumeDetectRegex = - new(VOLUME_DETECT_PATTERN, RegexOptions.Compiled | RegexOptions.ExplicitCapture); - public Task GetAudioInfoAsync(string file, int track = 0) + public Task GetAudioInfoAsync(string file, int track = 0) => GetInfoAsync(file, 'a', track); - public Task GetVideoInfoAsync(string file, int track = 0) + public Task GetVideoInfoAsync(string file, int track = 0) => GetInfoAsync(file, 'v', track); - public async Task GetVolumeInfoAsync(string file, int track = 0) + public async Task GetVolumeInfoAsync(string file, int track = 0) { if (!File.Exists(file)) { - throw FileNotFound(file, 'a'); + return null; } var args = new FFmpegArgs( - Inputs: new FFmpegInput[] - { + Inputs: + [ new(file, null), - }, - Mapping: new[] - { + ], + Mapping: + [ $"0:a:{track}", - }, + ], Args: _VolumeArgs, AudioFilters: _VolumeAudioFilters, VideoFilters: null, @@ -75,7 +73,7 @@ public async Task GetVolumeInfoAsync(string file, int track = 0) return; } - var match = VolumeDetectRegex.Match(e.Data); + var match = ParseVolume().Match(e.Data); if (!match.Success) { return; @@ -134,20 +132,17 @@ private static JsonSerializerOptions CreateJsonOptions() return options; } - private static SourceInfoGatheringException FileNotFound(string file, char stream) - => new(file, stream, new FileNotFoundException("File does not exist", file)); - - private static async Task GetInfoAsync(string file, char stream, int track) + private static async Task GetInfoAsync(string file, char stream, int track) where T : SourceInfo { if (!File.Exists(file)) { - throw FileNotFound(file, stream); + return null; } var args = new FFmpegArgs( - Inputs: Array.Empty(), - Mapping: Array.Empty(), + Inputs: [], + Mapping: [], Args: new Dictionary { ["v"] = "quiet", @@ -203,4 +198,7 @@ private sealed record Output( [property: JsonPropertyName("streams")] T[] Streams ); + + [GeneratedRegex(VOLUME_DETECT_PATTERN, RegexOptions.ExplicitCapture | RegexOptions.Compiled)] + private static partial Regex ParseVolume(); } \ No newline at end of file diff --git a/src/SongProcessor/Gatherers/GathererUtils.cs b/src/SongProcessor/Gatherers/GathererUtils.cs index ca6ed64..f0a2c28 100644 --- a/src/SongProcessor/Gatherers/GathererUtils.cs +++ b/src/SongProcessor/Gatherers/GathererUtils.cs @@ -4,8 +4,7 @@ namespace SongProcessor.Gatherers; public static class GathererUtils { - private static HttpClient? _DefaultGathererClient; - public static HttpClient DefaultGathererClient => _DefaultGathererClient ??= CreateClient(); + public static HttpClient DefaultGathererClient => field ??= CreateClient(); public static FormatException InvalidPropertyProvided( this IAnimeGatherer gatherer, diff --git a/src/SongProcessor/Models/Anime.cs b/src/SongProcessor/Models/Anime.cs index 37e56be..93163a8 100644 --- a/src/SongProcessor/Models/Anime.cs +++ b/src/SongProcessor/Models/Anime.cs @@ -19,10 +19,7 @@ public class Anime : IAnime public Anime(string file, IAnimeBase other, VideoInfo? videoInfo) { - if (file is null) - { - throw new ArgumentNullException(nameof(file)); - } + ArgumentNullException.ThrowIfNull(file); if (!Path.IsPathFullyQualified(file)) { throw new ArgumentException("Must be an absolute path.", nameof(file)); diff --git a/src/SongProcessor/SongProcessor.cs b/src/SongProcessor/SongProcessor.cs index dd70b9f..04cdfd6 100644 --- a/src/SongProcessor/SongProcessor.cs +++ b/src/SongProcessor/SongProcessor.cs @@ -146,11 +146,11 @@ private static IReadOnlyList GetValidResolutions(IAnime anime) // Source is smaller than 480p, return mp3 and souce size (but treat as 480p status) if (height < Resolution.RES_480.Size) { - return new[] - { + return + [ Resolution.RES_MP3, new(height, Status.Res480), - }; + ]; } // Source is smaller than 720p, return mp3 and 480p else if (height < Resolution.RES_720.Size) diff --git a/tests/SongProcessor.Tests/FFmpeg/Jobs/Mp3SongJob_Tests.cs b/tests/SongProcessor.Tests/FFmpeg/Jobs/Mp3SongJob_Tests.cs index b32bd86..c27aa1b 100644 --- a/tests/SongProcessor.Tests/FFmpeg/Jobs/Mp3SongJob_Tests.cs +++ b/tests/SongProcessor.Tests/FFmpeg/Jobs/Mp3SongJob_Tests.cs @@ -34,13 +34,13 @@ public void ArgsMp3CleanPath_Test() actual.Should().NotBeEquivalentTo(@default); actual.Should().BeEquivalentTo(@default with { - Inputs = new FFmpegInput[] - { + Inputs = + [ new(job.Song.GetCleanFile(job.Anime)!, new Dictionary { ["to"] = job.Song.GetLength().ToString(), }), - }, + ], }); } @@ -55,10 +55,10 @@ public void ArgsMp3OverrideAudioTrack_Test() actual.Should().NotBeEquivalentTo(@default); actual.Should().BeEquivalentTo(@default with { - Mapping = new[] - { + Mapping = + [ $"0:a:{job.Song.OverrideAudioTrack}", - }, + ], }); } @@ -128,7 +128,7 @@ public async Task ProcessMp3Complicated_Test() // Create a duplicate version to treat as a clean version var cleanPath = await GetSingleFileProducedAsync(temp.Dir, job).ConfigureAwait(false); var cleanVolumeInfo = await Gatherer.GetVolumeInfoAsync(cleanPath).ConfigureAwait(false); - AssertValidLength(cleanVolumeInfo.NSamples, VolumeInfo.NSamples); + AssertValidLength(cleanVolumeInfo!.NSamples, VolumeInfo.NSamples); { var movedPath = Path.Combine( @@ -153,8 +153,8 @@ public async Task ProcessMp3Complicated_Test() var file = GetSingleFile(temp.Dir); var newVolumeInfo = await Gatherer.GetVolumeInfoAsync(file).ConfigureAwait(false); AssertValidLength(job, newVolumeInfo); - newVolumeInfo.MaxVolume.Should().BeLessThan(VolumeInfo.MaxVolume); - newVolumeInfo.MeanVolume.Should().BeLessThan(VolumeInfo.MeanVolume); + newVolumeInfo!.MaxVolume.Should().BeLessThan(VolumeInfo.MaxVolume); + newVolumeInfo!.MeanVolume.Should().BeLessThan(VolumeInfo.MeanVolume); } protected override Mp3SongJob GenerateJob(Anime anime, Song song) @@ -163,15 +163,15 @@ protected override Mp3SongJob GenerateJob(Anime anime, Song song) private static FFmpegArgs GenerateDefaultJobArgs(Mp3SongJob job) { return new FFmpegArgs( - Inputs: new FFmpegInput[] - { + Inputs: + [ new(job.Anime.GetSourceFile(), new Dictionary { ["ss"] = job.Song.Start.ToString(), ["to"] = job.Song.End.ToString(), }), - }, - Mapping: new[] { "0:a:0" }, + ], + Mapping: ["0:a:0"], Args: Mp3SongJob.AudioArgs, AudioFilters: null, VideoFilters: null, @@ -179,9 +179,9 @@ private static FFmpegArgs GenerateDefaultJobArgs(Mp3SongJob job) ); } - private void AssertValidLength(SongJob job, VolumeInfo info) + private void AssertValidLength(SongJob job, VolumeInfo? info) { - var duration = (double)info.NSamples; + var duration = (double)info!.NSamples; var divisor = VideoInfo.Duration!.Value / job.Song.GetLength().TotalSeconds; var expected = VolumeInfo.NSamples / divisor; AssertValidLength(duration, expected); diff --git a/tests/SongProcessor.Tests/FFmpeg/Jobs/VideoSongJob_Tests.cs b/tests/SongProcessor.Tests/FFmpeg/Jobs/VideoSongJob_Tests.cs index 5263815..a2e7c14 100644 --- a/tests/SongProcessor.Tests/FFmpeg/Jobs/VideoSongJob_Tests.cs +++ b/tests/SongProcessor.Tests/FFmpeg/Jobs/VideoSongJob_Tests.cs @@ -34,12 +34,12 @@ public void ArgsVideoCleanPath_Test() actual.Should().NotBeEquivalentTo(@default); actual.Should().BeEquivalentTo(@default with { - Inputs = new FFmpegInput[] - { + Inputs = + [ @default.Inputs[0], new(job.Song.GetCleanFile(job.Anime)!, null), - }, - Mapping = new[] { "0:v:0", "1:a:0" }, + ], + Mapping = ["0:v:0", "1:a:0"], }); } @@ -143,11 +143,11 @@ public void ArgsVideoOverrideTracks_Test() actual.Should().NotBeEquivalentTo(@default); actual.Should().BeEquivalentTo(@default with { - Mapping = new[] - { + Mapping = + [ $"0:a:{job.Song.OverrideAudioTrack}", $"0:v:{job.Song.OverrideVideoTrack}", - }, + ], }); } @@ -271,15 +271,15 @@ private static void AssertValidLength(SongJob job, VideoInfo info) private static FFmpegArgs GenerateDefaultJobArgs(VideoSongJob job) { return new FFmpegArgs( - Inputs: new FFmpegInput[] - { + Inputs: + [ new(job.Anime.GetSourceFile(), new Dictionary { ["ss"] = job.Song.Start.ToString(), ["to"] = job.Song.End.ToString(), }), - }, - Mapping: new[] { "0:v:0", "0:a:0" }, + ], + Mapping: ["0:v:0", "0:a:0"], Args: VideoSongJob.VideoArgs, AudioFilters: null, VideoFilters: null, diff --git a/tests/SongProcessor.Tests/FFmpeg/SourceInfoGatherer_Tests.cs b/tests/SongProcessor.Tests/FFmpeg/SourceInfoGatherer_Tests.cs index e1a8b88..25752b9 100644 --- a/tests/SongProcessor.Tests/FFmpeg/SourceInfoGatherer_Tests.cs +++ b/tests/SongProcessor.Tests/FFmpeg/SourceInfoGatherer_Tests.cs @@ -37,11 +37,8 @@ public async Task GetAudioInfoInvalidFile_Test() [TestMethod] public async Task GetAudioInfoNonExistentFile_Test() { - Func getInfo = () => Gatherer.GetAudioInfoAsync(FAKE_FILE); - (await getInfo.Should() - .ThrowAsync() - .ConfigureAwait(false)) - .WithInnerException(); + var result = await Gatherer.GetAudioInfoAsync(FAKE_FILE).ConfigureAwait(false); + result.Should().BeNull(); } [TestMethod] @@ -70,11 +67,8 @@ public async Task GetVideoInfoInvalidFile_Test() [TestMethod] public async Task GetVideoInfoNonExistentFile_Test() { - Func getInfo = () => Gatherer.GetVideoInfoAsync(FAKE_FILE); - (await getInfo.Should() - .ThrowAsync() - .ConfigureAwait(false)) - .WithInnerException(); + var result = await Gatherer.GetVideoInfoAsync(FAKE_FILE).ConfigureAwait(false); + result.Should().BeNull(); } [TestMethod] @@ -103,10 +97,7 @@ public async Task GetVolumeInfoInvalidFile_Test() [TestMethod] public async Task GetVolumeInfoNonExistentFile_Test() { - Func getInfo = () => Gatherer.GetVolumeInfoAsync(FAKE_FILE); - (await getInfo.Should() - .ThrowAsync() - .ConfigureAwait(false)) - .WithInnerException(); + var result = await Gatherer.GetVolumeInfoAsync(FAKE_FILE).ConfigureAwait(false); + result.Should().BeNull(); } } \ No newline at end of file diff --git a/tests/SongProcessor.Tests/SongLoader_Tests.cs b/tests/SongProcessor.Tests/SongLoader_Tests.cs index dfcfb83..5827492 100644 --- a/tests/SongProcessor.Tests/SongLoader_Tests.cs +++ b/tests/SongProcessor.Tests/SongLoader_Tests.cs @@ -70,8 +70,8 @@ public async Task SaveAndLoad_Test() { using var temp = new TempDirectory(); var expected = CreateAnime(temp.Dir); - expected.Songs.AddRange(new Song[] - { + expected.Songs.AddRange( + [ new() { Name = "Song1", @@ -84,7 +84,7 @@ public async Task SaveAndLoad_Test() Artist = "Artist2", Type = SongType.Ed.Create(1), }, - }); + ]); await _Loader.SaveAsync(expected).ConfigureAwait(false); var actual = await _Loader.LoadAsync(expected.AbsoluteInfoPath).ConfigureAwait(false); diff --git a/tests/SongProcessor.Tests/SongProcessor_Tests.cs b/tests/SongProcessor.Tests/SongProcessor_Tests.cs index 7cbc14f..19e7f54 100644 --- a/tests/SongProcessor.Tests/SongProcessor_Tests.cs +++ b/tests/SongProcessor.Tests/SongProcessor_Tests.cs @@ -17,10 +17,10 @@ public sealed class SongProcessor_Tests : FFmpeg_TestsBase [TestMethod] public void CreateJobsNoSongs_Test() { - var actual = ((ISongProcessor)_Processor).CreateJobs(new Anime[] - { + var actual = ((ISongProcessor)_Processor).CreateJobs( + [ CreateAnime(), - }); + ]); actual.Should().BeEmpty(); } @@ -35,39 +35,39 @@ public void CreateJobsSomeExisting_Test() new VideoSongJob(anime, anime.Songs.Single(), 480), }; - var actual = ((ISongProcessor)_Processor).CreateJobs(new[] { anime }); + var actual = ((ISongProcessor)_Processor).CreateJobs([anime]); actual.Should().BeEquivalentTo(expected); } [TestMethod] public void CreateJobsSongHasNoTimestamp_Test() { - var actual = ((ISongProcessor)_Processor).CreateJobs(new Anime[] - { - CreateAnime(createSongs: () => new Song[] - { + var actual = ((ISongProcessor)_Processor).CreateJobs( + [ + CreateAnime(createSongs: () => + [ new() { Start = TimeSpan.FromSeconds(0), }, - }), - }); + ]), + ]); actual.Should().BeEmpty(); } [TestMethod] public void CreateJobsSongIsIgnored_Test() { - var actual = ((ISongProcessor)_Processor).CreateJobs(new Anime[] - { - CreateAnime(createSongs: () => new Song[] - { + var actual = ((ISongProcessor)_Processor).CreateJobs( + [ + CreateAnime(createSongs: () => + [ new() { ShouldIgnore = true, }, - }), - }); + ]), + ]); actual.Should().BeEmpty(); } @@ -81,7 +81,7 @@ public void CreateJobsVideo360p_Test() new VideoSongJob(anime, anime.Songs.Single(), anime.VideoInfo!.Height), }; - var actual = ((ISongProcessor)_Processor).CreateJobs(new[] { anime }); + var actual = ((ISongProcessor)_Processor).CreateJobs([anime]); actual.Should().BeEquivalentTo(expected); } @@ -95,7 +95,7 @@ public void CreateJobsVideo480p_Test() new VideoSongJob(anime, anime.Songs.Single(), 480), }; - var actual = ((ISongProcessor)_Processor).CreateJobs(new[] { anime }); + var actual = ((ISongProcessor)_Processor).CreateJobs([anime]); actual.Should().BeEquivalentTo(expected); } @@ -110,30 +110,30 @@ public void CreateJobsVideo720p_Test() new VideoSongJob(anime, anime.Songs.Single(), 720), }; - var actual = ((ISongProcessor)_Processor).CreateJobs(new[] { anime }); + var actual = ((ISongProcessor)_Processor).CreateJobs([anime]); actual.Should().BeEquivalentTo(expected); } [TestMethod] public void CreateJobsVideoIsNull_Test() { - var actual = ((ISongProcessor)_Processor).CreateJobs(new Anime[] - { + var actual = ((ISongProcessor)_Processor).CreateJobs( + [ CreateAnime(createVideoInfo: () => null), - }); + ]); actual.Should().BeEmpty(); } private Anime CreateAnime(int height) { - return CreateAnime(createSongs: () => new Song[] - { + return CreateAnime(createSongs: () => + [ new() { Start = TimeSpan.FromSeconds(1), End = TimeSpan.FromSeconds(2), }, - }, createVideoInfo: () => VideoInfo with + ], createVideoInfo: () => VideoInfo with { Height = height });