// Kyoo - A portable and vast media library solution. // Copyright (c) Kyoo. // // See AUTHORS.md and LICENSE file in the project root for full license information. // // Kyoo is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // any later version. // // Kyoo is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Kyoo. If not, see . using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using JetBrains.Annotations; using Kyoo.Abstractions.Models; using Kyoo.Abstractions.Models.Attributes; using Kyoo.Utils; using Xunit; namespace Kyoo.Tests.Utility { public class MergerTests { [Fact] public void NullifyTest() { Genre genre = new("test") { ID = 5 }; Merger.Nullify(genre); Assert.Equal(0, genre.ID); Assert.Null(genre.Name); Assert.Null(genre.Slug); } [Fact] public void MergeTest() { Genre genre = new() { ID = 5 }; Genre genre2 = new() { Name = "test" }; Genre ret = Merger.Merge(genre, genre2); Assert.True(ReferenceEquals(genre, ret)); Assert.Equal(5, ret.ID); Assert.Equal("test", genre.Name); Assert.Null(genre.Slug); } [Fact] [SuppressMessage("ReSharper", "ExpressionIsAlwaysNull")] public void MergeNullTests() { Genre genre = new() { ID = 5 }; Assert.True(ReferenceEquals(genre, Merger.Merge(genre, null))); Assert.True(ReferenceEquals(genre, Merger.Merge(null, genre))); Assert.Null(Merger.Merge(null, null)); } private class TestIOnMerge : IOnMerge { public void OnMerge(object other) { Exception exception = new(); exception.Data[0] = other; throw exception; } } [Fact] public void OnMergeTest() { TestIOnMerge test = new(); TestIOnMerge test2 = new(); Assert.Throws(() => Merger.Merge(test, test2)); try { Merger.Merge(test, test2); } catch (Exception ex) { Assert.True(ReferenceEquals(test2, ex.Data[0])); } } private class Test { public int ID { get; set; } public int[] Numbers { get; set; } } [Fact] public void GlobalMergeListTest() { Test test = new() { ID = 5, Numbers = new[] { 1 } }; Test test2 = new() { Numbers = new[] { 3 } }; Test ret = Merger.Merge(test, test2); Assert.True(ReferenceEquals(test, ret)); Assert.Equal(5, ret.ID); Assert.Equal(2, ret.Numbers.Length); Assert.Equal(1, ret.Numbers[0]); Assert.Equal(3, ret.Numbers[1]); } [Fact] public void GlobalMergeListDuplicatesTest() { Test test = new() { ID = 5, Numbers = new[] { 1 } }; Test test2 = new() { Numbers = new[] { 1, 3, 3 } }; Test ret = Merger.Merge(test, test2); Assert.True(ReferenceEquals(test, ret)); Assert.Equal(5, ret.ID); Assert.Equal(4, ret.Numbers.Length); Assert.Equal(1, ret.Numbers[0]); Assert.Equal(1, ret.Numbers[1]); Assert.Equal(3, ret.Numbers[2]); Assert.Equal(3, ret.Numbers[3]); } private class MergeDictionaryTest { public int ID { get; set; } public Dictionary Dictionary { get; set; } } [Fact] public void GlobalMergeDictionariesTest() { MergeDictionaryTest test = new() { ID = 5, Dictionary = new Dictionary { [2] = "two" } }; MergeDictionaryTest test2 = new() { Dictionary = new Dictionary { [3] = "third" } }; MergeDictionaryTest ret = Merger.Merge(test, test2); Assert.True(ReferenceEquals(test, ret)); Assert.Equal(5, ret.ID); Assert.Equal(2, ret.Dictionary.Count); Assert.Equal("two", ret.Dictionary[2]); Assert.Equal("third", ret.Dictionary[3]); } [Fact] public void GlobalMergeDictionariesDuplicatesTest() { MergeDictionaryTest test = new() { ID = 5, Dictionary = new Dictionary { [2] = "two" } }; MergeDictionaryTest test2 = new() { Dictionary = new Dictionary { [2] = "nope", [3] = "third" } }; MergeDictionaryTest ret = Merger.Merge(test, test2); Assert.True(ReferenceEquals(test, ret)); Assert.Equal(5, ret.ID); Assert.Equal(2, ret.Dictionary.Count); Assert.Equal("two", ret.Dictionary[2]); Assert.Equal("third", ret.Dictionary[3]); } [Fact] public void GlobalMergeListDuplicatesResourcesTest() { Show test = new() { ID = 5, Genres = new[] { new Genre("test") } }; Show test2 = new() { Genres = new[] { new Genre("test"), new Genre("test2") } }; Show ret = Merger.Merge(test, test2); Assert.True(ReferenceEquals(test, ret)); Assert.Equal(5, ret.ID); Assert.Equal(2, ret.Genres.Count); Assert.Equal("test", ret.Genres.ToArray()[0].Slug); Assert.Equal("test2", ret.Genres.ToArray()[1].Slug); } [Fact] public void MergeListTest() { int[] first = { 1 }; int[] second = { 3, 3 }; int[] ret = Merger.MergeLists(first, second); Assert.Equal(3, ret.Length); Assert.Equal(1, ret[0]); Assert.Equal(3, ret[1]); Assert.Equal(3, ret[2]); } [Fact] public void MergeListDuplicateTest() { int[] first = { 1 }; int[] second = { 1, 3, 3 }; int[] ret = Merger.MergeLists(first, second); Assert.Equal(4, ret.Length); Assert.Equal(1, ret[0]); Assert.Equal(1, ret[1]); Assert.Equal(3, ret[2]); Assert.Equal(3, ret[3]); } [Fact] public void MergeListDuplicateCustomEqualityTest() { int[] first = { 1 }; int[] second = { 3, 2 }; int[] ret = Merger.MergeLists(first, second, (x, y) => x % 2 == y % 2); Assert.Equal(2, ret.Length); Assert.Equal(1, ret[0]); Assert.Equal(2, ret[1]); } [Fact] public void MergeDictionariesTest() { Dictionary first = new() { [1] = "test", [5] = "value" }; Dictionary second = new() { [3] = "third", }; IDictionary ret = Merger.MergeDictionaries(first, second); Assert.Equal(3, ret.Count); Assert.Equal("test", ret[1]); Assert.Equal("value", ret[5]); Assert.Equal("third", ret[3]); } [Fact] public void MergeDictionariesDuplicateTest() { Dictionary first = new() { [1] = "test", [5] = "value" }; Dictionary second = new() { [3] = "third", [5] = "new-value", }; IDictionary ret = Merger.MergeDictionaries(first, second); Assert.Equal(3, ret.Count); Assert.Equal("test", ret[1]); Assert.Equal("value", ret[5]); Assert.Equal("third", ret[3]); } [Fact] public void CompleteTest() { Genre genre = new() { ID = 5, Name = "merged" }; Genre genre2 = new() { Name = "test" }; Genre ret = Merger.Complete(genre, genre2); Assert.True(ReferenceEquals(genre, ret)); Assert.Equal(5, ret.ID); Assert.Equal("test", genre.Name); Assert.Null(genre.Slug); } [Fact] public void CompleteDictionaryTest() { Collection collection = new() { ID = 5, Name = "merged", Images = new Dictionary { [Images.Logo] = "logo", [Images.Poster] = "poster" } }; Collection collection2 = new() { Name = "test", Images = new Dictionary { [Images.Poster] = "new-poster", [Images.Thumbnail] = "thumbnails" } }; Collection ret = Merger.Complete(collection, collection2); Assert.True(ReferenceEquals(collection, ret)); Assert.Equal(5, ret.ID); Assert.Equal("test", ret.Name); Assert.Null(ret.Slug); Assert.Equal(3, ret.Images.Count); Assert.Equal("new-poster", ret.Images[Images.Poster]); Assert.Equal("thumbnails", ret.Images[Images.Thumbnail]); Assert.Equal("logo", ret.Images[Images.Logo]); } [Fact] public void CompleteDictionaryOutParam() { Dictionary first = new() { [Images.Logo] = "logo", [Images.Poster] = "poster" }; Dictionary second = new() { [Images.Poster] = "new-poster", [Images.Thumbnail] = "thumbnails" }; IDictionary ret = Merger.CompleteDictionaries(first, second, out bool changed); Assert.True(changed); Assert.Equal(3, ret.Count); Assert.Equal("new-poster", ret[Images.Poster]); Assert.Equal("thumbnails", ret[Images.Thumbnail]); Assert.Equal("logo", ret[Images.Logo]); } [Fact] public void CompleteDictionaryEqualTest() { Dictionary first = new() { [Images.Poster] = "poster" }; Dictionary second = new() { [Images.Poster] = "new-poster", }; IDictionary ret = Merger.CompleteDictionaries(first, second, out bool changed); Assert.True(changed); Assert.Single(ret); Assert.Equal("new-poster", ret[Images.Poster]); } private class TestMergeSetter { public Dictionary Backing; [UsedImplicitly] public Dictionary Dictionary { get => Backing; set { Backing = value; KAssert.Fail(); } } } [Fact] public void CompleteDictionaryNoChangeNoSetTest() { TestMergeSetter first = new() { Backing = new Dictionary { [2] = 3 } }; TestMergeSetter second = new() { Backing = new Dictionary() }; Merger.Complete(first, second); // This should no call the setter of first so the test should pass. } [Fact] public void MergeDictionaryNoChangeNoSetTest() { TestMergeSetter first = new() { Backing = new Dictionary { [2] = 3 } }; TestMergeSetter second = new() { Backing = new Dictionary() }; Merger.Merge(first, second); // This should no call the setter of first so the test should pass. } [Fact] public void MergeDictionaryNullValue() { Dictionary first = new() { [Images.Logo] = "logo", [Images.Poster] = null }; Dictionary second = new() { [Images.Poster] = "new-poster", [Images.Thumbnail] = "thumbnails" }; IDictionary ret = Merger.MergeDictionaries(first, second, out bool changed); Assert.True(changed); Assert.Equal(3, ret.Count); Assert.Equal("new-poster", ret[Images.Poster]); Assert.Equal("thumbnails", ret[Images.Thumbnail]); Assert.Equal("logo", ret[Images.Logo]); } [Fact] public void MergeDictionaryNullValueNoChange() { Dictionary first = new() { [Images.Logo] = "logo", [Images.Poster] = null }; Dictionary second = new() { [Images.Poster] = null, }; IDictionary ret = Merger.MergeDictionaries(first, second, out bool changed); Assert.False(changed); Assert.Equal(2, ret.Count); Assert.Null(ret[Images.Poster]); Assert.Equal("logo", ret[Images.Logo]); } [Fact] public void CompleteDictionaryNullValue() { Dictionary first = new() { [Images.Logo] = "logo", [Images.Poster] = null }; Dictionary second = new() { [Images.Poster] = "new-poster", [Images.Thumbnail] = "thumbnails" }; IDictionary ret = Merger.CompleteDictionaries(first, second, out bool changed); Assert.True(changed); Assert.Equal(3, ret.Count); Assert.Equal("new-poster", ret[Images.Poster]); Assert.Equal("thumbnails", ret[Images.Thumbnail]); Assert.Equal("logo", ret[Images.Logo]); } [Fact] public void CompleteDictionaryNullValueNoChange() { Dictionary first = new() { [Images.Logo] = "logo", [Images.Poster] = null }; Dictionary second = new() { [Images.Poster] = null, }; IDictionary ret = Merger.CompleteDictionaries(first, second, out bool changed); Assert.False(changed); Assert.Equal(2, ret.Count); Assert.Null(ret[Images.Poster]); Assert.Equal("logo", ret[Images.Logo]); } } }