예제 #1
0
        public static void Generate(AssemblyGeneratorContext context, TextWriter errorOutput)
        {
            var referenceAssemblies = AssemblyReflecter.ProbeReferenceAssemblies(context.TemporaryPath);

            context.SourceAssembly = SpecFlowUtils.ProbeProjectAssemblyName(referenceAssemblies, context.TemporaryPath);
            var addedSpecRun = AddSpecRunIfNecessary(context, referenceAssemblies);

            var specFlowProject = SpecFlowUtils.ReadSpecFlowProject(context.TemporaryPath, context.SourceAssembly, context.DefaultNamespace);
            var generator       = SpecFlowUtils.SetupGenerator(context.VerboseOutput, errorOutput);

            generator.ProcessProject(specFlowProject, false /* forceGeneration */);

            GenerateFeatureAssembly(
                context.TemporaryPath,
                referenceAssemblies.Select(assembly => assembly.FullPath).ToArray(),
                context.OutputPath,
                context.FeatureAssemblyName);

            CopyGeneratedAssemblies(context, addedSpecRun);
            GenerateConfiguration(
                Path.Combine(context.SourcePath, context.FeatureDllName + ".config"),
                AssemblyReflecter.GetStepAssemblyNames(referenceAssemblies, context.TemporaryPath));

            DeleteRedundantFiles(context.TemporaryPath);
        }
예제 #2
0
        private static void WriteSpecRunToSourcePath(AssemblyGeneratorContext context, bool addedSpecRun)
        {
            const string template = @"<?xml version=""1.0"" encoding=""utf-8""?>
<TestProfile xmlns=""http://www.specflow.org/schemas/plus/TestProfile/1.5"">
  <Settings projectName=""{0}"" projectId=""{{{1}}}"" />
  <Execution stopAfterFailures=""3"" testThreadCount=""1"" testSchedulingMode=""Sequential"" />
  <TestAssemblyPaths>
    <TestAssemblyPath>{2}</TestAssemblyPath>
  </TestAssemblyPaths>
  <DeploymentTransformation>
    <Steps>
    </Steps>
  </DeploymentTransformation>
</TestProfile>";

            var specRunDll = Path.Combine(context.SourcePath, SpecRunAssemblyName);

            if (addedSpecRun && !File.Exists(specRunDll))
            {
                File.Copy(Path.Combine(context.TemporaryPath, SpecRunAssemblyName), specRunDll, true);
            }

            var usingSpecRun  = File.Exists(specRunDll);
            var srProfilePath = Path.Combine(context.SourcePath, (context.SpecifiedFeatureAssemblyName ?? context.SourceAssembly.AssemblyName) + ".srprofile");

            if (usingSpecRun && !File.Exists(srProfilePath))
            {
                var srProfile = string.Format(template, context.SourceAssembly.AssemblyName, Guid.NewGuid().ToString(), context.FeatureDllName);
                File.WriteAllText(srProfilePath, srProfile, System.Text.Encoding.UTF8);
            }
        }
예제 #3
0
        static void CopyGeneratedAssemblies(AssemblyGeneratorContext context, bool addedSpecRun)
        {
            File.Copy(Path.Combine(context.OutputPath, context.FeatureDllName), Path.Combine(context.SourcePath, context.FeatureDllName), true);
            File.Copy(Path.Combine(context.OutputPath, context.FeatureAssemblyName + ".pdb"), Path.Combine(context.SourcePath, context.FeatureAssemblyName + ".pdb"), true);

            WriteSpecRunToSourcePath(context, addedSpecRun);
        }
예제 #4
0
        public static void Register(CommandLineApplication cmdApp)
        {
            cmdApp.Command("generate", command =>
            {
                command.Description = "Produce assembly for the project containing .feature cases.";


                var argProjectDir       = command.Argument("[project]", "Optional. A folder path containing the project with .feature cases. The working directory will be used if not specified.", multipleValues: false);
                var optAssemblyName     = command.Option("--assembly-name <ASSEMBLY_NAME>", "Optional. The name of the generated assembly. A random one will be used if not specified", CommandOptionType.SingleValue);
                var optDefaultNamespace = command.Option("--namespace <DEFAULT_NAMESPACE>", "The default namespace used to generate feature classes.", CommandOptionType.SingleValue);
                var optVerbose          = command.Option("-v|--verbose", "Show verbose output", CommandOptionType.NoValue);

                command.HelpOption("-?|-h|--help");



                command.OnExecute(() =>
                {
                    var basePath = argProjectDir.Value;
                    basePath     = Path.IsPathRooted(basePath) ? basePath : Environment.CurrentDirectory;

                    var context = new AssemblyGeneratorContext
                    {
                        VerboseOutput                = optVerbose.HasValue(),
                        DefaultNamespace             = optDefaultNamespace.Value(),
                        SourcePath                   = basePath,
                        SpecifiedFeatureAssemblyName = optAssemblyName.Value(),
                        TemporaryPath                = Path.Combine(Path.GetTempPath(), "SpecFlowFeatureAssemblyGenerator", "f" + Guid.NewGuid().ToString("N").Substring(0, 9))
                    };

                    return(Run(context));
                });
            });
        }
예제 #5
0
        static bool AddSpecRunIfNecessary(AssemblyGeneratorContext context, IList <LoadedAssembly> referenceAssemblies)
        {
            if (context.SourceAssembly.HasSpecFlowConfigured)
            {
                return(false);
            }

            var specRunPath = Path.Combine(context.TemporaryPath, SpecRunAssemblyName);
            var addSpecRun  = !File.Exists(specRunPath);

            if (addSpecRun)
            {
                File.Copy(Path.Combine(DirectoryUtils.GetContainingDirectory(Assembly.GetExecutingAssembly().Location), SpecRunAssemblyName), specRunPath, true);
                referenceAssemblies.Add(new LoadedAssembly {
                    FullPath = specRunPath, Definition = null
                });
            }
            return(addSpecRun);
        }
예제 #6
0
        static int Run(AssemblyGeneratorContext context)
        {
            var defaultColor = Console.ForegroundColor;
            var exitCode     = 0;

            try
            {
                if (context.VerboseOutput)
                {
                    Console.WriteLine("Generating source code using temporary path {0}", context.TemporaryPath);
                }
                Directory.CreateDirectory(context.TemporaryPath);
                Directory.CreateDirectory(context.OutputPath);
                DirectoryUtils.CopyDirectory(context.SourcePath, context.TemporaryPath);


                AssemblyGenerator.Generate(context, Console.Error);


                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("Successfully generated assembly {0}", context.FeatureDllName);
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.DarkRed;
                Console.Error.WriteLine("Could not generate assembly for the project.");
                Console.ForegroundColor = defaultColor;

                if (context.VerboseOutput)
                {
                    Console.Error.WriteLine(ex.Message);
                    Console.Error.WriteLine(ex.StackTrace);
                }
                exitCode = -1;
            }
            finally
            {
                Console.ForegroundColor = defaultColor;
            }

            return(exitCode);
        }