Class: YardExampleTest::Example

Inherits:
Minitest::Spec
  • Object
show all
Includes:
Comparison
Defined in:
lib/yard_example_test/example.rb,
lib/yard_example_test/example/evaluator.rb,
lib/yard_example_test/example/comparison.rb,
lib/yard_example_test/example/constant_sandbox.rb

Overview

Represents a YARD +@example+ tag as a runnable +Minitest::Spec+

Each instance is populated from a single +@example+ tag by YARD::CLI::TestExamples#build_spec and holds everything needed to generate and execute a test:

  • #definition — the YARD path of the documented object (e.g. +"MyClass#my_method"+), used as the spec description

  • #filepath — the source location of the documented object (e.g. +"lib/my_class.rb:10"+), prepended to failure backtraces

  • #expectations — the list of Expectation objects parsed from the example body, each pairing a Ruby expression to evaluate with an optional expected return value

Calling #generate dynamically defines and registers an anonymous +Minitest::Spec+ subclass that wraps the expectations in a single +it+ block. The registered spec is then picked up by +Minitest.autorun+ when the process exits.

Each expectation is evaluated inside a binding scoped to the owning object's class (if one can be resolved), so instance methods and constants are available without qualification, mirroring how the code appears in the source documentation.

Evaluation is delegated to an Evaluator (binding management and +eval+), constant isolation is handled by ConstantSandbox, and assertion / matcher logic lives in the Comparison module.

Defined Under Namespace

Modules: Comparison Classes: ConstantSandbox, Evaluator

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#definitionString

The YARD namespace path of the documented object (e.g. +Foo#bar+)

Examples:

example.definition #=> 'Foo#bar'


61
62
63
# File 'lib/yard_example_test/example.rb', line 61

def definition
  @definition
end

#expectationsArray<YardExampleTest::Expectation>

The list of expectations parsed from the example body

Examples:

example.expectations #=> []


81
82
83
# File 'lib/yard_example_test/example.rb', line 81

def expectations
  @expectations
end

#filepathString

The source location of the documented object (e.g. +app/app.rb:10+)

Examples:

example.filepath #=> 'app/app.rb:10'


71
72
73
# File 'lib/yard_example_test/example.rb', line 71

def filepath
  @filepath
end

Instance Method Details

#generate

This method returns an undefined value.

Dynamically defines and registers a +Minitest::Spec+ for this example

Creates an anonymous subclass of this class and evaluates a +describe+/+it+ block inside it. The steps are:

  1. Calls +load_helpers+ to require any +example_test_helper+ files found in +.+, +support/+, +spec/+, or +test/+.
  2. Skips silently if YardExampleTest.skips contains a substring that matches #definition.
  3. Opens a +describe+ block keyed on #definition, which becomes the spec group name reported by Minitest.
  4. Registers any matching +before+/+after+ hooks via +register_hooks+. These are registered by the user with YardExampleTest.before and YardExampleTest.after.
  5. Opens an +it+ block keyed on +name+ (the +@example+ tag title) that calls +run_expectations+ to evaluate every YardExampleTest::Expectation in #expectations.

The anonymous class and its specs are registered with Minitest's internal list by the +describe+ call. They will be executed when +Minitest.autorun+'s +at_exit+ hook fires.

Examples:

example.generate


109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/yard_example_test/example.rb', line 109

def generate
  self.class.send(:load_helpers)
  return if skipped?

  this = self
  Class.new(this.class).class_eval do
    describe this.definition do
      register_hooks(example_name_for(this), YardExampleTest.hooks, this)
      it(this.name) { run_expectations(this) }
    end
  end
end