├── .gitignore ├── Cuke4Nuke ├── Core │ ├── AfterHook.cs │ ├── BeforeHook.cs │ ├── Core.csproj │ ├── ExtensionMethods.cs │ ├── Hook.cs │ ├── Listener.cs │ ├── Loader.cs │ ├── LogEventArgs.cs │ ├── ObjectFactory.cs │ ├── Processor.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Repository.cs │ ├── SnippetBuilder.cs │ ├── StepArgument.cs │ ├── StepDefinition.cs │ └── TableConverter.cs ├── Cuke4Nuke.sln ├── Framework │ ├── AfterAttribute.cs │ ├── BeforeAttribute.cs │ ├── Framework.csproj │ ├── GivenAttribute.cs │ ├── HookAttribute.cs │ ├── Languages │ │ └── Steps.cs │ ├── PendingAttribute.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── StepDefinitionAttribute.cs │ ├── Table.cs │ ├── TableAssertionException.cs │ ├── ThenAttribute.cs │ └── WhenAttribute.cs ├── Server │ ├── App.config │ ├── NukeServer.cs │ ├── Options.cs │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── Server.csproj ├── Specifications │ ├── Core │ │ ├── AfterHook_Specification.cs │ │ ├── AsyncListener.cs │ │ ├── BeforeHook_Specification.cs │ │ ├── Hook_Specification.cs │ │ ├── Listener_Specification.cs │ │ ├── Loader_Specification.cs │ │ ├── ObjectFactory_Specification.cs │ │ ├── Processor_Specification.cs │ │ ├── SnippetBuilder_Specification.cs │ │ ├── StepDefinition_Specification.cs │ │ ├── TableConverter_Specification.cs │ │ └── Table_Specification.cs │ ├── JsonAssert.cs │ ├── Language │ │ └── NO │ │ │ └── Norwegian_StepDefinition_Specification.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Reflection.cs │ ├── Server │ │ ├── NukeServer_Specification.cs │ │ ├── Options_Specification.cs │ │ └── Program_Specification.cs │ └── Specifications.csproj ├── TestStepDefinitions │ ├── ExternalSteps.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── TestStepDefinitions.csproj └── lib │ ├── Castle.Core.dll │ ├── Castle.MicroKernel.dll │ ├── LitJson.dll │ ├── NDesk.Options.dll │ ├── Newtonsoft.Json.dll │ ├── log4net.dll │ └── nunit.framework.dll ├── History.txt ├── README.markdown ├── Rakefile ├── examples ├── Calc │ ├── Calc.sln │ ├── Calc │ │ ├── .gitignore │ │ ├── Calc.csproj │ │ └── Calculator.cs │ ├── CalcFeatures │ │ ├── .gitignore │ │ ├── CalcFeatures.csproj │ │ ├── CalculatorSteps.cs │ │ └── features │ │ │ ├── addition.feature │ │ │ ├── division.feature │ │ │ └── step_definitons │ │ │ ├── calculator_steps.rb │ │ │ └── cucumber.wire │ ├── README.textile │ └── lib │ │ ├── Cuke4Nuke.Framework.dll │ │ └── nunit.framework.dll ├── WatiN │ ├── Google │ │ ├── Google.csproj │ │ ├── Google.sln │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── StepDefinitions │ │ │ └── SearchSteps.cs │ │ └── features │ │ │ ├── search.feature │ │ │ └── step_definitions │ │ │ └── cucumber.wire │ └── lib │ │ ├── Interop.SHDocVw.dll │ │ ├── Microsoft.mshtml.dll │ │ └── WatiN.Core.dll ├── language │ └── no │ │ ├── Kalkulator.5.0.ReSharper.user │ │ ├── Kalkulator.sln │ │ ├── Kalkulator │ │ ├── Kalkulator.cs │ │ ├── Kalkulator.csproj │ │ ├── Kalkulator.sln │ │ └── Properties │ │ │ └── AssemblyInfo.cs │ │ └── KalkulatorFeatures │ │ ├── KalkulatorFeatures.csproj │ │ ├── KalkulatorSteps.cs │ │ ├── Properties │ │ └── AssemblyInfo.cs │ │ └── features │ │ ├── Kalkulator.feature │ │ └── step_definitions │ │ └── cucumber.wire └── self_test │ └── .gitignore ├── features ├── cuke4nuke.feature ├── hooks.feature ├── pending.feature ├── shared_state.feature ├── snippets.feature ├── step_definitions │ ├── cucumber_steps.rb │ └── cuke4nuke_steps.rb ├── support │ ├── env.rb │ └── steps_template.cs.erb ├── tables.feature └── wrapper.feature ├── gem ├── Rakefile ├── VERSION ├── bin │ └── cuke4nuke ├── cuke4nuke.gemspec ├── dotnet │ └── .gitignore └── lib │ └── cuke4nuke │ └── main.rb └── lib ├── code_template └── C#_template.cs.erb └── task └── Cuke4NukeCodeGeneration.rake /.gitignore: -------------------------------------------------------------------------------- 1 | obj 2 | bin 3 | deploy 4 | deploy/* 5 | _ReSharper.* 6 | *.csproj.user 7 | *.resharper.user 8 | *.resharper 9 | *.suo 10 | *.cache 11 | ~$*.DS_Store 12 | .DS_Store 13 | ._* 14 | examples/self_test 15 | !gem/bin/* 16 | gem/pkg/* 17 | gem/dotnet/Cuke4NukeLog.txt* 18 | *.gem 19 | TestResult.xml 20 | .idea -------------------------------------------------------------------------------- /Cuke4Nuke/Core/AfterHook.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Reflection; 6 | using Cuke4Nuke.Framework; 7 | 8 | namespace Cuke4Nuke.Core 9 | { 10 | public class AfterHook : Hook 11 | { 12 | public AfterHook(MethodInfo method) 13 | : base(method) 14 | { 15 | if (!AfterHook.IsValidMethod(method)) 16 | { 17 | throw new ArgumentException(String.Format("<{0}> is not a valid After hook method.", method)); 18 | } 19 | Method = method; 20 | } 21 | 22 | public new static bool IsValidMethod(MethodInfo method) 23 | { 24 | bool hasAHookAttribute = GetHookAttributes(method).Length == 1; 25 | bool hasNoParameters = method.GetParameters().Length == 0; 26 | return hasAHookAttribute && hasNoParameters; 27 | } 28 | 29 | private static HookAttribute[] GetHookAttributes(MethodInfo method) 30 | { 31 | return (HookAttribute[])method.GetCustomAttributes(typeof(AfterAttribute), true); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Cuke4Nuke/Core/BeforeHook.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Reflection; 6 | using Cuke4Nuke.Framework; 7 | 8 | namespace Cuke4Nuke.Core 9 | { 10 | public class BeforeHook : Hook 11 | { 12 | public BeforeHook(MethodInfo method) : base(method) 13 | { 14 | if (!BeforeHook.IsValidMethod(method)) 15 | { 16 | throw new ArgumentException(String.Format("<{0}> is not a valid Before hook method.", method)); 17 | } 18 | Method = method; 19 | } 20 | 21 | public new static bool IsValidMethod(MethodInfo method) 22 | { 23 | bool hasAHookAttribute = GetHookAttributes(method).Length == 1; 24 | bool hasNoParameters = method.GetParameters().Length == 0; 25 | return hasAHookAttribute && hasNoParameters; 26 | } 27 | 28 | private static HookAttribute[] GetHookAttributes(MethodInfo method) 29 | { 30 | return (HookAttribute[])method.GetCustomAttributes(typeof(BeforeAttribute), true); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Cuke4Nuke/Core/Core.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {3CF36FF9-CE32-4868-84EC-D76E1E75148C} 9 | Library 10 | Properties 11 | Cuke4Nuke.Core 12 | Cuke4Nuke.Core 13 | v3.5 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | False 36 | ..\lib\Castle.Core.dll 37 | 38 | 39 | False 40 | ..\lib\Castle.MicroKernel.dll 41 | 42 | 43 | False 44 | ..\lib\LitJson.dll 45 | 46 | 47 | False 48 | ..\lib\log4net.dll 49 | 50 | 51 | False 52 | ..\lib\Newtonsoft.Json.dll 53 | 54 | 55 | False 56 | ..\lib\nunit.framework.dll 57 | 58 | 59 | 60 | 3.5 61 | 62 | 63 | 3.0 64 | 65 | 66 | 3.5 67 | 68 | 69 | 3.5 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | {12400276-AA80-418A-9D57-AE4B77EAAF51} 94 | Framework 95 | 96 | 97 | 98 | 105 | -------------------------------------------------------------------------------- /Cuke4Nuke/Core/ExtensionMethods.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cuke4Nuke.Core 4 | { 5 | public static class ExtensionMethods 6 | { 7 | public static string FullNameWithArgTypes(this System.Reflection.MethodInfo methodInfo) 8 | { 9 | // Is there a better way of getting a fully qualified signature that includes the parameter types? 10 | var signatureWithReturnType = methodInfo.ToString(); 11 | var positionOfSpaceAfterReturnType = signatureWithReturnType.IndexOf(' '); 12 | var signatureWithoutReturnType = signatureWithReturnType.Substring(positionOfSpaceAfterReturnType + 1); 13 | var methodName = String.Format("{0}.{1}", methodInfo.DeclaringType.FullName, signatureWithoutReturnType); 14 | return methodName; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Cuke4Nuke/Core/Hook.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using System.Text.RegularExpressions; 5 | using Cuke4Nuke.Framework; 6 | 7 | namespace Cuke4Nuke.Core 8 | { 9 | public class Hook 10 | { 11 | protected Hook() 12 | { 13 | } 14 | 15 | public Hook(MethodInfo method) 16 | { 17 | if (!IsValidMethod(method)) 18 | { 19 | throw new ArgumentException(String.Format("<{0}> is not a valid hook method.", method)); 20 | } 21 | 22 | 23 | var hookAttribute = GetHookAttributes(method)[0]; 24 | 25 | if (hookAttribute.Tag != null) 26 | { 27 | Tag = Regex.Replace(hookAttribute.Tag, @"^@(.*)$", @"$1"); 28 | } 29 | 30 | Method = method; 31 | } 32 | 33 | public bool HasTags 34 | { 35 | get { return !string.IsNullOrEmpty(Tag); } 36 | } 37 | 38 | public MethodInfo Method { get; protected set; } 39 | 40 | public string Tag { get; set; } 41 | 42 | public static bool IsValidMethod(MethodInfo method) 43 | { 44 | bool hasAHookAttribute = GetHookAttributes(method).Length == 1; 45 | bool hasNoParameters = method.GetParameters().Length == 0; 46 | return hasAHookAttribute && hasNoParameters; 47 | } 48 | 49 | private static HookAttribute[] GetHookAttributes(MethodInfo method) 50 | { 51 | return (HookAttribute[]) method.GetCustomAttributes(typeof (HookAttribute), true); 52 | } 53 | 54 | public void Invoke(ObjectFactory objectFactory) 55 | { 56 | try 57 | { 58 | object instance = null; 59 | if (!Method.IsStatic) 60 | { 61 | instance = objectFactory.GetObject(Method.DeclaringType); 62 | } 63 | Method.Invoke(instance, null); 64 | } 65 | catch (TargetInvocationException ex) 66 | { 67 | throw ex.InnerException; 68 | } 69 | } 70 | 71 | public void Invoke(ObjectFactory objectFactory, string[] scenarioTags) 72 | { 73 | if (!HasTags || ScenarioHasMatchingTag(scenarioTags, Tag)) 74 | { 75 | Invoke(objectFactory); 76 | } 77 | } 78 | 79 | private bool ScenarioHasMatchingTag(string[] scenarioTags, string hookTag) 80 | { 81 | return (new List(scenarioTags)).Contains(hookTag); 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /Cuke4Nuke/Core/Listener.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Net; 4 | using System.Net.Sockets; 5 | using System.Threading; 6 | 7 | namespace Cuke4Nuke.Core 8 | { 9 | public class Listener 10 | { 11 | readonly IProcessor _processor; 12 | readonly int _port; 13 | bool _stopping; 14 | 15 | protected AutoResetEvent Started = new AutoResetEvent(false); 16 | protected AutoResetEvent Stopped = new AutoResetEvent(false); 17 | 18 | public EventHandler MessageLogged; 19 | 20 | public Listener(IProcessor processor, int port) 21 | { 22 | _processor = processor; 23 | _port = port; 24 | } 25 | 26 | public virtual void Start() 27 | { 28 | Run(); 29 | } 30 | 31 | public virtual void Stop() 32 | { 33 | _stopping = true; 34 | Log("Stopping."); 35 | } 36 | 37 | protected void Run() 38 | { 39 | var listener = StartTcpListener(); 40 | 41 | Started.Set(); 42 | 43 | while (!_stopping) 44 | { 45 | using (var client = WaitForClientToConnect(listener)) 46 | { 47 | if (!_stopping) 48 | { 49 | Process(client); 50 | client.Close(); 51 | } 52 | } 53 | } 54 | 55 | listener.Stop(); 56 | 57 | Stopped.Set(); 58 | } 59 | 60 | TcpListener StartTcpListener() 61 | { 62 | var endPoint = new IPEndPoint(IPAddress.Any, _port); 63 | var listener = new TcpListener(endPoint); 64 | 65 | listener.Start(0); 66 | Log("Listening on port " + _port); 67 | 68 | return listener; 69 | } 70 | 71 | protected virtual TcpClient WaitForClientToConnect(TcpListener listener) 72 | { 73 | TcpClient client = null; 74 | 75 | Log("Waiting for client to connect."); 76 | 77 | while (!_stopping) 78 | { 79 | if (listener.Pending()) 80 | { 81 | client = listener.AcceptTcpClient(); 82 | Log("Connected to client."); 83 | break; 84 | } 85 | Thread.Sleep(100); 86 | } 87 | 88 | return client; 89 | } 90 | 91 | protected virtual void Process(TcpClient client) 92 | { 93 | var stream = client.GetStream(); 94 | var reader = new StreamReader(stream); 95 | var writer = new StreamWriter(stream); 96 | 97 | try 98 | { 99 | while (!_stopping) 100 | { 101 | var request = GetRequest(reader); 102 | if (request == null) 103 | { 104 | Log("Client disconnected."); 105 | break; 106 | } 107 | 108 | var response = _processor.Process(request); 109 | Write(response, writer); 110 | } 111 | } 112 | catch (IOException x) 113 | { 114 | Log("Exception: " + x.Message); 115 | } 116 | } 117 | 118 | protected virtual string GetRequest(StreamReader reader) 119 | { 120 | Log("Waiting for request."); 121 | var command = reader.ReadLine(); 122 | Log("Received request <" + command + ">."); 123 | return command; 124 | } 125 | 126 | void Write(string response, StreamWriter writer) 127 | { 128 | Log("Responded with <" + response + ">."); 129 | writer.WriteLine(response); 130 | writer.Flush(); 131 | } 132 | 133 | protected void Log(string message) 134 | { 135 | var handler = MessageLogged; 136 | 137 | if (handler != null) 138 | { 139 | handler(this, new LogEventArgs(message)); 140 | } 141 | } 142 | } 143 | } -------------------------------------------------------------------------------- /Cuke4Nuke/Core/Loader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | 5 | namespace Cuke4Nuke.Core 6 | { 7 | public class Loader 8 | { 9 | private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 10 | 11 | readonly IEnumerable _assemblyPaths; 12 | readonly ObjectFactory _objectFactory; 13 | 14 | public Loader(IEnumerable assemblyPaths, ObjectFactory objectFactory) 15 | { 16 | _assemblyPaths = assemblyPaths; 17 | _objectFactory = objectFactory; 18 | } 19 | 20 | public virtual Repository Load() 21 | { 22 | var repository = new Repository(); 23 | 24 | foreach (var assemblyPath in _assemblyPaths) 25 | { 26 | var assembly = Assembly.LoadFrom(assemblyPath); 27 | foreach (var type in assembly.GetTypes()) 28 | { 29 | foreach (var method in type.GetMethods(StepDefinition.MethodFlags)) 30 | { 31 | if (StepDefinition.IsValidMethod(method)) 32 | { 33 | repository.StepDefinitions.Add(new StepDefinition(method)); 34 | _objectFactory.AddClass(method.ReflectedType); 35 | } 36 | if (BeforeHook.IsValidMethod(method)) 37 | { 38 | repository.BeforeHooks.Add(new BeforeHook(method)); 39 | _objectFactory.AddClass(method.ReflectedType); 40 | } 41 | if (AfterHook.IsValidMethod(method)) 42 | { 43 | repository.AfterHooks.Add(new AfterHook(method)); 44 | _objectFactory.AddClass(method.ReflectedType); 45 | } 46 | } 47 | } 48 | } 49 | 50 | return repository; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /Cuke4Nuke/Core/LogEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cuke4Nuke.Core 4 | { 5 | public class LogEventArgs : EventArgs 6 | { 7 | public string Message { get; private set; } 8 | 9 | public LogEventArgs(string message) 10 | { 11 | Message = message; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Cuke4Nuke/Core/ObjectFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Castle.MicroKernel; 6 | using System.Reflection; 7 | using System.Diagnostics; 8 | 9 | namespace Cuke4Nuke.Core 10 | { 11 | public class ObjectFactory 12 | { 13 | private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 14 | 15 | List _classes = new List(); 16 | IKernel _kernel; 17 | 18 | public void AddClass(Type type) 19 | { 20 | if (!_classes.Contains(type)) 21 | { 22 | _classes.Add(type); 23 | foreach (ConstructorInfo ci in type.GetConstructors()) 24 | { 25 | foreach (ParameterInfo pi in ci.GetParameters()) 26 | { 27 | AddClass(pi.ParameterType); 28 | } 29 | } 30 | } 31 | } 32 | 33 | public void CreateObjects() 34 | { 35 | _kernel = new DefaultKernel(); 36 | foreach (Type type in _classes) 37 | { 38 | _kernel.AddComponent(type.ToString(), type); 39 | } 40 | } 41 | 42 | public object GetObject(Type type) 43 | { 44 | if (_kernel == null || !_kernel.HasComponent(type)) 45 | { 46 | return null; 47 | } 48 | 49 | return _kernel[type]; 50 | } 51 | 52 | public void DisposeObjects() 53 | { 54 | if (_kernel != null) 55 | { 56 | _kernel.Dispose(); 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Cuke4Nuke/Core/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("Core")] 8 | [assembly: AssemblyDescription("Cuke4Nuke Core")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("Core")] 12 | [assembly: AssemblyCopyright("Copyright © 2009 Richard Laurence, Declan Whelan")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("d3f65fc4-0683-40c1-906a-78fb8351b35c")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Cuke4Nuke/Core/Repository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Cuke4Nuke.Core 7 | { 8 | public class Repository 9 | { 10 | public Repository() 11 | { 12 | StepDefinitions = new List(); 13 | BeforeHooks = new List(); 14 | AfterHooks = new List(); 15 | } 16 | 17 | public Repository(List stepDefinitions, List beforeHooks, List afterHooks) 18 | { 19 | StepDefinitions = stepDefinitions; 20 | BeforeHooks = beforeHooks; 21 | AfterHooks = afterHooks; 22 | } 23 | 24 | public List StepDefinitions { get; private set; } 25 | public List BeforeHooks { get; private set; } 26 | public List AfterHooks { get; private set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Cuke4Nuke/Core/SnippetBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using System.Text.RegularExpressions; 3 | using System; 4 | 5 | namespace Cuke4Nuke.Core 6 | { 7 | public class SnippetBuilder 8 | { 9 | public string GenerateSnippet(string keyword, string stepName) 10 | { 11 | string multilineArgClass = String.Empty; 12 | return GenerateSnippet(keyword, stepName, multilineArgClass); 13 | } 14 | 15 | public string GenerateSnippet(string keyword, string stepName, string multilineArgClass) 16 | { 17 | string parameter = ""; 18 | if (multilineArgClass == "Cucumber::Ast::Table") 19 | { 20 | parameter = "Table table"; 21 | } 22 | else if (multilineArgClass == "Cucumber::Ast::PyString") 23 | { 24 | parameter = "string str"; 25 | } 26 | 27 | string methodName = StepNameToMethodName(stepName); 28 | stepName = stepName.Replace("\"", "\"\""); 29 | StringBuilder sb = new StringBuilder(); 30 | sb.Append("[Pending]\n"); 31 | sb.AppendFormat("[{0}(@\"^{1}$\")]\n", keyword, stepName); 32 | sb.AppendFormat("public void {0}({1})\n", methodName, parameter); 33 | sb.Append("{\n"); 34 | sb.Append("}"); 35 | string snippet = sb.ToString(); 36 | return snippet; 37 | } 38 | 39 | public string StepNameToMethodName(string stepName) 40 | { 41 | string s = stepName; 42 | s = Regex.Replace(s, @"[^A-Za-z0-9\s]", ""); 43 | s = Regex.Replace(s, @"\s+", " "); 44 | s = s.Trim(); 45 | string[] words = s.Split(' '); 46 | StringBuilder methodNameBuilder = new StringBuilder(); 47 | foreach (string word in words) 48 | { 49 | methodNameBuilder.Append(word.Substring(0, 1).ToUpper()); 50 | if (word.Length > 1) 51 | { 52 | methodNameBuilder.Append(word.Substring(1).ToLower()); 53 | } 54 | } 55 | return methodNameBuilder.ToString(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Cuke4Nuke/Core/StepArgument.cs: -------------------------------------------------------------------------------- 1 | namespace Cuke4Nuke.Core 2 | { 3 | class StepArgument 4 | { 5 | public string Val { get; private set; } 6 | public int Pos { get; private set; } 7 | 8 | public StepArgument(string val, int pos) 9 | { 10 | Val = val; 11 | Pos = pos; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Cuke4Nuke/Core/StepDefinition.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using System.Text.RegularExpressions; 5 | 6 | using Cuke4Nuke.Framework; 7 | using System.ComponentModel; 8 | 9 | namespace Cuke4Nuke.Core 10 | { 11 | public class StepDefinition : IEquatable 12 | { 13 | private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 14 | 15 | public const BindingFlags MethodFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; 16 | 17 | private Regex _regex; 18 | public MethodInfo Method { get; private set; } 19 | public string Id { get; private set; } 20 | 21 | public StepDefinition(MethodInfo method) 22 | { 23 | var attributes = GetStepDefinitionAttributes(method); 24 | if (attributes.Length == 0) 25 | { 26 | throw new ArgumentException("method " + method + " does not have a step definition attribute"); 27 | } 28 | _regex = new Regex(attributes[0].Pattern); 29 | 30 | Method = method; 31 | 32 | Id = method.FullNameWithArgTypes(); 33 | 34 | Pending = (method.GetCustomAttributes(typeof(PendingAttribute), true).Length == 1); 35 | } 36 | 37 | public static bool IsValidMethod(MethodInfo method) 38 | { 39 | return GetStepDefinitionAttributes(method).Length == 1; 40 | } 41 | 42 | static StepDefinitionAttribute[] GetStepDefinitionAttributes(MethodInfo method) 43 | { 44 | return (StepDefinitionAttribute[]) method.GetCustomAttributes(typeof (StepDefinitionAttribute), true); 45 | } 46 | 47 | public void Invoke(ObjectFactory objectFactory, params string[] args) 48 | { 49 | ParameterInfo[] parameters = Method.GetParameters(); 50 | if (parameters.Length != args.Length) 51 | { 52 | throw new ArgumentException("Expected " + parameters.Length + " argument(s); got " + args.Length); 53 | } 54 | var typedArgs = new object[args.Length]; 55 | for (int i = 0; i < args.Length; ++i) 56 | { 57 | TypeConverter converter = TypeDescriptor.GetConverter(parameters[i].ParameterType); 58 | typedArgs[i] = converter.ConvertFromString(args[i]); 59 | } 60 | 61 | object instance = null; 62 | if (!Method.IsStatic) 63 | { 64 | instance = objectFactory.GetObject(Method.DeclaringType); 65 | } 66 | Method.Invoke(instance, typedArgs); 67 | } 68 | 69 | public bool Equals(StepDefinition other) 70 | { 71 | return other != null && other.Id == Id; 72 | } 73 | 74 | public override bool Equals(object obj) 75 | { 76 | return Equals(obj as StepDefinition); 77 | } 78 | 79 | public override int GetHashCode() 80 | { 81 | return Id.GetHashCode(); 82 | } 83 | 84 | public bool Pending 85 | { 86 | get; 87 | set; 88 | } 89 | 90 | internal List ArgumentsFrom(string stepName) 91 | { 92 | List arguments = null; 93 | Match match = _regex.Match(stepName); 94 | if(match.Success) 95 | { 96 | arguments = new List(); 97 | for (int i = 1; i < match.Groups.Count; i++) 98 | { 99 | Group group = match.Groups[i]; 100 | arguments.Add(new StepArgument(group.Value, group.Index)); 101 | } 102 | } 103 | return arguments; 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /Cuke4Nuke/Core/TableConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Globalization; 5 | using Cuke4Nuke.Framework; 6 | using Newtonsoft.Json; 7 | using Newtonsoft.Json.Linq; 8 | 9 | namespace Cuke4Nuke.Core 10 | { 11 | public class TableConverter : TypeConverter 12 | { 13 | private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 14 | 15 | public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 16 | { 17 | if (sourceType == typeof(string)) 18 | { 19 | return true; 20 | } 21 | return base.CanConvertFrom(context, sourceType); 22 | } 23 | 24 | public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) 25 | { 26 | if (value is string) 27 | { 28 | return JsonToTable(value.ToString()); 29 | } 30 | return base.ConvertFrom(context, culture, value); 31 | } 32 | 33 | public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) 34 | { 35 | if (destinationType == typeof(string)) 36 | { 37 | return true; 38 | } 39 | return base.CanConvertTo(context, destinationType); 40 | } 41 | 42 | public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) 43 | { 44 | if (destinationType == typeof(string)) 45 | { 46 | return TableToJsonString(((Table)value)); 47 | } 48 | return base.ConvertTo(context, culture, value, destinationType); 49 | } 50 | 51 | public Table JsonToTable(string jsonTable) 52 | { 53 | Table table = new Table(); 54 | 55 | if (jsonTable == null || jsonTable == String.Empty) 56 | { 57 | return table; 58 | } 59 | 60 | ArgumentException invalidDataEx = new ArgumentException("Input not in expected format. Expecting a JSON array of string arrays."); 61 | 62 | JArray rows; 63 | try 64 | { 65 | rows = JArray.Parse(jsonTable); 66 | } 67 | catch (Exception) 68 | { 69 | throw invalidDataEx; 70 | } 71 | 72 | if (rows.Count == 0) 73 | { 74 | return table; 75 | } 76 | 77 | foreach (JToken row in rows.Children()) 78 | { 79 | if (!(row.Type == JTokenType.Array)) 80 | { 81 | throw invalidDataEx; 82 | } 83 | 84 | var values = new List(); 85 | 86 | foreach (JToken cell in row.Children()) 87 | { 88 | if (!(cell.Type == JTokenType.String)) 89 | { 90 | throw invalidDataEx; 91 | } 92 | values.Add(cell.Value() as string); 93 | } 94 | 95 | table.Data.Add(values); 96 | } 97 | return table; 98 | } 99 | 100 | public string TableToJsonString(Table table) 101 | { 102 | return JsonConvert.SerializeObject(table.Data, Formatting.None); 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Cuke4Nuke/Cuke4Nuke.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Server", "Server\Server.csproj", "{936E6D55-416C-4008-A682-84825AE0E4DB}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Specifications", "Specifications\Specifications.csproj", "{F1BCCFD7-5B2D-4255-887C-BF06A03D4D2F}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Framework", "Framework\Framework.csproj", "{12400276-AA80-418A-9D57-AE4B77EAAF51}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core", "Core\Core.csproj", "{3CF36FF9-CE32-4868-84EC-D76E1E75148C}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestStepDefinitions", "TestStepDefinitions\TestStepDefinitions.csproj", "{AE068AEA-645F-4DF7-BAD1-671B5DE5576D}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Any CPU = Debug|Any CPU 17 | Release|Any CPU = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {936E6D55-416C-4008-A682-84825AE0E4DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {936E6D55-416C-4008-A682-84825AE0E4DB}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {936E6D55-416C-4008-A682-84825AE0E4DB}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {936E6D55-416C-4008-A682-84825AE0E4DB}.Release|Any CPU.Build.0 = Release|Any CPU 24 | {F1BCCFD7-5B2D-4255-887C-BF06A03D4D2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {F1BCCFD7-5B2D-4255-887C-BF06A03D4D2F}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {F1BCCFD7-5B2D-4255-887C-BF06A03D4D2F}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {F1BCCFD7-5B2D-4255-887C-BF06A03D4D2F}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {12400276-AA80-418A-9D57-AE4B77EAAF51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {12400276-AA80-418A-9D57-AE4B77EAAF51}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {12400276-AA80-418A-9D57-AE4B77EAAF51}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {12400276-AA80-418A-9D57-AE4B77EAAF51}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {3CF36FF9-CE32-4868-84EC-D76E1E75148C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {3CF36FF9-CE32-4868-84EC-D76E1E75148C}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {3CF36FF9-CE32-4868-84EC-D76E1E75148C}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {3CF36FF9-CE32-4868-84EC-D76E1E75148C}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {AE068AEA-645F-4DF7-BAD1-671B5DE5576D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 37 | {AE068AEA-645F-4DF7-BAD1-671B5DE5576D}.Debug|Any CPU.Build.0 = Debug|Any CPU 38 | {AE068AEA-645F-4DF7-BAD1-671B5DE5576D}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {AE068AEA-645F-4DF7-BAD1-671B5DE5576D}.Release|Any CPU.Build.0 = Release|Any CPU 40 | EndGlobalSection 41 | GlobalSection(SolutionProperties) = preSolution 42 | HideSolutionNode = FALSE 43 | EndGlobalSection 44 | EndGlobal 45 | -------------------------------------------------------------------------------- /Cuke4Nuke/Framework/AfterAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace Cuke4Nuke.Framework 2 | { 3 | public class AfterAttribute : HookAttribute 4 | { 5 | public AfterAttribute() 6 | : base() 7 | { 8 | } 9 | 10 | public AfterAttribute(string tag) 11 | : base(tag) 12 | { 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Cuke4Nuke/Framework/BeforeAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace Cuke4Nuke.Framework 2 | { 3 | public class BeforeAttribute : HookAttribute 4 | { 5 | public BeforeAttribute() 6 | : base() 7 | { 8 | } 9 | 10 | public BeforeAttribute(string tag) 11 | : base(tag) 12 | { 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Cuke4Nuke/Framework/Framework.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {12400276-AA80-418A-9D57-AE4B77EAAF51} 9 | Library 10 | Properties 11 | Cuke4Nuke.Framework 12 | Cuke4Nuke.Framework 13 | v3.5 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 3.5 37 | 38 | 39 | 40 | 41 | 3.5 42 | 43 | 44 | 3.5 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | Code 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 73 | -------------------------------------------------------------------------------- /Cuke4Nuke/Framework/GivenAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace Cuke4Nuke.Framework 2 | { 3 | public class GivenAttribute : StepDefinitionAttribute 4 | { 5 | public GivenAttribute(string pattern) : base(pattern) 6 | { 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Cuke4Nuke/Framework/HookAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cuke4Nuke.Framework 4 | { 5 | [AttributeUsage(AttributeTargets.Method)] 6 | public abstract class HookAttribute : Attribute 7 | { 8 | public string Tag { get; private set; } 9 | 10 | public HookAttribute() 11 | { 12 | } 13 | 14 | public HookAttribute(string tag) 15 | { 16 | Tag = tag; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Cuke4Nuke/Framework/PendingAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cuke4Nuke.Framework 4 | { 5 | [AttributeUsage(AttributeTargets.Method)] 6 | public class PendingAttribute : Attribute 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Cuke4Nuke/Framework/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("Framework")] 8 | [assembly: AssemblyDescription("Cuke4Nuke Framework")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("Framework")] 12 | [assembly: AssemblyCopyright("Copyright © 2009 Richard Laurence, Declan Whelan")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("59c471e3-a34e-4a58-9373-2836add5a3bb")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Cuke4Nuke/Framework/StepDefinitionAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cuke4Nuke.Framework 4 | { 5 | [AttributeUsage(AttributeTargets.Method)] 6 | public abstract class StepDefinitionAttribute : Attribute 7 | { 8 | public string Pattern { get; private set; } 9 | 10 | protected StepDefinitionAttribute(string pattern) 11 | { 12 | Pattern = pattern; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Cuke4Nuke/Framework/Table.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Cuke4Nuke.Framework 7 | { 8 | public class Table 9 | { 10 | public List> Hashes() 11 | { 12 | var hashes = new List>(); 13 | if (_data.Count == 0) 14 | return hashes; 15 | 16 | var keys = Headers(); 17 | 18 | for (int i = 1; i < _data.Count; i++) 19 | { 20 | var hash = new Dictionary(); 21 | for (int j = 0; j < _data[i].Count; j++) 22 | { 23 | hash.Add(keys[j], _data[i][j]); 24 | } 25 | hashes.Add(hash); 26 | } 27 | 28 | return hashes; 29 | } 30 | 31 | List> _data = new List>(); 32 | public List> Data 33 | { 34 | get 35 | { 36 | return _data; 37 | } 38 | } 39 | 40 | public void AssertSameAs(Table expectedTable) 41 | { 42 | throw new TableAssertionException(this, expectedTable); 43 | } 44 | 45 | public bool Includes(Table expectedTable) 46 | { 47 | foreach (var exRow in expectedTable.Hashes()) 48 | { 49 | bool hasMatchingRow = false; 50 | foreach (var acRow in this.Hashes()) 51 | { 52 | foreach (var key in exRow.Keys) 53 | { 54 | if (exRow[key] == acRow[key]) 55 | { 56 | hasMatchingRow = true; 57 | } 58 | else 59 | { 60 | hasMatchingRow = false; 61 | break; 62 | } 63 | } 64 | if (hasMatchingRow) 65 | break; 66 | } 67 | if (!hasMatchingRow) 68 | return false; 69 | } 70 | return true; 71 | } 72 | 73 | public List Headers() 74 | { 75 | if (Data.Count == 0) 76 | return new List(); 77 | else 78 | return Data[0]; 79 | } 80 | 81 | public Dictionary RowHashes() 82 | { 83 | if (_data.Count == 0 || _data[0].Count != 2) 84 | throw new InvalidOperationException("Table must contain exactly two columns to use RowHashes()."); 85 | 86 | var rowHashes = new Dictionary(); 87 | foreach (var row in _data) 88 | { 89 | rowHashes.Add(row[0], row[1]); 90 | } 91 | return rowHashes; 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Cuke4Nuke/Framework/TableAssertionException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Cuke4Nuke.Framework 7 | { 8 | public class TableAssertionException : Exception 9 | { 10 | public Table Actual { get; private set; } 11 | public Table Expected { get; private set; } 12 | 13 | public TableAssertionException(Table actualTable, Table expectedTable) 14 | { 15 | this.Actual = actualTable; 16 | this.Expected = expectedTable; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Cuke4Nuke/Framework/ThenAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace Cuke4Nuke.Framework 2 | { 3 | public class ThenAttribute : StepDefinitionAttribute 4 | { 5 | public ThenAttribute(string pattern) : base(pattern) 6 | { 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /Cuke4Nuke/Framework/WhenAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace Cuke4Nuke.Framework 2 | { 3 | public class WhenAttribute : StepDefinitionAttribute 4 | { 5 | public WhenAttribute(string pattern) : base(pattern) 6 | { 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /Cuke4Nuke/Server/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Cuke4Nuke/Server/NukeServer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | using Cuke4Nuke.Core; 5 | 6 | namespace Cuke4Nuke.Server 7 | { 8 | public class NukeServer 9 | { 10 | private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 11 | 12 | private readonly Listener _listener; 13 | readonly Options _options; 14 | 15 | public NukeServer(Listener listener, Options options) 16 | { 17 | _listener = listener; 18 | _options = options; 19 | } 20 | 21 | public void Start() 22 | { 23 | if (_options.ShowHelp) 24 | { 25 | ShowHelp(); 26 | } 27 | else 28 | { 29 | Run(); 30 | } 31 | } 32 | 33 | void Run() 34 | { 35 | _listener.MessageLogged += listener_LogMessage; 36 | try 37 | { 38 | _listener.Start(); 39 | } 40 | catch (Exception ex) 41 | { 42 | string message = "Unable to start listener. Exception:\n\n" + ex.Message; 43 | log.Fatal(message); 44 | } 45 | finally 46 | { 47 | try 48 | { 49 | _listener.Stop(); 50 | } 51 | catch (Exception e) 52 | { 53 | string message = "Unable to gracefully stop listener. Exception:\n\n" + e.Message; 54 | log.Fatal(message); 55 | } 56 | } 57 | } 58 | 59 | void ShowHelp() 60 | { 61 | Log("Usage: Cuke4Nuke.Server.exe [OPTIONS]"); 62 | Log("Start the Cuke4Nuke server to invoke .NET Cucumber step definitions."); 63 | Log(""); 64 | Log(_options.ToString()); 65 | } 66 | 67 | void listener_LogMessage(object sender, LogEventArgs e) 68 | { 69 | Log(e.Message); 70 | } 71 | 72 | void Log(string message) 73 | { 74 | log.Info(message); 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /Cuke4Nuke/Server/Options.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.ObjectModel; 3 | using System.IO; 4 | 5 | using NDesk.Options; 6 | using System.Collections.Generic; 7 | 8 | namespace Cuke4Nuke.Server 9 | { 10 | public class Options 11 | { 12 | public static readonly int DefaultPort = 3901; 13 | 14 | public int Port { get; set; } 15 | public bool ShowHelp { get; set; } 16 | public ICollection AssemblyPaths { get; set; } 17 | 18 | private readonly OptionSet options; 19 | 20 | public Options(params string[] args) 21 | { 22 | Port = DefaultPort; 23 | AssemblyPaths = new Collection(); 24 | 25 | options = new OptionSet 26 | { 27 | { 28 | "p|port=", 29 | "the {PORT} the server should listen on (default=" + DefaultPort + ").", 30 | (int v) => Port = v 31 | }, 32 | { 33 | "a|assembly=", 34 | "an assembly to search for step definition methods.", 35 | v => AssemblyPaths.Add(v) 36 | }, 37 | { 38 | "h|?|help", 39 | "show this message and exit.", 40 | v => ShowHelp = v != null 41 | } 42 | }; 43 | options.Parse(args); 44 | } 45 | 46 | public void Write(TextWriter textWriter) 47 | { 48 | textWriter.WriteLine("Options:"); 49 | options.WriteOptionDescriptions(textWriter); 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /Cuke4Nuke/Server/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.IO.IsolatedStorage; 4 | 5 | using Cuke4Nuke.Core; 6 | 7 | namespace Cuke4Nuke.Server 8 | { 9 | public class Program 10 | { 11 | [STAThread] 12 | static void Main(string[] args) 13 | { 14 | 15 | var options = new Options(args); 16 | var objectFactory = new ObjectFactory(); 17 | var loader = new Loader(options.AssemblyPaths, objectFactory); 18 | var processor = new Processor(loader, objectFactory); 19 | var listener = new Listener(processor, options.Port); 20 | log4net.Config.XmlConfigurator.Configure(); 21 | 22 | new NukeServer(listener, options).Start(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Cuke4Nuke/Server/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("Server")] 8 | [assembly: AssemblyDescription("Cuke4Nuke Server")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("Server")] 12 | [assembly: AssemblyCopyright("Copyright © 2009 Richard Laurence, Declan Whelan")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("a120e28b-8a5c-48d3-a60f-9f0f2613aec5")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Cuke4Nuke/Server/Server.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {936E6D55-416C-4008-A682-84825AE0E4DB} 9 | Exe 10 | Properties 11 | Cuke4Nuke.Server 12 | Cuke4Nuke.Server 13 | v3.5 14 | 512 15 | Cuke4Nuke.Server.Program 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | x86 34 | 35 | 36 | 37 | False 38 | ..\lib\log4net.dll 39 | 40 | 41 | False 42 | ..\lib\NDesk.Options.dll 43 | 44 | 45 | 46 | 3.5 47 | 48 | 49 | 3.5 50 | 51 | 52 | 3.5 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | {3CF36FF9-CE32-4868-84EC-D76E1E75148C} 66 | Core 67 | 68 | 69 | {AE068AEA-645F-4DF7-BAD1-671B5DE5576D} 70 | TestStepDefinitions 71 | 72 | 73 | 74 | 75 | 76 | 77 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /Cuke4Nuke/Specifications/Core/AfterHook_Specification.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using NUnit.Framework; 6 | using Cuke4Nuke.Framework; 7 | using Cuke4Nuke.Core; 8 | 9 | namespace Cuke4Nuke.Specifications.Core 10 | { 11 | public class AfterHook_Specification 12 | { 13 | [Test] 14 | public void Should_load_After_method_successfully() 15 | { 16 | var method = Reflection.GetMethod(typeof(ValidHooks), "After1"); 17 | var hook = new AfterHook(method); 18 | Assert.That(hook.Method, Is.EqualTo(method)); 19 | } 20 | 21 | [Test] 22 | [ExpectedException(typeof(ArgumentException))] 23 | public void Should_not_load_Before_method() 24 | { 25 | var method = Reflection.GetMethod(typeof(InvalidHooks), "Before1"); 26 | var hook = new AfterHook(method); 27 | } 28 | 29 | public class ValidHooks 30 | { 31 | [After] 32 | public void After1() { } 33 | } 34 | 35 | public class InvalidHooks 36 | { 37 | [Before] 38 | private void Before1() { } 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Cuke4Nuke/Specifications/Core/AsyncListener.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | 3 | using Cuke4Nuke.Core; 4 | 5 | namespace Cuke4Nuke.Specifications.Core 6 | { 7 | internal class AsyncListener : Listener 8 | { 9 | readonly Thread _thread; 10 | 11 | public int ReadTimeout { get; set; } 12 | 13 | public AsyncListener(IProcessor processor, int port) 14 | : base(processor, port) 15 | { 16 | _thread = new Thread(Run) { Name = "AsyncListener" }; 17 | } 18 | 19 | public override void Start() 20 | { 21 | _thread.Start(); 22 | Started.WaitOne(); 23 | } 24 | 25 | public override void Stop() 26 | { 27 | base.Stop(); 28 | 29 | Log("Waiting for stopped event."); 30 | Stopped.WaitOne(); 31 | 32 | Log("Waiting for listener thread to complete."); 33 | _thread.Join(); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /Cuke4Nuke/Specifications/Core/BeforeHook_Specification.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using NUnit.Framework; 6 | using Cuke4Nuke.Framework; 7 | using Cuke4Nuke.Core; 8 | 9 | namespace Cuke4Nuke.Specifications.Core 10 | { 11 | public class BeforeHook_Specification 12 | { 13 | [Test] 14 | public void Should_load_Before_method_successfully() 15 | { 16 | var method = Reflection.GetMethod(typeof(ValidHooks), "Before1"); 17 | var hook = new BeforeHook(method); 18 | Assert.That(hook.Method, Is.EqualTo(method)); 19 | } 20 | 21 | [Test] 22 | [ExpectedException(typeof(ArgumentException))] 23 | public void Should_not_load_After_method() 24 | { 25 | var method = Reflection.GetMethod(typeof(InvalidHooks), "After1"); 26 | var hook = new BeforeHook(method); 27 | } 28 | 29 | public class ValidHooks 30 | { 31 | [Before] 32 | private void Before1() { } 33 | } 34 | 35 | public class InvalidHooks 36 | { 37 | [After] 38 | public void After1() { } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Cuke4Nuke/Specifications/Core/Hook_Specification.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using NUnit.Framework; 6 | using Cuke4Nuke.Framework; 7 | using System.Reflection; 8 | using Cuke4Nuke.Core; 9 | 10 | namespace Cuke4Nuke.Specifications.Core 11 | { 12 | [TestFixture] 13 | public class Hook_Specification 14 | { 15 | const BindingFlags MethodFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly; 16 | 17 | [Test] 18 | public void Should_allow_valid_methods() 19 | { 20 | var methods = typeof(ValidHooks).GetMethods(MethodFlags); 21 | foreach (MethodInfo method in methods) 22 | { 23 | Assert.IsTrue(Hook.IsValidMethod(method), String.Format("<{0}> is not a valid hook method.", method)); 24 | } 25 | } 26 | 27 | [Test] 28 | public void Should_not_allow_invalid_methods() 29 | { 30 | var methods = typeof(InvalidHooks).GetMethods(MethodFlags); 31 | foreach (MethodInfo method in methods) 32 | { 33 | Assert.IsFalse(Hook.IsValidMethod(method), String.Format("<{0}> is a valid hook method.", method)); 34 | } 35 | } 36 | 37 | [Test] 38 | public void Constructor_should_take_a_method_for_Method_property() 39 | { 40 | var method = Reflection.GetMethod(typeof(ValidHooks), "Before1"); 41 | var hook = new Hook(method); 42 | Assert.That(hook.Method, Is.EqualTo(method)); 43 | } 44 | 45 | [Test] 46 | [ExpectedException(typeof(ArgumentException))] 47 | public void Constructor_should_throw_given_invalid_method() 48 | { 49 | var method = Reflection.GetMethod(typeof(InvalidHooks), "Before1"); 50 | var hook = new Hook(method); 51 | } 52 | 53 | [Test] 54 | public void Should_invoke_method_successfully() 55 | { 56 | ObjectFactory objectFactory = new ObjectFactory(); 57 | objectFactory.AddClass(typeof(ValidHooks)); 58 | objectFactory.CreateObjects(); 59 | var method = Reflection.GetMethod(typeof(ValidHooks), "Before1"); 60 | var hook = new Hook(method); 61 | hook.Invoke(objectFactory); 62 | } 63 | 64 | [Test] 65 | public void Should_invoke_tagged_hook_when_scenario_has_matching_tag() 66 | { 67 | ObjectFactory objectFactory = new ObjectFactory(); 68 | objectFactory.AddClass(typeof(ValidHooks)); 69 | objectFactory.CreateObjects(); 70 | var method = Reflection.GetMethod(typeof(ValidHooks), "BeforeWithTagThrowsException"); 71 | var hook = new Hook(method); 72 | Assert.Throws(() => hook.Invoke(objectFactory, new string[] {"my_tag"})); 73 | } 74 | 75 | [Test] 76 | public void Should_not_invoke_tagged_hook_when_scenario_has_no_matching_tag() 77 | { 78 | ObjectFactory objectFactory = new ObjectFactory(); 79 | objectFactory.AddClass(typeof(ValidHooks)); 80 | objectFactory.CreateObjects(); 81 | var method = Reflection.GetMethod(typeof(ValidHooks), "BeforeWithTagThrowsException"); 82 | var hook = new Hook(method); 83 | hook.Invoke(objectFactory, new string[] { "not_my_tag" }); 84 | } 85 | 86 | [Test] 87 | public void Should_not_invoke_tagged_hook_when_scenario_has_no_tags() 88 | { 89 | ObjectFactory objectFactory = new ObjectFactory(); 90 | objectFactory.AddClass(typeof(ValidHooks)); 91 | objectFactory.CreateObjects(); 92 | var method = Reflection.GetMethod(typeof(ValidHooks), "BeforeWithTagThrowsException"); 93 | var hook = new Hook(method); 94 | hook.Invoke(objectFactory, new string[0]); 95 | } 96 | 97 | [Test] 98 | [ExpectedException(typeof(Exception))] 99 | public void Invoke_should_throw_when_method_throws() 100 | { 101 | ObjectFactory objectFactory = new ObjectFactory(); 102 | objectFactory.AddClass(typeof(ValidHooks)); 103 | objectFactory.CreateObjects(); 104 | var method = Reflection.GetMethod(typeof(ValidHooks), "ThrowsException"); 105 | var hook = new Hook(method); 106 | hook.Invoke(objectFactory); 107 | } 108 | 109 | [Test] 110 | public void Constructor_should_get_tag_from_attribute() 111 | { 112 | var method = Reflection.GetMethod(typeof(ValidHooks), "BeforeWithTag"); 113 | var hook = new Hook(method); 114 | Assert.That(hook.Tag, Is.EqualTo("my_tag")); 115 | } 116 | 117 | [Test] 118 | public void Constructor_should_set_HasTags_to_true_when_tags_on_attribute() 119 | { 120 | var method = Reflection.GetMethod(typeof(ValidHooks), "BeforeWithTag"); 121 | var hook = new Hook(method); 122 | Assert.That(hook.HasTags, Is.True); 123 | } 124 | 125 | [Test] 126 | public void Constructor_should_set_HasTags_to_false_when_no_tags_on_attribute() 127 | { 128 | var method = Reflection.GetMethod(typeof(ValidHooks), "Before1"); 129 | var hook = new Hook(method); 130 | Assert.That(hook.HasTags, Is.False); 131 | } 132 | 133 | public class ValidHooks 134 | { 135 | [Before] 136 | private void Before1() { } 137 | 138 | [Before] 139 | internal void Before2() { } 140 | 141 | [Before] 142 | protected void Before3() { } 143 | 144 | [Before] 145 | public void Before4() { } 146 | 147 | [Before] 148 | public static void Before5() { } 149 | 150 | [Before("@my_tag")] 151 | public static void BeforeWithTag() { } 152 | 153 | [Before] 154 | private void ThrowsException() 155 | { 156 | throw new Exception(); 157 | } 158 | 159 | [Before("@my_tag")] 160 | private void BeforeWithTagThrowsException() 161 | { 162 | throw new Exception(); 163 | } 164 | } 165 | 166 | public class InvalidHooks 167 | { 168 | // has a parameter 169 | [Before] 170 | public void Before1(object arg) { } 171 | 172 | // doesn't have an attribute 173 | public void Before2() { } 174 | 175 | // has a step definition attribute 176 | [Given("")] 177 | public void Before3() { } 178 | } 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /Cuke4Nuke/Specifications/Core/Listener_Specification.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Net.Sockets; 4 | 5 | using Cuke4Nuke.Core; 6 | 7 | using NUnit.Framework; 8 | 9 | namespace Cuke4Nuke.Specifications.Core 10 | { 11 | [TestFixture] 12 | public class Listener_Specification 13 | { 14 | public const int TestPort = 3902; 15 | 16 | static bool _logging; 17 | 18 | TcpClient _client; 19 | AsyncListener _listener; 20 | MockProcessor _processor; 21 | 22 | [TestFixtureSetUp] 23 | public void FixtureSetUp() 24 | { 25 | _logging = false; 26 | } 27 | 28 | [SetUp] 29 | public void SetUp() 30 | { 31 | StartListener(); 32 | StartClient(); 33 | } 34 | 35 | [TearDown] 36 | public void TearDown() 37 | { 38 | StopClient(); 39 | StopListener(); 40 | } 41 | 42 | [Test] 43 | public void Should_read_request_from_client_socket() 44 | { 45 | ProcessRequest("hunky"); 46 | 47 | Assert.That(_processor.Request, Is.EqualTo("hunky")); 48 | } 49 | 50 | [Test] 51 | public void Should_write_response_to_client_socket() 52 | { 53 | _processor.Response = "dory"; 54 | var response = ProcessRequest("hunky"); 55 | 56 | Assert.That(response, Is.EqualTo("dory")); 57 | } 58 | 59 | [Test] 60 | public void Should_rewait_for_clients_if_client_exits() 61 | { 62 | StopClient(); 63 | StartClient(); 64 | 65 | _processor.Response = "dory"; 66 | var response = ProcessRequest("hunky"); 67 | 68 | Assert.That(response, Is.EqualTo("dory")); 69 | } 70 | 71 | void StartClient() 72 | { 73 | _client = new TcpClient("localhost", TestPort); 74 | } 75 | 76 | void StopClient() 77 | { 78 | _client.Close(); 79 | } 80 | 81 | void StartListener() 82 | { 83 | _processor = new MockProcessor(); 84 | _listener = new AsyncListener(_processor, TestPort); 85 | _listener.MessageLogged += _listener_MessageLogged; 86 | _listener.Start(); 87 | } 88 | 89 | void StopListener() 90 | { 91 | _listener.Stop(); 92 | } 93 | 94 | string ProcessRequest(string request) 95 | { 96 | SendRequest(request); 97 | return GetResponse(); 98 | } 99 | 100 | void SendRequest(string request) 101 | { 102 | var writer = new StreamWriter(_client.GetStream()); 103 | writer.WriteLine(request); 104 | writer.Flush(); 105 | } 106 | 107 | string GetResponse() 108 | { 109 | var reader = new StreamReader(_client.GetStream()); 110 | return reader.ReadLine(); 111 | } 112 | 113 | private static void _listener_MessageLogged(object sender, LogEventArgs e) 114 | { 115 | if (_logging) 116 | { 117 | Console.WriteLine(e.Message); 118 | } 119 | } 120 | 121 | class MockProcessor : IProcessor 122 | { 123 | public string Request; 124 | public string Response; 125 | 126 | public string Process(string request) 127 | { 128 | Request = request; 129 | return Response; 130 | } 131 | } 132 | } 133 | } -------------------------------------------------------------------------------- /Cuke4Nuke/Specifications/Core/Loader_Specification.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Cuke4Nuke.Core; 5 | using Cuke4Nuke.TestStepDefinitions; 6 | 7 | using NUnit.Framework; 8 | 9 | namespace Cuke4Nuke.Specifications.Core 10 | { 11 | [TestFixture] 12 | public class Loader_Specification 13 | { 14 | static readonly Type ValidStepDefinitionClass = typeof(StepDefinition_Specification.ValidStepDefinitions); 15 | static readonly Type ExternalStepDefinitionClass = typeof(ExternalSteps); 16 | 17 | List _stepDefinitions; 18 | 19 | [SetUp] 20 | public void SetUp() 21 | { 22 | _stepDefinitions = new List(); 23 | } 24 | 25 | [Test] 26 | public void Should_load_step_definitions_from_external_assembly_in_options() 27 | { 28 | var assemblyPaths = new List{"Cuke4Nuke.TestStepDefinitions.dll"}; 29 | var loader = new Loader(assemblyPaths, new ObjectFactory()); 30 | 31 | _stepDefinitions = loader.Load().StepDefinitions; 32 | 33 | AssertAllMethodsLoaded(ExternalStepDefinitionClass); 34 | } 35 | 36 | [Test] 37 | public void Should_load_step_definitions_from_multiple_assemblies_in_options() 38 | { 39 | var assemblyPaths = new List { "Cuke4Nuke.TestStepDefinitions.dll", "Cuke4Nuke.Specifications.dll" }; 40 | var loader = new Loader(assemblyPaths, new ObjectFactory()); 41 | 42 | _stepDefinitions = loader.Load().StepDefinitions; 43 | 44 | AssertAllMethodsLoaded(ValidStepDefinitionClass); 45 | AssertAllMethodsLoaded(ExternalStepDefinitionClass); 46 | } 47 | 48 | void AssertAllMethodsLoaded(Type type) 49 | { 50 | var expectedMethods = StepDefinition_Specification.GetStepDefinitionMethods(type); 51 | 52 | foreach (var method in expectedMethods) 53 | { 54 | var stepDefinition = new StepDefinition(method); 55 | Assert.That(_stepDefinitions, Has.Member(stepDefinition), "Missing method: " + stepDefinition.Id); 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Cuke4Nuke/Specifications/Core/ObjectFactory_Specification.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using NUnit.Framework; 6 | using Cuke4Nuke.Core; 7 | 8 | namespace Cuke4Nuke.Specifications.Core 9 | { 10 | public class ObjectFactory_Specification 11 | { 12 | [Test] 13 | public void Should_have_AddClass_method() 14 | { 15 | ObjectFactory objectFactory = new ObjectFactory(); 16 | objectFactory.AddClass(typeof(Dummy)); 17 | } 18 | 19 | [Test] 20 | public void Should_have_CreateObjects_method() 21 | { 22 | ObjectFactory objectFactory = new ObjectFactory(); 23 | objectFactory.AddClass(typeof(Dummy)); 24 | objectFactory.CreateObjects(); 25 | } 26 | 27 | [Test] 28 | public void Should_have_GetObject_method() 29 | { 30 | ObjectFactory objectFactory = new ObjectFactory(); 31 | objectFactory.AddClass(typeof(Dummy)); 32 | objectFactory.CreateObjects(); 33 | Dummy dummy = (Dummy) objectFactory.GetObject(typeof(Dummy)); 34 | } 35 | 36 | [Test] 37 | public void Should_return_null_from_GetObject_if_CreateObjects_not_called_first() 38 | { 39 | ObjectFactory objectFactory = new ObjectFactory(); 40 | objectFactory.AddClass(typeof(Dummy)); 41 | Assert.That(objectFactory.GetObject(typeof(Dummy)), Is.Null); 42 | } 43 | 44 | [Test] 45 | public void Should_return_same_object_from_multiple_GetObject_calls() 46 | { 47 | ObjectFactory objectFactory = new ObjectFactory(); 48 | objectFactory.AddClass(typeof(Dummy)); 49 | objectFactory.CreateObjects(); 50 | Dummy dummy1 = (Dummy)objectFactory.GetObject(typeof(Dummy)); 51 | dummy1.Value = "foo"; 52 | Dummy dummy2 = (Dummy)objectFactory.GetObject(typeof(Dummy)); 53 | Assert.That(dummy2.Value, Is.EqualTo("foo")); 54 | } 55 | 56 | [Test] 57 | public void Should_have_DisposeObjects_method() 58 | { 59 | ObjectFactory objectFactory = new ObjectFactory(); 60 | objectFactory.AddClass(typeof(Dummy)); 61 | objectFactory.CreateObjects(); 62 | objectFactory.DisposeObjects(); 63 | } 64 | 65 | [Test] 66 | public void Should_return_null_from_GetObject_after_DisposeObjects_is_called() 67 | { 68 | ObjectFactory objectFactory = new ObjectFactory(); 69 | objectFactory.AddClass(typeof(Dummy)); 70 | objectFactory.CreateObjects(); 71 | Assert.That(objectFactory.GetObject(typeof(Dummy)), Is.Not.Null); 72 | objectFactory.DisposeObjects(); 73 | Assert.That(objectFactory.GetObject(typeof(Dummy)), Is.Null); 74 | } 75 | 76 | [Test] 77 | public void Should_successfully_create_an_object_without_a_parameterless_constructor() 78 | { 79 | ObjectFactory objectFactory = new ObjectFactory(); 80 | objectFactory.AddClass(typeof(DummyBox)); 81 | objectFactory.CreateObjects(); 82 | DummyBox dummyBox = (DummyBox)objectFactory.GetObject(typeof(DummyBox)); 83 | } 84 | } 85 | 86 | public class Dummy 87 | { 88 | public String Value { get; set; } 89 | } 90 | 91 | public class DummyBox 92 | { 93 | Dummy _dummy; 94 | 95 | public DummyBox(Dummy dummy) 96 | { 97 | _dummy = dummy; 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /Cuke4Nuke/Specifications/Core/SnippetBuilder_Specification.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using NUnit.Framework; 6 | using Cuke4Nuke.Core; 7 | 8 | namespace Cuke4Nuke.Specifications.Core 9 | { 10 | public class SnippetBuilder_Specification 11 | { 12 | [Test] 13 | public void StepNameToMethodName_ShouldReturnLegalMethodName() 14 | { 15 | SnippetBuilder sb = new SnippetBuilder(); 16 | string stepName = "we're all wired"; 17 | Assert.That(sb.StepNameToMethodName(stepName), Is.EqualTo("WereAllWired")); 18 | } 19 | 20 | [Test] 21 | public void StepNameToMethodName_ShouldReturnLegalMethodName_TrailingComma() 22 | { 23 | SnippetBuilder sb = new SnippetBuilder(); 24 | string stepName = "the separator is ,"; 25 | Assert.That(sb.StepNameToMethodName(stepName), Is.EqualTo("TheSeparatorIs")); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Cuke4Nuke/Specifications/Core/StepDefinition_Specification.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | 5 | using Cuke4Nuke.Framework; 6 | using NUnit.Framework; 7 | 8 | using Cuke4Nuke.Core; 9 | 10 | namespace Cuke4Nuke.Specifications.Core 11 | { 12 | [TestFixture] 13 | public class StepDefinition_Specification 14 | { 15 | protected const BindingFlags MethodFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; 16 | 17 | MethodInfo _successMethod; 18 | MethodInfo _exceptionMethod; 19 | StepDefinition _stepDefinition; 20 | 21 | [SetUp] 22 | public void SetUp() 23 | { 24 | _successMethod = Reflection.GetMethod(typeof(ValidStepDefinitions), "Succeeds"); 25 | _exceptionMethod = Reflection.GetMethod(typeof(ValidStepDefinitions), "ThrowsException"); 26 | 27 | _stepDefinition = new StepDefinition(_successMethod); 28 | } 29 | 30 | [Test] 31 | public void Should_allow_method_with_a_Given_attribute() 32 | { 33 | AssertMethodIsValid("Given"); 34 | } 35 | 36 | 37 | 38 | 39 | [Test] 40 | public void Should_allow_method_with_a_When_attribute() 41 | { 42 | AssertMethodIsValid("When"); 43 | } 44 | 45 | [Test] 46 | public void Should_allow_method_with_a_Then_attribute() 47 | { 48 | AssertMethodIsValid("Then"); 49 | } 50 | 51 | [Test] 52 | public void Should_allow_public_methods() 53 | { 54 | AssertMethodIsValid("Public"); 55 | } 56 | 57 | [Test] 58 | public void Should_allow_internal_methods() 59 | { 60 | AssertMethodIsValid("Internal"); 61 | } 62 | 63 | [Test] 64 | public void Should_allow_protected_methods() 65 | { 66 | AssertMethodIsValid("Protected"); 67 | } 68 | 69 | [Test] 70 | public void Should_allow_private_methods() 71 | { 72 | AssertMethodIsValid("Private"); 73 | } 74 | 75 | [Test] 76 | public void Should_allow_methods_with_arguments() 77 | { 78 | AssertMethodIsValid("WithArguments"); 79 | } 80 | 81 | [Test] 82 | public void Should_allow_methods_without_arguments() 83 | { 84 | AssertMethodIsValid("WithoutArguments"); 85 | } 86 | 87 | [Test] 88 | public void Should_allow_instance_methods() 89 | { 90 | AssertMethodIsValid("Instance"); 91 | } 92 | 93 | [Test] 94 | public void Should_not_allow_methods_without_a_step_definition_attribute() 95 | { 96 | AssertMethodIsInvalid("NoAttribute"); 97 | } 98 | 99 | [Test] 100 | [ExpectedException(typeof(ArgumentException))] 101 | public void Constructor_should_throw_if_a_method_does_not_have_a_step_definition_attribute() 102 | { 103 | var invalidMethod = GetInvalidMethod("NoAttribute"); 104 | new StepDefinition(invalidMethod); 105 | } 106 | 107 | [Test] 108 | public void Method_property_should_be_set_from_constructor() 109 | { 110 | Assert.That(_stepDefinition.Method, Is.SameAs(_successMethod)); 111 | } 112 | 113 | [Test] 114 | public void Id_property_should_be_fully_qualified_method_name_with_parameter_types() 115 | { 116 | var fullNameForParameterlessMethod = typeof(ValidStepDefinitions).FullName + "." + _stepDefinition.Method.Name + "()"; 117 | Assert.That(_stepDefinition.Id, Is.EqualTo(fullNameForParameterlessMethod)); 118 | 119 | var parameterizedStepDefinition = new StepDefinition(Reflection.GetMethod(typeof(ValidStepDefinitions), "WithArguments")); 120 | var fullNameForParameterizedMethod = typeof(ValidStepDefinitions).FullName + "." + parameterizedStepDefinition.Method.Name + "(Int32)"; 121 | Assert.That(parameterizedStepDefinition.Id, Is.EqualTo(fullNameForParameterizedMethod)); 122 | } 123 | 124 | [Test] 125 | public void Id_property_of_equivalent_step_definitions_should_be_equal() 126 | { 127 | var _equivalentStepDefinition = new StepDefinition(_successMethod); 128 | Assert.That(_equivalentStepDefinition.Id, Is.EqualTo(_stepDefinition.Id)); 129 | } 130 | 131 | [Test] 132 | public void Successful_invocation_should_not_throw() 133 | { 134 | _stepDefinition.Invoke(null); 135 | } 136 | 137 | [Test] 138 | public void Successful_invocation_of_instance_should_not_throw() 139 | { 140 | var objectFactory = new ObjectFactory(); 141 | objectFactory.AddClass(typeof(ValidStepDefinitions)); 142 | objectFactory.CreateObjects(); 143 | var stepDefinition = new StepDefinition(GetValidMethod("Instance")); 144 | stepDefinition.Invoke(objectFactory); 145 | } 146 | 147 | [Test] 148 | public void Pending_should_be_false_when_method_does_not_have_Pending_attribute() 149 | { 150 | var stepDefinition = new StepDefinition(GetValidMethod("Given")); 151 | Assert.That(stepDefinition.Pending, Is.False); 152 | } 153 | 154 | [Test] 155 | public void Pending_should_be_true_when_method_has_Pending_attribute() 156 | { 157 | var stepDefinition = new StepDefinition(GetValidMethod("Pending")); 158 | Assert.That(stepDefinition.Pending, Is.True); 159 | } 160 | 161 | [Test] 162 | [ExpectedException(typeof(ArgumentException))] 163 | public void Incorrect_parameter_count_should_throw_exception() 164 | { 165 | _stepDefinition.Invoke(null, "parameter to cause invocation failure"); 166 | } 167 | 168 | [Test] 169 | [ExpectedException(typeof(TargetInvocationException))] 170 | public void Method_that_throws_should_result_in_a_TargetInvocationException_being_thrown() 171 | { 172 | var stepDefinition = new StepDefinition(_exceptionMethod); 173 | stepDefinition.Invoke(null); 174 | } 175 | 176 | public static void AssertMethodIsValid(string methodName) 177 | { 178 | var method = GetValidMethod(methodName); 179 | Assert.IsTrue(StepDefinition.IsValidMethod(method)); 180 | } 181 | 182 | static void AssertMethodIsInvalid(string methodName) 183 | { 184 | var method = GetInvalidMethod(methodName); 185 | Assert.IsFalse(StepDefinition.IsValidMethod(method)); 186 | } 187 | 188 | static MethodInfo GetValidMethod(string methodName) 189 | { 190 | return Reflection.GetMethod(typeof(ValidStepDefinitions), methodName); 191 | } 192 | 193 | static MethodInfo GetInvalidMethod(string methodName) 194 | { 195 | return Reflection.GetMethod(typeof(InvalidStepDefinitions), methodName); 196 | } 197 | 198 | public static List GetStepDefinitionMethods() 199 | { 200 | return GetStepDefinitionMethods(typeof(ValidStepDefinitions)); 201 | } 202 | 203 | public static List GetStepDefinitionMethods(Type type) 204 | { 205 | var methods = type.GetMethods(BindingFlags.DeclaredOnly | MethodFlags); 206 | return new List(methods); 207 | } 208 | 209 | public class ValidStepDefinitions 210 | { 211 | [Given("pattern")] 212 | public static void Succeeds() { } 213 | 214 | [Given("")] 215 | public static void ThrowsException() { throw new Exception("inner test Exception"); } 216 | 217 | [Given("")] 218 | public static void Given() { } 219 | 220 | [When("")] 221 | public static void When() { } 222 | 223 | [Then("")] 224 | public static void Then() { } 225 | 226 | [Given("")] 227 | public static void Public() { } 228 | 229 | [Given("")] 230 | internal static void Internal() { } 231 | 232 | [Given("")] 233 | protected static void Protected() { } 234 | 235 | [Given("")] 236 | private static void Private() { } 237 | 238 | [Given("")] 239 | public static void WithArguments(int arg) { } 240 | 241 | [Given("")] 242 | public static void WithoutArguments() { } 243 | 244 | [Given("")] 245 | public void Instance() { } 246 | 247 | [Given("")] 248 | [Pending] 249 | public void Pending() { } 250 | } 251 | 252 | public class InvalidStepDefinitions 253 | { 254 | public static void NoAttribute() { } 255 | } 256 | } 257 | } -------------------------------------------------------------------------------- /Cuke4Nuke/Specifications/Core/TableConverter_Specification.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using NUnit.Framework; 5 | using Cuke4Nuke.Core; 6 | using Cuke4Nuke.Framework; 7 | 8 | namespace Cuke4Nuke.Specifications.Core 9 | { 10 | public class TableConverter_Specification 11 | { 12 | [SetUp] 13 | public void SetUp() 14 | { 15 | TypeConverterAttribute attr = new TypeConverterAttribute(typeof(TableConverter)); 16 | TypeDescriptor.AddAttributes(typeof(Table), new Attribute[] { attr }); 17 | } 18 | 19 | [Test] 20 | public void ShouldConvertFromString() 21 | { 22 | string serializedTable = "[[\"foo\",\"1\"],[\"bar\",\"2\"]]"; 23 | Assert.DoesNotThrow(delegate { 24 | TypeConverter converter = TypeDescriptor.GetConverter(typeof(Table)); 25 | Table table = (Table) converter.ConvertFromString(serializedTable); 26 | }); 27 | } 28 | 29 | [Test] 30 | public void JsonToTable_ShouldConvertFromString_EmptyString() 31 | { 32 | string serializedTable = ""; 33 | TableConverter converter = new TableConverter(); 34 | Table table = converter.JsonToTable(serializedTable); 35 | Assert.That(table.Hashes().Count, Is.EqualTo(0)); 36 | } 37 | 38 | [Test] 39 | public void JsonToTable_ShouldThrowForInvalidData_NotAnArray() 40 | { 41 | string serializedTable = "{\"foo\":\"bar\"}"; 42 | TableConverter converter = new TableConverter(); 43 | Assert.Throws(delegate { 44 | Table table = converter.JsonToTable(serializedTable); 45 | }); 46 | } 47 | 48 | [Test] 49 | public void JsonToTable_ShouldThrowForInvalidData_NoInternalArrays() 50 | { 51 | string serializedTable = "[{\"foo\":\"1\"},{\"bar\":\"2\"}]"; 52 | TableConverter converter = new TableConverter(); 53 | Assert.Throws(delegate 54 | { 55 | Table table = converter.JsonToTable(serializedTable); 56 | }); 57 | } 58 | 59 | [Test] 60 | public void JsonToTable_ShouldThrowForInvalidData_NonStringDataInInternalArray() 61 | { 62 | string serializedTable = "[[2,1],[42,2]]"; 63 | TableConverter converter = new TableConverter(); 64 | //converter.JsonToTable(serializedTable); 65 | Assert.Throws(delegate 66 | { 67 | Table table = converter.JsonToTable(serializedTable); 68 | }); 69 | } 70 | 71 | [Test] 72 | public void JsonToTable_ShouldConvertFromString_HeaderRowOnly() 73 | { 74 | string serializedTable = "[[\"item\",\"count\"]]"; 75 | TableConverter converter = new TableConverter(); 76 | Table table = converter.JsonToTable(serializedTable); 77 | Assert.That(table.Hashes().Count, Is.EqualTo(0)); 78 | } 79 | 80 | [Test] 81 | public void JsonToTable_ShouldConvertFromString_HeaderAndDataRows() 82 | { 83 | string serializedTable = "[[\"item\",\"count\"],[\"cucumbers\",\"3\"],[\"bananas\",\"5\"],[\"tomatoes\",\"2\"]]"; 84 | TableConverter converter = new TableConverter(); 85 | Table table = converter.JsonToTable(serializedTable); 86 | Assert.That(table.Data.Count, Is.EqualTo(4)); 87 | } 88 | 89 | [Test] 90 | public void TableToJsonString_ShouldConvertFromTable_EmptyTable() 91 | { 92 | Table table = new Table(); 93 | string expectedJsonString = "[]"; 94 | TableConverter converter = new TableConverter(); 95 | string actualJsonString = converter.TableToJsonString(table); 96 | Assert.That(actualJsonString, Is.EqualTo(expectedJsonString)); 97 | } 98 | 99 | [Test] 100 | public void TableToJsonString_ShouldConvertFromTable_HeaderRowOnly() 101 | { 102 | Table table = new Table(); 103 | table.Data.Add(new List(new string[] { "item", "count" })); 104 | string expectedJsonString = "[[\"item\",\"count\"]]"; 105 | TableConverter converter = new TableConverter(); 106 | string actualJsonString = converter.TableToJsonString(table); 107 | Assert.That(actualJsonString, Is.EqualTo(expectedJsonString)); 108 | } 109 | 110 | [Test] 111 | public void TableToJsonString_ShouldConvertFromTable_HeaderAndDataRows() 112 | { 113 | Table table = new Table(); 114 | table.Data.Add(new List(new string[] { "item", "count" })); 115 | table.Data.Add(new List(new string[] { "cucumbers", "3" })); 116 | table.Data.Add(new List(new string[] { "bananas", "5" })); 117 | table.Data.Add(new List(new string[] { "tomatoes", "2" })); 118 | string expectedJsonString = "[[\"item\",\"count\"],[\"cucumbers\",\"3\"],[\"bananas\",\"5\"],[\"tomatoes\",\"2\"]]"; 119 | TableConverter converter = new TableConverter(); 120 | string actualJsonString = converter.TableToJsonString(table); 121 | Assert.That(actualJsonString, Is.EqualTo(expectedJsonString)); 122 | } 123 | 124 | [Test] 125 | public void ShouldConvertToString() 126 | { 127 | Table table = new Table(); 128 | table.Data.Add(new List(new string[] { "foo", "1" })); 129 | table.Data.Add(new List(new string[] { "bar", "2" })); 130 | string expectedJsonString = "[[\"foo\",\"1\"],[\"bar\",\"2\"]]"; 131 | string actualJsonString = null; 132 | Assert.DoesNotThrow(delegate { 133 | TypeConverter converter = TypeDescriptor.GetConverter(typeof(Table)); 134 | actualJsonString = (string)converter.ConvertToString(table); 135 | }); 136 | Assert.That(actualJsonString, Is.EqualTo(expectedJsonString)); 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /Cuke4Nuke/Specifications/Core/Table_Specification.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using NUnit.Framework; 6 | using Cuke4Nuke.Framework; 7 | 8 | namespace Cuke4Nuke.Specifications.Core 9 | { 10 | public class Table_Specification 11 | { 12 | [Test] 13 | public void HashesShouldTreatFirstRowAsHeaders() 14 | { 15 | Table table = new Table(); 16 | table.Data.Add(new List { "item", "count" }); 17 | table.Data.Add(new List { "cucumbers", "3" }); 18 | table.Data.Add(new List { "bananas", "5" }); 19 | table.Data.Add(new List { "tomatoes", "2" }); 20 | 21 | var hashes = table.Hashes(); 22 | Assert.That(hashes.Count, Is.EqualTo(3)); 23 | Assert.That(hashes[0].Keys, Has.Member("item")); 24 | Assert.That(hashes[0].Keys, Has.Member("count")); 25 | Assert.That(hashes[1]["item"], Is.EqualTo("bananas")); 26 | } 27 | 28 | [Test] 29 | public void AssertSameAsShouldThrow() 30 | { 31 | Table actualTable = new Table(); 32 | Table expectedTable = new Table(); 33 | Assert.Throws(delegate() 34 | { 35 | actualTable.AssertSameAs(expectedTable); 36 | }); 37 | } 38 | 39 | [Test] 40 | public void AssertSameAsShouldProvideTablesInException() 41 | { 42 | Table actualTable = new Table(); 43 | Table expectedTable = new Table(); 44 | try 45 | { 46 | actualTable.AssertSameAs(expectedTable); 47 | } 48 | catch (TableAssertionException ex) 49 | { 50 | Assert.AreSame(actualTable, ex.Actual); 51 | Assert.AreSame(expectedTable, ex.Expected); 52 | } 53 | } 54 | 55 | [Test] 56 | public void IncludesShouldReturnTrueWithOneColumMatching() 57 | { 58 | Table expTable = new Table(); 59 | Table actTable = new Table(); 60 | 61 | expTable.Data.Add(new List(new []{"Provider"})); 62 | expTable.Data.Add(new List(new[]{"Nurse (Ann)"})); 63 | 64 | actTable.Data.Add(new List(new[] { "Provider" })); 65 | actTable.Data.Add(new List(new[] { "Nurse (Ann)" })); 66 | actTable.Data.Add(new List(new[] { "Doctor (Zeke)" })); 67 | 68 | Assert.That(actTable.Includes(expTable)); 69 | } 70 | 71 | [Test] 72 | public void IncludesShouldReturnFalseWithOneColumnNotMatching() 73 | { 74 | Table expTable = new Table(); 75 | Table actTable = new Table(); 76 | 77 | expTable.Data.Add(new List(new[] { "Provider" })); 78 | expTable.Data.Add(new List(new[] { "Nurse (Sue)" })); 79 | 80 | actTable.Data.Add(new List(new[] { "Provider" })); 81 | actTable.Data.Add(new List(new[] { "Nurse (Ann)" })); 82 | actTable.Data.Add(new List(new[] { "Doctor (Zeke)" })); 83 | 84 | Assert.That(actTable.Includes(expTable), Is.False); 85 | } 86 | 87 | [Test] 88 | public void IncludesShouldReturnTrueWithTwoColumnMatching() 89 | { 90 | Table expTable = new Table(); 91 | Table actTable = new Table(); 92 | 93 | expTable.Data.Add(new List(new[] { "Provider", "Date" })); 94 | expTable.Data.Add(new List(new[] { "Nurse (Ann)", "01/15/2010" })); 95 | 96 | actTable.Data.Add(new List(new[] { "Provider", "Date" })); 97 | actTable.Data.Add(new List(new[] { "Nurse (Ann)", "01/15/2010" })); 98 | actTable.Data.Add(new List(new[] { "Doctor (Zeke)", "01/15/2010" })); 99 | 100 | Assert.That(actTable.Includes(expTable)); 101 | } 102 | 103 | [Test] 104 | public void IncludesShouldReturnFalseWithTwoColumnsWithMismatchInFirstColumn() 105 | { 106 | Table expTable = new Table(); 107 | Table actTable = new Table(); 108 | 109 | expTable.Data.Add(new List(new[] { "Provider", "Date" })); 110 | expTable.Data.Add(new List(new[] { "Nurse (Sue)", "01/15/2010" })); 111 | 112 | actTable.Data.Add(new List(new[] { "Provider", "Date" })); 113 | actTable.Data.Add(new List(new[] { "Nurse (Ann)", "01/15/2010" })); 114 | actTable.Data.Add(new List(new[] { "Doctor (Zeke)", "01/15/2010" })); 115 | 116 | Assert.That(actTable.Includes(expTable), Is.False); 117 | } 118 | 119 | [Test] 120 | public void IncludesShouldReturnFalseWithTwoColumnsWithMismatchInSecondColumn() 121 | { 122 | Table expTable = new Table(); 123 | Table actTable = new Table(); 124 | 125 | expTable.Data.Add(new List(new[] { "Provider", "Date" })); 126 | expTable.Data.Add(new List(new[] { "Nurse (Ann)", "01/15/2015" })); 127 | 128 | actTable.Data.Add(new List(new[] { "Provider", "Date" })); 129 | actTable.Data.Add(new List(new[] { "Nurse (Ann)", "01/15/2010" })); 130 | actTable.Data.Add(new List(new[] { "Doctor (Zeke)", "01/15/2010" })); 131 | 132 | Assert.That(actTable.Includes(expTable), Is.False); 133 | } 134 | 135 | [Test] 136 | public void IncludesShouldReturnTrueWithTwoColumnsWithSameData() 137 | { 138 | Table expTable = new Table(); 139 | Table actTable = new Table(); 140 | 141 | expTable.Data.Add(new List(new[] { "Provider", "Date" })); 142 | expTable.Data.Add(new List(new[] { "Nurse (Ann)", "01/15/2010" })); 143 | expTable.Data.Add(new List(new[] { "Doctor (Zeke)", "01/15/2010" })); 144 | 145 | actTable.Data.Add(new List(new[] { "Provider", "Date" })); 146 | actTable.Data.Add(new List(new[] { "Nurse (Ann)", "01/15/2010" })); 147 | actTable.Data.Add(new List(new[] { "Doctor (Zeke)", "01/15/2010" })); 148 | 149 | Assert.That(actTable.Includes(expTable), Is.True); 150 | } 151 | 152 | [Test] 153 | public void HeadersShouldReturnListOfHeaders() 154 | { 155 | Table tbl = new Table(); 156 | 157 | tbl.Data.Add(new List(new[] { "Provider", "Date" })); 158 | tbl.Data.Add(new List(new[] { "Nurse (Ann)", "01/15/2010" })); 159 | tbl.Data.Add(new List(new[] { "Doctor (Zeke)", "01/15/2010" })); 160 | 161 | Assert.That(tbl.Headers(), Is.EqualTo(new List(new[] { "Provider", "Date" }))); 162 | } 163 | 164 | [Test] 165 | public void HeadersShouldReturnEmptyListForEmptyTable() 166 | { 167 | Table tbl = new Table(); 168 | Assert.That(tbl.Headers(), Is.EqualTo(new List())); 169 | } 170 | 171 | [Test] 172 | public void RowHashesShouldReturnDictionaryForTwoColumnTable() 173 | { 174 | Table tbl = new Table(); 175 | tbl.Data.Add(new List(new[] { "Key1", "Value1" })); 176 | tbl.Data.Add(new List(new[] { "Key2", "Value2" })); 177 | tbl.Data.Add(new List(new[] { "Key3", "Value3" })); 178 | 179 | Assert.That(tbl.RowHashes(), Is.EqualTo(new Dictionary() 180 | { 181 | { "Key1", "Value1" }, 182 | { "Key2", "Value2" }, 183 | { "Key3", "Value3" } 184 | } 185 | )); 186 | } 187 | 188 | [Test] 189 | public void RowHashesShouldThrowForOneColumnTable() 190 | { 191 | Table tbl = new Table(); 192 | tbl.Data.Add(new List(new[] { "Value1" })); 193 | tbl.Data.Add(new List(new[] { "Value2" })); 194 | tbl.Data.Add(new List(new[] { "Value3" })); 195 | 196 | Assert.Throws(delegate 197 | { 198 | tbl.RowHashes(); 199 | }); 200 | } 201 | 202 | [Test] 203 | public void RowHashesShouldThrowForThreeColumnTable() 204 | { 205 | Table tbl = new Table(); 206 | tbl.Data.Add(new List(new[] { "Value1", "Value1", "Value1" })); 207 | tbl.Data.Add(new List(new[] { "Value2", "Value2", "Value2" })); 208 | tbl.Data.Add(new List(new[] { "Value3", "Value3", "Value3" })); 209 | 210 | Assert.Throws(delegate 211 | { 212 | tbl.RowHashes(); 213 | }); 214 | } 215 | 216 | [Test] 217 | public void RowHashesShouldThrowForEmptyTable() 218 | { 219 | Table tbl = new Table(); 220 | 221 | Assert.Throws(delegate 222 | { 223 | tbl.RowHashes(); 224 | }); 225 | } 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /Cuke4Nuke/Specifications/JsonAssert.cs: -------------------------------------------------------------------------------- 1 | using LitJson; 2 | 3 | using NUnit.Framework; 4 | 5 | namespace Cuke4Nuke.Specifications 6 | { 7 | public static class JsonAssert 8 | { 9 | public static void HasString(JsonData jsonData, string name, string value) 10 | { 11 | Assert.That(jsonData[name].IsString); 12 | Assert.That(jsonData[name].ToString(), Is.EqualTo(value)); 13 | } 14 | 15 | public static void HasString(JsonData jsonData, string name) 16 | { 17 | Assert.That(jsonData[name].IsString); 18 | } 19 | 20 | public static void IsObject(JsonData jsonData) 21 | { 22 | Assert.That(jsonData.IsObject); 23 | } 24 | 25 | public static void IsArray(JsonData jsonData) 26 | { 27 | Assert.That(jsonData.IsArray); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /Cuke4Nuke/Specifications/Language/NO/Norwegian_StepDefinition_Specification.cs: -------------------------------------------------------------------------------- 1 | using Cuke4Nuke.Core; 2 | using Cuke4Nuke.Framework.Languages.NO; 3 | using NUnit.Framework; 4 | 5 | namespace Cuke4Nuke.Specifications.Language.NO 6 | { 7 | [TestFixture] 8 | public class Norwegian_StepDefinition_Specification 9 | { 10 | 11 | [Test] 12 | public void Should_allow_method_with_a_Gitt_attribute() 13 | { 14 | AssertMethodIsValid("Gitt"); 15 | } 16 | 17 | [Test] 18 | public void Should_allow_method_with_a_Når_attribute() 19 | { 20 | AssertMethodIsValid("Når"); 21 | } 22 | 23 | [Test] 24 | public void Should_allow_method_with_a_Så_attribute() 25 | { 26 | AssertMethodIsValid("Så"); 27 | } 28 | 29 | private void AssertMethodIsValid(string methodName) 30 | { 31 | var method = Reflection.GetMethod(typeof (ValidNorwegianSteps), methodName); 32 | Assert.IsTrue(StepDefinition.IsValidMethod(method)); 33 | } 34 | 35 | 36 | public class ValidNorwegianSteps 37 | { 38 | [Gitt("test")] 39 | public static void Gitt() { } 40 | 41 | [Når("test")] 42 | public static void Når(){} 43 | 44 | [Så("test")] 45 | public static void Så(){} 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /Cuke4Nuke/Specifications/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("Test")] 8 | [assembly: AssemblyDescription("Cuke4Nuke Specifications")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("Test")] 12 | [assembly: AssemblyCopyright("Copyright © 2009 Richard Laurence, Declan Whelan")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("08d680a9-26f3-4ac6-9d74-b4384fae77ee")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Cuke4Nuke/Specifications/Reflection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace Cuke4Nuke.Specifications 5 | { 6 | public static class Reflection 7 | { 8 | public static MethodInfo GetMethod(Type type, string MethodName) 9 | { 10 | const BindingFlags Flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; 11 | 12 | return type.GetMethod(MethodName, Flags); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Cuke4Nuke/Specifications/Server/NukeServer_Specification.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | using Cuke4Nuke.Core; 4 | using Cuke4Nuke.Server; 5 | using Cuke4Nuke.Specifications.Core; 6 | 7 | using NUnit.Framework; 8 | 9 | namespace Cuke4Nuke.Specifications.Server 10 | { 11 | [TestFixture] 12 | public class NukeServer_Specification 13 | { 14 | MockListener _listener; 15 | StringWriter _outputWriter; 16 | 17 | [SetUp] 18 | public void SetUp() 19 | { 20 | _listener = new MockListener(); 21 | _outputWriter = new StringWriter(); 22 | } 23 | 24 | [Test] 25 | public void Start_without_help_option_should_start_the_listener() 26 | { 27 | var server = new NukeServer(_listener, new Options()); 28 | server.Start(); 29 | 30 | Assert.That(_listener.HasMessageLoggedListeners()); 31 | Assert.That(_listener.StartCalled); 32 | Assert.That(_listener.StopCalled); 33 | } 34 | 35 | class MockListener : Listener 36 | { 37 | internal bool StartCalled; 38 | internal bool StopCalled; 39 | 40 | public MockListener() 41 | : base(new Processor(new Loader(new System.Collections.Generic.List(), null), null), 0) 42 | { 43 | } 44 | 45 | public override void Start() 46 | { 47 | StartCalled = true; 48 | } 49 | 50 | public override void Stop() 51 | { 52 | StopCalled = true; 53 | } 54 | 55 | internal bool HasMessageLoggedListeners() 56 | { 57 | return MessageLogged != null; 58 | } 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /Cuke4Nuke/Specifications/Server/Options_Specification.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | using Cuke4Nuke.Server; 5 | 6 | using NUnit.Framework; 7 | 8 | namespace Cuke4Nuke.Specifications.Server 9 | { 10 | [TestFixture] 11 | public class Options_Specification 12 | { 13 | [Test] 14 | public void Port_should_default_correctly() 15 | { 16 | var options = new Options(""); 17 | Assert.That(options.Port, Is.EqualTo(Options.DefaultPort)); 18 | } 19 | 20 | [Test] 21 | public void Should_parse_p_into_port() 22 | { 23 | var options = new Options("-p=1234"); 24 | Assert.That(options.Port, Is.EqualTo(1234)); 25 | } 26 | 27 | [Test] 28 | public void Should_parse_port_into_port() 29 | { 30 | var options = new Options("-port=1234"); 31 | Assert.That(options.Port, Is.EqualTo(1234)); 32 | } 33 | 34 | [Test] 35 | public void ShowHelp_should_default_to_false() 36 | { 37 | var options = new Options(""); 38 | Assert.That(options.ShowHelp, Is.False); 39 | } 40 | 41 | [Test] 42 | public void Should_parse_h_into_ShowHelp() 43 | { 44 | var options = new Options("-h"); 45 | Assert.That(options.ShowHelp, Is.True); 46 | } 47 | 48 | [Test] 49 | public void Should_parse_question_mark_into_ShowHelp() 50 | { 51 | var options = new Options("-h"); 52 | Assert.That(options.ShowHelp, Is.True); 53 | } 54 | 55 | [Test] 56 | public void Should_parse_help_into_ShowHelp() 57 | { 58 | var options = new Options("-help"); 59 | Assert.That(options.ShowHelp, Is.True); 60 | } 61 | 62 | [Test] 63 | public void AssemblyPaths_should_default_to_empty_collection() 64 | { 65 | var options = new Options(""); 66 | Assert.That(options.AssemblyPaths.Count, Is.EqualTo(0)); 67 | } 68 | 69 | [Test] 70 | public void Should_parse_a_into_AssemblyPaths() 71 | { 72 | var options = new Options("-a=foo"); 73 | Assert.That(options.AssemblyPaths.Count, Is.EqualTo(1)); 74 | Assert.That(options.AssemblyPaths.Contains("foo")); 75 | } 76 | 77 | [Test] 78 | public void Should_parse_assembly_into_AssemblyPaths() 79 | { 80 | var options = new Options("-assembly=foo"); 81 | Assert.That(options.AssemblyPaths.Count, Is.EqualTo(1)); 82 | Assert.That(options.AssemblyPaths.Contains("foo")); 83 | } 84 | 85 | [Test] 86 | public void Should_parse_multiple_assembly_options_into_AssemblyPaths() 87 | { 88 | var options = new Options("-a=foo", "-a=bar"); 89 | Assert.That(options.AssemblyPaths.Count, Is.EqualTo(2)); 90 | Assert.That(options.AssemblyPaths.Contains("foo")); 91 | Assert.That(options.AssemblyPaths.Contains("bar")); 92 | } 93 | 94 | [Test] 95 | public void Write_should_write_options_label_line() 96 | { 97 | var output = new StringWriter(); 98 | var options = new Options(); 99 | options.Write(output); 100 | Assert.That(output.ToString().StartsWith("Options:" + Environment.NewLine)); 101 | } 102 | 103 | [Test] 104 | [Explicit("Supports exploratory testing of options")] 105 | public void Write_should_write_options_label_lin() 106 | { 107 | var options = new Options(); 108 | options.Write(Console.Out); 109 | } 110 | } 111 | } -------------------------------------------------------------------------------- /Cuke4Nuke/Specifications/Server/Program_Specification.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Net.Sockets; 4 | 5 | using Cuke4Nuke.Specifications.Core; 6 | 7 | using NUnit.Framework; 8 | 9 | namespace Cuke4Nuke.Specifications.Server 10 | { 11 | [TestFixture] 12 | public class Program_Specification 13 | { 14 | Process _serverProcess; 15 | TcpClient _client; 16 | 17 | [TestFixtureSetUp] 18 | public void TestFixtureSetup() 19 | { 20 | var startInfo = new ProcessStartInfo("Cuke4Nuke.Server.exe", "-p " + Listener_Specification.TestPort) 21 | { 22 | UseShellExecute = false, 23 | CreateNoWindow = true 24 | }; 25 | _serverProcess = Process.Start(startInfo); 26 | 27 | _client = new TcpClient("localhost", Listener_Specification.TestPort); 28 | } 29 | 30 | [TestFixtureTearDown] 31 | public void TestFixtureTeardown() 32 | { 33 | try 34 | { 35 | _serverProcess.Kill(); 36 | } 37 | catch (Exception) 38 | { 39 | } 40 | _client.Close(); 41 | } 42 | 43 | [Test] 44 | public void Starting_server_process_should_start_the_server() 45 | { 46 | Assert.That(_client.Connected); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Cuke4Nuke/Specifications/Specifications.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {F1BCCFD7-5B2D-4255-887C-BF06A03D4D2F} 9 | Library 10 | Properties 11 | Cuke4Nuke.Specifications 12 | Cuke4Nuke.Specifications 13 | v3.5 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | False 36 | ..\lib\LitJson.dll 37 | 38 | 39 | False 40 | ..\lib\nunit.framework.dll 41 | 42 | 43 | 44 | 3.5 45 | 46 | 47 | 3.5 48 | 49 | 50 | 3.5 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | {3CF36FF9-CE32-4868-84EC-D76E1E75148C} 79 | Core 80 | 81 | 82 | {12400276-AA80-418A-9D57-AE4B77EAAF51} 83 | Framework 84 | 85 | 86 | {936E6D55-416C-4008-A682-84825AE0E4DB} 87 | Server 88 | 89 | 90 | {AE068AEA-645F-4DF7-BAD1-671B5DE5576D} 91 | TestStepDefinitions 92 | 93 | 94 | 95 | 102 | -------------------------------------------------------------------------------- /Cuke4Nuke/TestStepDefinitions/ExternalSteps.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using Cuke4Nuke.Framework; 4 | 5 | namespace Cuke4Nuke.TestStepDefinitions 6 | { 7 | public class ExternalSteps 8 | { 9 | [Given("^nothing$")] 10 | public static void DoNothing() 11 | { 12 | } 13 | 14 | [Then("^it should pass.$")] 15 | public static void ItShouldPass() 16 | { 17 | } 18 | 19 | [Then("^it should fail.$")] 20 | public static void ItShouldFail() 21 | { 22 | throw new Exception("intentional"); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Cuke4Nuke/TestStepDefinitions/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("Specifications")] 8 | [assembly: AssemblyDescription("Cuke4Nuke Specifications")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("Specifications")] 12 | [assembly: AssemblyCopyright("Copyright © 2009 Richard Laurence, Declan Whelan")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("94497020-b137-40ee-a75a-5ea8725ef5e3")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Cuke4Nuke/TestStepDefinitions/TestStepDefinitions.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {AE068AEA-645F-4DF7-BAD1-671B5DE5576D} 9 | Library 10 | Properties 11 | Cuke4Nuke.TestStepDefinitions 12 | Cuke4Nuke.TestStepDefinitions 13 | v3.5 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | False 36 | ..\lib\nunit.framework.dll 37 | 38 | 39 | 40 | 3.5 41 | 42 | 43 | 3.5 44 | 45 | 46 | 3.5 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | {12400276-AA80-418A-9D57-AE4B77EAAF51} 58 | Framework 59 | 60 | 61 | 62 | 69 | -------------------------------------------------------------------------------- /Cuke4Nuke/lib/Castle.Core.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richardlawrence/Cuke4Nuke/ddec8b87af32b981768a2cf2aaf5ba8c1cd5c251/Cuke4Nuke/lib/Castle.Core.dll -------------------------------------------------------------------------------- /Cuke4Nuke/lib/Castle.MicroKernel.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richardlawrence/Cuke4Nuke/ddec8b87af32b981768a2cf2aaf5ba8c1cd5c251/Cuke4Nuke/lib/Castle.MicroKernel.dll -------------------------------------------------------------------------------- /Cuke4Nuke/lib/LitJson.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richardlawrence/Cuke4Nuke/ddec8b87af32b981768a2cf2aaf5ba8c1cd5c251/Cuke4Nuke/lib/LitJson.dll -------------------------------------------------------------------------------- /Cuke4Nuke/lib/NDesk.Options.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richardlawrence/Cuke4Nuke/ddec8b87af32b981768a2cf2aaf5ba8c1cd5c251/Cuke4Nuke/lib/NDesk.Options.dll -------------------------------------------------------------------------------- /Cuke4Nuke/lib/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richardlawrence/Cuke4Nuke/ddec8b87af32b981768a2cf2aaf5ba8c1cd5c251/Cuke4Nuke/lib/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /Cuke4Nuke/lib/log4net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richardlawrence/Cuke4Nuke/ddec8b87af32b981768a2cf2aaf5ba8c1cd5c251/Cuke4Nuke/lib/log4net.dll -------------------------------------------------------------------------------- /Cuke4Nuke/lib/nunit.framework.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richardlawrence/Cuke4Nuke/ddec8b87af32b981768a2cf2aaf5ba8c1cd5c251/Cuke4Nuke/lib/nunit.framework.dll -------------------------------------------------------------------------------- /History.txt: -------------------------------------------------------------------------------- 1 | == In Git 2 | === Features 3 | 4 | === Bugs Fixed 5 | 6 | == 0.4.0 2010-11-03 7 | === Features 8 | * Simple hook tags 9 | * Internationalized Given/When/Then attributes 10 | * Debug rather than Release binaries to support step definition debugging 11 | * Table diff response changed to diff! to allow Cucumber to format table diff output 12 | * Removed systemu dependency, thereby enabling colors (without wac) and incremental output (#21, Dan Fitch) 13 | 14 | == 0.3.1 2010-02-07 15 | === Features 16 | * Additional methods on Table 17 | 18 | === Bugs Fixed 19 | * Trailing punctuation in a step breaks snippet generation (#26) 20 | * JSON is not properly escaped for snippets (#29; Dan Fitch) 21 | 22 | == 0.3.0 2009-12-30 23 | === Features 24 | * Snippets work, including tables and multiline strings 25 | * Support for pending step definitions 26 | * Table diffing works 27 | * Updated WatiN example to use new timeout feature in wire file 28 | * Bumped cucumber dependency to 0.5.2 29 | 30 | == 0.2.4 2009-12-17 31 | 32 | Updated gem dependency to newer version of cucumber. 33 | 34 | == 0.2.3 2009-12-17 35 | 36 | Gem cleanup, snippets, table parameters on step definitions. 37 | 38 | == 0.2.2 2009-12-02 39 | === Features 40 | * Compatibility with WatiN (Issue #19; Luke Smith) 41 | * WatiN example 42 | * Bumped cucumber dependency to 0.4.4. 43 | 44 | == 0.2.1 2009-11-13 45 | 46 | Added gem dependency on json. 47 | 48 | == 0.2.0 2009-11-06 49 | 50 | Added a gem to make installation easy and to allow users to run the Cuke4Nuke server and cucumber all in one command. 51 | 52 | == 0.1.1 2009-10-23 53 | 54 | Added support for Before and After hooks. 55 | 56 | == 0.1 2009-10-22 57 | 58 | First release; includes contributions from Declan Whelan, Åsmund Eldhuset, Aslak Hellesoy. 59 | 60 | === Features 61 | * Given, When, Then step definitions in .NET 62 | * Typed step definition parameters (Issues #1 and #10) 63 | * Shared state between steps, including steps in separate step definition classes (#4) 64 | * All-JSON wire protocol -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | Cuke4Nuke 2 | ========= 3 | 4 | Documentation is at [http://wiki.github.com/richardlawrence/Cuke4Nuke](http://wiki.github.com/richardlawrence/Cuke4Nuke). -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | task :default => :build 2 | 3 | Dir['lib/task/*.rake'].each do |rake| 4 | import rake 5 | end 6 | 7 | desc "Build the C# code with MSBuild" 8 | task :build do 9 | msbuild = 'c:\windows\microsoft.net\framework\v3.5\msbuild.exe' 10 | solution = File.expand_path(File.dirname(__FILE__) + '/Cuke4Nuke/Cuke4Nuke.sln') 11 | sh %{#{msbuild} "#{solution}" /p:configuration=Debug} 12 | end 13 | 14 | desc "Run the unit tests with NUnit" 15 | task :test do 16 | nunit = 'C:\Program Files\NUnit 2.5.2\bin\net-2.0\nunit-console.exe' 17 | tests = File.expand_path(File.dirname(__FILE__) + '/Cuke4Nuke/Specifications/bin/Debug/Cuke4Nuke.Specifications.dll') 18 | sh %{"#{nunit}" "#{tests}"} 19 | end 20 | 21 | task :log => 'log:less' 22 | 23 | namespace :log do 24 | desc "Clear log" 25 | task :clear do 26 | `rm -rf #{log}` 27 | end 28 | 29 | desc "View log in less" 30 | task :less do 31 | exec %{less #{log}} 32 | end 33 | end 34 | 35 | def log 36 | file = File.expand_path(File.dirname(__FILE__) + '/Cuke4Nuke/Server/bin/Debug/Cuke4NukeLog.txt') 37 | %{"#{file}"} 38 | end -------------------------------------------------------------------------------- /examples/Calc/Calc.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 10.00 2 | # Visual C# Express 2008 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Calc", "Calc\Calc.csproj", "{389AB9E8-7FC2-4A8D-952E-43D34A30C192}" 4 | EndProject 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalcFeatures", "CalcFeatures\CalcFeatures.csproj", "{88C2A71A-1F36-4356-819B-1D0CF301362A}" 6 | ProjectSection(ProjectDependencies) = postProject 7 | {389AB9E8-7FC2-4A8D-952E-43D34A30C192} = {389AB9E8-7FC2-4A8D-952E-43D34A30C192} 8 | EndProjectSection 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {389AB9E8-7FC2-4A8D-952E-43D34A30C192}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {389AB9E8-7FC2-4A8D-952E-43D34A30C192}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {389AB9E8-7FC2-4A8D-952E-43D34A30C192}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {389AB9E8-7FC2-4A8D-952E-43D34A30C192}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {88C2A71A-1F36-4356-819B-1D0CF301362A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {88C2A71A-1F36-4356-819B-1D0CF301362A}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {88C2A71A-1F36-4356-819B-1D0CF301362A}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {88C2A71A-1F36-4356-819B-1D0CF301362A}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /examples/Calc/Calc/.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | obj -------------------------------------------------------------------------------- /examples/Calc/Calc/Calc.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {389AB9E8-7FC2-4A8D-952E-43D34A30C192} 9 | Library 10 | Properties 11 | Calc 12 | Calc 13 | v3.5 14 | 512 15 | 16 | 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /examples/Calc/Calc/Calculator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Calc 5 | { 6 | public class Calculator 7 | { 8 | private List args = new List(); 9 | 10 | public void Push(double n) 11 | { 12 | args.Add(n); 13 | } 14 | 15 | public double Add() 16 | { 17 | double result = 0; 18 | foreach (double n in args) 19 | { 20 | result += n; 21 | } 22 | return result; 23 | } 24 | 25 | public double Divide() 26 | { 27 | double result = args[0]; 28 | foreach (int n in args.GetRange(1, args.Count-1)) 29 | { 30 | result /= n; 31 | } 32 | return result; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /examples/Calc/CalcFeatures/.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | obj -------------------------------------------------------------------------------- /examples/Calc/CalcFeatures/CalcFeatures.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {88C2A71A-1F36-4356-819B-1D0CF301362A} 9 | Library 10 | Properties 11 | CalcFeatures 12 | CalcFeatures 13 | v3.5 14 | 512 15 | 16 | 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 43 | 44 | 45 | 46 | 47 | 48 | False 49 | ..\lib\Cuke4Nuke.Framework.dll 50 | 51 | 52 | False 53 | ..\lib\nunit.framework.dll 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | {389AB9E8-7FC2-4A8D-952E-43D34A30C192} 62 | Calc 63 | 64 | 65 | -------------------------------------------------------------------------------- /examples/Calc/CalcFeatures/CalculatorSteps.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Calc; 3 | using Cuke4Nuke.Framework; 4 | using NUnit.Framework; 5 | 6 | namespace CalcFeatures 7 | { 8 | class CalculatorSteps 9 | { 10 | private Calculator _calculator; 11 | private double _result; 12 | 13 | [Before] 14 | public void CreateCalculator() 15 | { 16 | _calculator = new Calculator(); 17 | } 18 | 19 | [Given(@"^I have entered (\d+) into the calculator$")] 20 | public void EnterNumber(double n) 21 | { 22 | _calculator.Push(n); 23 | } 24 | 25 | [When(@"^I press divide$")] 26 | public void Divide() 27 | { 28 | _result = _calculator.Divide(); 29 | } 30 | 31 | [When(@"^I press add$")] 32 | public void Add() 33 | { 34 | _result = _calculator.Add(); 35 | } 36 | 37 | [Then(@"^the result should be (.*) on the screen$")] 38 | public void CheckResult(double expected) 39 | { 40 | Assert.That(_result, Is.EqualTo(expected)); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /examples/Calc/CalcFeatures/features/addition.feature: -------------------------------------------------------------------------------- 1 | # language: en 2 | Feature: Addition 3 | In order to avoid silly mistakes 4 | As a math idiot 5 | I want to be told the sum of two numbers 6 | 7 | Scenario Outline: Add two numbers 8 | Given I have entered into the calculator 9 | And I have entered into the calculator 10 | When I press