site_prism.vcr 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +5 -13
  2. data/.travis.yml +5 -0
  3. data/CHANGELOG.md +51 -4
  4. data/Gemfile +3 -4
  5. data/README.md +88 -10
  6. data/TODO.md +29 -31
  7. data/lib/site_prism_vcr/applier.rb +51 -13
  8. data/lib/site_prism_vcr/dsl/adjuster.rb +1 -1
  9. data/lib/site_prism_vcr/dsl/initial_adjuster.rb +26 -6
  10. data/lib/site_prism_vcr/fixture.rb +7 -4
  11. data/lib/site_prism_vcr/fixtures/manager.rb +30 -11
  12. data/lib/site_prism_vcr/fixtures/modifiers/path.rb +6 -6
  13. data/lib/site_prism_vcr/fixtures/modifiers/shortcut_path.rb +25 -0
  14. data/lib/site_prism_vcr/mixins/element.rb +23 -0
  15. data/lib/site_prism_vcr/mixins/page.rb +63 -0
  16. data/lib/site_prism_vcr/options.rb +20 -6
  17. data/lib/site_prism_vcr/patches/element.rb +4 -0
  18. data/lib/site_prism_vcr/patches/page.rb +2 -38
  19. data/lib/site_prism_vcr/version.rb +1 -1
  20. data/lib/site_prism_vcr.rb +2 -2
  21. data/spec/integration/elements/apply_spec.rb +4 -0
  22. data/spec/integration/pages/custom_event_spec.rb +1 -1
  23. data/spec/integration/pages/load_spec.rb +11 -0
  24. data/spec/spec_helper.rb +3 -2
  25. data/spec/spec_integration_helper.rb +0 -3
  26. data/spec/support/shared/integration/home_path.rb +1 -1
  27. data/spec/support/shared/integration/shortcut_path.rb +13 -0
  28. data/spec/support/site_prism/pages/page_load/subpage_with_fixtures.rb +14 -0
  29. data/spec/unit/applier_spec.rb +97 -43
  30. data/spec/unit/dsl/adjuster_spec.rb +7 -7
  31. data/spec/unit/dsl/initial_adjuster_spec.rb +29 -13
  32. data/spec/unit/element_spec.rb +3 -3
  33. data/spec/unit/fixture_spec.rb +47 -17
  34. data/spec/unit/fixtures/converter_spec.rb +1 -1
  35. data/spec/unit/fixtures/handler_spec.rb +3 -3
  36. data/spec/unit/fixtures/manager_spec.rb +76 -29
  37. data/spec/unit/fixtures/modifiers/path_spec.rb +10 -10
  38. data/spec/unit/fixtures/modifiers/relative_path_spec.rb +1 -1
  39. data/spec/unit/fixtures/modifiers/shortcut_path_spec.rb +61 -0
  40. data/spec/unit/{patches/element_container_spec.rb → mixins/element_spec.rb} +2 -2
  41. data/spec/unit/mixins/page_spec.rb +105 -0
  42. data/spec/unit/options_spec.rb +6 -6
  43. data/spec/unit/waiter_spec.rb +3 -3
  44. metadata +28 -22
  45. data/lib/site_prism_vcr/fixtures/modifiers/home_path.rb +0 -25
  46. data/lib/site_prism_vcr/patches/element_container.rb +0 -19
  47. data/spec/unit/fixtures/modifiers/home_path_spec.rb +0 -58
  48. data/spec/unit/patches/page_spec.rb +0 -50
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NjBjNmM0Nzk1NjIxZmU2NGQ4OGQ0M2U3MDkwNDU3YWIxNDUxMjM5ZQ==
5
- data.tar.gz: !binary |-
6
- NGVkNTk1MDVlMTNlN2Y5ZTgwMTRjYWM4MzdjMDFlMjYzY2FkZTFlOA==
2
+ SHA1:
3
+ metadata.gz: b27bc15efc9ef02cdac9c19415638b241c327929
4
+ data.tar.gz: 051ad78469fee6ab6d34d7a27c687edf15c31aa6
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- ZjQyYmM5Y2M5ZGM3ZTY1NWQyNDY3ZTEwYjQ4ODkzNDcwY2Y2Y2M0ODY5NjA1
10
- ZGNjNGUyZGEzYTQyYjZhYTNiZjA4NmM3Yzc3OWZhZTYxNWY2NTdlYTZiZTdm
11
- NzVlMGM4ZjJlNThjMWQwMzNhZWE0NDFjNTcxYzY3MjMwZjUwYmY=
12
- data.tar.gz: !binary |-
13
- MGFiMGI5YTk0OGRjYWIyMDRlMGUyNDU3YTI0MmNhNjY2ZjkyYWMyNTFhODIw
14
- ZGIyMDAzMDY2M2MxNGQwZTJjNDY2NjQ1YTE3ZDY2YjQxZDkwNzRlMDNiMjgz
15
- ODY5MGIwM2QwOTRkZTdmYjg1YTVkYzE5ZDhmYjIxZDRhNzZiNWE=
6
+ metadata.gz: ff5719ce35f903b3cf9146f9dba1f293f7bfdd7f081750333ec1dafb13c85dd3e799e6d66c14f8740a63c0577ba7f2bae8364dfc1a5d2ec1823805d4db8659d9
7
+ data.tar.gz: 0c0b1d6d25328740b32f1a5bc577189e100e7cbf35871a4d36744274fdfcaa5c22bcf8a2111e97567c696a758687e6ba260c7c6f58cc349c2147c5b75baae725
data/.travis.yml CHANGED
@@ -1,5 +1,10 @@
1
1
  language: ruby
2
2
  rvm:
3
+ - 2.2.0
4
+ - 2.1.5
5
+ - 2.1.4
6
+ - 2.1.3
7
+ - 2.1.2
3
8
  - 2.1.1
4
9
  - 2.1.0
5
10
  - 2.0.0
data/CHANGELOG.md CHANGED
@@ -1,12 +1,59 @@
1
+ # 0.2.0
2
+
3
+ * fixed code for ejecting cassettes from Vcr. Now SitePrism.Vcr ejects only cassettes injected by itself, any other cassettes which are injected outside of this library won't be touched.
4
+ * added a new functionality to alter default cassettes defined in a parent class page. Now if additional cassettes should be added to a default cassettes list, it can be done with the `adjust_parent_vcr_options` method (waiter can be replaced as well).
5
+
6
+ ```ruby
7
+ class BasePage < SitePrism::Page
8
+ vcr_options_for_load do
9
+ fixtures ['cars', 'products']
10
+
11
+ waiter &:wait_for_cars_list
12
+ end
13
+ end
14
+
15
+ class CarsPage < BasePage
16
+ adjust_parent_vcr_options do
17
+ fixtures ['features']
18
+
19
+ waiter &:wait_for_cars_and_features_list
20
+
21
+ union # if it is omitted, the fixtures list defined in this block will
22
+ # replace the fixtures list defined in the parent page class
23
+ end
24
+ end
25
+ ```
26
+
27
+ * added `shortcut_path` helper method to use it while pointing a path to cassettes. Before this change only one shortcut (the shortcut for the home path `~/`) could be defined, now any path to cassettes can be defined as a shortcut.
28
+
29
+ ```ruby
30
+ self.some_link.click_and_apply_vcr do
31
+ home_path 'cars'
32
+
33
+ shortcut_path 'ferrari', 'cars/f1/ferrari'
34
+
35
+ fixtures [
36
+ '~/ford_fiesta',
37
+ ':ferrari/f13t',
38
+ ':ferrari/f14t',
39
+ ':ferrari/f15t'
40
+ ]
41
+ end
42
+ ```
43
+
44
+ # 0.1.2
45
+
46
+ * fixed the issue with storing a fixture into a correct sub directory if it is provided along with a fixture name (It happened only for `path` helper method which used with a home path symbol).
47
+
1
48
  # 0.1.1
2
49
 
3
50
  * fixed the issue with using replace and union actions in one block.
4
51
 
5
52
  ```ruby
6
53
  self.some_link.click_and_apply_vcr do
7
- fixtures ['test', 'test2']
54
+ fixtures ['ford', 'ferrari']
8
55
  union
9
- fixtures ['test3']
56
+ fixtures ['jeep']
10
57
  replace
11
58
  end
12
59
  ```
@@ -18,9 +65,9 @@
18
65
 
19
66
  ```ruby
20
67
  self.some_link.click_and_apply_vcr do
21
- home_path 'custom'
68
+ home_path 'cars'
22
69
 
23
- fixtures ['~/../test'] # '~' indicates a home path which is defined above in this block
70
+ fixtures ['~/../ford'] # '~' indicates a home path which is defined above in this block
24
71
  end
25
72
  ```
26
73
 
data/Gemfile CHANGED
@@ -5,10 +5,9 @@ gemspec
5
5
 
6
6
  gem 'sinatra'
7
7
  gem 'httpi'
8
- gem 'capybara-firebug'
8
+ gem 'capybara', '~> 2.4'
9
9
  gem 'sandi_meter'
10
10
 
11
- gem 'rspec', '~> 2.14.1'
12
- gem 'rspec-fire'
13
- gem 'selenium-webdriver', '~> 2.41.0'
11
+ gem 'rspec', '~> 3'
12
+ gem 'selenium-webdriver', '~> 2'
14
13
  gem 'coveralls', require: false
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # SitePrism.Vcr
2
2
 
3
- [![Code Climate](https://codeclimate.com/github/nestd/site_prism.vcr.png)](https://codeclimate.com/github/nestd/site_prism.vcr)
3
+ [![Code Climate](https://codeclimate.com/github/dnesteryuk/site_prism.vcr.png)](https://codeclimate.com/github/dnesteryuk/site_prism.vcr)
4
4
  [![Build Status](https://secure.travis-ci.org/dnesteryuk/site_prism.vcr.png?branch=master)](https://travis-ci.org/dnesteryuk/site_prism.vcr)
5
5
  [![Coverage Status](https://coveralls.io/repos/dnesteryuk/site_prism.vcr/badge.png)](https://coveralls.io/r/dnesteryuk/site_prism.vcr)
6
6
  [![Dependency Status](https://gemnasium.com/dnesteryuk/site_prism.vcr.png)](https://gemnasium.com/dnesteryuk/site_prism.vcr)
@@ -15,7 +15,7 @@ Such integration allows you to write acceptance tests more easily since you rece
15
15
  * Links VCR cassettes with SitePrism pages.
16
16
  * Applies VCR cassettes on any event (click, change, blur etc).
17
17
  * Applies VCR cassettes on page loading.
18
- * Defines a waiter which will be used for waiting until an expected element is on a page or until an expected element has disappeared from a page (It is very helpful when a few external API requests are being executed after raising an event).
18
+ * Defines a waiter to wait on a result of an action.
19
19
  * Allows to redefine default VCR cassettes (cassettes which were specified while describing a SitePrism element or a SitePrism page).
20
20
  * Allows to redefine a default waiter (a waiter which was specified while describing a SitePrism element or a SitePrism page).
21
21
 
@@ -51,7 +51,7 @@ end
51
51
 
52
52
  `fixtures` helper method is used for defining VCR cassettes. All cassettes are taken from a path which you have defined in `cassette_library_dir` configuration option of VCR. Please, refer to [documentation](https://relishapp.com/vcr/vcr/v/2-5-0/docs/configuration/cassette-library-dir) of VCR to get more info about configuration options.
53
53
 
54
- You can specify cassettes for already defined elements, for example, your page inherits another one:
54
+ You can specify cassettes for already defined elements, if your page inherits another one:
55
55
 
56
56
  ```ruby
57
57
  class TransportPage < SitePrism::Page
@@ -67,7 +67,7 @@ end
67
67
 
68
68
  #### Path helper method
69
69
 
70
- In case you have a lot of cassettes which are stored in some subdirectory, there is more better way for defining cassettes:
70
+ In case you have a lot of cassettes which are stored in some subdirectory, you can use `path` helper method to specify a list of such cassettes:
71
71
 
72
72
  ```ruby
73
73
  class ProductsPage < SitePrism::Page
@@ -115,7 +115,7 @@ class ProductsPage < SitePrism::Page
115
115
  end
116
116
  ```
117
117
 
118
- If some cassette name begins with `~/`, it means that a defined home path will be applied to find such cassette. The previous example is identical to this one:
118
+ Here `~` points to `cars/small` directory, all cassettes will be taken from this directory. The previous example is identical to this one:
119
119
 
120
120
  ```ruby
121
121
  class ProductsPage < SitePrism::Page
@@ -161,6 +161,26 @@ class ProductsPage < SitePrism::Page
161
161
  end
162
162
  ```
163
163
 
164
+ #### Shortcut path helper method
165
+
166
+ The home path helper method helps you to avoid duplication while specifing cassettes. There is a `shortcut_path` method which does the same, but it can be used to define shorcuts for any path:
167
+
168
+ ```ruby
169
+ class ProductsPage < SitePrism::Page
170
+ element_with_vcr \
171
+ :car_details_link,
172
+ '#car_details' do
173
+ shortcut_path 'cars', 'cars/small'
174
+
175
+ fixture [':cars/ford']
176
+ end
177
+ end
178
+ ```
179
+
180
+ Here `:cars` points to the `cars/small` directory.
181
+
182
+ Everything described for the `home_path` helper method works for the `shortcut_path` method as well.
183
+
164
184
  ### Applying VCR cassettes on click
165
185
 
166
186
  Cassettes can be applied on a click event:
@@ -230,7 +250,7 @@ Home path can be defined while applying Vcr:
230
250
  end
231
251
  ```
232
252
 
233
- #### Exchange default fixtures
253
+ #### Exchange default cassettes
234
254
 
235
255
  There may be a situation when you need to exchange some default cassette for one specific test. It is a very easy to do:
236
256
 
@@ -353,7 +373,7 @@ The block which is passed to `shift_event` method is executed in a context of an
353
373
 
354
374
  ### Linking and applying VCR cassettes with SitePrism pages
355
375
 
356
- External HTTP interactions may be done on page loading as well. This gem supports capability to apply Vcr cassettes on page loading. To define default cassettes you have to use `vcr_options_for_load` class method:
376
+ External HTTP interactions may be done on page loading as well. This gem supports capability to apply Vcr cassettes on page loading. To define default cassettes you have to use the `vcr_options_for_load` class method:
357
377
 
358
378
  ```ruby
359
379
  class ProductsPage < SitePrism::Page
@@ -365,7 +385,7 @@ end
365
385
 
366
386
  Everything described above about defining cassettes for SitePrism elements is true for defining cassettes for pages.
367
387
 
368
- Applying cassettes is almost the same as you saw for a click event:
388
+ Applying cassettes is almost the same as it is shown for SitePrism elements:
369
389
 
370
390
  ```ruby
371
391
  page.load_and_apply_vcr do
@@ -375,7 +395,7 @@ page.load_and_apply_vcr do
375
395
  end
376
396
  ```
377
397
 
378
- All arguments passed to `load_and_apply_vcr` method will be passed to `load` method of SitePrism. It allows you to change an url of the being loaded page.
398
+ All arguments passed to the `load_and_apply_vcr` method will be passed to the `load` method of SitePrism. It allows to change an url of the being loaded page:
379
399
 
380
400
  ```ruby
381
401
  page.load_and_apply_vcr(cat: 'tom') do
@@ -391,6 +411,65 @@ In this case, SitePrism will alter an url and it will look like:
391
411
  http://localhost/cats/tom
392
412
  ```
393
413
 
414
+ #### Altering default cassettes in sub-classes of pages
415
+
416
+ There is a possibility to alter default cassettes defined for a parent page class. It can be done with the `adjust_parent_vcr_options` method:
417
+
418
+ ```ruby
419
+ class BasePage < SitePrism::Page
420
+ vcr_options_for_load do
421
+ fixtures ['cars', 'products']
422
+
423
+ waiter &:wait_for_cars_list
424
+ end
425
+ end
426
+
427
+ class CarsPage < BasePage
428
+ adjust_parent_vcr_options do
429
+ fixtures ['features']
430
+
431
+ waiter &:wait_for_cars_and_features_list
432
+
433
+ union # if it is omitted, the cassettes defined in this block will
434
+ # replace the cassettes defined in the parent page class
435
+ end
436
+ end
437
+ ```
438
+
439
+ In this case `cars`, `products`, `features` cassettes will be applied while loading the cars page.
440
+
441
+ Any helper methods can be used in a block passed to the `adjust_parent_vcr_options` method.
442
+
443
+ ### Applying VCR cassettes in sections
444
+
445
+ There isn't any method which you can use to apply VCR cassettes with sections. Actually, it is needless, because usually we do actions over elements. But, if you need such functionality for sections, you already have such possibility:
446
+
447
+ ```ruby
448
+ class ListSection < SitePrism::Section
449
+ # elements here
450
+
451
+ def initialize(parent, element)
452
+ super
453
+
454
+ @applier = SPV::Applier.new(self)
455
+ end
456
+
457
+ def show_more
458
+ @applier.shift_event{
459
+ self.scroll_down
460
+ }.apply_vcr do
461
+ fixtures ["storages/more_storages"]
462
+
463
+ waiter { self.wait_until_loading_indicator_invisible }
464
+ end
465
+ end
466
+ end
467
+ ```
468
+
469
+ In this example we apply VCR cassettes after scrolling down the content in a section.
470
+
471
+ It may be useful to stub the API request produced by an event which isn't directly related to any element rather it related to overall elements in a section.
472
+
394
473
  ### Using Vcr options for cassettes
395
474
 
396
475
  Vcr provides number of options which can be used for cassettes. For example, you may [pass ERB into cassettes](https://relishapp.com/vcr/vcr/v/2-5-0/docs/cassettes/dynamic-erb-cassettes). This gem doesn't bother you use any options for Vcr cassettes. If you want to do so, you have to use a hash instead of a cassette name:
@@ -427,6 +506,5 @@ The simple example of using this gem you can find [here](https://github.com/dnes
427
506
  4. Push to the branch (`git push origin my-new-feature`)
428
507
  5. Create new Pull Request
429
508
 
430
-
431
509
  [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/nestd/site_prism.vcr/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
432
510
 
data/TODO.md CHANGED
@@ -1,28 +1,37 @@
1
1
  # TODO
2
2
 
3
- ## Release 0.1.2
4
-
5
- 1. Think how to avoid monkey patching to add stuffs to SitePrism
6
- 2. Change code to use DI with build (http://solnic.eu/2013/12/17/the-world-needs-another-post-about-dependency-injection-in-ruby.html)
7
- 3. Think about using something like:
3
+ ## Release 0.3.0
8
4
 
5
+ 1. Add code not to remove one specific cassete from VCR
6
+ 2. Find better names for `vcr_options_for_load` and `adjust_parent_vcr_options` methods.
7
+ 3. Think about using DCI:
9
8
  ```ruby
10
- ~/../bundle_offerings
9
+ class SPV:Page < SitePrism:Page
10
+ def load_and_apply_vcr(*args, &block)
11
+ shift_event { load(*args) }.apply_vcr(&block)
12
+ end
13
+
14
+ def shift_event(&block)
15
+ vcr_applier.shift_event(&block)
16
+ end
17
+ end
18
+ ```
19
+ 4. Add possibility to get a defined cassettes for a page or section:
20
+ ```ruby
21
+ @dashboard_page.vcr_cassettes # returns a defined cassetted for this page
22
+ @form_section.vcr_cassettes # returns a defined cassetted for this section
11
23
  ```
12
24
 
13
- when define a path to a fixture, for that we can use a standard class Pathname of Ruby.
14
-
15
- ## Release 0.2.0
16
-
17
- 1. Pages and elements should inherit fixtures defined for their parents
18
- 2. When we eject fixtures from Vcr we should eject only fixtures inserted into Vcr by one specific fixtures manager (See SPV#eject)
19
- 3. Make this gem working on JRuby (since we eject all VCR cassettes, it may be not thread safe)
20
- 4. Think about creating set of fixtures which can be exchanged by a name of set. It will be very helpful when you have to exchange a set of fixtures.
21
- 5. Add code to not remove one specific cassete from VCR
22
-
23
- ## Should be implemented?
25
+ ## Things to think over
24
26
 
25
- 1. Create possibility to define fixtures without the click action:
27
+ 1. Should we add the integration tests for page load to make sure 2 HTTP requests will be handled properly?
28
+ 2. Should we add own integration tests to test the path helper method?
29
+ 3. Should we add a test for testing to HTTP requests on page load?
30
+ 4. Should be Options class immutable?
31
+ 5. Think about renaming current integration tests on acceptance tests and create new integration tests which will test integration between classes without involving a browser. It will solve a lot of issues with shared tests to check the same things for pages and elements. In acceptance tests we will test very basic stuffs.
32
+ 6. May be SPV::Fixtures::TmpKeeper is redundant and SPV::Fixtures can be used as a tmp keeper of fixtures?
33
+ 7. Elements should inherit fixtures defined for their parents
34
+ 8. Create possibility to define fixtures without the click action (it can be done with `alter_fixtures` method from the applier, but it is not accessible outside of the applier):
26
35
 
27
36
  ```ruby
28
37
  self.confirm_btn.vcr do
@@ -40,16 +49,5 @@ when define a path to a fixture, for that we can use a standard class Pathname o
40
49
  ```
41
50
 
42
51
  will use previously defined fixtures
43
-
44
-
45
- ## Things to think over
46
-
47
- 1. Should we add the integration tests for page load to make sure 2 HTTP requests will be handled properly?
48
- 2. Should we add own integration tests to test the path helper method?
49
- 3. Should we add a test for testing to HTTP requests on page load?
50
- 4. Should be Options class immutable?
51
- 5. May be it makes sense to separately keep path from the name of a fixture? See SPV::Fixture class
52
- 6. Think about renaming current integration tests on acceptance tests and create new integration tests which will test integration between classes without involving a browser. It will solve a lot of issues with shared tests to check the same things for pages and elements. In acceptance tests we will test very basic stuffs.
53
- 7. May be SPV::Fixtures::TmpKeeper is redundant and SPV::Fixtures can be used as a tmp keeper of fixtures?
54
-
55
-
52
+
53
+ 9. Think about creating set of fixtures which can be exchanged by a name of set. It will be very helpful when you have to exchange a set of fixtures.
@@ -13,16 +13,44 @@ module SPV
13
13
  end
14
14
 
15
15
  @fixtures = adjuster.prepare_fixtures
16
-
17
- @fixtures_manager = Fixtures::Manager.new(@options)
18
16
  end
19
17
 
18
+ # Stores a block with an action (click, scroll down, mouse over etc)
19
+ # VCR should be applied on.
20
+ #
21
+ # This block will be called over an object VCR linked to.
22
+ #
23
+ # Example:
24
+ # @my_element.shift_event do
25
+ # self.click
26
+ # end
27
+ #
28
+ # @param block [Proc]
29
+ #
30
+ # @return [SPV::Applier] The current applier object.
31
+ #
32
+ # @api public
20
33
  def shift_event(&block)
21
34
  @event_action = block
22
35
 
23
36
  self
24
37
  end
25
38
 
39
+ # Alters default fixtures and options.
40
+ #
41
+ # @param adjusting_block [Proc] It allows to
42
+ # change fixtures through DSL (@see SPV::DSL::InitialAdjuster
43
+ # and @see SPV::DSL::Adjuster)
44
+ #
45
+ # @return [void]
46
+ #
47
+ # @api public
48
+ def alter_fixtures(&block)
49
+ @fixtures = adjust_fixtures(
50
+ @options, &block
51
+ )
52
+ end
53
+
26
54
  # Applies fixtures to be used for stubbing HTTP interactions
27
55
  # caused by an event (click on an element or page loading).
28
56
  #
@@ -34,27 +62,26 @@ module SPV
34
62
  # and @see SPV::DSL::Adjuster)
35
63
  #
36
64
  # @return [void]
37
- def apply_vcr(&block)
65
+ #
66
+ # @api public
67
+ def apply_vcr(&block)
38
68
  verify_define_event!
39
69
 
40
- options = @options.clone_options
41
-
42
- adjuster = DSL::Adjuster.new(
43
- options,
44
- @fixtures
45
- )
70
+ fixtures, options = @fixtures, @options.clone_options
46
71
 
47
72
  if block_given?
48
- adjuster.instance_eval &block
73
+ fixtures = adjust_fixtures(options, &block)
49
74
  end
50
75
 
51
- @fixtures_manager.inject(adjuster.prepare_fixtures)
76
+ fixtures_manager = Fixtures::Manager.inject(
77
+ fixtures, options
78
+ )
52
79
 
53
80
  @event_action.call
54
81
 
55
82
  Waiter.wait(
56
83
  @node,
57
- @fixtures_manager,
84
+ fixtures_manager,
58
85
  options
59
86
  )
60
87
  end
@@ -62,8 +89,19 @@ module SPV
62
89
  private
63
90
  def verify_define_event!
64
91
  raise EventError.new(
65
- 'Event is not shifted, before applying Vcr you have to shift event with "shift_event" method'
92
+ 'Event is not shifted, before applying VCR you have to shift event with "shift_event" method'
66
93
  ) if @event_action.nil?
67
94
  end
95
+
96
+ def adjust_fixtures(options, &block)
97
+ adjuster = DSL::Adjuster.new(
98
+ options,
99
+ @fixtures
100
+ )
101
+
102
+ adjuster.instance_eval &block
103
+
104
+ adjuster.prepare_fixtures
105
+ end
68
106
  end # class Applier
69
107
  end # module SPV
@@ -61,7 +61,7 @@ module SPV
61
61
  #
62
62
  # @api public
63
63
  def exchange(old_fixtures, new_fixtures)
64
- home_path_modifier = Fixtures::Modifiers::HomePath.new(@options)
64
+ home_path_modifier = Fixtures::Modifiers::ShortcutPath.new(@options)
65
65
 
66
66
  old_fixtures = [old_fixtures] unless old_fixtures.is_a?(Array)
67
67
  new_fixtures = [new_fixtures] unless new_fixtures.is_a?(Array)
@@ -20,7 +20,7 @@ module SPV
20
20
  prepared_fixtures = @fixtures_handler.handle_raw(
21
21
  list,
22
22
  [
23
- Fixtures::Modifiers::HomePath.new(@options),
23
+ Fixtures::Modifiers::ShortcutPath.new(@options),
24
24
  Fixtures::Modifiers::RelativePath.new(@options)
25
25
  ]
26
26
  )
@@ -28,9 +28,12 @@ module SPV
28
28
  @tmp_keeper.add_fixtures(prepared_fixtures)
29
29
  end
30
30
 
31
- # Defines path to fixtures. Later this path
32
- # can be used for defining fixtures. It is especially
33
- # useful when you use deep subdirectories structure for storing fixtures.
31
+ # Defines a home path to fixtures. Later this path
32
+ # can be used for defining fixtures.
33
+ #
34
+ # Example:
35
+ # home_path 'cassettes/cars/ford'
36
+ # fixtures['~/car']
34
37
  #
35
38
  # @param path [String] Path to fixtures.
36
39
  #
@@ -38,7 +41,24 @@ module SPV
38
41
  #
39
42
  # @api public
40
43
  def home_path(path)
41
- @options.home_path = path
44
+ @options.add_shortcut_path('~', path)
45
+ end
46
+
47
+ # Defines a shortcut path to fixtures. Later this path
48
+ # can be used for defining fixtures.
49
+ #
50
+ # Example:
51
+ # shortcut_path 'ford', 'cassettes/cars/ford'
52
+ # fixtures[':ford/car']
53
+ #
54
+ # @param name [String] Shortcut name to be used while defining a path to fixtures..
55
+ # @param path [String] Path to fixtures.
56
+ #
57
+ # @return [void]
58
+ #
59
+ # @api public
60
+ def shortcut_path(name, path)
61
+ @options.add_shortcut_path(name, path)
42
62
  end
43
63
 
44
64
  # Applies a given path to list of fixtures and defines
@@ -57,7 +77,7 @@ module SPV
57
77
  options_with_path.path = path
58
78
 
59
79
  path_modifier = Fixtures::Modifiers::Path.new(options_with_path)
60
- home_path_modifier = Fixtures::Modifiers::HomePath.new(options_with_path)
80
+ home_path_modifier = Fixtures::Modifiers::ShortcutPath.new(options_with_path)
61
81
 
62
82
  prepared_fixtures = @fixtures_handler.handle_raw(
63
83
  fixture_names,
@@ -26,12 +26,15 @@ module SPV
26
26
  self.path = Pathname.new(val) + self.path
27
27
  end
28
28
 
29
- def set_home_path(home_path)
30
- self.path = self.path.to_path.gsub(/\A(\~\/|\~)/, home_path)
29
+ def set_home_path(path_to)
30
+ self.path = self.path.to_path.gsub(
31
+ /\A(\:#{self.shortcut_path}\/|:#{self.shortcut_path}|\~\/|\~)/,
32
+ path_to
33
+ )
31
34
  end
32
35
 
33
- def has_link_to_home_path?
34
- self.name[0..1] == '~/'
36
+ def shortcut_path
37
+ res = (self.name.match(/:(\w+)\//) || self.name.match(/(~)\//)) and res[1]
35
38
  end
36
39
 
37
40
  # Returns a name without a link to a home path
@@ -3,35 +3,54 @@ module SPV
3
3
  # Takes cares about inserting and ejecting fixtures
4
4
  # from Vcr.
5
5
  class Manager
6
- def initialize(options)
7
- @options = options
6
+ # Initializes a new instance of the fixtures manager class,
7
+ # injects given fixtures into VCR,
8
+ # returns an instance of the fixtures manager class
9
+ #
10
+ # @param fixtures [SPV::Fixtures] List of fixtures.
11
+ # @param options [SPV::Options] An object with all options.
12
+ #
13
+ # @return [SPV::Fixtures::Manager]
14
+ def self.inject(fixtures, options)
15
+ manager = new(fixtures, options)
16
+ manager.inject
17
+ manager
8
18
  end
9
19
 
10
- # Injects given fixtures to Vcr.
20
+ # Initializes a new instance
11
21
  #
12
22
  # @param fixtures [SPV::Fixtures] List of fixtures.
23
+ # @param options [SPV::Options] An object with all options.
24
+ #
25
+ # @return [void]
26
+ def initialize(fixtures, options)
27
+ @fixtures, @options = fixtures, options
28
+ end
29
+
30
+ # Injects given fixtures to Vcr.
13
31
  #
14
32
  # @return [void]
15
33
  #
16
34
  # @raise [ArgumentError] If a list of fixtures is empty.
17
- def inject(fixtures)
35
+ def inject
18
36
  raise ArgumentError.new(
19
37
  'No fixtures were specified to insert them into VCR'
20
- ) if fixtures.size == 0
38
+ ) if @fixtures.size == 0
21
39
 
22
- fixtures.each do |fixture|
40
+ @fixtures.each do |fixture|
23
41
  VCR.insert_cassette fixture.name, fixture.options
24
42
  end
25
43
  end
26
44
 
27
- # Ejects all fixtures from Vcr.
28
- # Now it doesn't care which fixtures were inserted by
29
- # an instance of this class. After calling this method
30
- # Vcr will have no inserted fixtures at all.
45
+ # Ejects only fixtures from Vcr which are injected
46
+ # by this instance of the fixtures manager class.
31
47
  #
32
48
  # @return [void]
33
49
  def eject
34
- SPV::Helpers.eject_all_cassettes
50
+ inserted_names = @fixtures.map(&:name)
51
+
52
+ # TODO: find better way, may be some pull request to the VCR?
53
+ VCR.send(:cassettes).delete_if{|cassette| inserted_names.include?(cassette.name) }
35
54
  end
36
55
  end # class Manager
37
56
  end # class Fixtures
@@ -6,12 +6,12 @@ module SPV
6
6
  # It takes a fixture and adds a path to it.
7
7
  class Path < Base
8
8
  def modify(fixture)
9
- if fixture.has_link_to_home_path?
10
- raise HomePathError.new(
11
- "You cannot use the home path while listing fixtures in the 'path' method. " <<
9
+ if shortcut = fixture.shortcut_path
10
+ raise ShortcutPathError.new(
11
+ "You cannot use a shortcut path while listing fixtures in the 'path' method. " <<
12
12
  "Please, use 'fixtures' method for '#{fixture.clean_name}' fixture or " <<
13
- "you can additionally use the 'path' method where you will specify a home path as a path name." <<
14
- "Example: path('~/', ['#{fixture.clean_name}'])"
13
+ "you can additionally use the 'path' method where you will specify a shortcut path as a path name." <<
14
+ "Example: path(':#{shortcut}', ['#{fixture.clean_name}'])"
15
15
  )
16
16
  else
17
17
  path = @options.path
@@ -21,7 +21,7 @@ module SPV
21
21
  end
22
22
  end
23
23
 
24
- class HomePathError < ArgumentError; end
24
+ class ShortcutPathError < ArgumentError; end
25
25
  end
26
26
  end
27
27
  end