class YARD::Doctest::Example
Attributes
asserts[RW]
@return [Array<Hash>] assertions to be done
definition[RW]
@return [String] namespace path of example (e.g. `Foo#bar`)
filepath[RW]
@return [String] filepath to definition (e.g. `app/app.rb:10`)
Protected Class Methods
register_hooks(example_name, all_hooks, example)
click to toggle source
@param [String] example_name The name of the example. @param [Hash<Symbol, Array<Hash<(test: String, block: Proc)>>] all_hooks @param [Example] example
# File lib/yard/doctest/example.rb, line 151 def register_hooks(example_name, all_hooks, example) all_hooks.each do |type, hooks| global_hooks = hooks.reject { |hook| hook[:test] } test_hooks = hooks.select { |hook| hook[:test] && example_name.include?(hook[:test]) } __send__(type) do (global_hooks + test_hooks).each { |hook| instance_exec(example, &hook[:block]) } end end end
Public Instance Methods
generate()
click to toggle source
Generates a spec and registers it to Minitest runner.
# File lib/yard/doctest/example.rb, line 17 def generate this = self Class.new(this.class).class_eval do require 'minitest/autorun' %w[. support spec].each do |dir| require "#{dir}/doctest_helper" if File.exist?("#{dir}/doctest_helper.rb") end return if YARD::Doctest.skips.any? { |skip| this.definition.include?(skip) } describe this.definition do # Append this.name to this.definition if YARD's @example tag is followed by # descriptive text, to support hooks for multiple examples per code object. example_name = if this.name.empty? this.definition else "#{this.definition}@#{this.name}" end register_hooks(example_name, YARD::Doctest.hooks, this) it this.name do begin object_name = this.definition.split(/#|\./).first scope = Object.const_get(object_name) if self.class.const_defined?(object_name) rescue NameError end global_constants = Object.constants scope_constants = scope.constants if scope && scope.respond_to?(:constants) this.asserts.each do |assert| expected, actual = assert[:expected], assert[:actual] if expected.empty? evaluate_example(this, actual, scope) else assert_example(this, expected, actual, scope) end end clear_extra_constants(Object, global_constants) clear_extra_constants(scope, scope_constants) if scope && scope.respond_to?(:constants) end end end end
Protected Instance Methods
add_filepath_to_backtrace(exception, filepath)
click to toggle source
# File lib/yard/doctest/example.rb, line 131 def add_filepath_to_backtrace(exception, filepath) backtrace = exception.backtrace line = backtrace.find { |l| l =~ %r{lib/yard/doctest/example} } index = backtrace.index(line) backtrace = backtrace.insert(index + 1, filepath) exception.set_backtrace backtrace end
assert_example(example, expected, actual, bind)
click to toggle source
# File lib/yard/doctest/example.rb, line 73 def assert_example(example, expected, actual, bind) expected = evaluate_with_assertion(expected, bind) actual = evaluate_with_assertion(actual, bind) if both_are_errors?(expected, actual) assert_equal("#<#{expected.class}: #{expected}>", "#<#{actual.class}: #{actual}>") elsif (error = only_one_is_error?(expected, actual)) raise error elsif expected.nil? assert_nil(actual) else assert_equal(expected, actual) end rescue Minitest::Assertion => error add_filepath_to_backtrace(error, example.filepath) raise error end
both_are_errors?(expected, actual)
click to toggle source
# File lib/yard/doctest/example.rb, line 119 def both_are_errors?(expected, actual) expected.is_a?(StandardError) && actual.is_a?(StandardError) end
clear_extra_constants(scope, constants)
click to toggle source
# File lib/yard/doctest/example.rb, line 139 def clear_extra_constants(scope, constants) (scope.constants - constants).each do |constant| scope.__send__(:remove_const, constant) end end
context(bind)
click to toggle source
# File lib/yard/doctest/example.rb, line 101 def context(bind) @context ||= begin if bind context = bind.class_eval('binding', __FILE__, __LINE__) # Oh my god, what is happening here? # We need to transplant instance variables from the current binding. instance_variables.each do |instance_variable_name| local_variable_name = "__yard_doctest__#{instance_variable_name.to_s.delete('@')}" context.local_variable_set(local_variable_name, instance_variable_get(instance_variable_name)) context.eval("#{instance_variable_name} = #{local_variable_name}") end context else binding end end end
evaluate(code, bind)
click to toggle source
# File lib/yard/doctest/example.rb, line 97 def evaluate(code, bind) context(bind).eval(code) end
evaluate_example(example, actual, bind)
click to toggle source
# File lib/yard/doctest/example.rb, line 66 def evaluate_example(example, actual, bind) evaluate(actual, bind) rescue StandardError => error add_filepath_to_backtrace(error, example.filepath) raise error end
evaluate_with_assertion(code, bind)
click to toggle source
# File lib/yard/doctest/example.rb, line 91 def evaluate_with_assertion(code, bind) evaluate(code, bind) rescue StandardError => error error end
only_one_is_error?(expected, actual)
click to toggle source
# File lib/yard/doctest/example.rb, line 123 def only_one_is_error?(expected, actual) if expected.is_a?(StandardError) && !actual.is_a?(StandardError) expected elsif !expected.is_a?(StandardError) && actual.is_a?(StandardError) actual end end