示例#1
0
        private string CreateLearningObjectivesPart(ExerciseObjectTree exerciseObjectTree)
        {
            var conceptList = exerciseObjectTree.Exercises
                              .SelectMany(ex => ex.Concepts)
                              .Where(c => c.LearningObjectives.Count > 0)
                              .OrderBy(c => c.Name)
                              .Select(c => new
                                      { name               = "`" + c.Name + "`",
                                        learningObjectives = "<ul><li>" + string.Join("<li>", c.LearningObjectives) })
                              .ToList();

            if (conceptList.Count == 0)
            {
                return(string.Empty);
            }
            int           longestConceptName        = conceptList.Max(c => c.name.Length);
            int           longestLearningObjectives = conceptList.Max(c => c.learningObjectives.Length);
            StringBuilder sb     = new StringBuilder();
            var           format = "| {0,-" + longestConceptName + "} | {1,-" + longestLearningObjectives + "} |" + Environment.NewLine;

            sb.AppendLine();
            sb.AppendLine("## Learning Objectives");
            sb.AppendLine();
            sb.AppendFormat(format, "Concept", "Learning Objectives");
            sb.AppendFormat(format, new String('-', longestConceptName), new String('-', longestLearningObjectives));

            foreach (var text in conceptList)
            {
                sb.AppendFormat(format, text.name, text.learningObjectives);
            }
            return(sb.ToString());
        }
示例#2
0
        // distance from v3/languages/csharp/reference to v3/reference
        // for location of track neutral concepts README.md

        public string CreateReport(ExerciseObjectTree exerciseObjectTree)
        {
            var concepts           = CreateConceptPart(exerciseObjectTree);
            var conceptDefiniitons = CreateLearningObjectivesPart(exerciseObjectTree);
            var linkReferences     = CreateLinkReferences(exerciseObjectTree);

            return(concepts + conceptDefiniitons + linkReferences);
        }
示例#3
0
        private static List <Error> ValidateExercises(ExerciseObjectTree exerciseObjectTree)
        {
            var errors = exerciseObjectTree.Exercises.Select(ex => ValidateExercise(ex))
                         .Where(exo => !string.IsNullOrWhiteSpace(exo))
                         .Select(exo => new Error(ErrorSource.Exercise, Severity.Error, exo))
                         .ToList();

            return(errors);
        }
示例#4
0
        public string ToString(ExerciseObjectTree exerciseObjectTree)
        {
            var options = new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true,
                WriteIndented = true,
            };

            options.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase));
            return(JsonSerializer.Serialize(exerciseObjectTree, options));
        }
示例#5
0
        private void GetConcepts(StringBuilder sb, ExerciseObjectTree exerciseObjectTree, Level level)
        {
            var reportLines = exerciseObjectTree.Exercises
                              .SelectMany(ex => ex.Concepts, (ex,
                                                              c) => new { Exercise = ex, Concept = c })
                              .Where(p => p.Exercise.Level == level)
                              .OrderBy(p => p.Concept.Name)
                              .Select(p => FormatConceptReportLine(p.Exercise, p.Concept)).DefaultIfEmpty("None");

            foreach (string reportLine in reportLines)
            {
                sb.AppendLine(reportLine);
            }
        }
示例#6
0
        private string CreateLinkReferences(ExerciseObjectTree exerciseObjectTree)
        {
            StringBuilder sb        = new StringBuilder();
            var           issueRefs = exerciseObjectTree.Exercises
                                      .Where(ex => ex.CompletionStatus == CompletionStatus.NewExerciseIssueRaised)
                                      .OrderBy(ex => ex.Slug)
                                      .Select(ex => $"[issue-{ex.Slug}]: {ex.DocumentLink}");

            sb.AppendLine();
            foreach (string issueRef in issueRefs)
            {
                sb.AppendLine(issueRef);
            }

            var designRefs = exerciseObjectTree.Exercises
                             .Where(ex => ex.CompletionStatus == CompletionStatus.Complete)
                             .OrderBy(ex => ex.Slug)
                             .Select(ex => $"[design-{ex.Slug}]: {Path.Combine(GetExerciseLocationLink(ex.Slug), PathNames.Default.DesignDocName)}");

            sb.AppendLine();
            foreach (string designRef in designRefs)
            {
                sb.AppendLine(designRef);
            }

            var exerciseLocations = exerciseObjectTree.Exercises
                                    .Where(ex => ex.CompletionStatus == CompletionStatus.Complete)
                                    .OrderBy(ex => ex.Slug)
                                    .Select(ex => $"[exercise-{ex.Slug}]: {GetExerciseLocationLink(ex.Slug)}");

            sb.AppendLine();
            foreach (string exerciseLocation in exerciseLocations)
            {
                sb.AppendLine(exerciseLocation);
            }

            var trackNeutralConcepts = exerciseObjectTree.Exercises
                                       .SelectMany(ex => ex.Concepts)
                                       .Where(c => !string.IsNullOrWhiteSpace(c.TrackNeutralConcept))
                                       .OrderBy(c => c.Name)
                                       .Select(c => $"[tnc-{c.Name}]: {Path.Combine(Relativity, c.TrackNeutralConcept)}");

            sb.AppendLine();
            foreach (string trackNeutralConcept in trackNeutralConcepts)
            {
                sb.AppendLine(trackNeutralConcept);
            }
            return(sb.ToString());
        }
示例#7
0
        private void MergeLearningObjectives(ExerciseObjectTree exerciseObjectTree,
                                             LearningObjectives learningObjectives)
        {
            var concepts = exerciseObjectTree.Exercises.SelectMany(ex => ex.Concepts);

            foreach (var concept in concepts)
            {
                var objectives = learningObjectives.GetObjectivesForConcept(concept.Name);
                if (objectives != null)
                {
                    concept.LearningObjectives.Clear();
                    foreach (string objective in objectives)
                    {
                        concept.LearningObjectives.Add(objective);
                    }
                }
            }
        }
示例#8
0
        private List <Error> ReportUnmatchedConcepts(ExerciseObjectTree exerciseObjectTree,
                                                     LearningObjectives learningObjectives)
        {
            var exerciseMap = exerciseObjectTree.Exercises
                              .SelectMany(ex => ex.Concepts)
                              .Select(con => con.Name)
                              .ToHashSet();

            List <Error> errors = new List <Error>();

            foreach ((string DocId, string ConceptName)conceptDetails in learningObjectives.ConceptsInclDesignDocId)
            {
                if (!exerciseMap.Contains(conceptDetails.ConceptName))
                {
                    errors.Add(new Error(ErrorSource.Merge, Severity.Error,
                                         $"Failed to find concept {conceptDetails.ConceptName}, from the {conceptDetails.DocId} {Constants.DesignMd}, in {Constants.ExercisesJson} file"));
                }
            }

            return(errors);
        }
示例#9
0
        private List <Error> ReportMissingLearningObjectives(ExerciseObjectTree exerciseObjectTree)
        {
            var errors = exerciseObjectTree.Exercises.Where(ex => ex.CompletionStatus == CompletionStatus.Complete)
                         .SelectMany(ex => ex.Concepts, (Exercise, Concept) => (Exercise, Concept))
                         .Where(e_and_c => e_and_c.Concept.LearningObjectives.Count == 0)
                         .Select(e_and_c =>
                                 new Error(ErrorSource.MissingLearningObjective,
                                           Severity.Error,
                                           $"The {e_and_c.Concept.Name} concept has no learning objectives on the exercise report - update the {Constants.DesignMd} for the {e_and_c.Exercise.Slug} exercise")
                                 ).ToList();

            if (errors.Count > maxErrors)
            {
                errors.Add(
                    new Error(ErrorSource.MissingLearningObjective,
                              Severity.Fatal,
                              $"Too many concepts have no learning objectives - see {Constants.ExerciseErrorsJson}")
                    );
            }

            return(errors);
        }
示例#10
0
        private string CreateConceptPart(ExerciseObjectTree exerciseObjectTree)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append(GetResourceAsString(Constants.ExerciseReportIntroResource));
            sb.AppendLine();
            sb.AppendLine("### Introductory Concepts");
            sb.AppendLine();
            GetConcepts(sb, exerciseObjectTree, Level.Introductory);
            sb.AppendLine();
            sb.AppendLine("### Essential Concepts");
            sb.AppendLine();
            GetConcepts(sb, exerciseObjectTree, Level.Essential);
            sb.AppendLine();
            sb.AppendLine("### Advanced Concepts");
            sb.AppendLine();
            GetConcepts(sb, exerciseObjectTree, Level.Advanced);
            sb.AppendLine();
            sb.AppendLine("### Unallocated Concepts");
            sb.AppendLine();
            GetConcepts(sb, exerciseObjectTree, Level.None);
            return(sb.ToString());
        }