contracts 0.12.0 → 0.16.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,7 +7,7 @@ RSpec.describe "Contracts:" do
7
7
  it "should fail for insufficient arguments" do
8
8
  expect do
9
9
  @o.hello
10
- end.to raise_error
10
+ end.to raise_error ArgumentError
11
11
  end
12
12
 
13
13
  it "should fail for insufficient contracts" do
@@ -32,7 +32,7 @@ RSpec.describe "Contracts:" do
32
32
  1
33
33
  end
34
34
  end
35
- end.to raise_error
35
+ end.to raise_error NameError
36
36
  end
37
37
  end
38
38
 
@@ -141,32 +141,6 @@ RSpec.describe "Contracts:" do
141
141
  end.to raise_error(ContractError, /Expected: String/)
142
142
  end
143
143
 
144
- context "when owner class does not include Contracts" do
145
- let(:error) do
146
- # NOTE Unable to support this user-friendly error for ruby
147
- # 1.8.7 and jruby 1.8, 1.9 it has much less support for
148
- # singleton inheritance hierarchy
149
- if Contracts::Support.eigenclass_hierarchy_supported?
150
- [Contracts::ContractsNotIncluded, Contracts::ContractsNotIncluded::DEFAULT_MESSAGE]
151
- else
152
- [NoMethodError, /undefined method `Contract'/]
153
- end
154
- end
155
-
156
- it "fails with descriptive error" do
157
- expect do
158
- Class.new(GenericExample) do
159
- class << self
160
- Contract String => String
161
- def hoge(name)
162
- "super#{name}"
163
- end
164
- end
165
- end
166
- end.to raise_error(*error)
167
- end
168
- end
169
-
170
144
  describe "builtin contracts usage" do
171
145
  it "allows to use builtin contracts without namespacing and redundant Contracts inclusion" do
172
146
  expect do
@@ -176,6 +150,14 @@ RSpec.describe "Contracts:" do
176
150
  end
177
151
  end
178
152
 
153
+ describe "usage in the singleton class of a subclass" do
154
+ subject { SingletonInheritanceExampleSubclass }
155
+
156
+ it "should work with a valid contract on a singleton method" do
157
+ expect(subject.num(1)).to eq(1)
158
+ end
159
+ end
160
+
179
161
  describe "no contracts feature" do
180
162
  it "disables normal contract checks" do
181
163
  object = NoContractsSimpleExample.new
@@ -655,6 +637,28 @@ RSpec.describe "Contracts:" do
655
637
  end.to raise_error(ContractError, not_s(delim "String or Symbol"))
656
638
  end
657
639
 
640
+ it "should wrap and pretty print for long param contracts" do
641
+ expect do
642
+ @o.long_array_param_contracts(true)
643
+ end.to(
644
+ raise_error(
645
+ ParamContractError,
646
+ /\[\(String or Symbol\),\n \(String or Symbol\),/
647
+ )
648
+ )
649
+ end
650
+
651
+ it "should wrap and pretty print for long return contracts" do
652
+ expect do
653
+ @o.long_array_return_contracts
654
+ end.to(
655
+ raise_error(
656
+ ReturnContractError,
657
+ /\[\(String or Symbol\),\n \(String or Symbol\),/
658
+ )
659
+ )
660
+ end
661
+
658
662
  it "should not contain Contracts:: module prefix" do
659
663
  expect do
660
664
  @o.double("bad")
@@ -714,7 +718,7 @@ RSpec.describe "Contracts:" do
714
718
  it "should apply the contract to an inherited method" do
715
719
  c = Child.new
716
720
  expect { c.double(2) }.to_not raise_error
717
- expect { c.double("asd") }.to raise_error
721
+ expect { c.double("asd") }.to raise_error ParamContractError
718
722
  end
719
723
  end
720
724
 
@@ -745,5 +749,22 @@ RSpec.describe "Contracts:" do
745
749
  it "works correctly with methods with passing contracts" do
746
750
  expect { klass.new.foo(42) }.to raise_error(ContractError, /Expected: String/)
747
751
  end
752
+
753
+ # See the discussion on this issue:
754
+ # https://github.com/egonSchiele/contracts.ruby/issues/229
755
+ it "should not fail with 'undefined method 'Contract''" do
756
+ expect do
757
+ class ModuleThenContracts
758
+ include ModuleWithContracts
759
+ include Contracts::Core
760
+
761
+ # fails on this line
762
+ Contract C::Num => C::Num
763
+ def double(x)
764
+ x * 2
765
+ end
766
+ end
767
+ end.to_not raise_error
768
+ end
748
769
  end
749
770
  end
@@ -104,6 +104,10 @@ class GenericExample
104
104
  def person(data)
105
105
  end
106
106
 
107
+ Contract C::StrictHash[{ :name => String, :age => Fixnum }] => nil
108
+ def strict_person(data)
109
+ end
110
+
107
111
  Contract ({ :rigged => C::Or[TrueClass, FalseClass] }) => nil
108
112
  def hash_complex_contracts(data)
109
113
  end
@@ -119,6 +123,11 @@ class GenericExample
119
123
  def person_keywordargs(data)
120
124
  end
121
125
 
126
+ # Testing overloaded method
127
+ Contract String, Fixnum => nil
128
+ def person_keywordargs(name, age)
129
+ end
130
+
122
131
  Contract C::KeywordArgs[:hash => C::HashOf[Symbol, C::Num]] => nil
123
132
  def hash_keywordargs(data)
124
133
  end
@@ -143,6 +152,30 @@ class GenericExample
143
152
  def nested_array_complex_contracts(data)
144
153
  end
145
154
 
155
+ Contract [
156
+ C::Or[String, Symbol],
157
+ C::Or[String, Symbol],
158
+ C::Or[String, Symbol],
159
+ C::Or[String, Symbol],
160
+ C::Or[String, Symbol],
161
+ C::Or[String, Symbol],
162
+ C::Or[String, Symbol]
163
+ ] => nil
164
+ def long_array_param_contracts(data)
165
+ end
166
+
167
+ Contract C::None => [
168
+ C::Or[String, Symbol],
169
+ C::Or[String, Symbol],
170
+ C::Or[String, Symbol],
171
+ C::Or[String, Symbol],
172
+ C::Or[String, Symbol],
173
+ C::Or[String, Symbol],
174
+ C::Or[String, Symbol]
175
+ ]
176
+ def long_array_return_contracts
177
+ end
178
+
146
179
  Contract Proc => C::Any
147
180
  def do_call(&block)
148
181
  block.call
@@ -263,6 +296,10 @@ class GenericExample
263
296
  r.first
264
297
  end
265
298
 
299
+ Contract C::DescendantOf[Enumerable] => nil
300
+ def enumerable_descendant_test(enum)
301
+ end
302
+
266
303
  Contract C::Bool => nil
267
304
  def bool_test(x)
268
305
  end
@@ -621,6 +658,12 @@ class SingletonInheritanceExample
621
658
  end
622
659
 
623
660
  class SingletonInheritanceExampleSubclass < SingletonInheritanceExample
661
+ class << self
662
+ Contract Integer => Integer
663
+ def num(int)
664
+ int
665
+ end
666
+ end
624
667
  end
625
668
 
626
669
  class BareOptionalContractUsed
@@ -670,3 +713,18 @@ module ModuleContractExample
670
713
  :world
671
714
  end
672
715
  end
716
+
717
+ module ModuleWithContracts
718
+ def self.included(base)
719
+ base.extend ClassMethods
720
+ end
721
+
722
+ module ClassMethods
723
+ include Contracts::Core
724
+
725
+ Contract C::None => String
726
+ def foo
727
+ "bar"
728
+ end
729
+ end
730
+ end
@@ -0,0 +1,54 @@
1
+ RSpec.describe "Contracts:" do
2
+ describe "method called with blocks" do
3
+ module FuncTest
4
+ include Contracts::Core
5
+ include Contracts::Builtin
6
+
7
+ Contract Func[Num=>Num] => nil
8
+ def foo(&blk)
9
+ _ = blk.call(2)
10
+ nil
11
+ end
12
+
13
+ Contract Num, Func[Num=>Num] => nil
14
+ def foo2(a, &blk)
15
+ _ = blk.call(2)
16
+ nil
17
+ end
18
+
19
+ Contract Func[Num=>Num] => nil
20
+ def bar(blk)
21
+ _ = blk.call(2)
22
+ nil
23
+ end
24
+
25
+ Contract Num, Func[Num=>Num] => nil
26
+ def bar2(a, blk)
27
+ _ = blk.call(2)
28
+ nil
29
+ end
30
+ end
31
+
32
+ def obj
33
+ Object.new.tap do |o|
34
+ o.extend(FuncTest)
35
+ end
36
+ end
37
+
38
+ it "should enforce return value inside block with no other parameter" do
39
+ expect { obj.foo(&:to_s) }.to raise_error ReturnContractError
40
+ end
41
+
42
+ it "should enforce return value inside block with other parameter" do
43
+ expect { obj.foo2(2) { |x| x.to_s } }.to raise_error ReturnContractError
44
+ end
45
+
46
+ it "should enforce return value inside lambda with no other parameter" do
47
+ expect { obj.bar lambda { |x| x.to_s } }.to raise_error ReturnContractError
48
+ end
49
+
50
+ it "should enforce return value inside lambda with other parameter" do
51
+ expect { obj.bar2(2, lambda { |x| x.to_s }) }.to raise_error ReturnContractError
52
+ end
53
+ end
54
+ end
@@ -120,7 +120,7 @@ RSpec.describe Contract do
120
120
  end.to raise_error(ContractError)
121
121
 
122
122
  expect(obj.greet(double("name"))).to match(
123
- /hello, #\[Double "name"\]/
123
+ /hello, #\[.*Double.*"name"\]/
124
124
  )
125
125
  end
126
126
 
@@ -7,6 +7,11 @@ class GenericExample
7
7
  Contract ({foo: C::Nat}) => nil
8
8
  def nat_test_with_kwarg(foo: 10)
9
9
  end
10
+
11
+ Contract C::KeywordArgs[name: C::Optional[String]], C::Func[String => String] => String
12
+ def keyword_args_hello(name: "Adit", &block)
13
+ "Hey, #{yield name}!"
14
+ end
10
15
  end
11
16
 
12
17
  RSpec.describe "Contracts:" do
@@ -37,4 +42,14 @@ RSpec.describe "Contracts:" do
37
42
  expect { @o.nat_test_with_kwarg }.to raise_error(ContractError)
38
43
  end
39
44
  end
45
+
46
+ describe "keyword args with defaults, with a block" do
47
+ it "should work when both keyword args and a block is given" do
48
+ expect(@o.keyword_args_hello(name: "maggie", &:upcase)).to eq("Hey, MAGGIE!")
49
+ end
50
+
51
+ it "should work even when keyword args aren't given" do
52
+ expect(@o.keyword_args_hello(&:upcase)).to eq("Hey, ADIT!")
53
+ end
54
+ end
40
55
  end
@@ -51,7 +51,7 @@ RSpec.describe "Contracts:" do
51
51
  end.to raise_error(ContractError)
52
52
  end
53
53
 
54
- it "should fail when passed nil to an optional argument which contract shouldnt accept nil" do
54
+ it "should fail when passed nil to an optional argument which contract shouldn't accept nil" do
55
55
  expect do
56
56
  @o.complicated("a", true, :b, :c, 2.0, e: (1..5), f: nil, g: :d) do |x|
57
57
  x
@@ -7,7 +7,7 @@ RSpec.describe "Contract validators" do
7
7
  it "passes when value is in range" do
8
8
  expect do
9
9
  o.method_with_range_contract(5)
10
- end.not_to raise_error(ContractError)
10
+ end.not_to raise_error
11
11
  end
12
12
 
13
13
  it "fails when value is not in range" do
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.12.0
4
+ version: 0.16.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aditya Bhargava
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-20 00:00:00.000000000 Z
11
+ date: 2021-04-17 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,12 +18,15 @@ executables: []
18
18
  extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
- - .gitignore
22
- - .rspec
23
- - .rubocop.yml
24
- - .travis.yml
21
+ - ".github/workflows/code_style_checks.yaml"
22
+ - ".github/workflows/tests.yaml"
23
+ - ".gitignore"
24
+ - ".rspec"
25
+ - ".rubocop.yml"
26
+ - ".rubocop_todo.yml"
25
27
  - CHANGELOG.markdown
26
28
  - Gemfile
29
+ - LICENSE
27
30
  - README.md
28
31
  - Rakefile
29
32
  - TODO.markdown
@@ -35,8 +38,10 @@ files:
35
38
  - benchmarks/wrap_test.rb
36
39
  - contracts.gemspec
37
40
  - cucumber.yml
41
+ - dependabot.yml
38
42
  - features/README.md
39
43
  - features/basics/functype.feature
44
+ - features/basics/pretty-print.feature
40
45
  - features/basics/simple_example.feature
41
46
  - features/builtin_contracts/README.md
42
47
  - features/builtin_contracts/and.feature
@@ -49,9 +54,11 @@ files:
49
54
  - features/builtin_contracts/exactly.feature
50
55
  - features/builtin_contracts/func.feature
51
56
  - features/builtin_contracts/hash_of.feature
57
+ - features/builtin_contracts/int.feature
52
58
  - features/builtin_contracts/keyword_args.feature
53
59
  - features/builtin_contracts/maybe.feature
54
60
  - features/builtin_contracts/nat.feature
61
+ - features/builtin_contracts/nat_pos.feature
55
62
  - features/builtin_contracts/neg.feature
56
63
  - features/builtin_contracts/none.feature
57
64
  - features/builtin_contracts/not.feature
@@ -65,6 +72,7 @@ files:
65
72
  - features/builtin_contracts/xor.feature
66
73
  - features/support/env.rb
67
74
  - lib/contracts.rb
75
+ - lib/contracts/attrs.rb
68
76
  - lib/contracts/builtin_contracts.rb
69
77
  - lib/contracts/call_with.rb
70
78
  - lib/contracts/core.rb
@@ -81,14 +89,15 @@ files:
81
89
  - lib/contracts/support.rb
82
90
  - lib/contracts/validators.rb
83
91
  - lib/contracts/version.rb
84
- - script/cucumber
85
92
  - script/docs-release
86
93
  - script/docs-staging
87
94
  - script/rubocop.rb
95
+ - spec/attrs_spec.rb
88
96
  - spec/builtin_contracts_spec.rb
89
97
  - spec/contracts_spec.rb
90
98
  - spec/fixtures/fixtures.rb
91
99
  - spec/invariants_spec.rb
100
+ - spec/methods_spec.rb
92
101
  - spec/module_spec.rb
93
102
  - spec/override_validators_spec.rb
94
103
  - spec/ruby_version_specific/contracts_spec_1.9.rb
@@ -98,26 +107,28 @@ files:
98
107
  - spec/support.rb
99
108
  - spec/support_spec.rb
100
109
  - spec/validators_spec.rb
101
- homepage: http://github.com/egonSchiele/contracts.ruby
102
- licenses: []
110
+ homepage: https://github.com/egonSchiele/contracts.ruby
111
+ licenses:
112
+ - BSD-2-Clause
103
113
  metadata: {}
104
- post_install_message:
114
+ post_install_message: "\n 0.16.x will be the supporting Ruby 2.x and be feature
115
+ frozen (only fixes will be released)\n For Ruby 3.x use 0.17.x or later (might
116
+ not be released yet)\n "
105
117
  rdoc_options: []
106
118
  require_paths:
107
119
  - lib
108
120
  required_ruby_version: !ruby/object:Gem::Requirement
109
121
  requirements:
110
- - - ! '>='
122
+ - - ">="
111
123
  - !ruby/object:Gem::Version
112
124
  version: '0'
113
125
  required_rubygems_version: !ruby/object:Gem::Requirement
114
126
  requirements:
115
- - - ! '>='
127
+ - - ">="
116
128
  - !ruby/object:Gem::Version
117
129
  version: '0'
118
130
  requirements: []
119
- rubyforge_project:
120
- rubygems_version: 2.4.8
131
+ rubygems_version: 3.0.3
121
132
  signing_key:
122
133
  specification_version: 4
123
134
  summary: Contracts for Ruby.