thor 0.19.1 → 0.19.2
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 +24 -0
- data/CONTRIBUTING.md +15 -0
- data/README.md +7 -1
- data/lib/thor.rb +31 -23
- data/lib/thor/actions.rb +21 -22
- data/lib/thor/actions/create_file.rb +1 -1
- data/lib/thor/actions/create_link.rb +1 -1
- data/lib/thor/actions/directory.rb +2 -2
- data/lib/thor/actions/empty_directory.rb +8 -8
- data/lib/thor/actions/file_manipulation.rb +23 -12
- data/lib/thor/actions/inject_into_file.rb +10 -14
- data/lib/thor/base.rb +33 -33
- data/lib/thor/command.rb +9 -9
- data/lib/thor/core_ext/hash_with_indifferent_access.rb +9 -1
- data/lib/thor/core_ext/io_binary_read.rb +7 -5
- data/lib/thor/core_ext/ordered_hash.rb +94 -63
- data/lib/thor/error.rb +3 -3
- data/lib/thor/group.rb +12 -12
- data/lib/thor/invocation.rb +4 -5
- data/lib/thor/parser/argument.rb +4 -7
- data/lib/thor/parser/arguments.rb +16 -16
- data/lib/thor/parser/option.rb +39 -19
- data/lib/thor/parser/options.rb +7 -5
- data/lib/thor/runner.rb +25 -25
- data/lib/thor/shell.rb +1 -1
- data/lib/thor/shell/basic.rb +41 -26
- data/lib/thor/shell/color.rb +1 -1
- data/lib/thor/shell/html.rb +4 -4
- data/lib/thor/util.rb +8 -7
- data/lib/thor/version.rb +1 -1
- data/thor.gemspec +6 -9
- metadata +6 -148
- data/Thorfile +0 -29
- data/spec/actions/create_file_spec.rb +0 -168
- data/spec/actions/create_link_spec.rb +0 -96
- data/spec/actions/directory_spec.rb +0 -169
- data/spec/actions/empty_directory_spec.rb +0 -129
- data/spec/actions/file_manipulation_spec.rb +0 -392
- data/spec/actions/inject_into_file_spec.rb +0 -135
- data/spec/actions_spec.rb +0 -331
- data/spec/base_spec.rb +0 -298
- data/spec/command_spec.rb +0 -79
- data/spec/core_ext/hash_with_indifferent_access_spec.rb +0 -48
- data/spec/core_ext/ordered_hash_spec.rb +0 -115
- data/spec/exit_condition_spec.rb +0 -19
- data/spec/fixtures/application.rb +0 -2
- data/spec/fixtures/app{1}/README +0 -3
- data/spec/fixtures/bundle/execute.rb +0 -6
- data/spec/fixtures/bundle/main.thor +0 -1
- data/spec/fixtures/command.thor +0 -10
- data/spec/fixtures/doc/%file_name%.rb.tt +0 -1
- data/spec/fixtures/doc/COMMENTER +0 -11
- data/spec/fixtures/doc/README +0 -3
- data/spec/fixtures/doc/block_helper.rb +0 -3
- data/spec/fixtures/doc/config.rb +0 -1
- data/spec/fixtures/doc/config.yaml.tt +0 -1
- data/spec/fixtures/doc/excluding/%file_name%.rb.tt +0 -1
- data/spec/fixtures/enum.thor +0 -10
- data/spec/fixtures/group.thor +0 -128
- data/spec/fixtures/invoke.thor +0 -131
- data/spec/fixtures/path with spaces b/data/spec/fixtures/path with → spaces +0 -0
- data/spec/fixtures/preserve/script.sh +0 -3
- data/spec/fixtures/script.thor +0 -220
- data/spec/fixtures/subcommand.thor +0 -17
- data/spec/group_spec.rb +0 -222
- data/spec/helper.rb +0 -80
- data/spec/invocation_spec.rb +0 -120
- data/spec/line_editor/basic_spec.rb +0 -28
- data/spec/line_editor/readline_spec.rb +0 -69
- data/spec/line_editor_spec.rb +0 -43
- data/spec/parser/argument_spec.rb +0 -53
- data/spec/parser/arguments_spec.rb +0 -66
- data/spec/parser/option_spec.rb +0 -210
- data/spec/parser/options_spec.rb +0 -414
- data/spec/quality_spec.rb +0 -75
- data/spec/rake_compat_spec.rb +0 -72
- data/spec/register_spec.rb +0 -227
- data/spec/runner_spec.rb +0 -246
- data/spec/sandbox/application.rb +0 -2
- data/spec/sandbox/app{1}/README +0 -3
- data/spec/sandbox/bundle/execute.rb +0 -6
- data/spec/sandbox/bundle/main.thor +0 -1
- data/spec/sandbox/command.thor +0 -10
- data/spec/sandbox/doc/%file_name%.rb.tt +0 -1
- data/spec/sandbox/doc/COMMENTER +0 -11
- data/spec/sandbox/doc/README +0 -3
- data/spec/sandbox/doc/block_helper.rb +0 -3
- data/spec/sandbox/doc/config.rb +0 -1
- data/spec/sandbox/doc/config.yaml.tt +0 -1
- data/spec/sandbox/doc/excluding/%file_name%.rb.tt +0 -1
- data/spec/sandbox/enum.thor +0 -10
- data/spec/sandbox/group.thor +0 -128
- data/spec/sandbox/invoke.thor +0 -131
- data/spec/sandbox/path with spaces b/data/spec/sandbox/path with → spaces +0 -0
- data/spec/sandbox/preserve/script.sh +0 -3
- data/spec/sandbox/script.thor +0 -220
- data/spec/sandbox/subcommand.thor +0 -17
- data/spec/shell/basic_spec.rb +0 -337
- data/spec/shell/color_spec.rb +0 -119
- data/spec/shell/html_spec.rb +0 -31
- data/spec/shell_spec.rb +0 -47
- data/spec/subcommand_spec.rb +0 -48
- data/spec/thor_spec.rb +0 -505
- data/spec/util_spec.rb +0 -196
data/spec/base_spec.rb
DELETED
@@ -1,298 +0,0 @@
|
|
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
|
data/spec/command_spec.rb
DELETED
@@ -1,79 +0,0 @@
|
|
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
|
@@ -1,48 +0,0 @@
|
|
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
|
@@ -1,115 +0,0 @@
|
|
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
|