contracts-lite 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.codeclimate.yml +30 -0
- data/.gitignore +6 -0
- data/.rspec +2 -0
- data/.rubocop.yml +131 -0
- data/.travis.yml +22 -0
- data/Gemfile +8 -4
- data/README.md +13 -3
- data/Rakefile +1 -0
- data/TUTORIAL.md +6 -6
- data/bin/console +11 -0
- data/{script → bin}/rubocop +1 -2
- data/contracts.gemspec +1 -1
- data/docs/_config.yml +1 -0
- data/docs/index.md +112 -0
- data/lib/contracts.rb +8 -210
- data/lib/contracts/args_validator.rb +96 -0
- data/lib/contracts/builtin_contracts.rb +42 -35
- data/lib/contracts/contract.rb +136 -0
- data/lib/contracts/contract/call_with.rb +119 -0
- data/lib/contracts/contract/failure_callback.rb +61 -0
- data/lib/contracts/{validators.rb → contract/validators.rb} +9 -14
- data/lib/contracts/core.rb +4 -25
- data/lib/contracts/decorators.rb +1 -1
- data/lib/contracts/engine/base.rb +4 -5
- data/lib/contracts/engine/eigenclass.rb +3 -4
- data/lib/contracts/engine/target.rb +1 -3
- data/lib/contracts/error_formatter.rb +6 -6
- data/lib/contracts/errors.rb +2 -2
- data/lib/contracts/formatters.rb +20 -21
- data/lib/contracts/invariants.rb +10 -6
- data/lib/contracts/method_handler.rb +26 -31
- data/lib/contracts/method_reference.rb +13 -14
- data/lib/contracts/support.rb +2 -16
- data/lib/contracts/version.rb +1 -1
- data/spec/contracts_spec.rb +25 -6
- data/spec/error_formatter_spec.rb +0 -1
- data/spec/fixtures/fixtures.rb +5 -5
- data/spec/ruby_version_specific/contracts_spec_1.9.rb +17 -1
- data/spec/ruby_version_specific/contracts_spec_2.0.rb +1 -1
- data/spec/ruby_version_specific/contracts_spec_2.1.rb +1 -1
- data/spec/spec_helper.rb +17 -68
- metadata +15 -8
- data/TODO.markdown +0 -6
- data/lib/contracts/call_with.rb +0 -97
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a9c1b2376cd43e4d7d2a992e27f59a4dff19f060
|
4
|
+
data.tar.gz: 33bb50fa438a689706fe7ba08ede597e88e71170
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 092d9f8d84c5e6d98f431e93f0297911927ed7ad1671a4319962a6e9fa415188a362e67d42beb3409008bed60e4bef4dd7b7061b7713009181eb4dec9f50ab5e
|
7
|
+
data.tar.gz: 639b6b326b48dbbb2a9fba32310f82fe9475d02a4f2041d5719d2d76b8f5107e6964f48679fee3dfacd639b3711bc9c46ffb106aed07f53257c9ec068b60b80c
|
data/.codeclimate.yml
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
engines:
|
2
|
+
rubocop:
|
3
|
+
enabled: true
|
4
|
+
exclude_fingerprints:
|
5
|
+
- a6b358051ceb7af2b92a34028cd85b0e
|
6
|
+
|
7
|
+
bundler-audit:
|
8
|
+
enabled: false
|
9
|
+
|
10
|
+
fixme:
|
11
|
+
enabled: true
|
12
|
+
|
13
|
+
duplication:
|
14
|
+
enabled: true
|
15
|
+
exclude_fingerprints:
|
16
|
+
- d155301f1ed91235c5db306b793cddd6
|
17
|
+
- e2ddafaebd868c909253e9231b294e9b
|
18
|
+
|
19
|
+
config:
|
20
|
+
languages:
|
21
|
+
- ruby
|
22
|
+
|
23
|
+
ratings:
|
24
|
+
paths:
|
25
|
+
- "**.rb"
|
26
|
+
|
27
|
+
exclude_paths:
|
28
|
+
- spec/**/*
|
29
|
+
- benchmarks/**/*
|
30
|
+
- .rubocop.yml
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
AllCops:
|
2
|
+
Exclude:
|
3
|
+
- "tmp/**/*"
|
4
|
+
|
5
|
+
# forces method defs to have params in parens
|
6
|
+
Style/MethodDefParentheses:
|
7
|
+
Enabled: true
|
8
|
+
|
9
|
+
Style/StringLiterals:
|
10
|
+
EnforcedStyle: double_quotes
|
11
|
+
|
12
|
+
# changes x != nil to !x.nil?
|
13
|
+
Style/NonNilCheck:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
# changes %{} to %()
|
17
|
+
Style/PercentLiteralDelimiters:
|
18
|
+
Enabled: false
|
19
|
+
|
20
|
+
# changes lambdas to ruby 1.9-style ->
|
21
|
+
# not compatible with ruby 1.8
|
22
|
+
Style/Lambda:
|
23
|
+
Enabled: false
|
24
|
+
|
25
|
+
# changes to new hash syntax
|
26
|
+
# not compatible with ruby 1.8
|
27
|
+
Style/HashSyntax:
|
28
|
+
Enabled: false
|
29
|
+
|
30
|
+
# we use unused method args a lot in tests/fixtures (a quirk of this lib)
|
31
|
+
Lint/UnusedMethodArgument:
|
32
|
+
Enabled: false
|
33
|
+
|
34
|
+
# changes x ** 2 to x**2
|
35
|
+
Style/SpaceAroundOperators:
|
36
|
+
Enabled: false
|
37
|
+
|
38
|
+
# doesn't allow vars starting with _
|
39
|
+
Lint/UnderscorePrefixedVariableName:
|
40
|
+
Enabled: false
|
41
|
+
|
42
|
+
# enforces method length of 10 lines
|
43
|
+
Metrics/MethodLength:
|
44
|
+
Enabled: false
|
45
|
+
|
46
|
+
# forces you to document classes
|
47
|
+
# TODO: try to enable this cop
|
48
|
+
Style/Documentation:
|
49
|
+
Enabled: false
|
50
|
+
|
51
|
+
# enforces line length of 80
|
52
|
+
# TODO enable
|
53
|
+
Metrics/LineLength:
|
54
|
+
Enabled: false
|
55
|
+
|
56
|
+
# triggered by Contract ({ :name => String, :age => Fixnum }) => nil
|
57
|
+
Lint/ParenthesesAsGroupedExpression:
|
58
|
+
Enabled: false
|
59
|
+
|
60
|
+
# checks how much a method branches.
|
61
|
+
# TODO try to get this cop enabled
|
62
|
+
Metrics/AbcSize:
|
63
|
+
Enabled: true
|
64
|
+
|
65
|
+
# checks complexity of method
|
66
|
+
# TODO try to get this cop enabled
|
67
|
+
Metrics/CyclomaticComplexity:
|
68
|
+
Enabled: false
|
69
|
+
|
70
|
+
# checks for too many nested ifs, whiles or rescues (but not too many nested blocks)
|
71
|
+
# TODO: try to get this cop enabled eventually
|
72
|
+
Metrics/BlockNesting:
|
73
|
+
Enabled: false
|
74
|
+
|
75
|
+
# calls out class variables.
|
76
|
+
# TODO: try to get this cop enabled eventually
|
77
|
+
Style/ClassVars:
|
78
|
+
Enabled: false
|
79
|
+
|
80
|
+
# enforces class length of < 100 lines
|
81
|
+
Metrics/ClassLength:
|
82
|
+
Enabled: false
|
83
|
+
|
84
|
+
# TODO: try to get this cop enabled eventually
|
85
|
+
Metrics/PerceivedComplexity:
|
86
|
+
Enabled: false
|
87
|
+
|
88
|
+
# checks for duplicate methods, but contracts
|
89
|
+
# provides this functionality (multi-dispatch)
|
90
|
+
Lint/DuplicateMethods:
|
91
|
+
Enabled: false
|
92
|
+
|
93
|
+
# checks to see if you could've used attr_accessor instead.
|
94
|
+
# nice in theory but noisy cop with false positives
|
95
|
+
Style/TrivialAccessors:
|
96
|
+
Enabled: false
|
97
|
+
|
98
|
+
Style/MultilineOperationIndentation:
|
99
|
+
EnforcedStyle: indented
|
100
|
+
|
101
|
+
# Asks you to use %w{array of words} if possible.
|
102
|
+
# Not a style I like.
|
103
|
+
Style/WordArray:
|
104
|
+
Enabled: false
|
105
|
+
|
106
|
+
# conflicts with contracts
|
107
|
+
# we define contracts like `Baz = 1`
|
108
|
+
Style/ConstantName:
|
109
|
+
Enabled: false
|
110
|
+
|
111
|
+
# `Contract` violates this, otherwise a good cop (enforces snake_case method names)
|
112
|
+
# TODO possible to get this enabled but ignore `Contract`?
|
113
|
+
Style/MethodName:
|
114
|
+
Enabled: false
|
115
|
+
|
116
|
+
# checks for !!
|
117
|
+
Style/DoubleNegation:
|
118
|
+
Enabled: false
|
119
|
+
|
120
|
+
# enforces < 5 params for a function.
|
121
|
+
# contracts-specific (long parameter list for test)
|
122
|
+
Metrics/ParameterLists:
|
123
|
+
Enabled: false
|
124
|
+
|
125
|
+
# Checks that braces used for hash literals have or don't have surrounding space depending on configuration.
|
126
|
+
Style/SpaceInsideHashLiteralBraces:
|
127
|
+
Enabled: false
|
128
|
+
|
129
|
+
# TODO enable
|
130
|
+
Style/SpecialGlobalVars:
|
131
|
+
Enabled: false
|
data/.travis.yml
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
dist: trusty
|
2
|
+
|
3
|
+
language: ruby
|
4
|
+
cache: bundler
|
5
|
+
rvm:
|
6
|
+
- "2.1"
|
7
|
+
- "2.2"
|
8
|
+
- "2.3"
|
9
|
+
|
10
|
+
before_install:
|
11
|
+
- gem install bundler
|
12
|
+
|
13
|
+
script:
|
14
|
+
- bundle exec rspec
|
15
|
+
# - bundle exec bin/rubocop
|
16
|
+
|
17
|
+
bundler_args: --without development
|
18
|
+
|
19
|
+
matrix:
|
20
|
+
include:
|
21
|
+
- rvm: jruby-20mode # JRuby in 1.9 mode
|
22
|
+
dist: precise
|
data/Gemfile
CHANGED
@@ -1,16 +1,20 @@
|
|
1
|
-
source "
|
1
|
+
source "https://rubygems.org"
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
+
|
5
6
|
group :test do
|
6
7
|
gem "rspec"
|
7
|
-
gem "
|
8
|
+
gem "codecov"
|
9
|
+
gem "rubocop", "~> 0.46", :platform => [:ruby_20, :ruby_21, :ruby_22, :ruby_23]
|
8
10
|
end
|
9
11
|
|
10
12
|
group :development do
|
11
|
-
gem "relish"
|
12
13
|
gem "method_profiler"
|
13
14
|
gem "ruby-prof"
|
15
|
+
end
|
16
|
+
|
17
|
+
group :test, :development do
|
18
|
+
gem "byebug", :platform => [:ruby_20, :ruby_21, :ruby_22, :ruby_23]
|
14
19
|
gem "rake"
|
15
|
-
gem "byebug"
|
16
20
|
end
|
data/README.md
CHANGED
@@ -1,4 +1,14 @@
|
|
1
|
-
# contracts.ruby
|
1
|
+
# contracts.ruby
|
2
|
+
[](https://travis-ci.org/ddd-ruby/contracts.ruby)
|
3
|
+
[](https://codeclimate.com/github/ddd-ruby/contracts.ruby)
|
4
|
+
[](https://codecov.io/gh/ddd-ruby/contracts.ruby)
|
5
|
+
[](https://gemnasium.com/ddd-ruby/contracts.ruby)
|
6
|
+
|
7
|
+
|
8
|
+
## Fork of https://github.com/egonSchiele/contracts.ruby
|
9
|
+
Until this issue https://github.com/egonSchiele/contracts.ruby/pull/246 is resolved, we decided to mainain our own fork of contracts named `contracts-lite`.
|
10
|
+
|
11
|
+
<hr>
|
2
12
|
|
3
13
|
Contracts let you clearly – even beautifully – express how your code behaves, and free you from writing tons of boilerplate, defensive code.
|
4
14
|
|
@@ -6,7 +16,7 @@ You can think of contracts as `assert` on steroids.
|
|
6
16
|
|
7
17
|
## Installation
|
8
18
|
|
9
|
-
gem install contracts
|
19
|
+
gem install contracts-lite
|
10
20
|
|
11
21
|
## Hello World
|
12
22
|
|
@@ -69,7 +79,7 @@ To get started do the following:
|
|
69
79
|
|
70
80
|
2. Run our test suite
|
71
81
|
|
72
|
-
`bundle exec
|
82
|
+
`bundle exec rspec`
|
73
83
|
|
74
84
|
## Performance
|
75
85
|
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/TUTORIAL.md
CHANGED
@@ -214,7 +214,7 @@ product([1, 2, 3, "foo"])
|
|
214
214
|
### Another Product Function
|
215
215
|
|
216
216
|
```ruby
|
217
|
-
Contract C::
|
217
|
+
Contract C::SplatArgs[C::Num] => C::Num
|
218
218
|
def product(*vals)
|
219
219
|
total = 1
|
220
220
|
vals.each do |val|
|
@@ -224,13 +224,13 @@ def product(*vals)
|
|
224
224
|
end
|
225
225
|
```
|
226
226
|
|
227
|
-
This function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `
|
227
|
+
This function uses varargs (`*args`) instead of an array. To make a contract on varargs, use the `SplatArgs` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,
|
228
228
|
|
229
|
-
`
|
229
|
+
`SplatArgs[Num]` means they should all be numbers.
|
230
230
|
|
231
|
-
`
|
231
|
+
`SplatArgs[Or[Num, String]]` means they should all be numbers or strings.
|
232
232
|
|
233
|
-
`
|
233
|
+
`SplatArgs[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).
|
234
234
|
|
235
235
|
### Contracts On Arrays
|
236
236
|
|
@@ -598,7 +598,7 @@ Possible validator overrides:
|
|
598
598
|
- `override_validator(Hash)` - e.g. `{ :a => C::Num, :b => String }`,
|
599
599
|
- `override_validator(Range)` - e.g. `(1..10)`,
|
600
600
|
- `override_validator(Regexp)` - e.g. `/foo/`,
|
601
|
-
- `override_validator(Contracts::
|
601
|
+
- `override_validator(Contracts::SplatArgs)` - e.g. `C::SplatArgs[C::Num]`,
|
602
602
|
- `override_validator(Contracts::Func)` - e.g. `C::Func[C::Num => C::Num]`,
|
603
603
|
- `override_validator(:valid)` - allows to override how contracts that respond to `:valid?` are handled,
|
604
604
|
- `override_validator(:class)` - allows to override how class/module contract constants are handled,
|
data/bin/console
ADDED
data/{script → bin}/rubocop
RENAMED
data/contracts.gemspec
CHANGED
@@ -5,7 +5,7 @@ Gem::Specification.new do |s|
|
|
5
5
|
s.version = Contracts::VERSION
|
6
6
|
s.summary = "Contracts for Ruby. (fork)"
|
7
7
|
s.description = "This library provides contracts for Ruby. Contracts let you clearly express how your code behaves, and free you from writing tons of boilerplate, defensive code."
|
8
|
-
s.author = "Aditya Bhargava"
|
8
|
+
s.author = "Aditya Bhargava, Ruslan Gatyatov, Roman Heinrich"
|
9
9
|
s.email = "bluemangroupie@gmail.com"
|
10
10
|
s.files = `git ls-files`.split("\n")
|
11
11
|
s.homepage = "http://github.com/ddd-ruby/contracts.ruby"
|
data/docs/_config.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
theme: jekyll-theme-minimal
|
data/docs/index.md
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
# contracts.ruby
|
2
|
+
[](https://travis-ci.org/ddd-ruby/contracts.ruby)
|
3
|
+
[](https://codeclimate.com/github/ddd-ruby/contracts.ruby)
|
4
|
+
[](https://codecov.io/gh/ddd-ruby/contracts.ruby)
|
5
|
+
[](https://gemnasium.com/ddd-ruby/contracts.ruby)
|
6
|
+
|
7
|
+
|
8
|
+
## Fork of https://github.com/egonSchiele/contracts.ruby
|
9
|
+
Until this issue https://github.com/egonSchiele/contracts.ruby/pull/246 is resolved, we decided to mainain our own fork of contracts named `contracts-lite`.
|
10
|
+
|
11
|
+
<hr>
|
12
|
+
|
13
|
+
Contracts let you clearly – even beautifully – express how your code behaves, and free you from writing tons of boilerplate, defensive code.
|
14
|
+
|
15
|
+
You can think of contracts as `assert` on steroids.
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
gem install contracts-lite
|
20
|
+
|
21
|
+
## Hello World
|
22
|
+
|
23
|
+
A contract is one line of code that you write above a method definition. It validates the arguments to the method, and validates the return value of the method.
|
24
|
+
|
25
|
+
Here is a simple contract:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
Contract Num => Num
|
29
|
+
def double(x)
|
30
|
+
```
|
31
|
+
|
32
|
+
This says that double expects a number and returns a number. Here's the full code:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
require 'contracts'
|
36
|
+
|
37
|
+
class Example
|
38
|
+
include Contracts::Core
|
39
|
+
include Contracts::Builtin
|
40
|
+
|
41
|
+
Contract Num => Num
|
42
|
+
def double(x)
|
43
|
+
x * 2
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
puts Example.new.double("oops")
|
48
|
+
```
|
49
|
+
|
50
|
+
Save this in a file and run it. Notice we are calling `double` with `"oops"`, which is not a number. The contract fails with a detailed error message:
|
51
|
+
|
52
|
+
```
|
53
|
+
ParamContractError: Contract violation for argument 1 of 1:
|
54
|
+
Expected: Num,
|
55
|
+
Actual: "oops"
|
56
|
+
Value guarded in: Example::double
|
57
|
+
With Contract: Num => Num
|
58
|
+
At: main.rb:8
|
59
|
+
...stack trace...
|
60
|
+
```
|
61
|
+
|
62
|
+
Instead of throwing an exception, you could log it, print a clean error message for your user...whatever you want. contracts.ruby is here to help you handle bugs better, not to get in your way.
|
63
|
+
|
64
|
+
## Tutorial
|
65
|
+
|
66
|
+
Check out [this awesome tutorial](http://egonschiele.github.com/contracts.ruby).
|
67
|
+
|
68
|
+
## Use Cases
|
69
|
+
|
70
|
+
Check out [this screencast](https://vimeo.com/85883356).
|
71
|
+
|
72
|
+
## Development
|
73
|
+
|
74
|
+
To get started do the following:
|
75
|
+
|
76
|
+
1. Install required gems for development
|
77
|
+
|
78
|
+
`bundle install`
|
79
|
+
|
80
|
+
2. Run our test suite
|
81
|
+
|
82
|
+
`bundle exec rspec`
|
83
|
+
|
84
|
+
## Performance
|
85
|
+
|
86
|
+
Using contracts.ruby results in very little slowdown. Check out [this blog post](http://adit.io/posts/2013-03-04-How-I-Made-My-Ruby-Project-10x-Faster.html#seconds-6) for more info.
|
87
|
+
|
88
|
+
**Q.** What Rubies can I use this with?
|
89
|
+
|
90
|
+
**A.** It's been tested with `1.9.2`, `1.9.3`, `2.0.0`, `2.1`, `2.2`, and `jruby` (1.9 mode).
|
91
|
+
|
92
|
+
If you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)
|
93
|
+
|
94
|
+
## Testimonials
|
95
|
+
|
96
|
+
> Contracts literally saves us hours of pain at Snowplow every day
|
97
|
+
|
98
|
+
Alexander Dean, creator of [Snowplow](https://github.com/snowplow/snowplow)
|
99
|
+
|
100
|
+
> Contracts caught a bug that saved us several hundred dollars. It took less than 30 seconds to add the contract.
|
101
|
+
|
102
|
+
Michael Tomer
|
103
|
+
|
104
|
+
## Credits
|
105
|
+
|
106
|
+
Inspired by [contracts.coffee](http://disnetdev.com/contracts.coffee/).
|
107
|
+
|
108
|
+
Copyright 2012-2015 [Aditya Bhargava](http://adit.io).
|
109
|
+
Major improvements by [Alexey Fedorov](https://github.com/waterlink).
|
110
|
+
|
111
|
+
BSD Licensed.
|
112
|
+
|