blood_contracts-ext 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.rubocop.yml +31 -0
- data/.travis.yml +19 -0
- data/CHANGELOG.md +23 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +369 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/blood_contracts-ext.gemspec +27 -0
- data/lib/blood_contracts/core/defineable_error.rb +61 -0
- data/lib/blood_contracts/core/exception_caught.rb +33 -0
- data/lib/blood_contracts/core/exception_handling.rb +36 -0
- data/lib/blood_contracts/core/expected_error.rb +16 -0
- data/lib/blood_contracts/core/extractable.rb +85 -0
- data/lib/blood_contracts/core/map_value.rb +45 -0
- data/lib/blood_contracts/core/policy_failure.rb +42 -0
- data/lib/blood_contracts/core/sum_policy_failure.rb +9 -0
- data/lib/blood_contracts/core/tuple_policy_failure.rb +39 -0
- data/lib/blood_contracts/ext/pipe.rb +27 -0
- data/lib/blood_contracts/ext/refined.rb +59 -0
- data/lib/blood_contracts/ext/sum.rb +29 -0
- data/lib/blood_contracts/ext/tuple.rb +28 -0
- data/lib/blood_contracts/ext.rb +28 -0
- data/spec/blood_contracts/ext/exception_caught_spec.rb +50 -0
- data/spec/blood_contracts/ext/expected_error_spec.rb +56 -0
- data/spec/blood_contracts/ext/map_value_spec.rb +54 -0
- data/spec/blood_contracts/ext/policy_failure_spec.rb +151 -0
- data/spec/blood_contracts/ext/policy_spec.rb +138 -0
- data/spec/fixtures/en.yml +19 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/support/fixtures_helper.rb +11 -0
- metadata +202 -0
@@ -0,0 +1,54 @@
|
|
1
|
+
RSpec.describe BloodContracts::Core::MapValue do
|
2
|
+
before do
|
3
|
+
module Test
|
4
|
+
require "forwardable"
|
5
|
+
|
6
|
+
class JsonMapper
|
7
|
+
def self.call(**payload)
|
8
|
+
JSON.pretty_generate(payload)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class ContactType < ::BC::Ext::Refined
|
13
|
+
extend Forwardable
|
14
|
+
extract :name
|
15
|
+
extract :phone
|
16
|
+
extract :manager_id
|
17
|
+
|
18
|
+
def_delegators :@value, :name, :phone, :manager_id
|
19
|
+
end
|
20
|
+
|
21
|
+
ContactJsonType = ContactType.and_then(BC::MapValue.with(JsonMapper))
|
22
|
+
Contact = Struct.new(:name, :phone, :manager_id)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
subject { Test::ContactJsonType.match(value) }
|
27
|
+
|
28
|
+
context "when value is a valid contact" do
|
29
|
+
let(:value) { Test::Contact.new("Nick Cage", "2-333-111-444", 4113) }
|
30
|
+
let(:valid_json) do
|
31
|
+
<<~JSON.strip
|
32
|
+
{
|
33
|
+
"name": "Nick Cage",
|
34
|
+
"phone": "2-333-111-444",
|
35
|
+
"manager_id": 4113
|
36
|
+
}
|
37
|
+
JSON
|
38
|
+
end
|
39
|
+
|
40
|
+
it do
|
41
|
+
is_expected.to be_valid
|
42
|
+
expect(subject.unpack).to eq(valid_json)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "when value is an invalid contact" do
|
47
|
+
let(:value) { "Nick Cage, 2-333-111-444, 4113" }
|
48
|
+
|
49
|
+
it do
|
50
|
+
is_expected.to be_invalid
|
51
|
+
is_expected.to match(kind_of(::BC::ExceptionCaught))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
RSpec.describe BloodContracts::Core::PolicyFailure do
|
2
|
+
before do
|
3
|
+
module Test
|
4
|
+
class Phone < ::BC::Ext::Refined
|
5
|
+
REGEX = /\A(\+7|8)(9|8)\d{9}\z/i
|
6
|
+
|
7
|
+
def match
|
8
|
+
context[:phone_input] = value.to_s
|
9
|
+
clean_phone = context[:phone_input].gsub(/[\s\(\)-]/, "")
|
10
|
+
return failure(:invalid_phone) if clean_phone !~ REGEX
|
11
|
+
context[:clean_phone] = clean_phone
|
12
|
+
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def mapped
|
17
|
+
context[:clean_phone]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Email < ::BC::Ext::Refined
|
22
|
+
REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
|
23
|
+
INVALID_EMAIL = define_error(:invalid_email)
|
24
|
+
|
25
|
+
def match
|
26
|
+
context[:email_input] = value.to_s
|
27
|
+
return failure(INVALID_EMAIL) if context[:email_input] !~ REGEX
|
28
|
+
context[:email] = context[:email_input]
|
29
|
+
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
def mapped
|
34
|
+
context[:email]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class Ascii < ::BC::Ext::Refined
|
39
|
+
REGEX = /^[[:ascii:]]+$/i
|
40
|
+
|
41
|
+
def match
|
42
|
+
context[:ascii_input] = value.to_s
|
43
|
+
return failure("Not ASCII") if context[:ascii_input] !~ REGEX
|
44
|
+
context[:ascii] = context[:ascii_input]
|
45
|
+
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
def mapped
|
50
|
+
context[:ascii]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
Login = Email.or_a(Phone)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "Errors composition with Tram::Policy::Errors" do
|
59
|
+
context "when using `OR` composition" do
|
60
|
+
subject { Test::Login.match(value) }
|
61
|
+
|
62
|
+
context "when value is invalid" do
|
63
|
+
let(:value) { "tasf" }
|
64
|
+
let(:errors_list) do
|
65
|
+
[
|
66
|
+
{ Test::Login => [kind_of(Tram::Policy::Errors)] },
|
67
|
+
{ Test::Email => [kind_of(Tram::Policy::Errors)] },
|
68
|
+
{ Test::Phone => [kind_of(Tram::Policy::Errors)] }
|
69
|
+
]
|
70
|
+
end
|
71
|
+
let(:policy_errors) do
|
72
|
+
[
|
73
|
+
kind_of(Tram::Policy::Errors),
|
74
|
+
kind_of(Tram::Policy::Errors)
|
75
|
+
]
|
76
|
+
end
|
77
|
+
let(:validation_context) { { phone_input: value, email_input: value } }
|
78
|
+
let(:messages) do
|
79
|
+
[
|
80
|
+
"Value `tasf` is not a valid phone",
|
81
|
+
"Given value is not a valid email"
|
82
|
+
]
|
83
|
+
end
|
84
|
+
|
85
|
+
it do
|
86
|
+
is_expected.to be_invalid
|
87
|
+
expect { subject.unpack }.not_to raise_error
|
88
|
+
expect(subject.errors).to match_array(errors_list)
|
89
|
+
expect(subject.policy_errors).to match(policy_errors)
|
90
|
+
expect(subject.messages).to match_array(messages)
|
91
|
+
expect(subject.context).to include(validation_context)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "when using `AND` composition" do
|
97
|
+
subject { Test::RegistrationInput.match(email, phone) }
|
98
|
+
|
99
|
+
before do
|
100
|
+
module Test
|
101
|
+
class RegistrationInput < ::BC::Ext::Tuple
|
102
|
+
attribute :login, Login
|
103
|
+
attribute :password, Ascii
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context "when input is invalid" do
|
109
|
+
let(:email) { "admin" }
|
110
|
+
let(:phone) { "not_a_phone" }
|
111
|
+
let(:login_error) { { Test::Login => [kind_of(Tram::Policy::Errors)] } }
|
112
|
+
let(:password) { "newP@ssw0rd" }
|
113
|
+
let(:attributes) do
|
114
|
+
attribute_errors.merge(password: kind_of(Test::Ascii))
|
115
|
+
end
|
116
|
+
let(:attribute_errors) do
|
117
|
+
{
|
118
|
+
login: kind_of(BC::PolicyFailure),
|
119
|
+
base: kind_of(BC::TuplePolicyFailure)
|
120
|
+
}
|
121
|
+
end
|
122
|
+
let(:errors) do
|
123
|
+
[
|
124
|
+
{ Test::Email => [kind_of(Tram::Policy::Errors)] },
|
125
|
+
{ Test::Phone => [kind_of(Tram::Policy::Errors)] },
|
126
|
+
{ Test::Login => [kind_of(Tram::Policy::Errors)] },
|
127
|
+
{ Test::RegistrationInput => [kind_of(Tram::Policy::Errors)] }
|
128
|
+
]
|
129
|
+
end
|
130
|
+
let(:attribute_messages) do
|
131
|
+
{
|
132
|
+
login: [
|
133
|
+
"Given value is not a valid email",
|
134
|
+
"Value `admin` is not a valid phone"
|
135
|
+
],
|
136
|
+
base: ["Data for registration is invalid"]
|
137
|
+
}
|
138
|
+
end
|
139
|
+
|
140
|
+
it do
|
141
|
+
expect(subject).to be_invalid
|
142
|
+
expect(subject.attributes).to match(attributes)
|
143
|
+
expect(subject.to_h).to match(hash_including(login: login_error))
|
144
|
+
expect(subject.errors).to match_array(errors)
|
145
|
+
expect(subject.attribute_errors).to match(attribute_errors)
|
146
|
+
expect(subject.attribute_messages).to match(attribute_messages)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
RSpec.describe "BC::Ext::Refined validation delegated to Tram::Policy" do
|
2
|
+
before do
|
3
|
+
module Test
|
4
|
+
class AddressPolicy < Tram::Policy
|
5
|
+
option :country_code
|
6
|
+
option :city
|
7
|
+
option :street
|
8
|
+
|
9
|
+
validate :city_correctness
|
10
|
+
validate :country_code_correctness
|
11
|
+
validate :street_correctness
|
12
|
+
|
13
|
+
def country_code_correctness
|
14
|
+
return if country_code.to_s.size == 2
|
15
|
+
errors.add :invalid_country_code, value: country_code
|
16
|
+
end
|
17
|
+
|
18
|
+
def city_correctness
|
19
|
+
return if (2..30).cover?(city.to_s.size)
|
20
|
+
errors.add :invalid_city_name, value: city
|
21
|
+
end
|
22
|
+
|
23
|
+
def street_correctness
|
24
|
+
return if (5..75).cover?(street.to_s.size)
|
25
|
+
errors.add :invalid_street, value: street
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class AddressType < BC::Ext::Refined
|
30
|
+
self.policy = AddressPolicy
|
31
|
+
|
32
|
+
extract :city
|
33
|
+
extract :country_code, method_name: :country
|
34
|
+
extract :street
|
35
|
+
|
36
|
+
def city
|
37
|
+
return value.city if value.respond_to?(:city)
|
38
|
+
stringify_hash_keys(value.to_h)
|
39
|
+
.values_at("city", "City")
|
40
|
+
.compact
|
41
|
+
.first
|
42
|
+
end
|
43
|
+
|
44
|
+
def country
|
45
|
+
return value.country if value.respond_to?(:country)
|
46
|
+
stringify_hash_keys(value.to_h)
|
47
|
+
.values_at("country", "country_code", "CountryCode")
|
48
|
+
.compact
|
49
|
+
.first
|
50
|
+
end
|
51
|
+
|
52
|
+
def street
|
53
|
+
return value.street if value.respond_to?(:street)
|
54
|
+
stringify_hash_keys(value.to_h)
|
55
|
+
.values_at("street", "street_line", "StreetLine")
|
56
|
+
.compact
|
57
|
+
.first
|
58
|
+
end
|
59
|
+
|
60
|
+
private def stringify_hash_keys(hash)
|
61
|
+
hash.reduce({}) { |a, (k, v)| a.merge!(k.to_s => v) }
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
Address = Struct.new(:country, :city, :street)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
subject { Test::AddressType.match(value) }
|
71
|
+
|
72
|
+
context "when input is valid address" do
|
73
|
+
let(:mapped_data) do
|
74
|
+
{ city: "Moscow", country_code: "RU", street: "ul. Novoslobodskaya" }
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when value is an Test::Address" do
|
78
|
+
let(:value) do
|
79
|
+
Test::Address.new("RU", "Moscow", "ul. Novoslobodskaya")
|
80
|
+
end
|
81
|
+
|
82
|
+
it do
|
83
|
+
expect(subject).to be_valid
|
84
|
+
expect(subject).to be_kind_of(Test::AddressType)
|
85
|
+
expect(subject.unpack).to match(mapped_data)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context "when value is a parsed json" do
|
90
|
+
let(:json) do
|
91
|
+
'{"CountryCode": "RU", '\
|
92
|
+
'"City": "Moscow", '\
|
93
|
+
'"StreetLine": "ul. Novoslobodskaya"}'
|
94
|
+
end
|
95
|
+
let(:value) { JSON.parse(json) }
|
96
|
+
|
97
|
+
it do
|
98
|
+
expect(subject).to be_valid
|
99
|
+
expect(subject).to be_kind_of(Test::AddressType)
|
100
|
+
expect(subject.unpack).to match(mapped_data)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context "when input is invalid address" do
|
106
|
+
let(:mapped_data) do
|
107
|
+
{ Test::AddressType => [kind_of(Tram::Policy::Errors)] }
|
108
|
+
end
|
109
|
+
let(:error_messages) do
|
110
|
+
["The value `M` is not a valid city name",
|
111
|
+
"The value `RUS` is not a valid ISO country code",
|
112
|
+
"The value `ul` is not a valid street"]
|
113
|
+
end
|
114
|
+
|
115
|
+
context "when value is an Test::Address" do
|
116
|
+
let(:value) { Test::Address.new("RUS", "M", "ul") }
|
117
|
+
|
118
|
+
it do
|
119
|
+
expect(subject).to be_invalid
|
120
|
+
expect(subject).to be_kind_of(BC::PolicyFailure)
|
121
|
+
expect(subject.unpack).to match(mapped_data)
|
122
|
+
expect(subject.messages).to match(error_messages)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "when value is a parsed json" do
|
127
|
+
let(:json) { '{"country": "RUS", "city": "M", "street": "ul"}' }
|
128
|
+
let(:value) { JSON.parse(json) }
|
129
|
+
|
130
|
+
it do
|
131
|
+
expect(subject).to be_invalid
|
132
|
+
expect(subject).to be_kind_of(BC::PolicyFailure)
|
133
|
+
expect(subject.unpack).to match(mapped_data)
|
134
|
+
expect(subject.messages).to match(error_messages)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
---
|
2
|
+
en:
|
3
|
+
bad: Something bad has happened
|
4
|
+
contracts:
|
5
|
+
test/email:
|
6
|
+
invalid_email: Given value is not a valid email
|
7
|
+
test/phone:
|
8
|
+
invalid_phone: Value `%{phone_input}` is not a valid phone
|
9
|
+
test/login:
|
10
|
+
no_matches: Data for login is invalid
|
11
|
+
test/registration_input:
|
12
|
+
invalid_tuple: Data for registration is invalid
|
13
|
+
test/plain_text_error:
|
14
|
+
message: "Service responded with a message: `%{plain_text}`"
|
15
|
+
tram-policy:
|
16
|
+
test/address_policy:
|
17
|
+
invalid_city_name: The value `%{value}` is not a valid city name
|
18
|
+
invalid_country_code: The value `%{value}` is not a valid ISO country code
|
19
|
+
invalid_street: The value `%{value}` is not a valid street
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
require "blood_contracts/ext"
|
3
|
+
|
4
|
+
require_relative "support/fixtures_helper.rb"
|
5
|
+
|
6
|
+
RSpec.configure do |config|
|
7
|
+
# Enable flags like --only-failures and --next-failure
|
8
|
+
config.example_status_persistence_file_path = ".rspec_status"
|
9
|
+
|
10
|
+
# Disable RSpec exposing methods globally on `Module` and `main`
|
11
|
+
config.disable_monkey_patching!
|
12
|
+
|
13
|
+
config.expect_with :rspec do |c|
|
14
|
+
c.syntax = :expect
|
15
|
+
end
|
16
|
+
|
17
|
+
config.around do |example|
|
18
|
+
I18n.available_locales = %w[en]
|
19
|
+
I18n.backend.store_translations :en, yaml_fixture_file("en.yml")["en"]
|
20
|
+
module Test; end
|
21
|
+
example.run
|
22
|
+
Object.send(:remove_const, :Test)
|
23
|
+
end
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,202 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: blood_contracts-ext
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sergey Dolganov (sclinede)
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-07-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: blood_contracts-core
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.4'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.4'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: tram-policy
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: i18n
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
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
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '10.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '10.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubocop
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0.49'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0.49'
|
125
|
+
description: Extra helpers for BloodContracts::Core
|
126
|
+
email:
|
127
|
+
- sclinede@evilmartians.com
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files:
|
131
|
+
- CODE_OF_CONDUCT.md
|
132
|
+
- README.md
|
133
|
+
- LICENSE
|
134
|
+
- CHANGELOG.md
|
135
|
+
files:
|
136
|
+
- ".gitignore"
|
137
|
+
- ".rspec"
|
138
|
+
- ".rubocop.yml"
|
139
|
+
- ".travis.yml"
|
140
|
+
- CHANGELOG.md
|
141
|
+
- CODE_OF_CONDUCT.md
|
142
|
+
- Gemfile
|
143
|
+
- LICENSE
|
144
|
+
- README.md
|
145
|
+
- Rakefile
|
146
|
+
- bin/console
|
147
|
+
- bin/setup
|
148
|
+
- blood_contracts-ext.gemspec
|
149
|
+
- lib/blood_contracts/core/defineable_error.rb
|
150
|
+
- lib/blood_contracts/core/exception_caught.rb
|
151
|
+
- lib/blood_contracts/core/exception_handling.rb
|
152
|
+
- lib/blood_contracts/core/expected_error.rb
|
153
|
+
- lib/blood_contracts/core/extractable.rb
|
154
|
+
- lib/blood_contracts/core/map_value.rb
|
155
|
+
- lib/blood_contracts/core/policy_failure.rb
|
156
|
+
- lib/blood_contracts/core/sum_policy_failure.rb
|
157
|
+
- lib/blood_contracts/core/tuple_policy_failure.rb
|
158
|
+
- lib/blood_contracts/ext.rb
|
159
|
+
- lib/blood_contracts/ext/pipe.rb
|
160
|
+
- lib/blood_contracts/ext/refined.rb
|
161
|
+
- lib/blood_contracts/ext/sum.rb
|
162
|
+
- lib/blood_contracts/ext/tuple.rb
|
163
|
+
- spec/blood_contracts/ext/exception_caught_spec.rb
|
164
|
+
- spec/blood_contracts/ext/expected_error_spec.rb
|
165
|
+
- spec/blood_contracts/ext/map_value_spec.rb
|
166
|
+
- spec/blood_contracts/ext/policy_failure_spec.rb
|
167
|
+
- spec/blood_contracts/ext/policy_spec.rb
|
168
|
+
- spec/fixtures/en.yml
|
169
|
+
- spec/spec_helper.rb
|
170
|
+
- spec/support/fixtures_helper.rb
|
171
|
+
homepage: https://github.com/sclinede/blood_contracts-ext
|
172
|
+
licenses:
|
173
|
+
- MIT
|
174
|
+
metadata: {}
|
175
|
+
post_install_message:
|
176
|
+
rdoc_options: []
|
177
|
+
require_paths:
|
178
|
+
- lib
|
179
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
180
|
+
requirements:
|
181
|
+
- - ">="
|
182
|
+
- !ruby/object:Gem::Version
|
183
|
+
version: '2.4'
|
184
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
185
|
+
requirements:
|
186
|
+
- - ">="
|
187
|
+
- !ruby/object:Gem::Version
|
188
|
+
version: '0'
|
189
|
+
requirements: []
|
190
|
+
rubygems_version: 3.0.3
|
191
|
+
signing_key:
|
192
|
+
specification_version: 4
|
193
|
+
summary: Extra helpers for BloodContracts::Core
|
194
|
+
test_files:
|
195
|
+
- spec/blood_contracts/ext/exception_caught_spec.rb
|
196
|
+
- spec/blood_contracts/ext/expected_error_spec.rb
|
197
|
+
- spec/blood_contracts/ext/map_value_spec.rb
|
198
|
+
- spec/blood_contracts/ext/policy_failure_spec.rb
|
199
|
+
- spec/blood_contracts/ext/policy_spec.rb
|
200
|
+
- spec/fixtures/en.yml
|
201
|
+
- spec/spec_helper.rb
|
202
|
+
- spec/support/fixtures_helper.rb
|