thor 0.12.0 → 0.13.0

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 (43) hide show
  1. data/CHANGELOG.rdoc +5 -5
  2. data/README.rdoc +65 -2
  3. data/Thorfile +15 -9
  4. data/bin/thor +1 -0
  5. data/lib/thor/actions/create_file.rb +2 -2
  6. data/lib/thor/actions/directory.rb +2 -4
  7. data/lib/thor/actions/file_manipulation.rb +10 -6
  8. data/lib/thor/actions/inject_into_file.rb +10 -7
  9. data/lib/thor/actions.rb +6 -5
  10. data/lib/thor/base.rb +45 -32
  11. data/lib/thor/core_ext/file_binary_read.rb +9 -0
  12. data/lib/thor/group.rb +46 -37
  13. data/lib/thor/runner.rb +49 -42
  14. data/lib/thor/shell/basic.rb +49 -29
  15. data/lib/thor/shell/color.rb +1 -1
  16. data/lib/thor/shell.rb +1 -1
  17. data/lib/thor/task.rb +27 -38
  18. data/lib/thor/util.rb +4 -22
  19. data/lib/thor/version.rb +1 -1
  20. data/lib/thor.rb +43 -45
  21. data/spec/actions/create_file_spec.rb +7 -7
  22. data/spec/actions/directory_spec.rb +5 -4
  23. data/spec/actions/file_manipulation_spec.rb +29 -16
  24. data/spec/actions/inject_into_file_spec.rb +29 -0
  25. data/spec/actions_spec.rb +14 -13
  26. data/spec/base_spec.rb +16 -1
  27. data/spec/fixtures/bundle/main.thor +1 -0
  28. data/spec/fixtures/doc/%file_name%.rb.tt +1 -0
  29. data/spec/fixtures/doc/README +3 -0
  30. data/spec/fixtures/group.thor +83 -0
  31. data/spec/fixtures/invoke.thor +112 -0
  32. data/spec/fixtures/script.thor +134 -0
  33. data/spec/fixtures/task.thor +10 -0
  34. data/spec/group_spec.rb +1 -7
  35. data/spec/runner_spec.rb +35 -39
  36. data/spec/shell/basic_spec.rb +56 -62
  37. data/spec/shell/color_spec.rb +6 -6
  38. data/spec/spec.opts +1 -0
  39. data/spec/spec_helper.rb +5 -4
  40. data/spec/task_spec.rb +14 -32
  41. data/spec/thor_spec.rb +21 -22
  42. data/spec/util_spec.rb +7 -31
  43. metadata +28 -19
data/spec/runner_spec.rb CHANGED
@@ -26,11 +26,11 @@ describe Thor::Runner do
26
26
 
27
27
  it "shows information about a specific Thor group class" do
28
28
  content = capture(:stdout){ Thor::Runner.start(["help", "my_counter"]) }
29
- content.must =~ /my_counter N \[N\]/
29
+ content.must =~ /my_counter N/
30
30
  end
31
31
 
32
32
  it "raises error if a class/task cannot be found" do
33
- mock(Thor::Runner).exit(1)
33
+ Thor::Runner.should_receive(:exit).with(1)
34
34
  content = capture(:stderr){ Thor::Runner.start(["help", "unknown"]) }
35
35
  content.must =~ /could not find Thor class or task 'unknown'/
36
36
  end
@@ -39,7 +39,7 @@ describe Thor::Runner do
39
39
  describe "#start" do
40
40
  it "invokes a task from Thor::Runner" do
41
41
  ARGV.replace ["list"]
42
- capture(:stdout){ Thor::Runner.start }.must =~ /my_counter N \[N\]/
42
+ capture(:stdout){ Thor::Runner.start }.must =~ /my_counter N/
43
43
  end
44
44
 
45
45
  it "invokes a task from a specific Thor class" do
@@ -68,7 +68,7 @@ describe Thor::Runner do
68
68
  end
69
69
 
70
70
  it "raises an error if class/task can't be found" do
71
- mock(Thor::Runner).exit(1)
71
+ Thor::Runner.should_receive(:exit).with(1)
72
72
  ARGV.replace ["unknown"]
73
73
  capture(:stderr){ Thor::Runner.start }.must =~ /could not find Thor class or task 'unknown'/
74
74
  end
@@ -78,12 +78,12 @@ describe Thor::Runner do
78
78
  lambda { Thor::Runner.start }.must raise_error(NoMethodError)
79
79
  end
80
80
 
81
- it "does not swallow Thor::Group ArgumentError" do
81
+ it "does not swallow Thor::Group InvocationError" do
82
82
  ARGV.replace ["whiny_generator"]
83
83
  lambda { Thor::Runner.start }.must raise_error(ArgumentError, /Are you sure it has arity equals to 0\?/)
84
84
  end
85
85
 
86
- it "does not swallow Thor ArgumentError" do
86
+ it "does not swallow Thor InvocationError" do
87
87
  ARGV.replace ["my_script:animal"]
88
88
  capture(:stderr) { Thor::Runner.start }.must =~ /'animal' was called incorrectly\. Call as 'my_script:animal TYPE'/
89
89
  end
@@ -96,26 +96,28 @@ describe Thor::Runner do
96
96
  "random" => {
97
97
  :location => @location,
98
98
  :filename => "4a33b894ffce85d7b412fc1b36f88fe0",
99
- :constants => ["Amazing"]
99
+ :namespaces => ["amazing"]
100
100
  }
101
101
  }
102
102
 
103
+ root_file = File.join(Thor::Util.thor_root, "thor.yml")
104
+
103
105
  # Stub load and save to avoid thor.yaml from being overwritten
104
- stub(YAML).load_file { @original_yaml }
105
- stub(File).exists?(File.join(Thor::Util.thor_root, "thor.yml")){ true }
106
- stub(File).open(File.join(Thor::Util.thor_root, "thor.yml"), "w")
106
+ YAML.stub!(:load_file).and_return(@original_yaml)
107
+ File.stub!(:exists?).with(root_file).and_return(true)
108
+ File.stub!(:open).with(root_file, "w")
107
109
  end
108
110
 
109
111
  describe "list" do
110
112
  it "gives a list of the available tasks" do
111
113
  ARGV.replace ["list"]
112
114
  content = capture(:stdout) { Thor::Runner.start }
113
- content.must =~ /amazing:describe NAME \[\-\-forcefully\]\s+# say that someone is amazing/m
115
+ content.must =~ /amazing:describe NAME\s+# say that someone is amazing/m
114
116
  end
115
117
 
116
118
  it "gives a list of the available Thor::Group classes" do
117
119
  ARGV.replace ["list"]
118
- capture(:stdout) { Thor::Runner.start }.must =~ /my_counter N \[N\]/
120
+ capture(:stdout) { Thor::Runner.start }.must =~ /my_counter N/
119
121
  end
120
122
 
121
123
  it "can filter a list of the available tasks by --group" do
@@ -141,33 +143,19 @@ describe Thor::Runner do
141
143
 
142
144
  it "presents tasks in the default namespace with an empty namespace" do
143
145
  ARGV.replace ["list"]
144
- capture(:stdout) { Thor::Runner.start }.must =~ /^:test\s+# prints 'test'/m
146
+ capture(:stdout) { Thor::Runner.start }.must =~ /^thor :test\s+# prints 'test'/m
145
147
  end
146
148
 
147
149
  it "runs tasks with an empty namespace from the default namespace" do
148
150
  ARGV.replace [":test"]
149
151
  capture(:stdout) { Thor::Runner.start }.must == "test\n"
150
152
  end
151
-
152
- it "updates the yaml file when invoked" do
153
- capture(:stdout) { Thor::Runner.start(["list"]) }
154
- @original_yaml["random"][:namespaces].must == ["amazing"]
155
- end
156
- end
157
-
158
- describe "update" do
159
- it "updates existing thor files" do
160
- mock.instance_of(Thor::Runner).install(@original_yaml["random"][:location]) { true }
161
- stub(File).delete(File.join(Thor::Util.thor_root, @original_yaml["random"][:filename]))
162
- silence(:stdout) { Thor::Runner.start(["update", "random"]) }
163
- end
164
153
  end
165
154
 
166
155
  describe "uninstall" do
167
156
  before(:each) do
168
- stub.instance_of(Thor::Runner).save_yaml(anything)
169
- stub(File).delete(anything)
170
- stub(@original_yaml).delete(anything)
157
+ path = File.join(Thor::Util.thor_root, @original_yaml["random"][:filename])
158
+ FileUtils.should_receive(:rm_rf).with(path)
171
159
  end
172
160
 
173
161
  it "uninstalls existing thor modules" do
@@ -177,26 +165,34 @@ describe Thor::Runner do
177
165
 
178
166
  describe "installed" do
179
167
  before(:each) do
180
- stub(Dir).[](anything) { [] }
168
+ Dir.should_receive(:[]).and_return([])
181
169
  end
182
170
 
183
171
  it "displays the modules installed in a pretty way" do
184
172
  stdout = capture(:stdout) { Thor::Runner.start(["installed"]) }
185
173
  stdout.must =~ /random\s*amazing/
186
- stdout.must =~ /amazing:describe NAME \[\-\-forcefully\]\s+# say that someone is amazing/m
174
+ stdout.must =~ /amazing:describe NAME\s+# say that someone is amazing/m
187
175
  end
188
176
  end
189
177
 
190
- describe "install" do
191
- it "installs thor files" do
192
- ARGV.replace ["install", @location]
178
+ describe "install/update" do
179
+ before(:each) do
180
+ FileUtils.stub!(:mkdir_p)
181
+ FileUtils.stub!(:touch)
182
+ $stdin.stub!(:gets).and_return("Y")
193
183
 
194
- # Stubs for the file system interactions
195
- stub.instance_of(Thor::Base.shell).no? { false }
196
- stub(FileUtils).mkdir_p
197
- stub(FileUtils).touch
184
+ path = File.join(Thor::Util.thor_root, Digest::MD5.hexdigest(@location + "random"))
185
+ File.should_receive(:open).with(path, "w")
186
+ end
198
187
 
199
- mock(File).open(File.join(Thor::Util.thor_root, Digest::MD5.hexdigest(@location + "random")), "w")
188
+ it "updates existing thor files" do
189
+ path = File.join(Thor::Util.thor_root, @original_yaml["random"][:filename])
190
+ File.should_receive(:delete).with(path)
191
+ silence(:stdout) { Thor::Runner.start(["update", "random"]) }
192
+ end
193
+
194
+ it "installs thor files" do
195
+ ARGV.replace ["install", @location]
200
196
  silence(:stdout) { Thor::Runner.start }
201
197
  end
202
198
  end
@@ -17,107 +17,85 @@ describe Thor::Shell::Basic do
17
17
 
18
18
  describe "#ask" do
19
19
  it "prints a message to the user and gets the response" do
20
- mock($stdout).print("Should I overwrite it? ")
21
- mock($stdin).gets{ "Sure" }
20
+ $stdout.should_receive(:print).with("Should I overwrite it? ")
21
+ $stdin.should_receive(:gets).and_return('Sure')
22
22
  shell.ask("Should I overwrite it?").must == "Sure"
23
23
  end
24
24
  end
25
25
 
26
26
  describe "#yes?" do
27
27
  it "asks the user and returns true if the user replies yes" do
28
- mock($stdout).print("Should I overwrite it? ")
29
- mock($stdin).gets{ "y" }
28
+ $stdout.should_receive(:print).with("Should I overwrite it? ")
29
+ $stdin.should_receive(:gets).and_return('y')
30
30
  shell.yes?("Should I overwrite it?").must be_true
31
31
 
32
- mock($stdout).print("Should I overwrite it? ")
33
- mock($stdin).gets{ "n" }
32
+ $stdout.should_receive(:print).with("Should I overwrite it? ")
33
+ $stdin.should_receive(:gets).and_return('n')
34
34
  shell.yes?("Should I overwrite it?").must_not be_true
35
35
  end
36
36
  end
37
37
 
38
38
  describe "#no?" do
39
39
  it "asks the user and returns true if the user replies no" do
40
- mock($stdout).print("Should I overwrite it? ")
41
- mock($stdin).gets{ "n" }
40
+ $stdout.should_receive(:print).with("Should I overwrite it? ")
41
+ $stdin.should_receive(:gets).and_return('n')
42
42
  shell.no?("Should I overwrite it?").must be_true
43
43
 
44
- mock($stdout).print("Should I overwrite it? ")
45
- mock($stdin).gets{ "Yes" }
44
+ $stdout.should_receive(:print).with("Should I overwrite it? ")
45
+ $stdin.should_receive(:gets).and_return('Yes')
46
46
  shell.no?("Should I overwrite it?").must be_false
47
47
  end
48
48
  end
49
49
 
50
50
  describe "#say" do
51
51
  it "prints a message to the user" do
52
- mock($stdout).puts("Running...")
52
+ $stdout.should_receive(:puts).with("Running...")
53
53
  shell.say("Running...")
54
54
  end
55
55
 
56
56
  it "prints a message to the user without new line if it ends with a whitespace" do
57
- mock($stdout).print("Running... ")
57
+ $stdout.should_receive(:print).with("Running... ")
58
58
  shell.say("Running... ")
59
59
  end
60
60
 
61
61
  it "prints a message to the user without new line" do
62
- mock($stdout).print("Running...")
62
+ $stdout.should_receive(:print).with("Running...")
63
63
  shell.say("Running...", nil, false)
64
64
  end
65
65
  end
66
66
 
67
67
  describe "#say_status" do
68
68
  it "prints a message to the user with status" do
69
- mock($stdout).puts(" create ~/.thor/task.thor")
69
+ $stdout.should_receive(:puts).with(" create ~/.thor/task.thor")
70
70
  shell.say_status(:create, "~/.thor/task.thor")
71
71
  end
72
72
 
73
73
  it "always use new line" do
74
- mock($stdout).puts(" create ")
74
+ $stdout.should_receive(:puts).with(" create ")
75
75
  shell.say_status(:create, "")
76
76
  end
77
77
 
78
78
  it "does not print a message if base is set to quiet" do
79
79
  base = MyCounter.new [1,2]
80
- mock(base).options { Hash.new(:quiet => true) }
80
+ base.should_receive(:options).and_return(:quiet => true)
81
81
 
82
- dont_allow($stdout).puts
82
+ $stdout.should_not_receive(:puts)
83
83
  shell.base = base
84
84
  shell.say_status(:created, "~/.thor/task.thor")
85
85
  end
86
86
 
87
87
  it "does not print a message if log status is set to false" do
88
- dont_allow($stdout).puts
88
+ $stdout.should_not_receive(:puts)
89
89
  shell.say_status(:created, "~/.thor/task.thor", false)
90
90
  end
91
91
 
92
92
  it "uses padding to set messages left margin" do
93
93
  shell.padding = 2
94
- mock($stdout).puts(" create ~/.thor/task.thor")
94
+ $stdout.should_receive(:puts).with(" create ~/.thor/task.thor")
95
95
  shell.say_status(:create, "~/.thor/task.thor")
96
96
  end
97
97
  end
98
98
 
99
- describe "#print_list" do
100
- before(:each) do
101
- @list = ["abc", "#123", "first three"]
102
- end
103
-
104
- it "prints a list" do
105
- content = capture(:stdout){ shell.print_list(@list) }
106
- content.must == <<-LIST
107
- abc
108
- #123
109
- first three
110
- LIST
111
- end
112
-
113
- it "prints a list inline" do
114
- content = capture(:stdout){ shell.print_list(@list, :mode => :inline) }
115
- content.must == <<-LIST
116
- abc, #123, and first three
117
- LIST
118
- end
119
- end
120
-
121
99
  describe "#print_table" do
122
100
  before(:each) do
123
101
  @table = []
@@ -141,41 +119,57 @@ TABLE
141
119
  abc #123 first three
142
120
  #0 empty
143
121
  xyz #786 last three
122
+ TABLE
123
+ end
124
+
125
+ it "uses maximum terminal width" do
126
+ shell.should_receive(:terminal_width).and_return(20)
127
+ content = capture(:stdout){ shell.print_table(@table, :ident => 2, :truncate => true) }
128
+ content.must == <<-TABLE
129
+ abc #123 firs...
130
+ #0 empty
131
+ xyz #786 last...
144
132
  TABLE
145
133
  end
146
134
  end
147
135
 
148
136
  describe "#file_collision" do
149
137
  it "shows a menu with options" do
150
- mock($stdout).print('Overwrite foo? (enter "h" for help) [Ynaqh] ')
151
- mock($stdin).gets{ 'n' }
138
+ $stdout.should_receive(:print).with('Overwrite foo? (enter "h" for help) [Ynaqh] ')
139
+ $stdin.should_receive(:gets).and_return('n')
152
140
  shell.file_collision('foo')
153
141
  end
154
142
 
143
+ it "returns true if the user choose default option" do
144
+ $stdout.stub!(:print)
145
+ $stdin.should_receive(:gets).and_return('')
146
+ shell.file_collision('foo').must be_true
147
+ end
148
+
155
149
  it "returns false if the user choose no" do
156
- stub($stdout).print
157
- mock($stdin).gets{ 'n' }
150
+ $stdout.stub!(:print)
151
+ $stdin.should_receive(:gets).and_return('n')
158
152
  shell.file_collision('foo').must be_false
159
153
  end
160
154
 
161
155
  it "returns true if the user choose yes" do
162
- stub($stdout).print
163
- mock($stdin).gets{ 'y' }
156
+ $stdout.stub!(:print)
157
+ $stdin.should_receive(:gets).and_return('y')
164
158
  shell.file_collision('foo').must be_true
165
159
  end
166
160
 
167
161
  it "shows help usage if the user choose help" do
168
- stub($stdout).print
169
- mock($stdin).gets{ 'h' }
170
- mock($stdin).gets{ 'n' }
162
+ $stdout.stub!(:print)
163
+ $stdin.should_receive(:gets).and_return('h')
164
+ $stdin.should_receive(:gets).and_return('n')
171
165
  help = capture(:stdout){ shell.file_collision('foo') }
172
166
  help.must =~ /h \- help, show this help/
173
167
  end
174
168
 
175
169
  it "quits if the user choose quit" do
176
- stub($stdout).print
177
- mock($stdout).puts('Aborting...')
178
- mock($stdin).gets{ 'q' }
170
+ $stdout.stub!(:print)
171
+ $stdout.should_receive(:puts).with('Aborting...')
172
+ $stdin.should_receive(:gets).and_return('q')
179
173
 
180
174
  lambda {
181
175
  shell.file_collision('foo')
@@ -183,27 +177,27 @@ TABLE
183
177
  end
184
178
 
185
179
  it "always returns true if the user choose always" do
186
- mock($stdout).print('Overwrite foo? (enter "h" for help) [Ynaqh] ')
187
- mock($stdin).gets{ 'a' }
180
+ $stdout.should_receive(:print).with('Overwrite foo? (enter "h" for help) [Ynaqh] ')
181
+ $stdin.should_receive(:gets).and_return('a')
188
182
 
189
183
  shell.file_collision('foo').must be_true
190
184
 
191
- dont_allow($stdout).print
185
+ $stdout.should_not_receive(:print)
192
186
  shell.file_collision('foo').must be_true
193
187
  end
194
188
 
195
189
  describe "when a block is given" do
196
190
  it "displays diff options to the user" do
197
- mock($stdout).print('Overwrite foo? (enter "h" for help) [Ynaqdh] ')
198
- mock($stdin).gets{ 's' }
191
+ $stdout.should_receive(:print).with('Overwrite foo? (enter "h" for help) [Ynaqdh] ')
192
+ $stdin.should_receive(:gets).and_return('s')
199
193
  shell.file_collision('foo'){ }
200
194
  end
201
195
 
202
196
  it "invokes the diff command" do
203
- stub($stdout).print
204
- mock($stdin).gets{ 'd' }
205
- mock($stdin).gets{ 'n' }
206
- mock(shell).system(/diff -u/)
197
+ $stdout.stub!(:print)
198
+ $stdin.should_receive(:gets).and_return('d')
199
+ $stdin.should_receive(:gets).and_return('n')
200
+ shell.should_receive(:system).with(/diff -u/)
207
201
  capture(:stdout){ shell.file_collision('foo'){ } }
208
202
  end
209
203
  end
@@ -7,19 +7,19 @@ describe Thor::Shell::Color do
7
7
 
8
8
  describe "#say" do
9
9
  it "set the color if specified" do
10
- mock($stdout).puts("\e[32mWow! Now we have colors!\e[0m")
10
+ $stdout.should_receive(:puts).with("\e[32mWow! Now we have colors!\e[0m")
11
11
  shell.say "Wow! Now we have colors!", :green
12
12
  end
13
13
 
14
14
  it "does not use a new line even with colors" do
15
- mock($stdout).print("\e[32mWow! Now we have colors! \e[0m")
15
+ $stdout.should_receive(:print).with("\e[32mWow! Now we have colors! \e[0m")
16
16
  shell.say "Wow! Now we have colors! ", :green
17
17
  end
18
18
  end
19
19
 
20
20
  describe "#say_status" do
21
21
  it "uses color to say status" do
22
- mock($stdout).puts("\e[1m\e[31m conflict\e[0m README")
22
+ $stdout.should_receive(:puts).with("\e[1m\e[31m conflict\e[0m README")
23
23
  shell.say_status :conflict, "README", :red
24
24
  end
25
25
  end
@@ -27,9 +27,9 @@ describe Thor::Shell::Color do
27
27
  describe "#file_collision" do
28
28
  describe "when a block is given" do
29
29
  it "invokes the diff command" do
30
- stub($stdout).print
31
- mock($stdin).gets{ 'd' }
32
- mock($stdin).gets{ 'n' }
30
+ $stdout.stub!(:print)
31
+ $stdin.should_receive(:gets).and_return('d')
32
+ $stdin.should_receive(:gets).and_return('n')
33
33
 
34
34
  output = capture(:stdout){ shell.file_collision('spec/fixtures/doc/README'){ "README\nEND\n" } }
35
35
  output.must =~ /\e\[31m\- __start__\e\[0m/
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
data/spec/spec_helper.rb CHANGED
@@ -2,12 +2,15 @@ $TESTING=true
2
2
 
3
3
  $:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
4
4
  require 'thor'
5
+ require 'thor/group'
5
6
  require 'stringio'
6
7
 
7
8
  require 'rubygems'
8
- require 'rr'
9
+ require 'rdoc'
9
10
  require 'diff/lcs' # You need diff/lcs installed to run specs (but not to run Thor).
10
11
 
12
+ $thor_runner = true
13
+
11
14
  # Load fixtures
12
15
  load File.join(File.dirname(__FILE__), "fixtures", "task.thor")
13
16
  load File.join(File.dirname(__FILE__), "fixtures", "group.thor")
@@ -25,8 +28,6 @@ Kernel.module_eval do
25
28
  end
26
29
 
27
30
  Spec::Runner.configure do |config|
28
- config.mock_with :rr
29
-
30
31
  def capture(stream)
31
32
  begin
32
33
  stream = stream.to_s
@@ -48,5 +49,5 @@ Spec::Runner.configure do |config|
48
49
  File.join(File.dirname(__FILE__), 'sandbox')
49
50
  end
50
51
 
51
- alias silence capture
52
+ alias :silence :capture
52
53
  end
data/spec/task_spec.rb CHANGED
@@ -10,32 +10,22 @@ describe Thor::Task do
10
10
  end
11
11
 
12
12
  describe "#formatted_usage" do
13
- it "shows usage with options" do
14
- task('foo' => true, :bar => :required).formatted_usage.must == "can_has --bar=BAR [--foo]"
15
- end
16
-
17
13
  it "includes namespace within usage" do
18
- stub(Object).namespace{ "foo" }
19
- stub(Object).arguments{ [] }
20
- task(:bar => :required).formatted_usage(Object, true).must == "foo:can_has --bar=BAR"
21
- end
22
-
23
- it "does not show options if required" do
24
- stub(Object).namespace{ "foo" }
25
- stub(Object).arguments{ [] }
26
- task(:bar => :required).formatted_usage(Object, true, false).must == "foo:can_has"
14
+ Object.stub!(:namespace).and_return("foo")
15
+ Object.stub!(:arguments).and_return([])
16
+ task(:bar => :required).formatted_usage(Object).must == "foo:can_has --bar=BAR"
27
17
  end
28
18
 
29
19
  it "removes default from namespace" do
30
- stub(Object).namespace{ "default:foo" }
31
- stub(Object).arguments{ [] }
32
- task(:bar => :required).formatted_usage(Object, true).must == ":foo:can_has --bar=BAR"
20
+ Object.stub!(:namespace).and_return("default:foo")
21
+ Object.stub!(:arguments).and_return([])
22
+ task(:bar => :required).formatted_usage(Object).must == ":foo:can_has --bar=BAR"
33
23
  end
34
24
 
35
25
  it "injects arguments into usage" do
36
- stub(Object).namespace{ "foo" }
37
- stub(Object).arguments{ [ Thor::Argument.new(:bar, nil, true, :string) ] }
38
- task(:foo => true).formatted_usage(Object).must == "can_has BAR [--foo]"
26
+ Object.stub!(:namespace).and_return("foo")
27
+ Object.stub!(:arguments).and_return([ Thor::Argument.new(:bar, nil, true, :string) ])
28
+ task(:foo => :required).formatted_usage(Object).must == "foo:can_has BAR --foo=FOO"
39
29
  end
40
30
  end
41
31
 
@@ -64,25 +54,17 @@ describe Thor::Task do
64
54
 
65
55
  describe "#run" do
66
56
  it "runs a task by calling a method in the given instance" do
67
- mock = mock!.send("can_has", 1, 2, 3).subject
57
+ mock = mock()
58
+ mock.should_receive(:send).with("can_has", 1, 2, 3)
68
59
  task.run(mock, [1, 2, 3])
69
60
  end
70
61
 
71
62
  it "raises an error if the method to be invoked is private" do
72
- mock = mock!.private_methods{ [ 'can_has' ] }.subject
63
+ mock = mock()
64
+ mock.should_receive(:private_methods).and_return(['can_has'])
73
65
  lambda {
74
66
  task.run(mock)
75
- }.must raise_error(Thor::UndefinedTaskError, "the 'can_has' task of Object is private")
76
- end
77
- end
78
-
79
- describe "#short_description" do
80
- it "returns the first line of the description" do
81
- Thor::Task.new(:task, "I can has\ncheezburger", "can_has").short_description == "I can has"
82
- end
83
-
84
- it "returns the whole description if it's one line" do
85
- Thor::Task.new(:task, "I can has cheezburger", "can_has").short_description == "I can has cheezburger"
67
+ }.must raise_error(Thor::UndefinedTaskError, "the 'can_has' task of Spec::Mocks::Mock is private")
86
68
  end
87
69
  end
88
70
  end
data/spec/thor_spec.rb CHANGED
@@ -72,7 +72,7 @@ describe Thor do
72
72
 
73
73
  describe "when :for is supplied" do
74
74
  it "overwrites a previous defined task" do
75
- capture(:stdout) { MyChildScript.start(["help"]) }.must =~ /animal KIND \[\-\-other=OTHER\]\s+# fish around/m
75
+ capture(:stdout) { MyChildScript.start(["help"]) }.must =~ /animal KIND \s+# fish around/m
76
76
  end
77
77
  end
78
78
  end
@@ -133,7 +133,7 @@ describe Thor do
133
133
  end
134
134
 
135
135
  it "raises when an exception happens within the task call" do
136
- lambda { MyScript.start(["call_myself_with_wrong_arity"]) }.must raise_error
136
+ lambda { MyScript.start(["call_myself_with_wrong_arity"]) }.must raise_error(ArgumentError)
137
137
  end
138
138
  end
139
139
 
@@ -148,25 +148,31 @@ describe Thor do
148
148
  end
149
149
 
150
150
  it "provides useful help info for the help method itself" do
151
- @content.must =~ /help \[TASK\]\s+# Describe available tasks/m
151
+ @content.must =~ /help \[TASK\]\s+# Describe available tasks/
152
152
  end
153
153
 
154
154
  it "provides useful help info for a method with params" do
155
- @content.must =~ /animal TYPE\s+# horse around/m
155
+ @content.must =~ /animal TYPE\s+# horse around/
156
+ end
157
+
158
+ it "uses the maximum terminal size to show tasks" do
159
+ @shell.should_receive(:terminal_width).and_return(80)
160
+ content = capture(:stdout){ MyScript.help(shell) }
161
+ content.must =~ /aaa\.\.\.$/
156
162
  end
157
163
 
158
164
  it "provides description for tasks from classes in the same namespace" do
159
- @content.must =~ /baz\s+# do some bazing/m
165
+ @content.must =~ /baz\s+# do some bazing/
160
166
  end
161
167
 
162
168
  it "shows superclass tasks" do
163
169
  content = capture(:stdout){ MyChildScript.help(shell) }
164
- content.must =~ /foo BAR \[\-\-force\]\s+# do some fooing/m
170
+ content.must =~ /foo BAR \s+# do some fooing/
165
171
  end
166
172
 
167
173
  it "shows class options information" do
168
174
  content = capture(:stdout){ MyChildScript.help(shell) }
169
- content.must =~ /Class options\:/
175
+ content.must =~ /Options\:/
170
176
  content.must =~ /\[\-\-param=N\]/
171
177
  end
172
178
 
@@ -178,11 +184,11 @@ describe Thor do
178
184
 
179
185
  describe "for a specific task" do
180
186
  it "provides full help info when talking about a specific task" do
181
- capture(:stdout) { MyScript.help(shell, "foo") }.must == <<END
187
+ capture(:stdout) { MyScript.task_help(shell, "foo") }.must == <<END
182
188
  Usage:
183
- foo BAR
189
+ thor my_script:foo BAR
184
190
 
185
- Method options:
191
+ Options:
186
192
  [--force] # Force to do some fooing
187
193
 
188
194
  do some fooing
@@ -193,25 +199,18 @@ END
193
199
 
194
200
  it "raises an error if the task can't be found" do
195
201
  lambda {
196
- MyScript.help(shell, "unknown")
202
+ MyScript.task_help(shell, "unknown")
197
203
  }.must raise_error(Thor::Error, "task 'unknown' could not be found in namespace 'my_script'")
198
204
  end
199
205
  end
200
206
 
201
- describe "options" do
202
- it "shows the namespace if required" do
203
- capture(:stdout){ MyScript.help(shell, nil, :namespace => true) }.must =~ /my_script:foo BAR/
204
- end
205
-
206
- it "does not show superclass tasks if required" do
207
- capture(:stdout){ MyScript.help(shell, nil, :short => true) }.must_not =~ /help/
207
+ describe "instance method" do
208
+ it "calls the class method" do
209
+ capture(:stdout){ MyScript.start(["help"]) }.must =~ /Tasks:/
208
210
  end
209
- end
210
211
 
211
- describe "instance method" do
212
212
  it "calls the class method" do
213
- stub(MyScript).help(mock.instance_of(Thor::Base.shell), nil, :namespace => nil)
214
- MyScript.start(["help"])
213
+ capture(:stdout){ MyScript.start(["help", "foo"]) }.must =~ /Usage:/
215
214
  end
216
215
  end
217
216
  end