public void IgnoreOperation() { const int expectedResult = 42; var mock = Substitute.For <IControlCandidate <int> >(); mock.Control().Returns(expectedResult); mock.Candidate().Returns(0); var ex = new Exception(); var result = Scientist.Science <int>(nameof(IgnoreOperation), experiment => { experiment.Thrown(mock.Thrown); experiment.Ignore((x, y) => { throw ex; }); experiment.Use(mock.Control); experiment.Try(mock.Candidate); }); Assert.Equal(expectedResult, result); mock.Received().Thrown(Operation.Ignore, ex); }
public void ThrowsMismatchException() { var mock = Substitute.For <IControlCandidate <int> >(); mock.Control().Returns(x => 1); mock.Candidate().Returns(x => 2); const string experimentName = nameof(ThrowsMismatchException); var ex = Assert.Throws <AggregateException>(() => { Scientist.Science <int>(experimentName, experiment => { experiment.ThrowOnMismatches = true; experiment.Use(mock.Control); experiment.Try(mock.Candidate); }); }); Exception baseException = ex.GetBaseException(); Assert.IsType <MismatchException <int, int> >(baseException); mock.Received().Control(); mock.Received().Candidate(); var result = TestHelper.Results <int>(experimentName).First(); var mismatchException = (MismatchException <int, int>)baseException; Assert.Equal(experimentName, mismatchException.Name); Assert.Same(result, mismatchException.Result); }
public void KeepingItClean() { const int expectedResult = 42; const string expectedCleanResult = "Forty Two"; var mock = Substitute.For <IControlCandidate <int, string> >(); mock.Control().Returns(expectedResult); mock.Candidate().Returns(0); mock.Clean(expectedResult).Returns(expectedCleanResult); var result = Scientist.Science <int, string>(nameof(KeepingItClean), experiment => { experiment.Use(mock.Control); experiment.Try(mock.Candidate); experiment.Clean(mock.Clean); }); Assert.Equal(expectedResult, result); // Make sure that the observations aren't cleaned unless called explicitly. mock.DidNotReceive().Clean(expectedResult); Assert.Equal( expectedCleanResult, TestHelper.Results <int, string>(nameof(KeepingItClean)).First().Control.CleanedValue); mock.Received().Clean(expectedResult); }
static void Main(string[] args) { var repository = new AtendeeRepository(); var smtpGateway = new SmtpEmailGateway(); var cloudGateway = new CloudEmailServiceGateway(); Scientist.ResultPublisher = new ConsolePublisher(); var atendeesToNotify = repository.GetAll(); foreach (var atendee in atendeesToNotify) { //bool isValidEmail = smtpGateway.IsValidEmail(atendee.Email); bool isValidEmail = Scientist.Science <bool>("Cloud-email-gatway", experiment => { experiment.Use(() => smtpGateway.IsValidEmail(atendee.Email)); experiment.Try(() => cloudGateway.ValidateEmailAddres(atendee.Email)); }); if (isValidEmail) { smtpGateway.Send(atendee.Email, "Hello, our event will be held at Youtube on the 29th August"); } else { Console.WriteLine($"Cannot send mail to {atendee.FirstName}, the email addres is invalid"); } } }
public void ScientistDisablesExperiment() { const int expectedResult = 42; var mock = Substitute.For <IControlCandidate <int> >(); mock.Control().Returns(expectedResult); mock.Candidate().Returns(0); var settings = Substitute.For <IScientistSettings>(); settings.Enabled().Returns(Task.FromResult(false)); using (Swap.Enabled(settings.Enabled)) { var result = Scientist.Science <int>(nameof(ScientistDisablesExperiment), experiment => { experiment.Use(mock.Control); experiment.Try(mock.Candidate); }); Assert.Equal(expectedResult, result); mock.DidNotReceive().Candidate(); mock.Received().Control(); settings.Received().Enabled(); } }
public void AllTrysAreRun() { var mock = Substitute.For <IControlCandidate <int> >(); mock.Control().Returns(42); mock.Candidate().Returns(42); var mockTwo = Substitute.For <IControlCandidate <int> >(); mockTwo.Candidate().Returns(42); var mockThree = Substitute.For <IControlCandidate <int> >(); mockThree.Candidate().Returns(42); const string experimentName = nameof(AllTrysAreRun); var result = Scientist.Science <int>(experimentName, experiment => { experiment.Use(mock.Control); experiment.Try("candidate one", mock.Candidate); experiment.Try("candidate two", mockTwo.Candidate); experiment.Try("candidate three", mockThree.Candidate); }); Assert.Equal(42, result); mock.Received().Candidate(); mockTwo.Received().Candidate(); mockThree.Received().Candidate(); }
public void SingleCandidateDifferenceCausesMismatch() { var mock = Substitute.For <IControlCandidate <int> >(); mock.Control().Returns(42); mock.Candidate().Returns(42); var mockTwo = Substitute.For <IControlCandidate <int> >(); mockTwo.Candidate().Returns(42); var mockThree = Substitute.For <IControlCandidate <int> >(); mockThree.Candidate().Returns(0); const string experimentName = nameof(SingleCandidateDifferenceCausesMismatch); var result = Scientist.Science <int>(experimentName, experiment => { experiment.Use(mock.Control); experiment.Try("candidate one", mock.Candidate); experiment.Try("candidate two", mockTwo.Candidate); experiment.Try("candidate three", mockThree.Candidate); }); Assert.Equal(42, result); Assert.False(TestHelper.Results <int>(experimentName).First().Matched); }
public void EnabledOperation() { var settings = Substitute.For <IScientistSettings>(); var ex = new Exception(); settings.Enabled().Throws(ex); using (Swap.Enabled(settings.Enabled)) { const int expectedResult = 42; var mock = Substitute.For <IControlCandidate <int> >(); mock.Control().Returns(expectedResult); mock.Candidate().Returns(0); var result = Scientist.Science <int>(nameof(EnabledOperation), experiment => { experiment.Thrown(mock.Thrown); experiment.Use(mock.Control); experiment.Try(mock.Candidate); }); Assert.Equal(expectedResult, result); mock.Received().Thrown(Operation.Enabled, ex); } }
public void DefaultThrow() { var mock = Substitute.For <IControlCandidate <int> >(); var ex = new Exception(); Action action = () => Scientist.Science <int>(nameof(DefaultThrow), experiment => { experiment.Compare((x, y) => { throw ex; }); experiment.Use(mock.Control); experiment.Try(mock.Candidate); }); var exception = Assert.Throws <AggregateException>(action); var operationException = Assert.IsType <OperationException>(exception.InnerException); Assert.Equal(Operation.Compare, operationException.Operation); var actualException = Assert.IsType <Exception>(operationException.InnerException); Assert.Equal(ex, actualException); }
public void SingleContextIncludedWithPublish() { var mock = Substitute.For <IControlCandidate <int> >(); mock.Control().Returns(42); mock.Candidate().Returns(42); const string experimentName = nameof(SingleContextIncludedWithPublish); var result = Scientist.Science <int>(experimentName, e => { e.Use(mock.Control); e.Try(mock.Candidate); e.AddContext("test", "data"); }); var publishResults = TestHelper.Results <int>(experimentName).First(); Assert.Equal(42, result); Assert.Equal(1, publishResults.Contexts.Count); var context = publishResults.Contexts.First(); Assert.Equal("test", context.Key); Assert.Equal("data", context.Value); }
public IActionResult Exception([Required] string numbers) { if (!ModelState.IsValid) { return(View(numbers)); } var list = new List <int>(); foreach (var n in numbers.Split(',', StringSplitOptions.RemoveEmptyEntries)) { if (int.TryParse(n, out var result)) { list.Add(result); } } var resultSummary = Scientist.Science <Result>("Math", experiment => { experiment.Compare((x, y) => x.Largest == y.Largest && Math.Abs(x.Average - y.Average) < .5 && x.Smallest == y.Smallest && x.Sum == y.Sum); experiment.Use(() => OldApi.Math.Summary(list.ToArray())); experiment.Try(() => throw new Exception("Oh Oh Spaghettios")); }); ViewData.Add("Result", ((ResultPublisher)Scientist.ResultPublisher).Result); return(View(resultSummary)); }
public void ContextReturnsComplexObjectInPublish() { var mock = Substitute.For <IControlCandidate <int> >(); mock.Control().Returns(42); mock.Candidate().Returns(42); const string experimentName = nameof(ContextReturnsComplexObjectInPublish); var testTime = DateTime.UtcNow; var result = Scientist.Science <int>(experimentName, e => { e.Use(mock.Control); e.Try(mock.Candidate); e.AddContext("test", new { Id = 1, Name = "name", Date = testTime }); }); var publishResults = TestHelper.Results <int>(experimentName).First(); Assert.Equal(42, result); Assert.Equal(1, publishResults.Contexts.Count); var context = publishResults.Contexts.First(); Assert.Equal("test", context.Key); Assert.Equal(1, context.Value.Id); Assert.Equal("name", context.Value.Name); Assert.Equal(testTime, context.Value.Date); }
public async Task HandlesExceptionsThrownImmediatelyByInnerPublisher() { const int expectedResult = 42; var exceptionToThrow = new PublishException(); var exceptionsThrown = new List <Exception>(); var innerPublisher = Substitute.For <IResultPublisher>(); innerPublisher.Publish(Arg.Any <Result <int, int> >()) .Throws(exceptionToThrow); var fireAndForgetPublisher = new FireAndForgetResultPublisher(innerPublisher, ex => { exceptionsThrown.Add(ex); }); var mock = Substitute.For <IControlCandidate <int, string> >(); mock.Control().Returns(expectedResult); mock.Candidate().Returns(expectedResult); using (Swap.Publisher(fireAndForgetPublisher)) { var result = Scientist.Science <int>("myExperiment", experiment => { experiment.Use(mock.Control); experiment.Try(mock.Candidate); }); } await fireAndForgetPublisher.WhenPublished(); Assert.Equal(new List <Exception> { exceptionToThrow }, exceptionsThrown); }
public void RunsBothBranchesOfTheExperimentWithResultComparisonSetAndReportsFailure() { var mock = Substitute.For <IControlCandidate <ComplexResult> >(); mock.Control().Returns(new ComplexResult { Count = 10, Name = "Tester" }); mock.Candidate().Returns(new ComplexResult { Count = 10, Name = "Tester2" }); const string experimentName = nameof(RunsBothBranchesOfTheExperimentWithResultComparisonSetAndReportsFailure); var result = Scientist.Science <ComplexResult>(experimentName, experiment => { experiment.Compare((a, b) => a.Count == b.Count && a.Name == b.Name); experiment.Use(mock.Control); experiment.Try("candidate", mock.Candidate); }); Assert.Equal(10, result.Count); Assert.Equal("Tester", result.Name); mock.Received().Control(); mock.Received().Candidate(); Assert.False(TestHelper.Results <ComplexResult>(experimentName).First().Matched); }
public void PublishOperation() { var publisher = Substitute.For <IResultPublisher>(); var ex = new Exception(); publisher.Publish(Arg.Any <Result <int, int> >()).Throws(ex); using (Swap.Publisher(publisher)) { const int expectedResult = 42; var mock = Substitute.For <IControlCandidate <int> >(); mock.Control().Returns(expectedResult); mock.Candidate().Returns(0); var result = Scientist.Science <int>(nameof(PublishOperation), experiment => { experiment.Thrown(mock.Thrown); experiment.Use(mock.Control); experiment.Try(mock.Candidate); }); Assert.Equal(expectedResult, result); mock.Received().Thrown(Operation.Publish, ex); } }
public void EnsureNullGuardIsWorking() { #if !DEBUG Assert.Throws <ArgumentNullException>(() => Scientist.Science <object>(null, _ => { }) ); #endif }
public int Subtract(int x, int y) { return(Scientist.Science <int>("calculator.subtract", experiment => { experiment.Use(() => reference.Subtract(x, y)); experiment.Try(() => observation.Subtract(x, y)); })); }
public int Add(int x, int y) { return(Scientist.Science <int>("calculator.add", experiment => { experiment.Use(() => reference.Add(x, y)); experiment.Try(() => observation.Add(x, y)); })); }
public static bool IsMeme(string phrase) { // Runs and returns the control // Runs the experiment as well (but does not return it) return(Scientist.Science <bool>("recording-results-example", experiment => { experiment.Use(() => MemeBot2000.IsMeme(phrase)); // Control experiment.Try(() => MemeBot3000.IsMeme(phrase)); // Candidate })); }
public IEnumerable <WeatherForecast> Get() { return(Scientist.Science <IEnumerable <WeatherForecast> >("weather-report", experiment => { experiment.Compare((original, _new) => Serialize(original) == Serialize(_new)); experiment.Use(OriginalForecast); experiment.Try(NewForecast); })); }
public User ProcessUserExperiment(int userID) { var user = Scientist.Science <User>("ProcessUserExperiment", experiment => { experiment.Use(() => ProcessUser(userID)); experiment.Try(() => InitialiseUser(userID)); }); return(user); }
public ActionResult Index() { var permissions = Scientist.Science <IEnumerable <Permission> >("Permissions", experiment => { experiment.Compare((x, y) => x.SequenceEqual(y)); experiment.Use(() => db.GetApplicationPermissionsV1().ToList()); experiment.Try(() => db.GetApplicationPermissionsV3().ToList()); }); return(View(permissions)); }
public void AllowsReturningNullFromControlOrTest() { var result = Scientist.Science <object>("failure", experiment => { experiment.Use(() => null); experiment.Try(() => null); }); Assert.Null(result); Assert.True(TestHelper.Observation.First(m => m.Name == "failure").Success); }
public static bool IsMeme(string phrase) { return(Scientist.Science <bool>("adding-context-example", experiment => { // If you add context here... experiment.AddContext("phrase", phrase); experiment.AddContext("when", DateTimeOffset.Now); experiment.Use(() => MemeBot2000.IsMeme(phrase)); // Control experiment.Try(() => MemeBot3000.IsMeme(phrase)); // Candidate })); }
public async Task PublishesAsynchronously() { const int expectedResult = 42; var pendingPublishTask = new TaskCompletionSource <object>(); // Create a new publisher that will delay all // publishing to account for this test. var innerPublisher = Substitute.For <IResultPublisher>(); innerPublisher.Publish(Arg.Any <Result <int, int> >()) .Returns(call => pendingPublishTask.Task); var fireAndForgetPublisher = new FireAndForgetResultPublisher(innerPublisher, ex => { }); var mock = Substitute.For <IControlCandidate <int, string> >(); mock.Control().Returns(expectedResult); mock.Candidate().Returns(expectedResult); const int count = 10; using (Swap.Publisher(fireAndForgetPublisher)) { Parallel.ForEach( Enumerable.Repeat(0, count), src => { var result = Scientist.Science <int>("myExperiment", experiment => { experiment.Use(mock.Control); experiment.Try(mock.Candidate); }); Assert.Equal(expectedResult, result); }); } // Make sure that the above science calls are still publishing. Task whenPublished = fireAndForgetPublisher.WhenPublished(); Assert.NotNull(whenPublished); // Ensure that the mock was called before the when published task has completed. mock.Received(count).Control(); mock.Received(count).Candidate(); Assert.False(whenPublished.IsCompleted, "When Published Task completed early."); pendingPublishTask.SetResult(null); await whenPublished; Assert.True(whenPublished.IsCompleted, "When Published Task isn't complete."); }
public void AllowsReturningNullFromControlOrTest() { const string experimentName = nameof(AllowsReturningNullFromControlOrTest); var result = Scientist.Science <object>(experimentName, experiment => { experiment.Use(() => null); experiment.Try("candidate", () => null); }); Assert.Null(result); Assert.True(TestHelper.Results <object>(experimentName).First().Matched); }
public static bool IsMeme(string phrase) { // Runs and returns the control // Runs the experiment as well (but does not return it) // Note! This doesn't actually output or record anything about the experiment. // To see how that's done, look at 02-RecordingResultsExample.cs. return(Scientist.Science <bool>("basic-example", experiment => { experiment.Use(() => MemeBot2000.IsMeme(phrase)); // Control experiment.Try(() => MemeBot3000.IsMeme(phrase)); // Candidate })); }
private static int GetResultWithScientist(int randomInput) { int result = Scientist.Science <int>("First experiment", experiment => { experiment.AddContext("Random Data", randomInput); experiment.Use(() => new ComplicatedCalc_V1().GetResult(randomInput)); // Old Version experiment.Try(() => new ComplicatedCalc_V2().GetResult(randomInput)); // New Version }); return(result); }
public void NoCandidateMeansNoPublish() { const string experimentName = "noCandidateNoPublish"; var result = Scientist.Science <int>(experimentName, experiment => { experiment.Use(() => 42); }); // verify that no results were published for this experiment Assert.Empty(TestHelper.Results <int>(experimentName)); }
public InventoryResult Post([FromBody] Inventory value) { Scientist.ResultPublisher = new MyResultPublisher(); return(Scientist.Science <InventoryResult>("VatIsCorrect", experiment => { experiment.Compare((x, y) => x.TotalPrice == y.TotalPrice); experiment.Use(() => _vatService.Result(value)); // old way experiment.Try(() => _vatService.NewResults(value)); // new way })); }