diff --git a/src/Machine.Specifications.Specs/Explorers/AssemblyExplorerSpecs.cs b/src/Machine.Specifications.Specs/Explorers/AssemblyExplorerSpecs.cs index 4d10d104b..39579d455 100644 --- a/src/Machine.Specifications.Specs/Explorers/AssemblyExplorerSpecs.cs +++ b/src/Machine.Specifications.Specs/Explorers/AssemblyExplorerSpecs.cs @@ -3,6 +3,7 @@ using System.Reflection; using Machine.Specifications.Explorers; using Machine.Specifications.Model; +using Machine.Specifications.Runner; using Machine.Specifications.Specs.Runner; namespace Machine.Specifications.Specs.Explorers @@ -181,4 +182,43 @@ public void OnAssemblyComplete() { } } + + public class TestContext : ITestContext + { + public void OnAssemblyStart(AssemblyInfo assembly) + { + } + + public void OnAssemblyEnd(AssemblyInfo assembly) + { + } + + public void OnRunStart() + { + } + + public void OnRunEnd() + { + } + + public void OnContextStart(ContextInfo context) + { + } + + public void OnContextEnd(ContextInfo context) + { + } + + public void OnSpecificationStart(SpecificationInfo specification) + { + } + + public void OnSpecificationEnd(SpecificationInfo specification, Result result) + { + } + + public void OnFatalError(ExceptionResult exception) + { + } + } } diff --git a/src/Machine.Specifications/Explorers/AssemblyExplorer.cs b/src/Machine.Specifications/Explorers/AssemblyExplorer.cs index 9a1008754..f0db97b3b 100644 --- a/src/Machine.Specifications/Explorers/AssemblyExplorer.cs +++ b/src/Machine.Specifications/Explorers/AssemblyExplorer.cs @@ -47,8 +47,15 @@ public IEnumerable FindSpecificationSupplements public IEnumerable FindAssemblyContextsIn(Assembly assembly) { return assembly.GetExportedTypes() - .Where(x => x.GetTypeInfo().IsClass && !x.GetTypeInfo().IsAbstract && x.GetInterfaces().Contains(typeof(IAssemblyContext))) - .Select(x => (IAssemblyContext)Activator.CreateInstance(x)); + .Where(x => x.GetTypeInfo().IsClass && !x.GetTypeInfo().IsAbstract && x.GetInterfaces().Contains(typeof(IAssemblyContext))) + .Select(x => (IAssemblyContext)Activator.CreateInstance(x)); + } + + public IEnumerable FindTestContextsIn(Assembly assembly) + { + return assembly.GetExportedTypes() + .Where(x => x.GetTypeInfo().IsClass && !x.GetTypeInfo().IsAbstract && x.GetInterfaces().Contains(typeof(ITestContext))) + .Select(x => (ITestContext)Activator.CreateInstance(x)); } Context CreateContextFrom(Type type) diff --git a/src/Machine.Specifications/ITestContext.cs b/src/Machine.Specifications/ITestContext.cs new file mode 100644 index 000000000..b2df56cbe --- /dev/null +++ b/src/Machine.Specifications/ITestContext.cs @@ -0,0 +1,8 @@ +using Machine.Specifications.Runner; + +namespace Machine.Specifications +{ + public interface ITestContext : ISpecificationRunListener + { + } +} diff --git a/src/Machine.Specifications/Runner/Impl/AssemblyRunner.cs b/src/Machine.Specifications/Runner/Impl/AssemblyRunner.cs index e37001372..3aac9b732 100644 --- a/src/Machine.Specifications/Runner/Impl/AssemblyRunner.cs +++ b/src/Machine.Specifications/Runner/Impl/AssemblyRunner.cs @@ -19,13 +19,16 @@ internal class AssemblyRunner readonly IList _executedAssemblyContexts; readonly AssemblyExplorer _explorer; + readonly TestContextListener _testContext; public AssemblyRunner(ISpecificationRunListener listener, RunOptions options) { - RedirectOutputState state = new RedirectOutputState(); + var state = new RedirectOutputState(); + _testContext = new TestContextListener(); _listener = new AggregateRunListener(new[] { new AssemblyLocationAwareListener(), + _testContext, new SetUpRedirectOutputRunListener(state), listener, new TearDownRedirectOutputRunListener(state), @@ -77,9 +80,12 @@ void OnAssemblyStart(Assembly assembly) { try { + var testContexts = _explorer.FindTestContextsIn(assembly); + _testContext.SetTestContexts(testContexts.ToList()); + _listener.OnAssemblyStart(assembly.GetInfo()); - IEnumerable assemblyContexts = _explorer.FindAssemblyContextsIn(assembly); + var assemblyContexts = _explorer.FindAssemblyContextsIn(assembly); assemblyContexts.Each(assemblyContext => { assemblyContext.OnAssemblyStart(); @@ -122,11 +128,11 @@ public void EndExplicitRunScope(Assembly assembly) } void RunContext(Context context, - IEnumerable globalCleanups, - IEnumerable supplements) + IEnumerable globalCleanups, + IEnumerable supplements) { var runner = ContextRunnerFactory.GetContextRunnerFor(context); runner.Run(context, _listener, _options, globalCleanups, supplements); } } -} \ No newline at end of file +} diff --git a/src/Machine.Specifications/Runner/Impl/TestContextListener.cs b/src/Machine.Specifications/Runner/Impl/TestContextListener.cs new file mode 100644 index 000000000..090d19585 --- /dev/null +++ b/src/Machine.Specifications/Runner/Impl/TestContextListener.cs @@ -0,0 +1,93 @@ +using System.Collections.Generic; + +namespace Machine.Specifications.Runner.Impl +{ + public class TestContextListener : RunListenerBase + { + List _testContext = new List(); + + public void SetTestContexts(List testContexts) + { + _testContext = testContexts ?? new List(); + } + + public override void OnAssemblyStart(AssemblyInfo assembly) + { + foreach (var testContext in _testContext) + { + testContext.OnAssemblyStart(assembly); + } + } + + public override void OnAssemblyEnd(AssemblyInfo assembly) + { + foreach (var testContext in _testContext) + { + testContext.OnAssemblyEnd(assembly); + } + } + + public override void OnRunStart() + { + foreach (var testContext in _testContext) + { + testContext.OnRunStart(); + } + } + + public override void OnRunEnd() + { + foreach (var testContext in _testContext) + { + testContext.OnRunEnd(); + } + } + + public override void OnContextStart(ContextInfo context) + { + foreach (var testContext in _testContext) + { + testContext.OnContextStart(context); + } + } + + public override void OnContextEnd(ContextInfo context) + { + foreach (var testContext in _testContext) + { + testContext.OnContextEnd(context); + } + } + + public override void OnSpecificationStart(SpecificationInfo specification) + { + foreach (var testContext in _testContext) + { + testContext.OnSpecificationStart(specification); + } + } + + public override void OnSpecificationEnd(SpecificationInfo specification, Result result) + { + foreach (var testContext in _testContext) + { + testContext.OnSpecificationEnd(specification, result); + } + } + + public override void OnFatalError(ExceptionResult exception) + { + foreach (var testContext in _testContext) + { + try + { + testContext.OnFatalError(exception); + } + catch + { + // ignored + } + } + } + } +}