Skip to content

Commit

Permalink
feat: make statistic interfaces generic (#545)
Browse files Browse the repository at this point in the history
* Make statistic interfaces generic to reflect the stored data.
* Accept API changes
  • Loading branch information
vbreuss authored Apr 1, 2024
1 parent 6e4d75c commit 284f0cc
Show file tree
Hide file tree
Showing 17 changed files with 139 additions and 110 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Testably.Abstractions.Testing.Statistics;

internal class CallStatistics : IStatistics
internal class CallStatistics<TType> : IStatistics<TType>
{
private readonly ConcurrentQueue<MethodStatistic> _methods = new();
private readonly string _name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,54 +13,64 @@ internal sealed class FileSystemStatistics : IFileSystemStatistics, IStatisticsG
/// </summary>
public int TotalCount => _counter;

internal readonly CallStatistics Directory;
internal readonly PathStatistics DirectoryInfo;
internal readonly PathStatistics DriveInfo;
internal readonly CallStatistics File;
internal readonly PathStatistics FileInfo;
internal readonly PathStatistics FileStream;
internal readonly PathStatistics FileSystemWatcher;
internal readonly CallStatistics Path;
internal readonly CallStatistics<IDirectory> Directory;
internal readonly PathStatistics<IDirectoryInfoFactory, IDirectoryInfo> DirectoryInfo;
internal readonly PathStatistics<IDriveInfoFactory, IDriveInfo> DriveInfo;
internal readonly CallStatistics<IFile> File;
internal readonly PathStatistics<IFileInfoFactory, IFileInfo> FileInfo;
internal readonly PathStatistics<IFileStreamFactory, FileSystemStream> FileStream;

internal readonly PathStatistics<IFileSystemWatcherFactory, IFileSystemWatcher>
FileSystemWatcher;

internal readonly CallStatistics<IPath> Path;
private int _counter;

public FileSystemStatistics(MockFileSystem fileSystem)
{
DirectoryInfo = new PathStatistics(this, fileSystem, nameof(IFileSystem.DirectoryInfo));
DriveInfo = new PathStatistics(this, fileSystem, nameof(IFileSystem.DriveInfo));
FileInfo = new PathStatistics(this, fileSystem, nameof(IFileSystem.FileInfo));
FileStream = new PathStatistics(this, fileSystem, nameof(IFileSystem.FileStream));
FileSystemWatcher =
new PathStatistics(this, fileSystem, nameof(IFileSystem.FileSystemWatcher));
File = new CallStatistics(this, nameof(IFileSystem.File));
Directory = new CallStatistics(this, nameof(IFileSystem.Directory));
Path = new CallStatistics(this, nameof(IFileSystem.Path));
Directory = new CallStatistics<IDirectory>(this, nameof(IFileSystem.Directory));
DirectoryInfo = new PathStatistics<IDirectoryInfoFactory, IDirectoryInfo>(
this, fileSystem, nameof(IFileSystem.DirectoryInfo));
DriveInfo = new PathStatistics<IDriveInfoFactory, IDriveInfo>(
this, fileSystem, nameof(IFileSystem.DriveInfo));
File = new CallStatistics<IFile>(this, nameof(IFileSystem.File));
FileInfo = new PathStatistics<IFileInfoFactory, IFileInfo>(
this, fileSystem, nameof(IFileSystem.FileInfo));
FileStream = new PathStatistics<IFileStreamFactory, FileSystemStream>(
this, fileSystem, nameof(IFileSystem.FileStream));
FileSystemWatcher = new PathStatistics<IFileSystemWatcherFactory, IFileSystemWatcher>(
this, fileSystem, nameof(IFileSystem.FileSystemWatcher));
Path = new CallStatistics<IPath>(this, nameof(IFileSystem.Path));
}

#region IFileSystemStatistics Members

/// <inheritdoc cref="IFileSystemStatistics.Directory" />
IStatistics IFileSystemStatistics.Directory => Directory;
IStatistics<IDirectory> IFileSystemStatistics.Directory => Directory;

/// <inheritdoc cref="IFileSystemStatistics.DirectoryInfo" />
IPathStatistics IFileSystemStatistics.DirectoryInfo => DirectoryInfo;
IPathStatistics<IDirectoryInfoFactory, IDirectoryInfo> IFileSystemStatistics.DirectoryInfo
=> DirectoryInfo;

/// <inheritdoc cref="IFileSystemStatistics.DriveInfo" />
IPathStatistics IFileSystemStatistics.DriveInfo => DriveInfo;
IPathStatistics<IDriveInfoFactory, IDriveInfo> IFileSystemStatistics.DriveInfo => DriveInfo;

/// <inheritdoc cref="IFileSystemStatistics.File" />
IStatistics IFileSystemStatistics.File => File;
IStatistics<IFile> IFileSystemStatistics.File => File;

/// <inheritdoc cref="IFileSystemStatistics.FileInfo" />
IPathStatistics IFileSystemStatistics.FileInfo => FileInfo;
IPathStatistics<IFileInfoFactory, IFileInfo> IFileSystemStatistics.FileInfo => FileInfo;

/// <inheritdoc cref="IFileSystemStatistics.FileStream" />
IPathStatistics IFileSystemStatistics.FileStream => FileStream;
IPathStatistics<IFileStreamFactory, FileSystemStream> IFileSystemStatistics.FileStream
=> FileStream;

/// <inheritdoc cref="IFileSystemStatistics.FileSystemWatcher" />
IPathStatistics IFileSystemStatistics.FileSystemWatcher => FileSystemWatcher;
IPathStatistics<IFileSystemWatcherFactory, IFileSystemWatcher> IFileSystemStatistics.
FileSystemWatcher => FileSystemWatcher;

/// <inheritdoc cref="IFileSystemStatistics.Path" />
IStatistics IFileSystemStatistics.Path => Path;
IStatistics<IPath> IFileSystemStatistics.Path => Path;

#endregion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,40 @@ public interface IFileSystemStatistics
/// <summary>
/// Statistical information about calls to <see cref="IFileSystem.Directory" />.
/// </summary>
IStatistics Directory { get; }
IStatistics<IDirectory> Directory { get; }

/// <summary>
/// Statistical information about calls to <see cref="IFileSystem.DirectoryInfo" />.
/// </summary>
IPathStatistics DirectoryInfo { get; }
IPathStatistics<IDirectoryInfoFactory, IDirectoryInfo> DirectoryInfo { get; }

/// <summary>
/// Statistical information about calls to <see cref="IFileSystem.DriveInfo" />.
/// </summary>
IPathStatistics DriveInfo { get; }
IPathStatistics<IDriveInfoFactory, IDriveInfo> DriveInfo { get; }

/// <summary>
/// Statistical information about calls to <see cref="IFileSystem.File" />.
/// </summary>
IStatistics File { get; }
IStatistics<IFile> File { get; }

/// <summary>
/// Statistical information about calls to <see cref="IFileSystem.FileInfo" />.
/// </summary>
IPathStatistics FileInfo { get; }
IPathStatistics<IFileInfoFactory, IFileInfo> FileInfo { get; }

/// <summary>
/// Statistical information about calls to <see cref="IFileSystem.FileStream" />.
/// </summary>
IPathStatistics FileStream { get; }
IPathStatistics<IFileStreamFactory, FileSystemStream> FileStream { get; }

/// <summary>
/// Statistical information about calls to <see cref="IFileSystem.FileSystemWatcher" />.
/// </summary>
IPathStatistics FileSystemWatcher { get; }
IPathStatistics<IFileSystemWatcherFactory, IFileSystemWatcher> FileSystemWatcher { get; }

/// <summary>
/// Statistical information about calls to <see cref="IFileSystem.Path" />.
/// </summary>
IStatistics Path { get; }
IStatistics<IPath> Path { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
/// <remarks>
/// See also <seealso cref="IStatistics" /> .
/// </remarks>
public interface IPathStatistics : IStatistics
public interface IPathStatistics<TFactory, TType> : IStatistics<TFactory>
{
/// <summary>
/// Returns the underlying <see cref="IStatistics" /> under <paramref name="path" />.
/// </summary>
IStatistics this[string path]
IStatistics<TType> this[string path]
{
get;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,12 @@ public interface IStatistics
/// </summary>
PropertyStatistic[] Properties { get; }
}

/// <summary>
/// Contains statistical information about the mock usage.
/// </summary>
// ReSharper disable once UnusedTypeParameter
public interface IStatistics<TType> : IStatistics
{
// Empty wrapper interface to by type-safe.
}
20 changes: 10 additions & 10 deletions Source/Testably.Abstractions.Testing/Statistics/PathStatistics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

namespace Testably.Abstractions.Testing.Statistics;

internal class PathStatistics : CallStatistics, IPathStatistics
internal class PathStatistics<TFactory, TType> : CallStatistics<TFactory>, IPathStatistics<TFactory, TType>
{
private readonly MockFileSystem _fileSystem;

private readonly ConcurrentDictionary<string, CallStatistics> _statistics;
private readonly ConcurrentDictionary<string, CallStatistics<TType>> _statistics;
private readonly IStatisticsGate _statisticsGate;

public PathStatistics(
Expand All @@ -18,7 +18,7 @@ public PathStatistics(
string name)
: base(statisticsGate, name)
{
_statistics = new ConcurrentDictionary<string, CallStatistics>(
_statistics = new ConcurrentDictionary<string, CallStatistics<TType>>(
fileSystem.Execute.StringComparisonMode == StringComparison.Ordinal
? StringComparer.Ordinal
: StringComparer.OrdinalIgnoreCase);
Expand All @@ -28,14 +28,14 @@ public PathStatistics(

#region IPathStatistics Members

/// <inheritdoc cref="IPathStatistics.this[string]" />
public IStatistics this[string path]
/// <inheritdoc cref="IPathStatistics{TFactory,TType}.this[string]" />
public IStatistics<TType> this[string path]
{
get
{
string key = CreateKey(_fileSystem.Storage.CurrentDirectory, path);
return _statistics.GetOrAdd(key,
k => new CallStatistics(_statisticsGate, $"{ToString()}[{k}]"));
k => new CallStatistics<TType>(_statisticsGate, $"{ToString()}[{k}]"));
}
}

Expand All @@ -49,9 +49,9 @@ internal IDisposable RegisterMethod(string path, string name,
params ParameterDescription[] parameters)
{
string key = CreateKey(_fileSystem.Storage.CurrentDirectory, path);
CallStatistics callStatistics =
CallStatistics<TType> callStatistics =
_statistics.GetOrAdd(key,
k => new CallStatistics(_statisticsGate, $"{ToString()}[{k}]"));
k => new CallStatistics<TType>(_statisticsGate, $"{ToString()}[{k}]"));
return callStatistics.RegisterMethod(name, parameters);
}

Expand All @@ -63,9 +63,9 @@ internal IDisposable RegisterMethod(string path, string name,
internal IDisposable RegisterProperty(string path, string name, PropertyAccess access)
{
string key = CreateKey(_fileSystem.Storage.CurrentDirectory, path);
CallStatistics callStatistics =
CallStatistics<TType> callStatistics =
_statistics.GetOrAdd(key,
k => new CallStatistics(_statisticsGate, $"{ToString()}[{k}]"));
k => new CallStatistics<TType>(_statisticsGate, $"{ToString()}[{k}]"));
return callStatistics.RegisterProperty(name, access);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,24 +269,25 @@ namespace Testably.Abstractions.Testing.Statistics
{
public interface IFileSystemStatistics
{
Testably.Abstractions.Testing.Statistics.IStatistics Directory { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics DirectoryInfo { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics DriveInfo { get; }
Testably.Abstractions.Testing.Statistics.IStatistics File { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics FileInfo { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics FileStream { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics FileSystemWatcher { get; }
Testably.Abstractions.Testing.Statistics.IStatistics Path { get; }
Testably.Abstractions.Testing.Statistics.IStatistics<System.IO.Abstractions.IDirectory> Directory { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics<System.IO.Abstractions.IDirectoryInfoFactory, System.IO.Abstractions.IDirectoryInfo> DirectoryInfo { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics<System.IO.Abstractions.IDriveInfoFactory, System.IO.Abstractions.IDriveInfo> DriveInfo { get; }
Testably.Abstractions.Testing.Statistics.IStatistics<System.IO.Abstractions.IFile> File { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics<System.IO.Abstractions.IFileInfoFactory, System.IO.Abstractions.IFileInfo> FileInfo { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics<System.IO.Abstractions.IFileStreamFactory, System.IO.Abstractions.FileSystemStream> FileStream { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics<System.IO.Abstractions.IFileSystemWatcherFactory, System.IO.Abstractions.IFileSystemWatcher> FileSystemWatcher { get; }
Testably.Abstractions.Testing.Statistics.IStatistics<System.IO.Abstractions.IPath> Path { get; }
}
public interface IPathStatistics : Testably.Abstractions.Testing.Statistics.IStatistics
public interface IPathStatistics<TFactory, TType> : Testably.Abstractions.Testing.Statistics.IStatistics, Testably.Abstractions.Testing.Statistics.IStatistics<TFactory>
{
Testably.Abstractions.Testing.Statistics.IStatistics this[string path] { get; }
Testably.Abstractions.Testing.Statistics.IStatistics<TType> this[string path] { get; }
}
public interface IStatistics
{
Testably.Abstractions.Testing.Statistics.MethodStatistic[] Methods { get; }
Testably.Abstractions.Testing.Statistics.PropertyStatistic[] Properties { get; }
}
public interface IStatistics<TType> : Testably.Abstractions.Testing.Statistics.IStatistics { }
public sealed class MethodStatistic
{
public int Counter { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,24 +269,25 @@ namespace Testably.Abstractions.Testing.Statistics
{
public interface IFileSystemStatistics
{
Testably.Abstractions.Testing.Statistics.IStatistics Directory { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics DirectoryInfo { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics DriveInfo { get; }
Testably.Abstractions.Testing.Statistics.IStatistics File { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics FileInfo { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics FileStream { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics FileSystemWatcher { get; }
Testably.Abstractions.Testing.Statistics.IStatistics Path { get; }
Testably.Abstractions.Testing.Statistics.IStatistics<System.IO.Abstractions.IDirectory> Directory { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics<System.IO.Abstractions.IDirectoryInfoFactory, System.IO.Abstractions.IDirectoryInfo> DirectoryInfo { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics<System.IO.Abstractions.IDriveInfoFactory, System.IO.Abstractions.IDriveInfo> DriveInfo { get; }
Testably.Abstractions.Testing.Statistics.IStatistics<System.IO.Abstractions.IFile> File { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics<System.IO.Abstractions.IFileInfoFactory, System.IO.Abstractions.IFileInfo> FileInfo { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics<System.IO.Abstractions.IFileStreamFactory, System.IO.Abstractions.FileSystemStream> FileStream { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics<System.IO.Abstractions.IFileSystemWatcherFactory, System.IO.Abstractions.IFileSystemWatcher> FileSystemWatcher { get; }
Testably.Abstractions.Testing.Statistics.IStatistics<System.IO.Abstractions.IPath> Path { get; }
}
public interface IPathStatistics : Testably.Abstractions.Testing.Statistics.IStatistics
public interface IPathStatistics<TFactory, TType> : Testably.Abstractions.Testing.Statistics.IStatistics, Testably.Abstractions.Testing.Statistics.IStatistics<TFactory>
{
Testably.Abstractions.Testing.Statistics.IStatistics this[string path] { get; }
Testably.Abstractions.Testing.Statistics.IStatistics<TType> this[string path] { get; }
}
public interface IStatistics
{
Testably.Abstractions.Testing.Statistics.MethodStatistic[] Methods { get; }
Testably.Abstractions.Testing.Statistics.PropertyStatistic[] Properties { get; }
}
public interface IStatistics<TType> : Testably.Abstractions.Testing.Statistics.IStatistics { }
public sealed class MethodStatistic
{
public int Counter { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,24 +267,25 @@ namespace Testably.Abstractions.Testing.Statistics
{
public interface IFileSystemStatistics
{
Testably.Abstractions.Testing.Statistics.IStatistics Directory { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics DirectoryInfo { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics DriveInfo { get; }
Testably.Abstractions.Testing.Statistics.IStatistics File { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics FileInfo { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics FileStream { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics FileSystemWatcher { get; }
Testably.Abstractions.Testing.Statistics.IStatistics Path { get; }
Testably.Abstractions.Testing.Statistics.IStatistics<System.IO.Abstractions.IDirectory> Directory { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics<System.IO.Abstractions.IDirectoryInfoFactory, System.IO.Abstractions.IDirectoryInfo> DirectoryInfo { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics<System.IO.Abstractions.IDriveInfoFactory, System.IO.Abstractions.IDriveInfo> DriveInfo { get; }
Testably.Abstractions.Testing.Statistics.IStatistics<System.IO.Abstractions.IFile> File { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics<System.IO.Abstractions.IFileInfoFactory, System.IO.Abstractions.IFileInfo> FileInfo { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics<System.IO.Abstractions.IFileStreamFactory, System.IO.Abstractions.FileSystemStream> FileStream { get; }
Testably.Abstractions.Testing.Statistics.IPathStatistics<System.IO.Abstractions.IFileSystemWatcherFactory, System.IO.Abstractions.IFileSystemWatcher> FileSystemWatcher { get; }
Testably.Abstractions.Testing.Statistics.IStatistics<System.IO.Abstractions.IPath> Path { get; }
}
public interface IPathStatistics : Testably.Abstractions.Testing.Statistics.IStatistics
public interface IPathStatistics<TFactory, TType> : Testably.Abstractions.Testing.Statistics.IStatistics, Testably.Abstractions.Testing.Statistics.IStatistics<TFactory>
{
Testably.Abstractions.Testing.Statistics.IStatistics this[string path] { get; }
Testably.Abstractions.Testing.Statistics.IStatistics<TType> this[string path] { get; }
}
public interface IStatistics
{
Testably.Abstractions.Testing.Statistics.MethodStatistic[] Methods { get; }
Testably.Abstractions.Testing.Statistics.PropertyStatistic[] Properties { get; }
}
public interface IStatistics<TType> : Testably.Abstractions.Testing.Statistics.IStatistics { }
public sealed class MethodStatistic
{
public int Counter { get; }
Expand Down
Loading

0 comments on commit 284f0cc

Please sign in to comment.