dry-matcher 0.7.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +170 -67
- data/LICENSE +20 -0
- data/README.md +20 -14
- data/dry-matcher.gemspec +34 -0
- data/lib/dry-matcher.rb +2 -0
- data/lib/dry/matcher.rb +18 -1
- data/lib/dry/matcher/case.rb +21 -21
- data/lib/dry/matcher/either_matcher.rb +8 -1
- data/lib/dry/matcher/evaluator.rb +12 -18
- data/lib/dry/matcher/result_matcher.rb +52 -22
- data/lib/dry/matcher/version.rb +3 -1
- metadata +23 -61
- data/Gemfile +0 -14
- data/LICENSE.md +0 -9
- data/Rakefile +0 -10
- data/spec/examples.txt +0 -18
- data/spec/integration/class_enhancement_spec.rb +0 -64
- data/spec/integration/matcher_spec.rb +0 -96
- data/spec/integration/result_matcher_spec.rb +0 -56
- data/spec/spec_helper.rb +0 -57
- data/spec/unit/case_spec.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b0215bfb6c841e25bcd167ebf29b6dd05c642926c04bb253cabe5a3d430ee27
|
4
|
+
data.tar.gz: 6a69936b8ce9b3edfd22653c0e358f8c6d1149064a74782661b8a251e306ba86
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0641213eab8f65143040b0c6a61913415822e34fa985ff68a3efae84e4a21ffeb04675ad4ba5aaf7476cfd7d4bc89128f5faec7d705d36f8d262a0b131d2c76
|
7
|
+
data.tar.gz: 5b42966da62e0b5665ca89c20aaef62683a9e52e4fae91ae4eb852f9e2900f417800f5ce5ca82ccf3e5403d39ce54af7862942e7ee4fda12215eee297450c21f
|
data/CHANGELOG.md
CHANGED
@@ -1,119 +1,222 @@
|
|
1
|
-
|
1
|
+
<!--- DO NOT EDIT THIS FILE - IT'S AUTOMATICALLY GENERATED VIA DEVTOOLS --->
|
2
2
|
|
3
|
-
##
|
3
|
+
## 0.9.0 2021-03-05
|
4
|
+
|
5
|
+
|
6
|
+
### Changed
|
7
|
+
|
8
|
+
- Matcher evaluator is now a standard `Object` descendant (see #32) (@solnic)
|
9
|
+
|
10
|
+
[Compare v0.8.3...v0.9.0](https://github.com/dry-rb/dry-matcher/compare/v0.8.3...v0.9.0)
|
11
|
+
|
12
|
+
## 0.8.3 2020-01-07
|
13
|
+
|
14
|
+
|
15
|
+
### Fixed
|
16
|
+
|
17
|
+
- Delegation warnings about keyword arguments (flash-gordon)
|
18
|
+
|
19
|
+
|
20
|
+
[Compare v0.8.2...v0.8.3](https://github.com/dry-rb/dry-matcher/compare/v0.8.2...v0.8.3)
|
21
|
+
|
22
|
+
## 0.8.2 2019-09-06
|
23
|
+
|
24
|
+
|
25
|
+
### Fixed
|
26
|
+
|
27
|
+
- Minimal dry-core version set to 0.4.8 (flash-gordon)
|
28
|
+
|
29
|
+
|
30
|
+
[Compare v0.8.1...v0.8.2](https://github.com/dry-rb/dry-matcher/compare/v0.8.1...v0.8.2)
|
31
|
+
|
32
|
+
## 0.8.1 2019-08-13
|
33
|
+
|
34
|
+
|
35
|
+
### Added
|
36
|
+
|
37
|
+
- `Dry::Matcher#for` is a shortcut for `Dry::Matcher.for(..., with: matcher)` (flash-gordon)
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
require 'dry/matcher/result_matcher'
|
41
|
+
|
42
|
+
class CreateUser
|
43
|
+
include Dry::Matcher::ResultMatcher.for(:call)
|
44
|
+
|
45
|
+
def call(...)
|
46
|
+
# code returning an instance of Dry::Monads::Result
|
47
|
+
end
|
48
|
+
end
|
49
|
+
```
|
50
|
+
|
51
|
+
|
52
|
+
[Compare v0.8.0...v0.8.1](https://github.com/dry-rb/dry-matcher/compare/v0.8.0...v0.8.1)
|
53
|
+
|
54
|
+
## 0.8.0 2019-07-30
|
55
|
+
|
56
|
+
|
57
|
+
### Added
|
58
|
+
|
59
|
+
- API for cases was changed to work with a single block instead of `match`/`resolve` combination (flash-gordon in [#23](https://github.com/dry-rb/dry-matcher/pull/23)):
|
60
|
+
```ruby
|
61
|
+
Dry::Matcher::Case.new do |value, patterns|
|
62
|
+
if patterns.include?(value)
|
63
|
+
# value will be passed to the block
|
64
|
+
value
|
65
|
+
else
|
66
|
+
# Undefined stands for no match
|
67
|
+
Dry::Matcher::Undefined
|
68
|
+
end
|
69
|
+
end
|
70
|
+
```
|
71
|
+
- `ResultMatcher` now uses patterns for matching and matches against the first element if an array is passed (flash-gordon in [#24](https://github.com/dry-rb/dry-matcher/pull/24) and [#22](https://github.com/dry-rb/dry-matcher/pull/22) and michaelherold in [#21](https://github.com/dry-rb/dry-matcher/pull/21))
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
value = Dry::Monads::Result::Failure.new([:invalid, :reasons])
|
75
|
+
|
76
|
+
Dry::Matcher::ResultMatcher.(value) do |m|
|
77
|
+
m.success do |v|
|
78
|
+
"Yay: #{v}"
|
79
|
+
end
|
80
|
+
|
81
|
+
m.failure(:not_found) do
|
82
|
+
"No such thing"
|
83
|
+
end
|
84
|
+
|
85
|
+
m.failure(:invalid) do |_code, errors|
|
86
|
+
"Cannot be done: #{errors.inspect}"
|
87
|
+
end
|
88
|
+
end #=> "Cannot be done: :reasons"
|
89
|
+
```
|
90
|
+
|
91
|
+
### Changed
|
92
|
+
|
93
|
+
- [BREAKING] Support for Ruby 2.3 was dropped as it's EOL
|
94
|
+
|
95
|
+
[Compare v0.7.0...v0.8.0](https://github.com/dry-rb/dry-matcher/compare/v0.7.0...v0.8.0)
|
96
|
+
|
97
|
+
## 0.7.0 2018-01-11
|
98
|
+
|
99
|
+
|
100
|
+
### Changed
|
4
101
|
|
5
102
|
- `EitherMatcher` was renamed to `ResultMatcher` according to match the rename of `Either` to `Result` in dry-monads 0.4.0. The previous name is still there for backward compatibility, we'll deprecate and drop it in furure releases (flash-gordon in [#13](https://github.com/dry-rb/dry-matcher/pull/13))
|
6
103
|
|
7
104
|
[Compare v0.6.0...v0.7.0](https://github.com/dry-rb/dry-matcher/compare/v0.6.0...v0.7.0)
|
8
105
|
|
9
|
-
|
106
|
+
## 0.6.0 2016-12-19
|
107
|
+
|
10
108
|
|
11
|
-
|
109
|
+
### Added
|
12
110
|
|
13
111
|
- API documentation for most methods (alsemyonov in [#8](https://github.com/dry-rb/dry-matcher/pull/8))
|
14
112
|
|
15
|
-
|
113
|
+
### Fixed
|
16
114
|
|
17
|
-
-
|
18
|
-
- `Dry::Matcher::Case` objects can now be created without a `resolve:` proc. In this case, a default will be provided that passes the result value through (timriley in [#9](https://github.com/dry-rb/dry-matcher/pull/9))
|
115
|
+
- Fixed handling of calls to non-existent cases within a matcher block (timriley)
|
19
116
|
|
20
|
-
|
117
|
+
### Changed
|
21
118
|
|
22
|
-
-
|
119
|
+
- Matches must now be exhaustive - when matching against a value, at least one match block must be provided for each of a matcher's cases (timriley in [#7](https://github.com/dry-rb/dry-matcher/pull/7))
|
120
|
+
- `Dry::Matcher::Case` objects can now be created without a `resolve:` proc. In this case, a default will be provided that passes the result value through (timriley in [#9](https://github.com/dry-rb/dry-matcher/pull/9))
|
23
121
|
|
24
122
|
[Compare v0.5.0...v0.6.0](https://github.com/dry-rb/dry-matcher/compare/v0.5.0...v0.6.0)
|
25
123
|
|
26
|
-
|
124
|
+
## 0.5.0 2016-06-30
|
27
125
|
|
28
|
-
|
126
|
+
|
127
|
+
### Added
|
29
128
|
|
30
129
|
- Added support for building custom matchers, with an any number of match cases, each offering their own matching and resolving logic. This is now the primary API for dry-matcher. (timriley)
|
31
130
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
57
|
-
|
58
|
-
m.failure :not_found do |v|
|
59
|
-
"Oops, not found: #{v}"
|
60
|
-
end
|
61
|
-
|
62
|
-
m.failure do |v|
|
63
|
-
"Boo: #{v}"
|
64
|
-
end
|
131
|
+
```ruby
|
132
|
+
# Match `[:ok, some_value]` for success
|
133
|
+
success_case = Dry::Matcher::Case.new(
|
134
|
+
match: -> value { value.first == :ok },
|
135
|
+
resolve: -> value { value.last }
|
136
|
+
)
|
137
|
+
|
138
|
+
# Match `[:err, some_error_code, some_value]` for failure
|
139
|
+
failure_case = Dry::Matcher::Case.new(
|
140
|
+
match: -> value, *pattern {
|
141
|
+
value[0] == :err && (pattern.any? ? pattern.include?(value[1]) : true)
|
142
|
+
},
|
143
|
+
resolve: -> value { value.last }
|
144
|
+
)
|
145
|
+
|
146
|
+
# Build the matcher
|
147
|
+
matcher = Dry::Matcher.new(success: success_case, failure: failure_case)
|
148
|
+
|
149
|
+
# Then put it to use
|
150
|
+
my_success = [:ok, "success!"]
|
151
|
+
|
152
|
+
result = matcher.(my_success) do |m|
|
153
|
+
m.success do |v|
|
154
|
+
"Yay: #{v}"
|
65
155
|
end
|
66
156
|
|
67
|
-
|
68
|
-
|
157
|
+
m.failure :not_found do |v|
|
158
|
+
"Oops, not found: #{v}"
|
159
|
+
end
|
69
160
|
|
70
|
-
|
161
|
+
m.failure do |v|
|
162
|
+
"Boo: #{v}"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
result # => "Yay: success!"
|
167
|
+
```
|
168
|
+
|
169
|
+
### Changed
|
71
170
|
|
72
171
|
- Renamed to `dry-matcher`, since this is now a flexible, general purpose pattern matching API. All components are now available under the `Dry::Matcher` namespace. (timriley)
|
73
172
|
- `Dry::Matcher.for` requires a matcher object to be passed when being included in a class:
|
74
173
|
|
75
|
-
|
76
|
-
|
174
|
+
```ruby
|
175
|
+
MyMatcher = Dry::Matcher.new(...)
|
77
176
|
|
78
|
-
|
79
|
-
|
177
|
+
class MyOperation
|
178
|
+
include Dry::Matcher.for(:call, with: MyMatcher)
|
80
179
|
|
81
|
-
|
82
|
-
end
|
180
|
+
def call
|
83
181
|
end
|
84
|
-
|
182
|
+
end
|
183
|
+
```
|
85
184
|
- The previous `Dry::ResultMatcher.match` behaviour (for matching `Either` monads) has been moved to `Dry::Matcher::EitherMatcher.call`
|
86
185
|
|
87
186
|
[Compare v0.4.0...v0.5.0](https://github.com/dry-rb/dry-matcher/compare/v0.4.0...v0.5.0)
|
88
187
|
|
89
|
-
|
188
|
+
## 0.4.0 2016-06-08
|
189
|
+
|
90
190
|
|
91
|
-
|
191
|
+
### Added
|
92
192
|
|
93
|
-
|
193
|
+
- Support convertible result objects responding to `#to_either` (ttdonovan)
|
94
194
|
|
95
|
-
|
195
|
+
### Changed
|
96
196
|
|
97
|
-
|
197
|
+
- Expect monads from [dry-monads](https://github.com/dry-rb/dry-monads) instead of [Kleisli](https://github.com/txus/kleisli) (ttdonovan)
|
98
198
|
|
99
199
|
[Compare v0.3.0...v0.4.0](https://github.com/dry-rb/dry-matcher/compare/v0.3.0...v0.4.0)
|
100
200
|
|
101
|
-
|
201
|
+
## 0.3.0 2016-03-23
|
102
202
|
|
103
|
-
## Changed
|
104
203
|
|
105
|
-
|
204
|
+
### Changed
|
205
|
+
|
206
|
+
- Renamed to `dry-result_matcher`. Match results using `Dry::ResultMatcher.match` or extend your own classes with `Dry::ResultMatcher.for`.
|
106
207
|
|
107
208
|
[Compare v0.2.0...v0.3.0](https://github.com/dry-rb/dry-matcher/compare/v0.2.0...v0.3.0)
|
108
209
|
|
109
|
-
|
210
|
+
## 0.2.0 2016-02-10
|
211
|
+
|
212
|
+
|
213
|
+
### Added
|
110
214
|
|
111
|
-
|
215
|
+
- Added `EitherResultMatcher.for(*methods)` to return a module wrapping the specified methods (returning an `Either`) with the match block API. Example usage, in a class with a `#call` method: `include EitherResultMatcher.for(:call)`.
|
112
216
|
|
113
|
-
* Added `EitherResultMatcher.for(*methods)` to return a module wrapping the specified methods (returning an `Either`) with the match block API. Example usage, in a class with a `#call` method: `include EitherResultMatcher.for(:call)`.
|
114
217
|
|
115
|
-
[Compare v0.1.0...v0.
|
218
|
+
[Compare v0.1.0...v0.2.0](https://github.com/dry-rb/dry-matcher/compare/v0.1.0...v0.2.0)
|
116
219
|
|
117
|
-
|
220
|
+
## 0.1.0 2015-12-03
|
118
221
|
|
119
222
|
Initial release.
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015-2021 dry-rb team
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,23 +1,29 @@
|
|
1
|
-
[gitter]: https://gitter.im/dry-rb/chat
|
2
1
|
[gem]: https://rubygems.org/gems/dry-matcher
|
3
|
-
[
|
4
|
-
[
|
5
|
-
[
|
2
|
+
[actions]: https://github.com/dry-rb/dry-matcher/actions
|
3
|
+
[codacy]: https://www.codacy.com/gh/dry-rb/dry-matcher
|
4
|
+
[chat]: https://dry-rb.zulipchat.com
|
5
|
+
[inchpages]: http://inch-ci.org/github/dry-rb/dry-matcher
|
6
6
|
|
7
|
-
# dry-matcher [![Join the
|
7
|
+
# dry-matcher [![Join the chat at https://dry-rb.zulipchat.com](https://img.shields.io/badge/dry--rb-join%20chat-%23346b7a.svg)][chat]
|
8
8
|
|
9
|
-
[![Gem Version](https://
|
10
|
-
[![
|
11
|
-
[![
|
12
|
-
[![
|
13
|
-
[![
|
14
|
-
|
15
|
-
Flexible, expressive pattern matching for Ruby.
|
9
|
+
[![Gem Version](https://badge.fury.io/rb/dry-matcher.svg)][gem]
|
10
|
+
[![CI Status](https://github.com/dry-rb/dry-matcher/workflows/ci/badge.svg)][actions]
|
11
|
+
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/f09a7d1745fd430d829a1f825357db88)][codacy]
|
12
|
+
[![Codacy Badge](https://api.codacy.com/project/badge/Coverage/f09a7d1745fd430d829a1f825357db88)][codacy]
|
13
|
+
[![Inline docs](http://inch-ci.org/github/dry-rb/dry-matcher.svg?branch=master)][inchpages]
|
16
14
|
|
17
15
|
## Links
|
18
16
|
|
19
|
-
* [
|
17
|
+
* [User documentation](http://dry-rb.org/gems/dry-matcher)
|
18
|
+
* [API documentation](http://rubydoc.info/gems/dry-matcher)
|
19
|
+
|
20
|
+
## Supported Ruby versions
|
21
|
+
|
22
|
+
This library officially supports the following Ruby versions:
|
23
|
+
|
24
|
+
* MRI >= `2.5`
|
25
|
+
* jruby >= `9.2`
|
20
26
|
|
21
27
|
## License
|
22
28
|
|
23
|
-
|
29
|
+
See `LICENSE` file.
|
data/dry-matcher.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# this file is managed by dry-rb/devtools project
|
3
|
+
|
4
|
+
lib = File.expand_path('lib', __dir__)
|
5
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
6
|
+
require 'dry/matcher/version'
|
7
|
+
|
8
|
+
Gem::Specification.new do |spec|
|
9
|
+
spec.name = 'dry-matcher'
|
10
|
+
spec.authors = ["Tim Riley", "Nikita Shilnikov"]
|
11
|
+
spec.email = ["tim@icelab.com.au", "fg@flashgordon.ru"]
|
12
|
+
spec.license = 'MIT'
|
13
|
+
spec.version = Dry::Matcher::VERSION.dup
|
14
|
+
|
15
|
+
spec.summary = "Flexible, expressive pattern matching for Ruby"
|
16
|
+
spec.description = spec.summary
|
17
|
+
spec.homepage = 'https://dry-rb.org/gems/dry-matcher'
|
18
|
+
spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-matcher.gemspec", "lib/**/*"]
|
19
|
+
spec.bindir = 'bin'
|
20
|
+
spec.executables = []
|
21
|
+
spec.require_paths = ['lib']
|
22
|
+
|
23
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
24
|
+
spec.metadata['changelog_uri'] = 'https://github.com/dry-rb/dry-matcher/blob/master/CHANGELOG.md'
|
25
|
+
spec.metadata['source_code_uri'] = 'https://github.com/dry-rb/dry-matcher'
|
26
|
+
spec.metadata['bug_tracker_uri'] = 'https://github.com/dry-rb/dry-matcher/issues'
|
27
|
+
|
28
|
+
spec.required_ruby_version = ">= 2.5.0"
|
29
|
+
|
30
|
+
# to update dependencies edit project.yml
|
31
|
+
spec.add_runtime_dependency "dry-core", "~> 0.4", ">= 0.4.8"
|
32
|
+
|
33
|
+
spec.add_development_dependency "rake"
|
34
|
+
end
|
data/lib/dry-matcher.rb
CHANGED
data/lib/dry/matcher.rb
CHANGED
@@ -1,9 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/core/constants"
|
1
4
|
require "dry/matcher/case"
|
2
5
|
require "dry/matcher/evaluator"
|
3
6
|
|
4
7
|
module Dry
|
5
8
|
# @see http://dry-rb.org/gems/dry-matcher
|
6
9
|
class Matcher
|
10
|
+
include Core::Constants
|
11
|
+
|
12
|
+
RUBY2_KEYWORDS = respond_to?(:ruby2_keywords, true)
|
13
|
+
|
7
14
|
# Generates a module containing pattern matching for methods listed in
|
8
15
|
# `match_methods` argument with behavior defined by `with` matcher
|
9
16
|
#
|
@@ -40,6 +47,7 @@ module Dry
|
|
40
47
|
result
|
41
48
|
end
|
42
49
|
end
|
50
|
+
ruby2_keywords(match_method) if RUBY2_KEYWORDS
|
43
51
|
end
|
44
52
|
end
|
45
53
|
|
@@ -70,7 +78,7 @@ module Dry
|
|
70
78
|
# after matched pattern
|
71
79
|
#
|
72
80
|
# @example Usage with `dry-monads`
|
73
|
-
# require 'dry
|
81
|
+
# require 'dry/monads/result'
|
74
82
|
# require 'dry/matcher/result_matcher'
|
75
83
|
#
|
76
84
|
# value = Dry::Monads::Result::Failure.new('failure!')
|
@@ -82,5 +90,14 @@ module Dry
|
|
82
90
|
def call(result, &block)
|
83
91
|
Evaluator.new(result, cases).call(&block)
|
84
92
|
end
|
93
|
+
|
94
|
+
# Shortcut for Dry::Matcher.for(..., with: matcher)
|
95
|
+
#
|
96
|
+
# @param [Array[Symbol]]
|
97
|
+
#
|
98
|
+
# @return [Module]
|
99
|
+
def for(*methods)
|
100
|
+
self.class.for(*methods, with: self)
|
101
|
+
end
|
85
102
|
end
|
86
103
|
end
|
data/lib/dry/matcher/case.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Dry
|
2
4
|
class Matcher
|
3
5
|
# {Case} object contains logic for pattern matching and resolving result
|
@@ -7,29 +9,27 @@ module Dry
|
|
7
9
|
|
8
10
|
# @param match [#call] callable used to test given pattern against value
|
9
11
|
# @param resolve [#call] callable used to resolve value into a result
|
10
|
-
def initialize(match
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
def matches?(value, *pattern)
|
23
|
-
@match.(value, *pattern)
|
12
|
+
def initialize(match: Undefined, resolve: DEFAULT_RESOLVE, &block)
|
13
|
+
if block
|
14
|
+
@match = block
|
15
|
+
else
|
16
|
+
@match = proc do |value, patterns|
|
17
|
+
if match.(value, *patterns)
|
18
|
+
resolve.(value)
|
19
|
+
else
|
20
|
+
Undefined
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
24
|
end
|
25
25
|
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
# @
|
30
|
-
#
|
31
|
-
def
|
32
|
-
@
|
26
|
+
# @param [Object] value Value to match
|
27
|
+
# @param [Array<Object>] patterns Optional list of patterns to match against
|
28
|
+
# @yieldparam [Object] v Resolved value if match succeeds
|
29
|
+
# @return [Object,Dry::Core::Constants::Undefined] Either the yield result
|
30
|
+
# or Undefined if match wasn't successful
|
31
|
+
def call(value, patterns = EMPTY_ARRAY, &block)
|
32
|
+
Undefined.map(@match.(value, patterns), &block)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -1,7 +1,14 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dry/core/deprecations'
|
4
|
+
require 'dry/matcher/result_matcher'
|
2
5
|
|
3
6
|
module Dry
|
4
7
|
class Matcher
|
8
|
+
extend Dry::Core::Deprecations[:'dry-matcher']
|
9
|
+
|
5
10
|
EitherMatcher = ResultMatcher
|
11
|
+
|
12
|
+
deprecate_constant(:EitherMatcher, message: 'Dry::Matcher::ResultMatcher')
|
6
13
|
end
|
7
14
|
end
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Dry
|
2
4
|
class Matcher
|
3
5
|
NonExhaustiveMatchError = Class.new(StandardError)
|
4
6
|
|
5
7
|
# {Evaluator} is used in {Dry::Matcher#call Dry::Matcher#call} block to handle different {Case}s
|
6
|
-
class Evaluator
|
8
|
+
class Evaluator
|
7
9
|
# @param [Object] result
|
8
10
|
# @param [Hash{Symbol => Case}] cases
|
9
11
|
def initialize(result, cases)
|
@@ -11,8 +13,6 @@ module Dry
|
|
11
13
|
@result = result
|
12
14
|
|
13
15
|
@unhandled_cases = @cases.keys.map(&:to_sym)
|
14
|
-
@matched = false
|
15
|
-
@output = nil
|
16
16
|
end
|
17
17
|
|
18
18
|
def call
|
@@ -20,14 +20,14 @@ module Dry
|
|
20
20
|
|
21
21
|
ensure_exhaustive_match
|
22
22
|
|
23
|
-
@output
|
23
|
+
@output if defined? @output
|
24
24
|
end
|
25
25
|
|
26
26
|
# Checks whether `cases` given to {#initialize} contains one called `name`
|
27
27
|
# @param [String] name
|
28
28
|
# @param [Boolean] include_private
|
29
29
|
# @return [Boolean]
|
30
|
-
def respond_to_missing?(name,
|
30
|
+
def respond_to_missing?(name, _include_private = false)
|
31
31
|
@cases.key?(name)
|
32
32
|
end
|
33
33
|
|
@@ -46,10 +46,15 @@ module Dry
|
|
46
46
|
# @raise [NoMethodError] if there was no case called `name` given to
|
47
47
|
# {#initialize} in `cases` hash
|
48
48
|
def method_missing(name, *args, &block)
|
49
|
-
|
49
|
+
kase = @cases.fetch(name) { return super }
|
50
50
|
|
51
51
|
@unhandled_cases.delete name
|
52
|
-
|
52
|
+
|
53
|
+
unless defined? @output
|
54
|
+
kase.(@result, args) do |result|
|
55
|
+
@output = yield(result)
|
56
|
+
end
|
57
|
+
end
|
53
58
|
end
|
54
59
|
|
55
60
|
private
|
@@ -59,17 +64,6 @@ module Dry
|
|
59
64
|
::Kernel.raise NonExhaustiveMatchError, "cases +#{@unhandled_cases.join(', ')}+ not handled"
|
60
65
|
end
|
61
66
|
end
|
62
|
-
|
63
|
-
# @param [Case] kase
|
64
|
-
# @param [Array] pattern
|
65
|
-
def handle_case(kase, *pattern)
|
66
|
-
return @output if @matched
|
67
|
-
|
68
|
-
if kase.matches?(@result, *pattern)
|
69
|
-
@matched = true
|
70
|
-
@output = yield(kase.resolve(@result))
|
71
|
-
end
|
72
|
-
end
|
73
67
|
end
|
74
68
|
end
|
75
69
|
end
|
@@ -1,7 +1,21 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dry/matcher'
|
2
4
|
|
3
5
|
module Dry
|
4
6
|
class Matcher
|
7
|
+
match = ::Proc.new do |value, patterns|
|
8
|
+
if patterns.empty?
|
9
|
+
value
|
10
|
+
elsif value.is_a?(::Array) && patterns.any? { |p| p === value[0] }
|
11
|
+
value
|
12
|
+
elsif patterns.any? { |p| p === value }
|
13
|
+
value
|
14
|
+
else
|
15
|
+
Undefined
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
5
19
|
# Built-in {Matcher} ready to use with `Result` or `Try` monads from
|
6
20
|
# [dry-monads](/gems/dry-monads) or any other compatible gems.
|
7
21
|
#
|
@@ -16,7 +30,7 @@ module Dry
|
|
16
30
|
# @return [Dry::Matcher]
|
17
31
|
#
|
18
32
|
# @example Usage with `dry-monads`
|
19
|
-
# require 'dry
|
33
|
+
# require 'dry/monads/result'
|
20
34
|
# require 'dry/matcher/result_matcher'
|
21
35
|
#
|
22
36
|
# value = Dry::Monads::Result::Success.new('success!')
|
@@ -48,27 +62,43 @@ module Dry
|
|
48
62
|
# m.success { |v| "#{v.inspect} is truthy" }
|
49
63
|
# m.failure { |v| "#{v.inspect} is falsey" }
|
50
64
|
# end # => "nil is falsey"
|
65
|
+
#
|
66
|
+
# @example Usage with error codes
|
67
|
+
# value = Dry::Monads::Result::Failure.new([:invalid, :reasons])
|
68
|
+
#
|
69
|
+
# Dry::Matcher::ResultMatcher.(value) do |m|
|
70
|
+
# m.success do |v|
|
71
|
+
# "Yay: #{v}"
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
# m.failure(:not_found) do
|
75
|
+
# "No such thing"
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# m.failure(:invalid) do |_code, errors|
|
79
|
+
# "Cannot be done: #{errors.inspect}"
|
80
|
+
# end
|
81
|
+
# end #=> "Cannot be done: :reasons"
|
82
|
+
#
|
51
83
|
ResultMatcher = Dry::Matcher.new(
|
52
|
-
success: Case.new
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
result.failure
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
},
|
71
|
-
)
|
84
|
+
success: Case.new { |result, patterns|
|
85
|
+
result = result.to_result
|
86
|
+
|
87
|
+
if result.success?
|
88
|
+
match.(result.value!, patterns)
|
89
|
+
else
|
90
|
+
Undefined
|
91
|
+
end
|
92
|
+
},
|
93
|
+
failure: Case.new { |result, patterns|
|
94
|
+
result = result.to_result
|
95
|
+
|
96
|
+
if result.failure?
|
97
|
+
match.(result.failure, patterns)
|
98
|
+
else
|
99
|
+
Undefined
|
100
|
+
end
|
101
|
+
}
|
72
102
|
)
|
73
103
|
end
|
74
104
|
end
|
data/lib/dry/matcher/version.rb
CHANGED
metadata
CHANGED
@@ -1,73 +1,38 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-matcher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Riley
|
8
|
+
- Nikita Shilnikov
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2021-03-05 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
15
|
+
name: dry-core
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
16
17
|
requirements:
|
17
18
|
- - "~>"
|
18
19
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
-
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '1.10'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rake
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 10.4.2
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 10.4.2
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rspec
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
20
|
+
version: '0.4'
|
21
|
+
- - ">="
|
46
22
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
48
|
-
type: :
|
23
|
+
version: 0.4.8
|
24
|
+
type: :runtime
|
49
25
|
prerelease: false
|
50
26
|
version_requirements: !ruby/object:Gem::Requirement
|
51
27
|
requirements:
|
52
28
|
- - "~>"
|
53
29
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
55
|
-
-
|
56
|
-
name: simplecov
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 0.10.0
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
30
|
+
version: '0.4'
|
31
|
+
- - ">="
|
67
32
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.
|
33
|
+
version: 0.4.8
|
69
34
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
35
|
+
name: rake
|
71
36
|
requirement: !ruby/object:Gem::Requirement
|
72
37
|
requirements:
|
73
38
|
- - ">="
|
@@ -83,15 +48,15 @@ dependencies:
|
|
83
48
|
description: Flexible, expressive pattern matching for Ruby
|
84
49
|
email:
|
85
50
|
- tim@icelab.com.au
|
51
|
+
- fg@flashgordon.ru
|
86
52
|
executables: []
|
87
53
|
extensions: []
|
88
54
|
extra_rdoc_files: []
|
89
55
|
files:
|
90
56
|
- CHANGELOG.md
|
91
|
-
-
|
92
|
-
- LICENSE.md
|
57
|
+
- LICENSE
|
93
58
|
- README.md
|
94
|
-
-
|
59
|
+
- dry-matcher.gemspec
|
95
60
|
- lib/dry-matcher.rb
|
96
61
|
- lib/dry/matcher.rb
|
97
62
|
- lib/dry/matcher/case.rb
|
@@ -99,16 +64,14 @@ files:
|
|
99
64
|
- lib/dry/matcher/evaluator.rb
|
100
65
|
- lib/dry/matcher/result_matcher.rb
|
101
66
|
- lib/dry/matcher/version.rb
|
102
|
-
-
|
103
|
-
- spec/integration/class_enhancement_spec.rb
|
104
|
-
- spec/integration/matcher_spec.rb
|
105
|
-
- spec/integration/result_matcher_spec.rb
|
106
|
-
- spec/spec_helper.rb
|
107
|
-
- spec/unit/case_spec.rb
|
108
|
-
homepage: http://dry-rb.org/gems/dry-matcher
|
67
|
+
homepage: https://dry-rb.org/gems/dry-matcher
|
109
68
|
licenses:
|
110
69
|
- MIT
|
111
|
-
metadata:
|
70
|
+
metadata:
|
71
|
+
allowed_push_host: https://rubygems.org
|
72
|
+
changelog_uri: https://github.com/dry-rb/dry-matcher/blob/master/CHANGELOG.md
|
73
|
+
source_code_uri: https://github.com/dry-rb/dry-matcher
|
74
|
+
bug_tracker_uri: https://github.com/dry-rb/dry-matcher/issues
|
112
75
|
post_install_message:
|
113
76
|
rdoc_options: []
|
114
77
|
require_paths:
|
@@ -117,15 +80,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
117
80
|
requirements:
|
118
81
|
- - ">="
|
119
82
|
- !ruby/object:Gem::Version
|
120
|
-
version: 2.
|
83
|
+
version: 2.5.0
|
121
84
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
85
|
requirements:
|
123
86
|
- - ">="
|
124
87
|
- !ruby/object:Gem::Version
|
125
88
|
version: '0'
|
126
89
|
requirements: []
|
127
|
-
|
128
|
-
rubygems_version: 2.7.3
|
90
|
+
rubygems_version: 3.1.4
|
129
91
|
signing_key:
|
130
92
|
specification_version: 4
|
131
93
|
summary: Flexible, expressive pattern matching for Ruby
|
data/Gemfile
DELETED
data/LICENSE.md
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
The MIT License (MIT)
|
2
|
-
|
3
|
-
Copyright © 2015-2016 [Icelab](http://icelab.com.au/).
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
6
|
-
|
7
|
-
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
8
|
-
|
9
|
-
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
DELETED
data/spec/examples.txt
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
example_id | status | run_time |
|
2
|
-
----------------------------------------------------- | ------ | --------------- |
|
3
|
-
./spec/integration/class_enhancement_spec.rb[1:1:1:1] | passed | 0.00011 seconds |
|
4
|
-
./spec/integration/class_enhancement_spec.rb[1:1:2:1] | passed | 0.0001 seconds |
|
5
|
-
./spec/integration/class_enhancement_spec.rb[1:2:1:1] | passed | 0.00014 seconds |
|
6
|
-
./spec/integration/class_enhancement_spec.rb[1:2:2:1] | passed | 0.0001 seconds |
|
7
|
-
./spec/integration/matcher_spec.rb[1:1:1] | passed | 0.00017 seconds |
|
8
|
-
./spec/integration/matcher_spec.rb[1:1:2] | passed | 0.0001 seconds |
|
9
|
-
./spec/integration/matcher_spec.rb[1:1:3] | passed | 0.00122 seconds |
|
10
|
-
./spec/integration/matcher_spec.rb[1:1:4:1] | passed | 0.00009 seconds |
|
11
|
-
./spec/integration/matcher_spec.rb[1:1:4:2] | passed | 0.00147 seconds |
|
12
|
-
./spec/integration/result_matcher_spec.rb[1:1:1:1] | passed | 0.00012 seconds |
|
13
|
-
./spec/integration/result_matcher_spec.rb[1:1:2:1] | passed | 0.00008 seconds |
|
14
|
-
./spec/integration/result_matcher_spec.rb[1:1:3:1:1] | passed | 0.00015 seconds |
|
15
|
-
./spec/integration/result_matcher_spec.rb[1:1:3:2:1] | passed | 0.00017 seconds |
|
16
|
-
./spec/unit/case_spec.rb[1:1:1] | passed | 0.00087 seconds |
|
17
|
-
./spec/unit/case_spec.rb[1:2:1] | passed | 0.00008 seconds |
|
18
|
-
./spec/unit/case_spec.rb[1:2:2] | passed | 0.00056 seconds |
|
@@ -1,64 +0,0 @@
|
|
1
|
-
require "dry-monads"
|
2
|
-
require "dry/matcher/result_matcher"
|
3
|
-
|
4
|
-
RSpec.describe "Class enhancement with Dry::Matcher.for" do
|
5
|
-
let(:operation) {
|
6
|
-
Class.new do
|
7
|
-
include Dry::Matcher.for(:call, with: Dry::Matcher::ResultMatcher)
|
8
|
-
|
9
|
-
def call(bool)
|
10
|
-
bool ? Dry::Monads::Success("a success") : Dry::Monads::Failure("a failure")
|
11
|
-
end
|
12
|
-
end.new
|
13
|
-
}
|
14
|
-
|
15
|
-
describe "match blocks" do
|
16
|
-
subject(:match) {
|
17
|
-
operation.call(input) do |m|
|
18
|
-
m.success do |v|
|
19
|
-
"Matched success: #{v}"
|
20
|
-
end
|
21
|
-
|
22
|
-
m.failure do |v|
|
23
|
-
"Matched failure: #{v}"
|
24
|
-
end
|
25
|
-
end
|
26
|
-
}
|
27
|
-
|
28
|
-
context "successful result" do
|
29
|
-
let(:input) { true }
|
30
|
-
|
31
|
-
it "matches on success" do
|
32
|
-
expect(match).to eq "Matched success: a success"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
context "failed result" do
|
37
|
-
let(:input) { false }
|
38
|
-
|
39
|
-
it "matches on failure" do
|
40
|
-
expect(match).to eq "Matched failure: a failure"
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
describe "without match blocks" do
|
46
|
-
subject(:result) { operation.call(input) }
|
47
|
-
|
48
|
-
context "successful result" do
|
49
|
-
let(:input) { true }
|
50
|
-
|
51
|
-
it "returns the result" do
|
52
|
-
expect(result).to eq Dry::Monads::Success("a success")
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
context "failed result" do
|
57
|
-
let(:input) { false }
|
58
|
-
|
59
|
-
it "returns the result" do
|
60
|
-
expect(result).to eq Dry::Monads::Failure("a failure")
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
@@ -1,96 +0,0 @@
|
|
1
|
-
require "dry-monads"
|
2
|
-
|
3
|
-
RSpec.describe Dry::Matcher do
|
4
|
-
context "with match cases provided" do
|
5
|
-
let(:success_case) {
|
6
|
-
Dry::Matcher::Case.new(
|
7
|
-
match: -> result { result.success? },
|
8
|
-
resolve: -> result { result.value! },
|
9
|
-
)
|
10
|
-
}
|
11
|
-
|
12
|
-
let(:failure_case) {
|
13
|
-
Dry::Matcher::Case.new(
|
14
|
-
match: -> result { result.failure? },
|
15
|
-
resolve: -> result { result.failure },
|
16
|
-
)
|
17
|
-
}
|
18
|
-
|
19
|
-
let(:matcher) {
|
20
|
-
Dry::Matcher.new(
|
21
|
-
success: success_case,
|
22
|
-
failure: failure_case,
|
23
|
-
)
|
24
|
-
}
|
25
|
-
|
26
|
-
def call_match(input)
|
27
|
-
matcher.(input) do |m|
|
28
|
-
m.success do |v|
|
29
|
-
"Success: #{v}"
|
30
|
-
end
|
31
|
-
|
32
|
-
m.failure do |v|
|
33
|
-
"Failure: #{v}"
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
it "matches on success" do
|
39
|
-
input = Dry::Monads::Success("Yes!")
|
40
|
-
expect(call_match(input)).to eq "Success: Yes!"
|
41
|
-
end
|
42
|
-
|
43
|
-
it "matches on failure" do
|
44
|
-
input = Dry::Monads::Failure("No!")
|
45
|
-
expect(call_match(input)).to eq "Failure: No!"
|
46
|
-
end
|
47
|
-
|
48
|
-
it "requires an exhaustive match" do
|
49
|
-
input = Dry::Monads::Success("Yes!")
|
50
|
-
|
51
|
-
expect {
|
52
|
-
matcher.(input) do |m|
|
53
|
-
m.success { |v| "Success: #{v}" }
|
54
|
-
end
|
55
|
-
}.to raise_error Dry::Matcher::NonExhaustiveMatchError
|
56
|
-
end
|
57
|
-
|
58
|
-
context "with patterns" do
|
59
|
-
let(:success_case) {
|
60
|
-
Dry::Matcher::Case.new(
|
61
|
-
match: -> result { result.first == :ok },
|
62
|
-
resolve: -> result { result.last },
|
63
|
-
)
|
64
|
-
}
|
65
|
-
|
66
|
-
let(:failure_case) {
|
67
|
-
Dry::Matcher::Case.new(
|
68
|
-
match: -> result, failure_type {
|
69
|
-
result.length == 3 && result[0] == :failure && result[1] == failure_type
|
70
|
-
},
|
71
|
-
resolve: -> result { result.last },
|
72
|
-
)
|
73
|
-
}
|
74
|
-
|
75
|
-
def call_match(input)
|
76
|
-
matcher.(input) do |m|
|
77
|
-
m.success
|
78
|
-
|
79
|
-
m.failure :my_error do |v|
|
80
|
-
"Pattern-matched failure: #{v}"
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
it "matches using the provided pattern" do
|
86
|
-
input = [:failure, :my_error, "No!"]
|
87
|
-
expect(call_match(input)).to eq "Pattern-matched failure: No!"
|
88
|
-
end
|
89
|
-
|
90
|
-
it "doesn't match if the pattern doesn't match" do
|
91
|
-
input = [:failure, :non_matching_error, "No!"]
|
92
|
-
expect(call_match(input)).to be_nil
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
@@ -1,56 +0,0 @@
|
|
1
|
-
require "dry-monads"
|
2
|
-
require "dry/matcher/result_matcher"
|
3
|
-
|
4
|
-
RSpec.describe "Dry::Matcher::ResultMatcher" do
|
5
|
-
describe "external matching" do
|
6
|
-
subject(:match) {
|
7
|
-
Dry::Matcher::ResultMatcher.(result) do |m|
|
8
|
-
m.success do |v|
|
9
|
-
"Matched success: #{v}"
|
10
|
-
end
|
11
|
-
|
12
|
-
m.failure do |v|
|
13
|
-
"Matched failure: #{v}"
|
14
|
-
end
|
15
|
-
end
|
16
|
-
}
|
17
|
-
|
18
|
-
context "successful result" do
|
19
|
-
let(:result) { Dry::Monads::Success("a success") }
|
20
|
-
|
21
|
-
it "matches on success" do
|
22
|
-
expect(match).to eq "Matched success: a success"
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
context "failed result" do
|
27
|
-
let(:result) { Dry::Monads::Failure("a failure") }
|
28
|
-
|
29
|
-
it "matches on failure" do
|
30
|
-
expect(match).to eq "Matched failure: a failure"
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
context "result convertible to result" do
|
35
|
-
context "converts to success" do
|
36
|
-
let(:result) {
|
37
|
-
Dry::Monads::Try.lift([StandardError], -> { 'a success' })
|
38
|
-
}
|
39
|
-
|
40
|
-
it "matches on success" do
|
41
|
-
expect(match).to eq "Matched success: a success"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
context "converts to failure" do
|
46
|
-
let(:result) {
|
47
|
-
Dry::Monads::Try.lift([StandardError], -> { raise('a failure') })
|
48
|
-
}
|
49
|
-
|
50
|
-
it "matches on failure" do
|
51
|
-
expect(match).to eq "Matched failure: a failure"
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.3"
|
2
|
-
require "simplecov"
|
3
|
-
SimpleCov.start
|
4
|
-
end
|
5
|
-
|
6
|
-
|
7
|
-
begin
|
8
|
-
require "byebug"
|
9
|
-
rescue LoadError; end
|
10
|
-
|
11
|
-
require "dry-matcher"
|
12
|
-
|
13
|
-
Dir[File.join(File.dirname(__FILE__), "support/**/*.rb")].each do |f| require f end
|
14
|
-
|
15
|
-
RSpec.configure do |config|
|
16
|
-
config.disable_monkey_patching!
|
17
|
-
|
18
|
-
config.expect_with :rspec do |expectations|
|
19
|
-
# This option will default to `true` in RSpec 4.
|
20
|
-
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
21
|
-
end
|
22
|
-
|
23
|
-
config.mock_with :rspec do |mocks|
|
24
|
-
# This option will default to `true` in RSpec 4.
|
25
|
-
mocks.verify_partial_doubles = true
|
26
|
-
end
|
27
|
-
|
28
|
-
# Allows RSpec to persist some state between runs in order to support
|
29
|
-
# the `--only-failures` and `--next-failure` CLI options. We recommend
|
30
|
-
# you configure your source control system to ignore this file.
|
31
|
-
config.example_status_persistence_file_path = "spec/examples.txt"
|
32
|
-
|
33
|
-
# This setting enables warnings. It's recommended, but in some cases may
|
34
|
-
# be too noisy due to issues in dependencies.
|
35
|
-
config.warnings = true
|
36
|
-
|
37
|
-
# Many RSpec users commonly either run the entire suite or an individual
|
38
|
-
# file, and it's useful to allow more verbose output when running an
|
39
|
-
# individual spec file.
|
40
|
-
if config.files_to_run.one?
|
41
|
-
# Use the documentation formatter for detailed output, unless a formatter
|
42
|
-
# has already been configured (e.g. via a command-line flag).
|
43
|
-
config.default_formatter = "doc"
|
44
|
-
end
|
45
|
-
|
46
|
-
# Run specs in random order to surface order dependencies. If you find an
|
47
|
-
# order dependency and want to debug it, you can fix the order by providing
|
48
|
-
# the seed, which is printed after each run.
|
49
|
-
# --seed 1234
|
50
|
-
config.order = :random
|
51
|
-
|
52
|
-
# Seed global randomization in this process using the `--seed` CLI option.
|
53
|
-
# Setting this allows you to use `--seed` to deterministically reproduce
|
54
|
-
# test failures related to randomization by passing the same `--seed` value
|
55
|
-
# as the one that triggered the failure.
|
56
|
-
Kernel.srand config.seed
|
57
|
-
end
|
data/spec/unit/case_spec.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
RSpec.describe Dry::Matcher::Case do
|
2
|
-
describe "#matches?" do
|
3
|
-
it "calls the match proc with the value" do
|
4
|
-
kase = described_class.new(match: -> value { value.even? })
|
5
|
-
expect(kase.matches?(2)).to be true
|
6
|
-
expect(kase.matches?(1)).to be false
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
describe "#resolve" do
|
11
|
-
it "calls the resolve proc with the value" do
|
12
|
-
kase = described_class.new(match: -> * { true }, resolve: -> value { value.to_s })
|
13
|
-
|
14
|
-
expect(kase.resolve(123)).to eq "123"
|
15
|
-
end
|
16
|
-
|
17
|
-
it "defaults to passing through the value" do
|
18
|
-
kase = described_class.new(match: -> * { true })
|
19
|
-
expect(kase.resolve(123)).to eq 123
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|