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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +30 -0
  3. data/.gitignore +6 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +131 -0
  6. data/.travis.yml +22 -0
  7. data/Gemfile +8 -4
  8. data/README.md +13 -3
  9. data/Rakefile +1 -0
  10. data/TUTORIAL.md +6 -6
  11. data/bin/console +11 -0
  12. data/{script → bin}/rubocop +1 -2
  13. data/contracts.gemspec +1 -1
  14. data/docs/_config.yml +1 -0
  15. data/docs/index.md +112 -0
  16. data/lib/contracts.rb +8 -210
  17. data/lib/contracts/args_validator.rb +96 -0
  18. data/lib/contracts/builtin_contracts.rb +42 -35
  19. data/lib/contracts/contract.rb +136 -0
  20. data/lib/contracts/contract/call_with.rb +119 -0
  21. data/lib/contracts/contract/failure_callback.rb +61 -0
  22. data/lib/contracts/{validators.rb → contract/validators.rb} +9 -14
  23. data/lib/contracts/core.rb +4 -25
  24. data/lib/contracts/decorators.rb +1 -1
  25. data/lib/contracts/engine/base.rb +4 -5
  26. data/lib/contracts/engine/eigenclass.rb +3 -4
  27. data/lib/contracts/engine/target.rb +1 -3
  28. data/lib/contracts/error_formatter.rb +6 -6
  29. data/lib/contracts/errors.rb +2 -2
  30. data/lib/contracts/formatters.rb +20 -21
  31. data/lib/contracts/invariants.rb +10 -6
  32. data/lib/contracts/method_handler.rb +26 -31
  33. data/lib/contracts/method_reference.rb +13 -14
  34. data/lib/contracts/support.rb +2 -16
  35. data/lib/contracts/version.rb +1 -1
  36. data/spec/contracts_spec.rb +25 -6
  37. data/spec/error_formatter_spec.rb +0 -1
  38. data/spec/fixtures/fixtures.rb +5 -5
  39. data/spec/ruby_version_specific/contracts_spec_1.9.rb +17 -1
  40. data/spec/ruby_version_specific/contracts_spec_2.0.rb +1 -1
  41. data/spec/ruby_version_specific/contracts_spec_2.1.rb +1 -1
  42. data/spec/spec_helper.rb +17 -68
  43. metadata +15 -8
  44. data/TODO.markdown +0 -6
  45. data/lib/contracts/call_with.rb +0 -97
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5a0087eb9cbfbfbac59abc12f636caccf3699b81
4
- data.tar.gz: eb6161c0401a24b4a37ac8fff330de398198fd74
3
+ metadata.gz: a9c1b2376cd43e4d7d2a992e27f59a4dff19f060
4
+ data.tar.gz: 33bb50fa438a689706fe7ba08ede597e88e71170
5
5
  SHA512:
6
- metadata.gz: 681aa159502c17ae1dccc23060193b73cd70f81034a724398003edf886156ecd7c5e23199c53a1a5c1f90a0cd03257ace3de9733058c76c616d2e0af2356fb27
7
- data.tar.gz: 170938443f38a9cbc575e1ae4261dc6365d44c7615108fc5cd25195af0554e8f4afc82395f04bdd17e9f0f4eff859d0a262a57a00c527f5ee01843ecb350cbc7
6
+ metadata.gz: 092d9f8d84c5e6d98f431e93f0297911927ed7ad1671a4319962a6e9fa415188a362e67d42beb3409008bed60e4bef4dd7b7061b7713009181eb4dec9f50ab5e
7
+ data.tar.gz: 639b6b326b48dbbb2a9fba32310f82fe9475d02a4f2041d5719d2d76b8f5107e6964f48679fee3dfacd639b3711bc9c46ffb106aed07f53257c9ec068b60b80c
@@ -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
@@ -0,0 +1,6 @@
1
+ *.swp
2
+ *.swo
3
+ Gemfile.lock
4
+ tmp/
5
+ coverage/
6
+ .byebug*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -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
@@ -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 "http://rubygems.org"
1
+ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
+
5
6
  group :test do
6
7
  gem "rspec"
7
- gem "rubocop", "~> 0.29.1", :platform => [:ruby_20, :ruby_21, :ruby_22, :ruby_23]
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 [![Build Status](https://travis-ci.org/ddd-ruby/contracts.ruby.png?branch=master)](https://travis-ci.org/ddd-ruby/contracts.ruby) [![Join the chat at https://gitter.im/egonSchiele/contracts.ruby](https://img.shields.io/badge/gitter-join%20chat-brightgreen.svg)](https://gitter.im/egonSchiele/contracts.ruby)
1
+ # contracts.ruby
2
+ [![Build Status](https://travis-ci.org/ddd-ruby/contracts.ruby.png)](https://travis-ci.org/ddd-ruby/contracts.ruby)
3
+ [![Code Climate](https://codeclimate.com/github/ddd-ruby/contracts.ruby/badges/gpa.svg)](https://codeclimate.com/github/ddd-ruby/contracts.ruby)
4
+ [![codecov](https://codecov.io/gh/ddd-ruby/contracts.ruby/branch/master/graph/badge.svg)](https://codecov.io/gh/ddd-ruby/contracts.ruby)
5
+ [![Dependency Status](https://gemnasium.com/ddd-ruby/contracts.ruby.png)](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 rake`
82
+ `bundle exec rspec`
73
83
 
74
84
  ## Performance
75
85
 
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -214,7 +214,7 @@ product([1, 2, 3, "foo"])
214
214
  ### Another Product Function
215
215
 
216
216
  ```ruby
217
- Contract C::Args[C::Num] => C::Num
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 `Args` contract. It takes one contract as an argument and uses it to validate every element passed in through `*args`. So for example,
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
- `Args[Num]` means they should all be numbers.
229
+ `SplatArgs[Num]` means they should all be numbers.
230
230
 
231
- `Args[Or[Num, String]]` means they should all be numbers or strings.
231
+ `SplatArgs[Or[Num, String]]` means they should all be numbers or strings.
232
232
 
233
- `Args[Any]` means all arguments are allowed (`Any` is a contract that passes for any argument).
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::Args)` - e.g. `C::Args[C::Num]`,
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,
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "contracts"
5
+
6
+ require_relative "../spec/support"
7
+ require_relative "../spec/fixtures/fixtures"
8
+ puts "preloaded fixtures from spec/fixtures/fixtures"
9
+
10
+ require "irb"
11
+ IRB.start
@@ -2,6 +2,5 @@
2
2
 
3
3
  if RUBY_VERSION.to_f > 2.1
4
4
  puts "running rubocop..."
5
- puts `bundle exec rubocop -D spec/ lib/`
6
- exit $?.exitstatus
5
+ exec("bundle exec rubocop -a -D lib/")
7
6
  end
@@ -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"
@@ -0,0 +1 @@
1
+ theme: jekyll-theme-minimal
@@ -0,0 +1,112 @@
1
+ # contracts.ruby
2
+ [![Build Status](https://travis-ci.org/ddd-ruby/contracts.ruby.png)](https://travis-ci.org/ddd-ruby/contracts.ruby)
3
+ [![Code Climate](https://codeclimate.com/github/ddd-ruby/contracts.ruby/badges/gpa.svg)](https://codeclimate.com/github/ddd-ruby/contracts.ruby)
4
+ [![codecov](https://codecov.io/gh/ddd-ruby/contracts.ruby/branch/master/graph/badge.svg)](https://codecov.io/gh/ddd-ruby/contracts.ruby)
5
+ [![Dependency Status](https://gemnasium.com/ddd-ruby/contracts.ruby.png)](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
+