contracts 0.17.1 → 0.17.3
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/.github/dependabot.yml +22 -0
- data/.github/workflows/code_style_checks.yaml +4 -2
- data/.github/workflows/tests.yaml +19 -9
- data/.rubocop_todo.yml +1 -1
- data/CHANGELOG.markdown +24 -1
- data/Gemfile +1 -1
- data/Rakefile +8 -0
- data/contracts.gemspec +1 -1
- data/features/advanced/pattern_matching.feature +133 -0
- data/features/basics/{pretty-print.feature → pretty-print_@before_ruby_3_3.feature} +2 -1
- data/features/basics/pretty-print_after_ruby_3_4.feature +242 -0
- data/lib/contracts/formatters.rb +0 -2
- data/lib/contracts/method_handler.rb +3 -1
- data/lib/contracts/version.rb +1 -1
- data/spec/ruby_version_specific/contracts_spec_2.1.rb +5 -1
- metadata +11 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9a3e8688e39f57c226e61188412d8afcadc4b3836818b6287e774eb0c1c50e5a
|
|
4
|
+
data.tar.gz: fc13d092a656848c127f4f49dbb2a5cf60996c766a6309ed207ca6b556402f6d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 386ecf5ae50df02c70b7adb1051b933866aea337213ae2103899b6a004fac17b3e453ea2efad63811e525acfc7372bc01ff4d553b8dbcb456d17f83beab3880c
|
|
7
|
+
data.tar.gz: ef5360cc907a2699d0f6aa4710b0b5d3fd75d89e58d766e8ef8f6a53a48702d271cf1779ac2a440fd1266aecbb369f126cff6bd503ecdad74728e47e6ad1f5dd
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
|
|
4
|
+
- package-ecosystem: bundler
|
|
5
|
+
directory: "/"
|
|
6
|
+
schedule:
|
|
7
|
+
interval: monthly
|
|
8
|
+
time: "06:00"
|
|
9
|
+
timezone: Asia/Hong_Kong
|
|
10
|
+
open-pull-requests-limit: 10
|
|
11
|
+
labels:
|
|
12
|
+
- "dependencies"
|
|
13
|
+
|
|
14
|
+
- package-ecosystem: github-actions
|
|
15
|
+
directory: "/"
|
|
16
|
+
schedule:
|
|
17
|
+
interval: monthly
|
|
18
|
+
time: "06:00"
|
|
19
|
+
timezone: Asia/Hong_Kong
|
|
20
|
+
open-pull-requests-limit: 10
|
|
21
|
+
labels:
|
|
22
|
+
- "dependencies"
|
|
@@ -6,11 +6,13 @@ on:
|
|
|
6
6
|
- master
|
|
7
7
|
paths-ignore:
|
|
8
8
|
- 'README.md'
|
|
9
|
+
- 'CHANGELOG.markdown'
|
|
9
10
|
push:
|
|
10
11
|
branches:
|
|
11
12
|
- master
|
|
12
13
|
paths-ignore:
|
|
13
14
|
- 'README.md'
|
|
15
|
+
- 'CHANGELOG.markdown'
|
|
14
16
|
|
|
15
17
|
jobs:
|
|
16
18
|
rubocop:
|
|
@@ -22,11 +24,11 @@ jobs:
|
|
|
22
24
|
os:
|
|
23
25
|
- ubuntu
|
|
24
26
|
ruby:
|
|
25
|
-
- "3.
|
|
27
|
+
- "3.4"
|
|
26
28
|
runs-on: ${{ matrix.os }}-latest
|
|
27
29
|
steps:
|
|
28
30
|
- name: Checkout
|
|
29
|
-
uses: actions/checkout@
|
|
31
|
+
uses: actions/checkout@v6
|
|
30
32
|
- name: Setup Ruby
|
|
31
33
|
uses: ruby/setup-ruby@v1
|
|
32
34
|
with:
|
|
@@ -6,11 +6,13 @@ on:
|
|
|
6
6
|
- master
|
|
7
7
|
paths-ignore:
|
|
8
8
|
- 'README.md'
|
|
9
|
+
- 'CHANGELOG.markdown'
|
|
9
10
|
push:
|
|
10
11
|
branches:
|
|
11
12
|
- master
|
|
12
13
|
paths-ignore:
|
|
13
14
|
- 'README.md'
|
|
15
|
+
- 'CHANGELOG.markdown'
|
|
14
16
|
|
|
15
17
|
jobs:
|
|
16
18
|
unit_tests:
|
|
@@ -20,22 +22,30 @@ jobs:
|
|
|
20
22
|
fail-fast: false
|
|
21
23
|
matrix:
|
|
22
24
|
os:
|
|
23
|
-
- ubuntu
|
|
25
|
+
- ubuntu-latest
|
|
24
26
|
ruby:
|
|
25
|
-
- "3.3"
|
|
26
|
-
- "3.2"
|
|
27
|
-
- "3.1"
|
|
28
27
|
- "3.0"
|
|
29
|
-
|
|
30
|
-
- "
|
|
31
|
-
|
|
28
|
+
- "3.1"
|
|
29
|
+
- "3.2"
|
|
30
|
+
- "3.3"
|
|
31
|
+
- "3.4"
|
|
32
|
+
- "4.0"
|
|
33
|
+
allow_failures:
|
|
34
|
+
- false
|
|
35
|
+
include:
|
|
36
|
+
- os: ubuntu-latest
|
|
37
|
+
ruby: ruby-head
|
|
38
|
+
allow_failures: true
|
|
39
|
+
env:
|
|
40
|
+
ALLOW_FAILURES: "${{ matrix.allow_failures }}"
|
|
41
|
+
runs-on: ${{ matrix.os }}
|
|
32
42
|
steps:
|
|
33
43
|
- name: Checkout
|
|
34
|
-
uses: actions/checkout@
|
|
44
|
+
uses: actions/checkout@v6
|
|
35
45
|
- name: Setup Ruby
|
|
36
46
|
uses: ruby/setup-ruby@v1
|
|
37
47
|
with:
|
|
38
48
|
ruby-version: ${{ matrix.ruby }}
|
|
39
49
|
bundler-cache: true
|
|
40
50
|
- name: Test
|
|
41
|
-
run:
|
|
51
|
+
run: "bundle exec rspec && bundle exec rake cucumber || $ALLOW_FAILURES"
|
data/.rubocop_todo.yml
CHANGED
data/CHANGELOG.markdown
CHANGED
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
## [v0.17.3]
|
|
2
|
+
- Relax `required_ruby_version` to support Ruby 4.0
|
|
3
|
+
- Bump cucumber, rubocop, actions/checkout
|
|
4
|
+
|
|
5
|
+
## [v0.17.2] - 2024-10-06
|
|
6
|
+
|
|
7
|
+
[v0.17.2]: https://github.com/egonSchiele/contracts.ruby/compare/v0.17.1...v0.17.2
|
|
8
|
+
|
|
9
|
+
- Bugfix: Fix pattern matching - [PikachuEXE](https://github.com/PikachuEXE) [#308](https://github.com/egonSchiele/contracts.ruby/pull/308)
|
|
10
|
+
|
|
11
|
+
## [v0.17.1] - 2024-10-06
|
|
12
|
+
|
|
13
|
+
[v0.17.1]: https://github.com/egonSchiele/contracts.ruby/compare/v0.17...v0.17.1
|
|
14
|
+
|
|
15
|
+
- Bugfix: Fix keyword arguments contract when used with optional positional arguments - [PikachuEXE](https://github.com/PikachuEXE) [#305](https://github.com/egonSchiele/contracts.ruby/pull/305)
|
|
16
|
+
- Enhancement: Always load version.rb, suppress legacy deprecation warning - [Vlad Pisanov](https://github.com/vlad-pisanov) [#301](https://github.com/egonSchiele/contracts.ruby/pull/306)
|
|
17
|
+
- Enhancement: Update doc & spec about deprecated `Fixnum` to `Integer` - [PikachuEXE](https://github.com/PikachuEXE) [#301](https://github.com/egonSchiele/contracts.ruby/pull/301)
|
|
18
|
+
|
|
19
|
+
## [v0.17] - 2021-09-28
|
|
20
|
+
|
|
21
|
+
[v0.17]: https://github.com/egonSchiele/contracts.ruby/compare/v0.16.1...v0.17
|
|
22
|
+
|
|
23
|
+
- Update implementation & spec to be 3.0 compatible **Support for Ruby 2 has been discontinued** - [PikachuEXE](https://github.com/PikachuEXE) [#295](https://github.com/egonSchiele/contracts.ruby/pull/295)
|
|
1
24
|
|
|
2
25
|
## [v0.16.1] - 2021-04-17
|
|
3
26
|
|
|
@@ -20,7 +43,7 @@
|
|
|
20
43
|
[v0.15.0]: https://github.com/egonSchiele/contracts.ruby/compare/v0.14.0...v0.15.0
|
|
21
44
|
|
|
22
45
|
- Bugfix: Func contract's return value isn't enforced with blocks - [Piotr Szmielew](https://github.com/esse) [#251](https://github.com/egonSchiele/contracts.ruby/pull/251)
|
|
23
|
-
-
|
|
46
|
+
- Bugfix: Fix contracts used in AR-models - [Gert Goet](https://github.com/eval) [#237](https://github.com/egonSchiele/contracts.ruby/pull/237)
|
|
24
47
|
|
|
25
48
|
## [v0.14.0] - 2016-04-26
|
|
26
49
|
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
task :default => [:spec]
|
|
4
4
|
|
|
5
|
+
task :cucumber do
|
|
6
|
+
if RUBY_VERSION >= "3.4"
|
|
7
|
+
sh "cucumber --tags 'not @before_ruby_3_3'"
|
|
8
|
+
else
|
|
9
|
+
sh "cucumber --tags 'not @after_ruby_3_4'"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
5
13
|
task :add_tag do
|
|
6
14
|
`git tag -a v#{Contracts::VERSION} -m 'v#{Contracts::VERSION}'`
|
|
7
15
|
end
|
data/contracts.gemspec
CHANGED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
Feature: Method Overloading
|
|
2
|
+
|
|
3
|
+
You can use contracts for method overloading! This is commonly called "pattern matching" in functional programming languages.
|
|
4
|
+
|
|
5
|
+
```ruby
|
|
6
|
+
Contract 1 => 1
|
|
7
|
+
def fact x
|
|
8
|
+
x
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
Contract C::Num => C::Num
|
|
12
|
+
def fact x
|
|
13
|
+
x * fact(x - 1)
|
|
14
|
+
end
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Background:
|
|
18
|
+
Given a file named "method_overloading_with_positional_args_usage.rb" with:
|
|
19
|
+
"""ruby
|
|
20
|
+
require "contracts"
|
|
21
|
+
C = Contracts
|
|
22
|
+
|
|
23
|
+
class Example
|
|
24
|
+
include Contracts::Core
|
|
25
|
+
|
|
26
|
+
Contract 1 => 1
|
|
27
|
+
def fact(x)
|
|
28
|
+
x
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
Contract C::Num => C::Num
|
|
32
|
+
def fact(x)
|
|
33
|
+
x * fact(x - 1)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
Given a file named "method_overloading_with_keyword_args_usage.rb" with:
|
|
39
|
+
"""ruby
|
|
40
|
+
require "contracts"
|
|
41
|
+
C = Contracts
|
|
42
|
+
|
|
43
|
+
class Example
|
|
44
|
+
include Contracts::Core
|
|
45
|
+
|
|
46
|
+
Contract C::KeywordArgs[age: Integer, size: Symbol] => String
|
|
47
|
+
def speak(age:, size:)
|
|
48
|
+
"age: #{age} size: #{size}"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
Contract C::KeywordArgs[sound: String] => String
|
|
52
|
+
def speak(sound:)
|
|
53
|
+
"sound: #{sound}"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
Scenario: Positional Args Method 1
|
|
59
|
+
Given a file named "positional_args_method_1.rb" with:
|
|
60
|
+
"""ruby
|
|
61
|
+
require "./method_overloading_with_positional_args_usage"
|
|
62
|
+
puts Example.new.fact(1)
|
|
63
|
+
"""
|
|
64
|
+
When I run `ruby positional_args_method_1.rb`
|
|
65
|
+
Then the output should contain:
|
|
66
|
+
"""
|
|
67
|
+
1
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
Scenario: Positional Args Method 2
|
|
71
|
+
Given a file named "positional_args_method_2.rb" with:
|
|
72
|
+
"""ruby
|
|
73
|
+
require "./method_overloading_with_positional_args_usage"
|
|
74
|
+
puts Example.new.fact(4)
|
|
75
|
+
"""
|
|
76
|
+
When I run `ruby positional_args_method_2.rb`
|
|
77
|
+
Then the output should contain:
|
|
78
|
+
"""
|
|
79
|
+
24
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
Scenario: Keyword Args Method 1
|
|
83
|
+
Given a file named "keyword_args_method_1.rb" with:
|
|
84
|
+
"""ruby
|
|
85
|
+
require "./method_overloading_with_keyword_args_usage"
|
|
86
|
+
puts Example.new.speak(age: 5, size: :large)
|
|
87
|
+
"""
|
|
88
|
+
When I run `ruby keyword_args_method_1.rb`
|
|
89
|
+
Then the output should contain:
|
|
90
|
+
"""
|
|
91
|
+
age: 5 size: large
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
Scenario: Keyword Args Method 2
|
|
95
|
+
Given a file named "keyword_args_method_2.rb" with:
|
|
96
|
+
"""ruby
|
|
97
|
+
require "./method_overloading_with_keyword_args_usage"
|
|
98
|
+
puts Example.new.speak(sound: "woof")
|
|
99
|
+
"""
|
|
100
|
+
When I run `ruby keyword_args_method_2.rb`
|
|
101
|
+
Then the output should contain:
|
|
102
|
+
"""
|
|
103
|
+
sound: woof
|
|
104
|
+
"""
|
|
105
|
+
|
|
106
|
+
Scenario: Incorrect Positional Args Method
|
|
107
|
+
Given a file named "incorrect_positional_args_method.rb" with:
|
|
108
|
+
"""ruby
|
|
109
|
+
require "contracts"
|
|
110
|
+
C = Contracts
|
|
111
|
+
|
|
112
|
+
class Example
|
|
113
|
+
include Contracts::Core
|
|
114
|
+
|
|
115
|
+
# Notice that this method's contract is wider than the one below
|
|
116
|
+
# This would cause this method to be called every time but never the one below
|
|
117
|
+
Contract C::Num => C::Num
|
|
118
|
+
def fact(x)
|
|
119
|
+
x * fact(x - 1)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
Contract 1 => 1
|
|
123
|
+
def fact(x)
|
|
124
|
+
x
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
puts Example.new.fact(4)
|
|
128
|
+
"""
|
|
129
|
+
When I run `ruby incorrect_positional_args_method.rb`
|
|
130
|
+
Then the output should contain:
|
|
131
|
+
"""
|
|
132
|
+
stack level too deep (SystemStackError)
|
|
133
|
+
"""
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
@after_ruby_3_4
|
|
2
|
+
Feature: Pretty printing Contract violations (Ruby 3.4+)
|
|
3
|
+
|
|
4
|
+
Scenario: Big array argument being passed to big array method parameter
|
|
5
|
+
Given a file named "example.rb" with:
|
|
6
|
+
"""ruby
|
|
7
|
+
require "contracts"
|
|
8
|
+
C = Contracts
|
|
9
|
+
|
|
10
|
+
class Example
|
|
11
|
+
include Contracts::Core
|
|
12
|
+
|
|
13
|
+
class << self
|
|
14
|
+
Contract [
|
|
15
|
+
C::Or[String, Symbol],
|
|
16
|
+
C::Or[String, Symbol],
|
|
17
|
+
C::Or[String, Symbol],
|
|
18
|
+
C::Or[String, Symbol],
|
|
19
|
+
C::Or[String, Symbol],
|
|
20
|
+
C::Or[String, Symbol],
|
|
21
|
+
C::Or[String, Symbol]
|
|
22
|
+
] => nil
|
|
23
|
+
def run(data)
|
|
24
|
+
nil
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
puts Example.run([
|
|
30
|
+
["foo", "foo"],
|
|
31
|
+
["foo", "foo"],
|
|
32
|
+
["foo", "foo"],
|
|
33
|
+
["foo", "foo"],
|
|
34
|
+
["foo", "foo"],
|
|
35
|
+
["foo", "foo"],
|
|
36
|
+
["foo", "foo"],
|
|
37
|
+
["foo", "foo"],
|
|
38
|
+
["foo", "foo"]
|
|
39
|
+
])
|
|
40
|
+
"""
|
|
41
|
+
When I run `ruby example.rb`
|
|
42
|
+
Then the output should contain:
|
|
43
|
+
"""
|
|
44
|
+
: Contract violation for argument 1 of 1: (ParamContractError)
|
|
45
|
+
Expected: [(String or Symbol),
|
|
46
|
+
(String or Symbol),
|
|
47
|
+
(String or Symbol),
|
|
48
|
+
(String or Symbol),
|
|
49
|
+
(String or Symbol),
|
|
50
|
+
(String or Symbol),
|
|
51
|
+
(String or Symbol)],
|
|
52
|
+
Actual: [["foo", "foo"],
|
|
53
|
+
["foo", "foo"],
|
|
54
|
+
["foo", "foo"],
|
|
55
|
+
["foo", "foo"],
|
|
56
|
+
["foo", "foo"],
|
|
57
|
+
["foo", "foo"],
|
|
58
|
+
["foo", "foo"],
|
|
59
|
+
["foo", "foo"],
|
|
60
|
+
["foo", "foo"]]
|
|
61
|
+
Value guarded in: Example::run
|
|
62
|
+
With Contract: Array => NilClass
|
|
63
|
+
At: example.rb:17
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
Scenario: Big array value being returned from method expecting different big array type
|
|
67
|
+
Given a file named "example.rb" with:
|
|
68
|
+
"""ruby
|
|
69
|
+
require "contracts"
|
|
70
|
+
C = Contracts
|
|
71
|
+
|
|
72
|
+
class Example
|
|
73
|
+
include Contracts::Core
|
|
74
|
+
|
|
75
|
+
class << self
|
|
76
|
+
Contract C::None => [
|
|
77
|
+
C::Or[String, Symbol],
|
|
78
|
+
C::Or[String, Symbol],
|
|
79
|
+
C::Or[String, Symbol],
|
|
80
|
+
C::Or[String, Symbol],
|
|
81
|
+
C::Or[String, Symbol],
|
|
82
|
+
C::Or[String, Symbol],
|
|
83
|
+
C::Or[String, Symbol]
|
|
84
|
+
]
|
|
85
|
+
def run
|
|
86
|
+
[
|
|
87
|
+
["foo", "foo"],
|
|
88
|
+
["foo", "foo"],
|
|
89
|
+
["foo", "foo"],
|
|
90
|
+
["foo", "foo"],
|
|
91
|
+
["foo", "foo"],
|
|
92
|
+
["foo", "foo"],
|
|
93
|
+
["foo", "foo"],
|
|
94
|
+
["foo", "foo"],
|
|
95
|
+
["foo", "foo"]
|
|
96
|
+
]
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
puts Example.run
|
|
102
|
+
"""
|
|
103
|
+
When I run `ruby example.rb`
|
|
104
|
+
Then the output should contain:
|
|
105
|
+
"""
|
|
106
|
+
: Contract violation for return value: (ReturnContractError)
|
|
107
|
+
Expected: [(String or Symbol),
|
|
108
|
+
(String or Symbol),
|
|
109
|
+
(String or Symbol),
|
|
110
|
+
(String or Symbol),
|
|
111
|
+
(String or Symbol),
|
|
112
|
+
(String or Symbol),
|
|
113
|
+
(String or Symbol)],
|
|
114
|
+
Actual: [["foo", "foo"],
|
|
115
|
+
["foo", "foo"],
|
|
116
|
+
["foo", "foo"],
|
|
117
|
+
["foo", "foo"],
|
|
118
|
+
["foo", "foo"],
|
|
119
|
+
["foo", "foo"],
|
|
120
|
+
["foo", "foo"],
|
|
121
|
+
["foo", "foo"],
|
|
122
|
+
["foo", "foo"]]
|
|
123
|
+
Value guarded in: Example::run
|
|
124
|
+
With Contract: None => Array
|
|
125
|
+
At: example.rb:17
|
|
126
|
+
"""
|
|
127
|
+
|
|
128
|
+
Scenario: Big hash argument being passed to big hash method parameter
|
|
129
|
+
Given a file named "example.rb" with:
|
|
130
|
+
"""ruby
|
|
131
|
+
require "contracts"
|
|
132
|
+
C = Contracts
|
|
133
|
+
|
|
134
|
+
class Example
|
|
135
|
+
include Contracts::Core
|
|
136
|
+
|
|
137
|
+
class << self
|
|
138
|
+
Contract ({
|
|
139
|
+
a: C::Or[String, Symbol],
|
|
140
|
+
b: C::Or[String, Symbol],
|
|
141
|
+
c: C::Or[String, Symbol],
|
|
142
|
+
d: C::Or[String, Symbol],
|
|
143
|
+
e: C::Or[String, Symbol],
|
|
144
|
+
f: C::Or[String, Symbol],
|
|
145
|
+
g: C::Or[String, Symbol]
|
|
146
|
+
}) => nil
|
|
147
|
+
def run(data)
|
|
148
|
+
nil
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
puts Example.run({
|
|
154
|
+
a: ["foo", "foo"],
|
|
155
|
+
b: ["foo", "foo"],
|
|
156
|
+
c: ["foo", "foo"],
|
|
157
|
+
d: ["foo", "foo"],
|
|
158
|
+
e: ["foo", "foo"],
|
|
159
|
+
f: ["foo", "foo"],
|
|
160
|
+
g: ["foo", "foo"]
|
|
161
|
+
})
|
|
162
|
+
"""
|
|
163
|
+
When I run `ruby example.rb`
|
|
164
|
+
Then the output should contain:
|
|
165
|
+
"""
|
|
166
|
+
: Contract violation for argument 1 of 1: (ParamContractError)
|
|
167
|
+
Expected: {a: (String or Symbol),
|
|
168
|
+
b: (String or Symbol),
|
|
169
|
+
c: (String or Symbol),
|
|
170
|
+
d: (String or Symbol),
|
|
171
|
+
e: (String or Symbol),
|
|
172
|
+
f: (String or Symbol),
|
|
173
|
+
g: (String or Symbol)},
|
|
174
|
+
Actual: {a: ["foo", "foo"],
|
|
175
|
+
b: ["foo", "foo"],
|
|
176
|
+
c: ["foo", "foo"],
|
|
177
|
+
d: ["foo", "foo"],
|
|
178
|
+
e: ["foo", "foo"],
|
|
179
|
+
f: ["foo", "foo"],
|
|
180
|
+
g: ["foo", "foo"]}
|
|
181
|
+
Value guarded in: Example::run
|
|
182
|
+
With Contract: Hash => NilClass
|
|
183
|
+
At: example.rb:17
|
|
184
|
+
"""
|
|
185
|
+
|
|
186
|
+
Scenario: Big hash value being returned from method expecting different big hash type
|
|
187
|
+
Given a file named "example.rb" with:
|
|
188
|
+
"""ruby
|
|
189
|
+
require "contracts"
|
|
190
|
+
C = Contracts
|
|
191
|
+
|
|
192
|
+
class Example
|
|
193
|
+
include Contracts::Core
|
|
194
|
+
|
|
195
|
+
class << self
|
|
196
|
+
Contract C::None => ({
|
|
197
|
+
a: C::Or[String, Symbol],
|
|
198
|
+
b: C::Or[String, Symbol],
|
|
199
|
+
c: C::Or[String, Symbol],
|
|
200
|
+
d: C::Or[String, Symbol],
|
|
201
|
+
e: C::Or[String, Symbol],
|
|
202
|
+
f: C::Or[String, Symbol],
|
|
203
|
+
g: C::Or[String, Symbol]
|
|
204
|
+
})
|
|
205
|
+
def run
|
|
206
|
+
{
|
|
207
|
+
a: ["foo", "foo"],
|
|
208
|
+
b: ["foo", "foo"],
|
|
209
|
+
c: ["foo", "foo"],
|
|
210
|
+
d: ["foo", "foo"],
|
|
211
|
+
e: ["foo", "foo"],
|
|
212
|
+
f: ["foo", "foo"],
|
|
213
|
+
g: ["foo", "foo"]
|
|
214
|
+
}
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
puts Example.run
|
|
220
|
+
"""
|
|
221
|
+
When I run `ruby example.rb`
|
|
222
|
+
Then the output should contain:
|
|
223
|
+
"""
|
|
224
|
+
: Contract violation for return value: (ReturnContractError)
|
|
225
|
+
Expected: {a: (String or Symbol),
|
|
226
|
+
b: (String or Symbol),
|
|
227
|
+
c: (String or Symbol),
|
|
228
|
+
d: (String or Symbol),
|
|
229
|
+
e: (String or Symbol),
|
|
230
|
+
f: (String or Symbol),
|
|
231
|
+
g: (String or Symbol)},
|
|
232
|
+
Actual: {a: ["foo", "foo"],
|
|
233
|
+
b: ["foo", "foo"],
|
|
234
|
+
c: ["foo", "foo"],
|
|
235
|
+
d: ["foo", "foo"],
|
|
236
|
+
e: ["foo", "foo"],
|
|
237
|
+
f: ["foo", "foo"],
|
|
238
|
+
g: ["foo", "foo"]}
|
|
239
|
+
Value guarded in: Example::run
|
|
240
|
+
With Contract: None => Hash
|
|
241
|
+
At: example.rb:17
|
|
242
|
+
"""
|
data/lib/contracts/formatters.rb
CHANGED
|
@@ -174,8 +174,10 @@ https://github.com/egonSchiele/contracts.ruby/issues
|
|
|
174
174
|
|
|
175
175
|
def validate_pattern_matching!
|
|
176
176
|
new_args_contract = decorator.args_contracts
|
|
177
|
+
new_kargs_contract = decorator.kargs_contract
|
|
177
178
|
matched = decorated_methods.select do |contract|
|
|
178
|
-
contract.args_contracts == new_args_contract
|
|
179
|
+
contract.args_contracts == new_args_contract &&
|
|
180
|
+
contract.kargs_contract == new_kargs_contract
|
|
179
181
|
end
|
|
180
182
|
|
|
181
183
|
return if matched.empty?
|
data/lib/contracts/version.rb
CHANGED
|
@@ -56,7 +56,11 @@ RSpec.describe "Contracts:" do
|
|
|
56
56
|
@o.complicated("a", true, :b, :c, 2.0, e: (1..5), f: nil, g: :d) do |x|
|
|
57
57
|
x
|
|
58
58
|
end
|
|
59
|
-
end.to raise_error(
|
|
59
|
+
end.to raise_error(
|
|
60
|
+
ContractError,
|
|
61
|
+
# 3.3- vs 3.4+ error message format
|
|
62
|
+
/(Expected: \(KeywordArgs\[{:e=>Range, :f=>Optional\[Num\], :g=>Symbol}\]\)|Expected: \(KeywordArgs\[{e: Range, f: Optional\[Num\], g: Symbol}\]\))/,
|
|
63
|
+
)
|
|
60
64
|
end
|
|
61
65
|
end
|
|
62
66
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: contracts
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.17.
|
|
4
|
+
version: 0.17.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Aditya Bhargava
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2025-12-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: This library provides contracts for Ruby. Contracts let you clearly express
|
|
14
14
|
how your code behaves, and free you from writing tons of boilerplate, defensive
|
|
@@ -18,6 +18,7 @@ executables: []
|
|
|
18
18
|
extensions: []
|
|
19
19
|
extra_rdoc_files: []
|
|
20
20
|
files:
|
|
21
|
+
- ".github/dependabot.yml"
|
|
21
22
|
- ".github/workflows/code_style_checks.yaml"
|
|
22
23
|
- ".github/workflows/tests.yaml"
|
|
23
24
|
- ".gitignore"
|
|
@@ -40,8 +41,10 @@ files:
|
|
|
40
41
|
- cucumber.yml
|
|
41
42
|
- dependabot.yml
|
|
42
43
|
- features/README.md
|
|
44
|
+
- features/advanced/pattern_matching.feature
|
|
43
45
|
- features/basics/functype.feature
|
|
44
|
-
- features/basics/pretty-
|
|
46
|
+
- features/basics/pretty-print_@before_ruby_3_3.feature
|
|
47
|
+
- features/basics/pretty-print_after_ruby_3_4.feature
|
|
45
48
|
- features/basics/simple_example.feature
|
|
46
49
|
- features/builtin_contracts/README.md
|
|
47
50
|
- features/builtin_contracts/and.feature
|
|
@@ -112,7 +115,7 @@ homepage: https://github.com/egonSchiele/contracts.ruby
|
|
|
112
115
|
licenses:
|
|
113
116
|
- BSD-2-Clause
|
|
114
117
|
metadata: {}
|
|
115
|
-
post_install_message:
|
|
118
|
+
post_install_message:
|
|
116
119
|
rdoc_options: []
|
|
117
120
|
require_paths:
|
|
118
121
|
- lib
|
|
@@ -123,15 +126,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
123
126
|
version: '3.0'
|
|
124
127
|
- - "<"
|
|
125
128
|
- !ruby/object:Gem::Version
|
|
126
|
-
version: '
|
|
129
|
+
version: '5'
|
|
127
130
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
131
|
requirements:
|
|
129
132
|
- - ">="
|
|
130
133
|
- !ruby/object:Gem::Version
|
|
131
134
|
version: '0'
|
|
132
135
|
requirements: []
|
|
133
|
-
rubygems_version: 3.
|
|
134
|
-
signing_key:
|
|
136
|
+
rubygems_version: 3.0.3.1
|
|
137
|
+
signing_key:
|
|
135
138
|
specification_version: 4
|
|
136
139
|
summary: Contracts for Ruby.
|
|
137
140
|
test_files: []
|