1require 'rubygems'
2$:.unshift File.expand_path('../../lib', __FILE__)
3
4begin
5  gem 'minitest'
6rescue Gem::LoadError
7end
8
9require 'minitest/autorun'
10require 'rake'
11require 'tmpdir'
12require File.expand_path('../file_creation', __FILE__)
13
14begin
15  require_relative '../ruby/envutil'
16rescue NoMethodError, LoadError
17  # for ruby trunk
18end
19
20class Rake::TestCase < MiniTest::Unit::TestCase
21  include FileCreation
22
23  include Rake::DSL
24
25  class TaskManager
26    include Rake::TaskManager
27  end
28
29  RUBY = defined?(EnvUtil) ? EnvUtil.rubybin : Gem.ruby
30
31  def setup
32    ARGV.clear
33
34    test_dir = File.basename File.dirname File.expand_path __FILE__
35
36    @rake_root = if test_dir == 'test' then
37                   # rake repository
38                   File.expand_path '../../', __FILE__
39                 else
40                   # ruby repository
41                   File.expand_path '../../../', __FILE__
42                 end
43
44    @rake_exec = File.join @rake_root, 'bin', 'rake'
45    @rake_lib  = File.join @rake_root, 'lib'
46
47    @orig_PWD = Dir.pwd
48    @orig_APPDATA      = ENV['APPDATA']
49    @orig_HOME         = ENV['HOME']
50    @orig_HOMEDRIVE    = ENV['HOMEDRIVE']
51    @orig_HOMEPATH     = ENV['HOMEPATH']
52    @orig_RAKE_COLUMNS = ENV['RAKE_COLUMNS']
53    @orig_RAKE_SYSTEM  = ENV['RAKE_SYSTEM']
54    @orig_RAKEOPT      = ENV['RAKEOPT']
55    @orig_USERPROFILE  = ENV['USERPROFILE']
56    ENV.delete 'RAKE_COLUMNS'
57    ENV.delete 'RAKE_SYSTEM'
58    ENV.delete 'RAKEOPT'
59
60    tmpdir = Dir.chdir Dir.tmpdir do Dir.pwd end
61    @tempdir = File.join tmpdir, "test_rake_#{$$}"
62
63    FileUtils.mkdir_p @tempdir
64
65    Dir.chdir @tempdir
66
67    Rake.application = Rake::Application.new
68    Rake::TaskManager.record_task_metadata = true
69    RakeFileUtils.verbose_flag = false
70  end
71
72  def teardown
73    Dir.chdir @orig_PWD
74    FileUtils.rm_rf @tempdir
75
76    if @orig_APPDATA then
77      ENV['APPDATA'] = @orig_APPDATA
78    else
79      ENV.delete 'APPDATA'
80    end
81
82    ENV['HOME']         = @orig_HOME
83    ENV['HOMEDRIVE']    = @orig_HOMEDRIVE
84    ENV['HOMEPATH']     = @orig_HOMEPATH
85    ENV['RAKE_COLUMNS'] = @orig_RAKE_COLUMNS
86    ENV['RAKE_SYSTEM']  = @orig_RAKE_SYSTEM
87    ENV['RAKEOPT']      = @orig_RAKEOPT
88    ENV['USERPROFILE']  = @orig_USERPROFILE
89  end
90
91  def ignore_deprecations
92    Rake.application.options.ignore_deprecate = true
93    yield
94  ensure
95    Rake.application.options.ignore_deprecate = false
96  end
97
98  def rake_system_dir
99    @system_dir = 'system'
100
101    FileUtils.mkdir_p @system_dir
102
103    open File.join(@system_dir, 'sys1.rake'), 'w' do |io|
104      io << <<-SYS
105task "sys1" do
106  puts "SYS1"
107end
108      SYS
109    end
110
111    ENV['RAKE_SYSTEM'] = @system_dir
112  end
113
114  def rakefile contents
115    open 'Rakefile', 'w' do |io|
116      io << contents
117    end
118  end
119
120  def rakefile_access
121    rakefile <<-ACCESS
122TOP_LEVEL_CONSTANT = 0
123
124def a_top_level_function
125end
126
127task :default => [:work, :obj, :const]
128
129task :work do
130  begin
131    a_top_level_function
132    puts "GOOD:M Top level methods can be called in tasks"
133  rescue NameError => ex
134    puts "BAD:M  Top level methods can not be called in tasks"
135  end
136end
137
138# TODO: remove `disabled_' when DeprecatedObjectDSL removed
139task :obj
140task :disabled_obj do
141  begin
142    Object.new.instance_eval { task :xyzzy }
143    puts "BAD:D  Rake DSL are polluting objects"
144  rescue StandardError => ex
145    puts "GOOD:D Rake DSL are not polluting objects"
146  end
147end
148
149task :const do
150  begin
151    TOP_LEVEL_CONSTANT
152    puts "GOOD:C Top level constants are available in tasks"
153  rescue StandardError => ex
154    puts "BAD:C  Top level constants are NOT available in tasks"
155  end
156end
157    ACCESS
158  end
159
160  def rakefile_chains
161    rakefile <<-DEFAULT
162task :default => "play.app"
163
164file "play.scpt" => "base" do |t|
165  cp t.prerequisites.first, t.name
166end
167
168rule ".app" => ".scpt" do |t|
169  cp t.source, t.name
170end
171
172file 'base' do
173  touch 'base'
174end
175    DEFAULT
176  end
177
178  def rakefile_comments
179    rakefile <<-COMMENTS
180# comment for t1
181task :t1 do
182end
183
184# no comment or task because there's a blank line
185
186task :t2 do
187end
188
189desc "override comment for t3"
190# this is not the description
191multitask :t3 do
192end
193
194# this is not the description
195desc "override comment for t4"
196file :t4 do
197end
198    COMMENTS
199  end
200
201  def rakefile_default
202    rakefile <<-DEFAULT
203if ENV['TESTTOPSCOPE']
204  puts "TOPSCOPE"
205end
206
207task :default do
208  puts "DEFAULT"
209end
210
211task :other => [:default] do
212  puts "OTHER"
213end
214
215task :task_scope do
216  if ENV['TESTTASKSCOPE']
217    puts "TASKSCOPE"
218  end
219end
220    DEFAULT
221  end
222
223  def rakefile_dryrun
224    rakefile <<-DRYRUN
225task :default => ["temp_main"]
226
227file "temp_main" => [:all_apps]  do touch "temp_main" end
228
229task :all_apps => [:one, :two]
230task :one => ["temp_one"]
231task :two => ["temp_two"]
232
233file "temp_one" do |t|
234  touch "temp_one"
235end
236file "temp_two" do |t|
237  touch "temp_two"
238end
239
240task :clean do
241  ["temp_one", "temp_two", "temp_main"].each do |file|
242    rm_f file
243  end
244end
245    DRYRUN
246
247    FileUtils.touch 'temp_main'
248    FileUtils.touch 'temp_two'
249  end
250
251  def rakefile_extra
252    rakefile 'task :default'
253
254    FileUtils.mkdir_p 'rakelib'
255
256    open File.join('rakelib', 'extra.rake'), 'w' do |io|
257      io << <<-EXTRA_RAKE
258# Added for testing
259
260namespace :extra do
261  desc "An Extra Task"
262  task :extra do
263    puts "Read all about it"
264  end
265end
266      EXTRA_RAKE
267    end
268  end
269
270  def rakefile_file_creation
271    rakefile <<-'FILE_CREATION'
272N = 2
273
274task :default => :run
275
276BUILD_DIR = 'build'
277task :clean do
278  rm_rf 'build'
279  rm_rf 'src'
280end
281
282task :run
283
284TARGET_DIR = 'build/copies'
285
286FileList['src/*'].each do |src|
287  directory TARGET_DIR
288  target = File.join TARGET_DIR, File.basename(src)
289  file target => [src, TARGET_DIR] do
290    cp src, target
291    # sleep 3 if src !~ /foo#{N-1}$/   # I'm commenting out this sleep, it doesn't seem to do anything.
292  end
293  task :run => target
294end
295
296task :prep => :clean do
297  mkdir_p 'src'
298  N.times do |n|
299    touch "src/foo#{n}"
300  end
301end
302    FILE_CREATION
303  end
304
305  def rakefile_imports
306    rakefile <<-IMPORTS
307require 'rake/loaders/makefile'
308
309task :default
310
311task :other do
312  puts "OTHER"
313end
314
315file "dynamic_deps" do |t|
316  open(t.name, "w") do |f| f.puts "puts 'DYNAMIC'" end
317end
318
319import "dynamic_deps"
320import "static_deps"
321import "static_deps"
322import "deps.mf"
323puts "FIRST"
324    IMPORTS
325
326    open 'deps.mf', 'w' do |io|
327      io << <<-DEPS
328default: other
329      DEPS
330    end
331
332    open "static_deps", "w" do |f|
333      f.puts 'puts "STATIC"'
334    end
335  end
336
337  def rakefile_multidesc
338    rakefile <<-MULTIDESC
339task :b
340
341desc "A"
342task :a
343
344desc "B"
345task :b
346
347desc "A2"
348task :a
349
350task :c
351
352desc "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
353task :d
354    MULTIDESC
355  end
356
357  def rakefile_namespace
358    rakefile <<-NAMESPACE
359desc "copy"
360task :copy do
361  puts "COPY"
362end
363
364namespace "nest" do
365  desc "nest copy"
366  task :copy do
367    puts "NEST COPY"
368  end
369  task :xx => :copy
370end
371
372anon_ns = namespace do
373  desc "anonymous copy task"
374  task :copy do
375    puts "ANON COPY"
376  end
377end
378
379desc "Top level task to run the anonymous version of copy"
380task :anon => anon_ns[:copy]
381
382namespace "very" do
383  namespace "nested" do
384    task "run" => "rake:copy"
385  end
386end
387
388namespace "a" do
389  desc "Run task in the 'a' namespace"
390  task "run" do
391    puts "IN A"
392  end
393end
394
395namespace "b" do
396  desc "Run task in the 'b' namespace"
397  task "run" => "a:run" do
398    puts "IN B"
399  end
400end
401
402namespace "file1" do
403  file "xyz.rb" do
404    puts "XYZ1"
405  end
406end
407
408namespace "file2" do
409  file "xyz.rb" do
410    puts "XYZ2"
411  end
412end
413
414namespace "scopedep" do
415  task :prepare do
416    touch "scopedep.rb"
417    puts "PREPARE"
418  end
419  file "scopedep.rb" => [:prepare] do
420    puts "SCOPEDEP"
421  end
422end
423    NAMESPACE
424  end
425
426  def rakefile_nosearch
427    FileUtils.touch 'dummy'
428  end
429
430  def rakefile_rakelib
431    FileUtils.mkdir_p 'rakelib'
432
433    Dir.chdir 'rakelib' do
434      open 'test1.rb', 'w' do |io|
435        io << <<-TEST1
436task :default do
437  puts "TEST1"
438end
439        TEST1
440      end
441
442      open 'test2.rake', 'w' do |io|
443        io << <<-TEST1
444task :default do
445  puts "TEST2"
446end
447        TEST1
448      end
449    end
450  end
451
452  def rakefile_rbext
453    open 'rakefile.rb', 'w' do |io|
454      io << 'task :default do puts "OK" end'
455    end
456  end
457
458  def rakefile_unittest
459    rakefile '# Empty Rakefile for Unit Test'
460
461    readme = File.join 'subdir', 'README'
462    FileUtils.mkdir_p File.dirname readme
463
464    FileUtils.touch readme
465  end
466
467  def rakefile_verbose
468    rakefile <<-VERBOSE
469task :standalone_verbose_true do
470  verbose true
471  sh "#{RUBY} -e '0'"
472end
473
474task :standalone_verbose_false do
475  verbose false
476  sh "#{RUBY} -e '0'"
477end
478
479task :inline_verbose_default do
480  sh "#{RUBY} -e '0'"
481end
482
483task :inline_verbose_false do
484  sh "#{RUBY} -e '0'", :verbose => false
485end
486
487task :inline_verbose_true do
488  sh "#{RUBY} -e '0'", :verbose => true
489end
490
491task :block_verbose_true do
492  verbose(true) do
493    sh "#{RUBY} -e '0'"
494  end
495end
496
497task :block_verbose_false do
498  verbose(false) do
499    sh "#{RUBY} -e '0'"
500  end
501end
502    VERBOSE
503  end
504
505  def rakefile_test_signal
506    rakefile <<-TEST_SIGNAL
507require 'rake/testtask'
508
509Rake::TestTask.new(:a) do |t|
510  t.test_files = ['a_test.rb']
511end
512
513Rake::TestTask.new(:b) do |t|
514  t.test_files = ['b_test.rb']
515end
516
517task :test do
518  Rake::Task[:a].invoke
519  Rake::Task[:b].invoke
520end
521
522task :default => :test
523    TEST_SIGNAL
524    open 'a_test.rb', 'w' do |io|
525      io << 'puts "ATEST"' << "\n"
526      io << '$stdout.flush' << "\n"
527      io << 'Process.kill("TERM", $$)' << "\n"
528    end
529    open 'b_test.rb', 'w' do |io|
530      io << 'puts "BTEST"' << "\n"
531      io << '$stdout.flush' << "\n"
532    end
533  end
534
535  def rakefile_failing_test_task
536    rakefile <<-TEST_TASK
537require 'rake/testtask'
538
539task :default => :test
540Rake::TestTask.new(:test) do |t|
541  t.test_files = ['a_test.rb']
542end
543    TEST_TASK
544    open 'a_test.rb', 'w' do |io|
545      io << "require 'minitest/autorun'\n"
546      io << "class ExitTaskTest < MiniTest::Unit::TestCase\n"
547      io << "  def test_exit\n"
548      io << "    assert false, 'this should fail'\n"
549      io << "  end\n"
550      io << "end\n"
551    end
552  end
553
554  def rakefile_stand_alone_filelist
555    open 'stand_alone_filelist.rb', 'w' do |io|
556      io << "require 'rake/file_list'\n"
557      io << "FL = Rake::FileList['*.rb']\n"
558      io << "puts FL\n"
559    end
560  end
561
562end
563