Class: TestML::Runtime
- Inherits:
-
Object
- Object
- TestML::Runtime
- Defined in:
- lib/testml/runtime.rb
Direct Known Subclasses
Defined Under Namespace
Classes: Unit
Instance Attribute Summary collapse
-
#base ⇒ Object
Returns the value of attribute base.
-
#bridge ⇒ Object
Returns the value of attribute bridge.
-
#compiler ⇒ Object
Returns the value of attribute compiler.
-
#error ⇒ Object
Returns the value of attribute error.
-
#function ⇒ Object
Returns the value of attribute function.
-
#global ⇒ Object
Returns the value of attribute global.
-
#library ⇒ Object
Returns the value of attribute library.
-
#skip ⇒ Object
Returns the value of attribute skip.
-
#testml ⇒ Object
Returns the value of attribute testml.
Instance Method Summary collapse
- #apply_signature(function, args) ⇒ Object
- #compile_testml ⇒ Object
- #get_label ⇒ Object
- #get_point(name) ⇒ Object
-
#initialize(attributes = {}) ⇒ Runtime
constructor
A new instance of Runtime.
- #initialize_runtime ⇒ Object
- #lookup_callable(name) ⇒ Object
- #read_testml_file(file) ⇒ Object
- #replace_label(var) ⇒ Object
- #run ⇒ Object
- #run_assertion(left, assert) ⇒ Object
- #run_assignment(assignment) ⇒ Object
- #run_call(call, context = nil) ⇒ Object
- #run_expression(expr) ⇒ Object
- #run_function(function, args) ⇒ Object
- #run_statement(statement) ⇒ Object
- #select_blocks(wanted) ⇒ Object
Constructor Details
#initialize(attributes = {}) ⇒ Runtime
Returns a new instance of Runtime.
15 16 17 18 19 |
# File 'lib/testml/runtime.rb', line 15 def initialize(attributes={}) attributes.each { |k,v| self.send "#{k}=", v } $TestMLRuntimeSingleton = self @base ||= 'test' end |
Instance Attribute Details
#base ⇒ Object
Returns the value of attribute base.
13 14 15 |
# File 'lib/testml/runtime.rb', line 13 def base @base end |
#bridge ⇒ Object
Returns the value of attribute bridge.
5 6 7 |
# File 'lib/testml/runtime.rb', line 5 def bridge @bridge end |
#compiler ⇒ Object
Returns the value of attribute compiler.
7 8 9 |
# File 'lib/testml/runtime.rb', line 7 def compiler @compiler end |
#error ⇒ Object
Returns the value of attribute error.
11 12 13 |
# File 'lib/testml/runtime.rb', line 11 def error @error end |
#function ⇒ Object
Returns the value of attribute function.
10 11 12 |
# File 'lib/testml/runtime.rb', line 10 def function @function end |
#global ⇒ Object
Returns the value of attribute global.
12 13 14 |
# File 'lib/testml/runtime.rb', line 12 def global @global end |
#library ⇒ Object
Returns the value of attribute library.
6 7 8 |
# File 'lib/testml/runtime.rb', line 6 def library @library end |
#skip ⇒ Object
Returns the value of attribute skip.
8 9 10 |
# File 'lib/testml/runtime.rb', line 8 def skip @skip end |
#testml ⇒ Object
Returns the value of attribute testml.
4 5 6 |
# File 'lib/testml/runtime.rb', line 4 def testml @testml end |
Instance Method Details
#apply_signature(function, args) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/testml/runtime.rb', line 45 def apply_signature(function, args) signature = function.signature || [] fail "Function received #{args.size} args but expected #{signature.size}" \ if ! signature.empty? and args.size != signature.size @function.setvar('Self', function) signature.each_with_index do |sig_elem, i| arg = args[i] arg = run_expression(arg) \ if arg.kind_of? TestML::Expression function.setvar(sig_elem, arg) end end |
#compile_testml ⇒ Object
198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/testml/runtime.rb', line 198 def compile_testml fail "'testml' document required but not found" \ unless @testml if @testml !~ /\n/ @testml =~ /(.*)\/(.*)/ or fail testml = $2 @base = @base + '/' + $1 @testml = read_testml_file testml end @function = @compiler.new.compile(@testml) end |
#get_label ⇒ Object
231 232 233 234 235 |
# File 'lib/testml/runtime.rb', line 231 def get_label label = @function.getvar('Label') or return label = label.value label.gsub(/\$(\w+)/) {|m| replace_label($1)} end |
#get_point(name) ⇒ Object
173 174 175 176 177 178 179 |
# File 'lib/testml/runtime.rb', line 173 def get_point(name) value = @function.getvar('Block').points[name] or return if value.sub!(/\n+\z/, "\n") and value == "\n" value = '' end return TestML::Str.new(value) end |
#initialize_runtime ⇒ Object
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/testml/runtime.rb', line 210 def initialize_runtime @global = @function.outer @global.setvar('Block', TestML::Block.new) @global.setvar('Label', TestML::Str.new('$BlockLabel')) @global.setvar('True', TestML::Constant::True) @global.setvar('False', TestML::Constant::False) @global.setvar('None', TestML::Constant::None) @global.setvar('TestNumber', TestML::Num.new(0)) @global.setvar('Library', TestML::List.new) library = @function.getvar('Library') [@bridge, @library].each do |lib| if lib.kind_of? Array lib.each {|l| library.push(l.new)} else library.push(lib.new) end end end |
#lookup_callable(name) ⇒ Object
159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/testml/runtime.rb', line 159 def lookup_callable(name) @function.getvar('Library').value.each do |library| if library.respond_to?(name) function = lambda do |*args| library.method(name).call(*args) end callable = TestML::Callable.new(function) @function.setvar(name, callable) return callable end end return nil end |
#read_testml_file(file) ⇒ Object
249 250 251 252 |
# File 'lib/testml/runtime.rb', line 249 def read_testml_file file path = @base + '/' + file File.read(path) end |
#replace_label(var) ⇒ Object
237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/testml/runtime.rb', line 237 def replace_label(var) block = @function.getvar('Block') if var == 'BlockLabel' block.label elsif v = block.points[var] v.sub!(/\n.*/m, '') v.strip elsif v = function.getvar(var) v.value end end |
#run ⇒ Object
21 22 23 24 25 |
# File 'lib/testml/runtime.rb', line 21 def run compile_testml initialize_runtime run_function(@function, []) end |
#run_assertion(left, assert) ⇒ Object
79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/testml/runtime.rb', line 79 def run_assertion left, assert method_ = method(('assert_' + assert.name).to_sym) @function.getvar('TestNumber').value += 1 if assert.expr method_.call(left, run_expression(assert.expr)) else method_.call(left) end end |
#run_assignment(assignment) ⇒ Object
72 73 74 75 76 77 |
# File 'lib/testml/runtime.rb', line 72 def run_assignment(assignment) @function.setvar( assignment.name, run_expression(assignment.expr) ) end |
#run_call(call, context = nil) ⇒ Object
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/testml/runtime.rb', line 115 def run_call call, context=nil if call.kind_of? TestML::Object return call end if call.kind_of? TestML::Function return call end if call.kind_of? TestML::Point return get_point(call.name) end if call.kind_of? TestML::Call name = call.name callable = @function.getvar(name) || get_point(name) || lookup_callable(name) || fail("Can't locate '#{name}' callable") if callable.kind_of? TestML::Object return callable end return callable unless call.args or !context.nil? call.args ||= [] args = call.args.map{|arg| run_expression(arg)} args.unshift context if !context.nil? if callable.kind_of? TestML::Callable begin value = callable.value.call(*args) rescue @error = $!. # @error = "#{$!.class}: #{$!.message}\n at #{$!.backtrace[0]}" return TestML::Error.new(@error) end fail "'#{name}' did not return a TestML::Object object" \ unless value.kind_of? TestML::Object return value end if callable.kind_of? TestML::Function return run_function(callable, args) end fail end fail end |
#run_expression(expr) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/testml/runtime.rb', line 91 def run_expression(expr) context = nil @error = nil if expr.kind_of? TestML::Expression calls = expr.calls.clone fail if calls.size <= 1 context = run_call(calls.shift) calls.each do |call| if @error next unless call.kind_of?(TestML::Call) and call.name == 'Catch' end context = run_call(call, context) end else context = run_call(expr) end if @error fail @error end return context end |
#run_function(function, args) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/testml/runtime.rb', line 27 def run_function(function, args) signature = apply_signature(function, args) parent = @function @function = function function.statements.each do |statement| if statement.kind_of? TestML::Assignment run_assignment(statement) else run_statement(statement) end end @function = parent return end |
#run_statement(statement) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/testml/runtime.rb', line 60 def run_statement(statement) blocks = select_blocks(statement.points || []) blocks.each do |block| @function.setvar('Block', block) if block != 1 result = run_expression(statement.expr) if assertion = statement.assert run_assertion(result, assertion) end end end |
#select_blocks(wanted) ⇒ Object
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/testml/runtime.rb', line 181 def select_blocks(wanted) return [1] if wanted.empty? selected = [] @function.data.each do |block| points = block.points next if points.key?('SKIP') next unless wanted.all?{|point| points.key?(point)} if points.key?('ONLY') selected = [block] break end selected << block break if points.key?('LAST') end return selected end |