|
1 |
| -using AggregateConfigBuildTask.Contracts; |
| 1 | +using AggregateConfigBuildTask.Contracts; |
2 | 2 | using Microsoft.Build.Framework;
|
3 | 3 | using Moq;
|
4 | 4 | using Newtonsoft.Json;
|
@@ -477,6 +477,117 @@ public void StressTest_ShouldAddSourcePropertyManyFiles()
|
477 | 477 | }
|
478 | 478 | }
|
479 | 479 |
|
| 480 | + [TestMethod] |
| 481 | + [DataRow("arm", new[] { "json", "yml", "arm" }, DisplayName = "ARM -> JSON -> YAML -> ARM")] |
| 482 | + [DataRow("arm", new[] { "yml", "json", "arm" }, DisplayName = "ARM -> YAML -> JSON -> ARM")] |
| 483 | + [DataRow("json", new[] { "arm", "yml", "json" }, DisplayName = "JSON -> ARM -> YAML -> JSON")] |
| 484 | + [DataRow("json", new[] { "yml", "arm", "json" }, DisplayName = "JSON -> YAML -> ARM -> JSON")] |
| 485 | + [DataRow("yml", new[] { "arm", "json", "yml" }, DisplayName = "YAML -> ARM -> JSON -> YAML")] |
| 486 | + [DataRow("yml", new[] { "json", "arm", "yml" }, DisplayName = "YAML -> JSON -> ARM -> YAML")] |
| 487 | + [Description("Test that files are correctly translated between ARM, JSON, and YAML.")] |
| 488 | + public void ShouldTranslateBetweenFormatsAndValidateNoDataLoss(string inputType, string[] steps) |
| 489 | + { |
| 490 | + Assert.IsTrue(steps?.Length > 0); |
| 491 | + |
| 492 | + // Arrange: Prepare paths and sample data based on the input type. |
| 493 | + var inputDir = $"{testPath}\\input"; |
| 494 | + virtualFileSystem.CreateDirectory(inputDir); |
| 495 | + |
| 496 | + // Write the initial input file |
| 497 | + var inputFilePath = $"{inputDir}\\input.{(inputType == "arm" ? "json" : inputType)}"; |
| 498 | + virtualFileSystem.WriteAllText(inputFilePath, GetSampleDataForType(inputType)); |
| 499 | + |
| 500 | + string previousInputPath = inputFilePath; |
| 501 | + string previousOutputType = inputType; |
| 502 | + |
| 503 | + // Execute the translation steps dynamically |
| 504 | + for (int i = 0; i < steps.Length; i++) |
| 505 | + { |
| 506 | + var outputType = steps[i]; |
| 507 | + var stepDir = $"{testPath}\\step{i + 1}"; |
| 508 | + var stepOutputPath = $"{stepDir}\\output.{(outputType == "arm" ? "json" : outputType)}"; |
| 509 | + |
| 510 | + virtualFileSystem.CreateDirectory(stepDir); |
| 511 | + |
| 512 | + // Execute translation for this step |
| 513 | + ExecuteTranslationTask(previousOutputType, outputType, previousInputPath, stepOutputPath); |
| 514 | + |
| 515 | + // Update paths for the next iteration |
| 516 | + previousInputPath = stepOutputPath; |
| 517 | + previousOutputType = outputType; |
| 518 | + } |
| 519 | + |
| 520 | + // Final step: Convert the final output back to the original input type |
| 521 | + var finalDir = $"{testPath}\\final"; |
| 522 | + var finalOutputPath = $"{finalDir}\\final_output.{(inputType == "arm" ? "json" : inputType)}"; |
| 523 | + virtualFileSystem.CreateDirectory(finalDir); |
| 524 | + |
| 525 | + ExecuteTranslationTask(previousOutputType, inputType, previousInputPath, finalOutputPath); |
| 526 | + |
| 527 | + // Assert: Compare final output with original input to check no data loss |
| 528 | + AssertNoDataLoss(inputFilePath, finalOutputPath, inputType); |
| 529 | + } |
| 530 | + |
| 531 | + private void ExecuteTranslationTask(string inputType, string outputType, string inputFilePath, string outputFilePath) |
| 532 | + { |
| 533 | + var task = new AggregateConfig(virtualFileSystem, mockLogger.Object) |
| 534 | + { |
| 535 | + InputDirectory = inputFilePath, |
| 536 | + InputType = inputType, |
| 537 | + OutputFile = outputFilePath, |
| 538 | + OutputType = outputType, |
| 539 | + BuildEngine = Mock.Of<IBuildEngine>() |
| 540 | + }; |
| 541 | + bool result = task.Execute(); |
| 542 | + Assert.IsTrue(result, $"Failed translation: {inputType} -> {outputType}"); |
| 543 | + } |
| 544 | + |
| 545 | + private void AssertNoDataLoss(string originalFilePath, string finalFilePath, string inputType) |
| 546 | + { |
| 547 | + string originalInput = virtualFileSystem.ReadAllText(originalFilePath); |
| 548 | + string finalOutput = virtualFileSystem.ReadAllText(finalFilePath); |
| 549 | + Assert.AreEqual(originalInput, finalOutput, $"Data mismatch after full conversion cycle for {inputType}"); |
| 550 | + } |
| 551 | + |
| 552 | + private static string GetSampleDataForType(string type) |
| 553 | + { |
| 554 | + return type switch |
| 555 | + { |
| 556 | + "json" => @"{ |
| 557 | + ""options"": [ |
| 558 | + { |
| 559 | + ""name"": ""Option 1"", |
| 560 | + ""description"": ""First option"", |
| 561 | + ""isTrue"": true, |
| 562 | + ""number"": 100 |
| 563 | + } |
| 564 | + ] |
| 565 | +}", |
| 566 | + "arm" => @"{ |
| 567 | + ""$schema"": ""https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#"", |
| 568 | + ""contentVersion"": ""1.0.0.0"", |
| 569 | + ""parameters"": { |
| 570 | + ""options"": { |
| 571 | + ""type"": ""object"", |
| 572 | + ""value"": { |
| 573 | + ""name"": ""Option 1"", |
| 574 | + ""description"": ""First option"", |
| 575 | + ""isTrue"": true, |
| 576 | + ""number"": 100 |
| 577 | + } |
| 578 | + } |
| 579 | + } |
| 580 | +}", |
| 581 | + "yml" => @"options: |
| 582 | +- name: Option 1 |
| 583 | + description: First option |
| 584 | + isTrue: true |
| 585 | + number: 100 |
| 586 | +", |
| 587 | + _ => throw new InvalidOperationException("Unknown type") |
| 588 | + }; |
| 589 | + } |
| 590 | + |
480 | 591 | /// <summary>
|
481 | 592 | /// Check if an option exists with a given name and source
|
482 | 593 | /// </summary>
|
|
0 commit comments