nunit-core team mailing list archive
-
nunit-core team
-
Mailing list archive
-
Message #01425
[Merge] lp:~jterrell/nunitv2/action-attributes into lp:nunitv2
You have been requested to review the proposed merge of lp:~jterrell/nunitv2/action-attributes into lp:nunitv2.
Implements new Action Attributes feature.
--
https://code.launchpad.net/~jterrell/nunitv2/action-attributes/+merge/43316
Your team NUnit Core Developers is requested to review the proposed merge of lp:~jterrell/nunitv2/action-attributes into lp:nunitv2.
=== added file 'src/NUnitCore/core/ActionsHelper.cs'
--- src/NUnitCore/core/ActionsHelper.cs 1970-01-01 00:00:00 +0000
+++ src/NUnitCore/core/ActionsHelper.cs 2010-12-10 03:36:07 +0000
@@ -0,0 +1,127 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text;
+
+namespace NUnit.Core
+{
+ internal static class ActionsHelper
+ {
+ private static Type _ActionInterfaceType = null;
+ private static Hashtable _ActionTypes = null;
+
+ static ActionsHelper()
+ {
+ _ActionInterfaceType = Type.GetType(NUnitFramework.ActionInterface);
+ _ActionTypes = new Hashtable();
+
+ _ActionTypes.Add(ActionLevel.Suite, Type.GetType(NUnitFramework.SuiteActionInterface));
+ _ActionTypes.Add(ActionLevel.Test, Type.GetType(NUnitFramework.TestActionInterface));
+ }
+
+ public static object[] GetActionsFromAttributes(ICustomAttributeProvider attributeProvider)
+ {
+ ArrayList resultList = new ArrayList();
+
+ object[] attributes = attributeProvider.GetCustomAttributes(true);
+
+ foreach (Attribute attribute in attributes)
+ {
+ if (_ActionInterfaceType.IsAssignableFrom(attribute.GetType()))
+ resultList.Add(attribute);
+ }
+
+ object[] results = new object[resultList.Count];
+ resultList.CopyTo(results);
+
+ return results;
+ }
+
+ public static void ExecuteActions(ActionLevel level, ActionPhase phase, IEnumerable actions, object fixture, MethodInfo method)
+ {
+ if (actions == null)
+ throw new ArgumentNullException("actions");
+
+ Type actionType = GetActionType(level);
+ MethodInfo actionMethod = GetActionMethod(actionType, level, phase);
+
+ object[] filteredActions = GetFilteredAndSortedActions(actions, phase, actionType);
+
+
+
+ foreach (object action in filteredActions)
+ {
+ if (action == null)
+ continue;
+
+ if(level == ActionLevel.Suite)
+ Reflect.InvokeMethod(actionMethod, action, fixture);
+ else
+ Reflect.InvokeMethod(actionMethod, action, fixture, method);
+ }
+ }
+
+ private static object[] GetFilteredAndSortedActions(IEnumerable actions, ActionPhase phase, Type actionType)
+ {
+ ArrayList filteredActions = new ArrayList();
+ foreach(object actionItem in actions)
+ {
+ if(actionItem == null)
+ continue;
+
+ if(actionItem is IEnumerable)
+ {
+ foreach(object nestedItem in ((IEnumerable)actionItem))
+ {
+ if(nestedItem == null)
+ continue;
+
+ if (actionType.IsAssignableFrom(nestedItem.GetType()) && filteredActions.Contains(nestedItem) != true)
+ filteredActions.Add(nestedItem);
+ }
+ }
+ else if(actionType.IsAssignableFrom(actionItem.GetType()) && filteredActions.Contains(actionItem) != true)
+ filteredActions.Add(actionItem);
+ }
+
+ if(phase == ActionPhase.After)
+ filteredActions.Reverse();
+
+ return filteredActions.ToArray();
+ }
+
+ private static Type GetActionType(ActionLevel level)
+ {
+ return (Type) _ActionTypes[level];
+ }
+
+ private static MethodInfo GetActionMethod(Type actionType, ActionLevel level, ActionPhase phase)
+ {
+ if (phase == ActionPhase.Before)
+ {
+ if (level == ActionLevel.Suite)
+ return Reflect.GetNamedMethod(actionType, "BeforeSuite");
+
+ return Reflect.GetNamedMethod(actionType, "BeforeTest");
+ }
+
+ if (level == ActionLevel.Suite)
+ return Reflect.GetNamedMethod(actionType, "AfterSuite");
+
+ return Reflect.GetNamedMethod(actionType, "AfterTest");
+ }
+ }
+
+ internal enum ActionLevel
+ {
+ Suite,
+ Test
+ }
+
+ internal enum ActionPhase
+ {
+ Before,
+ After
+ }
+}
=== modified file 'src/NUnitCore/core/Builders/TestAssemblyBuilder.cs'
--- src/NUnitCore/core/Builders/TestAssemblyBuilder.cs 2010-08-09 02:30:40 +0000
+++ src/NUnitCore/core/Builders/TestAssemblyBuilder.cs 2010-12-10 03:36:07 +0000
@@ -86,12 +86,12 @@
// a type, we handle it specially
Type testType = assembly.GetType(testName);
if (testType != null)
- return Build(assemblyName, testType, autoSuites);
+ return Build(assembly, assemblyName, testType, autoSuites);
// Assume that testName is a namespace and get all fixtures in it
IList fixtures = GetFixtures(assembly, testName);
- if (fixtures.Count > 0)
- return BuildTestAssembly(assemblyName, fixtures, autoSuites);
+ if (fixtures.Count > 0)
+ return BuildTestAssembly(this.assembly, assemblyName, fixtures, autoSuites);
return null;
}
@@ -107,11 +107,11 @@
if (this.assembly == null) return null;
IList fixtures = GetFixtures(assembly, null);
- return BuildTestAssembly(assemblyName, fixtures, autoSuites);
+ return BuildTestAssembly(this.assembly, assemblyName, fixtures, autoSuites);
}
}
- private Test Build( string assemblyName, Type testType, bool autoSuites )
+ private Test Build( Assembly assembly, string assemblyName, Type testType, bool autoSuites )
{
// TODO: This is the only situation in which we currently
// recognize and load legacy suites. We need to determine
@@ -119,14 +119,14 @@
if ( legacySuiteBuilder.CanBuildFrom( testType ) )
return legacySuiteBuilder.BuildFrom( testType );
else if ( TestFixtureBuilder.CanBuildFrom( testType ) )
- return BuildTestAssembly( assemblyName,
+ return BuildTestAssembly( assembly, assemblyName,
new Test[] { TestFixtureBuilder.BuildFrom( testType ) }, autoSuites );
return null;
}
- private TestSuite BuildTestAssembly( string assemblyName, IList fixtures, bool autoSuites )
+ private TestSuite BuildTestAssembly( Assembly assembly, string assemblyName, IList fixtures, bool autoSuites )
{
- TestSuite testAssembly = new TestAssembly( assemblyName );
+ TestSuite testAssembly = new TestAssembly( assembly, assemblyName );
if ( autoSuites )
{
=== modified file 'src/NUnitCore/core/NUnitFramework.cs'
--- src/NUnitCore/core/NUnitFramework.cs 2010-11-04 18:12:55 +0000
+++ src/NUnitCore/core/NUnitFramework.cs 2010-12-10 03:36:07 +0000
@@ -23,8 +23,8 @@
#region Constants
#region Attribute Names
- // NOTE: Attributes used in switch statements must be const
-
+ // NOTE: Attributes used in switch statements must be const
+
// Attributes that apply to Assemblies, Classes and Methods
public const string IgnoreAttribute = "NUnit.Framework.IgnoreAttribute";
public const string PlatformAttribute = "NUnit.Framework.PlatformAttribute";
@@ -54,7 +54,12 @@
public static readonly string SuiteAttribute = "NUnit.Framework.SuiteAttribute";
#endregion
- #region Other Framework Types
+ #region Other Framework Types
+
+ public static readonly string SuiteActionInterface = "NUnit.Framework.ISuiteAction, NUnit.Framework";
+ public static readonly string TestActionInterface = "NUnit.Framework.ITestAction, NUnit.Framework";
+ public static readonly string ActionInterface = "NUnit.Framework.IAction, NUnit.Framework";
+
public static readonly string AssertException = "NUnit.Framework.AssertionException";
public static readonly string IgnoreException = "NUnit.Framework.IgnoreException";
public static readonly string InconclusiveException = "NUnit.Framework.InconclusiveException";
=== modified file 'src/NUnitCore/core/NUnitTestFixture.cs'
--- src/NUnitCore/core/NUnitTestFixture.cs 2009-04-17 07:12:10 +0000
+++ src/NUnitCore/core/NUnitTestFixture.cs 2010-12-10 03:36:07 +0000
@@ -4,8 +4,9 @@
// copyright ownership at http://nunit.org.
// ****************************************************************
-using System;
-using System.Reflection;
+using System;
+using System.Reflection;
+using System.Collections;
namespace NUnit.Core
{
@@ -27,7 +28,19 @@
this.setUpMethods =
Reflect.GetMethodsWithAttribute(this.FixtureType, NUnitFramework.SetUpAttribute, true);
this.tearDownMethods =
- Reflect.GetMethodsWithAttribute(this.FixtureType, NUnitFramework.TearDownAttribute, true);
+ Reflect.GetMethodsWithAttribute(this.FixtureType, NUnitFramework.TearDownAttribute, true);
+
+ ArrayList collectedActions = new ArrayList();
+
+ collectedActions.AddRange(ActionsHelper.GetActionsFromAttributes(fixtureType));
+
+ Type[] fixtureInterfaces = this.FixtureType.GetInterfaces();
+
+ foreach (Type fixtureInterface in fixtureInterfaces)
+ collectedActions.AddRange(ActionsHelper.GetActionsFromAttributes(fixtureInterface));
+
+ this.actions = new Attribute[collectedActions.Count];
+ collectedActions.CopyTo(this.actions);
}
protected override void DoOneTimeSetUp(TestResult suiteResult)
=== modified file 'src/NUnitCore/core/ParameterizedTestMethodSuite.cs'
--- src/NUnitCore/core/ParameterizedTestMethodSuite.cs 2010-09-21 19:07:23 +0000
+++ src/NUnitCore/core/ParameterizedTestMethodSuite.cs 2010-12-10 03:36:07 +0000
@@ -2,7 +2,8 @@
// Copyright 2008, Charlie Poole
// This is free software licensed under the NUnit license. You may
// obtain a copy of the license at http://nunit.org.
-// ****************************************************************
+// ****************************************************************
+using System.Collections;
using System.Reflection;
using System.Text;
@@ -14,7 +15,8 @@
/// </summary>
public class ParameterizedMethodSuite : TestSuite
{
- private bool isTheory;
+ private bool isTheory;
+ private MethodInfo method;
/// <summary>
/// Construct from a MethodInfo
@@ -24,7 +26,8 @@
: base(method.ReflectedType.FullName, method.Name)
{
this.maintainTestOrder = true;
- this.isTheory = Reflect.HasAttribute(method, NUnitFramework.TheoryAttribute, true);
+ this.isTheory = Reflect.HasAttribute(method, NUnitFramework.TheoryAttribute, true);
+ this.method = method;
}
/// <summary>
@@ -56,9 +59,11 @@
if (suite != null)
{
this.setUpMethods = suite.GetSetUpMethods();
- this.tearDownMethods = suite.GetTearDownMethods();
+ this.tearDownMethods = suite.GetTearDownMethods();
}
- }
+ }
+
+ this.actions = ActionsHelper.GetActionsFromAttributes(this.method);
// DYNAMIC: Get the parameters, and add the methods here.
@@ -74,7 +79,8 @@
this.Fixture = null;
this.setUpMethods = null;
- this.tearDownMethods = null;
+ this.tearDownMethods = null;
+ this.actions = null;
return result;
}
@@ -95,6 +101,6 @@
/// <param name="suiteResult"></param>
protected override void DoOneTimeTearDown(TestResult suiteResult)
{
- }
+ }
}
}
=== modified file 'src/NUnitCore/core/SetUpFixture.cs'
--- src/NUnitCore/core/SetUpFixture.cs 2010-01-31 21:39:24 +0000
+++ src/NUnitCore/core/SetUpFixture.cs 2010-12-10 03:36:07 +0000
@@ -27,7 +27,9 @@
this.TestName.Name = this.TestName.Name.Substring(index + 1);
this.fixtureSetUpMethods = Reflect.GetMethodsWithAttribute( type, NUnitFramework.SetUpAttribute, true );
- this.fixtureTearDownMethods = Reflect.GetMethodsWithAttribute( type, NUnitFramework.TearDownAttribute, true );
+ this.fixtureTearDownMethods = Reflect.GetMethodsWithAttribute( type, NUnitFramework.TearDownAttribute, true );
+
+ this.actions = ActionsHelper.GetActionsFromAttributes(type);
}
#endregion
=== modified file 'src/NUnitCore/core/TestAssembly.cs'
--- src/NUnitCore/core/TestAssembly.cs 2010-01-31 21:39:24 +0000
+++ src/NUnitCore/core/TestAssembly.cs 2010-12-10 03:36:07 +0000
@@ -4,8 +4,9 @@
// copyright ownership at http://nunit.org.
// ****************************************************************
-using System;
-
+using System;
+using System.Reflection;
+
namespace NUnit.Core
{
/// <summary>
@@ -18,7 +19,10 @@
/// Initializes a new instance of the <see cref="TestAssembly"/> class.
/// </summary>
/// <param name="path">The path.</param>
- public TestAssembly(string path) : base(path) { }
+ public TestAssembly(Assembly assembly, string path) : base(path)
+ {
+ this.actions = ActionsHelper.GetActionsFromAttributes(assembly);
+ }
/// <summary>
/// Gets the type of the test.
=== modified file 'src/NUnitCore/core/TestMethod.cs'
--- src/NUnitCore/core/TestMethod.cs 2010-10-10 02:04:39 +0000
+++ src/NUnitCore/core/TestMethod.cs 2010-12-10 03:36:07 +0000
@@ -2,12 +2,11 @@
// This is free software licensed under the NUnit license. You
// may obtain a copy of the license as well as information regarding
// copyright ownership at http://nunit.org.
-// ****************************************************************
-
+// ****************************************************************
namespace NUnit.Core
{
using System;
- using System.Collections;
+ using System.Collections;
using System.Runtime.Remoting.Messaging;
using System.Threading;
using System.Text;
@@ -42,7 +41,17 @@
/// <summary>
/// The teardown method
/// </summary>
- protected MethodInfo[] tearDownMethods;
+ protected MethodInfo[] tearDownMethods;
+
+ /// <summary>
+ /// The actions
+ /// </summary>
+ protected object[] actions;
+
+ /// <summary>
+ /// The parent suite's actions
+ /// </summary>
+ protected object[] suiteActions;
/// <summary>
/// The ExpectedExceptionProcessor for this test, if any
@@ -210,22 +219,25 @@
ContextDictionary context = Context;
context._ec = TestExecutionContext.CurrentContext;
- CallContext.SetData("NUnit.Framework.TestContext", context);
-
- if (this.Parent != null)
- {
- this.Fixture = this.Parent.Fixture;
- TestSuite suite = this.Parent as TestSuite;
- if (suite != null)
- {
- this.setUpMethods = suite.GetSetUpMethods();
- this.tearDownMethods = suite.GetTearDownMethods();
- }
- }
-
- try
- {
- // Temporary... to allow for tests that directly execute a test case
+ CallContext.SetData("NUnit.Framework.TestContext", context);
+
+ if (this.Parent != null)
+ {
+ this.Fixture = this.Parent.Fixture;
+ TestSuite suite = this.Parent as TestSuite;
+ if (suite != null)
+ {
+ this.setUpMethods = suite.GetSetUpMethods();
+ this.tearDownMethods = suite.GetTearDownMethods();
+ this.suiteActions = suite.GetTestActions();
+ }
+ }
+
+ try
+ {
+ this.actions = ActionsHelper.GetActionsFromAttributes(method);
+
+ // Temporary... to allow for tests that directly execute a test case);
if (Fixture == null && !method.IsStatic)
Fixture = Reflect.Construct(this.FixtureType);
@@ -300,9 +312,10 @@
TestResult testResult = new TestResult(this);
TestExecutionContext.CurrentContext.CurrentResult = testResult;
- try
- {
+ try
+ {
RunSetUp();
+ RunBeforeActions();
RunTestCase( testResult );
}
@@ -317,7 +330,8 @@
}
finally
{
- RunTearDown( testResult );
+ RunAfterActions(testResult);
+ RunTearDown( testResult );
DateTime stop = DateTime.Now;
TimeSpan span = stop.Subtract(start);
@@ -354,7 +368,29 @@
#region Invoke Methods by Reflection, Recording Errors
- private void RunSetUp()
+ private void RunBeforeActions()
+ {
+ object[][] targetActions = new object[][] {this.suiteActions, this.actions};
+ ActionsHelper.ExecuteActions(ActionLevel.Test, ActionPhase.Before, targetActions, this.Fixture, this.Method);
+ }
+
+ private void RunAfterActions(TestResult testResult)
+ {
+ try
+ {
+ object[][] targetActions = new object[][] { this.suiteActions, this.actions };
+ ActionsHelper.ExecuteActions(ActionLevel.Test, ActionPhase.After, targetActions, this.Fixture, this.Method);
+ }
+ catch(Exception ex)
+ {
+ if (ex is NUnitException)
+ ex = ex.InnerException;
+ // TODO: What about ignore exceptions in teardown?
+ testResult.Error(ex, FailureSite.TearDown);
+ }
+ }
+
+ private void RunSetUp()
{
if (setUpMethods != null)
foreach( MethodInfo setUpMethod in setUpMethods )
=== modified file 'src/NUnitCore/core/TestSuite.cs'
--- src/NUnitCore/core/TestSuite.cs 2010-09-19 22:47:12 +0000
+++ src/NUnitCore/core/TestSuite.cs 2010-12-10 03:36:07 +0000
@@ -46,7 +46,12 @@
/// <summary>
/// The teardown methods for this suite
/// </summary>
- protected MethodInfo[] tearDownMethods;
+ protected MethodInfo[] tearDownMethods;
+
+ /// <summary>
+ /// The actions for this suite
+ /// </summary>
+ protected object[] actions;
/// <summary>
/// Set to true to suppress sorting this suite's contents
@@ -187,6 +192,24 @@
{
return tearDownMethods;
}
+
+ internal virtual object[] GetTestActions()
+ {
+ ArrayList allActions = new ArrayList();
+
+ if (this.Parent != null && this.Parent is TestSuite)
+ {
+ object[] parentActions = ((TestSuite)this.Parent).GetTestActions();
+
+ if (parentActions != null)
+ allActions.AddRange(parentActions);
+ }
+
+ if (this.actions != null)
+ allActions.AddRange(this.actions);
+
+ return allActions.ToArray();
+ }
#endregion
#region Test Overrides
@@ -268,7 +291,8 @@
{
TestResult suiteResult = new TestResult(this);
- DoOneTimeSetUp(suiteResult);
+ DoOneTimeSetUp(suiteResult);
+ DoOneTimeBeforeTestSuiteActions(suiteResult);
if (this.Properties["_SETCULTURE"] != null)
TestExecutionContext.CurrentContext.CurrentCulture =
@@ -292,8 +316,9 @@
{
RunAllTests(suiteResult, listener, filter);
}
- finally
- {
+ finally
+ {
+ DoOneTimeAfterTestSuiteActions(suiteResult);
DoOneTimeTearDown(suiteResult);
}
break;
@@ -342,6 +367,36 @@
}
}
+ protected virtual void DoOneTimeBeforeTestSuiteActions(TestResult suiteResult)
+ {
+ try
+ {
+ if (this.actions != null)
+ ActionsHelper.ExecuteActions(ActionLevel.Suite, ActionPhase.Before, this.actions, this.Fixture, null);
+
+ TestExecutionContext.CurrentContext.Update();
+ }
+ catch (Exception ex)
+ {
+ if (ex is NUnitException || ex is System.Reflection.TargetInvocationException)
+ ex = ex.InnerException;
+
+ if (ex is InvalidTestFixtureException)
+ suiteResult.Invalid(ex.Message);
+ else if (IsIgnoreException(ex))
+ {
+ this.RunState = RunState.Ignored;
+ suiteResult.Ignore(ex.Message);
+ suiteResult.StackTrace = ex.StackTrace;
+ this.IgnoreReason = ex.Message;
+ }
+ else if (IsAssertException(ex))
+ suiteResult.Failure(ex.Message, ex.StackTrace, FailureSite.SetUp);
+ else
+ suiteResult.Error(ex, FailureSite.SetUp);
+ }
+ }
+
protected virtual void CreateUserFixture()
{
if (arguments != null && arguments.Length > 0)
@@ -387,6 +442,26 @@
}
}
+ protected virtual void DoOneTimeAfterTestSuiteActions(TestResult suiteResult)
+ {
+ try
+ {
+ if (this.actions != null)
+ ActionsHelper.ExecuteActions(ActionLevel.Suite, ActionPhase.After, this.actions, this.Fixture, null);
+ }
+ catch (Exception ex)
+ {
+ // Error in TestFixtureTearDown or Dispose causes the
+ // suite to be marked as a failure, even if
+ // all the contained tests passed.
+ NUnitException nex = ex as NUnitException;
+ if (nex != null)
+ ex = nex.InnerException;
+
+ suiteResult.Failure(ex.Message, ex.StackTrace, FailureSite.TearDown);
+ }
+ }
+
protected virtual bool IsAssertException(Exception ex)
{
return ex.GetType().FullName == NUnitFramework.AssertException;
@@ -422,9 +497,9 @@
{
test.RunState = this.RunState;
test.IgnoreReason = this.IgnoreReason;
- }
-
- TestResult result = test.Run(listener, filter);
+ }
+
+ TestResult result = test.Run(listener, filter);
log.Debug("Test result = " + result.ResultState);
=== modified file 'src/NUnitCore/core/nunit.core.build'
--- src/NUnitCore/core/nunit.core.build 2010-12-09 05:10:05 +0000
+++ src/NUnitCore/core/nunit.core.build 2010-12-10 03:36:07 +0000
@@ -3,6 +3,7 @@
<patternset id="source-files">
<include name="AbstractTestCaseDecoration.cs"/>
+ <include name="ActionsHelper.cs" />
<include name="AssemblyInfo.cs"/>
<include name="AssemblyHelper.cs"/>
<include name="AssemblyReader.cs"/>
=== modified file 'src/NUnitCore/core/nunit.core.dll.csproj'
--- src/NUnitCore/core/nunit.core.dll.csproj 2010-11-07 15:49:05 +0000
+++ src/NUnitCore/core/nunit.core.dll.csproj 2010-12-10 03:36:07 +0000
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<ProjectType>Local</ProjectType>
- <ProductVersion>9.0.21022</ProductVersion>
+ <ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{EBD43A7F-AFCA-4281-BB53-5CDD91F966A3}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -117,6 +117,7 @@
<Compile Include="AssemblyInfo.cs" />
<Compile Include="AssemblyReader.cs" />
<Compile Include="AssemblyResolver.cs" />
+ <Compile Include="ActionsHelper.cs" />
<Compile Include="Builders\CombinatorialStrategy.cs" />
<Compile Include="Builders\CombinatorialTestCaseProvider.cs" />
<Compile Include="Builders\CombiningStrategy.cs" />
=== added file 'src/NUnitCore/tests/ActionAttributeTests.cs'
--- src/NUnitCore/tests/ActionAttributeTests.cs 1970-01-01 00:00:00 +0000
+++ src/NUnitCore/tests/ActionAttributeTests.cs 2010-12-10 03:36:07 +0000
@@ -0,0 +1,209 @@
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using NUnit.Framework;
+using NUnit.TestData.ActionAttributeTests;
+
+namespace NUnit.Core.Tests
+{
+ [TestFixture]
+ public class ActionAttributeTests
+ {
+ private class ActionAttributeFixtureFilter : TestFilter
+ {
+ public override bool Match(ITest test)
+ {
+ return test.TestName.FullName.StartsWith(typeof(ActionAttributeFixture).FullName);
+ }
+ }
+
+ private TestResult _result = null;
+ private readonly string[] _definitionSites = new string[]
+ {
+ "Assembly",
+ "SetUpFixture",
+ "Fixture",
+ "Interface",
+ "Method"
+ };
+
+ [TestFixtureSetUp]
+ public void Setup()
+ {
+ ActionAttributeFixture.Results = new StringCollection();
+
+ TestSuiteBuilder builder = new TestSuiteBuilder();
+ TestPackage package = new TestPackage(AssemblyHelper.GetAssemblyPath(typeof(ActionAttributeFixture)));
+ package.TestName = typeof(ActionAttributeFixture).Namespace;
+
+ Test suite = builder.Build(package);
+ _result = suite.Run(new NullListener(), new ActionAttributeFixtureFilter());
+ }
+
+ [Test]
+ public void TestsRunsSuccessfully()
+ {
+ Assert.IsTrue(_result.IsSuccess, "Test run was not successful.");
+ Assert.Contains("SomeTest-Case1", ActionAttributeFixture.Results, "Test Case 1 was not run.");
+ Assert.Contains("SomeTest-Case2", ActionAttributeFixture.Results, "Test Case 2 was not run.");
+ Assert.Contains("SomeOtherTest", ActionAttributeFixture.Results, "SomeOtherTest was not run.");
+
+ foreach(string message in ActionAttributeFixture.Results)
+ Console.WriteLine(message);
+ }
+
+ [Test]
+ public void FirstFourDefinitionSites_BeforeSuite_ExecuteFirst_InOrder()
+ {
+ for(int i = 0; i < 4; i++)
+ {
+ string prefix = string.Format("{0}.BeforeSuite-", _definitionSites[i]);
+
+ Assert.IsTrue(
+ ActionAttributeFixture.Results[i].StartsWith(prefix),
+ string.Format("Did not find prefix '{0}' at index {1}", prefix, i));
+ }
+ }
+
+
+ [Test]
+ public void FirstFourDefinitionSites_AfterSuite_ExecuteLast_InOrder()
+ {
+ int lastIndex = ActionAttributeFixture.Results.Count - 1;
+ for (int i = lastIndex; i > lastIndex - 4; i--)
+ {
+ string prefix = string.Format("{0}.AfterSuite-", _definitionSites[lastIndex - i]);
+
+ Assert.IsTrue(
+ ActionAttributeFixture.Results[i].StartsWith(prefix),
+ string.Format("Did not find prefix '{0}' at index {1}", prefix, i));
+ }
+ }
+
+ [Test]
+ public void FirstFourDefinitionSites_BeforeTest_ExecuteInOrder_ForSomeOtherTest()
+ {
+ int startIndex = ActionAttributeFixture.Results.IndexOf("SomeOtherTest") - 4;
+ for (int i = startIndex; i < startIndex; i++)
+ {
+ string prefix = string.Format("{0}.BeforeTest-", _definitionSites[i - startIndex]);
+
+ Assert.IsTrue(
+ ActionAttributeFixture.Results[i].StartsWith(prefix),
+ string.Format("Did not find prefix '{0}' at index {1}", prefix, i));
+ }
+ }
+
+ [Test]
+ public void FirstFourDefinitionSites_AfterTest_ExecuteInOrder_ForSomeOtherTest()
+ {
+ int startIndex = ActionAttributeFixture.Results.IndexOf("SomeOtherTest");
+ for (int i = 1; i <= 4; i++)
+ {
+ string prefix = string.Format("{0}.AfterTest-", _definitionSites[4 - i]);
+
+ Assert.IsTrue(
+ ActionAttributeFixture.Results[startIndex + i].StartsWith(prefix),
+ string.Format("Did not find prefix '{0}' at index {1}", prefix, i));
+ }
+ }
+
+ [Test]
+ public void AllDefinitionSites_BeforeTest_ExecuteInOrder_ForSomeTestCase1()
+ {
+ int startIndex = ActionAttributeFixture.Results.IndexOf("SomeTest-Case1") - 5;
+ for (int i = startIndex; i < startIndex; i++)
+ {
+ string prefix = string.Format("{0}.BeforeTest-", _definitionSites[i - startIndex]);
+
+ Assert.IsTrue(
+ ActionAttributeFixture.Results[i].StartsWith(prefix),
+ string.Format("Did not find prefix '{0}' at index {1}", prefix, i));
+ }
+ }
+
+ [Test]
+ public void AllDefinitionSites_AfterTest_ExecuteInOrder_ForSomeTestCase1()
+ {
+ int startIndex = ActionAttributeFixture.Results.IndexOf("SomeTest-Case1");
+ for (int i = 1; i <= 5; i++)
+ {
+ string prefix = string.Format("{0}.AfterTest-", _definitionSites[5 - i]);
+
+ Assert.IsTrue(
+ ActionAttributeFixture.Results[startIndex + i].StartsWith(prefix),
+ string.Format("Did not find prefix '{0}' at index {1}", prefix, i));
+ }
+ }
+
+ [Test]
+ public void AllDefinitionSites_BeforeTest_ExecuteInOrder_ForSomeTestCase2()
+ {
+ int startIndex = ActionAttributeFixture.Results.IndexOf("SomeTest-Case2") - 5;
+ for (int i = startIndex; i < startIndex; i++)
+ {
+ string prefix = string.Format("{0}.BeforeTest-", _definitionSites[i - startIndex]);
+
+ Assert.IsTrue(
+ ActionAttributeFixture.Results[i].StartsWith(prefix),
+ string.Format("Did not find prefix '{0}' at index {1}", prefix, i));
+ }
+ }
+
+ [Test]
+ public void AllDefinitionSites_AfterTest_ExecuteInOrder_ForSomeTestCase2()
+ {
+ int startIndex = ActionAttributeFixture.Results.IndexOf("SomeTest-Case2");
+ for (int i = 1; i <= 5; i++)
+ {
+ string prefix = string.Format("{0}.AfterTest-", _definitionSites[5 - i]);
+
+ Assert.IsTrue(
+ ActionAttributeFixture.Results[startIndex + i].StartsWith(prefix),
+ string.Format("Did not find prefix '{0}' at index {1}", prefix, i));
+ }
+ }
+
+ [Test]
+ public void MethodDefinedSite_BeforeSuite_BeforeSomeTestCase1()
+ {
+ int testCase = ActionAttributeFixture.Results.IndexOf("SomeTest-Case1");
+ Assert.IsTrue(testCase > ActionAttributeFixture.Results.IndexOf("Method.BeforeSuite-ActionAttributeFixture"));
+ }
+
+ [Test]
+ public void MethodDefinedSite_AfterSuite_BeforeSomeTestCase2()
+ {
+ int testCase = ActionAttributeFixture.Results.IndexOf("SomeTest-Case2");
+ Assert.IsTrue(testCase < ActionAttributeFixture.Results.IndexOf("Method.AfterSuite-ActionAttributeFixture"));
+ }
+
+ [Test]
+ public void AllActions_BeforeAndAfterTest_HasAccessToFixture()
+ {
+ foreach(string message in ActionAttributeFixture.Results)
+ {
+ if (message.Contains("BeforeTest") || message.Contains("AfterTest"))
+ Assert.IsTrue(message.Contains(typeof(ActionAttributeFixture).Name), string.Format("'{0}' shows action does not have access to fixture.", message));
+ }
+ }
+
+ [Test]
+ public void AllActions_BeforeAndAfterTest_HasAccessToMethodInfo()
+ {
+ StringCollection validEndSegments = new StringCollection();
+ validEndSegments.AddRange(new string[] {"SomeOtherTest", "SomeTest"});
+
+ foreach (string message in ActionAttributeFixture.Results)
+ {
+ if (message.Contains("BeforeTest") || message.Contains("AfterTest"))
+ {
+ string endSegment = message.Substring(message.LastIndexOf('-') + 1);
+
+ Assert.IsTrue(validEndSegments.Contains(endSegment),
+ string.Format("'{0}' shows action does not have access to method info.", message));
+ }
+ }
+ }
+ }
+}
=== modified file 'src/NUnitCore/tests/nunit.core.tests.csproj'
--- src/NUnitCore/tests/nunit.core.tests.csproj 2010-12-09 05:10:05 +0000
+++ src/NUnitCore/tests/nunit.core.tests.csproj 2010-12-10 03:36:07 +0000
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<ProjectType>Local</ProjectType>
- <ProductVersion>9.0.21022</ProductVersion>
+ <ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{DD758D21-E5D5-4D40-9450-5F65A32F359C}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -141,6 +141,7 @@
<Compile Include="AttributeDescriptionFixture.cs" />
<Compile Include="AttributeInheritance.cs" />
<Compile Include="BasicRunnerTests.cs" />
+ <Compile Include="ActionAttributeTests.cs" />
<Compile Include="CallContextTests.cs" />
<Compile Include="CategoryAttributeTests.cs" />
<Compile Include="CombinatorialTests.cs" />
=== added directory 'src/NUnitFramework/framework/Interfaces'
=== added file 'src/NUnitFramework/framework/Interfaces/IAction.cs'
--- src/NUnitFramework/framework/Interfaces/IAction.cs 1970-01-01 00:00:00 +0000
+++ src/NUnitFramework/framework/Interfaces/IAction.cs 2010-12-10 03:36:07 +0000
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace NUnit.Framework
+{
+ public interface IAction
+ {
+ }
+}
=== added file 'src/NUnitFramework/framework/Interfaces/ISuiteAction.cs'
--- src/NUnitFramework/framework/Interfaces/ISuiteAction.cs 1970-01-01 00:00:00 +0000
+++ src/NUnitFramework/framework/Interfaces/ISuiteAction.cs 2010-12-10 03:36:07 +0000
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace NUnit.Framework
+{
+ public interface ISuiteAction : IAction
+ {
+ void BeforeSuite(object fixture);
+ void AfterSuite(object fixture);
+ }
+}
=== added file 'src/NUnitFramework/framework/Interfaces/ITestAction.cs'
--- src/NUnitFramework/framework/Interfaces/ITestAction.cs 1970-01-01 00:00:00 +0000
+++ src/NUnitFramework/framework/Interfaces/ITestAction.cs 2010-12-10 03:36:07 +0000
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text;
+
+namespace NUnit.Framework
+{
+ public interface ITestAction : IAction
+ {
+ void BeforeTest(object fixture, MethodInfo method);
+ void AfterTest(object fixture, MethodInfo method);
+ }
+}
=== modified file 'src/NUnitFramework/framework/nunit.framework.build'
--- src/NUnitFramework/framework/nunit.framework.build 2010-12-09 18:18:45 +0000
+++ src/NUnitFramework/framework/nunit.framework.build 2010-12-10 03:36:07 +0000
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<project name="NUnitFramework" default="build" basedir=".">
- <patternset id="source-files">
+ <patternset id="source-files">
<include name="Attributes/CategoryAttribute.cs"/>
<include name="Attributes/DatapointAttributes.cs"/>
<include name="Attributes/DescriptionAttribute.cs"/>
@@ -75,6 +75,9 @@
<include name="Exceptions/IgnoreException.cs"/>
<include name="Exceptions/InconclusiveException.cs"/>
<include name="Exceptions/SuccessException.cs"/>
+ <include name="Interfaces/IAction.cs" />
+ <include name="Interfaces/ISuiteAction.cs" />
+ <include name="Interfaces/ITestAction.cs" />
<include name="AssemblyInfo.cs"/>
<include name="Assert.cs"/>
<include name="AssertionHelper.cs"/>
@@ -101,6 +104,7 @@
<include name="Text.cs"/>
<include name="TextMessageWriter.cs"/>
<include name="Throws.cs"/>
+<<<<<<< TREE
</patternset>
<target name="build">
@@ -141,4 +145,46 @@
</copy>
</target>
-</project>
\ No newline at end of file
+</project>=======
+ </patternset>
+
+ <target name="build">
+
+ <csc target="library"
+ output="${current.framework.dir}/nunit.framework.dll"
+ doc="${current.framework.dir}/nunit.framework.xml"
+ debug="${build.debug}"
+ define="${build.defines}">
+ <nowarn>
+ <warning number="618,672"/>
+ <warning number="1699" if="${runtime.version=='2.0'}"/>
+ </nowarn>
+ <sources basedir=".">
+ <patternset refid="source-files"/>
+ <include name="../../GeneratedAssemblyInfo.cs" />
+ </sources>
+ </csc>
+
+ <!-- Needed locally by some NUnit tests -->
+ <copy file="${current.framework.dir}/nunit.framework.dll"
+ todir="${current.test.dir}"/>
+
+ <!-- Needed in base dir by pnunit tests -->
+ <copy file="${current.framework.dir}/nunit.framework.dll"
+ todir="${current.build.dir}"/>
+
+ </target>
+
+ <target name="package">
+ <copy todir="${package.src.dir}/NUnitFramework/framework">
+ <fileset>
+ <patternset refid="source-files"/>
+ <include name="nunit.framework.build"/>
+ <include name="nunit.framework.dll.csproj"/>
+ <include name="SyntaxElements.txt"/>
+ </fileset>
+ </copy>
+ </target>
+
+</project>
+>>>>>>> MERGE-SOURCE
=== modified file 'src/NUnitFramework/framework/nunit.framework.dll.csproj'
--- src/NUnitFramework/framework/nunit.framework.dll.csproj 2010-11-07 15:49:05 +0000
+++ src/NUnitFramework/framework/nunit.framework.dll.csproj 2010-12-10 03:36:07 +0000
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<ProjectType>Local</ProjectType>
- <ProductVersion>9.0.21022</ProductVersion>
+ <ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{83DD7E12-A705-4DBA-9D71-09C8973D9382}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -155,9 +155,12 @@
<Compile Include="FileAssert.cs" />
<Compile Include="GlobalSettings.cs" />
<Compile Include="Has.cs" />
+ <Compile Include="Interfaces\IAction.cs" />
<Compile Include="IExpectException.cs" />
<Compile Include="Is.cs" />
+ <Compile Include="Interfaces\ITestAction.cs" />
<Compile Include="ITestCaseData.cs" />
+ <Compile Include="Interfaces\ISuiteAction.cs" />
<Compile Include="Iz.cs" />
<Compile Include="List.cs" />
<Compile Include="ListMapper.cs" />
=== modified file 'src/NUnitFramework/tests/nunit.framework.tests.csproj'
--- src/NUnitFramework/tests/nunit.framework.tests.csproj 2010-11-07 15:49:05 +0000
+++ src/NUnitFramework/tests/nunit.framework.tests.csproj 2010-12-10 03:36:07 +0000
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<ProjectType>Local</ProjectType>
- <ProductVersion>9.0.21022</ProductVersion>
+ <ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{8C326431-AE57-4645-ACC1-A90A0B425129}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
=== added file 'src/tests/test-assembly/ActionAttributeFixture.cs'
--- src/tests/test-assembly/ActionAttributeFixture.cs 1970-01-01 00:00:00 +0000
+++ src/tests/test-assembly/ActionAttributeFixture.cs 2010-12-10 03:36:07 +0000
@@ -0,0 +1,97 @@
+using System;
+using System.Collections.Specialized;
+using NUnit.Framework;
+using System.Diagnostics;
+using System.Reflection;
+using NUnit.TestData.ActionAttributeTests;
+
+[assembly: SampleAction("Assembly")]
+
+namespace NUnit.TestData.ActionAttributeTests
+{
+ [SetUpFixture]
+ [SampleAction("SetUpFixture")]
+ public class SetupFixture
+ {
+ }
+
+ [TestFixture]
+ [SampleAction("Fixture")]
+ public class ActionAttributeFixture : IWithAction
+ {
+ private static StringCollection _Results = null;
+ public static StringCollection Results
+ {
+ get { return _Results; }
+ set { _Results = value; }
+ }
+
+ StringCollection IWithAction.Results { get { return Results; } }
+
+ [Test, TestCase("SomeTest-Case1"), TestCase("SomeTest-Case2")]
+ [SampleAction("Method")]
+ public void SomeTest(string message)
+ {
+ ((IWithAction)this).Results.Add(message);
+ }
+
+ [Test]
+ public void SomeOtherTest()
+ {
+ ((IWithAction)this).Results.Add("SomeOtherTest");
+ }
+
+ }
+
+ [SampleAction("Interface")]
+ public interface IWithAction
+ {
+ StringCollection Results { get; }
+ }
+
+ [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Method | AttributeTargets.Module, AllowMultiple = true, Inherited = true)]
+ public class SampleActionAttribute : Attribute, ISuiteAction, ITestAction
+ {
+ private string _Prefix = null;
+
+ public SampleActionAttribute(string prefix)
+ {
+ _Prefix = prefix;
+ }
+
+ void ISuiteAction.BeforeSuite(object fixture)
+ {
+ AddResult(fixture, null);
+ }
+
+ void ISuiteAction.AfterSuite(object fixture)
+ {
+ AddResult(fixture, null);
+ }
+
+ void ITestAction.BeforeTest(object fixture, MethodInfo method)
+ {
+ AddResult(fixture, method);
+ }
+
+ void ITestAction.AfterTest(object fixture, MethodInfo method)
+ {
+ AddResult(fixture, method);
+ }
+
+ private void AddResult(object fixture, MethodInfo method)
+ {
+ StackFrame frame = new StackFrame(1);
+ MethodBase actionMethod = frame.GetMethod();
+
+ string actionMethodName = actionMethod.Name.Substring(actionMethod.Name.LastIndexOf('.') + 1);
+ string message = string.Format("{0}.{1}-{2}" + (method != null ? "-{3}" : ""),
+ _Prefix,
+ actionMethodName,
+ fixture == null ? "{no-fixture}" : fixture.GetType().Name,
+ method != null ? method.Name : "");
+
+ ActionAttributeFixture.Results.Add(message);
+ }
+ }
+}
=== modified file 'src/tests/test-assembly/test-assembly.csproj'
--- src/tests/test-assembly/test-assembly.csproj 2010-11-07 15:49:05 +0000
+++ src/tests/test-assembly/test-assembly.csproj 2010-12-10 03:36:07 +0000
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<ProjectType>Local</ProjectType>
- <ProductVersion>9.0.21022</ProductVersion>
+ <ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{1960CAC4-9A82-47C5-A9B3-55BC37572C3C}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -126,6 +126,7 @@
</Compile>
<Compile Include="AttributeDescriptionTests.cs" />
<Compile Include="AttributeInheritance.cs" />
+ <Compile Include="ActionAttributeFixture.cs" />
<Compile Include="CategoryAttributeTests.cs" />
<Compile Include="ConsoleRunnerTest.cs" />
<Compile Include="CultureAttributeTests.cs" />