snapshot_testing 0.2.2 → 0.3.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/.travis.yml +4 -0
- data/Gemfile +0 -1
- data/README.md +6 -2
- data/Rakefile +12 -3
- data/examples/__snapshots__/named.minitest.spec.txt +1 -0
- data/examples/__snapshots__/named.minitest.test.txt +1 -0
- data/examples/__snapshots__/named.rspec.txt +1 -0
- data/examples/__snapshots__/named.unit.txt +1 -0
- data/examples/minitest.rb +10 -2
- data/examples/rspec.rb +4 -0
- data/examples/test_unit.rb +4 -0
- data/lib/snapshot_testing.rb +3 -0
- data/lib/snapshot_testing/minitest.rb +11 -10
- data/lib/snapshot_testing/recorder.rb +87 -42
- data/lib/snapshot_testing/rspec.rb +19 -23
- data/lib/snapshot_testing/test_unit.rb +7 -4
- data/lib/snapshot_testing/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a09c878dab9b37cfb19478f2647d404fc1091840
|
4
|
+
data.tar.gz: 83d05b1d4a199a08f44e0c4a3d5a01b3e07f9754
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d630db5ee68d5dcb9df88b29f6991eacbdee0f150c03282f6e6121eb434bf9476985111e71438e5b8ae8d66af1c29d12d50078f6fd18b558ecd3bf77281ed0a
|
7
|
+
data.tar.gz: 44402a6591987118f01cdc357e5b089625a0406850da4e8e2e16c8134a7571102d02f3594dc3d0212dc423115abf20b3b0a3e54acd8ee270e705904e66a8976a
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -47,6 +47,7 @@ RSpec.describe "Example" do
|
|
47
47
|
it "takes a snapshot" do
|
48
48
|
expect("hello").to match_snapshot
|
49
49
|
expect("goodbye").to match_snapshot
|
50
|
+
expect("hello").to match_snapshot("hello.txt")
|
50
51
|
end
|
51
52
|
end
|
52
53
|
```
|
@@ -63,6 +64,7 @@ class ExampleTest < Minitest::Test
|
|
63
64
|
def test_takes_a_snapshot
|
64
65
|
assert_snapshot "hello"
|
65
66
|
assert_snapshot "goodbye"
|
67
|
+
assert_snapshot "hello.txt", "hello"
|
66
68
|
end
|
67
69
|
end
|
68
70
|
|
@@ -70,8 +72,9 @@ class ExampleSpec < Minitest::Spec
|
|
70
72
|
include SnapshotTesting::Minitest
|
71
73
|
|
72
74
|
it "takes a snapshot" do
|
73
|
-
"hello".must_match_snapshot
|
74
|
-
"goodbye".must_match_snapshot
|
75
|
+
_("hello").must_match_snapshot
|
76
|
+
_("goodbye").must_match_snapshot
|
77
|
+
_("hello").must_match_snapshot "hello.txt"
|
75
78
|
end
|
76
79
|
end
|
77
80
|
```
|
@@ -88,6 +91,7 @@ class ExampleTest < Test::Unit::TestCase
|
|
88
91
|
def test_snapshot
|
89
92
|
assert_snapshot "hello"
|
90
93
|
assert_snapshot "goodbye"
|
94
|
+
assert_snapshot "hello.txt", "hello"
|
91
95
|
end
|
92
96
|
end
|
93
97
|
```
|
data/Rakefile
CHANGED
@@ -3,10 +3,19 @@ require "rspec/core/rake_task"
|
|
3
3
|
|
4
4
|
RSpec::Core::RakeTask.new(:spec)
|
5
5
|
|
6
|
+
def info(message)
|
7
|
+
puts "\033[1m#{message}\033[0m"
|
8
|
+
end
|
9
|
+
|
6
10
|
task :examples do
|
7
|
-
|
8
|
-
ruby
|
9
|
-
|
11
|
+
info "==>> Running RSpec..."
|
12
|
+
ruby "examples/rspec.rb -f progress"
|
13
|
+
|
14
|
+
info "\n\n==>> Running Minitest..."
|
15
|
+
ruby "examples/minitest.rb"
|
16
|
+
|
17
|
+
info "\n\n==>> Running TestUnit..."
|
18
|
+
ruby "examples/test_unit.rb"
|
10
19
|
end
|
11
20
|
|
12
21
|
task :default => :spec
|
@@ -0,0 +1 @@
|
|
1
|
+
named
|
@@ -0,0 +1 @@
|
|
1
|
+
named
|
@@ -0,0 +1 @@
|
|
1
|
+
named
|
@@ -0,0 +1 @@
|
|
1
|
+
named
|
data/examples/minitest.rb
CHANGED
@@ -9,13 +9,21 @@ class ExampleTest < Minitest::Test
|
|
9
9
|
assert_snapshot "hello"
|
10
10
|
assert_snapshot "goodbye"
|
11
11
|
end
|
12
|
+
|
13
|
+
def test_named_snapshot
|
14
|
+
assert_snapshot "named.minitest.test.txt", "named"
|
15
|
+
end
|
12
16
|
end
|
13
17
|
|
14
18
|
class ExampleSpec < Minitest::Spec
|
15
19
|
include SnapshotTesting::Minitest
|
16
20
|
|
17
21
|
it "takes a snapshot" do
|
18
|
-
"hello".must_match_snapshot
|
19
|
-
"goodbye".must_match_snapshot
|
22
|
+
_("hello").must_match_snapshot
|
23
|
+
_("goodbye").must_match_snapshot
|
24
|
+
end
|
25
|
+
|
26
|
+
it "takes a named snapshot" do
|
27
|
+
_("named").must_match_snapshot "named.minitest.spec.txt"
|
20
28
|
end
|
21
29
|
end
|
data/examples/rspec.rb
CHANGED
data/examples/test_unit.rb
CHANGED
data/lib/snapshot_testing.rb
CHANGED
@@ -2,17 +2,10 @@ require "snapshot_testing"
|
|
2
2
|
|
3
3
|
module SnapshotTesting
|
4
4
|
module Minitest
|
5
|
-
def self.included(_)
|
6
|
-
return unless defined?(::Minitest::Expectations)
|
7
|
-
return if ::Minitest::Expectations.method_defined?(:must_match_snapshot)
|
8
|
-
::Minitest::Expectations.infect_an_assertion(:assert_snapshot, :must_match_snapshot, true)
|
9
|
-
end
|
10
|
-
|
11
5
|
def before_setup
|
12
6
|
@__snapshot_recorder__ = SnapshotTesting::Recorder.new(
|
13
7
|
name: name,
|
14
|
-
path: method(name).source_location.first
|
15
|
-
update: !ENV['UPDATE_SNAPSHOTS'].nil?
|
8
|
+
path: method(name).source_location.first
|
16
9
|
)
|
17
10
|
super
|
18
11
|
end
|
@@ -22,8 +15,16 @@ module SnapshotTesting
|
|
22
15
|
@__snapshot_recorder__.commit
|
23
16
|
end
|
24
17
|
|
25
|
-
def assert_snapshot(actual)
|
26
|
-
|
18
|
+
def assert_snapshot(name = nil, actual)
|
19
|
+
if name.nil?
|
20
|
+
assert_equal(@__snapshot_recorder__.record(actual), actual)
|
21
|
+
else
|
22
|
+
assert_equal(@__snapshot_recorder__.record_file(name, actual), actual)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
if respond_to? :infect_an_assertion
|
27
|
+
infect_an_assertion :assert_snapshot, :must_match_snapshot
|
27
28
|
end
|
28
29
|
end
|
29
30
|
end
|
@@ -2,80 +2,125 @@ require "fileutils"
|
|
2
2
|
|
3
3
|
module SnapshotTesting
|
4
4
|
class Recorder
|
5
|
-
def initialize(name:, path:, update:)
|
5
|
+
def initialize(name:, path:, update: SnapshotTesting.update?)
|
6
6
|
@name = name
|
7
7
|
@path = path
|
8
8
|
@update = update
|
9
|
-
@
|
9
|
+
@visited = []
|
10
|
+
@added = 0
|
11
|
+
@updated = 0
|
10
12
|
end
|
11
13
|
|
12
|
-
def
|
13
|
-
File.join(File.
|
14
|
-
end
|
15
|
-
|
16
|
-
def snapshot_file
|
17
|
-
File.join(snapshot_dir, "#{File.basename(@path)}.snap")
|
14
|
+
def snapshot_path
|
15
|
+
File.join(snapshots_path, "#{File.basename(path)}.snap")
|
18
16
|
end
|
19
17
|
|
20
18
|
def snapshots
|
21
19
|
@snapshots ||= begin
|
22
|
-
Snapshot.load_file(
|
20
|
+
Snapshot.load_file(snapshot_path)
|
23
21
|
rescue Errno::ENOENT
|
24
22
|
{}
|
25
23
|
end
|
26
24
|
end
|
27
25
|
|
26
|
+
def record_file(name, actual)
|
27
|
+
expected = begin
|
28
|
+
read(name)
|
29
|
+
rescue Errno::ENOENT
|
30
|
+
write(name, actual)
|
31
|
+
log(1, :written)
|
32
|
+
actual
|
33
|
+
end
|
34
|
+
|
35
|
+
if update? && actual != expected
|
36
|
+
write(name, actual)
|
37
|
+
log(1, :updated)
|
38
|
+
actual
|
39
|
+
else
|
40
|
+
expected
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
28
44
|
def record(actual)
|
29
|
-
key = "#{
|
45
|
+
key = "#{name} #{visited.length + 1}"
|
30
46
|
|
31
|
-
|
32
|
-
@state[key] = actual
|
47
|
+
self.visited << key
|
33
48
|
|
34
|
-
|
35
|
-
|
49
|
+
unless snapshots.key?(key)
|
50
|
+
self.added += 1
|
51
|
+
self.snapshots[key] = actual
|
52
|
+
end
|
36
53
|
|
37
|
-
|
38
|
-
|
54
|
+
if update? && actual != snapshots[key]
|
55
|
+
self.updated += 1
|
56
|
+
self.snapshots[key] = actual
|
57
|
+
end
|
39
58
|
|
40
|
-
# otherwise, compare actual to the snapshot
|
41
59
|
snapshots[key]
|
42
60
|
end
|
43
61
|
|
44
62
|
def commit
|
45
|
-
|
46
|
-
|
47
|
-
removed
|
48
|
-
|
49
|
-
|
63
|
+
removed = snapshots.keys - visited
|
64
|
+
removed = removed.grep(/^#{name}\s\d+$/)
|
65
|
+
removed.each { |key| snapshots.delete(key) }
|
66
|
+
|
67
|
+
write_snapshots(snapshots) if write?
|
68
|
+
log(added, :written) unless added.zero?
|
69
|
+
log(updated, :updated) unless updated.zero?
|
70
|
+
log(removed.length, :removed) if update? && !removed.empty?
|
71
|
+
log(removed.length, :obsolete) if !update? && !removed.empty?
|
72
|
+
end
|
50
73
|
|
51
|
-
|
52
|
-
result = result.merge(changed) if @update
|
53
|
-
result = result.reject { |k, _| removed.include?(k) } if @update
|
74
|
+
protected
|
54
75
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
76
|
+
# the number of added snapshots
|
77
|
+
attr_accessor :added
|
78
|
+
|
79
|
+
# the number of updated snapshots
|
80
|
+
attr_accessor :updated
|
81
|
+
|
82
|
+
# all snapshots that have been compared
|
83
|
+
attr_reader :visited
|
61
84
|
|
62
85
|
private
|
63
86
|
|
64
|
-
|
87
|
+
# the name of the current test
|
88
|
+
attr_reader :name
|
89
|
+
|
90
|
+
# the file location of the current test
|
91
|
+
attr_reader :path
|
92
|
+
|
93
|
+
# should we update failing snapshots?
|
94
|
+
def update?
|
95
|
+
@update
|
96
|
+
end
|
97
|
+
|
98
|
+
# should we write to the filesystem?
|
99
|
+
def write?
|
100
|
+
update? || !added.zero?
|
101
|
+
end
|
102
|
+
|
103
|
+
def snapshots_path
|
104
|
+
File.join(File.dirname(path), "__snapshots__")
|
105
|
+
end
|
106
|
+
|
107
|
+
def log(count, status)
|
65
108
|
label = count == 1 ? "snapshot" : "snapshots"
|
66
|
-
|
109
|
+
warn "\e[33m#{count} #{label} #{status}\e[0m"
|
110
|
+
end
|
67
111
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
112
|
+
def read(name)
|
113
|
+
File.read(File.join(snapshots_path, name))
|
114
|
+
end
|
115
|
+
|
116
|
+
def write(name, data)
|
117
|
+
FileUtils.mkdir_p(snapshots_path)
|
118
|
+
File.write(File.join(snapshots_path, name), data)
|
74
119
|
end
|
75
120
|
|
76
|
-
def
|
77
|
-
FileUtils.mkdir_p(
|
78
|
-
File.write(
|
121
|
+
def write_snapshots(snapshots)
|
122
|
+
FileUtils.mkdir_p(snapshots_path)
|
123
|
+
File.write(snapshot_path, Snapshot.dump(snapshots))
|
79
124
|
end
|
80
125
|
end
|
81
126
|
end
|
@@ -2,12 +2,13 @@ require "snapshot_testing"
|
|
2
2
|
|
3
3
|
module SnapshotTesting
|
4
4
|
module RSpec
|
5
|
+
extend ::RSpec::Matchers::DSL
|
6
|
+
|
5
7
|
def self.included(base)
|
6
8
|
base.let :__snapshot_recorder__ do |example|
|
7
9
|
SnapshotTesting::Recorder.new(
|
8
10
|
name: example.description,
|
9
|
-
path: example.metadata[:absolute_file_path]
|
10
|
-
update: !ENV['UPDATE_SNAPSHOTS'].nil?
|
11
|
+
path: example.metadata[:absolute_file_path]
|
11
12
|
)
|
12
13
|
end
|
13
14
|
|
@@ -16,35 +17,30 @@ module SnapshotTesting
|
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
matcher :match_snapshot do |name|
|
21
|
+
match do |actual|
|
22
|
+
@expected = if name.nil?
|
23
|
+
__snapshot_recorder__.record(actual)
|
24
|
+
else
|
25
|
+
__snapshot_recorder__.record_file(name, actual)
|
26
|
+
end
|
25
27
|
|
26
|
-
|
27
|
-
@recorder = recorder
|
28
|
+
@expected == actual
|
28
29
|
end
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
@expected = @recorder.record(@actual)
|
33
|
-
@actual == @expected
|
34
|
-
end
|
31
|
+
diffable
|
32
|
+
description { "match snapshot #{expected_formatted}"}
|
35
33
|
|
36
|
-
|
37
|
-
|
38
|
-
actual = ::RSpec::Support::ObjectFormatter.format(@actual)
|
39
|
-
"\nexpected: #{expected}\n got: #{actual}\n\n(compared using ==)\n"
|
34
|
+
failure_message do |actual|
|
35
|
+
"\nexpected: #{expected_formatted}\n got: #{actual_formatted}\n\n(compared using ==)\n"
|
40
36
|
end
|
41
37
|
|
42
|
-
def
|
43
|
-
|
38
|
+
def expected_formatted
|
39
|
+
::RSpec::Support::ObjectFormatter.format(@expected)
|
44
40
|
end
|
45
41
|
|
46
|
-
def
|
47
|
-
|
42
|
+
def actual_formatted
|
43
|
+
::RSpec::Support::ObjectFormatter.format(@actual)
|
48
44
|
end
|
49
45
|
end
|
50
46
|
end
|
@@ -5,8 +5,7 @@ module SnapshotTesting
|
|
5
5
|
def setup
|
6
6
|
@__snapshot_recorder__ = SnapshotTesting::Recorder.new(
|
7
7
|
name: method_name,
|
8
|
-
path: method(method_name).source_location.first
|
9
|
-
update: !ENV['UPDATE_SNAPSHOTS'].nil?
|
8
|
+
path: method(method_name).source_location.first
|
10
9
|
)
|
11
10
|
super
|
12
11
|
end
|
@@ -16,8 +15,12 @@ module SnapshotTesting
|
|
16
15
|
@__snapshot_recorder__.commit
|
17
16
|
end
|
18
17
|
|
19
|
-
def assert_snapshot(actual)
|
20
|
-
|
18
|
+
def assert_snapshot(name = nil, actual)
|
19
|
+
if name.nil?
|
20
|
+
assert_equal(@__snapshot_recorder__.record(actual), actual)
|
21
|
+
else
|
22
|
+
assert_equal(@__snapshot_recorder__.record_file(name, actual), actual)
|
23
|
+
end
|
21
24
|
end
|
22
25
|
end
|
23
26
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: snapshot_testing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ray Zane
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-12-
|
11
|
+
date: 2019-12-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -110,6 +110,10 @@ files:
|
|
110
110
|
- bin/console
|
111
111
|
- bin/setup
|
112
112
|
- examples/__snapshots__/minitest.rb.snap
|
113
|
+
- examples/__snapshots__/named.minitest.spec.txt
|
114
|
+
- examples/__snapshots__/named.minitest.test.txt
|
115
|
+
- examples/__snapshots__/named.rspec.txt
|
116
|
+
- examples/__snapshots__/named.unit.txt
|
113
117
|
- examples/__snapshots__/rspec.rb.snap
|
114
118
|
- examples/__snapshots__/test_unit.rb.snap
|
115
119
|
- examples/minitest.rb
|