Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Feature.Flags.props
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
<DefineConstants Condition="'$(IS_NET8_OR_HIGHER)' == '1'">$(DefineConstants);FEATURE_GUID_FORMATPROVIDER</DefineConstants>
<DefineConstants Condition="'$(IS_NET8_OR_HIGHER)' == '1'">$(DefineConstants);FEATURE_RANDOM_ITEMS</DefineConstants>
<DefineConstants Condition="'$(IS_NET8_OR_HIGHER)' == '1'">$(DefineConstants);FEATURE_COMPRESSION_STREAM</DefineConstants>
<DefineConstants Condition="'$(IS_NET8_OR_HIGHER)' == '1'">$(DefineConstants);FEATURE_STOPWATCH_GETELAPSEDTIME</DefineConstants>
<DefineConstants Condition="'$(IS_NET9_OR_HIGHER)' == '1'">$(DefineConstants);FEATURE_PATH_SPAN</DefineConstants>
<DefineConstants Condition="'$(IS_NET9_OR_HIGHER)' == '1'">$(DefineConstants);FEATURE_FILE_SPAN</DefineConstants>
<DefineConstants Condition="'$(IS_NET9_OR_HIGHER)' == '1'">$(DefineConstants);FEATURE_GUID_V7</DefineConstants>
Expand Down
58 changes: 32 additions & 26 deletions Pipeline/Build.Compile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,35 +120,41 @@ partial class Build
ReportSummary(s => s
.WhenNotNull(SemVer, (summary, semVer) => summary
.AddPair("Version", semVer)));

UpdateReadme(MainVersion!.FileVersion, false);
foreach (var mainProject in MainProjects)

if (BuildScope != BuildScope.CoreOnly)
{
ClearNugetPackages(mainProject.Directory / "bin");
DotNetBuild(s => s
.SetProjectFile(mainProject)
.SetConfiguration(Configuration)
.EnableNoLogo()
.EnableNoRestore()
.SetProcessAdditionalArguments($"/p:SolutionDir={RootDirectory}/")
.SetVersion(MainVersion.FileVersion + CoreVersion!.PreRelease)
.SetAssemblyVersion(MainVersion.FileVersion)
.SetFileVersion(MainVersion.FileVersion));
UpdateReadme(MainVersion!.FileVersion, false);
foreach (var mainProject in MainProjects)
{
ClearNugetPackages(mainProject.Directory / "bin");
DotNetBuild(s => s
.SetProjectFile(mainProject)
.SetConfiguration(Configuration)
.EnableNoLogo()
.EnableNoRestore()
.SetProcessAdditionalArguments($"/p:SolutionDir={RootDirectory}/")
.SetVersion(MainVersion.FileVersion + CoreVersion!.PreRelease)
.SetAssemblyVersion(MainVersion.FileVersion)
.SetFileVersion(MainVersion.FileVersion));
}
}

UpdateReadme(CoreVersion!.FileVersion, true);
foreach (var coreProject in CoreProjects)

if (BuildScope != BuildScope.MainOnly)
{
ClearNugetPackages(coreProject.Directory / "bin");
DotNetBuild(s => s
.SetProjectFile(coreProject)
.SetConfiguration(Configuration)
.EnableNoLogo()
.EnableNoRestore()
.SetProcessAdditionalArguments($"/p:SolutionDir={RootDirectory}/")
.SetVersion(CoreVersion.FileVersion + CoreVersion.PreRelease)
.SetAssemblyVersion(CoreVersion.FileVersion)
.SetFileVersion(CoreVersion.FileVersion));
UpdateReadme(CoreVersion!.FileVersion, true);
foreach (var coreProject in CoreProjects)
{
ClearNugetPackages(coreProject.Directory / "bin");
DotNetBuild(s => s
.SetProjectFile(coreProject)
.SetConfiguration(Configuration)
.EnableNoLogo()
.EnableNoRestore()
.SetProcessAdditionalArguments($"/p:SolutionDir={RootDirectory}/")
.SetVersion(CoreVersion.FileVersion + CoreVersion.PreRelease)
.SetAssemblyVersion(CoreVersion.FileVersion)
.SetFileVersion(CoreVersion.FileVersion));
}
}
});

Expand Down
2 changes: 1 addition & 1 deletion Pipeline/Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ partial class Build : NukeBuild
/// <para />
/// Afterward, you can update the package reference in `Directory.Packages.props` and reset this flag.
/// </summary>
readonly BuildScope BuildScope = BuildScope.Default;
readonly BuildScope BuildScope = BuildScope.CoreOnly;

[Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")]
readonly Configuration Configuration = IsLocalBuild ? Configuration.Debug : Configuration.Release;
Expand Down
6 changes: 6 additions & 0 deletions Source/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,10 @@
</PackageReference>
</ItemGroup>

<PropertyGroup>
<!-- The version is only set to support local builds.
In the build pipeline it is overwritten with the actual version in the `nuke Compile` step -->
<Version>255.255.255.255</Version>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@
<PackageReference Include="System.IO.FileSystem.AccessControl" />
</ItemGroup>

<ItemGroup>
<ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
<PackageReference Include="Testably.Abstractions.Interface" />
</ItemGroup>

<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
<ProjectReference Include="..\Testably.Abstractions.Interface\Testably.Abstractions.Interface.csproj" />
</ItemGroup>

<ItemGroup>
<AssemblyAttribute Include="System.CLSCompliant">
<_Parameter1>true</_Parameter1>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@
Link="Docs\Compression.md" />
</ItemGroup>

<ItemGroup>
<ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
<PackageReference Include="Testably.Abstractions.Interface" />
</ItemGroup>

<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
<ProjectReference Include="..\Testably.Abstractions.Interface\Testably.Abstractions.Interface.csproj" />
</ItemGroup>

<ItemGroup>
<InternalsVisibleTo Include="Testably.Abstractions.Compression.Tests" PublicKey="$(PublicKey)" />
</ItemGroup>
Expand Down
5 changes: 5 additions & 0 deletions Source/Testably.Abstractions.Interface/ITimeSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ public interface ITimeSystem
/// </summary>
IDateTime DateTime { get; }

/// <summary>
/// Abstractions for <see cref="System.Diagnostics.Stopwatch" />.
/// </summary>
IStopwatchFactory Stopwatch { get; }

/// <summary>
/// Abstractions for <see cref="System.Threading.Tasks.Task" />.
/// </summary>
Expand Down
34 changes: 34 additions & 0 deletions Source/Testably.Abstractions.Interface/TimeSystem/IStopwatch.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Diagnostics;

namespace Testably.Abstractions.TimeSystem;

/// <summary>
/// Abstractions for <see cref="Stopwatch" />.
/// </summary>
public interface IStopwatch : ITimeSystemEntity
{
/// <inheritdoc cref="Stopwatch.Elapsed" />
TimeSpan Elapsed { get; }

/// <inheritdoc cref="Stopwatch.ElapsedMilliseconds" />
long ElapsedMilliseconds { get; }

/// <inheritdoc cref="Stopwatch.ElapsedTicks" />
long ElapsedTicks { get; }

/// <inheritdoc cref="Stopwatch.IsRunning" />
bool IsRunning { get; }

/// <inheritdoc cref="Stopwatch.Reset()" />
void Reset();

/// <inheritdoc cref="Stopwatch.Restart()" />
void Restart();

/// <inheritdoc cref="Stopwatch.Start()" />
void Start();

/// <inheritdoc cref="Stopwatch.Stop()" />
void Stop();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System.Diagnostics;
#if FEATURE_STOPWATCH_GETELAPSEDTIME
using System;
#endif

namespace Testably.Abstractions.TimeSystem;

/// <summary>
/// Factory for abstracting creation of <see cref="Stopwatch" />.
/// </summary>
public interface IStopwatchFactory : ITimeSystemEntity
{
/// <inheritdoc cref="Stopwatch.Frequency" />
long Frequency { get; }

/// <inheritdoc cref="Stopwatch.IsHighResolution" />
bool IsHighResolution { get; }

/// <inheritdoc cref="Stopwatch.GetTimestamp()" />
long GetTimestamp();

/// <inheritdoc cref="Stopwatch()" />
IStopwatch New();

/// <inheritdoc cref="Stopwatch.StartNew()" />
IStopwatch StartNew();

/// <summary>
/// Wraps the <paramref name="stopwatch" /> to the testable <see cref="IStopwatch" />.
/// </summary>
IStopwatch Wrap(Stopwatch stopwatch);

#if FEATURE_STOPWATCH_GETELAPSEDTIME
/// <inheritdoc cref="Stopwatch.GetElapsedTime(long)" />
TimeSpan GetElapsedTime(long startingTimestamp);

/// <inheritdoc cref="Stopwatch.GetElapsedTime(long, long)" />
TimeSpan GetElapsedTime(long startingTimestamp, long endingTimestamp);
#endif
}
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ internal static NotSupportedException NotSupportedSafeFileHandle()
=> new(
"You cannot mock a safe file handle in the mocked file system without registering a strategy explicitly. Use `MockFileSystem.WithSafeFileHandleStrategy`!");

internal static NotSupportedException NotSupportedStopwatchWrapping()
=> new("You cannot wrap an existing Stopwatch in the MockTimeSystem instance!");

internal static NotSupportedException NotSupportedTimerWrapping()
=> new("You cannot wrap an existing Timer in the MockTimeSystem instance!");

Expand Down
16 changes: 11 additions & 5 deletions Source/Testably.Abstractions.Testing/MockTimeSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ public INotificationHandler On
/// <summary>
/// The handler for mocked timers.
/// </summary>
public ITimerHandler TimerHandler => _timerMock;
public ITimerHandler TimerHandler => _timerFactoryMock;

private readonly NotificationHandler _callbackHandler;
private readonly DateTimeMock _dateTimeMock;
private readonly StopwatchFactoryMock _stopwatchFactoryMock;
private readonly TaskMock _taskMock;
private readonly ThreadMock _threadMock;
private readonly TimerFactoryMock _timerMock;
private readonly TimerFactoryMock _timerFactoryMock;

/// <summary>
/// Initializes the <see cref="MockTimeSystem" /> with a random time.
Expand All @@ -55,9 +56,10 @@ public MockTimeSystem(ITimeProvider timeProvider)
TimeProvider = timeProvider;
_callbackHandler = new NotificationHandler();
_dateTimeMock = new DateTimeMock(this, _callbackHandler);
_stopwatchFactoryMock = new StopwatchFactoryMock(this);
_threadMock = new ThreadMock(this, _callbackHandler);
_taskMock = new TaskMock(this, _callbackHandler);
_timerMock = new TimerFactoryMock(this);
_timerFactoryMock = new TimerFactoryMock(this);
}

#region ITimeSystem Members
Expand All @@ -66,6 +68,10 @@ public MockTimeSystem(ITimeProvider timeProvider)
public IDateTime DateTime
=> _dateTimeMock;

/// <inheritdoc cref="ITimeSystem.Stopwatch" />
public IStopwatchFactory Stopwatch
=> _stopwatchFactoryMock;

/// <inheritdoc cref="ITimeSystem.Task" />
public ITask Task
=> _taskMock;
Expand All @@ -76,7 +82,7 @@ public IThread Thread

/// <inheritdoc cref="ITimeSystem.Timer" />
public ITimerFactory Timer
=> _timerMock;
=> _timerFactoryMock;

#endregion

Expand All @@ -90,7 +96,7 @@ public override string ToString()
/// <param name="timerStrategy">The timer strategy. </param>
public MockTimeSystem WithTimerStrategy(ITimerStrategy timerStrategy)
{
_timerMock.SetTimerStrategy(timerStrategy);
_timerFactoryMock.SetTimerStrategy(timerStrategy);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@
<None Include="$(SolutionDir)Docs/Nuget/Testing.md" Pack="true" PackagePath="/Docs/" Link="Docs\Testing.md" />
</ItemGroup>

<ItemGroup>
<ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
<PackageReference Include="Testably.Abstractions.Interface" />
</ItemGroup>

<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
<ProjectReference Include="..\Testably.Abstractions.Interface\Testably.Abstractions.Interface.csproj" />
</ItemGroup>

<ItemGroup>
<AssemblyAttribute Include="System.CLSCompliant">
<_Parameter1>true</_Parameter1>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using System;
using System.Diagnostics;
using Testably.Abstractions.Testing.Helpers;
using Testably.Abstractions.TimeSystem;
using IStopwatch = Testably.Abstractions.TimeSystem.IStopwatch;

namespace Testably.Abstractions.Testing.TimeSystem;

internal sealed class StopwatchFactoryMock : IStopwatchFactory
{
private readonly MockTimeSystem _mockTimeSystem;

internal StopwatchFactoryMock(MockTimeSystem timeSystem)
{
_mockTimeSystem = timeSystem;
}

#region IStopwatchFactory Members

/// <inheritdoc cref="IStopwatchFactory.Frequency" />
public long Frequency => TimeSpan.TicksPerSecond;

/// <inheritdoc cref="IStopwatchFactory.IsHighResolution" />
public bool IsHighResolution => true;

/// <inheritdoc cref="ITimeSystemEntity.TimeSystem" />
public ITimeSystem TimeSystem
=> _mockTimeSystem;

#if FEATURE_STOPWATCH_GETELAPSEDTIME
/// <inheritdoc cref="IStopwatchFactory.GetElapsedTime(long)" />
public TimeSpan GetElapsedTime(long startingTimestamp)
=> GetElapsedTime(startingTimestamp, GetTimestamp());
#endif

#if FEATURE_STOPWATCH_GETELAPSEDTIME
/// <inheritdoc cref="IStopwatchFactory.GetElapsedTime(long, long)" />
public TimeSpan GetElapsedTime(long startingTimestamp, long endingTimestamp)
=> TimeSpan.FromTicks(endingTimestamp - startingTimestamp);
#endif

/// <inheritdoc cref="IStopwatchFactory.GetTimestamp()" />
public long GetTimestamp()
=> _mockTimeSystem.TimeProvider.Read().Ticks;

/// <inheritdoc cref="IStopwatchFactory.New()" />
public IStopwatch New()
{
StopwatchMock stopwatchMock = new(_mockTimeSystem);
return stopwatchMock;
}

/// <inheritdoc cref="IStopwatchFactory.StartNew()" />
public IStopwatch StartNew()
{
IStopwatch stopwatch = New();
stopwatch.Start();
return stopwatch;
}

/// <inheritdoc cref="IStopwatchFactory.Wrap(Stopwatch)" />
public IStopwatch Wrap(Stopwatch stopwatch)
=> throw ExceptionFactory.NotSupportedStopwatchWrapping();

#endregion
}
Loading