summaryrefslogtreecommitdiff
path: root/test/rake/test_rake_file_task.rb
blob: a6a9fa2c510ee8bed735b9393f3071fb8104e2cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
require File.expand_path('../helper', __FILE__)
require 'fileutils'
require 'pathname'

class TestRakeFileTask < Rake::TestCase
  include Rake

  def setup
    super

    Task.clear
    @runs = Array.new
    FileUtils.rm_f NEWFILE
    FileUtils.rm_f OLDFILE
  end

  def test_file_need
    name = "dummy"
    file name

    ftask = Task[name]

    assert_equal name.to_s, ftask.name
    File.delete(ftask.name) rescue nil

    assert ftask.needed?, "file should be needed"

    open(ftask.name, "w") { |f| f.puts "HI" }

    assert_equal nil, ftask.prerequisites.map { |n| Task[n].timestamp }.max
    assert ! ftask.needed?, "file should not be needed"
  ensure
    File.delete(ftask.name) rescue nil
  end

  def test_file_times_new_depends_on_old
    create_timed_files(OLDFILE, NEWFILE)

    t1 = Rake.application.intern(FileTask, NEWFILE).enhance([OLDFILE])
    t2 = Rake.application.intern(FileTask, OLDFILE)
    assert ! t2.needed?, "Should not need to build old file"
    assert ! t1.needed?, "Should not need to rebuild new file because of old"
  end

  def test_file_times_new_depend_on_regular_task_timestamps
    load_phony

    name = "dummy"
    task name

    create_timed_files(NEWFILE)

    t1 = Rake.application.intern(FileTask, NEWFILE).enhance([name])

    assert t1.needed?, "depending on non-file task uses Time.now"

    task(name => :phony)

    assert t1.needed?, "unless the non-file task has a timestamp"
  end

  def test_file_times_old_depends_on_new
    create_timed_files(OLDFILE, NEWFILE)

    t1 = Rake.application.intern(FileTask, OLDFILE).enhance([NEWFILE])
    t2 = Rake.application.intern(FileTask, NEWFILE)
    assert ! t2.needed?, "Should not need to build new file"
    preq_stamp = t1.prerequisites.map { |t| Task[t].timestamp }.max
    assert_equal t2.timestamp, preq_stamp
    assert t1.timestamp < preq_stamp, "T1 should be older"
    assert t1.needed?, "Should need to rebuild old file because of new"
  end

  def test_file_depends_on_task_depend_on_file
    create_timed_files(OLDFILE, NEWFILE)

    file NEWFILE => [:obj] do |t| @runs << t.name end
    task :obj => [OLDFILE] do |t| @runs << t.name end
    file OLDFILE           do |t| @runs << t.name end

    Task[:obj].invoke
    Task[NEWFILE].invoke
    assert @runs.include?(NEWFILE)
  end

  def test_existing_file_depends_on_non_existing_file
    @ran = false

    create_file(OLDFILE)
    delete_file(NEWFILE)
    file NEWFILE do
      @ran = true
    end

    file OLDFILE => NEWFILE

    Task[OLDFILE].invoke

    assert @ran
  end

  def test_needed_eh_build_all
    create_file 'a'

    file 'a'

    a_task = Task['a']

    refute a_task.needed?

    Rake.application.options.build_all = true

    assert a_task.needed?
  ensure
    delete_file 'a'
  end

  def test_needed_eh_dependency
    create_file 'a', Time.now
    create_file 'b', Time.now - 60

    create_file 'c', Time.now
    create_file 'd', Time.now - 60

    file 'b' => 'a'

    b_task = Task['b']

    assert b_task.needed?

    file 'c' => 'd'

    c_task = Task['c']

    refute c_task.needed?
  ensure
    delete_file 'old'
    delete_file 'new'
  end

  def test_needed_eh_exists
    name = "dummy"
    file name

    ftask = Task[name]

    assert ftask.needed?

    create_file name

    refute ftask.needed?
  ensure
    delete_file name
  end

  def test_source_is_first_prerequisite
    t = file :f => ["preqA", "preqB"]
    assert_equal "preqA", t.source
  end

  def test_sources_is_all_prerequisites
    t = file :f => ["preqA", "preqB"]
    assert_equal ["preqA", "preqB"], t.sources
  end

  def test_task_can_be_pathname
      name = "dummy"
      file Pathname.new name

      ftask = Task[name]

      assert_equal name.to_s, ftask.name
  end

  def test_prerequisite_can_be_pathname
    t = file :f => Pathname.new("preq")
    assert_equal "preq", t.source
  end

  # I have currently disabled this test.  I'm not convinced that
  # deleting the file target on failure is always the proper thing to
  # do.  I'm willing to hear input on this topic.
  def ztest_file_deletes_on_failure
    task :obj
    file NEWFILE => [:obj] do |t|
      FileUtils.touch NEWFILE
      fail "Ooops"
    end
    assert Task[NEWFILE]
    begin
      Task[NEWFILE].invoke
    rescue Exception
    end
    assert(! File.exist?(NEWFILE), "NEWFILE should be deleted")
  end

  def load_phony
    load File.join(@rake_lib, "rake/phony.rb")
  end

end