├── .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 11 | Then the result should be on the screen 12 | 13 | Examples: 14 | | input_1 | input_2 | button | output | 15 | | 20 | 30 | add | 50 | 16 | | 2 | 5 | add | 7 | 17 | | 0 | 40 | add | 40 | 18 | -------------------------------------------------------------------------------- /examples/Calc/CalcFeatures/features/division.feature: -------------------------------------------------------------------------------- 1 | # language: en 2 | Feature: Division 3 | In order to avoid silly mistakes 4 | Cashiers must be able to calculate a fraction 5 | 6 | Scenario: Regular numbers 7 | Given I have entered 3 into the calculator 8 | And I have entered 2 into the calculator 9 | When I press divide 10 | Then the result should be 1.5 on the screen 11 | -------------------------------------------------------------------------------- /examples/Calc/CalcFeatures/features/step_definitons/calculator_steps.rb: -------------------------------------------------------------------------------- 1 | if Cucumber::IRONRUBY # We only want this to run on IronRuby 2 | 3 | require 'spec/expectations' 4 | $:.unshift(File.dirname(__FILE__) + '/../../bin/Debug') # So we find the .dll 5 | require 'Calc.dll' 6 | 7 | Before do 8 | @calc = Calc::Calculator.new 9 | end 10 | 11 | Given "I have entered $n into the calculator" do |n| 12 | @calc.Push(n.to_f) 13 | end 14 | 15 | When /I press divide/ do 16 | @result = @calc.Divide 17 | end 18 | 19 | When /I press add/ do 20 | @result = @calc.Add 21 | end 22 | 23 | Then /the result should be (.*) on the screen/ do |result| 24 | @result.should == result.to_f 25 | end 26 | 27 | end -------------------------------------------------------------------------------- /examples/Calc/CalcFeatures/features/step_definitons/cucumber.wire: -------------------------------------------------------------------------------- 1 | host: localhost 2 | port: 3901 3 | -------------------------------------------------------------------------------- /examples/Calc/README.textile: -------------------------------------------------------------------------------- 1 | h1. Calculator Example 2 | 3 | This project contains Cucumber features for the Calc project. 4 | There are step definitions in both C# and Ruby. 5 | 6 | h2. C# 7 | 8 | The C# step definitions require Cuke4Nuke and MRI to run. You don't need IronRuby for this. 9 | This is the fastest option. 10 | 11 | h3. Install MRI and Cucumber 12 | 13 | Download and install "Ruby 1.8.6-26 Final Release":http://rubyforge.org/frs/?group_id=167&release_id=28426 14 | Make sure Ruby's bin directory is on your PATH. 15 | 16 | Then, open a command window and install the required gems: 17 | 18 | 19 | gem install cucumber json win32console --no-ri --no-rdoc 20 | 21 | 22 | Leave the command window open. 23 | 24 | h3. Build Calc.sln 25 | 26 | Open up the solution in Vidual Studio (Express) and build it. 27 | The solution contains both the Calc project and the CalcFeatures project. 28 | 29 | h3. Start Cuke4Nuke 30 | 31 | Open another command window, cd to the directory of this README.textile file and start Cuke4Nuke: 32 | 33 | 34 | ..\..\Cuke4Nuke\Server\bin\Release\Cuke4Nuke.Server.exe -a CalcFeatures\bin\Release\CalcFeatures.dll 35 | 36 | 37 | h3. Run Cucumber 38 | 39 | Return to the command window you used to install the gems. We have to work around some small wrinkles: 40 | 41 | 42 | chcp 1252 43 | 44 | 45 | Now, set your command window's font to a TrueType font, such as Lucida Console. See "troubleshooting":http://wiki.github.com/aslakhellesoy/cucumber/troubleshooting 46 | for more info about why you need to do this. 47 | 48 | Now, cd to the directory of this README.textile file and run: 49 | 50 | 51 | cucumber CalcFeatures\features 52 | 53 | 54 | That should be all green and nice. Try to change some of the numbers in one of the .feature 55 | files and run again. You should see red! 56 | 57 | Happy cuking! 58 | 59 | h2. IronRuby 60 | 61 | The other option you have to run Cucumber on .NET is via IronRuby. This is about twice as slow, since 62 | IronRuby takes a while to start, and Cuke4Nuke is faster. So when you use IronRuby you will not use Cuke4Nuke. 63 | 64 | h3. Install IronRuby 65 | 66 | Just follow the installation instructions over at the "IronRuby web site":http://www.ironruby.net/Download 67 | When you have unzipped the archive, make sure IronRuby's bin directory is on your PATH. 68 | 69 | Then, open a command window and install the required gems: 70 | 71 | 72 | igem install cucumber rspec --no-ri --no-rdoc 73 | 74 | 75 | Now, copy the launcher scripts: 76 | 77 | 78 | copy C:\ironruby-0.9.1\lib\IronRuby\gems\1.8\bin\cucumber C:\ironruby-0.9.1\bin\icucumber 79 | copy C:\ironruby-0.9.1\lib\IronRuby\gems\1.8\bin\cucumber.bat C:\ironruby-0.9.1\bin\icucumber.bat 80 | 81 | 82 | (You only have to do this once. If you upgrade cucumber later you don't need to do this again). 83 | 84 | h3. Install Wac 85 | 86 | There is no ANSI color support for IronRuby, so you need to install "Wac":http://github.com/aslakhellesoy/wac instead. 87 | 88 | h3. Build Calc.sln 89 | 90 | Open up the solution in Vidual Studio (Express) and build it. 91 | The solution contains both the Calc project and the CalcFeatures project. 92 | 93 | h3. Run Cucumber 94 | 95 | (You may have to remove CalcFeatures\features\step_definitions\cucumber.wire first). 96 | 97 | Now, cd to the directory of this README.textile file and run: 98 | 99 | 100 | icucumber CalcFeatures\features | wac 101 | 102 | 103 | That should be all green and nice. Try to change some of the numbers in one of the .feature 104 | files and run again. You should see red! 105 | 106 | Happy cuking! 107 | -------------------------------------------------------------------------------- /examples/Calc/lib/Cuke4Nuke.Framework.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richardlawrence/Cuke4Nuke/ddec8b87af32b981768a2cf2aaf5ba8c1cd5c251/examples/Calc/lib/Cuke4Nuke.Framework.dll -------------------------------------------------------------------------------- /examples/Calc/lib/nunit.framework.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richardlawrence/Cuke4Nuke/ddec8b87af32b981768a2cf2aaf5ba8c1cd5c251/examples/Calc/lib/nunit.framework.dll -------------------------------------------------------------------------------- /examples/WatiN/Google/Google.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {F6A91691-B135-42FA-8FC1-2036F52CE621} 9 | Library 10 | Properties 11 | Google 12 | Google 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 | ..\..\..\Cuke4Nuke\Framework\bin\Release\Cuke4Nuke.Framework.dll 37 | 38 | 39 | False 40 | ..\..\..\Cuke4Nuke\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 | False 56 | ..\lib\WatiN.Core.dll 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 75 | -------------------------------------------------------------------------------- /examples/WatiN/Google/Google.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google", "Google.csproj", "{F6A91691-B135-42FA-8FC1-2036F52CE621}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Any CPU = Debug|Any CPU 9 | Release|Any CPU = Release|Any CPU 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {F6A91691-B135-42FA-8FC1-2036F52CE621}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 13 | {F6A91691-B135-42FA-8FC1-2036F52CE621}.Debug|Any CPU.Build.0 = Debug|Any CPU 14 | {F6A91691-B135-42FA-8FC1-2036F52CE621}.Release|Any CPU.ActiveCfg = Release|Any CPU 15 | {F6A91691-B135-42FA-8FC1-2036F52CE621}.Release|Any CPU.Build.0 = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /examples/WatiN/Google/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Google")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Google")] 13 | [assembly: AssemblyCopyright("Copyright © 2009")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("a9c7af33-98f4-4c72-a3c3-d145703515ba")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /examples/WatiN/Google/StepDefinitions/SearchSteps.cs: -------------------------------------------------------------------------------- 1 | using Cuke4Nuke.Framework; 2 | using NUnit.Framework; 3 | using WatiN.Core; 4 | 5 | namespace Google.StepDefinitions 6 | { 7 | public class SearchSteps 8 | { 9 | Browser _browser; 10 | 11 | [Before] 12 | public void SetUp() 13 | { 14 | _browser = new WatiN.Core.IE(); 15 | } 16 | 17 | [After] 18 | public void TearDown() 19 | { 20 | if (_browser != null) 21 | { 22 | _browser.Dispose(); 23 | } 24 | } 25 | 26 | [When(@"^(?:I'm on|I go to) the search page$")] 27 | public void GoToSearchPage() 28 | { 29 | _browser.GoTo("http://www.google.com/"); 30 | } 31 | 32 | [When("^I search for \"(.*)\"$")] 33 | public void SearchFor(string query) 34 | { 35 | _browser.TextField(Find.ByName("q")).TypeText(query); 36 | _browser.Button(Find.ByName("btnG")).Click(); 37 | } 38 | 39 | [Then("^I should be on the search page$")] 40 | public void IsOnSearchPage() 41 | { 42 | Assert.That(_browser.Title == "Google"); 43 | } 44 | 45 | [Then("^I should see \"(.*)\" in the results$")] 46 | public void ResultsContain(string expectedResult) 47 | { 48 | Assert.That(_browser.ContainsText(expectedResult)); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /examples/WatiN/Google/features/search.feature: -------------------------------------------------------------------------------- 1 | Feature: Google search 2 | In order find things on the internet 3 | As a user 4 | I want to search for web pages with particular text in them 5 | 6 | Scenario: Load search page 7 | When I go to the search page 8 | Then I should be on the search page 9 | 10 | Scenario: Search 11 | Given I'm on the search page 12 | When I search for "richard lawrence" 13 | Then I should see "www.richardlawrence.info" in the results 14 | -------------------------------------------------------------------------------- /examples/WatiN/Google/features/step_definitions/cucumber.wire: -------------------------------------------------------------------------------- 1 | host: localhost 2 | port: 3901 3 | timeout: 4 | invoke: 35 5 | begin_scenario: 35 6 | end_scenario: 35 -------------------------------------------------------------------------------- /examples/WatiN/lib/Interop.SHDocVw.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richardlawrence/Cuke4Nuke/ddec8b87af32b981768a2cf2aaf5ba8c1cd5c251/examples/WatiN/lib/Interop.SHDocVw.dll -------------------------------------------------------------------------------- /examples/WatiN/lib/Microsoft.mshtml.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richardlawrence/Cuke4Nuke/ddec8b87af32b981768a2cf2aaf5ba8c1cd5c251/examples/WatiN/lib/Microsoft.mshtml.dll -------------------------------------------------------------------------------- /examples/WatiN/lib/WatiN.Core.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richardlawrence/Cuke4Nuke/ddec8b87af32b981768a2cf2aaf5ba8c1cd5c251/examples/WatiN/lib/WatiN.Core.dll -------------------------------------------------------------------------------- /examples/language/no/Kalkulator.5.0.ReSharper.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | False 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | Never 27 | 28 | -------------------------------------------------------------------------------- /examples/language/no/Kalkulator.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kalkulator", "Kalkulator\Kalkulator.csproj", "{2ADD960E-8D9C-4F71-8D52-286A41A20EFD}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KalkulatorFeatures", "KalkulatorFeatures\KalkulatorFeatures.csproj", "{F16EC30E-B4CB-408D-8163-7E200EA793D4}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {2ADD960E-8D9C-4F71-8D52-286A41A20EFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {2ADD960E-8D9C-4F71-8D52-286A41A20EFD}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {2ADD960E-8D9C-4F71-8D52-286A41A20EFD}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {2ADD960E-8D9C-4F71-8D52-286A41A20EFD}.Release|Any CPU.Build.0 = Release|Any CPU 18 | {F16EC30E-B4CB-408D-8163-7E200EA793D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {F16EC30E-B4CB-408D-8163-7E200EA793D4}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {F16EC30E-B4CB-408D-8163-7E200EA793D4}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {F16EC30E-B4CB-408D-8163-7E200EA793D4}.Release|Any CPU.Build.0 = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /examples/language/no/Kalkulator/Kalkulator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Kalkulator 7 | { 8 | public class Kalkulator 9 | { 10 | private int _sum; 11 | 12 | public void LeggSammen(int tall, int annetTall) 13 | { 14 | _sum = tall + annetTall; 15 | } 16 | 17 | public int Sum() 18 | { 19 | return _sum; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /examples/language/no/Kalkulator/Kalkulator.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {2ADD960E-8D9C-4F71-8D52-286A41A20EFD} 9 | Library 10 | Properties 11 | Kalkulator 12 | Kalkulator 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 | 3.5 40 | 41 | 42 | 3.5 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 59 | -------------------------------------------------------------------------------- /examples/language/no/Kalkulator/Kalkulator.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kalkulator", "Kalkulator.csproj", "{2ADD960E-8D9C-4F71-8D52-286A41A20EFD}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KalkulatorFeatures", "..\KalkulatorFeatures\KalkulatorFeatures.csproj", "{F16EC30E-B4CB-408D-8163-7E200EA793D4}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {2ADD960E-8D9C-4F71-8D52-286A41A20EFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {2ADD960E-8D9C-4F71-8D52-286A41A20EFD}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {2ADD960E-8D9C-4F71-8D52-286A41A20EFD}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {2ADD960E-8D9C-4F71-8D52-286A41A20EFD}.Release|Any CPU.Build.0 = Release|Any CPU 18 | {F16EC30E-B4CB-408D-8163-7E200EA793D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {F16EC30E-B4CB-408D-8163-7E200EA793D4}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {F16EC30E-B4CB-408D-8163-7E200EA793D4}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {F16EC30E-B4CB-408D-8163-7E200EA793D4}.Release|Any CPU.Build.0 = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /examples/language/no/Kalkulator/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Kalkulator")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Bekk")] 12 | [assembly: AssemblyProduct("Kalkulator")] 13 | [assembly: AssemblyCopyright("Copyright © Bekk 2010")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("25e7f39f-79be-4277-baea-282c1ad4d11a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /examples/language/no/KalkulatorFeatures/KalkulatorFeatures.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {F16EC30E-B4CB-408D-8163-7E200EA793D4} 9 | Library 10 | Properties 11 | KalkulatorFeatures 12 | KalkulatorFeatures 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 | ..\..\..\..\Cuke4Nuke\Framework\bin\Debug\Cuke4Nuke.Framework.dll 37 | 38 | 39 | False 40 | ..\..\..\..\Cuke4Nuke\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 | features\Kalkulator.feature 62 | 63 | 64 | 65 | 66 | 67 | {2ADD960E-8D9C-4F71-8D52-286A41A20EFD} 68 | Kalkulator 69 | 70 | 71 | 72 | 79 | -------------------------------------------------------------------------------- /examples/language/no/KalkulatorFeatures/KalkulatorSteps.cs: -------------------------------------------------------------------------------- 1 | using Cuke4Nuke.Framework.Languages.NO; 2 | using NUnit.Framework; 3 | 4 | namespace KalkulatorFeatures 5 | { 6 | class KalkulatorSteps 7 | { 8 | private Kalkulator.Kalkulator kalkulator; 9 | 10 | 11 | [Gitt(@"^at jeg trykker ""(.+)"" pluss ""(.+)""$")] 12 | public void AtJegTrykker4Pluss4(string tall, string annetTall) 13 | { 14 | kalkulator = new Kalkulator.Kalkulator(); 15 | kalkulator.LeggSammen(int.Parse(tall), int.Parse(annetTall)); 16 | } 17 | 18 | [Så(@"^skal jeg få ""(\d+)""$")] 19 | public void SkalJegF8(string result) 20 | { 21 | Assert.That(int.Parse(result), Is.EqualTo(kalkulator.Sum())); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /examples/language/no/KalkulatorFeatures/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("KalkulatorFeatures")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Bekk")] 12 | [assembly: AssemblyProduct("KalkulatorFeatures")] 13 | [assembly: AssemblyCopyright("Copyright © Bekk 2010")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("5f09f727-a0e2-4a74-891f-66de5d7195e4")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /examples/language/no/KalkulatorFeatures/features/Kalkulator.feature: -------------------------------------------------------------------------------- 1 | # language: no 2 | Egenskap: Kalkulator 3 | Som en bruker 4 | Ønsker jeg å få hjelp til å regne 5 | Slik at jeg ikke får regne feil 6 | 7 | Scenario: Legge sammen 8 | Gitt at jeg trykker "4" pluss "4" 9 | Så skal jeg få "8" 10 | -------------------------------------------------------------------------------- /examples/language/no/KalkulatorFeatures/features/step_definitions/cucumber.wire: -------------------------------------------------------------------------------- 1 | host: localhost 2 | port: 3901 3 | -------------------------------------------------------------------------------- /examples/self_test/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richardlawrence/Cuke4Nuke/ddec8b87af32b981768a2cf2aaf5ba8c1cd5c251/examples/self_test/.gitignore -------------------------------------------------------------------------------- /features/cuke4nuke.feature: -------------------------------------------------------------------------------- 1 | Feature: Run .NET step definitions from Cucumber 2 | 3 | Background: 4 | Given a standard Cucumber project directory structure 5 | And a file named "features/wired.feature" with: 6 | """ 7 | Feature: So wired 8 | Scenario: Wired 9 | Given we're all wired 10 | 11 | """ 12 | And a file named "features/step_definitions/some_remote_place.wire" with: 13 | """ 14 | host: localhost 15 | port: 3901 16 | 17 | """ 18 | 19 | Scenario: Dry run finds no step match 20 | Given Cuke4Nuke started with no step definition assemblies 21 | When I run cucumber --dry-run -f progress features 22 | Then STDERR should be empty 23 | And it should pass with 24 | """ 25 | U 26 | 27 | 1 scenario (1 undefined) 28 | 1 step (1 undefined) 29 | 30 | You can implement step definitions for undefined steps with these snippets: 31 | 32 | [Pending] 33 | [Given(@"^we're all wired$")] 34 | public void WereAllWired() 35 | { 36 | } 37 | 38 | 39 | """ 40 | 41 | Scenario: Dry run finds a step match 42 | Given Cuke4Nuke started with a step definition assembly containing: 43 | """ 44 | public class GeneratedSteps 45 | { 46 | [Given("^we're all wired$")] 47 | public static void AllWired() 48 | { 49 | } 50 | } 51 | """ 52 | When I run cucumber --dry-run -f progress features 53 | Then STDERR should be empty 54 | And it should pass with 55 | """ 56 | - 57 | 58 | 1 scenario (1 skipped) 59 | 1 step (1 skipped) 60 | 61 | """ 62 | 63 | Scenario: Invoke a step definition which passes 64 | Given Cuke4Nuke started with a step definition assembly containing: 65 | """ 66 | public class GeneratedSteps 67 | { 68 | [Given("^we're all wired$")] 69 | public static void AllWired() 70 | { 71 | } 72 | } 73 | """ 74 | When I run cucumber -f progress features 75 | Then STDERR should be empty 76 | And it should pass with 77 | """ 78 | . 79 | 80 | 1 scenario (1 passed) 81 | 1 step (1 passed) 82 | 83 | """ 84 | 85 | Scenario: Invoke a step definition which passes, using pretty format 86 | Given Cuke4Nuke started with a step definition assembly containing: 87 | """ 88 | public class GeneratedSteps 89 | { 90 | [Given("^we're all wired$")] 91 | public static void AllWired() 92 | { 93 | } 94 | } 95 | """ 96 | When I run cucumber --no-source -f pretty features 97 | Then STDERR should be empty 98 | And it should pass with 99 | """ 100 | Feature: So wired 101 | 102 | Scenario: Wired 103 | Given we're all wired 104 | 105 | 1 scenario (1 passed) 106 | 1 step (1 passed) 107 | 108 | """ 109 | 110 | Scenario: Invoke a step definition which fails 111 | Given Cuke4Nuke started with a step definition assembly containing: 112 | """ 113 | public class GeneratedSteps 114 | { 115 | [Given("^we're all wired$")] 116 | public static void AllWired() 117 | { 118 | throw new Exception("message"); 119 | } 120 | } 121 | """ 122 | When I run cucumber -f progress features 123 | Then it should fail -------------------------------------------------------------------------------- /features/hooks.feature: -------------------------------------------------------------------------------- 1 | Feature: Run .NET Before and After hooks from Cucumber 2 | 3 | Background: 4 | Given a standard Cucumber project directory structure 5 | And a file named "features/step_definitions/some_remote_place.wire" with: 6 | """ 7 | host: localhost 8 | port: 3901 9 | 10 | """ 11 | 12 | Scenario: Before hook 13 | Given a file named "features/adding.feature" with: 14 | """ 15 | Feature: Test Feature 16 | 17 | Scenario: Cuke count set in Before 18 | Then I should have 4 cukes 19 | 20 | """ 21 | And Cuke4Nuke started with a step definition assembly containing: 22 | """ 23 | public class GeneratedSteps 24 | { 25 | int _cukeCount = 0; 26 | 27 | [Before] 28 | public void Setup() 29 | { 30 | _cukeCount = 4; 31 | } 32 | 33 | [Then(@"^I should have (\d+) cukes$")] 34 | public void ExpectCukes(int cukes) 35 | { 36 | if (_cukeCount != cukes) 37 | { 38 | throw new Exception("Expected value: " + cukes.ToString() + ". Actual value: " + _cukeCount.ToString() + "."); 39 | } 40 | } 41 | } 42 | """ 43 | When I run cucumber -f progress features 44 | Then STDERR should be empty 45 | And it should pass with 46 | """ 47 | . 48 | 49 | 1 scenario (1 passed) 50 | 1 step (1 passed) 51 | 52 | """ 53 | 54 | Scenario: After hook throws exception (how else do we know it's called?) 55 | Given a file named "features/adding.feature" with: 56 | """ 57 | Feature: Test Feature 58 | 59 | Scenario: After hook defined 60 | Given a passing step 61 | 62 | """ 63 | And Cuke4Nuke started with a step definition assembly containing: 64 | """ 65 | public class GeneratedSteps 66 | { 67 | [After] 68 | public void Teardown() 69 | { 70 | throw new Exception(); 71 | } 72 | 73 | [Given(@"^a passing step$")] 74 | public void PassingStep() 75 | { 76 | } 77 | } 78 | """ 79 | When I run cucumber -f progress features 80 | Then it should fail 81 | 82 | Scenario: Tagged Before hook (string, positive) 83 | Given a file named "features/adding.feature" with: 84 | """ 85 | Feature: Test Feature 86 | 87 | @my_tag 88 | Scenario: Was Before hook called? 89 | Then the Before hook should be called 90 | 91 | """ 92 | And Cuke4Nuke started with a step definition assembly containing: 93 | """ 94 | public class GeneratedSteps 95 | { 96 | bool _isBeforeCalled = false; 97 | 98 | [Before("@my_tag")] 99 | public void Setup() 100 | { 101 | _isBeforeCalled = true; 102 | } 103 | 104 | [Then(@"^the Before hook should be called$")] 105 | public void ExpectBeforeHookCalled() 106 | { 107 | Assert.True(_isBeforeCalled); 108 | } 109 | } 110 | """ 111 | When I run cucumber -f progress features 112 | Then STDERR should be empty 113 | And it should pass with 114 | """ 115 | . 116 | 117 | 1 scenario (1 passed) 118 | 1 step (1 passed) 119 | 120 | """ 121 | 122 | Scenario: Tagged Before hook (string, negative) 123 | Given a file named "features/adding.feature" with: 124 | """ 125 | Feature: Test Feature 126 | 127 | @my_tag 128 | Scenario: Was Before hook called? 129 | Then the Before hook should not be called 130 | 131 | """ 132 | And Cuke4Nuke started with a step definition assembly containing: 133 | """ 134 | public class GeneratedSteps 135 | { 136 | bool _isBeforeCalled = false; 137 | 138 | [Before("@not_my_tag")] 139 | public void Setup() 140 | { 141 | _isBeforeCalled = true; 142 | } 143 | 144 | [Then(@"^the Before hook should not be called$")] 145 | public void ExpectBeforeHookNotCalled() 146 | { 147 | Assert.False(_isBeforeCalled); 148 | } 149 | } 150 | """ 151 | When I run cucumber -f progress features 152 | Then STDERR should be empty 153 | And it should pass with 154 | """ 155 | . 156 | 157 | 1 scenario (1 passed) 158 | 1 step (1 passed) 159 | 160 | """ 161 | 162 | Scenario: Tagged After hook (string, positive) 163 | Given a file named "features/adding.feature" with: 164 | """ 165 | Feature: Test Feature 166 | 167 | @my_tag 168 | Scenario: After hook defined 169 | Given a passing step 170 | 171 | """ 172 | And Cuke4Nuke started with a step definition assembly containing: 173 | """ 174 | public class GeneratedSteps 175 | { 176 | [After("@my_tag")] 177 | public void TearDown() 178 | { 179 | throw new Exception(); 180 | } 181 | 182 | [Given(@"^a passing step$")] 183 | public void APassingStep() 184 | { 185 | } 186 | } 187 | """ 188 | When I run cucumber -f progress features 189 | Then it should fail 190 | 191 | Scenario: Tagged After hook (string, negative) 192 | Given a file named "features/adding.feature" with: 193 | """ 194 | Feature: Test Feature 195 | 196 | @my_tag 197 | Scenario: After hook defined 198 | Given a passing step 199 | 200 | """ 201 | And Cuke4Nuke started with a step definition assembly containing: 202 | """ 203 | public class GeneratedSteps 204 | { 205 | [After("@not_my_tag")] 206 | public void TearDown() 207 | { 208 | throw new Exception(); 209 | } 210 | 211 | [Given(@"^a passing step$")] 212 | public void APassingStep() 213 | { 214 | } 215 | } 216 | """ 217 | When I run cucumber -f progress features 218 | Then STDERR should be empty 219 | And it should pass with 220 | """ 221 | . 222 | 223 | 1 scenario (1 passed) 224 | 1 step (1 passed) 225 | 226 | """ 227 | 228 | -------------------------------------------------------------------------------- /features/pending.feature: -------------------------------------------------------------------------------- 1 | Feature: Pending Steps 2 | 3 | Background: 4 | Given a standard Cucumber project directory structure 5 | And a file named "features/wired.feature" with: 6 | """ 7 | Feature: Test Feature 8 | 9 | Scenario: Wired 10 | Given we're all wired 11 | 12 | """ 13 | And a file named "features/step_definitions/some_remote_place.wire" with: 14 | """ 15 | host: localhost 16 | port: 3901 17 | 18 | """ 19 | 20 | Scenario: Pending step gives pending output 21 | Given Cuke4Nuke started with a step definition assembly containing: 22 | """ 23 | public class GeneratedSteps 24 | { 25 | [Pending] 26 | [Given("^we're all wired$")] 27 | public static void AllWired() 28 | { 29 | } 30 | } 31 | """ 32 | When I run cucumber -f pretty -q 33 | Then it should pass with 34 | """ 35 | Feature: Test Feature 36 | 37 | Scenario: Wired 38 | Given we're all wired 39 | TODO (Cucumber::Pending) 40 | features\wired.feature:4:in `Given we're all wired' 41 | 42 | 1 scenario (1 pending) 43 | 1 step (1 pending) 44 | 45 | """ -------------------------------------------------------------------------------- /features/shared_state.feature: -------------------------------------------------------------------------------- 1 | Feature: Run .NET step definitions with shared state from Cucumber 2 | 3 | Background: 4 | Given a standard Cucumber project directory structure 5 | And a file named "features/step_definitions/some_remote_place.wire" with: 6 | """ 7 | host: localhost 8 | port: 3901 9 | 10 | """ 11 | 12 | Scenario: Shared state in one step definition class 13 | Given a file named "features/adding.feature" with: 14 | """ 15 | Feature: Test Feature 16 | 17 | Scenario: Adding 18 | Given 2 cukes 19 | When I add 2 more cukes 20 | Then I should have 4 cukes 21 | 22 | """ 23 | And Cuke4Nuke started with a step definition assembly containing: 24 | """ 25 | public class GeneratedSteps 26 | { 27 | int _cukeCount = 0; 28 | 29 | [Given(@"^(\d+) cukes$")] 30 | public void GivenSomeCukes(int cukes) 31 | { 32 | _cukeCount = cukes; 33 | } 34 | 35 | [When(@"^I add (\d+) more cukes$")] 36 | public void AddCukes(int cukes) 37 | { 38 | _cukeCount += cukes; 39 | } 40 | 41 | [Then(@"^I should have (\d+) cukes$")] 42 | public void ExpectCukes(int cukes) 43 | { 44 | if (_cukeCount != cukes) 45 | { 46 | throw new Exception("Expected value: " + cukes.ToString() + ". Actual value: " + _cukeCount.ToString() + "."); 47 | } 48 | } 49 | } 50 | """ 51 | When I run cucumber -f progress features 52 | Then STDERR should be empty 53 | And it should pass with 54 | """ 55 | ... 56 | 57 | 1 scenario (1 passed) 58 | 3 steps (3 passed) 59 | 60 | """ 61 | 62 | Scenario: Multiple scenarios each get their own state 63 | Given a file named "features/adding.feature" with: 64 | """ 65 | Feature: Test Feature 66 | 67 | Scenario: Adding with pickles 68 | Given 2 cukes 69 | And 2 pickles 70 | When I add 2 more cukes 71 | Then I should have 4 cukes 72 | And I should have 2 pickles 73 | 74 | Scenario: Adding without pickles 75 | Given 2 cukes 76 | When I add 2 more cukes 77 | Then I should have 4 cukes 78 | And I should have 0 pickles 79 | 80 | """ 81 | And Cuke4Nuke started with a step definition assembly containing: 82 | """ 83 | public class GeneratedSteps 84 | { 85 | int _cukeCount = 0; 86 | int _pickleCount = 0; 87 | 88 | [Given(@"^(\d+) cukes$")] 89 | public void GivenSomeCukes(int cukes) 90 | { 91 | _cukeCount = cukes; 92 | } 93 | 94 | [Given(@"^(\d+) pickles$")] 95 | public void GivenSomePickles(int pickles) 96 | { 97 | _pickleCount = pickles; 98 | } 99 | 100 | [When(@"^I add (\d+) more cukes$")] 101 | public void AddCukes(int cukes) 102 | { 103 | _cukeCount += cukes; 104 | } 105 | 106 | [Then(@"^I should have (\d+) cukes$")] 107 | public void ExpectCukes(int cukes) 108 | { 109 | if (_cukeCount != cukes) 110 | { 111 | throw new Exception("Expected value: " + cukes.ToString() + ". Actual value: " + _cukeCount.ToString() + "."); 112 | } 113 | } 114 | 115 | [Then(@"^I should have (\d+) pickles$")] 116 | public void ExpectPickles(int pickles) 117 | { 118 | if (_pickleCount != pickles) 119 | { 120 | throw new Exception("Expected value: " + pickles.ToString() + ". Actual value: " + _pickleCount.ToString() + "."); 121 | } 122 | } 123 | } 124 | """ 125 | When I run cucumber -f progress features 126 | Then STDERR should be empty 127 | And it should pass with 128 | """ 129 | ......... 130 | 131 | 2 scenarios (2 passed) 132 | 9 steps (9 passed) 133 | 134 | """ 135 | 136 | Scenario: Shared state between two step definition classes 137 | Given a file named "features/adding.feature" with: 138 | """ 139 | Feature: Test Feature 140 | 141 | Scenario: Adding 142 | Given 2 cukes 143 | When I add 2 more cukes 144 | Then I should have 4 cukes 145 | 146 | """ 147 | And Cuke4Nuke started with a step definition assembly containing: 148 | """ 149 | public class CukeJar 150 | { 151 | public int CukeCount { get; set; } 152 | } 153 | 154 | public class Steps1 155 | { 156 | CukeJar _cukeJar; 157 | 158 | public Steps1(CukeJar cukeJar) 159 | { 160 | _cukeJar = cukeJar; 161 | } 162 | 163 | [Given(@"^(\d+) cukes$")] 164 | public void GivenSomeCukes(int cukes) 165 | { 166 | _cukeJar.CukeCount = cukes; 167 | } 168 | 169 | [When(@"^I add (\d+) more cukes$")] 170 | public void AddCukes(int cukes) 171 | { 172 | _cukeJar.CukeCount += cukes; 173 | } 174 | } 175 | 176 | public class Steps2 177 | { 178 | CukeJar _cukeJar; 179 | 180 | public Steps2(CukeJar cukeJar) 181 | { 182 | _cukeJar = cukeJar; 183 | } 184 | 185 | [Then(@"^I should have (\d+) cukes$")] 186 | public void ExpectCukes(int cukes) 187 | { 188 | if (_cukeJar.CukeCount != cukes) 189 | { 190 | throw new Exception("Expected value: " + cukes.ToString() + ". Actual value: " + _cukeJar.CukeCount.ToString() + "."); 191 | } 192 | } 193 | } 194 | """ 195 | When I run cucumber -f progress features 196 | Then STDERR should be empty 197 | And it should pass with 198 | """ 199 | ... 200 | 201 | 1 scenario (1 passed) 202 | 3 steps (3 passed) 203 | 204 | """ 205 | -------------------------------------------------------------------------------- /features/snippets.feature: -------------------------------------------------------------------------------- 1 | Feature: Print step definition snippets for undefined steps 2 | 3 | Background: 4 | Given a standard Cucumber project directory structure 5 | And a file named "features/step_definitions/some_remote_place.wire" with: 6 | """ 7 | host: localhost 8 | port: 3901 9 | 10 | """ 11 | 12 | Scenario: Undefined prints snippet 13 | Given a file named "features/wired.feature" with: 14 | """ 15 | Feature: Test Feature 16 | 17 | Scenario: Wired 18 | Given we're all wired 19 | 20 | """ 21 | And Cuke4Nuke started with no step definition assemblies 22 | When I run cucumber -f pretty 23 | Then the output should contain 24 | """ 25 | [Pending] 26 | [Given(@"^we're all wired$")] 27 | public void WereAllWired() 28 | { 29 | } 30 | """ 31 | 32 | Scenario: Snippet with a table 33 | Given a file named "features/wired.feature" with: 34 | """ 35 | Feature: Test Feature 36 | 37 | Scenario: Wired 38 | Given we're all wired 39 | | who | 40 | | Richard | 41 | | Matt | 42 | | Aslak | 43 | """ 44 | And Cuke4Nuke started with no step definition assemblies 45 | When I run cucumber -f pretty 46 | Then the output should contain 47 | """ 48 | [Pending] 49 | [Given(@"^we're all wired$")] 50 | public void WereAllWired(Table table) 51 | { 52 | } 53 | """ 54 | 55 | Scenario: Snippet with a multiline string 56 | Given a file named "features/wired.feature" with: 57 | """ 58 | Feature: Test Feature 59 | 60 | Scenario: Wired 61 | Given we're all wired 62 | \"\"\" 63 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. 64 | Morbi porttitor semper lobortis. Duis nec nibh felis, vitae tempor augue. 65 | \"\"\" 66 | """ 67 | And Cuke4Nuke started with no step definition assemblies 68 | When I run cucumber -f pretty 69 | Then the output should contain 70 | """ 71 | [Pending] 72 | [Given(@"^we're all wired$")] 73 | public void WereAllWired(string str) 74 | { 75 | } 76 | """ 77 | 78 | Scenario: Snippet with a scenario outline 79 | Given a file named "features/wired.feature" with: 80 | """ 81 | Feature: Test Feature 82 | 83 | Scenario Outline: Wired 84 | Given we're all 85 | 86 | Examples: 87 | | something | 88 | | wired | 89 | | not wired | 90 | 91 | """ 92 | And Cuke4Nuke started with no step definition assemblies 93 | When I run cucumber -f pretty 94 | Then the output should contain 95 | """ 96 | [Pending] 97 | [Given(@"^we're all wired$")] 98 | public void WereAllWired() 99 | { 100 | } 101 | """ 102 | And the output should contain 103 | """ 104 | [Pending] 105 | [Given(@"^we're all not wired$")] 106 | public void WereAllNotWired() 107 | { 108 | } 109 | """ 110 | 111 | Scenario: Snippet with Background 112 | Given a file named "features/wired.feature" with: 113 | """ 114 | Feature: Test Feature 115 | 116 | Background: 117 | Given something to do first 118 | 119 | Scenario: Wired 120 | Given we're all wired 121 | 122 | """ 123 | And Cuke4Nuke started with no step definition assemblies 124 | When I run cucumber -f pretty 125 | Then the output should contain 126 | """ 127 | [Pending] 128 | [Given(@"^we're all wired$")] 129 | public void WereAllWired() 130 | { 131 | } 132 | """ 133 | And the output should contain 134 | """ 135 | [Pending] 136 | [Given(@"^something to do first$")] 137 | public void SomethingToDoFirst() 138 | { 139 | } 140 | """ 141 | 142 | Scenario: Snippet for step with trailing comma 143 | Given a file named "features/wired.feature" with: 144 | """ 145 | Feature: Test Feature 146 | 147 | Scenario: Comma separated 148 | Given the separator is , 149 | 150 | """ 151 | And Cuke4Nuke started with no step definition assemblies 152 | When I run cucumber -f pretty 153 | Then STDERR should be empty 154 | And the output should contain 155 | """ 156 | [Pending] 157 | [Given(@"^the separator is ,$")] 158 | public void TheSeparatorIs() 159 | { 160 | } 161 | """ 162 | 163 | Scenario: Snippet for step with double quotes 164 | Given a file named "features/wired.feature" with: 165 | """ 166 | Feature: Test Feature 167 | 168 | Scenario: Quotes 169 | Given I "love" quotes 170 | 171 | """ 172 | And Cuke4Nuke started with no step definition assemblies 173 | When I run cucumber -f pretty 174 | Then the output should contain 175 | """ 176 | [Given(@"^I ""love"" quotes$")] 177 | """ 178 | -------------------------------------------------------------------------------- /features/step_definitions/cucumber_steps.rb: -------------------------------------------------------------------------------- 1 | require 'tempfile' 2 | 3 | Given /^I am in (.*)$/ do |example_dir_relative_path| 4 | @current_dir = examples_dir(example_dir_relative_path) 5 | end 6 | 7 | Given /^a standard Cucumber project directory structure$/ do 8 | @current_dir = working_dir 9 | in_current_dir do 10 | FileUtils.mkdir_p 'features/support' 11 | FileUtils.mkdir 'features/step_definitions' 12 | end 13 | end 14 | 15 | Given /^the (.*) directory is empty$/ do |directory| 16 | in_current_dir do 17 | FileUtils.remove_dir(directory) rescue nil 18 | FileUtils.mkdir 'tmp' 19 | end 20 | end 21 | 22 | Given /^a file named "([^\"]*)"$/ do |file_name| 23 | create_file(file_name, '') 24 | end 25 | 26 | Given /^a file named "([^\"]*)" with:$/ do |file_name, file_content| 27 | create_file(file_name, file_content) 28 | end 29 | 30 | Given /^the following profiles? (?:are|is) defined:$/ do |profiles| 31 | create_file('cucumber.yml', profiles) 32 | end 33 | 34 | Given /^I am running spork in the background$/ do 35 | run_spork_in_background 36 | end 37 | 38 | Given /^I am running spork in the background on port (\d+)$/ do |port| 39 | run_spork_in_background(port.to_i) 40 | end 41 | 42 | Given /^I am not running (?:.*) in the background$/ do 43 | # no-op 44 | end 45 | 46 | Given /^I have environment variable (\w+) set to "([^\"]*)"$/ do |variable, value| 47 | set_env_var(variable, value) 48 | end 49 | 50 | When /^I run cucumber (.*)$/ do |cucumber_opts| 51 | ruby_path = Cucumber::RUBY_BINARY.gsub('/', '\\') 52 | cucumber_path = Cucumber::BINARY.gsub('/', '\\') 53 | run %{"#{ruby_path}" "#{cucumber_path}" --no-color #{cucumber_opts}} 54 | end 55 | 56 | When /^I run rake (.*)$/ do |rake_opts| 57 | run "rake #{rake_opts} --trace" 58 | end 59 | 60 | Then /^it should (fail|pass)$/ do |success| 61 | if success == 'fail' 62 | last_exit_status.should_not == 0 63 | else 64 | if last_exit_status != 0 65 | raise "Failed with exit status #{last_exit_status}\nSTDOUT:\n#{last_stdout}\nSTDERR:\n#{last_stderr}" 66 | end 67 | end 68 | end 69 | 70 | Then /^it should (fail|pass) with$/ do |success, output| 71 | last_stdout.should == output 72 | Then("it should #{success}") 73 | end 74 | 75 | Then /^the output should contain$/ do |text| 76 | last_stdout.should include(text) 77 | end 78 | 79 | Then /^the output should not contain$/ do |text| 80 | last_stdout.should_not include(text) 81 | end 82 | 83 | Then /^the output should be$/ do |text| 84 | last_stdout.should == text 85 | end 86 | 87 | 88 | Then /^"([^\"]*)" should contain$/ do |file, text| 89 | strip_duration(IO.read(file)).should == text 90 | end 91 | 92 | Then /^"([^\"]*)" with junit duration "([^\"]*)" should contain$/ do |actual_file, duration_replacement, text| 93 | actual = IO.read(actual_file) 94 | actual = replace_junit_duration(actual, duration_replacement) 95 | actual = strip_ruby186_extra_trace(actual) 96 | actual.should == text 97 | end 98 | 99 | Then /^"([^\"]*)" should match "([^\"]*)"$/ do |file, text| 100 | IO.read(file).should =~ Regexp.new(text) 101 | end 102 | 103 | Then /^"([^\"]*)" should have the same contents as "([^\"]*)"$/ do |actual_file, expected_file| 104 | actual = IO.read(actual_file) 105 | actual = replace_duration(actual, '0m30.005s') 106 | # Comment out to replace expected file. Use with care! 107 | # File.open(expected_file, "w") {|io| io.write(actual)} 108 | actual.should == IO.read(expected_file) 109 | end 110 | 111 | Then /^STDERR should match$/ do |text| 112 | last_stderr.should =~ /#{text}/ 113 | end 114 | 115 | Then /^STDERR should not match$/ do |text| 116 | last_stderr.should_not =~ /#{text}/ 117 | end 118 | 119 | Then /^STDERR should be$/ do |text| 120 | last_stderr.should == text 121 | end 122 | 123 | Then /^STDERR should be empty$/ do 124 | last_stderr.should == "" 125 | end 126 | 127 | Then /^"([^\"]*)" should exist$/ do |file| 128 | File.exists?(file).should be_true 129 | FileUtils.rm(file) 130 | end 131 | 132 | Then /^"([^\"]*)" should not be required$/ do |file_name| 133 | last_stdout.should_not include("* #{file_name}") 134 | end 135 | 136 | Then /^"([^\"]*)" should be required$/ do |file_name| 137 | last_stdout.should include("* #{file_name}") 138 | end 139 | 140 | Then /^exactly these files should be loaded:\s*(.*)$/ do |files| 141 | last_stdout.scan(/^ \* (.*\.rb)$/).flatten.should == files.split(/,\s+/) 142 | end 143 | 144 | Then /^exactly these features should be ran:\s*(.*)$/ do |files| 145 | last_stdout.scan(/^ \* (.*\.feature)$/).flatten.should == files.split(/,\s+/) 146 | end 147 | 148 | Then /^the (.*) profile should be used$/ do |profile| 149 | last_stdout.should =~ /Using the #{profile} profile/ 150 | end 151 | 152 | Then /^print output$/ do 153 | puts last_stdout 154 | end 155 | 156 | 157 | -------------------------------------------------------------------------------- /features/step_definitions/cuke4nuke_steps.rb: -------------------------------------------------------------------------------- 1 | Given /^Cuke4Nuke started with no step definition assemblies$/ do 2 | run_in_background cuke4nuke_server_exe 3 | end 4 | 5 | Given /^Cuke4Nuke started with a step definition assembly containing:$/ do |contents| 6 | assembly_path = build_step_definitions(contents) 7 | run_in_background %{#{cuke4nuke_server_exe} -a "#{assembly_path}"} 8 | end 9 | 10 | Given /^a step definition assembly containing:$/ do |contents| 11 | @last_assembly_path = build_step_definitions(contents) 12 | end 13 | 14 | When /^I run the cuke4nuke wrapper$/ do 15 | ruby_path = Cucumber::RUBY_BINARY.gsub('/', '\\') 16 | run %{"#{ruby_path}" "#{cuke4nuke_wrapper_path}" "#{@last_assembly_path}" -b --no-color -f progress features} 17 | end -------------------------------------------------------------------------------- /features/support/env.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'tempfile' 3 | require 'spec/expectations' 4 | require 'fileutils' 5 | require 'forwardable' 6 | require 'win32/process' 7 | require 'erb' 8 | 9 | class CucumberWorld 10 | extend Forwardable 11 | def_delegators CucumberWorld, :examples_dir, :self_test_dir, :working_dir, :cucumber_lib_dir, :cuke4nuke_server_exe, :cuke4nuke_wrapper_path 12 | 13 | def self.examples_dir(subdir=nil) 14 | @examples_dir ||= File.expand_path(File.join(File.dirname(__FILE__), '../../examples')) 15 | subdir ? File.join(@examples_dir, subdir) : @examples_dir 16 | end 17 | 18 | def self.self_test_dir 19 | @self_test_dir ||= examples_dir('self_test') 20 | end 21 | 22 | def self.working_dir 23 | @working_dir ||= examples_dir('self_test/tmp') 24 | end 25 | 26 | def cucumber_lib_dir 27 | @cucumber_lib_dir ||= File.expand_path(File.join(File.dirname(__FILE__), '../../lib')) 28 | end 29 | 30 | def cuke4nuke_server_exe 31 | @cuke4nuke_server_exe ||= File.expand_path(File.join(File.dirname(__FILE__), '../../Cuke4Nuke/Server/bin/Debug/Cuke4Nuke.Server.exe')) 32 | end 33 | 34 | def cuke4nuke_wrapper_path 35 | @cuke4nuke_wrapper_path ||= File.expand_path(File.join(File.dirname(__FILE__), '../../gem/bin/cuke4nuke')) 36 | end 37 | 38 | def initialize 39 | @current_dir = self_test_dir 40 | end 41 | 42 | private 43 | attr_reader :last_exit_status, :last_stderr 44 | 45 | def build_step_definitions(contents) 46 | csc_path = "C:\\WINDOWS\\Microsoft.NET\\Framework\\v3.5\\csc.exe" 47 | assembly_path = File.join(working_dir, 'bin/GeneratedStepDefinitions.dll').gsub('/', '\\') 48 | src_path = File.join(working_dir, 'src/GeneratedStepDefinitions.cs').gsub('/', '\\') 49 | cuke4nuke_ref_path = File.expand_path(File.join(examples_dir, '../Cuke4Nuke/Framework/bin/Debug/Cuke4Nuke.Framework.dll')).gsub('/', '\\') 50 | nunit_ref_path = File.expand_path(File.join(examples_dir, '../Cuke4Nuke/Specifications/bin/Debug/nunit.framework.dll')).gsub('/', '\\') 51 | template_path = File.expand_path(File.join(File.dirname(__FILE__), 'steps_template.cs.erb')) 52 | generated_code = ERB.new(File.read(template_path)).result(binding) 53 | create_file(assembly_path, '') 54 | create_file(src_path, generated_code) 55 | in_current_dir do 56 | FileUtils.cp nunit_ref_path, File.join(working_dir, 'bin') 57 | command = %{#{csc_path} /target:library /out:"#{assembly_path}" /reference:"#{cuke4nuke_ref_path}" /reference:"#{nunit_ref_path}" "#{src_path}"} 58 | run command 59 | raise "Failed to build #{src_path}:\nCMD:#{command}\nEXIT:#{@last_exit_status.to_i}\nSTDERR:\n#{@last_stderr}\nSTDOUT:\n#{@last_stdout}" if @last_exit_status.to_i != 0 60 | end 61 | assembly_path 62 | end 63 | 64 | # The last standard out, with the duration line taken out (unpredictable) 65 | def last_stdout 66 | strip_duration(@last_stdout) 67 | end 68 | 69 | def strip_duration(s) 70 | s.gsub(/^\d+m\d+\.\d+s\n/m, "") 71 | end 72 | 73 | def replace_duration(s, replacement) 74 | s.gsub(/\d+m\d+\.\d+s/m, replacement) 75 | end 76 | 77 | def replace_junit_duration(s, replacement) 78 | s.gsub(/\d+\.\d\d+/m, replacement) 79 | end 80 | 81 | def strip_ruby186_extra_trace(s) 82 | s.gsub(/^.*\.\/features\/step_definitions(.*)\n/, "") 83 | end 84 | 85 | def create_file(file_name, file_content) 86 | file_content.gsub!("CUCUMBER_LIB", "'#{cucumber_lib_dir}'") # Some files, such as Rakefiles need to use the lib dir 87 | in_current_dir do 88 | FileUtils.mkdir_p(File.dirname(file_name)) unless File.directory?(File.dirname(file_name)) 89 | File.open(file_name, 'w') { |f| f << file_content } 90 | end 91 | end 92 | 93 | def set_env_var(variable, value) 94 | @original_env_vars ||= {} 95 | @original_env_vars[variable] = ENV[variable] 96 | ENV[variable] = value 97 | end 98 | 99 | def background_jobs 100 | @background_jobs ||= [] 101 | end 102 | 103 | def in_current_dir(&block) 104 | Dir.chdir(@current_dir, &block) 105 | end 106 | 107 | def run(command) 108 | stderr_file = Tempfile.new('cucumber') 109 | stderr_file.close 110 | in_current_dir do 111 | mode = Cucumber::RUBY_1_9 ? {:external_encoding=>"UTF-8"} : 'r' 112 | IO.popen("#{command} 2> #{stderr_file.path}", mode) do |io| 113 | @last_stdout = io.read 114 | end 115 | 116 | @last_exit_status = $?.exitstatus 117 | end 118 | @last_stderr = IO.read(stderr_file.path) 119 | end 120 | 121 | def run_in_background(command) 122 | in_current_dir do 123 | process = IO.popen(command, 'r') 124 | background_jobs << process.pid 125 | end 126 | end 127 | 128 | def terminate_background_jobs 129 | if @background_jobs 130 | @background_jobs.each do |pid| 131 | Process.kill(9, pid) 132 | end 133 | end 134 | end 135 | 136 | def restore_original_env_vars 137 | @original_env_vars.each { |variable, value| ENV[variable] = value } if @original_env_vars 138 | end 139 | 140 | end 141 | 142 | World do 143 | CucumberWorld.new 144 | end 145 | 146 | Before do 147 | FileUtils.remove_dir(CucumberWorld.working_dir) if File.exists? CucumberWorld.working_dir 148 | FileUtils.mkdir CucumberWorld.working_dir 149 | end 150 | 151 | After do 152 | terminate_background_jobs 153 | restore_original_env_vars 154 | end 155 | -------------------------------------------------------------------------------- /features/support/steps_template.cs.erb: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using NUnit.Framework; 4 | using Cuke4Nuke.Framework; 5 | 6 | namespace Cuke4Nuke.TestStepDefinitions 7 | { 8 | <%= contents %> 9 | } 10 | -------------------------------------------------------------------------------- /features/tables.feature: -------------------------------------------------------------------------------- 1 | Feature: Use table multi-line step arguments 2 | 3 | Background: 4 | Given a standard Cucumber project directory structure 5 | And a file named "features/step_definitions/some_remote_place.wire" with: 6 | """ 7 | host: localhost 8 | port: 3901 9 | 10 | """ 11 | 12 | Scenario: Table in a Given 13 | Given a file named "features/table.feature" with: 14 | """ 15 | Feature: Test Feature 16 | 17 | Scenario: Shopping list 18 | Given I have a shopping list with the following items: 19 | | item | count | 20 | | cucumbers | 3 | 21 | | bananas | 5 | 22 | | tomatoes | 2 | 23 | When I buy everything on my list 24 | Then my cart should contain 10 items 25 | """ 26 | And Cuke4Nuke started with a step definition assembly containing: 27 | """ 28 | public class GeneratedSteps 29 | { 30 | Cuke4Nuke.Framework.Table _shoppingList; 31 | int _itemsInCart = 0; 32 | 33 | [Given(@"^I have a shopping list with the following items:$")] 34 | public void GivenAShoppingList(Cuke4Nuke.Framework.Table shoppingList) 35 | { 36 | _shoppingList = shoppingList; 37 | } 38 | 39 | [When(@"^I buy everything on my list$")] 40 | public void BuyEverything() 41 | { 42 | foreach (System.Collections.Generic.Dictionary row in _shoppingList.Hashes()) 43 | { 44 | _itemsInCart += Int32.Parse(row["count"]); 45 | } 46 | } 47 | 48 | [Then(@"^my cart should contain (\d+) items$")] 49 | public void CartContainsNItems(int itemCount) 50 | { 51 | if (_itemsInCart != itemCount) 52 | { 53 | throw new Exception("Expected value: " + itemCount.ToString() + ". Actual value: " + _itemsInCart.ToString() + "."); 54 | } 55 | } 56 | } 57 | """ 58 | When I run cucumber -f progress features 59 | Then STDERR should be empty 60 | And it should pass with 61 | """ 62 | ... 63 | 64 | 1 scenario (1 passed) 65 | 3 steps (3 passed) 66 | 67 | """ 68 | 69 | Scenario: Table in a Then 70 | Given a file named "features/table.feature" with: 71 | """ 72 | Feature: Test Feature 73 | 74 | Scenario: Build a shopping list 75 | Given I need 3 cucumbers 76 | And I need 5 bananas 77 | And I need 2 tomatoes 78 | When I build my shopping list 79 | Then the shopping list should look like: 80 | | item | count | 81 | | cucumbers | 3 | 82 | | bananas | 5 | 83 | | tomatoes | 2 | 84 | """ 85 | And Cuke4Nuke started with a step definition assembly containing: 86 | """ 87 | public class GeneratedSteps 88 | { 89 | Table _shoppingList = new Table(); 90 | List> _listEntries = new List>(); 91 | 92 | [Given(@"^I need (\d+) (.*)$")] 93 | public void INeedNItems(int count, string item) 94 | { 95 | _listEntries.Add(new List(new string[]{item, count.ToString()})); 96 | } 97 | 98 | [When(@"^I build my shopping list$")] 99 | public void IBuildMyShoppingList() 100 | { 101 | _shoppingList.Data.Add(new List(new string[]{"item", "count"})); 102 | _listEntries.ForEach(x => _shoppingList.Data.Add(x)); 103 | } 104 | 105 | [Then(@"^the shopping list should look like:$")] 106 | public void TheShoppingListShouldLookLike(Table expectedShoppingList) 107 | { 108 | _shoppingList.AssertSameAs(expectedShoppingList); 109 | } 110 | } 111 | """ 112 | When I run cucumber -b -f progress features 113 | Then STDERR should be empty 114 | And it should pass with 115 | """ 116 | ..... 117 | 118 | 1 scenario (1 passed) 119 | 5 steps (5 passed) 120 | 121 | """ 122 | 123 | Scenario: Table in a Then - Failed Diff 124 | Given a file named "features/table.feature" with: 125 | """ 126 | Feature: Test Feature 127 | 128 | Scenario: Build a shopping list 129 | Given I need 3 cucumbers 130 | And I need 5 bananas 131 | And I need 2 tomatoes 132 | When I build my shopping list 133 | Then the shopping list should look like: 134 | | item | count | 135 | | cucumbers | 3 | 136 | | bananas | 5 | 137 | # | tomatoes | 2 | 138 | """ 139 | And Cuke4Nuke started with a step definition assembly containing: 140 | """ 141 | public class GeneratedSteps 142 | { 143 | Table _shoppingList = new Table(); 144 | List> _listEntries = new List>(); 145 | 146 | [Given(@"^I need (\d+) (.*)$")] 147 | public void INeedNItems(int count, string item) 148 | { 149 | _listEntries.Add(new List(new string[]{item, count.ToString()})); 150 | } 151 | 152 | [When(@"^I build my shopping list$")] 153 | public void IBuildMyShoppingList() 154 | { 155 | _shoppingList.Data.Add(new List(new string[]{"item", "count"})); 156 | _listEntries.ForEach(x => _shoppingList.Data.Add(x)); 157 | } 158 | 159 | [Then(@"^the shopping list should look like:$")] 160 | public void TheShoppingListShouldLookLike(Table expectedShoppingList) 161 | { 162 | _shoppingList.AssertSameAs(expectedShoppingList); 163 | } 164 | } 165 | """ 166 | When I run cucumber -f pretty features 167 | Then STDERR should be empty 168 | And it should fail -------------------------------------------------------------------------------- /features/wrapper.feature: -------------------------------------------------------------------------------- 1 | Feature: Run Cuke4Nuke and Cucumber from a single command 2 | 3 | Background: 4 | Given a standard Cucumber project directory structure 5 | And a file named "features/wired.feature" with: 6 | """ 7 | Feature: Test Feature 8 | 9 | Scenario: Wired 10 | Given we're all wired 11 | 12 | """ 13 | And a file named "features/step_definitions/some_remote_place.wire" with: 14 | """ 15 | host: localhost 16 | port: 3901 17 | 18 | """ 19 | 20 | Scenario: A passing step 21 | Given a step definition assembly containing: 22 | """ 23 | public class GeneratedSteps 24 | { 25 | [Given("^we're all wired$")] 26 | public static void AllWired() 27 | { 28 | } 29 | } 30 | """ 31 | When I run the cuke4nuke wrapper 32 | Then STDERR should be empty 33 | And it should pass with 34 | """ 35 | . 36 | 37 | 1 scenario (1 passed) 38 | 1 step (1 passed) 39 | 40 | """ 41 | 42 | Scenario: A failing step 43 | Given a step definition assembly containing: 44 | """ 45 | public class GeneratedSteps 46 | { 47 | [Given("^we're all wired$")] 48 | public static void AllWired() 49 | { 50 | throw new Exception("message"); 51 | } 52 | } 53 | """ 54 | When I run the cuke4nuke wrapper 55 | Then it should fail -------------------------------------------------------------------------------- /gem/Rakefile: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'rake' 3 | 4 | begin 5 | require 'jeweler' 6 | Jeweler::Tasks.new do |gem| 7 | gem.name = "cuke4nuke" 8 | gem.summary = %Q{Cucumber for .NET} 9 | gem.description = %Q{Runs Cucumber with .NET step definitions.} 10 | gem.email = "richard@humanizingwork.com" 11 | gem.homepage = "http://github.com/richardlawrence/Cuke4Nuke" 12 | gem.authors = ["Richard Lawrence"] 13 | gem.executables = ["cuke4nuke"] 14 | 15 | gem.add_dependency "cucumber", ">=0.5.2" 16 | gem.add_dependency "win32-process", ">=0.6.1" 17 | gem.add_dependency "json", ">=1.2.0" 18 | gem.add_dependency "win32console", ">=1.2.0" 19 | 20 | gem.files += FileList['dotnet/*.{dll,exe,config}'] 21 | gem.test_files = [] 22 | end 23 | Jeweler::GemcutterTasks.new 24 | rescue LoadError 25 | puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler" 26 | end 27 | 28 | task :gemspec => :copy_binaries 29 | 30 | desc "Copy Cuke4Nuke binaries to the dotnet directory" 31 | task :copy_binaries do 32 | Dir[File.dirname(__FILE__) + '/../Cuke4Nuke/Server/bin/Debug/*.{pdb,dll,exe,config}'].each do |file| 33 | cp file, 'dotnet' unless file =~ /vshost/ 34 | end 35 | end -------------------------------------------------------------------------------- /gem/VERSION: -------------------------------------------------------------------------------- 1 | 0.4.0 2 | -------------------------------------------------------------------------------- /gem/bin/cuke4nuke: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | $:.unshift(File.dirname(__FILE__) + '/../lib') unless $:.include?(File.dirname(__FILE__) + '/../lib') 3 | 4 | require 'cuke4nuke/main' 5 | 6 | Cuke4Nuke::Main.new.run(ARGV.dup) -------------------------------------------------------------------------------- /gem/cuke4nuke.gemspec: -------------------------------------------------------------------------------- 1 | # Generated by jeweler 2 | # DO NOT EDIT THIS FILE DIRECTLY 3 | # Instead, edit Jeweler::Tasks in rakefile, and run the gemspec command 4 | # -*- encoding: utf-8 -*- 5 | 6 | Gem::Specification.new do |s| 7 | s.name = %q{cuke4nuke} 8 | s.version = "0.4.0" 9 | 10 | s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= 11 | s.authors = ["Richard Lawrence"] 12 | s.date = %q{2010-11-03} 13 | s.default_executable = %q{cuke4nuke} 14 | s.description = %q{Runs Cucumber with .NET step definitions.} 15 | s.email = %q{richard@humanizingwork.com} 16 | s.executables = ["cuke4nuke"] 17 | s.files = [ 18 | "Rakefile", 19 | "VERSION", 20 | "bin/cuke4nuke", 21 | "cuke4nuke.gemspec", 22 | "dotnet/.gitignore", 23 | "dotnet/Castle.Core.dll", 24 | "dotnet/Castle.MicroKernel.dll", 25 | "dotnet/Cuke4Nuke.Core.dll", 26 | "dotnet/Cuke4Nuke.Framework.dll", 27 | "dotnet/Cuke4Nuke.Server.exe", 28 | "dotnet/Cuke4Nuke.Server.exe.config", 29 | "dotnet/Cuke4Nuke.TestStepDefinitions.dll", 30 | "dotnet/LitJson.dll", 31 | "dotnet/NDesk.Options.dll", 32 | "dotnet/Newtonsoft.Json.dll", 33 | "dotnet/log4net.dll", 34 | "lib/cuke4nuke/main.rb" 35 | ] 36 | s.homepage = %q{http://github.com/richardlawrence/Cuke4Nuke} 37 | s.rdoc_options = ["--charset=UTF-8"] 38 | s.require_paths = ["lib"] 39 | s.rubygems_version = %q{1.3.5} 40 | s.summary = %q{Cucumber for .NET} 41 | 42 | if s.respond_to? :specification_version then 43 | current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION 44 | s.specification_version = 3 45 | 46 | if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then 47 | s.add_runtime_dependency(%q, [">= 0.5.2"]) 48 | s.add_runtime_dependency(%q, [">= 0.6.1"]) 49 | s.add_runtime_dependency(%q, [">= 1.2.0"]) 50 | s.add_runtime_dependency(%q, [">= 1.2.0"]) 51 | else 52 | s.add_dependency(%q, [">= 0.5.2"]) 53 | s.add_dependency(%q, [">= 0.6.1"]) 54 | s.add_dependency(%q, [">= 1.2.0"]) 55 | s.add_dependency(%q, [">= 1.2.0"]) 56 | end 57 | else 58 | s.add_dependency(%q, [">= 0.5.2"]) 59 | s.add_dependency(%q, [">= 0.6.1"]) 60 | s.add_dependency(%q, [">= 1.2.0"]) 61 | s.add_dependency(%q, [">= 1.2.0"]) 62 | end 63 | end 64 | 65 | -------------------------------------------------------------------------------- /gem/dotnet/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll 2 | *.exe 3 | *.txt 4 | *.config 5 | *.pdb -------------------------------------------------------------------------------- /gem/lib/cuke4nuke/main.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'rubygems' 4 | require 'win32/process' 5 | 6 | module Cuke4Nuke 7 | class Main 8 | def run(args) 9 | if args.empty? || ['-h', '-?', '/?', '--help'].include?(args[0]) 10 | show_usage 11 | else 12 | step_definitions_dll_path = File.expand_path(args.shift) 13 | 14 | if !File.file?(step_definitions_dll_path) 15 | puts %{"#{step_definitions_dll_path}" is not a valid file path.\n\n} 16 | show_usage 17 | exit 1 18 | end 19 | 20 | launch_cuke4nuke_process(step_definitions_dll_path) 21 | 22 | @exit_status = 1 23 | begin 24 | cucumber_status = launch_cucumber(args) 25 | @exit_status = cucumber_status.exitstatus 26 | ensure 27 | kill_cuke4nuke_process 28 | end 29 | exit @exit_status 30 | end 31 | end 32 | 33 | def launch_cuke4nuke_process(step_definitions_dll_path) 34 | cuke4nuke_server_exe = File.expand_path(File.join(File.dirname(__FILE__), '../../dotnet/Cuke4Nuke.Server.exe')) 35 | command = %{"#{cuke4nuke_server_exe}" -a "#{step_definitions_dll_path}"} 36 | process = IO.popen(command, 'r') 37 | @cuke4nuke_server_pid = process.pid 38 | end 39 | 40 | def kill_cuke4nuke_process 41 | Process.kill(9, @cuke4nuke_server_pid) 42 | end 43 | 44 | def launch_cucumber(args) 45 | command = "cucumber #{args.join(' ')} 2>&1" 46 | system(command) 47 | $? 48 | end 49 | 50 | def show_usage 51 | puts "Usage: cuke4nuke STEP_DEFINITION_DLL_PATH [CUCUMBER_ARGUMENTS]\n\n" 52 | puts "The following is Cucumber's help. Anything after the cucumber command can be" 53 | puts "passed in the CUCUMBER_ARGUMENTS argument for cuke4nuke:\n\n" 54 | launch_cucumber(['--help']) 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /lib/code_template/C#_template.cs.erb: -------------------------------------------------------------------------------- 1 | namespace Cuke4Nuke.Framework.Languages.<%= language %> 2 | { 3 | <% keywords.each do |keyword| %> 4 | public class <%= keyword.strip %>Attribute : StepDefinitionAttribute 5 | { 6 | public <%= keyword.strip %>Attribute(string pattern): base(pattern) { } 7 | } 8 | <% end %> 9 | } 10 | -------------------------------------------------------------------------------- /lib/task/Cuke4NukeCodeGeneration.rake: -------------------------------------------------------------------------------- 1 | 2 | 3 | namespace :generate do 4 | desc "Generating cuke4nuke attributes for all i18n supported languages in Gherkin" 5 | task :attributes do 6 | require 'gherkin/i18n' 7 | require 'erb' 8 | 9 | csharp = ERB.new(IO.read(File.dirname(__FILE__) + '/../code_template/C#_template.cs.erb'), nil, '-') 10 | File.open('Cuke4Nuke/Framework/Languages/Steps.cs', 'wb') do |io| 11 | Gherkin::I18n.all.each do |i18n_language| 12 | language = i18n_language.sanitized_key.upcase 13 | keywords = i18n_language.gwt_keywords.reject{|kw| kw =~ /\*/ }.map do |key| 14 | key.gsub(/[ |']/, "") 15 | end 16 | 17 | io.write(csharp.result(binding)) 18 | end 19 | end 20 | 21 | end 22 | end 23 | --------------------------------------------------------------------------------
bin
PATH
19 | gem install cucumber json win32console --no-ri --no-rdoc 20 |
34 | ..\..\Cuke4Nuke\Server\bin\Release\Cuke4Nuke.Server.exe -a CalcFeatures\bin\Release\CalcFeatures.dll 35 |
42 | chcp 1252 43 |
51 | cucumber CalcFeatures\features 52 |
.feature
72 | igem install cucumber rspec --no-ri --no-rdoc 73 |
78 | copy C:\ironruby-0.9.1\lib\IronRuby\gems\1.8\bin\cucumber C:\ironruby-0.9.1\bin\icucumber 79 | copy C:\ironruby-0.9.1\lib\IronRuby\gems\1.8\bin\cucumber.bat C:\ironruby-0.9.1\bin\icucumber.bat 80 |
100 | icucumber CalcFeatures\features | wac 101 |