diff --git a/exercises/book-store/BookStoreTest.cs b/exercises/book-store/BookStoreTest.cs index 31d1e6190d..d8f15bf5af 100644 --- a/exercises/book-store/BookStoreTest.cs +++ b/exercises/book-store/BookStoreTest.cs @@ -7,91 +7,91 @@ public class BookStoreTest [Fact] public void Only_a_single_book() { - var input = new[] { 1 }; - Assert.Equal(8, BookStore.Total(input)); + var basket = new[] { 1 }; + Assert.Equal(8, BookStore.Total(basket)); } [Fact(Skip = "Remove to run test")] public void Two_of_the_same_book() { - var input = new[] { 2, 2 }; - Assert.Equal(16, BookStore.Total(input)); + var basket = new[] { 2, 2 }; + Assert.Equal(16, BookStore.Total(basket)); } [Fact(Skip = "Remove to run test")] public void Empty_basket() { - var input = new int[0]; - Assert.Equal(0, BookStore.Total(input)); + var basket = new int[0]; + Assert.Equal(0, BookStore.Total(basket)); } [Fact(Skip = "Remove to run test")] public void Two_different_books() { - var input = new[] { 1, 2 }; - Assert.Equal(15.2, BookStore.Total(input)); + var basket = new[] { 1, 2 }; + Assert.Equal(15.2, BookStore.Total(basket)); } [Fact(Skip = "Remove to run test")] public void Three_different_books() { - var input = new[] { 1, 2, 3 }; - Assert.Equal(21.6, BookStore.Total(input)); + var basket = new[] { 1, 2, 3 }; + Assert.Equal(21.6, BookStore.Total(basket)); } [Fact(Skip = "Remove to run test")] public void Four_different_books() { - var input = new[] { 1, 2, 3, 4 }; - Assert.Equal(25.6, BookStore.Total(input)); + var basket = new[] { 1, 2, 3, 4 }; + Assert.Equal(25.6, BookStore.Total(basket)); } [Fact(Skip = "Remove to run test")] public void Five_different_books() { - var input = new[] { 1, 2, 3, 4, 5 }; - Assert.Equal(30, BookStore.Total(input)); + var basket = new[] { 1, 2, 3, 4, 5 }; + Assert.Equal(30, BookStore.Total(basket)); } [Fact(Skip = "Remove to run test")] public void Two_groups_of_four_is_cheaper_than_group_of_five_plus_group_of_three() { - var input = new[] { 1, 1, 2, 2, 3, 3, 4, 5 }; - Assert.Equal(51.2, BookStore.Total(input)); + var basket = new[] { 1, 1, 2, 2, 3, 3, 4, 5 }; + Assert.Equal(51.2, BookStore.Total(basket)); } [Fact(Skip = "Remove to run test")] public void Group_of_four_plus_group_of_two_is_cheaper_than_two_groups_of_three() { - var input = new[] { 1, 1, 2, 2, 3, 4 }; - Assert.Equal(40.8, BookStore.Total(input)); + var basket = new[] { 1, 1, 2, 2, 3, 4 }; + Assert.Equal(40.8, BookStore.Total(basket)); } [Fact(Skip = "Remove to run test")] public void Two_each_of_first_4_books_and_1_copy_each_of_rest() { - var input = new[] { 1, 1, 2, 2, 3, 3, 4, 4, 5 }; - Assert.Equal(55.6, BookStore.Total(input)); + var basket = new[] { 1, 1, 2, 2, 3, 3, 4, 4, 5 }; + Assert.Equal(55.6, BookStore.Total(basket)); } [Fact(Skip = "Remove to run test")] public void Two_copies_of_each_book() { - var input = new[] { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 }; - Assert.Equal(60, BookStore.Total(input)); + var basket = new[] { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 }; + Assert.Equal(60, BookStore.Total(basket)); } [Fact(Skip = "Remove to run test")] public void Three_copies_of_first_book_and_2_each_of_remaining() { - var input = new[] { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 1 }; - Assert.Equal(68, BookStore.Total(input)); + var basket = new[] { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 1 }; + Assert.Equal(68, BookStore.Total(basket)); } [Fact(Skip = "Remove to run test")] public void Three_each_of_first_2_books_and_2_each_of_remaining_books() { - var input = new[] { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 1, 2 }; - Assert.Equal(75.2, BookStore.Total(input)); + var basket = new[] { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 1, 2 }; + Assert.Equal(75.2, BookStore.Total(basket)); } } \ No newline at end of file diff --git a/exercises/complex-numbers/ComplexNumbersTest.cs b/exercises/complex-numbers/ComplexNumbersTest.cs index f2016ece46..c1e3380204 100644 --- a/exercises/complex-numbers/ComplexNumbersTest.cs +++ b/exercises/complex-numbers/ComplexNumbersTest.cs @@ -52,8 +52,8 @@ public void Imaginary_unit() { var sut = new ComplexNumber(0, 1); var expected = new ComplexNumber(-1, 0); - Assert.Equal(expected.Real(), sut.Mul(new ComplexNumber(0, 1)).Real(), 15); - Assert.Equal(expected.Imaginary(), sut.Mul(new ComplexNumber(0, 1)).Imaginary(), 15); + Assert.Equal(expected.Real(), sut.Mul(new ComplexNumber(0, 1)).Real(), precision: 15); + Assert.Equal(expected.Imaginary(), sut.Mul(new ComplexNumber(0, 1)).Imaginary(), precision: 15); } [Fact(Skip = "Remove to run test")] @@ -61,8 +61,8 @@ public void Add_purely_real_numbers() { var sut = new ComplexNumber(1, 0); var expected = new ComplexNumber(3, 0); - Assert.Equal(expected.Real(), sut.Add(new ComplexNumber(2, 0)).Real(), 15); - Assert.Equal(expected.Imaginary(), sut.Add(new ComplexNumber(2, 0)).Imaginary(), 15); + Assert.Equal(expected.Real(), sut.Add(new ComplexNumber(2, 0)).Real(), precision: 15); + Assert.Equal(expected.Imaginary(), sut.Add(new ComplexNumber(2, 0)).Imaginary(), precision: 15); } [Fact(Skip = "Remove to run test")] @@ -70,8 +70,8 @@ public void Add_purely_imaginary_numbers() { var sut = new ComplexNumber(0, 1); var expected = new ComplexNumber(0, 3); - Assert.Equal(expected.Real(), sut.Add(new ComplexNumber(0, 2)).Real(), 15); - Assert.Equal(expected.Imaginary(), sut.Add(new ComplexNumber(0, 2)).Imaginary(), 15); + Assert.Equal(expected.Real(), sut.Add(new ComplexNumber(0, 2)).Real(), precision: 15); + Assert.Equal(expected.Imaginary(), sut.Add(new ComplexNumber(0, 2)).Imaginary(), precision: 15); } [Fact(Skip = "Remove to run test")] @@ -79,8 +79,8 @@ public void Add_numbers_with_real_and_imaginary_part() { var sut = new ComplexNumber(1, 2); var expected = new ComplexNumber(4, 6); - Assert.Equal(expected.Real(), sut.Add(new ComplexNumber(3, 4)).Real(), 15); - Assert.Equal(expected.Imaginary(), sut.Add(new ComplexNumber(3, 4)).Imaginary(), 15); + Assert.Equal(expected.Real(), sut.Add(new ComplexNumber(3, 4)).Real(), precision: 15); + Assert.Equal(expected.Imaginary(), sut.Add(new ComplexNumber(3, 4)).Imaginary(), precision: 15); } [Fact(Skip = "Remove to run test")] @@ -88,8 +88,8 @@ public void Subtract_purely_real_numbers() { var sut = new ComplexNumber(1, 0); var expected = new ComplexNumber(-1, 0); - Assert.Equal(expected.Real(), sut.Sub(new ComplexNumber(2, 0)).Real(), 15); - Assert.Equal(expected.Imaginary(), sut.Sub(new ComplexNumber(2, 0)).Imaginary(), 15); + Assert.Equal(expected.Real(), sut.Sub(new ComplexNumber(2, 0)).Real(), precision: 15); + Assert.Equal(expected.Imaginary(), sut.Sub(new ComplexNumber(2, 0)).Imaginary(), precision: 15); } [Fact(Skip = "Remove to run test")] @@ -97,8 +97,8 @@ public void Subtract_purely_imaginary_numbers() { var sut = new ComplexNumber(0, 1); var expected = new ComplexNumber(0, -1); - Assert.Equal(expected.Real(), sut.Sub(new ComplexNumber(0, 2)).Real(), 15); - Assert.Equal(expected.Imaginary(), sut.Sub(new ComplexNumber(0, 2)).Imaginary(), 15); + Assert.Equal(expected.Real(), sut.Sub(new ComplexNumber(0, 2)).Real(), precision: 15); + Assert.Equal(expected.Imaginary(), sut.Sub(new ComplexNumber(0, 2)).Imaginary(), precision: 15); } [Fact(Skip = "Remove to run test")] @@ -106,8 +106,8 @@ public void Subtract_numbers_with_real_and_imaginary_part() { var sut = new ComplexNumber(1, 2); var expected = new ComplexNumber(-2, -2); - Assert.Equal(expected.Real(), sut.Sub(new ComplexNumber(3, 4)).Real(), 15); - Assert.Equal(expected.Imaginary(), sut.Sub(new ComplexNumber(3, 4)).Imaginary(), 15); + Assert.Equal(expected.Real(), sut.Sub(new ComplexNumber(3, 4)).Real(), precision: 15); + Assert.Equal(expected.Imaginary(), sut.Sub(new ComplexNumber(3, 4)).Imaginary(), precision: 15); } [Fact(Skip = "Remove to run test")] @@ -115,8 +115,8 @@ public void Multiply_purely_real_numbers() { var sut = new ComplexNumber(1, 0); var expected = new ComplexNumber(2, 0); - Assert.Equal(expected.Real(), sut.Mul(new ComplexNumber(2, 0)).Real(), 15); - Assert.Equal(expected.Imaginary(), sut.Mul(new ComplexNumber(2, 0)).Imaginary(), 15); + Assert.Equal(expected.Real(), sut.Mul(new ComplexNumber(2, 0)).Real(), precision: 15); + Assert.Equal(expected.Imaginary(), sut.Mul(new ComplexNumber(2, 0)).Imaginary(), precision: 15); } [Fact(Skip = "Remove to run test")] @@ -124,8 +124,8 @@ public void Multiply_purely_imaginary_numbers() { var sut = new ComplexNumber(0, 1); var expected = new ComplexNumber(-2, 0); - Assert.Equal(expected.Real(), sut.Mul(new ComplexNumber(0, 2)).Real(), 15); - Assert.Equal(expected.Imaginary(), sut.Mul(new ComplexNumber(0, 2)).Imaginary(), 15); + Assert.Equal(expected.Real(), sut.Mul(new ComplexNumber(0, 2)).Real(), precision: 15); + Assert.Equal(expected.Imaginary(), sut.Mul(new ComplexNumber(0, 2)).Imaginary(), precision: 15); } [Fact(Skip = "Remove to run test")] @@ -133,8 +133,8 @@ public void Multiply_numbers_with_real_and_imaginary_part() { var sut = new ComplexNumber(1, 2); var expected = new ComplexNumber(-5, 10); - Assert.Equal(expected.Real(), sut.Mul(new ComplexNumber(3, 4)).Real(), 15); - Assert.Equal(expected.Imaginary(), sut.Mul(new ComplexNumber(3, 4)).Imaginary(), 15); + Assert.Equal(expected.Real(), sut.Mul(new ComplexNumber(3, 4)).Real(), precision: 15); + Assert.Equal(expected.Imaginary(), sut.Mul(new ComplexNumber(3, 4)).Imaginary(), precision: 15); } [Fact(Skip = "Remove to run test")] @@ -142,8 +142,8 @@ public void Divide_purely_real_numbers() { var sut = new ComplexNumber(1, 0); var expected = new ComplexNumber(0.5, 0); - Assert.Equal(expected.Real(), sut.Div(new ComplexNumber(2, 0)).Real(), 15); - Assert.Equal(expected.Imaginary(), sut.Div(new ComplexNumber(2, 0)).Imaginary(), 15); + Assert.Equal(expected.Real(), sut.Div(new ComplexNumber(2, 0)).Real(), precision: 15); + Assert.Equal(expected.Imaginary(), sut.Div(new ComplexNumber(2, 0)).Imaginary(), precision: 15); } [Fact(Skip = "Remove to run test")] @@ -151,8 +151,8 @@ public void Divide_purely_imaginary_numbers() { var sut = new ComplexNumber(0, 1); var expected = new ComplexNumber(0.5, 0); - Assert.Equal(expected.Real(), sut.Div(new ComplexNumber(0, 2)).Real(), 15); - Assert.Equal(expected.Imaginary(), sut.Div(new ComplexNumber(0, 2)).Imaginary(), 15); + Assert.Equal(expected.Real(), sut.Div(new ComplexNumber(0, 2)).Real(), precision: 15); + Assert.Equal(expected.Imaginary(), sut.Div(new ComplexNumber(0, 2)).Imaginary(), precision: 15); } [Fact(Skip = "Remove to run test")] @@ -160,8 +160,8 @@ public void Divide_numbers_with_real_and_imaginary_part() { var sut = new ComplexNumber(1, 2); var expected = new ComplexNumber(0.44, 0.08); - Assert.Equal(expected.Real(), sut.Div(new ComplexNumber(3, 4)).Real(), 15); - Assert.Equal(expected.Imaginary(), sut.Div(new ComplexNumber(3, 4)).Imaginary(), 15); + Assert.Equal(expected.Real(), sut.Div(new ComplexNumber(3, 4)).Real(), precision: 15); + Assert.Equal(expected.Imaginary(), sut.Div(new ComplexNumber(3, 4)).Imaginary(), precision: 15); } [Fact(Skip = "Remove to run test")] @@ -204,8 +204,8 @@ public void Conjugate_a_purely_real_number() { var sut = new ComplexNumber(5, 0); var expected = new ComplexNumber(5, 0); - Assert.Equal(expected.Real(), sut.Conjugate().Real(), 15); - Assert.Equal(expected.Imaginary(), sut.Conjugate().Imaginary(), 15); + Assert.Equal(expected.Real(), sut.Conjugate().Real(), precision: 15); + Assert.Equal(expected.Imaginary(), sut.Conjugate().Imaginary(), precision: 15); } [Fact(Skip = "Remove to run test")] @@ -213,8 +213,8 @@ public void Conjugate_a_purely_imaginary_number() { var sut = new ComplexNumber(0, 5); var expected = new ComplexNumber(0, -5); - Assert.Equal(expected.Real(), sut.Conjugate().Real(), 15); - Assert.Equal(expected.Imaginary(), sut.Conjugate().Imaginary(), 15); + Assert.Equal(expected.Real(), sut.Conjugate().Real(), precision: 15); + Assert.Equal(expected.Imaginary(), sut.Conjugate().Imaginary(), precision: 15); } [Fact(Skip = "Remove to run test")] @@ -222,8 +222,8 @@ public void Conjugate_a_number_with_real_and_imaginary_part() { var sut = new ComplexNumber(1, 1); var expected = new ComplexNumber(1, -1); - Assert.Equal(expected.Real(), sut.Conjugate().Real(), 15); - Assert.Equal(expected.Imaginary(), sut.Conjugate().Imaginary(), 15); + Assert.Equal(expected.Real(), sut.Conjugate().Real(), precision: 15); + Assert.Equal(expected.Imaginary(), sut.Conjugate().Imaginary(), precision: 15); } [Fact(Skip = "Remove to run test")] @@ -231,8 +231,8 @@ public void Eulers_identity_formula() { var sut = new ComplexNumber(0, Math.PI); var expected = new ComplexNumber(-1, 0); - Assert.Equal(expected.Real(), sut.Exp().Real(), 15); - Assert.Equal(expected.Imaginary(), sut.Exp().Imaginary(), 15); + Assert.Equal(expected.Real(), sut.Exp().Real(), precision: 15); + Assert.Equal(expected.Imaginary(), sut.Exp().Imaginary(), precision: 15); } [Fact(Skip = "Remove to run test")] @@ -240,8 +240,8 @@ public void Exponential_of_0() { var sut = new ComplexNumber(0, 0); var expected = new ComplexNumber(1, 0); - Assert.Equal(expected.Real(), sut.Exp().Real(), 15); - Assert.Equal(expected.Imaginary(), sut.Exp().Imaginary(), 15); + Assert.Equal(expected.Real(), sut.Exp().Real(), precision: 15); + Assert.Equal(expected.Imaginary(), sut.Exp().Imaginary(), precision: 15); } [Fact(Skip = "Remove to run test")] @@ -249,7 +249,7 @@ public void Exponential_of_a_purely_real_number() { var sut = new ComplexNumber(1, 0); var expected = new ComplexNumber(Math.E, 0); - Assert.Equal(expected.Real(), sut.Exp().Real(), 15); - Assert.Equal(expected.Imaginary(), sut.Exp().Imaginary(), 15); + Assert.Equal(expected.Real(), sut.Exp().Real(), precision: 15); + Assert.Equal(expected.Imaginary(), sut.Exp().Imaginary(), precision: 15); } } \ No newline at end of file diff --git a/generators/Exercises/AllYourBase.cs b/generators/Exercises/AllYourBase.cs index 518b28b58a..29290dc8a3 100644 --- a/generators/Exercises/AllYourBase.cs +++ b/generators/Exercises/AllYourBase.cs @@ -9,8 +9,6 @@ protected override void UpdateCanonicalData(CanonicalData canonicalData) { foreach (var canonicalDataCase in canonicalData.Cases) { - canonicalDataCase.Input["input_digits"] = canonicalDataCase.Input["input_digits"].ConvertToEnumerable(); - canonicalDataCase.ExceptionThrown = canonicalDataCase.Expected is null ? typeof(ArgumentException) : null; canonicalDataCase.UseVariablesForInput = true; canonicalDataCase.UseVariableForExpected = true; diff --git a/generators/Exercises/Allergies.cs b/generators/Exercises/Allergies.cs index 844879fc37..b8fe732146 100644 --- a/generators/Exercises/Allergies.cs +++ b/generators/Exercises/Allergies.cs @@ -1,8 +1,5 @@ -using System.Collections.Generic; -using System.Linq; -using Generators.Input; +using Generators.Input; using Generators.Output; -using Newtonsoft.Json.Linq; namespace Generators.Exercises { @@ -13,19 +10,11 @@ protected override void UpdateCanonicalData(CanonicalData canonicalData) foreach (var canonicalDataCase in canonicalData.Cases) { if (canonicalDataCase.Property == "allergicTo") - { canonicalDataCase.Property = "IsAllergicTo"; - } else if (canonicalDataCase.Property == "list") - { - canonicalDataCase.Expected = canonicalDataCase.Expected.ConvertToEnumerable(); canonicalDataCase.UseVariableForExpected = true; - } - canonicalDataCase.ConstructorInput = new Dictionary - { - ["score"] = canonicalDataCase.Properties["score"] - }; + canonicalDataCase.SetConstructorInputParameters("score"); } } @@ -41,17 +30,10 @@ private static string RenderIsAllergicToAssert(TestMethodBody testMethodBody) { const string template = @"{%- for allergy in Allergies -%} -Assert.{% if allergy.Result %}True{% else %}False{% endif %}(sut.IsAllergicTo(""{{ allergy.Substance }}"")); +Assert.{% if allergy.result %}True{% else %}False{% endif %}(sut.IsAllergicTo(""{{ allergy.substance }}"")); {%- endfor -%}"; - - var templateParameters = new - { - Allergies = ((JArray) testMethodBody.CanonicalDataCase.Expected) - .Children() - .Select(x => new {Result = x["result"].Value(), Substance = x["substance"].Value()}) - .ToArray() - }; - + + var templateParameters = new { Allergies = testMethodBody.CanonicalDataCase.Expected }; return TemplateRenderer.RenderInline(template, templateParameters); } } diff --git a/generators/Exercises/Alphametics.cs b/generators/Exercises/Alphametics.cs index 711bab80e5..5fc5de598e 100644 --- a/generators/Exercises/Alphametics.cs +++ b/generators/Exercises/Alphametics.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; +using System.Linq; using Generators.Input; -using Newtonsoft.Json.Linq; namespace Generators.Exercises { @@ -17,16 +17,13 @@ protected override void UpdateCanonicalData(CanonicalData canonicalData) if (canonicalDataCase.Expected == null) canonicalDataCase.ExceptionThrown = typeof(ArgumentException); else - canonicalDataCase.Expected = ((JObject)canonicalDataCase.Expected).ToObject>(); + canonicalDataCase.Expected = ConvertExpected(canonicalDataCase); } } - protected override HashSet AddAdditionalNamespaces() - { - return new HashSet() - { - typeof(Dictionary).Namespace - }; - } + private static dynamic ConvertExpected(CanonicalDataCase canonicalDataCase) + => ((Dictionary)canonicalDataCase.Expected).ToDictionary(kv => kv.Key[0], kv => int.Parse(kv.Value.ToString())); + + protected override HashSet AddAdditionalNamespaces() => new HashSet { typeof(Dictionary).Namespace }; } } \ No newline at end of file diff --git a/generators/Exercises/Anagram.cs b/generators/Exercises/Anagram.cs index 8a740f71a3..b632de810b 100644 --- a/generators/Exercises/Anagram.cs +++ b/generators/Exercises/Anagram.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using Generators.Input; namespace Generators.Exercises @@ -9,15 +8,9 @@ protected override void UpdateCanonicalData(CanonicalData canonicalData) { foreach (var canonicalDataCase in canonicalData.Cases) { - canonicalDataCase.ConstructorInput = new Dictionary - { - ["subject"] = canonicalDataCase.Input["subject"] - }; - canonicalDataCase.Input["candidates"] = canonicalDataCase.Input["candidates"].ConvertToEnumerable(); - canonicalDataCase.Expected = canonicalDataCase.Expected.ConvertToEnumerable(); - canonicalDataCase.UseVariablesForInput = true; canonicalDataCase.UseVariableForExpected = true; + canonicalDataCase.SetConstructorInputParameters("subject"); } } } diff --git a/generators/Exercises/BinarySearch.cs b/generators/Exercises/BinarySearch.cs index 841ba4857d..a3cfbc6752 100644 --- a/generators/Exercises/BinarySearch.cs +++ b/generators/Exercises/BinarySearch.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using Generators.Input; +using Generators.Input; namespace Generators.Exercises { @@ -9,12 +8,8 @@ protected override void UpdateCanonicalData(CanonicalData canonicalData) { foreach (var canonicalDataCase in canonicalData.Cases) { - canonicalDataCase.ConstructorInput = new Dictionary - { - ["array"] = canonicalDataCase.Input["array"].ConvertToEnumerable() - }; - canonicalDataCase.UseVariablesForConstructorParameters = true; + canonicalDataCase.SetConstructorInputParameters("array"); } } } diff --git a/generators/Exercises/BookStore.cs b/generators/Exercises/BookStore.cs index 2d78a212e4..18f7fb0372 100644 --- a/generators/Exercises/BookStore.cs +++ b/generators/Exercises/BookStore.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using Generators.Input; +using Generators.Input; namespace Generators.Exercises { @@ -9,10 +8,7 @@ protected override void UpdateCanonicalData(CanonicalData canonicalData) { foreach (var canonicalDataCase in canonicalData.Cases) { - canonicalDataCase.Input = new Dictionary - { - ["input"] = canonicalDataCase.Input["basket"].ConvertToEnumerable() - }; + canonicalDataCase.SetInputParameters("basket"); canonicalDataCase.UseVariablesForInput = true; } } diff --git a/generators/Exercises/BracketPush.cs b/generators/Exercises/BracketPush.cs index 67fc1eb019..2577d376a3 100644 --- a/generators/Exercises/BracketPush.cs +++ b/generators/Exercises/BracketPush.cs @@ -8,7 +8,7 @@ protected override void UpdateCanonicalData(CanonicalData canonicalData) { foreach (var canonicalDataCase in canonicalData.Cases) { - canonicalDataCase.Input["input"] = ((string)canonicalDataCase.Input["input"]).Replace("\\", "\\\\"); + canonicalDataCase.Properties["input"] = canonicalDataCase.Properties["input"].Replace("\\", "\\\\"); canonicalDataCase.UseVariablesForInput = true; } } diff --git a/generators/Exercises/CollatzConjecture.cs b/generators/Exercises/CollatzConjecture.cs index a832fda10e..a6ada6b4b1 100644 --- a/generators/Exercises/CollatzConjecture.cs +++ b/generators/Exercises/CollatzConjecture.cs @@ -8,9 +8,7 @@ public class CollatzConjecture : Exercise protected override void UpdateCanonicalData(CanonicalData canonicalData) { foreach (var canonicalDataCase in canonicalData.Cases) - { - canonicalDataCase.ExceptionThrown = (long)canonicalDataCase.Input["number"] <= 0 ? typeof(ArgumentException) : null; - } + canonicalDataCase.ExceptionThrown = canonicalDataCase.Input["number"] <= 0 ? typeof(ArgumentException) : null; } } } \ No newline at end of file diff --git a/generators/Exercises/ComplexNumbers.cs b/generators/Exercises/ComplexNumbers.cs index 0ef1f04be3..141424cc6b 100644 --- a/generators/Exercises/ComplexNumbers.cs +++ b/generators/Exercises/ComplexNumbers.cs @@ -20,38 +20,30 @@ protected override void UpdateCanonicalData(CanonicalData canonicalData) { // Process expected if (IsComplexNumber(canonicalDataCase.Expected)) - { canonicalDataCase.UseVariableForExpected = true; - } canonicalDataCase.Expected = ConvertToType(canonicalDataCase.Expected); // Process constructor param var constructorParamName = canonicalDataCase.Input.ContainsKey("input") ? "input" : "z1"; - var constructorParamValues = canonicalDataCase.Input[constructorParamName] - .ConvertToEnumerable() - .Select(v => ConvertMathDouble(v)) - .ToArray(); + canonicalDataCase.Properties["real"] = ConvertMathDouble(canonicalDataCase.Input[constructorParamName][0]); + canonicalDataCase.Properties["imaginary"] = ConvertMathDouble(canonicalDataCase.Input[constructorParamName][1]); - canonicalDataCase.ConstructorInput = new Dictionary - { - ["real"] = constructorParamValues[0], - ["imaginary"] = constructorParamValues[1] - }; - - canonicalDataCase.Input.Remove(constructorParamName); + canonicalDataCase.SetConstructorInputParameters("real", "imaginary"); + canonicalDataCase.SetInputParameters(GetInputParameters(canonicalDataCase, constructorParamName)); // Process function param var keys = canonicalDataCase.Input.Keys.ToArray(); foreach (var key in keys) - { - canonicalDataCase.Input[key] = ConvertToType(canonicalDataCase.Input[key]); - } + canonicalDataCase.Properties[key] = ConvertToType(canonicalDataCase.Properties[key]); } } + private static string[] GetInputParameters(CanonicalDataCase canonicalDataCase, string constructorParamName) + => canonicalDataCase.Input.Keys.Where(x => x != constructorParamName).ToArray(); + protected override string RenderTestMethodBodyAssert(TestMethodBody testMethodBody) { if (testMethodBody.UseVariableForExpected) @@ -62,55 +54,36 @@ protected override string RenderTestMethodBodyAssert(TestMethodBody testMethodBo private static string RenderComplexNumberAssert(TestMethodBody testMethodBody) { - var template = "Assert.Equal({{ ExpectedParameter }}.Real(), {{ TestedValue }}.Real(), 15);\r\nAssert.Equal({{ ExpectedParameter }}.Imaginary(), {{ TestedValue }}.Imaginary(), 15);"; + const string template = "Assert.Equal({{ ExpectedParameter }}.Real(), {{ TestedValue }}.Real(), precision: 15);\r\nAssert.Equal({{ ExpectedParameter }}.Imaginary(), {{ TestedValue }}.Imaginary(), precision: 15);"; return TemplateRenderer.RenderInline(template, testMethodBody.AssertTemplateParameters); } - protected override HashSet AddAdditionalNamespaces() + protected override HashSet AddAdditionalNamespaces() => new HashSet { - return new HashSet() - { - typeof(Math).Namespace - }; - } + typeof(Math).Namespace + }; - private object ConvertToType(object rawValue) + private static object ConvertToType(dynamic rawValue) { if (IsComplexNumber(rawValue)) - { - var array = rawValue - .ConvertToEnumerable() - .Select(rv => ConvertToType(rv)) - .ToArray(); + return new UnescapedValue($"new ComplexNumber({ValueFormatter.Format(ConvertMathDouble(rawValue[0]))}, {ValueFormatter.Format(ConvertMathDouble(rawValue[1]))})"); - return new UnescapedValue($"new ComplexNumber({array[0]}, {array[1]})"); - } - else if (rawValue is string) - { - return ConvertMathDouble((string)rawValue); - } - else - { - return rawValue; - } + return rawValue; } - private bool IsComplexNumber(object rawValue) - { - return rawValue is JArray; - } + private static bool IsComplexNumber(object rawValue) => rawValue is int[] || rawValue is double[] || rawValue is float[] || rawValue is JArray; - private object ConvertMathDouble(string value) + private static object ConvertMathDouble(dynamic value) { - switch (value) + switch (value.ToString()) { case "e": return new UnescapedValue("Math.E"); case "pi": return new UnescapedValue("Math.PI"); default: - return double.Parse(value); + return double.Parse(value.ToString()); } } } diff --git a/generators/Exercises/Convert.cs b/generators/Exercises/Convert.cs new file mode 100644 index 0000000000..eb37b5f1f6 --- /dev/null +++ b/generators/Exercises/Convert.cs @@ -0,0 +1,7 @@ +namespace Generators.Exercises +{ + public static class Convert + { + public static string ToMultiLineString(this object obj) => string.Join("\n", obj as object[]); + } +} \ No newline at end of file diff --git a/generators/Exercises/ConvertExtensions.cs b/generators/Exercises/ConvertExtensions.cs deleted file mode 100644 index 7ccfa38169..0000000000 --- a/generators/Exercises/ConvertExtensions.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json.Linq; - -namespace Generators.Exercises -{ - public static class ConvertExtensions - { - public static string ConvertMultiLineString(this object obj) => string.Join("\n", (JArray)obj); - - public static IEnumerable ConvertToEnumerable(this object obj) => ((JArray) obj).Values(); - } -} diff --git a/generators/Exercises/CryptoSquare.cs b/generators/Exercises/CryptoSquare.cs index c7a27e33b2..310734d154 100644 --- a/generators/Exercises/CryptoSquare.cs +++ b/generators/Exercises/CryptoSquare.cs @@ -1,5 +1,4 @@ using Generators.Input; -using Newtonsoft.Json.Linq; namespace Generators.Exercises { @@ -11,9 +10,6 @@ protected override void UpdateCanonicalData(CanonicalData canonicalData) { canonicalDataCase.UseVariablesForInput = true; canonicalDataCase.UseVariableForExpected = true; - - if (canonicalDataCase.Expected is JArray expected) - canonicalDataCase.Expected = expected.Values(); } } } diff --git a/generators/Exercises/FoodChain.cs b/generators/Exercises/FoodChain.cs index f02dbef02f..2f4aee7537 100644 --- a/generators/Exercises/FoodChain.cs +++ b/generators/Exercises/FoodChain.cs @@ -8,7 +8,7 @@ protected override void UpdateCanonicalData(CanonicalData canonicalData) { foreach (var canonicalDataCase in canonicalData.Cases) { - canonicalDataCase.Expected = canonicalDataCase.Expected.ConvertMultiLineString(); + canonicalDataCase.Expected = Convert.ToMultiLineString(canonicalDataCase.Expected); canonicalDataCase.UseVariableForExpected = true; } } diff --git a/generators/Exercises/Gigasecond.cs b/generators/Exercises/Gigasecond.cs index 924c0c6a40..b0623cbacf 100644 --- a/generators/Exercises/Gigasecond.cs +++ b/generators/Exercises/Gigasecond.cs @@ -11,24 +11,16 @@ protected override void UpdateCanonicalData(CanonicalData canonicalData) { foreach (var canonicalDataCase in canonicalData.Cases) { - // Update input - var input = DateTime.Parse(canonicalDataCase.Input["input"].ToString()); - canonicalDataCase.Input["input"] = new UnescapedValue(FormatDateTime(input)); - - // Update expected + var input = DateTime.Parse(canonicalDataCase.Properties["input"].ToString()); + canonicalDataCase.Properties["input"] = new UnescapedValue(FormatDateTime(input)); + canonicalDataCase.Expected = new UnescapedValue(FormatDateTime((DateTime)canonicalDataCase.Expected)); } } - protected override HashSet AddAdditionalNamespaces() - { - return new HashSet() - { - typeof(DateTime).Namespace - }; - } + protected override HashSet AddAdditionalNamespaces() => new HashSet { typeof(DateTime).Namespace }; - private string FormatDateTime(DateTime dateTime) + private static string FormatDateTime(DateTime dateTime) { return dateTime.Hour == 0 && dateTime.Minute == 0 && dateTime.Second == 0 ? $"new DateTime({dateTime.Year}, {dateTime.Month}, {dateTime.Day})" diff --git a/generators/Exercises/Grains.cs b/generators/Exercises/Grains.cs index cba4865dce..95928069d8 100644 --- a/generators/Exercises/Grains.cs +++ b/generators/Exercises/Grains.cs @@ -10,20 +10,12 @@ protected override void UpdateCanonicalData(CanonicalData canonicalData) foreach (var canonicalDataCase in canonicalData.Cases) { if (ShouldThrowException(canonicalDataCase.Expected)) - { canonicalDataCase.ExceptionThrown = typeof(ArgumentOutOfRangeException); - } else - { - canonicalDataCase.Expected = ulong.Parse(canonicalDataCase.Expected.ToString()); - } + canonicalDataCase.Expected = (ulong)canonicalDataCase.Expected; } } - private static bool ShouldThrowException(object value) - { - return int.TryParse(value.ToString(), out int result) - && result == -1; - } + private static bool ShouldThrowException(dynamic value) => value == -1; } } \ No newline at end of file diff --git a/generators/Exercises/Hamming.cs b/generators/Exercises/Hamming.cs index c971de2db3..4a6ec24a61 100644 --- a/generators/Exercises/Hamming.cs +++ b/generators/Exercises/Hamming.cs @@ -8,9 +8,7 @@ public class Hamming : Exercise protected override void UpdateCanonicalData(CanonicalData canonicalData) { foreach (var canonicalDataCase in canonicalData.Cases) - { canonicalDataCase.ExceptionThrown = canonicalDataCase.Expected is long ? null : typeof(ArgumentException); - } } } } diff --git a/generators/Exercises/House.cs b/generators/Exercises/House.cs index 8459b20561..9e1d1517d0 100644 --- a/generators/Exercises/House.cs +++ b/generators/Exercises/House.cs @@ -9,7 +9,7 @@ protected override void UpdateCanonicalData(CanonicalData canonicalData) foreach (var canonicalDataCase in canonicalData.Cases) { canonicalDataCase.UseVariableForExpected = true; - canonicalDataCase.Expected = canonicalDataCase.Expected.ConvertMultiLineString(); + canonicalDataCase.Expected = Convert.ToMultiLineString(canonicalDataCase.Expected); } } } diff --git a/generators/Exercises/PerfectNumbers.cs b/generators/Exercises/PerfectNumbers.cs index 2b35b211f3..bbbe8f4278 100644 --- a/generators/Exercises/PerfectNumbers.cs +++ b/generators/Exercises/PerfectNumbers.cs @@ -2,7 +2,6 @@ using Generators.Input; using Generators.Output; using Humanizer; -using Newtonsoft.Json.Linq; namespace Generators.Exercises { @@ -12,10 +11,10 @@ protected override void UpdateCanonicalData(CanonicalData canonicalData) { foreach (var canonicalDataCase in canonicalData.Cases) { - canonicalDataCase.ExceptionThrown = canonicalDataCase.Expected is JObject ? typeof(ArgumentOutOfRangeException) : null; - if (canonicalDataCase.Expected is string classificationType) canonicalDataCase.Expected = new UnescapedValue($"Classification.{classificationType.Transform(To.SentenceCase)}"); + else + canonicalDataCase.ExceptionThrown = typeof(ArgumentOutOfRangeException); } } } diff --git a/generators/Exercises/Poker.cs b/generators/Exercises/Poker.cs index 2303a85932..e19da3dbed 100644 --- a/generators/Exercises/Poker.cs +++ b/generators/Exercises/Poker.cs @@ -10,9 +10,6 @@ protected override void UpdateCanonicalData(CanonicalData canonicalData) { canonicalDataCase.UseVariableForExpected = true; canonicalDataCase.UseVariableForTested = true; - - canonicalDataCase.Expected = canonicalDataCase.Expected.ConvertToEnumerable(); - canonicalDataCase.Input["input"] = canonicalDataCase.Input["input"].ConvertToEnumerable(); } } } diff --git a/generators/Exercises/QueenAttack.cs b/generators/Exercises/QueenAttack.cs index 2402536ea5..c63d722bec 100644 --- a/generators/Exercises/QueenAttack.cs +++ b/generators/Exercises/QueenAttack.cs @@ -1,8 +1,7 @@ using Generators.Input; using Generators.Output; -using Newtonsoft.Json.Linq; using System; -using System.Collections.Generic; +using System.Linq; namespace Generators.Exercises { @@ -10,26 +9,17 @@ public class QueenAttack : Exercise { protected override void UpdateCanonicalData(CanonicalData canonicalData) { - foreach (var canonicalDataCase in canonicalData.Cases) - { - if (canonicalDataCase.Property == "create") - { - SetCreatePropertyData(canonicalDataCase); - } - } + foreach (var canonicalDataCase in canonicalData.Cases.Where(canonicalDataCase => canonicalDataCase.Property == "create")) + SetCreatePropertyData(canonicalDataCase); } protected override string RenderTestMethodBodyAssert(TestMethodBody testMethodBody) { if (testMethodBody.CanonicalDataCase.Property == "canAttack") - { return RenderCanAttackAssert(testMethodBody); - } if (testMethodBody.UseVariableForTested) - { return string.Empty; - } return base.RenderTestMethodBodyAssert(testMethodBody); } @@ -56,9 +46,9 @@ private static string RenderCanAttackAssert(TestMethodBody testMethodBody) return TemplateRenderer.RenderInline(template, templateParameters); } - private static Tuple GetCoordinatesFromPosition(object rawPosition) + private static Tuple GetCoordinatesFromPosition(dynamic expected) { - var coordinates = ((JObject)rawPosition).ToObject>()["position"].Split(','); + var coordinates = expected["position"].Split(','); var positionX = int.Parse(coordinates[0].TrimStart('(')); var positionY = int.Parse(coordinates[1].TrimEnd(')')); @@ -68,18 +58,17 @@ private static Tuple GetCoordinatesFromPosition(object rawPosition) private static void SetCreatePropertyData(CanonicalDataCase canonicalDataCase) { - var validExpected = (long)canonicalDataCase.Expected >= 0; + var validExpected = canonicalDataCase.Expected >= 0; canonicalDataCase.UseVariableForTested = validExpected; canonicalDataCase.ExceptionThrown = validExpected ? null : typeof(ArgumentOutOfRangeException); canonicalDataCase.Description = validExpected ? canonicalDataCase.Description + " does not throw exception" : canonicalDataCase.Description; var coordinates = GetCoordinatesFromPosition(canonicalDataCase.Input["queen"]); - canonicalDataCase.Input = new Dictionary - { - ["X"] = coordinates.Item1, - ["Y"] = coordinates.Item2 - }; + canonicalDataCase.Properties["X"] = coordinates.Item1; + canonicalDataCase.Properties["Y"] = coordinates.Item2; + + canonicalDataCase.SetInputParameters("X", "Y"); } } } diff --git a/generators/Exercises/RailFenceCipher.cs b/generators/Exercises/RailFenceCipher.cs index 8753152f55..255473318e 100644 --- a/generators/Exercises/RailFenceCipher.cs +++ b/generators/Exercises/RailFenceCipher.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using Generators.Input; +using Generators.Input; namespace Generators.Exercises { @@ -9,13 +8,9 @@ protected override void UpdateCanonicalData(CanonicalData canonicalData) { foreach (var canonicalDataCase in canonicalData.Cases) { - canonicalDataCase.ConstructorInput = new Dictionary - { - ["rails"] = canonicalDataCase.Properties["rails"] - }; - canonicalDataCase.UseVariablesForInput = true; canonicalDataCase.UseVariableForExpected = true; + canonicalDataCase.SetConstructorInputParameters("rails"); } } } diff --git a/generators/Exercises/RnaTranscription.cs b/generators/Exercises/RnaTranscription.cs index 747046172f..05bc2b6e95 100644 --- a/generators/Exercises/RnaTranscription.cs +++ b/generators/Exercises/RnaTranscription.cs @@ -8,9 +8,7 @@ public class RnaTranscription : Exercise protected override void UpdateCanonicalData(CanonicalData canonicalData) { foreach (var canonicalDataCase in canonicalData.Cases) - { canonicalDataCase.ExceptionThrown = canonicalDataCase.Expected is null ? typeof(ArgumentException) : null; - } } } } \ No newline at end of file diff --git a/generators/Exercises/SecretHandshake.cs b/generators/Exercises/SecretHandshake.cs index c5f0085e1a..d0cedbd76d 100644 --- a/generators/Exercises/SecretHandshake.cs +++ b/generators/Exercises/SecretHandshake.cs @@ -1,15 +1,6 @@ -using Generators.Input; - -namespace Generators.Exercises +namespace Generators.Exercises { public class SecretHandshake : Exercise { - protected override void UpdateCanonicalData(CanonicalData canonicalData) - { - foreach (var canonicalDataCase in canonicalData.Cases) - { - canonicalDataCase.Expected = canonicalDataCase.Expected.ConvertToEnumerable(); - } - } } } \ No newline at end of file diff --git a/generators/Exercises/Sieve.cs b/generators/Exercises/Sieve.cs index 64a73f8715..d823a1d139 100644 --- a/generators/Exercises/Sieve.cs +++ b/generators/Exercises/Sieve.cs @@ -10,7 +10,7 @@ protected override void UpdateCanonicalData(CanonicalData canonicalData) foreach (var canonicalDataCase in canonicalData.Cases) { canonicalDataCase.UseVariableForExpected = true; - canonicalDataCase.ExceptionThrown = (long)canonicalDataCase.Input["limit"] < 2 ? typeof(ArgumentOutOfRangeException) : null; + canonicalDataCase.ExceptionThrown = canonicalDataCase.Input["limit"] < 2 ? typeof(ArgumentOutOfRangeException) : null; } } } diff --git a/generators/Exercises/SpaceAge.cs b/generators/Exercises/SpaceAge.cs index 9fe7c6ca34..3aa7dd7e46 100644 --- a/generators/Exercises/SpaceAge.cs +++ b/generators/Exercises/SpaceAge.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using Generators.Input; +using Generators.Input; namespace Generators.Exercises { @@ -9,13 +8,9 @@ protected override void UpdateCanonicalData(CanonicalData canonicalData) { foreach (var canonicalDataCase in canonicalData.Cases) { - canonicalDataCase.ConstructorInput = new Dictionary - { - ["seconds"] = canonicalDataCase.Properties["seconds"] - }; - canonicalDataCase.Property = $"On_{canonicalDataCase.Input["planet"]}"; - canonicalDataCase.Input.Remove("planet"); + canonicalDataCase.SetInputParameters(); + canonicalDataCase.SetConstructorInputParameters("seconds"); } } } diff --git a/generators/Exercises/SumOfMultiples.cs b/generators/Exercises/SumOfMultiples.cs index 222b616731..7b745f242b 100644 --- a/generators/Exercises/SumOfMultiples.cs +++ b/generators/Exercises/SumOfMultiples.cs @@ -1,22 +1,6 @@ -using System; -using System.Linq; -using Generators.Input; - -namespace Generators.Exercises +namespace Generators.Exercises { public class SumOfMultiples : Exercise { - protected override void UpdateCanonicalData(CanonicalData canonicalData) - { - foreach (var canonicalDataCase in canonicalData.Cases) - { - var hasFactors = canonicalDataCase.Input["factors"].ConvertToEnumerable().Any(); - - if (!hasFactors) - { - canonicalDataCase.Input["factors"] = Enumerable.Empty(); - } - } - } } } \ No newline at end of file diff --git a/generators/Exercises/Transpose.cs b/generators/Exercises/Transpose.cs index 2772ccb219..b0f50cf141 100644 --- a/generators/Exercises/Transpose.cs +++ b/generators/Exercises/Transpose.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using Generators.Input; namespace Generators.Exercises @@ -10,11 +9,9 @@ protected override void UpdateCanonicalData(CanonicalData canonicalData) foreach (var canonicalDataCase in canonicalData.Cases) { canonicalDataCase.Property = "String"; - canonicalDataCase.Input = new Dictionary - { - ["input"] = canonicalDataCase.Input["input"].ConvertMultiLineString() - }; - canonicalDataCase.Expected = canonicalDataCase.Expected.ConvertMultiLineString(); + canonicalDataCase.Properties["input"] = Convert.ToMultiLineString(canonicalDataCase.Properties["input"]); + canonicalDataCase.Expected = Convert.ToMultiLineString(canonicalDataCase.Expected); + canonicalDataCase.UseVariablesForInput = true; canonicalDataCase.UseVariableForExpected = true; } diff --git a/generators/Exercises/WordCount.cs b/generators/Exercises/WordCount.cs index 5a3c68241c..2b5258e834 100644 --- a/generators/Exercises/WordCount.cs +++ b/generators/Exercises/WordCount.cs @@ -1,6 +1,6 @@ using Generators.Input; -using Newtonsoft.Json.Linq; using System.Collections.Generic; +using System.Linq; namespace Generators.Exercises { @@ -12,16 +12,13 @@ protected override void UpdateCanonicalData(CanonicalData canonicalData) { canonicalDataCase.UseVariableForExpected = true; canonicalDataCase.UseVariableForTested = true; - canonicalDataCase.Expected = ((JObject)canonicalDataCase.Expected).ToObject>(); + canonicalDataCase.Expected = ConvertExpected(canonicalDataCase.Expected); } } - protected override HashSet AddAdditionalNamespaces() - { - return new HashSet() - { - typeof(Dictionary).Namespace - }; - } + private static dynamic ConvertExpected(dynamic expected) + => ((Dictionary)expected).ToDictionary(kv => kv.Key, kv => int.Parse(kv.Value.ToString())); + + protected override HashSet AddAdditionalNamespaces() => new HashSet { typeof(Dictionary).Namespace }; } } diff --git a/generators/Input/CanonicalDataCase.cs b/generators/Input/CanonicalDataCase.cs index 00459fe513..a6df34f562 100644 --- a/generators/Input/CanonicalDataCase.cs +++ b/generators/Input/CanonicalDataCase.cs @@ -1,15 +1,16 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -using Newtonsoft.Json; using System.Linq; +using Newtonsoft.Json; namespace Generators.Input { [JsonConverter(typeof(CanonicalDataCaseJsonConverter))] public class CanonicalDataCase { - private IDictionary _constructorInput; + private readonly HashSet _inputParameters = new HashSet(); + private readonly HashSet _constructorInputParameters = new HashSet(); [Required] public string Description { get; set; } @@ -18,28 +19,22 @@ public class CanonicalDataCase public string Property { get; set; } [JsonIgnore] - public IDictionary Input { get; set; } + public IReadOnlyDictionary Input + => _inputParameters.ToDictionary(parameter => parameter, parameter => Properties[parameter]); [JsonIgnore] - public IDictionary ConstructorInput - { - get - { - return _constructorInput; - } - set - { - RemoveDuplicateInputEntries(value); - UpdateInstanceType(value); - - _constructorInput = value; - } - } + public IReadOnlyDictionary ConstructorInput + => _constructorInputParameters.ToDictionary(parameter => parameter, parameter => Properties[parameter]); - public object Expected { get; set; } + [JsonIgnore] + public IDictionary Properties { get; set; } [JsonIgnore] - public IDictionary Properties { get; set; } + public dynamic Expected + { + get => Properties["expected"]; + set => Properties["expected"] = value; + } [JsonIgnore] public bool UseVariablesForInput { get; set; } @@ -59,23 +54,22 @@ public IDictionary ConstructorInput [JsonIgnore] public Type ExceptionThrown { get; set; } - private void RemoveDuplicateInputEntries(IDictionary constructorInputDictionary) + public void SetInputParameters(params string[] properties) { - foreach (var key in constructorInputDictionary.Keys) - { - if (Input.ContainsKey(key)) - { - Input.Remove(key); - } - } + _inputParameters.Clear(); + _inputParameters.UnionWith(properties); + + _constructorInputParameters.ExceptWith(properties); } - private void UpdateInstanceType(IDictionary constructorInputDictionary) + public void SetConstructorInputParameters(params string[] properties) { - if (constructorInputDictionary.Keys.Any()) - { - TestedMethodType = TestedMethodType.Instance; - } + _constructorInputParameters.Clear(); + _constructorInputParameters.UnionWith(properties); + + _inputParameters.ExceptWith(properties); + + TestedMethodType = TestedMethodType.Instance; } } } \ No newline at end of file diff --git a/generators/Input/CanonicalDataCaseJson.cs b/generators/Input/CanonicalDataCaseJson.cs new file mode 100644 index 0000000000..89b1eae89a --- /dev/null +++ b/generators/Input/CanonicalDataCaseJson.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json.Linq; + +namespace Generators.Input +{ + public static class CanonicalDataCaseJson + { + public static IDictionary ToDictionary(JToken jToken) => ConvertProperty(jToken); + + private static dynamic ConvertProperty(dynamic property) + { + if (property is JArray jArray) + return ConvertArrayProperty(property, jArray); + + if (property is JToken jToken) + return ConvertTokenProperty(jToken); + + return property; + } + + private static dynamic ConvertTokenProperty(JToken jToken) + { + var properties = jToken.ToObject>(); + + for (var i = 0; i < properties.Count; i++) + { + var key = properties.Keys.ElementAt(i); + properties[key] = ConvertProperty(properties[key]); + } + + return properties; + } + + private static dynamic ConvertArrayProperty(dynamic property, JArray jArray) + { + // We can't determine the type of the array if the array is empty + if (!jArray.Any()) + return property; + + // We can only convert when all values have the same type + if (jArray.Select(x => x.Type).Distinct().Count() != 1) + return property; + + switch (jArray[0].Type) + { + case JTokenType.Object: + return jArray.Select(ConvertProperty).ToArray(); + case JTokenType.Integer: + return jArray.ToObject(); + case JTokenType.Float: + return jArray.ToObject(); + case JTokenType.String: + return jArray.ToObject(); + case JTokenType.Boolean: + return jArray.ToObject(); + case JTokenType.Date: + return jArray.ToObject(); + case JTokenType.Bytes: + return jArray.ToObject(); + case JTokenType.Guid: + return jArray.ToObject(); + case JTokenType.Uri: + return jArray.ToObject(); + case JTokenType.TimeSpan: + return jArray.ToObject(); + default: + return property; + } + } + } +} diff --git a/generators/Input/CanonicalDataCaseJsonConverter.cs b/generators/Input/CanonicalDataCaseJsonConverter.cs index 2903c25fa0..08e9ed93c2 100644 --- a/generators/Input/CanonicalDataCaseJsonConverter.cs +++ b/generators/Input/CanonicalDataCaseJsonConverter.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -7,7 +8,7 @@ namespace Generators.Input { public class CanonicalDataCaseJsonConverter : JsonConverter { - private static readonly string[] NonInputProperties = {"description", "property", "expected", "comments"}; + private static readonly string[] NonInputProperties = { "description", "property", "expected", "comments" }; public override bool CanConvert(Type objectType) => typeof(CanonicalDataCase) == objectType; @@ -17,23 +18,14 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist var canonicalDataCase = new CanonicalDataCase(); serializer.Populate(new JTokenReader(jToken), canonicalDataCase); - - canonicalDataCase.Properties = jToken.ToObject>(); - canonicalDataCase.Input = GetInputProperty(jToken); - canonicalDataCase.ConstructorInput = new Dictionary(); - + + canonicalDataCase.Properties = CanonicalDataCaseJson.ToDictionary(jToken); + canonicalDataCase.SetInputParameters(GetInputProperties(canonicalDataCase.Properties)); + return canonicalDataCase; } - private static IDictionary GetInputProperty(JToken jToken) - { - var allProperties = jToken.ToObject>(); - - foreach (var nonInputProperty in NonInputProperties) - allProperties.Remove(nonInputProperty); - - return allProperties; - } + private static string[] GetInputProperties(IDictionary properties) => properties.Keys.Except(NonInputProperties).ToArray(); public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException(); } diff --git a/generators/Input/CanonicalDataCasesJson.cs b/generators/Input/CanonicalDataCasesJson.cs new file mode 100644 index 0000000000..a32b486831 --- /dev/null +++ b/generators/Input/CanonicalDataCasesJson.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json.Linq; + +namespace Generators.Input +{ + public static class CanonicalDataCasesJson + { + private const string TokensPath = "$..*[?(@.property)]"; + + public static CanonicalDataCase[] ToArray(JToken casesToken) + { + var caseTokens = new JArray(casesToken.SelectTokens(TokensPath)); + var canonicalDataCases = new JArray(caseTokens).ToObject(); + + ConvertEmptyJArrayToArray(canonicalDataCases); + + return canonicalDataCases; + } + + private static void ConvertEmptyJArrayToArray(CanonicalDataCase[] canonicalDataCases) + { + foreach (var groupedCanonicalDataCases in canonicalDataCases.ToLookup(c => c.Property)) + { + foreach (var groupedProperties in groupedCanonicalDataCases.SelectMany(x => x.Properties).ToLookup(x => x.Key)) + { + var arrayType = GetArrayType(groupedProperties); + if (arrayType == null) + continue; + + foreach (var groupedCanonicalDataCase in GetEmptyJArrays(groupedCanonicalDataCases, groupedProperties)) + groupedCanonicalDataCase.Properties[groupedProperties.Key] = Array.CreateInstance(arrayType, 0); + } + } + } + + private static Type GetArrayType(IGrouping> groupedProperties) + { + if (groupedProperties.Any(x => x.Value is string[])) + return typeof(string); + + if (groupedProperties.Any(x => x.Value is int[])) + return typeof(int); + + if (groupedProperties.Any(x => x.Value is float[])) + return typeof(float); + + return null; + } + + private static IEnumerable GetEmptyJArrays(IGrouping groupedCanonicalDataCases, IGrouping> groupedProperties) + => groupedCanonicalDataCases.Where(canonicalDataCase => IsEmptyJArray(canonicalDataCase, groupedProperties)); + + private static bool IsEmptyJArray(CanonicalDataCase x, IGrouping> groupedProperties) + => x.Properties[groupedProperties.Key] is JArray jArray && jArray.Count == 0; + } +} \ No newline at end of file diff --git a/generators/Input/CanonicalDataCasesJsonConverter.cs b/generators/Input/CanonicalDataCasesJsonConverter.cs index 273149c41b..571ab5a726 100644 --- a/generators/Input/CanonicalDataCasesJsonConverter.cs +++ b/generators/Input/CanonicalDataCasesJsonConverter.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Reflection; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -8,17 +7,10 @@ namespace Generators.Input { public class CanonicalDataCasesJsonConverter : JsonConverter { - private const string TokensPath = "$..*[?(@.property)]"; + public override bool CanConvert(Type objectType) => typeof(CanonicalDataCase[]).GetTypeInfo().IsAssignableFrom(objectType); - public override bool CanConvert(Type objectType) => typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(objectType); - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - var casesToken = JToken.ReadFrom(reader); - var caseTokens = new JArray(casesToken.SelectTokens(TokensPath)); - - return new JArray(caseTokens).ToObject(objectType); - } + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + => CanonicalDataCasesJson.ToArray(JToken.ReadFrom(reader)); public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException(); } diff --git a/generators/Output/TestMethodBodyData.cs b/generators/Output/TestMethodBodyData.cs index 694d401108..588cc6ae1e 100644 --- a/generators/Output/TestMethodBodyData.cs +++ b/generators/Output/TestMethodBodyData.cs @@ -19,7 +19,7 @@ public TestMethodBodyData(TestMethodBody testMethodBody) } public object TestedValue => _testMethodBody.UseVariableForTested ? TestedVariableName : TestedMethodInvocation; - public object InputParameters => _testMethodBody.UseVariablesForInput ? string.Join(", ", CanonicalDataCase.Input.Keys.Select(key => NameExtensions.ToVariableName(key))) : Input; + public object InputParameters => _testMethodBody.UseVariablesForInput ? string.Join(", ", CanonicalDataCase.Input.Keys.Select(key => key.ToVariableName())) : Input; public object ExpectedParameter => _testMethodBody.UseVariableForExpected ? ExpectedVariableName : Expected; public object ConstructorParameters => _testMethodBody.UseVariablesForConstructorParameters ? string.Join(", ", CanonicalDataCase.ConstructorInput.Keys.Select(key => key.ToVariableName())) : ConstructorInput; diff --git a/generators/Output/ValueFormatter.cs b/generators/Output/ValueFormatter.cs index fbb82fa3f1..129d9992ff 100644 --- a/generators/Output/ValueFormatter.cs +++ b/generators/Output/ValueFormatter.cs @@ -41,8 +41,8 @@ public static object Format(object val) } } - public static string[] FormatVariables(IDictionary dict) - => dict.Keys.SelectMany((key, i) => FormatVariable(dict[key], key.ToVariableName())).ToArray(); + public static string[] FormatVariables(IReadOnlyDictionary dict) + => dict.Keys.SelectMany(key => FormatVariable(dict[key], key.ToVariableName())).ToArray(); public static string[] FormatVariable(object val, string name) { @@ -50,10 +50,6 @@ public static string[] FormatVariable(object val, string name) { case string str when str.Contains("\n"): return FormatMultiLineString(name, str); - case int[] ints when ints.Any(): - return FormatMultiLineEnumerable(ints.Select(x => x.ToString(CultureInfo.InvariantCulture)), name); - case string[] strings when strings.Any(): - return FormatMultiLineEnumerable(strings, name); case IDictionary dict: return FormatMultiLineEnumerable(dict.Keys.Select((key, i) => $"[{Format(key)}] = {Format(dict[key])}" + (i < dict.Keys.Count - 1 ? "," : "")), name, "new Dictionary"); case IDictionary dict: