spec_views 1.1.1 → 2.0.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.
- checksums.yaml +4 -4
- data/README.md +88 -5
- data/Rakefile +3 -1
- data/app/assets/config/spec_views_manifest.js +1 -0
- data/app/assets/javascripts/spec_views/diff.js +60 -0
- data/app/assets/javascripts/spec_views/jsdiff.js +1055 -0
- data/app/controllers/spec_views/views_controller.rb +18 -60
- data/app/models/spec_views/base_matcher.rb +64 -0
- data/app/models/spec_views/directory.rb +133 -0
- data/app/models/spec_views/html_matcher.rb +39 -0
- data/app/models/spec_views/http_response_extractor.rb +31 -0
- data/app/models/spec_views/mail_message_extractor.rb +30 -0
- data/app/models/spec_views/pdf_matcher.rb +49 -0
- data/app/views/layouts/spec_views.html.erb +261 -0
- data/app/views/spec_views/views/_actions.html.erb +11 -0
- data/app/views/spec_views/views/_directory_footer.html.erb +14 -0
- data/app/views/spec_views/views/compare.html.erb +11 -0
- data/app/views/spec_views/views/diff.html.erb +16 -0
- data/app/views/spec_views/views/index.html.erb +48 -0
- data/app/views/spec_views/views/preview.html.erb +32 -0
- data/config/routes.rb +3 -0
- data/lib/spec_views/configuration.rb +3 -2
- data/lib/spec_views/engine.rb +10 -0
- data/lib/spec_views/support.rb +56 -174
- data/lib/spec_views/version.rb +3 -1
- data/lib/spec_views.rb +3 -1
- data/lib/tasks/spec_views_tasks.rake +1 -0
- metadata +26 -15
- data/app/views/layouts/spec_views.html.haml +0 -200
- data/app/views/spec_views/views/compare.html.haml +0 -16
- data/app/views/spec_views/views/index.html.haml +0 -29
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3184a08acda31e87ed515d6f32819e70183e5ae887f430e3d21b8e84828a66fe
|
4
|
+
data.tar.gz: 7a852a0f05d557cef81590cea27faf5db52a4c82726a384823985b4a3ebf2cb2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19c5aeeef63e2db2b68073076fca8217631241a1aa65e45f94ebacf45d141135e93f9f001c882aff5b9f2b2e62aeaa0bcf3afd38a890682256b1dfad8e53daec
|
7
|
+
data.tar.gz: 1bb5e90a3fe9fad27653d439bc6b91d140f18c0be9500125f8a2bda0573fb7f68aca301c0fef0f545a6bf6fa9e5e4f5698c91fcbd02c0ce3a4b89c86bf782f25
|
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# SpecViews
|
2
|
-
|
2
|
+
Save views from request and controller specs for comparision.
|
3
3
|
|
4
4
|
## Installation
|
5
5
|
Add this line to your application's Gemfile:
|
@@ -13,7 +13,7 @@ And this to RSpec's rails_helper.rb:
|
|
13
13
|
require 'spec_views/support'
|
14
14
|
```
|
15
15
|
|
16
|
-
|
16
|
+
Then execute:
|
17
17
|
```bash
|
18
18
|
$ bundle
|
19
19
|
```
|
@@ -25,19 +25,102 @@ Ignore some generated files in your .gitignore:
|
|
25
25
|
```
|
26
26
|
|
27
27
|
## Usage
|
28
|
-
|
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:
|
29
101
|
|
30
102
|
```ruby
|
31
103
|
RSpec.describe HomeController, type: :controller do
|
32
104
|
describe 'GET #show' do
|
33
|
-
|
105
|
+
render_views
|
106
|
+
|
107
|
+
it 'renders the homepage' do
|
34
108
|
get :show
|
109
|
+
expect(response).to match_html_fixture
|
35
110
|
end
|
36
111
|
end
|
37
112
|
end
|
38
113
|
```
|
39
114
|
|
40
|
-
|
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
|
+
```
|
41
124
|
|
42
125
|
## License
|
43
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(
|
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
|
+
}
|