rspec_fixtures 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 824a68775a4a3f44ab6c7f897de7df47431f7b1b233e4f3224cb71b9dc4ca5a1
4
- data.tar.gz: 1d8830af166d11392768543e9ab6cc924e1dc9c985c52f1906f44da3d94b77f1
3
+ metadata.gz: 45b4a358e1d0676243ab8e196d564a24004925cea26a4e4e7fea2260c207947b
4
+ data.tar.gz: 24e457d02d6cb4508da343bbce5bf55bc8c69978db0590a2fc78ea305c1aeef5
5
5
  SHA512:
6
- metadata.gz: b8a0198c92a30cbd6600598b41d74df121f64d96202d368a187a04027689301175c256ca672cfe2d34aa7e63a152382f4c27b3a771220b0bc6dbc68fa6a2d3eb
7
- data.tar.gz: 7d5687f648b7e9e5b3e2ff733a3e91495c4279103726069f91c9d53d5872386169a221c4f64c78bac55dc4127cea6bd0713972fc0ed80c34379d0c26815c2a62
6
+ metadata.gz: 5b0ba1c117b24f8f5eda492b846d6e398e284243823a64039fb8178a5921f19eaf5ccf55880a3f370a0d7f5b16f2dff174b64f994ca748fb4429ad515066ebe7
7
+ data.tar.gz: 2143684b0101b840ef918a91d8eaf55ae87cac86bcfd2772207c8c24dc93b96f57cf10bb248a79302a7e83a7d85d4f551b05bcc216779c342a649016d82b3cee
data/README.md CHANGED
@@ -17,6 +17,7 @@ content.
17
17
  ---
18
18
 
19
19
 
20
+
20
21
  Install
21
22
  --------------------------------------------------
22
23
 
@@ -31,6 +32,7 @@ gem 'rspec_fixtures'
31
32
  ```
32
33
 
33
34
 
35
+
34
36
  Usage
35
37
  --------------------------------------------------
36
38
 
@@ -51,10 +53,12 @@ describe 'ls' do
51
53
  end
52
54
  ```
53
55
 
56
+
57
+
54
58
  Matchers
55
59
  --------------------------------------------------
56
60
 
57
- ### `match_fixture`
61
+ ### `match_fixture` - Compare Strings
58
62
 
59
63
  Compare a string with a pre-approved fixture.
60
64
 
@@ -62,7 +66,8 @@ Compare a string with a pre-approved fixture.
62
66
  expect('some string').to match_fixture('fixture_filename')
63
67
  ```
64
68
 
65
- ### `output_fixture`
69
+
70
+ ### `output_fixture` - Compare STDOUT/STDERR
66
71
 
67
72
  Compare an output (stdout or stderr) with a pre-approved fixture.
68
73
 
@@ -75,6 +80,24 @@ expect{ $stderr.puts "hello" }.to output_fixture('fixture_filename').to_stderr
75
80
  ```
76
81
 
77
82
 
83
+ ### `diff` - String Similarity
84
+
85
+ Adding `diff(distance)` to either `match_fixture` or `output_fixture` will
86
+ change the matching behavior. Instead of expecting the strings to be exactly
87
+ the same, using `diff` compares the strings using the Levenshtein text
88
+ similarity algorithm.
89
+
90
+ In the below example, we allow up to 5 characters to be different.
91
+
92
+ ```ruby
93
+ expect('some string').to match_fixture('fixture_filename').diff(5)
94
+ expect{ puts 'some string' }.to output_fixture('fixture_filename').diff(5)
95
+ ```
96
+
97
+ Distance is measured using the Levenshtein algorithm.
98
+
99
+
100
+
78
101
  Configuration
79
102
  --------------------------------------------------
80
103
 
@@ -90,6 +113,7 @@ RSpec.configure do |config|
90
113
  end
91
114
  ```
92
115
 
116
+
93
117
  ### `fixtures_path`
94
118
 
95
119
  By default, fixtures are stored in `spec/fixtures`. To change the path,
@@ -99,4 +123,5 @@ add this to your `spec_helper`.
99
123
  RSpec.configure do |config|
100
124
  config.fixtures_path = 'spec/anywhere/else'
101
125
  end
102
- ```
126
+ ```
127
+
@@ -2,6 +2,8 @@ require 'colsole'
2
2
  require 'io/console'
3
3
 
4
4
  module RSpecFixtures
5
+
6
+ # Handles user input and interactive fixture approvals
5
7
  class ApprovalHandler
6
8
  include Colsole
7
9
 
@@ -1,52 +1,98 @@
1
1
  module RSpecFixtures
2
2
  module Matchers
3
3
 
4
+ # A base matcher for fixture approvals
4
5
  class Base
5
- attr_reader :fixture_name, :actual
6
+ attr_reader :fixture_name, :actual, :distance, :actual_distance
6
7
 
7
8
  def initialize(fixture_name=nil)
8
9
  @fixture_name = fixture_name
9
10
  end
10
11
 
12
+ # Called by RSpec. This will be overridden by child matchers.
11
13
  def matches?(actual)
12
- @actual = actual
13
- false
14
+ @actual ||= actual
15
+
16
+ success = strings_match?
17
+
18
+ if success or !interactive?
19
+ success
20
+ else
21
+ approve_fixture
22
+ end
23
+ end
24
+
25
+ # Provides a chained matcher to do something like:
26
+ # `expect(string).to match_fixture(file).diff(10)
27
+ # The distance argument is the max allowed Levenshtein Distance.
28
+ def diff(distance)
29
+ @distance = distance
30
+ self
14
31
  end
15
32
 
33
+ # Returns the expected value, from a fixture file
16
34
  def expected
17
35
  @expected ||= expected!
18
36
  end
19
37
 
38
+ # Called by RSpec when there is a failure
20
39
  def failure_message
21
- "expected #{actual}\nto match #{expected}"
40
+ result = "expected: #{actual}\nto match: #{expected}"
41
+
42
+ if distance
43
+ result = "#{result}\n(actual distance is #{actual_distance} instead of the expected #{distance})"
44
+ end
45
+
46
+ result
22
47
  end
23
48
 
49
+ # Lets RSpec know these matchers support diffing
24
50
  def diffable?
25
51
  true
26
52
  end
27
53
 
54
+ # Returns true if RSpec is configured to allow interactivity.
55
+ # By default, interactivity is enabled unless the environment
56
+ # variable `CI` is set.
28
57
  def interactive?
29
58
  RSpec.configuration.interactive_fixtures
30
59
  end
31
60
 
61
+ # Returns the path to the fixtures directory.
62
+ # Default: `spec/fixtures`
32
63
  def fixtures_dir
33
64
  RSpec.configuration.fixtures_path
34
65
  end
35
66
 
67
+ # Returns the path to the fixture file
36
68
  def fixture_file
37
69
  "#{fixtures_dir}/#{fixture_name}"
38
70
  end
39
71
 
40
72
  protected
41
73
 
74
+ # Asks for user approval. Used by child classes.
42
75
  def approve_fixture
43
76
  approval_handler = ApprovalHandler.new
44
77
  approval_handler.run expected, actual, fixture_file
45
78
  end
46
79
 
80
+ # Returns the actual fixture file content.
47
81
  def expected!
48
82
  File.exist?(fixture_file) ? File.read(fixture_file) : ''
49
83
  end
84
+
85
+ # Do the actual test. If .diff() was used, then distance will be
86
+ # set and then we "levenshtein it". Otherwise, compare with ==
87
+ def strings_match?
88
+ if distance
89
+ @actual_distance = String::Similarity.levenshtein_distance expected, actual
90
+ @actual_distance <= distance
91
+ else
92
+ actual == expected
93
+ end
94
+ end
95
+
50
96
  end
51
97
 
52
98
  end
@@ -1,18 +1,14 @@
1
+ require 'string-similarity'
2
+
1
3
  module RSpecFixtures
2
4
  module Matchers
5
+ # Adds the matcher to RSpec:
6
+ # `expect(string).to match_fixture(file)`
3
7
  def match_fixture(expected)
4
8
  MatchFixture.new expected
5
9
  end
6
10
 
7
11
  class MatchFixture < Base
8
- def matches?(actual)
9
- @actual = actual
10
- if actual == expected or !interactive?
11
- actual == expected
12
- else
13
- approve_fixture
14
- end
15
- end
16
12
  end
17
13
 
18
14
  end
@@ -1,30 +1,34 @@
1
1
  module RSpecFixtures
2
2
  module Matchers
3
+ # Adds the matcher to RSpec:
4
+ # `expect{ stream }.to output_fixture(file)`
3
5
  def output_fixture(expected)
4
6
  OutputFixture.new expected
5
7
  end
6
8
 
7
9
  class OutputFixture < Base
10
+ # Called by RSpec
8
11
  def matches?(block)
9
12
  return false unless block.is_a? Proc
10
13
  @actual = stream_capturer.capture block
11
-
12
- if actual == expected or !interactive?
13
- actual == expected
14
- else
15
- approve_fixture
16
- end
14
+ super
17
15
  end
18
16
 
17
+ # Lets RSpec know that this matcher requires a block.
19
18
  def supports_block_expectations?
20
19
  true
21
20
  end
22
21
 
22
+ # Adds chained matcher, to allow:
23
+ # expect{ stream }.to output_fixture(file).to_stdout
24
+ # This is the default, and only provided for completeness.
23
25
  def to_stdout
24
26
  @stream_capturer = CaptureStdout
25
27
  self
26
28
  end
27
29
 
30
+ # Adds chained matcher, to allow:
31
+ # expect{ stream }.to output_fixture(file).to_stderr
28
32
  def to_stderr
29
33
  @stream_capturer = CaptureStderr
30
34
  self
@@ -1,3 +1,4 @@
1
+ # Add our custom matchers and configuration options to RSpec
1
2
  if defined? RSpec
2
3
  RSpec.configure do |config|
3
4
  config.include RSpecFixtures::Matchers
@@ -1,4 +1,6 @@
1
1
  module RSpecFixtures
2
+ # Capture stdout and stderr
3
+ #
2
4
  # These methods are borrowed from rspec's built in matchers
3
5
  # https://github.com/rspec/rspec-expectations/blob/add9b271ecb1d65f7da5bc8a9dd8c64d81d92303/lib/rspec/matchers/built_in/output.rb
4
6
  module CaptureStdout
@@ -1,3 +1,3 @@
1
1
  module RSpecFixtures
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec_fixtures
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danny Ben Shitrit
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-08 00:00:00.000000000 Z
11
+ date: 2018-02-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colsole
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0.9'
111
+ - !ruby/object:Gem::Dependency
112
+ name: string-similarity
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '2.0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '2.0'
111
125
  description: Automatic interactive fixtures for rspec
112
126
  email: db@dannyben.com
113
127
  executables: []