diff --git a/.gitignore b/.gitignore
index 2ccbc81f7..1ffa2eee3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,12 +30,16 @@ obj/
[Dd]ebug*/
[Rr]elease*/
Ankh.NoLoad
+.vscode/
#MonoDevelop files
*.userprefs
*.pidb
*~
+#Webstorm files
+.idea/
+
#Tooling
_ReSharper*/
*.resharper
@@ -82,3 +86,4 @@ packages/Chocolatey/
# Fody
!src/Pickles/packages/Fody*/build/*
src/Pickles/.vs/config/applicationhost.config
+src/Pickles/Pickles/PortabilityAnalysis.html
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8c4fa24b0..39d360181 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,8 +10,23 @@ This project adheres to [Semantic Versioning](http://semver.org). We consider th
- The settings file of the GUI runner
- The JSON output of the JSON format
+Features in Experimental are subject to change and removal without being considered breaking.
+
This document is formatted according to the principles of [Keep A CHANGELOG](http://keepachangelog.com).
+
+## [2.5.0] - 2016-03-21
+
+### Added
+
+- Experimental features - see the [documentation](http://docs.picklesdoc.com/en/latest/ExperimentalFeatures/) (by [@dirkrombauts](https://github.com/dirkrombauts)).
+
+### Experimental
+
+- Using a different MarkDown component. Warning: it is not entirely compatible with the static HTML version. ([#269](https://github.com/picklesdoc/pickles/issues/269)) (by [@dirkrombauts](https://github.com/dirkrombauts)).
+- Enabling mathematics in the description elements in the DHTML version. Warning: requires internet connectivity. ([#281](https://github.com/picklesdoc/pickles/issues/281)) (by [@dirkrombauts](https://github.com/dirkrombauts)).
+- Overview Dashboard on DHTML Pickles Site with Summary Charts by Namespace and Tags ([#295](https://github.com/picklesdoc/pickles/pull/295)) (by [@ocsurfnut](https://github.com/ocsurfnut))
+
## [2.4.1] - 2016-03-01
### Fixed
diff --git a/DeployArtifacts.cmd b/DeployArtifacts.cmd
new file mode 100644
index 000000000..aae3b8997
--- /dev/null
+++ b/DeployArtifacts.cmd
@@ -0,0 +1,4 @@
+@ECHO OFF
+call DeployOutput.cmd %1
+call DeployToChocolatey.cmd %1
+call DeployToNuget.cmd %1
diff --git a/build.bat b/build.bat
index 80aa11899..059610bdf 100644
--- a/build.bat
+++ b/build.bat
@@ -1,5 +1,5 @@
@echo off
-set "picklesVersion=2.4.1"
+set "picklesVersion=2.5.0"
cls
diff --git a/build.cmd b/build.cmd
new file mode 100644
index 000000000..95de4cac9
--- /dev/null
+++ b/build.cmd
@@ -0,0 +1 @@
+call build.bat
\ No newline at end of file
diff --git a/chocolatey.fsx b/chocolatey.fsx
index 5c2c85631..a39b3d2e4 100644
--- a/chocolatey.fsx
+++ b/chocolatey.fsx
@@ -33,6 +33,9 @@ Target "CreatePackage CMD" (fun _ ->
cmdDir + "PicklesDoc.Pickles.ObjectModel.dll";
cmdDir + "PicklesDoc.Pickles.TestFrameworks.dll";
cmdDir + "System.IO.Abstractions.dll";
+ cmdDir + "FeatureSwitcher.dll";
+ cmdDir + "Strike.Jint.dll";
+ cmdDir + "Jint.dll";
cmdDir + "pickles.exe";
cmdDir + "NLog.config" ]
@@ -70,6 +73,9 @@ Target "CreatePackage GUI" (fun _ ->
guiDir + "PicklesDoc.Pickles.ObjectModel.dll";
guiDir + "PicklesDoc.Pickles.TestFrameworks.dll";
guiDir + "System.IO.Abstractions.dll";
+ guiDir + "FeatureSwitcher.dll";
+ guiDir + "Strike.Jint.dll";
+ guiDir + "Jint.dll";
guiDir + "System.Windows.Interactivity.dll";
guiDir + "picklesui.exe";
guiDir + "NLog.config";
diff --git a/chocolatey/pickles.nuspec b/chocolatey/pickles.nuspec
index 8966aa52e..ffcb9df71 100644
--- a/chocolatey/pickles.nuspec
+++ b/chocolatey/pickles.nuspec
@@ -50,6 +50,9 @@ Optionally, *Pickles* can **integrate test results**, so that your stakeholders
+
+
+
diff --git a/chocolatey/picklesui.nuspec b/chocolatey/picklesui.nuspec
index 3b7cef978..ce27c3da2 100644
--- a/chocolatey/picklesui.nuspec
+++ b/chocolatey/picklesui.nuspec
@@ -57,6 +57,9 @@ Optionally, *Pickles* can **integrate test results**, so that your stakeholders
+
+
+
diff --git a/nuget.fsx b/nuget.fsx
index f1f7a3c1e..cfdb69bbd 100644
--- a/nuget.fsx
+++ b/nuget.fsx
@@ -35,6 +35,9 @@ Target "CreatePackageCommandLine" (fun _ ->
cmdDir + "PicklesDoc.Pickles.ObjectModel.dll";
cmdDir + "PicklesDoc.Pickles.TestFrameworks.dll";
cmdDir + "System.IO.Abstractions.dll";
+ cmdDir + "FeatureSwitcher.dll";
+ cmdDir + "Strike.Jint.dll";
+ cmdDir + "Jint.dll";
cmdDir + "pickles.exe";
cmdDir + "NLog.config" ]
@@ -64,6 +67,9 @@ Target "CreatePackageMsBuild" (fun _ ->
msBuildDir + "PicklesDoc.Pickles.ObjectModel.dll";
msBuildDir + "PicklesDoc.Pickles.TestFrameworks.dll";
msBuildDir + "System.IO.Abstractions.dll";
+ msBuildDir + "FeatureSwitcher.dll";
+ msBuildDir + "Strike.Jint.dll";
+ msBuildDir + "Jint.dll";
msBuildDir + "PicklesDoc.Pickles.MSBuild.Tasks.dll";
msBuildDir + "build/Pickles.MSBuild.targets";]
@@ -94,6 +100,9 @@ Target "CreatePackagePowerShell" (fun _ ->
powerShellDir + "PicklesDoc.Pickles.TestFrameworks.dll";
powerShellDir + "PicklesDoc.Pickles.PowerShell.dll";
powerShellDir + "System.IO.Abstractions.dll";
+ powerShellDir + "FeatureSwitcher.dll";
+ powerShellDir + "Strike.Jint.dll";
+ powerShellDir + "Jint.dll";
"src/Pickles/Pickles.PowerShell/init.ps1" ]
NuGet (fun p ->
diff --git a/src/Pickles/Examples/Features/Arithmetic.feature b/src/Pickles/Examples/Features/Arithmetic.feature
index 17845dae2..f00fb8873 100644
--- a/src/Pickles/Examples/Features/Arithmetic.feature
+++ b/src/Pickles/Examples/Features/Arithmetic.feature
@@ -1,7 +1,10 @@
Feature: Arithmetic
- In order to avoid silly mistakes
- As a math idiot
- I want to be able to perform arithmetic on the calculator
+In order to avoid silly mistakes
+As a math idiot
+I want to be able to perform arithmetic on the calculator
+
+When $a \ne 0$, there are two solutions to $\(ax^2 + bx + c = 0\)$ and they are
+$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
@arithmetic @fast
Scenario: Add two numbers
diff --git a/src/Pickles/Pickles.BaseDhtmlFiles/Index.html b/src/Pickles/Pickles.BaseDhtmlFiles/Index.html
index a0da40862..7b1c91122 100644
--- a/src/Pickles/Pickles.BaseDhtmlFiles/Index.html
+++ b/src/Pickles/Pickles.BaseDhtmlFiles/Index.html
@@ -14,9 +14,10 @@
+ #### EMBED EXPERIMENTALS ####
-
+
Loading...
@@ -82,15 +83,25 @@
+
+
+
+
+ Overview and Summary
+
+
+
-
+
+
@@ -201,6 +245,8 @@
+
+
@@ -209,8 +255,9 @@
+
+
+";
+
+ this.WriteTextFile(folder, "Index.html", "#### EMBED EXPERIMENTALS ####", mathScript);
+ }
+ else
+ {
+ this.WriteTextFile(folder, "Index.html", "#### EMBED EXPERIMENTALS ####", "");
+ }
this.WriteTextFile(folder, "pickledFeatures.js");
string cssFolder = this.FileSystem.Path.Combine(folder, "css");
@@ -65,6 +83,9 @@ public void WriteTo(string folder)
this.WriteScript(scriptsFolder, "stringFormatting.js");
this.WriteScript(scriptsFolder, "typeaheadList.js");
this.WriteScript(scriptsFolder, "underscore-min.js");
+ this.WriteScript(scriptsFolder, "Chart.min.js");
+ this.WriteScript(scriptsFolder, "Chart.StackedBar.js");
+ this.WriteScript(scriptsFolder, "picklesOverview.js");
}
private void EnsureFolder(string cssFolder)
diff --git a/src/Pickles/Pickles/DocumentationBuilders/HTML/ResourceWriter.cs b/src/Pickles/Pickles/DocumentationBuilders/HTML/ResourceWriter.cs
index 35a2c8f00..a175ac765 100644
--- a/src/Pickles/Pickles/DocumentationBuilders/HTML/ResourceWriter.cs
+++ b/src/Pickles/Pickles/DocumentationBuilders/HTML/ResourceWriter.cs
@@ -70,12 +70,24 @@ protected void WriteStyleSheet(string folder, string filename)
}
protected void WriteTextFile(string folder, string filename)
+ {
+ this.WriteTextFile(folder, filename, null, null);
+ }
+
+ protected void WriteTextFile(string folder, string filename, string toBeReplaced, string replacement)
{
string path = this.fileSystem.Path.Combine(folder, filename);
using (var reader = GetResourceStreamReader(this.namespaceOfResources + filename))
{
- this.fileSystem.File.WriteAllText(path, reader.ReadToEnd());
+ var contents = reader.ReadToEnd();
+
+ if (!string.IsNullOrWhiteSpace(toBeReplaced))
+ {
+ contents = contents.Replace(toBeReplaced, replacement ?? string.Empty);
+ }
+
+ this.fileSystem.File.WriteAllText(path, contents);
}
}
diff --git a/src/Pickles/Pickles/DocumentationBuilders/JSON/IJsonFeatureElement.cs b/src/Pickles/Pickles/DocumentationBuilders/JSON/IJsonFeatureElement.cs
index 3d785e026..70c47ec91 100644
--- a/src/Pickles/Pickles/DocumentationBuilders/JSON/IJsonFeatureElement.cs
+++ b/src/Pickles/Pickles/DocumentationBuilders/JSON/IJsonFeatureElement.cs
@@ -18,12 +18,22 @@
//
// --------------------------------------------------------------------------------------------------------------------
-using System;
-
namespace PicklesDoc.Pickles.DocumentationBuilders.JSON
{
+ using System.Collections.Generic;
+
public interface IJsonFeatureElement
{
JsonFeature Feature { get; set; }
+
+ string Name { get; set; }
+
+ string Description { get; set; }
+
+ List Steps { get; set; }
+
+ List Tags { get; set; }
+
+ JsonTestResult Result { get; set; }
}
}
diff --git a/src/Pickles/Pickles/DocumentationBuilders/JSON/JSONDocumentationBuilder.cs b/src/Pickles/Pickles/DocumentationBuilders/JSON/JSONDocumentationBuilder.cs
index af270184a..64e84d111 100644
--- a/src/Pickles/Pickles/DocumentationBuilders/JSON/JSONDocumentationBuilder.cs
+++ b/src/Pickles/Pickles/DocumentationBuilders/JSON/JSONDocumentationBuilder.cs
@@ -29,10 +29,12 @@
using NLog;
using PicklesDoc.Pickles.DirectoryCrawler;
using PicklesDoc.Pickles.ObjectModel;
-using PicklesDoc.Pickles.TestFrameworks;
namespace PicklesDoc.Pickles.DocumentationBuilders.JSON
{
+ using System.Linq;
+ using System.Text.RegularExpressions;
+
public class JsonDocumentationBuilder : IDocumentationBuilder
{
public const string JsonFileName = @"pickledFeatures.json";
@@ -101,6 +103,7 @@ private string GenerateJson(List features)
var data = new
{
Features = features,
+ Summary = this.GenerateSummary(features),
Configuration = new
{
SutName = this.configuration.SystemUnderTestName,
@@ -127,5 +130,110 @@ private void CreateFile(string outputFolderName, string jsonToWrite)
writer.Close();
}
}
+
+ private dynamic GenerateSummary(List features)
+ {
+ // master lists
+ // TODO: support filtering out of certain tags
+ var filteredFeatures = features.Where(x => true).ToList();
+ var scenarios = features.SelectMany(x => x.Feature.FeatureElements).ToList();
+ var filteredScenarios = scenarios;
+
+ // calculate tag summary - total scenarios (combining features and scenarios with tags)
+ var tagSummary = features
+ .SelectMany(x => x.Feature.Tags)
+ .Union(scenarios.SelectMany(x => x.Tags))
+ .Distinct()
+ .Select(tag =>
+ {
+ var scenariosWithTag = features
+ .Where(f => f.Feature.Tags.Contains(tag)).SelectMany(f => f.Feature.FeatureElements)
+ .Union(scenarios.Where(s => s.Tags.Contains(tag)))
+ .Distinct()
+ .ToList();
+
+ return new
+ {
+ Tag = tag,
+ Total = scenariosWithTag.Count,
+ Passing = scenariosWithTag.LongCount(x => x.Result.WasExecuted && x.Result.WasSuccessful),
+ Failing = scenariosWithTag.LongCount(x => x.Result.WasExecuted && !x.Result.WasSuccessful),
+ Inconclusive = scenariosWithTag.LongCount(x => !x.Result.WasExecuted)
+ };
+ });
+
+ // calculate top-level folder summary - total scenarios (excluding filtered scenarios)
+ var topLevelFolderName = new Regex(@"^(.*?)\\\\?.*$", RegexOptions.Compiled);
+
+ var topLevelFolderSummary = filteredFeatures
+ .Select(x => topLevelFolderName.Replace(x.RelativeFolder, "$1"))
+ .Distinct()
+ .Select(folder =>
+ {
+ var scenariosInFolder = filteredFeatures
+ .Where(f => f.RelativeFolder.StartsWith(folder))
+ .SelectMany(f => f.Feature.FeatureElements)
+ .Where(s => filteredScenarios.Contains(s))
+ .ToList();
+
+ return new
+ {
+ Folder = folder,
+ Total = scenariosInFolder.Count,
+ Passing = scenariosInFolder.LongCount(x => x.Result.WasExecuted && x.Result.WasSuccessful),
+ Failing = scenariosInFolder.LongCount(x => x.Result.WasExecuted && !x.Result.WasSuccessful),
+ Inconclusive = scenariosInFolder.LongCount(x => !x.Result.WasExecuted)
+ };
+ });
+
+ var notTestedScenarios = features
+ .Where(f => f.Feature.Tags.Contains("@NotTested")).SelectMany(f => f.Feature.FeatureElements)
+ .Union(scenarios.Where(s => s.Tags.Contains("@NotTested")))
+ .Distinct()
+ .ToList();
+
+ // calculate top-level folder summary - @NotTested scenarios only
+ var topLevelNotTestedFolderSummary = features
+ .Select(x => topLevelFolderName.Replace(x.RelativeFolder, "$1"))
+ .Distinct()
+ .Select(folder =>
+ {
+ var notTestedScenariosInFolder = filteredFeatures
+ .Where(f => f.RelativeFolder.StartsWith(folder))
+ .SelectMany(f => f.Feature.FeatureElements)
+ .Where(s => notTestedScenarios.Contains(s))
+ .ToList();
+
+ return new
+ {
+ Folder = folder,
+ Total = notTestedScenariosInFolder.Count,
+ Passing = notTestedScenariosInFolder.LongCount(x => x.Result.WasExecuted && x.Result.WasSuccessful),
+ Failing = notTestedScenariosInFolder.LongCount(x => x.Result.WasExecuted && !x.Result.WasSuccessful),
+ Inconclusive = notTestedScenariosInFolder.LongCount(x => !x.Result.WasExecuted)
+ };
+ });
+
+ return new
+ {
+ Tags = tagSummary,
+ Folders = topLevelFolderSummary,
+ NotTestedFolders = topLevelNotTestedFolderSummary,
+ Scenarios = new
+ {
+ Total = filteredScenarios.Count,
+ Passing = filteredScenarios.LongCount(x => x.Result.WasExecuted && x.Result.WasSuccessful),
+ Failing = filteredScenarios.LongCount(x => x.Result.WasExecuted && !x.Result.WasSuccessful),
+ Inconclusive = filteredScenarios.LongCount(x => !x.Result.WasExecuted)
+ },
+ Features = new
+ {
+ Total = filteredFeatures.Count,
+ Passing = filteredFeatures.LongCount(x => x.Result.WasExecuted && x.Result.WasSuccessful),
+ Failing = filteredFeatures.LongCount(x => x.Result.WasExecuted && !x.Result.WasSuccessful),
+ Inconclusive = filteredFeatures.LongCount(x => !x.Result.WasExecuted)
+ }
+ };
+ }
}
}
diff --git a/src/Pickles/Pickles/FeatureToggles/AlternateMarkdownProvider.cs b/src/Pickles/Pickles/FeatureToggles/AlternateMarkdownProvider.cs
new file mode 100644
index 000000000..85bc6b635
--- /dev/null
+++ b/src/Pickles/Pickles/FeatureToggles/AlternateMarkdownProvider.cs
@@ -0,0 +1,28 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// 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.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+using FeatureSwitcher;
+
+namespace PicklesDoc.Pickles.FeatureToggles
+{
+ public class AlternateMarkdownProvider : IFeature
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/Pickles/Pickles/Pickles.csproj b/src/Pickles/Pickles/Pickles.csproj
index aeb57fbd0..b92a5ec1a 100644
--- a/src/Pickles/Pickles/Pickles.csproj
+++ b/src/Pickles/Pickles/Pickles.csproj
@@ -51,10 +51,17 @@
..\packages\DocumentFormat.OpenXml.2.5\lib\DocumentFormat.OpenXml.dll
True
+
+ ..\packages\FeatureSwitcher.1.1.0\lib\4.0\FeatureSwitcher.dll
+ True
+
..\packages\Gherkin.3.2.0\lib\net45\Gherkin.dll
True
+
+ ..\packages.nonnuget\Strike.Jint\Jint.dll
+
False
..\packages\MarkdownDeep.NET.1.5\lib\.NetFramework 3.5\MarkdownDeep.dll
@@ -75,6 +82,9 @@
..\packages\NLog.4.2.3\lib\net45\NLog.dll
True
+
+ ..\packages.nonnuget\Strike.Jint\Strike.Jint.dll
+
@@ -177,6 +187,7 @@
+
@@ -194,6 +205,7 @@
Resources.resx
+
@@ -314,6 +326,21 @@
Pickles.TestFrameworks
+
+
+ Resources\Dhtml\js\Chart.min.js
+
+
+
+
+ Resources\Dhtml\js\Chart.StackedBar.js
+
+
+
+
+ Resources\Dhtml\js\picklesOverview.js
+
+