dry-matcher 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7b7b475f9c2a102c0da7f6cf3422b8553e0f5d2f
4
+ data.tar.gz: 5c618057052448e4986233291fcadbe794c4b687
5
+ SHA512:
6
+ metadata.gz: 93a241b0c7fd705e703f6f3b021cbcf19b3ef1f88eeb45605dfcb815daf670ab547e9f306178c8fa8859c0d190de3c13c99d4d6a9a319ee09f84328d744630b5
7
+ data.tar.gz: 0e3cc0b1df1587600fe864336d84fcbecf94432c363a279c0f0382c96dbd0542ddf0b1d9c5ba63d321e1bc450e44724e13db5dcb561f9ec227dbd154e33f1dda
data/CHANGELOG.md ADDED
@@ -0,0 +1,92 @@
1
+ # 0.5.0 / 2016-06-30
2
+
3
+ ## Added
4
+
5
+ - 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)
6
+
7
+ ```ruby
8
+ # Match `[:ok, some_value]` for success
9
+ success_case = Dry::Matcher::Case.new(
10
+ match: -> value { value.first == :ok },
11
+ resolve: -> value { value.last }
12
+ )
13
+
14
+ # Match `[:err, some_error_code, some_value]` for failure
15
+ failure_case = Dry::Matcher::Case.new(
16
+ match: -> value, *pattern {
17
+ value[0] == :err && (pattern.any? ? pattern.include?(value[1]) : true)
18
+ },
19
+ resolve: -> value { value.last }
20
+ )
21
+
22
+ # Build the matcher
23
+ matcher = Dry::Matcher.new(success: success_case, failure: failure_case)
24
+
25
+ # Then put it to use
26
+ my_success = [:ok, "success!"]
27
+
28
+ result = matcher.(my_success) do |m|
29
+ m.success do |v|
30
+ "Yay: #{v}"
31
+ end
32
+
33
+ m.failure :not_found do |v|
34
+ "Oops, not found: #{v}"
35
+ end
36
+
37
+ m.failure do |v|
38
+ "Boo: #{v}"
39
+ end
40
+ end
41
+
42
+ result # => "Yay: success!"
43
+ ```
44
+
45
+ ## Changed
46
+
47
+ - 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)
48
+ - `Dry::Matcher.for` requires a matcher object to be passed when being included in a class:
49
+
50
+ ```ruby
51
+ MyMatcher = Dry::Matcher.new(...)
52
+
53
+ class MyOperation
54
+ include Dry::Matcher.for(:call, with: MyMatcher)
55
+
56
+ def call
57
+ end
58
+ end
59
+ ```
60
+ - The previous `Dry::ResultMatcher.match` behaviour (for matching `Either` monads) has been moved to `Dry::Matcher::EitherMatcher.call`
61
+
62
+ # 0.4.0 / 2016-06-08
63
+
64
+ ## Added
65
+
66
+ * Support convertible result objects responding to `#to_either` (ttdonovan)
67
+
68
+ ## Changed
69
+
70
+ * Expect monads from [dry-monads](https://github.com/dry-rb/dry-monads) instead of [Kleisli](https://github.com/txus/kleisli) (ttdonovan)
71
+
72
+ [Compare v0.3.0...v0.4.0](https://github.com/dry-rb/dry-result_matcher/compare/v0.3.0...v0.4.0)
73
+
74
+ # 0.3.0 / 2016-03-23
75
+
76
+ ## Changed
77
+
78
+ * Renamed to `dry-result_matcher`. Match results using `Dry::ResultMatcher.match` or extend your own classes with `Dry::ResultMatcher.for`.
79
+
80
+ [Compare v0.2.0...v0.3.0](https://github.com/dry-rb/dry-result_matcher/compare/v0.2.0...v0.3.0)
81
+
82
+ # 0.2.0 / 2016-02-10
83
+
84
+ ## Added
85
+
86
+ * 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)`.
87
+
88
+ [Compare v0.1.0...v0.22.0](https://github.com/dry-rb/dry-result_matcher/compare/v0.1.0...v0.2.0)
89
+
90
+ # 0.1.0 / 2015-12-03
91
+
92
+ Initial release.
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem "codeclimate-test-reporter", "~> 0.5.0"
7
+ gem "dry-monads", "~> 0.0.2"
8
+ end
9
+
10
+ group :tools do
11
+ gem "byebug", platform: :mri
12
+ gem "pry"
13
+ end
data/LICENSE.md ADDED
@@ -0,0 +1,9 @@
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/README.md ADDED
@@ -0,0 +1,23 @@
1
+ [gitter]: https://gitter.im/dry-rb/chat
2
+ [gem]: https://rubygems.org/gems/dry-matcher
3
+ [travis]: https://travis-ci.org/dry-rb/dry-matcher
4
+ [code_climate]: https://codeclimate.com/github/dry-rb/dry-matcher
5
+ [inch]: http://inch-ci.org/github/dry-rb/dry-matcher
6
+
7
+ # dry-matcher [![Join the Gitter chat](https://badges.gitter.im/Join%20Chat.svg)][gitter]
8
+
9
+ [![Gem Version](https://img.shields.io/gem/v/dry-matcher.svg)][gem]
10
+ [![Build Status](https://img.shields.io/travis/dry-rb/dry-matcher.svg)][travis]
11
+ [![Code Climate](https://img.shields.io/codeclimate/github/dry-rb/dry-matcher.svg)][code_climate]
12
+ [![Test Coverage](https://img.shields.io/codeclimate/coverage/github/dry-rb/dry-matcher.svg)][code_climate]
13
+ [![API Documentation Coverage](http://inch-ci.org/github/dry-rb/dry-matcher.svg)][inch]
14
+
15
+ Flexible, expressive pattern matching for Ruby.
16
+
17
+ ## Links
18
+
19
+ * [Documentation](http://dry-rb.org/gems/dry-matcher)
20
+
21
+ ## License
22
+
23
+ Copyright © 2015-2016 [Icelab](http://icelab.com.au/). dry-matcher is free software, and may be redistributed under the terms specified in the [license](LICENSE.md).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require "rspec/core/rake_task"
4
+ RSpec::Core::RakeTask.new
5
+
6
+ task default: :spec
@@ -0,0 +1 @@
1
+ require "dry/matcher"
@@ -0,0 +1,42 @@
1
+ require "dry/matcher/case"
2
+ require "dry/matcher/evaluator"
3
+
4
+ module Dry
5
+ class Matcher
6
+ def self.for(*match_methods, with:)
7
+ matcher = with
8
+
9
+ matchers_mod = Module.new do
10
+ match_methods.each do |match_method|
11
+ define_method(match_method) do |*args, &block|
12
+ result = super(*args)
13
+
14
+ if block
15
+ matcher.(result, &block)
16
+ else
17
+ result
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ Module.new do
24
+ const_set :Matchers, matchers_mod
25
+
26
+ def self.included(klass)
27
+ klass.prepend const_get(:Matchers)
28
+ end
29
+ end
30
+ end
31
+
32
+ attr_reader :cases
33
+
34
+ def initialize(cases = {})
35
+ @cases = cases
36
+ end
37
+
38
+ def call(result, &block)
39
+ Evaluator.new(result, cases).call(&block)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,18 @@
1
+ module Dry
2
+ class Matcher
3
+ class Case
4
+ def initialize(match:, resolve:)
5
+ @match = match
6
+ @resolve = resolve
7
+ end
8
+
9
+ def matches?(value, *pattern)
10
+ @match.(value, *pattern)
11
+ end
12
+
13
+ def resolve(value)
14
+ @resolve.(value)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,28 @@
1
+ require "dry/matcher"
2
+
3
+ module Dry
4
+ class Matcher
5
+ EitherMatcher = Dry::Matcher.new(
6
+ success: Case.new(
7
+ match: -> result, *pattern {
8
+ result = result.to_either
9
+ result.right?
10
+ },
11
+ resolve: -> result {
12
+ result = result.to_either
13
+ result.value
14
+ },
15
+ ),
16
+ failure: Case.new(
17
+ match: -> result, *pattern {
18
+ result = result.to_either
19
+ result.left?
20
+ },
21
+ resolve: -> result {
22
+ result = result.to_either
23
+ result.value
24
+ },
25
+ )
26
+ )
27
+ end
28
+ end
@@ -0,0 +1,38 @@
1
+ module Dry
2
+ class Matcher
3
+ class Evaluator < BasicObject
4
+ def initialize(result, cases)
5
+ @cases = cases
6
+ @result = result
7
+ @matched = false
8
+ @output = nil
9
+ end
10
+
11
+ def call
12
+ yield self
13
+ @output
14
+ end
15
+
16
+ def respond_to_missing?(name, include_private = false)
17
+ @cases.key?(name) || super
18
+ end
19
+
20
+ def method_missing(name, *args, &block)
21
+ return super unless @cases.key?(name)
22
+
23
+ handle_case @cases[name], *args, &block
24
+ end
25
+
26
+ private
27
+
28
+ def handle_case(kase, *pattern)
29
+ return @output if @matched
30
+
31
+ if kase.matches?(@result, *pattern)
32
+ @matched = true
33
+ @output = yield(kase.resolve(@result))
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,5 @@
1
+ module Dry
2
+ class Matcher
3
+ VERSION = "0.5.0".freeze
4
+ end
5
+ end
data/spec/examples.txt ADDED
@@ -0,0 +1,14 @@
1
+ example_id | status | run_time |
2
+ ----------------------------------------------------- | ------ | --------------- |
3
+ ./spec/integration/class_enhancement_spec.rb[1:1:1:1] | passed | 0.00016 seconds |
4
+ ./spec/integration/class_enhancement_spec.rb[1:1:2:1] | passed | 0.00013 seconds |
5
+ ./spec/integration/class_enhancement_spec.rb[1:2:1:1] | passed | 0.00022 seconds |
6
+ ./spec/integration/class_enhancement_spec.rb[1:2:2:1] | passed | 0.00141 seconds |
7
+ ./spec/integration/either_matcher_spec.rb[1:1:1:1] | passed | 0.00008 seconds |
8
+ ./spec/integration/either_matcher_spec.rb[1:1:2:1] | passed | 0.00008 seconds |
9
+ ./spec/integration/either_matcher_spec.rb[1:1:3:1:1] | passed | 0.00015 seconds |
10
+ ./spec/integration/either_matcher_spec.rb[1:1:3:2:1] | passed | 0.00016 seconds |
11
+ ./spec/integration/matcher_spec.rb[1:1:1] | passed | 0.00013 seconds |
12
+ ./spec/integration/matcher_spec.rb[1:1:2] | passed | 0.00012 seconds |
13
+ ./spec/integration/matcher_spec.rb[1:1:3:1] | passed | 0.00015 seconds |
14
+ ./spec/integration/matcher_spec.rb[1:1:3:2] | passed | 0.00224 seconds |
@@ -0,0 +1,64 @@
1
+ require "dry-monads"
2
+ require "dry/matcher/either_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::EitherMatcher)
8
+
9
+ def call(bool)
10
+ bool ? Dry::Monads::Right("a success") : Dry::Monads::Left("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::Right("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::Left("a failure")
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,56 @@
1
+ require "dry-monads"
2
+ require "dry/matcher/either_matcher"
3
+
4
+ RSpec.describe "Dry::Matcher::EitherMatcher" do
5
+ describe "external matching" do
6
+ subject(:match) {
7
+ Dry::Matcher::EitherMatcher.(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::Right("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::Left("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 either" 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
@@ -0,0 +1,77 @@
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.right? },
8
+ resolve: -> result { result.value },
9
+ )
10
+ }
11
+
12
+ let(:failure_case) {
13
+ Dry::Matcher::Case.new(
14
+ match: -> result { result.left? },
15
+ resolve: -> result { result.value },
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::Right("Yes!")
40
+ expect(call_match(input)).to eq "Success: Yes!"
41
+ end
42
+
43
+ it "matches on failure" do
44
+ input = Dry::Monads::Left("No!")
45
+ expect(call_match(input)).to eq "Failure: No!"
46
+ end
47
+
48
+ context "with patterns" do
49
+ let(:failure_case) {
50
+ Dry::Matcher::Case.new(
51
+ match: -> result, failure_type {
52
+ result.length == 3 && result[0] == :failure && result[1] == failure_type
53
+ },
54
+ resolve: -> result { result.last },
55
+ )
56
+ }
57
+
58
+ def call_match(input)
59
+ matcher.(input) do |m|
60
+ m.failure :my_error do |v|
61
+ "Pattern-matched failure: #{v}"
62
+ end
63
+ end
64
+ end
65
+
66
+ it "matches using the provided pattern" do
67
+ input = [:failure, :my_error, "No!"]
68
+ expect(call_match(input)).to eq "Pattern-matched failure: No!"
69
+ end
70
+
71
+ it "doesn't match if the pattern doesn't match" do
72
+ input = [:failure, :non_matching_error, "No!"]
73
+ expect(call_match(input)).to be_nil
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,60 @@
1
+ if RUBY_ENGINE == "ruby"
2
+ require "codeclimate-test-reporter"
3
+ CodeClimate::TestReporter.start
4
+
5
+ SimpleCov.start do
6
+ add_filter "/spec/"
7
+ end
8
+ end
9
+
10
+ begin
11
+ require "byebug"
12
+ rescue LoadError; end
13
+
14
+ require "dry-matcher"
15
+
16
+ Dir[File.join(File.dirname(__FILE__), "support/**/*.rb")].each do |f| require f end
17
+
18
+ RSpec.configure do |config|
19
+ config.disable_monkey_patching!
20
+
21
+ config.expect_with :rspec do |expectations|
22
+ # This option will default to `true` in RSpec 4.
23
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
24
+ end
25
+
26
+ config.mock_with :rspec do |mocks|
27
+ # This option will default to `true` in RSpec 4.
28
+ mocks.verify_partial_doubles = true
29
+ end
30
+
31
+ # Allows RSpec to persist some state between runs in order to support
32
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
33
+ # you configure your source control system to ignore this file.
34
+ config.example_status_persistence_file_path = "spec/examples.txt"
35
+
36
+ # This setting enables warnings. It's recommended, but in some cases may
37
+ # be too noisy due to issues in dependencies.
38
+ config.warnings = true
39
+
40
+ # Many RSpec users commonly either run the entire suite or an individual
41
+ # file, and it's useful to allow more verbose output when running an
42
+ # individual spec file.
43
+ if config.files_to_run.one?
44
+ # Use the documentation formatter for detailed output, unless a formatter
45
+ # has already been configured (e.g. via a command-line flag).
46
+ config.default_formatter = "doc"
47
+ end
48
+
49
+ # Run specs in random order to surface order dependencies. If you find an
50
+ # order dependency and want to debug it, you can fix the order by providing
51
+ # the seed, which is printed after each run.
52
+ # --seed 1234
53
+ config.order = :random
54
+
55
+ # Seed global randomization in this process using the `--seed` CLI option.
56
+ # Setting this allows you to use `--seed` to deterministically reproduce
57
+ # test failures related to randomization by passing the same `--seed` value
58
+ # as the one that triggered the failure.
59
+ Kernel.srand config.seed
60
+ end
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dry-matcher
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ platform: ruby
6
+ authors:
7
+ - Tim Riley
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-06-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
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
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 3.3.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 3.3.0
55
+ - !ruby/object:Gem::Dependency
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
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.10.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: yard
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Flexible, expressive pattern matching for Ruby
84
+ email:
85
+ - tim@icelab.com.au
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - CHANGELOG.md
91
+ - Gemfile
92
+ - LICENSE.md
93
+ - README.md
94
+ - Rakefile
95
+ - lib/dry-matcher.rb
96
+ - lib/dry/matcher.rb
97
+ - lib/dry/matcher/case.rb
98
+ - lib/dry/matcher/either_matcher.rb
99
+ - lib/dry/matcher/evaluator.rb
100
+ - lib/dry/matcher/version.rb
101
+ - spec/examples.txt
102
+ - spec/integration/class_enhancement_spec.rb
103
+ - spec/integration/either_matcher_spec.rb
104
+ - spec/integration/matcher_spec.rb
105
+ - spec/spec_helper.rb
106
+ homepage: http://dry-rb.org/gems/dry-matcher
107
+ licenses:
108
+ - MIT
109
+ metadata: {}
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: 2.1.0
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubyforge_project:
126
+ rubygems_version: 2.5.1
127
+ signing_key:
128
+ specification_version: 4
129
+ summary: Flexible, expressive pattern matching for Ruby
130
+ test_files: []
131
+ has_rdoc: