dsawardekar/speckle

View on GitHub
lib/speckle.riml

Summary

Maintainability
Test Coverage
"" utils
riml_include 'logger.riml'
riml_include 'echo_log_writer.riml'
riml_include 'spec_timer.riml'
riml_include 'spec_meta.riml'
riml_include 'statistician.riml'

"" matchers
riml_include 'equality_matcher.riml'
riml_include 'boolean_matcher.riml'
riml_include 'existance_matcher.riml'
riml_include 'above_matcher.riml'
riml_include 'below_matcher.riml'
riml_include 'between_matcher.riml'
riml_include 'length_matcher.riml'
riml_include 'atleast_matcher.riml'
riml_include 'atmost_matcher.riml'
riml_include 'within_matcher.riml'
riml_include 'regexp_matcher.riml'
riml_include 'dict_key_matcher.riml'

"" matcher internals
riml_include 'match_item.riml'
riml_include 'match_tester.riml'
riml_include 'matchers.riml'

"" writers
riml_include 'file_writer.riml'
riml_include 'console_writer.riml'
riml_include 'buffer_writer.riml'
riml_include 'writer_factory.riml'
riml_include 'file_log_writer.riml'

"" reporters
riml_include 'base_reporter.riml'
riml_include 'spec_reporter.riml'
riml_include 'min_reporter.riml'
riml_include 'tap_reporter.riml'
riml_include 'dotmatrix_reporter.riml'
riml_include 'fivemat_reporter.riml'
riml_include 'reporter_factory.riml'

"" runners
riml_include 'spec_runner.riml'
riml_include 'runner.riml'

"" dsl
riml_include 'expectation.riml'

"" main entry point
class g:Speckle
  defm configure()
    options_map = {
      \ 'output_file': '"speckle.log"',
      \ 'file_mode': '0',
      \ 'reporter_name': '"spec"',
      \ 'slow_threshold': '10',
      \ 'colorize': '1',
      \ 'bail': '0',
      \ 'tag': '""'
    \}

    self.options(options_map)
  end

  def options(options_map)
    for [name, value] in items(options_map)
      self.option(name, value)
    end
  end

  def option(variable, default)
    if !exists("g:speckle_#{variable}")
      execute("let g:speckle_#{variable} = #{default}")
    end
  end

  defm get_writer()
    factory = new WriterFactory()
    writer = factory.get_writer('buffer')

    if self.is_file_mode()
      writer.set_output_file(self.get_output_file())
    end

    return writer
  end

  defm get_reporter(writer)
    factory = new ReporterFactory()
    reporter = factory.get_reporter(self.get_reporter_name())
    reporter.set_writer(writer)

    logger = get_logger()
    logger.add_log_writer(reporter)

    return reporter
  end

  defm is_file_mode
    return g:speckle_file_mode
  end

  defm get_output_file
    return g:speckle_output_file
  end

  defm get_exit_code_file
    return self.get_output_file() . '.exit'
  end

  defm get_reporter_name
    return g:speckle_reporter_name
  end

  defm get_slow_threshold
    return g:speckle_slow_threshold
  end

  defm get_colorize
    return g:speckle_colorize
  end

  defm get_bail
    return g:speckle_bail
  end

  defm get_tag
    return g:speckle_tag
  end

  defm run()
    self.configure()

    writer = self.get_writer()
    stats = new Statistician()
    reporter = self.get_reporter(writer)
    reporter.set_colorize_output(self.get_colorize())

    runner = new Runner()
    runner.set_bail(self.get_bail())
    runner.set_tag(self.get_tag())

    functions = ''
    :redir => functions
    :silent function /Spec\(_.*Constructor\|Constructor\)$/
    :redir END

    self.add_specs(runner, functions)

    runner.start(reporter, stats)

    if self.is_file_mode()
      writer.flush()
    end

    self.write_exit_code(stats.is_ok())
  end

  defm add_specs(runner, lines)
    classes = split(lines, "\n")
    map(classes, "substitute(v:val, 'function ', '', '')")

    for klass in classes
      klass_instance = eval("a:runner.add(#{klass})")
      res = matchlist(klass, '\v%(\<SNR\>\d+_)?(.*)SpecConstructor\(\)$')
      if len(res) >= 2
        spec_name = res[1]
        klass_instance.spec_name = spec_name
      end
    end
  end

  defm get_exit_code(ok)
    return ok == true ? '0' : '1'
  end

  defm write_exit_code(ok)
    writer = new FileWriter()
    writer.set_output_file(self.get_exit_code_file())
    writer.write(self.get_exit_code(ok))
    writer.flush()
  end
end