wijet-thor 0.14.6

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.
Files changed (75) hide show
  1. data/CHANGELOG.rdoc +103 -0
  2. data/LICENSE +20 -0
  3. data/README.md +307 -0
  4. data/Thorfile +24 -0
  5. data/bin/rake2thor +86 -0
  6. data/bin/thor +6 -0
  7. data/lib/thor.rb +334 -0
  8. data/lib/thor/actions.rb +314 -0
  9. data/lib/thor/actions/create_file.rb +105 -0
  10. data/lib/thor/actions/create_link.rb +57 -0
  11. data/lib/thor/actions/directory.rb +93 -0
  12. data/lib/thor/actions/empty_directory.rb +134 -0
  13. data/lib/thor/actions/file_manipulation.rb +270 -0
  14. data/lib/thor/actions/inject_into_file.rb +109 -0
  15. data/lib/thor/base.rb +579 -0
  16. data/lib/thor/core_ext/file_binary_read.rb +9 -0
  17. data/lib/thor/core_ext/hash_with_indifferent_access.rb +75 -0
  18. data/lib/thor/core_ext/ordered_hash.rb +100 -0
  19. data/lib/thor/error.rb +30 -0
  20. data/lib/thor/group.rb +273 -0
  21. data/lib/thor/invocation.rb +168 -0
  22. data/lib/thor/parser.rb +4 -0
  23. data/lib/thor/parser/argument.rb +67 -0
  24. data/lib/thor/parser/arguments.rb +161 -0
  25. data/lib/thor/parser/option.rb +120 -0
  26. data/lib/thor/parser/options.rb +173 -0
  27. data/lib/thor/rake_compat.rb +66 -0
  28. data/lib/thor/runner.rb +309 -0
  29. data/lib/thor/shell.rb +88 -0
  30. data/lib/thor/shell/basic.rb +290 -0
  31. data/lib/thor/shell/color.rb +108 -0
  32. data/lib/thor/shell/html.rb +121 -0
  33. data/lib/thor/task.rb +114 -0
  34. data/lib/thor/util.rb +229 -0
  35. data/lib/thor/version.rb +3 -0
  36. data/spec/actions/create_file_spec.rb +170 -0
  37. data/spec/actions/directory_spec.rb +136 -0
  38. data/spec/actions/empty_directory_spec.rb +98 -0
  39. data/spec/actions/file_manipulation_spec.rb +310 -0
  40. data/spec/actions/inject_into_file_spec.rb +135 -0
  41. data/spec/actions_spec.rb +322 -0
  42. data/spec/base_spec.rb +269 -0
  43. data/spec/core_ext/hash_with_indifferent_access_spec.rb +43 -0
  44. data/spec/core_ext/ordered_hash_spec.rb +115 -0
  45. data/spec/fixtures/application.rb +2 -0
  46. data/spec/fixtures/bundle/execute.rb +6 -0
  47. data/spec/fixtures/bundle/main.thor +1 -0
  48. data/spec/fixtures/doc/%file_name%.rb.tt +1 -0
  49. data/spec/fixtures/doc/README +3 -0
  50. data/spec/fixtures/doc/block_helper.rb +3 -0
  51. data/spec/fixtures/doc/components/.empty_directory +0 -0
  52. data/spec/fixtures/doc/config.rb +1 -0
  53. data/spec/fixtures/group.thor +114 -0
  54. data/spec/fixtures/invoke.thor +112 -0
  55. data/spec/fixtures/path with spaces b/data/spec/fixtures/path with → spaces +0 -0
  56. data/spec/fixtures/script.thor +184 -0
  57. data/spec/fixtures/task.thor +10 -0
  58. data/spec/group_spec.rb +178 -0
  59. data/spec/invocation_spec.rb +100 -0
  60. data/spec/parser/argument_spec.rb +47 -0
  61. data/spec/parser/arguments_spec.rb +64 -0
  62. data/spec/parser/option_spec.rb +202 -0
  63. data/spec/parser/options_spec.rb +319 -0
  64. data/spec/rake_compat_spec.rb +68 -0
  65. data/spec/register_spec.rb +104 -0
  66. data/spec/runner_spec.rb +210 -0
  67. data/spec/shell/basic_spec.rb +223 -0
  68. data/spec/shell/color_spec.rb +41 -0
  69. data/spec/shell/html_spec.rb +27 -0
  70. data/spec/shell_spec.rb +47 -0
  71. data/spec/spec_helper.rb +54 -0
  72. data/spec/task_spec.rb +74 -0
  73. data/spec/thor_spec.rb +334 -0
  74. data/spec/util_spec.rb +163 -0
  75. metadata +193 -0
@@ -0,0 +1,100 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'thor/base'
3
+
4
+ describe Thor::Invocation do
5
+ describe "#invoke" do
6
+ it "invokes a task inside another task" do
7
+ capture(:stdout){ A.new.invoke(:two) }.should == "2\n3\n"
8
+ end
9
+
10
+ it "invokes a task just once" do
11
+ capture(:stdout){ A.new.invoke(:one) }.should == "1\n2\n3\n"
12
+ end
13
+
14
+ it "invokes a task just once even if they belongs to different classes" do
15
+ capture(:stdout){ Defined.new.invoke(:one) }.should == "1\n2\n3\n4\n5\n"
16
+ end
17
+
18
+ it "invokes a task with arguments" do
19
+ A.new.invoke(:five, [5]).should be_true
20
+ A.new.invoke(:five, [7]).should be_false
21
+ end
22
+
23
+ it "invokes the default task if none is given to a Thor class" do
24
+ content = capture(:stdout){ A.new.invoke("b") }
25
+ content.should =~ /Tasks/
26
+ content.should =~ /LAST_NAME/
27
+ end
28
+
29
+ it "accepts a class as argument without a task to invoke" do
30
+ content = capture(:stdout){ A.new.invoke(B) }
31
+ content.should =~ /Tasks/
32
+ content.should =~ /LAST_NAME/
33
+ end
34
+
35
+ it "accepts a class as argument with a task to invoke" do
36
+ base = A.new([], :last_name => "Valim")
37
+ base.invoke(B, :one, ["Jose"]).should == "Valim, Jose"
38
+ end
39
+
40
+ it "allows customized options to be given" do
41
+ base = A.new([], :last_name => "Wrong")
42
+ base.invoke(B, :one, ["Jose"], :last_name => "Valim").should == "Valim, Jose"
43
+ end
44
+
45
+ it "reparses options in the new class" do
46
+ A.start(["invoker", "--last-name", "Valim"]).should == "Valim, Jose"
47
+ end
48
+
49
+ it "shares initialize options with invoked class" do
50
+ A.new([], :foo => :bar).invoke("b:two").should == { "foo" => :bar }
51
+ end
52
+
53
+ it "dump configuration values to be used in the invoked class" do
54
+ base = A.new
55
+ base.invoke("b:three").shell.should == base.shell
56
+ end
57
+
58
+ it "allow extra configuration values to be given" do
59
+ base, shell = A.new, Thor::Base.shell.new
60
+ base.invoke("b:three", [], {}, :shell => shell).shell.should == shell
61
+ end
62
+
63
+ it "invokes a Thor::Group and all of its tasks" do
64
+ capture(:stdout){ A.new.invoke(:c) }.should == "1\n2\n3\n"
65
+ end
66
+
67
+ it "does not invoke a Thor::Group twice" do
68
+ base = A.new
69
+ silence(:stdout){ base.invoke(:c) }
70
+ capture(:stdout){ base.invoke(:c) }.should be_empty
71
+ end
72
+
73
+ it "does not invoke any of Thor::Group tasks twice" do
74
+ base = A.new
75
+ silence(:stdout){ base.invoke(:c) }
76
+ capture(:stdout){ base.invoke("c:one") }.should be_empty
77
+ end
78
+
79
+ it "raises Thor::UndefinedTaskError if the task can't be found" do
80
+ lambda do
81
+ A.new.invoke("foo:bar")
82
+ end.should raise_error(Thor::UndefinedTaskError)
83
+ end
84
+
85
+ it "raises Thor::UndefinedTaskError if the task can't be found even if all tasks where already executed" do
86
+ base = C.new
87
+ silence(:stdout){ base.invoke_all }
88
+
89
+ lambda do
90
+ base.invoke("foo:bar")
91
+ end.should raise_error(Thor::UndefinedTaskError)
92
+ end
93
+
94
+ it "raises an error if a non Thor class is given" do
95
+ lambda do
96
+ A.new.invoke(Object)
97
+ end.should raise_error(RuntimeError, "Expected Thor class, got Object")
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,47 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'thor/parser'
3
+
4
+ describe Thor::Argument do
5
+
6
+ def argument(name, type=:string, default=nil, required=nil)
7
+ @argument ||= Thor::Argument.new(name, nil, required || default.nil?, type, default)
8
+ end
9
+
10
+ describe "errors" do
11
+ it "raises an error if name is not supplied" do
12
+ lambda {
13
+ argument(nil)
14
+ }.should raise_error(ArgumentError, "Argument name can't be nil.")
15
+ end
16
+
17
+ it "raises an error if type is unknown" do
18
+ lambda {
19
+ argument(:task, :unknown)
20
+ }.should raise_error(ArgumentError, "Type :unknown is not valid for arguments.")
21
+ end
22
+
23
+ it "raises an error if argument is required and have default values" do
24
+ lambda {
25
+ argument(:task, :string, "bar", true)
26
+ }.should raise_error(ArgumentError, "An argument cannot be required and have default value.")
27
+ end
28
+ end
29
+
30
+ describe "#usage" do
31
+ it "returns usage for string types" do
32
+ argument(:foo, :string).usage.should == "FOO"
33
+ end
34
+
35
+ it "returns usage for numeric types" do
36
+ argument(:foo, :numeric).usage.should == "N"
37
+ end
38
+
39
+ it "returns usage for array types" do
40
+ argument(:foo, :array).usage.should == "one two three"
41
+ end
42
+
43
+ it "returns usage for hash types" do
44
+ argument(:foo, :hash).usage.should == "key:value"
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,64 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'thor/parser'
3
+
4
+ describe Thor::Arguments do
5
+ def create(opts={})
6
+ arguments = opts.map do |type, default|
7
+ Thor::Argument.new(type.to_s, nil, default.nil?, type, default)
8
+ end
9
+
10
+ arguments.sort!{ |a,b| b.name <=> a.name }
11
+ @opt = Thor::Arguments.new(arguments)
12
+ end
13
+
14
+ def parse(*args)
15
+ @opt.parse(args)
16
+ end
17
+
18
+ describe "#parse" do
19
+ it "parses arguments in the given order" do
20
+ create :string => nil, :numeric => nil
21
+ parse("name", "13")["string"].should == "name"
22
+ parse("name", "13")["numeric"].should == 13
23
+ end
24
+
25
+ it "accepts hashes" do
26
+ create :string => nil, :hash => nil
27
+ parse("product", "title:string", "age:integer")["string"].should == "product"
28
+ parse("product", "title:string", "age:integer")["hash"].should == { "title" => "string", "age" => "integer"}
29
+ end
30
+
31
+ it "accepts arrays" do
32
+ create :string => nil, :array => nil
33
+ parse("product", "title", "age")["string"].should == "product"
34
+ parse("product", "title", "age")["array"].should == %w(title age)
35
+ end
36
+
37
+ describe "with no inputs" do
38
+ it "and no arguments returns an empty hash" do
39
+ create
40
+ parse.should == {}
41
+ end
42
+
43
+ it "and required arguments raises an error" do
44
+ create :string => nil, :numeric => nil
45
+ lambda { parse }.should raise_error(Thor::RequiredArgumentMissingError, "No value provided for required arguments 'string', 'numeric'")
46
+ end
47
+
48
+ it "and default arguments returns default values" do
49
+ create :string => "name", :numeric => 13
50
+ parse.should == { "string" => "name", "numeric" => 13 }
51
+ end
52
+ end
53
+
54
+ it "returns the input if it's already parsed" do
55
+ create :string => nil, :hash => nil, :array => nil, :numeric => nil
56
+ parse("", 0, {}, []).should == { "string" => "", "numeric" => 0, "hash" => {}, "array" => [] }
57
+ end
58
+
59
+ it "returns the default value if none is provided" do
60
+ create :string => "foo", :numeric => 3.0
61
+ parse("bar").should == { "string" => "bar", "numeric" => 3.0 }
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,202 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'thor/parser'
3
+
4
+ describe Thor::Option do
5
+ def parse(key, value)
6
+ Thor::Option.parse(key, value)
7
+ end
8
+
9
+ def option(name, *args)
10
+ @option ||= Thor::Option.new(name, *args)
11
+ end
12
+
13
+ describe "#parse" do
14
+
15
+ describe "with value as a symbol" do
16
+ describe "and symbol is a valid type" do
17
+ it "has type equals to the symbol" do
18
+ parse(:foo, :string).type.should == :string
19
+ parse(:foo, :numeric).type.should == :numeric
20
+ end
21
+
22
+ it "has not default value" do
23
+ parse(:foo, :string).default.should be_nil
24
+ parse(:foo, :numeric).default.should be_nil
25
+ end
26
+ end
27
+
28
+ describe "equals to :required" do
29
+ it "has type equals to :string" do
30
+ parse(:foo, :required).type.should == :string
31
+ end
32
+
33
+ it "has no default value" do
34
+ parse(:foo, :required).default.should be_nil
35
+ end
36
+ end
37
+
38
+ describe "and symbol is not a reserved key" do
39
+ it "has type equals to :string" do
40
+ parse(:foo, :bar).type.should == :string
41
+ end
42
+
43
+ it "has no default value" do
44
+ parse(:foo, :bar).default.should be_nil
45
+ end
46
+ end
47
+ end
48
+
49
+ describe "with value as hash" do
50
+ it "has default type :hash" do
51
+ parse(:foo, :a => :b).type.should == :hash
52
+ end
53
+
54
+ it "has default value equals to the hash" do
55
+ parse(:foo, :a => :b).default.should == { :a => :b }
56
+ end
57
+ end
58
+
59
+ describe "with value as array" do
60
+ it "has default type :array" do
61
+ parse(:foo, [:a, :b]).type.should == :array
62
+ end
63
+
64
+ it "has default value equals to the array" do
65
+ parse(:foo, [:a, :b]).default.should == [:a, :b]
66
+ end
67
+ end
68
+
69
+ describe "with value as string" do
70
+ it "has default type :string" do
71
+ parse(:foo, "bar").type.should == :string
72
+ end
73
+
74
+ it "has default value equals to the string" do
75
+ parse(:foo, "bar").default.should == "bar"
76
+ end
77
+ end
78
+
79
+ describe "with value as numeric" do
80
+ it "has default type :numeric" do
81
+ parse(:foo, 2.0).type.should == :numeric
82
+ end
83
+
84
+ it "has default value equals to the numeric" do
85
+ parse(:foo, 2.0).default.should == 2.0
86
+ end
87
+ end
88
+
89
+ describe "with value as boolean" do
90
+ it "has default type :boolean" do
91
+ parse(:foo, true).type.should == :boolean
92
+ parse(:foo, false).type.should == :boolean
93
+ end
94
+
95
+ it "has default value equals to the boolean" do
96
+ parse(:foo, true).default.should == true
97
+ parse(:foo, false).default.should == false
98
+ end
99
+ end
100
+
101
+ describe "with key as a symbol" do
102
+ it "sets the name equals to the key" do
103
+ parse(:foo, true).name.should == "foo"
104
+ end
105
+ end
106
+
107
+ describe "with key as an array" do
108
+ it "sets the first items in the array to the name" do
109
+ parse([:foo, :bar, :baz], true).name.should == "foo"
110
+ end
111
+
112
+ it "sets all other items as aliases" do
113
+ parse([:foo, :bar, :baz], true).aliases.should == [:bar, :baz]
114
+ end
115
+ end
116
+ end
117
+
118
+ it "returns the switch name" do
119
+ option("foo").switch_name.should == "--foo"
120
+ option("--foo").switch_name.should == "--foo"
121
+ end
122
+
123
+ it "returns the human name" do
124
+ option("foo").human_name.should == "foo"
125
+ option("--foo").human_name.should == "foo"
126
+ end
127
+
128
+ it "converts underscores to dashes" do
129
+ option("foo_bar").switch_name.should == "--foo-bar"
130
+ end
131
+
132
+ it "can be required and have default values" do
133
+ option = option("foo", nil, true, :string, "bar")
134
+ option.default.should == "bar"
135
+ option.should be_required
136
+ end
137
+
138
+ it "cannot be required and have type boolean" do
139
+ lambda {
140
+ option("foo", nil, true, :boolean)
141
+ }.should raise_error(ArgumentError, "An option cannot be boolean and required.")
142
+ end
143
+
144
+ it "allows type predicates" do
145
+ parse(:foo, :string).should be_string
146
+ parse(:foo, :boolean).should be_boolean
147
+ parse(:foo, :numeric).should be_numeric
148
+ end
149
+
150
+ it "raises an error on method missing" do
151
+ lambda {
152
+ parse(:foo, :string).unknown?
153
+ }.should raise_error(NoMethodError)
154
+ end
155
+
156
+ describe "#usage" do
157
+
158
+ it "returns usage for string types" do
159
+ parse(:foo, :string).usage.should == "[--foo=FOO]"
160
+ end
161
+
162
+ it "returns usage for numeric types" do
163
+ parse(:foo, :numeric).usage.should == "[--foo=N]"
164
+ end
165
+
166
+ it "returns usage for array types" do
167
+ parse(:foo, :array).usage.should == "[--foo=one two three]"
168
+ end
169
+
170
+ it "returns usage for hash types" do
171
+ parse(:foo, :hash).usage.should == "[--foo=key:value]"
172
+ end
173
+
174
+ it "returns usage for boolean types" do
175
+ parse(:foo, :boolean).usage.should == "[--foo]"
176
+ end
177
+
178
+ it "uses padding when no aliases is given" do
179
+ parse(:foo, :boolean).usage(4).should == " [--foo]"
180
+ end
181
+
182
+ it "uses banner when supplied" do
183
+ option(:foo, nil, false, :string, nil, "BAR").usage.should == "[--foo=BAR]"
184
+ end
185
+
186
+ it "checkes when banner is an empty string" do
187
+ option(:foo, nil, false, :string, nil, "").usage.should == "[--foo]"
188
+ end
189
+
190
+ describe "with required values" do
191
+ it "does not show the usage between brackets" do
192
+ parse(:foo, :required).usage.should == "--foo=FOO"
193
+ end
194
+ end
195
+
196
+ describe "with aliases" do
197
+ it "does not show the usage between brackets" do
198
+ parse([:foo, "-f", "-b"], :required).usage.should == "-f, -b, --foo=FOO"
199
+ end
200
+ end
201
+ end
202
+ end
@@ -0,0 +1,319 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'thor/parser'
3
+
4
+ describe Thor::Options do
5
+ def create(opts, defaults={})
6
+ opts.each do |key, value|
7
+ opts[key] = Thor::Option.parse(key, value) unless value.is_a?(Thor::Option)
8
+ end
9
+
10
+ @opt = Thor::Options.new(opts, defaults)
11
+ end
12
+
13
+ def parse(*args)
14
+ @opt.parse(args.flatten)
15
+ end
16
+
17
+ def check_unknown!
18
+ @opt.check_unknown!
19
+ end
20
+
21
+ describe "#to_switches" do
22
+ it "turns true values into a flag" do
23
+ Thor::Options.to_switches(:color => true).should == "--color"
24
+ end
25
+
26
+ it "ignores nil" do
27
+ Thor::Options.to_switches(:color => nil).should == ""
28
+ end
29
+
30
+ it "ignores false" do
31
+ Thor::Options.to_switches(:color => false).should == ""
32
+ end
33
+
34
+ it "writes --name value for anything else" do
35
+ Thor::Options.to_switches(:format => "specdoc").should == '--format "specdoc"'
36
+ end
37
+
38
+ it "joins several values" do
39
+ switches = Thor::Options.to_switches(:color => true, :foo => "bar").split(' ').sort
40
+ switches.should == ['"bar"', "--color", "--foo"]
41
+ end
42
+
43
+ it "accepts arrays" do
44
+ Thor::Options.to_switches(:count => [1,2,3]).should == "--count 1 2 3"
45
+ end
46
+
47
+ it "accepts hashes" do
48
+ Thor::Options.to_switches(:count => {:a => :b}).should == "--count a:b"
49
+ end
50
+
51
+ it "accepts underscored options" do
52
+ Thor::Options.to_switches(:under_score_option => "foo bar").should == '--under_score_option "foo bar"'
53
+ end
54
+
55
+ end
56
+
57
+ describe "#parse" do
58
+ it "allows multiple aliases for a given switch" do
59
+ create ["--foo", "--bar", "--baz"] => :string
60
+ parse("--foo", "12")["foo"].should == "12"
61
+ parse("--bar", "12")["foo"].should == "12"
62
+ parse("--baz", "12")["foo"].should == "12"
63
+ end
64
+
65
+ it "allows custom short names" do
66
+ create "-f" => :string
67
+ parse("-f", "12").should == {"f" => "12"}
68
+ end
69
+
70
+ it "allows custom short-name aliases" do
71
+ create ["--bar", "-f"] => :string
72
+ parse("-f", "12").should == {"bar" => "12"}
73
+ end
74
+
75
+ it "accepts conjoined short switches" do
76
+ create ["--foo", "-f"] => true, ["--bar", "-b"] => true, ["--app", "-a"] => true
77
+ opts = parse("-fba")
78
+ opts["foo"].should be_true
79
+ opts["bar"].should be_true
80
+ opts["app"].should be_true
81
+ end
82
+
83
+ it "accepts conjoined short switches with input" do
84
+ create ["--foo", "-f"] => true, ["--bar", "-b"] => true, ["--app", "-a"] => :required
85
+ opts = parse "-fba", "12"
86
+ opts["foo"].should be_true
87
+ opts["bar"].should be_true
88
+ opts["app"].should == "12"
89
+ end
90
+
91
+ it "returns the default value if none is provided" do
92
+ create :foo => "baz", :bar => :required
93
+ parse("--bar", "boom")["foo"].should == "baz"
94
+ end
95
+
96
+ it "returns the default value from defaults hash to required arguments" do
97
+ create Hash[:bar => :required], Hash[:bar => "baz"]
98
+ parse["bar"].should == "baz"
99
+ end
100
+
101
+ it "gives higher priority to defaults given in the hash" do
102
+ create Hash[:bar => true], Hash[:bar => false]
103
+ parse["bar"].should == false
104
+ end
105
+
106
+ it "raises an error for unknown switches" do
107
+ create :foo => "baz", :bar => :required
108
+ parse("--bar", "baz", "--baz", "unknown")
109
+ lambda { check_unknown! }.should raise_error(Thor::UnknownArgumentError, "Unknown switches '--baz'")
110
+ end
111
+
112
+ it "skips leading non-switches" do
113
+ create(:foo => "baz")
114
+
115
+ parse("asdf", "--foo", "bar").should == {"foo" => "bar"}
116
+ end
117
+
118
+ it "correctly recognizes things that look kind of like options, but aren't, as not options" do
119
+ create(:foo => "baz")
120
+ parse("--asdf---asdf", "baz", "--foo", "--asdf---dsf--asdf").should == {"foo" => "--asdf---dsf--asdf"}
121
+ check_unknown!
122
+ end
123
+
124
+ it "excepts underscores in commandline args hash for boolean" do
125
+ create :foo_bar => :boolean
126
+ parse("--foo_bar")["foo_bar"].should == true
127
+ parse("--no_foo_bar")["foo_bar"].should == false
128
+ end
129
+
130
+ it "excepts underscores in commandline args hash for strings" do
131
+ create :foo_bar => :string, :baz_foo => :string
132
+ parse("--foo_bar", "baz")["foo_bar"].should == "baz"
133
+ parse("--baz_foo", "foo bar")["baz_foo"].should == "foo bar"
134
+ end
135
+
136
+ describe "with no input" do
137
+ it "and no switches returns an empty hash" do
138
+ create({})
139
+ parse.should == {}
140
+ end
141
+
142
+ it "and several switches returns an empty hash" do
143
+ create "--foo" => :boolean, "--bar" => :string
144
+ parse.should == {}
145
+ end
146
+
147
+ it "and a required switch raises an error" do
148
+ create "--foo" => :required
149
+ lambda { parse }.should raise_error(Thor::RequiredArgumentMissingError, "No value provided for required options '--foo'")
150
+ end
151
+ end
152
+
153
+ describe "with one required and one optional switch" do
154
+ before :each do
155
+ create "--foo" => :required, "--bar" => :boolean
156
+ end
157
+
158
+ it "raises an error if the required switch has no argument" do
159
+ lambda { parse("--foo") }.should raise_error(Thor::MalformattedArgumentError)
160
+ end
161
+
162
+ it "raises an error if the required switch isn't given" do
163
+ lambda { parse("--bar") }.should raise_error(Thor::RequiredArgumentMissingError)
164
+ end
165
+
166
+ it "raises an error if the required switch is set to nil" do
167
+ lambda { parse("--no-foo") }.should raise_error(Thor::RequiredArgumentMissingError)
168
+ end
169
+
170
+ it "does not raises an error if the required option has a default value" do
171
+ create :foo => Thor::Option.new("foo", nil, true, :string, "baz"), :bar => :boolean
172
+ lambda { parse("--bar") }.should_not raise_error
173
+ end
174
+ end
175
+
176
+ describe "with :string type" do
177
+ before(:each) do
178
+ create ["--foo", "-f"] => :required
179
+ end
180
+
181
+ it "accepts a switch <value> assignment" do
182
+ parse("--foo", "12")["foo"].should == "12"
183
+ end
184
+
185
+ it "accepts a switch=<value> assignment" do
186
+ parse("-f=12")["foo"].should == "12"
187
+ parse("--foo=12")["foo"].should == "12"
188
+ parse("--foo=bar=baz")["foo"].should == "bar=baz"
189
+ end
190
+
191
+ it "must accept underscores switch=value assignment" do
192
+ create :foo_bar => :required
193
+ parse("--foo_bar=http://example.com/under_score/")["foo_bar"].should == "http://example.com/under_score/"
194
+ end
195
+
196
+ it "accepts a --no-switch format" do
197
+ create "--foo" => "bar"
198
+ parse("--no-foo")["foo"].should be_nil
199
+ end
200
+
201
+ it "does not consume an argument for --no-switch format" do
202
+ create "--cheese" => :string
203
+ parse('burger', '--no-cheese', 'fries')["cheese"].should be_nil
204
+ end
205
+
206
+ it "accepts a --switch format on non required types" do
207
+ create "--foo" => :string
208
+ parse("--foo")["foo"].should == "foo"
209
+ end
210
+
211
+ it "accepts a --switch format on non required types with default values" do
212
+ create "--baz" => :string, "--foo" => "bar"
213
+ parse("--baz", "bang", "--foo")["foo"].should == "bar"
214
+ end
215
+
216
+ it "overwrites earlier values with later values" do
217
+ parse("--foo=bar", "--foo", "12")["foo"].should == "12"
218
+ parse("--foo", "12", "--foo", "13")["foo"].should == "13"
219
+ end
220
+ end
221
+
222
+ describe "with :boolean type" do
223
+ before(:each) do
224
+ create "--foo" => false
225
+ end
226
+
227
+ it "accepts --opt assignment" do
228
+ parse("--foo")["foo"].should == true
229
+ parse("--foo", "--bar")["foo"].should == true
230
+ end
231
+
232
+ it "accepts --opt=value assignment" do
233
+ parse("--foo=true")["foo"].should == true
234
+ parse("--foo=false")["foo"].should == false
235
+ end
236
+
237
+ it "accepts --[no-]opt variant, setting false for value" do
238
+ parse("--no-foo")["foo"].should == false
239
+ end
240
+
241
+ it "accepts --[skip-]opt variant, setting false for value" do
242
+ parse("--skip-foo")["foo"].should == false
243
+ end
244
+
245
+ it "will prefer 'no-opt' variant over inverting 'opt' if explicitly set" do
246
+ create "--no-foo" => true
247
+ parse("--no-foo")["no-foo"].should == true
248
+ end
249
+
250
+ it "will prefer 'skip-opt' variant over inverting 'opt' if explicitly set" do
251
+ create "--skip-foo" => true
252
+ parse("--skip-foo")["skip-foo"].should == true
253
+ end
254
+
255
+ it "accepts inputs in the human name format" do
256
+ create :foo_bar => :boolean
257
+ parse("--foo-bar")["foo_bar"].should == true
258
+ parse("--no-foo-bar")["foo_bar"].should == false
259
+ parse("--skip-foo-bar")["foo_bar"].should == false
260
+ end
261
+ end
262
+
263
+ describe "with :hash type" do
264
+ before(:each) do
265
+ create "--attributes" => :hash
266
+ end
267
+
268
+ it "accepts a switch=<value> assignment" do
269
+ parse("--attributes=name:string", "age:integer")["attributes"].should == {"name" => "string", "age" => "integer"}
270
+ end
271
+
272
+ it "accepts a switch <value> assignment" do
273
+ parse("--attributes", "name:string", "age:integer")["attributes"].should == {"name" => "string", "age" => "integer"}
274
+ end
275
+
276
+ it "must not mix values with other switches" do
277
+ parse("--attributes", "name:string", "age:integer", "--baz", "cool")["attributes"].should == {"name" => "string", "age" => "integer"}
278
+ end
279
+ end
280
+
281
+ describe "with :array type" do
282
+ before(:each) do
283
+ create "--attributes" => :array
284
+ end
285
+
286
+ it "accepts a switch=<value> assignment" do
287
+ parse("--attributes=a", "b", "c")["attributes"].should == ["a", "b", "c"]
288
+ end
289
+
290
+ it "accepts a switch <value> assignment" do
291
+ parse("--attributes", "a", "b", "c")["attributes"].should == ["a", "b", "c"]
292
+ end
293
+
294
+ it "must not mix values with other switches" do
295
+ parse("--attributes", "a", "b", "c", "--baz", "cool")["attributes"].should == ["a", "b", "c"]
296
+ end
297
+ end
298
+
299
+ describe "with :numeric type" do
300
+ before(:each) do
301
+ create "n" => :numeric, "m" => 5
302
+ end
303
+
304
+ it "accepts a -nXY assignment" do
305
+ parse("-n12")["n"].should == 12
306
+ end
307
+
308
+ it "converts values to numeric types" do
309
+ parse("-n", "3", "-m", ".5").should == {"n" => 3, "m" => 0.5}
310
+ end
311
+
312
+ it "raises error when value isn't numeric" do
313
+ lambda { parse("-n", "foo") }.should raise_error(Thor::MalformattedArgumentError,
314
+ "Expected numeric value for '-n'; got \"foo\"")
315
+ end
316
+ end
317
+
318
+ end
319
+ end