speckle 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/.gitignore +22 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +22 -0
- data/README.md +39 -0
- data/Rakefile +230 -0
- data/bin/speckle +12 -0
- data/lib/dsl.riml +29 -0
- data/lib/expectation.riml +34 -0
- data/lib/matchers/above_matcher.riml +13 -0
- data/lib/matchers/atleast_matcher.riml +13 -0
- data/lib/matchers/atmost_matcher.riml +13 -0
- data/lib/matchers/below_matcher.riml +13 -0
- data/lib/matchers/between_matcher.riml +19 -0
- data/lib/matchers/boolean_matcher.riml +13 -0
- data/lib/matchers/dict_key_matcher.riml +14 -0
- data/lib/matchers/equality_matcher.riml +13 -0
- data/lib/matchers/existance_matcher.riml +13 -0
- data/lib/matchers/length_matcher.riml +14 -0
- data/lib/matchers/match_item.riml +8 -0
- data/lib/matchers/match_tester.riml +33 -0
- data/lib/matchers/matchers.riml +72 -0
- data/lib/matchers/regexp_matcher.riml +14 -0
- data/lib/matchers/within_matcher.riml +28 -0
- data/lib/reporters/base_reporter.riml +126 -0
- data/lib/reporters/dotmatrix_reporter.riml +47 -0
- data/lib/reporters/min_reporter.riml +13 -0
- data/lib/reporters/reporter_factory.riml +15 -0
- data/lib/reporters/spec_reporter.riml +58 -0
- data/lib/reporters/tap_reporter.riml +38 -0
- data/lib/runners/runner.riml +49 -0
- data/lib/runners/spec_runner.riml +96 -0
- data/lib/speckle/cli/app.rb +18 -0
- data/lib/speckle/cli/controller.rb +67 -0
- data/lib/speckle/cli/environment.rb +148 -0
- data/lib/speckle/cli/rake_app.rb +146 -0
- data/lib/speckle/cli/router.rb +16 -0
- data/lib/speckle/loader.rb +10 -0
- data/lib/speckle/version.rb +3 -0
- data/lib/speckle.rb +4 -0
- data/lib/speckle.riml +148 -0
- data/lib/utils/spec_meta.riml +30 -0
- data/lib/utils/spec_timer.riml +30 -0
- data/lib/utils/statistician.riml +70 -0
- data/lib/writers/buffer_writer.riml +37 -0
- data/lib/writers/console_writer.riml +28 -0
- data/lib/writers/file_writer.riml +31 -0
- data/lib/writers/writer_factory.riml +13 -0
- data/spec/after_hooks_spec.riml +58 -0
- data/spec/before_hooks_spec.riml +38 -0
- data/spec/matchers/above_matcher_spec.riml +27 -0
- data/spec/matchers/atleast_matcher_spec.riml +28 -0
- data/spec/matchers/atmost_matcher_spec.riml +29 -0
- data/spec/matchers/below_matcher_spec.riml +28 -0
- data/spec/matchers/between_matcher_spec.riml +17 -0
- data/spec/matchers/boolean_matcher_spec.riml +27 -0
- data/spec/matchers/custom_matcher_spec.riml +47 -0
- data/spec/matchers/dict_key_matcher_spec.riml +19 -0
- data/spec/matchers/equality_matcher_spec.riml +31 -0
- data/spec/matchers/existance_matcher_spec.riml +17 -0
- data/spec/matchers/length_matcher_spec.riml +18 -0
- data/spec/matchers/regexp_matcher_spec.riml +31 -0
- data/spec/matchers/within_matcher_spec.riml +18 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/speckle/cli/environment_spec.rb +296 -0
- data/speckle.gemspec +30 -0
- metadata +210 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MWZhOGE2OTdjMTZmYzIzYmRhMWUxZDZjM2FjMzlhNDAzZjFhZTg2Zg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ODcwYzhhOGU5OTliY2UzNjQwMzNhN2JlMzkwMzM1MWJiMTViN2VjNA==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YTEwYzIwN2I0MDY4M2U2N2QyOTIwZDExODc5NzlhZTcxZWEzNzFhMDRjMGUw
|
10
|
+
NTZhNWExODI2YzJiMjljNDIyYTQzMGY2YTZjZmEwMmNiYzY1NTk1ZmQ2Y2Jk
|
11
|
+
ZmM3MWJhMjYyMWQ1YmRlYTUxYmNkZmUxNTBiN2I5ZGRmMjU5ZmI=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
YmQ5NjJkOWQzMTUzNjQ4MTZmOTc3OTliMDIzN2FlODM1OTdhYzA2MzgzMTZm
|
14
|
+
NTViZjIxMzViYTNjMmI1ZjRmNTNhMTM5MDdhNzg3NTMxZjcyODE4ZGNmOGEx
|
15
|
+
OWNjNzQ3NDMyZmYzNDUxNzkyNTViY2IxNDQ0YTBiYWNiNTYzMjg=
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
*.swp
|
4
|
+
*.swo
|
5
|
+
.bundle
|
6
|
+
.config
|
7
|
+
.yardoc
|
8
|
+
Gemfile.lock
|
9
|
+
InstalledFiles
|
10
|
+
_yardoc
|
11
|
+
coverage
|
12
|
+
doc/
|
13
|
+
lib/bundler/man
|
14
|
+
pkg
|
15
|
+
rdoc
|
16
|
+
spec/reports
|
17
|
+
test/tmp
|
18
|
+
test/version_tmp
|
19
|
+
tmp
|
20
|
+
build
|
21
|
+
scratch.vim
|
22
|
+
lib/scratch.riml
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Darshan Sawardekar <darshan@sawardekar.org>
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# Speckle
|
2
|
+
|
3
|
+
Behaviour driven framework for testing vim scripts written in Riml.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
$ gem install speckle
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
$ speckle [options] [file(s) OR directory]
|
12
|
+
-a, --all Compile and run tests (default)
|
13
|
+
-t, --test Only run tests
|
14
|
+
-c, --compile Only compile tests
|
15
|
+
|
16
|
+
Options:
|
17
|
+
|
18
|
+
-I, --libs <libs> Specify additional riml library path(s)
|
19
|
+
-g, --grep <pattern> Only run tests matching the pattern
|
20
|
+
-i, --invert Inverts --grep matches
|
21
|
+
-r, --reporter <reporter> Specify the reporter to use (spec, min, dot, tap)
|
22
|
+
-b, --bail Bail on first test failure
|
23
|
+
-w, --watch Watch tests for changes
|
24
|
+
-m, --vim <vim> Vim program used to test, default(vim)
|
25
|
+
-s, --slow-threshold <ms> Threshold in milliseconds to indicate slow tests
|
26
|
+
-k, --skip-vimrc Does not load ~/.vimrc file
|
27
|
+
-C, --no-colors Disable color output
|
28
|
+
-v, --verbose Display verbose output
|
29
|
+
-D, --debug Display debug output
|
30
|
+
-V, --version Print Speckle version
|
31
|
+
-h, --help Print Speckle help
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
1. Fork it
|
36
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
37
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
38
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
39
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,230 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
|
5
|
+
desc 'Default task :compile_and_test'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
# :spec task from rspec
|
9
|
+
desc "Run speckle's rspec tests"
|
10
|
+
RSpec::Core::RakeTask.new(:spec)
|
11
|
+
|
12
|
+
desc 'Run rspec and speckle tests'
|
13
|
+
task :test => [:spec, 'speckle:compile_and_test']
|
14
|
+
|
15
|
+
desc 'Clean temporary files'
|
16
|
+
task :clean => ['speckle:clean']
|
17
|
+
|
18
|
+
desc 'Clobber temporary files'
|
19
|
+
task :clobber => ['speckle:clobber']
|
20
|
+
|
21
|
+
# speckle tasks
|
22
|
+
namespace :speckle do
|
23
|
+
|
24
|
+
require 'rake/clean'
|
25
|
+
require 'tempfile'
|
26
|
+
|
27
|
+
# build paths
|
28
|
+
BUILD_DIR = ENV['BUILD_DIR'] || 'build'
|
29
|
+
|
30
|
+
# misc config
|
31
|
+
VERBOSE = ENV.has_key?('VERBOSE')
|
32
|
+
DEBUG = ENV.has_key?('DEBUG')
|
33
|
+
SLOW_THRESHOLD = ENV['SLOW_THRESHOLD'] || 10
|
34
|
+
SKIP_VIMRC = ENV['SKIP_VIMRC'] == '1' || false
|
35
|
+
COLORIZE = ENV['COLORIZE'] || 1
|
36
|
+
BAIL = ENV['BAIL'] || 0
|
37
|
+
|
38
|
+
# speckle sources
|
39
|
+
SPECKLE_DIR = File.dirname(__FILE__)
|
40
|
+
SPECKLE_BUILD_DIR = "#{SPECKLE_DIR}/build"
|
41
|
+
LIB_DIR = "#{SPECKLE_DIR}/lib"
|
42
|
+
SPECKLE_LIBS = Dir.glob("#{LIB_DIR}/**/*").select { |f| File.directory? f }.push(LIB_DIR).join(':')
|
43
|
+
SPECKLE_MAIN = 'speckle.riml'
|
44
|
+
SPECKLE_SOURCE = "#{LIB_DIR}/#{SPECKLE_MAIN}"
|
45
|
+
SPECKLE_TEMP_OUTPUT = "#{SPECKLE_MAIN}".ext('vim')
|
46
|
+
SPECKLE_OUTPUT = "#{SPECKLE_BUILD_DIR}/#{SPECKLE_TEMP_OUTPUT}"
|
47
|
+
SPECKLE_VIM = ENV['SPECKLE_VIM'] || SPECKLE_MAIN.ext('vim')
|
48
|
+
|
49
|
+
SPECKLE_DSL = 'dsl.riml'
|
50
|
+
SPECKLE_DSL_SOURCE = "#{LIB_DIR}/#{SPECKLE_DSL}"
|
51
|
+
SPECKLE_DSL_TEMP_OUTPUT = "#{SPECKLE_DSL}".ext('vim')
|
52
|
+
SPECKLE_DSL_OUTPUT = "#{SPECKLE_BUILD_DIR}/#{SPECKLE_DSL_TEMP_OUTPUT}"
|
53
|
+
|
54
|
+
# clean
|
55
|
+
CLEAN.include("#{BUILD_DIR}/**/*.vim")
|
56
|
+
CLEAN.include("#{BUILD_DIR}/**/*.log")
|
57
|
+
CLOBBER.include(BUILD_DIR)
|
58
|
+
|
59
|
+
# test sources
|
60
|
+
TEST_LIBS = ENV['TEST_LIBS'] || "spec:#{LIB_DIR}"
|
61
|
+
TEST_VIM = ENV['TEST_VIM'] || 'vim'
|
62
|
+
TEST_REPORTER = ENV['TEST_REPORTER'] || 'spec'
|
63
|
+
TEST_LOG = "#{BUILD_DIR}/speckle.log"
|
64
|
+
TEST_SOURCES = FileList.new do |fl|
|
65
|
+
sources = ENV['TEST_SOURCES']
|
66
|
+
if sources
|
67
|
+
sources = sources.split(';')
|
68
|
+
sources.each do |s|
|
69
|
+
fl.include(s)
|
70
|
+
end
|
71
|
+
else
|
72
|
+
fl.include('spec/**/*_spec.riml')
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
TEST_COMPILED = FileList.new do |fl|
|
77
|
+
fl.exclude("#{SPECKLE_OUTPUT}")
|
78
|
+
compiled = ENV['TEST_COMPILED']
|
79
|
+
if compiled
|
80
|
+
compiled = compiled.split(';')
|
81
|
+
compiled.each do |c|
|
82
|
+
fl.include("#{BUILD_DIR}/#{c}")
|
83
|
+
end
|
84
|
+
else
|
85
|
+
fl.include("#{BUILD_DIR}/**/*.vim")
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
desc 'All tasks'
|
90
|
+
task :all => [:clean, :compile, :compile_tests, :test]
|
91
|
+
|
92
|
+
desc 'Build files and folders'
|
93
|
+
task :build do
|
94
|
+
verbose DEBUG do
|
95
|
+
mkdir_p BUILD_DIR
|
96
|
+
mkdir_p SPECKLE_BUILD_DIR
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
desc "Compile #{SPECKLE_MAIN}"
|
101
|
+
task :compile => [:build] do
|
102
|
+
puts "Compiling: #{SPECKLE_MAIN}"
|
103
|
+
verbose VERBOSE do
|
104
|
+
sh "riml -c #{SPECKLE_SOURCE} -I #{SPECKLE_LIBS}"
|
105
|
+
end
|
106
|
+
verbose DEBUG do
|
107
|
+
mv "#{SPECKLE_TEMP_OUTPUT}", "#{SPECKLE_OUTPUT}"
|
108
|
+
end
|
109
|
+
|
110
|
+
verbose VERBOSE do
|
111
|
+
sh "riml -c #{SPECKLE_DSL_SOURCE}"
|
112
|
+
end
|
113
|
+
|
114
|
+
verbose DEBUG do
|
115
|
+
mv "#{SPECKLE_DSL_TEMP_OUTPUT}", "#{SPECKLE_DSL_OUTPUT}"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
task :scratch => [:build] do
|
120
|
+
sh "riml -c lib/scratch.riml -I #{SPECKLE_LIBS}"
|
121
|
+
end
|
122
|
+
|
123
|
+
desc "Compile specs"
|
124
|
+
task :compile_tests => [:build] do
|
125
|
+
TEST_SOURCES.each do |t|
|
126
|
+
verbose VERBOSE do
|
127
|
+
puts "Compiling: #{t} "
|
128
|
+
sh "riml -c #{t} -I #{TEST_LIBS}"
|
129
|
+
end
|
130
|
+
|
131
|
+
spec_dir = "#{BUILD_DIR}/#{File.dirname(t)}"
|
132
|
+
verbose DEBUG do
|
133
|
+
mkdir_p "#{spec_dir}"
|
134
|
+
mv "#{File.basename(t).ext('vim')}", "#{spec_dir}"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
puts
|
139
|
+
end
|
140
|
+
|
141
|
+
desc "Compile and test specs"
|
142
|
+
task :compile_and_test => [:compile_tests] do
|
143
|
+
verbose VERBOSE do
|
144
|
+
Rake::Task['speckle:test'].invoke
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
desc "Launch test runner"
|
149
|
+
task :test do
|
150
|
+
unless File.exists?(SPECKLE_OUTPUT)
|
151
|
+
Rake::Task['speckle:compile'].invoke
|
152
|
+
end
|
153
|
+
|
154
|
+
puts 'Running tests: '
|
155
|
+
puts
|
156
|
+
|
157
|
+
launch_vim
|
158
|
+
end
|
159
|
+
|
160
|
+
desc "Watch files for changes and run tests"
|
161
|
+
task :watch do
|
162
|
+
puts '--- TODO ---'
|
163
|
+
end
|
164
|
+
|
165
|
+
def get_vim_options
|
166
|
+
cmd = ''
|
167
|
+
if SKIP_VIMRC
|
168
|
+
cmd += "-u NONE -i NONE"
|
169
|
+
end
|
170
|
+
|
171
|
+
cmd
|
172
|
+
end
|
173
|
+
|
174
|
+
def launch_vim
|
175
|
+
begin
|
176
|
+
verbose DEBUG do
|
177
|
+
launch_file = get_launch_cmd_file()
|
178
|
+
sh "#{TEST_VIM} #{get_vim_options()} -S #{launch_file.path}"
|
179
|
+
sh "cat #{TEST_LOG}"
|
180
|
+
launch_file.unlink
|
181
|
+
end
|
182
|
+
rescue RuntimeError => error
|
183
|
+
puts error
|
184
|
+
if DEBUG
|
185
|
+
puts error.backtrace
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
# utils
|
191
|
+
def get_launch_cmd_source
|
192
|
+
launch_cmd = <<CMD
|
193
|
+
source #{SPECKLE_OUTPUT}
|
194
|
+
CMD
|
195
|
+
|
196
|
+
TEST_COMPILED.each do |t|
|
197
|
+
launch_cmd += <<CMD
|
198
|
+
source #{t}
|
199
|
+
CMD
|
200
|
+
end
|
201
|
+
|
202
|
+
launch_cmd += <<CMD
|
203
|
+
let g:speckle_file_mode = 1
|
204
|
+
let g:speckle_output_file = '#{TEST_LOG}'
|
205
|
+
let g:speckle_reporter_name = '#{TEST_REPORTER}'
|
206
|
+
let g:speckle_slow_threshold = #{SLOW_THRESHOLD}
|
207
|
+
let g:speckle_colorize = #{COLORIZE}
|
208
|
+
let g:speckle_bail = #{BAIL}
|
209
|
+
let speckle = g:SpeckleConstructor()
|
210
|
+
:autocmd VimEnter * :call speckle.run()
|
211
|
+
:q!
|
212
|
+
CMD
|
213
|
+
|
214
|
+
if DEBUG
|
215
|
+
puts launch_cmd
|
216
|
+
end
|
217
|
+
launch_cmd.gsub!(/([^\n])\n([^\n])/, '\1 | \2')
|
218
|
+
end
|
219
|
+
|
220
|
+
def get_launch_cmd_file
|
221
|
+
cmd = get_launch_cmd_source
|
222
|
+
file = Tempfile.new('speckle')
|
223
|
+
file.write(cmd)
|
224
|
+
file.close
|
225
|
+
|
226
|
+
file
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
230
|
+
|
data/bin/speckle
ADDED
data/lib/dsl.riml
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
if !exists("g:speckle_env")
|
2
|
+
g:speckle_env = {}
|
3
|
+
g:speckle_env.matchers = g:MatchersConstructor()
|
4
|
+
g:speckle_env.assertions = 0
|
5
|
+
end
|
6
|
+
|
7
|
+
|
8
|
+
def expect(actual)
|
9
|
+
env = g:speckle_env
|
10
|
+
env.actual = actual
|
11
|
+
matchers = env.matchers
|
12
|
+
|
13
|
+
expectation = g:ExpectationConstructor(a:actual)
|
14
|
+
expectation.load(matchers)
|
15
|
+
|
16
|
+
return expectation
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_matchers()
|
20
|
+
env = g:speckle_env
|
21
|
+
matchers = env.matchers
|
22
|
+
|
23
|
+
return matchers
|
24
|
+
end
|
25
|
+
|
26
|
+
def define_matcher(ok_name, not_ok_name, matcher)
|
27
|
+
matchers = get_matchers()
|
28
|
+
matchers.define_pair(ok_name, not_ok_name, matcher)
|
29
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class Expectation
|
2
|
+
|
3
|
+
def initialize(actual)
|
4
|
+
self.actual = actual
|
5
|
+
end
|
6
|
+
|
7
|
+
defm load(matchers)
|
8
|
+
matchers.load_defaults()
|
9
|
+
|
10
|
+
match_tester = new MatchTester()
|
11
|
+
match_items = matchers.get_match_items()
|
12
|
+
|
13
|
+
for match_item in match_items
|
14
|
+
func_name = "g:Expectation_#{match_item.name}"
|
15
|
+
matcher_func = <<EOS
|
16
|
+
function! #{func_name}(...) dict
|
17
|
+
if a:0 == 0
|
18
|
+
let expected = 'null'
|
19
|
+
else
|
20
|
+
let expected = a:1
|
21
|
+
endif
|
22
|
+
|
23
|
+
let matcher_name = '#{match_item.name}'
|
24
|
+
let match_tester = g:MatchTesterConstructor()
|
25
|
+
call match_tester.test_from_env(matcher_name, expected)"
|
26
|
+
endfunction"
|
27
|
+
EOS
|
28
|
+
:exe matcher_func
|
29
|
+
|
30
|
+
self[match_item.name] = function(func_name)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class AboveMatcher
|
2
|
+
defm match(expected, actual)
|
3
|
+
return actual > expected
|
4
|
+
end
|
5
|
+
|
6
|
+
defm failure_message_for_match(expected, actual)
|
7
|
+
return "expected “#{actual}” to be above “#{expected}”"
|
8
|
+
end
|
9
|
+
|
10
|
+
defm failure_message_for_mismatch(expected, actual)
|
11
|
+
return "expected “#{actual}” to not be above “#{expected}”"
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class AtleastMatcher
|
2
|
+
defm match(expected, actual)
|
3
|
+
return actual >= expected
|
4
|
+
end
|
5
|
+
|
6
|
+
defm failure_message_for_match(expected, actual)
|
7
|
+
return "expected “#{actual}” to be greater than or equal to “#{expected}”"
|
8
|
+
end
|
9
|
+
|
10
|
+
defm failure_message_for_mismatch(expected, actual)
|
11
|
+
return "expected “#{actual}” to not be greater than or equal to “#{expected}”"
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class AtmostMatcher
|
2
|
+
defm match(expected, actual)
|
3
|
+
return actual <= expected
|
4
|
+
end
|
5
|
+
|
6
|
+
defm failure_message_for_match(expected, actual)
|
7
|
+
return "expected “#{actual}” to be less than or equal to “#{expected}”"
|
8
|
+
end
|
9
|
+
|
10
|
+
defm failure_message_for_mismatch(expected, actual)
|
11
|
+
return "expected “#{actual}” to not be less than or equal to “#{expected}”"
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class BelowMatcher
|
2
|
+
defm match(expected, actual)
|
3
|
+
return actual < expected
|
4
|
+
end
|
5
|
+
|
6
|
+
defm failure_message_for_match(expected, actual)
|
7
|
+
return "expected “#{actual}” to be below “#{expected}”"
|
8
|
+
end
|
9
|
+
|
10
|
+
defm failure_message_for_mismatch(expected, actual)
|
11
|
+
return "expected “#{actual}” to not be below “#{expected}”"
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class BetweenMatcher
|
2
|
+
defm match(bounds, actual)
|
3
|
+
min = bounds[0]
|
4
|
+
max = bounds[1]
|
5
|
+
return actual >= min && actual <= max
|
6
|
+
end
|
7
|
+
|
8
|
+
defm failure_message_for_match(bounds, actual)
|
9
|
+
min = bounds[0]
|
10
|
+
max = bounds[1]
|
11
|
+
return "expected “#{actual}” to be between “#{min} .. #{max}”"
|
12
|
+
end
|
13
|
+
|
14
|
+
defm failure_message_for_mismatch(bounds, actual)
|
15
|
+
min = bounds[0]
|
16
|
+
max = bounds[1]
|
17
|
+
return "expected “#{actual}” to not be between “#{min} .. #{max}”"
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class BooleanMatcher
|
2
|
+
defm match(expected, actual)
|
3
|
+
return actual == true
|
4
|
+
end
|
5
|
+
|
6
|
+
defm failure_message_for_match(expected, actual)
|
7
|
+
return "expected “#{actual}” to be true"
|
8
|
+
end
|
9
|
+
|
10
|
+
defm failure_message_for_mismatch(expected, actual)
|
11
|
+
return "expected “#{actual}” to be false"
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class DictKeyMatcher
|
2
|
+
defm match(expected, actual)
|
3
|
+
return has_key(actual, expected)
|
4
|
+
end
|
5
|
+
|
6
|
+
defm failure_message_for_match(expected, actual)
|
7
|
+
return "expected dict to have key #{actual}"
|
8
|
+
end
|
9
|
+
|
10
|
+
defm failure_message_for_mismatch(expected, actual)
|
11
|
+
return "expected dict to not have key #{actual}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class EqualityMatcher
|
2
|
+
defm match(expected, actual)
|
3
|
+
return actual == expected
|
4
|
+
end
|
5
|
+
|
6
|
+
defm failure_message_for_match(expected, actual)
|
7
|
+
return "expected “#{actual}” to equal “#{expected}”"
|
8
|
+
end
|
9
|
+
|
10
|
+
defm failure_message_for_mismatch(expected, actual)
|
11
|
+
return "expected “#{actual}” to not equal “#{expected}”"
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class ExistanceMatcher
|
2
|
+
defm match(expected, actual)
|
3
|
+
return exists(actual)
|
4
|
+
end
|
5
|
+
|
6
|
+
defm failure_message_for_match(expected, actual)
|
7
|
+
return "expected “#{actual}” to exist"
|
8
|
+
end
|
9
|
+
|
10
|
+
defm failure_message_for_mismatch(expected, actual)
|
11
|
+
return "expected “#{actual}” to not exist"
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class LengthMatcher
|
2
|
+
defm match(expected, actual)
|
3
|
+
self.result = len(actual)
|
4
|
+
return self.result == expected
|
5
|
+
end
|
6
|
+
|
7
|
+
defm failure_message_for_match(expected, actual)
|
8
|
+
return "expected length of “#{actual}” to be “#{expected}”, but was #{self.result}"
|
9
|
+
end
|
10
|
+
|
11
|
+
defm failure_message_for_mismatch(expected, actual)
|
12
|
+
return "expected length of “#{actual}” to not be “#{expected}”, but was #{self.result}"
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class MatchTester
|
2
|
+
|
3
|
+
defm test_from_env(matcher_name, expected)
|
4
|
+
env = g:speckle_env
|
5
|
+
matchers = env.matchers
|
6
|
+
match_item = matchers.get_match_item(matcher_name)
|
7
|
+
negate = match_item.negate
|
8
|
+
matcher = match_item.matcher
|
9
|
+
actual = env.actual
|
10
|
+
|
11
|
+
tester = new MatchTester()
|
12
|
+
tester.test(matcher, negate, a:expected, actual)
|
13
|
+
end
|
14
|
+
|
15
|
+
defm test(matcher, negate, expected, actual)
|
16
|
+
result = matcher.match(expected, actual)
|
17
|
+
g:speckle_env.assertions += 1
|
18
|
+
if negate
|
19
|
+
if result
|
20
|
+
message = matcher.failure_message_for_mismatch(expected, actual)
|
21
|
+
message = "AssertionError: #{message}"
|
22
|
+
throw message
|
23
|
+
end
|
24
|
+
else
|
25
|
+
unless result
|
26
|
+
message = matcher.failure_message_for_match(expected, actual)
|
27
|
+
message = "AssertionError: #{message}"
|
28
|
+
throw message
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
class Matchers
|
2
|
+
def initialize()
|
3
|
+
self.matchers = {}
|
4
|
+
end
|
5
|
+
|
6
|
+
defm load_defaults()
|
7
|
+
matcher = new EqualityMatcher()
|
8
|
+
self.define_pair('to_equal', 'to_not_equal', matcher)
|
9
|
+
self.define_pair('to_eq', 'to_neq', matcher)
|
10
|
+
|
11
|
+
matcher = new BooleanMatcher()
|
12
|
+
self.define_pair('to_be_true', 'to_be_false', matcher)
|
13
|
+
self.define_pair('to_be_ok', 'to_not_be_ok', matcher)
|
14
|
+
|
15
|
+
matcher = new ExistanceMatcher()
|
16
|
+
self.define_pair('to_exist', 'to_not_exist', matcher)
|
17
|
+
|
18
|
+
matcher = new AboveMatcher()
|
19
|
+
self.define_pair('to_be_above', 'to_not_be_above', matcher)
|
20
|
+
self.define_pair('to_be_gt', 'to_not_be_gt', matcher)
|
21
|
+
|
22
|
+
matcher = new BelowMatcher()
|
23
|
+
self.define_pair('to_be_below', 'to_not_be_below', matcher)
|
24
|
+
self.define_pair('to_be_lt', 'to_not_be_lt', matcher)
|
25
|
+
|
26
|
+
matcher = new BetweenMatcher()
|
27
|
+
self.define_pair('to_be_between', 'to_not_be_between', matcher)
|
28
|
+
|
29
|
+
matcher = new LengthMatcher()
|
30
|
+
self.define_pair('to_have_length', 'to_not_have_length', matcher)
|
31
|
+
|
32
|
+
matcher = new AtleastMatcher()
|
33
|
+
self.define_pair('to_be_at_least', 'to_not_be_at_least', matcher)
|
34
|
+
self.define_pair('to_be_gte', 'to_not_be_gte', matcher)
|
35
|
+
|
36
|
+
matcher = new AtmostMatcher()
|
37
|
+
self.define_pair('to_be_at_most', 'to_not_be_at_most', matcher)
|
38
|
+
self.define_pair('to_be_lte', 'to_not_be_lte', matcher)
|
39
|
+
|
40
|
+
matcher = new WithinMatcher()
|
41
|
+
self.define_pair('to_be_within', 'to_not_be_within', matcher)
|
42
|
+
|
43
|
+
matcher = new RegExpMatcher()
|
44
|
+
self.define_pair('to_match', 'to_not_match', matcher)
|
45
|
+
self.define_pair('to_have_string', 'to_not_have_string', matcher)
|
46
|
+
|
47
|
+
matcher = new DictKeyMatcher()
|
48
|
+
self.define_pair('to_have_key', 'to_not_have_key', matcher)
|
49
|
+
end
|
50
|
+
|
51
|
+
defm get_match_items()
|
52
|
+
return values(self.matchers)
|
53
|
+
end
|
54
|
+
|
55
|
+
defm get_match_item(name)
|
56
|
+
return self.matchers[name]
|
57
|
+
end
|
58
|
+
|
59
|
+
defm define_single(name, matcher)
|
60
|
+
item = new MatchItem(name, matcher)
|
61
|
+
self.matchers[name] = item
|
62
|
+
end
|
63
|
+
|
64
|
+
defm define_pair(ok_name, not_ok_name, matcher)
|
65
|
+
ok_item = new MatchItem(ok_name, matcher, false)
|
66
|
+
not_ok_item = new MatchItem(not_ok_name, matcher, true)
|
67
|
+
|
68
|
+
self.matchers[ok_name] = ok_item
|
69
|
+
self.matchers[not_ok_name] = not_ok_item
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|