lib/qed/script.rb in qed-1.1.0 vs lib/qed/script.rb in qed-1.2
- old
+ new
@@ -1,6 +1,7 @@
module QED
+ require 'yaml'
require 'facets/dir/ascend'
require 'ae'
require 'qed/reporter/dotprogress'
@@ -30,16 +31,21 @@
def initialize(file, output=nil)
@file = file
@output = output || Reporter::Verbatim.new #(self)
source = File.read(file)
- index = source.rindex('---')
+ index = source.rindex('---') || source.size
@source = source[0...index]
- @helper = source[index+3...-1].strip
+ @helper = source[index+3...-1].to_s.strip
end
+ # File basename less extension.
+ def name
+ @name ||= File.basename(file).chomp(File.extname(file))
+ end
+
#def convert
# @source.gsub(/^\w/, '# \1')
#end
# Run the script.
@@ -51,34 +57,86 @@
case step
when /^[=#]/
output.report_header(step)
when /^\S/
output.report_comment(step)
+ context.When.each do |(regex, proc)|
+ if md = regex.match(step)
+ proc.call(*md[1..-1])
+ end
+ end
else
- run_step(step)
+ #if context.table
+ # run_table(step)
+ #else
+ run_step(step)
+ #end
end
end
end
#
- def run_step(step, &blk)
- context.before.call if context.before
+ def run_step(step=nil, &blk)
+ context.Before.call if context.Before
begin
if blk
blk.call #eval(step, context._binding)
else
eval(step, context._binding, @file) # TODO: would be nice to know file and lineno here
end
- output.report_pass(step)
+ output.report_pass(step) if step
rescue Assertion => error
output.report_fail(step, error)
rescue Exception => error
output.report_error(step, error)
ensure
+ context.After.call if context.After
+ end
+ end
+
+=begin
+ #
+ def run_table(step)
+ file = context.table
+ Dir.ascend(Dir.pwd) do |path|
+ f1 = File.join(path, file)
+ f2 = File.join(path, 'fixtures', file)
+ fr = File.file?(f1) ? f1 : File.exist?(f2) ? f2 : nil
+ (file = fr; break) if fr
+ end
+ output.report_pass(step) #step)
+
+ tbl = YAML.load(File.new(file))
+ key = tbl.shift
+ tbl.each do |set|
+ assign = key.zip(set).map{ |k, v| "#{k}=#{v.inspect};" }.join
+ run_table_step(assign + step, set)
+ #run_step(set.inspect.tabto(4)){ blk.call(set) }
+ #@_script.run_step(set.to_yaml.tabto(2)){ blk.call(set) }
+ #@_script.output.report_table(set)
+ end
+ #output.report_pass(step) #step)
+ context.table = nil
+ end
+
+ #
+ #def run_table_step(step, set)
+ def run_table_step(set, &blk)
+ context.before.call if context.before
+ begin
+ #eval(step, context._binding, @file) # TODO: would be nice to know file and lineno here
+ blk.call(*set)
+ output.report_pass(' ' + set.inspect) #step)
+ rescue Assertion => error
+ output.report_fail(set.inspect, error)
+ rescue Exception => error
+ output.report_error(set.inspect, error)
+ ensure
context.after.call if context.after
end
end
+=end
# Cut-up script into steps.
def steps
@steps ||= (
code = false
@@ -86,18 +144,18 @@
steps = []
@source.each_line do |line|
if /^\s*$/.match line
str << line
elsif /^[=]/.match line
- steps << str.chomp("\n")
- steps << line.chomp("\n")
+ steps << str #.chomp("\n")
+ steps << line #.chomp("\n")
str = ''
#str << line
code = false
elsif /^\S/.match line
if code
- steps << str.chomp("\n")
+ steps << str #.chomp("\n")
str = ''
str << line
code = false
else
str << line
@@ -112,10 +170,11 @@
code = true
end
end
end
steps << str
+ #steps.map{ |s| s.chomp("\n") }
steps
)
end
# The run context.
@@ -126,59 +185,107 @@
end
#
class Context < Module
+ TABLE = /^TABLE\[(.*?)\]/i
+
def initialize(script)
@_script = script
+ @_when = []
+ @_tables = []
end
def _binding
@_binding ||= binding
end
- # Set before step.
- def before(&f)
- @_before = f if f
+ # Before each step.
+ def Before(&procedure)
+ @_before = procedure if procedure
@_before
end
- # Set after step.
- def after(&f)
- @_after = f if f
+ # After each step.
+ def After(&procedure)
+ @_after = procedure if procedure
@_after
end
- # Table-based steps.
- def table(file=nil, &blk)
- require 'yaml'
-
- file ||= File.basename(@_script.file).chomp(File.extname(@_script.file)) + '.yaml'
-
- Dir.ascend(Dir.pwd) do |path|
- f1 = File.join(path, file)
- f2 = File.join(path, 'fixtures', file)
- fr = File.file?(f1) ? f1 : File.exist?(f2) ? f2 : nil
- (file = fr; break) if fr
+ #
+ def When(pattern=nil, &procedure)
+ return @_when unless procedure
+ raise ArgumentError unless pattern
+ unless Regexp === pattern
+ pattern = __when_string_to_regexp(pattern)
end
+ @_when << [pattern, procedure]
+ end
+ # Table-based steps.
+ def Table(file=nil, &blk)
+ file = file || @_tables.last
tbl = YAML.load(File.new(file))
tbl.each do |set|
- @_script.run_step(set.to_yaml.tabto(2)){ blk.call(set) }
- #@_script.output.report_table(set)
+ blk.call(*set)
end
+ @_tables << file
end
- def fixture(fname, content=nil)
- raise if File.directory?(fname)
+ # Read/Write a fixture.
+ def Data(file, &content)
+ raise if File.directory?(file)
if content
FileUtils.mkdir_p(File.dirname(fname))
- File.open(fname, 'w'){ |f| f << content }
+ case File.extname(file)
+ when '.yml', '.yaml'
+ File.open(file, 'w'){ |f| f << content.call.to_yaml }
+ else
+ File.open(file, 'w'){ |f| f << content.call }
+ end
else
- raise LoadError, "no such fixture file -- #{fname}" unless File.exist?(fname)
- File.read(fname)
+ #raise LoadError, "no such fixture file -- #{fname}" unless File.exist?(fname)
+ case File.extname(file)
+ when '.yml', '.yaml'
+ YAML.load(File.new(file))
+ else
+ File.read(file)
+ end
end
end
+
+ private
+
+ def __when_string_to_regexp(str)
+ str = str.split(/(\(\(.*?\)\))(?!\))/).map{ |x|
+ x =~ /\A\(\((.*)\)\)\z/ ? $1 : Regexp.escape(x)
+ }.join
+ str = str.gsub(/(\\\ )+/, '\s+')
+ Regexp.new(str, Regexp::IGNORECASE)
+
+ #rexps = []
+ #str = str.gsub(/\(\((.*?)\)\)/) do |m|
+ # rexps << '(' + $1 + ')'
+ # "\0"
+ #end
+ #str = Regexp.escape(str)
+ #rexps.each do |r|
+ # str = str.sub("\0", r)
+ #end
+ #str = str.gsub(/(\\\ )+/, '\s+')
+ #Regexp.new(str, Regexp::IGNORECASE)
+ end
+
+ #
+ # check only local and maybe start paths
+ #def __locate_file(file)
+ # Dir.ascend(Dir.pwd) do |path|
+ # f1 = File.join(path, file)
+ # f2 = File.join(path, 'fixtures', file)
+ # fr = File.file?(f1) ? f1 : File.exist?(f2) ? f2 : nil
+ # (file = fr; break) if fr
+ # end
+ #end
end
end