lib/atp/runner.rb in atp-0.3.3 vs lib/atp/runner.rb in atp-0.4.0
- old
+ new
@@ -3,36 +3,74 @@
# set of runtime conditions.
# A subset of the input AST will be returned containing only the nodes that would
# be hit when the flow is executed under the given conditions.
class Runner < Processor
def run(node, options = {})
+ options = {
+ evaluate_flow_flags: true,
+ evaluate_run_flags: true,
+ evaluate_set_result: true
+ }.merge(options)
@options = options
@completed = false
@groups = []
- process(Processors::AddIDs.new.run(node))
+ @groups_on_fail = []
+ @groups_on_pass = []
+ node = Processors::AddIDs.new.run(node)
+ node = Processors::AddSetResult.new.run(node)
+ process(node)
end
def on_flow(node)
- @flow = []
- process_all(node.children)
- node.updated(nil, @flow)
+ c = open_container do
+ process_all(node.children)
+ end
+ node.updated(nil, c)
end
+ def on_name(node)
+ container << node
+ end
+
def on_flow_flag(node)
- flag, enabled, *nodes = *node
- flag = [flag].flatten
- active = flag.any? { |f| flow_flags.include?(f) }
- if (enabled && active) || (!enabled && !active)
- process_all(nodes)
+ if @options[:evaluate_flow_flags]
+ flag, enabled, *nodes = *node
+ flag = [flag].flatten
+ active = flag.any? { |f| flow_flags.include?(f) }
+ if (enabled && active) || (!enabled && !active)
+ process_all(nodes)
+ end
+ else
+ c = open_container do
+ process_all(node.children)
+ end
+ container << node.updated(nil, node.children.take(2) + c)
end
end
def on_run_flag(node)
- flag, enabled, *nodes = *node
- flag = [flag].flatten
- active = flag.any? { |f| run_flags.include?(f) }
- if (enabled && active) || (!enabled && !active)
+ if @options[:evaluate_run_flags]
+ flag, enabled, *nodes = *node
+ flag = [flag].flatten
+ active = flag.any? { |f| run_flags.include?(f) }
+ if (enabled && active) || (!enabled && !active)
+ process_all(nodes)
+ end
+ else
+ c = open_container do
+ process_all(node.children)
+ end
+ container << node.updated(nil, node.children.take(2) + c)
+ end
+ end
+
+ # Not sure why this method is here, all test_result nodes should have been
+ # converted to run_flag nodes by now
+ def on_test_result(node)
+ id, passed, *nodes = *node
+ if (passed && !failed_test_ids.include?(id)) ||
+ (!passed && failed_test_ids.include?(id))
process_all(nodes)
end
end
def on_test(node)
@@ -41,61 +79,79 @@
if failed_test_ids.include?(id)
node = node.add(n0(:failed))
failed = true
end
end
- @flow << node unless completed?
+ # If there is a group on_fail, then remove any test specific one as that
+ # will be overridden
+ if @groups_on_fail.last
+ if n_on_fail = node.find(:on_fail)
+ node = node.remove(n_on_fail)
+ end
+ end
+ if @groups_on_pass.last
+ if n_on_pass = node.find(:on_pass)
+ node = node.remove(n_on_pass)
+ end
+ end
+ container << node unless completed?
if failed
# Give indication to the parent group that at least one test within it failed
if @groups.last
@groups.pop
@groups << false
end
if n = node.find(:on_fail)
- @continue = !!n.find(:continue)
+ # If it has been set by a parent group, don't clear it
+ orig = @continue
+ @continue ||= !!n.find(:continue)
process_all(n)
- @continue = false
+ @continue = orig
end
else
if n = node.find(:on_pass)
process_all(n)
end
end
end
def on_group(node)
- @groups << true # This will be set to false by any tests that fail within the group
- process_all(node.find(:members))
- if !@groups.pop # If failed
- if n = node.find(:on_fail)
- @continue = !!n.find(:continue)
- process_all(n)
- @continue = false
+ on_fail = node.find(:on_fail)
+ on_pass = node.find(:on_pass)
+ c = open_container do
+ @groups << true # This will be set to false by any tests that fail within the group
+ @groups_on_fail << on_fail
+ @groups_on_pass << on_pass
+ if on_fail
+ orig = @continue
+ @continue = !!on_fail.find(:continue)
+ process_all(node.children - [on_fail, on_pass])
+ @continue = orig
+ else
+ process_all(node.children - [on_fail, on_pass])
end
- else
- if n = node.find(:on_pass)
- process_all(n)
+ if !@groups.pop # If failed
+ if on_fail
+ @continue = !!on_fail.find(:continue)
+ process_all(on_fail)
+ @continue = false
+ end
+ else
+ if on_pass
+ process_all(on_pass)
+ end
end
+ @groups_on_fail.pop
+ @groups_on_pass.pop
end
+ container << node.updated(nil, c + [on_fail, on_pass])
end
- def on_members(node)
- # Do nothing, will be processed directly by the on_group handler
- end
-
- def on_test_result(node)
- id, passed, *nodes = *node
- if (passed && !failed_test_ids.include?(id)) ||
- (!passed && failed_test_ids.include?(id))
- process_all(nodes)
- end
- end
-
def on_set_result(node)
unless @continue
- @flow << node unless completed?
- @completed = true
+ container << node unless completed?
+ @completed = true if @options[:evaluate_set_result]
end
end
def on_set_run_flag(node)
run_flags << node.to_a[0]
@@ -108,11 +164,11 @@
def on_disable_flow_flag(node)
flow_flags.delete(node.value)
end
def on_log(node)
- @flow << node unless completed?
+ container << node unless completed?
end
alias_method :on_render, :on_log
def on_job(node)
jobs, state, *nodes = *node
@@ -148,8 +204,19 @@
@flow_flags ||= [@options[:flow_flag] || @options[:flow_flags]].flatten.compact
end
def completed?
@completed
+ end
+
+ def open_container(c = [])
+ @containers ||= []
+ @containers << c
+ yield
+ @containers.pop
+ end
+
+ def container
+ @containers.last
end
end
end