lib/coderunner/merged_code_runner.rb in coderunner-0.14.24 vs lib/coderunner/merged_code_runner.rb in coderunner-0.15.0
- old
+ new
@@ -6,35 +6,94 @@
def merge_method(meth, *args)
send(meth, *args)
end
+ # This class allows the analysis of multiple root folders as if they were
+ # one. For every normal runner (instance of CodeRunner) that is added to the merged runner
+ # (instance of CodeRunner::Merged), the runs of that normal runner are added to the merged
+ # run_list. Normal runner function such as CodeRunner#graphkit() can then be called.
+ #
+ # In order to keep the run_list unique, the runs from each component runner are not added
+ # to the merged runner directly: instead they are wrapped in a container of class Run::Merged
+ # which behaves like a standard run object except that it redefines the id to be [runner_index, id].
+ # Thus, within the merged runner, the id of run 43 from the third runner to be added to the merged
+ # runner is [2,43].
+ #
class Merged < CodeRunner
+ # Iterates over the runners contained within the merged runner.
+ # E.g.
+ # merged_runner.each{|runner| p runner.root_folder}
def each
@runners.each{|r| yield(r)}
end
include Enumerable
+ # Create a new merged runner. <tt>runners</tt> is an array of standard runners
+ # (i.e. instances of CodeRunner).
def initialize(*runners)
@runners = []
r = runners[0]
r.instance_variables.each do |v|
instance_variable_set(v, r.instance_variable_get(v))
end
@run_list = {}
runners.each{|runner| add_runner(runner)}
end
+ # Raises an error. At the present time, submitting
+ # from a merged runner has no defined behaviour and
+ # is not implemented.
+ def submit(*args)
+ raise "Submitting from a merged runner is currently not supported"
+ end
+ # A string prepended to each line of the status output for merged
+ # runners... see CodeRunner#print_out
+ def merged_runner_info(run)
+ #run.id.inspect + " : "
+ run.id[0].to_s + ","
+ #""
+ end
+ # Merge an additional runner.
def add_runner(runner)
+ index = @runners.size
@runners.push runner
runner.run_list.each do |id, run|
#raise "Duplicate ids: #{id}" if @run_list[id]
- @run_list[id] = run
+ merged_run = Run::Merged.new(index, run)
+ @run_list[merged_run.id] = merged_run
end
@ids = @run_list.keys
end
+ # Call a method on each runner and combine the results according to
+ # the block.
+ # E.g.
+ # string_of_root_folders = merged_runner.merge_method(:root_folder){|string, folder| string << "," << folder}
def merge_method(meth, *args, &block)
results = @runners.map{|r| r.send(meth, *args)}
return results.inject{|o,n| yield(o,n)}
end
end
+ # This is a container for run objects for use in a merged runner.
+ # Basically its job is to route all methods to the run it contains,
+ # except for the id method, which is redefined.
+ #
+ # Instead of being a number, the id of the run is now an array of two
+ # numbers, of which the second is the id of the run contained, but the
+ # first is the index of the runner which the run corresponds to.
+ #
+ # Thus, within a merged runner (an instance of CodeRunner::Merged), each
+ # run has a unique id, and the merged runner can treat the Run::Merged objects
+ # exactly as if they were simply Run objects.
+ class Run::Merged
+ attr_reader :run
+ attr_accessor :id
+ def initialize(runner_index, run)
+ @runner_index = runner_index
+ @run = run
+ @id = [@runner_index, @run.id]
+ end
+ def method_missing(meth, *args)
+ @run.send(meth, *args)
+ end
+ end
end