public void TestPerformCoreTemplateQuery_UniqueNameMatchesCorrectly() { List <ITemplateInfo> templatesToSearch = new List <ITemplateInfo>(); templatesToSearch.Add(new TemplateInfo() { ShortName = "Template1", Name = "Long name of Template1", Identity = "Template1", CacheParameters = new Dictionary <string, ICacheParameter>(), Tags = new Dictionary <string, ICacheTag>() }); templatesToSearch.Add(new TemplateInfo() { ShortName = "Template2", Name = "Long name of Template2", Identity = "Template2", CacheParameters = new Dictionary <string, ICacheParameter>(), Tags = new Dictionary <string, ICacheTag>() }); INewCommandInput userInputs = new MockNewCommandInput() { TemplateName = "Template2" }; TemplateListResolutionResult matchResult = TemplateListResolver.GetTemplateResolutionResult(templatesToSearch, new MockHostSpecificDataLoader(), userInputs, null); Assert.Equal(1, matchResult.GetBestTemplateMatchList().Count); Assert.Equal("Template2", matchResult.GetBestTemplateMatchList()[0].Info.Identity); Assert.True(matchResult.TryGetUnambiguousTemplateGroupToUse(out IReadOnlyList <ITemplateMatchInfo> unambiguousGroup)); Assert.Equal(1, unambiguousGroup.Count); Assert.Equal("Template2", unambiguousGroup[0].Info.Identity); }
private static CreationResultStatus DisplayHelpForAmbiguousTemplateGroup(TemplateListResolutionResult templateResolutionResult, IEngineEnvironmentSettings environmentSettings, INewCommandInput commandInput, IHostSpecificDataLoader hostDataLoader, ITelemetryLogger telemetryLogger, string defaultLanguage) { if (!string.IsNullOrEmpty(commandInput.TemplateName) && templateResolutionResult.GetBestTemplateMatchList(true).Count > 0 && templateResolutionResult.GetBestTemplateMatchList(true).All(x => x.MatchDisposition.Any(d => d.Location == MatchLocation.Language && d.Kind == MatchKind.Mismatch))) { string errorMessage = GetLanguageMismatchErrorMessage(commandInput); Reporter.Error.WriteLine(errorMessage.Bold().Red()); Reporter.Error.WriteLine(string.Format(LocalizableStrings.RunHelpForInformationAboutAcceptedParameters, $"{commandInput.CommandName} {commandInput.TemplateName}").Bold().Red()); return(CreationResultStatus.NotFound); } // The following occurs when: // --alias <value> is specifed // --help is specified // template (group) can't be resolved if (!string.IsNullOrWhiteSpace(commandInput.Alias)) { Reporter.Error.WriteLine(LocalizableStrings.InvalidInputSwitch.Bold().Red()); Reporter.Error.WriteLine(" " + commandInput.TemplateParamInputFormat("--alias").Bold().Red()); return(CreationResultStatus.NotFound); } bool hasInvalidParameters = false; IReadOnlyList <ITemplateMatchInfo> templatesForDisplay = templateResolutionResult.GetBestTemplateMatchList(true); GetParametersInvalidForTemplatesInList(templatesForDisplay, out IReadOnlyList <string> invalidForAllTemplates, out IReadOnlyList <string> invalidForSomeTemplates); if (invalidForAllTemplates.Any() || invalidForSomeTemplates.Any()) { hasInvalidParameters = true; DisplayInvalidParameters(invalidForAllTemplates); DisplayParametersInvalidForSomeTemplates(invalidForSomeTemplates, LocalizableStrings.PartialTemplateMatchSwitchesNotValidForAllMatches); } ShowContextAndTemplateNameMismatchHelp(templateResolutionResult, commandInput.TemplateName, commandInput.TypeFilter, out bool shouldShowTemplateList); if (shouldShowTemplateList) { DisplayTemplateList(templatesForDisplay, environmentSettings, commandInput.Language, defaultLanguage); } if (!commandInput.IsListFlagSpecified) { TemplateUsageHelp.ShowInvocationExamples(templateResolutionResult, hostDataLoader, commandInput.CommandName); } if (hasInvalidParameters) { return(CreationResultStatus.NotFound); } else if (commandInput.IsListFlagSpecified || commandInput.IsHelpFlagSpecified) { return(!templateResolutionResult.IsNoTemplatesMatchedState ? CreationResultStatus.Success : CreationResultStatus.NotFound); } else { return(CreationResultStatus.OperationNotSpecified); } }
public void MultipleTemplatesInGroupParamPartiaMatch_TheOneHavingSingleStartsWithIsTheSingularInvokableMatch() { List <ITemplateInfo> templatesToSearch = new List <ITemplateInfo>(); templatesToSearch.Add(new TemplateInfo() { ShortName = "foo", Name = "Foo template", Identity = "foo.test_1", GroupIdentity = "foo.test.template", Precedence = 100, Tags = new Dictionary <string, ICacheTag>(StringComparer.OrdinalIgnoreCase) { { "MyChoice", ResolutionTestHelper.CreateTestCacheTag(new List <string>() { "value_1" }) } }, CacheParameters = new Dictionary <string, ICacheParameter>(), }); templatesToSearch.Add(new TemplateInfo() { ShortName = "foo", Name = "Foo template", Identity = "foo.test_2", GroupIdentity = "foo.test.template", Precedence = 200, Tags = new Dictionary <string, ICacheTag>(StringComparer.OrdinalIgnoreCase) { { "MyChoice", ResolutionTestHelper.CreateTestCacheTag(new List <string>() { "value_2", "value_3" }) } }, CacheParameters = new Dictionary <string, ICacheParameter>(), }); INewCommandInput userInputs = new MockNewCommandInput( new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase) { { "MyChoice", "value_" } } ) { TemplateName = "foo" }; IHostSpecificDataLoader hostSpecificDataLoader = new MockHostSpecificDataLoader(); TemplateListResolutionResult matchResult = TemplateListResolver.GetTemplateResolutionResult(templatesToSearch, hostSpecificDataLoader, userInputs, null); // make sure there's an unambiguous group, otherwise the singular match check is meaningless Assert.True(matchResult.TryGetUnambiguousTemplateGroupToUse(out IReadOnlyList <ITemplateMatchInfo> unambiguousGroup)); Assert.Equal(2, unambiguousGroup.Count); Assert.Equal(2, matchResult.GetBestTemplateMatchList().Count); Assert.True(matchResult.TryGetSingularInvokableMatch(out ITemplateMatchInfo singularInvokableMatch, out SingularInvokableMatchCheckStatus resultStatus)); Assert.Equal(SingularInvokableMatchCheckStatus.SingleMatch, resultStatus); Assert.Equal("foo.test_1", singularInvokableMatch.Info.Identity); }
public void GivenTwoInvokableTemplatesNonDefaultLanguage_HighPrecedenceIsChosen() { List <ITemplateInfo> templatesToSearch = new List <ITemplateInfo>(); templatesToSearch.Add(new TemplateInfo() { ShortName = "foo", Name = "Foo template", Identity = "foo.test_1.FSharp", GroupIdentity = "foo.test.template", Precedence = 100, Tags = new Dictionary <string, ICacheTag>(StringComparer.OrdinalIgnoreCase) { { "language", ResolutionTestHelper.CreateTestCacheTag(new List <string>() { "F#" }) }, }, CacheParameters = new Dictionary <string, ICacheParameter>(), }); templatesToSearch.Add(new TemplateInfo() { ShortName = "foo", Name = "Foo template", Identity = "foo.test_1.VB", GroupIdentity = "foo.test.template", Precedence = 200, Tags = new Dictionary <string, ICacheTag>(StringComparer.OrdinalIgnoreCase) { { "language", ResolutionTestHelper.CreateTestCacheTag(new List <string>() { "VB" }) }, }, CacheParameters = new Dictionary <string, ICacheParameter>(), }); INewCommandInput userInputs = new MockNewCommandInput( new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase) { } ) { TemplateName = "foo" }; IHostSpecificDataLoader hostSpecificDataLoader = new MockHostSpecificDataLoader(); TemplateListResolutionResult matchResult = TemplateListResolver.GetTemplateResolutionResult(templatesToSearch, hostSpecificDataLoader, userInputs, null); // make sure there's an unambiguous group, otherwise the singular match check is meaningless Assert.True(matchResult.TryGetUnambiguousTemplateGroupToUse(out IReadOnlyList <ITemplateMatchInfo> unambiguousGroup)); Assert.Equal(2, unambiguousGroup.Count); Assert.Equal(2, matchResult.GetBestTemplateMatchList().Count); Assert.True(matchResult.TryGetSingularInvokableMatch(out ITemplateMatchInfo singularInvokableMatch, out SingularInvokableMatchCheckStatus resultStatus)); Assert.Equal(SingularInvokableMatchCheckStatus.SingleMatch, resultStatus); Assert.Equal("foo.test_1.VB", singularInvokableMatch.Info.Identity); }
public static void ShowInvocationExamples(TemplateListResolutionResult templateResolutionResult, IHostSpecificDataLoader hostDataLoader, string commandName) { const int ExamplesToShow = 2; IReadOnlyList <string> preferredNameList = new List <string>() { "mvc" }; int numShown = 0; IReadOnlyList <ITemplateMatchInfo> bestMatchedTemplates = templateResolutionResult.GetBestTemplateMatchList() .Where(x => !x.HasNameMismatch()).ToList(); if (bestMatchedTemplates.Count == 0) { return; } IList <ITemplateInfo> templateList = bestMatchedTemplates.Select(x => x.Info).ToList(); Reporter.Output.WriteLine("Examples:"); HashSet <string> usedGroupIds = new HashSet <string>(StringComparer.OrdinalIgnoreCase); foreach (string preferredName in preferredNameList) { ITemplateInfo template = templateList.FirstOrDefault(x => string.Equals(x.ShortName, preferredName, StringComparison.OrdinalIgnoreCase)); if (template != null) { string identity = string.IsNullOrWhiteSpace(template.GroupIdentity) ? string.IsNullOrWhiteSpace(template.Identity) ? string.Empty : template.Identity : template.GroupIdentity; if (usedGroupIds.Add(identity)) { GenerateUsageForTemplate(template, hostDataLoader, commandName); numShown++; } } templateList.Remove(template); // remove it so it won't get chosen again } // show up to 2 examples (total, including the above) Random rnd = new Random(); for (int i = numShown; i < ExamplesToShow && templateList.Count > 0; i++) { int index = rnd.Next(0, templateList.Count - 1); ITemplateInfo template = templateList[index]; string identity = string.IsNullOrWhiteSpace(template.GroupIdentity) ? string.IsNullOrWhiteSpace(template.Identity) ? string.Empty : template.Identity : template.GroupIdentity; if (usedGroupIds.Add(identity) && !GenerateUsageForTemplate(template, hostDataLoader, commandName)) { --i; } templateList.Remove(template); // remove it so it won't get chosen again } // show a help example Reporter.Output.WriteLine($" dotnet {commandName} --help"); }
public void TestPerformCoreTemplateQuery_InvalidChoiceValueInvalidatesMatch() { List <ITemplateInfo> templatesToSearch = new List <ITemplateInfo>(); templatesToSearch.Add(new TemplateInfo() { ShortName = "foo", Name = "Foo template", Identity = "foo.test.1x", GroupIdentity = "foo.test.template", Precedence = 100, Tags = new Dictionary <string, ICacheTag>(StringComparer.OrdinalIgnoreCase) { { "framework", ResolutionTestHelper.CreateTestCacheTag(new List <string>() { "netcoreapp1.0", "netcoreapp1.1" }) } }, CacheParameters = new Dictionary <string, ICacheParameter>() }); templatesToSearch.Add(new TemplateInfo() { ShortName = "foo", Name = "Foo template", Identity = "foo.test.2x", GroupIdentity = "foo.test.template", Precedence = 200, Tags = new Dictionary <string, ICacheTag>(StringComparer.OrdinalIgnoreCase) { { "framework", ResolutionTestHelper.CreateTestCacheTag(new List <string>() { "netcoreapp2.0" }) } }, CacheParameters = new Dictionary <string, ICacheParameter>() }); INewCommandInput userInputs = new MockNewCommandInput( new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase) { { "framework", "netcoreapp3.0" } } ) { TemplateName = "foo" }; IHostSpecificDataLoader hostSpecificDataLoader = new MockHostSpecificDataLoader(); TemplateListResolutionResult matchResult = TemplateListResolver.GetTemplateResolutionResult(templatesToSearch, hostSpecificDataLoader, userInputs, null); Assert.True(matchResult.TryGetUnambiguousTemplateGroupToUse(out IReadOnlyList <ITemplateMatchInfo> unambiguousGroup)); Assert.Equal(2, unambiguousGroup.Count); Assert.Equal(2, matchResult.GetBestTemplateMatchList().Count); Assert.Contains(unambiguousGroup[0].MatchDisposition, x => x.Kind == MatchKind.InvalidParameterValue); Assert.Contains(unambiguousGroup[1].MatchDisposition, x => x.Kind == MatchKind.InvalidParameterValue); }
public void TestPerformCoreTemplateQuery_GroupIsFound() { List <ITemplateInfo> templatesToSearch = new List <ITemplateInfo>(); templatesToSearch.Add(new TemplateInfo() { ShortName = "foo", Name = "Foo template old", Identity = "foo.test.old", GroupIdentity = "foo.test.template", Precedence = 100, CacheParameters = new Dictionary <string, ICacheParameter>(), Tags = new Dictionary <string, ICacheTag>() }); templatesToSearch.Add(new TemplateInfo() { ShortName = "foo", Name = "Foo template new", Identity = "foo.test.new", GroupIdentity = "foo.test.template", Precedence = 200, CacheParameters = new Dictionary <string, ICacheParameter>(), Tags = new Dictionary <string, ICacheTag>() }); templatesToSearch.Add(new TemplateInfo() { ShortName = "bar", Name = "Bar template", Identity = "bar.test", GroupIdentity = "bar.test.template", Precedence = 100, CacheParameters = new Dictionary <string, ICacheParameter>(), Tags = new Dictionary <string, ICacheTag>() }); INewCommandInput userInputs = new MockNewCommandInput() { TemplateName = "foo" }; TemplateListResolutionResult matchResult = TemplateListResolver.GetTemplateResolutionResult(templatesToSearch, new MockHostSpecificDataLoader(), userInputs, null); Assert.Equal(2, matchResult.GetBestTemplateMatchList().Count); Assert.True(matchResult.TryGetUnambiguousTemplateGroupToUse(out IReadOnlyList <ITemplateMatchInfo> unambiguousGroup)); Assert.Equal(2, unambiguousGroup.Count); Assert.Contains(unambiguousGroup, x => string.Equals(x.Info.Identity, "foo.test.old")); Assert.Contains(unambiguousGroup, x => string.Equals(x.Info.Identity, "foo.test.new")); }
public void TestPerformCoreTemplateQuery_InputLanguageIsPreferredOverDefault() { List <ITemplateInfo> templatesToSearch = new List <ITemplateInfo>(); templatesToSearch.Add(new TemplateInfo() { ShortName = "foo", Name = "Description of foo Perl template", Identity = "foo.test.Perl", GroupIdentity = "foo.test.template", Tags = new Dictionary <string, ICacheTag>(StringComparer.OrdinalIgnoreCase) { { "language", ResolutionTestHelper.CreateTestCacheTag("Perl") } }, CacheParameters = new Dictionary <string, ICacheParameter>() }); templatesToSearch.Add(new TemplateInfo() { ShortName = "foo", Name = "Description of foo LISP template", Identity = "foo.test.Lisp", GroupIdentity = "foo.test.template", Tags = new Dictionary <string, ICacheTag>(StringComparer.OrdinalIgnoreCase) { { "language", ResolutionTestHelper.CreateTestCacheTag("LISP") } }, CacheParameters = new Dictionary <string, ICacheParameter>() }); INewCommandInput userInputs = new MockNewCommandInput() { TemplateName = "foo", Language = "LISP" }; TemplateListResolutionResult matchResult = TemplateListResolver.GetTemplateResolutionResult(templatesToSearch, new MockHostSpecificDataLoader(), userInputs, "Perl"); Assert.Equal(1, matchResult.GetBestTemplateMatchList().Count); Assert.True(matchResult.TryGetUnambiguousTemplateGroupToUse(out IReadOnlyList <ITemplateMatchInfo> unambiguousGroup)); Assert.Equal(1, unambiguousGroup.Count); Assert.Equal("foo.test.Lisp", unambiguousGroup[0].Info.Identity); }
private static void GetContextBasedAndOtherPartialMatches(TemplateListResolutionResult templateResolutionResult, out IReadOnlyList <IReadOnlyList <ITemplateMatchInfo> > contextProblemMatchGroups, out IReadOnlyList <IReadOnlyList <ITemplateMatchInfo> > remainingPartialMatchGroups) { Dictionary <string, List <ITemplateMatchInfo> > contextProblemMatches = new Dictionary <string, List <ITemplateMatchInfo> >(); Dictionary <string, List <ITemplateMatchInfo> > remainingPartialMatches = new Dictionary <string, List <ITemplateMatchInfo> >(); // this filtering / grouping ignores language differences. foreach (ITemplateMatchInfo template in templateResolutionResult.GetBestTemplateMatchList(true)) { if (template.MatchDisposition.Any(x => x.Location == MatchLocation.Context && x.Kind != MatchKind.Exact)) { if (!contextProblemMatches.TryGetValue(template.Info.GroupIdentity, out List <ITemplateMatchInfo> templateGroup)) { templateGroup = new List <ITemplateMatchInfo>(); contextProblemMatches.Add(template.Info.GroupIdentity, templateGroup); } templateGroup.Add(template); } else if (!templateResolutionResult.UsingContextMatches && template.MatchDisposition.Any(t => t.Location != MatchLocation.Context && t.Kind != MatchKind.Mismatch && t.Kind != MatchKind.Unspecified)) { if (!remainingPartialMatches.TryGetValue(template.Info.GroupIdentity, out List <ITemplateMatchInfo> templateGroup)) { templateGroup = new List <ITemplateMatchInfo>(); remainingPartialMatches.Add(template.Info.GroupIdentity, templateGroup); } templateGroup.Add(template); } } // context mismatches from the "matched" templates contextProblemMatchGroups = contextProblemMatches.Values.ToList(); // other templates with anything matching remainingPartialMatchGroups = remainingPartialMatches.Values.ToList(); }