Skip to content

Commit

Permalink
(GH-33) Implemented command: t (Test) (#44)
Browse files Browse the repository at this point in the history
* (GH-33) Implemented command: t (Test)
  • Loading branch information
nils-a authored Aug 3, 2020
1 parent 45d514c commit 23bbec9
Show file tree
Hide file tree
Showing 23 changed files with 958 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@

using Xunit;

namespace Cake.SevenZip.Tests.Parsers
namespace Cake.SevenZip.Tests.Commands
{
public class AbstractOutputCommandTests
{
[Fact]
public void AbstractOutputCommand_sets_raw_output()
{
var command = new Mock<OutputCommand<object>>();
var parser = new Mock<IOutputParser<object>>();
var command = new Mock<OutputCommand<IOutput>>();
var parser = new Mock<IOutputParser<IOutput>>();
command.Setup(c => c.OutputParser).Returns(parser.Object);
var expected = new[] { "this", "was", "the", "output" };
var partialMock = command.Object;
Expand All @@ -30,8 +30,8 @@ public void AbstractOutputCommand_sets_raw_output()
[Fact]
public void AbstractOutputCommand_sets_nothing_when_called_with_null()
{
var command = new Mock<OutputCommand<object>>();
var parser = new Mock<IOutputParser<object>>();
var command = new Mock<OutputCommand<IOutput>>();
var parser = new Mock<IOutputParser<IOutput>>();
command.Setup(c => c.OutputParser).Returns(parser.Object);
var partialMock = command.Object;
string[] actual = null;
Expand All @@ -45,18 +45,18 @@ public void AbstractOutputCommand_sets_nothing_when_called_with_null()
[Fact]
public void AbstractOutputCommand_uses_parser_to_set_non_raw_output()
{
var expected = new object();
var command = new Mock<OutputCommand<object>>();
var parser = new Mock<IOutputParser<object>>();
parser.Setup(p => p.Parse(It.IsAny<string[]>())).Returns(expected);
var expected = new Mock<IOutput>();
var command = new Mock<OutputCommand<IOutput>>();
var parser = new Mock<IOutputParser<IOutput>>();
parser.Setup(p => p.Parse(It.IsAny<string[]>())).Returns(expected.Object);
command.Setup(c => c.OutputParser).Returns(parser.Object);
var partialMock = command.Object;
object actual = null;
partialMock.OutputAction = o => actual = o;

((ICanParseOutput)partialMock).SetRawOutput(new string[] { });

actual.Should().Be(expected);
actual.Should().Be(expected.Object);
}
}
}
40 changes: 40 additions & 0 deletions src/Cake.7zip.Tests/Commands/GeneralOutputCommandTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;
using System.Collections;
using System.Collections.Generic;

using Cake.SevenZip.Commands;
using Cake.SevenZip.Parsers;

using FluentAssertions;

using Xunit;

namespace Cake.SevenZip.Tests.Commands
{
public class GeneralOutputCommandTests
{
[Theory]
[ClassData(typeof(TestData))]
public void OutputCommand_uses_its_own_parser<T>(OutputCommand<T> command, Type expectedParserType)
where T : IOutput
{
var actual = command.OutputParser;
actual.Should().NotBeNull();
actual.Should().BeOfType(expectedParserType);
}

private class TestData : IEnumerable<object[]>
{
public IEnumerator<object[]> GetEnumerator()
{
yield return new object[] { new InformationCommand(), typeof(InformationOutputParser) };
yield return new object[] { new TestCommand(), typeof(TestOutputParser) };
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
}
36 changes: 36 additions & 0 deletions src/Cake.7zip.Tests/Fixtures/Outputs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,41 @@ 0 8 4 CRC64
return demoOutput.ToArrayOfLines();
}
}

public static string[] Test
{
get
{
const string testOutput = @"
7-Zip 19.00 (x64) : Copyright (c) 1999-2018 Igor Pavlov : 2019-02-21
Scanning the drive for archives:
2 files, 2201618 bytes (2151 KiB)
Testing archive: foo.zip
ERROR: foo.zip
foo.zip
Open ERROR: Can not open the file as [zip] archive
ERRORS:
Is not archive
Testing archive: .\nested.zip
--
Path = .\nested.zip
Type = zip
Physical Size = 2198368
Everything is Ok
Archives: 2
OK archives: 1
Can't open as archive: 1
Files: 3
Size: 2359279
Compressed: 2198368";
return testOutput.ToArrayOfLines();
}
}
}
}
59 changes: 50 additions & 9 deletions src/Cake.7zip.Tests/FluentBuilder/BaseOutputBuilderTest.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;

using Cake.SevenZip.Builder;
using Cake.SevenZip.Commands;
using Cake.SevenZip.Parsers;

using FluentAssertions;

Expand All @@ -12,14 +14,13 @@

namespace Cake.SevenZip.Tests.FluentBuilder
{
[SuppressMessage("ReSharper", "InconsistentNaming", Justification = "I like my 'local functions' camelCase.")]
public class BaseOutputBuilderTest
{
[Fact]
public void WithCommandOutput_returns_the_builder()
{
var expected = new MockOutputBuilder();
var command = new Mock<OutputCommand<object>>();
var command = new Mock<OutputCommand<IOutput>>();
expected.MockCommand = command.Object;

var actual = expected.WithCommandOutput(null);
Expand All @@ -31,7 +32,7 @@ public void WithCommandOutput_returns_the_builder()
public void WithCommandRawOutput_returns_the_builder()
{
var expected = new MockOutputBuilder();
var command = new Mock<OutputCommand<object>>();
var command = new Mock<OutputCommand<IOutput>>();
expected.MockCommand = command.Object;

var actual = expected.WithCommandRawOutput(null);
Expand All @@ -43,7 +44,7 @@ public void WithCommandRawOutput_returns_the_builder()
public void WithCommandOutput_sets_the_outputAction_on_the_command()
{
var builder = new MockOutputBuilder();
var command = new Mock<OutputCommand<object>>();
var command = new Mock<OutputCommand<IOutput>>();
builder.MockCommand = command.Object;
Action<object> expected = x => { };

Expand All @@ -56,7 +57,7 @@ public void WithCommandOutput_sets_the_outputAction_on_the_command()
public void WithCommandRawOutput_sets_the_rawOutputAction_on_the_command()
{
var builder = new MockOutputBuilder();
var command = new Mock<OutputCommand<object>>();
var command = new Mock<OutputCommand<IOutput>>();
builder.MockCommand = command.Object;
Action<object> expected = x => { };

Expand All @@ -65,10 +66,50 @@ public void WithCommandRawOutput_sets_the_rawOutputAction_on_the_command()
command.Object.RawOutputAction.Should().Be(expected);
}

private class MockOutputBuilder : BaseOutputBuilder<MockOutputBuilder, object>
[Fact]
public void All_outputBuilders_are_implementing_the_interface()
{
var baseOutputCommandType = typeof(OutputCommand<>);
var outputCommandTypes = baseOutputCommandType.Assembly.GetTypes().Where(t =>
{
if (t.BaseType == null) // isn't this "object" as a "minimum" and never null?
{
return false;
}

if (!t.BaseType.IsGenericType)
{
return false;
}

return t.BaseType.GetGenericTypeDefinition() == baseOutputCommandType;
});

foreach (var commandType in outputCommandTypes)
{
var builderTypeName = commandType.Name + "Builder";
var builderType = baseOutputCommandType.Assembly.GetTypes().Single(t => t.Name == builderTypeName);
var expected = Activator.CreateInstance(commandType);
var builder = builderType.GetConstructor(
BindingFlags.Instance | BindingFlags.NonPublic,
null,
new[] { commandType.MakeByRefType() },
null).Invoke(new[] { expected });

var commandProperty = builderType.BaseType
.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic)
.Single();
var commandPropertyGetter = commandProperty.GetMethod;
var actual = commandPropertyGetter.Invoke(builder, new object[0]);

actual.Should().Be(expected);
}
}

private class MockOutputBuilder : BaseOutputBuilder<MockOutputBuilder, IOutput>
{
public OutputCommand<object> MockCommand { private get; set; }
protected override OutputCommand<object> OutputCommand => MockCommand;
public OutputCommand<IOutput> MockCommand { private get; set; }
protected override OutputCommand<IOutput> OutputCommand => MockCommand;
}
}
}
Loading

0 comments on commit 23bbec9

Please sign in to comment.