spec_views 1.0.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +101 -16
  3. data/Rakefile +3 -1
  4. data/app/assets/config/spec_views_manifest.js +1 -0
  5. data/app/assets/javascripts/spec_views/diff.js +60 -0
  6. data/app/assets/javascripts/spec_views/jsdiff.js +1055 -0
  7. data/app/controllers/spec_views/views_controller.rb +18 -60
  8. data/app/models/spec_views/base_matcher.rb +64 -0
  9. data/app/models/spec_views/directory.rb +133 -0
  10. data/app/models/spec_views/html_matcher.rb +39 -0
  11. data/app/models/spec_views/http_response_extractor.rb +31 -0
  12. data/app/models/spec_views/mail_message_extractor.rb +30 -0
  13. data/app/models/spec_views/pdf_matcher.rb +49 -0
  14. data/app/views/layouts/spec_views.html.erb +261 -0
  15. data/app/views/spec_views/views/_actions.html.erb +11 -0
  16. data/app/views/spec_views/views/_directory_footer.html.erb +14 -0
  17. data/app/views/spec_views/views/compare.html.erb +11 -0
  18. data/app/views/spec_views/views/diff.html.erb +16 -0
  19. data/app/views/spec_views/views/index.html.erb +48 -0
  20. data/app/views/spec_views/views/preview.html.erb +32 -0
  21. data/config/routes.rb +3 -0
  22. data/lib/spec_views/configuration.rb +3 -2
  23. data/lib/spec_views/engine.rb +10 -0
  24. data/lib/spec_views/support.rb +56 -166
  25. data/lib/spec_views/version.rb +3 -1
  26. data/lib/spec_views.rb +3 -1
  27. data/lib/tasks/spec_views_tasks.rake +1 -0
  28. metadata +26 -15
  29. data/app/views/layouts/spec_views.html.haml +0 -200
  30. data/app/views/spec_views/views/compare.html.haml +0 -16
  31. data/app/views/spec_views/views/index.html.haml +0 -29
  32. data/app/views/spec_views/views/preview.html.haml +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 327822c86f6aac9cd2d8e9c31e06465df710a3b4806d42c5899cbbf6e6a59a02
4
- data.tar.gz: 99f42b68d14679146f5b2a7c9e01bad4e9c9a0a1b241d1880a223bb560004126
3
+ metadata.gz: 3184a08acda31e87ed515d6f32819e70183e5ae887f430e3d21b8e84828a66fe
4
+ data.tar.gz: 7a852a0f05d557cef81590cea27faf5db52a4c82726a384823985b4a3ebf2cb2
5
5
  SHA512:
6
- metadata.gz: c02702e4aa11e099daf606f54bedae303f330a6e5135e786835ff7c5483d329a9ac6218e1e584e76aa9f74feb69d64bfb29a38bd9087cc5c9141917e004aa8d5
7
- data.tar.gz: 186aa286db5f8d583f747a39a46ac8531036156715308468d1eb07847626e8337260583d48e084a5063b2200dc1ae1e29e9e1f3cc06221037cd46a82b96b93c7
6
+ metadata.gz: 19c5aeeef63e2db2b68073076fca8217631241a1aa65e45f94ebacf45d141135e93f9f001c882aff5b9f2b2e62aeaa0bcf3afd38a890682256b1dfad8e53daec
7
+ data.tar.gz: 1bb5e90a3fe9fad27653d439bc6b91d140f18c0be9500125f8a2bda0573fb7f68aca301c0fef0f545a6bf6fa9e5e4f5698c91fcbd02c0ce3a4b89c86bf782f25
data/README.md CHANGED
@@ -1,18 +1,5 @@
1
1
  # SpecViews
2
- Render views from controller specs for comparision
3
-
4
- ## Usage
5
- Replace selected RSpec `it` methods with `render`:
6
-
7
- ```ruby
8
- RSpec.describe HomeController, type: :controller do
9
- describe 'GET #show' do
10
- render 'homepage' do
11
- get :show
12
- end
13
- end
14
- end
15
- ```
2
+ Save views from request and controller specs for comparision.
16
3
 
17
4
  ## Installation
18
5
  Add this line to your application's Gemfile:
@@ -26,16 +13,114 @@ And this to RSpec's rails_helper.rb:
26
13
  require 'spec_views/support'
27
14
  ```
28
15
 
29
- And then execute:
16
+ Then execute:
30
17
  ```bash
31
18
  $ bundle
32
19
  ```
33
20
 
34
21
  Ignore some generated files in your .gitignore:
35
22
  ```bash
36
- /spec/fixtures/views/*/challenger.html
23
+ /spec/fixtures/views/*/challenger.*
37
24
  /spec/fixtures/views/*/last_run.txt
38
25
  ```
39
26
 
27
+ ## Usage
28
+ Use the `match_html_fixture` matcher in your spec:
29
+
30
+ ```ruby
31
+ RSpec.describe "Articles", type: :request do
32
+ describe 'GET /articles' do
33
+ it 'renders the listing' do
34
+ get articles_path
35
+ expect(response).to match_html_fixture
36
+ end
37
+ end
38
+ end
39
+ ```
40
+
41
+ Run this spec to see it failing. Open SpecView UI [http://localhost:3000/spec_views](http://localhost:3000/spec_views) on Rails development server to accept the new view. When rerunning the spec it compares its rendering with the reference view. Use SpecView UI to review, accept or reject changed views.
42
+
43
+ ### it_renders
44
+ You can also use the shortcut to skip the matcher and the word "renders" from your description:
45
+
46
+ ```ruby
47
+ RSpec.describe "Articles", type: :request do
48
+ describe 'GET /articles' do
49
+ it_renders 'the listing' do
50
+ get articles_path
51
+ end
52
+ end
53
+ end
54
+ ```
55
+
56
+ ### Different response status
57
+ By default only status 200 responses are compared. Tell the matcher if your response has another one:
58
+
59
+ ```ruby
60
+ RSpec.describe "Articles", type: :request do
61
+ describe 'GET /articles' do
62
+ it 'renders the listing' do
63
+ get articles_path
64
+ expect(response).to match_html_fixture.for_status(:not_found) # or 404
65
+ end
66
+ end
67
+ end
68
+ ```
69
+
70
+ ### PDF matching
71
+ If your request responds with a PDF you can compare it as well:
72
+
73
+ ```ruby
74
+ RSpec.describe "Articles", type: :request do
75
+ describe 'GET /articles/1/download' do
76
+ it 'downloads as PDF' do
77
+ get article_path(1, format: :pdf)
78
+ expect(response).to match_pdf_fixture
79
+ end
80
+ end
81
+ end
82
+ ```
83
+
84
+ ### Mailer specs
85
+ Compare HTML mailers. `match_html_fixture` tries to find the HTML part of your mail automatically:
86
+
87
+ ```ruby
88
+ RSpec.describe NotificationsMailer, :type => :mailer do
89
+ describe '#notify' do
90
+ let(:mail) { NotificationsMailer.signup }
91
+
92
+ it 'renders the body' do
93
+ expect(mail).to match_html_fixture
94
+ end
95
+ end
96
+ end
97
+ ```
98
+
99
+ ### Controller specs
100
+ Prefer request specs over controller specs. If you still want to use controller specs enable the `render_views` feature:
101
+
102
+ ```ruby
103
+ RSpec.describe HomeController, type: :controller do
104
+ describe 'GET #show' do
105
+ render_views
106
+
107
+ it 'renders the homepage' do
108
+ get :show
109
+ expect(response).to match_html_fixture
110
+ end
111
+ end
112
+ end
113
+ ```
114
+
115
+ The `it_renders` shortcuts enables `render_views` automatically.
116
+
117
+ ## Configuration
118
+ Configure SpecView by adding and modifying lines to `config/environments/test.rb` and `config/environments/development.rb`:
119
+
120
+ ```ruby
121
+ config.spec_views.directory = 'spec/fixtures/views'
122
+ config.spec_views.ui_url = 'http://localhost:3000/spec_views'
123
+ ```
124
+
40
125
  ## License
41
126
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  begin
2
4
  require 'bundler/setup'
3
5
  rescue LoadError
@@ -14,7 +16,7 @@ RDoc::Task.new(:rdoc) do |rdoc|
14
16
  rdoc.rdoc_files.include('lib/**/*.rb')
15
17
  end
16
18
 
17
- APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
19
+ APP_RAKEFILE = File.expand_path('spec/dummy/Rakefile', __dir__)
18
20
  load 'rails/tasks/engine.rake'
19
21
 
20
22
  load 'rails/tasks/statistics.rake'
@@ -0,0 +1 @@
1
+ //= link spec_views/diff.js
@@ -0,0 +1,60 @@
1
+ //= require spec_views/jsdiff
2
+
3
+ var a = document.getElementById('diff-champion');
4
+ var b = document.getElementById('diff-challenger');
5
+ var result = document.getElementById('diff-result');
6
+
7
+ function changed() {
8
+ var diff = JsDiff[window.diffType](a.textContent, b.textContent);
9
+ var fragment = document.createDocumentFragment();
10
+ for (var i=0; i < diff.length; i++) {
11
+
12
+ if (diff[i].added && diff[i + 1] && diff[i + 1].removed) {
13
+ var swap = diff[i];
14
+ diff[i] = diff[i + 1];
15
+ diff[i + 1] = swap;
16
+ }
17
+
18
+ var node;
19
+ if (diff[i].removed) {
20
+ node = document.createElement('del');
21
+ node.appendChild(document.createTextNode(diff[i].value));
22
+ } else if (diff[i].added) {
23
+ node = document.createElement('ins');
24
+ node.appendChild(document.createTextNode(diff[i].value));
25
+ } else {
26
+ node = document.createTextNode(diff[i].value);
27
+ }
28
+ fragment.appendChild(node);
29
+ }
30
+
31
+ result.textContent = '';
32
+ result.appendChild(fragment);
33
+ }
34
+
35
+ window.onload = function() {
36
+ onDiffTypeChange(document.querySelector('#diff-settings [name="diff_type"]:checked'));
37
+ changed();
38
+ };
39
+
40
+ a.onpaste = a.onchange =
41
+ b.onpaste = b.onchange = changed;
42
+
43
+ if ('oninput' in a) {
44
+ a.oninput = b.oninput = changed;
45
+ } else {
46
+ a.onkeyup = b.onkeyup = changed;
47
+ }
48
+
49
+ function onDiffTypeChange(radio) {
50
+ window.diffType = radio.value;
51
+ document.title = "Diff " + radio.value.slice(4);
52
+ }
53
+
54
+ var radio = document.getElementsByName('diff_type');
55
+ for (var i = 0; i < radio.length; i++) {
56
+ radio[i].onchange = function(e) {
57
+ onDiffTypeChange(e.target);
58
+ changed();
59
+ }
60
+ }