PlayNicely.Projects
1.0.4-prerelease-20240228-095702
See the version list below for details.
dotnet add package PlayNicely.Projects --version 1.0.4-prerelease-20240228-095702
NuGet\Install-Package PlayNicely.Projects -Version 1.0.4-prerelease-20240228-095702
<PackageReference Include="PlayNicely.Projects" Version="1.0.4-prerelease-20240228-095702" />
paket add PlayNicely.Projects --version 1.0.4-prerelease-20240228-095702
#r "nuget: PlayNicely.Projects, 1.0.4-prerelease-20240228-095702"
// Install PlayNicely.Projects as a Cake Addin #addin nuget:?package=PlayNicely.Projects&version=1.0.4-prerelease-20240228-095702&prerelease // Install PlayNicely.Projects as a Cake Tool #tool nuget:?package=PlayNicely.Projects&version=1.0.4-prerelease-20240228-095702&prerelease
Play Nicely Projects
The Play Nicely Projects supports the definition and packaging (for reading or writing) of MSBuild Projects. These projects can be used to release test NuGet tool projects that you may be developing. This package provides foundation artefacts for tool project testing, however, the actual test execution code and supporting BDD extensions are developed separately.
- PlayNicely.Executor
- PlayNicely.Executor.DotNet
- PlayNicely.SpecFlow.Executor
- PlayNicely.SpecFlow.DotNet
In use in these tools packages:
Getting Started
This base package supports the definition of a TestCaseProject
via a generic
FileSystem
interface. This interface allows for the definition of directories
and files, and also the contents of those files.
The other artefacts support reading or writing of a TestCaseProject
to
media. At this time, the project supports reading from .NET assembly
resources and writing to the physical file system. Implement concrete versions
of IProjectPackageReader
and IProjectPackageWriter
if you have a specific
media that you wish to support.
Defining Projects
The TestCaseProject
class represents a virtual project, you can define a
FileSystem
by adding directories and files using it's fluent interface. You
can also specify the ProjectFile from the same file system. Once defined the
TestCaseProject
doesn't do much on its own, but when combined with
PlayNicely.Executor, or
other dependent packages, it can have commands executed against it and any
output collected for assertions.
var testCaseProject = new TestCaseProject("my-project");
var projectFile = testCaseProject.AddDirectory("project1")
.AddFile("proj.csproj");
testCaseProject.ProjectFile = projectFile;
using(var writer = new StreamWriter(projectFile.OpenWriteStream()))
{
writer.WriteLine("<Project Sdk=\"Microsoft.NET.Sdk\">");
writer.WriteLine(" <PropertyGroup>");
writer.WriteLine(" <TargetFramework>netstandard2.0</TargetFramework>");
writer.WriteLine(" </PropertyGroup>");
writer.WriteLine("</Project>");
}
Using Resource (resx) files
Building test case projects in code is fine, but there is already a tool to
easily define and edit MSBuild projects, the IDE. To support this, Projects
provides a IProjectPackageReader
implementation for .NET resources. The basic
idea is to add files to the resx with names equivalent to the project file
structure. The ResourceSetPackageReader
can then be used to read a package
into a test case project, including the file contents.
Example
If you want a TestCaseProject
with the following structure...
solution-dir
|-- Project1
| |-- Project1.csproj
| |-- Program.cs
|-- Project2
| |-- Project2.csproj
| |-- Program.cs
| |-- Consts.cs
|-- my-solution.sln
The .resx file should have the following resources defined (note the item keys).
<?xml version="1.0" encoding="utf-8"?>
<root>
<data name="ProjectFile" xml:space="preserve">
<value>my-solution.sln</value>
</data>
<data name="my-solution.sln" xml:space="preserve">
<value></value>
</data>
<data name="Project1/Project1.csproj" xml:space="preserve">
<value>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
</Project>
</value>
</data>
<data name="Project1/Program.cs" xml:space="preserve">
<value>
using System;
namespace Project1
{
public static class Program
{
public static int Main(params string[] args)
{
Console.WriteLine("Project1");
return 0;
}
}
}
</value>
</data>
<data name="Project2/Project2.csproj" xml:space="preserve">
<value>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
</Project>
</value>
</data>
<data name="Project2/Program.cs" xml:space="preserve">
<value>
using System;
namespace Project1
{
public static class Program
{
public static int Main(params string[] args)
{
Console.WriteLine("Project2: {0}", Consts.Version);
return 0;
}
}
}
</value>
</data>
<data name="Project2/Consts.cs" xml:space="preserve">
<value>
using System;
namespace Project1
{
public static class Consts
{
public const string Version = "1.2.3";
}
}
</value>
</data>
</root>
Note the special key ProjectFile which defines the
TestCaseProject.ProjectFile
path.
Example
If you have the following project structure...
solution-dir
|-- my-project.Specs # BDD Specifications for your project
| |-- TestCases.Projects # Define your test case 'packages' in resx files
| |-- Project1.resx
|-- TestCase.Projects # Define your test case projects in here using familiar tools.
| |-- Project1
| |-- Project1.csproj
| |-- Program.cs
|-- my-solution.sln
The .resx file should have the following resources defined (note the item keys).
<?xml version="1.0" encoding="utf-8"?>
<root>
<data name="Project1/Project1.csproj" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Project1/Project1.csproj;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="Project1/Program.cs" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Project1/Program.cs;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
</root>
And then to load these resources into a TestCaseProject
you can...
internal static class TestCases
{
// Where projectName is the same as the resx file name without the extension
public static async Task<TestCaseProject> LoadAsync(string projectName, CancellationToken cancel)
{
ArgumentException.ThrowIfNullOrEmpty(projectName);
cancel.ThrowIfCancellationRequested();
var resourceManager = new ResourceManager($"{ResourceNamespace}.{projectName}", ResourceAssembly);
using var resourceSet = resourceManager.GetResourceSet(CultureInfo.InvariantCulture, true, true)
?? throw new TestCaseException(string.Format(ContentRes.Error_ProjectNameDoesNotExist, projectName));
using var reader = new ResourceSetBlobReader(resourceSet);
var result = new TestCaseProject(projectName);
await result.LoadFromAsync(reader, cancel);
cancel.ThrowIfCancellationRequested();
return result;
}
public static Assembly ResourceAssembly => _resourceAssembly.Value;
public static string ResourceNamespace => _resourceNamespace.Value;
private static readonly Lazy<Assembly> _resourceAssembly = new(() => typeof(TestCases).Assembly);
private static readonly Lazy<string> _resourceNamespace = new(() => typeof(TestCases).Namespace ?? string.Empty);
}
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net8.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on PlayNicely.Projects:
Package | Downloads |
---|---|
PlayNicely.Executor
A framework that facilitates testing of Play Nicely functionality. Provides capability to execute programs, in a controlled environment, against test case projects. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.1.3-beta-550 | 100 | 10/4/2024 |
1.1.3-beta-543 | 114 | 9/28/2024 |
1.1.3-beta-535 | 108 | 9/28/2024 |
1.1.3-beta-529 | 97 | 9/23/2024 |
1.1.3-beta-518 | 113 | 9/21/2024 |
1.1.3-beta-511 | 99 | 9/20/2024 |
1.1.3-beta-509 | 100 | 9/20/2024 |
1.1.3-beta-507 | 100 | 9/20/2024 |
1.1.3-beta-505 | 99 | 9/19/2024 |
1.1.3-beta-501 | 127 | 9/18/2024 |
1.1.3-beta-499 | 109 | 9/18/2024 |
1.1.3-beta-496 | 114 | 9/18/2024 |
1.1.2 | 168 | 9/17/2024 |
1.1.2-beta-494 | 107 | 9/18/2024 |
1.1.2-beta-492 | 117 | 9/18/2024 |
1.1.2-beta-487 | 113 | 9/17/2024 |
1.1.1 | 222 | 6/1/2024 |
1.1.1-beta-479 | 122 | 9/14/2024 |
1.1.1-beta-472 | 116 | 9/14/2024 |
1.1.1-beta-465 | 131 | 9/7/2024 |
1.1.1-beta-450 | 107 | 7/14/2024 |
1.1.1-beta-442 | 104 | 7/12/2024 |
1.1.1-beta-432 | 107 | 7/11/2024 |
1.1.1-beta-418 | 106 | 6/1/2024 |
1.1.1-beta-398 | 112 | 6/1/2024 |
1.1.0 | 126 | 5/6/2024 |
1.1.0-beta-393 | 122 | 5/31/2024 |
1.1.0-beta-382 | 135 | 5/21/2024 |
1.1.0-beta-370 | 132 | 5/8/2024 |
1.1.0-beta-355 | 135 | 5/7/2024 |
1.1.0-beta-349 | 129 | 5/7/2024 |
1.1.0-beta-346 | 129 | 5/7/2024 |
1.1.0-beta-340 | 133 | 5/7/2024 |
1.1.0-beta-323 | 125 | 5/6/2024 |
1.0.7 | 340 | 4/11/2024 |
1.0.7-beta-312 | 130 | 4/26/2024 |
1.0.7-beta-299 | 145 | 4/14/2024 |
1.0.7-beta-296 | 129 | 4/14/2024 |
1.0.7-beta-287 | 123 | 4/11/2024 |
1.0.7-beta-282 | 127 | 4/11/2024 |
1.0.7-beta-280 | 133 | 4/10/2024 |
1.0.7-beta-278 | 126 | 4/10/2024 |
1.0.7-beta-276 | 122 | 4/10/2024 |
1.0.7-beta-274 | 146 | 4/9/2024 |
1.0.7-beta-272 | 136 | 4/9/2024 |
1.0.6 | 172 | 3/21/2024 |
1.0.6-beta-266 | 129 | 3/21/2024 |
1.0.6-beta-260 | 128 | 3/21/2024 |
1.0.5 | 215 | 3/10/2024 |
1.0.5-prerelease-20240301-0... | 113 | 3/1/2024 |
1.0.5-beta-227 | 133 | 3/10/2024 |
1.0.5-beta-221 | 141 | 3/9/2024 |
1.0.5-beta-214 | 139 | 3/9/2024 |
1.0.5-beta-208 | 135 | 3/1/2024 |
1.0.5-beta-206 | 131 | 3/1/2024 |
1.0.4 | 135 | 2/29/2024 |
1.0.4-prerelease-20240229-1... | 90 | 2/29/2024 |
1.0.4-prerelease-20240228-0... | 89 | 2/28/2024 |
1.0.4-prerelease-20240226-1... | 110 | 2/26/2024 |