Skip to content

Generators refactoring #601

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

Merged
merged 97 commits into from
Jul 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
1c0dbc2
generators: Ignore Rider settings files
ErikSchierboom Jun 17, 2018
d510410
generators: Refactor additional namespaces
ErikSchierboom Jun 17, 2018
2ae70ff
exercises: Update to latest canonical data
ErikSchierboom Jun 17, 2018
5123f65
exercises: Use Array.Empty<T> instead of new T[0]
ErikSchierboom Jun 18, 2018
5a43560
generators: Use static class
ErikSchierboom Jun 18, 2018
dc72c27
generators: Remove unused using statements
ErikSchierboom Jun 18, 2018
3fa390b
generators: Move exercise field to canonical data case class
ErikSchierboom Jun 18, 2018
745cc84
generators: Use environment specific newline
ErikSchierboom Jun 18, 2018
0d08690
generators: Fix culture-specific output
ErikSchierboom Jun 18, 2018
48779f2
generators: Replace UpdateCanonicalData with UpdateCanonicalDataCase
ErikSchierboom Jun 18, 2018
2a62574
generators: Test method body rendering methods return IEnumerable<str…
ErikSchierboom Jun 18, 2018
153376a
generators: Use var everywhere
ErikSchierboom Jun 18, 2018
6f4cc49
generator: Code cleanup
ErikSchierboom Jun 18, 2018
ff1f7bc
generators: Remove unused parameter
ErikSchierboom Jun 18, 2018
096dcab
generators: Move variables data to TestMethodData
ErikSchierboom Jun 19, 2018
67fefe6
generators: Make canonical data class immutable
ErikSchierboom Jun 20, 2018
55e4ff7
generators: Extract rendering logic from test data to test method body
ErikSchierboom Jun 21, 2018
bbc999b
generators: Replace Exercise and Property with TestedClass and Tested…
ErikSchierboom Jun 22, 2018
998873c
generators: Update package versions
ErikSchierboom Jun 23, 2018
ea4586b
generators: Don't use sealed
ErikSchierboom Jun 23, 2018
245e122
generators: Use UpdateTestClass/UpdateTestMethod/UpdateTestMethodBody…
ErikSchierboom Jun 23, 2018
9a81135
exercises: Sort namespaces
ErikSchierboom Jun 23, 2018
6de8d02
generator: Make GeneratorExercise API more consistent
ErikSchierboom Jun 24, 2018
0c9ddd8
generators: Remove unneeded initialization
ErikSchierboom Jun 24, 2018
4ce46a9
generators: Rename ExerciseWriter to TestClassFile
ErikSchierboom Jun 24, 2018
51caf22
generators: Move template specific code to separate namespace
ErikSchierboom Jun 24, 2018
9fe5b48
generators: Move helpers to separate namespace
ErikSchierboom Jun 24, 2018
761ee44
generators: Remove unneeded generator scripts
ErikSchierboom Jun 24, 2018
5c246fb
generators: Update namespace
ErikSchierboom Jun 24, 2018
a16860b
generators: Add separate test method for empty assertion
ErikSchierboom Jun 25, 2018
bacbd8a
generators: Improve naming of test method body implementations
ErikSchierboom Jun 25, 2018
a218912
generators: Don't use assert template parameters in generators
ErikSchierboom Jun 25, 2018
dfc170f
generators: Use consistent naming for TestMethodBody parameter
ErikSchierboom Jun 25, 2018
b3f5bdc
generators: Simplified test method and class code
ErikSchierboom Jun 25, 2018
a423ec1
generators: Make lifecycle of update methods be more sane
ErikSchierboom Jun 25, 2018
df1812f
generators: Simplify triangle generator
ErikSchierboom Jun 26, 2018
a09a1ea
generators: Introduce multiline string type
ErikSchierboom Jun 26, 2018
86a91c2
generators: Remove dynamic extensions
ErikSchierboom Jun 26, 2018
7aa7f29
generators: Remove type extensions
ErikSchierboom Jun 27, 2018
795dcc2
generators: Simplify description path logic
ErikSchierboom Jun 27, 2018
ecf032e
generators: Move JToken conversion helpers to separate class
ErikSchierboom Jun 27, 2018
8ce18d8
generators: Fix invalid ordering of test case when nesting is used
ErikSchierboom Jun 28, 2018
28a7d63
generators: Remove unused conversion cases
ErikSchierboom Jun 28, 2018
daa3e06
generators: Remove convert helper
ErikSchierboom Jun 28, 2018
091b9a6
generators: Introduce assertion rendering helper
ErikSchierboom Jun 29, 2018
b925e46
generators: Revert to using string as render output
ErikSchierboom Jun 29, 2018
88984f8
generators: Use assertion helpers
ErikSchierboom Jun 29, 2018
31627be
generators: Add throws assertion generic overload
ErikSchierboom Jun 29, 2018
bbfa24b
generators: Use standard value formatter in binary search tree generator
ErikSchierboom Jun 29, 2018
52d2233
generators: Introduce rendering namespace
ErikSchierboom Jun 30, 2018
cb0d78c
generators: Add enum rendering helper
ErikSchierboom Jun 30, 2018
5f17892
generators: Rename Format to Render
ErikSchierboom Jun 30, 2018
07874ba
generators: Move rendering logic to separate partial classes
ErikSchierboom Jun 30, 2018
e77a86f
generators: Make list rendering generic
ErikSchierboom Jun 30, 2018
5e459c5
generators: Make array rendering generic
ErikSchierboom Jun 30, 2018
fafae78
generators: Make dictionary rendering generic
ErikSchierboom Jul 1, 2018
f58aa78
generators: Improved friendly name generation
ErikSchierboom Jul 1, 2018
eced4e9
generators: Make multidimensional array rendering generic
ErikSchierboom Jul 1, 2018
72a1b21
generators: Make tuple rendering generic
ErikSchierboom Jul 1, 2018
b4efb09
isbn-verifier: Update tests
ErikSchierboom Jul 3, 2018
45bfaa0
generators: Add friendly name support for char and array types
ErikSchierboom Jul 3, 2018
ac62465
generators: Refactor dictionary variable rendering
ErikSchierboom Jul 3, 2018
dc07152
maintainers: Update ErikSchierboom info (#599)
ErikSchierboom Jun 18, 2018
b01c1a6
generators: Refactor dictionary variable rendering
ErikSchierboom Jul 3, 2018
34ebcd4
generators: Refactor multi-line string (variable) rendering
ErikSchierboom Jul 3, 2018
291dd13
generators: Simplify binary search tree generator
ErikSchierboom Jul 3, 2018
ac0fd06
generators: Have variable rendering only return single value
ErikSchierboom Jul 3, 2018
102e033
generators: Use Environment.Newline where possible
ErikSchierboom Jul 3, 2018
8257eb7
generators: Simplify ocr-numbers generator
ErikSchierboom Jul 3, 2018
4c9d6f5
generators: Refactor array variable rendering
ErikSchierboom Jul 3, 2018
0c722ce
generators: Remove unused methods
ErikSchierboom Jul 3, 2018
653bff3
generators: Simplify string/char escaping code
ErikSchierboom Jul 3, 2018
c947504
generators: Add collection initialization renderer
ErikSchierboom Jul 3, 2018
7fc5ea4
generators: Use variable render helper to render variables
ErikSchierboom Jul 3, 2018
f70d7c4
generators: Refactor generators
ErikSchierboom Jul 3, 2018
643b124
generators: Fix simple-cipher generator
ErikSchierboom Jul 4, 2018
4894680
generators: Correctly render null value
ErikSchierboom Jul 5, 2018
7a98721
generators: Return correct friendly name for Nullable<T> and ValueTup…
ErikSchierboom Jul 5, 2018
6b8c7f8
generators: Allow forced formatting of multi-line array
ErikSchierboom Jul 5, 2018
046ab42
generators: Fix list-ops nested empty list
ErikSchierboom Jul 5, 2018
76754ca
generators: Add missing namespace to nucleotide-count generator
ErikSchierboom Jul 5, 2018
5e82b5b
generators: Fix failing grep example implementation
ErikSchierboom Jul 5, 2018
3fe8b01
exercises: Use shorthand notation for ValueTuple
ErikSchierboom Jul 5, 2018
56a0fa2
generators: Fix multiline rendering not handling null references
Jul 6, 2018
42c4ee8
generators: Make TestClassFile static
Jul 6, 2018
4959a96
generators: Merge TestData with TestMethod
ErikSchierboom Jul 6, 2018
a47b54d
generators: Move TestClass and TestMethod rendering output to separat…
ErikSchierboom Jul 6, 2018
2b44b7f
generators: Extract different property handling paths to separate met…
ErikSchierboom Jul 8, 2018
f2d030d
generators: Simplify flatten-array generator
ErikSchierboom Jul 8, 2018
816b0a9
generators: Refactor test method output
ErikSchierboom Jul 8, 2018
8eb23b9
generators: Update docs
ErikSchierboom Jul 8, 2018
cc593f9
generators: Add missing links to docs and use consistent naming
ErikSchierboom Jul 9, 2018
fbe4a34
go-counting: Add space between operators in example implementation
ErikSchierboom Jul 9, 2018
523748a
generators: Use consistent formatting of input and expected values fo…
ErikSchierboom Jul 9, 2018
e50998c
generators: Increase length for single-line array initializers
ErikSchierboom Jul 10, 2018
2764341
generators: Remove automatic multi-line rendering for one-dimensional…
ErikSchierboom Jul 10, 2018
e46f687
generators: Update docs
ErikSchierboom Jul 15, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ packages/
obj/
bin/
*.userprefs
.dotnet/
*.DotSettings.user
.dotnet/

.vs/
Expand Down
4 changes: 2 additions & 2 deletions config/maintainers.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"name": "Erik Schierboom",
"link_text": "My blog",
"link_url": "http://www.erikschierboom.com/",
"avatar_url": null,
"bio": null
"avatar_url": "https://nl.gravatar.com/userimage/27030165/64dc5009cee6a1177883121d464d7743.jpg",
"bio": "I am a developer with a passion for learning new languages. C# is a well-designed and expressive language that I love programming in."
},
{
"github_username": "burtlo",
Expand Down
227 changes: 187 additions & 40 deletions docs/GENERATORS.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# Test Generators
# Test generators

Test generators allow tracks to generate tests automatically without having to write them ourselves. Each test generator reads from the exercise's `canonical data`, which defines the name of the test, its inputs, and outputs. You can read more about exercism's approach to test suites [here](https://github.com/exercism/docs/blob/master/language-tracks/exercises/anatomy/test-suites.md).

Generating tests automatically removes any sort of user error when creating tests. We want the tests to be accurate with respect to its canonical data. Test generation also makes it much easier to keep tests up to date. As the canonical data changes, the tests will be automatically updated when the generator for that test is run.
Generating tests automatically removes any sort of user error when creating tests. Furthermore, we want the tests to be accurate with respect to its canonical data. Test generation also makes it much easier to keep tests up to date. As the canonical data changes, the tests will be automatically updated when the generator for that test is run.

An example of a canonical data file can be found [here](https://github.com/exercism/problem-specifications/blob/master/exercises/bob/canonical-data.json)

## Common Terms
## Common terms

When looking through the canonical data and the generator code base, we use a lot of common terminology. This list hopefully clarifies what they represent.

- Canonical Data - Represents the entire test suite.
Expand All @@ -16,87 +17,232 @@ When looking through the canonical data and the generator code base, we use a lo
- Input - The input for the test case.
- Expected - The expected value when running the test case.

## Adding A Simple Generator
Adding a test generator file is straightforward. Simply add a new file to the generators folder with the name of the exercise (in PascalCase), and extend the `GeneratorExercise` abstract class.
## Adding a simple generator

Adding a test generator is straightforward. Simply add a new file to the `Exercises/Generators` folder with the name of the exercise (in PascalCase), and create a class that extends the `GeneratorExercise` class.

An example of a simple generator would be the Bob exercise. The source is below, but you can freely view it in the repository [here](https://github.com/exercism/csharp/blob/master/generators/Exercises/Bob.cs).
An example of a simple generator would be the Bob exercise. The source is displayed below, but you can freely view it in the repository [here](https://github.com/exercism/csharp/blob/master/generators/Exercises/Bob.cs).

```csharp
namespace Generators.Exercises
namespace Exercism.CSharp.Exercises.Generators
{
public class Bob : GeneratorExercise
{
}
}
```

This is a fully working generator, no other code needs to be written. However, it's simplicity stems from the fact that the test suite and the program itself are relatively trivial.
This is a fully working generator, no other code needs to be written! However, it's simplicity stems from the fact that the test suite and the program itself are relatively trivial.

## Adding a complex generator

## Adding A Complex Generator
When the generator's default output is not sufficient, you can override the `GeneratorExercise` class' virtual methods to override the default behavior.

A more *complex* generator would be the ComplexNumbers generator found [here](https://github.com/exercism/csharp/blob/master/generators/Exercises/ComplexNumbers.cs).
### Method 1: UpdateTestMethod(TestMethod testMethod)

The `GeneratorExercise` abstract class currently exposes five methods that are used for overriding the default behavior when generating an exercise.
Update the test method that described the test method being generated. When you are required to customize a test generator, overriding this method is virtually always what you want to do.

### void UpdateCanonicalData(CanonicalData canonicalData)
Update the canonical data for a given test.
There are many things that can be customized, of which we'll list the more common usages.

The most common use for this override is to iterate over each of the canonical data cases.
#### Customize test data

As an example, if you wanted to change the default behavior so that when the `Input` value of a test is a negative number, an exception should be thrown, the code would look like this.
It is not uncommon that a generator has to transform its input data or expected value to a different value/representation.

An example of this is the [bracket-push](https://github.com/exercism/csharp/blob/master/generators/Exercises/Generators/BracketPush.cs) generator, which has a `"value"` input value, which is of type `string`. However, this `string` value contains a backslash, which needs to escaped in order for it to be rendered correctly:

```csharp
protected override void UpdateCanonicalData(CanonicalData canonicalData)
protected override void UpdateTestMethod(TestMethod testMethod)
{
foreach (var canonicalDataCase in canonicalData.Cases)
{
var caseInputLessThanZero = (long)canonicalDataCase.Input["number"] < 0;
canonicalDataCase.ExceptionThrown = caseInputLessThanZero ? typeof(ArgumentException) : null;
}
testMethod.Input["value"] = testMethod.Input["value"].Replace("\\", "\\\\");
// [...]
}
```

### HashSet\<string\> AddAdditionalNamespaces()
Allows more namespaces to be added to the test suite.
Another common use case is to handle empty arrays. If an array is empty, its type will default to `JArray`, which doesn't have any type information. To allow the generator to output a correctly typed array, we have to convert the `JArray` to an array first.

The tests use `Xunit` so all tests will automatically include the `Xunit` namespace. However, more advanced tests may require additional namespaces.
An example of this is the [proverb](https://github.com/exercism/csharp/blob/master/generators/Exercises/Generators/Proverb.cs) generator, which converts the `JArray` to an empty `string` array:

```csharp
protected override HashSet<string> AddAdditionalNamespaces()
protected override void UpdateTestMethod(TestMethod testMethod)
{
return new HashSet<string>()
{
typeof(Dictionary<char, int>).Namespace
};
// [...]

if (testMethod.Input["strings"] is JArray)
testMethod.Input["strings"] = Array.Empty<string>();

if (testMethod.Expected is JArray)
testMethod.Expected = Array.Empty<string>();
}
```

#### Output test data as variables

Sometimes, it might make sense to not define a test method's data inline, but as variables.

An example of this is the [crypto-square](https://github.com/exercism/csharp/blob/master/generators/Exercises/Generators/CryptoSquare.cs) generator, which indicates that both the test method input as well as the expected value, should be stored in variables:

```csharp
protected override void UpdateTestMethod(TestMethod testMethod)
{
testMethod.UseVariablesForInput = true;
testMethod.UseVariableForExpected = true;
}
```

#### Custom tested method type

By default, the generator will test a static method. However, you can also test for instance methods, extension methods, properties and constructors.

An example of this is the [roman-numerals](https://github.com/exercism/csharp/blob/master/generators/Exercises/Generators/RomanNumerals.cs) generator, which indicates that it tests an extensions method:

```csharp
protected override void UpdateTestMethod(TestMethod testMethod)
{
testMethod.TestedMethodType = TestedMethodType.ExtensionMethod;
testMethod.TestedMethod = "ToRoman";
}
```

This snippet would add the namespace that the `Dictionary<char, int>` collection lives in (`System.Collections.Generic`).
#### Change names used

As we saw in the previous example, you can also customize the name of the tested method. You are also allowed to customize the tested class' name and the test method name.

### string RenderTestMethodBody[Arrange/Act/Assert]
Override the default behavior when rendering a test methods arrange, act, and/or assert sections.
An example of this is the [triangle](https://github.com/exercism/csharp/blob/master/generators/Exercises/Generators/Triangle.cs) generator, which by default generates duplicate test method names (which will be a compile-time error), but instead uses the `TestMethodNameWithPath` to use the full path as the test method name (effectively making the test method name unique):

```csharp
protected override void UpdateTestMethod(TestMethod testMethod)
{
// [...]
testMethod.TestMethodName = testMethod.TestMethodNameWithPath;
// [...]
}
```

More advanced tests may need to leverage a `template`. A template allows you to add additional code to a test and assert more complex statements.
#### Test for an exception being thrown

An example of this is the [RunLengthEncoding](https://github.com/exercism/csharp/blob/master/generators/Exercises/RunLengthEncoding.cs) test.
Some test methods want to verify that an exception is being thrown.

Here the **Assert** is being overridden. The assert needs to call additional functions, but only if the property is `consistency`. Otherwise, render the assert as usual.
An example of this is the [rna-transcription](https://github.com/exercism/csharp/blob/master/generators/Exercises/Generators/RnaTranscription.cs) generator, which defines that some of its test methods should throw an `ArgumentException`:

### string[] RenderAdditionalMethods()
Allow additional methods to be added to the test suite.
```csharp
protected override void UpdateTestMethod(TestMethod testMethod)
{
if (testMethod.Expected is null)
testMethod.ExceptionThrown = typeof(ArgumentException);
}
```

There may exist cases where a suite of unit tests will need to reuse the same logic in each of the tests. Rather than duplicating code, this method allows you to provide helper methods for the tests.
Note that `ArgumentException` type's namespace will be automatically added to the list of namespaces used in the test class.

An example of this is the [Tournament](https://github.com/exercism/csharp/blob/master/generators/Exercises/Tournament.cs#L45) generator.
#### Custom input/constructor parameters

Additional methods added using this override will be added to the bottom of the test suite.
In some cases, you might want to override the parameters that are used as input parameters.

An example of this is the [two-fer](https://github.com/exercism/csharp/blob/master/generators/Exercises/Generators/TwoFer.cs) generator, which does not use any input parameters when the `"name"` input parameter is set to `null`:

```csharp
protected override void UpdateTestMethod(TestMethod testMethod)
{
// [...]

if (testMethod.Input["name"] is null)
testMethod.InputParameters = Array.Empty<string>();
}
```

If a test method tests an instance method, you can also specify which parameters to use as constructor parameters (the others will be input parameters, unless specified otherwise).

An example of this is the [matrix](https://github.com/exercism/csharp/blob/master/generators/Exercises/Generators/Matrix.cs) generator, which specifies that the `"string"` parameter should be passed as a constructor parameter:

```csharp
protected override void UpdateTestMethod(TestMethod testMethod)
{
testMethod.TestedMethodType = TestedMethodType.InstanceMethod;
testMethod.ConstructorInputParameters = new[] { "string" };
}
```

#### Custom arrange/act/assert code

Although this should be used as a last resort, some generators might want to skip the default generation completely and control which arrange, act or assert code the test method should contain.

An example of this is the [run-length-encoding](https://github.com/exercism/csharp/blob/master/generators/Exercises/Generators/RunLengthEncoding.cs) generator, which uses a custom assertion for one specific property:

```csharp
protected override void UpdateTestMethod(TestMethod testMethod)
{
// [...]

if (testMethod.Property == "consistency")
testMethod.Assert = RenderConsistencyToAssert(testMethod);
}

private string RenderConsistencyToAssert(TestMethod testMethod)
{
var expected = Render.Object(testMethod.Expected);
var actual = $"{testMethod.TestedClass}.Decode({testMethod.TestedClass}.Encode({expected}))";
return Render.AssertEqual(expected, actual);
}
```

Note that the `Render` instance is used to render the assertion and the expected value.

### Method 2: UpdateNamespaces(ISet<string> namespaces)

Allows additional namespaces to be added to the test suite.

All tests use the `Xunit` framework, so each test class will automatically include the `Xunit` namespace. However, some test classes may require additional namespaces.

An example of this is the [gigasecond](https://github.com/exercism/csharp/blob/master/generators/Exercises/Generators/Gigasecond.cs) generator, which uses the `DateTime` class in its test methods, and thus adds its namespace to the list of namespaces:

```csharp
protected override void UpdateNamespaces(ISet<string> namespaces)
{
namespaces.Add(typeof(DateTime).Namespace);
}
```

Note that as mentioned before, the namespace of any thrown exception types are automatically added to the list of namespaces.

### Method 3: UpdateTestClass(TestClass testClass)

This method allows you to customize the output of the test class. Only in rare cases would you want to override this method. The most common use case to override this method, is to add additional (helper) methods to the test suite.

An example of this is the [tournament](https://github.com/exercism/csharp/blob/master/generators/Exercises/Generators/Tournament.cs) generator, which adds a helper method to the test suite:

```csharp
protected override void UpdateTestClass(TestClass testClass)
{
AddRunTallyMethod(testClass);
}

private static void AddRunTallyMethod(TestClass testClass)
{
testClass.AdditionalMethods.Add(@"
private string RunTally(string input)
{
var encoding = new UTF8Encoding();

using (var inStream = new MemoryStream(encoding.GetBytes(input)))
using (var outStream = new MemoryStream())
{
Tournament.Tally(inStream, outStream);
return encoding.GetString(outStream.ToArray());
}
}");
}
```

Additional methods will be added to the bottom of the test suite.

## Updating Existing Files

It is possible that an existing exercise does not match the canonical data. It is OK to update the exercise stub and/or the exercise example to follow the canonical data! An example might be that an exercise is named SumOfMultiples, but the SumOfMultiples.cs and Example.cs files both use `Multiples` as the name of the class.

Also, if you find an issue with one of the existing generators or test suites simply open up the generator that you would like to update, make your changes, and then run the generators.

## Running The Generators

This repository is coded against [.NET Core](https://www.microsoft.com/net/core). To run the generators all you need to do is run the following command in the generators directory:

`dotnet run`
Expand All @@ -112,4 +258,5 @@ Once the generator has been run, you can view the output of your generation by n
`exercises/bob/BobTest.cs`

## Submitting A Generator

If you are satisfied with the output of your generator, we would love for you to submit a pull request! Please include your generator, updated test suite, and any other corresponding files that you may have changed.
6 changes: 3 additions & 3 deletions exercises/all-your-base/AllYourBaseTest.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// This file was auto-generated based on version 2.3.0 of the canonical data.

using Xunit;
using System;
using Xunit;

public class AllYourBaseTest
{
Expand Down Expand Up @@ -89,7 +89,7 @@ public void Number_15_bit_integer()
public void Empty_list()
{
var inputBase = 2;
var digits = new int[0];
var digits = Array.Empty<int>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

var outputBase = 10;
var expected = new[] { 0 };
Assert.Equal(expected, AllYourBase.Rebase(inputBase, digits, outputBase));
Expand Down Expand Up @@ -138,7 +138,7 @@ public void Input_base_is_one()
public void Input_base_is_zero()
{
var inputBase = 0;
var digits = new int[0];
var digits = Array.Empty<int>();
var outputBase = 10;
Assert.Throws<ArgumentException>(() => AllYourBase.Rebase(inputBase, digits, outputBase));
}
Expand Down
2 changes: 1 addition & 1 deletion exercises/alphametics/AlphameticsTest.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// This file was auto-generated based on version 1.2.0 of the canonical data.

using Xunit;
using System;
using System.Collections.Generic;
using Xunit;

public class AlphameticsTest
{
Expand Down
28 changes: 14 additions & 14 deletions exercises/binary-search-tree/BinarySearchTreeTest.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// This file was auto-generated based on version 1.0.0 of the canonical data.

using Xunit;
using System.Linq;
using Xunit;

public class BinarySearchTreeTest
{
Expand All @@ -12,19 +12,6 @@ public void Data_is_retained()
Assert.Equal(4, tree.Value);
}

[Fact(Skip = "Remove to run test")]
public void Can_create_complex_tree()
{
var tree = new BinarySearchTree(new[] { 4, 2, 6, 1, 3, 5, 7 });
Assert.Equal(4, tree.Value);
Assert.Equal(2, tree.Left.Value);
Assert.Equal(1, tree.Left.Left.Value);
Assert.Equal(3, tree.Left.Right.Value);
Assert.Equal(6, tree.Right.Value);
Assert.Equal(5, tree.Right.Left.Value);
Assert.Equal(7, tree.Right.Right.Value);
}

[Fact(Skip = "Remove to run test")]
public void Smaller_number_at_left_node()
{
Expand All @@ -49,6 +36,19 @@ public void Greater_number_at_right_node()
Assert.Equal(5, tree.Right.Value);
}

[Fact(Skip = "Remove to run test")]
public void Can_create_complex_tree()
{
var tree = new BinarySearchTree(new[] { 4, 2, 6, 1, 3, 5, 7 });
Assert.Equal(4, tree.Value);
Assert.Equal(2, tree.Left.Value);
Assert.Equal(1, tree.Left.Left.Value);
Assert.Equal(3, tree.Left.Right.Value);
Assert.Equal(6, tree.Right.Value);
Assert.Equal(5, tree.Right.Left.Value);
Assert.Equal(7, tree.Right.Right.Value);
}

[Fact(Skip = "Remove to run test")]
public void Can_sort_single_number()
{
Expand Down
Loading