groovenauts-thor 0.19.1 → 0.19.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +0 -24
- data/groovenauts-thor.gemspec +1 -1
- data/lib/thor/base.rb +1 -1
- data/lib/thor/core_ext/ordered_hash.rb +63 -94
- data/lib/thor/parser/arguments.rb +1 -1
- data/lib/thor/parser/option.rb +0 -15
- data/lib/thor/version.rb +1 -1
- data/spec/actions/create_file_spec.rb +168 -0
- data/spec/actions/create_link_spec.rb +96 -0
- data/spec/actions/directory_spec.rb +169 -0
- data/spec/actions/empty_directory_spec.rb +129 -0
- data/spec/actions/file_manipulation_spec.rb +392 -0
- data/spec/actions/inject_into_file_spec.rb +135 -0
- data/spec/actions_spec.rb +331 -0
- data/spec/base_spec.rb +298 -0
- data/spec/command_spec.rb +79 -0
- data/spec/core_ext/hash_with_indifferent_access_spec.rb +48 -0
- data/spec/core_ext/ordered_hash_spec.rb +115 -0
- data/spec/exit_condition_spec.rb +19 -0
- data/spec/fixtures/application.rb +2 -0
- data/spec/fixtures/app{1}/README +3 -0
- data/spec/fixtures/bundle/execute.rb +6 -0
- data/spec/fixtures/bundle/main.thor +1 -0
- data/spec/fixtures/command.thor +10 -0
- data/spec/fixtures/doc/%file_name%.rb.tt +1 -0
- data/spec/fixtures/doc/COMMENTER +11 -0
- data/spec/fixtures/doc/README +3 -0
- data/spec/fixtures/doc/block_helper.rb +3 -0
- data/spec/fixtures/doc/config.rb +1 -0
- data/spec/fixtures/doc/config.yaml.tt +1 -0
- data/spec/fixtures/doc/excluding/%file_name%.rb.tt +1 -0
- data/spec/fixtures/enum.thor +10 -0
- data/spec/fixtures/group.thor +128 -0
- data/spec/fixtures/invoke.thor +131 -0
- data/spec/fixtures/path with spaces b/data/spec/fixtures/path with → spaces +0 -0
- data/spec/fixtures/preserve/script.sh +3 -0
- data/spec/fixtures/script.thor +220 -0
- data/spec/fixtures/subcommand.thor +17 -0
- data/spec/group_spec.rb +222 -0
- data/spec/helper.rb +80 -0
- data/spec/invocation_spec.rb +120 -0
- data/spec/line_editor/basic_spec.rb +28 -0
- data/spec/line_editor/readline_spec.rb +69 -0
- data/spec/line_editor_spec.rb +43 -0
- data/spec/parser/argument_spec.rb +53 -0
- data/spec/parser/arguments_spec.rb +66 -0
- data/spec/parser/option_spec.rb +210 -0
- data/spec/parser/options_spec.rb +414 -0
- data/spec/quality_spec.rb +75 -0
- data/spec/rake_compat_spec.rb +72 -0
- data/spec/register_spec.rb +227 -0
- data/spec/runner_spec.rb +246 -0
- data/spec/sandbox/application.rb +2 -0
- data/spec/sandbox/app{1}/README +3 -0
- data/spec/sandbox/bundle/execute.rb +6 -0
- data/spec/sandbox/bundle/main.thor +1 -0
- data/spec/sandbox/command.thor +10 -0
- data/spec/sandbox/doc/%file_name%.rb.tt +1 -0
- data/spec/sandbox/doc/COMMENTER +11 -0
- data/spec/sandbox/doc/README +3 -0
- data/spec/sandbox/doc/block_helper.rb +3 -0
- data/spec/sandbox/doc/config.rb +1 -0
- data/spec/sandbox/doc/config.yaml.tt +1 -0
- data/spec/sandbox/doc/excluding/%file_name%.rb.tt +1 -0
- data/spec/sandbox/enum.thor +10 -0
- data/spec/sandbox/group.thor +128 -0
- data/spec/sandbox/invoke.thor +131 -0
- data/spec/sandbox/path with spaces b/data/spec/sandbox/path with → spaces +0 -0
- data/spec/sandbox/preserve/script.sh +3 -0
- data/spec/sandbox/script.thor +220 -0
- data/spec/sandbox/subcommand.thor +17 -0
- data/spec/shell/basic_spec.rb +337 -0
- data/spec/shell/color_spec.rb +119 -0
- data/spec/shell/html_spec.rb +31 -0
- data/spec/shell_spec.rb +47 -0
- data/spec/subcommand_spec.rb +71 -0
- data/spec/thor_spec.rb +505 -0
- data/spec/util_spec.rb +196 -0
- metadata +146 -4
    
        data/spec/base_spec.rb
    ADDED
    
    | @@ -0,0 +1,298 @@ | |
| 1 | 
            +
            require "helper"
         | 
| 2 | 
            +
            require "thor/base"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class Amazing
         | 
| 5 | 
            +
              desc "hello", "say hello"
         | 
| 6 | 
            +
              def hello
         | 
| 7 | 
            +
                puts "Hello"
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
            end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            describe Thor::Base do
         | 
| 12 | 
            +
              describe "#initialize" do
         | 
| 13 | 
            +
                it "sets arguments array" do
         | 
| 14 | 
            +
                  base = MyCounter.new [1, 2]
         | 
| 15 | 
            +
                  expect(base.first).to eq(1)
         | 
| 16 | 
            +
                  expect(base.second).to eq(2)
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                it "sets arguments default values" do
         | 
| 20 | 
            +
                  base = MyCounter.new [1]
         | 
| 21 | 
            +
                  expect(base.second).to eq(2)
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                it "sets options default values" do
         | 
| 25 | 
            +
                  base = MyCounter.new [1, 2]
         | 
| 26 | 
            +
                  expect(base.options[:third]).to eq(3)
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                it "allows options to be given as symbols or strings" do
         | 
| 30 | 
            +
                  base = MyCounter.new [1, 2], :third => 4
         | 
| 31 | 
            +
                  expect(base.options[:third]).to eq(4)
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  base = MyCounter.new [1, 2], "third" => 4
         | 
| 34 | 
            +
                  expect(base.options[:third]).to eq(4)
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                it "creates options with indifferent access" do
         | 
| 38 | 
            +
                  base = MyCounter.new [1, 2], :third => 3
         | 
| 39 | 
            +
                  expect(base.options["third"]).to eq(3)
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                it "creates options with magic predicates" do
         | 
| 43 | 
            +
                  base = MyCounter.new [1, 2], :third => 3
         | 
| 44 | 
            +
                  expect(base.options.third).to eq(3)
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              describe "#no_commands" do
         | 
| 49 | 
            +
                it "avoids methods being added as commands" do
         | 
| 50 | 
            +
                  expect(MyScript.commands.keys).to include("animal")
         | 
| 51 | 
            +
                  expect(MyScript.commands.keys).not_to include("this_is_not_a_command")
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
              describe "#argument" do
         | 
| 56 | 
            +
                it "sets a value as required and creates an accessor for it" do
         | 
| 57 | 
            +
                  expect(MyCounter.start(%w[1 2 --third 3])[0]).to eq(1)
         | 
| 58 | 
            +
                  expect(Scripts::MyScript.start(%w[zoo my_special_param --param=normal_param])).to eq("my_special_param")
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                it "does not set a value in the options hash" do
         | 
| 62 | 
            +
                  expect(BrokenCounter.start(%w[1 2 --third 3])[0]).to be nil
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
              end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
              describe "#arguments" do
         | 
| 67 | 
            +
                it "returns the arguments for the class" do
         | 
| 68 | 
            +
                  expect(MyCounter.arguments.size).to be(2)
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
              end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
              describe ":aliases" do
         | 
| 73 | 
            +
                it "supports string aliases without a dash prefix" do
         | 
| 74 | 
            +
                  expect(MyCounter.start(%w[1 2 -z 3])[4]).to eq(3)
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                it "supports symbol aliases" do
         | 
| 78 | 
            +
                  expect(MyCounter.start(%w[1 2 -y 3])[5]).to eq(3)
         | 
| 79 | 
            +
                  expect(MyCounter.start(%w[1 2 -r 3])[5]).to eq(3)
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
              end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
              describe "#class_option" do
         | 
| 84 | 
            +
                it "sets options class wise" do
         | 
| 85 | 
            +
                  expect(MyCounter.start(%w[1 2 --third 3])[2]).to eq(3)
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                it "does not create an accessor for it" do
         | 
| 89 | 
            +
                  expect(BrokenCounter.start(%w[1 2 --third 3])[3]).to be false
         | 
| 90 | 
            +
                end
         | 
| 91 | 
            +
              end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
              describe "#class_options" do
         | 
| 94 | 
            +
                it "sets default options overwriting superclass definitions" do
         | 
| 95 | 
            +
                  options = Scripts::MyScript.class_options
         | 
| 96 | 
            +
                  expect(options[:force]).not_to be_required
         | 
| 97 | 
            +
                end
         | 
| 98 | 
            +
              end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
              describe "#remove_argument" do
         | 
| 101 | 
            +
                it "removes previously defined arguments from class" do
         | 
| 102 | 
            +
                  expect(ClearCounter.arguments).to be_empty
         | 
| 103 | 
            +
                end
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                it "undefine accessors if required" do
         | 
| 106 | 
            +
                  expect(ClearCounter.new).not_to respond_to(:first)
         | 
| 107 | 
            +
                  expect(ClearCounter.new).not_to respond_to(:second)
         | 
| 108 | 
            +
                end
         | 
| 109 | 
            +
              end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
              describe "#remove_class_option" do
         | 
| 112 | 
            +
                it "removes previous defined class option" do
         | 
| 113 | 
            +
                  expect(ClearCounter.class_options[:third]).to be nil
         | 
| 114 | 
            +
                end
         | 
| 115 | 
            +
              end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
              describe "#class_options_help" do
         | 
| 118 | 
            +
                before do
         | 
| 119 | 
            +
                  @content = capture(:stdout) { MyCounter.help(Thor::Base.shell.new) }
         | 
| 120 | 
            +
                end
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                it "shows option's description" do
         | 
| 123 | 
            +
                  expect(@content).to match(/# The third argument/)
         | 
| 124 | 
            +
                end
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                it "shows usage with banner content" do
         | 
| 127 | 
            +
                  expect(@content).to match(/\[\-\-third=THREE\]/)
         | 
| 128 | 
            +
                end
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                it "shows default values below descriptions" do
         | 
| 131 | 
            +
                  expect(@content).to match(/# Default: 3/)
         | 
| 132 | 
            +
                end
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                it "shows options in different groups" do
         | 
| 135 | 
            +
                  expect(@content).to match(/Options\:/)
         | 
| 136 | 
            +
                  expect(@content).to match(/Runtime options\:/)
         | 
| 137 | 
            +
                  expect(@content).to match(/\-p, \[\-\-pretend\]/)
         | 
| 138 | 
            +
                end
         | 
| 139 | 
            +
             | 
| 140 | 
            +
                it "use padding in options that do not have aliases" do
         | 
| 141 | 
            +
                  expect(@content).to match(/^  -t, \[--third/)
         | 
| 142 | 
            +
                  expect(@content).to match(/^          \[--fourth/)
         | 
| 143 | 
            +
                end
         | 
| 144 | 
            +
             | 
| 145 | 
            +
                it "allows extra options to be given" do
         | 
| 146 | 
            +
                  hash = {"Foo" => B.class_options.values}
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                  content = capture(:stdout) { MyCounter.send(:class_options_help, Thor::Base.shell.new, hash) }
         | 
| 149 | 
            +
                  expect(content).to match(/Foo options\:/)
         | 
| 150 | 
            +
                  expect(content).to match(/--last-name=LAST_NAME/)
         | 
| 151 | 
            +
                end
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                it "displays choices for enums" do
         | 
| 154 | 
            +
                  content = capture(:stdout) { Enum.help(Thor::Base.shell.new) }
         | 
| 155 | 
            +
                  expect(content).to match(/Possible values\: apple, banana/)
         | 
| 156 | 
            +
                end
         | 
| 157 | 
            +
              end
         | 
| 158 | 
            +
             | 
| 159 | 
            +
              describe "#namespace" do
         | 
| 160 | 
            +
                it "returns the default class namespace" do
         | 
| 161 | 
            +
                  expect(Scripts::MyScript.namespace).to eq("scripts:my_script")
         | 
| 162 | 
            +
                end
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                it "sets a namespace to the class" do
         | 
| 165 | 
            +
                  expect(Scripts::MyDefaults.namespace).to eq("default")
         | 
| 166 | 
            +
                end
         | 
| 167 | 
            +
              end
         | 
| 168 | 
            +
             | 
| 169 | 
            +
              describe "#group" do
         | 
| 170 | 
            +
                it "sets a group" do
         | 
| 171 | 
            +
                  expect(MyScript.group).to eq("script")
         | 
| 172 | 
            +
                end
         | 
| 173 | 
            +
             | 
| 174 | 
            +
                it "inherits the group from parent" do
         | 
| 175 | 
            +
                  expect(MyChildScript.group).to eq("script")
         | 
| 176 | 
            +
                end
         | 
| 177 | 
            +
             | 
| 178 | 
            +
                it "defaults to standard if no group is given" do
         | 
| 179 | 
            +
                  expect(Amazing.group).to eq("standard")
         | 
| 180 | 
            +
                end
         | 
| 181 | 
            +
              end
         | 
| 182 | 
            +
             | 
| 183 | 
            +
              describe "#subclasses" do
         | 
| 184 | 
            +
                it "tracks its subclasses in an Array" do
         | 
| 185 | 
            +
                  expect(Thor::Base.subclasses).to include(MyScript)
         | 
| 186 | 
            +
                  expect(Thor::Base.subclasses).to include(MyChildScript)
         | 
| 187 | 
            +
                  expect(Thor::Base.subclasses).to include(Scripts::MyScript)
         | 
| 188 | 
            +
                end
         | 
| 189 | 
            +
              end
         | 
| 190 | 
            +
             | 
| 191 | 
            +
              describe "#subclass_files" do
         | 
| 192 | 
            +
                it "returns tracked subclasses, grouped by the files they come from" do
         | 
| 193 | 
            +
                  thorfile = File.join(File.dirname(__FILE__), "fixtures", "script.thor")
         | 
| 194 | 
            +
                  expect(Thor::Base.subclass_files[File.expand_path(thorfile)]).to eq([
         | 
| 195 | 
            +
                    MyScript, MyScript::AnotherScript, MyChildScript, Barn,
         | 
| 196 | 
            +
                    PackageNameScript, Scripts::MyScript, Scripts::MyDefaults,
         | 
| 197 | 
            +
                    Scripts::ChildDefault, Scripts::Arities
         | 
| 198 | 
            +
                  ])
         | 
| 199 | 
            +
                end
         | 
| 200 | 
            +
             | 
| 201 | 
            +
                it "tracks a single subclass across multiple files" do
         | 
| 202 | 
            +
                  thorfile = File.join(File.dirname(__FILE__), "fixtures", "command.thor")
         | 
| 203 | 
            +
                  expect(Thor::Base.subclass_files[File.expand_path(thorfile)]).to include(Amazing)
         | 
| 204 | 
            +
                  expect(Thor::Base.subclass_files[File.expand_path(__FILE__)]).to include(Amazing)
         | 
| 205 | 
            +
                end
         | 
| 206 | 
            +
              end
         | 
| 207 | 
            +
             | 
| 208 | 
            +
              describe "#commands" do
         | 
| 209 | 
            +
                it "returns a list with all commands defined in this class" do
         | 
| 210 | 
            +
                  expect(MyChildScript.new).to respond_to("animal")
         | 
| 211 | 
            +
                  expect(MyChildScript.commands.keys).to include("animal")
         | 
| 212 | 
            +
                end
         | 
| 213 | 
            +
             | 
| 214 | 
            +
                it "raises an error if a command with reserved word is defined" do
         | 
| 215 | 
            +
                  expect do
         | 
| 216 | 
            +
                    klass = Class.new(Thor::Group)
         | 
| 217 | 
            +
                    klass.class_eval "def shell; end"
         | 
| 218 | 
            +
                  end.to raise_error(RuntimeError, /"shell" is a Thor reserved word and cannot be defined as command/)
         | 
| 219 | 
            +
                end
         | 
| 220 | 
            +
              end
         | 
| 221 | 
            +
             | 
| 222 | 
            +
              describe "#all_commands" do
         | 
| 223 | 
            +
                it "returns a list with all commands defined in this class plus superclasses" do
         | 
| 224 | 
            +
                  expect(MyChildScript.new).to respond_to("foo")
         | 
| 225 | 
            +
                  expect(MyChildScript.all_commands.keys).to include("foo")
         | 
| 226 | 
            +
                end
         | 
| 227 | 
            +
              end
         | 
| 228 | 
            +
             | 
| 229 | 
            +
              describe "#remove_command" do
         | 
| 230 | 
            +
                it "removes the command from its commands hash" do
         | 
| 231 | 
            +
                  expect(MyChildScript.commands.keys).not_to include("bar")
         | 
| 232 | 
            +
                  expect(MyChildScript.commands.keys).not_to include("boom")
         | 
| 233 | 
            +
                end
         | 
| 234 | 
            +
             | 
| 235 | 
            +
                it "undefines the method if desired" do
         | 
| 236 | 
            +
                  expect(MyChildScript.new).not_to respond_to("boom")
         | 
| 237 | 
            +
                end
         | 
| 238 | 
            +
              end
         | 
| 239 | 
            +
             | 
| 240 | 
            +
              describe "#from_superclass" do
         | 
| 241 | 
            +
                it "does not send a method to the superclass if the superclass does not respond to it" do
         | 
| 242 | 
            +
                  expect(MyCounter.get_from_super).to eq(13)
         | 
| 243 | 
            +
                end
         | 
| 244 | 
            +
              end
         | 
| 245 | 
            +
             | 
| 246 | 
            +
              describe "#start" do
         | 
| 247 | 
            +
                it "raises an error instead of rescuing if THOR_DEBUG=1 is given" do
         | 
| 248 | 
            +
                  begin
         | 
| 249 | 
            +
                    ENV["THOR_DEBUG"] = "1"
         | 
| 250 | 
            +
             | 
| 251 | 
            +
                    expect do
         | 
| 252 | 
            +
                      MyScript.start %w[what --debug]
         | 
| 253 | 
            +
                    end.to raise_error(Thor::UndefinedCommandError, 'Could not find command "what" in "my_script" namespace.')
         | 
| 254 | 
            +
                  ensure
         | 
| 255 | 
            +
                    ENV["THOR_DEBUG"] = nil
         | 
| 256 | 
            +
                  end
         | 
| 257 | 
            +
                end
         | 
| 258 | 
            +
             | 
| 259 | 
            +
                it "raises an error instead of rescuing if :debug option is given" do
         | 
| 260 | 
            +
                  expect do
         | 
| 261 | 
            +
                    MyScript.start %w[what], :debug => true
         | 
| 262 | 
            +
                  end.to raise_error(Thor::UndefinedCommandError, 'Could not find command "what" in "my_script" namespace.')
         | 
| 263 | 
            +
                end
         | 
| 264 | 
            +
             | 
| 265 | 
            +
                it "does not steal args" do
         | 
| 266 | 
            +
                  args = %w[foo bar --force true]
         | 
| 267 | 
            +
                  MyScript.start(args)
         | 
| 268 | 
            +
                  expect(args).to eq(%w[foo bar --force true])
         | 
| 269 | 
            +
                end
         | 
| 270 | 
            +
             | 
| 271 | 
            +
                it "checks unknown options" do
         | 
| 272 | 
            +
                  expect(capture(:stderr) do
         | 
| 273 | 
            +
                    MyScript.start(%w[foo bar --force true --unknown baz])
         | 
| 274 | 
            +
                  end.strip).to eq("Unknown switches '--unknown'")
         | 
| 275 | 
            +
                end
         | 
| 276 | 
            +
             | 
| 277 | 
            +
                it "checks unknown options except specified" do
         | 
| 278 | 
            +
                  expect(capture(:stderr) do
         | 
| 279 | 
            +
                    expect(MyScript.start(%w[with_optional NAME --omg --invalid])).to eq(["NAME", {}, %w[--omg --invalid]])
         | 
| 280 | 
            +
                  end.strip).to be_empty
         | 
| 281 | 
            +
                end
         | 
| 282 | 
            +
              end
         | 
| 283 | 
            +
             | 
| 284 | 
            +
              describe "attr_*" do
         | 
| 285 | 
            +
                it "does not add attr_reader as a command" do
         | 
| 286 | 
            +
                  expect(capture(:stderr) { MyScript.start(%w[another_attribute]) }).to match(/Could not find/)
         | 
| 287 | 
            +
                end
         | 
| 288 | 
            +
             | 
| 289 | 
            +
                it "does not add attr_writer as a command" do
         | 
| 290 | 
            +
                  expect(capture(:stderr) { MyScript.start(%w[another_attribute= foo]) }).to match(/Could not find/)
         | 
| 291 | 
            +
                end
         | 
| 292 | 
            +
             | 
| 293 | 
            +
                it "does not add attr_accessor as a command" do
         | 
| 294 | 
            +
                  expect(capture(:stderr) { MyScript.start(["some_attribute"]) }).to match(/Could not find/)
         | 
| 295 | 
            +
                  expect(capture(:stderr) { MyScript.start(["some_attribute=", "foo"]) }).to match(/Could not find/)
         | 
| 296 | 
            +
                end
         | 
| 297 | 
            +
              end
         | 
| 298 | 
            +
            end
         | 
| @@ -0,0 +1,79 @@ | |
| 1 | 
            +
            require "helper"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Thor::Command do
         | 
| 4 | 
            +
              def command(options = {})
         | 
| 5 | 
            +
                options.each do |key, value|
         | 
| 6 | 
            +
                  options[key] = Thor::Option.parse(key, value)
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                @command ||= Thor::Command.new(:can_has, "I can has cheezburger", "I can has cheezburger\nLots and lots of it", "can_has", options)
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              describe "#formatted_usage" do
         | 
| 13 | 
            +
                it "includes namespace within usage" do
         | 
| 14 | 
            +
                  object = Struct.new(:namespace, :arguments).new("foo", [])
         | 
| 15 | 
            +
                  expect(command(:bar => :required).formatted_usage(object)).to eq("foo:can_has --bar=BAR")
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                it "includes subcommand name within subcommand usage" do
         | 
| 19 | 
            +
                  object = Struct.new(:namespace, :arguments).new("main:foo", [])
         | 
| 20 | 
            +
                  expect(command(:bar => :required).formatted_usage(object, false, true)).to eq("foo can_has --bar=BAR")
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                it "removes default from namespace" do
         | 
| 24 | 
            +
                  object = Struct.new(:namespace, :arguments).new("default:foo", [])
         | 
| 25 | 
            +
                  expect(command(:bar => :required).formatted_usage(object)).to eq(":foo:can_has --bar=BAR")
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                it "injects arguments into usage" do
         | 
| 29 | 
            +
                  options = {:required => true, :type => :string}
         | 
| 30 | 
            +
                  object = Struct.new(:namespace, :arguments).new("foo", [Thor::Argument.new(:bar, options)])
         | 
| 31 | 
            +
                  expect(command(:foo => :required).formatted_usage(object)).to eq("foo:can_has BAR --foo=FOO")
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              describe "#dynamic" do
         | 
| 36 | 
            +
                it "creates a dynamic command with the given name" do
         | 
| 37 | 
            +
                  expect(Thor::DynamicCommand.new("command").name).to eq("command")
         | 
| 38 | 
            +
                  expect(Thor::DynamicCommand.new("command").description).to eq("A dynamically-generated command")
         | 
| 39 | 
            +
                  expect(Thor::DynamicCommand.new("command").usage).to eq("command")
         | 
| 40 | 
            +
                  expect(Thor::DynamicCommand.new("command").options).to eq({})
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                it "does not invoke an existing method" do
         | 
| 44 | 
            +
                  dub = double
         | 
| 45 | 
            +
                  expect(dub.class).to receive(:handle_no_command_error).with("to_s")
         | 
| 46 | 
            +
                  Thor::DynamicCommand.new("to_s").run(dub)
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              describe "#dup" do
         | 
| 51 | 
            +
                it "dup options hash" do
         | 
| 52 | 
            +
                  command = Thor::Command.new("can_has", nil, nil, nil, :foo => true, :bar => :required)
         | 
| 53 | 
            +
                  command.dup.options.delete(:foo)
         | 
| 54 | 
            +
                  expect(command.options[:foo]).to be
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
              describe "#run" do
         | 
| 59 | 
            +
                it "runs a command by calling a method in the given instance" do
         | 
| 60 | 
            +
                  dub = double
         | 
| 61 | 
            +
                  expect(dub).to receive(:can_has).and_return { |*args| args }
         | 
| 62 | 
            +
                  expect(command.run(dub, [1, 2, 3])).to eq([1, 2, 3])
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                it "raises an error if the method to be invoked is private" do
         | 
| 66 | 
            +
                  klass = Class.new do
         | 
| 67 | 
            +
                    def self.handle_no_command_error(name)
         | 
| 68 | 
            +
                      name
         | 
| 69 | 
            +
                    end
         | 
| 70 | 
            +
                    def can_has
         | 
| 71 | 
            +
                      "fail"
         | 
| 72 | 
            +
                    end
         | 
| 73 | 
            +
                    private :can_has
         | 
| 74 | 
            +
                  end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                  expect(command.run(klass.new)).to eq("can_has")
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
              end
         | 
| 79 | 
            +
            end
         | 
| @@ -0,0 +1,48 @@ | |
| 1 | 
            +
            require "helper"
         | 
| 2 | 
            +
            require "thor/core_ext/hash_with_indifferent_access"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe Thor::CoreExt::HashWithIndifferentAccess do
         | 
| 5 | 
            +
              before do
         | 
| 6 | 
            +
                @hash = Thor::CoreExt::HashWithIndifferentAccess.new :foo => "bar", "baz" => "bee", :force => true
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              it "has values accessible by either strings or symbols" do
         | 
| 10 | 
            +
                expect(@hash["foo"]).to eq("bar")
         | 
| 11 | 
            +
                expect(@hash[:foo]).to eq("bar")
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                expect(@hash.values_at(:foo, :baz)).to eq(%w[bar bee])
         | 
| 14 | 
            +
                expect(@hash.delete(:foo)).to eq("bar")
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              it "handles magic boolean predicates" do
         | 
| 18 | 
            +
                expect(@hash.force?).to be true
         | 
| 19 | 
            +
                expect(@hash.foo?).to be true
         | 
| 20 | 
            +
                expect(@hash.nothing?).to be false
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              it "handles magic comparisons" do
         | 
| 24 | 
            +
                expect(@hash.foo?("bar")).to be true
         | 
| 25 | 
            +
                expect(@hash.foo?("bee")).to be false
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              it "maps methods to keys" do
         | 
| 29 | 
            +
                expect(@hash.foo).to eq(@hash["foo"])
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              it "merges keys independent if they are symbols or strings" do
         | 
| 33 | 
            +
                @hash.merge!("force" => false, :baz => "boom")
         | 
| 34 | 
            +
                expect(@hash[:force]).to eq(false)
         | 
| 35 | 
            +
                expect(@hash["baz"]).to eq("boom")
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              it "creates a new hash by merging keys independent if they are symbols or strings" do
         | 
| 39 | 
            +
                other = @hash.merge("force" => false, :baz => "boom")
         | 
| 40 | 
            +
                expect(other[:force]).to eq(false)
         | 
| 41 | 
            +
                expect(other["baz"]).to eq("boom")
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              it "converts to a traditional hash" do
         | 
| 45 | 
            +
                expect(@hash.to_hash.class).to eq(Hash)
         | 
| 46 | 
            +
                expect(@hash).to eq("foo" => "bar", "baz" => "bee", "force" => true)
         | 
| 47 | 
            +
              end
         | 
| 48 | 
            +
            end
         | 
| @@ -0,0 +1,115 @@ | |
| 1 | 
            +
            require "helper"
         | 
| 2 | 
            +
            require "thor/core_ext/ordered_hash"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe Thor::CoreExt::OrderedHash do
         | 
| 5 | 
            +
              before do
         | 
| 6 | 
            +
                @hash = Thor::CoreExt::OrderedHash.new
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              describe "without any items" do
         | 
| 10 | 
            +
                it "returns nil for an undefined key" do
         | 
| 11 | 
            +
                  expect(@hash["foo"]).to be nil
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                it "doesn't iterate through any items" do
         | 
| 15 | 
            +
                  @hash.each { fail }
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                it "has an empty key and values list" do
         | 
| 19 | 
            +
                  expect(@hash.keys).to be_empty
         | 
| 20 | 
            +
                  expect(@hash.values).to be_empty
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                it "must be empty" do
         | 
| 24 | 
            +
                  expect(@hash).to be_empty
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              describe "with several items" do
         | 
| 29 | 
            +
                before do
         | 
| 30 | 
            +
                  @hash[:foo] = "Foo!"
         | 
| 31 | 
            +
                  @hash[:bar] = "Bar!"
         | 
| 32 | 
            +
                  @hash[:baz] = "Baz!"
         | 
| 33 | 
            +
                  @hash[:bop] = "Bop!"
         | 
| 34 | 
            +
                  @hash[:bat] = "Bat!"
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                it "returns nil for an undefined key" do
         | 
| 38 | 
            +
                  expect(@hash[:boom]).to be nil
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                it "returns the value for each key" do
         | 
| 42 | 
            +
                  expect(@hash[:foo]).to eq("Foo!")
         | 
| 43 | 
            +
                  expect(@hash[:bar]).to eq("Bar!")
         | 
| 44 | 
            +
                  expect(@hash[:baz]).to eq("Baz!")
         | 
| 45 | 
            +
                  expect(@hash[:bop]).to eq("Bop!")
         | 
| 46 | 
            +
                  expect(@hash[:bat]).to eq("Bat!")
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                it "iterates through the keys and values in order of assignment" do
         | 
| 50 | 
            +
                  arr = []
         | 
| 51 | 
            +
                  @hash.each do |key, value|
         | 
| 52 | 
            +
                    arr << [key, value]
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
                  expect(arr).to eq([[:foo, "Foo!"], [:bar, "Bar!"], [:baz, "Baz!"],
         | 
| 55 | 
            +
                                     [:bop, "Bop!"], [:bat, "Bat!"]])
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                it "returns the keys in order of insertion" do
         | 
| 59 | 
            +
                  expect(@hash.keys).to eq([:foo, :bar, :baz, :bop, :bat])
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                it "returns the values in order of insertion" do
         | 
| 63 | 
            +
                  expect(@hash.values).to eq(["Foo!", "Bar!", "Baz!", "Bop!", "Bat!"])
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                it "does not move an overwritten node to the end of the ordering" do
         | 
| 67 | 
            +
                  @hash[:baz] = "Bip!"
         | 
| 68 | 
            +
                  expect(@hash.values).to eq(["Foo!", "Bar!", "Bip!", "Bop!", "Bat!"])
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  @hash[:foo] = "Bip!"
         | 
| 71 | 
            +
                  expect(@hash.values).to eq(["Bip!", "Bar!", "Bip!", "Bop!", "Bat!"])
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                  @hash[:bat] = "Bip!"
         | 
| 74 | 
            +
                  expect(@hash.values).to eq(["Bip!", "Bar!", "Bip!", "Bop!", "Bip!"])
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                it "appends another ordered hash while preserving ordering" do
         | 
| 78 | 
            +
                  other_hash = Thor::CoreExt::OrderedHash.new
         | 
| 79 | 
            +
                  other_hash[1] = "one"
         | 
| 80 | 
            +
                  other_hash[2] = "two"
         | 
| 81 | 
            +
                  other_hash[3] = "three"
         | 
| 82 | 
            +
                  expect(@hash.merge(other_hash).values).to eq(["Foo!", "Bar!", "Baz!", "Bop!", "Bat!", "one", "two", "three"])
         | 
| 83 | 
            +
                end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                it "overwrites hash keys with matching appended keys" do
         | 
| 86 | 
            +
                  other_hash = Thor::CoreExt::OrderedHash.new
         | 
| 87 | 
            +
                  other_hash[:bar] = "bar"
         | 
| 88 | 
            +
                  expect(@hash.merge(other_hash)[:bar]).to eq("bar")
         | 
| 89 | 
            +
                  expect(@hash[:bar]).to eq("Bar!")
         | 
| 90 | 
            +
                end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                it "converts to an array" do
         | 
| 93 | 
            +
                  expect(@hash.to_a).to eq([[:foo, "Foo!"], [:bar, "Bar!"], [:baz, "Baz!"], [:bop, "Bop!"], [:bat, "Bat!"]])
         | 
| 94 | 
            +
                end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                it "must not be empty" do
         | 
| 97 | 
            +
                  expect(@hash).not_to be_empty
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                it "deletes values from hash" do
         | 
| 101 | 
            +
                  expect(@hash.delete(:baz)).to eq("Baz!")
         | 
| 102 | 
            +
                  expect(@hash.values).to eq(["Foo!", "Bar!", "Bop!", "Bat!"])
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                  expect(@hash.delete(:foo)).to eq("Foo!")
         | 
| 105 | 
            +
                  expect(@hash.values).to eq(["Bar!", "Bop!", "Bat!"])
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                  expect(@hash.delete(:bat)).to eq("Bat!")
         | 
| 108 | 
            +
                  expect(@hash.values).to eq(["Bar!", "Bop!"])
         | 
| 109 | 
            +
                end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                it "returns nil if the value to be deleted can't be found" do
         | 
| 112 | 
            +
                  expect(@hash.delete(:nothing)).to be nil
         | 
| 113 | 
            +
                end
         | 
| 114 | 
            +
              end
         | 
| 115 | 
            +
            end
         |