// Displays the list of templates in a table, one row per template group.
        //
        // The columns displayed are as follows:
        // Except where noted, the values are taken from the highest-precedence template in the group. The info could vary among the templates in the group, but shouldn't.
        // (There is no check that the info doesn't vary.)
        // - Template Name
        // - Short Name: displays the first short name from the highest precedence template in the group.
        // - Language: All languages supported by any template in the group are displayed, with the default language in brackets, e.g.: [C#]
        // - Tags
        private static void DisplayTemplateList(IReadOnlyCollection <ITemplateMatchInfo> templates, IEngineEnvironmentSettings environmentSettings, INewCommandInput commandInput, string defaultLanguage)
        {
            IReadOnlyCollection <TemplateGroupTableRow> groupsForDisplay = TemplateGroupDisplay.GetTemplateGroupsForListDisplay(templates, commandInput.Language, defaultLanguage);

            HelpFormatter <TemplateGroupTableRow> formatter =
                HelpFormatter
                .For(
                    environmentSettings,
                    commandInput,
                    groupsForDisplay,
                    columnPadding: 2,
                    headerSeparator: '-',
                    blankLineBetweenRows: false)
                .DefineColumn(t => t.Name, LocalizableStrings.ColumnNameTemplateName, shrinkIfNeeded: true, minWidth: 15, showAlways: true)
                .DefineColumn(t => t.ShortName, LocalizableStrings.ColumnNameShortName, showAlways: true)
                .DefineColumn(t => t.Languages, out object languageColumn, LocalizableStrings.ColumnNameLanguage, NewCommandInputCli.LanguageColumnFilter, defaultColumn: true)
                .DefineColumn(t => t.Type, LocalizableStrings.ColumnNameType, NewCommandInputCli.TypeColumnFilter, defaultColumn: false)
                .DefineColumn(t => t.Author, LocalizableStrings.ColumnNameAuthor, NewCommandInputCli.AuthorColumnFilter, defaultColumn: false, shrinkIfNeeded: true, minWidth: 10)
                .DefineColumn(t => t.Classifications, out object tagsColumn, LocalizableStrings.ColumnNameTags, NewCommandInputCli.TagsColumnFilter, defaultColumn: true)

                .OrderByDescending(languageColumn, new NullOrEmptyIsLastStringComparer())
                .OrderBy(tagsColumn);

            Reporter.Output.WriteLine(formatter.Layout());
        }
        private static void DisplayResultsForPack(TemplateSourceSearchResult sourceResult, IEngineEnvironmentSettings environmentSettings, INewCommandInput commandInput, string defaultLanguage)
        {
            string sourceHeader = string.Format(LocalizableStrings.SearchResultSourceIndicator, sourceResult.SourceDisplayName);

            Reporter.Output.WriteLine(sourceHeader);
            Reporter.Output.WriteLine();

            IReadOnlyCollection <SearchResultTableRow> data = GetSearchResultsForDisplay(sourceResult, commandInput.Language, defaultLanguage);

            HelpFormatter <SearchResultTableRow> formatter =
                HelpFormatter
                .For(
                    environmentSettings,
                    commandInput,
                    data,
                    columnPadding: 2,
                    headerSeparator: '-',
                    blankLineBetweenRows: false)
                .DefineColumn(r => r.TemplateGroupInfo.Name, LocalizableStrings.ColumnNameTemplateName, showAlways: true, shrinkIfNeeded: true, minWidth: 15)
                .DefineColumn(r => r.TemplateGroupInfo.ShortName, LocalizableStrings.ColumnNameShortName, showAlways: true)
                .DefineColumn(r => r.TemplateGroupInfo.Author, LocalizableStrings.ColumnNameAuthor, NewCommandInputCli.AuthorColumnFilter, defaultColumn: true, shrinkIfNeeded: true, minWidth: 10)
                .DefineColumn(r => r.TemplateGroupInfo.Languages, LocalizableStrings.ColumnNameLanguage, NewCommandInputCli.LanguageColumnFilter, defaultColumn: true)
                .DefineColumn(r => r.TemplateGroupInfo.Type, LocalizableStrings.ColumnNameType, NewCommandInputCli.TypeColumnFilter, defaultColumn: false)
                .DefineColumn(r => r.TemplateGroupInfo.Classifications, LocalizableStrings.ColumnNameTags, NewCommandInputCli.TagsColumnFilter, defaultColumn: false, shrinkIfNeeded: true, minWidth: 10)
                .DefineColumn(r => r.PackageName, out object packageColumn, LocalizableStrings.ColumnNamePackage, showAlways: true)
                .DefineColumn(r => r.PrintableTotalDownloads, LocalizableStrings.ColumnNameTotalDownloads, showAlways: true, rightAlign: true)
                .OrderBy(packageColumn);

            Reporter.Output.WriteLine(formatter.Layout());
        }
Exemple #3
0
        /// <summary>
        /// Displays the help when <paramref name="unambiguousTemplateGroup"/> contains the invokable templates with ambiguous precedence.
        /// </summary>
        /// <param name="unambiguousTemplateGroup">resolved unambiguous template group to use based on the command input</param>
        /// <param name="environmentSettings"></param>
        /// <param name="commandInput">the command input</param>
        /// <param name="installUnitDescriptors">the list of install unit descriptors</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">when <paramref name="unambiguousTemplateGroup"/>is <see cref="null"/></exception>
        /// <exception cref="ArgumentNullException">when <paramref name="commandInput"/>is <see cref="null"/></exception>
        private static CreationResultStatus DisplayAmbiguousPrecedenceError(
            TemplateGroup unambiguousTemplateGroup,
            IEngineEnvironmentSettings environmentSettings,
            INewCommandInput commandInput,
            IEnumerable <IInstallUnitDescriptor> installUnitDescriptors)
        {
            _ = unambiguousTemplateGroup ?? throw new ArgumentNullException(paramName: nameof(unambiguousTemplateGroup));
            _ = unambiguousTemplateGroup ?? throw new ArgumentNullException(paramName: nameof(commandInput));

            Reporter.Error.WriteLine(LocalizableStrings.AmbiguousTemplatesHeader.Bold().Red());
            List <AmbiguousTemplateDetails> ambiguousTemplateDetails = new List <AmbiguousTemplateDetails>();

            foreach (ITemplateMatchInfo template in unambiguousTemplateGroup.GetHighestPrecedenceInvokableTemplates(true))
            {
                ambiguousTemplateDetails.Add(new AmbiguousTemplateDetails
                {
                    TemplateIdentity       = template.Info.Identity,
                    TemplateName           = template.Info.Name,
                    TemplateShortName      = template.Info.ShortName,
                    TemplateLanguage       = template.Info.GetLanguage(),
                    TemplatePrecedence     = template.Info.Precedence,
                    TemplateAuthor         = template.Info.Author,
                    InstallationDescriptor = installUnitDescriptors?.FirstOrDefault(descriptor => descriptor.MountPointId == template.Info.ConfigMountPointId)
                });
            }

            HelpFormatter <AmbiguousTemplateDetails> formatter =
                HelpFormatter
                .For(
                    environmentSettings,
                    commandInput,
                    ambiguousTemplateDetails,
                    columnPadding: 2,
                    headerSeparator: '-',
                    blankLineBetweenRows: false)
                .DefineColumn(t => t.TemplateIdentity, LocalizableStrings.ColumnNameIdentity, showAlways: true)
                .DefineColumn(t => t.TemplateName, LocalizableStrings.ColumnNameTemplateName, shrinkIfNeeded: true, minWidth: 15, showAlways: true)
                .DefineColumn(t => t.TemplateShortName, LocalizableStrings.ColumnNameShortName, showAlways: true)
                .DefineColumn(t => t.TemplateLanguage, LocalizableStrings.ColumnNameLanguage, showAlways: true)
                .DefineColumn(t => t.TemplatePrecedence.ToString(), out object prcedenceColumn, LocalizableStrings.ColumnNamePrecedence, showAlways: true)
                .DefineColumn(t => t.TemplateAuthor, LocalizableStrings.ColumnNameAuthor, showAlways: true, shrinkIfNeeded: true, minWidth: 10)
                .DefineColumn(t => t.InstallationDescriptor != null ? t.InstallationDescriptor.Identifier : string.Empty, LocalizableStrings.ColumnNamePackage, showAlways: true)
                .OrderByDescending(prcedenceColumn, new NullOrEmptyIsLastStringComparer());

            Reporter.Error.WriteLine(formatter.Layout().Bold().Red());

            string hintMessage = LocalizableStrings.AmbiguousTemplatesMultiplePackagesHint;

            if (unambiguousTemplateGroup.Templates.AllAreTheSame(t => t.Info.ConfigMountPointId))
            {
                IInstallUnitDescriptor descriptor = installUnitDescriptors?.First(descriptor => descriptor.MountPointId == unambiguousTemplateGroup.Templates.First().Info.ConfigMountPointId);
                if (descriptor?.Details?.ContainsKey("NuGetPackageId") ?? false)
                {
                    hintMessage = string.Format(LocalizableStrings.AmbiguousTemplatesSamePackageHint, descriptor.Identifier);
                }
            }

            Reporter.Error.WriteLine(hintMessage.Bold().Red());
            return(CreationResultStatus.NotFound);
        }
        private static async Task <CreationResultStatus> DisplayAmbiguousPrecedenceErrorAsync(
            TemplateGroup unambiguousTemplateGroup,
            IEngineEnvironmentSettings environmentSettings,
            INewCommandInput commandInput)
        {
            _ = unambiguousTemplateGroup ?? throw new ArgumentNullException(paramName: nameof(unambiguousTemplateGroup));
            _ = unambiguousTemplateGroup ?? throw new ArgumentNullException(paramName: nameof(commandInput));

            Reporter.Error.WriteLine(LocalizableStrings.AmbiguousTemplatesHeader.Bold().Red());
            List <AmbiguousTemplateDetails> ambiguousTemplateDetails = new List <AmbiguousTemplateDetails>();

            foreach (ITemplateMatchInfo template in unambiguousTemplateGroup.GetHighestPrecedenceInvokableTemplates(true))
            {
                ambiguousTemplateDetails.Add(new AmbiguousTemplateDetails
                {
                    TemplateIdentity   = template.Info.Identity,
                    TemplateName       = template.Info.Name,
                    TemplateShortNames = template.Info.ShortNameList,
                    TemplateLanguage   = template.Info.GetLanguage(),
                    TemplatePrecedence = template.Info.Precedence,
                    TemplateAuthor     = template.Info.Author ?? string.Empty,
                    TemplatePackage    = await template.Info.GetTemplatePackageAsync(environmentSettings).ConfigureAwait(false) as IManagedTemplatePackage
                });
            }

            HelpFormatter <AmbiguousTemplateDetails> formatter =
                HelpFormatter
                .For(
                    environmentSettings,
                    commandInput,
                    ambiguousTemplateDetails,
                    columnPadding: 2,
                    headerSeparator: '-',
                    blankLineBetweenRows: false)
                .DefineColumn(t => t.TemplateIdentity, LocalizableStrings.ColumnNameIdentity, showAlways: true)
                .DefineColumn(t => t.TemplateName, LocalizableStrings.ColumnNameTemplateName, shrinkIfNeeded: true, minWidth: 15, showAlways: true)
                .DefineColumn(t => string.Join(",", t.TemplateShortNames), LocalizableStrings.ColumnNameShortName, showAlways: true)
                .DefineColumn(t => t.TemplateLanguage, LocalizableStrings.ColumnNameLanguage, showAlways: true)
                .DefineColumn(t => t.TemplatePrecedence.ToString(), out object prcedenceColumn, LocalizableStrings.ColumnNamePrecedence, showAlways: true)
                .DefineColumn(t => t.TemplateAuthor, LocalizableStrings.ColumnNameAuthor, showAlways: true, shrinkIfNeeded: true, minWidth: 10)
                .DefineColumn(t => t.TemplatePackage != null ? t.TemplatePackage.Identifier : string.Empty, LocalizableStrings.ColumnNamePackage, showAlways: true)
                .OrderByDescending(prcedenceColumn, new NullOrEmptyIsLastStringComparer());

            Reporter.Error.WriteLine(formatter.Layout().Bold().Red());

            string hintMessage = LocalizableStrings.AmbiguousTemplatesMultiplePackagesHint;

            if (unambiguousTemplateGroup.Templates.AllAreTheSame(t => t.Info.MountPointUri))
            {
                IManagedTemplatePackage?templatePackage = await unambiguousTemplateGroup.Templates.First().Info.GetTemplatePackageAsync(environmentSettings).ConfigureAwait(false) as IManagedTemplatePackage;

                if (templatePackage != null)
                {
                    hintMessage = string.Format(LocalizableStrings.AmbiguousTemplatesSamePackageHint, templatePackage.Identifier);
                }
            }
            Reporter.Error.WriteLine(hintMessage.Bold().Red());
            return(CreationResultStatus.NotFound);
        }
        // Displays the list of templates in a table, one row per template group.
        //
        // The columns displayed are as follows
        // Note: Except language, the values are taken from one template in the group. The info could vary among the templates in the group, but shouldn't.
        // There is no check that the info doesn't vary.
        //  - Templates
        //  - Short Name
        //  - Language: All languages supported by the group are displayed, with the default language in brackets, e.g.: [C#]
        //  - Tags
        private static void DisplayTemplateList(IReadOnlyList <ITemplateMatchInfo> templates, IEngineEnvironmentSettings environmentSettings, string language, string defaultLanguage)
        {
            IReadOnlyDictionary <ITemplateInfo, string> templateGroupsLanguages = GetLanguagesForTemplateGroups(templates, language, defaultLanguage);

            HelpFormatter <KeyValuePair <ITemplateInfo, string> > formatter = HelpFormatter.For(environmentSettings, templateGroupsLanguages, 6, '-', false)
                                                                              .DefineColumn(t => t.Key.Name, LocalizableStrings.Templates)
                                                                              .DefineColumn(t => t.Key.ShortName, LocalizableStrings.ShortName)
                                                                              .DefineColumn(t => t.Value, out object languageColumn, LocalizableStrings.Language)
                                                                              .DefineColumn(t => t.Key.Classifications != null ? string.Join("/", t.Key.Classifications) : null, out object tagsColumn, LocalizableStrings.Tags)
                                                                              //.OrderByDescending(languageColumn, new NullOrEmptyIsLastStringComparer())
                                                                              .OrderBy(tagsColumn);
            //Reporter.Output.WriteLine(formatter.Layout());
        }
        public void CanShowUserSelectedColumns()
        {
            ITemplateEngineHost host = new TestHost
            {
                HostIdentifier = "TestRunner",
                Version        = "1.0.0.0",
                Locale         = "en-US"
            };

            IEngineEnvironmentSettings environmentSettings = new MockEngineEnvironmentSettings()
            {
                Host        = host,
                Environment = new MockEnvironment()
                {
                    ConsoleBufferWidth = 100
                }
            };

            INewCommandInput command = new MockNewCommandInput()
            {
                Columns = new List <string>()
                {
                    "column3"
                }
            };

            IEnumerable <Tuple <string, string, string> > data = new List <Tuple <string, string, string> >()
            {
                new Tuple <string, string, string>("My test data", "My test data", "Column 3 data"),
                new Tuple <string, string, string>("My test data", "My test data", "Column 3 data")
            };

            string expectedOutput = $"Column 1      Column 3     {Environment.NewLine}------------  -------------{Environment.NewLine}My test data  Column 3 data{Environment.NewLine}My test data  Column 3 data{Environment.NewLine}";

            HelpFormatter <Tuple <string, string, string> > formatter =
                HelpFormatter
                .For(
                    environmentSettings,
                    command,
                    data,
                    columnPadding: 2,
                    headerSeparator: '-',
                    blankLineBetweenRows: false)
                .DefineColumn(t => t.Item1, "Column 1", showAlways: true)
                .DefineColumn(t => t.Item2, "Column 2", columnName: "column2")   //defaultColumn: true by default
                .DefineColumn(t => t.Item3, "Column 3", columnName: "column3", defaultColumn: false);

            string result = formatter.Layout();

            Assert.Equal(expectedOutput, result);
        }
Exemple #7
0
        // Displays the list of templates in a table, one row per template group.
        //
        // The columns displayed are as follows:
        // Except where noted, the values are taken from the highest-precedence template in the group. The info could vary among the templates in the group, but shouldn't.
        // (There is no check that the info doesn't vary.)
        // - Template Name
        // - Short Name: displays the first short name from the highest precedence template in the group.
        // - Language: All languages supported by any template in the group are displayed, with the default language in brackets, e.g.: [C#]
        // - Tags
        private static void DisplayTemplateList(IReadOnlyList <ITemplateMatchInfo> templates, IEngineEnvironmentSettings environmentSettings, string language, string defaultLanguage)
        {
            IReadOnlyList <TemplateGroupForListDisplay> groupsForDisplay = GetTemplateGroupsForListDisplay(templates, language, defaultLanguage);

            HelpFormatter <TemplateGroupForListDisplay> formatter = HelpFormatter.For(environmentSettings, groupsForDisplay, 6, '-', false)
                                                                    .DefineColumn(t => t.Name, LocalizableStrings.Templates)
                                                                    .DefineColumn(t => t.ShortName, LocalizableStrings.ShortName)
                                                                    .DefineColumn(t => t.Languages, out object languageColumn, LocalizableStrings.Language)
                                                                    .DefineColumn(t => t.Classifications, out object tagsColumn, LocalizableStrings.Tags)
                                                                    .OrderByDescending(languageColumn, new NullOrEmptyIsLastStringComparer())
                                                                    .OrderBy(tagsColumn);

            Reporter.Output.WriteLine(formatter.Layout());
        }
        public void CanShrinkMultipleColumns()
        {
            ITemplateEngineHost host = new TestHost
            {
                HostIdentifier = "TestRunner",
                Version        = "1.0.0.0",
                Locale         = "en-US"
            };

            IEngineEnvironmentSettings environmentSettings = new MockEngineEnvironmentSettings()
            {
                Host        = host,
                Environment = new MockEnvironment()
                {
                    ConsoleBufferWidth = 5 + 2 + 7 + 1,
                }
            };

            INewCommandInput command = new MockNewCommandInput();

            IEnumerable <Tuple <string, string> > data = new List <Tuple <string, string> >()
            {
                new Tuple <string, string>("My test data", "My test data"),
                new Tuple <string, string>("My test data", "My test data")
            };

            string expectedOutput = $"Co...  Colu...{Environment.NewLine}-----  -------{Environment.NewLine}My...  My t...{Environment.NewLine}My...  My t...{Environment.NewLine}";

            HelpFormatter <Tuple <string, string> > formatter =
                HelpFormatter
                .For(
                    environmentSettings,
                    command,
                    data,
                    columnPadding: 2,
                    headerSeparator: '-',
                    blankLineBetweenRows: false)
                .DefineColumn(t => t.Item1, "Column 1", shrinkIfNeeded: true, minWidth: 2)
                .DefineColumn(t => t.Item2, "Column 2", shrinkIfNeeded: true, minWidth: 2);

            string result = formatter.Layout();

            Assert.Equal(expectedOutput, result);
        }
Exemple #9
0
        public void CanRightAlign()
        {
            ITemplateEngineHost host = new TestHost
            {
                HostIdentifier = "TestRunner",
                Version        = "1.0.0.0",
                Locale         = "en-US"
            };

            IEngineEnvironmentSettings environmentSettings = new MockEngineEnvironmentSettings()
            {
                Host        = host,
                Environment = new MockEnvironment()
                {
                    ConsoleBufferWidth = 10, //less than need for data below
                }
            };

            INewCommandInput command = new MockNewCommandInput();

            IEnumerable <Tuple <string, string> > data = new List <Tuple <string, string> >()
            {
                new Tuple <string, string>("Monday", "Wednesday"),
                new Tuple <string, string>("Tuesday", "Sunday")
            };

            string expectedOutput = $"Column 1   Column 2{Environment.NewLine}--------  ---------{Environment.NewLine}Monday    Wednesday{Environment.NewLine}Tuesday      Sunday{Environment.NewLine}";

            HelpFormatter <Tuple <string, string> > formatter =
                HelpFormatter
                .For(
                    environmentSettings,
                    command,
                    data,
                    columnPadding: 2,
                    headerSeparator: '-',
                    blankLineBetweenRows: false)
                .DefineColumn(t => t.Item1, "Column 1")
                .DefineColumn(t => t.Item2, "Column 2", rightAlign: true);

            string result = formatter.Layout();

            Assert.Equal(expectedOutput, result);
        }
Exemple #10
0
        // Displays the list of templates in a table, one row per template group.
        //
        // The columns displayed are as follows:
        // Except where noted, the values are taken from the highest-precedence template in the group. The info could vary among the templates in the group, but shouldn't.
        // (There is no check that the info doesn't vary.)
        // - Template Name
        // - Short Name: displays the first short name from the highest precedence template in the group.
        // - Language: All languages supported by any template in the group are displayed, with the default language in brackets, e.g.: [C#]
        // - Tags
        private static void DisplayTemplateList(IReadOnlyCollection <IGrouping <string, ITemplateMatchInfo> > templates, IEngineEnvironmentSettings environmentSettings, string language, string defaultLanguage)
        {
            IReadOnlyCollection <TemplateGroupForListDisplay> groupsForDisplay = GetTemplateGroupsForListDisplay(templates, language, defaultLanguage);

            HelpFormatter <TemplateGroupForListDisplay> formatter =
                HelpFormatter
                .For(
                    environmentSettings,
                    groupsForDisplay,
                    columnPadding: 2,
                    headerSeparator: '-',
                    blankLineBetweenRows: false)
                .DefineColumn(t => t.Name, LocalizableStrings.Templates, shrinkIfNeeded: true)
                .DefineColumn(t => t.ShortName, LocalizableStrings.ShortName)
                .DefineColumn(t => t.Languages, out object languageColumn, LocalizableStrings.Language)
                .DefineColumn(t => t.Classifications, out object tagsColumn, LocalizableStrings.Tags)
                .OrderByDescending(languageColumn, new NullOrEmptyIsLastStringComparer())
                .OrderBy(tagsColumn);

            Reporter.Output.WriteLine(formatter.Layout());
        }
        public void CanShowAllColumns()
        {
            IEngineEnvironmentSettings environmentSettings = new MockEngineEnvironmentSettings()
            {
                Environment = new MockEnvironment()
                {
                    ConsoleBufferWidth = 100
                }
            };

            INewCommandInput command = new MockNewCommandInput().WithCommandOption("--columns-all");

            IEnumerable <Tuple <string, string, string> > data = new List <Tuple <string, string, string> >()
            {
                new Tuple <string, string, string>("Column 1 data", "Column 2 data", "Column 3 data"),
                new Tuple <string, string, string>("Column 1 data", "Column 2 data", "Column 3 data")
            };

            string expectedOutput = $"Column 1       Column 2       Column 3     {Environment.NewLine}-------------  -------------  -------------{Environment.NewLine}Column 1 data  Column 2 data  Column 3 data{Environment.NewLine}Column 1 data  Column 2 data  Column 3 data{Environment.NewLine}";

            HelpFormatter <Tuple <string, string, string> > formatter =
                HelpFormatter
                .For(
                    environmentSettings,
                    command,
                    data,
                    columnPadding: 2,
                    headerSeparator: '-',
                    blankLineBetweenRows: false)
                .DefineColumn(t => t.Item1, "Column 1", showAlways: true)
                .DefineColumn(t => t.Item2, "Column 2", columnName: "column2")  //defaultColumn: true by default
                .DefineColumn(t => t.Item3, "Column 3", columnName: "column3", defaultColumn: false);

            string result = formatter.Layout();

            Assert.Equal(expectedOutput, result);
        }
        public void CannotShrinkOverMinimumWidth()
        {
            IEngineEnvironmentSettings environmentSettings = new MockEngineEnvironmentSettings()
            {
                Environment = new MockEnvironment()
                {
                    ConsoleBufferWidth = 10, //less than need for data below
                }
            };

            INewCommandInput command = new MockNewCommandInput();

            IEnumerable <Tuple <string, string> > data = new List <Tuple <string, string> >()
            {
                new Tuple <string, string>("My test data", "My test data"),
                new Tuple <string, string>("My test data", "My test data")
            };

            string expectedOutput = $"Column 1      Column 2   {Environment.NewLine}------------  -----------{Environment.NewLine}My test data  My test ...{Environment.NewLine}My test data  My test ...{Environment.NewLine}";

            HelpFormatter <Tuple <string, string> > formatter =
                HelpFormatter
                .For(
                    environmentSettings,
                    command,
                    data,
                    columnPadding: 2,
                    headerSeparator: '-',
                    blankLineBetweenRows: false)
                .DefineColumn(t => t.Item1, "Column 1", shrinkIfNeeded: true, minWidth: 15)
                .DefineColumn(t => t.Item2, "Column 2", shrinkIfNeeded: true, minWidth: 8);

            string result = formatter.Layout();

            Assert.Equal(expectedOutput, result);
        }
        public void CanShrinkMultipleColumnsAndBalanceShrinking()
        {
            IEngineEnvironmentSettings environmentSettings = new MockEngineEnvironmentSettings()
            {
                Environment = new MockEnvironment()
                {
                    ConsoleBufferWidth = 6 + 2 + 6 + 1,
                }
            };

            INewCommandInput command = new MockNewCommandInput();

            IEnumerable <Tuple <string, string> > data = new List <Tuple <string, string> >()
            {
                new Tuple <string, string>("My test data", "My test data"),
                new Tuple <string, string>("My test data", "My test data")
            };

            string expectedOutput = $"Col...  Col...{Environment.NewLine}------  ------{Environment.NewLine}My ...  My ...{Environment.NewLine}My ...  My ...{Environment.NewLine}";

            HelpFormatter <Tuple <string, string> > formatter =
                HelpFormatter
                .For(
                    environmentSettings,
                    command,
                    data,
                    columnPadding: 2,
                    headerSeparator: '-',
                    blankLineBetweenRows: false)
                .DefineColumn(t => t.Item1, "Column 1", shrinkIfNeeded: true, minWidth: 2)
                .DefineColumn(t => t.Item2, "Column 2", shrinkIfNeeded: true, minWidth: 2);

            string result = formatter.Layout();

            Assert.Equal(expectedOutput, result);
        }