diff --git a/SpecFlow.Tools.MsBuild.Generation/FeatureCodeBehindGenerator.cs b/SpecFlow.Tools.MsBuild.Generation/FeatureCodeBehindGenerator.cs index af57c7c40..57aa0dc5a 100644 --- a/SpecFlow.Tools.MsBuild.Generation/FeatureCodeBehindGenerator.cs +++ b/SpecFlow.Tools.MsBuild.Generation/FeatureCodeBehindGenerator.cs @@ -1,7 +1,10 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using BoDi; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; using TechTalk.SpecFlow.Generator; using TechTalk.SpecFlow.Generator.Interfaces; using TechTalk.SpecFlow.Generator.Project; @@ -20,6 +23,7 @@ public FeatureCodeBehindGenerator(ITestGenerator testGenerator) public TestFileGeneratorResult GenerateCodeBehindFile(string featureFile) { var featureFileInput = new FeatureFileInput(featureFile); + var generatedFeatureFileName = Path.GetFileName(_testGenerator.GetTestFullPath(featureFileInput)); var testGeneratorResult = _testGenerator.GenerateTestFile(featureFileInput, new GenerationSettings()); diff --git a/SpecFlow.Tools.MsBuild.Generation/GenerateFeatureFileCodeBehindTask.cs b/SpecFlow.Tools.MsBuild.Generation/GenerateFeatureFileCodeBehindTask.cs index 58e575e01..c60ae54a8 100644 --- a/SpecFlow.Tools.MsBuild.Generation/GenerateFeatureFileCodeBehindTask.cs +++ b/SpecFlow.Tools.MsBuild.Generation/GenerateFeatureFileCodeBehindTask.cs @@ -41,6 +41,7 @@ public override bool Execute() var generateFeatureFileCodeBehindTaskContainerBuilder = new GenerateFeatureFileCodeBehindTaskContainerBuilder(); var generatorPlugins = GeneratorPlugins?.Select(gp => gp.ItemSpec).Select(p => new GeneratorPluginInfo(p)).ToArray() ?? Array.Empty(); var featureFiles = FeatureFiles?.Select(i => i.ItemSpec).ToArray() ?? Array.Empty(); + var msbuildInformationProvider = new MSBuildInformationProvider(MSBuildVersion); var generateFeatureFileCodeBehindTaskConfiguration = new GenerateFeatureFileCodeBehindTaskConfiguration(AnalyticsTransmitter, CodeBehindGenerator); var generateFeatureFileCodeBehindTaskInfo = new SpecFlowProjectInfo(generatorPlugins, featureFiles, ProjectPath, ProjectFolder, ProjectGuid, AssemblyName, OutputPath, RootNamespace, TargetFrameworks, TargetFramework); diff --git a/SpecFlow.Tools.MsBuild.Generation/SpecFlowProjectInfo.cs b/SpecFlow.Tools.MsBuild.Generation/SpecFlowProjectInfo.cs index d216ce000..2dd8bab7a 100644 --- a/SpecFlow.Tools.MsBuild.Generation/SpecFlowProjectInfo.cs +++ b/SpecFlow.Tools.MsBuild.Generation/SpecFlowProjectInfo.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using TechTalk.SpecFlow.Generator; +using TechTalk.SpecFlow.Utils; namespace SpecFlow.Tools.MsBuild.Generation { @@ -18,7 +19,7 @@ public SpecFlowProjectInfo( string currentTargetFramework) { GeneratorPlugins = generatorPlugins; - FeatureFiles = featureFiles; + FeatureFiles = FileFilter.GetValidFiles(featureFiles); ProjectFolder = projectFolder; OutputPath = outputPath; RootNamespace = rootNamespace; @@ -48,5 +49,6 @@ public SpecFlowProjectInfo( public string TargetFrameworks { get; } public string CurrentTargetFramework { get; } + } } diff --git a/TechTalk.SpecFlow.Utils/FileFilter.cs b/TechTalk.SpecFlow.Utils/FileFilter.cs new file mode 100644 index 000000000..8a3bfc406 --- /dev/null +++ b/TechTalk.SpecFlow.Utils/FileFilter.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace TechTalk.SpecFlow.Utils +{ + public static class FileFilter + { + public static IReadOnlyCollection GetValidFiles(IReadOnlyCollection filePaths) + { + var valids = filePaths.Where(ValidFile).ToList(); + return valids; + } + + private static bool ValidFile(string filePath) + { + try + { + return ValidateFileName(filePath) && ValidateFilePath(filePath); + } + catch (Exception) + { + return false; + } + } + + private static bool ValidateFileName(string filePath) + { + var invalidFileNameChars = Path.GetInvalidFileNameChars(); + var fileName = Path.GetFileName(filePath); + + return !string.IsNullOrEmpty(fileName) && + !fileName.Any(s => invalidFileNameChars.Contains(s)); + } + + private static bool ValidateFilePath(string filePath) + { + string pathWithoutSeparator = filePath + .Replace(Path.DirectorySeparatorChar.ToString(), string.Empty) + .Replace(Path.AltDirectorySeparatorChar.ToString(), string.Empty) + .Replace(Path.VolumeSeparatorChar.ToString(), string.Empty); + var invalidPathChars = Path.GetInvalidPathChars(); + + return !string.IsNullOrEmpty(pathWithoutSeparator) && + !pathWithoutSeparator.Any(invalidPathChars.Contains); + } + + } +} diff --git a/Tests/TechTalk.SpecFlow.GeneratorTests/FileFilterTests.cs b/Tests/TechTalk.SpecFlow.GeneratorTests/FileFilterTests.cs new file mode 100644 index 000000000..a3e3e56c3 --- /dev/null +++ b/Tests/TechTalk.SpecFlow.GeneratorTests/FileFilterTests.cs @@ -0,0 +1,71 @@ +using System.Collections.Generic; +using System.Linq; +using FluentAssertions; +using TechTalk.SpecFlow.Utils; +using Xunit; + +namespace TechTalk.SpecFlow.GeneratorTests +{ + public class FileFilterTests + { + private readonly List _validFeatureFilePaths; + + public FileFilterTests() + { + _validFeatureFilePaths = new List() + { + @"Features\SpecFlowFeature.feature", + @"Features\Math.feature", + @"Features\見.feature" + }; + } + + [Fact] + public void ShouldReturnValidFilePaths() + { + var validatedFilePaths = FileFilter.GetValidFiles(_validFeatureFilePaths); + validatedFilePaths.Should().BeEquivalentTo(_validFeatureFilePaths); + } + + [Fact] + public void ShouldRemoveInvalidFilePaths() + { + var notValidFeatureFilePaths = new List() + { + @"Features\SpecFlowFeature*.feature", + @"Features\Math?.feature", + @"Features\Project|Impossible.feature" + }; + + var featureFilePaths = _validFeatureFilePaths.Concat(notValidFeatureFilePaths).ToList(); + + var validatedPaths = FileFilter.GetValidFiles(featureFilePaths); + validatedPaths.Should().BeEquivalentTo(_validFeatureFilePaths); + } + + [Fact] + public void ShouldRemoveWildChars() + { + var wildCards = new List() + { + @"**\*.feature" + }; + + var featureFilePaths = _validFeatureFilePaths.Concat(wildCards).ToList(); + var validatedPaths = FileFilter.GetValidFiles(featureFilePaths); + validatedPaths.Should().BeEquivalentTo(_validFeatureFilePaths); + } + + [Fact] + public void ShouldBeAnEmptyListIfOnlyWildCards() + { + var wildCards = new List() + { + @"**\*.feature" + }; + + var validatedPaths = FileFilter.GetValidFiles(wildCards); + validatedPaths.Should().BeEmpty(); + } + } +} diff --git a/changelog.txt b/changelog.txt index 025149848..4811eb735 100644 --- a/changelog.txt +++ b/changelog.txt @@ -4,6 +4,7 @@ Fixes: + Update the default C# skeleton template to use context injection instead of the deprecated ScenarioContext.Current + Save generated files with UTF8-BOM encoding. + Revert "Replace NUnit.Framework.DescriptionAttribute to TestName in NUnit generator #1225" because of problems with the NUnit Test Adapter ++ Remove files with invalid characters from the FeatureFiles list (provided by msbuild) Features: + Created VerifyAllColumnsBound check for `table.CreateSet` and `table.CreateInstance`