Skip to content

Commit

Permalink
Add json validator (#368)
Browse files Browse the repository at this point in the history
* The start of json validator

* Start json validator as fsx file for maximum speeeeeeeed

* json validator working for missing

* jsonvalidator added checks for extra properties

* json validator, much progress, pick up on fields in optional records that are missing

* json validator now recognizes missing properties on optional types

* json validator working, no self on property

* json validator incorrect arrays working

* add more tests for more complex objects to json validator

* add to proj file

* jsonValidator final stages
  • Loading branch information
lefthandedgoat authored May 23, 2017
1 parent 55de1a4 commit 65075f9
Show file tree
Hide file tree
Showing 13 changed files with 575 additions and 9 deletions.
8 changes: 5 additions & 3 deletions csharptests/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ static void Main(string[] args)
configuration.reporter = new reporters.LiveHtmlReporter(types.BrowserStartMode.Chrome, configuration.chromeDir);

var testpage = "http://lefthandedgoat.github.io/canopy/testpages/";

jsonValidatorTests.All();

_.start(types.BrowserStartMode.Chrome);

Expand All @@ -27,7 +29,7 @@ static void Main(string[] args)
{
_.url("http://www.skipped.com");
});

_.test("Apostrophes don't break anything", () =>
{
_.url(testpage);
Expand Down Expand Up @@ -70,7 +72,7 @@ static void Main(string[] args)
_.write("#lastName", "Smith");
_.eq("#lastName", "Smith");
});

_.test("writing to #lastName (as element) sets text to John", () =>
{
_.url(testpage);
Expand Down Expand Up @@ -118,7 +120,7 @@ static void Main(string[] args)
_.rightClick("div:first");
_.displayed(".contextmenu");
});

_.run();

Console.ReadKey();
Expand Down
5 changes: 3 additions & 2 deletions csharptests/csharptests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,12 @@
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="WebDriver">
<Reference Include="WebDriver">
<HintPath>..\packages\Selenium.WebDriver\lib\net40\WebDriver.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="jsonValidatorTests.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
Expand All @@ -65,5 +66,5 @@
</Target>
<Target Name="AfterBuild">
</Target>
-->
-->
</Project>
106 changes: 106 additions & 0 deletions csharptests/jsonValidatorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
using System.Collections.Generic;
using _ = canopy.csharp.canopy;

namespace csharptests
{
public class jsonValidatorTests
{
static string person1 = @"{ ""first"":""jane"", ""middle"":""something"", ""last"":""doe"" }";
static string person2 = @"{ ""first"":""jane"", ""last"":""doe"" } ";
static string person3 = @"{ ""first"":""jane"", ""middle"":""something"", ""last"":""doe"", ""phone"":""800-555-5555"" } ";

static string location1 = @"{ ""lat"":4.0212, ""long"":12.102012, ""people"":[ 1, 2, 3 ] } ";
static string location2 = @"{ ""lat"":4.0212, ""long"":12.102012, ""people"":[ ] } ";

static string location3 = @"{ ""lat"":4.0212, ""long"":12.102012, ""people"":[ { ""first"":""jane"", ""middle"":""something"", ""last"":""doe"" } ] } ";
static string location4 = @"{ ""lat"":4.0212, ""long"":12.102012, ""people"":[ ] } ";
static string location5 = @"{ ""lat"":4.0212, ""long"":12.102012, ""people"":[ { ""first"":""jane"", ""last"":""doe"" } ] } ";
static string location6 = @"{ ""lat"":4.0212, ""long"":12.102012, ""people"":[ { ""first"":""jane"", ""middle"":""something"", ""last"":""doe"", ""phone"":""800-555-5555"" } ] } ";

static string location7 = @"{ ""lat"":4.0212, ""long"":12.102012, ""workers"":[ { ""first"":""jane"", ""last"":""doe"" } ] } ";
static string location8 = @"{ ""lat"":4.0212, ""long"":12.102012, ""people"":[ { ""first"":""jane"", ""middle"":""something"", ""last"":""doe"", ""phone"":""800-555-5555"" } ] } ";

static string class1 = @"{ ""name"":""bio 101"", ""building"":""science"", ""location"": { ""lat"":4.0212, ""long"":12.102012, ""people"": [ { ""first"":""jane"", ""middle"":""something"", ""last"":""doe"" } ] } }";
static string class2 = @"{ ""name"":""chem 101"", ""building"":""science"", ""location"": { ""lat"":4.0212, ""lng"":12.102012, ""people"": [ { ""first"":""jane"", ""last"":""doe"" } ] } }";

static List<string> empty = new List<string>();

public static void All()
{
_.context("json validator tests");

_.test("two identical people have no differences", () =>
{
var diff = _.diffJson(person1, person1);
_.equality(diff.Count, empty.Count);
_.validateJson(person1, person1);
});

_.test("missing property is identified", () =>
{
var diff = _.diffJson(person1, person2);
_.equality(1, diff.Count);
_.equality(true, diff.Contains("Missing {root}.middle"));
});

_.test("extra property is identified", () =>
{
var diff = _.diffJson(person1, person3);
_.equality(1, diff.Count);
_.equality(true, diff.Contains("Extra {root}.phone"));
});

_.test("empty array is acceptable array of ints", () =>
{
var diff = _.diffJson(location1, location2);
_.equality(diff.Count, empty.Count);
_.validateJson(location1, location2);
});

_.test("empty array is acceptable array of records", () =>
{
var diff = _.diffJson(location3, location4);
_.equality(diff.Count, empty.Count);
_.validateJson(location3, location4);
});

_.test("missing fields on records in arrays recognized correctly", () =>
{
var diff = _.diffJson(location3, location5);
_.equality(1, diff.Count);
_.equality(true, diff.Contains("Missing {root}.[people].{}.middle"));
});

_.test("extra fields on records in arrays recognized correctly", () =>
{
var diff = _.diffJson(location3, location6);
_.equality(1, diff.Count);
_.equality(true, diff.Contains("Extra {root}.[people].{}.phone"));
});

_.test("renamed field with extra property shows", () =>
{
var diff = _.diffJson(location7, location8);
_.equality(7, diff.Count);
_.equality(true, diff.Contains("Missing {root}.[workers]"));

_.equality(true, diff.Contains("Extra {root}.[people]"));
_.equality(true, diff.Contains("Extra {root}.[people].{}"));
_.equality(true, diff.Contains("Extra {root}.[people].{}.first"));
_.equality(true, diff.Contains("Extra {root}.[people].{}.last"));
_.equality(true, diff.Contains("Extra {root}.[people].{}.middle"));
_.equality(true, diff.Contains("Extra {root}.[people].{}.phone"));
});

_.test("nested objects with arrays reocgnized correctly", () =>
{
var diff = _.diffJson(class1, class2);
_.equality(3, diff.Count);
_.equality(true, diff.Contains("Missing {root}.{location}.long"));
_.equality(true, diff.Contains("Missing {root}.{location}.[people].{}.middle"));

_.equality(true, diff.Contains("Extra {root}.{location}.lng"));
});
}
}
}
3 changes: 2 additions & 1 deletion paket.dependencies
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ nuget NuGet.CommandLine
nuget FSharp.Core >= 3.0.2 lowest_matching:true
nuget Selenium.WebDriver
nuget FAKE
nuget FSharp.Formatting
nuget FSharp.Formatting
nuget FSharp.Data
3 changes: 3 additions & 0 deletions paket.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ NUGET
FAKE (4.52)
FSharp.Compiler.Service (2.0.0.6)
FSharp.Core (3.0.2)
FSharp.Data (2.3.3)
Zlib.Portable (>= 1.11) - framework: >= netstandard11, portable-net45+sl5+win8, portable-net45+win8, portable-net45+win8+wp8+wpa81
FSharp.Formatting (2.14.4)
FSharp.Compiler.Service (2.0.0.6)
FSharpVSPowerTools.Core (>= 2.3 < 2.4)
FSharpVSPowerTools.Core (2.3)
FSharp.Compiler.Service (>= 2.0.0.3)
NuGet.CommandLine (3.5)
Selenium.WebDriver (3.4)
Zlib.Portable (1.11) - framework: >= netstandard11, portable-net45+sl5+win8, portable-net45+win8, portable-net45+win8+wp8+wpa81
56 changes: 55 additions & 1 deletion src/canopy/canopy.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,10 @@
<None Include="paket.references" />
<Compile Include="screenSizes.fs" />
<Compile Include="userAgents.fs" />
<Compile Include="jsonValidator.fs" />
<Compile Include="csharp.fs" />
<None Include="companion\companion.fsx" />
<None Include="jsValidator.fsx" />
</ItemGroup>
<ItemGroup>
<Reference Include="mscorlib" />
Expand All @@ -75,7 +77,7 @@
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
Expand Down Expand Up @@ -112,6 +114,47 @@
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v4.0' Or $(TargetFrameworkVersion) == 'v4.5' Or $(TargetFrameworkVersion) == 'v4.5.1' Or $(TargetFrameworkVersion) == 'v4.5.2' Or $(TargetFrameworkVersion) == 'v4.5.3' Or $(TargetFrameworkVersion) == 'v4.6' Or $(TargetFrameworkVersion) == 'v4.6.1' Or $(TargetFrameworkVersion) == 'v4.6.2' Or $(TargetFrameworkVersion) == 'v4.6.3')">
<ItemGroup>
<Reference Include="System.Xml.Linq">
<Paket>True</Paket>
</Reference>
<Reference Include="FSharp.Data">
<HintPath>..\..\packages\FSharp.Data\lib\net40\FSharp.Data.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
<When Condition="($(TargetFrameworkIdentifier) == '.NETCore') Or ($(TargetFrameworkIdentifier) == '.NETStandard' And ($(TargetFrameworkVersion) == 'v1.1' Or $(TargetFrameworkVersion) == 'v1.2' Or $(TargetFrameworkVersion) == 'v1.3' Or $(TargetFrameworkVersion) == 'v1.4' Or $(TargetFrameworkVersion) == 'v1.5' Or $(TargetFrameworkVersion) == 'v1.6')) Or ($(TargetFrameworkIdentifier) == '.NETCoreApp' And $(TargetFrameworkVersion) == 'v1.0') Or ($(TargetFrameworkIdentifier) == 'MonoAndroid') Or ($(TargetFrameworkIdentifier) == 'MonoTouch') Or ($(TargetFrameworkIdentifier) == 'Xamarin.iOS') Or ($(TargetFrameworkIdentifier) == 'Xamarin.Mac') Or ($(TargetFrameworkProfile) == 'Profile7') Or ($(TargetFrameworkProfile) == 'Profile44')">
<ItemGroup>
<Reference Include="FSharp.Data">
<HintPath>..\..\packages\FSharp.Data\lib\portable-net45+netcore45\FSharp.Data.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
<When Condition="($(TargetFrameworkIdentifier) == 'WindowsPhoneApp') Or ($(TargetFrameworkIdentifier) == '.NETStandard' And $(TargetFrameworkVersion) == 'v1.0') Or ($(TargetFrameworkIdentifier) == 'WindowsPhone' And ($(TargetFrameworkVersion) == 'v8.0' Or $(TargetFrameworkVersion) == 'v8.1')) Or ($(TargetFrameworkProfile) == 'Profile31') Or ($(TargetFrameworkProfile) == 'Profile32') Or ($(TargetFrameworkProfile) == 'Profile49') Or ($(TargetFrameworkProfile) == 'Profile78') Or ($(TargetFrameworkProfile) == 'Profile84') Or ($(TargetFrameworkProfile) == 'Profile111') Or ($(TargetFrameworkProfile) == 'Profile151') Or ($(TargetFrameworkProfile) == 'Profile157') Or ($(TargetFrameworkProfile) == 'Profile259')">
<ItemGroup>
<Reference Include="FSharp.Data">
<HintPath>..\..\packages\FSharp.Data\lib\portable-net45+netcore45+wpa81+wp8\FSharp.Data.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
<When Condition="($(TargetFrameworkIdentifier) == 'Silverlight' And $(TargetFrameworkVersion) == 'v5.0') Or ($(TargetFrameworkProfile) == 'Profile24') Or ($(TargetFrameworkProfile) == 'Profile47')">
<ItemGroup>
<Reference Include="FSharp.Data">
<HintPath>..\..\packages\FSharp.Data\lib\portable-net45+sl50+netcore45\FSharp.Data.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v3.5'">
<ItemGroup>
Expand All @@ -132,4 +175,15 @@
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="($(TargetFrameworkProfile) == 'Profile5') Or ($(TargetFrameworkProfile) == 'Profile6') Or ($(TargetFrameworkProfile) == 'Profile7') Or ($(TargetFrameworkProfile) == 'Profile14') Or ($(TargetFrameworkProfile) == 'Profile19') Or ($(TargetFrameworkProfile) == 'Profile24') Or ($(TargetFrameworkProfile) == 'Profile31') Or ($(TargetFrameworkProfile) == 'Profile32') Or ($(TargetFrameworkProfile) == 'Profile37') Or ($(TargetFrameworkProfile) == 'Profile42') Or ($(TargetFrameworkProfile) == 'Profile44') Or ($(TargetFrameworkProfile) == 'Profile47') Or ($(TargetFrameworkProfile) == 'Profile49') Or ($(TargetFrameworkProfile) == 'Profile78') Or ($(TargetFrameworkProfile) == 'Profile84') Or ($(TargetFrameworkProfile) == 'Profile92') Or ($(TargetFrameworkProfile) == 'Profile102') Or ($(TargetFrameworkProfile) == 'Profile111') Or ($(TargetFrameworkProfile) == 'Profile136') Or ($(TargetFrameworkProfile) == 'Profile147') Or ($(TargetFrameworkProfile) == 'Profile151') Or ($(TargetFrameworkProfile) == 'Profile157') Or ($(TargetFrameworkProfile) == 'Profile158') Or ($(TargetFrameworkProfile) == 'Profile225') Or ($(TargetFrameworkProfile) == 'Profile240') Or ($(TargetFrameworkProfile) == 'Profile255') Or ($(TargetFrameworkProfile) == 'Profile259') Or ($(TargetFrameworkProfile) == 'Profile328') Or ($(TargetFrameworkProfile) == 'Profile336') Or ($(TargetFrameworkProfile) == 'Profile344')">
<ItemGroup>
<Reference Include="Zlib.Portable">
<HintPath>..\..\packages\Zlib.Portable\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
</Project>
9 changes: 8 additions & 1 deletion src/canopy/csharp.fs
Original file line number Diff line number Diff line change
Expand Up @@ -202,4 +202,11 @@ type canopy () =

static member onn url = onn url

static member on url = on url
static member on url = on url

static member diffJson example actual =
let diff = jsonValidator.diff example actual
let diffString = diff |> List.map (fun d -> match d with | jsonValidator.Missing s -> sprintf "Missing %s" s | jsonValidator.Extra s -> sprintf "Extra %s" s)
ResizeArray<string>(diffString)

static member validateJson example actual = jsonValidator.validate example actual
Loading

0 comments on commit 65075f9

Please sign in to comment.