approvals 0.0.9 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +3 -1
- data/Changelog.md +10 -0
- data/Gemfile +2 -0
- data/Gemfile.travis +8 -0
- data/README.md +72 -42
- data/lib/approvals/approval.rb +5 -1
- data/lib/approvals/error.rb +16 -0
- data/lib/approvals/extensions/rspec.rb +1 -0
- data/lib/approvals/extensions/rspec/dsl.rb +15 -0
- data/lib/approvals/utilities/dotfile.rb +7 -12
- data/lib/approvals/version.rb +1 -1
- data/spec/extensions/rspec_approvals_spec.rb +16 -0
- data/spec/fixtures/approvals/verifies_a_failure.approved.txt +1 -0
- data/spec/fixtures/approvals/verifies_a_failure_diff.approved.txt +1 -0
- data/spec/fixtures/approvals/verifies_directory/a_failure.approved.txt +0 -0
- data/spec/fixtures/approvals/verifies_directory/a_failure_diff.approved.txt +0 -0
- data/spec/reporters/first_working_reporter_spec.rb +3 -3
- metadata +8 -2
data/.travis.yml
CHANGED
data/Changelog.md
ADDED
data/Gemfile
CHANGED
data/Gemfile.travis
ADDED
data/README.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Approvals
|
2
2
|
|
3
|
+
[![Build Status](https://secure.travis-ci.org/kytrinyx/approvals.png?branch=master)](http://travis-ci.org/kytrinyx/approvals)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/approvals.png)](http://badge.fury.io/rb/approvals)
|
5
|
+
[![Code Climate](https://codeclimate.com/github/kytrinyx/approvals.png)](https://codeclimate.com/github/kytrinyx/approvals)
|
6
|
+
[![Gemnasium](https://gemnasium.com/kytrinyx/approvals.png)](https://gemnasium.com/kytrinyx/approvals)
|
7
|
+
|
8
|
+
|
3
9
|
Approvals are based on the idea of the *_golden master_*.
|
4
10
|
|
5
11
|
You take a snapshot of an object, and then compare all future
|
@@ -14,13 +20,15 @@ See [ApprovalTests](http://www.approvaltests.com) for videos and additional docu
|
|
14
20
|
Also, check out Herding Code's [podcast #117](http://t.co/GLn88R5) in
|
15
21
|
which Llewellyn Falco is interviewed about approvals.
|
16
22
|
|
17
|
-
|
23
|
+
|
18
24
|
|
19
25
|
## Configuration
|
20
26
|
|
21
|
-
|
22
|
-
|
23
|
-
|
27
|
+
```ruby
|
28
|
+
Approvals.configure do |c|
|
29
|
+
c.approvals_path = 'output/goes/here/'
|
30
|
+
end
|
31
|
+
```
|
24
32
|
|
25
33
|
The default location for the output files is
|
26
34
|
|
@@ -28,7 +36,9 @@ The default location for the output files is
|
|
28
36
|
|
29
37
|
## Usage
|
30
38
|
|
31
|
-
|
39
|
+
```ruby
|
40
|
+
Approvals.verify(your_subject, :format => :json)
|
41
|
+
```
|
32
42
|
|
33
43
|
This will raise an `ApprovalError` in the case of a failure.
|
34
44
|
|
@@ -48,31 +58,41 @@ Since you have not yet approved anything, the `*.approved` file does not exist,
|
|
48
58
|
|
49
59
|
For the moment the only direct integration is with RSpec.
|
50
60
|
|
51
|
-
|
61
|
+
```ruby
|
62
|
+
require 'approvals/rspec'
|
63
|
+
```
|
52
64
|
|
53
65
|
The default directory for output files when using RSpec is
|
54
66
|
|
55
|
-
|
67
|
+
```ruby
|
68
|
+
spec/fixtures/approvals/
|
69
|
+
```
|
56
70
|
|
57
71
|
You can override this:
|
58
72
|
|
59
|
-
|
60
|
-
|
61
|
-
|
73
|
+
```ruby
|
74
|
+
RSpec.configure do |c|
|
75
|
+
c.approvals_path = 'some/other/path'
|
76
|
+
end
|
77
|
+
```
|
62
78
|
|
63
79
|
The basic format of the approval is modeled after RSpec's `it`:
|
64
80
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
81
|
+
```ruby
|
82
|
+
it "works" do
|
83
|
+
verify do
|
84
|
+
"this is the the thing you want to verify"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
```
|
70
88
|
|
71
89
|
### Naming
|
72
90
|
|
73
91
|
When using RSpec, the namer is set for you, using the example's `full_description`.
|
74
92
|
|
75
|
-
|
93
|
+
```ruby
|
94
|
+
Approvals.verify(thing, :name => "the name of your test")
|
95
|
+
```
|
76
96
|
|
77
97
|
### Formatting
|
78
98
|
|
@@ -81,30 +101,36 @@ At the moment, only xml, html, and json are supported.
|
|
81
101
|
|
82
102
|
Simply add a `:format => :xml`, `:format => :html`, or `:format => :json` option to the example:
|
83
103
|
|
84
|
-
|
85
|
-
|
104
|
+
```ruby
|
105
|
+
page = "<html><head></head><body><h1>ZOMG</h1></body></html>"
|
106
|
+
Approvals.verify page, :format => :html
|
86
107
|
|
87
|
-
|
88
|
-
|
108
|
+
data = "{\"beverage\":\"coffee\"}"
|
109
|
+
Approvals.verify data, :format => :html
|
110
|
+
```
|
89
111
|
|
90
112
|
In RSpec, it looks like this:
|
91
113
|
|
92
|
-
|
93
|
-
|
94
|
-
|
114
|
+
```ruby
|
115
|
+
verify :format => :html do
|
116
|
+
"<html><head></head><body><h1>ZOMG</h1></body></html>"
|
117
|
+
end
|
95
118
|
|
96
|
-
|
97
|
-
|
98
|
-
|
119
|
+
verify :format => :json do
|
120
|
+
"{\"beverage\":\"coffee\"}"
|
121
|
+
end
|
122
|
+
```
|
99
123
|
|
100
124
|
### Exclude dynamicly changed values from json
|
101
125
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
126
|
+
```ruby
|
127
|
+
Approvals.configure do |c|
|
128
|
+
c.excluded_json_keys = {
|
129
|
+
:id =>/(\A|_)id$/,
|
130
|
+
:date => /_at$/
|
131
|
+
}
|
132
|
+
end
|
133
|
+
```
|
108
134
|
|
109
135
|
It will replace values with placeholders:
|
110
136
|
|
@@ -136,21 +162,25 @@ If this output looks right, approve the query. The next time the spec is run, it
|
|
136
162
|
|
137
163
|
If someone changes the query, then the comparison will fail. Both the previously approved command and the received command will be executed so that you can inspect the difference between the results of the two.
|
138
164
|
|
139
|
-
|
140
|
-
|
141
|
-
|
165
|
+
```ruby
|
166
|
+
executable = Approvals::Executable.new(subject.slow_sql) do |output|
|
167
|
+
# do something on failure
|
168
|
+
end
|
142
169
|
|
143
|
-
|
170
|
+
Approvals.verify(executable, :options => :here)
|
171
|
+
```
|
144
172
|
|
145
173
|
### RSpec executable
|
146
174
|
|
147
175
|
There is a convenience wrapper for RSpec that looks like so:
|
148
176
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
177
|
+
```ruby
|
178
|
+
verify do
|
179
|
+
executable(subject.slow_sql) do |command|
|
180
|
+
result = ActiveRecord::Base.connection.execute(command)
|
181
|
+
# do something to display the result
|
182
|
+
end
|
183
|
+
end
|
184
|
+
```
|
155
185
|
|
156
186
|
Copyright (c) 2011 Katrina Owen, released under the MIT license
|
data/lib/approvals/approval.rb
CHANGED
@@ -78,7 +78,11 @@ module Approvals
|
|
78
78
|
subject.on_failure.call(received_text)
|
79
79
|
end
|
80
80
|
|
81
|
-
|
81
|
+
error = ApprovalError.new("Approval Error: #{message}")
|
82
|
+
error.approved_path = approved_path
|
83
|
+
error.received_path = received_path
|
84
|
+
|
85
|
+
raise error
|
82
86
|
end
|
83
87
|
|
84
88
|
def diff_path
|
data/lib/approvals/error.rb
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
module Approvals
|
2
2
|
class ApprovalError < Exception
|
3
3
|
attr_accessor :received_path, :approved_path
|
4
|
+
|
5
|
+
def received_exists?
|
6
|
+
received_path && File.exist?(received_path)
|
7
|
+
end
|
8
|
+
|
9
|
+
def received_text
|
10
|
+
received_exists? && IO.read(received_path)
|
11
|
+
end
|
12
|
+
|
13
|
+
def approved_exists?
|
14
|
+
approved_path && File.exist?(approved_path)
|
15
|
+
end
|
16
|
+
|
17
|
+
def approved_text
|
18
|
+
approved_exists? && IO.read(approved_path)
|
19
|
+
end
|
4
20
|
end
|
5
21
|
end
|
@@ -7,5 +7,6 @@ if defined? RSpec
|
|
7
7
|
c.include Approvals::RSpec::DSL
|
8
8
|
c.add_setting :approvals_path, :default => 'spec/fixtures/approvals/'
|
9
9
|
c.add_setting :approvals_namer_class, :default => Approvals::Namers::DirectoryNamer
|
10
|
+
c.add_setting :diff_on_approval_failure, :default => false
|
10
11
|
end
|
11
12
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'rspec/expectations'
|
2
|
+
|
1
3
|
module Approvals
|
2
4
|
module RSpec
|
3
5
|
module DSL
|
@@ -9,6 +11,19 @@ module Approvals
|
|
9
11
|
group = eval "self", block.binding
|
10
12
|
namer = ::RSpec.configuration.approvals_namer_class.new(group.example)
|
11
13
|
Approvals.verify(block.call, options.merge(:namer => namer))
|
14
|
+
rescue ApprovalError => e
|
15
|
+
if diff_on_approval_failure?
|
16
|
+
::RSpec::Expectations.fail_with(e.message, e.approved_text, e.received_text)
|
17
|
+
else
|
18
|
+
raise e
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def diff_on_approval_failure?
|
25
|
+
::RSpec.configuration.diff_on_approval_failure? ||
|
26
|
+
example.metadata[:diff_on_approval_failure]
|
12
27
|
end
|
13
28
|
end
|
14
29
|
end
|
@@ -4,16 +4,7 @@ module Approvals
|
|
4
4
|
class << self
|
5
5
|
|
6
6
|
def reset
|
7
|
-
File.
|
8
|
-
touch
|
9
|
-
end
|
10
|
-
|
11
|
-
def path
|
12
|
-
File.join(Approvals.project_dir, '.approvals')
|
13
|
-
end
|
14
|
-
|
15
|
-
def touch
|
16
|
-
FileUtils.touch(path)
|
7
|
+
File.truncate(path, 0) if File.exists?(path)
|
17
8
|
end
|
18
9
|
|
19
10
|
def append(text)
|
@@ -22,6 +13,12 @@ module Approvals
|
|
22
13
|
end
|
23
14
|
end
|
24
15
|
|
16
|
+
private
|
17
|
+
|
18
|
+
def path
|
19
|
+
File.join(Approvals.project_dir, '.approvals')
|
20
|
+
end
|
21
|
+
|
25
22
|
def includes?(text)
|
26
23
|
system("cat #{path} | grep -q \"^#{text}$\"")
|
27
24
|
end
|
@@ -31,8 +28,6 @@ module Approvals
|
|
31
28
|
f.write "#{text}\n"
|
32
29
|
end
|
33
30
|
end
|
34
|
-
|
35
31
|
end
|
36
32
|
end
|
37
|
-
|
38
33
|
end
|
data/lib/approvals/version.rb
CHANGED
@@ -60,6 +60,22 @@ shared_context 'verify examples' do
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
63
|
+
|
64
|
+
specify "a failure" do
|
65
|
+
expect { verify { 'no.' } }.to raise_error(Approvals::ApprovalError)
|
66
|
+
end
|
67
|
+
|
68
|
+
specify "a failure diff" do
|
69
|
+
::RSpec.configuration.diff_on_approval_failure = true
|
70
|
+
::RSpec::Expectations.should_receive( :fail_with )
|
71
|
+
verify { 'no.' }
|
72
|
+
::RSpec.configuration.diff_on_approval_failure = false
|
73
|
+
end
|
74
|
+
|
75
|
+
specify "a failure diff", :diff_on_approval_failure => true do
|
76
|
+
::RSpec::Expectations.should_receive( :fail_with )
|
77
|
+
verify { 'no.' }
|
78
|
+
end
|
63
79
|
end
|
64
80
|
|
65
81
|
RSpec.configure do |c|
|
@@ -0,0 +1 @@
|
|
1
|
+
yes.
|
@@ -0,0 +1 @@
|
|
1
|
+
yes.
|
File without changes
|
File without changes
|
@@ -4,9 +4,9 @@ require 'approvals/reporters/first_working_reporter'
|
|
4
4
|
describe Approvals::Reporters::FirstWorkingReporter do
|
5
5
|
|
6
6
|
|
7
|
-
let(:no) {
|
8
|
-
let(:yes) {
|
9
|
-
let(:yes_too) {
|
7
|
+
let(:no) { double(:working_in_this_environment? => false) }
|
8
|
+
let(:yes) { double(:working_in_this_environment? => true) }
|
9
|
+
let(:yes_too) { double(:working_in_this_environment? => true) }
|
10
10
|
|
11
11
|
context "when at least one reporter works" do
|
12
12
|
subject { Approvals::Reporters::FirstWorkingReporter.new(no, yes) }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: approvals
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.10
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-01-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -85,7 +85,9 @@ extra_rdoc_files: []
|
|
85
85
|
files:
|
86
86
|
- .gitignore
|
87
87
|
- .travis.yml
|
88
|
+
- Changelog.md
|
88
89
|
- Gemfile
|
90
|
+
- Gemfile.travis
|
89
91
|
- License.txt
|
90
92
|
- README.md
|
91
93
|
- Rakefile
|
@@ -146,10 +148,14 @@ files:
|
|
146
148
|
- spec/fixtures/approvals/approvals_verifies_xml.approved.xml
|
147
149
|
- spec/fixtures/approvals/verifications_a_string.approved.txt
|
148
150
|
- spec/fixtures/approvals/verifies_a_complex_object.approved.txt
|
151
|
+
- spec/fixtures/approvals/verifies_a_failure.approved.txt
|
152
|
+
- spec/fixtures/approvals/verifies_a_failure_diff.approved.txt
|
149
153
|
- spec/fixtures/approvals/verifies_a_string.approved.txt
|
150
154
|
- spec/fixtures/approvals/verifies_an_array.approved.txt
|
151
155
|
- spec/fixtures/approvals/verifies_an_executable.approved.txt
|
152
156
|
- spec/fixtures/approvals/verifies_directory/a_complex_object.approved.txt
|
157
|
+
- spec/fixtures/approvals/verifies_directory/a_failure.approved.txt
|
158
|
+
- spec/fixtures/approvals/verifies_directory/a_failure_diff.approved.txt
|
153
159
|
- spec/fixtures/approvals/verifies_directory/a_string.approved.txt
|
154
160
|
- spec/fixtures/approvals/verifies_directory/an_array.approved.txt
|
155
161
|
- spec/fixtures/approvals/verifies_directory/an_executable.approved.txt
|