Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(validation): validate concerto objects from dotnet using node #29

Merged
merged 14 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ jobs:

strategy:
matrix:
node-version: [18.x, 20.x]
dotnet-version: ['6.0.x' ]
os:
- ubuntu-latest
Expand All @@ -23,6 +24,11 @@ jobs:
steps:
- name: git checkout
uses: actions/checkout@v2

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}

- name: Setup .NET Core SDK ${{ matrix.dotnet-version }}
uses: actions/setup-dotnet@v2
Expand All @@ -32,6 +38,7 @@ jobs:
run: |
dotnet restore AccordProject.Concerto.sln
dotnet restore ConcertoJsonConverter.sln
cd AccordProject.Concerto.Validate/concerto-validate && npm ci
- name: Build
run: |
dotnet build AccordProject.Concerto.sln --configuration Release --no-restore
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ jobs:

strategy:
matrix:
node-version: [20.x]
dotnet-version: ['6.0.x' ]
os:
- ubuntu-latest
Expand All @@ -31,6 +32,7 @@ jobs:
run: |
dotnet restore AccordProject.Concerto.sln
dotnet restore ConcertoJsonConverter.sln
cd AccordProject.Concerto.Validate/concerto-validate && npm ci
- name: Build
run: |
dotnet build AccordProject.Concerto.sln --configuration Release --no-restore
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,9 @@ FakesAssemblies/
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
*/node_modules/
*/dist/
dist/

# Visual Studio 6 build log
*.plg
Expand Down
10 changes: 5 additions & 5 deletions AccordProject.Concerto.Tests/AccordProject.Concerto.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@

<ItemGroup>
<PackageReference Include="ExpectedObjects" Version="3.5.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="xunit" Version="2.6.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.4">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<PackageReference Include="coverlet.collector" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace AccordProject.Concerto.Tests;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

[Collection("Sequential")]
public class ConcertoConverterNewtonsoftDeserializeTests
{
[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace AccordProject.Concerto.Tests;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

[Collection("Sequential")]
public class ConcertoConverterNewtonsoftMetamodelTests
{
[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace AccordProject.Concerto.Tests;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

[Collection("Sequential")]
public class ConcertoConverterNewtonsoftSerializeTests
{
[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace AccordProject.Concerto.Tests;
using AccordProject.Concerto;
using AccordProject.Concerto.Metamodel;

[Collection("Sequential")]
public class ConcertoTypeDictionaryTests
{
[Fact]
Expand Down
1 change: 1 addition & 0 deletions AccordProject.Concerto.Tests/ConcertoUtilsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace AccordProject.Concerto.Tests;
using System;
using AccordProject.Concerto;

[Collection("Sequential")]
public class ConcertoUtilsTests
{
[Fact]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.1" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.2.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.ClearScript.Complete" Version="7.4.4" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\AccordProject.Concerto.Validate\AccordProject.Concerto.Validate.csproj" />
</ItemGroup>
<ItemGroup>
<None Remove="Fixtures\" />
</ItemGroup>
<ItemGroup>
<None Update="Fixtures\testModelAST.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Fixtures\testInstanceInvalid.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Fixtures\testInstanceValid.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="Fixtures\" />
</ItemGroup>
<ItemGroup>
<Compile Condition=" '$(EnableDefaultCompileItems)' == 'true' " Update="GlobalUsings.cs">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Compile>
<Compile Condition=" '$(EnableDefaultCompileItems)' == 'true' " Update="UnitTest1.cs">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Compile>
<Compile Condition=" '$(EnableDefaultCompileItems)' == 'true' " Update="ValidationTests.cs">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Compile>
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"$class": "[email protected]",
"value": 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"$class": "[email protected]",
"value": "Hello, World!"
}
58 changes: 58 additions & 0 deletions AccordProject.Concerto.Validate.Tests/Fixtures/testModelAST.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"$class": "[email protected]",
"decorators": [],
"namespace": "[email protected]",
"imports": [],
"declarations": [
{
"$class": "[email protected]",
"name": "Basic",
"isAbstract": false,
"properties": [
{
"$class": "[email protected]",
"name": "value",
"isArray": false,
"isOptional": false
}
]
},
{
"$class": "[email protected]",
"name": "Thing",
"isAbstract": false,
"properties": [
{
"$class": "[email protected]",
"name": "id",
"isArray": false,
"isOptional": false
},
{
"$class": "[email protected]",
"name": "value",
"isArray": false,
"isOptional": false
}
],
"identified": {
"$class": "[email protected]",
"name": "id"
}
},
{
"$class": "[email protected]",
"name": "Defaults",
"isAbstract": false,
"properties": [
{
"$class": "[email protected]",
"name": "value",
"isArray": false,
"isOptional": false,
"defaultValue": "Hello, World!"
}
]
}
]
}
1 change: 1 addition & 0 deletions AccordProject.Concerto.Validate.Tests/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
global using Xunit;
47 changes: 47 additions & 0 deletions AccordProject.Concerto.Validate.Tests/ValidationTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using Microsoft.ClearScript.V8;
using AccordProject.Concerto.Validate;
using Jering.Javascript.NodeJS;
using Microsoft.Extensions.DependencyInjection;

namespace AccordProject.Concerto.Validate.Tests;

public class ValidationTests
{

[Fact]
public async void GivenValidModelWhenValidateCalledThenIsValidShouldBeTrue()
{

var model = File.ReadAllText("Fixtures/testModelAST.json");
var instance = File.ReadAllText("Fixtures/testInstanceValid.json");
var services = new ServiceCollection();
services.AddNodeJS();
ServiceProvider serviceProvider = services.BuildServiceProvider();
INodeJSService nodeJSService = serviceProvider.GetRequiredService<INodeJSService>();


var validator = new Validator(nodeJSService);
String[] models = { model };
var result =await validator.Validate(models, instance);
Assert.True(result.IsValid);
}

[Fact]
public async void GivenInvalidModelWhenValidateCalledThenIsValidShouldBeFalseAndMessageShouldBePresent()
{

var model = File.ReadAllText("Fixtures/testModelAST.json");
var instance = File.ReadAllText("Fixtures/testInstanceInvalid.json");
var services = new ServiceCollection();
services.AddNodeJS();
ServiceProvider serviceProvider = services.BuildServiceProvider();
INodeJSService nodeJSService = serviceProvider.GetRequiredService<INodeJSService>();


var validator = new Validator(nodeJSService);
String[] models = { model };
var result = await validator.Validate(models, instance);
Assert.False(result.IsValid);
Assert.NotEmpty(result.ErrorMessage);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<LangVersion>10.0</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<LangVersion>10.0</LangVersion>
</PropertyGroup>
<Target Name="WebPack" BeforeTargets="CoreCompile" DependsOnTargets="PrepareForBuild">
<Exec Command="npm run build" WorkingDirectory="./concerto-validate" />
</Target>
<ItemGroup>
<None Update="concerto-core.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="concerto-validate\dist\validate.js">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Jering.Javascript.NodeJS" Version="7.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
</Project>
27 changes: 27 additions & 0 deletions AccordProject.Concerto.Validate/Validator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using System.Threading.Tasks;
using Jering.Javascript.NodeJS;
using System.IO;
using Newtonsoft.Json;

namespace AccordProject.Concerto.Validate
{
public class Validator
{
private INodeJSService nodeJSService { get; set; }
private string script { get; set; }
public Validator(INodeJSService nodeJSService) {
this.nodeJSService = nodeJSService;
this.script = File.ReadAllText("concerto-validate/dist/validate.js");
}

public async Task<ValidationResult> Validate(string[] modelJson, string instanceJson)
{
var models = "[" + string.Join(",\n", modelJson) + "]";
var args = new[] { models, instanceJson };
var cacheIdentifier = "validate";
return await nodeJSService.InvokeFromStringAsync<ValidationResult>(script, cacheIdentifier, "validateInstance", args);
}
}
}

1 change: 1 addition & 0 deletions AccordProject.Concerto.Validate/concerto-validate/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
registry = "https://registry.npmjs.com/"
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
namespace AccordProject.Concerto.Validate
{
public class ValidationResult
{
public string Instance { get; set; }
public string Id { get; set; }
public Boolean IsValid { get; set; }
public string ErrorMessage{ get; set; }
}
}

Loading
Loading