shared_should 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,238 @@
1
+ # Shared Should - Share and reuse shoulds, contexts, and setups with Shoulda - easy, schmeasy.
2
+
3
+ Shared Should allows you to easily create reusable shoulds, contexts and setups with familiar looking Shoulda syntax. Inspired by Rspec's shared example groups for context reuse, Shared Should allows sharing of contexts, shoulds,
4
+ and setup blocks. Shared Should goes even further by allowing an initialization block and parameterization to fine-tune the usage of the shared functionality.
5
+
6
+ ## Quick-Start Examples
7
+
8
+ Some quick examples to get you started using Shared Should. The domain of the examples is customers renting and purchasing textbooks - like we do at [BookRenter.com](http://www.bookrenter.com "BookRenter.com").
9
+
10
+ ### Shared Should
11
+
12
+ Sharing shoulds is easy.
13
+
14
+ context "Book" do
15
+ context "with an in-stock book" do
16
+ setup { @book = Book.new(:quantity => 1, :price => 10_00 }
17
+
18
+ ### Define a shared should
19
+ share_should "be available for checkout" { assert @book.available_for_checkout? }
20
+
21
+ context "with a rentable book" do
22
+ setup { @book.rentable = true }
23
+
24
+ ### Use the "be available for checkout" share_should
25
+ use_should "be available for checkout"
26
+ end
27
+
28
+ context "with a purchasable book" do
29
+ setup { @book.purchasable = true }
30
+
31
+ ### Use the "be available for checkout" share_should in this context too
32
+ use_should "be available for checkout"
33
+ end
34
+
35
+ ### ...or DRY it up by using .when and an initialization block
36
+ use_should("be available for checkout").when("rentable") { @book.rentable = true }
37
+ use_should("be available for checkout").when("purchasable") { @book.purchasable = true }
38
+ end
39
+ end
40
+
41
+ ### Shared Setup
42
+
43
+ Sharing setups is easy, too.
44
+
45
+ context "Book" do
46
+ ### Define a shared setup
47
+ share_setup "for an in-stock book" { @book = Book.new(:quantity => 1, :price => 10_00) }
48
+
49
+ context "with an in-stock rentable book" do
50
+ ### Use the shared setup here
51
+ use_setup "for an in-stock book"
52
+
53
+ ### Do some additional setup after the shared setup
54
+ setup { @book.rentable = true }
55
+
56
+ should "be available for checkout" { assert @book.available_for_checkout? }
57
+ end
58
+
59
+ context "with an in-stock purchasable book" do
60
+ ### Use the shared setup again
61
+ use_setup "for an in-stock book"
62
+
63
+ setup { @book.purchasable = true }
64
+
65
+ should "be available for checkout" { assert @book.available_for_checkout? }
66
+ end
67
+ end
68
+
69
+ ### Shared Context
70
+
71
+ Sharing whole contexts? Schmeasy!
72
+
73
+ context "Book" do
74
+ context "with an in-stock book" do
75
+ setup { @book = Book.new(:quantity => 1, :price => 10_00) }
76
+
77
+ ### Define a shared context
78
+ share_context "for a book available for checkout" do
79
+ should "be in stock" { assert @book.quantity > 0 }
80
+ should "have a non-negative price" { assert @book.price > 0 }
81
+ should "be rentable or purchasable" { assert @book.rentable || @book.purchasable }
82
+ end
83
+
84
+ context "with a rentable book" do
85
+ setup { @book.rentable = true }
86
+
87
+ ### Run the shoulds inside the shared context with a rentable book
88
+ use_context "for a book available for checkout"
89
+ end
90
+
91
+ context "with a purchasable book" do
92
+ setup { @book.purchasable = true }
93
+
94
+ ### Run the shoulds inside the shared context again with a purchasable book
95
+ use_context "for a book available for checkout"
96
+ end
97
+
98
+ ### ...or DRY it up by using .when and an initialization block
99
+ use_context("for a book available for checkout").when("rentable") { @book.rentable = true }
100
+ use_context("for a book available for checkout").when("purchasable") { @book.purchasable = true }
101
+ end
102
+ end
103
+
104
+ ## More Information on Syntax and Usage
105
+
106
+ ### Finding Your Share
107
+
108
+ Some rules:
109
+
110
+ * When <tt>use\_should</tt>, <tt>use\_context</tt> or <tt>use\_setup</tt> is invoked, it searches up the context hierarchy to find a matching shared definition.
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
+ * Shares defined at the root (on your TestCase) are available in all contexts.
113
+ * If you define a shared setup at the root level, you will need to call <tt>super</tt> if you have a setup instance method for your test.
114
+
115
+ ### Initialization Block
116
+
117
+ The shared invocation accepts an initialization block by chaining <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.
118
+
119
+ context "Book" do
120
+ setup { @book = Book.new(:quantity => 1, :price => 10_00) }
121
+
122
+ share_should "be available for checkout" { assert @book.available_for_checkout? }
123
+
124
+ context "with a rentable book" do
125
+ # when share_should "be available for checkout" is executed, @book will have rentable equal to true
126
+ use_should("be available for checkout").when("rentable") { @book.rentable = true }
127
+ end
128
+
129
+ context "with a purchasable book" do
130
+ use_should("be available for checkout").when("purchasable") { @book.purchasable = true }
131
+ end
132
+ end
133
+
134
+ ### Parameterizing Shares
135
+
136
+ Shared functions can also be parameterized using block parameters. This can be done for shared setups, shoulds, and the setups and shoulds contained within a shared context. The value passed to the shared function is the return value of the <tt>with</tt> parameterization block. The below example parameterizes a shared setup.
137
+
138
+ context "Book" do
139
+ share_setup "for an in-stock book" do |rentable|
140
+ @book = Book.new(:quantity => 1, :price => 10_00, :rentable => rentable, :purchasable => false)
141
+ end
142
+
143
+ context "with rentable book" do
144
+ # the return value of the block is "true" which will be passed as the block parameter "rentable"
145
+ use_setup("for an in-stock book").with { true }
146
+
147
+ should "be available for checkout" { assert @book.available_for_checkout? }
148
+ end
149
+ end
150
+
151
+ Here is a parameterized shared should.
152
+
153
+ context "Book" do
154
+ context "with in-stock book" do
155
+ setup { @book = Book.new(:quantity => 1) }
156
+
157
+ share_should "be unavailable for checkout for price" do |price|
158
+ @book.price = price
159
+ assert_false @book.available_for_checkout?
160
+ end
161
+
162
+ use_should("be unavailable for checkout for price").with("zero") { 0 }
163
+ use_should("be unavailable for checkout for price").with("a negative price") { -1 }
164
+ end
165
+ end
166
+
167
+ And a parameterized shared context.
168
+
169
+ context "Book" do
170
+ context "with in-stock book" do
171
+ setup { @book = Book.new(:quantity => 1) }
172
+
173
+ share_context "for a book available for checkout at price" do
174
+ # parameters are on the setup and shoulds, not on the context
175
+ setup { |price| @book.price = price }
176
+
177
+ # we could also access price in the should blocks, but we don't need it again
178
+ should "be in stock" { assert @book.quantity > 0 }
179
+ should "have a non-negative price" { assert @book.price > 0 }
180
+ should "be rentable or purchasable" { assert @book.rentable || @book.purchasable }
181
+ end
182
+
183
+ use_context("for a book available for checkout at price").with("a positive price") { 10_00 }
184
+ end
185
+ end
186
+
187
+ The shared functions also accept multiple parameters when the parameterization block returns an array.
188
+
189
+ context "Book" do
190
+ context "with rentable book" do
191
+ setup { @book = Book.new(:rentable => true) }
192
+
193
+ share_should "be unavailable for checkout for quantity and price" do |quantity, price|
194
+ @book.quantity = quantity
195
+ @book.price = price
196
+ assert_false @book.available_for_checkout?
197
+ end
198
+
199
+ use_should("be unavailable for checkout for quantity and price").with("a zero quantity") { [0, 10_00] }
200
+ use_should("be unavailable for checkout for quantity and price").with("a zero price") { [1, 0] }
201
+ end
202
+ end
203
+
204
+ ### Creating a Library of Shared Functionality
205
+
206
+ The shared functions can also be re-usable across multiple test cases.
207
+
208
+ In your test helper file:
209
+
210
+ class Test::Unit::TestCase
211
+ share_setup "for an in-stock book" do |rentable, purchasable|
212
+ @book = Book.new(:quantity => 1, :price => 10_00, :rentable => rentable, :purchasable => purchasable)
213
+ end
214
+ end
215
+
216
+ In your test file:
217
+
218
+ class BookTest < Test::Unit::TestCase
219
+ context "with an in-stock book" do
220
+ use_setup("for an in-stock book").with { [true, true] }
221
+
222
+ should "be in stock" { assert @book.quantity > 0 }
223
+ end
224
+ end
225
+
226
+
227
+ # Credits
228
+
229
+ Shared Shoulda is maintained by [Michael Pearce](http://github.com/michaelgpearce) and is funded by [BookRenter.com](http://www.bookrenter.com "BookRenter.com"). Many of the ideas that have inspired Shared Should come
230
+ from practical usage by the Bookrenter software development team and conversations with Bookrenter developers [Andrew Wheeler](http://github.com/jawheeler), [Ben Somers](http://github.com/bensomers), and [Philippe Huibonhoa](http://github.com/phuibonhoa).
231
+
232
+ ![BookRenter.com Logo](http://assets0.bookrenter.com/images/header/bookrenter_logo.gif "BookRenter.com")
233
+
234
+
235
+ # Copyright
236
+
237
+ Copyright (c) 2011 Michael Pearce, Bookrenter.com. See LICENSE.txt for further details.
238
+
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.0
1
+ 0.6.1
data/lib/shared_should.rb CHANGED
@@ -120,7 +120,7 @@ module Shoulda::SharedContext
120
120
  shared_setup_block = find_shared_setup_block(shared_name)
121
121
  setup do
122
122
  if initialization_block = shared_proxy.initialization_block
123
- setup_shared_values(shared_proxy.when_description, shared_proxy.initialization_block)
123
+ setup_shared_values(shared_proxy.description, shared_proxy.initialization_block)
124
124
  end
125
125
  call_block_with_shared_value(shared_setup_block)
126
126
  end
@@ -310,29 +310,41 @@ end
310
310
 
311
311
 
312
312
  class Shoulda::SharedProxy
313
- attr_accessor :shared_name, :when_description, :initialization_block
313
+ attr_accessor :shared_name, :description, :initialization_blocks
314
314
 
315
315
  def initialize(shared_name)
316
316
  self.shared_name = shared_name
317
+ self.initialization_blocks = []
317
318
  end
318
319
 
319
- def when(when_description = nil, &initialization_block)
320
- when_helper("when", when_description, &initialization_block)
320
+ def when(description = nil, &initialization_block)
321
+ when_helper("when", description, &initialization_block)
322
+ return self
321
323
  end
322
324
 
323
- def with(with_description = nil, &initialization_block)
324
- when_helper("with", with_description, &initialization_block)
325
+ def with(description = nil, &initialization_block)
326
+ when_helper("with", description, &initialization_block)
327
+ return nil
325
328
  end
326
329
 
327
330
  def execute(context)
328
331
  method_name = context.send(:shared_method_name, :should, shared_name)
329
- context.send(method_name, when_description, &initialization_block)
332
+ context.send(method_name, description, &initialization_block)
333
+ end
334
+
335
+ def initialization_block
336
+ blocks = initialization_blocks
337
+ return Proc.new do
338
+ blocks.collect {|block| block.bind(self).call}.last
339
+ end
330
340
  end
331
341
 
332
342
  private
333
343
 
334
- def when_helper(when_name, when_description = nil, &initialization_block)
335
- self.when_description = when_description ? "#{when_name} #{when_description}" : nil
336
- self.initialization_block = initialization_block
344
+ def when_helper(conditional, description = nil, &initialization_block)
345
+ if description
346
+ self.description = "#{self.description}#{self.description.nil? ? nil : ' and '}#{conditional} #{description}"
347
+ end
348
+ self.initialization_blocks << initialization_block
337
349
  end
338
350
  end
@@ -5,23 +5,23 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{shared_should}
8
- s.version = "0.6.0"
8
+ s.version = "0.6.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Michael Pearce"]
12
- s.date = %q{2011-02-18}
12
+ s.date = %q{2011-03-02}
13
13
  s.description = %q{Share and reuse shoulds, contexts, and setup in Shoulda.}
14
14
  s.email = %q{michael.pearce@bookrenter.com}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE.txt",
17
- "README.rdoc"
17
+ "README.md"
18
18
  ]
19
19
  s.files = [
20
20
  ".document",
21
21
  "Gemfile",
22
22
  "Gemfile.lock",
23
23
  "LICENSE.txt",
24
- "README.rdoc",
24
+ "README.md",
25
25
  "Rakefile",
26
26
  "VERSION",
27
27
  "lib/shared_should.rb",
@@ -33,7 +33,7 @@ Gem::Specification.new do |s|
33
33
  s.homepage = %q{http://github.com/michaelgpearce/shared_should}
34
34
  s.licenses = ["MIT"]
35
35
  s.require_paths = ["lib"]
36
- s.rubygems_version = %q{1.4.0}
36
+ s.rubygems_version = %q{1.5.2}
37
37
  s.summary = %q{Share and reuse shoulds, contexts, and setup in Shoulda.}
38
38
  s.test_files = [
39
39
  "test/helper.rb",
@@ -64,7 +64,18 @@ class TestSharedShould < Test::Unit::TestCase
64
64
  end
65
65
  end
66
66
 
67
- use_context("for a valid specified value").when("true") { true }
67
+ use_context("for a valid specified value").with("true") { true }
68
+
69
+ context "with chaining" do
70
+ share_context "for a chained value" do
71
+ should "chain initialization block and be with params" do |value|
72
+ assert @chain
73
+ assert value
74
+ end
75
+ end
76
+
77
+ use_context("for a chained value").when("using initialization chain") { @chain = true }.with("true") { true }
78
+ end
68
79
  end
69
80
  end
70
81
 
@@ -138,7 +149,7 @@ class TestSharedShould < Test::Unit::TestCase
138
149
  end
139
150
 
140
151
  context "with value in initializer" do
141
- use_should("be a true value").with("true value") { @value = true }
152
+ use_should("be a true value").when("value is true") { @value = true }
142
153
  end
143
154
  end
144
155
 
@@ -151,7 +162,17 @@ class TestSharedShould < Test::Unit::TestCase
151
162
  assert_equal value, @value
152
163
  end
153
164
 
154
- use_should("be a valid specified value").when("true") { true }
165
+ use_should("be a valid specified value").with("true") { true }
166
+
167
+ context "with chaining" do
168
+ share_should "be a valid specified value" do |value|
169
+ assert @chain
170
+ assert value
171
+ end
172
+
173
+ use_should("be a valid specified value").when("using initialization chain") { @chain = true }.with("true") { true }
174
+ use_should("be a valid specified value").when("using initialization chain xxxx") { @chain = true }.with("true") { true }
175
+ end
155
176
  end
156
177
  end
157
178
 
@@ -248,7 +269,7 @@ class TestSharedShould < Test::Unit::TestCase
248
269
  @value = @initialization_value
249
270
  end
250
271
 
251
- use_setup("for value").with("true initialization value") { @initialization_value = true }
272
+ use_setup("for value").when("initialization value is true") { @initialization_value = true }
252
273
 
253
274
  should "have a true value from shared setup" do
254
275
  assert @value
@@ -256,7 +277,7 @@ class TestSharedShould < Test::Unit::TestCase
256
277
  end
257
278
  end
258
279
 
259
- context "with parameterized initialization block" do
280
+ context "with param block" do
260
281
  share_setup "for value" do |value|
261
282
  @value = value
262
283
  end
@@ -267,12 +288,30 @@ class TestSharedShould < Test::Unit::TestCase
267
288
  @value = false
268
289
  end
269
290
 
270
- use_setup("for value").with("true initialization value") { true }
291
+ use_setup("for value").with("true") { true }
271
292
 
272
293
  should "have a true value from shared setup" do
273
294
  assert @value
274
295
  end
275
296
  end
297
+
298
+ context "with chaining" do
299
+ setup do
300
+ @chain = nil
301
+ @value = nil
302
+ end
303
+
304
+ share_setup "for value" do |value|
305
+ @value = value
306
+ end
307
+
308
+ use_setup("for value").when("using initialization chain") { @chain = true }.with("true") { true }
309
+
310
+ should "have used share with chain and params" do
311
+ assert @chain
312
+ assert @value
313
+ end
314
+ end
276
315
  end
277
316
  end
278
317
 
@@ -394,41 +433,44 @@ class TestSharedShould < Test::Unit::TestCase
394
433
 
395
434
  # ensure test methods are created
396
435
  expected_method_names = [
397
- "test: .share_context with params when true for a valid specified value should call setup in shared context. ",
398
- "test: .share_context with params when true for a valid specified value should call setup in shared context. ",
399
- "test: .share_context with params when true for a valid specified value should have specified value. ",
400
- "test: .share_context with params when true for a valid specified value should setup @expected_value. ",
401
- "test: .share_context without params with value in initializer when a true value for a valid value should call setup in shared context. ",
402
- "test: .share_context without params with value in initializer when a true value for a valid value should have true value. ",
403
- "test: .share_context without params with value in setup for a valid value should call setup in shared context. ",
404
- "test: .share_context without params with value in setup for a valid value should have true value. ",
405
- "test: .shared_context_should with params be valid for specified value should call setup in shared context. ",
406
- "test: .shared_context_should with params be valid for specified value should have specified value. ",
407
- "test: .shared_context_should with params be valid for specified value should setup @expected_value. ",
408
- "test: .shared_context_should without params be valid should call setup in shared context. ",
409
- "test: .shared_context_should without params be valid should have true value. ",
410
- "test: .shared_setup with params with shared setup value should have a true value from shared setup. ",
411
- "test: .shared_setup without params with shared setup value should have a true value from shared setup. ",
412
- "test: .share_setup with parameterized initialization block with shared setup value should have a true value from shared setup. ",
413
- "test: .share_setup without params with initialization block should have a true value from shared setup. ",
414
- "test: .share_setup without params without initialization block should have a true value from shared setup. ",
415
- "test: .shared_should with params should have specified value. ",
416
- "test: .shared_should without params should have true value. ",
417
- "test: .share_should with params when true should be a valid specified value. ",
418
- "test: .share_should without params when value in initializer when value is true should be a true value. ",
419
- "test: .share_should without params with value in initializer with true value should be a true value. ",
420
- "test: .share_should without params with value in setup should be a true value. ",
421
- "test: context directly under test class for a valid context test should have a true value. ",
422
- "test: context directly under test class should be a valid should test. ",
423
- "test: parameterized block with an array be valid with shared context should do something with shared_value. ",
424
- "test: parameterized block with an array be valid with shared context should do something with value block param. ",
425
- "test: parameterized block with an array be valid with shared context should do something with value block params. ",
426
- "test: parameterized block with an array should be valid with shared should. ",
427
- "test: should be a valid should test in class. ",
428
- "test: for a valid context test in class should have a true value. ",
429
- "test: SharedShould should execute setup instance method. ",
430
- "test: shoulda macro should be a valid macro. "
431
- ].inject({}) do |hash, expected_method_name|
436
+ 'test: should be a valid should test in class. ',
437
+ 'test: .share_context with params with chaining when using initialization chain and with true for a chained value should chain initialization block and be with params. ',
438
+ 'test: .share_context with params with true for a valid specified value should call setup in shared context. ',
439
+ 'test: .share_context with params with true for a valid specified value should have specified value. ',
440
+ 'test: .share_context with params with true for a valid specified value should setup @expected_value. ',
441
+ 'test: .share_context without params with value in initializer when a true value for a valid value should call setup in shared context. ',
442
+ 'test: .share_context without params with value in initializer when a true value for a valid value should have true value. ',
443
+ 'test: .share_context without params with value in setup for a valid value should call setup in shared context. ',
444
+ 'test: .share_context without params with value in setup for a valid value should have true value. ',
445
+ 'test: .share_setup with param block with chaining should have used share with chain and params. ',
446
+ 'test: .share_setup with param block with shared setup value should have a true value from shared setup. ',
447
+ 'test: .share_setup without params with initialization block should have a true value from shared setup. ',
448
+ 'test: .share_setup without params without initialization block should have a true value from shared setup. ',
449
+ 'test: .share_should with params with chaining when using initialization chain and with true should be a valid specified value. ',
450
+ 'test: .share_should with params with chaining when using initialization chain xxxx and with true should be a valid specified value. ',
451
+ 'test: .share_should with params with true should be a valid specified value. ',
452
+ 'test: .share_should without params when value in initializer when value is true should be a true value. ',
453
+ 'test: .share_should without params with value in initializer when value is true should be a true value. ',
454
+ 'test: .share_should without params with value in setup should be a true value. ',
455
+ 'test: .shared_context_should with params be valid for specified value should call setup in shared context. ',
456
+ 'test: .shared_context_should with params be valid for specified value should have specified value. ',
457
+ 'test: .shared_context_should with params be valid for specified value should setup @expected_value. ',
458
+ 'test: .shared_context_should without params be valid should call setup in shared context. ',
459
+ 'test: .shared_context_should without params be valid should have true value. ',
460
+ 'test: .shared_setup with params with shared setup value should have a true value from shared setup. ',
461
+ 'test: .shared_setup without params with shared setup value should have a true value from shared setup. ',
462
+ 'test: .shared_should with params should have specified value. ',
463
+ 'test: .shared_should without params should have true value. ',
464
+ 'test: SharedShould should execute setup instance method. ',
465
+ 'test: context directly under test class for a valid context test should have a true value. ',
466
+ 'test: context directly under test class should be a valid should test. ',
467
+ 'test: for a valid context test in class should have a true value. ',
468
+ 'test: parameterized block with an array be valid with shared context should do something with shared_value. ',
469
+ 'test: parameterized block with an array be valid with shared context should do something with value block param. ',
470
+ 'test: parameterized block with an array be valid with shared context should do something with value block params. ',
471
+ 'test: parameterized block with an array should be valid with shared should. ',
472
+ 'test: shoulda macro should be a valid macro. '
473
+ ].inject({}) do |hash, expected_method_name|
432
474
  hash[expected_method_name] = true
433
475
  hash
434
476
  end
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: 7
4
+ hash: 5
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 6
9
- - 0
10
- version: 0.6.0
9
+ - 1
10
+ version: 0.6.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Michael Pearce
@@ -15,13 +15,11 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-18 00:00:00 -08:00
18
+ date: 2011-03-02 00:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- prerelease: false
23
22
  name: shoulda
24
- type: :development
25
23
  version_requirements: &id001 !ruby/object:Gem::Requirement
26
24
  none: false
27
25
  requirements:
@@ -31,11 +29,11 @@ dependencies:
31
29
  segments:
32
30
  - 0
33
31
  version: "0"
32
+ prerelease: false
33
+ type: :development
34
34
  requirement: *id001
35
35
  - !ruby/object:Gem::Dependency
36
- prerelease: false
37
36
  name: bundler
38
- type: :development
39
37
  version_requirements: &id002 !ruby/object:Gem::Requirement
40
38
  none: false
41
39
  requirements:
@@ -47,11 +45,11 @@ dependencies:
47
45
  - 0
48
46
  - 0
49
47
  version: 1.0.0
48
+ prerelease: false
49
+ type: :development
50
50
  requirement: *id002
51
51
  - !ruby/object:Gem::Dependency
52
- prerelease: false
53
52
  name: jeweler
54
- type: :development
55
53
  version_requirements: &id003 !ruby/object:Gem::Requirement
56
54
  none: false
57
55
  requirements:
@@ -63,11 +61,11 @@ dependencies:
63
61
  - 5
64
62
  - 2
65
63
  version: 1.5.2
64
+ prerelease: false
65
+ type: :development
66
66
  requirement: *id003
67
67
  - !ruby/object:Gem::Dependency
68
- prerelease: false
69
68
  name: rcov
70
- type: :development
71
69
  version_requirements: &id004 !ruby/object:Gem::Requirement
72
70
  none: false
73
71
  requirements:
@@ -77,11 +75,11 @@ dependencies:
77
75
  segments:
78
76
  - 0
79
77
  version: "0"
78
+ prerelease: false
79
+ type: :development
80
80
  requirement: *id004
81
81
  - !ruby/object:Gem::Dependency
82
- prerelease: false
83
82
  name: shoulda
84
- type: :runtime
85
83
  version_requirements: &id005 !ruby/object:Gem::Requirement
86
84
  none: false
87
85
  requirements:
@@ -91,11 +89,11 @@ dependencies:
91
89
  segments:
92
90
  - 0
93
91
  version: "0"
92
+ prerelease: false
93
+ type: :runtime
94
94
  requirement: *id005
95
95
  - !ruby/object:Gem::Dependency
96
- prerelease: false
97
96
  name: shoulda
98
- type: :development
99
97
  version_requirements: &id006 !ruby/object:Gem::Requirement
100
98
  none: false
101
99
  requirements:
@@ -105,6 +103,8 @@ dependencies:
105
103
  segments:
106
104
  - 0
107
105
  version: "0"
106
+ prerelease: false
107
+ type: :development
108
108
  requirement: *id006
109
109
  description: Share and reuse shoulds, contexts, and setup in Shoulda.
110
110
  email: michael.pearce@bookrenter.com
@@ -114,13 +114,13 @@ extensions: []
114
114
 
115
115
  extra_rdoc_files:
116
116
  - LICENSE.txt
117
- - README.rdoc
117
+ - README.md
118
118
  files:
119
119
  - .document
120
120
  - Gemfile
121
121
  - Gemfile.lock
122
122
  - LICENSE.txt
123
- - README.rdoc
123
+ - README.md
124
124
  - Rakefile
125
125
  - VERSION
126
126
  - lib/shared_should.rb
@@ -158,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
158
158
  requirements: []
159
159
 
160
160
  rubyforge_project:
161
- rubygems_version: 1.4.0
161
+ rubygems_version: 1.5.2
162
162
  signing_key:
163
163
  specification_version: 3
164
164
  summary: Share and reuse shoulds, contexts, and setup in Shoulda.
data/README.rdoc DELETED
@@ -1,235 +0,0 @@
1
- = Shared Should - Share and reuse shoulds, contexts, and setups with Shoulda - easy, schmeasy.
2
-
3
- Shared Should allows you to easily create reusable shoulds, contexts and setups with familiar looking Shoulda syntax. Inspired by Rspec's shared example groups for context reuse, Shared Should allows sharing of contexts, shoulds,
4
- and setup blocks. Shared Should goes even further by allowing an initialization block and parameterization to fine-tune the usage of the shared functionality.
5
-
6
- == Quick-Start Examples
7
-
8
- Some quick examples to get you started using Shared Should. The domain is customers renting and purchasing textbooks - like we do at Bookrenter.com.
9
-
10
- === Shared Should
11
-
12
- Sharing shoulds is easy.
13
-
14
- context "Book" do
15
- context "with an in-stock book" do
16
- setup { @book = Book.new(:quantity => 1, :price => 10_00 }
17
-
18
- ### Define a shared should
19
- share_should "be available for checkout" { assert @book.available_for_checkout? }
20
-
21
- context "with a rentable book" do
22
- setup { @book.rentable = true }
23
-
24
- ### Use the "be available for checkout" share_should
25
- use_should "be available for checkout"
26
- end
27
-
28
- context "with a purchasable book" do
29
- setup { @book.purchasable = true }
30
-
31
- ### Use the "be available for checkout" share_should in this context too
32
- use_should "be available for checkout"
33
- end
34
-
35
- ### ...or DRY it up by using .with or .when and an initialization block
36
- use_should("be available for checkout").when("rentable") { @book.rentable = true }
37
- use_should("be available for checkout").when("purchasable") { @book.purchasable = true }
38
- end
39
- end
40
-
41
- === Shared Setup
42
-
43
- Sharing setups is easy, too.
44
-
45
- context "Book" do
46
- ### Define a shared setup
47
- share_setup "for an in-stock book" { @book = Book.new(:quantity => 1, :price => 10_00) }
48
-
49
- context "with an in-stock rentable book" do
50
- ### Use the shared setup here
51
- use_setup "for an in-stock book"
52
-
53
- ### Do some additional setup after the shared setup
54
- setup { @book.rentable = true }
55
-
56
- should "be available for checkout" { assert @book.available_for_checkout? }
57
- end
58
-
59
- context "with an in-stock purchasable book" do
60
- ### Use the shared setup again
61
- use_setup "for an in-stock book"
62
-
63
- setup { @book.purchasable = true }
64
-
65
- should "be available for checkout" { assert @book.available_for_checkout? }
66
- end
67
- end
68
-
69
- === Shared Context
70
-
71
- Sharing whole contexts? Schmeasy!
72
-
73
- context "Book" do
74
- context "with an in-stock book" do
75
- setup { @book = Book.new(:quantity => 1, :price => 10_00) }
76
-
77
- ### Define a shared context
78
- share_context "for a book available for checkout" do
79
- should "be in stock" { assert @book.quantity > 0 }
80
- should "have a non-negative price" { assert @book.price > 0 }
81
- should "be rentable or purchasable" { assert @book.rentable || @book.purchasable }
82
- end
83
-
84
- context "with a rentable book" do
85
- setup { @book.rentable = true }
86
-
87
- ### Run the shoulds inside the shared context with a rentable book
88
- use_context "for a book available for checkout"
89
- end
90
-
91
- context "with a purchasable book" do
92
- setup { @book.purchasable = true }
93
-
94
- ### Run the shoulds inside the shared context again with a purchasable book
95
- use_context "for a book available for checkout"
96
- end
97
-
98
- ### ...or DRY it up by using .with or .when and an initialization block
99
- use_context("for a book available for checkout").when("rentable") { @book.rentable = true }
100
- use_context("for a book available for checkout").when("purchasable") { @book.purchasable = true }
101
- end
102
- end
103
-
104
- == More Information on Syntax and Usage
105
-
106
- === Finding Your Share
107
-
108
- Some rules:
109
- * When <tt>use_should</tt>, <tt>use_context</tt> or <tt>use_setup</tt> is invoked, it searches up the context hierarchy to find a matching shared definition.
110
- * You can redefine your shares by using the same name. These shares will only be available in in the current and descendant contexts.
111
- * Shares defined at the root (on your TestCase) are available in all contexts.
112
- * If you define a shared setup at the root level, you will need to call <tt>super</tt> if you have a setup instance method for your test.
113
-
114
- === Initialization Block
115
-
116
- The shared invocation accepts an initialization block by chaining <tt>when</tt> or <tt>with</tt>. This block can be used to create or modify instance variables used by the shared functionality. It always executes before the shared functionality.
117
-
118
- context "Book" do
119
- setup { @book = Book.new(:quantity => 1, :price => 10_00) }
120
-
121
- share_should "be available for checkout" { assert @book.available_for_checkout? }
122
-
123
- context "with a rentable book" do
124
- # when share_should "be available for checkout" is executed, @book will have rentable equal to true
125
- use_should "be available for checkout".when("rentable") { @book.rentable = true }
126
- end
127
-
128
- context "with a purchasable book" do
129
- use_should "be available for checkout".when("purchasable") { @book.purchasable = true }
130
- end
131
- end
132
-
133
- === Parameterizing Shares
134
-
135
- Shared functions can also be parameterized using block parameters. This can be done for shared setups, shoulds, and the setups and shoulds contained within a shared context. The value passed to the declared shared function is the return value of the initialization block. The below example parameterizes a shared setup.
136
-
137
- context "Book" do
138
- share_setup "for an in-stock book" do |rentable|
139
- @book = Book.new(:quantity => 1, :price => 10_00, :rentable => rentable, :purchasable => false)
140
- end
141
-
142
- context "with rentable book" do
143
- # the return value of the block is "true" which will be passed as the block parameter "rentable"
144
- use_setup("for an in-stock book").with("a rentable book") { true }
145
-
146
- should "be available for checkout" { assert @book.available_for_checkout? }
147
- end
148
- end
149
-
150
- Here is a parameterized shared should.
151
-
152
- context "Book" do
153
- context "with in-stock book" do
154
- setup { @book = Book.new(:quantity => 1) }
155
-
156
- share_should "be unavailable for checkout for price" do |price|
157
- @book.price = price
158
- assert_false @book.available_for_checkout?
159
- end
160
-
161
- use_should("be unavailable for checkout for price").when("zero") { 0 }
162
- use_should("be unavailable for checkout for price").when("negative") { -1 }
163
- end
164
- end
165
-
166
- And a parameterized shared context.
167
-
168
- context "Book" do
169
- context "with in-stock book" do
170
- setup { @book = Book.new(:quantity => 1) }
171
-
172
- share_context "for a book available for checkout at price" do
173
- # parameters are on the setup and shoulds, not on the context
174
- setup { |price| @book.price = price }
175
-
176
- # we could also access price in the should blocks, but we don't need it again
177
- should "be in stock" { assert @book.quantity > 0 }
178
- should "have a non-negative price" { assert @book.price > 0 }
179
- should "be rentable or purchasable" { assert @book.rentable || @book.purchasable }
180
- end
181
-
182
- use_context("for a book available for checkout at price").when("positive") { 10_00 }
183
- end
184
- end
185
-
186
- The shared functions also accept multiple parameters when the initialization block returns an array.
187
-
188
- context "Book" do
189
- context "with rentable book" do
190
- setup { @book = Book.new(:rentable => true) }
191
-
192
- share_should "be unavailable for checkout for quantity and price" do |quantity, price|
193
- @book.quantity = quantity
194
- @book.price = price
195
- assert_false @book.available_for_checkout?
196
- end
197
-
198
- use_should("be unavailable for checkout for quantity and price").when("zero quantity") { [0, 10_00] }
199
- use_should("be unavailable for checkout for quantity and price").when("zero price") { [1, 0] }
200
- end
201
- end
202
-
203
- === Creating a Library of Shared Functionality
204
-
205
- The shared functions can also be re-usable across multiple test cases.
206
-
207
- In your test helper file:
208
-
209
- class Test::Unit::TestCase
210
- share_setup "for an in-stock book" do |rentable, purchasable|
211
- @book = Book.new(:quantity => 1, :price => 10_00, :rentable => rentable, :purchasable => purchasable)
212
- end
213
- end
214
-
215
- In your test file:
216
-
217
- class BookTest < Test::Unit::TestCase
218
- context "with an in-stock book" do
219
- share_setup "for an in-stock book".with { [true, true] }
220
-
221
- should "be in stock" { assert @book.quantity > 0 }
222
- end
223
- end
224
-
225
-
226
- = Credits
227
-
228
- Shared Shoulda is maintained by Michael Pearce (michael.pearce__at__bookrenter__com) and is funded by Bookrenter.com[http://www.bookrenter.com]. Many of the ideas that have inspired Shared Should come
229
- from practical usage by the Bookrenter software development team and conversations with Bookrenter developers Andrew Wheeler and Philippe Huibonhoa.
230
-
231
-
232
- = Copyright
233
-
234
- Copyright (c) 2011 Michael Pearce, Bookrenter.com. See LICENSE.txt for further details.
235
-