diff --git a/src/chocolatey.tests/chocolatey.tests.csproj b/src/chocolatey.tests/chocolatey.tests.csproj index 32422dc74d..26ad3d9872 100644 --- a/src/chocolatey.tests/chocolatey.tests.csproj +++ b/src/chocolatey.tests/chocolatey.tests.csproj @@ -90,6 +90,7 @@ + diff --git a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyTemplateCommandSpecs.cs b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyTemplateCommandSpecs.cs new file mode 100644 index 0000000000..223af9dc63 --- /dev/null +++ b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyTemplateCommandSpecs.cs @@ -0,0 +1,308 @@ +// Copyright © 2017 - 2021 Chocolatey Software, Inc +// Copyright © 2011 - 2017 RealDimensions Software, LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace chocolatey.tests.infrastructure.app.commands +{ + using System; + using System.Collections.Generic; + using System.Linq; + using chocolatey.infrastructure.app.attributes; + using chocolatey.infrastructure.app.commands; + using chocolatey.infrastructure.app.configuration; + using chocolatey.infrastructure.app.domain; + using chocolatey.infrastructure.app.services; + using chocolatey.infrastructure.commandline; + using chocolatey.infrastructure.filesystem; + using Moq; + using Should; + + public class ChocolateyTemplateCommandSpecs + { + public abstract class ChocolateyTemplateCommandSpecsBase : TinySpec + { + protected ChocolateyTemplateCommand command; + protected Mock templateService = new Mock(); + protected ChocolateyConfiguration configuration = new ChocolateyConfiguration(); + + public override void Context() + { + command = new ChocolateyTemplateCommand(templateService.Object); + } + + public void reset() + { + templateService.ResetCalls(); + } + } + + public class when_implementing_command_for : ChocolateyTemplateCommandSpecsBase + { + private List results; + + public override void Because() + { + results = command.GetType().GetCustomAttributes(typeof(CommandForAttribute), false).Cast().Select(a => a.CommandName).ToList(); + } + + [Fact] + public void should_implement_help() + { + results.ShouldContain("template"); + results.ShouldContain("templates"); + } + } + + public class when_configurating_the_argument_parser : ChocolateyTemplateCommandSpecsBase + { + private OptionSet optionSet; + + public override void Context() + { + base.Context(); + optionSet = new OptionSet(); + } + + public override void Because() + { + command.configure_argument_parser(optionSet, configuration); + } + + [Fact] + public void should_add_name_to_the_option_set() + { + optionSet.Contains("name").ShouldBeTrue(); + } + + [Fact] + public void should_add_short_version_of_name_to_the_option_set() + { + optionSet.Contains("n").ShouldBeTrue(); + } + } + + + public class when_handling_additional_argument_parsing : ChocolateyTemplateCommandSpecsBase + { + private readonly IList unparsedArgs = new List(); + private Action because; + + public override void Because() + { + because = () => command.handle_additional_argument_parsing(unparsedArgs, configuration); + } + + public new void reset() + { + configuration.TemplateCommand.Name = string.Empty; + configuration.TemplateCommand.Command = TemplateCommandType.unknown; + unparsedArgs.Clear(); + base.reset(); + } + + [Fact] + public void should_use_the_first_unparsed_arg_as_the_subcommand() + { + reset(); + unparsedArgs.Add("list"); + because(); + + configuration.TemplateCommand.Command.ShouldEqual(TemplateCommandType.list); + } + + [Fact] + public void should_throw_when_more_than_one_unparsed_arg_is_passed() + { + reset(); + unparsedArgs.Add("badcommand"); + unparsedArgs.Add("bbq"); + var errorred = false; + Exception error = null; + + try + { + because(); + } + catch (Exception ex) + { + errorred = true; + error = ex; + } + + errorred.ShouldBeTrue(); + error.ShouldNotBeNull(); + error.ShouldBeType(); + error.Message.ShouldContain("A single template command must be listed"); + } + + [Fact] + public void should_accept_list_as_the_subcommand() + { + reset(); + unparsedArgs.Add("list"); + because(); + + configuration.TemplateCommand.Command.ShouldEqual(TemplateCommandType.list); + } + + [Fact] + public void should_accept_uppercase_list_as_the_subcommand() + { + reset(); + unparsedArgs.Add("LIST"); + because(); + + configuration.TemplateCommand.Command.ShouldEqual(TemplateCommandType.list); + } + + [Fact] + public void should_accept_info_as_the_subcommand() + { + reset(); + unparsedArgs.Add("info"); + because(); + + configuration.TemplateCommand.Command.ShouldEqual(TemplateCommandType.info); + } + + [Fact] + public void should_accept_uppercase_info_as_the_subcommand() + { + reset(); + unparsedArgs.Add("INFO"); + because(); + + configuration.TemplateCommand.Command.ShouldEqual(TemplateCommandType.info); + } + + [Fact] + public void should_set_unrecognized_values_to_list_as_the_subcommand() + { + reset(); + unparsedArgs.Add("badcommand"); + because(); + + configuration.TemplateCommand.Command.ShouldEqual(TemplateCommandType.list); + } + + [Fact] + public void should_default_to_list_as_the_subcommand() + { + reset(); + because(); + + configuration.TemplateCommand.Command.ShouldEqual(TemplateCommandType.list); + } + + [Fact] + public void should_handle_passing_in_an_empty_string() + { + reset(); + unparsedArgs.Add(" "); + because(); + + configuration.TemplateCommand.Command.ShouldEqual(TemplateCommandType.list); + } + } + + public class when_handling_validation : ChocolateyTemplateCommandSpecsBase + { + private Action because; + + public override void Because() + { + because = () => command.handle_validation(configuration); + } + + [Fact] + public void should_continue_when_command_is_list_and_name_is_set() + { + configuration.TemplateCommand.Command = TemplateCommandType.list; + configuration.TemplateCommand.Name = "bob"; + because(); + } + + [Fact] + public void should_continue_when_command_is_list_and_name_is_not_set() + { + configuration.TemplateCommand.Command = TemplateCommandType.list; + configuration.TemplateCommand.Name = ""; + because(); + } + + [Fact] + public void should_throw_when_command_is_info_and_name_is_not_set() + { + configuration.TemplateCommand.Command = TemplateCommandType.info; + configuration.TemplateCommand.Name = ""; + var errorred = false; + Exception error = null; + + try + { + because(); + } + catch (Exception ex) + { + errorred = true; + error = ex; + } + + errorred.ShouldBeTrue(); + error.ShouldNotBeNull(); + error.ShouldBeType(); + error.Message.ShouldEqual("When specifying the subcommand '{0}', you must also specify --name.".format_with(configuration.TemplateCommand.Command.to_string())); + } + + [Fact] + public void should_continue_when_command_info_and_name_is_set() + { + configuration.TemplateCommand.Command = TemplateCommandType.info; + configuration.TemplateCommand.Name = "bob"; + because(); + } + } + + public class when_noop_is_called : ChocolateyTemplateCommandSpecsBase + { + public override void Because() + { + configuration.TemplateCommand.Command = TemplateCommandType.list; + command.noop(configuration); + } + + [Fact] + public void should_call_service_list_noop() + { + templateService.Verify(c => c.list_noop(configuration), Times.Once); + } + } + + public class when_run_is_called : ChocolateyTemplateCommandSpecsBase + { + public override void Because() + { + configuration.TemplateCommand.Command = TemplateCommandType.list; + command.run(configuration); + } + + [Fact] + public void should_call_service_list() + { + templateService.Verify(c => c.list(configuration), Times.Once); + } + } + } +}