speckle 0.1.18 → 0.1.19

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- Y2ZiNzc1MmNlZDEzYTMxZWE5MDgwMDZmZmM3ODVhOTUxMDA5NTNkMg==
4
+ ZDlkY2JlNWI2YzU0Nzk1YWEyOWQ5M2YwZGNkNGIxMjIwZTIwMGI0ZA==
5
5
  data.tar.gz: !binary |-
6
- OWY0MGFjOWNmYjZlNzc3NTU4NmFjZjAyZjhkZTdhNTZkM2JkZjE1NA==
6
+ OWNlZjUyYTc2MjdmYTQwMzhiMTg1MzBhNTZmZjdjMmFmYTlkYTdjZg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- NjBjOTNiNDlkYTFkNjk2YjliZTY5OTBjNmNlM2UzOGNlMDllZGE3Y2YwMzZm
10
- Zjk4MzM5ODVjMDVjNWVkZWYzNTI5OTY0MWE1NjM5YTcwMGFhMzExNzBhZTJl
11
- OTM3N2I4Y2VkMmM3YWQ1YTk4ZmVmNzE4MWM1NzgxYTY3ZjIwZGI=
9
+ ODllNmEwN2E0ZGEzZDk5ZTNiMDljMmEyOGY5MTE0MjQyMmFiOGY2MDMzNzU3
10
+ Njk1Mzc4YzY1MmE0YzU1NDA4ZTkzZGI2NjEwNWE5ZGQxMjUxY2JiZTUzYTI5
11
+ ODRjZTU5ZmY3Y2EzZjU3MjI0ODZjODBiMDI3ODk0MzNiZTc4OGQ=
12
12
  data.tar.gz: !binary |-
13
- YTkxNmQ1ZGQ2ZjgwZWMxMTRjZmE2MmI1ZjFmN2EwODIzNmRiMjhlOTAwMTk1
14
- YjVlMDUxZjg0YjFkNzBlMzBiOTVlYzRkMGY1MjEwZmU3Y2Y4MjgyOTNmZDYx
15
- M2MwYTRhOWJlZjg4NzNiNGI1NjA0YWFmYzc4OGIzNGUzZWMyYjY=
13
+ NTAxMmE2M2MzNmQwOGQ2ZjA4NTFjNTQxMzQxODczMmY5MDNhMDE0MmM1ZjJj
14
+ OTBjMDY0YTM5ZGFlMTgwYzkyZjQ2ZTUwMzA3Y2QwYTllYWYyNGJmZDFmNWVl
15
+ ZTFjZDU0YjdlOGJlOWUxNWIzZjcyOTM4MDhmMjg5N2VkMGM5YTg=
data/README.md CHANGED
@@ -1,14 +1,277 @@
1
- # Speckle
1
+ ## Speckle
2
2
 
3
- Behaviour driven framework for testing vim scripts written in Riml.
3
+ Behaviour driven development framework for testing Vim plugins written in [Riml][1].
4
4
 
5
5
  [![Build Status](https://travis-ci.org/dsawardekar/speckle.png)](https://travis-ci.org/dsawardekar/speckle)
6
6
 
7
+ ### About Riml
8
+ For people unfamiliar with `Riml`. [Riml][1] is a programming language that compiles to Vimscript. It's constructs are very similar to languages like `Ruby` and `Coffeescript`. It also provides a layer of abstraction to write OOP code that is converted to Vimscript's Funcref prototype chains.
9
+
10
+ ### How Speckle works
11
+ Speckle uses `Riml`s object-oriented constructs to provide
12
+ a BDD testing framework for Riml. You can use it for both unit testing and functional testing. Using Riml and Speckle you can write Vim plugins using common OOP software idioms and have the same familar tools available in your development workflow.
13
+
14
+ Speckle is both a test compiler and test execution engine. It does compilation of the `_spec.riml` specs with [Riml][1] and runs them in a Vim instance, capturing assertions, stacktraces and errors and reports them back after
15
+ closing the launched vim instance.
16
+
17
+ [1]:https://github.com/luke-gru/riml
18
+
7
19
  ## Installation
8
20
 
9
21
  $ gem install speckle
10
22
 
11
- ## Usage
23
+ ## Basic Usage
24
+
25
+ Here's an example using Speckle.
26
+
27
+ ```ruby
28
+ riml_include 'dsl.riml'
29
+
30
+ class MyFirstSpec
31
+ defm describe
32
+ return 'My First Spec'
33
+ end
34
+
35
+ defm it_can_check_equality_of_strings
36
+ my_string = 'v' . 'i' . 'm'
37
+ expect(my_string).to_equal(vim)
38
+ end
39
+ end
40
+ ```
41
+
42
+ A test example is a `Riml` class with a test method that begins with `it`. You can optionally provide a `describe` method to change the displayed name for test in the reporter output.
43
+
44
+ Note the `riml_include dsl.riml`. This include provides Speckle's `expect` dsl for use inside the test examples. The path to this include is autoconfigured by Speckle. For including your own classes specify the path like `-I lib`. Where lib is the directory containing your Vim plugin .riml files.
45
+
46
+ Speckle looks for tests in the `spec` folder by default. The tests should be named in the form `{name}_spec.riml`. The above example could be saved as
47
+ `spec/my_first_spec.riml`. To run this test use,
48
+
49
+ $ speckle
50
+
51
+ If the test succeeded you will get a message like,
52
+
53
+ ```log
54
+ ✓ 1 tests completed (5ms)
55
+ Passed: 1, Failures: 0, Errors: 0, Assertions: 1
56
+ ```
57
+
58
+ If you change the input string to only `vi` and run it again you will
59
+ see a message like,
60
+
61
+ ```log
62
+ EqualityMatcher #it can check equality of strings
63
+ AssertionError: expected “vi” to equal “vim”
64
+
65
+
66
+ ✖ 1 tests completed (5ms)
67
+ Passed: 0, Failures: 1, Errors: 0, Assertions: 0
68
+ ```
69
+
70
+ ## Matchers
71
+
72
+ ### Equivalence
73
+
74
+ ```ruby
75
+ expect(actual).to_equal(expected) # passes if actual == expected
76
+ expect(actual).to_not_equal(expected) # passes if actual != expected
77
+ ```
78
+
79
+ Note: A type mismatch will be thrown when comparing values with
80
+ different types.
81
+
82
+ ### Comparisons
83
+
84
+ ```ruby
85
+ expect(actual).to_be_gt(expected) # -ve to_not_be_gt
86
+ expect(actual).to_be_gte(expected) # -ve to_not_be_gte
87
+ expect(actual).to_be_lte(expected) # -ve to_not_be_lte
88
+ expect(actual).to_be_lt(expected) # -ve to_not_be_lt
89
+ expect(actual).to_be_within([delta, expected]) # -ve to_not_be_within
90
+ expect(actual).to_be_between([min, max]) # -ve to_not_be_between
91
+ ```
92
+
93
+ ### Regular expressions
94
+
95
+ ```ruby
96
+ expect(actual).to_match(pattern) # -ve to_not_match
97
+ ```
98
+
99
+ ### Boolean
100
+
101
+ ```ruby
102
+ expect(actual).to_be_true(expected) # -ve to_be_false
103
+ expect(actual).to_be_ok(expected) # -ve to_not_be_ok
104
+ ```
105
+
106
+ ### Existance
107
+
108
+ ```ruby
109
+ expect(actual).to_exist() # passes if exists(actual) is not false
110
+ expect(actual).to_not_exist() # -ve
111
+ ```
112
+
113
+ ### Dictionary
114
+ ```ruby
115
+ expect(actual).to_have_key(expected) # passes if actual is a dict with key expected
116
+ expect(actual).to_not_have_key(expected) # -ve
117
+ ```
118
+ ### Length
119
+
120
+ ```ruby
121
+ expect(actual).to_have_length(expected) # passes if len(actual) == expected
122
+ expect(actual).to_not_have_length(expected) # -ve
123
+ ```
124
+
125
+ ## Custom Matchers
126
+
127
+ In addition to the above default matchers you can create custom
128
+ matchers easily.
129
+
130
+ Consider a Person class in Riml.
131
+
132
+ ```ruby
133
+ class Person
134
+ def initialize(name)
135
+ self.name = name
136
+ end
137
+
138
+ defm get_name()
139
+ return self.name
140
+ end
141
+ end
142
+ ```
143
+
144
+ To write matcher to check if a person has the correct name we can
145
+ write a `PersonNameMatcher`. The class must implement the methods, `match`, `failure_message_for_match` and `failure_message_for_mismatch` as shown below.
146
+
147
+ ```ruby
148
+ class PersonNameMatcher
149
+ defm match(expected, actual)
150
+ self.result = actual.get_name()
151
+ return self.result == expected
152
+ end
153
+
154
+ defm failure_message_for_match(expected, actual)
155
+ return "expected person name to be “#{expected}” but was “#{self.result}”"
156
+ end
157
+
158
+ defm failure_message_for_mismatch(expected, actual)
159
+ return "expected person name to not be “#{expected}” but was “#{self.result}”"
160
+ end
161
+ end
162
+
163
+ ```
164
+
165
+ Then inside your spec you need to register this matcher using `define_matcher`,
166
+
167
+ ```ruby
168
+ matcher = new PersonNameMatcher()
169
+ define_matcher('to_have_name', 'to_not_have_name', matcher)
170
+ ```
171
+
172
+ Now in a test you can use the custom matcher methods, `to_have_name`, and it's negative `to_not_have_name`.
173
+
174
+ ```ruby
175
+ defm it_can_check_for_persons_name
176
+ expect(self.person).to_have_name('john')
177
+ end
178
+
179
+ defm it_can_check_for_negation_of_persons_name
180
+ expect(self.person).to_not_have_name('foo')
181
+ end
182
+ ```
183
+
184
+ ## Hooks
185
+
186
+ Speckle supports `before`, `before_each`, `after` and `after_each` hooks
187
+ that will be run before/after the entire suite or before/after every test.
188
+
189
+ ```ruby
190
+ defm before
191
+ end
192
+
193
+ defm before_each
194
+ end
195
+
196
+ defm after
197
+ end
198
+
199
+ defm after_each
200
+ end
201
+ ```
202
+
203
+ ## Logging (alternate to echomsg)
204
+
205
+ Speckle provides a logger that captures output messages without
206
+ halting execution of tests. This allows development of vim plugins
207
+ without needing to use `echomsg` extensively.
208
+
209
+ The logger api is,
210
+
211
+ ```
212
+ get_logger().log(msg, ...)
213
+ get_logger().info(msg, ...)
214
+ get_logger().warn(msg, ...)
215
+ get_logger().error(msg, ...)
216
+ get_logger().debug(msg, ...)
217
+ ```
218
+
219
+ When running the tests the error messages are shown inline like below.
220
+
221
+ ```log
222
+ LoggerSpec
223
+ ✓ it logs a message
224
+
225
+ log: Hello World
226
+ log: A test warning
227
+ log: An error warning
228
+
229
+ ```
230
+
231
+ ## Stacktraces
232
+
233
+ Another useful feature of Speckle is it displays stacktraces in a
234
+ meaningful form to help with debugging.
235
+
236
+ The example below has a call to an undefined function.
237
+
238
+ ```ruby
239
+ defm it_has_unknown_function
240
+ CallFooFunction()
241
+ end
242
+ ```
243
+
244
+ When this test is run the following stacktrace will be shown.
245
+
246
+ ```ruby
247
+ VariousErrorsSpec #it has unknown function
248
+ Vim(call):E117: Unknown function: <SNR>144_CallFooFunction
249
+ at <SNR>143_s:Speckle_run
250
+ at <SNR>143_s:Runner_start
251
+ at <SNR>143_s:SpecRunner_start
252
+ at <SNR>144_s:VariousErrorsSpec_it_has_unknown_function, line 2
253
+ ```
254
+
255
+ ## Isolated Testing
256
+
257
+ Speckle can be made to run only specific tests using the `--grep` option. For example, to only run tests in the `spec/models` folder use
258
+
259
+ $ speckle --grep spec/models
260
+
261
+ Further to only run specific tests we can tag the test with a keyword, and then use `--tag keyword` to run only those tests. Tagging is done by adding a `_tagname` suffix to the test method name. For example to tag a spec with the tag `perf`, you would use,
262
+
263
+ ```ruby
264
+ defm it_will_work_perf
265
+ end
266
+ ```
267
+
268
+ And run the test with,
269
+
270
+ $ speckle --tag perf
271
+
272
+ Both these flags can be combined to limit the tests run.
273
+
274
+ ## Complete Usage
12
275
 
13
276
  $ speckle [options] [file(s) OR directory]
14
277
  -a, --all Compile and run tests (default)
@@ -20,7 +283,7 @@ Options:
20
283
  -I, --libs <libs> Specify additional riml library path(s)
21
284
  -g, --grep <pattern> Only run tests matching the pattern
22
285
  -i, --invert Inverts --grep matches
23
- -r, --reporter <reporter> Specify the reporter to use (spec, min, dot, tap)
286
+ -r, --reporter <reporter> Specify the reporter to use (spec, min, dot, tap, fivemat)
24
287
  -b, --bail Bail on first test failure
25
288
  -w, --watch Watch tests for changes
26
289
  -m, --vim <vim> Vim program used to test, default(vim)
@@ -34,8 +297,10 @@ Options:
34
297
 
35
298
  ## Contributing
36
299
 
37
- 1. Fork it
38
- 2. Create your feature branch (`git checkout -b my-new-feature`)
39
- 3. Commit your changes (`git commit -am 'Add some feature'`)
40
- 4. Push to the branch (`git push origin my-new-feature`)
41
- 5. Create new Pull Request
300
+ 1. Speckle uses [git flow](https://github.com/nvie/gitflow) based branching model.
301
+ 2. Pull requests should go against the `develop` branch.
302
+ 3. Try to include failing tests if possible.
303
+
304
+ ## License
305
+
306
+ MIT License. Copyright (c) 2013 Darshan Sawardekar.
@@ -25,6 +25,7 @@ class Runner
25
25
 
26
26
  defm add(spec)
27
27
  add(self.specs, spec)
28
+ return spec
28
29
  end
29
30
 
30
31
  defm start(reporter, stats)
@@ -23,7 +23,13 @@ class SpecRunner
23
23
  defm start(reporter, stats)
24
24
  spec = self.spec
25
25
  did_fail = false
26
- context = self.call_hook('describe')
26
+ if has_key(spec, 'describe')
27
+ context = self.call_hook('describe')
28
+ elseif has_key(spec, 'spec_name')
29
+ context = spec.spec_name
30
+ else
31
+ context = 'Unknown Spec'
32
+ end
27
33
  reporter.on_context_start(context, stats)
28
34
 
29
35
  try
@@ -4,6 +4,7 @@ module Speckle
4
4
 
5
5
  require 'optparse'
6
6
  require 'ostruct'
7
+ require 'find'
7
8
 
8
9
  class Environment
9
10
  include Loader
@@ -94,7 +95,7 @@ module Speckle
94
95
  opts.on('-v', '--verbose', 'Display verbose output') do
95
96
  options.verbose = true
96
97
  end
97
-
98
+
98
99
  opts.on('-D', '--debug', 'Display debug output') do
99
100
  options.verbose = true
100
101
  options.debug = true
@@ -140,14 +141,30 @@ module Speckle
140
141
  options.action = :show_parser_error
141
142
  end
142
143
 
144
+ if action_needs_args?(options.action) and options.libs.nil?
145
+ options.libs = build_riml_path(['lib', 'spec'])
146
+ end
147
+
143
148
  options
144
149
  end
145
150
 
146
151
  def action_needs_args?(action)
147
152
  [:compile_and_test, :compile, :test].include? action
148
153
  end
149
- end
150
154
 
155
+ def build_riml_path(dirs, pattern = /.*\.riml$/, spec_pattern = /.*_spec\.riml$/)
156
+ libs = []
157
+ dirs.each do |dir|
158
+ Find.find(dir) do |path|
159
+ if path =~ pattern && path !~ spec_pattern
160
+ libs << File.dirname(path)
161
+ end
162
+ end
163
+ end
164
+
165
+ libs.uniq.join(':')
166
+ end
167
+ end
151
168
 
152
169
  end
153
170
  end
@@ -1,3 +1,3 @@
1
1
  module Speckle
2
- VERSION = "0.1.18"
2
+ VERSION = "0.1.19"
3
3
  end
data/lib/speckle.riml CHANGED
@@ -120,7 +120,7 @@ class g:Speckle
120
120
  defm get_bail
121
121
  return g:speckle_bail
122
122
  end
123
-
123
+
124
124
  defm get_tag
125
125
  return g:speckle_tag
126
126
  end
@@ -156,7 +156,12 @@ class g:Speckle
156
156
  map(classes, "substitute(v:val, 'function ', '', '')")
157
157
 
158
158
  for klass in classes
159
- eval("a:runner.add(#{klass})")
159
+ klass_instance = eval("a:runner.add(#{klass})")
160
+ res = matchlist(klass, '\v%(\<SNR\>\d+_)?(.*)SpecConstructor\(\)$')
161
+ if len(res) >= 2
162
+ spec_name = res[1]
163
+ klass_instance.spec_name = spec_name
164
+ end
160
165
  end
161
166
  end
162
167
  end
@@ -35,4 +35,3 @@ class BeforeEachHookSpec
35
35
  expect(self.stuff).to_equal('foo')
36
36
  end
37
37
  end
38
-
@@ -0,0 +1,7 @@
1
+ riml_include 'dsl.riml'
2
+
3
+ class MySpecWithoutDescribeSpec
4
+ defm it_will_work_too
5
+ expect(true).to_be_true()
6
+ end
7
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: speckle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.18
4
+ version: 0.1.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Darshan Sawardekar
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-24 00:00:00.000000000 Z
11
+ date: 2013-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: riml
@@ -186,6 +186,7 @@ files:
186
186
  - spec/speckle_mode_spec.riml
187
187
  - spec/stacktrace_spec.riml
188
188
  - spec/tagged_spec.riml
189
+ - spec/with_describe_spec.riml
189
190
  - spec_errors/hook_errors_spec.riml
190
191
  - spec_errors/various_errors_spec.riml
191
192
  - speckle.gemspec
@@ -241,3 +242,4 @@ test_files:
241
242
  - spec/speckle_mode_spec.riml
242
243
  - spec/stacktrace_spec.riml
243
244
  - spec/tagged_spec.riml
245
+ - spec/with_describe_spec.riml