blood_contracts 0.2.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +63 -119
- data/Rakefile +30 -0
- data/bin/console +3 -2
- data/blood_contracts.gemspec +10 -27
- data/lib/blood_contracts.rb +3 -38
- data/spec/blood_contracts_spec.rb +36 -0
- data/spec/spec_helper.rb +16 -0
- metadata +20 -91
- data/.travis.yml +0 -5
- data/lib/blood_contracts/base_contract.rb +0 -42
- data/lib/blood_contracts/contracts/description.rb +0 -25
- data/lib/blood_contracts/contracts/iterator.rb +0 -34
- data/lib/blood_contracts/contracts/matcher.rb +0 -38
- data/lib/blood_contracts/contracts/statistics.rb +0 -34
- data/lib/blood_contracts/contracts/validator.rb +0 -47
- data/lib/blood_contracts/debugger.rb +0 -39
- data/lib/blood_contracts/runner.rb +0 -92
- data/lib/blood_contracts/storage.rb +0 -79
- data/lib/blood_contracts/storages/base_backend.rb +0 -59
- data/lib/blood_contracts/storages/file_backend.rb +0 -108
- data/lib/blood_contracts/storages/serializer.rb +0 -38
- data/lib/blood_contracts/suite.rb +0 -41
- data/lib/blood_contracts/version.rb +0 -3
- data/lib/extensions/string.rb +0 -31
- data/lib/rspec/meet_contract_matcher.rb +0 -106
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2c47ef6538d2aa19e88887ae50e12dd59518fa31077b75dbdf8c5d143cea7a2
|
4
|
+
data.tar.gz: 1bc58ec7ce70d3490454a123cf10dcdee4f97b9a94dc1129a1177319ec11d02a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b8a1a15937a6b35cdce7223d15efad1c5bc06edcb1eaabfcc34d0cf22ccceeb273ba0b6ed8da2c92ba7896fc0dc33fc20840a8c4f8f9b0f1329c2c9086d732c
|
7
|
+
data.tar.gz: a82397121b167e929cae791fcfefccf6aa90509606ca7836ca9640b580720a993ee4cd046c23e74a688540447878bf4a7b4ee8fb6e3f51439e7b8640c2fcf9ab
|
data/README.md
CHANGED
@@ -1,14 +1,68 @@
|
|
1
|
+
[adt_wiki]: https://en.wikipedia.org/wiki/Algebraic_data_type
|
2
|
+
[functional_programming_wiki]: https://en.wikipedia.org/wiki/Functional_programming
|
3
|
+
[refinement_types_wiki]: https://en.wikipedia.org/wiki/Refinement_type
|
4
|
+
[ebaymag]: https://ebaymag.com/
|
5
|
+
|
1
6
|
# BloodContracts
|
2
7
|
|
3
|
-
Ruby
|
8
|
+
Simple and agile Ruby data validation tool inspired by refinement types and functional approach
|
9
|
+
|
10
|
+
* **Powerful**. [Algebraic Data Type][adt_wiki] guarantees that gem is enough to implement any kind of complex data validation, while [Functional Approach][functional_programming_wiki] gives you full control over validation outcomes
|
11
|
+
* **Simple**. You could write your first [Refinment Type][refinement_types_wiki] as simple as single Ruby method in single class
|
12
|
+
* **Brings transparency**. Comes with instrumentation tools, so now you will exactly know how often each type matches in your production
|
13
|
+
* **Rubyish**. DSL is inspired by Ruby Struct. If you love Ruby way you'd like the BloodContracts types
|
14
|
+
* **Born in production**. Created on basis of [eBaymag][ebaymag] project, used as a tool to control and monitor data inside API communication
|
4
15
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
16
|
+
```ruby
|
17
|
+
# Write your "types" as simple as...
|
18
|
+
class Email < ::BC::Refined
|
19
|
+
REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
|
9
20
|
|
10
|
-
|
11
|
-
|
21
|
+
def match
|
22
|
+
return if (context[:email] = value.to_s) =~ REGEX
|
23
|
+
failure(:invalid_email)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Phone < ::BC::Refined
|
28
|
+
REGEX = /\A(\+7|8)(9|8)\d{9}\z/i
|
29
|
+
|
30
|
+
def match
|
31
|
+
return if (context[:phone] = value.to_s) =~ REGEX
|
32
|
+
failure(:invalid_phone)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# ... compose them...
|
37
|
+
Login = Email.or_a(Phone)
|
38
|
+
|
39
|
+
# ... and match!
|
40
|
+
case match = Login.match("not-a-login")
|
41
|
+
when Phone, Email
|
42
|
+
match # use as you wish, you exactly know what kind of login you received
|
43
|
+
when BC::ContractFailure # translate error message
|
44
|
+
match.messages # => [:no_matches, :invalid_phone, :invalid_email]
|
45
|
+
else raise # to make sure you covered all scenarios (Functional Way)
|
46
|
+
end
|
47
|
+
|
48
|
+
# And then in
|
49
|
+
# config/initializers/contracts.rb
|
50
|
+
|
51
|
+
module Contracts
|
52
|
+
class YabedaInstrument
|
53
|
+
def call(session)
|
54
|
+
valid_marker = session.valid? ? "V" : "I"
|
55
|
+
result = "[#{valid_marker}] #{session.result_type_name}"
|
56
|
+
Yabeda.api_contract_matches.increment(result: result)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
BloodContracts::Instrumentation.configure do |cfg|
|
62
|
+
# Attach to every BC::Refined ancestor with Login in the name
|
63
|
+
cfg.instrument "Login", Contracts::YabedaInstrument.new
|
64
|
+
end
|
65
|
+
```
|
12
66
|
|
13
67
|
## Installation
|
14
68
|
|
@@ -28,120 +82,10 @@ Or install it yourself as:
|
|
28
82
|
|
29
83
|
## Usage
|
30
84
|
|
31
|
-
|
32
|
-
# define contract
|
33
|
-
def contract
|
34
|
-
Hash[
|
35
|
-
success: {
|
36
|
-
check: ->(_input, output) do
|
37
|
-
data = output.data
|
38
|
-
shipping_cost = data.dig(
|
39
|
-
"BkgDetails", "QtdShp", "ShippingCharge"
|
40
|
-
)
|
41
|
-
output.success? && shipping_cost.present?
|
42
|
-
end,
|
43
|
-
threshold: 0.98,
|
44
|
-
},
|
45
|
-
data_missing_error: {
|
46
|
-
check: ->(_input, output) do
|
47
|
-
output.error_codes.present? &&
|
48
|
-
(output.error_codes - ["111"]).empty?
|
49
|
-
end,
|
50
|
-
limit: 0.01,
|
51
|
-
},
|
52
|
-
data_invalid_error: {
|
53
|
-
check: ->(_input, output) do
|
54
|
-
output.error_codes.present? &&
|
55
|
-
(output.error_codes - ["4300", "123454"]).empty?
|
56
|
-
end,
|
57
|
-
limit: 0.01,
|
58
|
-
},
|
59
|
-
strange_weight: {
|
60
|
-
check: ->(input, output) do
|
61
|
-
input.weight > 100 && output.error_codes.empty? && !output.success?
|
62
|
-
end,
|
63
|
-
limit: 0.01,
|
64
|
-
}
|
65
|
-
]
|
66
|
-
end
|
67
|
-
|
68
|
-
# define the API input
|
69
|
-
def generate_data
|
70
|
-
DHL::RequestData.new(
|
71
|
-
data_source.origin_addresses.sample,
|
72
|
-
data_source.destinations.sample,
|
73
|
-
data_source.prices.sample,
|
74
|
-
data_source.products.sample,
|
75
|
-
data_source.weights.sample,
|
76
|
-
data_source.dates.sample.days.since.to_date.to_s(:iso8601),
|
77
|
-
data_source.accounts.sample,
|
78
|
-
).to_h
|
79
|
-
end
|
80
|
-
|
81
|
-
def data_source
|
82
|
-
Hashie::Mash.new(load_fixture("dhl/obfuscated-production-data.yaml"))
|
83
|
-
end
|
84
|
-
|
85
|
-
# initiate contract suite
|
86
|
-
# with default storage (in tmp/blood_contracts/ folder of the project)
|
87
|
-
contract_suite = BloodContract::Suite.new(
|
88
|
-
contract: contract,
|
89
|
-
data_generator: method(:generate_data),
|
90
|
-
)
|
91
|
-
|
92
|
-
# with custom storage backend (e.g. Postgres DB)
|
93
|
-
conn = PG.connect( dbname: "blood_contracts" )
|
94
|
-
conn.exec(<<~SQL);
|
95
|
-
CREATE TABLE runs (
|
96
|
-
created_at timestamp DEFAULT current_timestamp,
|
97
|
-
contract_name text,
|
98
|
-
rules_matched array text[],
|
99
|
-
input text,
|
100
|
-
output text
|
101
|
-
);
|
102
|
-
SQL
|
103
|
-
|
104
|
-
contract_suite = BloodContract::Suite.new(
|
105
|
-
contract: contract,
|
106
|
-
data_generator: method(:generate_data),
|
107
|
-
|
108
|
-
storage_backend: ->(contract_name, rules_matched, input, output) do
|
109
|
-
conn.exec(<<~SQL, contract_name, rules_matched, input, output)
|
110
|
-
INSERT INTO runs (contract_name, rules_matched, input, output) VALUES (?, ?, ?, ?);
|
111
|
-
SQL
|
112
|
-
end
|
113
|
-
)
|
114
|
-
|
115
|
-
# run validation
|
116
|
-
runner = BloodContract::Runner.new(
|
117
|
-
->(input) { DHL::Client.call(input) }
|
118
|
-
suite: contract_suite,
|
119
|
-
time_to_run: 3600, # seconds
|
120
|
-
# or
|
121
|
-
# iterations: 1000
|
122
|
-
).tap(&:call)
|
123
|
-
|
124
|
-
# chech the results
|
125
|
-
runner.valid? # true if behavior was aligned with contract or false in any other case
|
126
|
-
runner.run_stats # stats about each contract rule or exceptions occasions during the run
|
127
|
-
|
128
|
-
```
|
129
|
-
|
130
|
-
## TODO
|
131
|
-
- Add rake task to run contracts validation
|
132
|
-
- Add executable to run contracts validation
|
133
|
-
|
134
|
-
## Possible Features
|
135
|
-
- Store the actual code of the contract rules in Storage (gem 'sourcify')
|
136
|
-
- Store reports in Storage
|
137
|
-
- Export/import contracts to YAML, JSON....
|
138
|
-
- Contracts inheritance (already exists using `Hash#merge`?)
|
139
|
-
- Export `Runner#run_stats` to CSV
|
140
|
-
- Create simple web app, to read the reports
|
85
|
+
This gem is just facade for the whole data validation and monitoring toolset.
|
141
86
|
|
142
|
-
|
87
|
+
For deeper understanding see [BloodContracts::Core](https://github.com/sclinede/blood_contracts-core), [BloodContracts::Ext](https://github.com/sclinede/blood_contracts-ext) and [BloodContracts::Instrumentation](https://github.com/sclinede/blood_contracts-instrumentation)
|
143
88
|
|
144
|
-
For Rack request/response validation use: `blood_contracts-rack`
|
145
89
|
|
146
90
|
## Development
|
147
91
|
|
data/Rakefile
CHANGED
@@ -4,3 +4,33 @@ require "rspec/core/rake_task"
|
|
4
4
|
RSpec::Core::RakeTask.new(:spec)
|
5
5
|
|
6
6
|
task default: :spec
|
7
|
+
task "db:prepare" do
|
8
|
+
require "dotenv"
|
9
|
+
Dotenv.load(".env.development")
|
10
|
+
sh "createdb #{env_database_name}" do
|
11
|
+
# Ignore errors
|
12
|
+
end
|
13
|
+
|
14
|
+
Dotenv.overload(".env.test")
|
15
|
+
sh "createdb #{env_database_name}" do
|
16
|
+
# Ignore errors
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
task "db:drop" do
|
21
|
+
require "dotenv"
|
22
|
+
Dotenv.load(".env.development")
|
23
|
+
sh "dropdb #{env_database_name}" do
|
24
|
+
# Ignore errors
|
25
|
+
end
|
26
|
+
|
27
|
+
Dotenv.overload(".env.test")
|
28
|
+
sh "dropdb #{env_database_name}" do
|
29
|
+
# Ignore errors
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def env_database_name
|
34
|
+
require "uri"
|
35
|
+
ENV.fetch("DATABASE_URL").split("/").last
|
36
|
+
end
|
data/bin/console
CHANGED
@@ -3,9 +3,10 @@
|
|
3
3
|
require "bundler/setup"
|
4
4
|
require "blood_contracts"
|
5
5
|
|
6
|
+
|
6
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
8
|
# with your gem easier. You can also use a different console, if you like.
|
8
9
|
|
9
10
|
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
-
require "
|
11
|
-
|
11
|
+
require "irb"
|
12
|
+
IRB.start
|
data/blood_contracts.gemspec
CHANGED
@@ -1,37 +1,20 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path("../lib", __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require "blood_contracts/version"
|
5
|
-
|
6
1
|
Gem::Specification.new do |spec|
|
7
2
|
spec.name = "blood_contracts"
|
8
3
|
|
9
|
-
spec.version =
|
10
|
-
spec.authors = ["Sergey Dolganov"]
|
11
|
-
spec.email = ["
|
4
|
+
spec.version = "1.0.0"
|
5
|
+
spec.authors = ["Sergey Dolganov (sclinede)"]
|
6
|
+
spec.email = ["sclinede@evilmartians.com"]
|
12
7
|
|
13
|
-
spec.summary = "Ruby gem
|
14
|
-
spec.description = "Ruby gem
|
8
|
+
spec.summary = " Ruby gem for runtime data validation and monitoring using the contracts approach."
|
9
|
+
spec.description = " Ruby gem for runtime data validation and monitoring using the contracts approach."
|
15
10
|
spec.homepage = "https://github.com/sclinede/blood_contracts"
|
16
11
|
spec.license = "MIT"
|
17
12
|
|
18
|
-
spec.files = `git ls-files
|
19
|
-
f.match(%r{^(test|spec|features)/})
|
20
|
-
end
|
21
|
-
|
22
|
-
# Will be introduced soon
|
23
|
-
# spec.bindir = "exe"
|
24
|
-
# spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
25
|
-
spec.require_paths = ["lib"]
|
26
|
-
|
27
|
-
spec.required_ruby_version = '>= 2.2.0'
|
13
|
+
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
28
14
|
|
29
|
-
spec.
|
30
|
-
spec.add_runtime_dependency "nanoid", "~> 0.2"
|
31
|
-
spec.add_runtime_dependency "hashie", "~> 3.0"
|
15
|
+
spec.required_ruby_version = ">= 2.4"
|
32
16
|
|
33
|
-
spec.
|
34
|
-
spec.
|
35
|
-
spec.
|
36
|
-
spec.add_development_dependency "pry", "~> 0.9"
|
17
|
+
spec.add_runtime_dependency "blood_contracts-core", "~> 0.4"
|
18
|
+
spec.add_runtime_dependency "blood_contracts-ext", "~> 0.1"
|
19
|
+
spec.add_runtime_dependency "blood_contracts-instrumentation", "~> 0.1"
|
37
20
|
end
|
data/lib/blood_contracts.rb
CHANGED
@@ -1,38 +1,3 @@
|
|
1
|
-
require "blood_contracts/
|
2
|
-
|
3
|
-
|
4
|
-
require "dry-initializer"
|
5
|
-
require "hashie/mash"
|
6
|
-
|
7
|
-
require_relative "blood_contracts/suite"
|
8
|
-
require_relative "blood_contracts/storage"
|
9
|
-
require_relative "blood_contracts/runner"
|
10
|
-
require_relative "blood_contracts/debugger"
|
11
|
-
require_relative "blood_contracts/base_contract"
|
12
|
-
|
13
|
-
module BloodContracts
|
14
|
-
def run_name
|
15
|
-
@__contracts_run_name
|
16
|
-
end
|
17
|
-
module_function :run_name
|
18
|
-
|
19
|
-
def run_name=(run_name)
|
20
|
-
@__contracts_run_name = run_name
|
21
|
-
end
|
22
|
-
module_function :run_name=
|
23
|
-
|
24
|
-
if defined?(RSpec) && RSpec.respond_to?(:configure)
|
25
|
-
require_relative "rspec/meet_contract_matcher"
|
26
|
-
|
27
|
-
RSpec.configure do |config|
|
28
|
-
config.include ::RSpec::MeetContractMatcher
|
29
|
-
config.filter_run_excluding contract: true
|
30
|
-
config.before(:suite) do
|
31
|
-
BloodContracts.run_name = ::Nanoid.generate(size: 10)
|
32
|
-
end
|
33
|
-
config.define_derived_metadata(file_path: %r{/spec/contracts/}) do |meta|
|
34
|
-
meta[:contract] = true
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
1
|
+
require "blood_contracts/core"
|
2
|
+
require "blood_contracts/ext"
|
3
|
+
require "blood_contracts/instrumentation"
|
@@ -0,0 +1,36 @@
|
|
1
|
+
RSpec.describe BloodContracts do
|
2
|
+
describe ".run_name" do
|
3
|
+
before { BloodContracts.run_name = "External run name" }
|
4
|
+
|
5
|
+
it { expect(BloodContracts.run_name).to eq("External run name") }
|
6
|
+
end
|
7
|
+
|
8
|
+
describe ".storage" do
|
9
|
+
context "when default configuration" do
|
10
|
+
let(:expected_backend) { BloodContracts::Storages::FileBackend }
|
11
|
+
it "has assigned storage" do
|
12
|
+
expect(BloodContracts.storage.backend).to be_kind_of(expected_backend)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "when custom storage configured" do
|
17
|
+
before do
|
18
|
+
BloodContracts.config { |config| config.storage[:type] = :postgres }
|
19
|
+
end
|
20
|
+
let(:expected_backend) { BloodContracts::Storages::PostgresBackend }
|
21
|
+
|
22
|
+
it "has assigned custom storage" do
|
23
|
+
expect(BloodContracts.storage.backend).to be_kind_of(expected_backend)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "when custom storage configured" do
|
29
|
+
end
|
30
|
+
|
31
|
+
context "when custom sampling configured" do
|
32
|
+
end
|
33
|
+
|
34
|
+
context "when RSpec is defined" do
|
35
|
+
end
|
36
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
require "blood_contracts"
|
3
|
+
require "dotenv"
|
4
|
+
Dotenv.load(".env.test")
|
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
|
+
end
|
metadata
CHANGED
@@ -1,122 +1,66 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blood_contracts
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Sergey Dolganov
|
7
|
+
- Sergey Dolganov (sclinede)
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-08-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: blood_contracts-core
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0.4'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0.4'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: blood_contracts-ext
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0.
|
33
|
+
version: '0.1'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0.
|
40
|
+
version: '0.1'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: blood_contracts-instrumentation
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '0.1'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
55
|
-
|
56
|
-
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '1.16'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '1.16'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: rake
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '10.0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '10.0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rspec
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '3.0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '3.0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: pry
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - "~>"
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '0.9'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - "~>"
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '0.9'
|
111
|
-
description: Ruby gem to define and validate behavior of API using contracts.
|
54
|
+
version: '0.1'
|
55
|
+
description: " Ruby gem for runtime data validation and monitoring using the contracts
|
56
|
+
approach."
|
112
57
|
email:
|
113
|
-
-
|
58
|
+
- sclinede@evilmartians.com
|
114
59
|
executables: []
|
115
60
|
extensions: []
|
116
61
|
extra_rdoc_files: []
|
117
62
|
files:
|
118
63
|
- ".gitignore"
|
119
|
-
- ".travis.yml"
|
120
64
|
- CODE_OF_CONDUCT.md
|
121
65
|
- Gemfile
|
122
66
|
- LICENSE.txt
|
@@ -126,22 +70,8 @@ files:
|
|
126
70
|
- bin/setup
|
127
71
|
- blood_contracts.gemspec
|
128
72
|
- lib/blood_contracts.rb
|
129
|
-
-
|
130
|
-
-
|
131
|
-
- lib/blood_contracts/contracts/iterator.rb
|
132
|
-
- lib/blood_contracts/contracts/matcher.rb
|
133
|
-
- lib/blood_contracts/contracts/statistics.rb
|
134
|
-
- lib/blood_contracts/contracts/validator.rb
|
135
|
-
- lib/blood_contracts/debugger.rb
|
136
|
-
- lib/blood_contracts/runner.rb
|
137
|
-
- lib/blood_contracts/storage.rb
|
138
|
-
- lib/blood_contracts/storages/base_backend.rb
|
139
|
-
- lib/blood_contracts/storages/file_backend.rb
|
140
|
-
- lib/blood_contracts/storages/serializer.rb
|
141
|
-
- lib/blood_contracts/suite.rb
|
142
|
-
- lib/blood_contracts/version.rb
|
143
|
-
- lib/extensions/string.rb
|
144
|
-
- lib/rspec/meet_contract_matcher.rb
|
73
|
+
- spec/blood_contracts_spec.rb
|
74
|
+
- spec/spec_helper.rb
|
145
75
|
homepage: https://github.com/sclinede/blood_contracts
|
146
76
|
licenses:
|
147
77
|
- MIT
|
@@ -154,16 +84,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
154
84
|
requirements:
|
155
85
|
- - ">="
|
156
86
|
- !ruby/object:Gem::Version
|
157
|
-
version: 2.
|
87
|
+
version: '2.4'
|
158
88
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
159
89
|
requirements:
|
160
90
|
- - ">="
|
161
91
|
- !ruby/object:Gem::Version
|
162
92
|
version: '0'
|
163
93
|
requirements: []
|
164
|
-
|
165
|
-
rubygems_version: 2.7.6
|
94
|
+
rubygems_version: 3.0.3
|
166
95
|
signing_key:
|
167
96
|
specification_version: 4
|
168
|
-
summary: Ruby gem
|
97
|
+
summary: Ruby gem for runtime data validation and monitoring using the contracts approach.
|
169
98
|
test_files: []
|