Skip to content

Commit

Permalink
Add comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Kai Yang committed May 19, 2015
1 parent 43cccdd commit 8659e68
Show file tree
Hide file tree
Showing 30 changed files with 978 additions and 70 deletions.
8 changes: 4 additions & 4 deletions Kfstorm.DoubanFM.Core.UnitTest/ServerConnectionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public async void TestServerException_Get()
responseMock.Setup(r => r.GetResponseStream()).Returns(new MemoryStream(Encoding.UTF8.GetBytes(Resource.ErrorResponseSample)));
serverConnection.Protected().Setup<HttpWebRequest>("CreateRequest", ItExpr.IsAny<Uri>()).Returns(requestMock.Object);

var ex = await AssertEx.ThrowsAsync<ServerException>(async () => await serverConnection.Object.Get(new Uri("http://anyUri.com")));
var ex = await AssertEx.ThrowsAsync<ServerException>(async () => await serverConnection.Object.Get(new Uri("http://anyUri.com"), null));
Assert.IsNotNull(ex);
Assert.AreEqual(123, ex.Code);
Assert.IsNotEmpty(ex.ErrorMessage);
Expand All @@ -53,7 +53,7 @@ public async void TestServerException_Get_OldApi()
responseMock.Setup(r => r.GetResponseStream()).Returns(new MemoryStream(Encoding.UTF8.GetBytes(Resource.ErrorResponseSample_OldApi)));
serverConnection.Protected().Setup<HttpWebRequest>("CreateRequest", ItExpr.IsAny<Uri>()).Returns(requestMock.Object);

var ex = await AssertEx.ThrowsAsync<ServerException>(async () => await serverConnection.Object.Get(new Uri("http://anyUri.com")));
var ex = await AssertEx.ThrowsAsync<ServerException>(async () => await serverConnection.Object.Get(new Uri("http://anyUri.com"), null));
Assert.IsNotNull(ex);
Assert.AreEqual(123, ex.Code);
Assert.IsNotEmpty(ex.ErrorMessage);
Expand All @@ -69,7 +69,7 @@ public async void TestServerException_Post()
responseMock.Setup(r => r.GetResponseStream()).Returns(new MemoryStream(Encoding.UTF8.GetBytes(Resource.ErrorResponseSample)));
serverConnection.Protected().Setup<HttpWebRequest>("CreateRequest", ItExpr.IsAny<Uri>()).Returns(requestMock.Object);

var ex = await AssertEx.ThrowsAsync<ServerException>(async () => await serverConnection.Object.Get(new Uri("http://anyUri.com")));
var ex = await AssertEx.ThrowsAsync<ServerException>(async () => await serverConnection.Object.Get(new Uri("http://anyUri.com"), null));
Assert.IsNotNull(ex);
Assert.AreEqual(123, ex.Code);
Assert.IsNotEmpty(ex.ErrorMessage);
Expand All @@ -85,7 +85,7 @@ public async void TestServerException_Post_OldApi()
responseMock.Setup(r => r.GetResponseStream()).Returns(new MemoryStream(Encoding.UTF8.GetBytes(Resource.ErrorResponseSample_OldApi)));
serverConnection.Protected().Setup<HttpWebRequest>("CreateRequest", ItExpr.IsAny<Uri>()).Returns(requestMock.Object);

var ex = await AssertEx.ThrowsAsync<ServerException>(async () => await serverConnection.Object.Get(new Uri("http://anyUri.com")));
var ex = await AssertEx.ThrowsAsync<ServerException>(async () => await serverConnection.Object.Get(new Uri("http://anyUri.com"), null));
Assert.IsNotNull(ex);
Assert.AreEqual(123, ex.Code);
Assert.IsNotEmpty(ex.ErrorMessage);
Expand Down
30 changes: 30 additions & 0 deletions Kfstorm.DoubanFM.Core/AuthenticationBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,42 @@

namespace Kfstorm.DoubanFM.Core
{
/// <summary>
/// A abstract base class for all implementations of <see cref="IAuthentication" /> interface
/// </summary>
public abstract class AuthenticationBase : IAuthentication
{
/// <summary>
/// Gets the logger.
/// </summary>
/// <value>
/// The logger.
/// </value>
protected ILog Logger { get; }

/// <summary>
/// Initializes a new instance of the <see cref="AuthenticationBase"/> class.
/// </summary>
/// <param name="serverConnection">The server connection.</param>
protected AuthenticationBase(IServerConnection serverConnection)
{
ServerConnection = serverConnection;
Logger = LogManager.GetLogger(GetType());
}

/// <summary>
/// Gets the server connection.
/// </summary>
/// <value>
/// The server connection.
/// </value>
protected IServerConnection ServerConnection { get; }

/// <summary>
/// Parses the result of logging on.
/// </summary>
/// <param name="jsonContent">Content of JSON format.</param>
/// <returns>The user information in the result.</returns>
protected UserInfo ParseLogOnResult(string jsonContent)
{
var obj = JObject.Parse(jsonContent);
Expand All @@ -29,6 +53,12 @@ protected UserInfo ParseLogOnResult(string jsonContent)
};
}

/// <summary>
/// Authenticates and returns user info.
/// </summary>
/// <returns>
/// The user info, including username and token.
/// </returns>
public abstract Task<UserInfo> Authenticate();
}
}
37 changes: 37 additions & 0 deletions Kfstorm.DoubanFM.Core/Channel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@

namespace Kfstorm.DoubanFM.Core
{
/// <summary>
/// An instance of Channel class indicates a channel in douban.fm. A channel usually contains a lot of songs.
/// </summary>
public class Channel : IEquatable<Channel>
{
/// <summary>
/// Initializes a new instance of the <see cref="Channel"/> class.
/// </summary>
/// <param name="id">The channel ID.</param>
public Channel(int id)
{
Id = id;
Expand All @@ -19,14 +26,44 @@ public override int GetHashCode()
return Id;
}

/// <summary>
/// Gets or sets the name of the channel.
/// </summary>
/// <value>
/// The name.
/// </value>
public string Name { get; set; }

/// <summary>
/// Gets or sets the description of the channel.
/// </summary>
/// <value>
/// The description.
/// </value>
public string Description { get; set; }

/// <summary>
/// Gets the ID of the channel.
/// </summary>
/// <value>
/// The ID.
/// </value>
public int Id { get; }

/// <summary>
/// Gets or sets the song count of the channel.
/// </summary>
/// <value>
/// The song count.
/// </value>
public int SongCount { get; set; }

/// <summary>
/// Gets or sets the cover URL of the channel.
/// </summary>
/// <value>
/// The cover URL.
/// </value>
public string CoverUrl { get; set; }

public override bool Equals(object obj)
Expand Down
21 changes: 21 additions & 0 deletions Kfstorm.DoubanFM.Core/ChannelGroup.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
namespace Kfstorm.DoubanFM.Core
{
/// <summary>
/// Represents a group of channels
/// </summary>
public class ChannelGroup
{
/// <summary>
/// Gets the ID of the group.
/// </summary>
/// <value>
/// The ID of the group.
/// </value>
public int GroupId { get; internal set; }
/// <summary>
/// Gets the name of the group.
/// </summary>
/// <value>
/// The name of the group.
/// </value>
public string GroupName { get; internal set; }
/// <summary>
/// Gets the channels.
/// </summary>
/// <value>
/// The channels.
/// </value>
public Channel[] Channels { get; internal set; }
}
}
9 changes: 9 additions & 0 deletions Kfstorm.DoubanFM.Core/ChannelList.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
namespace Kfstorm.DoubanFM.Core
{
/// <summary>
/// Represents a list of channels, including many channel groups.
/// </summary>
public class ChannelList
{
/// <summary>
/// Gets the channel groups.
/// </summary>
/// <value>
/// The channel groups.
/// </value>
public ChannelGroup[] ChannelGroups { get; internal set; }
}
}
3 changes: 3 additions & 0 deletions Kfstorm.DoubanFM.Core/ChannelNotSelectedException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace Kfstorm.DoubanFM.Core
{
/// <summary>
/// This type of exception will be thrown when some operations which need a selected channel are triggerred but the current channel of the player is not selected.
/// </summary>
public class ChannelNotSelectedException : Exception
{
}
Expand Down
4 changes: 4 additions & 0 deletions Kfstorm.DoubanFM.Core/EventArgs{T}.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

namespace Kfstorm.DoubanFM.Core
{
/// <summary>
/// A simple subclass of EventArgs which contains single data object.
/// </summary>
/// <typeparam name="T">The type of data object.</typeparam>
public class EventArgs<T> : EventArgs
{
public T Object { get; set; }
Expand Down
18 changes: 18 additions & 0 deletions Kfstorm.DoubanFM.Core/ExceptionHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,18 @@

namespace Kfstorm.DoubanFM.Core
{
/// <summary>
/// A helper class of exception
/// </summary>
public static class ExceptionHelper
{
/// <summary>
/// Logs the exception if the action throws any.
/// </summary>
/// <param name="logger">The logger.</param>
/// <param name="action">The action.</param>
/// <param name="message">The log message.</param>
/// <returns></returns>
public static async Task LogExceptionIfAny(ILog logger, Func<Task> action, string message = null)
{
try
Expand All @@ -19,6 +29,14 @@ public static async Task LogExceptionIfAny(ILog logger, Func<Task> action, strin
}
}

/// <summary>
/// Logs the exception if the action throws any.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="logger">The logger.</param>
/// <param name="action">The action.</param>
/// <param name="message">The log message.</param>
/// <returns></returns>
public static async Task<T> LogExceptionIfAny<T>(ILog logger, Func<Task<T>> action, string message = null)
{
try
Expand Down
7 changes: 7 additions & 0 deletions Kfstorm.DoubanFM.Core/IAuthentication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@

namespace Kfstorm.DoubanFM.Core
{
/// <summary>
/// Indicates a method of user authentication
/// </summary>
public interface IAuthentication
{
/// <summary>
/// Authenticates and returns user info.
/// </summary>
/// <returns>The user info, including username and token.</returns>
Task<UserInfo> Authenticate();
}
}
71 changes: 71 additions & 0 deletions Kfstorm.DoubanFM.Core/IPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,92 @@

namespace Kfstorm.DoubanFM.Core
{
/// <summary>
/// Controls playing logic, including channel/song switch and red heart marking.
/// </summary>
public interface IPlayer
{
/// <summary>
/// Gets the session.
/// </summary>
/// <value>
/// The session.
/// </value>
ISession Session { get; }
/// <summary>
/// Gets the server connection.
/// </summary>
/// <value>
/// The server connection.
/// </value>
IServerConnection ServerConnection { get; }
/// <summary>
/// Gets the current song.
/// </summary>
/// <value>
/// The current song.
/// </value>
Song CurrentSong { get; }
/// <summary>
/// Gets the channel list.
/// </summary>
/// <value>
/// The channel list.
/// </value>
/// <remarks>
/// The channel list is a collection of sample channels, organized by groups.
/// </remarks>
ChannelList ChannelList { get; }
/// <summary>
/// Gets the current channel.
/// </summary>
/// <value>
/// The current channel.
/// </value>
Channel CurrentChannel { get; }
/// <summary>
/// Gets the configuration.
/// </summary>
/// <value>
/// The configuration.
/// </value>
/// <remarks>
/// The configuration stores information needed by player. Such as music format and bit rate, which will be used when communiating with server.
/// </remarks>
IDictionary<string, object> Config { get; }

/// <summary>
/// Occurs when current song changed.
/// </summary>
event EventHandler<EventArgs<Song>> CurrentSongChanged;
/// <summary>
/// Occurs when current channel changed.
/// </summary>
event EventHandler<EventArgs<Channel>> CurrentChannelChanged;

/// <summary>
/// Refreshes the channel list.
/// </summary>
/// <returns></returns>
Task RefreshChannelList();
/// <summary>
/// Changes the channel.
/// </summary>
/// <param name="newChannel">The new channel.</param>
/// <returns></returns>
Task ChangeChannel(Channel newChannel);
/// <summary>
/// Switch to next song.
/// </summary>
/// <param name="type">the type of next operation.</param>
/// <returns></returns>
Task Next(NextCommandType type);
/// <summary>
/// Sets the red heart.
/// </summary>
/// <param name="redHeart">if set to <c>true</c> then current song will be marked with red heart, indicating that user likes this song. Otherwise remove the red heart mark.</param>
/// <returns></returns>
/// <remarks>Set redHeart to false doesn't means user dislike current song.</remarks>
Task SetRedHeart(bool redHeart);
}
}
Loading

0 comments on commit 8659e68

Please sign in to comment.