/tools/Ruby/lib/ruby/gems/1.8/gems/rake-0.9.2/test/test_rake_rules.rb

http://github.com/agross/netopenspace · Ruby · 346 lines · 310 code · 35 blank · 1 comment · 0 complexity · b74f8a3ce1b56cb848257ea20d767272 MD5 · raw file

  1. require File.expand_path('../helper', __FILE__)
  2. require 'fileutils'
  3. ######################################################################
  4. class TestRakeRules < Rake::TestCase
  5. include Rake
  6. SRCFILE = "testdata/abc.c"
  7. SRCFILE2 = "testdata/xyz.c"
  8. FTNFILE = "testdata/abc.f"
  9. OBJFILE = "testdata/abc.o"
  10. FOOFILE = "testdata/foo"
  11. DOTFOOFILE = "testdata/.foo"
  12. def setup
  13. super
  14. Task.clear
  15. @runs = []
  16. FileUtils.mkdir_p 'testdata' # HACK use tmpdir
  17. end
  18. def teardown
  19. FileList['testdata/*'].uniq.each do |f| rm_r(f, :verbose=>false) end
  20. super
  21. end
  22. def test_multiple_rules1
  23. create_file(FTNFILE)
  24. delete_file(SRCFILE)
  25. delete_file(OBJFILE)
  26. rule(/\.o$/ => ['.c']) do @runs << :C end
  27. rule(/\.o$/ => ['.f']) do @runs << :F end
  28. t = Task[OBJFILE]
  29. t.invoke
  30. Task[OBJFILE].invoke
  31. assert_equal [:F], @runs
  32. end
  33. def test_multiple_rules2
  34. create_file(FTNFILE)
  35. delete_file(SRCFILE)
  36. delete_file(OBJFILE)
  37. rule(/\.o$/ => ['.f']) do @runs << :F end
  38. rule(/\.o$/ => ['.c']) do @runs << :C end
  39. Task[OBJFILE].invoke
  40. assert_equal [:F], @runs
  41. end
  42. def test_create_with_source
  43. create_file(SRCFILE)
  44. rule(/\.o$/ => ['.c']) do |t|
  45. @runs << t.name
  46. assert_equal OBJFILE, t.name
  47. assert_equal SRCFILE, t.source
  48. end
  49. Task[OBJFILE].invoke
  50. assert_equal [OBJFILE], @runs
  51. end
  52. def test_single_dependent
  53. create_file(SRCFILE)
  54. rule(/\.o$/ => '.c') do |t|
  55. @runs << t.name
  56. end
  57. Task[OBJFILE].invoke
  58. assert_equal [OBJFILE], @runs
  59. end
  60. def test_rule_can_be_created_by_string
  61. create_file(SRCFILE)
  62. rule '.o' => ['.c'] do |t|
  63. @runs << t.name
  64. end
  65. Task[OBJFILE].invoke
  66. assert_equal [OBJFILE], @runs
  67. end
  68. def test_rule_prereqs_can_be_created_by_string
  69. create_file(SRCFILE)
  70. rule '.o' => '.c' do |t|
  71. @runs << t.name
  72. end
  73. Task[OBJFILE].invoke
  74. assert_equal [OBJFILE], @runs
  75. end
  76. def test_plain_strings_as_dependents_refer_to_files
  77. create_file(SRCFILE)
  78. rule '.o' => SRCFILE do |t|
  79. @runs << t.name
  80. end
  81. Task[OBJFILE].invoke
  82. assert_equal [OBJFILE], @runs
  83. end
  84. def test_file_names_beginning_with_dot_can_be_tricked_into_referring_to_file
  85. verbose(false) do
  86. chdir("testdata") do
  87. create_file('.foo')
  88. rule '.o' => "./.foo" do |t|
  89. @runs << t.name
  90. end
  91. Task[OBJFILE].invoke
  92. assert_equal [OBJFILE], @runs
  93. end
  94. end
  95. end
  96. def test_file_names_beginning_with_dot_can_be_wrapped_in_lambda
  97. verbose(false) do
  98. chdir("testdata") do
  99. create_file(".foo")
  100. rule '.o' => lambda{".foo"} do |t|
  101. @runs << "#{t.name} - #{t.source}"
  102. end
  103. Task[OBJFILE].invoke
  104. assert_equal ["#{OBJFILE} - .foo"], @runs
  105. end
  106. end
  107. end
  108. def test_file_names_containing_percent_can_be_wrapped_in_lambda
  109. verbose(false) do
  110. chdir("testdata") do
  111. create_file("foo%x")
  112. rule '.o' => lambda{"foo%x"} do |t|
  113. @runs << "#{t.name} - #{t.source}"
  114. end
  115. Task[OBJFILE].invoke
  116. assert_equal ["#{OBJFILE} - foo%x"], @runs
  117. end
  118. end
  119. end
  120. def test_non_extension_rule_name_refers_to_file
  121. verbose(false) do
  122. chdir("testdata") do
  123. create_file("abc.c")
  124. rule "abc" => '.c' do |t|
  125. @runs << t.name
  126. end
  127. Task["abc"].invoke
  128. assert_equal ["abc"], @runs
  129. end
  130. end
  131. end
  132. def test_pathmap_automatically_applies_to_name
  133. verbose(false) do
  134. chdir("testdata") do
  135. create_file("zzabc.c")
  136. rule ".o" => 'zz%{x,a}n.c' do |t|
  137. @runs << "#{t.name} - #{t.source}"
  138. end
  139. Task["xbc.o"].invoke
  140. assert_equal ["xbc.o - zzabc.c"], @runs
  141. end
  142. end
  143. end
  144. def test_plain_strings_are_just_filenames
  145. verbose(false) do
  146. chdir("testdata") do
  147. create_file("plainname")
  148. rule ".o" => 'plainname' do |t|
  149. @runs << "#{t.name} - #{t.source}"
  150. end
  151. Task["xbc.o"].invoke
  152. assert_equal ["xbc.o - plainname"], @runs
  153. end
  154. end
  155. end
  156. def test_rule_runs_when_explicit_task_has_no_actions
  157. create_file(SRCFILE)
  158. create_file(SRCFILE2)
  159. delete_file(OBJFILE)
  160. rule '.o' => '.c' do |t|
  161. @runs << t.source
  162. end
  163. file OBJFILE => [SRCFILE2]
  164. Task[OBJFILE].invoke
  165. assert_equal [SRCFILE], @runs
  166. end
  167. def test_close_matches_on_name_do_not_trigger_rule
  168. create_file("testdata/x.c")
  169. rule '.o' => ['.c'] do |t|
  170. @runs << t.name
  171. end
  172. assert_raises(RuntimeError) { Task['testdata/x.obj'].invoke }
  173. assert_raises(RuntimeError) { Task['testdata/x.xyo'].invoke }
  174. end
  175. def test_rule_rebuilds_obj_when_source_is_newer
  176. create_timed_files(OBJFILE, SRCFILE)
  177. rule(/\.o$/ => ['.c']) do
  178. @runs << :RULE
  179. end
  180. Task[OBJFILE].invoke
  181. assert_equal [:RULE], @runs
  182. end
  183. def test_rule_with_two_sources_runs_if_both_sources_are_present
  184. create_timed_files(OBJFILE, SRCFILE, SRCFILE2)
  185. rule OBJFILE => [lambda{SRCFILE}, lambda{SRCFILE2}] do
  186. @runs << :RULE
  187. end
  188. Task[OBJFILE].invoke
  189. assert_equal [:RULE], @runs
  190. end
  191. def test_rule_with_two_sources_but_one_missing_does_not_run
  192. create_timed_files(OBJFILE, SRCFILE)
  193. delete_file(SRCFILE2)
  194. rule OBJFILE => [lambda{SRCFILE}, lambda{SRCFILE2}] do
  195. @runs << :RULE
  196. end
  197. Task[OBJFILE].invoke
  198. assert_equal [], @runs
  199. end
  200. def test_rule_with_two_sources_builds_both_sources
  201. task 'x.aa'
  202. task 'x.bb'
  203. rule '.a' => '.aa' do
  204. @runs << "A"
  205. end
  206. rule '.b' => '.bb' do
  207. @runs << "B"
  208. end
  209. rule ".c" => ['.a', '.b'] do
  210. @runs << "C"
  211. end
  212. Task["x.c"].invoke
  213. assert_equal ["A", "B", "C"], @runs.sort
  214. end
  215. def test_second_rule_runs_when_first_rule_doesnt
  216. create_timed_files(OBJFILE, SRCFILE)
  217. delete_file(SRCFILE2)
  218. rule OBJFILE => [lambda{SRCFILE}, lambda{SRCFILE2}] do
  219. @runs << :RULE1
  220. end
  221. rule OBJFILE => [lambda{SRCFILE}] do
  222. @runs << :RULE2
  223. end
  224. Task[OBJFILE].invoke
  225. assert_equal [:RULE2], @runs
  226. end
  227. def test_second_rule_doest_run_if_first_triggers
  228. create_timed_files(OBJFILE, SRCFILE, SRCFILE2)
  229. rule OBJFILE => [lambda{SRCFILE}, lambda{SRCFILE2}] do
  230. @runs << :RULE1
  231. end
  232. rule OBJFILE => [lambda{SRCFILE}] do
  233. @runs << :RULE2
  234. end
  235. Task[OBJFILE].invoke
  236. assert_equal [:RULE1], @runs
  237. end
  238. def test_second_rule_doest_run_if_first_triggers_with_reversed_rules
  239. create_timed_files(OBJFILE, SRCFILE, SRCFILE2)
  240. rule OBJFILE => [lambda{SRCFILE}] do
  241. @runs << :RULE1
  242. end
  243. rule OBJFILE => [lambda{SRCFILE}, lambda{SRCFILE2}] do
  244. @runs << :RULE2
  245. end
  246. Task[OBJFILE].invoke
  247. assert_equal [:RULE1], @runs
  248. end
  249. def test_rule_with_proc_dependent_will_trigger
  250. mkdir_p("testdata/src/jw")
  251. create_file("testdata/src/jw/X.java")
  252. rule %r(classes/.*\.class) => [
  253. proc { |fn| fn.pathmap("%{classes,testdata/src}d/%n.java") }
  254. ] do |task|
  255. assert_equal task.name, 'classes/jw/X.class'
  256. assert_equal task.source, 'testdata/src/jw/X.java'
  257. @runs << :RULE
  258. end
  259. Task['classes/jw/X.class'].invoke
  260. assert_equal [:RULE], @runs
  261. ensure
  262. rm_r("testdata/src", :verbose=>false) rescue nil
  263. end
  264. def test_proc_returning_lists_are_flattened_into_prereqs
  265. ran = false
  266. mkdir_p("testdata/flatten")
  267. create_file("testdata/flatten/a.txt")
  268. task 'testdata/flatten/b.data' do |t|
  269. ran = true
  270. touch t.name, :verbose => false
  271. end
  272. rule '.html' =>
  273. proc { |fn|
  274. [
  275. fn.ext("txt"),
  276. "testdata/flatten/b.data"
  277. ]
  278. } do |task|
  279. end
  280. Task['testdata/flatten/a.html'].invoke
  281. assert ran, "Should have triggered flattened dependency"
  282. ensure
  283. rm_r("testdata/flatten", :verbose=>false) rescue nil
  284. end
  285. def test_recursive_rules_will_work_as_long_as_they_terminate
  286. actions = []
  287. create_file("testdata/abc.xml")
  288. rule '.y' => '.xml' do actions << 'y' end
  289. rule '.c' => '.y' do actions << 'c'end
  290. rule '.o' => '.c' do actions << 'o'end
  291. rule '.exe' => '.o' do actions << 'exe'end
  292. Task["testdata/abc.exe"].invoke
  293. assert_equal ['y', 'c', 'o', 'exe'], actions
  294. end
  295. def test_recursive_rules_that_dont_terminate_will_overflow
  296. create_file("testdata/a.a")
  297. prev = 'a'
  298. ('b'..'z').each do |letter|
  299. rule ".#{letter}" => ".#{prev}" do |t| puts "#{t.name}" end
  300. prev = letter
  301. end
  302. ex = assert_raises(Rake::RuleRecursionOverflowError) {
  303. Task["testdata/a.z"].invoke
  304. }
  305. assert_match(/a\.z => testdata\/a.y/, ex.message)
  306. end
  307. def test_rules_with_bad_dependents_will_fail
  308. rule "a" => [ 1 ] do |t| puts t.name end
  309. assert_raises(RuntimeError) do Task['a'].invoke end
  310. end
  311. end