entitlements-app 0.1.8 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (176) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/bin/deploy-entitlements +10 -1
  4. data/lib/contracts-ruby2/CHANGELOG.markdown +115 -0
  5. data/lib/contracts-ruby2/Gemfile +17 -0
  6. data/lib/contracts-ruby2/LICENSE +23 -0
  7. data/lib/contracts-ruby2/README.md +108 -0
  8. data/lib/contracts-ruby2/Rakefile +8 -0
  9. data/lib/contracts-ruby2/TODO.markdown +6 -0
  10. data/lib/contracts-ruby2/TUTORIAL.md +773 -0
  11. data/lib/contracts-ruby2/benchmarks/bench.rb +67 -0
  12. data/lib/contracts-ruby2/benchmarks/hash.rb +69 -0
  13. data/lib/contracts-ruby2/benchmarks/invariants.rb +91 -0
  14. data/lib/contracts-ruby2/benchmarks/io.rb +62 -0
  15. data/lib/contracts-ruby2/benchmarks/wrap_test.rb +57 -0
  16. data/lib/contracts-ruby2/contracts.gemspec +17 -0
  17. data/lib/contracts-ruby2/cucumber.yml +1 -0
  18. data/lib/contracts-ruby2/dependabot.yml +20 -0
  19. data/lib/contracts-ruby2/features/README.md +17 -0
  20. data/lib/contracts-ruby2/features/basics/functype.feature +71 -0
  21. data/lib/contracts-ruby2/features/basics/pretty-print.feature +241 -0
  22. data/lib/contracts-ruby2/features/basics/simple_example.feature +210 -0
  23. data/lib/contracts-ruby2/features/builtin_contracts/README.md +22 -0
  24. data/lib/contracts-ruby2/features/builtin_contracts/and.feature +103 -0
  25. data/lib/contracts-ruby2/features/builtin_contracts/any.feature +44 -0
  26. data/lib/contracts-ruby2/features/builtin_contracts/args.feature +80 -0
  27. data/lib/contracts-ruby2/features/builtin_contracts/array_of.feature +1 -0
  28. data/lib/contracts-ruby2/features/builtin_contracts/bool.feature +64 -0
  29. data/lib/contracts-ruby2/features/builtin_contracts/enum.feature +1 -0
  30. data/lib/contracts-ruby2/features/builtin_contracts/eq.feature +1 -0
  31. data/lib/contracts-ruby2/features/builtin_contracts/exactly.feature +1 -0
  32. data/lib/contracts-ruby2/features/builtin_contracts/func.feature +1 -0
  33. data/lib/contracts-ruby2/features/builtin_contracts/hash_of.feature +1 -0
  34. data/lib/contracts-ruby2/features/builtin_contracts/int.feature +93 -0
  35. data/lib/contracts-ruby2/features/builtin_contracts/keyword_args.feature +1 -0
  36. data/lib/contracts-ruby2/features/builtin_contracts/maybe.feature +1 -0
  37. data/lib/contracts-ruby2/features/builtin_contracts/nat.feature +115 -0
  38. data/lib/contracts-ruby2/features/builtin_contracts/nat_pos.feature +119 -0
  39. data/lib/contracts-ruby2/features/builtin_contracts/neg.feature +115 -0
  40. data/lib/contracts-ruby2/features/builtin_contracts/none.feature +145 -0
  41. data/lib/contracts-ruby2/features/builtin_contracts/not.feature +1 -0
  42. data/lib/contracts-ruby2/features/builtin_contracts/num.feature +64 -0
  43. data/lib/contracts-ruby2/features/builtin_contracts/or.feature +83 -0
  44. data/lib/contracts-ruby2/features/builtin_contracts/pos.feature +116 -0
  45. data/lib/contracts-ruby2/features/builtin_contracts/range_of.feature +1 -0
  46. data/lib/contracts-ruby2/features/builtin_contracts/respond_to.feature +78 -0
  47. data/lib/contracts-ruby2/features/builtin_contracts/send.feature +147 -0
  48. data/lib/contracts-ruby2/features/builtin_contracts/set_of.feature +1 -0
  49. data/lib/contracts-ruby2/features/builtin_contracts/xor.feature +99 -0
  50. data/lib/contracts-ruby2/features/support/env.rb +6 -0
  51. data/lib/contracts-ruby2/lib/contracts/attrs.rb +24 -0
  52. data/lib/contracts-ruby2/lib/contracts/builtin_contracts.rb +542 -0
  53. data/lib/contracts-ruby2/lib/contracts/call_with.rb +108 -0
  54. data/lib/contracts-ruby2/lib/contracts/core.rb +52 -0
  55. data/lib/contracts-ruby2/lib/contracts/decorators.rb +47 -0
  56. data/lib/contracts-ruby2/lib/contracts/engine/base.rb +136 -0
  57. data/lib/contracts-ruby2/lib/contracts/engine/eigenclass.rb +50 -0
  58. data/lib/contracts-ruby2/lib/contracts/engine/target.rb +70 -0
  59. data/lib/contracts-ruby2/lib/contracts/engine.rb +26 -0
  60. data/lib/contracts-ruby2/lib/contracts/errors.rb +71 -0
  61. data/lib/contracts-ruby2/lib/contracts/formatters.rb +136 -0
  62. data/lib/contracts-ruby2/lib/contracts/invariants.rb +68 -0
  63. data/lib/contracts-ruby2/lib/contracts/method_handler.rb +187 -0
  64. data/lib/contracts-ruby2/lib/contracts/method_reference.rb +100 -0
  65. data/lib/contracts-ruby2/lib/contracts/support.rb +61 -0
  66. data/lib/contracts-ruby2/lib/contracts/validators.rb +139 -0
  67. data/lib/contracts-ruby2/lib/contracts/version.rb +3 -0
  68. data/lib/contracts-ruby2/lib/contracts.rb +281 -0
  69. data/lib/contracts-ruby2/script/docs-release +3 -0
  70. data/lib/contracts-ruby2/script/docs-staging +3 -0
  71. data/lib/contracts-ruby2/script/rubocop.rb +5 -0
  72. data/lib/contracts-ruby2/spec/attrs_spec.rb +119 -0
  73. data/lib/contracts-ruby2/spec/builtin_contracts_spec.rb +461 -0
  74. data/lib/contracts-ruby2/spec/contracts_spec.rb +770 -0
  75. data/lib/contracts-ruby2/spec/fixtures/fixtures.rb +730 -0
  76. data/lib/contracts-ruby2/spec/invariants_spec.rb +17 -0
  77. data/lib/contracts-ruby2/spec/methods_spec.rb +54 -0
  78. data/lib/contracts-ruby2/spec/module_spec.rb +18 -0
  79. data/lib/contracts-ruby2/spec/override_validators_spec.rb +162 -0
  80. data/lib/contracts-ruby2/spec/ruby_version_specific/contracts_spec_1.9.rb +24 -0
  81. data/lib/contracts-ruby2/spec/ruby_version_specific/contracts_spec_2.0.rb +55 -0
  82. data/lib/contracts-ruby2/spec/ruby_version_specific/contracts_spec_2.1.rb +63 -0
  83. data/lib/contracts-ruby2/spec/spec_helper.rb +102 -0
  84. data/lib/contracts-ruby2/spec/support.rb +10 -0
  85. data/lib/contracts-ruby2/spec/support_spec.rb +21 -0
  86. data/lib/contracts-ruby2/spec/validators_spec.rb +47 -0
  87. data/lib/contracts-ruby3/CHANGELOG.markdown +117 -0
  88. data/lib/contracts-ruby3/Gemfile +21 -0
  89. data/lib/contracts-ruby3/LICENSE +23 -0
  90. data/lib/contracts-ruby3/README.md +114 -0
  91. data/lib/contracts-ruby3/Rakefile +10 -0
  92. data/lib/contracts-ruby3/TODO.markdown +6 -0
  93. data/lib/contracts-ruby3/TUTORIAL.md +773 -0
  94. data/lib/contracts-ruby3/benchmarks/bench.rb +67 -0
  95. data/lib/contracts-ruby3/benchmarks/hash.rb +69 -0
  96. data/lib/contracts-ruby3/benchmarks/invariants.rb +91 -0
  97. data/lib/contracts-ruby3/benchmarks/io.rb +62 -0
  98. data/lib/contracts-ruby3/benchmarks/wrap_test.rb +57 -0
  99. data/lib/contracts-ruby3/contracts.gemspec +20 -0
  100. data/lib/contracts-ruby3/cucumber.yml +1 -0
  101. data/lib/contracts-ruby3/dependabot.yml +20 -0
  102. data/lib/contracts-ruby3/features/README.md +17 -0
  103. data/lib/contracts-ruby3/features/basics/functype.feature +71 -0
  104. data/lib/contracts-ruby3/features/basics/pretty-print.feature +241 -0
  105. data/lib/contracts-ruby3/features/basics/simple_example.feature +210 -0
  106. data/lib/contracts-ruby3/features/builtin_contracts/README.md +22 -0
  107. data/lib/contracts-ruby3/features/builtin_contracts/and.feature +103 -0
  108. data/lib/contracts-ruby3/features/builtin_contracts/any.feature +44 -0
  109. data/lib/contracts-ruby3/features/builtin_contracts/args.feature +80 -0
  110. data/lib/contracts-ruby3/features/builtin_contracts/array_of.feature +1 -0
  111. data/lib/contracts-ruby3/features/builtin_contracts/bool.feature +64 -0
  112. data/lib/contracts-ruby3/features/builtin_contracts/enum.feature +1 -0
  113. data/lib/contracts-ruby3/features/builtin_contracts/eq.feature +1 -0
  114. data/lib/contracts-ruby3/features/builtin_contracts/exactly.feature +1 -0
  115. data/lib/contracts-ruby3/features/builtin_contracts/func.feature +1 -0
  116. data/lib/contracts-ruby3/features/builtin_contracts/hash_of.feature +1 -0
  117. data/lib/contracts-ruby3/features/builtin_contracts/int.feature +93 -0
  118. data/lib/contracts-ruby3/features/builtin_contracts/keyword_args.feature +1 -0
  119. data/lib/contracts-ruby3/features/builtin_contracts/maybe.feature +1 -0
  120. data/lib/contracts-ruby3/features/builtin_contracts/nat.feature +115 -0
  121. data/lib/contracts-ruby3/features/builtin_contracts/nat_pos.feature +119 -0
  122. data/lib/contracts-ruby3/features/builtin_contracts/neg.feature +115 -0
  123. data/lib/contracts-ruby3/features/builtin_contracts/none.feature +145 -0
  124. data/lib/contracts-ruby3/features/builtin_contracts/not.feature +1 -0
  125. data/lib/contracts-ruby3/features/builtin_contracts/num.feature +64 -0
  126. data/lib/contracts-ruby3/features/builtin_contracts/or.feature +83 -0
  127. data/lib/contracts-ruby3/features/builtin_contracts/pos.feature +116 -0
  128. data/lib/contracts-ruby3/features/builtin_contracts/range_of.feature +1 -0
  129. data/lib/contracts-ruby3/features/builtin_contracts/respond_to.feature +78 -0
  130. data/lib/contracts-ruby3/features/builtin_contracts/send.feature +147 -0
  131. data/lib/contracts-ruby3/features/builtin_contracts/set_of.feature +1 -0
  132. data/lib/contracts-ruby3/features/builtin_contracts/xor.feature +99 -0
  133. data/lib/contracts-ruby3/features/support/env.rb +8 -0
  134. data/lib/contracts-ruby3/lib/contracts/attrs.rb +26 -0
  135. data/lib/contracts-ruby3/lib/contracts/builtin_contracts.rb +575 -0
  136. data/lib/contracts-ruby3/lib/contracts/call_with.rb +119 -0
  137. data/lib/contracts-ruby3/lib/contracts/core.rb +54 -0
  138. data/lib/contracts-ruby3/lib/contracts/decorators.rb +50 -0
  139. data/lib/contracts-ruby3/lib/contracts/engine/base.rb +137 -0
  140. data/lib/contracts-ruby3/lib/contracts/engine/eigenclass.rb +51 -0
  141. data/lib/contracts-ruby3/lib/contracts/engine/target.rb +72 -0
  142. data/lib/contracts-ruby3/lib/contracts/engine.rb +28 -0
  143. data/lib/contracts-ruby3/lib/contracts/errors.rb +74 -0
  144. data/lib/contracts-ruby3/lib/contracts/formatters.rb +140 -0
  145. data/lib/contracts-ruby3/lib/contracts/invariants.rb +72 -0
  146. data/lib/contracts-ruby3/lib/contracts/method_handler.rb +197 -0
  147. data/lib/contracts-ruby3/lib/contracts/method_reference.rb +102 -0
  148. data/lib/contracts-ruby3/lib/contracts/support.rb +63 -0
  149. data/lib/contracts-ruby3/lib/contracts/validators.rb +143 -0
  150. data/lib/contracts-ruby3/lib/contracts/version.rb +5 -0
  151. data/lib/contracts-ruby3/lib/contracts.rb +290 -0
  152. data/lib/contracts-ruby3/script/docs-release +3 -0
  153. data/lib/contracts-ruby3/script/docs-staging +3 -0
  154. data/lib/contracts-ruby3/script/rubocop.rb +5 -0
  155. data/lib/contracts-ruby3/spec/attrs_spec.rb +119 -0
  156. data/lib/contracts-ruby3/spec/builtin_contracts_spec.rb +457 -0
  157. data/lib/contracts-ruby3/spec/contracts_spec.rb +773 -0
  158. data/lib/contracts-ruby3/spec/fixtures/fixtures.rb +725 -0
  159. data/lib/contracts-ruby3/spec/invariants_spec.rb +17 -0
  160. data/lib/contracts-ruby3/spec/methods_spec.rb +54 -0
  161. data/lib/contracts-ruby3/spec/module_spec.rb +18 -0
  162. data/lib/contracts-ruby3/spec/override_validators_spec.rb +162 -0
  163. data/lib/contracts-ruby3/spec/ruby_version_specific/contracts_spec_1.9.rb +24 -0
  164. data/lib/contracts-ruby3/spec/ruby_version_specific/contracts_spec_2.0.rb +55 -0
  165. data/lib/contracts-ruby3/spec/ruby_version_specific/contracts_spec_2.1.rb +63 -0
  166. data/lib/contracts-ruby3/spec/spec_helper.rb +102 -0
  167. data/lib/contracts-ruby3/spec/support.rb +10 -0
  168. data/lib/contracts-ruby3/spec/support_spec.rb +21 -0
  169. data/lib/contracts-ruby3/spec/validators_spec.rb +47 -0
  170. data/lib/entitlements/data/groups/calculated/yaml.rb +7 -1
  171. data/lib/entitlements/data/people/yaml.rb +9 -1
  172. data/lib/entitlements/extras/ldap_group/rules/ldap_group.rb +5 -1
  173. data/lib/entitlements/extras/orgchart/person_methods.rb +7 -1
  174. data/lib/entitlements.rb +13 -2
  175. data/lib/ruby_version_check.rb +17 -0
  176. metadata +209 -14
@@ -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
@@ -0,0 +1,18 @@
1
+ module Mod
2
+ include Contracts::Core
3
+
4
+ Contract C::Num => C::Num
5
+ def self.a_module_method a
6
+ a + 1
7
+ end
8
+ end
9
+
10
+ RSpec.describe "module methods" do
11
+ it "should pass for correct input" do
12
+ expect { Mod.a_module_method(2) }.to_not raise_error
13
+ end
14
+
15
+ it "should fail for incorrect input" do
16
+ expect { Mod.a_module_method("bad") }.to raise_error(ContractError)
17
+ end
18
+ end
@@ -0,0 +1,162 @@
1
+ RSpec.describe Contract do
2
+ describe ".override_validator" do
3
+ around do |example|
4
+ Contract.reset_validators
5
+ example.run
6
+ Contract.reset_validators
7
+ end
8
+
9
+ it "allows to override simple validators" do
10
+ Contract.override_validator(Hash) do |contract|
11
+ lambda do |arg|
12
+ return false unless arg.is_a?(Hash)
13
+ # Any hash in my system should have :it_is_a_hash key!
14
+ return false unless arg.key?(:it_is_a_hash)
15
+ contract.keys.all? do |k|
16
+ Contract.valid?(arg[k], contract[k])
17
+ end
18
+ end
19
+ end
20
+
21
+ klass = Class.new do
22
+ include Contracts::Core
23
+
24
+ Contract ({ :a => Contracts::Num, :b => String }) => nil
25
+ def something(opts)
26
+ nil
27
+ end
28
+ end
29
+
30
+ obj = klass.new
31
+
32
+ expect do
33
+ obj.something(:a => 35, :b => "hello")
34
+ end.to raise_error(ContractError)
35
+
36
+ expect do
37
+ obj.something(
38
+ :a => 35,
39
+ :b => "hello",
40
+ :it_is_a_hash => true
41
+ )
42
+ end.not_to raise_error
43
+ end
44
+
45
+ it "allows to override valid contract" do
46
+ Contract.override_validator(:valid) do |contract|
47
+ if contract.respond_to?(:in_valid_state?)
48
+ lambda do |arg|
49
+ contract.in_valid_state? && contract.valid?(arg)
50
+ end
51
+ else
52
+ lambda { |arg| contract.valid?(arg) }
53
+ end
54
+ end
55
+
56
+ stateful_contract = Class.new(Contracts::CallableClass) do
57
+ def initialize(contract)
58
+ @contract = contract
59
+ @state = 0
60
+ end
61
+
62
+ def in_valid_state?
63
+ @state < 3
64
+ end
65
+
66
+ def valid?(arg)
67
+ @state += 1
68
+ Contract.valid?(arg, @contract)
69
+ end
70
+ end
71
+
72
+ klass = Class.new do
73
+ include Contracts::Core
74
+
75
+ Contract stateful_contract[Contracts::Num] => Contracts::Num
76
+ def only_three_times(x)
77
+ x * x
78
+ end
79
+ end
80
+
81
+ obj = klass.new
82
+
83
+ expect(obj.only_three_times(3)).to eq(9)
84
+ expect(obj.only_three_times(3)).to eq(9)
85
+ expect(obj.only_three_times(3)).to eq(9)
86
+
87
+ expect do
88
+ obj.only_three_times(3)
89
+ end.to raise_error(ContractError)
90
+
91
+ expect do
92
+ obj.only_three_times(3)
93
+ end.to raise_error(ContractError)
94
+ end
95
+
96
+ it "allows to override class validator" do
97
+ # Make contracts accept all rspec doubles
98
+ Contract.override_validator(:class) do |contract|
99
+ lambda do |arg|
100
+ arg.is_a?(RSpec::Mocks::Double) ||
101
+ arg.is_a?(contract)
102
+ end
103
+ end
104
+
105
+ klass = Class.new do
106
+ include Contracts::Core
107
+
108
+ Contract String => String
109
+ def greet(name)
110
+ "hello, #{name}"
111
+ end
112
+ end
113
+
114
+ obj = klass.new
115
+
116
+ expect(obj.greet("world")).to eq("hello, world")
117
+
118
+ expect do
119
+ obj.greet(4)
120
+ end.to raise_error(ContractError)
121
+
122
+ expect(obj.greet(double("name"))).to match(
123
+ /hello, #\[.*Double.*"name"\]/
124
+ )
125
+ end
126
+
127
+ it "allows to override default validator" do
128
+ spy = double("spy")
129
+
130
+ Contract.override_validator(:default) do |contract|
131
+ lambda do |arg|
132
+ spy.log("#{arg} == #{contract}")
133
+ arg == contract
134
+ end
135
+ end
136
+
137
+ klass = Class.new do
138
+ include Contracts::Core
139
+
140
+ Contract 1, Contracts::Num => Contracts::Num
141
+ def gcd(_, b)
142
+ b
143
+ end
144
+
145
+ Contract Contracts::Num, Contracts::Num => Contracts::Num
146
+ def gcd(a, b)
147
+ gcd(b % a, a)
148
+ end
149
+ end
150
+
151
+ obj = klass.new
152
+
153
+ expect(spy).to receive(:log).with("8 == 1").ordered.once
154
+ expect(spy).to receive(:log).with("5 == 1").ordered.once
155
+ expect(spy).to receive(:log).with("3 == 1").ordered.once
156
+ expect(spy).to receive(:log).with("2 == 1").ordered.once
157
+ expect(spy).to receive(:log).with("1 == 1").ordered.once
158
+
159
+ obj.gcd(8, 5)
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,24 @@
1
+ class GenericExample
2
+ Contract C::Args[String], C::Num => C::ArrayOf[String]
3
+ def splat_then_arg(*vals, n)
4
+ vals.map { |v| v * n }
5
+ end
6
+
7
+ if ruby_version <= 1.9
8
+ Contract ({:foo => C::Nat}) => nil
9
+ def nat_test_with_kwarg(a_hash)
10
+ end
11
+ end
12
+ end
13
+
14
+ RSpec.describe "Contracts:" do
15
+ before :all do
16
+ @o = GenericExample.new
17
+ end
18
+
19
+ describe "Splat not last (or penultimate to block)" do
20
+ it "should work with arg after splat" do
21
+ expect { @o.splat_then_arg("hello", "world", 3) }.to_not raise_error
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,55 @@
1
+ class GenericExample
2
+ Contract C::Args[String], { repeat: C::Maybe[C::Num] } => C::ArrayOf[String]
3
+ def splat_then_optional_named(*vals, repeat: 2)
4
+ vals.map { |v| v * repeat }
5
+ end
6
+
7
+ Contract ({foo: C::Nat}) => nil
8
+ def nat_test_with_kwarg(foo: 10)
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
15
+ end
16
+
17
+ RSpec.describe "Contracts:" do
18
+ before :all do
19
+ @o = GenericExample.new
20
+ end
21
+
22
+ describe "Optional named arguments" do
23
+ it "should work with optional named argument unfilled after splat" do
24
+ expect { @o.splat_then_optional_named("hello", "world") }.to_not raise_error
25
+ end
26
+
27
+ it "should work with optional named argument filled after splat" do
28
+ expect { @o.splat_then_optional_named("hello", "world", repeat: 3) }.to_not raise_error
29
+ end
30
+ end
31
+
32
+ describe "Nat:" do
33
+ it "should pass for keyword args with correct arg given" do
34
+ expect { @o.nat_test_with_kwarg(foo: 10) }.to_not raise_error
35
+ end
36
+
37
+ it "should fail with a ContractError for wrong keyword args input" do
38
+ expect { @o.nat_test_with_kwarg(foo: -10) }.to raise_error(ContractError)
39
+ end
40
+
41
+ it "should fail with a ContractError for no input" do
42
+ expect { @o.nat_test_with_kwarg }.to raise_error(ContractError)
43
+ end
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
55
+ end
@@ -0,0 +1,63 @@
1
+ class GenericExample
2
+ Contract String, C::Bool, C::Args[Symbol], Float, C::KeywordArgs[e: Range, f: C::Optional[C::Num], g: Symbol], Proc =>
3
+ [Proc, Hash, C::Maybe[C::Num], Range, Float, C::ArrayOf[Symbol], C::Bool, String]
4
+ def complicated(a, b = true, *c, d, e:, f:2, **g, &h)
5
+ h.call [h, g, f, e, d, c, b, a]
6
+ end
7
+ end
8
+
9
+ RSpec.describe "Contracts:" do
10
+ before :all do
11
+ @o = GenericExample.new
12
+ end
13
+
14
+ describe "Required named arguments" do
15
+ describe "really complicated method signature" do
16
+ it "should work with default named args used" do
17
+ expect do
18
+ @o.complicated("a", false, :b, 2.0, e: (1..5), g: :d) { |x| x }
19
+ end.to_not raise_error
20
+ end
21
+
22
+ it "should work with all args filled manually, with extra splat and hash" do
23
+ expect do
24
+ @o.complicated("a", true, :b, :c, 2.0, e: (1..5), f: 8.3, g: :d) do |x|
25
+ x
26
+ end
27
+ end.to_not raise_error
28
+ end
29
+
30
+ it "should fail when the return is invalid" do
31
+ expect do
32
+ @o.complicated("a", true, :b, 2.0, e: (1..5)) { |_x| "bad" }
33
+ end.to raise_error(ContractError)
34
+ end
35
+
36
+ it "should fail when args are invalid" do
37
+ expect do
38
+ @o.complicated("a", "bad", :b, 2.0, e: (1..5)) { |x| x }
39
+ end.to raise_error(ContractError)
40
+ end
41
+
42
+ it "should fail when splat is invalid" do
43
+ expect do
44
+ @o.complicated("a", true, "bad", 2.0, e: (1..5)) { |x| x }
45
+ end.to raise_error(ContractError)
46
+ end
47
+
48
+ it "should fail when named argument is invalid" do
49
+ expect do
50
+ @o.complicated("a", true, :b, 2.0, e: "bad") { |x| x }
51
+ end.to raise_error(ContractError)
52
+ end
53
+
54
+ it "should fail when passed nil to an optional argument which contract shouldn't accept nil" do
55
+ expect do
56
+ @o.complicated("a", true, :b, :c, 2.0, e: (1..5), f: nil, g: :d) do |x|
57
+ x
58
+ end
59
+ end.to raise_error(ContractError, /Expected: \(KeywordArgs\[{:e=>Range, :f=>Optional\[Num\], :g=>Symbol}\]\)/)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,102 @@
1
+ require "contracts"
2
+ require File.expand_path(File.join(__FILE__, "../support"))
3
+ require File.expand_path(File.join(__FILE__, "../fixtures/fixtures"))
4
+
5
+ # This file was generated by the `rspec --init` command. Conventionally, all
6
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
7
+ # The generated `.rspec` file contains `--require spec_helper` which will cause this
8
+ # file to always be loaded, without a need to explicitly require it in any files.
9
+ #
10
+ # Given that it is always loaded, you are encouraged to keep this file as
11
+ # light-weight as possible. Requiring heavyweight dependencies from this file
12
+ # will add to the boot time of your test suite on EVERY test run, even for an
13
+ # individual file that may not need all of that loaded. Instead, consider making
14
+ # a separate helper file that requires the additional dependencies and performs
15
+ # the additional setup, and require it from the spec files that actually need it.
16
+ #
17
+ # The `.rspec` file also contains a few flags that are not defaults but that
18
+ # users commonly want.
19
+ #
20
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
21
+ RSpec.configure do |config|
22
+ config.pattern = "*.rb"
23
+
24
+ # Only load tests who's syntax is valid in the current Ruby
25
+ [1.9, 2.0, 2.1].each do |ver|
26
+ config.pattern << ",ruby_version_specific/*#{ver}.rb" if ruby_version >= ver
27
+ end
28
+
29
+ # rspec-expectations config goes here. You can use an alternate
30
+ # assertion/expectation library such as wrong or the stdlib/minitest
31
+ # assertions if you prefer.
32
+ config.expect_with :rspec do |expectations|
33
+ # This option will default to `true` in RSpec 4. It makes the `description`
34
+ # and `failure_message` of custom matchers include text for helper methods
35
+ # defined using `chain`, e.g.:
36
+ # be_bigger_than(2).and_smaller_than(4).description
37
+ # # => "be bigger than 2 and smaller than 4"
38
+ # ...rather than:
39
+ # # => "be bigger than 2"
40
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
41
+ end
42
+
43
+ # rspec-mocks config goes here. You can use an alternate test double
44
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
45
+ config.mock_with :rspec do |mocks|
46
+ # Prevents you from mocking or stubbing a method that does not exist on
47
+ # a real object. This is generally recommended, and will default to
48
+ # `true` in RSpec 4.
49
+ mocks.verify_partial_doubles = true
50
+ end
51
+
52
+ # These two settings work together to allow you to limit a spec run
53
+ # to individual examples or groups you care about by tagging them with
54
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
55
+ # get run.
56
+ config.filter_run :focus
57
+ config.run_all_when_everything_filtered = true
58
+
59
+ # Limits the available syntax to the non-monkey patched syntax that is recommended.
60
+ # For more details, see:
61
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
62
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
63
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
64
+ config.disable_monkey_patching!
65
+
66
+ # This setting enables warnings. It's recommended, but in some cases may
67
+ # be too noisy due to issues in dependencies.
68
+ # config.warnings = true
69
+
70
+ # Many RSpec users commonly either run the entire suite or an individual
71
+ # file, and it's useful to allow more verbose output when running an
72
+ # individual spec file.
73
+ if config.files_to_run.one?
74
+ # Use the documentation formatter for detailed output,
75
+ # unless a formatter has already been configured
76
+ # (e.g. via a command-line flag).
77
+ config.default_formatter = "doc"
78
+ end
79
+
80
+ # Print the 10 slowest examples and example groups at the
81
+ # end of the spec run, to help surface which specs are running
82
+ # particularly slow.
83
+ config.profile_examples = 10
84
+
85
+ # Run specs in random order to surface order dependencies. If you find an
86
+ # order dependency and want to debug it, you can fix the order by providing
87
+ # the seed, which is printed after each run.
88
+ # --seed 1234
89
+ # Unable to use it now
90
+ config.order = :random
91
+
92
+ # Seed global randomization in this process using the `--seed` CLI option.
93
+ # Setting this allows you to use `--seed` to deterministically reproduce
94
+ # test failures related to randomization by passing the same `--seed` value
95
+ # as the one that triggered the failure.
96
+ Kernel.srand config.seed
97
+
98
+ # Callbacks
99
+ config.after :each do
100
+ ::Contract.restore_failure_callback
101
+ end
102
+ end
@@ -0,0 +1,10 @@
1
+ def with_enabled_no_contracts
2
+ no_contracts = ENV["NO_CONTRACTS"]
3
+ ENV["NO_CONTRACTS"] = "true"
4
+ yield
5
+ ENV["NO_CONTRACTS"] = no_contracts
6
+ end
7
+
8
+ def ruby_version
9
+ RUBY_VERSION.match(/\d+\.\d+/)[0].to_f
10
+ end
@@ -0,0 +1,21 @@
1
+ module Contracts
2
+ RSpec.describe Support do
3
+ describe "eigenclass?" do
4
+ it "is falsey for non-singleton classes" do
5
+ expect(Contracts::Support.eigenclass? String).to be_falsey
6
+ end
7
+
8
+ it "is truthy for singleton classes" do
9
+ singleton_class = String.instance_exec { class << self; self; end }
10
+ expect(Contracts::Support.eigenclass? singleton_class).to be_truthy
11
+ end
12
+ end
13
+
14
+ describe "eigenclass_of" do
15
+ it "returns the eigenclass of a given object" do
16
+ singleton_class = String.instance_exec { class << self; self; end }
17
+ expect(Contracts::Support.eigenclass_of String).to eq singleton_class
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,47 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe "Contract validators" do
4
+ subject(:o) { GenericExample.new }
5
+
6
+ describe "Range" do
7
+ it "passes when value is in range" do
8
+ expect do
9
+ o.method_with_range_contract(5)
10
+ end.not_to raise_error
11
+ end
12
+
13
+ it "fails when value is not in range" do
14
+ expect do
15
+ o.method_with_range_contract(300)
16
+ end.to raise_error(ContractError, /Expected: 1\.\.10/)
17
+ end
18
+
19
+ it "fails when value is incorrect" do
20
+ expect do
21
+ o.method_with_range_contract("hello world")
22
+ end.to raise_error(ContractError, /Expected: 1\.\.10.*Actual: "hello world"/m)
23
+ end
24
+ end
25
+
26
+ describe "Regexp" do
27
+ it "should pass for a matching string" do
28
+ expect { o.should_contain_foo("containing foo") }.to_not raise_error
29
+ end
30
+
31
+ it "should fail for a non-matching string" do
32
+ expect { o.should_contain_foo("that's not F00") }.to raise_error(ContractError)
33
+ end
34
+
35
+ describe "within a hash" do
36
+ it "should pass for a matching string" do
37
+ expect { o.hash_containing_foo(:host => "foo.example.org") }.to_not raise_error
38
+ end
39
+ end
40
+
41
+ describe "within an array" do
42
+ it "should pass for a matching string" do
43
+ expect { o.array_containing_foo(["foo"]) }.to_not raise_error
44
+ end
45
+ end
46
+ end
47
+ end