speckle 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +22 -0
  3. data/Gemfile +2 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +39 -0
  6. data/Rakefile +230 -0
  7. data/bin/speckle +12 -0
  8. data/lib/dsl.riml +29 -0
  9. data/lib/expectation.riml +34 -0
  10. data/lib/matchers/above_matcher.riml +13 -0
  11. data/lib/matchers/atleast_matcher.riml +13 -0
  12. data/lib/matchers/atmost_matcher.riml +13 -0
  13. data/lib/matchers/below_matcher.riml +13 -0
  14. data/lib/matchers/between_matcher.riml +19 -0
  15. data/lib/matchers/boolean_matcher.riml +13 -0
  16. data/lib/matchers/dict_key_matcher.riml +14 -0
  17. data/lib/matchers/equality_matcher.riml +13 -0
  18. data/lib/matchers/existance_matcher.riml +13 -0
  19. data/lib/matchers/length_matcher.riml +14 -0
  20. data/lib/matchers/match_item.riml +8 -0
  21. data/lib/matchers/match_tester.riml +33 -0
  22. data/lib/matchers/matchers.riml +72 -0
  23. data/lib/matchers/regexp_matcher.riml +14 -0
  24. data/lib/matchers/within_matcher.riml +28 -0
  25. data/lib/reporters/base_reporter.riml +126 -0
  26. data/lib/reporters/dotmatrix_reporter.riml +47 -0
  27. data/lib/reporters/min_reporter.riml +13 -0
  28. data/lib/reporters/reporter_factory.riml +15 -0
  29. data/lib/reporters/spec_reporter.riml +58 -0
  30. data/lib/reporters/tap_reporter.riml +38 -0
  31. data/lib/runners/runner.riml +49 -0
  32. data/lib/runners/spec_runner.riml +96 -0
  33. data/lib/speckle/cli/app.rb +18 -0
  34. data/lib/speckle/cli/controller.rb +67 -0
  35. data/lib/speckle/cli/environment.rb +148 -0
  36. data/lib/speckle/cli/rake_app.rb +146 -0
  37. data/lib/speckle/cli/router.rb +16 -0
  38. data/lib/speckle/loader.rb +10 -0
  39. data/lib/speckle/version.rb +3 -0
  40. data/lib/speckle.rb +4 -0
  41. data/lib/speckle.riml +148 -0
  42. data/lib/utils/spec_meta.riml +30 -0
  43. data/lib/utils/spec_timer.riml +30 -0
  44. data/lib/utils/statistician.riml +70 -0
  45. data/lib/writers/buffer_writer.riml +37 -0
  46. data/lib/writers/console_writer.riml +28 -0
  47. data/lib/writers/file_writer.riml +31 -0
  48. data/lib/writers/writer_factory.riml +13 -0
  49. data/spec/after_hooks_spec.riml +58 -0
  50. data/spec/before_hooks_spec.riml +38 -0
  51. data/spec/matchers/above_matcher_spec.riml +27 -0
  52. data/spec/matchers/atleast_matcher_spec.riml +28 -0
  53. data/spec/matchers/atmost_matcher_spec.riml +29 -0
  54. data/spec/matchers/below_matcher_spec.riml +28 -0
  55. data/spec/matchers/between_matcher_spec.riml +17 -0
  56. data/spec/matchers/boolean_matcher_spec.riml +27 -0
  57. data/spec/matchers/custom_matcher_spec.riml +47 -0
  58. data/spec/matchers/dict_key_matcher_spec.riml +19 -0
  59. data/spec/matchers/equality_matcher_spec.riml +31 -0
  60. data/spec/matchers/existance_matcher_spec.riml +17 -0
  61. data/spec/matchers/length_matcher_spec.riml +18 -0
  62. data/spec/matchers/regexp_matcher_spec.riml +31 -0
  63. data/spec/matchers/within_matcher_spec.riml +18 -0
  64. data/spec/spec_helper.rb +1 -0
  65. data/spec/speckle/cli/environment_spec.rb +296 -0
  66. data/speckle.gemspec +30 -0
  67. metadata +210 -0
@@ -0,0 +1,148 @@
1
+ module Speckle
2
+
3
+ module CLI
4
+
5
+ require 'optparse'
6
+ require 'ostruct'
7
+
8
+ class Environment
9
+ include Loader
10
+
11
+ def load(args)
12
+ options = OpenStruct.new
13
+ options.libs = nil
14
+ options.grep_pattern = nil
15
+ options.grep_invert = false
16
+ options.reporter = 'dot'
17
+ options.args = args
18
+ options.verbose = false
19
+ options.vim = 'vim'
20
+ options.cwd = Dir.pwd
21
+ options.root_dir = ROOT_DIR
22
+ options.speckle_build_dir = "#{ROOT_DIR}/build"
23
+ options.speckle_lib_dir = "#{ROOT_DIR}/lib"
24
+ options.skip_vimrc = false
25
+ options.slow_threshold = 10
26
+ options.colorize = true
27
+ options.bail = false
28
+
29
+ parser = OptionParser.new do |opts|
30
+ options.opts = opts
31
+
32
+ opts.banner = "Usage: speckle [options] [file(s) OR directory]"
33
+ opts.separator ''
34
+ opts.separator 'Options:'
35
+ opts.separator ''
36
+
37
+ opts.on_head('-c', '--compile', 'Only compile tests') do
38
+ options.action = :compile
39
+ end
40
+
41
+ opts.on_head('-t', '--test', 'Only run tests') do
42
+ options.action = :test
43
+ end
44
+
45
+ opts.on_head('-a', '--all', 'Compile and run tests (default)') do
46
+ options.action = :compile_and_test
47
+ end
48
+
49
+ opts.on('-I', '--libs <libs>', 'Specify additional riml library path(s)') do |libs|
50
+ options.libs = libs
51
+ end
52
+
53
+ opts.on('-g', '--grep <pattern>', 'Only run tests matching the pattern') do |pattern|
54
+ options.grep_pattern = pattern.strip
55
+ end
56
+
57
+ opts.on('-i', '--invert', 'Inverts --grep matches') do
58
+ options.grep_invert = true
59
+ end
60
+
61
+ opts.on('-r', '--reporter <reporter>', 'Specify the reporter to use (spec, min, dot, tap)') do |reporter|
62
+ options.reporter = reporter.strip
63
+ end
64
+
65
+ opts.on('-b', '--bail', 'Bail on first test failure') do
66
+ options.bail = true
67
+ end
68
+
69
+ opts.on('-w', '--watch', 'Watch tests for changes') do
70
+ options.action = :watch
71
+ end
72
+
73
+ opts.on('-m', '--vim <vim>', 'Vim program used to test, default(vim)') do |vim|
74
+ options.vim = vim.strip
75
+ end
76
+
77
+ opts.on('-s', '--slow-threshold <ms>', Integer, 'Threshold in milliseconds to indicate slow tests') do |ms|
78
+ options.slow_threshold = ms
79
+ end
80
+
81
+ opts.on('-k', '--skip-vimrc', 'Does not load ~/.vimrc file') do
82
+ options.skip_vimrc = true
83
+ end
84
+
85
+ opts.on('-C', '--no-colors', 'Disable color output') do
86
+ options.colorize = false
87
+ end
88
+
89
+ opts.on('-v', '--verbose', 'Display verbose output') do
90
+ options.verbose = true
91
+ end
92
+
93
+ opts.on('-D', '--debug', 'Display debug output') do
94
+ options.verbose = true
95
+ options.debug = true
96
+ end
97
+
98
+ opts.on_tail('-V', '--version', 'Print Speckle version') do
99
+ options.action = :show_version
100
+ end
101
+
102
+ opts.on_tail('-h', '--help', 'Print Speckle help') do
103
+ options.action = :show_help
104
+ end
105
+ end
106
+
107
+ begin
108
+ parser.parse!(args)
109
+
110
+ if options.action.nil?
111
+ spec_dir = "#{options.cwd}/spec"
112
+ if File.directory?(spec_dir)
113
+ args << 'spec'
114
+ options.action = :compile_and_test
115
+ else
116
+ options.action = :show_no_spec_dir
117
+ end
118
+ elsif action_needs_args?(options.action) and args.empty?
119
+ spec_dir = "#{options.cwd}/spec"
120
+ if File.directory?(spec_dir)
121
+ args << 'spec'
122
+ options.action = :compile_and_test
123
+ end
124
+ end
125
+
126
+ options.inputs = args
127
+ rescue OptionParser::InvalidOption => e
128
+ options.error = e
129
+ options.action = :show_invalid_option
130
+ rescue OptionParser::MissingArgument => e
131
+ options.error = e
132
+ options.action = :show_missing_args
133
+ rescue OptionParser::ParseError => e
134
+ options.error = e
135
+ options.action = :show_parser_error
136
+ end
137
+
138
+ options
139
+ end
140
+
141
+ def action_needs_args?(action)
142
+ [:compile_and_test, :compile, :test].include? action
143
+ end
144
+ end
145
+
146
+
147
+ end
148
+ end
@@ -0,0 +1,146 @@
1
+ module Speckle
2
+ module CLI
3
+
4
+ require 'rake'
5
+
6
+ class RakeApp
7
+ def initialize(options)
8
+ @options = options
9
+ end
10
+
11
+ def inputs
12
+ @options.inputs
13
+ end
14
+
15
+ def verbose
16
+ @options.verbose
17
+ end
18
+
19
+ def debug
20
+ @options.debug
21
+ end
22
+
23
+ def rake
24
+ if @rake_app
25
+ return @rake_app
26
+ end
27
+
28
+ configure_rake
29
+ Dir.chdir @options.root_dir
30
+
31
+ @rake_app = Rake.application
32
+ @rake_app.init
33
+ @rake_app.load_rakefile
34
+
35
+ Dir.chdir @options.cwd
36
+ @rake_app
37
+ end
38
+
39
+ def invoke_task(name)
40
+ rake.invoke_task("speckle:#{name.to_s}")
41
+ end
42
+
43
+ def rake_env(key, value)
44
+ unless value.nil?
45
+ ENV[key] = if value.is_a?(Array) then value.join(';') else value end
46
+ puts "rake_env: #{key} = #{ENV[key]}" if debug
47
+ end
48
+ end
49
+
50
+ def configure_rake
51
+ rake_env('TEST_SOURCES', test_sources)
52
+ rake_env('TEST_LIBS', test_libs)
53
+ rake_env('BUILD_DIR', test_build_dir)
54
+ rake_env('TEST_COMPILED', test_compiled)
55
+ rake_env('TEST_VIM', @options.vim)
56
+ rake_env('TEST_REPORTER', @options.reporter)
57
+ rake_env('SLOW_THRESHOLD', @options.slow_threshold.to_s)
58
+ rake_env('SKIP_VIMRC', to_int(@options.skip_vimrc))
59
+ rake_env('COLORIZE', to_int(@options.colorize))
60
+ rake_env('BAIL', to_int(@options.bail))
61
+
62
+ if @options.verbose
63
+ rake_env('VERBOSE', 'yes')
64
+ end
65
+
66
+ if @options.debug
67
+ rake_env('DEBUG', 'yes')
68
+ end
69
+ end
70
+
71
+ def to_int(option)
72
+ option ? '1' : '0'
73
+ end
74
+
75
+ def test_build_dir
76
+ "#{@options.cwd}/build"
77
+ end
78
+
79
+ def test_compiled
80
+ compiled = test_sources.map do |s|
81
+ s.ext('vim')
82
+ end
83
+
84
+ compiled
85
+ end
86
+
87
+ def test_sources
88
+ sources = []
89
+ grep_pattern = @options.grep_pattern
90
+ grep_invert = @options.grep_invert
91
+ unless grep_pattern.nil?
92
+ regex = Regexp.new(grep_pattern)
93
+ end
94
+
95
+ inputs.each do |input|
96
+ if File.directory?(input)
97
+ if grep_pattern.nil?
98
+ sources << "#{input}/**/*_spec.riml"
99
+ else
100
+ sources = Dir.glob("#{input}/**/*_spec.riml")
101
+ sources.keep_if do |source|
102
+ matched = regex.match(source)
103
+ if grep_invert
104
+ matched = !matched
105
+ end
106
+
107
+ matched
108
+ end
109
+ end
110
+ else
111
+ if grep_pattern.nil?
112
+ sources << input
113
+ else
114
+ matched = regex.match(input)
115
+ if grep_invert
116
+ matched = !matched
117
+ end
118
+ sources << input if matched
119
+ end
120
+ end
121
+ end
122
+
123
+ sources
124
+ end
125
+
126
+ def test_libs
127
+ input_libs = @options.libs
128
+ return nil if input_libs.nil?
129
+
130
+ input_libs = input_libs.split(':')
131
+ input_libs << 'spec'
132
+ if File.directory?(@options.speckle_lib_dir)
133
+ input_libs << @options.speckle_lib_dir
134
+ end
135
+
136
+ libs = []
137
+ input_libs.each do |lib|
138
+ libs << File.absolute_path(lib)
139
+ end
140
+
141
+ libs.join(':')
142
+ end
143
+
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,16 @@
1
+ module Speckle
2
+ module CLI
3
+
4
+ require_relative 'rake_app'
5
+ require_relative 'controller'
6
+
7
+ class Router
8
+ def route(action, options)
9
+ rake_app = RakeApp.new(options)
10
+ controller = Controller.new(options, rake_app)
11
+ controller.send(action)
12
+ end
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ module Speckle
2
+
3
+ module Loader
4
+ ROOT_DIR = File.expand_path('../../../', __FILE__)
5
+ LIB_DIR = File.join(ROOT_DIR, 'lib')
6
+
7
+ $:.unshift(LIB_DIR) unless $:.include? LIB_DIR
8
+ end
9
+
10
+ end
@@ -0,0 +1,3 @@
1
+ module Speckle
2
+ VERSION = "0.1.2"
3
+ end
data/lib/speckle.rb ADDED
@@ -0,0 +1,4 @@
1
+ require "speckle/version"
2
+
3
+ module Speckle
4
+ end
data/lib/speckle.riml ADDED
@@ -0,0 +1,148 @@
1
+ "" utils
2
+ riml_include 'spec_timer.riml'
3
+ riml_include 'spec_meta.riml'
4
+ riml_include 'statistician.riml'
5
+
6
+ "" matchers
7
+ riml_include 'equality_matcher.riml'
8
+ riml_include 'boolean_matcher.riml'
9
+ riml_include 'existance_matcher.riml'
10
+ riml_include 'above_matcher.riml'
11
+ riml_include 'below_matcher.riml'
12
+ riml_include 'between_matcher.riml'
13
+ riml_include 'length_matcher.riml'
14
+ riml_include 'atleast_matcher.riml'
15
+ riml_include 'atmost_matcher.riml'
16
+ riml_include 'within_matcher.riml'
17
+ riml_include 'regexp_matcher.riml'
18
+ riml_include 'dict_key_matcher.riml'
19
+
20
+ "" matcher internals
21
+ riml_include 'match_item.riml'
22
+ riml_include 'match_tester.riml'
23
+ riml_include 'matchers.riml'
24
+
25
+ "" writers
26
+ riml_include 'file_writer.riml'
27
+ riml_include 'console_writer.riml'
28
+ riml_include 'buffer_writer.riml'
29
+ riml_include 'writer_factory.riml'
30
+
31
+ "" reporters
32
+ riml_include 'base_reporter.riml'
33
+ riml_include 'spec_reporter.riml'
34
+ riml_include 'min_reporter.riml'
35
+ riml_include 'tap_reporter.riml'
36
+ riml_include 'dotmatrix_reporter.riml'
37
+ riml_include 'reporter_factory.riml'
38
+
39
+ "" runners
40
+ riml_include 'spec_runner.riml'
41
+ riml_include 'runner.riml'
42
+
43
+ "" dsl
44
+ riml_include 'expectation.riml'
45
+
46
+ "" main entry point
47
+ class Speckle
48
+ defm configure()
49
+ options_map = {
50
+ \ 'output_file': '"speckle.log"',
51
+ \ 'file_mode': '0',
52
+ \ 'reporter_name': '"spec"',
53
+ \ 'slow_threshold': '10',
54
+ \ 'colorize': '1',
55
+ \ 'bail': '0'
56
+ \}
57
+
58
+ self.options(options_map)
59
+ end
60
+
61
+ defm options(options_map)
62
+ for [name, value] in items(options_map)
63
+ self.option(name, value)
64
+ end
65
+ end
66
+
67
+ defm option(variable, default)
68
+ if !exists("g:speckle_#{variable}")
69
+ execute("let g:speckle_#{variable} = #{default}")
70
+ end
71
+ end
72
+
73
+ defm get_writer()
74
+ factory = new WriterFactory()
75
+ writer = factory.get_writer('buffer')
76
+
77
+ if self.is_file_mode()
78
+ writer.set_output_file(self.get_output_file())
79
+ end
80
+
81
+ return writer
82
+ end
83
+
84
+ defm get_reporter(writer)
85
+ factory = new ReporterFactory()
86
+ reporter = factory.get_reporter(self.get_reporter_name())
87
+ reporter.set_writer(writer)
88
+
89
+ return reporter
90
+ end
91
+
92
+ defm is_file_mode
93
+ return g:speckle_file_mode
94
+ end
95
+
96
+ defm get_output_file
97
+ return g:speckle_output_file
98
+ end
99
+
100
+ defm get_reporter_name
101
+ return g:speckle_reporter_name
102
+ end
103
+
104
+ defm get_slow_threshold
105
+ return g:speckle_slow_threshold
106
+ end
107
+
108
+ defm get_colorize
109
+ return g:speckle_colorize
110
+ end
111
+
112
+ defm get_bail
113
+ return g:speckle_bail
114
+ end
115
+
116
+ defm run()
117
+ self.configure()
118
+
119
+ writer = self.get_writer()
120
+ stats = new Statistician()
121
+ reporter = self.get_reporter(writer)
122
+ reporter.set_colorize_output(self.get_colorize())
123
+ runner = new Runner()
124
+ runner.set_bail(self.get_bail())
125
+ functions = ''
126
+
127
+ :redir => functions
128
+ :silent function /SpecConstructor$/
129
+ :redir END
130
+
131
+ self.add_specs(runner, functions)
132
+
133
+ runner.start(reporter, stats)
134
+
135
+ if self.is_file_mode()
136
+ writer.flush()
137
+ end
138
+ end
139
+
140
+ defm add_specs(runner, lines)
141
+ classes = split(lines, "\n")
142
+ map(classes, "substitute(v:val, 'function ', '', '')")
143
+
144
+ for klass in classes
145
+ eval("a:runner.add(#{klass})")
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,30 @@
1
+ class SpecMeta
2
+ def initialize(context, method)
3
+ self.context = context
4
+ self.method = method
5
+ end
6
+
7
+ defm get_context()
8
+ return self.context
9
+ end
10
+
11
+ defm get_method()
12
+ return self.method
13
+ end
14
+
15
+ defm get_sentence()
16
+ return substitute(self.get_method(), '_', ' ', 'g')
17
+ end
18
+
19
+ defm set_duration(duration)
20
+ self.duration = duration
21
+ end
22
+
23
+ defm get_duration()
24
+ return self.duration
25
+ end
26
+
27
+ defm is_slow()
28
+ return self.get_duration() > g:speckle_slow_threshold
29
+ end
30
+ end
@@ -0,0 +1,30 @@
1
+ class SpecTimer
2
+ def initialize()
3
+ self.start_time = 0
4
+ self.end_time = 0
5
+ end
6
+
7
+ defm start()
8
+ self.start_time = reltime()
9
+ end
10
+
11
+ defm stop()
12
+ self.end_time = reltime()
13
+ self.duration = self.time_to_ms(reltime(self.start_time))
14
+ end
15
+
16
+ defm get_duration()
17
+ return self.duration
18
+ end
19
+
20
+ defm time_to_ms(time)
21
+ duration_str = reltimestr(time)
22
+ duration_split = split(duration_str, '\.')
23
+ seconds = str2nr(duration_split[0])
24
+ microseconds = str2nr(duration_split[1])
25
+ milliseconds = (seconds * 1000) + (microseconds / 1000)
26
+
27
+ return milliseconds
28
+ end
29
+
30
+ end
@@ -0,0 +1,70 @@
1
+ class Statistician
2
+ def initialize()
3
+ self.count = 0
4
+ self.passes = 0
5
+ self.failures = 0
6
+ self.errors = 0
7
+ self.pending = 0
8
+ end
9
+
10
+ defm inc_count()
11
+ self.count += 1
12
+ end
13
+
14
+ defm inc_passes()
15
+ self.inc_count()
16
+ self.passes += 1
17
+ end
18
+
19
+ defm inc_failures()
20
+ self.inc_count()
21
+ self.failures += 1
22
+ end
23
+
24
+ defm inc_pending()
25
+ self.inc_count()
26
+ self.pending += 1
27
+ end
28
+
29
+ defm inc_errors()
30
+ self.inc_count()
31
+ self.errors += 1
32
+ end
33
+
34
+ defm inc_assertions()
35
+ env = g:speckle_env
36
+ env.assertions += 1
37
+ end
38
+
39
+ defm get_count()
40
+ return self.count
41
+ end
42
+
43
+ defm get_passes()
44
+ return self.passes
45
+ end
46
+
47
+ defm get_failures()
48
+ return self.failures
49
+ end
50
+
51
+ defm get_pending()
52
+ return self.pending
53
+ end
54
+
55
+ defm get_errors()
56
+ return self.errors
57
+ end
58
+
59
+ defm get_assertions()
60
+ return g:speckle_env.assertions
61
+ end
62
+
63
+ defm is_ok()
64
+ return self.get_errors() == 0 && self.get_failures() == 0
65
+ end
66
+
67
+ defm is_not_ok()
68
+ return !self.is_ok()
69
+ end
70
+ end
@@ -0,0 +1,37 @@
1
+ class BufferWriter
2
+ def initialize()
3
+ self.writer = new FileWriter()
4
+ end
5
+
6
+ defm set_output_file(output_file)
7
+ self.writer.set_output_file(output_file)
8
+ end
9
+
10
+ defm strip_colors(line)
11
+ return substitute(line, '\e\[[0-9;]\+[mK]', '', 'g')
12
+ end
13
+
14
+ defm write(line)
15
+ self.writer.write(line)
16
+
17
+ line = self.strip_colors(line)
18
+ append(line('$'), line)
19
+ :normal gJ
20
+ end
21
+
22
+ defm writeln(line)
23
+ self.writer.writeln(line)
24
+
25
+ line = self.strip_colors(line)
26
+ append(line('$'), line)
27
+ :normal G
28
+ end
29
+
30
+ defm flush()
31
+ self.writer.flush()
32
+ end
33
+
34
+ defm flush_line()
35
+ self.writer.flush_line()
36
+ end
37
+ end
@@ -0,0 +1,28 @@
1
+ class ConsoleWriter
2
+ def initialize()
3
+ self.writer = new FileWriter()
4
+ end
5
+
6
+ defm set_output_file(output_file)
7
+ self.writer.set_output_file(output_file)
8
+ end
9
+
10
+ defm write(line)
11
+ self.writer.write(line)
12
+ echon line
13
+ end
14
+
15
+ defm writeln(line)
16
+ self.writer.writeln(line)
17
+ echomsg line
18
+ end
19
+
20
+ defm flush()
21
+ self.writer.flush()
22
+ end
23
+
24
+ defm flush_line()
25
+ self.writer.flush_line()
26
+ end
27
+ end
28
+
@@ -0,0 +1,31 @@
1
+ class FileWriter
2
+ def initialize()
3
+ self.lines = []
4
+ self.current_line = ''
5
+ end
6
+
7
+ defm set_output_file(output_file)
8
+ self.output_file = output_file
9
+ end
10
+
11
+ defm write(line)
12
+ self.current_line = "#{self.current_line}#{line}"
13
+ end
14
+
15
+ defm writeln(line)
16
+ self.flush_line()
17
+ add(self.lines, line)
18
+ end
19
+
20
+ defm flush_line()
21
+ unless self.current_line == ''
22
+ add(self.lines, self.current_line)
23
+ self.current_line = ''
24
+ end
25
+ end
26
+
27
+ defm flush()
28
+ self.flush_line()
29
+ writefile(self.lines, self.output_file)
30
+ end
31
+ end