Skip to content

Commit

Permalink
iteration two, ready for consumption by pac cli
Browse files Browse the repository at this point in the history
  • Loading branch information
abaskk-msft committed Jul 15, 2024
1 parent ef050cd commit ca58cc6
Show file tree
Hide file tree
Showing 12 changed files with 95 additions and 158 deletions.
20 changes: 20 additions & 0 deletions src/Persistence.Tests/YamlValidator/ValidatorFactoryTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using Microsoft.PowerPlatform.PowerApps.Persistence.YamlValidator;

namespace Persistence.Tests.YamlValidator;

[TestClass]
public class ValidatorFactoryTest
{
[TestMethod]
public void GetValidatorTest()
{
var factory = new ValidatorFactory();
var validator = factory.GetValidator();

Assert.IsNotNull(validator);
Assert.IsInstanceOfType(validator, typeof(Validator));
}
}
17 changes: 7 additions & 10 deletions src/Persistence.Tests/YamlValidator/ValidatorTest.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using Json.Schema;
using Microsoft.PowerPlatform.PowerApps.Persistence.YamlValidator;

namespace Persistence.Tests.YamlValidator;
Expand All @@ -16,15 +15,12 @@ public class ValidatorTest
private static readonly string _invalidPath = Path.Combine(".", "_TestData", "ValidatorTests", "InvalidYaml") +
Path.DirectorySeparatorChar;

private readonly JsonSchema _schema;
private readonly Validator _yamlValidator;

public ValidatorTest()
{
var schemaFileLoader = new SchemaLoader();
_schema = schemaFileLoader.Load();
var resultVerbosity = new VerbosityData(Constants.Verbose);
_yamlValidator = new Validator(resultVerbosity.EvalOptions, resultVerbosity.JsonOutputOptions);
var validatorFactory = new ValidatorFactory();
_yamlValidator = validatorFactory.GetValidator();
}

[TestMethod]
Expand All @@ -34,8 +30,8 @@ public ValidatorTest()

public void TestValidationValidYaml(string filename)
{
var rawYaml = Utility.ReadFileData($@"{_validPath}{filename}");
var result = _yamlValidator.Validate(_schema, rawYaml);
var rawYaml = File.ReadAllText($@"{_validPath}{filename}");
var result = _yamlValidator.Validate(rawYaml);
Assert.IsTrue(result.SchemaValid);
}

Expand All @@ -48,10 +44,11 @@ public void TestValidationValidYaml(string filename)
[DataRow("EmptyArray.yaml")]
[DataRow("Empty.yaml")]
[DataRow("NamelessObjectNoControl.yaml")]
[DataRow("NotYaml.yaml")]
public void TestValidationInvalidYaml(string filename)
{
var rawYaml = Utility.ReadFileData($@"{_invalidPath}{filename}");
var result = _yamlValidator.Validate(_schema, rawYaml);
var rawYaml = File.ReadAllText($@"{_invalidPath}{filename}");
var result = _yamlValidator.Validate(rawYaml);
Assert.IsFalse(result.SchemaValid);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
features => [
{
name => lorem ipsum,
points => [
"bullet 1",
"bullet 2"
]
},
{
name => lorem ipsum 2,
description => lorem ipsum 3
}
]
}
9 changes: 2 additions & 7 deletions src/Persistence/YamlValidator/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,9 @@ namespace Microsoft.PowerPlatform.PowerApps.Persistence.YamlValidator;

public static class Constants
{
public const string FileTypeName = "file";
public const string FolderTypeName = "folder";
public const string YamlFileExtension = ".pa.yaml";
public const string JsonFileExtension = ".json";

public const string Verbose = "verbose";

// runtime constants
// default schema path
public static readonly string DefaultSchemaPath = Path.Combine(".", "schema", "pa.yaml-schema.json");
public const string notYamlError = "File is not YAML";
public const string emptyYamlError = "Empty YAML file";
}
4 changes: 2 additions & 2 deletions src/Persistence/YamlValidator/SchemaLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ namespace Microsoft.PowerPlatform.PowerApps.Persistence.YamlValidator;

public class SchemaLoader
{
private const string _schemaFolderPath = "subschemas";
private const string _subschemaFolderPath = "subschemas";
private static readonly string _schemaPath = Path.Combine(".", "YamlValidator", "schema", "pa.yaml-schema.json");

public JsonSchema Load()
{
var node = JsonSchema.FromFile(_schemaPath);
var schemaFolder = Path.GetDirectoryName(_schemaPath);
var subschemaPaths = Directory.GetFiles($@"{schemaFolder}{Path.DirectorySeparatorChar}{_schemaFolderPath}",
var subschemaPaths = Directory.GetFiles($@"{schemaFolder}{Path.DirectorySeparatorChar}{_subschemaFolderPath}",
$"*{Constants.JsonFileExtension}");

foreach (var path in subschemaPaths)
Expand Down
6 changes: 0 additions & 6 deletions src/Persistence/YamlValidator/Utility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,6 @@ namespace Microsoft.PowerPlatform.PowerApps.Persistence.YamlValidator;

public class Utility
{
public static string ReadFileData(string filePath)
{
var yamlData = File.ReadAllText(filePath);
return yamlData;
}

public static YamlStream MakeYamlStream(string yamlString)
{
var stream = new YamlStream();
Expand Down
40 changes: 0 additions & 40 deletions src/Persistence/YamlValidator/ValidationProcessor.cs

This file was deleted.

6 changes: 0 additions & 6 deletions src/Persistence/YamlValidator/ValidationRequest.cs

This file was deleted.

31 changes: 18 additions & 13 deletions src/Persistence/YamlValidator/Validator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,45 @@
using Json.Schema;
using Yaml2JsonNode;
using System.Text.Json;
using YamlDotNet.Core;
using YamlDotNet.RepresentationModel;

namespace Microsoft.PowerPlatform.PowerApps.Persistence.YamlValidator;

public class Validator
{
private readonly EvaluationOptions _verbosityOptions;
private readonly JsonSerializerOptions _serializerOptions;

Check failure on line 14 in src/Persistence/YamlValidator/Validator.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

Private member 'Validator._serializerOptions' can be removed as the value assigned to it is never read (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0052)

Check failure on line 14 in src/Persistence/YamlValidator/Validator.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

Private member 'Validator._serializerOptions' can be removed as the value assigned to it is never read (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0052)

public Validator(EvaluationOptions options, JsonSerializerOptions resultSerializeOptions)
private readonly JsonSchema _schema;
public Validator(EvaluationOptions options, JsonSerializerOptions resultSerializeOptions, JsonSchema schema)
{
// to do: add verbosity flag and allow users to choose verbosity of evaluation
_verbosityOptions = options;
_serializerOptions = resultSerializeOptions;
_schema = schema;
}

public ValidatorResults Validate(JsonSchema schema, string yamlFileData)
public ValidatorResults Validate(string yamlFileData)
{
var yamlStream = Utility.MakeYamlStream(yamlFileData);
YamlStream yamlStream;
try
{
yamlStream = Utility.MakeYamlStream(yamlFileData);
}
catch (YamlException)
{
return new ValidatorResults(false, new List<ValidatorError> { new(Constants.notYamlError) });
}

var jsonData = yamlStream.Documents.Count > 0 ? yamlStream.Documents[0].ToJsonNode() : null;

// here we say that empty yaml is serialized as null json
if (jsonData == null)
{
return new ValidatorResults(false, new List<ValidatorError> { new("Empty YAML file") });
return new ValidatorResults(false, new List<ValidatorError> { new(Constants.emptyYamlError) });
}
var results = schema.Evaluate(jsonData, _verbosityOptions);

// not used but may help if we ever need to serialize the evaluation results into json format to feed into
// a VSCode extension or other tool
var output = JsonSerializer.Serialize(results, _serializerOptions);
var results = _schema.Evaluate(jsonData, _verbosityOptions);

var schemaValidity = results.IsValid;
// TBD: filter actual errors versus false positives
// we look for errors that are not valid, have errors, and have an instance location (i.e are not oneOf errors)
var yamlValidatorErrors = new List<ValidatorError>();
if (!schemaValidity)
{
Expand Down
31 changes: 31 additions & 0 deletions src/Persistence/YamlValidator/ValidatorFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using Json.Schema;
using System.Text.Json;

namespace Microsoft.PowerPlatform.PowerApps.Persistence.YamlValidator;

public class ValidatorFactory
{
public Validator GetValidator()
{
// register schema in from memory into global schema registry
var schemaLoader = new SchemaLoader();
var serializedSchema = schemaLoader.Load();

var evalOptions = new EvaluationOptions
{
OutputFormat = OutputFormat.List
};

// pass in serailization options for validator results object to json
// This is unused for now but can be useful for producing raw json validation results which can be consumed elsewhere
var resultSerializeOptions = new JsonSerializerOptions
{
Converters = { new EvaluationResultsJsonConverter() }
};

return new Validator(evalOptions, resultSerializeOptions, serializedSchema);
}
}
25 changes: 0 additions & 25 deletions src/Persistence/YamlValidator/VerbosityData.cs

This file was deleted.

49 changes: 0 additions & 49 deletions src/Persistence/YamlValidator/YamlLoader.cs

This file was deleted.

0 comments on commit ca58cc6

Please sign in to comment.