コード例 #1
0
        public async Task it_formats_func_instances(Language language)
        {
            var kernel = CreateKernel(language);

            var source = language switch
            {
                Language.CSharp => new[] {
                    "Func<int> func = () => 1;",
                    "func()",
                    "func"
                },

                Language.FSharp => new[] {
                    "let func () = 1",
                    "func()",
                    "func"
                },
            };

            await SubmitCode(kernel, source);

            KernelEvents.ValuesOnly()
            .Count(e => e is CommandHandled)
            .Should()
            .Be(3);

            KernelEvents.ValuesOnly()
            .OfType <ReturnValueProduced>()
            .Should()
            .Contain(e => ((SubmitCode)e.Command).Code == source[1])
            .And
            .Contain(e => ((SubmitCode)e.Command).Code == source[2]);
        }
コード例 #2
0
        public async Task it_can_load_assembly_references_using_r_directive()
        {
            var kernel = CreateKernel();

            var dll = new FileInfo(typeof(JsonConvert).Assembly.Location).FullName;

            await kernel.SendAsync(
                new SubmitCode($"#r \"{dll}\""));

            await kernel.SendAsync(
                new SubmitCode(@"
using Newtonsoft.Json;

var json = JsonConvert.SerializeObject(new { value = ""hello"" });

json
"));

            KernelEvents.ValuesOnly()
            .Should()
            .ContainSingle(e => e is ReturnValueProduced);

            KernelEvents.ValuesOnly()
            .OfType <ReturnValueProduced>()
            .Single()
            .Value
            .Should()
            .Be(new { value = "hello" }.ToJson());
        }
コード例 #3
0
        public async Task it_can_load_assembly_references_using_r_directive_at_quotedpaths(Language language)
        {
            var kernel = CreateKernel(language);

            // F# strings treat \ as an escape character.  So do C# strings, except #r in C# is special, and doesn't.  F# usually uses @ strings for paths @"c:\temp\...."
            var dllPath = new FileInfo(typeof(JsonConvert).Assembly.Location).FullName;

            var source = language switch
            {
                Language.FSharp => new[] {
                    $"#r @\"{dllPath}\"",
                    @"
open Newtonsoft.Json
let json = JsonConvert.SerializeObject( struct {| value = ""hello"" |} )
json
"
                }
            };

            await SubmitCode(kernel, source);

            KernelEvents.ValuesOnly()
            .Should()
            .ContainSingle(e => e is ReturnValueProduced);

            KernelEvents.ValuesOnly()
            .OfType <ReturnValueProduced>()
            .Single()
            .Value
            .Should()
            .Be(new { value = "hello" }.ToJson());
        }
コード例 #4
0
        public async Task it_produces_a_final_value_if_the_code_expression_evaluates(Language language)
        {
            var kernel = CreateKernel(language);

            var source = language switch
            {
                Language.FSharp => @"
open System
Console.Write(""value one"")
Console.Write(""value two"")
Console.Write(""value three"")
5",

                Language.CSharp => @"
Console.Write(""value one"");
Console.Write(""value two"");
Console.Write(""value three"");
5",
            };

            await SubmitCode(kernel, source);

            KernelEvents.ValuesOnly()
            .OfType <StandardOutputValueProduced>()
            .Should()
            .HaveCount(3);

            KernelEvents
            .ValuesOnly()
            .OfType <ReturnValueProduced>()
            .Last()
            .Value.Should().Be(5);
        }
コード例 #5
0
        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 Add(int x, int y) { return x + y; }",
                    "Add(2, 3)"
                }
            };

            var kernel = CreateKernel(language);

            await SubmitCode(kernel, source);

            KernelEvents.ValuesOnly()
            .OfType <ReturnValueProduced>()
            .Last()
            .Value
            .Should()
            .Be(5);
        }
コード例 #6
0
        //[InlineData(Language.FSharp)]
        // Todo: teach fsi about returning exceptions
        // > open System;;
        // > raise(new NotImplementedException());;
        //    raise(new NotImplementedException());;
        //    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

        //  stdin(7,1) : error FS0030: Value restriction.The value 'it' has been inferred to have generic type
        //       val it : '_a
        //  Either define 'it' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation.
        // >
        public async Task it_returns_exceptions_thrown_in_user_code(Language language)
        {
            var kernel = CreateKernel(language);

            var source = language switch
            {
                Language.FSharp => new[]
                {
                    "open System",
                    "raise (new NotImplementedException())"
                },

                Language.CSharp => new[]
                {
                    "using System;",
                    "throw new NotImplementedException();"
                }
            };

            await SubmitCode(kernel, source);

            KernelEvents.ValuesOnly()
            .Where(x => x.GetType() != typeof(KernelIdle) && x.GetType() != typeof(KernelBusy))
            .Last()
            .Should()
            .BeOfType <CommandFailed>()
            .Which
            .Exception
            .Should()
            .BeOfType <NotImplementedException>();
        }
コード例 #7
0
        //[InlineData(Language.FSharp)]                     // Todo: FSI interrupt command_failed : cancelled command
        public async Task it_can_cancel_execution(Language language)
        {
            var kernel = CreateKernel(language);

            var source = language switch
            {
                Language.FSharp => "System.Threading.Thread.Sleep(3000)",
                Language.CSharp => "System.Threading.Thread.Sleep(3000);"
            };

            var submitCodeCommand   = new SubmitCode(source);
            var codeSubmission      = kernel.SendAsync(submitCodeCommand);
            var interruptionCommand = new CancelCurrentCommand();
            await kernel.SendAsync(interruptionCommand);

            await codeSubmission;

            KernelEvents
            .ValuesOnly()
            .Single(e => e is CurrentCommandCancelled);

            KernelEvents
            .ValuesOnly()
            .OfType <CommandFailed>()
            .Should()
            .BeEquivalentTo(new CommandFailed(null, interruptionCommand, "Command cancelled"));
        }
コード例 #8
0
        public async Task it_produces_values_when_executing_Console_output(Language language)
        {
            var kernel = CreateKernel(language);

            var source = language switch
            {
                Language.FSharp => @"
open System
Console.Write(""value one"")
Console.Write(""value two"")
Console.Write(""value three"")",

                Language.CSharp => @"
Console.Write(""value one"");
Console.Write(""value two"");
Console.Write(""value three"");",
            };

            var kernelCommand = await SubmitCode(kernel, source);

            KernelEvents
            .ValuesOnly()
            .OfType <StandardOutputValueProduced>()
            .Should()
            .BeEquivalentTo(
                new StandardOutputValueProduced("value one", kernelCommand, new[] { new FormattedValue("text/plain", "value one"), }),
                new StandardOutputValueProduced("value two", kernelCommand, new[] { new FormattedValue("text/plain", "value two"), }),
                new StandardOutputValueProduced("value three", kernelCommand, new[] { new FormattedValue("text/plain", "value three"), }));
        }
コード例 #9
0
        public async Task it_aggregates_multiple_submissions(Language language)
        {
            var kernel = CreateKernel(language);

            var source = language switch
            {
                Language.FSharp => new[]
                {
                    // Todo: decide what to do with F# not auto-opening System.Collections.Generic, System.Linq
                    "open System.Collections.Generic",
                    "open System.Linq",
                    "let x = List<int>([|1;2|])",
                    "x.Add(3)",
                    "x.Max()"
                },

                Language.CSharp => new[]
                {
                    "var x = new List<int>{1,2};",
                    "x.Add(3);",
                    "x.Max()"
                }
            };

            await SubmitCode(kernel, source);

            KernelEvents.ValuesOnly()
            .OfType <ReturnValueProduced>()
            .Last()
            .Value
            .Should()
            .Be(3);
        }
コード例 #10
0
        public async Task Javascript_helper_emits_string_as_content_within_a_script_element(Language language)
        {
            var kernel = CreateKernel(language);

            var scriptContent = "alert('Hello World!');";

            var submission = language switch
            {
                Language.CSharp => $@"Javascript(""{scriptContent}"");",
                Language.FSharp => $@"Javascript(""{scriptContent}"")",
            };

            await kernel.SendAsync(new SubmitCode(submission));

            var formatted =
                KernelEvents
                .ValuesOnly()
                .OfType <DisplayedValueProduced>()
                .SelectMany(v => v.FormattedValues)
                .ToArray();

            formatted
            .Should()
            .ContainSingle(v =>
                           v.MimeType == "text/html" &&
                           v.Value.ToString().Contains($@"<script type=""text/javascript"">{scriptContent}</script>"));
        }
コード例 #11
0
        public async Task it_can_load_assembly_references_using_r_directive_at_triplequotedpaths(Language language)
        {
            var kernel = CreateKernel(language);

            var dllPath = new FileInfo(typeof(JsonConvert).Assembly.Location).FullName;

            var source = language switch
            {
                Language.FSharp => new[] {
                    $"#r \"\"\"{dllPath}\"\"\"",
                    @"
open Newtonsoft.Json
let json = JsonConvert.SerializeObject( struct {| value = ""hello"" |} )
json
"
                },
            };

            await SubmitCode(kernel, source);

            KernelEvents.ValuesOnly()
            .Should()
            .ContainSingle(e => e is ReturnValueProduced);

            KernelEvents.ValuesOnly()
            .OfType <ReturnValueProduced>()
            .Single()
            .Value
            .Should()
            .Be(new { value = "hello" }.ToJson());
        }
コード例 #12
0
        //[InlineData(Language.FSharp)]             //Todo: completion for F#
        public async Task it_returns_completion_list_for_previously_declared_variables(Language language)
        {
            var kernel = CreateKernel(language);

            var source = language switch
            {
                Language.FSharp => @"let alpha = new Random()",
                Language.CSharp => @"var alpha = new Random();"
            };

            await SubmitCode(kernel, source);

            await kernel.SendAsync(new RequestCompletion("al", 2));

            KernelEvents.ValuesOnly()
            .Should()
            .ContainSingle(e => e is CompletionRequestReceived);

            KernelEvents.ValuesOnly()
            .OfType <CompletionRequestCompleted>()
            .Single()
            .CompletionList
            .Should()
            .Contain(i => i.DisplayText == "alpha");
        }
コード例 #13
0
 private void AssertLastValue(object value)
 {
     KernelEvents.ValuesOnly()
     .OfType <ReturnValueProduced>()
     .Last()
     .Value
     .Should()
     .Be(value);
 }
コード例 #14
0
        public async Task it_can_analyze_code_submissions()
        {
            var kernel = CreateKernel();

            await kernel.SendAsync(new SubmitCode("var a = 12", submissionType : SubmissionType.Diagnose));

            var analysisResult = KernelEvents.ValuesOnly()
                                 .Single(e => e is IncompleteCodeSubmissionReceived);
        }
コード例 #15
0
        public async Task it_returns_the_result_of_a_non_null_expression()
        {
            var kernel = CreateKernel();

            await kernel.SendAsync(new SubmitCode("123"));

            KernelEvents.ValuesOnly()
            .OfType <ReturnValueProduced>()
            .Last()
            .Value
            .Should()
            .Be(123);
        }
コード例 #16
0
        public async Task expression_evaluated_to_null_has_result_with_null_value()
        {
            var kernel = CreateKernel();

            await kernel.SendAsync(new SubmitCode("null"));

            KernelEvents.ValuesOnly()
            .OfType <ReturnValueProduced>()
            .Last()
            .Value
            .Should()
            .BeNull();
        }
コード例 #17
0
        public async Task it_returns_a_result_for_a_if_expressions(Language language, string expression)
        {
            var kernel = CreateKernel(language);

            await SubmitCode(kernel, expression);

            KernelEvents.ValuesOnly()
            .OfType <ReturnValueProduced>()
            .Last()
            .Value
            .Should()
            .Be(25);
        }
コード例 #18
0
        public async Task it_returns_the_result_of_a_non_null_expression(Language language)
        {
            var kernel = CreateKernel(language);

            await SubmitCode(kernel, "123");

            KernelEvents.ValuesOnly()
            .OfType <ReturnValueProduced>()
            .Last()
            .Value
            .Should()
            .Be(123);
        }
コード例 #19
0
        public async Task it_supports_csharp_8()
        {
            var kernel = CreateKernel();

            await kernel.SendAsync(new SubmitCode("var text = \"meow? meow!\";"));

            await kernel.SendAsync(new SubmitCode("text[^5..^0]"));

            KernelEvents.ValuesOnly()
            .OfType <DisplayedValueProduced>()
            .Last()
            .Value
            .Should()
            .Be("meow!");
        }
コード例 #20
0
        public async Task kernel_captures_stderr(Language language)
        {
            var kernel = CreateKernel(language);

            var source = "eprintf \"hello from F#\"";

            await SubmitCode(kernel, source);

            KernelEvents.ValuesOnly()
            .OfType <StandardErrorValueProduced>()
            .Last()
            .Value
            .Should()
            .Be("hello from F#");
        }
コード例 #21
0
        public async Task it_returns_exceptions_thrown_in_user_code()
        {
            var kernel = CreateKernel();

            await kernel.SendAsync(new SubmitCode("using System;"));

            await kernel.SendAsync(new SubmitCode("throw new NotImplementedException();"));

            KernelEvents.ValuesOnly()
            .Last()
            .Should()
            .BeOfType <CommandFailed>()
            .Which
            .Exception
            .Should()
            .BeOfType <NotImplementedException>();
        }
コード例 #22
0
        public async Task it_aggregates_multiple_submissions()
        {
            var kernel = CreateKernel();

            await kernel.SendAsync(new SubmitCode("var x = new List<int>{1,2};"));

            await kernel.SendAsync(new SubmitCode("x.Add(3);"));

            await kernel.SendAsync(new SubmitCode("x.Max()"));

            KernelEvents.ValuesOnly()
            .OfType <ReturnValueProduced>()
            .Last()
            .Value
            .Should()
            .Be(3);
        }
コード例 #23
0
        public async Task it_returns_diagnostics()
        {
            var kernel = CreateKernel();

            await kernel.SendAsync(new SubmitCode("using System;"));

            await kernel.SendAsync(new SubmitCode("aaaadd"));

            KernelEvents.ValuesOnly()
            .Last()
            .Should()
            .BeOfType <CommandFailed>()
            .Which
            .Message
            .Should()
            .Be("(1,1): error CS0103: The name 'aaaadd' does not exist in the current context");
        }
コード例 #24
0
        public async Task it_notifies_when_submission_is_incomplete()
        {
            var kernel = CreateKernel();

            await kernel.SendAsync(new SubmitCode("var a ="));

            KernelEvents
            .Should()
            .NotContain(e => e.Value is ValueProduced);

            KernelEvents
            .ValuesOnly()
            .Should()
            .Contain(e => e is CodeSubmissionEvaluated)
            .And
            .Contain(e => e is IncompleteCodeSubmissionReceived);
        }
コード例 #25
0
        public async Task it_returns_completion_list_for_types()
        {
            var kernel = CreateKernel();

            await kernel.SendAsync(new RequestCompletion("System.Console.", 15));

            KernelEvents.ValuesOnly()
            .Should()
            .ContainSingle(e => e is CompletionRequestReceived);

            KernelEvents.ValuesOnly()
            .OfType <CompletionRequestCompleted>()
            .Single()
            .CompletionList
            .Should()
            .Contain(i => i.DisplayText == "ReadLine");
        }
コード例 #26
0
        public async Task it_produces_a_final_value_if_the_code_expression_evaluates()
        {
            var kernel = CreateKernel();

            var kernelCommand = new SubmitCode(@"
Console.Write(""value one"");
Console.Write(""value two"");
Console.Write(""value three"");
5", "csharp");
            await kernel.SendAsync(kernelCommand);

            KernelEvents.ValuesOnly()
            .OfType <ValueProduced>()
            .Should()
            .HaveCount(4)
            .And
            .ContainSingle(e => e.IsLastValue);
        }
コード例 #27
0
        public async Task Display_helper_can_be_called_without_specifying_class_name()
        {
            var kernel = CreateKernel();

            await kernel.SendAsync(new SubmitCode("display(b(\"hi!\"));"));

            var formatted =
                KernelEvents
                .ValuesOnly()
                .OfType <ValueProduced>()
                .SelectMany(v => v.FormattedValues);

            formatted
            .Should()
            .ContainSingle(v =>
                           v.MimeType == "text/html" &&
                           v.Value.ToString().Contains("<b>hi!</b>"));
        }
コード例 #28
0
        public async Task kernel_base_ignores_command_line_directives(Language language)
        {
            // The text `[1;2;3;4]` parses as a System.CommandLine directive; ensure it's not consumed and is passed on to the kernel.
            var kernel = CreateKernel(language);

            var source = @"
[1;2;3;4]
|> List.sum";

            await SubmitCode(kernel, source);

            KernelEvents.ValuesOnly()
            .OfType <ReturnValueProduced>()
            .Last()
            .Value
            .Should()
            .Be(10);
        }
コード例 #29
0
        // no F# equivalent, because it doesn't have the concept of complete/incomplete submissions
        public async Task it_can_analyze_incomplete_submissions(Language language)
        {
            var kernel = CreateKernel(language);

            var source = language switch
            {
                Language.CSharp => "var a ="
            };

            await SubmitCode(kernel, source, submissionType : SubmissionType.Diagnose);

            KernelEvents
            .ValuesOnly()
            .Single(e => e is IncompleteCodeSubmissionReceived);

            KernelEvents
            .Should()
            .Contain(e => e.Value is IncompleteCodeSubmissionReceived);
        }
コード例 #30
0
        public async Task it_produces_values_when_executing_Console_output()
        {
            var kernel = CreateKernel();

            var kernelCommand = new SubmitCode(@"
Console.Write(""value one"");
Console.Write(""value two"");
Console.Write(""value three"");");
            await kernel.SendAsync(kernelCommand);

            KernelEvents
            .ValuesOnly()
            .OfType <DisplayedValueProduced>()
            .Should()
            .BeEquivalentTo(
                new DisplayedValueProduced("value one", kernelCommand, new[] { new FormattedValue("text/plain", "value one"), }),
                new DisplayedValueProduced("value two", kernelCommand, new[] { new FormattedValue("text/plain", "value two"), }),
                new DisplayedValueProduced("value three", kernelCommand, new[] { new FormattedValue("text/plain", "value three"), }));
        }