museo 0.1.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 +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.rubocop.yml +1307 -0
- data/.ruby-version +1 -0
- data/.travis.yml +8 -0
- data/Appraisals +10 -0
- data/Gemfile +4 -0
- data/Guardfile +20 -0
- data/README.md +38 -0
- data/Rakefile +38 -0
- data/app/views/layouts/museo/snapshot.html.erb +8 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/museo +7 -0
- data/gemfiles/rails_4.gemfile +9 -0
- data/gemfiles/rails_4.gemfile.lock +200 -0
- data/gemfiles/rails_5.gemfile +8 -0
- data/gemfiles/rails_5.gemfile.lock +205 -0
- data/lib/museo/cli.rb +67 -0
- data/lib/museo/engine.rb +5 -0
- data/lib/museo/formatter.rb +49 -0
- data/lib/museo/minitest_integration.rb +33 -0
- data/lib/museo/rspec_integration.rb +33 -0
- data/lib/museo/snapshot/minitest.rb +13 -0
- data/lib/museo/snapshot/rspec.rb +13 -0
- data/lib/museo/snapshot.rb +63 -0
- data/lib/museo/test_integration.rb +51 -0
- data/lib/museo/version.rb +3 -0
- data/lib/museo.rb +68 -0
- data/lib/tasks/museo_tasks.rake +1 -0
- data/museo.gemspec +31 -0
- metadata +221 -0
@@ -0,0 +1,49 @@
|
|
1
|
+
module Museo
|
2
|
+
class Formatter
|
3
|
+
def initialize(options = {})
|
4
|
+
@indent = options.delete(:indent) || " ".freeze
|
5
|
+
end
|
6
|
+
|
7
|
+
def format(object, indent_level = 0)
|
8
|
+
case object
|
9
|
+
when Hash
|
10
|
+
format_hash(object, indent_level)
|
11
|
+
when Array
|
12
|
+
format_array(object, indent_level)
|
13
|
+
else
|
14
|
+
format_value(object)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def format_hash(hash, indent_level)
|
21
|
+
[
|
22
|
+
"{",
|
23
|
+
hash.map do |key, value|
|
24
|
+
"#{@indent * (indent_level + 1)}#{format(key)} => #{format(value, indent_level + 1)},"
|
25
|
+
end,
|
26
|
+
"#{@indent * indent_level}}",
|
27
|
+
].join("\n")
|
28
|
+
end
|
29
|
+
|
30
|
+
def format_array(array, indent_level)
|
31
|
+
[
|
32
|
+
"[",
|
33
|
+
array.map do |value|
|
34
|
+
"#{@indent * (indent_level + 1)}#{format(value, indent_level + 1)},"
|
35
|
+
end,
|
36
|
+
"#{@indent * indent_level}]",
|
37
|
+
].join("\n")
|
38
|
+
end
|
39
|
+
|
40
|
+
def format_value(value)
|
41
|
+
case value
|
42
|
+
when Symbol
|
43
|
+
value.inspect
|
44
|
+
else
|
45
|
+
value.to_s
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Museo
|
2
|
+
module MinitestIntegration
|
3
|
+
include TestIntegration
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def snapshot(description)
|
11
|
+
test "snapshot: #{description}" do
|
12
|
+
begin
|
13
|
+
_museo_setup
|
14
|
+
|
15
|
+
instance_eval(&Proc.new)
|
16
|
+
|
17
|
+
assert_snapshot
|
18
|
+
ensure
|
19
|
+
_museo_teardown
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def assert_snapshot
|
26
|
+
assert_equal(
|
27
|
+
Snapshot::Minitest.new(self).body,
|
28
|
+
Snapshot.sanitize_response(response.body),
|
29
|
+
"Snapshot did not match",
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Museo
|
2
|
+
module RspecIntegration
|
3
|
+
include TestIntegration
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.render_views
|
7
|
+
base.extend(ClassMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def snapshot(description)
|
12
|
+
it "matches snapshot: #{description}" do |example|
|
13
|
+
begin
|
14
|
+
_museo_setup
|
15
|
+
|
16
|
+
instance_exec(example, &Proc.new)
|
17
|
+
|
18
|
+
expect_matching_snapshot(example)
|
19
|
+
ensure
|
20
|
+
_museo_teardown
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def expect_matching_snapshot(example)
|
27
|
+
expect(Snapshot::Rspec.new(self, example.metadata).body).to(
|
28
|
+
eq(Snapshot.sanitize_response(response.body)),
|
29
|
+
"Snapshot did not match",
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require_relative "snapshot/rspec"
|
3
|
+
require_relative "snapshot/minitest"
|
4
|
+
|
5
|
+
module Museo
|
6
|
+
class Snapshot
|
7
|
+
class GenerationDisabledError < StandardError; end
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def sanitize_response(body)
|
11
|
+
body.gsub(/:0x[a-fA-F0-9]{4,}/, ":0xXXXXXX")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(klass:, test_name:, response:)
|
16
|
+
@class_name = klass.to_s
|
17
|
+
@test_name = test_name
|
18
|
+
@response = response
|
19
|
+
|
20
|
+
generate unless exists?
|
21
|
+
end
|
22
|
+
|
23
|
+
def body
|
24
|
+
exists? ? File.read(path) : nil
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def exists?
|
30
|
+
File.exist?(path)
|
31
|
+
end
|
32
|
+
|
33
|
+
def folder
|
34
|
+
Museo.pathname(@class_name)
|
35
|
+
end
|
36
|
+
|
37
|
+
def file_name
|
38
|
+
"#{Museo.clean_name(@test_name)}.snapshot"
|
39
|
+
end
|
40
|
+
|
41
|
+
def path
|
42
|
+
Museo.rails_root.join(folder, file_name)
|
43
|
+
end
|
44
|
+
|
45
|
+
def sanitized_response
|
46
|
+
self.class.sanitize_response(@response.body.to_s)
|
47
|
+
end
|
48
|
+
|
49
|
+
def generate
|
50
|
+
if Museo.configuration.generation_disabled
|
51
|
+
fail GenerationDisabledError,
|
52
|
+
"Can't generate snapshots in a CI environment. " \
|
53
|
+
"Please generate snapshots locally first"
|
54
|
+
end
|
55
|
+
|
56
|
+
FileUtils.mkdir_p(folder)
|
57
|
+
|
58
|
+
File.open(path, "wb") { |f| f.print sanitized_response }
|
59
|
+
|
60
|
+
puts "Updated snapshot for #{file_name.inspect}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Museo
|
2
|
+
module TestIntegration
|
3
|
+
def _museo_setup
|
4
|
+
_add_snapshot_helper_methods
|
5
|
+
_redefine_render_with_snapshot_layout
|
6
|
+
end
|
7
|
+
|
8
|
+
def _museo_teardown
|
9
|
+
_remove_snapshot_helper_methods
|
10
|
+
end
|
11
|
+
|
12
|
+
def _add_snapshot_helper_methods
|
13
|
+
@controller.class.helper do
|
14
|
+
Museo.configuration.stubbed_methods.each do |method_name, callable|
|
15
|
+
alias_method("_original_#{method_name}", method_name) if method_defined?(method_name)
|
16
|
+
|
17
|
+
define_method(method_name) do |*args, &block|
|
18
|
+
output = callable.respond_to?(:call) ? instance_exec(*args, block, &callable) : callable
|
19
|
+
|
20
|
+
[
|
21
|
+
"<!--",
|
22
|
+
"Stubbed method call: #{method_name}",
|
23
|
+
Museo.configuration.formatter.format(output),
|
24
|
+
"-->",
|
25
|
+
"",
|
26
|
+
].join("\n").html_safe
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def _remove_snapshot_helper_methods
|
33
|
+
@controller.class.helper do
|
34
|
+
Museo.configuration.stubbed_methods.each do |method_name, _callable|
|
35
|
+
remove_method method_name
|
36
|
+
|
37
|
+
if method_defined?("_original_#{method_name}")
|
38
|
+
alias_method method_name, "_original_#{method_name}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def _redefine_render_with_snapshot_layout
|
45
|
+
@controller.define_singleton_method(:render) do |*args|
|
46
|
+
options = args.length > 1 ? args.last : {}
|
47
|
+
super(*args[1..-2], options.merge(layout: "museo/snapshot"))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/museo.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require "rails"
|
2
|
+
require "museo/version"
|
3
|
+
require "museo/formatter"
|
4
|
+
require "museo/snapshot"
|
5
|
+
require "museo/test_integration"
|
6
|
+
require "museo/minitest_integration"
|
7
|
+
require "museo/rspec_integration"
|
8
|
+
require "museo/engine"
|
9
|
+
|
10
|
+
module Museo
|
11
|
+
class << self
|
12
|
+
def configure
|
13
|
+
yield(configuration)
|
14
|
+
end
|
15
|
+
|
16
|
+
def configuration
|
17
|
+
@configuration ||= Configuration.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def rails_root
|
21
|
+
@rails_root ||= Rails::Application.find_root(Dir.pwd)
|
22
|
+
end
|
23
|
+
|
24
|
+
def clean_name(name)
|
25
|
+
if name
|
26
|
+
name.gsub("::", "/").gsub(/[^0-9a-z\/]+/i, "_")
|
27
|
+
else
|
28
|
+
""
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def pathname(class_name = "")
|
33
|
+
test_directory = Museo.configuration.rspec ? "spec" : "test"
|
34
|
+
|
35
|
+
Museo.rails_root.join(test_directory, "snapshots", clean_name(class_name))
|
36
|
+
end
|
37
|
+
|
38
|
+
def clear_configuration!
|
39
|
+
@configuration = Configuration.new
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class Configuration
|
44
|
+
attr_accessor :formatter
|
45
|
+
attr_accessor :rspec
|
46
|
+
attr_accessor :generation_disabled
|
47
|
+
|
48
|
+
def initialize
|
49
|
+
@formatter = Museo::Formatter.new
|
50
|
+
@rspec = false
|
51
|
+
@generation_disabled = !!ENV["CI"]
|
52
|
+
end
|
53
|
+
|
54
|
+
def stubbed_methods
|
55
|
+
@stubbed_methods ||= {}
|
56
|
+
end
|
57
|
+
|
58
|
+
def stub(name, value = nil)
|
59
|
+
value = block_given? ? Proc.new : value
|
60
|
+
|
61
|
+
stubbed_methods[name] = value
|
62
|
+
end
|
63
|
+
|
64
|
+
def clear_stubs!
|
65
|
+
@stubbed_methods = {}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
# rake tasks
|
data/museo.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "museo/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "museo"
|
8
|
+
spec.version = Museo::VERSION
|
9
|
+
spec.authors = ["Daniel Ma"]
|
10
|
+
spec.email = ["drailskid@yahoo.com"]
|
11
|
+
|
12
|
+
spec.summary = %(Snapshot testing for Rails views)
|
13
|
+
spec.description = %(Provide snapshot testing utilities for Rails views)
|
14
|
+
spec.homepage = "https://github.com/danielma/museo"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.bindir = "exe"
|
18
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "rails", ">= 4", "< 5.1"
|
22
|
+
spec.add_development_dependency "appraisal"
|
23
|
+
spec.add_development_dependency "rubocop", "~> 0.42"
|
24
|
+
spec.add_development_dependency "rspec"
|
25
|
+
spec.add_development_dependency "rspec-rails"
|
26
|
+
spec.add_development_dependency "guard"
|
27
|
+
spec.add_development_dependency "guard-rspec"
|
28
|
+
spec.add_development_dependency "guard-minitest"
|
29
|
+
spec.add_development_dependency "pry"
|
30
|
+
spec.add_development_dependency "awesome_print"
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,221 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: museo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel Ma
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-12-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '5.1'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '4'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '5.1'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: appraisal
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rubocop
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0.42'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0.42'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rspec
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rspec-rails
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: guard
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: guard-rspec
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: guard-minitest
|
119
|
+
requirement: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
type: :development
|
125
|
+
prerelease: false
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
name: pry
|
133
|
+
requirement: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
type: :development
|
139
|
+
prerelease: false
|
140
|
+
version_requirements: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
- !ruby/object:Gem::Dependency
|
146
|
+
name: awesome_print
|
147
|
+
requirement: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
type: :development
|
153
|
+
prerelease: false
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
159
|
+
description: Provide snapshot testing utilities for Rails views
|
160
|
+
email:
|
161
|
+
- drailskid@yahoo.com
|
162
|
+
executables:
|
163
|
+
- museo
|
164
|
+
extensions: []
|
165
|
+
extra_rdoc_files: []
|
166
|
+
files:
|
167
|
+
- ".gitignore"
|
168
|
+
- ".rspec"
|
169
|
+
- ".rubocop.yml"
|
170
|
+
- ".ruby-version"
|
171
|
+
- ".travis.yml"
|
172
|
+
- Appraisals
|
173
|
+
- Gemfile
|
174
|
+
- Guardfile
|
175
|
+
- README.md
|
176
|
+
- Rakefile
|
177
|
+
- app/views/layouts/museo/snapshot.html.erb
|
178
|
+
- bin/console
|
179
|
+
- bin/setup
|
180
|
+
- exe/museo
|
181
|
+
- gemfiles/rails_4.gemfile
|
182
|
+
- gemfiles/rails_4.gemfile.lock
|
183
|
+
- gemfiles/rails_5.gemfile
|
184
|
+
- gemfiles/rails_5.gemfile.lock
|
185
|
+
- lib/museo.rb
|
186
|
+
- lib/museo/cli.rb
|
187
|
+
- lib/museo/engine.rb
|
188
|
+
- lib/museo/formatter.rb
|
189
|
+
- lib/museo/minitest_integration.rb
|
190
|
+
- lib/museo/rspec_integration.rb
|
191
|
+
- lib/museo/snapshot.rb
|
192
|
+
- lib/museo/snapshot/minitest.rb
|
193
|
+
- lib/museo/snapshot/rspec.rb
|
194
|
+
- lib/museo/test_integration.rb
|
195
|
+
- lib/museo/version.rb
|
196
|
+
- lib/tasks/museo_tasks.rake
|
197
|
+
- museo.gemspec
|
198
|
+
homepage: https://github.com/danielma/museo
|
199
|
+
licenses: []
|
200
|
+
metadata: {}
|
201
|
+
post_install_message:
|
202
|
+
rdoc_options: []
|
203
|
+
require_paths:
|
204
|
+
- lib
|
205
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
206
|
+
requirements:
|
207
|
+
- - ">="
|
208
|
+
- !ruby/object:Gem::Version
|
209
|
+
version: '0'
|
210
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
211
|
+
requirements:
|
212
|
+
- - ">="
|
213
|
+
- !ruby/object:Gem::Version
|
214
|
+
version: '0'
|
215
|
+
requirements: []
|
216
|
+
rubyforge_project:
|
217
|
+
rubygems_version: 2.4.5.1
|
218
|
+
signing_key:
|
219
|
+
specification_version: 4
|
220
|
+
summary: Snapshot testing for Rails views
|
221
|
+
test_files: []
|