Skip to content

Commit

Permalink
Add IMachine abstraction
Browse files Browse the repository at this point in the history
  • Loading branch information
patriksvensson committed Jul 1, 2024
1 parent e612c66 commit 02e1069
Show file tree
Hide file tree
Showing 7 changed files with 267 additions and 106 deletions.
22 changes: 15 additions & 7 deletions src/Spectre.IO.Testing/FakeEnvironment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,35 +31,43 @@ public sealed class FakeEnvironment : IEnvironment
/// <param name="family">The platform family.</param>
/// <param name="architecture">The platform processor architecture.</param>
public FakeEnvironment(PlatformFamily family, PlatformArchitecture architecture = PlatformArchitecture.X64)
: this(new FakePlatform(family, architecture))
{
}

/// <summary>
/// Initializes a new instance of the <see cref="FakeEnvironment"/> class.
/// </summary>
/// <param name="platform">The underlying platform for the environment.</param>
public FakeEnvironment(FakePlatform platform)
{
_environmentVariables = new Dictionary<string, string?>(StringComparer.OrdinalIgnoreCase);
Platform = platform ?? throw new ArgumentNullException(nameof(platform));

if (family == PlatformFamily.Windows)
if (Platform.Family == PlatformFamily.Windows)
{
WorkingDirectory = new DirectoryPath("C:/Working");
HomeDirectory = new DirectoryPath("C:/Users/JohnDoe");
}
else if (family == PlatformFamily.MacOs)
else if (Platform.Family == PlatformFamily.MacOs)
{
WorkingDirectory = new DirectoryPath("/Working");
HomeDirectory = new DirectoryPath("/Users/JohnDoe");
}
else if (family == PlatformFamily.FreeBSD)
else if (Platform.Family == PlatformFamily.FreeBSD)
{
WorkingDirectory = new DirectoryPath("/Working");
HomeDirectory = new DirectoryPath("/usr/home/JohnDoe");
}
else if (family == PlatformFamily.Linux)
else if (Platform.Family == PlatformFamily.Linux)
{
WorkingDirectory = new DirectoryPath("/Working");
HomeDirectory = new DirectoryPath("/home/JohnDoe");
}
else
{
throw new ArgumentException("Unknown platform family", nameof(family));
throw new ArgumentException("Unknown platform family", nameof(Platform.Family));
}

Platform = new FakePlatform(family, architecture);
}

/// <summary>
Expand Down
76 changes: 76 additions & 0 deletions src/Spectre.IO.Testing/FakeMachine.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
namespace Spectre.IO.Testing;

/// <summary>
/// Represents a fake machine.
/// </summary>
public sealed class FakeMachine : IMachine
{
/// <summary>
/// Gets the fake file system.
/// </summary>
public FakeFileSystem FileSystem { get; }

/// <summary>
/// Gets the fake environment.
/// </summary>
public FakeEnvironment Environment { get; }

/// <inheritdoc/>
IFileSystem IMachine.FileSystem => FileSystem;

/// <inheritdoc/>
IEnvironment IMachine.Environment => Environment;

/// <summary>
/// Initializes a new instance of the <see cref="FakeMachine"/> class.
/// </summary>
/// <param name="family">The platform family.</param>
/// <param name="architecture">The platform processor architecture.</param>
public FakeMachine(
PlatformFamily family,
PlatformArchitecture architecture = PlatformArchitecture.X64)
{
Environment = new FakeEnvironment(family, architecture);
FileSystem = new FakeFileSystem(Environment);
}

/// <summary>
/// Creates a Linux machine.
/// </summary>
/// <param name="architecture">The platform processor architecture.</param>
/// <returns>A Linux environment.</returns>
public static FakeMachine CreateLinuxMachine(PlatformArchitecture architecture = PlatformArchitecture.X64)
{
return new FakeMachine(PlatformFamily.Linux, architecture);
}

/// <summary>
/// Creates a macOS environment.
/// </summary>
/// <param name="architecture">The platform processor architecture.</param>
/// <returns>A macOS environment.</returns>
public static FakeMachine CreateMacOsMachine(PlatformArchitecture architecture = PlatformArchitecture.X64)
{
return new FakeMachine(PlatformFamily.MacOs, architecture);
}

/// <summary>
/// Creates a Windows environment.
/// </summary>
/// <param name="architecture">The platform processor architecture.</param>
/// <returns>A Windows environment.</returns>
public static FakeMachine CreateWindowsMachine(PlatformArchitecture architecture = PlatformArchitecture.X64)
{
return new FakeMachine(PlatformFamily.Windows, architecture);
}

/// <summary>
/// Creates a FreeBSD environment.
/// </summary>
/// <param name="architecture">The platform processor architecture.</param>
/// <returns>A Windows environment.</returns>
public static FakeMachine CreateFreeBsdMachine(PlatformArchitecture architecture = PlatformArchitecture.X64)
{
return new FakeMachine(PlatformFamily.FreeBSD, architecture);
}
}
193 changes: 95 additions & 98 deletions src/Spectre.IO.Tests/Fixtures/GlobberFixture.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
#nullable enable

using System;
using System.Linq;
using Spectre.IO.Testing;

Expand All @@ -7,134 +9,129 @@ namespace Spectre.IO.Tests.Fixtures;
internal sealed class GlobberFixture
{
public FakeFileSystem FileSystem { get; set; }
public IEnvironment Environment { get; set; }
public FakeEnvironment Environment { get; set; }

private GlobberFixture(FakeFileSystem filesystem, IEnvironment environment)
private GlobberFixture(FakeMachine machine)
{
FileSystem = filesystem;
Environment = environment;
FileSystem = machine.FileSystem;
Environment = machine.Environment;
}

public static GlobberFixture Windows()
{
var environment = FakeEnvironment.CreateWindowsEnvironment();
var filesystem = new FakeFileSystem(environment);
var machine = FakeMachine.CreateWindowsMachine();

// Directories
filesystem.CreateDirectory("C://Working");
filesystem.CreateDirectory("C://Working/Foo");
filesystem.CreateDirectory("C://Working/Foo/Bar");
filesystem.CreateDirectory("C:");
filesystem.CreateDirectory("C:/Program Files (x86)");
machine.FileSystem.CreateDirectory("C://Working");
machine.FileSystem.CreateDirectory("C://Working/Foo");
machine.FileSystem.CreateDirectory("C://Working/Foo/Bar");
machine.FileSystem.CreateDirectory("C:");
machine.FileSystem.CreateDirectory("C:/Program Files (x86)");

// UNC directories
filesystem.CreateDirectory(@"\\Server");
filesystem.CreateDirectory(@"\\Server\Foo");
filesystem.CreateDirectory(@"\\Server\Foo\Bar");
filesystem.CreateDirectory(@"\\Server\Bar");
filesystem.CreateDirectory(@"\\Foo\Bar");
filesystem.CreateDirectory(@"\\Foo (Bar)");
filesystem.CreateDirectory(@"\\Foo@Bar\");
filesystem.CreateDirectory(@"\\嵌套");
filesystem.CreateDirectory(@"\\嵌套\目录");
machine.FileSystem.CreateDirectory(@"\\Server");
machine.FileSystem.CreateDirectory(@"\\Server\Foo");
machine.FileSystem.CreateDirectory(@"\\Server\Foo\Bar");
machine.FileSystem.CreateDirectory(@"\\Server\Bar");
machine.FileSystem.CreateDirectory(@"\\Foo\Bar");
machine.FileSystem.CreateDirectory(@"\\Foo (Bar)");
machine.FileSystem.CreateDirectory(@"\\Foo@Bar\");
machine.FileSystem.CreateDirectory(@"\\嵌套");
machine.FileSystem.CreateDirectory(@"\\嵌套\目录");

// Files
filesystem.CreateFile("C:/Working/Foo/Bar/Qux.c");
filesystem.CreateFile("C:/Program Files (x86)/Foo.c");
filesystem.CreateFile("C:/Working/Project.A.Test.dll");
filesystem.CreateFile("C:/Working/Project.B.Test.dll");
filesystem.CreateFile("C:/Working/Project.IntegrationTest.dll");
filesystem.CreateFile("C:/Tools & Services/MyTool.dll");
filesystem.CreateFile("C:/Tools + Services/MyTool.dll");
filesystem.CreateFile("C:/Some %2F Directory/MyTool.dll");
filesystem.CreateFile("C:/Some ! Directory/MyTool.dll");
filesystem.CreateFile("C:/Some@Directory/MyTool.dll");
filesystem.CreateFile("C:/Working/foobar.rs");
filesystem.CreateFile("C:/Working/foobaz.rs");
filesystem.CreateFile("C:/Working/foobax.rs");
machine.FileSystem.CreateFile("C:/Working/Foo/Bar/Qux.c");
machine.FileSystem.CreateFile("C:/Program Files (x86)/Foo.c");
machine.FileSystem.CreateFile("C:/Working/Project.A.Test.dll");
machine.FileSystem.CreateFile("C:/Working/Project.B.Test.dll");
machine.FileSystem.CreateFile("C:/Working/Project.IntegrationTest.dll");
machine.FileSystem.CreateFile("C:/Tools & Services/MyTool.dll");
machine.FileSystem.CreateFile("C:/Tools + Services/MyTool.dll");
machine.FileSystem.CreateFile("C:/Some %2F Directory/MyTool.dll");
machine.FileSystem.CreateFile("C:/Some ! Directory/MyTool.dll");
machine.FileSystem.CreateFile("C:/Some@Directory/MyTool.dll");
machine.FileSystem.CreateFile("C:/Working/foobar.rs");
machine.FileSystem.CreateFile("C:/Working/foobaz.rs");
machine.FileSystem.CreateFile("C:/Working/foobax.rs");

// UNC files
filesystem.CreateFile(@"\\Server\Foo/Bar/Qux.c");
filesystem.CreateFile(@"\\Server\Foo/Bar/Qex.c");
filesystem.CreateFile(@"\\Server\Foo/Bar/Qux.h");
filesystem.CreateFile(@"\\Server\Foo/Baz/Qux.c");
filesystem.CreateFile(@"\\Server\Foo/Bar/Baz/Qux.c");
filesystem.CreateFile(@"\\Server\Bar/Qux.c");
filesystem.CreateFile(@"\\Server\Bar/Qux.h");
filesystem.CreateFile(@"\\Server\Foo.Bar.Test.dll");
filesystem.CreateFile(@"\\Server\Bar.Qux.Test.dll");
filesystem.CreateFile(@"\\Server\Quz.FooTest.dll");
filesystem.CreateFile(@"\\Foo\Bar.baz");
filesystem.CreateFile(@"\\Foo (Bar)\Baz.c");
filesystem.CreateFile(@"\\Foo@Bar\Baz.c");
filesystem.CreateFile(@"\\嵌套/目录/文件.延期");

return new GlobberFixture(filesystem, environment);
machine.FileSystem.CreateFile(@"\\Server\Foo/Bar/Qux.c");
machine.FileSystem.CreateFile(@"\\Server\Foo/Bar/Qex.c");
machine.FileSystem.CreateFile(@"\\Server\Foo/Bar/Qux.h");
machine.FileSystem.CreateFile(@"\\Server\Foo/Baz/Qux.c");
machine.FileSystem.CreateFile(@"\\Server\Foo/Bar/Baz/Qux.c");
machine.FileSystem.CreateFile(@"\\Server\Bar/Qux.c");
machine.FileSystem.CreateFile(@"\\Server\Bar/Qux.h");
machine.FileSystem.CreateFile(@"\\Server\Foo.Bar.Test.dll");
machine.FileSystem.CreateFile(@"\\Server\Bar.Qux.Test.dll");
machine.FileSystem.CreateFile(@"\\Server\Quz.FooTest.dll");
machine.FileSystem.CreateFile(@"\\Foo\Bar.baz");
machine.FileSystem.CreateFile(@"\\Foo (Bar)\Baz.c");
machine.FileSystem.CreateFile(@"\\Foo@Bar\Baz.c");
machine.FileSystem.CreateFile(@"\\嵌套/目录/文件.延期");

return new GlobberFixture(machine);
}

public static GlobberFixture UnixLike()
{
var environment = FakeEnvironment.CreateLinuxEnvironment();
var filesystem = new FakeFileSystem(environment);
var machine = FakeMachine.CreateLinuxMachine();

// Directories
filesystem.CreateDirectory("/RootDir");
filesystem.CreateDirectory("/home/JohnDoe");
filesystem.CreateDirectory("/Working");
filesystem.CreateDirectory("/Working/Foo");
filesystem.CreateDirectory("/Working/Foo/Bar");
filesystem.CreateDirectory("/Working/Bar");
filesystem.CreateDirectory("/Foo/Bar");
filesystem.CreateDirectory("/Foo (Bar)");
filesystem.CreateDirectory("/Foo@Bar/");
filesystem.CreateDirectory("/嵌套");
filesystem.CreateDirectory("/嵌套/目录");
machine.FileSystem.CreateDirectory("/RootDir");
machine.FileSystem.CreateDirectory("/home/JohnDoe");
machine.FileSystem.CreateDirectory("/Working");
machine.FileSystem.CreateDirectory("/Working/Foo");
machine.FileSystem.CreateDirectory("/Working/Foo/Bar");
machine.FileSystem.CreateDirectory("/Working/Bar");
machine.FileSystem.CreateDirectory("/Foo/Bar");
machine.FileSystem.CreateDirectory("/Foo (Bar)");
machine.FileSystem.CreateDirectory("/Foo@Bar/");
machine.FileSystem.CreateDirectory("/嵌套");
machine.FileSystem.CreateDirectory("/嵌套/目录");

// Files
filesystem.CreateFile("/RootFile.sh");
filesystem.CreateFile("/home/JohnDoe/foobar.rs");
filesystem.CreateFile("/home/JohnDoe/foobaz.rs");
filesystem.CreateFile("/home/JohnDoe/foobax.rs");
filesystem.CreateFile("/Working/Foo/Bar/Qux.c");
filesystem.CreateFile("/Working/Foo/Bar/Qex.c");
filesystem.CreateFile("/Working/Foo/Bar/Qux.h");
filesystem.CreateFile("/Working/Foo/Baz/Qux.c");
filesystem.CreateFile("/Working/Foo/Bar/Baz/Qux.c");
filesystem.CreateFile("/Working/Bar/Qux.c");
filesystem.CreateFile("/Working/Bar/Qux.h");
filesystem.CreateFile("/Working/Foo.Bar.Test.dll");
filesystem.CreateFile("/Working/Bar.Qux.Test.dll");
filesystem.CreateFile("/Working/Quz.FooTest.dll");
filesystem.CreateFile("/Foo/Bar.baz");
filesystem.CreateFile("/Foo (Bar)/Baz.c");
filesystem.CreateFile("/Foo@Bar/Baz.c");
filesystem.CreateFile("/嵌套/目录/文件.延期");
filesystem.CreateFile("/Working/foobar.rs");
filesystem.CreateFile("/Working/foobaz.rs");
filesystem.CreateFile("/Working/foobax.rs");

return new GlobberFixture(filesystem, environment);
machine.FileSystem.CreateFile("/RootFile.sh");
machine.FileSystem.CreateFile("/home/JohnDoe/foobar.rs");
machine.FileSystem.CreateFile("/home/JohnDoe/foobaz.rs");
machine.FileSystem.CreateFile("/home/JohnDoe/foobax.rs");
machine.FileSystem.CreateFile("/Working/Foo/Bar/Qux.c");
machine.FileSystem.CreateFile("/Working/Foo/Bar/Qex.c");
machine.FileSystem.CreateFile("/Working/Foo/Bar/Qux.h");
machine.FileSystem.CreateFile("/Working/Foo/Baz/Qux.c");
machine.FileSystem.CreateFile("/Working/Foo/Bar/Baz/Qux.c");
machine.FileSystem.CreateFile("/Working/Bar/Qux.c");
machine.FileSystem.CreateFile("/Working/Bar/Qux.h");
machine.FileSystem.CreateFile("/Working/Foo.Bar.Test.dll");
machine.FileSystem.CreateFile("/Working/Bar.Qux.Test.dll");
machine.FileSystem.CreateFile("/Working/Quz.FooTest.dll");
machine.FileSystem.CreateFile("/Foo/Bar.baz");
machine.FileSystem.CreateFile("/Foo (Bar)/Baz.c");
machine.FileSystem.CreateFile("/Foo@Bar/Baz.c");
machine.FileSystem.CreateFile("/嵌套/目录/文件.延期");
machine.FileSystem.CreateFile("/Working/foobar.rs");
machine.FileSystem.CreateFile("/Working/foobaz.rs");
machine.FileSystem.CreateFile("/Working/foobax.rs");

return new GlobberFixture(machine);
}

public void SetWorkingDirectory(DirectoryPath path)
{
Environment.SetWorkingDirectory(path);
}

public Path[] Match(string pattern)
{
return Match(pattern, null);
}

public Path[] Match(string pattern, Func<IFileSystemInfo, bool> directoryPredicate)
{
return Match(pattern, directoryPredicate, null);
}

public Path[] Match(string pattern, Func<IFileSystemInfo, bool> directoryPredicate, Func<IFile, bool> filePredicate)
public Path[] Match(
string pattern,
Func<IFileSystemInfo, bool>? directoryPredicate = null,
Func<IFile, bool>? filePredicate = null)
{
return new Globber(FileSystem, Environment)
.Match(pattern, new GlobberSettings { Predicate = directoryPredicate, FilePredicate = filePredicate })
.Match(pattern, new GlobberSettings
{
Predicate = directoryPredicate,
FilePredicate = filePredicate,
})
.ToArray();
}
}
4 changes: 3 additions & 1 deletion src/Spectre.IO.Tests/Utilities/ShouldlyExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Collections.Generic;
#nullable enable

using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Shouldly;
Expand Down
17 changes: 17 additions & 0 deletions src/Spectre.IO/Extensions/IMachineExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace Spectre.IO;

/// <summary>
/// Contains extensions for <see cref="IMachine"/>.
/// </summary>
public static class IMachineExtensions
{
/// <summary>
/// Creates a new <see cref="IGlobber"/> instance.
/// </summary>
/// <param name="machine">The machine to base the globber on.</param>
/// <returns>A <see cref="IGlobber"/> instance.</returns>
public static IGlobber CreateGlobber(this IMachine machine)
{
return new Globber(machine.FileSystem, machine.Environment);
}
}
Loading

0 comments on commit 02e1069

Please sign in to comment.