rake 0.9.2.2 → 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. data/CHANGES +4 -0
  2. data/README.rdoc +10 -8
  3. data/Rakefile +6 -1
  4. data/TODO +1 -0
  5. data/bin/rake +4 -0
  6. data/doc/command_line_usage.rdoc +61 -12
  7. data/doc/release_notes/rake-0.9.2.2.rdoc +55 -0
  8. data/doc/release_notes/rake-0.9.3.rdoc +102 -0
  9. data/install.rb +1 -1
  10. data/lib/rake/application.rb +244 -140
  11. data/lib/rake/backtrace.rb +18 -0
  12. data/lib/rake/clean.rb +1 -1
  13. data/lib/rake/cloneable.rb +7 -16
  14. data/lib/rake/contrib/ftptools.rb +2 -1
  15. data/lib/rake/contrib/sys.rb +6 -6
  16. data/lib/rake/dsl_definition.rb +13 -7
  17. data/lib/rake/ext/module.rb +1 -1
  18. data/lib/rake/ext/string.rb +2 -1
  19. data/lib/rake/ext/time.rb +2 -1
  20. data/lib/rake/file_list.rb +2 -2
  21. data/lib/rake/file_utils_ext.rb +4 -3
  22. data/lib/rake/multi_task.rb +2 -5
  23. data/lib/rake/phony.rb +13 -0
  24. data/lib/rake/private_reader.rb +20 -0
  25. data/lib/rake/promise.rb +99 -0
  26. data/lib/rake/rake_module.rb +15 -0
  27. data/lib/rake/rdoctask.rb +1 -1
  28. data/lib/rake/runtest.rb +1 -1
  29. data/lib/rake/task.rb +29 -7
  30. data/lib/rake/task_arguments.rb +1 -1
  31. data/lib/rake/task_manager.rb +1 -1
  32. data/lib/rake/testtask.rb +5 -1
  33. data/lib/rake/thread_history_display.rb +48 -0
  34. data/lib/rake/thread_pool.rb +155 -0
  35. data/lib/rake/version.rb +6 -4
  36. data/lib/rake.rb +1 -0
  37. data/test/helper.rb +30 -0
  38. data/test/test_private_reader.rb +42 -0
  39. data/test/test_rake_application.rb +12 -1
  40. data/test/test_rake_application_options.rb +114 -4
  41. data/test/test_rake_backtrace.rb +81 -0
  42. data/test/test_rake_directory_task.rb +16 -5
  43. data/test/test_rake_file_task.rb +21 -1
  44. data/test/test_rake_functional.rb +22 -0
  45. data/test/test_rake_multi_task.rb +8 -0
  46. data/test/test_rake_reduce_compat.rb +65 -0
  47. data/test/test_rake_task.rb +50 -1
  48. data/test/test_rake_thread_pool.rb +123 -0
  49. data/test/test_thread_history_display.rb +91 -0
  50. metadata +53 -37
@@ -36,4 +36,4 @@ class Module
36
36
  rake_original_const_missing(const_name)
37
37
  end
38
38
  end
39
- end
39
+ end unless defined? Rake::REDUCE_COMPAT
@@ -4,6 +4,7 @@ require 'rake/ext/core'
4
4
  # Rake extension methods for String.
5
5
  #
6
6
  class String
7
+
7
8
  rake_extension("ext") do
8
9
  # Replace the file extension with +newext+. If there is no extension on
9
10
  # the string, append the new extension to the end. If the new extension
@@ -163,5 +164,5 @@ class String
163
164
  result
164
165
  end
165
166
  end
166
- end # class String
167
167
 
168
+ end
data/lib/rake/ext/time.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  #--
2
2
  # Extensions to time to allow comparisons with an early time class.
3
3
 
4
+ require 'rake/early_time'
5
+
4
6
  class Time
5
7
  alias rake_original_time_compare :<=>
6
8
  def <=>(other)
@@ -11,4 +13,3 @@ class Time
11
13
  end
12
14
  end
13
15
  end
14
-
@@ -286,7 +286,7 @@ module Rake
286
286
  matched = 0
287
287
  each do |fn|
288
288
  begin
289
- open(fn, "rb", *options) do |inf|
289
+ open(fn, "r", *options) do |inf|
290
290
  count = 0
291
291
  inf.each do |line|
292
292
  count += 1
@@ -340,7 +340,7 @@ module Rake
340
340
 
341
341
  # Add matching glob patterns.
342
342
  def add_matching(pattern)
343
- Dir[pattern].each do |fn|
343
+ Rake.glob(pattern).each do |fn|
344
344
  self << fn unless exclude?(fn)
345
345
  end
346
346
  end
@@ -21,12 +21,13 @@ module Rake
21
21
  $fileutils_verbose = true
22
22
  $fileutils_nowrite = false
23
23
 
24
- FileUtils::OPT_TABLE.each do |name, opts|
24
+ FileUtils.commands.each do |name|
25
+ opts = FileUtils.options_of name
25
26
  default_options = []
26
- if opts.include?(:verbose) || opts.include?("verbose")
27
+ if opts.include?("verbose")
27
28
  default_options << ':verbose => FileUtilsExt.verbose_flag'
28
29
  end
29
- if opts.include?(:noop) || opts.include?("noop")
30
+ if opts.include?("noop")
30
31
  default_options << ':noop => FileUtilsExt.nowrite_flag'
31
32
  end
32
33
 
@@ -5,11 +5,8 @@ module Rake
5
5
  #
6
6
  class MultiTask < Task
7
7
  private
8
- def invoke_prerequisites(args, invocation_chain)
9
- threads = @prerequisites.collect { |p|
10
- Thread.new(p) { |r| application[r, @scope].invoke_with_call_chain(args, invocation_chain) }
11
- }
12
- threads.each { |t| t.join }
8
+ def invoke_prerequisites(task_args, invocation_chain) # :nodoc:
9
+ invoke_prerequisites_concurrently(task_args, invocation_chain)
13
10
  end
14
11
  end
15
12
 
data/lib/rake/phony.rb ADDED
@@ -0,0 +1,13 @@
1
+ # Defines a :phony task that you can use as a dependency. This allows
2
+ # file-based tasks to use non-file-based tasks as prerequisites
3
+ # without forcing them to rebuild.
4
+ #
5
+ # See FileTask#out_of_date? and Task#timestamp for more info.
6
+
7
+ require 'rake'
8
+
9
+ task :phony
10
+
11
+ def (Rake::Task[:phony]).timestamp
12
+ Time.at 0
13
+ end
@@ -0,0 +1,20 @@
1
+ module Rake
2
+
3
+ # Include PrivateReader to use +private_reader+.
4
+ module PrivateReader # :nodoc: all
5
+
6
+ def self.included(base)
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+
12
+ # Declare a list of private accessors
13
+ def private_reader(*names)
14
+ attr_reader(*names)
15
+ private(*names)
16
+ end
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,99 @@
1
+ module Rake
2
+
3
+ # A Promise object represents a promise to do work (a chore) in the
4
+ # future. The promise is created with a block and a list of
5
+ # arguments for the block. Calling value will return the value of
6
+ # the promised chore.
7
+ #
8
+ # Used by ThreadPool.
9
+ #
10
+ class Promise # :nodoc: all
11
+ NOT_SET = Object.new.freeze # :nodoc:
12
+
13
+ attr_accessor :recorder
14
+
15
+ # Create a promise to do the chore specified by the block.
16
+ def initialize(args, &block)
17
+ @mutex = Mutex.new
18
+ @result = NOT_SET
19
+ @error = NOT_SET
20
+ @args = args.collect { |a| begin; a.dup; rescue; a; end }
21
+ @block = block
22
+ end
23
+
24
+ # Return the value of this promise.
25
+ #
26
+ # If the promised chore is not yet complete, then do the work
27
+ # synchronously. We will wait.
28
+ def value
29
+ unless complete?
30
+ stat :sleeping_on, :item_id => object_id
31
+ @mutex.synchronize do
32
+ stat :has_lock_on, :item_id => object_id
33
+ chore
34
+ stat :releasing_lock_on, :item_id => object_id
35
+ end
36
+ end
37
+ error? ? raise(@error) : @result
38
+ end
39
+
40
+ # If no one else is working this promise, go ahead and do the chore.
41
+ def work
42
+ stat :attempting_lock_on, :item_id => object_id
43
+ if @mutex.try_lock
44
+ stat :has_lock_on, :item_id => object_id
45
+ chore
46
+ stat :releasing_lock_on, :item_id => object_id
47
+ @mutex.unlock
48
+ else
49
+ stat :bailed_on, :item_id => object_id
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ # Perform the chore promised
56
+ def chore
57
+ if complete?
58
+ stat :found_completed, :item_id => object_id
59
+ return
60
+ end
61
+ stat :will_execute, :item_id => object_id
62
+ begin
63
+ @result = @block.call(*@args)
64
+ rescue Exception => e
65
+ @error = e
66
+ end
67
+ stat :did_execute, :item_id => object_id
68
+ discard
69
+ end
70
+
71
+ # Do we have a result for the promise
72
+ def result?
73
+ ! @result.equal?(NOT_SET)
74
+ end
75
+
76
+ # Did the promise throw an error
77
+ def error?
78
+ ! @error.equal?(NOT_SET)
79
+ end
80
+
81
+ # Are we done with the promise
82
+ def complete?
83
+ result? || error?
84
+ end
85
+
86
+ # free up these items for the GC
87
+ def discard
88
+ @args = nil
89
+ @block = nil
90
+ end
91
+
92
+ # Record execution statistics if there is a recorder
93
+ def stat(*args)
94
+ @recorder.call(*args) if @recorder
95
+ end
96
+
97
+ end
98
+
99
+ end
@@ -24,6 +24,21 @@ module Rake
24
24
  def load_rakefile(path)
25
25
  load(path)
26
26
  end
27
+
28
+ # Add files to the rakelib list
29
+ def add_rakelib(*files)
30
+ application.options.rakelib ||= []
31
+ files.each do |file|
32
+ application.options.rakelib << file
33
+ end
34
+ end
35
+
36
+ # Get a sorted list of files matching the pattern. This method
37
+ # should be prefered to Dir[pattern] and Dir.glob[pattern] because
38
+ # the files returned are guaranteed to be sorted.
39
+ def glob(pattern, *args)
40
+ Dir.glob(pattern, *args).sort
41
+ end
27
42
  end
28
43
 
29
44
  end
data/lib/rake/rdoctask.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # rake/rdoctask is deprecated in favor of rdoc/task
2
2
 
3
3
  if Rake.application
4
- Rake.application.deprecate('require \'rake/rdoctask\'', 'require \'rdoc/task\' (in RDoc 2.4.2+)', __FILE__)
4
+ Rake.application.deprecate('require \'rake/rdoctask\'', 'require \'rdoc/task\' (in RDoc 2.4.2+)', caller.first)
5
5
  end
6
6
 
7
7
  require 'rubygems'
data/lib/rake/runtest.rb CHANGED
@@ -5,7 +5,7 @@ module Rake
5
5
  include Test::Unit::Assertions
6
6
 
7
7
  def run_tests(pattern='test/test*.rb', log_enabled=false)
8
- Dir["#{pattern}"].each { |fn|
8
+ Rake.glob(pattern).each { |fn|
9
9
  $stderr.puts fn if log_enabled
10
10
  begin
11
11
  require fn
data/lib/rake/task.rb CHANGED
@@ -123,6 +123,7 @@ module Rake
123
123
  def clear
124
124
  clear_prerequisites
125
125
  clear_actions
126
+ clear_comments
126
127
  self
127
128
  end
128
129
 
@@ -138,6 +139,13 @@ module Rake
138
139
  self
139
140
  end
140
141
 
142
+ # Clear the existing comments on a rake task.
143
+ def clear_comments
144
+ @full_comment = nil
145
+ @comment = nil
146
+ self
147
+ end
148
+
141
149
  # Invoke the task if it is needed. Prerequisites are invoked first.
142
150
  def invoke(*args)
143
151
  task_args = TaskArguments.new(arg_names, args)
@@ -150,7 +158,7 @@ module Rake
150
158
  new_chain = InvocationChain.append(self, invocation_chain)
151
159
  @lock.synchronize do
152
160
  if application.options.trace
153
- $stderr.puts "** Invoke #{name} #{format_trace_flags}"
161
+ application.trace "** Invoke #{name} #{format_trace_flags}"
154
162
  end
155
163
  return if @already_invoked
156
164
  @already_invoked = true
@@ -171,10 +179,24 @@ module Rake
171
179
 
172
180
  # Invoke all the prerequisites of a task.
173
181
  def invoke_prerequisites(task_args, invocation_chain) # :nodoc:
174
- prerequisite_tasks.each { |prereq|
175
- prereq_args = task_args.new_scope(prereq.arg_names)
176
- prereq.invoke_with_call_chain(prereq_args, invocation_chain)
177
- }
182
+ if application.options.always_multitask
183
+ invoke_prerequisites_concurrently(task_args, invocation_chain)
184
+ else
185
+ prerequisite_tasks.each { |prereq|
186
+ prereq_args = task_args.new_scope(prereq.arg_names)
187
+ prereq.invoke_with_call_chain(prereq_args, invocation_chain)
188
+ }
189
+ end
190
+ end
191
+
192
+ # Invoke all the prerequisites of a task in parallel.
193
+ def invoke_prerequisites_concurrently(args, invocation_chain) # :nodoc:
194
+ futures = @prerequisites.collect do |p|
195
+ application.thread_pool.future(p) do |r|
196
+ application[r, @scope].invoke_with_call_chain(args, invocation_chain)
197
+ end
198
+ end
199
+ futures.each { |f| f.value }
178
200
  end
179
201
 
180
202
  # Format the trace flags for display.
@@ -190,11 +212,11 @@ module Rake
190
212
  def execute(args=nil)
191
213
  args ||= EMPTY_TASK_ARGS
192
214
  if application.options.dryrun
193
- $stderr.puts "** Execute (dry run) #{name}"
215
+ application.trace "** Execute (dry run) #{name}"
194
216
  return
195
217
  end
196
218
  if application.options.trace
197
- $stderr.puts "** Execute #{name}"
219
+ application.trace "** Execute #{name}"
198
220
  end
199
221
  application.enhance_with_matching_rule(name) if @actions.empty?
200
222
  @actions.each do |act|
@@ -47,7 +47,7 @@ module Rake
47
47
  keys.map { |k| lookup(k) }
48
48
  end
49
49
 
50
- def method_missing(sym, *args, &block)
50
+ def method_missing(sym, *args)
51
51
  lookup(sym.to_sym)
52
52
  end
53
53
 
@@ -238,7 +238,7 @@ module Rake
238
238
  end
239
239
 
240
240
  def trace_rule(level, message)
241
- $stderr.puts "#{" "*level}#{message}" if Rake.application.options.trace_rules
241
+ options.trace_output.puts "#{" "*level}#{message}" if Rake.application.options.trace_rules
242
242
  end
243
243
 
244
244
  # Attempt to create a rule given the list of prerequisites.
data/lib/rake/testtask.rb CHANGED
@@ -96,7 +96,11 @@ module Rake
96
96
  desc "Run tests" + (@name==:test ? "" : " for #{@name}")
97
97
  task @name do
98
98
  FileUtilsExt.verbose(@verbose) do
99
- ruby "#{ruby_opts_string} #{run_code} #{file_list_string} #{option_list}"
99
+ ruby "#{ruby_opts_string} #{run_code} #{file_list_string} #{option_list}" do |ok, status|
100
+ if !ok && status.respond_to?(:signaled?) && status.signaled?
101
+ raise SignalException.new(status.termsig)
102
+ end
103
+ end
100
104
  end
101
105
  end
102
106
  self
@@ -0,0 +1,48 @@
1
+ require 'rake/private_reader'
2
+
3
+ module Rake
4
+
5
+ class ThreadHistoryDisplay # :nodoc: all
6
+ include Rake::PrivateReader
7
+
8
+ private_reader :stats, :items, :threads
9
+
10
+ def initialize(stats)
11
+ @stats = stats
12
+ @items = { :_seq_ => 1 }
13
+ @threads = { :_seq_ => "A" }
14
+ end
15
+
16
+ def show
17
+ puts "Job History:"
18
+ stats.each do |stat|
19
+ stat[:data] ||= {}
20
+ rename(stat, :thread, threads)
21
+ rename(stat[:data], :item_id, items)
22
+ rename(stat[:data], :new_thread, threads)
23
+ rename(stat[:data], :deleted_thread, threads)
24
+ printf("%8d %2s %-20s %s\n",
25
+ (stat[:time] * 1_000_000).round,
26
+ stat[:thread],
27
+ stat[:event],
28
+ stat[:data].map { |k,v| "#{k}:#{v}" }.join(" "))
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def rename(hash, key, renames)
35
+ if hash && hash[key]
36
+ original = hash[key]
37
+ value = renames[original]
38
+ unless value
39
+ value = renames[:_seq_]
40
+ renames[:_seq_] = renames[:_seq_].succ
41
+ renames[original] = value
42
+ end
43
+ hash[key] = value
44
+ end
45
+ end
46
+ end
47
+
48
+ end
@@ -0,0 +1,155 @@
1
+ require 'thread'
2
+ require 'set'
3
+
4
+ require 'rake/promise'
5
+
6
+ module Rake
7
+
8
+ class ThreadPool # :nodoc: all
9
+
10
+ # Creates a ThreadPool object.
11
+ # The parameter is the size of the pool.
12
+ def initialize(thread_count)
13
+ @max_active_threads = [thread_count, 0].max
14
+ @threads = Set.new
15
+ @threads_mon = Monitor.new
16
+ @queue = Queue.new
17
+ @join_cond = @threads_mon.new_cond
18
+
19
+ @history_start_time = nil
20
+ @history = []
21
+ @history_mon = Monitor.new
22
+ @total_threads_in_play = 0
23
+ end
24
+
25
+ # Creates a future executed by the +ThreadPool+.
26
+ #
27
+ # The args are passed to the block when executing (similarly to
28
+ # <tt>Thread#new</tt>) The return value is an object representing
29
+ # a future which has been created and added to the queue in the
30
+ # pool. Sending <tt>#value</tt> to the object will sleep the
31
+ # current thread until the future is finished and will return the
32
+ # result (or raise an exception thrown from the future)
33
+ def future(*args, &block)
34
+ promise = Promise.new(args, &block)
35
+ promise.recorder = lambda { |*stats| stat(*stats) }
36
+
37
+ @queue.enq promise
38
+ stat :queued, :item_id => promise.object_id
39
+ start_thread
40
+ promise
41
+ end
42
+
43
+ # Waits until the queue of futures is empty and all threads have exited.
44
+ def join
45
+ @threads_mon.synchronize do
46
+ begin
47
+ stat :joining
48
+ @join_cond.wait unless @threads.empty?
49
+ stat :joined
50
+ rescue Exception => e
51
+ stat :joined
52
+ $stderr.puts e
53
+ $stderr.print "Queue contains #{@queue.size} items. Thread pool contains #{@threads.count} threads\n"
54
+ $stderr.print "Current Thread #{Thread.current} status = #{Thread.current.status}\n"
55
+ $stderr.puts e.backtrace.join("\n")
56
+ @threads.each do |t|
57
+ $stderr.print "Thread #{t} status = #{t.status}\n"
58
+ # 1.8 doesn't support Thread#backtrace
59
+ $stderr.puts t.backtrace.join("\n") if t.respond_to? :backtrace
60
+ end
61
+ raise e
62
+ end
63
+ end
64
+ end
65
+
66
+ # Enable the gathering of history events.
67
+ def gather_history #:nodoc:
68
+ @history_start_time = Time.now if @history_start_time.nil?
69
+ end
70
+
71
+ # Return a array of history events for the thread pool.
72
+ #
73
+ # History gathering must be enabled to be able to see the events
74
+ # (see #gather_history). Best to call this when the job is
75
+ # complete (i.e. after ThreadPool#join is called).
76
+ def history # :nodoc:
77
+ @history_mon.synchronize { @history.dup }.
78
+ sort_by { |i| i[:time] }.
79
+ each { |i| i[:time] -= @history_start_time }
80
+ end
81
+
82
+ # Return a hash of always collected statistics for the thread pool.
83
+ def statistics # :nodoc:
84
+ {
85
+ :total_threads_in_play => @total_threads_in_play,
86
+ :max_active_threads => @max_active_threads,
87
+ }
88
+ end
89
+
90
+ private
91
+
92
+ # processes one item on the queue. Returns true if there was an
93
+ # item to process, false if there was no item
94
+ def process_queue_item #:nodoc:
95
+ return false if @queue.empty?
96
+
97
+ # Even though we just asked if the queue was empty, it
98
+ # still could have had an item which by this statement
99
+ # is now gone. For this reason we pass true to Queue#deq
100
+ # because we will sleep indefinitely if it is empty.
101
+ promise = @queue.deq(true)
102
+ stat :dequeued, :item_id => promise.object_id
103
+ promise.work
104
+ return true
105
+
106
+ rescue ThreadError # this means the queue is empty
107
+ false
108
+ end
109
+
110
+ def start_thread # :nodoc:
111
+ @threads_mon.synchronize do
112
+ next unless @threads.count < @max_active_threads
113
+
114
+ t = Thread.new do
115
+ begin
116
+ while @threads.count <= @max_active_threads
117
+ break unless process_queue_item
118
+ end
119
+ ensure
120
+ @threads_mon.synchronize do
121
+ @threads.delete Thread.current
122
+ stat :ended, :thread_count => @threads.count
123
+ @join_cond.broadcast if @threads.empty?
124
+ end
125
+ end
126
+ end
127
+ @threads << t
128
+ stat :spawned, :new_thread => t.object_id, :thread_count => @threads.count
129
+ @total_threads_in_play = @threads.count if @threads.count > @total_threads_in_play
130
+ end
131
+ end
132
+
133
+ def stat(event, data=nil) # :nodoc:
134
+ return if @history_start_time.nil?
135
+ info = {
136
+ :event => event,
137
+ :data => data,
138
+ :time => Time.now,
139
+ :thread => Thread.current.object_id,
140
+ }
141
+ @history_mon.synchronize { @history << info }
142
+ end
143
+
144
+ # for testing only
145
+
146
+ def __queue__ # :nodoc:
147
+ @queue
148
+ end
149
+
150
+ def __threads__ # :nodoc:
151
+ @threads.dup
152
+ end
153
+ end
154
+
155
+ end
data/lib/rake/version.rb CHANGED
@@ -1,8 +1,10 @@
1
1
  module Rake
2
- VERSION = '0.9.2.2'
3
-
4
2
  module Version # :nodoc: all
5
- MAJOR, MINOR, BUILD, PATCH = VERSION.split('.')
6
- NUMBERS = [ MAJOR, MINOR, BUILD, PATCH ]
3
+ NUMBERS = [
4
+ MAJOR = 0,
5
+ MINOR = 9,
6
+ BUILD = 3,
7
+ ]
7
8
  end
9
+ VERSION = Version::NUMBERS.join('.')
8
10
  end
data/lib/rake.rb CHANGED
@@ -58,6 +58,7 @@ require 'rake/early_time'
58
58
  require 'rake/name_space'
59
59
  require 'rake/task_manager'
60
60
  require 'rake/application'
61
+ require 'rake/backtrace'
61
62
 
62
63
  $trace = false
63
64
 
data/test/helper.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'rubygems'
2
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
3
 
3
4
  begin
4
5
  gem 'minitest'
@@ -488,5 +489,34 @@ end
488
489
  VERBOSE
489
490
  end
490
491
 
492
+ def rakefile_test_signal
493
+ rakefile <<-TEST_SIGNAL
494
+ require 'rake/testtask'
495
+
496
+ Rake::TestTask.new(:a) do |t|
497
+ t.test_files = ['a_test.rb']
498
+ end
499
+
500
+ Rake::TestTask.new(:b) do |t|
501
+ t.test_files = ['b_test.rb']
502
+ end
503
+
504
+ task :test do
505
+ Rake::Task[:a].invoke rescue nil
506
+ Rake::Task[:b].invoke rescue nil
491
507
  end
492
508
 
509
+ task :default => :test
510
+ TEST_SIGNAL
511
+ open 'a_test.rb', 'w' do |io|
512
+ io << 'puts "ATEST"' << "\n"
513
+ io << '$stdout.flush' << "\n"
514
+ io << 'Process.kill("TERM", $$)' << "\n"
515
+ end
516
+ open 'b_test.rb', 'w' do |io|
517
+ io << 'puts "BTEST"' << "\n"
518
+ io << '$stdout.flush' << "\n"
519
+ end
520
+ end
521
+
522
+ end
@@ -0,0 +1,42 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+ require 'rake/private_reader'
3
+
4
+ class TestPrivateAttrs < Rake::TestCase
5
+
6
+ class Sample
7
+ include Rake::PrivateReader
8
+
9
+ private_reader :reader, :a
10
+
11
+ def initialize
12
+ @reader = :RVALUE
13
+ end
14
+
15
+ def get_reader
16
+ reader
17
+ end
18
+
19
+ end
20
+
21
+ def setup
22
+ super
23
+ @sample = Sample.new
24
+ end
25
+
26
+ def test_private_reader_is_private
27
+ assert_private do @sample.reader end
28
+ assert_private do @sample.a end
29
+ end
30
+
31
+ def test_private_reader_returns_data
32
+ assert_equal :RVALUE, @sample.get_reader
33
+ end
34
+
35
+ private
36
+
37
+ def assert_private
38
+ ex = assert_raises(NoMethodError) do yield end
39
+ assert_match(/private/, ex.message)
40
+ end
41
+
42
+ end