saharspec 0.0.4 → 0.0.5
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/LICENSE.txt +1 -1
- data/README.md +24 -2
- data/lib/saharspec/its.rb +23 -3
- data/lib/saharspec/its/map.rb +3 -3
- data/lib/saharspec/matchers.rb +7 -4
- data/lib/saharspec/matchers/be_json.rb +99 -0
- data/lib/saharspec/matchers/ret.rb +9 -2
- data/lib/saharspec/matchers/send_message.rb +3 -3
- data/lib/saharspec/version.rb +1 -4
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 627f1f82b546e7a3e096497b74f25cab346d0fa2
|
|
4
|
+
data.tar.gz: d7efe0bcc330cdd47d426fb502b5114fbffa85e6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e2249769358166c5b72bee55ca94b9b0ed698715afc71e439e7687fba8f745b63641312e4cb7d52340c3e4f6a805458c0f7e0b7be9b23e4eeccb90487d6699a2
|
|
7
|
+
data.tar.gz: 945e11582fd5c21b7cb7fd8b0d7f1021611d546bb957446df2f8b1c7b2d5c1b060e19dfd80956b5dec8a0d6a4949cda0981e216d1093d9084d44e005cf25dd49
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
|
@@ -9,7 +9,8 @@ specs dry as a desert.
|
|
|
9
9
|
|
|
10
10
|
## Usage
|
|
11
11
|
|
|
12
|
-
Install it as a usual gem `saharspec
|
|
12
|
+
Install it as a usual gem `saharspec` with `gem install` or `gem "saharspec"` in `:test` group of
|
|
13
|
+
your `Gemfile`.
|
|
13
14
|
|
|
14
15
|
Then, probably in your `spec_helper.rb`
|
|
15
16
|
|
|
@@ -102,6 +103,27 @@ end
|
|
|
102
103
|
|
|
103
104
|
Plays really well with `its_call` shown below.
|
|
104
105
|
|
|
106
|
+
#### `be_json(value)` and `be_json_sym(value)` matchers
|
|
107
|
+
|
|
108
|
+
Simple matcher to check if string is valid JSON and optionally if it matches to expected values:
|
|
109
|
+
|
|
110
|
+
```ruby
|
|
111
|
+
expect('{}').to be_json # ok
|
|
112
|
+
expect('garbage').to be_json
|
|
113
|
+
# expected value to be a valid JSON string but failed: 765: unexpected token at 'garbage'
|
|
114
|
+
|
|
115
|
+
expect('{"foo": "bar"}').to be_json('foo' => 'bar') # ok
|
|
116
|
+
|
|
117
|
+
# be_json_sym is more convenient to check with hash keys, parses JSON to symbols
|
|
118
|
+
expect('{"foo": "bar"}').to be_json_sym(foo: 'bar')
|
|
119
|
+
|
|
120
|
+
# nested matchers work, too
|
|
121
|
+
expect('{"foo": [1, 2, 3]').to be_json_sym(foo: array_including(3))
|
|
122
|
+
|
|
123
|
+
# We need to go deeper!
|
|
124
|
+
expect(something_large).to be_json_sym(include(meta: include(next_page: Integer)))
|
|
125
|
+
```
|
|
126
|
+
|
|
105
127
|
#### `eq_multiline(text)` matcher
|
|
106
128
|
|
|
107
129
|
Dedicated to checking some multiline text generators.
|
|
@@ -241,4 +263,4 @@ checking them). Stay tuned.
|
|
|
241
263
|
|
|
242
264
|
## License
|
|
243
265
|
|
|
244
|
-
[MIT](https://github.com/zverok/
|
|
266
|
+
[MIT](https://github.com/zverok/saharspec/blob/master/LICENSE.txt).
|
data/lib/saharspec/its.rb
CHANGED
|
@@ -3,9 +3,29 @@ module Saharspec
|
|
|
3
3
|
#
|
|
4
4
|
# See:
|
|
5
5
|
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
6
|
+
# ## {Map#its_map #its_map}
|
|
7
|
+
#
|
|
8
|
+
# ```ruby
|
|
9
|
+
# subject { %w[1 2 3] }
|
|
10
|
+
# its_map(:to_s) { is_expected.to eq [1, 2, 3] }
|
|
11
|
+
# ```
|
|
12
|
+
#
|
|
13
|
+
# ## {Call#its_call #its_call}
|
|
14
|
+
#
|
|
15
|
+
# ```ruby
|
|
16
|
+
# subject { [1, 2, 3].method(:[]) }
|
|
17
|
+
# its_call(2) { is_expected.to ret 3 }
|
|
18
|
+
# its_call('foo') { is_expected.to raise_error }
|
|
19
|
+
# ```
|
|
20
|
+
#
|
|
21
|
+
# ## {Block#its_block #its_block}
|
|
22
|
+
#
|
|
23
|
+
# ```ruby
|
|
24
|
+
# subject { something_action }
|
|
25
|
+
# its_block { is_expected.not_to raise_error }
|
|
26
|
+
# its_block { is_expected.to change(some, :value).by(1) }
|
|
27
|
+
# ```
|
|
28
|
+
#
|
|
9
29
|
module Its
|
|
10
30
|
end
|
|
11
31
|
end
|
data/lib/saharspec/its/map.rb
CHANGED
|
@@ -11,7 +11,7 @@ module Saharspec
|
|
|
11
11
|
# its_map(:length) { is_expected.to eq [4, 2, 6] }
|
|
12
12
|
#
|
|
13
13
|
# # with attribute chain
|
|
14
|
-
# its_map(
|
|
14
|
+
# its_map('reverse.upcase') { is_expected.to eq %w[TSET EM ESAELP] }
|
|
15
15
|
#
|
|
16
16
|
# # with Hash (or any other object responding to `#[]`)
|
|
17
17
|
# subject {
|
|
@@ -35,8 +35,8 @@ module Saharspec
|
|
|
35
35
|
# TODO: better desciption for different cases
|
|
36
36
|
describe("map(&:#{attribute})") do
|
|
37
37
|
let(:__its_map_subject) do
|
|
38
|
-
if Array === attribute
|
|
39
|
-
if subject.all? { |s| Hash === s }
|
|
38
|
+
if Array === attribute
|
|
39
|
+
if subject.all? { |s| Hash === s }
|
|
40
40
|
subject.map do |s|
|
|
41
41
|
attribute.inject(s) { |inner, attr| inner[attr] }
|
|
42
42
|
end
|
data/lib/saharspec/matchers.rb
CHANGED
|
@@ -3,10 +3,11 @@ module Saharspec
|
|
|
3
3
|
#
|
|
4
4
|
# See:
|
|
5
5
|
#
|
|
6
|
-
# * {RSpec::Matchers#dont #dont}
|
|
7
|
-
# * {RSpec::Matchers#send_message #send_message}
|
|
8
|
-
# * {RSpec::Matchers#
|
|
9
|
-
# * {RSpec::Matchers#
|
|
6
|
+
# * {RSpec::Matchers#dont #dont}: `expect { block }.to change(this).and dont.change(that)`
|
|
7
|
+
# * {RSpec::Matchers#send_message #send_message}: `expect { block }.to send_message(File, :write)`
|
|
8
|
+
# * {RSpec::Matchers#ret #ret}: `expect { block }.to ret value`
|
|
9
|
+
# * {RSpec::Matchers#be_json #be_json}: `expect(response.body).to be_json('foo' => 'bar')`
|
|
10
|
+
# * {RSpec::Matchers#eq_multiline #eq_multiline}: multiline equality akin to squiggly heredoc
|
|
10
11
|
#
|
|
11
12
|
module Matchers
|
|
12
13
|
end
|
|
@@ -15,3 +16,5 @@ end
|
|
|
15
16
|
require_relative 'matchers/eq_multiline'
|
|
16
17
|
require_relative 'matchers/send_message'
|
|
17
18
|
require_relative 'matchers/ret'
|
|
19
|
+
require_relative 'matchers/dont'
|
|
20
|
+
require_relative 'matchers/be_json'
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
module Saharspec
|
|
4
|
+
module Matchers
|
|
5
|
+
# @private
|
|
6
|
+
class BeJson
|
|
7
|
+
NONE = Object.new.freeze
|
|
8
|
+
include RSpec::Matchers::Composable
|
|
9
|
+
include RSpec::Matchers # to have #match
|
|
10
|
+
|
|
11
|
+
attr_reader :actual, :expected
|
|
12
|
+
|
|
13
|
+
def initialize(expected, **parse_opts)
|
|
14
|
+
@expected_matcher = @expected = expected
|
|
15
|
+
# wrap to make be_json('foo' => matcher) work, too
|
|
16
|
+
@expected_matcher = match(expected) unless expected == NONE || expected.respond_to?(:matches?)
|
|
17
|
+
@parse_opts = parse_opts
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def matches?(json)
|
|
21
|
+
@actual = JSON.parse(json, **@parse_opts)
|
|
22
|
+
@expected_matcher == NONE || @expected_matcher === @actual
|
|
23
|
+
rescue JSON::ParserError => parse_error
|
|
24
|
+
@parser_error = parse_error
|
|
25
|
+
false
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def does_not_match?(*args)
|
|
29
|
+
!matches?(*args)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def diffable?
|
|
33
|
+
true
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def description
|
|
37
|
+
if @expected == NONE
|
|
38
|
+
'be a valid JSON string'
|
|
39
|
+
else
|
|
40
|
+
expected = @expected.respond_to?(:description) ? @expected.description : @expected
|
|
41
|
+
"be a valid JSON matching (#{expected})"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def failure_message
|
|
46
|
+
failed =
|
|
47
|
+
case
|
|
48
|
+
when @parser_error
|
|
49
|
+
"failed: #{@parser_error}"
|
|
50
|
+
when @expected != NONE
|
|
51
|
+
"was #{@actual}"
|
|
52
|
+
end
|
|
53
|
+
"expected value to #{description} but #{failed}"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def failure_message_when_negated
|
|
57
|
+
'expected value not to be parsed as JSON, but succeeded'
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
module RSpec
|
|
64
|
+
module Matchers
|
|
65
|
+
# `be_json` checks if provided value is JSON, and optionally checks it contents.
|
|
66
|
+
#
|
|
67
|
+
# If you need to check against some hashes, it is more convenient to use `be_json_sym`, which
|
|
68
|
+
# parses JSON with `symbolize_names: true`.
|
|
69
|
+
#
|
|
70
|
+
# @example
|
|
71
|
+
#
|
|
72
|
+
# expect('{}').to be_json # ok
|
|
73
|
+
# expect('garbage').to be_json
|
|
74
|
+
# # expected value to be a valid JSON string but failed: 765: unexpected token at 'garbage'
|
|
75
|
+
#
|
|
76
|
+
# expect('{"foo": "bar"}').to be_json('foo' => 'bar') # ok
|
|
77
|
+
# expect('{"foo": "bar"}').to be_json_sym(foo: 'bar') # more convenient
|
|
78
|
+
#
|
|
79
|
+
# expect('{"foo": [1, 2, 3]').to be_json_sym(foo: array_including(3)) # nested matchers work
|
|
80
|
+
# expect(something_large).to be_json_sym(include(meta: include(next_page: Integer)))
|
|
81
|
+
#
|
|
82
|
+
# @param expected Value or matcher to check JSON against. It should implement `#===` method,
|
|
83
|
+
# so all standard and custom RSpec matchers work.
|
|
84
|
+
def be_json(expected = Saharspec::Matchers::BeJson::NONE)
|
|
85
|
+
Saharspec::Matchers::BeJson.new(expected)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# `be_json_sym` checks if value is a valid JSON and parses it with `symbolize_names: true`. This
|
|
89
|
+
# way, it is convenient to check hashes content with Ruby's short symbolic keys syntax.
|
|
90
|
+
#
|
|
91
|
+
# See {#be_json_sym} for examples.
|
|
92
|
+
#
|
|
93
|
+
# @param expected Value or matcher to check JSON against. It should implement `#===` method,
|
|
94
|
+
# so all standard and custom RSpec matchers work.
|
|
95
|
+
def be_json_sym(expected = Saharspec::Matchers::BeJson::NONE)
|
|
96
|
+
Saharspec::Matchers::BeJson.new(expected, symbolize_names: true)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -4,6 +4,8 @@ module Saharspec
|
|
|
4
4
|
class Ret
|
|
5
5
|
include RSpec::Matchers::Composable
|
|
6
6
|
|
|
7
|
+
attr_reader :actual, :expected
|
|
8
|
+
|
|
7
9
|
def initialize(expected)
|
|
8
10
|
@expected = expected
|
|
9
11
|
end
|
|
@@ -12,13 +14,17 @@ module Saharspec
|
|
|
12
14
|
@subject = subject
|
|
13
15
|
return false unless subject.respond_to?(:call)
|
|
14
16
|
@actual = subject.call
|
|
15
|
-
@expected === @actual
|
|
17
|
+
@expected === @actual
|
|
16
18
|
end
|
|
17
19
|
|
|
18
20
|
def supports_block_expectations?
|
|
19
21
|
true
|
|
20
22
|
end
|
|
21
23
|
|
|
24
|
+
def diffable?
|
|
25
|
+
true
|
|
26
|
+
end
|
|
27
|
+
|
|
22
28
|
def description
|
|
23
29
|
"return #{@expected.respond_to?(:description) ? @expected.description : @expected.inspect}"
|
|
24
30
|
end
|
|
@@ -42,7 +48,8 @@ module RSpec
|
|
|
42
48
|
# It should be considered instead of simple value matchers (like `eq`) in the situations:
|
|
43
49
|
#
|
|
44
50
|
# 1. Several block behaviors tested in the same test, joined with `.and`, or in separate tests
|
|
45
|
-
# 2. You test what some block or method returns with arguments, using
|
|
51
|
+
# 2. You test what some block or method returns with arguments, using
|
|
52
|
+
# {Saharspec::Its::Call#its_call #its_call}
|
|
46
53
|
#
|
|
47
54
|
# Values are tested with `===`, which allows chaining other matchers and patterns to the check.
|
|
48
55
|
#
|
|
@@ -16,8 +16,8 @@ module Saharspec
|
|
|
16
16
|
self
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
def returning(res)
|
|
20
|
-
@res = res
|
|
19
|
+
def returning(*res)
|
|
20
|
+
@res = [*res]
|
|
21
21
|
self
|
|
22
22
|
end
|
|
23
23
|
|
|
@@ -91,7 +91,7 @@ module Saharspec
|
|
|
91
91
|
|
|
92
92
|
def allower
|
|
93
93
|
receive(@method).tap do |a|
|
|
94
|
-
a.and_return(
|
|
94
|
+
a.and_return(*@res) if @res
|
|
95
95
|
a.and_call_original if @call_original
|
|
96
96
|
end
|
|
97
97
|
end
|
data/lib/saharspec/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: saharspec
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Victor Shepelev
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2018-03-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rubocop
|
|
@@ -125,6 +125,7 @@ files:
|
|
|
125
125
|
- lib/saharspec/its/call.rb
|
|
126
126
|
- lib/saharspec/its/map.rb
|
|
127
127
|
- lib/saharspec/matchers.rb
|
|
128
|
+
- lib/saharspec/matchers/be_json.rb
|
|
128
129
|
- lib/saharspec/matchers/dont.rb
|
|
129
130
|
- lib/saharspec/matchers/eq_multiline.rb
|
|
130
131
|
- lib/saharspec/matchers/request_webmock.rb
|
|
@@ -153,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
153
154
|
version: '0'
|
|
154
155
|
requirements: []
|
|
155
156
|
rubyforge_project:
|
|
156
|
-
rubygems_version: 2.6.
|
|
157
|
+
rubygems_version: 2.6.14
|
|
157
158
|
signing_key:
|
|
158
159
|
specification_version: 4
|
|
159
160
|
summary: Several additions for DRYer RSpec code
|