Skip to content

Commit

Permalink
Merge 4fbfb3f into 6efd273
Browse files Browse the repository at this point in the history
  • Loading branch information
kurtmkurtm authored Dec 5, 2021
2 parents 6efd273 + 4fbfb3f commit 73b0114
Show file tree
Hide file tree
Showing 14 changed files with 312 additions and 130 deletions.
25 changes: 17 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ Liquid Test Reports are logger extensions for the [Visual Studio Test Platform](

### Latest:

##### 1.3.2 beta

- [Cli]
- Add filename pattern matching support for CLI

##### 1.2.1 beta

- [Cli]
Expand All @@ -31,13 +36,6 @@ Liquid Test Reports are logger extensions for the [Visual Studio Test Platform](
- Add TRX mapping
- Move template error logging from report generator into base test logger

#### 1.0.9

**Changed**

- [All] Revert target framework from .NET standard 2.1 back to .NET standard 2.0 for broader compatibility
- For use with .NET Core 2.x, see [Compatibility](#Compatibility)

[Previous changes](./docs/Changelog.md)


Expand All @@ -61,7 +59,8 @@ liquid [options]
**Options:**

**--inputs [inputs]** Array of formatted configuration strings for test report inputs, with configurations separated by a semicolon
- **File=file-name;** The path of the input file.
- **File=file-name;** The path or glob pattern for input file/s
- **Folder=folder-name;** - Base directory for finding test files
- **Format=report-format;** Optional input report format, case insensitive, supported values are `Trx` of `JUnit`. Defaults to `Trx`.
- **GroupTitle=group-title;** Optional title to group reports under, test runs with the same group title will be merged.
- **TestPrefix=test-prefix;** Optional test suffix, if provided test origination for the provided report will have the suffix appended to its name.
Expand Down Expand Up @@ -92,6 +91,16 @@ liquid --inputs "File=xUnit-net461-sample.trx;Format=Trx" --output-file SingleIn

#### More Examples

**File glob pattern relative to current directory**

```bash
liquid --inputs "File=**/*sample.trx" --output-file report.md
```
**File glob pattern using specific directory**
```bash
liquid --inputs "File=**/*sample.trx;Folder=C:\MyTestFolder" --output-file report.md
```

**Report from single input, with a custom title** - [Sample Output](docs/samples/cli/CustomTitle.md)

``` bash
Expand Down
4 changes: 1 addition & 3 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pool:
variables:
buildConfiguration: 'Release'
majorVersion: 1
minorVersion: 2
minorVersion: 3
suffix: 'beta'

stages:
Expand Down Expand Up @@ -52,7 +52,6 @@ stages:

- task: DotNetCoreCLI@2
displayName: 'dotnet pack'
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
inputs:
command: custom
projects: |
Expand All @@ -66,7 +65,6 @@ stages:

- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact'
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)
ArtifactName: 'drop'
Expand Down
7 changes: 7 additions & 0 deletions docs/Changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
## Changelog

#### 1.0.9

**Changed**

- [All] Revert target framework from .NET standard 2.1 back to .NET standard 2.0 for broader compatibility
- For use with .NET Core 2.x, see [Compatibility](#Compatibility)

#### 1.0.1

**Changed**
Expand Down
28 changes: 16 additions & 12 deletions src/LiquidTestReports.Cli/ConsoleRunner.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using DotLiquid;
using DotLiquid.Exceptions;
using LiquidTestReports.Cli.Models;
using LiquidTestReports.Cli.Resources;
using LiquidTestReports.Cli.Services;
using LiquidTestReports.Core;
Expand All @@ -24,8 +25,8 @@ internal class ConsoleRunner

internal ConsoleRunner(ReportInput[] inputs, FileInfo outputFile)
{
_errorConsole = AnsiConsole.Create(new AnsiConsoleSettings { Out = Console.Error });
_standardConsole = AnsiConsole.Create(new AnsiConsoleSettings { Out = Console.Out });
_errorConsole = AnsiConsole.Create(new AnsiConsoleSettings { Out = new AnsiConsoleOutput(Console.Error) });
_standardConsole = AnsiConsole.Create(new AnsiConsoleSettings { Out = new AnsiConsoleOutput(Console.Out) });
_inputs = inputs;
_outputFile = outputFile;
}
Expand Down Expand Up @@ -131,27 +132,30 @@ private void WriteInputTable()

foreach (var input in _inputs)
{
table.AddRow(input.File.Name,
string.IsNullOrEmpty(input.GroupTitle) ? "default" : input.GroupTitle,
string.IsNullOrEmpty(input.TestSuffix) ? "n/a" : input.TestSuffix,
input.File.Exists.ToString(),
input.Format.ToString(),
(!input.File.Exists || input.Format == InputFormatType.Unknown).ToString());
foreach (var file in input.Files)
{
table.AddRow(file.Name,
string.IsNullOrEmpty(input.GroupTitle) ? "default" : input.GroupTitle,
string.IsNullOrEmpty(input.TestSuffix) ? "n/a" : input.TestSuffix,
file.Exists.ToString(),
input.Format.ToString(),
(!file.Exists || input.Format == InputFormatType.Unknown).ToString());
}
}

_standardConsole.WriteLine();
_standardConsole.Render(table);
_standardConsole.Write(table);
}

private void WriteHeader(string title)
{
_standardConsole.WriteLine();
_standardConsole.Render(new FigletText("Liquid Test Reports").Centered().Color(Color.Blue));
_standardConsole.Write(new FigletText("Liquid Test Reports").Centered().Color(Color.Blue));
_standardConsole.WriteLine();
_standardConsole.Render(new FigletText("Cli Tool").Centered().Color(Color.White));
_standardConsole.Write(new FigletText("Cli Tool").Centered().Color(Color.White));
_standardConsole.WriteLine();
_standardConsole.WriteLine();
_standardConsole.Render(new Rule(title).RuleStyle("grey").LeftAligned());
_standardConsole.Write(new Rule(title).RuleStyle("grey").LeftAligned());
_standardConsole.WriteLine();
}

Expand Down
7 changes: 4 additions & 3 deletions src/LiquidTestReports.Cli/LiquidTestReports.Cli.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
<PackageIcon>nuget_cli.png</PackageIcon>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Spectre.Console" Version="0.38.0" />
<PackageReference Include="System.CommandLine.DragonFruit" Version="0.3.0-alpha.20574.7" />
<PackageReference Include="Microsoft.Extensions.FileSystemGlobbing" Version="5.0.0" />
<PackageReference Include="Spectre.Console" Version="0.42.0" />
<PackageReference Include="System.CommandLine.DragonFruit" Version="0.3.0-alpha.21216.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LiquidTestReports.Core\LiquidTestReports.Core.csproj" />
Expand Down Expand Up @@ -47,6 +48,6 @@
<PackageId>LiquidTestReports.Cli</PackageId>
<Product>LiquidTestReports.Cli</Product>
<Copyright>2021</Copyright>
<Description>.NET tool to combine and convert TRX tests reports into Markdown with Liquid template support</Description>
<Description>.NET tool to combine and convert TRX and JUnit tests reports into Markdown with Liquid template support</Description>
</PropertyGroup>
</Project>
129 changes: 129 additions & 0 deletions src/LiquidTestReports.Cli/Models/ReportInput.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
using DotLiquid;
using LiquidTestReports.Core.Models;
using Microsoft.Extensions.FileSystemGlobbing;
using Microsoft.Extensions.FileSystemGlobbing.Abstractions;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace LiquidTestReports.Cli.Models
{
/// <summary>
/// Per Test File Configuration
/// </summary>
public class ReportInput : IReportInput
{
/// <summary>
/// Configuration for test report input
/// </summary>
/// <example></example>
/// <param name="inputString">
/// Formatted configuration string for test report input - example: "File=TestRun1.trx;GroupTitle=.NETCORE 3.1 Tests;TestSuffix=Windows 10"
/// (Required) File=file-name - The path or glob pattern for input files
/// (Optional) Folder=folder-name - Base directory for finding test files
/// (Optional) Format=report-format - Optional input report format, case insensitive, supported values are `Trx` of `JUnit`
/// (Optional) GroupTitle=group-title - Optional title to group reports under, test runs with the same group title will be merged
/// (Optional) TestPrefix=optional:test-prefix - Optional test suffix, if provided test origination for the provided report will have the suffix appended to its name
/// </param>
public ReportInput(string inputString)
{
if(string.IsNullOrWhiteSpace(inputString))
throw new ArgumentNullException(nameof(inputString));

var splitInputs = inputString.Split(';');
var parameters = new Dictionary<string, string>(Template.NamingConvention.StringComparer);
foreach (var input in splitInputs)
{
var parameter = input.Split('=');
if (parameter.Length == 2 && !string.IsNullOrEmpty(parameter[0]) && !string.IsNullOrEmpty(parameter[1]))
{
parameters.Add(parameter[0], parameter[1]);
}
else
{
throw new ArgumentException($"Incorrect number of arguments provided, Confirm parameter '{inputString}' uses the convention of 'key=value;'");
}
}

if (parameters.TryGetValue(nameof(Folder), out var folder))
{
Folder = new DirectoryInfo(folder);
}

if (parameters.TryGetValue(nameof(File), out var file))
{
FileInfo fileInfo = null;

if (Folder is null)
{
fileInfo = new FileInfo(file);
}

if (fileInfo?.Exists is true)
{
Files = new[] { fileInfo };
}
else // treat as glob pattern
{
var workingFolder = Folder ?? new DirectoryInfo(Directory.GetCurrentDirectory());
var results = new Matcher()
.AddInclude(file)
.Execute(new DirectoryInfoWrapper(workingFolder));

Files = results.HasMatches ?
results.Files.Select(match => new FileInfo(match.Path)) :
throw new ArgumentException("File did not match any files");
}
}
else
{
throw new ArgumentNullException("No parameter file name has been provided");
}

if (parameters.TryGetValue(nameof(GroupTitle), out var title))
{
GroupTitle = title;
}

if (parameters.TryGetValue(nameof(TestSuffix), out var testPrefix))
{
TestSuffix = testPrefix;
}

if (parameters.TryGetValue(nameof(Format), out var format))
{
Format = Enum.TryParse<InputFormatType>(format, true, out var formatType)
? formatType
: InputFormatType.Unknown;
}
}

/// <summary>
/// Base directory for finding test files
/// </summary>
public DirectoryInfo Folder { get; }

/// <summary>
/// File containing test content
/// </summary>
public IEnumerable<FileInfo> Files { get; }

/// <summary>
/// Test file format, if not provided, defaults to Trx
/// </summary>
public InputFormatType Format { get; } = InputFormatType.Trx;

/// <summary>
/// Test group title, title used for all tests from this input,
/// Where group titles are the same, results will be merged into the same group
/// </summary>
public string GroupTitle { get; }

/// <summary>
/// Test suffix, this prefix will be appended to individual test titles
/// </summary>
public string TestSuffix { get; }

}
}
3 changes: 2 additions & 1 deletion src/LiquidTestReports.Cli/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using LiquidTestReports.Core.Models;
using LiquidTestReports.Cli.Models;
using LiquidTestReports.Core.Models;
using System;
using System.IO;
using System.Threading.Tasks;
Expand Down
34 changes: 19 additions & 15 deletions src/LiquidTestReports.Cli/Services/InputProcessingService.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using LiquidTestReports.Cli.adapters;
using LiquidTestReports.Cli.Loaders;
using LiquidTestReports.Cli.Models;
using LiquidTestReports.Core.Drops;
using LiquidTestReports.Core.Mappers;
using LiquidTestReports.Core.Models;
Expand Down Expand Up @@ -30,22 +31,25 @@ internal TestRunDrop Process()

foreach (var input in _inputs)
{
switch (input.Format)
foreach (var file in input.Files)
{
case InputFormatType.Trx:
{
var results = TrxLoader.FromFile(input.File.FullName);
TrxMapper.Map(results, testRunDrop, input);
break;
}
case InputFormatType.JUnit:
{
var results = JUnitLoader.FromFile(input.File.FullName);
JUnitMapper.Map(results, testRunDrop, input);
break;
}
default:
throw new NotImplementedException();
switch (input.Format)
{
case InputFormatType.Trx:
{
var results = TrxLoader.FromFile(file.FullName);
TrxMapper.Map(results, testRunDrop, input);
break;
}
case InputFormatType.JUnit:
{
var results = JUnitLoader.FromFile(file.FullName);
JUnitMapper.Map(results, testRunDrop, input);
break;
}
default:
throw new NotImplementedException();
}
}
}

Expand Down
13 changes: 13 additions & 0 deletions src/LiquidTestReports.Core/Abstractions/IReportInput.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Collections.Generic;
using System.IO;

namespace LiquidTestReports.Core.Models
{
public interface IReportInput
{
IEnumerable<FileInfo> Files { get; }
InputFormatType Format { get; }
string GroupTitle { get; }
string TestSuffix { get; }
}
}
2 changes: 1 addition & 1 deletion src/LiquidTestReports.Core/Mappers/JUnitMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public static class JUnitMapper
/// <param name="source">Instance of test results from deserialised JUnit input</param>
/// <param name="destination">Instance to map and merge results into</param>
/// <param name="inputConfiguration">User configured input for current source</param>
public static void Map(Testsuites source, TestRunDrop destination, ReportInput inputConfiguration = null)
public static void Map(Testsuites source, TestRunDrop destination, IReportInput inputConfiguration = null)
{
foreach (var testsuite in source.Testsuite)
{
Expand Down
2 changes: 1 addition & 1 deletion src/LiquidTestReports.Core/Mappers/TrxMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class TrxMapper
/// <param name="source">Instance of test results from deserialised TRX input</param>
/// <param name="destination">Instance to map and merge results into</param>
/// <param name="inputConfiguration">User configured input for current source</param>
public static void Map(TestRunType source, TestRunDrop destination, ReportInput inputConfiguration = null)
public static void Map(TestRunType source, TestRunDrop destination, IReportInput inputConfiguration = null)
{
var times = source.Times.FirstOrDefault();
var started = DateTimeOffset.Parse(times.Start);
Expand Down
Loading

0 comments on commit 73b0114

Please sign in to comment.