Skip to content

Commit

Permalink
Improve dataAttributeTheoryTests so that they can run individually in…
Browse files Browse the repository at this point in the history
… Rider (#682)

* Improve dataAttributeTheoryTests so that they can run individually in Rider

Use simple types and delay loading of the actual files to when it runs to get exception at the correct location.

* Make LoadData method static
  • Loading branch information
ivarne authored Jun 13, 2024
1 parent f858d9c commit 54ffade
Show file tree
Hide file tree
Showing 7 changed files with 248 additions and 252 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#nullable disable
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
Expand All @@ -12,12 +10,12 @@
using Altinn.App.Core.Models.Validation;
using Altinn.App.Core.Tests.Helpers;
using Altinn.App.Core.Tests.LayoutExpressions;
using Altinn.App.Core.Tests.TestUtils;
using Altinn.Platform.Storage.Interface.Models;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Moq;
using Xunit.Sdk;

namespace Altinn.App.Core.Tests.Features.Validators.Default;

Expand All @@ -37,7 +35,7 @@ public ExpressionValidatorTests()
_appMetadata
.Setup(ar => ar.GetApplicationMetadata())
.ReturnsAsync(new ApplicationMetadata("org/app") { DataTypes = new List<DataType>() { new() { } } });
_appResources.Setup(ar => ar.GetLayoutSetForTask(null)).Returns(new LayoutSet());
_appResources.Setup(ar => ar.GetLayoutSetForTask(It.IsAny<string>())).Returns(new LayoutSet());
_layoutInitializer = new(MockBehavior.Strict, _appResources.Object, _frontendSettings) { CallBase = false };
_validator = new ExpressionValidator(
_logger.Object,
Expand All @@ -47,10 +45,32 @@ public ExpressionValidatorTests()
);
}

private static readonly JsonSerializerOptions _jsonSerializerOptions =
new() { ReadCommentHandling = JsonCommentHandling.Skip, PropertyNamingPolicy = JsonNamingPolicy.CamelCase, };

public ExpressionValidationTestModel LoadData(string fileName, string folder)
{
var data = File.ReadAllText(Path.Join(folder, fileName));
return JsonSerializer.Deserialize<ExpressionValidationTestModel>(data, _jsonSerializerOptions)!;
}

[Theory]
[ExpressionTest]
public async Task RunExpressionValidationTest(ExpressionValidationTestModel testCase)
[FileNamesInFolderData("Features/Validators/expression-validation-tests/backend")]
public async Task RunExpressionValidationTestsForBackend(string fileName, string folder)
{
await RunExpressionValidationTest(fileName, folder);
}

[Theory]
[FileNamesInFolderData(["Features", "Validators", "expression-validation-tests", "shared"])]
public async Task RunExpressionValidationTestsForShared(string fileName, string folder)
{
await RunExpressionValidationTest(fileName, folder);
}

private async Task RunExpressionValidationTest(string fileName, string folder)
{
var testCase = LoadData(fileName, folder);
var instance = new Instance();
var dataElement = new DataElement();

Expand All @@ -68,7 +88,7 @@ public async Task RunExpressionValidationTest(ExpressionValidationTestModel test
)
.ReturnsAsync(evaluatorState);
_appResources
.Setup(ar => ar.GetValidationConfiguration(null))
.Setup(ar => ar.GetValidationConfiguration(It.IsAny<string>()))
.Returns(JsonSerializer.Serialize(testCase.ValidationConfig));

var validationIssues = await _validator.ValidateFormData(instance, dataElement, null!, null);
Expand All @@ -91,51 +111,28 @@ public async Task RunExpressionValidationTest(ExpressionValidationTestModel test
}
}

public class ExpressionTestAttribute : DataAttribute
{
private static readonly JsonSerializerOptions _jsonSerializerOptions =
new() { ReadCommentHandling = JsonCommentHandling.Skip, PropertyNamingPolicy = JsonNamingPolicy.CamelCase, };

public override IEnumerable<object[]> GetData(MethodInfo methodInfo)
{
var files = Directory
.GetFiles(Path.Join("Features", "Validators", "expression-validation-tests", "shared"))
.Concat(Directory.GetFiles(Path.Join("Features", "Validators", "expression-validation-tests", "backend")));

foreach (var file in files)
{
var data = File.ReadAllText(file);
ExpressionValidationTestModel testCase = JsonSerializer.Deserialize<ExpressionValidationTestModel>(
data,
_jsonSerializerOptions
)!;
yield return new object[] { testCase };
}
}
}

public class ExpressionValidationTestModel
{
public string Name { get; set; }
public required string Name { get; set; }

public ExpectedObject[] Expects { get; set; }
public required ExpectedObject[] Expects { get; set; }

public JsonElement ValidationConfig { get; set; }
public required JsonElement ValidationConfig { get; set; }

public JsonObject FormData { get; set; }
public required JsonObject FormData { get; set; }

[JsonConverter(typeof(LayoutModelConverterFromObject))]
public LayoutModel Layouts { get; set; }
public required LayoutModel Layouts { get; set; }

public class ExpectedObject
{
public string Message { get; set; }
public required string Message { get; set; }

[JsonConverter(typeof(FrontendSeverityConverter))]
public ValidationIssueSeverity Severity { get; set; }
public required ValidationIssueSeverity Severity { get; set; }

public string Field { get; set; }
public required string Field { get; set; }

public string ComponentId { get; set; }
public required string ComponentId { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,60 @@
using System.Reflection;
using System.Text.Json;
using Altinn.App.Core.Internal.Expressions;
using Altinn.App.Core.Tests.Helpers;
using Altinn.App.Core.Tests.TestUtils;
using FluentAssertions;
using Xunit.Abstractions;
using Xunit.Sdk;

namespace Altinn.App.Core.Tests.LayoutExpressions;

public class TestBackendExclusiveFunctions
{
private readonly ITestOutputHelper _output;

private static readonly JsonSerializerOptions _jsonSerializerOptions =
new() { ReadCommentHandling = JsonCommentHandling.Skip, PropertyNamingPolicy = JsonNamingPolicy.CamelCase, };

public TestBackendExclusiveFunctions(ITestOutputHelper output)
{
_output = output;
}

[Theory]
[ExclusiveTest("gatewayAction")]
public void GatewayAction_Theory(ExpressionTestCaseRoot test) => RunTestCase(test);
public void GatewayAction_Theory(string testName, string folder) => RunTestCase(testName, folder);

private void RunTestCase(ExpressionTestCaseRoot test)
private static ExpressionTestCaseRoot LoadTestCase(string testName, string folder)
{
var file = Path.Join(folder, testName);

ExpressionTestCaseRoot testCase = new();
var data = File.ReadAllText(file);
try
{
testCase = JsonSerializer.Deserialize<ExpressionTestCaseRoot>(data, _jsonSerializerOptions)!;
}
catch (Exception e)
{
using var jsonDocument = JsonDocument.Parse(data);

testCase.Name = jsonDocument.RootElement.GetProperty("name").GetString();
testCase.ExpectsFailure = jsonDocument.RootElement.TryGetProperty("expectsFailure", out var expectsFailure)
? expectsFailure.GetString()
: null;
testCase.ParsingException = e;
}

testCase.Filename = Path.GetFileName(file);
testCase.FullPath = file;
testCase.Folder = folder;
testCase.RawJson = data;

return testCase;
}

private void RunTestCase(string testName, string folder)
{
var test = LoadTestCase(testName, folder);
_output.WriteLine($"{test.Filename} in {test.Folder}");
_output.WriteLine(test.RawJson);
_output.WriteLine(test.FullPath);
Expand Down Expand Up @@ -113,51 +145,7 @@ public void Ensure_tests_For_All_Folders()
}
}

public class ExclusiveTestAttribute : DataAttribute
{
private static readonly JsonSerializerOptions _jsonSerializerOptions =
new() { ReadCommentHandling = JsonCommentHandling.Skip, PropertyNamingPolicy = JsonNamingPolicy.CamelCase, };

private readonly string _folder;

public ExclusiveTestAttribute(string folder)
{
_folder = folder;
}

public override IEnumerable<object[]> GetData(MethodInfo methodInfo)
{
var files = Directory.GetFiles(
Path.Join("LayoutExpressions", "CommonTests", "exclusive-tests", "functions", _folder)
);
foreach (var file in files)
{
ExpressionTestCaseRoot testCase = new();
var data = File.ReadAllText(file);
try
{
testCase = JsonSerializer.Deserialize<ExpressionTestCaseRoot>(data, _jsonSerializerOptions)!;
}
catch (Exception e)
{
using var jsonDocument = JsonDocument.Parse(data);

testCase.Name = jsonDocument.RootElement.GetProperty("name").GetString();
testCase.ExpectsFailure = jsonDocument.RootElement.TryGetProperty(
"expectsFailure",
out var expectsFailure
)
? expectsFailure.GetString()
: null;
testCase.ParsingException = e;
}

testCase.Filename = Path.GetFileName(file);
testCase.FullPath = file;
testCase.Folder = _folder;
testCase.RawJson = data;

yield return new object[] { testCase };
}
}
}
public class ExclusiveTestAttribute(string folder)
: FileNamesInFolderDataAttribute(
Path.Join("LayoutExpressions", "CommonTests", "exclusive-tests", "functions", folder)
) { }
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Text.Json.Serialization;
using Altinn.App.Core.Internal.Expressions;
using Altinn.App.Core.Tests.Helpers;
using Altinn.App.Core.Tests.TestUtils;
using FluentAssertions;
using Xunit.Abstractions;
using Xunit.Sdk;
Expand All @@ -23,22 +25,43 @@ public TestContextList(ITestOutputHelper output)

[Theory]
[SharedTestContextList("simple")]
public void Simple_Theory(ContextListRoot test) => RunTestCase(test);
public void Simple_Theory(string testName, string folder) => RunTestCase(testName, folder);

[Theory]
[SharedTestContextList("groups")]
public void Group_Theory(ContextListRoot test) => RunTestCase(test);
public void Group_Theory(string testName, string folder) => RunTestCase(testName, folder);

[Theory]
[SharedTestContextList("nonRepeatingGroups")]
public void NonRepeatingGroup_Theory(ContextListRoot test) => RunTestCase(test);
public void NonRepeatingGroup_Theory(string testName, string folder) => RunTestCase(testName, folder);

[Theory]
[SharedTestContextList("recursiveGroups")]
public void RecursiveGroup_Theory(ContextListRoot test) => RunTestCase(test);
public void RecursiveGroup_Theory(string testName, string folder) => RunTestCase(testName, folder);

private void RunTestCase(ContextListRoot test)
private static ContextListRoot LoadTestData(string testName, string folder)
{
ContextListRoot testCase = new();
var data = File.ReadAllText(Path.Join(folder, testName));
try
{
testCase = JsonSerializer.Deserialize<ContextListRoot>(data, _jsonSerializerOptions)!;
}
catch (Exception e)
{
testCase.ParsingException = e;
}

testCase.Filename = Path.GetFileName(testName);
testCase.FullPath = testName;
testCase.Folder = folder;
testCase.RawJson = data;
return testCase;
}

private void RunTestCase(string filename, string folder)
{
var test = LoadTestData(filename, folder);
_output.WriteLine($"{test.Filename} in {test.Folder}");
_output.WriteLine(test.RawJson);
_output.WriteLine(test.FullPath);
Expand Down Expand Up @@ -80,42 +103,7 @@ public void Ensure_tests_For_All_Folders()
}
}

public class SharedTestContextListAttribute : DataAttribute
{
private static readonly JsonSerializerOptions _jsonSerializerOptions =
new() { ReadCommentHandling = JsonCommentHandling.Skip, };

private readonly string _folder;

public SharedTestContextListAttribute(string folder)
{
_folder = folder;
}

public override IEnumerable<object[]> GetData(MethodInfo methodInfo)
{
var files = Directory.GetFiles(
Path.Join("LayoutExpressions", "CommonTests", "shared-tests", "context-lists", _folder)
);
foreach (var file in files)
{
ContextListRoot testCase = new();
var data = File.ReadAllText(file);
try
{
testCase = JsonSerializer.Deserialize<ContextListRoot>(data, _jsonSerializerOptions)!;
}
catch (Exception e)
{
testCase.ParsingException = e;
}

testCase.Filename = Path.GetFileName(file);
testCase.FullPath = file;
testCase.Folder = _folder;
testCase.RawJson = data;

yield return new object[] { testCase };
}
}
}
public class SharedTestContextListAttribute(string folder)
: FileNamesInFolderDataAttribute(
Path.Join("LayoutExpressions", "CommonTests", "shared-tests", "context-lists", folder)
) { }
Loading

0 comments on commit 54ffade

Please sign in to comment.