1require File.expand_path('../helper', __FILE__) 2require 'fileutils' 3 4class TestRakeFileTask < Rake::TestCase 5 include Rake 6 7 def setup 8 super 9 10 Task.clear 11 @runs = Array.new 12 FileUtils.rm_f NEWFILE 13 FileUtils.rm_f OLDFILE 14 end 15 16 def test_file_need 17 name = "dummy" 18 file name 19 20 ftask = Task[name] 21 22 assert_equal name.to_s, ftask.name 23 File.delete(ftask.name) rescue nil 24 25 assert ftask.needed?, "file should be needed" 26 27 open(ftask.name, "w") { |f| f.puts "HI" } 28 29 assert_equal nil, ftask.prerequisites.collect{|n| Task[n].timestamp}.max 30 assert ! ftask.needed?, "file should not be needed" 31 ensure 32 File.delete(ftask.name) rescue nil 33 end 34 35 def test_file_times_new_depends_on_old 36 create_timed_files(OLDFILE, NEWFILE) 37 38 t1 = Rake.application.intern(FileTask, NEWFILE).enhance([OLDFILE]) 39 t2 = Rake.application.intern(FileTask, OLDFILE) 40 assert ! t2.needed?, "Should not need to build old file" 41 assert ! t1.needed?, "Should not need to rebuild new file because of old" 42 end 43 44 def test_file_times_new_depend_on_regular_task_timestamps 45 load_phony 46 47 name = "dummy" 48 task name 49 50 create_timed_files(NEWFILE) 51 52 t1 = Rake.application.intern(FileTask, NEWFILE).enhance([name]) 53 54 assert t1.needed?, "depending on non-file task uses Time.now" 55 56 task(name => :phony) 57 58 assert ! t1.needed?, "unless the non-file task has a timestamp" 59 end 60 61 def test_file_times_old_depends_on_new 62 create_timed_files(OLDFILE, NEWFILE) 63 64 t1 = Rake.application.intern(FileTask,OLDFILE).enhance([NEWFILE]) 65 t2 = Rake.application.intern(FileTask, NEWFILE) 66 assert ! t2.needed?, "Should not need to build new file" 67 preq_stamp = t1.prerequisites.collect{|t| Task[t].timestamp}.max 68 assert_equal t2.timestamp, preq_stamp 69 assert t1.timestamp < preq_stamp, "T1 should be older" 70 assert t1.needed?, "Should need to rebuild old file because of new" 71 end 72 73 def test_file_depends_on_task_depend_on_file 74 create_timed_files(OLDFILE, NEWFILE) 75 76 file NEWFILE => [:obj] do |t| @runs << t.name end 77 task :obj => [OLDFILE] do |t| @runs << t.name end 78 file OLDFILE do |t| @runs << t.name end 79 80 Task[:obj].invoke 81 Task[NEWFILE].invoke 82 assert ! @runs.include?(NEWFILE) 83 end 84 85 def test_existing_file_depends_on_non_existing_file 86 @ran = false 87 88 create_file(OLDFILE) 89 delete_file(NEWFILE) 90 file NEWFILE do 91 @ran = true 92 end 93 94 file OLDFILE => NEWFILE 95 96 Task[OLDFILE].invoke 97 98 assert @ran 99 end 100 101 # I have currently disabled this test. I'm not convinced that 102 # deleting the file target on failure is always the proper thing to 103 # do. I'm willing to hear input on this topic. 104 def ztest_file_deletes_on_failure 105 task :obj 106 file NEWFILE => [:obj] do |t| 107 FileUtils.touch NEWFILE 108 fail "Ooops" 109 end 110 assert Task[NEWFILE] 111 begin 112 Task[NEWFILE].invoke 113 rescue Exception 114 end 115 assert( ! File.exist?(NEWFILE), "NEWFILE should be deleted") 116 end 117 118 def load_phony 119 load File.join(@rake_lib, "rake/phony.rb") 120 end 121 122end 123