lib/qed/evaluator.rb in qed-2.4.0 vs lib/qed/evaluator.rb in qed-2.5.0
- old
+ new
@@ -96,10 +96,11 @@
pass!(step)
end
end
# TODO: Not sure how to handle loading links in --comment runner mode.
+ # TODO: Do not think Scope should be reuseud by imported demo.
def evaluate_links(step)
step.text.scan(/\[qed:\/\/(.*?)\]/) do |match|
file = $1
# relative to demo script
if File.exist?(File.join(@script.directory,file))
@@ -108,11 +109,11 @@
# ruby or another demo
case File.extname(file)
when '.rb'
import!(file)
else
- Demo.new(file, @script.applique, :scope=>@script.scope).run
+ Demo.new(file, :scope=>@script.scope).run
end
end
end
#
@@ -140,22 +141,128 @@
end
# Dispatch event to observers and advice.
def advise!(signal, *args)
@observers.each{ |o| o.update(signal, *args) }
- @script.advise(signal, *args)
+
+ #@script.advise(signal, *args)
+ case signal
+ when :when
+ call_matchers(*args)
+ else
+ call_signals(signal, *args)
+ end
end
#
#def advise_when!(match)
# @advice.call_when(match)
#end
+ # React to an event.
+ #
+ # TODO: Should events short circuit on finding first match?
+ # In other words, should there be only one of each type of signal
+ # ragardless of how many applique layers?
+ def call_signals(type, *args)
+ @script.applique.each do |a|
+ signals = a.__signals__
+ proc = signals[type.to_sym]
+ #signals.each do |set|
+ #proc = set[type.to_sym]
+ #proc.call(*args) if proc
+ @script.scope.instance_exec(*args, &proc) if proc
+ #end
+ end
+
+ #@script.applique.each do |a|
+ # signals = a.__signals__
+ # proc = signals[type.to_sym]
+ # if proc
+ # @script.scope.instance_exec(*args, &proc)
+ # break
+ # end
+ #end
+
+ #meth = "qed_#{type}"
+ #if @script.scope.respond_to?(meth)
+ # meth = @script.scope.method(meth)
+ # if meth.arity == 0
+ # meth.call
+ # else
+ # meth.call(*args)
+ # end
+ #end
+
+ #@script.scope.__send__(meth, *args)
+ end
+
+ #
+ def call_matchers(section)
+ match = section.text
+ args = section.arguments
+ @script.applique.each do |a|
+ matchers = a.__matchers__
+ matchers.each do |(patterns, proc)|
+ compare = match
+ matched = true
+ params = []
+ patterns.each do |pattern|
+ case pattern
+ when Regexp
+ regex = pattern
+ else
+ regex = match_string_to_regexp(pattern)
+ end
+ if md = regex.match(compare)
+ params.concat(md[1..-1])
+ compare = md.post_match
+ else
+ matched = false
+ break
+ end
+ end
+ if matched
+ params += args
+ #proc.call(*params)
+ @script.scope.instance_exec(*params, &proc)
+ end
+ end
+ end
+ end
+
+ # Convert matching string into a regular expression. If the string
+ # contains double parenthesis, such as ((.*?)), then the text within
+ # them is treated as in regular expression and kept verbatium.
+ #
+ # TODO: Better way to isolate regexp. Maybe ?:(.*?) or /(.*?)/.
+ #
+ # TODO: Now that we can use multi-patterns, do we still need this?
+ #
+ def match_string_to_regexp(str)
+ str = str.split(/(\(\(.*?\)\))(?!\))/).map{ |x|
+ x =~ /\A\(\((.*)\)\)\Z/ ? $1 : Regexp.escape(x)
+ }.join
+ str = str.gsub(/\\\s+/, '\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
+
##
#def method_missing(s, *a)
# super(s, *a) unless /^tag/ =~ s.to_s
#end
end
end
-