-
Notifications
You must be signed in to change notification settings - Fork 563
Consolidate interactive tests #482
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
Conversation
| } | ||
|
|
||
| public async Task SubmitLines(KernelBase kernel, string[] lines) | ||
| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The naming is a bit misleading since multi-line submissions are very common.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like string[] codeSubmissions or codeFragments?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think submissions is fine.
|
Generally, agreed, though a switch expression would make this example a little more concise: [Theory]
[InlineData(Language.FSharp)]
[InlineData(Language.CSharp)]
public async Task it_remembers_state_between_submissions(Language language)
{
var source = language switch
{
Language.FSharp => new[]
{
"let add x y = x + y",
"add 2 3"
},
Language.CSharp => new[]
{
"int Multiply(int x, int y) { return x + y; };",
"Multiply(2, 3);"
}
};
var kernel = CreateKernel(language);
await SubmitLines(kernel, source);
KernelEvents.ValuesOnly()
.OfType<ReturnValueProduced>()
.Last()
.Value
.Should()
.Be(5);
} |
|
It would be helpful for reviewers to spot possible errors if you do the renames in a prior commit to the actual changes. |
| return kernel; | ||
| } | ||
|
|
||
| protected KernelBase CreateKernel() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd feel better if this function was removed. Tests that call this are really C#-specific tests so I'd like them to explicitly call CreateKernel(CSharp) or group them in a new class with IKernel CreateKernel() => base.CreateKernel(CSharp); just so it's explicit..
| return CreateKernel(Language.CSharp); | ||
| } | ||
|
|
||
| public async Task SubmitLines(KernelBase kernel, string[] lines) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
params string[] lines might be easier to consume, but ultimately I don't care too much.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It propose using submission or even array of string array
|
General request: To make the test cases easier to parse, could the switch statements/expressions be replaced with this? // I'm not married to the name of this function, but I think the use of `T` will make it easy to in the future return more than just strings.
public T GetElementForLanguage<T>(Language language, params (Language lang, T value)[] values)
{
// The use of `Single()` ensures that the test will fail if a value was not given for a specific language.
return values.Single(val => val.lang == language).value;
}That way the call sites will be a little more concise: var code = GetElementForLanguage(language, (Language.CSharp, "using System;"),
(Language.FSharp, "open System")); |
@jonsequitur, I tried it, unfortunately an array initializer is not an expression that can be returned from a switch expression. |
Oh the trick is to use new[]. Nice. |
|
I have added 4 different ways of doing a test based on the feedback, and other ideas. let me know what you like best. |
| [Theory] | ||
| [InlineData(Language.FSharp)] | ||
| [InlineData(Language.CSharp)] | ||
| public async Task it_remembers_state_between_submissions_option3(Language language) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to cast my vote for this style of test case because:
- The code to select different values is short and easy to read. I find the
switchexpression difficult because it's so verbose and requires adefaultcase that must explicitly throw, while the helper method here handles that for you. - Placing code in
[InlineData]works for compile-time constants, but won't be usable for expressions. We don't have a test that does this currently, but I can easily see a test that needs to callGetElementForLanguage()where the item returned is aTypeorExceptionor something that can't be placed in an attribute. - Finally, I like that the code variants are declared exactly where and when they're used instead of at the top of the function where I have to trace a variable through.
| string[] source = null; | ||
| switch (language) | ||
| { | ||
| case Language.FSharp: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be easier to provide a list of submissions instead of assuming one stein one submission.
| return CreateKernel(Language.CSharp); | ||
| } | ||
|
|
||
| public async Task SubmitLines(KernelBase kernel, string[] lines) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It propose using submission or even array of string array
| } | ||
|
|
||
| public async Task SubmitLines(KernelBase kernel, string[] lines) | ||
| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like string[] codeSubmissions or codeFragments?
|
SubmitSource is an overloaded method, so you can pass in a line or an array of lines. If we determine that we need an array of arrays then we can always add that overload when the need presents itself. Kevin |
|
|
||
| KernelEvents | ||
| .ValuesOnly() | ||
| .Single(e => e is IncompleteCodeSubmissionReceived); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.Should().ContainSingle()
| var source = language switch | ||
| { | ||
| Language.FSharp => "Console.WriteLine(\"Hello\")", | ||
| Language.CSharp => "Console.WriteLine(\"Hello\")" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case the test will pass for the wrong reason because this is not a complete C# statement unless you add a semicolon to the end.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jonsequitur
Console.WriteLine("Hello, World") is a complete C# expression, if it was incomplete this would fail:
KernelEvents
.Should()
.Contain(e => e.Value is CompleteCodeSubmissionReceived);
| json | ||
| "}, | ||
| Language.CSharp => new[] { | ||
| $"#r @\"{dllPath}\"", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$"#r @"{dllPath}"" [](start = 0, length = 20)
I believe this works if you remove the @. The issue is not the quoted path but rather than the command line parser expects this to be a response file. That can be disabled in KernelBase.GetDirectiveParser:
= new CommandLineBuilder(root)
.ParseResponseFileAs(ResponseFileHandling.Disabled)
.UseMiddleware(There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh … nice.
First attempt at rationalizing F# and C# interactive test cases.
Simplify and refactor: CSharpKernelTests/FSharpKernelTests/CSharpKernelTestBase/FSharpKernelTestBase/KernelTestBase into
LanguageKernelTests/LanguageKernelTestBase
Here is an example test case with C# and F# source variants:
https://github.com/dotnet/try/compare/master...KevinRansom:kr?expand=1#diff-d8de318123580f112042b15d5a087f4dR55
I really wish this was in F# the amount of ceremony in C# is unbelievable
In fact I may port this whole thing to F# just to show you.