Method: XSpec.dsl

Defined in:
lib/xspec.rb

.dsl(options = {}) ⇒ Object

The DSL is the core of XSpec. It dynamically generates a module that can be mixed into which ever context you choose (using ‘extend`), be that the top-level namespace or a specific class.

This enables different options to be specified per DSL, which is at the heart of XSpec’s modularity. It is easy to change every component to your liking.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/xspec.rb', line 15

def dsl(options = {})
  options = XSpec.add_defaults(options)

  Module.new do
    # Each DSL provides a standard set of methods provided by the [DSL
    # module](dsl.html).
    include DSL

    # In addition, each DSL has its own independent context, which is
    # described in detail in the
    # [`data_structures.rb`](data_structures.html).
    def __xspec_context
      evaluator = __xspec_opts.fetch(:evaluator)
      @__xspec_context ||= XSpec::Context.root(evaluator)
    end

    # Some meta-magic is needed to enable the options from local scope above
    # to be available inside the module.
    define_method(:__xspec_opts) { options }

    # `run!` is where the magic happens. Typically called at the end of a
    # file (or by `autorun!`), this method takes all the data that was
    # accumulated by the DSL methods above and runs it through the scheduler.
    def run!
      notifier  = __xspec_opts.fetch(:notifier)
      scheduler = __xspec_opts.fetch(:scheduler)

      scheduler.run(__xspec_context, notifier)
    end

    # It is often convenient to trigger a run after all files have been
    # processed, which is what `autorun!` sets up for you. Requiring
    # `xspec/autorun` does this automatically for you.
    def autorun!
      at_exit do
        exit 1 unless run!
      end
    end
  end
end