contracts 0.16.1 → 0.17.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/code_style_checks.yaml +2 -2
- data/.github/workflows/tests.yaml +7 -13
- data/.rubocop.yml +34 -8
- data/.rubocop_todo.yml +7 -4
- data/CHANGELOG.markdown +2 -0
- data/Gemfile +8 -4
- data/README.md +10 -2
- data/Rakefile +2 -0
- data/TUTORIAL.md +14 -14
- data/contracts.gemspec +3 -4
- data/features/builtin_contracts/keyword_args_with_optional_positional_args.feature +76 -0
- data/features/builtin_contracts/none.feature +15 -9
- data/features/support/env.rb +2 -0
- data/lib/contracts/attrs.rb +2 -0
- data/lib/contracts/builtin_contracts.rb +43 -10
- data/lib/contracts/call_with.rb +52 -30
- data/lib/contracts/core.rb +3 -1
- data/lib/contracts/decorators.rb +5 -2
- data/lib/contracts/engine/base.rb +4 -3
- data/lib/contracts/engine/eigenclass.rb +3 -2
- data/lib/contracts/engine/target.rb +2 -0
- data/lib/contracts/engine.rb +2 -0
- data/lib/contracts/errors.rb +3 -0
- data/lib/contracts/formatters.rb +17 -10
- data/lib/contracts/invariants.rb +8 -4
- data/lib/contracts/method_handler.rb +19 -9
- data/lib/contracts/method_reference.rb +4 -2
- data/lib/contracts/support.rb +4 -2
- data/lib/contracts/validators.rb +6 -2
- data/lib/contracts/version.rb +3 -1
- data/lib/contracts.rb +31 -39
- data/spec/builtin_contracts_spec.rb +9 -13
- data/spec/contracts_spec.rb +12 -9
- data/spec/fixtures/fixtures.rb +11 -16
- data/spec/override_validators_spec.rb +3 -3
- data/spec/ruby_version_specific/contracts_spec_2.0.rb +2 -2
- data/spec/validators_spec.rb +1 -1
- metadata +11 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a151d83a8b03910e5dd1171c384e0ea8a01ff9437d81140f995358d888ac0fa
|
4
|
+
data.tar.gz: b92d01b9dd8702b866e004c41834781885d8178b1ceacb1e5166982243a13a49
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94df8b86d22522b7c573f9cd7b3ee425568b024d7d3a88701759a2b47cdce691bd9ce7ec45710e7e8dafb993c7aa1cb93d6d9a0110d3c4effeece4b24fda29a9
|
7
|
+
data.tar.gz: dbbddaf090e48b52cde302f6a6b5b89fc84045e9c392ef1d34ddcfb2e149f65c3da825b8140ebd4b3d36672ed933b841e1c59b9e684098bb3144762bcd7b4b50
|
@@ -22,22 +22,16 @@ jobs:
|
|
22
22
|
os:
|
23
23
|
- ubuntu
|
24
24
|
ruby:
|
25
|
-
- "
|
26
|
-
- "
|
27
|
-
- "
|
28
|
-
- "
|
29
|
-
|
30
|
-
- "
|
31
|
-
- "2.7"
|
32
|
-
test_command: ["bundle exec rspec && bundle exec cucumber"]
|
33
|
-
include:
|
34
|
-
- os: ubuntu
|
35
|
-
ruby: "2.4.2"
|
36
|
-
test_command: "bundle exec rspec"
|
25
|
+
- "3.3"
|
26
|
+
- "3.2"
|
27
|
+
- "3.1"
|
28
|
+
- "3.0"
|
29
|
+
test_command:
|
30
|
+
- "bundle exec rspec && bundle exec cucumber"
|
37
31
|
runs-on: ${{ matrix.os }}-latest
|
38
32
|
steps:
|
39
33
|
- name: Checkout
|
40
|
-
uses: actions/checkout@
|
34
|
+
uses: actions/checkout@v4
|
41
35
|
- name: Setup Ruby
|
42
36
|
uses: ruby/setup-ruby@v1
|
43
37
|
with:
|
data/.rubocop.yml
CHANGED
@@ -1,12 +1,17 @@
|
|
1
1
|
inherit_from: .rubocop_todo.yml
|
2
2
|
|
3
3
|
AllCops:
|
4
|
-
TargetRubyVersion:
|
4
|
+
TargetRubyVersion: 3.0
|
5
5
|
DisplayCopNames: true
|
6
|
+
NewCops: disable
|
6
7
|
Exclude:
|
8
|
+
- "benchmarks/**/*"
|
7
9
|
- "tmp/**/*"
|
8
10
|
- "vendor/**/*"
|
11
|
+
- "script/**/*.rb"
|
12
|
+
- "spec/fixtures/*.rb"
|
9
13
|
- "spec/ruby_version_specific/*.rb"
|
14
|
+
- "spec/*.rb"
|
10
15
|
|
11
16
|
# forces method defs to have params in parens
|
12
17
|
Style/MethodDefParentheses:
|
@@ -38,7 +43,7 @@ Lint/UnusedMethodArgument:
|
|
38
43
|
Enabled: false
|
39
44
|
|
40
45
|
# changes x ** 2 to x**2
|
41
|
-
|
46
|
+
Layout/SpaceAroundOperators:
|
42
47
|
Enabled: false
|
43
48
|
|
44
49
|
# doesn't allow vars starting with _
|
@@ -56,10 +61,10 @@ Style/Documentation:
|
|
56
61
|
|
57
62
|
# enforces line length of 80
|
58
63
|
# TODO enable
|
59
|
-
|
64
|
+
Layout/LineLength:
|
60
65
|
Enabled: false
|
61
66
|
|
62
|
-
# triggered by Contract ({ :name => String, :age =>
|
67
|
+
# triggered by Contract ({ :name => String, :age => Integer }) => nil
|
63
68
|
Lint/ParenthesesAsGroupedExpression:
|
64
69
|
Enabled: false
|
65
70
|
|
@@ -101,7 +106,7 @@ Lint/DuplicateMethods:
|
|
101
106
|
Style/TrivialAccessors:
|
102
107
|
Enabled: false
|
103
108
|
|
104
|
-
|
109
|
+
Layout/MultilineOperationIndentation:
|
105
110
|
EnforcedStyle: indented
|
106
111
|
|
107
112
|
# Asks you to use %w{array of words} if possible.
|
@@ -111,12 +116,12 @@ Style/WordArray:
|
|
111
116
|
|
112
117
|
# conflicts with contracts
|
113
118
|
# we define contracts like `Baz = 1`
|
114
|
-
|
119
|
+
Naming/ConstantName:
|
115
120
|
Enabled: false
|
116
121
|
|
117
122
|
# `Contract` violates this, otherwise a good cop (enforces snake_case method names)
|
118
123
|
# TODO possible to get this enabled but ignore `Contract`?
|
119
|
-
|
124
|
+
Naming/MethodName:
|
120
125
|
Enabled: false
|
121
126
|
|
122
127
|
# checks for !!
|
@@ -129,9 +134,30 @@ Metrics/ParameterLists:
|
|
129
134
|
Enabled: false
|
130
135
|
|
131
136
|
# Checks that braces used for hash literals have or don't have surrounding space depending on configuration.
|
132
|
-
|
137
|
+
Layout/SpaceInsideHashLiteralBraces:
|
133
138
|
Enabled: false
|
134
139
|
|
135
140
|
# TODO enable
|
136
141
|
Style/SpecialGlobalVars:
|
137
142
|
Enabled: false
|
143
|
+
|
144
|
+
Style/IfUnlessModifier:
|
145
|
+
Enabled: false
|
146
|
+
|
147
|
+
Naming/MemoizedInstanceVariableName:
|
148
|
+
Enabled: false
|
149
|
+
|
150
|
+
Layout/FirstHashElementIndentation:
|
151
|
+
EnforcedStyle: consistent
|
152
|
+
|
153
|
+
Layout/HashAlignment:
|
154
|
+
EnforcedColonStyle: table
|
155
|
+
|
156
|
+
Style/TrailingCommaInHashLiteral:
|
157
|
+
EnforcedStyleForMultiline: consistent_comma
|
158
|
+
|
159
|
+
Style/TrailingCommaInArrayLiteral:
|
160
|
+
EnforcedStyleForMultiline: consistent_comma
|
161
|
+
|
162
|
+
Style/TrailingCommaInArguments:
|
163
|
+
EnforcedStyleForMultiline: consistent_comma
|
data/.rubocop_todo.yml
CHANGED
@@ -6,6 +6,9 @@
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
8
8
|
|
9
|
+
require:
|
10
|
+
- rubocop-performance
|
11
|
+
|
9
12
|
# Offense count: 2
|
10
13
|
Lint/NonLocalExitFromIterator:
|
11
14
|
Exclude:
|
@@ -32,14 +35,14 @@ Style/Alias:
|
|
32
35
|
# Offense count: 1
|
33
36
|
# Cop supports --auto-correct.
|
34
37
|
# Configuration parameters: AllowAdjacentOneLineDefs.
|
35
|
-
|
38
|
+
Layout/EmptyLineBetweenDefs:
|
36
39
|
Exclude:
|
37
40
|
- 'benchmarks/wrap_test.rb'
|
38
41
|
|
39
42
|
# Offense count: 1
|
40
43
|
# Cop supports --auto-correct.
|
41
44
|
# Configuration parameters: AllowForAlignment, ForceEqualSignAlignment.
|
42
|
-
|
45
|
+
Layout/ExtraSpacing:
|
43
46
|
Exclude:
|
44
47
|
- 'spec/builtin_contracts_spec.rb'
|
45
48
|
|
@@ -58,7 +61,7 @@ Style/IfInsideElse:
|
|
58
61
|
# Cop supports --auto-correct.
|
59
62
|
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
60
63
|
# SupportedStyles: symmetrical, new_line, same_line
|
61
|
-
|
64
|
+
Layout/MultilineHashBraceLayout:
|
62
65
|
Exclude:
|
63
66
|
- 'spec/contracts_spec.rb'
|
64
67
|
- 'spec/fixtures/fixtures.rb'
|
@@ -130,6 +133,6 @@ Style/TrailingUnderscoreVariable:
|
|
130
133
|
|
131
134
|
# Offense count: 1
|
132
135
|
# Cop supports --auto-correct.
|
133
|
-
Style/
|
136
|
+
Style/RedundantInterpolation:
|
134
137
|
Exclude:
|
135
138
|
- 'lib/contracts/formatters.rb'
|
data/CHANGELOG.markdown
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
|
2
2
|
## [v0.16.1] - 2021-04-17
|
3
3
|
|
4
|
+
[v0.16.1]: https://github.com/egonSchiele/contracts.ruby/compare/v0.16.0...v0.16.1
|
5
|
+
|
4
6
|
- Enhancement: Pretty-print contracts in error messages - [Corey Farwell](https://github.com/frewsxcv) [#289](https://github.com/egonSchiele/contracts.ruby/pull/289)
|
5
7
|
- Bugfix: Fix `attr_accessor_with_contract` with multiple attribute names input - [Kevin Yeh](https://github.com/kyeah) [#259](https://github.com/egonSchiele/contracts.ruby/pull/259)
|
6
8
|
- Bugfix: Fix "stack level too deep" in CI builds - [md-work](https://github.com/md-work) [#283](https://github.com/egonSchiele/contracts.ruby/pull/283)
|
data/Gemfile
CHANGED
@@ -1,17 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source "https://rubygems.org"
|
2
4
|
|
3
5
|
gemspec
|
4
6
|
|
5
7
|
group :test do
|
6
|
-
gem "rspec"
|
7
8
|
gem "aruba"
|
8
9
|
gem "cucumber", "~> 1.3.20"
|
9
|
-
gem "
|
10
|
+
gem "rspec"
|
11
|
+
|
12
|
+
gem "rubocop", ">= 1.0.0"
|
13
|
+
gem "rubocop-performance", ">= 1.0.0"
|
10
14
|
end
|
11
15
|
|
12
16
|
group :development do
|
13
|
-
gem "relish"
|
14
17
|
gem "method_profiler"
|
15
|
-
gem "ruby-prof"
|
16
18
|
gem "rake"
|
19
|
+
gem "relish"
|
20
|
+
gem "ruby-prof"
|
17
21
|
end
|
data/README.md
CHANGED
@@ -1,11 +1,19 @@
|
|
1
1
|
This project is looking for a new maintainer! [More details here](https://github.com/egonSchiele/contracts.ruby/issues/249)
|
2
2
|
|
3
|
-
|
3
|
+
|
4
|
+
|
5
|
+
# contracts.ruby [![GitHub Build Status](https://img.shields.io/github/actions/workflow/status/egonSchiele/contracts.ruby/tests.yaml?branch=master&style=flat-square)](https://github.com/egonSchiele/contracts.ruby/actions/workflows/tests.yaml) [![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)
|
4
6
|
|
5
7
|
Contracts let you clearly – even beautifully – express how your code behaves, and free you from writing tons of boilerplate, defensive code.
|
6
8
|
|
7
9
|
You can think of contracts as `assert` on steroids.
|
8
10
|
|
11
|
+
## 0.17.x = Ruby 3.x only
|
12
|
+
|
13
|
+
0.17.x only supports Ruby 3.x
|
14
|
+
Looking for Ruby 2.x support?
|
15
|
+
Use 0.16.x
|
16
|
+
|
9
17
|
## Installation
|
10
18
|
|
11
19
|
gem install contracts
|
@@ -83,7 +91,7 @@ Using contracts.ruby results in very little slowdown. Check out [this blog post]
|
|
83
91
|
|
84
92
|
**Q.** What Rubies can I use this with?
|
85
93
|
|
86
|
-
**A.** It's been tested with `
|
94
|
+
**A.** It's been tested with `3.0` and `3.1`. (In case this list becomes outdated see [`.github/workflows/tests.yaml`](/.github/workflows/tests.yaml))
|
87
95
|
|
88
96
|
If you're using the library, please [let me know](https://github.com/egonSchiele) what project you're using it on :)
|
89
97
|
|
data/Rakefile
CHANGED
data/TUTORIAL.md
CHANGED
@@ -80,8 +80,8 @@ contracts.ruby comes with a lot of built-in contracts, including the following:
|
|
80
80
|
|
81
81
|
* Logical combinations
|
82
82
|
* [`Maybe`](http://www.rubydoc.info/gems/contracts/Contracts/Builtin/Maybe) – specifies that a value _may be_ nil, e.g. `Maybe[String]` (equivalent to `Or[String,nil]`)
|
83
|
-
* [`Or`](http://www.rubydoc.info/gems/contracts/Contracts/Builtin/Or) – passes if any of the given contracts pass, e.g. `Or[
|
84
|
-
* [`Xor`](http://www.rubydoc.info/gems/contracts/Contracts/Builtin/Xor) – passes if exactly one of the given contracts pass, e.g. `Xor[
|
83
|
+
* [`Or`](http://www.rubydoc.info/gems/contracts/Contracts/Builtin/Or) – passes if any of the given contracts pass, e.g. `Or[Integer, Float]`
|
84
|
+
* [`Xor`](http://www.rubydoc.info/gems/contracts/Contracts/Builtin/Xor) – passes if exactly one of the given contracts pass, e.g. `Xor[Integer, Float]`
|
85
85
|
* [`And`](http://www.rubydoc.info/gems/contracts/Contracts/Builtin/And) – passes if all contracts pass, e.g. `And[Nat, -> (n) { n.even? }]`
|
86
86
|
* [`Not`](http://www.rubydoc.info/gems/contracts/Contracts/Builtin/Not) – passes if all contracts fail for the given argument, e.g. `Not[nil]`
|
87
87
|
|
@@ -89,7 +89,7 @@ contracts.ruby comes with a lot of built-in contracts, including the following:
|
|
89
89
|
* [`ArrayOf`](http://www.rubydoc.info/gems/contracts/Contracts/Builtin/ArrayOf) – checks that the argument is an array, and all elements pass the given contract, e.g. `ArrayOf[Num]`
|
90
90
|
* [`SetOf`](http://www.rubydoc.info/gems/contracts/Contracts/Builtin/SetOf) – checks that the argument is a set, and all elements pass the given contract, e.g. `SetOf[Num]`
|
91
91
|
* [`HashOf`](http://www.rubydoc.info/gems/contracts/Contracts/Builtin/HashOf) – checks that the argument is a hash, and all keys and values pass the given contract, e.g. `HashOf[Symbol => String]` or `HashOf[Symbol,String]`
|
92
|
-
* [`StrictHash`](http://www.rubydoc.info/gems/contracts/Contracts/Builtin/StrictHash) – checks that the argument is a hash, and every key passed is present in the given contract, e.g. `StrictHash[{ :description => String, :number =>
|
92
|
+
* [`StrictHash`](http://www.rubydoc.info/gems/contracts/Contracts/Builtin/StrictHash) – checks that the argument is a hash, and every key passed is present in the given contract, e.g. `StrictHash[{ :description => String, :number => Integer }]`
|
93
93
|
* [`RangeOf`](http://www.rubydoc.info/gems/contracts/Contracts/Builtin/RangeOf) – checks that the argument is a range whose elements (#first and #last) pass the given contract, e.g. `RangeOf[Date]`
|
94
94
|
* [`Enum`](http://www.rubydoc.info/gems/contracts/Contracts/Builtin/Enum) – checks that the argument is part of a given collection of objects, e.g. `Enum[:a, :b, :c]`
|
95
95
|
|
@@ -152,7 +152,7 @@ end
|
|
152
152
|
|
153
153
|
You always need to specify a contract for the return value. In this example, `hello` doesn't return anything, so the contract is `nil`. Now you know that you can use a constant like `nil` as the end of a contract. Valid values for a contract are:
|
154
154
|
|
155
|
-
- the name of a class (like `String` or `
|
155
|
+
- the name of a class (like `String` or `Integer`)
|
156
156
|
- a constant (like `nil` or `1`)
|
157
157
|
- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not
|
158
158
|
- a class that responds to the `valid?` class method (more on this later)
|
@@ -161,32 +161,32 @@ You always need to specify a contract for the return value. In this example, `he
|
|
161
161
|
### A Double Function
|
162
162
|
|
163
163
|
```ruby
|
164
|
-
Contract C::Or[
|
164
|
+
Contract C::Or[Integer, Float] => C::Or[Integer, Float]
|
165
165
|
def double(x)
|
166
166
|
2 * x
|
167
167
|
end
|
168
168
|
```
|
169
169
|
|
170
170
|
Sometimes you want to be able to choose between a few contracts. `Or` takes a variable number of contracts and checks the argument against all of them. If it passes for any of the contracts, then the `Or` contract passes.
|
171
|
-
This introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[
|
171
|
+
This introduces some new syntax. One of the valid values for a contract is an instance of a class that responds to the `valid?` method. This is what `Or[Integer, Float]` is. The longer way to write it would have been:
|
172
172
|
|
173
173
|
```ruby
|
174
|
-
Contract C::Or.new(
|
174
|
+
Contract C::Or.new(Integer, Float) => C::Or.new(Integer, Float)
|
175
175
|
```
|
176
176
|
|
177
177
|
All the built-in contracts have overridden the square brackets (`[]`) to give the same functionality. So you could write
|
178
178
|
|
179
179
|
```ruby
|
180
|
-
Contract C::Or[
|
180
|
+
Contract C::Or[Integer, Float] => C::Or[Integer, Float]
|
181
181
|
```
|
182
182
|
|
183
183
|
or
|
184
184
|
|
185
185
|
```ruby
|
186
|
-
Contract C::Or.new(
|
186
|
+
Contract C::Or.new(Integer, Float) => C::Or.new(Integer, Float)
|
187
187
|
```
|
188
188
|
|
189
|
-
whichever you prefer. They both mean the same thing here: make a new instance of `Or` with `
|
189
|
+
whichever you prefer. They both mean the same thing here: make a new instance of `Or` with `Integer` and `Float`. Use that instance to validate the argument.
|
190
190
|
|
191
191
|
### A Product Function
|
192
192
|
|
@@ -455,7 +455,7 @@ Now you can use `Person` wherever you would have used `Or[Hash, nil]`. Your code
|
|
455
455
|
|
456
456
|
Contracts are very easy to define. To re-iterate, there are 5 kinds of contracts:
|
457
457
|
|
458
|
-
- the name of a class (like `String` or `
|
458
|
+
- the name of a class (like `String` or `Integer`)
|
459
459
|
- a constant (like `nil` or `1`)
|
460
460
|
- a `Proc` that takes a value and returns true or false to indicate whether the contract passed or not
|
461
461
|
- a class that responds to the `valid?` class method (more on this later)
|
@@ -511,7 +511,7 @@ The `Or` contract takes a sequence of contracts, and passes if any of them pass.
|
|
511
511
|
This class inherits from `CallableClass`, which allows us to use `[]` when using the class:
|
512
512
|
|
513
513
|
```ruby
|
514
|
-
Contract C::Or[
|
514
|
+
Contract C::Or[Integer, Float] => C::Num
|
515
515
|
def double(x)
|
516
516
|
2 * x
|
517
517
|
end
|
@@ -520,7 +520,7 @@ end
|
|
520
520
|
Without `CallableClass`, we would have to use `.new` instead:
|
521
521
|
|
522
522
|
```ruby
|
523
|
-
Contract C::Or.new(
|
523
|
+
Contract C::Or.new(Integer, Float) => C::Num
|
524
524
|
def double(x)
|
525
525
|
# etc
|
526
526
|
```
|
@@ -723,7 +723,7 @@ class MyBirthday < Struct.new(:day, :month)
|
|
723
723
|
invariant(:day) { 1 <= day && day <= 31 }
|
724
724
|
invariant(:month) { 1 <= month && month <= 12 }
|
725
725
|
|
726
|
-
Contract C::None =>
|
726
|
+
Contract C::None => Integer
|
727
727
|
def silly_next_day!
|
728
728
|
self.day += 1
|
729
729
|
end
|
data/contracts.gemspec
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require File.expand_path(File.join(__FILE__, "../lib/contracts/version"))
|
2
4
|
|
3
5
|
Gem::Specification.new do |s|
|
@@ -10,8 +12,5 @@ Gem::Specification.new do |s|
|
|
10
12
|
s.files = `git ls-files`.split("\n")
|
11
13
|
s.homepage = "https://github.com/egonSchiele/contracts.ruby"
|
12
14
|
s.license = "BSD-2-Clause"
|
13
|
-
s.
|
14
|
-
0.16.x will be the supporting Ruby 2.x and be feature frozen (only fixes will be released)
|
15
|
-
For Ruby 3.x use 0.17.x or later (might not be released yet)
|
16
|
-
"
|
15
|
+
s.required_ruby_version = [">= 3.0", "< 4"]
|
17
16
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
Feature: KeywordArgs when used with optional positional arguments
|
2
|
+
|
3
|
+
Checks that the argument is an options hash, and all required keyword arguments are present, and all values pass their respective contracts
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
Contract Any, KeywordArgs[:number => Num, :description => Optional[String]] => Any
|
7
|
+
```
|
8
|
+
|
9
|
+
Background:
|
10
|
+
Given a file named "keyword_args_with_optional_positional_args_usage.rb" with:
|
11
|
+
"""ruby
|
12
|
+
require "contracts"
|
13
|
+
C = Contracts
|
14
|
+
|
15
|
+
class Example
|
16
|
+
include Contracts::Core
|
17
|
+
|
18
|
+
Contract C::Any, String, C::KeywordArgs[b: C::Optional[String]] => Symbol
|
19
|
+
def foo(output, a = 'a', b: 'b')
|
20
|
+
p [a, b]
|
21
|
+
output
|
22
|
+
end
|
23
|
+
end
|
24
|
+
"""
|
25
|
+
|
26
|
+
Scenario: Accepts arguments when only require arguments filled and valid
|
27
|
+
Given a file named "accepts_all_filled_valid_args.rb" with:
|
28
|
+
"""ruby
|
29
|
+
require "./keyword_args_with_optional_positional_args_usage"
|
30
|
+
puts Example.new.foo(:output)
|
31
|
+
"""
|
32
|
+
When I run `ruby accepts_all_filled_valid_args.rb`
|
33
|
+
Then output should contain:
|
34
|
+
"""
|
35
|
+
["a", "b"]
|
36
|
+
output
|
37
|
+
"""
|
38
|
+
|
39
|
+
Scenario: Accepts arguments when all filled and valid
|
40
|
+
Given a file named "accepts_all_filled_valid_args.rb" with:
|
41
|
+
"""ruby
|
42
|
+
require "./keyword_args_with_optional_positional_args_usage"
|
43
|
+
puts Example.new.foo(:output, 'c', b: 'd')
|
44
|
+
"""
|
45
|
+
When I run `ruby accepts_all_filled_valid_args.rb`
|
46
|
+
Then output should contain:
|
47
|
+
"""
|
48
|
+
["c", "d"]
|
49
|
+
output
|
50
|
+
"""
|
51
|
+
|
52
|
+
Scenario: Accepts arguments when only require arguments & optional keyword arguments filled and valid
|
53
|
+
Given a file named "accepts_all_filled_valid_args.rb" with:
|
54
|
+
"""ruby
|
55
|
+
require "./keyword_args_with_optional_positional_args_usage"
|
56
|
+
puts Example.new.foo(:output, b: 'd')
|
57
|
+
"""
|
58
|
+
When I run `ruby accepts_all_filled_valid_args.rb`
|
59
|
+
Then output should contain:
|
60
|
+
"""
|
61
|
+
["a", "d"]
|
62
|
+
output
|
63
|
+
"""
|
64
|
+
|
65
|
+
Scenario: Accepts arguments when only require arguments & optional positional arguments filled and valid
|
66
|
+
Given a file named "accepts_all_filled_valid_args.rb" with:
|
67
|
+
"""ruby
|
68
|
+
require "./keyword_args_with_optional_positional_args_usage"
|
69
|
+
puts Example.new.foo(:output, 'c')
|
70
|
+
"""
|
71
|
+
When I run `ruby accepts_all_filled_valid_args.rb`
|
72
|
+
Then output should contain:
|
73
|
+
"""
|
74
|
+
["c", "b"]
|
75
|
+
output
|
76
|
+
"""
|
@@ -26,7 +26,8 @@ Feature: None
|
|
26
26
|
def autorescue
|
27
27
|
yield
|
28
28
|
rescue => e
|
29
|
-
|
29
|
+
# Since ruby 3.2 the `#inspect` output becomes a bit different
|
30
|
+
puts e.inspect.gsub(/^#</, "").gsub(/Error:\"/, "Error: ")
|
30
31
|
end
|
31
32
|
"""
|
32
33
|
Given a file named "none_usage.rb" with:
|
@@ -42,6 +43,11 @@ Feature: None
|
|
42
43
|
def self.a_symbol(*args)
|
43
44
|
:a_symbol
|
44
45
|
end
|
46
|
+
|
47
|
+
Contract C::None => Symbol
|
48
|
+
def a_symbol(*args)
|
49
|
+
:a_symbol
|
50
|
+
end
|
45
51
|
end
|
46
52
|
"""
|
47
53
|
|
@@ -61,14 +67,14 @@ Feature: None
|
|
61
67
|
Given a file named "anything.rb" with:
|
62
68
|
"""ruby
|
63
69
|
require "./none_usage"
|
64
|
-
autorescue { Example.a_symbol(nil) }
|
65
|
-
autorescue { Example.a_symbol(12) }
|
66
|
-
autorescue { Example.a_symbol(37.5) }
|
67
|
-
autorescue { Example.a_symbol("foo") }
|
68
|
-
autorescue { Example.a_symbol(:foo) }
|
69
|
-
autorescue { Example.a_symbol({}) }
|
70
|
-
autorescue { Example.a_symbol([]) }
|
71
|
-
autorescue { Example.a_symbol(Object) }
|
70
|
+
autorescue { Example.new.a_symbol(nil) }
|
71
|
+
autorescue { Example.new.a_symbol(12) }
|
72
|
+
autorescue { Example.new.a_symbol(37.5) }
|
73
|
+
autorescue { Example.new.a_symbol("foo") }
|
74
|
+
autorescue { Example.new.a_symbol(:foo) }
|
75
|
+
autorescue { Example.new.a_symbol({}) }
|
76
|
+
autorescue { Example.new.a_symbol([]) }
|
77
|
+
autorescue { Example.new.a_symbol(Object) }
|
72
78
|
"""
|
73
79
|
When I run `ruby anything.rb`
|
74
80
|
|
data/features/support/env.rb
CHANGED