static public ProcessWithLog <string, Result <string, (TreeWithStringPath tree, LoadCompositionOrigin origin)> > LoadFromPathResolvingNetworkDependencies(string sourcePath)
    {
        var asProcess = AsProcessWithStringLog(sourcePath);

        if (LoadFromGitHubOrGitLab.ParseUrl(sourcePath) != null)
        {
            return
                (asProcess
                 .WithLogEntryAdded("This path looks like a URL into a remote git repository. Trying to load from there...")
                 .MapResult(LoadFromGitHubOrGitLab.LoadFromUrl)
                 .ResultAddLogEntriesIfOk(LogEntriesForLoadFromGitSuccess)
                 .ResultMap(loadFromGitOk => (loadFromGitOk.tree, new LoadCompositionOrigin(FromGit: loadFromGitOk))));
        }

        if (LoadFromElmEditor.ParseUrl(sourcePath) != null)
        {
            return
                (asProcess
                 .WithLogEntryAdded("This path looks like a URL into a code editor. Trying to load from there...")
                 .MapResult(LoadFromElmEditor.LoadFromUrl)
                 .ResultMap(loadFromEditorOk => (loadFromEditorOk.tree, new LoadCompositionOrigin(FromEditor: loadFromEditorOk.parsedUrl))));
        }

        return
            (asProcess
             .WithLogEntryAdded("Trying to load from local file system...")
             .MapResult(sourcePath =>
        {
            try
            {
                var treeComponentFromSource = LoadFromLocalFilesystem.LoadSortedTreeFromPath(sourcePath);

                if (treeComponentFromSource == null)
                {
                    return new Result <string, TreeWithStringPath>
                    {
                        Err = "I did not find a file or directory at '" + sourcePath + "'.",
                    }
                }
                ;

                return
                new Result <string, TreeWithStringPath>(Ok: treeComponentFromSource);
            }
            catch (Exception e)
            {
                return Result <string, TreeWithStringPath> .err("Failed to load from local file system: " + e?.ToString());
            }
        })
             .ResultMap(tree => (tree, new LoadCompositionOrigin(FromLocalFileSystem: new object()))));
    }
Пример #2
0
        public void TestElmInteractiveScenarios()
        {
            var scenariosResults = new Dictionary <string, InteractiveScenarioTestResult>();

            foreach (var scenarioDirectory in Directory.EnumerateDirectories(pathToScenariosDirectory))
            {
                var scenarioName = Path.GetFileName(scenarioDirectory);

                if (Directory.EnumerateFiles(scenarioDirectory, "*", searchOption: SearchOption.AllDirectories).Take(1).Count() < 1)
                {
                    // Do not stumble over empty directory here. It could be a leftover after git checkout.
                    continue;
                }

                bool      scenarioPassed    = false;
                Exception scenarioException = null;

                try
                {
                    var appCodeTree =
                        LoadFromLocalFilesystem.LoadSortedTreeFromPath(Path.Combine(scenarioDirectory, "context-app"));

                    var stepsDirectories =
                        Directory.EnumerateDirectories(
                            Path.Combine(scenarioDirectory, "steps"),
                            searchPattern: "*",
                            searchOption: SearchOption.TopDirectoryOnly)
                        .OrderBy(directory => directory)
                        .ToImmutableList();

                    if (stepsDirectories.Count < 1)
                    {
                        throw new Exception("stepsDirectories.Count < 1");
                    }

                    using (var interactiveSession = new elm_fullstack.InteractiveSession(appCodeTree: appCodeTree))
                    {
                        foreach (var stepDirectory in stepsDirectories)
                        {
                            var stepName = Path.GetFileName(stepDirectory);

                            string submission = null;

                            try
                            {
                                submission =
                                    File.ReadAllText(Path.Combine(stepDirectory, "submission"), System.Text.Encoding.UTF8);

                                var evalResult =
                                    interactiveSession.SubmitAndGetResultingValue(submission);

                                var expectedValueFilePath = Path.Combine(stepDirectory, "expected-value");

                                if (File.Exists(expectedValueFilePath))
                                {
                                    var expectedValue = File.ReadAllText(expectedValueFilePath, System.Text.Encoding.UTF8);

                                    Assert.IsNull(evalResult.Err, "Submission result has error: " + evalResult.Err);

                                    Assert.AreEqual(
                                        expectedValue,
                                        evalResult.Ok?.valueAsElmExpressionText,
                                        "Value from evaluation does not match expected value.");
                                }
                            }
                            catch (Exception e)
                            {
                                throw new Exception("Failed step '" + stepName + "' with exception.\nSubmission in this step:\n" + submission, e);
                            }
                        }
                    }

                    scenarioPassed = true;
                }
                catch (Exception e)
                {
                    scenarioException = e;
                }

                scenariosResults[scenarioName] =
                    new InteractiveScenarioTestResult
                {
                    passed    = scenarioPassed,
                    exception = scenarioException,
                };
            }

            Console.WriteLine("Total scenarios: " + scenariosResults.Count);
            Console.WriteLine("Passed: " + scenariosResults.Values.Count(scenarioResult => scenarioResult.passed));

            var failedScenarios =
                scenariosResults
                .Where(scenarioNameAndResult => !scenarioNameAndResult.Value.passed)
                .ToImmutableList();

            foreach (var scenarioNameAndResult in failedScenarios)
            {
                var causeText =
                    scenarioNameAndResult.Value.exception != null ?
                    "exception:\n" + scenarioNameAndResult.Value.exception.ToString()
                    :
                    "unknown cause";

                Console.WriteLine("Scenario '" + scenarioNameAndResult.Key + "' failed with " + causeText);
            }

            if (0 < failedScenarios.Count)
            {
                throw new Exception(
                          "Failed for " + failedScenarios.Count + " scenarios:\n" +
                          string.Join("\n", failedScenarios.Select(scenarioNameAndResult => scenarioNameAndResult.Key)));
            }
        }