Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for .NET9 #735

Merged
merged 11 commits into from
Jan 29, 2025
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
2 changes: 1 addition & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<PackageVersion Include="DotNet.Glob" Version="3.1.3"/>
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3"/>
<PackageVersion Include="System.Linq.Async" Version="6.0.1"/>
<PackageVersion Include="TestableIO.System.IO.Abstractions" Version="21.2.8"/>
<PackageVersion Include="TestableIO.System.IO.Abstractions" Version="21.3.1"/>
<PackageVersion Include="System.IO.Compression" Version="4.3.0"/>
<PackageVersion Include="System.IO.FileSystem.AccessControl" Version="5.0.0"/>
</ItemGroup>
Expand Down
10 changes: 7 additions & 3 deletions Feature.Flags.props
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<Project>

<PropertyGroup>
<IS_NET21_OR_HIGHER Condition="'$(TargetFramework)' == 'net6.0' OR '$(TargetFramework)' == 'net8.0' OR '$(TargetFramework)' == 'netstandard2.1'">1</IS_NET21_OR_HIGHER>
<IS_NET6_OR_HIGHER Condition="'$(TargetFramework)' == 'net6.0' OR '$(TargetFramework)' == 'net8.0'">1</IS_NET6_OR_HIGHER>
<IS_NET8_OR_HIGHER Condition="'$(TargetFramework)' == 'net8.0'">1</IS_NET8_OR_HIGHER>
<IS_NET21_OR_HIGHER Condition="'$(TargetFramework)' == 'net6.0' OR '$(TargetFramework)' == 'net8.0' OR '$(TargetFramework)' == 'net9.0' OR '$(TargetFramework)' == 'netstandard2.1'">1</IS_NET21_OR_HIGHER>
<IS_NET6_OR_HIGHER Condition="'$(TargetFramework)' == 'net6.0' OR '$(TargetFramework)' == 'net8.0' OR '$(TargetFramework)' == 'net9.0'">1</IS_NET6_OR_HIGHER>
<IS_NET8_OR_HIGHER Condition="'$(TargetFramework)' == 'net8.0' OR '$(TargetFramework)' == 'net9.0'">1</IS_NET8_OR_HIGHER>
<IS_NET9_OR_HIGHER Condition="'$(TargetFramework)' == 'net9.0'">1</IS_NET9_OR_HIGHER>

<DefineConstants Condition="'$(TargetFramework)' == 'net48' OR '$(TargetFramework)' == 'netstandard2.0'">$(DefineConstants);NETFRAMEWORK</DefineConstants>
<DefineConstants Condition="'$(IS_NET6_OR_HIGHER)' == '1'">$(DefineConstants);CAN_SIMULATE_OTHER_OS</DefineConstants>
Expand All @@ -30,6 +31,9 @@
<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_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>
</PropertyGroup>

</Project>
2 changes: 1 addition & 1 deletion Source/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</PropertyGroup>

<PropertyGroup>
<TargetFrameworks>net6.0;net8.0;netstandard2.1;netstandard2.0</TargetFrameworks>
<TargetFrameworks>net6.0;net8.0;net9.0;netstandard2.1;netstandard2.0</TargetFrameworks>
<TargetFrameworks Condition="'$(NetFrameworkOnly)' == 'True'">netstandard2.0</TargetFrameworks>
</PropertyGroup>

Expand Down
10 changes: 10 additions & 0 deletions Source/Testably.Abstractions.Interface/Helpers/GuidSystemBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ protected GuidSystemBase(IRandomSystem randomSystem)
/// <inheritdoc cref="IGuid.NewGuid()" />
public abstract Guid NewGuid();

#if FEATURE_GUID_V7
/// <inheritdoc cref="IGuid.CreateVersion7()" />
public abstract Guid CreateVersion7();
#endif

#if FEATURE_GUID_V7
/// <inheritdoc cref="IGuid.CreateVersion7(DateTimeOffset)" />
public abstract Guid CreateVersion7(DateTimeOffset timestamp);
#endif

#if FEATURE_GUID_PARSE
#pragma warning disable MA0011
/// <inheritdoc cref="IGuid.Parse(string)" />
Expand Down
10 changes: 10 additions & 0 deletions Source/Testably.Abstractions.Interface/RandomSystem/IGuid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ public interface IGuid : IRandomSystemEntity
/// <inheritdoc cref="Guid.NewGuid()" />
Guid NewGuid();

#if FEATURE_GUID_V7
/// <inheritdoc cref="Guid.CreateVersion7()" />
Guid CreateVersion7();
#endif

#if FEATURE_GUID_V7
/// <inheritdoc cref="Guid.CreateVersion7(DateTimeOffset)" />
Guid CreateVersion7(DateTimeOffset timestamp);
#endif

#if FEATURE_GUID_PARSE
/// <inheritdoc cref="Guid.Parse(string)" />
Guid Parse(string input);
Expand Down
201 changes: 201 additions & 0 deletions Source/Testably.Abstractions.Testing/FileSystem/FileMock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,74 @@ internal FileMock(MockFileSystem fileSystem)
/// <inheritdoc cref="IFileSystemEntity.FileSystem" />
public IFileSystem FileSystem
=> _fileSystem;

#if FEATURE_FILE_SPAN
/// <inheritdoc cref="IFile.AppendAllBytes(string,byte[])"/>
public void AppendAllBytes(string path, byte[] bytes)
{
using IDisposable registration = _fileSystem.StatisticsRegistration
.File.RegisterMethod(nameof(AppendAllBytes),
path, bytes);

IStorageContainer container =
_fileSystem.Storage.GetOrCreateContainer(
_fileSystem.Storage.GetLocation(
path.EnsureValidFormat(_fileSystem)),
InMemoryContainer.NewFile);

if (container.Type != FileSystemTypes.File)
{
throw ExceptionFactory.AccessToPathDenied(path);
}

using (container.RequestAccess(
FileAccess.ReadWrite,
FileStreamFactoryMock.DefaultShare))
{
container.AppendBytes(bytes);
}
}
#endif

#if FEATURE_FILE_SPAN
/// <inheritdoc cref="IFile.AppendAllBytes(string,ReadOnlySpan{byte})"/>
public void AppendAllBytes(string path, ReadOnlySpan<byte> bytes)
{
using IDisposable registration = _fileSystem.StatisticsRegistration
.File.RegisterMethod(nameof(AppendAllBytes),
path, bytes);

AppendAllBytes(path, bytes.ToArray());
}
#endif

#if FEATURE_FILE_SPAN
/// <inheritdoc cref="IFile.AppendAllBytesAsync(string,byte[],CancellationToken)"/>
public Task AppendAllBytesAsync(string path, byte[] bytes, CancellationToken cancellationToken = default)
{
using IDisposable registration = _fileSystem.StatisticsRegistration
.File.RegisterMethod(nameof(AppendAllBytesAsync),
path, bytes, cancellationToken);

ThrowIfCancelled(cancellationToken);
AppendAllBytes(path, bytes);
return Task.CompletedTask;
}
#endif

#if FEATURE_FILE_SPAN
/// <inheritdoc cref="IFile.AppendAllBytesAsync(string,ReadOnlyMemory{byte},CancellationToken)"/>
public Task AppendAllBytesAsync(string path, ReadOnlyMemory<byte> bytes, CancellationToken cancellationToken = default)
{
using IDisposable registration = _fileSystem.StatisticsRegistration
.File.RegisterMethod(nameof(AppendAllBytesAsync),
path, bytes, cancellationToken);

ThrowIfCancelled(cancellationToken);
AppendAllBytes(path, bytes.ToArray());
return Task.CompletedTask;
}
#endif

/// <inheritdoc cref="IFile.AppendAllLines(string, IEnumerable{string})" />
public void AppendAllLines(string path, IEnumerable<string> contents)
Expand Down Expand Up @@ -132,6 +200,30 @@ public void AppendAllText(string path, string? contents, Encoding encoding)
}
}
}

#if FEATURE_FILE_SPAN
/// <inheritdoc cref="IFile.AppendAllText(string,ReadOnlySpan{char})"/>
public void AppendAllText(string path, ReadOnlySpan<char> contents)
{
using IDisposable registration = _fileSystem.StatisticsRegistration
.File.RegisterMethod(nameof(AppendAllText),
path, contents);

AppendAllText(path, contents.ToString(), Encoding.Default);
}
#endif

#if FEATURE_FILE_SPAN
/// <inheritdoc cref="IFile.AppendAllText(string,ReadOnlySpan{char},Encoding)"/>
public void AppendAllText(string path, ReadOnlySpan<char> contents, Encoding encoding)
{
using IDisposable registration = _fileSystem.StatisticsRegistration
.File.RegisterMethod(nameof(AppendAllText),
path, contents, encoding);

AppendAllText(path, contents.ToString(), encoding);
}
#endif

#if FEATURE_FILESYSTEM_ASYNC
/// <inheritdoc cref="IFile.AppendAllTextAsync(string, string?, CancellationToken)" />
Expand Down Expand Up @@ -160,6 +252,35 @@ public Task AppendAllTextAsync(string path, string? contents, Encoding encoding,
return Task.CompletedTask;
}
#endif

#if FEATURE_FILE_SPAN
/// <inheritdoc cref="IFile.AppendAllTextAsync(string,ReadOnlyMemory{char},CancellationToken)"/>
public Task AppendAllTextAsync(string path, ReadOnlyMemory<char> contents, CancellationToken cancellationToken = default)
{
using IDisposable registration = _fileSystem.StatisticsRegistration
.File.RegisterMethod(nameof(AppendAllTextAsync),
path, contents, cancellationToken);

ThrowIfCancelled(cancellationToken);
AppendAllText(path, contents.ToString(), Encoding.Default);
return Task.CompletedTask;
}
#endif

#if FEATURE_FILE_SPAN
/// <inheritdoc cref="IFile.AppendAllTextAsync(string,ReadOnlyMemory{char},Encoding,CancellationToken)"/>
public Task AppendAllTextAsync(string path, ReadOnlyMemory<char> contents, Encoding encoding,
CancellationToken cancellationToken = default)
{
using IDisposable registration = _fileSystem.StatisticsRegistration
.File.RegisterMethod(nameof(AppendAllTextAsync),
path, contents, encoding, cancellationToken);

ThrowIfCancelled(cancellationToken);
AppendAllText(path, contents.ToString(), encoding);
return Task.CompletedTask;
}
#endif

/// <inheritdoc cref="IFile.AppendText(string)" />
public StreamWriter AppendText(string path)
Expand Down Expand Up @@ -1241,6 +1362,18 @@ public void WriteAllBytes(string path, byte[] bytes)
container.WriteBytes(bytes);
}
}

#if FEATURE_FILE_SPAN
/// <inheritdoc cref="IFile.WriteAllBytes(string,ReadOnlySpan{byte})"/>
public void WriteAllBytes(string path, ReadOnlySpan<byte> bytes)
{
using IDisposable registration = _fileSystem.StatisticsRegistration
.File.RegisterMethod(nameof(WriteAllBytes),
path, bytes);

WriteAllBytes(path, bytes.ToArray());
}
#endif

#if FEATURE_FILESYSTEM_ASYNC
/// <inheritdoc cref="IFile.WriteAllBytesAsync(string, byte[], CancellationToken)" />
Expand All @@ -1256,6 +1389,20 @@ public Task WriteAllBytesAsync(string path, byte[] bytes,
return Task.CompletedTask;
}
#endif

#if FEATURE_FILE_SPAN
/// <inheritdoc cref="IFile.WriteAllBytesAsync(string,ReadOnlyMemory{byte},CancellationToken)"/>
public Task WriteAllBytesAsync(string path, ReadOnlyMemory<byte> bytes, CancellationToken cancellationToken = default)
{
using IDisposable registration = _fileSystem.StatisticsRegistration
.File.RegisterMethod(nameof(WriteAllBytesAsync),
path, bytes, cancellationToken);

ThrowIfCancelled(cancellationToken);
WriteAllBytes(path, bytes.ToArray());
return Task.CompletedTask;
}
#endif

/// <inheritdoc cref="IFile.WriteAllLines(string, string[])" />
public void WriteAllLines(string path, string[] contents)
Expand Down Expand Up @@ -1388,6 +1535,31 @@ public void WriteAllText(string path, string? contents, Encoding encoding)
}
}
}

#if FEATURE_FILE_SPAN
/// <inheritdoc cref="IFile.WriteAllText(string,ReadOnlySpan{char})"/>
public void WriteAllText(string path, ReadOnlySpan<char> contents)
{
using IDisposable registration = _fileSystem.StatisticsRegistration
.File.RegisterMethod(nameof(WriteAllText),
path, contents);

WriteAllText(path, contents.ToString(), Encoding.Default);
}
#endif

#if FEATURE_FILE_SPAN

/// <inheritdoc cref="IFile.WriteAllText(string,ReadOnlySpan{char},Encoding)"/>
public void WriteAllText(string path, ReadOnlySpan<char> contents, Encoding encoding)
{
using IDisposable registration = _fileSystem.StatisticsRegistration
.File.RegisterMethod(nameof(WriteAllText),
path, contents, encoding);

WriteAllText(path, contents.ToString(), encoding);
}
#endif

#if FEATURE_FILESYSTEM_ASYNC
/// <inheritdoc cref="IFile.WriteAllTextAsync(string, string?, CancellationToken)" />
Expand Down Expand Up @@ -1416,6 +1588,35 @@ public Task WriteAllTextAsync(string path, string? contents, Encoding encoding,
return Task.CompletedTask;
}
#endif

#if FEATURE_FILE_SPAN
/// <inheritdoc cref="IFile.WriteAllTextAsync(string,ReadOnlyMemory{char},CancellationToken)"/>
public Task WriteAllTextAsync(string path, ReadOnlyMemory<char> contents, CancellationToken cancellationToken = default)
{
using IDisposable registration = _fileSystem.StatisticsRegistration
.File.RegisterMethod(nameof(WriteAllTextAsync),
path, contents, cancellationToken);

ThrowIfCancelled(cancellationToken);
WriteAllText(path, contents.ToString(), Encoding.Default);
return Task.CompletedTask;
}
#endif

#if FEATURE_FILE_SPAN
/// <inheritdoc cref="IFile.WriteAllTextAsync(string,ReadOnlyMemory{char},Encoding,CancellationToken)"/>
public Task WriteAllTextAsync(string path, ReadOnlyMemory<char> contents, Encoding encoding,
CancellationToken cancellationToken = default)
{
using IDisposable registration = _fileSystem.StatisticsRegistration
.File.RegisterMethod(nameof(WriteAllTextAsync),
path, contents, encoding, cancellationToken);

ThrowIfCancelled(cancellationToken);
WriteAllText(path, contents.ToString(), encoding);
return Task.CompletedTask;
}
#endif

#endregion

Expand Down
24 changes: 24 additions & 0 deletions Source/Testably.Abstractions.Testing/FileSystem/PathMock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,18 @@ public string Combine(params string[] paths)

return _fileSystem.Execute.Path.Combine(paths);
}

#if FEATURE_PATH_SPAN
/// <inheritdoc cref="IPath.Combine(ReadOnlySpan{string})" />
public string Combine(params ReadOnlySpan<string> paths)
{
using IDisposable register = _fileSystem.StatisticsRegistration
.Path.RegisterMethod(nameof(Combine),
paths);

return _fileSystem.Execute.Path.Combine(paths);
}
#endif

#if FEATURE_PATH_ADVANCED
/// <inheritdoc cref="IPath.EndsInDirectorySeparator(ReadOnlySpan{char})" />
Expand Down Expand Up @@ -512,6 +524,18 @@ public string Join(params string?[] paths)
return _fileSystem.Execute.Path.Join(paths);
}
#endif

#if FEATURE_PATH_SPAN
/// <inheritdoc cref="IPath.Join(ReadOnlySpan{string})" />
public string Join(params ReadOnlySpan<string?> paths)
{
using IDisposable register = _fileSystem.StatisticsRegistration
.Path.RegisterMethod(nameof(Join),
paths);

return _fileSystem.Execute.Path.Join(paths);
}
#endif

#if FEATURE_PATH_ADVANCED
/// <inheritdoc cref="IPath.TrimEndingDirectorySeparator(ReadOnlySpan{char})" />
Expand Down
12 changes: 12 additions & 0 deletions Source/Testably.Abstractions.Testing/Helpers/Execute.NativePath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ public string Combine(string path1, string path2, string path3, string path4)
/// <inheritdoc cref="Path.Combine(string[])" />
public string Combine(params string[] paths)
=> System.IO.Path.Combine(paths);

#if FEATURE_PATH_SPAN
/// <inheritdoc cref="Path.Combine(ReadOnlySpan{string})" />
public string Combine(params ReadOnlySpan<string> paths)
=> System.IO.Path.Combine(paths);
#endif

#if FEATURE_PATH_ADVANCED
/// <inheritdoc cref="Path.EndsInDirectorySeparator(ReadOnlySpan{char})" />
Expand Down Expand Up @@ -279,6 +285,12 @@ public string Join(string? path1, string? path2, string? path3, string? path4)
public string Join(params string?[] paths)
=> System.IO.Path.Join(paths);
#endif

#if FEATURE_PATH_SPAN
/// <inheritdoc cref="Path.Join(ReadOnlySpan{string})" />
public string Join(params ReadOnlySpan<string?> paths)
=> System.IO.Path.Join(paths);
#endif

#if FEATURE_PATH_ADVANCED
/// <inheritdoc cref="Path.TrimEndingDirectorySeparator(ReadOnlySpan{char})" />
Expand Down
Loading
Loading