1require File.expand_path('../helper', __FILE__)
2
3class TestRakeApplication < Rake::TestCase
4
5  def setup
6    super
7
8    @app = Rake.application
9    @app.options.rakelib = []
10  end
11
12  def test_constant_warning
13    _, err = capture_io do @app.instance_eval { const_warning("Task") } end
14    assert_match(/warning/i, err)
15    assert_match(/deprecated/i, err)
16    assert_match(/Task/i, err)
17  end
18
19  def test_display_tasks
20    @app.options.show_tasks = :tasks
21    @app.options.show_task_pattern = //
22    @app.last_description = "COMMENT"
23    @app.define_task(Rake::Task, "t")
24    out, = capture_io do @app.instance_eval { display_tasks_and_comments } end
25    assert_match(/^rake t/, out)
26    assert_match(/# COMMENT/, out)
27  end
28
29  def test_display_tasks_with_long_comments
30    @app.terminal_columns = 80
31    @app.options.show_tasks = :tasks
32    @app.options.show_task_pattern = //
33    @app.last_description = "1234567890" * 8
34    @app.define_task(Rake::Task, "t")
35
36    out, = capture_io do @app.instance_eval { display_tasks_and_comments } end
37
38    assert_match(/^rake t/, out)
39    assert_match(/# 12345678901234567890123456789012345678901234567890123456789012345\.\.\./, out)
40  end
41
42  def test_display_tasks_with_task_name_wider_than_tty_display
43    @app.terminal_columns = 80
44    @app.options.show_tasks = :tasks
45    @app.options.show_task_pattern = //
46    task_name = "task name" * 80
47    @app.last_description = "something short"
48    @app.define_task(Rake::Task, task_name )
49
50    out, = capture_io do @app.instance_eval { display_tasks_and_comments } end
51
52    # Ensure the entire task name is output and we end up showing no description
53    assert_match(/rake #{task_name}  # .../, out)
54  end
55
56  def test_display_tasks_with_very_long_task_name_to_a_non_tty_shows_name_and_comment
57    @app.options.show_tasks = :tasks
58    @app.options.show_task_pattern = //
59    @app.tty_output = false
60    description = "something short"
61    task_name = "task name" * 80
62    @app.last_description = "something short"
63    @app.define_task(Rake::Task, task_name )
64
65    out, = capture_io do @app.instance_eval { display_tasks_and_comments } end
66
67    # Ensure the entire task name is output and we end up showing no description
68    assert_match(/rake #{task_name}  # #{description}/, out)
69  end
70
71  def test_display_tasks_with_long_comments_to_a_non_tty_shows_entire_comment
72    @app.options.show_tasks = :tasks
73    @app.options.show_task_pattern = //
74    @app.tty_output = false
75    @app.last_description = "1234567890" * 8
76    @app.define_task(Rake::Task, "t")
77    out, = capture_io do @app.instance_eval { display_tasks_and_comments } end
78    assert_match(/^rake t/, out)
79    assert_match(/# #{@app.last_description}/, out)
80  end
81
82  def test_display_tasks_with_long_comments_to_a_non_tty_with_columns_set_truncates_comments
83    @app.terminal_columns = 80
84    @app.options.show_tasks = :tasks
85    @app.options.show_task_pattern = //
86    @app.tty_output = false
87    @app.last_description = "1234567890" * 8
88    @app.define_task(Rake::Task, "t")
89
90    out, = capture_io do @app.instance_eval { display_tasks_and_comments } end
91
92    assert_match(/^rake t/, out)
93    assert_match(/# 12345678901234567890123456789012345678901234567890123456789012345\.\.\./, out)
94  end
95
96  def test_describe_tasks
97    @app.options.show_tasks = :describe
98    @app.options.show_task_pattern = //
99    @app.last_description = "COMMENT"
100    @app.define_task(Rake::Task, "t")
101    out, = capture_io do @app.instance_eval { display_tasks_and_comments } end
102    assert_match(/^rake t$/, out)
103    assert_match(/^ {4}COMMENT$/, out)
104  end
105
106  def test_show_lines
107    @app.options.show_tasks = :lines
108    @app.options.show_task_pattern = //
109    @app.last_description = "COMMENT"
110    @app.define_task(Rake::Task, "t")
111    @app['t'].locations << "HERE:1"
112    out, = capture_io do @app.instance_eval { display_tasks_and_comments } end
113    assert_match(/^rake t +[^:]+:\d+ *$/, out)
114  end
115
116  def test_finding_rakefile
117    rakefile_default
118
119    assert_match(/Rakefile/i, @app.instance_eval { have_rakefile })
120  end
121
122  def test_not_finding_rakefile
123    @app.instance_eval { @rakefiles = ['NEVER_FOUND'] }
124    assert( ! @app.instance_eval do have_rakefile end )
125    assert_nil @app.rakefile
126  end
127
128  def test_load_rakefile
129    rakefile_unittest
130
131    @app.instance_eval do
132      handle_options
133      options.silent = true
134      load_rakefile
135    end
136
137    assert_equal "rakefile", @app.rakefile.downcase
138    assert_equal @tempdir, Dir.pwd
139  end
140
141  def test_load_rakefile_doesnt_print_rakefile_directory_from_same_dir
142    rakefile_unittest
143
144    _, err = capture_io do
145      @app.instance_eval do
146        # pretend we started from the unittest dir
147        @original_dir = File.expand_path(".")
148        raw_load_rakefile
149      end
150    end
151
152    assert_empty err
153  end
154
155  def test_load_rakefile_from_subdir
156    rakefile_unittest
157    Dir.chdir 'subdir'
158
159    @app.instance_eval do
160      handle_options
161      options.silent = true
162      load_rakefile
163    end
164
165    assert_equal "rakefile", @app.rakefile.downcase
166    assert_equal @tempdir, Dir.pwd
167  end
168
169  def test_load_rakefile_prints_rakefile_directory_from_subdir
170    rakefile_unittest
171    Dir.chdir 'subdir'
172
173    app = Rake::Application.new
174    app.options.rakelib = []
175
176    _, err = capture_io do
177      app.instance_eval do
178        raw_load_rakefile
179      end
180    end
181
182    assert_equal "(in #{@tempdir}\)\n", err
183  end
184
185  def test_load_rakefile_doesnt_print_rakefile_directory_from_subdir_if_silent
186    rakefile_unittest
187    Dir.chdir 'subdir'
188
189    _, err = capture_io do
190      @app.instance_eval do
191        handle_options
192        options.silent = true
193        raw_load_rakefile
194      end
195    end
196
197    assert_empty err
198  end
199
200  def test_load_rakefile_not_found
201    Dir.chdir @tempdir
202    ENV['RAKE_SYSTEM'] = 'not_exist'
203
204    @app.instance_eval do
205      handle_options
206      options.silent = true
207    end
208
209    ex = assert_raises(RuntimeError) do
210      @app.instance_eval do raw_load_rakefile end
211    end
212
213    assert_match(/no rakefile found/i, ex.message)
214  end
215
216  def test_load_from_system_rakefile
217    rake_system_dir
218
219    @app.instance_eval do
220      handle_options
221      options.silent = true
222      options.load_system = true
223      options.rakelib = []
224      load_rakefile
225    end
226
227    assert_equal @system_dir, @app.system_dir
228    assert_nil @app.rakefile
229  rescue SystemExit
230    flunk 'failed to load rakefile'
231  end
232
233  def test_load_from_calculated_system_rakefile
234    rakefile_default
235    def @app.standard_system_dir
236      "__STD_SYS_DIR__"
237    end
238
239    ENV['RAKE_SYSTEM'] = nil
240
241    @app.instance_eval do
242      handle_options
243      options.silent = true
244      options.load_system = true
245      options.rakelib = []
246      load_rakefile
247    end
248
249    assert_equal "__STD_SYS_DIR__", @app.system_dir
250  rescue SystemExit
251    flunk 'failed to find system rakefile'
252  end
253
254  def test_terminal_columns
255    old_RAKE_COLUMNS = ENV['RAKE_COLUMNS']
256
257    ENV['RAKE_COLUMNS'] = '42'
258
259    app = Rake::Application.new
260
261    assert_equal 42, app.terminal_columns
262  ensure
263    if old_RAKE_COLUMNS then
264      ENV['RAKE_COLUMNS'].delete
265    else
266      ENV['RAKE_COLUMNS'] = old_RAKE_COLUMNS
267    end
268  end
269
270  def test_windows
271    assert ! (@app.windows? && @app.unix?)
272  end
273
274  def test_loading_imports
275    loader = util_loader
276
277    @app.instance_eval do
278      add_loader("dummy", loader)
279      add_import("x.dummy")
280      load_imports
281    end
282
283    # HACK no assertions
284  end
285
286  def test_building_imported_files_on_demand
287    loader = util_loader
288
289    @app.instance_eval do
290      intern(Rake::Task, "x.dummy").enhance do loader.make_dummy end
291      add_loader("dummy", loader)
292      add_import("x.dummy")
293      load_imports
294    end
295
296    # HACK no assertions
297  end
298
299  def test_handle_options_should_strip_options_from_ARGV
300    assert !@app.options.trace
301
302    valid_option = '--trace'
303    ARGV.clear
304    ARGV << valid_option
305
306    @app.handle_options
307
308    assert !ARGV.include?(valid_option)
309    assert @app.options.trace
310  end
311
312  def test_handle_options_trace_default_is_stderr
313    ARGV.clear
314    ARGV << "--trace"
315
316    @app.handle_options
317
318    assert_equal STDERR, @app.options.trace_output
319    assert @app.options.trace
320  end
321
322  def test_handle_options_trace_overrides_to_stdout
323    ARGV.clear
324    ARGV << "--trace=stdout"
325
326    @app.handle_options
327
328    assert_equal STDOUT, @app.options.trace_output
329    assert @app.options.trace
330  end
331
332  def test_handle_options_trace_does_not_eat_following_task_names
333    assert !@app.options.trace
334
335    ARGV.clear
336    ARGV << "--trace" << "sometask"
337
338    @app.handle_options
339    assert ARGV.include?("sometask")
340    assert @app.options.trace
341  end
342
343  def test_good_run
344    ran = false
345
346    ARGV << '--rakelib=""'
347
348    @app.options.silent = true
349
350    @app.instance_eval do
351      intern(Rake::Task, "default").enhance { ran = true }
352    end
353
354    rakefile_default
355
356    out, err = capture_io do
357      @app.run
358    end
359
360    assert ran
361    assert_empty err
362    assert_equal "DEFAULT\n", out
363  end
364
365  def test_display_task_run
366    ran = false
367    ARGV.clear
368    ARGV << '-f' << '-s' << '--tasks' << '--rakelib=""'
369    @app.last_description = "COMMENT"
370    @app.define_task(Rake::Task, "default")
371    out, = capture_io { @app.run }
372    assert @app.options.show_tasks
373    assert ! ran
374    assert_match(/rake default/, out)
375    assert_match(/# COMMENT/, out)
376  end
377
378  def test_display_prereqs
379    ran = false
380    ARGV.clear
381    ARGV << '-f' << '-s' << '--prereqs' << '--rakelib=""'
382    @app.last_description = "COMMENT"
383    t = @app.define_task(Rake::Task, "default")
384    t.enhance([:a, :b])
385    @app.define_task(Rake::Task, "a")
386    @app.define_task(Rake::Task, "b")
387    out, = capture_io { @app.run }
388    assert @app.options.show_prereqs
389    assert ! ran
390    assert_match(/rake a$/, out)
391    assert_match(/rake b$/, out)
392    assert_match(/rake default\n( *(a|b)\n){2}/m, out)
393  end
394
395  def test_bad_run
396    @app.intern(Rake::Task, "default").enhance { fail }
397    ARGV.clear
398    ARGV << '-f' << '-s' <<  '--rakelib=""'
399    assert_raises(SystemExit) {
400      _, err = capture_io { @app.run }
401      assert_match(/see full trace/, err)
402    }
403  ensure
404    ARGV.clear
405  end
406
407  def test_bad_run_with_trace
408    @app.intern(Rake::Task, "default").enhance { fail }
409    ARGV.clear
410    ARGV << '-f' << '-s' << '-t'
411    assert_raises(SystemExit) {
412      _, err = capture_io { @app.run }
413      refute_match(/see full trace/, err)
414    }
415  ensure
416    ARGV.clear
417  end
418
419  def test_bad_run_with_backtrace
420    @app.intern(Rake::Task, "default").enhance { fail }
421    ARGV.clear
422    ARGV << '-f' << '-s' << '--backtrace'
423    assert_raises(SystemExit) {
424      _, err = capture_io { @app.run }
425      refute_match(/see full trace/, err)
426    }
427  ensure
428    ARGV.clear
429  end
430
431  def test_run_with_bad_options
432    @app.intern(Rake::Task, "default").enhance { fail }
433    ARGV.clear
434    ARGV << '-f' << '-s' << '--xyzzy'
435    assert_raises(SystemExit) {
436      capture_io { @app.run }
437    }
438  ensure
439    ARGV.clear
440  end
441
442  def test_deprecation_message
443    _, err = capture_io do
444      @app.deprecate("a", "b", "c")
445    end
446    assert_match(/'a' is deprecated/i, err)
447    assert_match(/use 'b' instead/i, err)
448    assert_match(/at c$/i, err)
449  end
450
451  def test_standard_exception_handling_invalid_option
452    out, err = capture_io do
453      e = assert_raises SystemExit do
454        @app.standard_exception_handling do
455          raise OptionParser::InvalidOption, 'blah'
456        end
457      end
458
459      assert_equal 1, e.status
460    end
461
462    assert_empty out
463    assert_equal "invalid option: blah\n", err
464  end
465
466  def test_standard_exception_handling_other
467    out, err = capture_io do
468      e = assert_raises SystemExit do
469        @app.standard_exception_handling do
470          raise 'blah'
471        end
472      end
473
474      assert_equal 1, e.status
475    end
476
477    assert_empty out
478    assert_match "rake aborted!\n", err
479    assert_match "blah\n", err
480  end
481
482  def test_standard_exception_handling_system_exit
483    out, err = capture_io do
484      e = assert_raises SystemExit do
485        @app.standard_exception_handling do
486          exit 0
487        end
488      end
489
490      assert_equal 0, e.status
491    end
492
493    assert_empty out
494    assert_empty err
495  end
496
497  def test_standard_exception_handling_system_exit_nonzero
498    out, err = capture_io do
499      e = assert_raises SystemExit do
500        @app.standard_exception_handling do
501          exit 5
502        end
503      end
504
505      assert_equal 5, e.status
506    end
507
508    assert_empty out
509    assert_empty err
510  end
511
512  def util_loader
513    loader = Object.new
514
515    loader.instance_variable_set :@load_called, false
516    def loader.load arg
517      raise 'called more than once' if @load_called
518      raise ArgumentError, arg unless arg == 'x.dummy'
519      @load_called = true
520    end
521
522    loader.instance_variable_set :@make_dummy_called, false
523    def loader.make_dummy
524      raise 'called more than once' if @make_dummy_called
525      @make_dummy_called = true
526    end
527
528    loader
529  end
530
531end
532