approvals 0.0.8 → 0.0.9
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.
- data/README.md +19 -0
- data/lib/approvals/approval.rb +18 -3
- data/lib/approvals/configuration.rb +5 -0
- data/lib/approvals/version.rb +1 -1
- data/lib/approvals/writer.rb +12 -6
- data/lib/approvals/writers/binary_writer.rb +59 -0
- data/lib/approvals/writers/json_writer.rb +37 -1
- data/spec/approvals_spec.rb +21 -0
- data/spec/fixtures/approvals/approvals_supports_excluded_keys_option_for_json_also_supports_an_array_of_hashes.approved.json +10 -0
- data/spec/fixtures/approvals/approvals_supports_excluded_keys_option_for_json_verifies_json_with_excluded_keys.approved.json +8 -0
- metadata +6 -3
- data/spec/fixtures/approvals/approvals_fails.approved.txt +0 -0
data/README.md
CHANGED
@@ -48,6 +48,8 @@ Since you have not yet approved anything, the `*.approved` file does not exist,
|
|
48
48
|
|
49
49
|
For the moment the only direct integration is with RSpec.
|
50
50
|
|
51
|
+
require 'approvals/rspec'
|
52
|
+
|
51
53
|
The default directory for output files when using RSpec is
|
52
54
|
|
53
55
|
spec/fixtures/approvals/
|
@@ -95,6 +97,23 @@ In RSpec, it looks like this:
|
|
95
97
|
"{\"beverage\":\"coffee\"}"
|
96
98
|
end
|
97
99
|
|
100
|
+
### Exclude dynamicly changed values from json
|
101
|
+
|
102
|
+
Approvals.configure do |c|
|
103
|
+
c.excluded_json_keys = {
|
104
|
+
:id =>/(\A|_)id$/,
|
105
|
+
:date => /_at$/
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
It will replace values with placeholders:
|
110
|
+
|
111
|
+
{id: 5, created_at: "2013-08-29 13:48:08 -0700"}
|
112
|
+
|
113
|
+
=>
|
114
|
+
|
115
|
+
{id: "<id>", created_at: "<date>"}
|
116
|
+
|
98
117
|
### Approving a spec
|
99
118
|
|
100
119
|
If the contents of the received file is to your liking, you can approve
|
data/lib/approvals/approval.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'erb' # It is referenced on line 56
|
1
2
|
module Approvals
|
2
3
|
class Approval
|
3
4
|
class << self
|
@@ -15,9 +16,17 @@ module Approvals
|
|
15
16
|
Approvals::Approval.namer || Namers::DefaultNamer.new(name)
|
16
17
|
end
|
17
18
|
|
19
|
+
# Add a Proc that tests if subject is a kind of format
|
20
|
+
IDENTITIES = {
|
21
|
+
hash: Proc.new(){|subject|subject.respond_to? :each_pair},
|
22
|
+
array: Proc.new(){|subject|subject.respond_to? :each_with_index},
|
23
|
+
}
|
24
|
+
|
18
25
|
def identify_format
|
19
|
-
|
20
|
-
|
26
|
+
IDENTITIES.each_pair do |format, id_test|
|
27
|
+
return format if id_test.call(subject)
|
28
|
+
end
|
29
|
+
# otherwise
|
21
30
|
return :txt
|
22
31
|
end
|
23
32
|
|
@@ -51,8 +60,14 @@ module Approvals
|
|
51
60
|
File.exists? approved_path
|
52
61
|
end
|
53
62
|
|
63
|
+
BINARY_FORMATS = [:binary]
|
64
|
+
|
54
65
|
def received_matches?
|
55
|
-
|
66
|
+
if BINARY_FORMATS.include?(@format) # Read without ERB
|
67
|
+
IO.read(received_path).chomp == IO.read(approved_path).chomp
|
68
|
+
else
|
69
|
+
IO.read(received_path).chomp == ERB.new(IO.read(approved_path).chomp).result
|
70
|
+
end
|
56
71
|
end
|
57
72
|
|
58
73
|
def fail_with(message)
|
@@ -16,9 +16,14 @@ module Approvals
|
|
16
16
|
include Singleton
|
17
17
|
|
18
18
|
attr_writer :approvals_path
|
19
|
+
attr_writer :excluded_json_keys
|
19
20
|
|
20
21
|
def approvals_path
|
21
22
|
@approvals_path ||= 'fixtures/approvals/'
|
22
23
|
end
|
24
|
+
|
25
|
+
def excluded_json_keys
|
26
|
+
@excluded_json_keys ||= {}
|
27
|
+
end
|
23
28
|
end
|
24
29
|
end
|
data/lib/approvals/version.rb
CHANGED
data/lib/approvals/writer.rb
CHANGED
@@ -4,19 +4,25 @@ require 'approvals/writers/hash_writer'
|
|
4
4
|
require 'approvals/writers/html_writer'
|
5
5
|
require 'approvals/writers/xml_writer'
|
6
6
|
require 'approvals/writers/json_writer'
|
7
|
+
require 'approvals/writers/binary_writer'
|
7
8
|
|
8
9
|
module Approvals
|
9
10
|
module Writer
|
10
11
|
extend Writers
|
12
|
+
|
13
|
+
REGISTRY = {
|
14
|
+
json: Writers::JsonWriter.instance,
|
15
|
+
xml: Writers::XmlWriter.instance,
|
16
|
+
html: Writers::HtmlWriter.instance,
|
17
|
+
hash: Writers::HashWriter.instance,
|
18
|
+
array: Writers::ArrayWriter.instance,
|
19
|
+
}
|
20
|
+
|
11
21
|
|
12
22
|
class << self
|
13
23
|
def for(format)
|
14
|
-
|
15
|
-
|
16
|
-
when :xml then XmlWriter.instance
|
17
|
-
when :html then HtmlWriter.instance
|
18
|
-
when :hash then HashWriter.instance
|
19
|
-
when :array then ArrayWriter.instance
|
24
|
+
if REGISTRY.include?(format)
|
25
|
+
REGISTRY[format]
|
20
26
|
else
|
21
27
|
TextWriter.instance
|
22
28
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Approvals
|
2
|
+
|
3
|
+
module Writers
|
4
|
+
|
5
|
+
class BinaryWriter
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
EXCEPTION_WRITER = Proc.new do |data, file|
|
9
|
+
raise "BinaryWriter#callback missing"
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(opts = {})
|
13
|
+
self.autoregister = opts[:autoregister] || true
|
14
|
+
self.detect = opts[:detect]
|
15
|
+
self.extension = opts[:extension] || ''
|
16
|
+
self.write = opts[:write] || EXCEPTION_WRITER
|
17
|
+
self.format = opts[:format] || :binary
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_accessor :autoregister
|
21
|
+
attr_accessor :extension
|
22
|
+
attr_accessor :write
|
23
|
+
attr_accessor :detect
|
24
|
+
|
25
|
+
|
26
|
+
attr_reader :format
|
27
|
+
|
28
|
+
def format=(sym)
|
29
|
+
unregister if autoregister
|
30
|
+
|
31
|
+
@format = sym
|
32
|
+
|
33
|
+
register if autoregister
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def register
|
38
|
+
if @format
|
39
|
+
Writer::REGISTRY[@format] = self
|
40
|
+
Approval::BINARY_FORMATS << @format
|
41
|
+
Approval::IDENTITIES[@format] = @detect if @detect
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def unregister
|
46
|
+
if @format
|
47
|
+
Writer::REGISTRY.delete!(@format)
|
48
|
+
Approval::BINARY_FORMATS.delete!(@format)
|
49
|
+
Approval::IDENTITIES.delete!(@format)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def write(data,path)
|
54
|
+
@write.call(data,path)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -7,9 +7,45 @@ module Approvals
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def format(data)
|
10
|
-
|
10
|
+
hash_or_array = parse_data(data)
|
11
|
+
|
12
|
+
apply_filters!(hash_or_array) if filters.any?
|
13
|
+
|
14
|
+
JSON.pretty_generate(hash_or_array)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def filters
|
20
|
+
Approvals.configuration.excluded_json_keys
|
11
21
|
end
|
12
22
|
|
23
|
+
def parse_data(data)
|
24
|
+
JSON.parse(data)
|
25
|
+
end
|
26
|
+
|
27
|
+
def apply_filters!(hash_or_array)
|
28
|
+
case hash_or_array
|
29
|
+
when Array
|
30
|
+
for i in (0 ... hash_or_array.size) do
|
31
|
+
apply_filters!(hash_or_array[i])
|
32
|
+
end
|
33
|
+
when Hash
|
34
|
+
hash_or_array.each do |key, value|
|
35
|
+
next if value.nil?
|
36
|
+
|
37
|
+
if value.is_a?(Hash) || value.is_a?(Array)
|
38
|
+
apply_filters!(value)
|
39
|
+
else
|
40
|
+
filters.each do |placeholder, pattern|
|
41
|
+
if pattern && key.match(pattern)
|
42
|
+
hash_or_array[key] = "<#{placeholder}>"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
13
49
|
end
|
14
50
|
end
|
15
51
|
end
|
data/spec/approvals_spec.rb
CHANGED
@@ -86,4 +86,25 @@ describe Approvals do
|
|
86
86
|
string = "We have, I fear, confused power with greatness."
|
87
87
|
Approvals.verify string, :namer => namer
|
88
88
|
end
|
89
|
+
|
90
|
+
describe "supports excluded keys option for json" do
|
91
|
+
let(:hash) { {:object => {:id => rand(100), :created_at => Time.now, :name => 'test', deleted_at: nil}} }
|
92
|
+
|
93
|
+
before do
|
94
|
+
Approvals.configure do |c|
|
95
|
+
c.excluded_json_keys = {
|
96
|
+
:id => /(\A|_)id$/,
|
97
|
+
:date => /_at$/
|
98
|
+
}
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
it "verifies json with excluded keys" do
|
103
|
+
Approvals.verify JSON.dump(hash), :format => :json, :namer => namer
|
104
|
+
end
|
105
|
+
|
106
|
+
it "also supports an array of hashes" do
|
107
|
+
Approvals.verify JSON.dump([hash]), :format => :json, :namer => namer
|
108
|
+
end
|
109
|
+
end
|
89
110
|
end
|
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.9
|
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: 2013-
|
12
|
+
date: 2013-10-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -123,6 +123,7 @@ files:
|
|
123
123
|
- lib/approvals/version.rb
|
124
124
|
- lib/approvals/writer.rb
|
125
125
|
- lib/approvals/writers/array_writer.rb
|
126
|
+
- lib/approvals/writers/binary_writer.rb
|
126
127
|
- lib/approvals/writers/hash_writer.rb
|
127
128
|
- lib/approvals/writers/html_writer.rb
|
128
129
|
- lib/approvals/writers/json_writer.rb
|
@@ -131,8 +132,9 @@ files:
|
|
131
132
|
- spec/approvals_spec.rb
|
132
133
|
- spec/configuration_spec.rb
|
133
134
|
- spec/extensions/rspec_approvals_spec.rb
|
134
|
-
- spec/fixtures/approvals/approvals_fails.approved.txt
|
135
135
|
- spec/fixtures/approvals/approvals_passes_approved_files_through_erb.approved.txt
|
136
|
+
- spec/fixtures/approvals/approvals_supports_excluded_keys_option_for_json_also_supports_an_array_of_hashes.approved.json
|
137
|
+
- spec/fixtures/approvals/approvals_supports_excluded_keys_option_for_json_verifies_json_with_excluded_keys.approved.json
|
136
138
|
- spec/fixtures/approvals/approvals_verifies_a_complex_object.approved.txt
|
137
139
|
- spec/fixtures/approvals/approvals_verifies_a_hash.approved.txt
|
138
140
|
- spec/fixtures/approvals/approvals_verifies_a_string.approved.txt
|
@@ -201,3 +203,4 @@ signing_key:
|
|
201
203
|
specification_version: 3
|
202
204
|
summary: Approval Tests for Ruby
|
203
205
|
test_files: []
|
206
|
+
has_rdoc:
|
File without changes
|