lib/atp/flow.rb in atp-0.2.0 vs lib/atp/flow.rb in atp-0.2.1
- old
+ new
@@ -1,23 +1,26 @@
module ATP
# Implements the main user API for building and interacting
# with an abstract test program
class Flow
- attr_reader :program
+ attr_reader :program, :name
# Returns the raw AST
attr_reader :raw
- def initialize(program)
+ def initialize(program, name = nil)
@program = program
+ @name = name
@builder = AST::Builder.new
@raw = builder.flow
end
# Returns a processed/optimized AST, this is the one that should be
# used to build and represent the given test flow
def ast
ast = Processors::PreCleaner.new.process(raw)
+ Validators::DuplicateIDs.new(self).process(ast)
+ Validators::MissingIDs.new(self).process(ast)
ast = Processors::Condition.new.process(ast)
ast = Processors::Relationship.new.process(ast)
ast = Processors::PostCleaner.new.process(ast)
end
@@ -42,64 +45,90 @@
# @option options [String] :description A description of what the test does, usually formatted in markdown
# @option options [Hash] :on_fail What action to take if the test fails, e.g. assign a bin
# @option options [Hash] :on_pass What action to take if the test passes
# @option options [Hash] :conditions What conditions must be met to execute the test
def test(instance, options = {})
+ extract_meta!(options)
r = options.delete(:return)
- if options[:context] == :current
- options[:conditions] = builder.context[:conditions]
- end
- # Allows any continue, bin, or soft bin argument passed in at the options top-level to be assumed
- # to be the action to take if the test fails
- if b = options.delete(:bin)
- options[:on_fail] ||= {}
- options[:on_fail][:bin] = b
- end
- if b = options.delete(:softbin) || b = options.delete(:sbin) || b = options.delete(:soft_bin)
- options[:on_fail] ||= {}
- options[:on_fail][:softbin] = b
- end
- if options.delete(:continue)
- options[:on_fail] ||= {}
- options[:on_fail][:continue] = true
- end
- builder.new_context
-
- t = builder.test(instance, options)
- unless options[:context] == :current
- open_conditions.each do |conditions|
- t = builder.apply_conditions(t, conditions)
+ t = apply_open_conditions(options) do |options|
+ # Allows any continue, bin, or soft bin argument passed in at the options top-level to be assumed
+ # to be the action to take if the test fails
+ if b = options.delete(:bin)
+ options[:on_fail] ||= {}
+ options[:on_fail][:bin] = b
end
+ if b = options.delete(:softbin) || b = options.delete(:sbin) || b = options.delete(:soft_bin)
+ options[:on_fail] ||= {}
+ options[:on_fail][:softbin] = b
+ end
+ if options.delete(:continue)
+ options[:on_fail] ||= {}
+ options[:on_fail][:continue] = true
+ end
+ builder.test(instance, options)
end
append(t) unless r
t
end
def bin(number, options = {})
- fail 'A :type option set to :pass or :fail is required when calling bin' unless options[:type]
- options[:bin] = number
- options[:softbin] ||= options[:soft_bin] || options[:sbin]
- append builder.set_result(options[:type], options)
+ extract_meta!(options)
+ t = apply_open_conditions(options) do |options|
+ fail 'A :type option set to :pass or :fail is required when calling bin' unless options[:type]
+ options[:bin] = number
+ options[:softbin] ||= options[:soft_bin] || options[:sbin]
+ builder.set_result(options[:type], options)
+ end
+ append(t)
end
def cz(instance, cz_setup, options = {})
- options[:return] = true
- append(builder.cz(cz_setup, test(instance, options)))
+ extract_meta!(options)
+ t = apply_open_conditions(options) do |options|
+ conditions = options.delete(:conditions)
+ options[:return] = true
+ builder.cz(cz_setup, test(instance, options), conditions: conditions)
+ end
+ append(t)
end
alias_method :characterize, :cz
# Append a log message line to the flow
def log(message, options = {})
- append builder.log(message)
+ extract_meta!(options)
+ t = apply_open_conditions(options) do |options|
+ builder.log(message, options)
+ end
+ append(t)
end
+ # Enable a flow control variable
+ def enable(var, options = {})
+ extract_meta!(options)
+ t = apply_open_conditions(options) do |options|
+ builder.enable_flow_flag(var, options)
+ end
+ append(t)
+ end
+
+ # Disable a flow control variable
+ def disable(var, options = {})
+ extract_meta!(options)
+ t = apply_open_conditions(options) do |options|
+ builder.disable_flow_flag(var, options)
+ end
+ append(t)
+ end
+
# Insert explicitly rendered content in to the flow
def render(str, options = {})
+ extract_meta!(options)
append builder.render(str)
end
def with_condition(options)
+ extract_meta!(options)
open_conditions.push(options)
yield
open_conditions.pop
end
alias_method :with_conditions, :with_condition
@@ -109,9 +138,28 @@
Formatters::Datalog.run_and_format(ast, options)
nil
end
private
+
+ def apply_open_conditions(options)
+ if options[:context] == :current
+ options[:conditions] = builder.context[:conditions]
+ end
+ builder.new_context
+ t = yield(options)
+ unless options[:context] == :current
+ open_conditions.each do |conditions|
+ t = builder.apply_conditions(t, conditions)
+ end
+ end
+ t
+ end
+
+ def extract_meta!(options)
+ builder.source_file = options.delete(:source_file) if options[:source_file]
+ builder.source_line_number = options.delete(:source_line_number) if options[:source_line_number]
+ end
# For testing
def raw=(ast)
@raw = ast
end