shared_should 0.6.6 → 0.7.0
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.
- data/README.md +34 -1
- data/VERSION +1 -1
- data/lib/shared_should.rb +32 -83
- data/shared_should.gemspec +1 -1
- data/test/test_shared_should.rb +0 -170
- data/test/test_shared_should_helper.rb +0 -26
- metadata +4 -4
data/README.md
CHANGED
@@ -111,7 +111,7 @@ Some rules:
|
|
111
111
|
* You can redefine your shares by using the same name. These shares will only be available in in the current and descendant contexts.
|
112
112
|
* Shares defined at the root (on your TestCase) are available in all contexts.
|
113
113
|
|
114
|
-
### Initialization
|
114
|
+
### Initialization Blocks
|
115
115
|
|
116
116
|
The shared invocation accepts an initialization block by chaining <tt>with</tt> (or its alias <tt>when</tt>) followed by a block. This block can be used to create or modify instance variables used by the shared functionality. It always executes before the shared functionality.
|
117
117
|
|
@@ -200,6 +200,39 @@ The shared functions also accept multiple parameters when the parameterization b
|
|
200
200
|
end
|
201
201
|
end
|
202
202
|
|
203
|
+
### Chaining shared setups with <tt>with_setup</tt>
|
204
|
+
|
205
|
+
Shared setup can be chained for use with shared shoulds and shared contexts.
|
206
|
+
|
207
|
+
context "Book" do
|
208
|
+
share_setup "for a rentable book" do
|
209
|
+
@book = Book.new(:quantity => 1, :price => 10_00, :rentable => true, :purchasable => false)
|
210
|
+
end
|
211
|
+
|
212
|
+
share_should "be available for checkout" { assert @book.available_for_checkout? }
|
213
|
+
|
214
|
+
use_should("be available for checkout").with_setup("for a rentable book")
|
215
|
+
end
|
216
|
+
|
217
|
+
And can be parameterized using a <tt>given</tt> clause.
|
218
|
+
|
219
|
+
context "Book" do
|
220
|
+
share_setup "for an in-stock book" do |rentable|
|
221
|
+
@book = Book.new(:quantity => 1, :price => 10_00, :rentable => rentable, :purchasable => false)
|
222
|
+
end
|
223
|
+
|
224
|
+
share_should "be available for checkout" { assert @book.available_for_checkout? }
|
225
|
+
|
226
|
+
use_should("be available for checkout").with_setup("for an in-stock book").given("the book is rentable") { true }
|
227
|
+
end
|
228
|
+
|
229
|
+
Multiple shared setups can then be combined with an initialization block.
|
230
|
+
|
231
|
+
use_should("successfully checkout shopping cart").
|
232
|
+
with_setup("for an empty shopping cart").
|
233
|
+
with_setup("for a rentable book").
|
234
|
+
with("a book in shopping cart") { @shopping_cart.add_book(@book) }
|
235
|
+
|
203
236
|
### Creating a Library of Shared Functionality
|
204
237
|
|
205
238
|
The shared functions can also be re-usable across multiple test cases.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.7.0
|
data/lib/shared_should.rb
CHANGED
@@ -1,20 +1,5 @@
|
|
1
1
|
require 'shoulda'
|
2
2
|
|
3
|
-
class Shoulda::Context
|
4
|
-
alias :method_missing_without_shared_method_check :method_missing
|
5
|
-
def method_missing(method, *args, &blk)
|
6
|
-
current_context = self
|
7
|
-
while current_context.kind_of?(Shoulda::Context) || current_context < Test::Unit::TestCase do
|
8
|
-
if Test::Unit::TestCase.shared_context_block_owner(current_context).shared_context_blocks[method.to_s]
|
9
|
-
return current_context.send(method, args[0], self, &blk)
|
10
|
-
end
|
11
|
-
break unless current_context.kind_of?(Shoulda::Context)
|
12
|
-
current_context = current_context.parent
|
13
|
-
end
|
14
|
-
method_missing_without_shared_method_check(method, *args, &blk)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
3
|
class Test::Unit::TestCase
|
19
4
|
attr_accessor :shared_value
|
20
5
|
@@shared_proxies_executed = {}
|
@@ -108,20 +93,20 @@ module Shoulda::SharedContext
|
|
108
93
|
end
|
109
94
|
|
110
95
|
def use_should(shared_name)
|
111
|
-
shared_proxy = Shoulda::SharedProxy.new(self, shared_name)
|
96
|
+
shared_proxy = Shoulda::SharedProxy.new(self, :should, shared_name)
|
112
97
|
shared_proxies << shared_proxy
|
113
98
|
return shared_proxy
|
114
99
|
end
|
115
100
|
|
116
101
|
def use_context(shared_name)
|
117
|
-
shared_proxy = Shoulda::SharedProxy.new(self, shared_name)
|
102
|
+
shared_proxy = Shoulda::SharedProxy.new(self, :context, shared_name)
|
118
103
|
shared_proxies << shared_proxy
|
119
104
|
return shared_proxy
|
120
105
|
end
|
121
106
|
|
122
107
|
def use_setup(shared_name)
|
123
|
-
shared_proxy = Shoulda::SharedProxy.new(self, shared_name)
|
124
|
-
shared_setup_block =
|
108
|
+
shared_proxy = Shoulda::SharedProxy.new(self, :setup, shared_name)
|
109
|
+
shared_setup_block = find_shared_block(:setup, shared_name)
|
125
110
|
setup do
|
126
111
|
shared_proxy.execute_and_set_shared_value(self)
|
127
112
|
call_block_with_shared_value(shared_setup_block)
|
@@ -163,11 +148,6 @@ module Shoulda::SharedContext
|
|
163
148
|
end
|
164
149
|
end
|
165
150
|
|
166
|
-
# deprecated
|
167
|
-
def shared_context_should(shared_context_name, &shared_context_block)
|
168
|
-
share_context(shared_context_name, &shared_context_block)
|
169
|
-
end
|
170
|
-
|
171
151
|
def share_context(shared_context_name, &shared_context_block)
|
172
152
|
wrapping_shared_context_block = Proc.new do
|
173
153
|
context shared_context_name do
|
@@ -175,12 +155,7 @@ module Shoulda::SharedContext
|
|
175
155
|
end
|
176
156
|
end
|
177
157
|
|
178
|
-
|
179
|
-
end
|
180
|
-
|
181
|
-
# deprecated
|
182
|
-
def shared_should(shared_should_name, &shared_should_block)
|
183
|
-
share_should(shared_should_name, &shared_should_block)
|
158
|
+
Test::Unit::TestCase.shared_context_block_owner(shared_context_for_block(shared_context_block)).shared_context_blocks[shared_context_name] = wrapping_shared_context_block
|
184
159
|
end
|
185
160
|
|
186
161
|
def share_should(shared_should_name, &shared_should_block)
|
@@ -190,16 +165,7 @@ module Shoulda::SharedContext
|
|
190
165
|
end
|
191
166
|
end
|
192
167
|
|
193
|
-
|
194
|
-
end
|
195
|
-
|
196
|
-
# deprecated
|
197
|
-
def shared_setup(shared_name, &setup_block)
|
198
|
-
shared_setup_block = Proc.new do
|
199
|
-
call_block_with_shared_value(setup_block)
|
200
|
-
end
|
201
|
-
|
202
|
-
do_shared_setup(shared_name, shared_context_for_block(setup_block), &shared_setup_block)
|
168
|
+
Test::Unit::TestCase.shared_context_block_owner(shared_context_for_block(shared_should_block)).shared_should_blocks[shared_should_name] = shared_context_block
|
203
169
|
end
|
204
170
|
|
205
171
|
def share_setup(shared_name, &setup_block)
|
@@ -219,16 +185,25 @@ module Shoulda::SharedContext
|
|
219
185
|
@shared_setup_blocks ||= {}
|
220
186
|
end
|
221
187
|
|
222
|
-
|
188
|
+
def find_shared_block(share_type, shared_name)
|
189
|
+
current_context = self
|
190
|
+
while current_context.kind_of?(Shoulda::Context) || current_context < Test::Unit::TestCase do
|
191
|
+
if shared_block = Test::Unit::TestCase.shared_context_block_owner(current_context).send("shared_#{share_type}_blocks")[shared_name]
|
192
|
+
return shared_block
|
193
|
+
end
|
194
|
+
raise "Unable to find share_#{share_type}('#{shared_name}')" if current_context.kind_of?(Class)
|
195
|
+
break unless current_context.kind_of?(Shoulda::Context)
|
196
|
+
current_context = current_context.parent
|
197
|
+
end
|
198
|
+
raise "Unable to find share_#{share_type}('#{shared_name}')"
|
199
|
+
end
|
200
|
+
|
201
|
+
private
|
223
202
|
|
224
203
|
def shared_context_for_block(shared_block)
|
225
204
|
eval("self", shared_block.binding)
|
226
205
|
end
|
227
206
|
|
228
|
-
def do_shared_context(shared_context_name, destination_context, &shared_context_block)
|
229
|
-
do_shared_helper(shared_context_name, destination_context, :should, :merge_shared_context, &shared_context_block)
|
230
|
-
end
|
231
|
-
|
232
207
|
def merge_shared_context(shared_context_block, caller_context, name, initialization_block)
|
233
208
|
name = '' if name.nil?
|
234
209
|
|
@@ -268,37 +243,6 @@ module Shoulda::SharedContext
|
|
268
243
|
end
|
269
244
|
end
|
270
245
|
|
271
|
-
def do_shared_helper(shared_name, destination_context, method_prefix, merge_method, &shared_setup_block)
|
272
|
-
method_name = shared_method_name(method_prefix, shared_name)
|
273
|
-
Test::Unit::TestCase.shared_context_block_owner(destination_context).shared_context_blocks[method_name] = shared_setup_block
|
274
|
-
|
275
|
-
# Ruby 1.8 workaround for define_method with a block
|
276
|
-
# http://coderrr.wordpress.com/2008/10/29/using-define_method-with-blocks-in-ruby-18/
|
277
|
-
eval <<-EOM
|
278
|
-
def destination_context.#{method_name}(name = nil, context = self, &setup_block)
|
279
|
-
#{merge_method}(Test::Unit::TestCase.shared_context_block_owner(self).shared_context_blocks['#{method_name}'], context, name, block_given? ? setup_block : nil)
|
280
|
-
end
|
281
|
-
EOM
|
282
|
-
end
|
283
|
-
|
284
|
-
def shared_method_name(method_prefix, context_name)
|
285
|
-
"#{method_prefix}_#{context_name.downcase.gsub(' ', '_').gsub(/[^_A-Za-z0-9]/, '')}"
|
286
|
-
end
|
287
|
-
|
288
|
-
private
|
289
|
-
|
290
|
-
def find_shared_setup_block(shared_name)
|
291
|
-
current_context = self
|
292
|
-
while current_context.kind_of?(Shoulda::Context) || current_context < Test::Unit::TestCase do
|
293
|
-
if shared_setup_block = Test::Unit::TestCase.shared_context_block_owner(current_context).shared_setup_blocks[shared_name]
|
294
|
-
return shared_setup_block
|
295
|
-
end
|
296
|
-
raise "Unable to find share_setup('#{shared_name}')" if current_context.kind_of?(Class)
|
297
|
-
break unless current_context.kind_of?(Shoulda::Context)
|
298
|
-
current_context = current_context.parent
|
299
|
-
end
|
300
|
-
raise "Unable to find share_setup('#{shared_name}')"
|
301
|
-
end
|
302
246
|
end
|
303
247
|
end
|
304
248
|
|
@@ -312,10 +256,11 @@ end
|
|
312
256
|
|
313
257
|
|
314
258
|
class Shoulda::SharedProxy
|
315
|
-
attr_accessor :shared_name, :description, :block_configs, :context
|
259
|
+
attr_accessor :shared_name, :share_type, :description, :block_configs, :context
|
316
260
|
|
317
|
-
def initialize(context, shared_name)
|
261
|
+
def initialize(context, share_type, shared_name)
|
318
262
|
self.context = context
|
263
|
+
self.share_type = share_type
|
319
264
|
self.shared_name = shared_name
|
320
265
|
self.block_configs = []
|
321
266
|
end
|
@@ -334,13 +279,19 @@ class Shoulda::SharedProxy
|
|
334
279
|
end
|
335
280
|
|
336
281
|
def with_setup(description)
|
337
|
-
initialization_block = context.
|
282
|
+
initialization_block = context.find_shared_block(:setup, description)
|
338
283
|
add_proxy_block(:with_setup, "with setup", description, :disable_and => true, &initialization_block)
|
339
284
|
end
|
340
285
|
|
341
286
|
def execute
|
342
|
-
|
343
|
-
|
287
|
+
raise "execute cannot be called for share_setup" if share_type == :setup
|
288
|
+
shared_proxy = self
|
289
|
+
context.context description do
|
290
|
+
setup do
|
291
|
+
shared_proxy.execute_and_set_shared_value(self)
|
292
|
+
end
|
293
|
+
shared_proxy.context.find_shared_block(shared_proxy.share_type, shared_proxy.shared_name).bind(self).call
|
294
|
+
end
|
344
295
|
end
|
345
296
|
|
346
297
|
def execute_and_set_shared_value(test_context)
|
@@ -358,8 +309,6 @@ class Shoulda::SharedProxy
|
|
358
309
|
call_block_with_shared_value(block) if block
|
359
310
|
end
|
360
311
|
end.last
|
361
|
-
# # TODO: needs shared_value
|
362
|
-
# blocks.collect {|block| block.bind(self).call if block}.last
|
363
312
|
end
|
364
313
|
end
|
365
314
|
|
data/shared_should.gemspec
CHANGED
data/test/test_shared_should.rb
CHANGED
@@ -102,57 +102,6 @@ class TestSharedShould < Test::Unit::TestCase
|
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
|
-
context ".shared_context_should" do
|
106
|
-
context "without params" do
|
107
|
-
setup do
|
108
|
-
@value = true
|
109
|
-
end
|
110
|
-
|
111
|
-
shared_context_should "be valid" do
|
112
|
-
setup do
|
113
|
-
@context_value = true
|
114
|
-
end
|
115
|
-
|
116
|
-
should "have true value" do
|
117
|
-
assert @value
|
118
|
-
end
|
119
|
-
|
120
|
-
should "call setup in shared context" do
|
121
|
-
assert @context_value
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
should_be_valid
|
126
|
-
end
|
127
|
-
|
128
|
-
context "with params" do
|
129
|
-
setup do
|
130
|
-
@value = true
|
131
|
-
end
|
132
|
-
|
133
|
-
shared_context_should "be valid for specified value" do
|
134
|
-
setup do |value|
|
135
|
-
@expected_value = value
|
136
|
-
@context_value = true
|
137
|
-
end
|
138
|
-
|
139
|
-
should "have specified value" do |value|
|
140
|
-
assert_equal value, @value
|
141
|
-
end
|
142
|
-
|
143
|
-
should "setup @expected_value" do |value|
|
144
|
-
assert_equal value, @expected_value
|
145
|
-
end
|
146
|
-
|
147
|
-
should "call setup in shared context" do
|
148
|
-
assert @context_value
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
should_be_valid_for_specified_value { true }
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
105
|
context ".share_should" do
|
157
106
|
context "without params" do
|
158
107
|
share_should "be a true value" do
|
@@ -199,70 +148,6 @@ class TestSharedShould < Test::Unit::TestCase
|
|
199
148
|
end
|
200
149
|
end
|
201
150
|
|
202
|
-
context ".shared_should" do
|
203
|
-
context "without params" do
|
204
|
-
setup do
|
205
|
-
@value = true
|
206
|
-
end
|
207
|
-
|
208
|
-
shared_should "have true value" do
|
209
|
-
assert @value
|
210
|
-
end
|
211
|
-
|
212
|
-
should_have_true_value
|
213
|
-
end
|
214
|
-
|
215
|
-
context "with params" do
|
216
|
-
setup do
|
217
|
-
@value = true
|
218
|
-
end
|
219
|
-
|
220
|
-
shared_should "have specified value" do |value|
|
221
|
-
assert_equal value, @value
|
222
|
-
end
|
223
|
-
|
224
|
-
should_have_specified_value { true }
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
context ".shared_setup" do
|
229
|
-
context "without params" do
|
230
|
-
shared_setup "for value" do
|
231
|
-
@value = true
|
232
|
-
end
|
233
|
-
|
234
|
-
context "with shared setup value" do
|
235
|
-
setup do
|
236
|
-
@value = false
|
237
|
-
end
|
238
|
-
|
239
|
-
setup_for_value
|
240
|
-
|
241
|
-
should "have a true value from shared setup" do
|
242
|
-
assert @value
|
243
|
-
end
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
context "with params" do
|
248
|
-
shared_setup "for value" do |value|
|
249
|
-
@value = value
|
250
|
-
end
|
251
|
-
|
252
|
-
context "with shared setup value" do
|
253
|
-
setup do
|
254
|
-
@value = false
|
255
|
-
end
|
256
|
-
|
257
|
-
setup_for_value("with true") { true }
|
258
|
-
|
259
|
-
should "have a true value from shared setup" do
|
260
|
-
assert @value
|
261
|
-
end
|
262
|
-
end
|
263
|
-
end
|
264
|
-
end
|
265
|
-
|
266
151
|
context ".share_setup" do
|
267
152
|
context "without params" do
|
268
153
|
context "without initialization block" do
|
@@ -339,48 +224,6 @@ class TestSharedShould < Test::Unit::TestCase
|
|
339
224
|
end
|
340
225
|
end
|
341
226
|
|
342
|
-
context "parameterized block" do
|
343
|
-
shared_context_should "be valid with shared context" do
|
344
|
-
setup do
|
345
|
-
assert [1, 2, 3], shared_value
|
346
|
-
end
|
347
|
-
|
348
|
-
setup do |value|
|
349
|
-
assert [1, 2, 3], value
|
350
|
-
end
|
351
|
-
|
352
|
-
setup do |first, second, third|
|
353
|
-
assert 1, first
|
354
|
-
assert 2, second
|
355
|
-
assert 3, third
|
356
|
-
end
|
357
|
-
|
358
|
-
should "do something with shared_value" do
|
359
|
-
assert [1, 2, 3], shared_value
|
360
|
-
end
|
361
|
-
|
362
|
-
should "do something with value block param" do |value|
|
363
|
-
assert [1, 2, 3], value
|
364
|
-
end
|
365
|
-
|
366
|
-
should "do something with value block params" do |first, second, third|
|
367
|
-
assert 1, first
|
368
|
-
assert 2, second
|
369
|
-
assert 3, third
|
370
|
-
end
|
371
|
-
end
|
372
|
-
|
373
|
-
shared_should "be valid with shared should" do |first, second, third|
|
374
|
-
assert 1, first
|
375
|
-
assert 2, second
|
376
|
-
assert 3, third
|
377
|
-
end
|
378
|
-
|
379
|
-
should_be_valid_with_shared_context("with an array") { ['1', '2', '3'] }
|
380
|
-
|
381
|
-
should_be_valid_with_shared_should("with an array") { ['1', '2', '3'] }
|
382
|
-
end
|
383
|
-
|
384
227
|
context "context directly under test class" do
|
385
228
|
share_setup "for a true value" do
|
386
229
|
@value = true
|
@@ -512,23 +355,10 @@ class TestSharedShould < Test::Unit::TestCase
|
|
512
355
|
'test: .share_should without params when value in initializer when value is true should be a true value. ',
|
513
356
|
'test: .share_should without params with value in initializer when value is true should be a true value. ',
|
514
357
|
'test: .share_should without params with value in setup should be a true value. ',
|
515
|
-
'test: .shared_context_should with params be valid for specified value should call setup in shared context. ',
|
516
|
-
'test: .shared_context_should with params be valid for specified value should have specified value. ',
|
517
|
-
'test: .shared_context_should with params be valid for specified value should setup @expected_value. ',
|
518
|
-
'test: .shared_context_should without params be valid should call setup in shared context. ',
|
519
|
-
'test: .shared_context_should without params be valid should have true value. ',
|
520
|
-
'test: .shared_setup with params with shared setup value should have a true value from shared setup. ',
|
521
|
-
'test: .shared_setup without params with shared setup value should have a true value from shared setup. ',
|
522
|
-
'test: .shared_should with params should have specified value. ',
|
523
|
-
'test: .shared_should without params should have true value. ',
|
524
358
|
'test: SharedShould should execute setup instance method. ',
|
525
359
|
'test: context directly under test class for a valid context test should have a true value. ',
|
526
360
|
'test: context directly under test class should be a valid should test. ',
|
527
361
|
'test: for a valid context test in class should have a true value. ',
|
528
|
-
'test: parameterized block with an array be valid with shared context should do something with shared_value. ',
|
529
|
-
'test: parameterized block with an array be valid with shared context should do something with value block param. ',
|
530
|
-
'test: parameterized block with an array be valid with shared context should do something with value block params. ',
|
531
|
-
'test: parameterized block with an array should be valid with shared should. ',
|
532
362
|
'test: shoulda macro should be a valid macro. ',
|
533
363
|
'test: expected methods should have expected methods in test. ',
|
534
364
|
"test: .share_context with params given true for a valid specified value should call setup in shared context. ",
|
@@ -2,10 +2,6 @@ require 'helper'
|
|
2
2
|
|
3
3
|
# Create a subclass for some shares
|
4
4
|
class SubclassTestCase < Test::Unit::TestCase
|
5
|
-
shared_should "have true value for shared should helper" do
|
6
|
-
assert @value
|
7
|
-
end
|
8
|
-
|
9
5
|
share_should "be a true value for shared should helper" do
|
10
6
|
assert @value
|
11
7
|
end
|
@@ -17,22 +13,12 @@ end
|
|
17
13
|
|
18
14
|
# re-open Test::Unit::TestCase class for some shares
|
19
15
|
class Test::Unit::TestCase
|
20
|
-
shared_context_should "be valid for shared context helper" do
|
21
|
-
should "be true value" do
|
22
|
-
assert @value
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
16
|
share_context "for a true value for shared context helper" do
|
27
17
|
should "be true value" do
|
28
18
|
assert @value
|
29
19
|
end
|
30
20
|
end
|
31
21
|
|
32
|
-
shared_setup "for shared setup helper" do
|
33
|
-
@value = true
|
34
|
-
end
|
35
|
-
|
36
22
|
share_setup "for a true value for shared setup helper" do
|
37
23
|
@value = true
|
38
24
|
end
|
@@ -45,8 +31,6 @@ class TestSharedShouldHelper < SubclassTestCase
|
|
45
31
|
@value = true
|
46
32
|
end
|
47
33
|
|
48
|
-
should_have_true_value_for_shared_should_helper
|
49
|
-
|
50
34
|
use_should "be a true value for shared should helper"
|
51
35
|
end
|
52
36
|
|
@@ -55,19 +39,9 @@ class TestSharedShouldHelper < SubclassTestCase
|
|
55
39
|
@value = true
|
56
40
|
end
|
57
41
|
|
58
|
-
should_be_valid_for_shared_context_helper
|
59
|
-
|
60
42
|
use_context "for a true value for shared context helper"
|
61
43
|
end
|
62
44
|
|
63
|
-
context "with shared_setup helper" do
|
64
|
-
setup_for_shared_setup_helper
|
65
|
-
|
66
|
-
should "be true value" do
|
67
|
-
assert @value
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
45
|
context "with share_setup helper" do
|
72
46
|
use_setup "for a true value for shared setup helper"
|
73
47
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shared_should
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 3
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 7
|
9
|
+
- 0
|
10
|
+
version: 0.7.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Michael Pearce
|