test_assistant 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +2 -0
- data/Guardfile +29 -0
- data/README.md +40 -1
- data/lib/test_assistant/json/expectation.rb +48 -9
- data/lib/test_assistant/version.rb +1 -1
- data/spec/eql_json_spec.rb +256 -0
- data/spec/spec_helper.rb +4 -0
- data/test_assistant.gemspec +5 -2
- metadata +53 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49e305f2819ade85d5d24f684b4793021fc5b9a4
|
4
|
+
data.tar.gz: d665d5ac5bb5ac475e76c897fbb755cef7bb2a3d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 398f6cfb2cde42b5d13b1f1daf392986400258bfa1e64e7e3c73b0215078fd9adfe458c3085d2e345d796ef15e3aa798e2162dd6ed082b2261ae148b3f7cc1f1
|
7
|
+
data.tar.gz: b571f52714417646144182f5051a88346d8b46b52538f68ecd478cc850e4494dc4453b5c7d4b6c5b4e50c4d499f20a627e7e608d8a128aed3e570a836b527d56
|
data/.rspec
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
2
|
+
require "guard/rspec/dsl"
|
3
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
4
|
+
|
5
|
+
last_run_spec = nil
|
6
|
+
|
7
|
+
watch(%r{^lib/(.+)\.rb$}) do |match|
|
8
|
+
file_path =
|
9
|
+
if match[1] === 'lib'
|
10
|
+
"spec/lib/#{match[2]}_spec.rb"
|
11
|
+
else
|
12
|
+
"spec/#{match[2]}_spec.rb"
|
13
|
+
end
|
14
|
+
|
15
|
+
if File.exists?(file_path)
|
16
|
+
file_path
|
17
|
+
else
|
18
|
+
last_run_spec
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# RSpec files
|
23
|
+
rspec = dsl.rspec
|
24
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
25
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
26
|
+
watch(rspec.spec_files) do |spec|
|
27
|
+
last_run_spec = spec[0]
|
28
|
+
end
|
29
|
+
end
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# TestAssistant
|
2
2
|
|
3
|
-
A collection of testing tools
|
3
|
+
A collection of testing tools and utilities for writing and fixing tests faster
|
4
4
|
|
5
5
|
## Stability
|
6
6
|
|
@@ -84,6 +84,45 @@ RSpec.describe 'making some valid request', type: :request do
|
|
84
84
|
end
|
85
85
|
```
|
86
86
|
|
87
|
+
## JSON expectations
|
88
|
+
|
89
|
+
RSpec's failed equality reports are often extremely difficult to interpret when dealing with complicated JSON objects. A minor difference, deeply nested in arrays and objects can take a long time to locate because RSpec dumps the entire object in the failure message.
|
90
|
+
|
91
|
+
|
92
|
+
When enabled, Test Assistant provides a method `json_response` that automatically parses the last response object as json and a custom assertion `eql_json` that reports failed equality of complicated json objects in a format that is much clearer. The full `expected` and `actual` values are still reported, but below them Test Assistant prints only the paths to the failed nested values and their differences, removing the need to manually compare the two complete objects to find what is different.
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
TestAssistant.configure(config) do |ta_config|
|
96
|
+
ta_config.include_json_helpers type: :request
|
97
|
+
end
|
98
|
+
```
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
RSpec.describe 'making some valid request', type: :request do
|
102
|
+
context 'some important context' do
|
103
|
+
it 'should return some complicated JSON' do
|
104
|
+
|
105
|
+
perform_request
|
106
|
+
|
107
|
+
expect(json_response).to eql_json([
|
108
|
+
{
|
109
|
+
"a" => [
|
110
|
+
1, 2, 3
|
111
|
+
],
|
112
|
+
"c" => { "d" => "d'"}
|
113
|
+
},
|
114
|
+
{
|
115
|
+
"b" => [
|
116
|
+
1, 2, 3
|
117
|
+
],
|
118
|
+
"c" => { "d" => "d'"}
|
119
|
+
}
|
120
|
+
])
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
```
|
125
|
+
|
87
126
|
## Email expectations
|
88
127
|
|
89
128
|
|
@@ -12,15 +12,17 @@ module TestAssistant::Json
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def matches?(actual)
|
15
|
+
@message = ''
|
16
|
+
@reported_differences = {}
|
17
|
+
|
15
18
|
@actual = actual
|
16
19
|
@expected.eql?(@actual)
|
17
20
|
end
|
18
21
|
|
19
22
|
def failure_message
|
20
|
-
message
|
21
|
-
message += "
|
22
|
-
message += "
|
23
|
-
message += "Differences\n\n"
|
23
|
+
@message += "Expected: #{@expected}\n\n"
|
24
|
+
@message += "Actual: #{@actual}\n\n"
|
25
|
+
@message += "Differences\n\n"
|
24
26
|
|
25
27
|
differences = HashDiff.diff(@actual, @expected)
|
26
28
|
|
@@ -31,29 +33,66 @@ module TestAssistant::Json
|
|
31
33
|
when '-'
|
32
34
|
attribute, value = operands
|
33
35
|
|
34
|
-
|
36
|
+
expected_value = attribute_value(@expected, attribute)
|
37
|
+
add_diff_description(attribute, format_diff(attribute, expected_value, value))
|
38
|
+
|
35
39
|
when '+'
|
36
40
|
attribute, value = operands
|
37
41
|
|
38
|
-
|
42
|
+
actual_value = attribute_value(@actual, attribute)
|
43
|
+
|
44
|
+
add_diff_description(attribute, format_diff(attribute, value, actual_value))
|
45
|
+
|
39
46
|
else
|
40
47
|
attribute, actual_value, expected_value = operands
|
41
48
|
|
42
|
-
|
49
|
+
add_diff_description(attribute, format_diff(attribute, expected_value, actual_value))
|
43
50
|
end
|
44
51
|
end
|
45
52
|
|
46
|
-
message
|
53
|
+
@message
|
47
54
|
end
|
48
55
|
|
49
56
|
private
|
50
57
|
|
58
|
+
def add_diff_description(attribute, difference_description)
|
59
|
+
unless already_reported_difference?(attribute)
|
60
|
+
@message += difference_description
|
61
|
+
@reported_differences[attribute] = true
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def already_reported_difference?(attribute)
|
66
|
+
!!@reported_differences[attribute]
|
67
|
+
end
|
68
|
+
|
69
|
+
def attribute_value(target, attribute_path)
|
70
|
+
keys = attribute_path.split(/\[|\]|\./)
|
71
|
+
|
72
|
+
keys = keys.map do |key|
|
73
|
+
if key.to_i == 0 && key != '0'
|
74
|
+
key
|
75
|
+
else
|
76
|
+
key.to_i
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
result = target
|
81
|
+
|
82
|
+
keys.each do |key|
|
83
|
+
unless key == ''
|
84
|
+
result = result[key]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
result
|
89
|
+
end
|
90
|
+
|
51
91
|
def format_diff(attribute, expected, actual)
|
52
92
|
diff_description = ''
|
53
93
|
diff_description += "#{attribute}\n"
|
54
94
|
diff_description += "Expected: #{format_value(expected)}\n"
|
55
95
|
diff_description += "Actual: #{format_value(actual)}\n\n"
|
56
|
-
diff_description
|
57
96
|
end
|
58
97
|
|
59
98
|
def format_value(value)
|
@@ -0,0 +1,256 @@
|
|
1
|
+
require './lib/test_assistant/json/helpers'
|
2
|
+
|
3
|
+
RSpec.describe "eql_json" do
|
4
|
+
include TestAssistant::Json::Helpers
|
5
|
+
|
6
|
+
context "when comparing strings" do
|
7
|
+
let(:expected) { 'a' }
|
8
|
+
let(:actual) { 'b' }
|
9
|
+
|
10
|
+
it "then correctly reports any differences" do
|
11
|
+
|
12
|
+
expect(actual).to eql_json(actual)
|
13
|
+
|
14
|
+
expect(actual).to_not eql(expected)
|
15
|
+
|
16
|
+
expect {
|
17
|
+
expect(actual).to eql_json(expected)
|
18
|
+
}.to raise_error.with_message(error_message(expected, actual, {
|
19
|
+
'' => {
|
20
|
+
expected: "'#{expected}'",
|
21
|
+
actual: "'#{actual}'"
|
22
|
+
}
|
23
|
+
}))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "when comparing integers" do
|
28
|
+
let(:expected) { 2 }
|
29
|
+
let(:actual) { 1 }
|
30
|
+
|
31
|
+
it "then correctly reports any differences" do
|
32
|
+
|
33
|
+
expect(actual).to eql_json(actual)
|
34
|
+
|
35
|
+
expect(actual).to_not eql(expected)
|
36
|
+
|
37
|
+
expect {
|
38
|
+
expect(actual).to eql_json(expected)
|
39
|
+
}.to raise_error.with_message(error_message(expected, actual, {
|
40
|
+
'' => {
|
41
|
+
expected: expected,
|
42
|
+
actual: actual
|
43
|
+
}
|
44
|
+
}))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "when comparing nil" do
|
49
|
+
let(:expected) { 2 }
|
50
|
+
let(:actual) { nil }
|
51
|
+
|
52
|
+
it "then correctly reports any differences" do
|
53
|
+
expect(actual).to eql_json(actual)
|
54
|
+
|
55
|
+
expect(actual).to_not eql(expected)
|
56
|
+
|
57
|
+
expect {
|
58
|
+
expect(actual).to eql_json(expected)
|
59
|
+
}.to raise_error.with_message(error_message(expected, actual, {
|
60
|
+
'' => {
|
61
|
+
expected: expected,
|
62
|
+
actual: actual
|
63
|
+
}
|
64
|
+
}))
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when comparing arrays" do
|
71
|
+
let(:expected) { [ 1, 3, 4, 5 ] }
|
72
|
+
let(:actual) { [ 1, 2, 3 ] }
|
73
|
+
|
74
|
+
it "then correctly reports the elements that have changed" do
|
75
|
+
|
76
|
+
expect(actual).to eql(actual)
|
77
|
+
|
78
|
+
expect(actual).to_not eql(expected)
|
79
|
+
|
80
|
+
begin
|
81
|
+
expect(actual).to eql_json(expected)
|
82
|
+
rescue RSpec::Expectations::ExpectationNotMetError => e
|
83
|
+
|
84
|
+
expect(e.message).to eql(error_message(expected, actual, {
|
85
|
+
|
86
|
+
'[1]' => {
|
87
|
+
expected: 3,
|
88
|
+
actual: 2
|
89
|
+
},
|
90
|
+
'[2]' => {
|
91
|
+
expected: 4,
|
92
|
+
actual: 3
|
93
|
+
},
|
94
|
+
'[3]' => {
|
95
|
+
expected: 5,
|
96
|
+
actual: ''
|
97
|
+
}
|
98
|
+
|
99
|
+
}))
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
context "when comparing objects" do
|
108
|
+
let(:expected) { {
|
109
|
+
'a' => 'a',
|
110
|
+
'c' => 'd',
|
111
|
+
'e' => 'e'
|
112
|
+
} }
|
113
|
+
|
114
|
+
let(:actual) { {
|
115
|
+
'a' => 'a',
|
116
|
+
'b' => 'b',
|
117
|
+
'c' => 'c'
|
118
|
+
} }
|
119
|
+
|
120
|
+
it "then correctly reports the elements that have changed" do
|
121
|
+
|
122
|
+
expect(actual).to eql(actual)
|
123
|
+
|
124
|
+
expect(actual).to_not eql(expected)
|
125
|
+
|
126
|
+
begin
|
127
|
+
expect(actual).to eql_json(expected)
|
128
|
+
rescue RSpec::Expectations::ExpectationNotMetError => e
|
129
|
+
|
130
|
+
expect(e.message).to eql(error_message(expected, actual, {
|
131
|
+
|
132
|
+
'b' => {
|
133
|
+
expected: '',
|
134
|
+
actual: "'b'"
|
135
|
+
},
|
136
|
+
'c' => {
|
137
|
+
expected: "'d'",
|
138
|
+
actual: "'c'"
|
139
|
+
},
|
140
|
+
'e' => {
|
141
|
+
expected: "'e'",
|
142
|
+
actual: ''
|
143
|
+
}
|
144
|
+
|
145
|
+
}))
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
context "when comparing nested objects" do
|
154
|
+
let(:actual) { {
|
155
|
+
'a' => 'a',
|
156
|
+
'b' => {
|
157
|
+
'b' => 'b'
|
158
|
+
},
|
159
|
+
'c' => {
|
160
|
+
'd' => 'd',
|
161
|
+
'e' => 'e',
|
162
|
+
'f' => {
|
163
|
+
'g' => 'g'
|
164
|
+
},
|
165
|
+
'h' => [1,2,3]
|
166
|
+
},
|
167
|
+
'i' => {
|
168
|
+
'j' => 'j',
|
169
|
+
'k' => 'k'
|
170
|
+
}
|
171
|
+
} }
|
172
|
+
|
173
|
+
let(:expected ) { {
|
174
|
+
'a' => 'a',
|
175
|
+
'c' => {
|
176
|
+
'e' => 'e2',
|
177
|
+
'f' => {
|
178
|
+
'g2' => 'g2'
|
179
|
+
},
|
180
|
+
'h' => [1,2,4]
|
181
|
+
},
|
182
|
+
'i' => {
|
183
|
+
'j' => 'j',
|
184
|
+
}
|
185
|
+
} }
|
186
|
+
|
187
|
+
it "then correctly reports the elements that have changed" do
|
188
|
+
|
189
|
+
expect(actual).to eql(actual)
|
190
|
+
|
191
|
+
expect(actual).to_not eql(expected)
|
192
|
+
|
193
|
+
begin
|
194
|
+
expect(actual).to eql_json(expected)
|
195
|
+
rescue RSpec::Expectations::ExpectationNotMetError => e
|
196
|
+
|
197
|
+
expect(e.message).to eql(error_message(expected, actual, {
|
198
|
+
|
199
|
+
'b' => {
|
200
|
+
expected: '',
|
201
|
+
actual: '{"b"=>"b"}'
|
202
|
+
},
|
203
|
+
'c.d' => {
|
204
|
+
expected: '',
|
205
|
+
actual: "'d'"
|
206
|
+
},
|
207
|
+
'c.e' => {
|
208
|
+
expected: "'e2'",
|
209
|
+
actual: "'e'"
|
210
|
+
},
|
211
|
+
'c.f.g' => {
|
212
|
+
expected: '',
|
213
|
+
actual: "'g'"
|
214
|
+
},
|
215
|
+
'c.f.g2' => {
|
216
|
+
expected: "'g2'",
|
217
|
+
actual: ''
|
218
|
+
},
|
219
|
+
'c.h[2]' => {
|
220
|
+
expected: '4',
|
221
|
+
actual: '3'
|
222
|
+
},
|
223
|
+
'i.k' => {
|
224
|
+
expected: '',
|
225
|
+
actual: "'k'"
|
226
|
+
},
|
227
|
+
|
228
|
+
|
229
|
+
}))
|
230
|
+
|
231
|
+
end
|
232
|
+
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|
236
|
+
|
237
|
+
|
238
|
+
private
|
239
|
+
|
240
|
+
def error_message(expected, actual, differences)
|
241
|
+
message_lines = [
|
242
|
+
"Expected: #{expected}\n\n",
|
243
|
+
"Actual: #{actual}\n\n",
|
244
|
+
"Differences\n\n"
|
245
|
+
]
|
246
|
+
|
247
|
+
differences.each do |attribute_name, difference|
|
248
|
+
message_lines.push("#{attribute_name}\n")
|
249
|
+
message_lines.push("Expected: #{difference[:expected]}\n")
|
250
|
+
message_lines.push("Actual: #{difference[:actual]}\n\n")
|
251
|
+
end
|
252
|
+
|
253
|
+
|
254
|
+
message_lines.join
|
255
|
+
end
|
256
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/test_assistant.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Aleck Greenham"]
|
10
10
|
spec.email = ["greenhama13@gmail.com"]
|
11
11
|
spec.summary = "A toolbox for increased testing efficiency with RSpec"
|
12
|
-
spec.description = "A collection of testing tools
|
12
|
+
spec.description = "A collection of testing tools and utilities for writing and fixing tests faster"
|
13
13
|
spec.homepage = "https://github.com/greena13/test_assistant"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
@@ -18,9 +18,12 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency "rspec-rails", "~> 3.0"
|
22
21
|
spec.add_dependency 'capybara', '~> 2.5', '>= 2.5.0'
|
23
22
|
spec.add_dependency 'hashdiff', '~> 0'
|
23
|
+
|
24
24
|
spec.add_development_dependency "bundler", "~> 1.6"
|
25
25
|
spec.add_development_dependency "rake", "~> 0"
|
26
|
+
spec.add_development_dependency "guard", "~> 2.1"
|
27
|
+
spec.add_development_dependency "rspec", ">= 3.5.0"
|
28
|
+
spec.add_development_dependency "guard-rspec", "~> 4.7"
|
26
29
|
end
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: test_assistant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aleck Greenham
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: rspec-rails
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '3.0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '3.0'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: capybara
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,8 +72,50 @@ dependencies:
|
|
86
72
|
- - "~>"
|
87
73
|
- !ruby/object:Gem::Version
|
88
74
|
version: '0'
|
89
|
-
|
90
|
-
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: guard
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '2.1'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '2.1'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: rspec
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: 3.5.0
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 3.5.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: '4.7'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - "~>"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '4.7'
|
117
|
+
description: A collection of testing tools and utilities for writing and fixing tests
|
118
|
+
faster
|
91
119
|
email:
|
92
120
|
- greenhama13@gmail.com
|
93
121
|
executables: []
|
@@ -95,7 +123,9 @@ extensions: []
|
|
95
123
|
extra_rdoc_files: []
|
96
124
|
files:
|
97
125
|
- ".gitignore"
|
126
|
+
- ".rspec"
|
98
127
|
- Gemfile
|
128
|
+
- Guardfile
|
99
129
|
- LICENSE.txt
|
100
130
|
- README.md
|
101
131
|
- Rakefile
|
@@ -107,6 +137,8 @@ files:
|
|
107
137
|
- lib/test_assistant/json/expectation.rb
|
108
138
|
- lib/test_assistant/json/helpers.rb
|
109
139
|
- lib/test_assistant/version.rb
|
140
|
+
- spec/eql_json_spec.rb
|
141
|
+
- spec/spec_helper.rb
|
110
142
|
- test_assistant.gemspec
|
111
143
|
homepage: https://github.com/greena13/test_assistant
|
112
144
|
licenses:
|
@@ -132,4 +164,6 @@ rubygems_version: 2.2.2
|
|
132
164
|
signing_key:
|
133
165
|
specification_version: 4
|
134
166
|
summary: A toolbox for increased testing efficiency with RSpec
|
135
|
-
test_files:
|
167
|
+
test_files:
|
168
|
+
- spec/eql_json_spec.rb
|
169
|
+
- spec/spec_helper.rb
|