Skip to content

Commit

Permalink
#12 Add setting for row order
Browse files Browse the repository at this point in the history
Adds the ability to sort the repos in the table either alphabetically or according to their last modification.
Ascending or descending order can be set as well.
  • Loading branch information
MaxAtoms committed Jan 30, 2022
1 parent 664976f commit d7b19ba
Show file tree
Hide file tree
Showing 13 changed files with 277 additions and 37 deletions.
2 changes: 2 additions & 0 deletions src/RepoStatusTable/DependencyInjection/ServiceBindings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using RepoStatusTable.Facade;
using RepoStatusTable.Model;
using RepoStatusTable.Utilities;
using RepoStatusTable.Utilities.ReposDirectory;
using RepoStatusTable.View;
using RepoStatusTable.View.SpectreConsoleFigletHeadlineView;
using RepoStatusTable.View.SpectreConsoleTableView;
Expand Down Expand Up @@ -45,6 +46,7 @@ public ServiceProviderBuilder ConfigureServices()

// Utilities
_collection.AddSingleton<IReposDirectoryUtility, ReposDirectoryUtility>();
_collection.AddSingleton<IReposOrderProvider, ReposOrderProvider>();

// Factories
_collection.AddSingleton<ISpectreFigletFactory, SpectreFigletFactory>();
Expand Down
8 changes: 8 additions & 0 deletions src/RepoStatusTable/Facade/FileSystemFacade.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ public interface IFileSystemFacade

/// <inheritdoc cref="File.ReadLines(string)" />
IEnumerable<string> ReadText( string path );

/// <inheritdoc cref="Directory.GetLastWriteTime(string)" />
DateTime GetLastWriteTime( string path );
}

public class FileSystemFacade : IFileSystemFacade
Expand Down Expand Up @@ -57,4 +60,9 @@ public IEnumerable<string> ReadText( string path )
{
return File.ReadLines( path );
}

public DateTime GetLastWriteTime( string path )
{
return Directory.GetLastWriteTime( path );
}
}
28 changes: 26 additions & 2 deletions src/RepoStatusTable/Options/RepoOptions.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
namespace RepoStatusTable.Options;

[SuppressMessage( "ReSharper", "CollectionNeverUpdated.Global" )]
[SuppressMessage( "ReSharper", "AutoPropertyCanBeMadeGetOnly.Global" )]
[SuppressMessage( "ReSharper", "UnusedAutoPropertyAccessor.Global" )]
public class RepoOptions
{
/// <summary>
Expand All @@ -16,4 +15,29 @@ public class RepoOptions
/// Each directory must contain a VSC repository
/// </remarks>
public IList<string> RepoDirs { get; set; } = new List<string>();

/// <summary>
/// Order according to which the repos should be sorted in the table
/// </summary>
/// <remarks>
/// Can be either Ascending or Descending
/// </remarks>
public RepoOrder Order { get; set; }

/// <summary>
/// Order aspect according to which the repos should be sorted in the table
/// </summary>
/// <remarks>
/// <list type="table">
/// <item>
/// <term>Alphabetically</term>
/// <description>Order repos according to the alphabet</description>
/// </item>
/// <item>
/// <term>LastModified</term>
/// <description>Order repos depending to when they were last modified</description>
/// </item>
/// </list>
/// </remarks>
public RepoOrderBy OrderBy { get; set; }
}
13 changes: 13 additions & 0 deletions src/RepoStatusTable/Utilities/ReposDirectory/RepoOrder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace RepoStatusTable.Options;

public enum RepoOrderBy
{
Alphabetically,
LastModified
}

public enum RepoOrder
{
Ascending,
Descending
}
43 changes: 43 additions & 0 deletions src/RepoStatusTable/Utilities/ReposDirectory/RepoOrderProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using RepoStatusTable.Facade;
using RepoStatusTable.Options;

namespace RepoStatusTable.Utilities.ReposDirectory;

public interface IReposOrderProvider
{
public IEnumerable<string> OrderAccordingToOptions( IEnumerable<string> directories );
}

public class ReposOrderProvider : IReposOrderProvider
{
private readonly IFileSystemFacade _fileSystemFacade;
private readonly IOptions<RepoOptions> _repoOptions;

public ReposOrderProvider( IOptions<RepoOptions> repoOptions, IFileSystemFacade fileSystemFacade )
{
_repoOptions = repoOptions;
_fileSystemFacade = fileSystemFacade;
}

public IEnumerable<string> OrderAccordingToOptions( IEnumerable<string> directories )
{
var orderFunc = GetCompareFunc();

return _repoOptions.Value.Order switch
{
RepoOrder.Ascending => directories.OrderBy( orderFunc ),
RepoOrder.Descending => directories.OrderByDescending( orderFunc ),
_ => throw new ArgumentOutOfRangeException()
};
}

private Func<string, IComparable> GetCompareFunc()
{
return _repoOptions.Value.OrderBy switch
{
RepoOrderBy.Alphabetically => d => d,
RepoOrderBy.LastModified => d => _fileSystemFacade.GetLastWriteTime( d ),
_ => throw new ArgumentOutOfRangeException()
};
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
using RepoStatusTable.Facade;
using RepoStatusTable.Options;

namespace RepoStatusTable.Utilities;
namespace RepoStatusTable.Utilities.ReposDirectory;

public class ReposDirectoryUtility : IReposDirectoryUtility
{
private readonly IFileSystemFacade _fileSystemFacade;
private readonly RepoOptions _repoOptions;
private readonly IReposOrderProvider _reposOrderProvider;
private readonly IVcsFacade _vcsFacade;

public ReposDirectoryUtility(
IOptions<RepoOptions> repoOptions,
IFileSystemFacade fileSystemFacade,
IVcsFacade vcsFacade )
IVcsFacade vcsFacade,
IReposOrderProvider reposOrderProvider )
{
_fileSystemFacade = fileSystemFacade;
_vcsFacade = vcsFacade;
_reposOrderProvider = reposOrderProvider;
_repoOptions = repoOptions.Value;
}

Expand All @@ -27,7 +30,7 @@ public IEnumerable<string> GetRepoDirectories()
repos.AddRange( GetAllDirsInRoots() );

var directories = repos.Where( d => _vcsFacade.IsVcsRepo( d ) );
return directories.OrderBy( d => d );
return _reposOrderProvider.OrderAccordingToOptions( directories );
}

private IEnumerable<string> GetAllRepoDirs()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using RepoStatusTable.Options.SpectreConsole;
using RepoStatusTable.Options.Validation;
using RepoStatusTable.Utilities;
using RepoStatusTable.Utilities.ReposDirectory;
using RepoStatusTable.View;
using RepoStatusTable.View.SpectreConsoleFigletHeadlineView;
using RepoStatusTable.View.SpectreConsoleTableView;
Expand Down Expand Up @@ -69,6 +70,7 @@ private void ConfigureRegularServices()

// Utilities
_collection.AddSingleton<IReposDirectoryUtility, ReposDirectoryUtility>();
_collection.AddSingleton<IReposOrderProvider, ReposOrderProvider>();

// Factories
_collection.AddSingleton<ISpectreFigletFactory, SpectreFigletFactory>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using Moq;
using RepoStatusTable.Facade;
Expand Down Expand Up @@ -37,4 +38,9 @@ public IEnumerable<string> ReadText( string path )
{
return InternalMock.Object.ReadText( path );
}

public DateTime GetLastWriteTime( string path )
{
return InternalMock.Object.GetLastWriteTime( path );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using RepoStatusTable.Facade;
using RepoStatusTable.Options;
using RepoStatusTable.Utilities;
using RepoStatusTable.Utilities.ReposDirectory;

namespace RepoStatusTable.UnitTests.Utilities;

Expand All @@ -17,6 +18,8 @@ public class ReposDirectoryUtilityBuilder
RepoRoots = new List<string>()
};

private readonly Mock<IReposOrderProvider> _reposOrderProvider = new(MockBehavior.Strict);

private readonly Mock<IVcsFacade> _vscFacade = new(MockBehavior.Strict);

public ReposDirectoryUtilityBuilder WithRepoOptionsRepoDir( string path )
Expand Down Expand Up @@ -55,11 +58,20 @@ public ReposDirectoryUtilityBuilder WithVscFacadeIsValid( string path, bool isVa
return this;
}

public ReposDirectoryUtilityBuilder WithReposOrderProvider( params string[] dirs )
{
_reposOrderProvider.Setup( m => m.OrderAccordingToOptions( dirs ) )
.Returns( dirs );
return this;
}

public IReposDirectoryUtility Build()
{
return new ReposDirectoryUtility( new OptionsWrapper<RepoOptions>( _repoOptions ),
_fileSystemFacade.Object,
_vscFacade.Object );
_vscFacade.Object,
_reposOrderProvider.Object
);
}

public void VerifyNoOtherCalls()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public void GetRepoDirectories_WithEmptyOptions_ShouldReturnEmptyList()
{
var builder = new ReposDirectoryUtilityBuilder();
var result = builder
.WithReposOrderProvider()
.Build()
.GetRepoDirectories();

Expand All @@ -40,7 +41,8 @@ public void GetRepoDirectories_WithValidRepoDirs_ShouldReturnDirectoryList()
.WithFileSystemFacadeDirectoryExists( RepoPathD, true )
.WithVscFacadeIsValid( RepoPathA, true )
.WithVscFacadeIsValid( RepoPathC, false )
.WithVscFacadeIsValid( RepoPathD, true );
.WithVscFacadeIsValid( RepoPathD, true )
.WithReposOrderProvider( RepoPathA, RepoPathD );

var uut = builder.Build();

Expand All @@ -67,6 +69,7 @@ public void GetRepoDirectories_WithValidRepoRoots_ShouldReturnContainingDirs()
.WithVscFacadeIsValid( "repoAB", false )
.WithVscFacadeIsValid( "repoBA", false )
.WithVscFacadeIsValid( "repoBB", true )
.WithReposOrderProvider( "repoAA", "repoBB" )
.Build();

var result = uut.GetRepoDirectories().ToList();
Expand All @@ -79,34 +82,4 @@ public void GetRepoDirectories_WithValidRepoRoots_ShouldReturnContainingDirs()

Assert.AreEqual( expected, result );
}

[Test]
public void GetRepoDirectories_WithUnorderedRepos_ShouldReturnAlphabeticalOrder()
{
var uut = new ReposDirectoryUtilityBuilder()
.WithRepoOptionsRepoDir( RepoPathD )
.WithRepoOptionsRepoDir( RepoPathA )
.WithRepoOptionsRepoDir( RepoPathB )
.WithFileSystemFacadeDirectoryExists( RepoPathD, true )
.WithFileSystemFacadeDirectoryExists( RepoPathA, true )
.WithFileSystemFacadeDirectoryExists( RepoPathB, true )
.WithFileSystemFacadeGetFullPathReturns( RepoPathB )
.WithFileSystemFacadeGetFullPathReturns( RepoPathA )
.WithFileSystemFacadeGetFullPathReturns( RepoPathD )
.WithVscFacadeIsValid( RepoPathD, true )
.WithVscFacadeIsValid( RepoPathA, true )
.WithVscFacadeIsValid( RepoPathB, true )
.Build();

var result = uut.GetRepoDirectories().ToList();

var expected = new List<string>
{
RepoPathA,
RepoPathB,
RepoPathD
};

Assert.AreEqual( expected, result );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System;
using Microsoft.Extensions.Options;
using RepoStatusTable.Facade;
using RepoStatusTable.Options;
using RepoStatusTable.Utilities.ReposDirectory;

namespace RepoStatusTable.UnitTests.Utilities;

public class ReposOrderProviderBuilder
{
private readonly Mock<IFileSystemFacade> _fileSystemFacade = new(MockBehavior.Strict);
private readonly RepoOptions _options = new();

public ReposOrderProviderBuilder WithDescendingOrder()
{
_options.Order = RepoOrder.Descending;
return this;
}

public ReposOrderProviderBuilder WithAscendingOrder()
{
_options.Order = RepoOrder.Ascending;
return this;
}

public ReposOrderProviderBuilder WithOrderByAlphabetically()
{
_options.OrderBy = RepoOrderBy.Alphabetically;
return this;
}

public ReposOrderProviderBuilder WithOrderByLastModified()
{
_options.OrderBy = RepoOrderBy.LastModified;
return this;
}

public ReposOrderProviderBuilder WithFileSystemFacadeLastWriteTimeReturns( string path, DateTime dateTime )
{
_fileSystemFacade.Setup( m => m.GetLastWriteTime( path ) )
.Returns( dateTime );
return this;
}

public ReposOrderProvider Build()
{
return new ReposOrderProvider(
new OptionsWrapper<RepoOptions>( _options ),
_fileSystemFacade.Object );
}
}
Loading

0 comments on commit d7b19ba

Please sign in to comment.