class SpecRunner def initialize(spec) self.spec = spec self.stopped = false self.bail = false self.bailed = false self.tag = '' end defm set_bail(bail) self.bail = bail end defm set_tag(tag) self.tag = tag end defm has_bailed() return self.bailed end defm start(reporter, stats) spec = self.spec did_fail = false if has_key(spec, 'describe') context = self.call_hook('describe') elseif has_key(spec, 'spec_name') context = spec.spec_name else context = 'Unknown Spec' end reporter.on_context_start(context, stats) try self.call_hook('before') catch /.*/ self.report_hook_error('before', context, reporter, stats) self.stopped = true end for method in keys(spec) if self.stopped break end if self.can_run_test_for(method) timer = new SpecTimer() meta = new SpecMeta(context, method) reporter.on_spec_start(meta, stats) result = 0 try self.call_hook('before_each') timer.start() res = call(self.spec[method], [], self.spec) timer.stop() self.call_hook('after_each') meta.set_duration(timer.get_duration()) stats.inc_passes() reporter.on_spec_pass(meta, stats) catch /Unknown function.*expect/ did_fail = true stats.inc_failures() error = new DSLError('expect() not found, dsl.riml may not be included') reporter.on_spec_failure(meta, error, stats) catch /Unknown function.*define_matcher/ did_fail = true stats.inc_failures() error = new DSLError('define_matcher() not found, dsl.riml may not be included') reporter.on_spec_failure(meta, error, stats) catch /^AssertionError/ did_fail = true stats.inc_failures() " exeption carries the assertion failure message " error = new AssertionError(v:exception) reporter.on_spec_failure(meta, error, stats) catch /.*/ did_fail = true stats.inc_errors() error = new VimError(v:exception) reporter.on_spec_error(meta, error, stats) end reporter.on_spec_end(meta, stats) :redraw if did_fail && self.bail self.bailed = true break end end end try unless self.stopped self.call_hook('after') end catch /.*/ self.report_hook_error('after', context, reporter, stats) end reporter.on_context_end(context, stats) end defm report_hook_error(hook, context, reporter, stats) meta = new SpecMeta(context, hook) reporter.on_spec_start(meta, stats) stats.inc_errors() error = new VimError(v:exception) reporter.on_spec_error(meta, error, stats) end defm call_hook(hook) if has_key(self.spec, hook) return call(self.spec[hook], [], self.spec) else return "Undefined hook: #{hook}" end end defm stop() self.stopped = true end defm is_test_method(method) return method =~ '^it' end defm is_tagged(method) return method =~ "_#{self.tag}$" end defm can_run_test_for(method) if self.tag == '' return self.is_test_method(method) else return self.is_test_method(method) && self.is_tagged(method) end end end class SpecError def initialize(message) self.is_spec_error = true self.message = message self.exception = v:exception self.throwpoint = v:throwpoint end defm get_message() return self.message end defm get_stacktrace() unless has_key(self, 'stacktrace') self.build_stacktrace() end return self.stacktrace end defm build_stacktrace() str = substitute(self.throwpoint, '\v(function )', '', '') self.stacktrace = split(str, '\.\.') self.stacktrace = map(self.stacktrace, '"at " . v:val') end end class DSLError < SpecError def initialize(message) super(message) self.is_dsl_error = true end end class AssertionError < SpecError def initialize(message) super(message) self.is_assertion_error = true end end class VimError < SpecError def initialize(message) super(message) self.is_vim_error = true end end