Module: Yadriggy::Assert

Defined in:
lib/yadriggy/assert.rb

Overview

Power assert by Yadriggy

Defined Under Namespace

Classes: AssertFailure, Reason

Class Method Summary collapse

Class Method Details

.assert(&block) ⇒ Object

Checks the given assertion is correct and prints the result if the assertion fails.

Parameters:

  • block (Proc)

    the assertion.



13
14
15
16
17
18
19
20
21
22
23
# File 'lib/yadriggy/assert.rb', line 13

def self.assert(&block)
  reason = Reason.new
  begin
    res = assertion(reason, block)
    puts_reason(reason) unless res
    return res
  rescue AssertFailure => evar
    puts_reason(evar.reason, evar)
    raise evar.cause
  end
end

.assertion(reason, block) ⇒ Object

Checks the given assertion is correct.

Parameters:

  • reason (Reason)

    the object where the reason that the assertion fails will be stored.

  • block (Proc)

    the assertion.

Returns:

  • (Object)

    the result of executing the given block.



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/yadriggy/assert.rb', line 41

def self.assertion(reason, block)
  return if block.nil?
  ast = Yadriggy::reify(block)
  begin
    results = {}
    reason.setup(ast.tree.body, results)
    run_ast(ast.tree.body, block.binding, results)[1]
  rescue => evar
    raise AssertFailure.new(reason, evar.message, evar)
  end
end

.eval_by_ruby(ast, blk_binding) ⇒ Pair<String,Object>

Eval the AST by the RubyVM

Returns:

  • (Pair<String,Object>)

    an array. The first element is the source code and the second element is the resulting value.



217
218
219
220
221
# File 'lib/yadriggy/assert.rb', line 217

def self.eval_by_ruby(ast, blk_binding)
  src = PrettyPrinter.ast_to_s(ast)
  loc = ast.source_location
  [src, eval(src, blk_binding, loc[0], loc[1])]
end

.puts_reason(reason, evar = nil) ⇒ Object



26
27
28
29
30
31
32
33
# File 'lib/yadriggy/assert.rb', line 26

def self.puts_reason(reason, evar=nil)
  puts '--- Yadriggy::Assert ---'
  print evar.cause.class.name, ': ' if evar&.cause
  puts evar.message if evar&.message
  puts(reason.ast.source_location_string)
  puts(reason.show)
  puts '------------------------'
end

.run_ast(ast, blk_binding, results) ⇒ Pair<String,Object>

Executes the given AST and records the result.

Parameters:

  • ast (ASTnode)

    the given AST.

  • blk_binding (Binding)

    the binding for executing the AST.

  • results (Hash<ASTnode,Pair<String,Object>>)

    a map from ASTs to their source and values.

Returns:

  • (Pair<String,Object>)

    the result of the execution of the given AST. It is also recorded in ‘results`. The first element is the source code and the second one is the resulting value.



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/yadriggy/assert.rb', line 179

def self.run_ast(ast, blk_binding, results)
  if ast.is_a?(Paren)
    res = run_ast(ast.expression, blk_binding, results)
    src = "(#{res[0]})"
    results[ast] = [src, res[1]]
  elsif ast.is_a?(Call) && ast.block_arg.nil? && ast.block.nil?
    if ast.receiver.nil?
      receiver = ['self', blk_binding.eval('self')]
    else
      receiver = run_ast(ast.receiver, blk_binding, results)
    end
    args = ast.args.map {|e| run_ast(e, blk_binding, results) }
    arg_values = args.map {|e| e[1] }
    res = receiver[1].send(ast.name.name, *arg_values)
    arg_src = args.each_with_object('') do |e, code|
      code << ', ' if code.size > 0
      code << e[0]
    end
    src = "#{receiver[0]}.#{ast.name.name.to_s}(#{arg_src.to_s})"
    results[ast] = [src, res]
  elsif ast.is_a?(Binary)
    left_value = run_ast(ast.left, blk_binding, results)
    right_value = run_ast(ast.right, blk_binding, results)
    res = left_value[1].send(ast.op, right_value[1])
    results[ast] = ["#{left_value[0]} #{ast.op.to_s} #{right_value[0]}", res]
  elsif ast.is_a?(Unary)
    value = run_ast(ast.operand, blk_binding, results)
    res = value[1].send(ast.op)
    results[ast] = ["#{ast.real_operator.to_s}#{value[0]}", res]
  else
    results[ast] = eval_by_ruby(ast, blk_binding)
  end
end