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 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
@@ -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
- return :hash if subject.respond_to? :each_pair
20
- return :array if subject.respond_to? :each_with_index
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
- IO.read(received_path).chomp == ERB.new(IO.read(approved_path).chomp).result
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
@@ -1,3 +1,3 @@
1
1
  module Approvals
2
- VERSION = '0.0.8'
2
+ VERSION = '0.0.9'
3
3
  end
@@ -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
- case format
15
- when :json then JsonWriter.instance
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
- JSON.pretty_generate(JSON.parse(data))
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
@@ -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
@@ -0,0 +1,10 @@
1
+ [
2
+ {
3
+ "object": {
4
+ "id": "<id>",
5
+ "created_at": "<date>",
6
+ "name": "test",
7
+ "deleted_at": null
8
+ }
9
+ }
10
+ ]
@@ -0,0 +1,8 @@
1
+ {
2
+ "object": {
3
+ "id": "<id>",
4
+ "created_at": "<date>",
5
+ "name": "test",
6
+ "deleted_at": null
7
+ }
8
+ }
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.8
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-06-29 00:00:00.000000000 Z
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