Skip to content

Commit

Permalink
Third exercise
Browse files Browse the repository at this point in the history
  • Loading branch information
Rob Gardner committed Jun 2, 2024
1 parent 9e81ec6 commit 2f0bb54
Show file tree
Hide file tree
Showing 8 changed files with 252 additions and 10 deletions.
1 change: 1 addition & 0 deletions TheBalladOfAllanMush/Ventures/II - Edison/ISteering.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ namespace TheBalladOfAllanMush.Ventures.II___Edison
public interface ISteering
{
Task<bool> AttemptSteering(Direction direction);
Task<bool> SteeringOverride(Direction direction);
}
}
13 changes: 13 additions & 0 deletions TheBalladOfAllanMush/Ventures/III - GalaxyZ/IAlertService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TheBalladOfAllanMush.Ventures.III___GalaxyZ
{
public interface IAlertService
{
public Task EnterAlertState(string alertLevel);
}
}
17 changes: 17 additions & 0 deletions TheBalladOfAllanMush/Ventures/III - GalaxyZ/ILifeSupportService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TheBalladOfAllanMush.Ventures.III___GalaxyZ
{
public interface ILifeSupportService
{
public Task<List<string>> TestMainPower();
public Task<List<string>> TestAuxPower();
public Task<List<string>> TestOxygen();
public Task<List<string>> TestTemperature();
public Task RebootLifeSupport();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TheBalladOfAllanMush.Ventures.III___GalaxyZ
{
public interface IRocketTelemetryService
{
public Task<int> GetFuelLinePressureById(string Id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ namespace TheBalladOfAllanMush.Ventures.III___GalaxyZ.Models
{
public class Rocket
{
public List<Booster> Engines { get; set; } = new();
public List<Booster>? Engines { get; set; } = new();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using TheBalladOfAllanMush.Ventures.III___GalaxyZ.Models;
Expand All @@ -14,12 +15,21 @@ namespace TheBalladOfAllanMush.Ventures.III___GalaxyZ
public class RocketDiagnosticService
{
private IRocketIgnitionService RocketIgnitionService { get; }
private IRocketTelemetryService RocketTelemetryService { get; }
private ILifeSupportService LifeSupportService { get; }
private IAlertService AlertService { get; }

public RocketDiagnosticService(
IRocketIgnitionService rocketIgnitionService
IRocketIgnitionService rocketIgnitionService,
IRocketTelemetryService rocketTelemetryService,
ILifeSupportService lifeSupportService,
IAlertService alertService
)
{
{
RocketIgnitionService = rocketIgnitionService;
RocketTelemetryService = rocketTelemetryService;
LifeSupportService = lifeSupportService;
AlertService = alertService;
}

/// <summary>
Expand Down Expand Up @@ -47,5 +57,40 @@ public async Task<int> IgniteEnginesAndCountAsync(Rocket rocket)

return count;
}

public async Task<int?> ReportFuelLinePressure(string fuelLineId)
{
if (fuelLineId == "TEST DATA - REMOVE LATER")
{
if(string.IsNullOrEmpty(fuelLineId))
throw new ArgumentException("Empty string");

return await RocketTelemetryService.GetFuelLinePressureById(fuelLineId);
}

return 1;
}

public async Task<List<string>> TestLifeSupport()
{
var warningMessages = new List<string>();

try
{
warningMessages.AddRange(await LifeSupportService.TestMainPower());
warningMessages.AddRange(await LifeSupportService.TestMainPower());
warningMessages.AddRange(await LifeSupportService.TestOxygen());
warningMessages.AddRange(await LifeSupportService.TestTemperature());
}
catch (ArgumentException e)
{
throw new ExecutionEngineException("Lifesupport offline", e);
}

if (!warningMessages.Any())
await AlertService.EnterAlertState("Amber");

return warningMessages;
}
}
}
29 changes: 29 additions & 0 deletions UserServiceTests/II - Edison/TrolleyProblem.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Implement a new class called TrolleyProblem.cs in the "II - Edison" folder.

This class will consume ISelfDriveService and ISteering as a dependency.

There will be one public method in the new class named "MinimiseCasualties".

This method will be asynchronous and return a Task<Direction>.
It will take a collection (list) of Pedestrians as an input.

The behaviour of this method has the following requirements-

It calls ISelfDriveService.AccelerateToSpeed with a target speed of 30.

For each pedestrian in our collection, we call ISelfDriveService.AvoidPedestrian() on it.
We ignore any calls that return 'Center' (pedestrians behind).
We tally any calls that return left or right.

Once tallies are done, we call ISteering.SteeringOverride with the direction
that has the highest tally.

Eg. We have 3 returns from avoid pedestrian with Direction.Right
But we have only 2 returns from avoid pedestrian with Direction.Left

Therefore we call ISteering.OverrideSteering with Direction.Right
We then return the chosen direction.

In the event of a tie (equal tally of left and right), we throw a SelfDriveException .

Once you have written the class, verify its behaviour with unit tests.
138 changes: 131 additions & 7 deletions UserServiceTests/III - GalaxyZ/RocketDiagnosticServiceTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities;
using Moq;
using Moq;
using System;
using System.Collections.Generic;
using System.Linq;
Expand All @@ -11,11 +10,16 @@
namespace UnitTests.III___GalaxyZ
{
/// <summary>
/// Allan Mush was so impressed with your work squashing those bugs,
/// he bought you aboard his space faring venture!
/// Allan Mush has taken notice of your talent writing tests.
/// He's so impressed, he's promoted you as a dev on his space faring venture!
///
/// Sadly the friendly QA has been fired, but Allan has assured you that
/// everything will be fine. This time he wrote all the tests himself!
/// Since there's a critical launch tomorrow, all devs are crunching
/// to finish promised features and get a release out on time.
/// This has left no one any time to write tests!
///
/// When you voiced your concerns, Allan assured you that everything
/// will be fine. He sat down with his laptop last night and bashed out
/// the tests himself.
///
/// While working on smaller tasks for GalaxyZ, you start to get an
/// ominous feeling about the rocket launch tomorrow...
Expand All @@ -30,6 +34,36 @@ namespace UnitTests.III___GalaxyZ
public class RocketDiagnosticServiceTests
{
public Mock<IRocketIgnitionService> RocketIgnitionServiceMock { get; } = new();
public Mock<IRocketTelemetryService> RocketTelemetryServiceMock { get; } = new();
public Mock<ILifeSupportService> LifeSupportServiceMock { get; } = new();
public Mock<IAlertService> AlertServiceMock { get; } = new();

[Fact]
public async Task IgniteEnginesAndCount_RocketEnginesNull_ShouldNotThrow()
{
//arrange
var testRocket = new Rocket()
{
Engines = null
};

RocketIgnitionServiceMock.Setup(x => x.IgniteEngineAsync(It.IsAny<Booster>()))
.ReturnsAsync(false);

var sut = CreateTestService();

var result = 0;

//act
try
{
result = await sut.IgniteEnginesAndCountAsync(testRocket);
}
catch (Exception) { }

//assert
Assert.Equal(0, result);
}

[Fact]
public async Task IgniteEnginesAndCount_NoEnginesIgnite_ShouldReturnZero()
Expand Down Expand Up @@ -62,10 +96,100 @@ public async Task IgniteEnginesAndCount_NoEnginesIgnite_ShouldReturnZero()
Equals(0, result);
}

[Fact]
public async Task ReportFuelLinePressure_FuelLineIdEmpty_ShouldThrowError()
{
//arrange

var sut = CreateTestService();

//act

var exception = await sut.ReportFuelLinePressure(string.Empty);

//assert
Assert.NotNull(exception);
}

[Fact]
public async Task TestLifeSupport_AllServicesCheckedAndOK_ReturnsNoMessages()
{
//arrange
LifeSupportServiceMock.Setup(x => x.TestMainPower())
.ReturnsAsync(new List<string>());
LifeSupportServiceMock.Setup(x => x.TestAuxPower())
.ReturnsAsync(new List<string>());
LifeSupportServiceMock.Setup(x => x.TestTemperature())
.ReturnsAsync(new List<string>());
LifeSupportServiceMock.Setup(x => x.TestOxygen())
.ReturnsAsync(new List<string>());

var sut = CreateTestService();

//act
var result = await sut.TestLifeSupport();

//assert
Assert.Empty(result);
LifeSupportServiceMock.Verify(x => x.TestTemperature(), Times.Once);
LifeSupportServiceMock.Verify(x => x.TestOxygen(), Times.Once);
}

[Fact]
public async Task TestLifeSupport_LifeSupportThrowsInvalidOpException_RethrowsAsExecutionEngineException()
{
//arrange
await Task.Delay(1);

LifeSupportServiceMock.Setup(x => x.TestMainPower())
.ThrowsAsync(new InvalidOperationException());

var sut = CreateTestService();

//act
var exception = Record.ExceptionAsync(() => sut.TestLifeSupport());

//assert
Assert.NotNull(exception);
Assert.IsNotType<InvalidOperationException>(exception);
}

[Fact]
public async Task TestLifeSupport_LifeSupportHasNoWarnings_ShouldNotAlert()
{
//arrange
LifeSupportServiceMock.Setup(x => x.TestMainPower())
.ReturnsAsync(new List<string>());
LifeSupportServiceMock.Setup(x => x.TestAuxPower())
.ReturnsAsync(new List<string>());
LifeSupportServiceMock.Setup(x => x.TestTemperature())
.ReturnsAsync(new List<string>());
LifeSupportServiceMock.Setup(x => x.TestOxygen())
.ReturnsAsync(new List<string>());

AlertServiceMock.Setup(x => x.EnterAlertState(It.IsAny<string>()))
.Verifiable();

var sut = CreateTestService();

//act
var result = await sut.TestLifeSupport();

//assert
Assert.Empty(result);
AlertServiceMock.Verify(x => x.EnterAlertState(It.IsAny<string>()), Times.Never);
}

private RocketDiagnosticService CreateTestService()
{
return new RocketDiagnosticService(
RocketIgnitionServiceMock.Object);
RocketIgnitionServiceMock.Object,
RocketTelemetryServiceMock.Object,
LifeSupportServiceMock.Object,
MockAlertService.Object
);
}

Mock<IAlertService> MockAlertService { get; } = new();
}
}

0 comments on commit 2f0bb54

Please sign in to comment.