Skip to content

Commit

Permalink
refactor: Start of simple rewrite with fluent api in mind
Browse files Browse the repository at this point in the history
  • Loading branch information
JoshHiles committed Jan 8, 2024
1 parent f529002 commit 24cf9bb
Show file tree
Hide file tree
Showing 17 changed files with 616 additions and 862 deletions.
60 changes: 60 additions & 0 deletions Scientist.Test/Comparison/ComparisonTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using FakeItEasy;
using Scientist.Test.Helpers;
using System;

namespace Scientist.Test.Comparison
{
public class ComparisonTests
{
[Test]
public void OverrideComparison()
{
var testMethods = A.Fake<ITestClass<ComplexResult>>();

var complexResult = A.Fake<ComplexResult>();
complexResult.Name = "Tester";
complexResult.Count = 10;
A.CallTo(() => testMethods.Control()).Returns(complexResult);
A.CallTo(() => testMethods.Candidate()).Returns(complexResult);

var result = new Experiment<ComplexResult>(
name: nameof(OverrideComparison),
control: testMethods.Control,
throwOnMismatch: true
)
.AddCandidate(testMethods.Candidate)
.Compare((a, b) => a.Count == b.Count && a.Name == b.Name)
.Run();

A.CallTo(() => testMethods.Control()).MustHaveHappened();
A.CallTo(() => testMethods.Candidate()).MustHaveHappened();
result.Should().Be(complexResult);
}

[Test]
public void ThrowMismatchOnOverrideComparison()
{
var testMethods = A.Fake<ITestClass<ComplexResult>>();

var complexResult = A.Fake<ComplexResult>();
complexResult.Name = "Tester";
complexResult.Count = 10;
A.CallTo(() => testMethods.Control()).Returns(complexResult);
A.CallTo(() => testMethods.Candidate()).Returns(complexResult);

Action act = () => new Experiment<ComplexResult>(
name: nameof(ThrowMismatchOnOverrideComparison),
control: testMethods.Control,
throwOnMismatch: true
)
.AddCandidate(testMethods.Candidate)
.Compare((a, b) => a.Count == 2 && a.Name == b.Name)
.Run();

act.Should().Throw<MismatchException<ComplexResult>>()
.WithMessage($"Experiment '{nameof(ThrowMismatchOnOverrideComparison)}' observations mismatched");
A.CallTo(() => testMethods.Control()).MustHaveHappened();
A.CallTo(() => testMethods.Candidate()).MustHaveHappened();
}
}
}
111 changes: 111 additions & 0 deletions Scientist.Test/Experiment/ExperimentTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using FakeItEasy;
using Scientist.Test.Helpers;
using System;

namespace Scientist.Test.Experiment
{
public class ExperimentTests
{
[Test]
public void WithoutACandidate()
{
int actualResult = 42;

var testMethods = A.Fake<ITestClass<int>>();
A.CallTo(() => testMethods.Control()).Returns(actualResult);
A.CallTo(() => testMethods.Candidate()).Returns(actualResult);

var result = new Experiment<int>(name: nameof(WithoutACandidate), control: testMethods.Control, throwOnMismatch: true).Run();

A.CallTo(() => testMethods.Control()).MustHaveHappened();
result.Should().Be(actualResult);
}

[Test]
public void WithACandidate()
{
int actualResult = 42;

var testMethods = A.Fake<ITestClass<int>>();
A.CallTo(() => testMethods.Control()).Returns(actualResult);
A.CallTo(() => testMethods.Candidate()).Returns(actualResult);

var result = new Experiment<int>(name: nameof(WithACandidate), control: testMethods.Control, throwOnMismatch: true).AddCandidate(testMethods.Candidate)
.Run();

A.CallTo(() => testMethods.Control()).MustHaveHappened();
A.CallTo(() => testMethods.Candidate()).MustHaveHappened();
result.Should().Be(actualResult);
}

[Test]
public void WithMultipleCandidates()
{
int actualResult = 42;

var testMethods = A.Fake<ITestClass<int>>();
var fakeCandidate = A.Fake<Func<int>>();
A.CallTo(() => testMethods.Control()).Returns(actualResult);
A.CallTo(() => testMethods.Candidate()).Returns(actualResult);
A.CallTo(() => fakeCandidate()).Returns(actualResult);

var result = new Experiment<int>(
name: nameof(WithMultipleCandidates),
control: testMethods.Control, throwOnMismatch: true)
.AddCandidate(testMethods.Candidate)
.AddCandidate(fakeCandidate)
.Run();

A.CallTo(() => testMethods.Control()).MustHaveHappened();
A.CallTo(() => testMethods.Candidate()).MustHaveHappened();
A.CallTo(() => fakeCandidate()).MustHaveHappened();
result.Should().Be(actualResult);
}

[Test]
public void ThrowOnMismatch()
{
int actualResult = 42;

var testMethods = A.Fake<ITestClass<int>>();
var fakeCandidate = A.Fake<Func<int>>();
A.CallTo(() => testMethods.Control()).Returns(actualResult);
A.CallTo(() => testMethods.Candidate()).Returns(33);
A.CallTo(() => fakeCandidate()).Returns(21);

Action act = () => new Experiment<int>(
name: nameof(ThrowOnMismatch),
control: testMethods.Control, throwOnMismatch: true)
.AddCandidate(testMethods.Candidate)
.AddCandidate(testMethods.Candidate)
.Run();

act.Should().Throw<MismatchException<int>>()
.WithMessage($"Experiment '{nameof(ThrowOnMismatch)}' observations mismatched");
A.CallTo(() => testMethods.Control()).MustHaveHappened();
A.CallTo(() => testMethods.Candidate()).MustHaveHappened();
}


[Test]
public void ThrowOnMismatchTurnedOffDoesntThrow()
{
int actualResult = 42;

var testMethods = A.Fake<ITestClass<int>>();
var fakeCandidate = A.Fake<Func<int>>();
A.CallTo(() => testMethods.Control()).Returns(actualResult);
A.CallTo(() => testMethods.Candidate()).Returns(33);

Action act = () => new Experiment<int>(
name: nameof(ThrowOnMismatchTurnedOffDoesntThrow),
control: testMethods.Control)
.AddCandidate(testMethods.Candidate)
.Run();

act.Should().NotThrow<MismatchException<int>>();
A.CallTo(() => testMethods.Control()).MustHaveHappened();
A.CallTo(() => testMethods.Candidate()).MustHaveHappened();
}
}
}
2 changes: 2 additions & 0 deletions Scientist.Test/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
global using NUnit.Framework;
global using FluentAssertions;
22 changes: 22 additions & 0 deletions Scientist.Test/Helpers/ComplexResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Scientist.Test.Helpers
{
public class ComplexResult : IEquatable<ComplexResult>
{
public int Count { get; set; }
public string Name { get; set; }

public bool Equals(ComplexResult other)
{
if (other == null)
return false;

return Count == other.Count && Name == other.Name;
}
}
}
14 changes: 14 additions & 0 deletions Scientist.Test/Helpers/ITestClass.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Scientist.Test.Helpers
{
public interface ITestClass<T>
{
T Control();
T Candidate();
}
}
14 changes: 14 additions & 0 deletions Scientist.Test/Publishing/PublishingTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Scientist.Test.Publishing
{
public class PublishingTests
{
[Test]
public void DefaultPublisher() { }

[Test]
public void CustomPublisher() { }

[Test]
public void FireAndForget() { }
}
}
54 changes: 54 additions & 0 deletions Scientist.Test/RunIf/RunIfTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using FakeItEasy;
using Scientist.Test.Helpers;
using System;

namespace Scientist.Test.RunIf
{
public class RunIfTests
{

[Test]
public void RunIfFalse()
{
int actualResult = 42;

var testMethods = A.Fake<ITestClass<int>>();
var runIf = A.Fake<Func<bool>>();
A.CallTo(() => testMethods.Control()).Returns(actualResult);
A.CallTo(() => runIf()).Returns(false);

var result = new Experiment<int>(
name: nameof(RunIfFalse),
control: testMethods.Control)
.AddCandidate(testMethods.Candidate)
.RunIf(runIf);

A.CallTo(() => testMethods.Control()).MustHaveHappened();
A.CallTo(() => runIf()).MustHaveHappened();
A.CallTo(() => testMethods.Candidate()).MustNotHaveHappened();
result.Should().Be(actualResult);
}

[Test]
public void RunIfTrue()
{
int actualResult = 42;

var testMethods = A.Fake<ITestClass<int>>();
var runIf = A.Fake<Func<bool>>();
A.CallTo(() => testMethods.Control()).Returns(actualResult);
A.CallTo(() => runIf()).Returns(true);

var result = new Experiment<int>(
name: nameof(RunIfTrue),
control: testMethods.Control)
.AddCandidate(testMethods.Candidate)
.RunIf(runIf);

A.CallTo(() => testMethods.Control()).MustHaveHappened();
A.CallTo(() => runIf()).MustHaveHappened();
A.CallTo(() => testMethods.Candidate()).MustHaveHappened();
result.Should().Be(actualResult);
}
}
}
23 changes: 14 additions & 9 deletions Scientist.Test/Scientist.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.msbuild" Version="3.1.0">
<PackageReference Include="coverlet.msbuild" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="5.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.0">
<PackageReference Include="FakeItEasy" Version="8.1.0" />
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="NUnit" Version="4.0.1" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
<PackageReference Include="coverlet.collector" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand All @@ -30,6 +31,10 @@
<ProjectReference Include="..\Scientist\Scientist.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="Context\" />
</ItemGroup>

<PropertyGroup>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>
Expand Down
14 changes: 0 additions & 14 deletions Scientist.Test/Scientist.cs

This file was deleted.

Loading

0 comments on commit 24cf9bb

Please sign in to comment.