diff --git a/Selector.Tests/Equality.cs b/Selector.Tests/Equality.cs new file mode 100644 index 0000000..d35f88b --- /dev/null +++ b/Selector.Tests/Equality.cs @@ -0,0 +1,227 @@ +using System; +using System.Collections.Generic; +using Xunit; +using Moq; +using FluentAssertions; +using SpotifyAPI.Web; + +using Selector; + +namespace Selector.Tests +{ + public class UriEqualityTests + { + public static IEnumerable TrackData => + new List + { + // SAME + new object[] { + Helper.FullTrack("1", "1", "1"), + Helper.FullTrack("1", "1", "1"), + true, + true + }, + // WRONG ALBUM BUT IGNORING + new object[] { + Helper.FullTrack("1", "1", "1"), + Helper.FullTrack("1", "2", "1"), + false, + true + }, + // WRONG TRACK + new object[] { + Helper.FullTrack("1", "1", "1"), + Helper.FullTrack("2", "1", "1"), + true, + false + }, + // WRONG ARTIST + new object[] { + Helper.FullTrack("1", "1", "1"), + Helper.FullTrack("1", "1", "2"), + true, + false + }, + // WRONG TRACK/ARTIST + new object[] { + Helper.FullTrack("1", "1", "1"), + Helper.FullTrack("2", "1", "2"), + true, + false + }, + // RIGHT MULTIPLE ARTISTS + new object[] { + Helper.FullTrack("1", "1", new List() { "1", "2" }), + Helper.FullTrack("1", "1", new List() { "1", "2" }), + true, + true + }, + // WRONG ARTISTS + new object[] { + Helper.FullTrack("1", "1", new List() { "1", "2" }), + Helper.FullTrack("1", "1", new List() { "1" }), + true, + false + } + }; + + [Theory] + [MemberData(nameof(TrackData))] + public void TrackEquality(FullTrack track1, FullTrack track2, bool includingAlbum, bool shouldEqual) + { + var eq = new UriEquality(); + eq.Track(track1, track2, includingAlbum: includingAlbum).Should().Be(shouldEqual); + } + + public static IEnumerable AlbumData => + new List + { + // SAME + new object[] { + Helper.SimpleAlbum("1", "1"), + Helper.SimpleAlbum("1", "1"), + true + }, + // DIFFERENT NAME + new object[] { + Helper.SimpleAlbum("1", "1"), + Helper.SimpleAlbum("2", "1"), + false + }, + // DIFFERENT ARTIST + new object[] { + Helper.SimpleAlbum("1", "1"), + Helper.SimpleAlbum("1", "2"), + false + }, + // SAME ARTISTS + new object[] { + Helper.SimpleAlbum("1", new List() { "1", "2" }), + Helper.SimpleAlbum("1", new List() { "1", "2" }), + true + }, + // DIFFERENT ARTISTS + new object[] { + Helper.SimpleAlbum("1", new List() { "1", "2" }), + Helper.SimpleAlbum("1", new List() { "1" }), + false + }, + }; + + [Theory] + [MemberData(nameof(AlbumData))] + public void AlbumEquality(SimpleAlbum album1, SimpleAlbum album2, bool shouldEqual) + { + var eq = new UriEquality(); + eq.Album(album1, album2).Should().Be(shouldEqual); + } + } + + public class StringEqualityTests + { + public static IEnumerable TrackData => + new List + { + // SAME + new object[] { + Helper.FullTrack("1", "1", "1"), + Helper.FullTrack("1", "1", "1"), + true, + true + }, + // WRONG ALBUM BUT IGNORING + new object[] { + Helper.FullTrack("1", "1", "1"), + Helper.FullTrack("1", "2", "1"), + false, + true + }, + // WRONG TRACK + new object[] { + Helper.FullTrack("1", "1", "1"), + Helper.FullTrack("2", "1", "1"), + true, + false + }, + // WRONG ARTIST + new object[] { + Helper.FullTrack("1", "1", "1"), + Helper.FullTrack("1", "1", "2"), + true, + false + }, + // WRONG TRACK/ARTIST + new object[] { + Helper.FullTrack("1", "1", "1"), + Helper.FullTrack("2", "1", "2"), + true, + false + }, + // RIGHT MULTIPLE ARTISTS + new object[] { + Helper.FullTrack("1", "1", new List() { "1", "2" }), + Helper.FullTrack("1", "1", new List() { "1", "2" }), + true, + true + }, + // WRONG ARTISTS + new object[] { + Helper.FullTrack("1", "1", new List() { "1", "2" }), + Helper.FullTrack("1", "1", new List() { "1" }), + true, + false + } + }; + + [Theory] + [MemberData(nameof(TrackData))] + public void TrackEquality(FullTrack track1, FullTrack track2, bool includingAlbum, bool shouldEqual) + { + var eq = new StringEquality(); + eq.Track(track1, track2, includingAlbum: includingAlbum).Should().Be(shouldEqual); + } + + public static IEnumerable AlbumData => + new List + { + // SAME + new object[] { + Helper.SimpleAlbum("1", "1"), + Helper.SimpleAlbum("1", "1"), + true + }, + // DIFFERENT NAME + new object[] { + Helper.SimpleAlbum("1", "1"), + Helper.SimpleAlbum("2", "1"), + false + }, + // DIFFERENT ARTIST + new object[] { + Helper.SimpleAlbum("1", "1"), + Helper.SimpleAlbum("1", "2"), + false + }, + // SAME ARTISTS + new object[] { + Helper.SimpleAlbum("1", new List() { "1", "2" }), + Helper.SimpleAlbum("1", new List() { "1", "2" }), + true + }, + // DIFFERENT ARTISTS + new object[] { + Helper.SimpleAlbum("1", new List() { "1", "2" }), + Helper.SimpleAlbum("1", new List() { "1" }), + false + }, + }; + + [Theory] + [MemberData(nameof(AlbumData))] + public void AlbumEquality(SimpleAlbum album1, SimpleAlbum album2, bool shouldEqual) + { + var eq = new StringEquality(); + eq.Album(album1, album2).Should().Be(shouldEqual); + } + } +} diff --git a/Selector.Tests/Helper.cs b/Selector.Tests/Helper.cs new file mode 100644 index 0000000..85d0031 --- /dev/null +++ b/Selector.Tests/Helper.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using SpotifyAPI.Web; + +namespace Selector.Tests +{ + static class Helper + { + public static FullTrack FullTrack(string name, string album, List artists) + { + return new FullTrack() + { + Name = name, + Uri = name, + Album = SimpleAlbum(album, artists), + Artists = artists.Select(a => SimpleArtist(a)).ToList() + }; + } + + public static FullTrack FullTrack(string name, string album, string artist) + { + return FullTrack(name, album, new List() { artist }); + } + + public static SimpleAlbum SimpleAlbum(string name, List artists) + { + return new SimpleAlbum() + { + Name = name, + Uri = name, + Artists = artists.Select(a => SimpleArtist(a)).ToList() + }; + } + + public static SimpleAlbum SimpleAlbum(string name, string artist) + { + return SimpleAlbum(name, new List() { artist }); + } + + public static SimpleArtist SimpleArtist(string name) + { + return new SimpleArtist() + { + Name = name, + Uri = name + }; + } + } +} diff --git a/Selector.Tests/PlayerWatcher.cs b/Selector.Tests/PlayerWatcher.cs new file mode 100644 index 0000000..e314c3d --- /dev/null +++ b/Selector.Tests/PlayerWatcher.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using Xunit; +using Moq; +using FluentAssertions; +using SpotifyAPI.Web; + +using Selector; + +namespace Selector.Tests +{ + public class PlayerWatcherTests + { + //public static IEnumerable TrackData => + //new List + //{ + // new object[] { new List(){ + // new CurrentlyPlaying(){ + // Item = new FullTrack() { + + // } + // } + // }, 1 } + //}; + + //[Theory] + //[MemberData(nameof(TrackData))] + //public void Test1(List playing) + //{ + // var spotMock = new Mock(); + // // spotMock.Setup(spot => spot.GetCurrentlyPlaying(It.IsAny())).Returns(); + // // var watch = new Watcher(); + //} + + // [Fact] + // public void Test2() + // { + // var artist = new SimpleArtist(){ + // Name = "test" + // }; + // var track = new FullTrack() { + // Name = "Test", + // Album = new SimpleAlbum() { + // Name = "test", + // Artists = new List(){ + // artist + // } + // }, + // Artists = new List(){ + // artist + // } + // }; + + // var track2 = new FullTrack() { + // Name = "Test", + // Album = new SimpleAlbum() { + // Name = "test", + // Artists = new List(){ + // artist + // } + // }, + // Artists = new List(){ + // artist + // } + // }; + + // track.Should().Be(track2); + // } + } +} diff --git a/Selector.Tests/Selector.Tests.csproj b/Selector.Tests/Selector.Tests.csproj index 6a6a2ad..38a4b1d 100644 --- a/Selector.Tests/Selector.Tests.csproj +++ b/Selector.Tests/Selector.Tests.csproj @@ -7,7 +7,9 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Selector.Tests/UnitTest1.cs b/Selector.Tests/UnitTest1.cs deleted file mode 100644 index 0c526f0..0000000 --- a/Selector.Tests/UnitTest1.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using Xunit; - -using Selector; - -namespace Selector.Tests -{ - public class UnitTest1 - { - [Fact] - public void Test1() - { - // var watch = new Watcher(); - } - } -} diff --git a/Selector/Equality/IEqualityChecker.cs b/Selector/Equality/IEqualityChecker.cs new file mode 100644 index 0000000..78c85ce --- /dev/null +++ b/Selector/Equality/IEqualityChecker.cs @@ -0,0 +1,18 @@ +using System; +using SpotifyAPI.Web; + +namespace Selector { + + public interface IEqualityChecker { + public bool Track(FullTrack track1, FullTrack track2, bool includingAlbum); + public bool Album(FullAlbum album1, FullAlbum album2); + public bool Artist(FullArtist artist1, FullArtist artist2); + + public bool Track(SimpleTrack track1, SimpleTrack track2); + public bool Album(SimpleAlbum album1, SimpleAlbum album2); + public bool Artist(SimpleArtist artist1, SimpleArtist artist2); + + public bool Context(Context context1, Context context2); + public bool Device(Device device1, Device device2); + } +} \ No newline at end of file diff --git a/Selector/Equality/StringEquality.cs b/Selector/Equality/StringEquality.cs new file mode 100644 index 0000000..456b8c3 --- /dev/null +++ b/Selector/Equality/StringEquality.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using SpotifyAPI.Web; + +namespace Selector { + + public class StringEquality: UriEquality { + + new public bool Track(FullTrack track1, FullTrack track2, bool includingAlbum = true) + { + var ret = includingAlbum ? Album(track1.Album, track2.Album): true; + + return ret + && track1.Name == track2.Name + && Enumerable.SequenceEqual(track1.Artists.Select(a => a.Name), track2.Artists.Select(a => a.Name)); + } + new public bool Album(FullAlbum album1, FullAlbum album2) + { + return album1.Name == album1.Name + && Enumerable.SequenceEqual(album1.Artists.Select(a => a.Name), album2.Artists.Select(a => a.Name)); + } + new public bool Artist(FullArtist artist1, FullArtist artist2) + { + return artist1.Name == artist2.Name; + } + + new public bool Track(SimpleTrack track1, SimpleTrack track2) + { + return track1.Name == track2.Name + && Enumerable.SequenceEqual(track1.Artists.Select(a => a.Name), track2.Artists.Select(a => a.Name)); + } + new public bool Album(SimpleAlbum album1, SimpleAlbum album2) + { + return album1.Name == album1.Name + && Enumerable.SequenceEqual(album1.Artists.Select(a => a.Name), album2.Artists.Select(a => a.Name)); + } + new public bool Artist(SimpleArtist artist1, SimpleArtist artist2) + { + return artist1.Name == artist2.Name; + } + } +} \ No newline at end of file diff --git a/Selector/Equality/UriEquality.cs b/Selector/Equality/UriEquality.cs new file mode 100644 index 0000000..dd5db27 --- /dev/null +++ b/Selector/Equality/UriEquality.cs @@ -0,0 +1,50 @@ +using System; +using System.Linq; +using SpotifyAPI.Web; + +namespace Selector { + + public class UriEquality: IEqualityChecker { + public bool Track(FullTrack track1, FullTrack track2, bool includingAlbum = true) + { + var ret = includingAlbum ? Album(track1.Album, track2.Album) : true; + + return ret + && track1.Uri == track2.Uri + && Enumerable.SequenceEqual(track1.Artists.Select(a => a.Uri), track2.Artists.Select(a => a.Uri)); + } + public bool Album(FullAlbum album1, FullAlbum album2) + { + return album1.Uri == album2.Uri + && Enumerable.SequenceEqual(album1.Artists.Select(a => a.Uri), album2.Artists.Select(a => a.Uri)); + } + public bool Artist(FullArtist artist1, FullArtist artist2) + { + return artist1.Uri == artist2.Uri; + } + + public bool Track(SimpleTrack track1, SimpleTrack track2) + { + return track1.Uri == track2.Uri + && Enumerable.SequenceEqual(track1.Artists.Select(a => a.Uri), track2.Artists.Select(a => a.Uri)); + } + public bool Album(SimpleAlbum album1, SimpleAlbum album2) + { + return album1.Uri == album2.Uri + && Enumerable.SequenceEqual(album1.Artists.Select(a => a.Uri), album2.Artists.Select(a => a.Uri)); + } + public bool Artist(SimpleArtist artist1, SimpleArtist artist2) + { + return artist1.Uri == artist2.Uri; + } + + public bool Context(Context context1, Context context2) + { + return context1.Uri == context2.Uri; + } + public bool Device(Device device1, Device device2) + { + return device1.Id == device2.Id; + } + } +} \ No newline at end of file diff --git a/Selector/Watcher.cs b/Selector/Watcher.cs deleted file mode 100644 index 15116cc..0000000 --- a/Selector/Watcher.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using SpotifyAPI.Web; - -namespace Selector -{ - public class Watcher - { - private readonly IPlayerClient spotifyClient; - - public Watcher(IPlayerClient spotifyClient) { - this.spotifyClient = spotifyClient; - } - } -} diff --git a/Selector/Watcher/Interfaces/Events.cs b/Selector/Watcher/Interfaces/Events.cs new file mode 100644 index 0000000..a6df283 --- /dev/null +++ b/Selector/Watcher/Interfaces/Events.cs @@ -0,0 +1,10 @@ +using System; +using SpotifyAPI.Web; + +namespace Selector +{ + public class ListeningChangeEventArgs: EventArgs { + public CurrentlyPlaying Previous; + public CurrentlyPlaying Current; + } +} diff --git a/Selector/Watcher/Interfaces/IPlayerWatcher.cs b/Selector/Watcher/Interfaces/IPlayerWatcher.cs new file mode 100644 index 0000000..65c776b --- /dev/null +++ b/Selector/Watcher/Interfaces/IPlayerWatcher.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using SpotifyAPI.Web; + +namespace Selector +{ + public interface IPlayerWatcher: IWatcher + { + public event EventHandler TrackChange; + public event EventHandler AlbumChange; + public event EventHandler ArtistChange; + public event EventHandler ContextChange; + + public event EventHandler VolumeChange; + public event EventHandler DeviceChange; + + public CurrentlyPlaying NowPlaying(); + // recently playing + } +} diff --git a/Selector/Watcher/Interfaces/IWatchScheduler.cs b/Selector/Watcher/Interfaces/IWatchScheduler.cs new file mode 100644 index 0000000..6f69740 --- /dev/null +++ b/Selector/Watcher/Interfaces/IWatchScheduler.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Selector +{ + public interface IScheduler + { + public int SleepTime(); + } +} diff --git a/Selector/Watcher/Interfaces/IWatcher.cs b/Selector/Watcher/Interfaces/IWatcher.cs new file mode 100644 index 0000000..d1bbc3e --- /dev/null +++ b/Selector/Watcher/Interfaces/IWatcher.cs @@ -0,0 +1,13 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using SpotifyAPI.Web; + +namespace Selector +{ + public interface IWatcher + { + public Task WatchOne(); + public Task Watch(CancellationToken cancelToken); + } +} diff --git a/Selector/Watcher/PlayerWatcher.cs b/Selector/Watcher/PlayerWatcher.cs new file mode 100644 index 0000000..3c954df --- /dev/null +++ b/Selector/Watcher/PlayerWatcher.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using SpotifyAPI.Web; + +namespace Selector +{ + public class PlayerWatcher: IPlayerWatcher + { + private readonly IPlayerClient spotifyClient; + private IScheduler sleepScheduler; + private IEqualityChecker equalityChecker; + + public event EventHandler TrackChange; + public event EventHandler AlbumChange; + public event EventHandler ArtistChange; + public event EventHandler ContextChange; + + public event EventHandler VolumeChange; + public event EventHandler DeviceChange; + + private CurrentlyPlaying live { get; set; } + //public List LastPlays { get; private set; } + + public PlayerWatcher(IPlayerClient spotifyClient, IScheduler sleepScheduler, IEqualityChecker equalityChecker) { + this.spotifyClient = spotifyClient; + this.sleepScheduler = sleepScheduler; + this.equalityChecker = equalityChecker; + } + + public async Task WatchOne() + { + + } + + public Task Watch(CancellationToken cancelToken) + { + return Task.CompletedTask; + } + + public CurrentlyPlaying NowPlaying() + { + throw new NotImplementedException(); + } + + protected virtual void OnTrackChange(ListeningChangeEventArgs args) + { + TrackChange?.Invoke(this, args); + } + + protected virtual void OnAlbumChange(ListeningChangeEventArgs args) + { + AlbumChange?.Invoke(this, args); + } + + protected virtual void OnArtistChange(ListeningChangeEventArgs args) + { + ArtistChange?.Invoke(this, args); + } + + protected virtual void OnContextChange(ListeningChangeEventArgs args) + { + ContextChange?.Invoke(this, args); + } + + + protected virtual void OnVolumeChange(ListeningChangeEventArgs args) + { + ArtistChange?.Invoke(this, args); + } + + protected virtual void OnDeviceChange(ListeningChangeEventArgs args) + { + ContextChange?.Invoke(this, args); + } + } +}