diff --git a/Generator/TechTalk.SpecFlow.Generator.csproj b/Generator/TechTalk.SpecFlow.Generator.csproj index 9e91a1bdd..70701ee13 100644 --- a/Generator/TechTalk.SpecFlow.Generator.csproj +++ b/Generator/TechTalk.SpecFlow.Generator.csproj @@ -49,9 +49,18 @@ + + Configuration\ConfigDefaults.cs + Configuration\ConfigurationSectionHandler.cs + + Configuration\ConfigurationServices.cs + + + Configuration\MissingOrPendingStepsOutcome.cs + StringExtensions.cs diff --git a/Runtime.Silverlight/Compatibility/ConfigurationErrorsException.cs b/Runtime.Silverlight/Compatibility/ConfigurationErrorsException.cs new file mode 100644 index 000000000..b296ca49f --- /dev/null +++ b/Runtime.Silverlight/Compatibility/ConfigurationErrorsException.cs @@ -0,0 +1,23 @@ +using System; +using System.Net; +using System.Runtime.Serialization; + + +namespace System.Configuration +{ + public class ConfigurationErrorsException : Exception + { + public ConfigurationErrorsException() + { + } + + public ConfigurationErrorsException(string message) : base(message) + { + } + + public ConfigurationErrorsException(string message, Exception inner) + : base(message, inner) + { + } + } +} diff --git a/Runtime.Silverlight/Compatibility/CultureInfoHelper.cs b/Runtime.Silverlight/Compatibility/CultureInfoHelper.cs new file mode 100644 index 000000000..c0cdf0aea --- /dev/null +++ b/Runtime.Silverlight/Compatibility/CultureInfoHelper.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; + +namespace TechTalk.SpecFlow.Compatibility +{ + internal static class CultureInfoHelper + { + public static CultureInfo GetCultureInfo(string cultureName) + { + return new CultureInfo(cultureName); + } + } +} diff --git a/Runtime.Silverlight/Compatibility/EnumHelper.cs b/Runtime.Silverlight/Compatibility/EnumHelper.cs new file mode 100644 index 000000000..2005e6c08 --- /dev/null +++ b/Runtime.Silverlight/Compatibility/EnumHelper.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace TechTalk.SpecFlow.Compatibility +{ + internal static class EnumHelper + { + public static Array GetValues(Type enumType) + { + if (!enumType.IsEnum) + { + throw new ArgumentException("Type '" + enumType.Name + "' is not an enum"); + } + + var values = new List(); + + var fields = from field in enumType.GetFields() + where field.IsLiteral + select field; + + foreach (FieldInfo field in fields) + { + object value = field.GetValue(enumType); + values.Add(value); + } + + return values.ToArray(); + } + } +} diff --git a/Runtime.Silverlight/Compatibility/Stopwatch.cs b/Runtime.Silverlight/Compatibility/Stopwatch.cs new file mode 100644 index 000000000..e1042c112 --- /dev/null +++ b/Runtime.Silverlight/Compatibility/Stopwatch.cs @@ -0,0 +1,113 @@ +using System; + +namespace System.Diagnostics +{ + /// + /// Stopwatch is used to measure the general performance of Silverlight functionality. Silverlight + /// does not currently provide a high resolution timer as is available in many operating systems, + /// so the resolution of this timer is limited to milliseconds. This class is best used to measure + /// the relative performance of functions over many iterations. + /// + public sealed class Stopwatch + { + private long _startTick; + private long _elapsed; + private bool _isRunning; + + /// + /// Creates a new instance of the class and starts the watch immediately. + /// + /// An instance of Stopwatch, running. + public static Stopwatch StartNew() + { + Stopwatch sw = new Stopwatch(); + sw.Start(); + return sw; + } + + /// + /// Creates an instance of the Stopwatch class. + /// + public Stopwatch() { } + + /// + /// Completely resets and deactivates the timer. + /// + public void Reset() + { + _elapsed = 0; + _isRunning = false; + _startTick = 0; + } + + /// + /// Begins the timer. + /// + public void Start() + { + if (!_isRunning) + { + _startTick = GetCurrentTicks(); + _isRunning = true; + } + } + + /// + /// Stops the current timer. + /// + public void Stop() + { + if (_isRunning) + { + _elapsed += GetCurrentTicks() - _startTick; + _isRunning = false; + } + } + + /// + /// Gets a value indicating whether the instance is currently recording. + /// + public bool IsRunning + { + get { return _isRunning; } + } + + /// + /// Gets the Elapsed time as a Timespan. + /// + public TimeSpan Elapsed + { + get { return TimeSpan.FromMilliseconds(ElapsedMilliseconds); } + } + + /// + /// Gets the Elapsed time as the total number of milliseconds. + /// + public long ElapsedMilliseconds + { + get { return GetCurrentElapsedTicks() / TimeSpan.TicksPerMillisecond; } + } + + /// + /// Gets the Elapsed time as the total number of ticks (which is faked + /// as Silverlight doesn't have a way to get at the actual "Ticks") + /// + public long ElapsedTicks + { + get { return GetCurrentElapsedTicks(); } + } + + private long GetCurrentElapsedTicks() + { + return (long)(this._elapsed + (IsRunning ? (GetCurrentTicks() - _startTick) : 0)); + } + + private long GetCurrentTicks() + { + // TickCount: Gets the number of milliseconds elapsed since the system started. + return Environment.TickCount * TimeSpan.TicksPerMillisecond; + } + } + +} + diff --git a/Runtime.Silverlight/Configuration/ConfigDefaults.cs b/Runtime.Silverlight/Configuration/ConfigDefaults.cs new file mode 100644 index 000000000..523ebaf7c --- /dev/null +++ b/Runtime.Silverlight/Configuration/ConfigDefaults.cs @@ -0,0 +1,20 @@ +namespace TechTalk.SpecFlow.Configuration +{ + public static class ConfigDefaults + { + internal const string FeatureLanguage = "en-US"; + internal const string ToolLanguage = ""; + + internal const string UnitTestProviderName = "MSTestSilverlight"; + + internal const bool DetectAmbiguousMatches = true; + internal const bool StopAtFirstError = false; + internal const MissingOrPendingStepsOutcome MissingOrPendingStepsOutcome = TechTalk.SpecFlow.Configuration.MissingOrPendingStepsOutcome.Inconclusive; + + internal const bool TraceSuccessfulSteps = true; + internal const bool TraceTimings = false; + internal const string MinTracedDuration = "0:0:0.1"; + + internal const bool AllowDebugGeneratedFiles = false; + } +} \ No newline at end of file diff --git a/Runtime.Silverlight/Properties/AssemblyInfo.cs b/Runtime.Silverlight/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..9da5cad6a --- /dev/null +++ b/Runtime.Silverlight/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("TechTalk.SpecFlow.Silverlight")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("TechTalk.SpecFlow.Silverlight")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2010")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("04dec58a-9677-4f58-ae8b-4744bbffb9a9")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Runtime.Silverlight/TechTalk.SpecFlow.Silverlight.csproj b/Runtime.Silverlight/TechTalk.SpecFlow.Silverlight.csproj new file mode 100644 index 000000000..2ac937e87 --- /dev/null +++ b/Runtime.Silverlight/TechTalk.SpecFlow.Silverlight.csproj @@ -0,0 +1,209 @@ + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {B93F95CF-BF89-4D92-BB0F-86885B9B6DCE} + {A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + TechTalk.SpecFlow + TechTalk.SpecFlow.Silverlight + v3.5 + false + true + true + + + true + full + false + Bin\Debug + DEBUG;TRACE;SILVERLIGHT + true + true + prompt + 4 + + + pdbonly + true + Bin\Release + TRACE;SILVERLIGHT + true + true + prompt + 4 + + + + + + + + + + + + + Attributes.cs + + + Bindings\BindingMatch.cs + + + Bindings\BindingRegistry.cs + + + Bindings\BindingType.cs + + + Bindings\EventBinding.cs + + + Bindings\StepArgs.cs + + + Bindings\StepArgumentTypeConverter.cs + + + Bindings\StepBinding.cs + + + Bindings\StepDefinitionKeyword.cs + + + Bindings\StepMethodBinding.cs + + + Bindings\StepTransformationBinding.cs + + + Configuration\ConfigurationServices.cs + + + Configuration\MissingOrPendingStepsOutcome.cs + + + Configuration\RuntimeConfiguration.cs + + + CultureInfoScope.cs + + + ErrorHandling\BindingException.cs + + + ErrorHandling\ErrorProvider.cs + + + ErrorHandling\MissingStepDefinitionException.cs + + + ErrorHandling\PendingStepException.cs + + + ErrorHandling\SpecFlowException.cs + + + FeatureContext.cs + + + FeatureInfo.cs + + + ITestRunner.cs + + + ObjectContainer.cs + + + ScenarioBlock.cs + + + ScenarioContext.cs + + + ScenarioInfo.cs + + + SpecFlowContext.cs + + + Steps.cs + + + StringExtensions.cs + + + Table.cs + + + TestRunner.cs + + + Tracing\DefaultListener.cs + + + Tracing\ITraceListener.cs + + + Tracing\LanguageHelper.cs + + + Tracing\NullListener.cs + + + Tracing\StepDefinitonSkeletonProvider.cs + + + Tracing\StepFormatter.cs + + + Tracing\TestTracer.cs + + + UnitTestProvider\IUnitTestRuntimeProvider.cs + + + UnitTestProvider\MbUnitRuntimeProvider.cs + + + UnitTestProvider\MsTestRuntimeProvider.cs + + + UnitTestProvider\NUnitRuntimeProvider.cs + + + UnitTestProvider\XUnitRuntimeProvider.cs + + + + + + + + + + + + Languages.xml + + + + + + + + + + + + \ No newline at end of file diff --git a/Runtime.Silverlight/UnitTestProvider/MsTestSilverlightRuntimeProvider.cs b/Runtime.Silverlight/UnitTestProvider/MsTestSilverlightRuntimeProvider.cs new file mode 100644 index 000000000..6fa4f9a75 --- /dev/null +++ b/Runtime.Silverlight/UnitTestProvider/MsTestSilverlightRuntimeProvider.cs @@ -0,0 +1,16 @@ + +namespace TechTalk.SpecFlow.UnitTestProvider +{ + public class MsTestSilverlightRuntimeProvider : MsTestRuntimeProvider + { + private const string MSTEST_ASSEMBLY = "Microsoft.VisualStudio.QualityTools.UnitTesting.Silverlight, Version=2.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; + + public override string AssemblyName + { + get + { + return MSTEST_ASSEMBLY; + } + } + } +} diff --git a/Runtime/Bindings/StepBinding.cs b/Runtime/Bindings/StepBinding.cs index caae3c71f..6315d4be9 100644 --- a/Runtime/Bindings/StepBinding.cs +++ b/Runtime/Bindings/StepBinding.cs @@ -8,12 +8,20 @@ public class StepBinding : MethodBinding public BindingType Type { get; private set; } public Regex Regex { get; private set; } +#if SILVERLIGHT + private static RegexOptions RegexOptions = RegexOptions.CultureInvariant; +#else + private static RegexOptions RegexOptions = RegexOptions.Compiled | RegexOptions.CultureInvariant; +#endif + public StepBinding(BindingType type, string regexString, MethodInfo methodInfo) : base(methodInfo) { Type = type; - Regex regex = new Regex("^" + regexString + "$", RegexOptions.Compiled | RegexOptions.CultureInvariant); + Regex regex = new Regex("^" + regexString + "$", RegexOptions); Regex = regex; } + + } } \ No newline at end of file diff --git a/Runtime/Bindings/StepMethodBinding.cs b/Runtime/Bindings/StepMethodBinding.cs index 309ffa535..b13538fc4 100644 --- a/Runtime/Bindings/StepMethodBinding.cs +++ b/Runtime/Bindings/StepMethodBinding.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; +using TechTalk.SpecFlow.Compatibility; using TechTalk.SpecFlow.Configuration; using TechTalk.SpecFlow.ErrorHandling; using TechTalk.SpecFlow.Tracing; diff --git a/Runtime/Bindings/StepTransformationBinding.cs b/Runtime/Bindings/StepTransformationBinding.cs index 7ffaa88e3..5108e74b1 100644 --- a/Runtime/Bindings/StepTransformationBinding.cs +++ b/Runtime/Bindings/StepTransformationBinding.cs @@ -8,12 +8,19 @@ namespace TechTalk.SpecFlow.Bindings { public class StepTransformationBinding : MethodBinding { + +#if SILVERLIGHT + private static RegexOptions RegexOptions = RegexOptions.CultureInvariant; +#else + private static RegexOptions RegexOptions = RegexOptions.Compiled | RegexOptions.CultureInvariant; +#endif + public Regex Regex { get; private set; } public StepTransformationBinding(string regexString, MethodInfo methodInfo) : base(methodInfo) { - Regex regex = new Regex("^" + regexString + "$", RegexOptions.Compiled | RegexOptions.CultureInvariant); + Regex regex = new Regex("^" + regexString + "$", RegexOptions); Regex = regex; } diff --git a/Runtime/Compatibility/CultureInfoHelper.cs b/Runtime/Compatibility/CultureInfoHelper.cs new file mode 100644 index 000000000..748611506 --- /dev/null +++ b/Runtime/Compatibility/CultureInfoHelper.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; + +namespace TechTalk.SpecFlow.Compatibility +{ + internal static class CultureInfoHelper + { + public static CultureInfo GetCultureInfo(string cultureName) + { + return CultureInfo.GetCultureInfo(cultureName); + } + } +} diff --git a/Runtime/Compatibility/EnumHelper.cs b/Runtime/Compatibility/EnumHelper.cs new file mode 100644 index 000000000..b0bfc271d --- /dev/null +++ b/Runtime/Compatibility/EnumHelper.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace TechTalk.SpecFlow.Compatibility +{ + internal static class EnumHelper + { + public static Array GetValues(Type type) + { + return Enum.GetValues(type); + } + } +} diff --git a/Runtime/Configuration/ConfigDefaults.cs b/Runtime/Configuration/ConfigDefaults.cs new file mode 100644 index 000000000..ee5c2f327 --- /dev/null +++ b/Runtime/Configuration/ConfigDefaults.cs @@ -0,0 +1,20 @@ +namespace TechTalk.SpecFlow.Configuration +{ + public static class ConfigDefaults + { + internal const string FeatureLanguage = "en-US"; + internal const string ToolLanguage = ""; + + internal const string UnitTestProviderName = "NUnit"; + + internal const bool DetectAmbiguousMatches = true; + internal const bool StopAtFirstError = false; + internal const MissingOrPendingStepsOutcome MissingOrPendingStepsOutcome = TechTalk.SpecFlow.Configuration.MissingOrPendingStepsOutcome.Inconclusive; + + internal const bool TraceSuccessfulSteps = true; + internal const bool TraceTimings = false; + internal const string MinTracedDuration = "0:0:0.1"; + + internal const bool AllowDebugGeneratedFiles = false; + } +} \ No newline at end of file diff --git a/Runtime/Configuration/ConfigurationSectionHandler.cs b/Runtime/Configuration/ConfigurationSectionHandler.cs index aa1892fea..717c7eab2 100644 --- a/Runtime/Configuration/ConfigurationSectionHandler.cs +++ b/Runtime/Configuration/ConfigurationSectionHandler.cs @@ -7,77 +7,6 @@ namespace TechTalk.SpecFlow.Configuration { - public enum MissingOrPendingStepsOutcome - { - Inconclusive, - Ignore, - Error - } - - public static class ConfigDefaults - { - internal const string FeatureLanguage = "en-US"; - internal const string ToolLanguage = ""; - - internal const string UnitTestProviderName = "NUnit"; - - internal const bool DetectAmbiguousMatches = true; - internal const bool StopAtFirstError = false; - internal const MissingOrPendingStepsOutcome MissingOrPendingStepsOutcome = TechTalk.SpecFlow.Configuration.MissingOrPendingStepsOutcome.Inconclusive; - - internal const bool TraceSuccessfulSteps = true; - internal const bool TraceTimings = false; - internal const string MinTracedDuration = "0:0:0.1"; - - internal const bool AllowDebugGeneratedFiles = false; - } - - public static class ConfigurationServices - { - public static TInterface CreateInstance(Type type) - { - // do not use ErrorProvider for thowing exceptions here, because of the potential - // infinite loop - try - { - return (TInterface)Activator.CreateInstance(type); - } - catch (InvalidCastException) - { - throw new ConfigurationErrorsException( - String.Format("The specified type '{0}' does not implement interface '{1}'", - type.FullName, typeof(TInterface).FullName)); - } - catch (Exception ex) - { - throw new ConfigurationErrorsException( - String.Format("Unable to create instance of type '{0}': {1}", - type.FullName, ex.Message), ex); - } - } - public static TInterface CreateInstance(Type type, params object[] arguments) - { - // do not use ErrorProvider for thowing exceptions here, because of the potential - // infinite loop - try - { - return (TInterface)Activator.CreateInstance(type, arguments); - } - catch (InvalidCastException) - { - throw new ConfigurationErrorsException( - String.Format("The specified type '{0}' does not implement interface '{1}'", - type.FullName, typeof(TInterface).FullName)); - } - catch (Exception ex) - { - throw new ConfigurationErrorsException( - String.Format("Unable to create instance of type '{0}': {1}", - type.FullName, ex.Message), ex); - } - } - } - partial class ConfigurationSectionHandler : ConfigurationSection { [ConfigurationProperty("language", IsRequired = false)] diff --git a/Runtime/Configuration/ConfigurationServices.cs b/Runtime/Configuration/ConfigurationServices.cs new file mode 100644 index 000000000..2efb5e110 --- /dev/null +++ b/Runtime/Configuration/ConfigurationServices.cs @@ -0,0 +1,51 @@ +using System; +using System.Configuration; + +namespace TechTalk.SpecFlow.Configuration +{ + public static class ConfigurationServices + { + public static TInterface CreateInstance(Type type) + { + // do not use ErrorProvider for thowing exceptions here, because of the potential + // infinite loop + try + { + return (TInterface)Activator.CreateInstance(type); + } + catch (InvalidCastException) + { + throw new ConfigurationErrorsException( + String.Format("The specified type '{0}' does not implement interface '{1}'", + type.FullName, typeof(TInterface).FullName)); + } + catch (Exception ex) + { + throw new ConfigurationErrorsException( + String.Format("Unable to create instance of type '{0}': {1}", + type.FullName, ex.Message), ex); + } + } + public static TInterface CreateInstance(Type type, params object[] arguments) + { + // do not use ErrorProvider for thowing exceptions here, because of the potential + // infinite loop + try + { + return (TInterface)Activator.CreateInstance(type, arguments); + } + catch (InvalidCastException) + { + throw new ConfigurationErrorsException( + String.Format("The specified type '{0}' does not implement interface '{1}'", + type.FullName, typeof(TInterface).FullName)); + } + catch (Exception ex) + { + throw new ConfigurationErrorsException( + String.Format("Unable to create instance of type '{0}': {1}", + type.FullName, ex.Message), ex); + } + } + } +} \ No newline at end of file diff --git a/Runtime/Configuration/MissingOrPendingStepsOutcome.cs b/Runtime/Configuration/MissingOrPendingStepsOutcome.cs new file mode 100644 index 000000000..bd27235eb --- /dev/null +++ b/Runtime/Configuration/MissingOrPendingStepsOutcome.cs @@ -0,0 +1,9 @@ +namespace TechTalk.SpecFlow.Configuration +{ + public enum MissingOrPendingStepsOutcome + { + Inconclusive, + Ignore, + Error + } +} \ No newline at end of file diff --git a/Runtime/Configuration/RuntimeConfiguration.cs b/Runtime/Configuration/RuntimeConfiguration.cs index a82f3b70e..c5089ed32 100644 --- a/Runtime/Configuration/RuntimeConfiguration.cs +++ b/Runtime/Configuration/RuntimeConfiguration.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Reflection; +using TechTalk.SpecFlow.Compatibility; using TechTalk.SpecFlow.Tracing; using TechTalk.SpecFlow.UnitTestProvider; @@ -53,8 +54,8 @@ public IEnumerable AdditionalStepAssemblies public RuntimeConfiguration() { ToolLanguage = string.IsNullOrEmpty(ConfigDefaults.ToolLanguage) ? - CultureInfo.GetCultureInfo(ConfigDefaults.FeatureLanguage) : - CultureInfo.GetCultureInfo(ConfigDefaults.ToolLanguage); + CultureInfoHelper.GetCultureInfo(ConfigDefaults.FeatureLanguage) : + CultureInfoHelper.GetCultureInfo(ConfigDefaults.ToolLanguage); SetUnitTestDefaultsByName(ConfigDefaults.UnitTestProviderName); @@ -68,6 +69,7 @@ public RuntimeConfiguration() MinTracedDuration = TimeSpan.Parse(ConfigDefaults.MinTracedDuration); } +#if !SILVERLIGHT public static RuntimeConfiguration LoadFromConfigFile() { var section = (ConfigurationSectionHandler)ConfigurationManager.GetSection("specFlow"); @@ -138,11 +140,12 @@ private static Type GetTypeConfig(string typeName) typeName, ex.Message), ex); } } - +#endif private void SetUnitTestDefaultsByName(string name) { - switch (name.ToLowerInvariant()) + switch (name.ToLower()) { +#if !SILVERLIGHT case "nunit": RuntimeUnitTestProviderType = typeof(NUnitRuntimeProvider); break; @@ -155,11 +158,22 @@ private void SetUnitTestDefaultsByName(string name) case "mstest": RuntimeUnitTestProviderType = typeof(MsTestRuntimeProvider); break; +#else + case "mstestsilverlight": + RuntimeUnitTestProviderType = typeof (MsTestSilverlightRuntimeProvider); + break; +#endif default: RuntimeUnitTestProviderType = null; break; } + } +#if SILVERLIGHT + internal static RuntimeConfiguration CreateForSilverlight() + { + return new RuntimeConfiguration(); } +#endif } } \ No newline at end of file diff --git a/Runtime/ErrorHandling/BindingException.cs b/Runtime/ErrorHandling/BindingException.cs index fe29aa33b..681e014cb 100644 --- a/Runtime/ErrorHandling/BindingException.cs +++ b/Runtime/ErrorHandling/BindingException.cs @@ -5,7 +5,10 @@ // the exceptions are part of the public API, keep them in TechTalk.SpecFlow namespace namespace TechTalk.SpecFlow { +#if !SILVERLIGHT [Serializable] +#endif + public class BindingException : SpecFlowException { public BindingException() @@ -20,10 +23,13 @@ public BindingException(string message, Exception inner) : base(message, inner) { } +#if !SILVERLIGHT protected BindingException( SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif + } } \ No newline at end of file diff --git a/Runtime/ErrorHandling/MissingStepDefinitionException.cs b/Runtime/ErrorHandling/MissingStepDefinitionException.cs index a05b9d244..03affaa66 100644 --- a/Runtime/ErrorHandling/MissingStepDefinitionException.cs +++ b/Runtime/ErrorHandling/MissingStepDefinitionException.cs @@ -5,7 +5,9 @@ // the exceptions are part of the public API, keep them in TechTalk.SpecFlow namespace namespace TechTalk.SpecFlow { +#if !SILVERLIGHT [Serializable] +#endif public class MissingStepDefinitionException : SpecFlowException { public MissingStepDefinitionException() @@ -13,10 +15,14 @@ public MissingStepDefinitionException() { } +#if !SILVERLIGHT protected MissingStepDefinitionException( SerializationInfo info, - StreamingContext context) : base(info, context) + StreamingContext context) + : base(info, context) { } +#endif + } } \ No newline at end of file diff --git a/Runtime/ErrorHandling/PendingStepException.cs b/Runtime/ErrorHandling/PendingStepException.cs index b061cba02..48d6c38d3 100644 --- a/Runtime/ErrorHandling/PendingStepException.cs +++ b/Runtime/ErrorHandling/PendingStepException.cs @@ -5,7 +5,9 @@ // the exceptions are part of the public API, keep them in TechTalk.SpecFlow namespace namespace TechTalk.SpecFlow { +#if !SILVERLIGHT [Serializable] +#endif public class PendingStepException : SpecFlowException { public PendingStepException() @@ -13,10 +15,12 @@ public PendingStepException() { } +#if !SILVERLIGHT protected PendingStepException( SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif } } \ No newline at end of file diff --git a/Runtime/ErrorHandling/SpecFlowException.cs b/Runtime/ErrorHandling/SpecFlowException.cs index fa2e7665e..22b0ed9fe 100644 --- a/Runtime/ErrorHandling/SpecFlowException.cs +++ b/Runtime/ErrorHandling/SpecFlowException.cs @@ -5,7 +5,9 @@ // the exceptions are part of the public API, keep them in TechTalk.SpecFlow namespace namespace TechTalk.SpecFlow { +#if !SILVERLIGHT [Serializable] +#endif public class SpecFlowException : Exception { public SpecFlowException() @@ -20,10 +22,12 @@ public SpecFlowException(string message, Exception inner) : base(message, inner) { } +#if !SILVERLIGHT protected SpecFlowException( SerializationInfo info, StreamingContext context) : base(info, context) { } +#endif } } \ No newline at end of file diff --git a/Runtime/FeatureContext.cs b/Runtime/FeatureContext.cs index 341de5e5b..655933cf2 100644 --- a/Runtime/FeatureContext.cs +++ b/Runtime/FeatureContext.cs @@ -2,6 +2,10 @@ using System.Diagnostics; using System.Linq; +#if SILVERLIGHT +using TechTalk.SpecFlow.Compatibility; +#endif + namespace TechTalk.SpecFlow { public class FeatureContext : SpecFlowContext diff --git a/Runtime/ObjectContainer.cs b/Runtime/ObjectContainer.cs index 35c8b243f..8815a6164 100644 --- a/Runtime/ObjectContainer.cs +++ b/Runtime/ObjectContainer.cs @@ -28,9 +28,21 @@ public static RuntimeConfiguration Configuration { get { - return GetOrCreate(ref configuration, RuntimeConfiguration.LoadFromConfigFile); + return GetOrCreate(ref configuration, GetConfiguration); } } + +#if SILVERLIGHT + private static RuntimeConfiguration GetConfiguration() + { + return RuntimeConfiguration.CreateForSilverlight(); + } +#else + private static RuntimeConfiguration GetConfiguration() + { + return RuntimeConfiguration.LoadFromConfigFile(); + } +#endif #endregion #region TestRunner diff --git a/Runtime/ScenarioContext.cs b/Runtime/ScenarioContext.cs index fb81d21ce..0dfbf1d2d 100644 --- a/Runtime/ScenarioContext.cs +++ b/Runtime/ScenarioContext.cs @@ -3,6 +3,10 @@ using System.Diagnostics; using System.Linq; +#if SILVERLIGHT +using TechTalk.SpecFlow.Compatibility; +#endif + namespace TechTalk.SpecFlow { internal enum TestStatus diff --git a/Runtime/TechTalk.SpecFlow.csproj b/Runtime/TechTalk.SpecFlow.csproj index 697d17ac9..a3bf1aeff 100644 --- a/Runtime/TechTalk.SpecFlow.csproj +++ b/Runtime/TechTalk.SpecFlow.csproj @@ -53,6 +53,11 @@ + + + + + diff --git a/Runtime/TestRunner.cs b/Runtime/TestRunner.cs index 019a321cc..63b5195c5 100644 --- a/Runtime/TestRunner.cs +++ b/Runtime/TestRunner.cs @@ -43,11 +43,14 @@ public virtual void InitializeTestRunner(Assembly[] bindingAssemblies) } OnTestRunnerStart(); +#if !SILVERLIGHT AppDomain.CurrentDomain.DomainUnload += delegate { OnTestRunnerEnd(); }; + //TODO: Siverlight +#endif } protected virtual void OnTestRunnerStart() diff --git a/Runtime/Tracing/LanguageHelper.cs b/Runtime/Tracing/LanguageHelper.cs index 732944873..9f7c7cf44 100644 --- a/Runtime/Tracing/LanguageHelper.cs +++ b/Runtime/Tracing/LanguageHelper.cs @@ -7,6 +7,8 @@ using System.Text; using System.Xml.Linq; using TechTalk.SpecFlow.Bindings; +using TechTalk.SpecFlow.Compatibility; + namespace TechTalk.SpecFlow.Tracing { @@ -53,7 +55,8 @@ static public CultureInfo GetSpecificCultureInfo(CultureInfo language) private static KeywordTranslation LoadTranslation(CultureInfo language) { - var docStream = typeof(LanguageHelper).Assembly.GetManifestResourceStream("TechTalk.SpecFlow.Languages.xml"); + var assembly = typeof(LanguageHelper).Assembly; + var docStream = assembly.GetManifestResourceStream("TechTalk.SpecFlow.Languages.xml"); if (docStream == null) throw new InvalidOperationException("Language resource not found."); @@ -71,16 +74,16 @@ private static KeywordTranslation LoadTranslation(CultureInfo language) { var defaultSpecificCultureAttr = langElm.Attribute(XName.Get("defaultSpecificCulture", "")); if (defaultSpecificCultureAttr == null) - result.DefaultSpecificCulture = CultureInfo.GetCultureInfo("en-US"); + result.DefaultSpecificCulture = CultureInfoHelper.GetCultureInfo("en-US"); else - result.DefaultSpecificCulture = CultureInfo.GetCultureInfo(defaultSpecificCultureAttr.Value); + result.DefaultSpecificCulture = CultureInfoHelper.GetCultureInfo(defaultSpecificCultureAttr.Value); } else { result.DefaultSpecificCulture = language; } - foreach (StepDefinitionKeyword keyword in Enum.GetValues(typeof(StepDefinitionKeyword))) + foreach (StepDefinitionKeyword keyword in EnumHelper.GetValues(typeof (StepDefinitionKeyword))) { //NOTE: we only load the first translation of each keyword XElement keywordElm = langElm.Element(keyword.ToString()); diff --git a/Runtime/UnitTestProvider/MsTestRuntimeProvider.cs b/Runtime/UnitTestProvider/MsTestRuntimeProvider.cs index e6ed05f9f..86bc1c620 100644 --- a/Runtime/UnitTestProvider/MsTestRuntimeProvider.cs +++ b/Runtime/UnitTestProvider/MsTestRuntimeProvider.cs @@ -36,15 +36,21 @@ public static Action GetAssertMethod(string assemblyName, string typeNam public class MsTestRuntimeProvider : IUnitTestRuntimeProvider { private const string MSTEST_ASSEMBLY = "Microsoft.VisualStudio.QualityTools.UnitTestFramework"; + private const string ASSERT_TYPE = "Microsoft.VisualStudio.TestTools.UnitTesting.Assert"; Action assertInconclusive = null; + + public virtual string AssemblyName + { + get { return MSTEST_ASSEMBLY; } + } public void TestInconclusive(string message) { if (assertInconclusive == null) { - assertInconclusive = UnitTestRuntimeProviderHelper.GetAssertMethod(MSTEST_ASSEMBLY, ASSERT_TYPE, "Inconclusive"); + assertInconclusive = UnitTestRuntimeProviderHelper.GetAssertMethod(AssemblyName, ASSERT_TYPE, "Inconclusive"); } assertInconclusive(message); @@ -59,5 +65,7 @@ public bool DelayedFixtureTearDown { get { return true; } } + + } } \ No newline at end of file diff --git a/TechTalk.SpecFlow.Silverlight/Compatibility/ConfigurationErrorsException.cs b/TechTalk.SpecFlow.Silverlight/Compatibility/ConfigurationErrorsException.cs new file mode 100644 index 000000000..b296ca49f --- /dev/null +++ b/TechTalk.SpecFlow.Silverlight/Compatibility/ConfigurationErrorsException.cs @@ -0,0 +1,23 @@ +using System; +using System.Net; +using System.Runtime.Serialization; + + +namespace System.Configuration +{ + public class ConfigurationErrorsException : Exception + { + public ConfigurationErrorsException() + { + } + + public ConfigurationErrorsException(string message) : base(message) + { + } + + public ConfigurationErrorsException(string message, Exception inner) + : base(message, inner) + { + } + } +} diff --git a/TechTalk.SpecFlow.Silverlight/Compatibility/CultureInfoHelper.cs b/TechTalk.SpecFlow.Silverlight/Compatibility/CultureInfoHelper.cs new file mode 100644 index 000000000..c0cdf0aea --- /dev/null +++ b/TechTalk.SpecFlow.Silverlight/Compatibility/CultureInfoHelper.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; + +namespace TechTalk.SpecFlow.Compatibility +{ + internal static class CultureInfoHelper + { + public static CultureInfo GetCultureInfo(string cultureName) + { + return new CultureInfo(cultureName); + } + } +} diff --git a/TechTalk.SpecFlow.Silverlight/Compatibility/EnumHelper.cs b/TechTalk.SpecFlow.Silverlight/Compatibility/EnumHelper.cs new file mode 100644 index 000000000..2005e6c08 --- /dev/null +++ b/TechTalk.SpecFlow.Silverlight/Compatibility/EnumHelper.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace TechTalk.SpecFlow.Compatibility +{ + internal static class EnumHelper + { + public static Array GetValues(Type enumType) + { + if (!enumType.IsEnum) + { + throw new ArgumentException("Type '" + enumType.Name + "' is not an enum"); + } + + var values = new List(); + + var fields = from field in enumType.GetFields() + where field.IsLiteral + select field; + + foreach (FieldInfo field in fields) + { + object value = field.GetValue(enumType); + values.Add(value); + } + + return values.ToArray(); + } + } +} diff --git a/TechTalk.SpecFlow.Silverlight/Compatibility/Stopwatch.cs b/TechTalk.SpecFlow.Silverlight/Compatibility/Stopwatch.cs new file mode 100644 index 000000000..e1042c112 --- /dev/null +++ b/TechTalk.SpecFlow.Silverlight/Compatibility/Stopwatch.cs @@ -0,0 +1,113 @@ +using System; + +namespace System.Diagnostics +{ + /// + /// Stopwatch is used to measure the general performance of Silverlight functionality. Silverlight + /// does not currently provide a high resolution timer as is available in many operating systems, + /// so the resolution of this timer is limited to milliseconds. This class is best used to measure + /// the relative performance of functions over many iterations. + /// + public sealed class Stopwatch + { + private long _startTick; + private long _elapsed; + private bool _isRunning; + + /// + /// Creates a new instance of the class and starts the watch immediately. + /// + /// An instance of Stopwatch, running. + public static Stopwatch StartNew() + { + Stopwatch sw = new Stopwatch(); + sw.Start(); + return sw; + } + + /// + /// Creates an instance of the Stopwatch class. + /// + public Stopwatch() { } + + /// + /// Completely resets and deactivates the timer. + /// + public void Reset() + { + _elapsed = 0; + _isRunning = false; + _startTick = 0; + } + + /// + /// Begins the timer. + /// + public void Start() + { + if (!_isRunning) + { + _startTick = GetCurrentTicks(); + _isRunning = true; + } + } + + /// + /// Stops the current timer. + /// + public void Stop() + { + if (_isRunning) + { + _elapsed += GetCurrentTicks() - _startTick; + _isRunning = false; + } + } + + /// + /// Gets a value indicating whether the instance is currently recording. + /// + public bool IsRunning + { + get { return _isRunning; } + } + + /// + /// Gets the Elapsed time as a Timespan. + /// + public TimeSpan Elapsed + { + get { return TimeSpan.FromMilliseconds(ElapsedMilliseconds); } + } + + /// + /// Gets the Elapsed time as the total number of milliseconds. + /// + public long ElapsedMilliseconds + { + get { return GetCurrentElapsedTicks() / TimeSpan.TicksPerMillisecond; } + } + + /// + /// Gets the Elapsed time as the total number of ticks (which is faked + /// as Silverlight doesn't have a way to get at the actual "Ticks") + /// + public long ElapsedTicks + { + get { return GetCurrentElapsedTicks(); } + } + + private long GetCurrentElapsedTicks() + { + return (long)(this._elapsed + (IsRunning ? (GetCurrentTicks() - _startTick) : 0)); + } + + private long GetCurrentTicks() + { + // TickCount: Gets the number of milliseconds elapsed since the system started. + return Environment.TickCount * TimeSpan.TicksPerMillisecond; + } + } + +} + diff --git a/TechTalk.SpecFlow.Silverlight/Configuration/ConfigDefaults.cs b/TechTalk.SpecFlow.Silverlight/Configuration/ConfigDefaults.cs new file mode 100644 index 000000000..36a805583 --- /dev/null +++ b/TechTalk.SpecFlow.Silverlight/Configuration/ConfigDefaults.cs @@ -0,0 +1,20 @@ +namespace TechTalk.SpecFlow.Configuration +{ + public static class ConfigDefaults + { + internal const string FeatureLanguage = "en-US"; + internal const string ToolLanguage = ""; + + internal const string UnitTestProviderName = "MSTest"; + + internal const bool DetectAmbiguousMatches = true; + internal const bool StopAtFirstError = false; + internal const MissingOrPendingStepsOutcome MissingOrPendingStepsOutcome = TechTalk.SpecFlow.Configuration.MissingOrPendingStepsOutcome.Inconclusive; + + internal const bool TraceSuccessfulSteps = true; + internal const bool TraceTimings = false; + internal const string MinTracedDuration = "0:0:0.1"; + + internal const bool AllowDebugGeneratedFiles = false; + } +} \ No newline at end of file diff --git a/TechTalk.SpecFlow.Silverlight/Properties/AssemblyInfo.cs b/TechTalk.SpecFlow.Silverlight/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..9da5cad6a --- /dev/null +++ b/TechTalk.SpecFlow.Silverlight/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("TechTalk.SpecFlow.Silverlight")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("TechTalk.SpecFlow.Silverlight")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2010")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("04dec58a-9677-4f58-ae8b-4744bbffb9a9")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/TechTalk.SpecFlow.Silverlight/TechTalk.SpecFlow.Silverlight.csproj b/TechTalk.SpecFlow.Silverlight/TechTalk.SpecFlow.Silverlight.csproj new file mode 100644 index 000000000..680a572af --- /dev/null +++ b/TechTalk.SpecFlow.Silverlight/TechTalk.SpecFlow.Silverlight.csproj @@ -0,0 +1,208 @@ + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {B93F95CF-BF89-4D92-BB0F-86885B9B6DCE} + {A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + TechTalk.SpecFlow.Silverlight + TechTalk.SpecFlow.Silverlight + v3.5 + false + true + true + + + true + full + false + Bin\Debug + DEBUG;TRACE;SILVERLIGHT + true + true + prompt + 4 + + + pdbonly + true + Bin\Release + TRACE;SILVERLIGHT + true + true + prompt + 4 + + + + + + + + + + + + + Attributes.cs + + + Bindings\BindingMatch.cs + + + Bindings\BindingRegistry.cs + + + Bindings\BindingType.cs + + + Bindings\EventBinding.cs + + + Bindings\StepArgs.cs + + + Bindings\StepArgumentTypeConverter.cs + + + Bindings\StepBinding.cs + + + Bindings\StepDefinitionKeyword.cs + + + Bindings\StepMethodBinding.cs + + + Bindings\StepTransformationBinding.cs + + + Configuration\ConfigurationServices.cs + + + Configuration\MissingOrPendingStepsOutcome.cs + + + Configuration\RuntimeConfiguration.cs + + + CultureInfoScope.cs + + + ErrorHandling\BindingException.cs + + + ErrorHandling\ErrorProvider.cs + + + ErrorHandling\MissingStepDefinitionException.cs + + + ErrorHandling\PendingStepException.cs + + + ErrorHandling\SpecFlowException.cs + + + FeatureContext.cs + + + FeatureInfo.cs + + + ITestRunner.cs + + + ObjectContainer.cs + + + ScenarioBlock.cs + + + ScenarioContext.cs + + + ScenarioInfo.cs + + + SpecFlowContext.cs + + + Steps.cs + + + StringExtensions.cs + + + Table.cs + + + TestRunner.cs + + + Tracing\DefaultListener.cs + + + Tracing\ITraceListener.cs + + + Tracing\LanguageHelper.cs + + + Tracing\NullListener.cs + + + Tracing\StepDefinitonSkeletonProvider.cs + + + Tracing\StepFormatter.cs + + + Tracing\TestTracer.cs + + + UnitTestProvider\IUnitTestRuntimeProvider.cs + + + UnitTestProvider\MbUnitRuntimeProvider.cs + + + UnitTestProvider\MsTestRuntimeProvider.cs + + + UnitTestProvider\NUnitRuntimeProvider.cs + + + UnitTestProvider\XUnitRuntimeProvider.cs + + + + + + + + + + + Languages.xml + + + + + + + + + + + + \ No newline at end of file diff --git a/TechTalk.SpecFlow.sln b/TechTalk.SpecFlow.sln index 648c807db..d345cfba9 100644 --- a/TechTalk.SpecFlow.sln +++ b/TechTalk.SpecFlow.sln @@ -47,6 +47,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Resources", "Resources", "{ Installer\Resources\welcome_dialog.bmp = Installer\Resources\welcome_dialog.bmp EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TechTalk.SpecFlow.Silverlight", "Runtime.Silverlight\TechTalk.SpecFlow.Silverlight.csproj", "{B93F95CF-BF89-4D92-BB0F-86885B9B6DCE}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -185,6 +187,16 @@ Global {89167EB9-F458-48DA-9D8F-F639A74F5871}.Release|Mixed Platforms.Build.0 = Release|x86 {89167EB9-F458-48DA-9D8F-F639A74F5871}.Release|x86.ActiveCfg = Release|x86 {89167EB9-F458-48DA-9D8F-F639A74F5871}.Release|x86.Build.0 = Release|x86 + {B93F95CF-BF89-4D92-BB0F-86885B9B6DCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B93F95CF-BF89-4D92-BB0F-86885B9B6DCE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B93F95CF-BF89-4D92-BB0F-86885B9B6DCE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {B93F95CF-BF89-4D92-BB0F-86885B9B6DCE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {B93F95CF-BF89-4D92-BB0F-86885B9B6DCE}.Debug|x86.ActiveCfg = Debug|Any CPU + {B93F95CF-BF89-4D92-BB0F-86885B9B6DCE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B93F95CF-BF89-4D92-BB0F-86885B9B6DCE}.Release|Any CPU.Build.0 = Release|Any CPU + {B93F95CF-BF89-4D92-BB0F-86885B9B6DCE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {B93F95CF-BF89-4D92-BB0F-86885B9B6DCE}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {B93F95CF-BF89-4D92-BB0F-86885B9B6DCE}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE