Skip to content

Commit

Permalink
Continue loading feature files after parsing errors (#445)
Browse files Browse the repository at this point in the history
* Make FeatureParser throw correct exceptions

* Split FeatureParser into two

* Get rid of string-based crawl overload

* Introduce ParsingReport

* Give immediate feedback when a feature cannot be parsed
  • Loading branch information
dirkrombauts authored Mar 9, 2017
1 parent 5fee5ee commit 1585406
Show file tree
Hide file tree
Showing 21 changed files with 404 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public sealed class StepDefinitions : BaseFixture /* God object antipattern */
public void IHaveThisFeatureDescription(string featureDescription)
{
var configuration = this.Configuration;
FeatureParser parser = new FeatureParser(this.FileSystem, configuration);
FeatureParser parser = new FeatureParser(configuration);

var feature = parser.Parse(new StringReader(featureDescription));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Dan moet het resultaat 120 zijn
| 2 |
";

var parser = new FeatureParser(FileSystem, this.Configuration);
var parser = new FeatureParser(this.Configuration);
Feature feature = parser.Parse(new StringReader(featureText));

var formatter = Container.Resolve<HtmlFeatureFormatter>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public sealed class StepDefinitions : BaseFixture /* God object antipattern */
public void IHaveThisFeatureDescription(string featureDescription)
{
var configuration = this.Configuration;
FeatureParser parser = new FeatureParser(this.FileSystem, configuration);
FeatureParser parser = new FeatureParser(configuration);

var feature = parser.Parse(new StringReader(featureDescription));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ public class WhenBuildingWordDocuments : BaseFixture
[SetUp]
public void Setup()
{
var rootPath = FileSystem.DirectoryInfo.FromDirectoryName(RootPath);

AddFakeFolderStructures();

Configuration.OutputFolder = this.FileSystem.DirectoryInfo.FromDirectoryName(FileSystemPrefix);
this.features = Container.Resolve<DirectoryTreeCrawler>().Crawl(RootPath);
this.features = Container.Resolve<DirectoryTreeCrawler>().Crawl(rootPath, new ParsingReport());
this.builder = Container.Resolve<WordDocumentationBuilder>();
}

Expand Down
119 changes: 119 additions & 0 deletions src/Pickles/Pickles.Test/FeatureNodeFactoryTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="FeatureNodeFactoryTests.cs" company="PicklesDoc">
// Copyright 2011 Jeffrey Cameron
// Copyright 2012-present PicklesDoc team and community contributors
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.IO;
using System.IO.Abstractions.TestingHelpers;
using System.Linq;
using NFluent;
using NUnit.Framework;
using PicklesDoc.Pickles.DirectoryCrawler;
using PicklesDoc.Pickles.DocumentationBuilders.Html;

namespace PicklesDoc.Pickles.Test
{
[TestFixture]
public class FeatureNodeFactoryTests : BaseFixture
{
[Test]
public void Create_InvalidFeatureFile_AddsEntryToReport()
{
FileSystem.AddFile(@"c:\test.feature", new MockFileData("Invalid feature file"));

var featureNodeFactory = this.CreateFeatureNodeFactory();

var report = new ParsingReport();

featureNodeFactory.Create(null, FileSystem.FileInfo.FromFileName(@"c:\test.feature"), report);

Check.That(report.First()).Contains(@"c:\test.feature");
}

private FeatureNodeFactory CreateFeatureNodeFactory()
{
return new FeatureNodeFactory(
new RelevantFileDetector(),
new FileSystemBasedFeatureParser(
new FeatureParser(Configuration),
FileSystem),
new HtmlMarkdownFormatter(
new MarkdownProvider()),
FileSystem);
}

[Test]
public void Create_InvalidFileType_AddsEntryToReport()
{
FileSystem.AddFile(@"c:\test.dll", new MockFileData("Invalid feature file"));

var featureNodeFactory = this.CreateFeatureNodeFactory();

var report = new ParsingReport();

featureNodeFactory.Create(null, FileSystem.FileInfo.FromFileName(@"c:\test.dll"), report);

Check.That(report.First()).Contains(@"c:\test.dll");
}

[Test]
public void Create_BogusLocationType_AddsEntryToReport()
{
var featureNodeFactory = this.CreateFeatureNodeFactory();

var report = new ParsingReport();

featureNodeFactory.Create(null, new BogusFileSystemInfoBase { fullName = "Totally Bad Name"}, report);

Check.That(report.First()).Contains(@"Totally Bad Name");
}

private class BogusFileSystemInfoBase : System.IO.Abstractions.FileSystemInfoBase
{
internal string fullName;

public override void Delete()
{
throw new NotImplementedException();
}

public override void Refresh()
{
throw new NotImplementedException();
}

public override FileAttributes Attributes { get; set; }
public override DateTime CreationTime { get; set; }
public override DateTime CreationTimeUtc { get; set; }
public override bool Exists { get; }
public override string Extension { get; }

public override string FullName
{
get { return this.fullName; }
}

public override DateTime LastAccessTime { get; set; }
public override DateTime LastAccessTimeUtc { get; set; }
public override DateTime LastWriteTime { get; set; }
public override DateTime LastWriteTimeUtc { get; set; }
public override string Name { get; }
}
}
}
41 changes: 41 additions & 0 deletions src/Pickles/Pickles.Test/FeatureParserTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="FeatureParserTests.cs" company="PicklesDoc">
// Copyright 2011 Jeffrey Cameron
// Copyright 2012-present PicklesDoc team and community contributors
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

using System;
using NFluent;
using NUnit.Framework;

namespace PicklesDoc.Pickles.Test
{
[TestFixture]
public class FeatureParserTests : BaseFixture
{
[Test]
public void Parse_InvalidFeatureContent_ThrowsFeatureParseException()
{
var parser = new FeatureParser(Configuration);

var reader = new System.IO.StringReader("Invalid feature file");

Check.ThatCode(() => parser.Parse(reader)).Throws<FeatureParseException>()
.WithMessage("Unable to parse feature");
}
}
}
43 changes: 43 additions & 0 deletions src/Pickles/Pickles.Test/FileSystemBasedFeatureParserTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="FileSystemBasedFeatureParserTests.cs" company="PicklesDoc">
// Copyright 2011 Jeffrey Cameron
// Copyright 2012-present PicklesDoc team and community contributors
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.IO.Abstractions.TestingHelpers;
using NFluent;
using NUnit.Framework;

namespace PicklesDoc.Pickles.Test
{
[TestFixture]
public class FileSystemBasedFeatureParserTests : BaseFixture
{
[Test]
public void Parse_InvalidFeatureFile_ThrowsFeatureParseExceptionWithFilename()
{
FileSystem.AddFile(@"c:\temp\featurefile.feature", new MockFileData("Invalid feature file"));
var parser = new FileSystemBasedFeatureParser(new FeatureParser(Configuration), FileSystem);

Check.ThatCode(() => parser.Parse(@"c:\temp\featurefile.feature")).Throws<FeatureParseException>()
.WithMessage(@"There was an error parsing the feature file here: c:\temp\featurefile.feature" +
Environment.NewLine + @"Errormessage was: 'Unable to parse feature'");
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ public class HtmlDocumentationBuilderTests : BaseFixture
[Test]
public void ShouldNotBlowUpWHenParsingEmptyFolder()
{
var rootPath = FileSystem.DirectoryInfo.FromDirectoryName(RootPath);

this.AddFakeFolderStructures();

var configuration = this.Configuration;
configuration.OutputFolder = this.FileSystem.DirectoryInfo.FromDirectoryName(FileSystemPrefix);
var features = Container.Resolve<DirectoryTreeCrawler>().Crawl(RootPath);
var features = Container.Resolve<DirectoryTreeCrawler>().Crawl(rootPath, new ParsingReport());
var builder = Container.Resolve<HtmlDocumentationBuilder>();

builder.Build(features);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ public class WhenCreatingAFeatureWithMetaInfoAndTestResultInMstestFormat : BaseF
public string Setup()
{
const string OutputDirectoryName = FileSystemPrefix + @"JSONFeatureOutput";
const string RootPath = FileSystemPrefix + @"JSON\Features";
var rootPath = FileSystem.DirectoryInfo.FromDirectoryName(FileSystemPrefix + @"JSON\Features");

const string TestResultFilePath = FileSystemPrefix + @"JSON\results-example-failing-and-pasing-mstest.trx";

string filePath = FileSystem.Path.Combine(OutputDirectoryName, JsonDocumentationBuilder.JsonFileName);
Expand All @@ -59,7 +60,7 @@ public string Setup()
var resultFile = RetrieveContentOfFileFromResources(ResourcePrefix + "JSON.results-example-failing-and-pasing-mstest.trx");
FileSystem.AddFile(TestResultFilePath, resultFile);

Tree features = Container.Resolve<DirectoryTreeCrawler>().Crawl(RootPath);
Tree features = Container.Resolve<DirectoryTreeCrawler>().Crawl(rootPath, new ParsingReport());

var outputDirectory = FileSystem.DirectoryInfo.FromDirectoryName(OutputDirectoryName);
if (!outputDirectory.Exists)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@ public class WhenFormattingAFolderStructureWithFeatures : BaseFixture

public void Setup()
{
var rootPath = FileSystem.DirectoryInfo.FromDirectoryName(FileSystemPrefix);

this.AddFakeFolderStructures();

Tree features = Container.Resolve<DirectoryTreeCrawler>().Crawl(FileSystemPrefix);
Tree features = Container.Resolve<DirectoryTreeCrawler>().Crawl(rootPath, new ParsingReport());

var outputDirectory = FileSystem.DirectoryInfo.FromDirectoryName(OutputDirectory);
if (!outputDirectory.Exists)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@ public class TableOfContentsShouldBeCreatedFromAFolderStructure : BaseFixture

public void Setup()
{
var rootPath = FileSystem.DirectoryInfo.FromDirectoryName(RootPath);

this.AddFakeFolderStructures();

Tree features = Container.Resolve<DirectoryTreeCrawler>().Crawl(RootPath);
Tree features = Container.Resolve<DirectoryTreeCrawler>().Crawl(rootPath, new ParsingReport());

var formatter = new HtmlTableOfContentsFormatter(null, this.FileSystem);
this.toc = formatter.Format(
Expand Down
3 changes: 3 additions & 0 deletions src/Pickles/Pickles.Test/Pickles.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@
<Compile Include="DescriptionProcessorTests.cs" />
<Compile Include="DirectoryCrawlers\ImageFileDetectorTests.cs" />
<Compile Include="DirectoryCrawlers\RelevantFileDetectorTests.cs" />
<Compile Include="FeatureNodeFactoryTests.cs" />
<Compile Include="FeatureParserTests.cs" />
<Compile Include="FileSystemBasedFeatureParserTests.cs" />
<Compile Include="GlobalSuppressions.cs" />
<Compile Include="LanguageServicesRegistryTests.cs" />
<Compile Include="ObjectModel\Factory.cs" />
Expand Down
4 changes: 2 additions & 2 deletions src/Pickles/Pickles.Test/WhenCrawlingFoldersForFeatures.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ public void Then_can_crawl_all_folders_including_subfolders_for_features_success
{
this.AddFakeFolderStructures();

string rootPath = FileSystemPrefix + @"FeatureCrawlerTests";
Tree features = Container.Resolve<DirectoryTreeCrawler>().Crawl(rootPath);
var rootPath = FileSystem.DirectoryInfo.FromDirectoryName(FileSystemPrefix + @"FeatureCrawlerTests");
Tree features = Container.Resolve<DirectoryTreeCrawler>().Crawl(rootPath, new ParsingReport());

Check.That(features).IsNotNull();

Expand Down
11 changes: 8 additions & 3 deletions src/Pickles/Pickles.Test/WhenParsingLocalizedFeatureFiles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ När den körs
Så skall jag se att det inträffat";

var configuration = this.Configuration;
var parser = new FeatureParser(FileSystem, configuration);
var parser = this.CreateParser(configuration);
Feature feature = parser.Parse(new StringReader(featureText));

Check.That(feature).IsNotNull();
Expand Down Expand Up @@ -88,6 +88,11 @@ Vill jag skriva mina krav på svenska
Check.That(thenStep.TableArgument).IsNull();
}

private FeatureParser CreateParser(IConfiguration configuration)
{
return new FeatureParser(configuration);
}

[Test]
public void WhenSettingTheLanguageInTheConfiguration_ThenCanParseMostBasicFeatureSuccessfully()
{
Expand All @@ -107,7 +112,7 @@ När den körs

configuration.Language = "sv";

var parser = new FeatureParser(FileSystem, configuration);
var parser = this.CreateParser(configuration);
Feature feature = parser.Parse(new StringReader(featureText));

Check.That(feature).IsNotNull();
Expand Down Expand Up @@ -157,7 +162,7 @@ Als ik plus druk
Dan moet het resultaat 120 zijn";

var configuration = this.Configuration;
var parser = new FeatureParser(FileSystem, configuration);
var parser = this.CreateParser(configuration);
Feature feature = parser.Parse(new StringReader(featureText));

Check.That(feature).IsNotNull();
Expand Down
Loading

0 comments on commit 1585406

Please sign in to comment.