rdl 2.0.1 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +13 -0
- data/CHANGES.md +35 -0
- data/README.md +153 -116
- data/bin/rdl_query +1 -1
- data/extras/type_tests/typetests.rb +905 -0
- data/lib/rdl.rb +0 -1
- data/lib/rdl/boot.rb +108 -77
- data/lib/rdl/boot_rails.rb +2 -8
- data/lib/rdl/config.rb +44 -17
- data/lib/rdl/contracts/flat.rb +1 -1
- data/lib/rdl/info.rb +3 -3
- data/lib/rdl/query.rb +11 -11
- data/lib/rdl/typecheck.rb +399 -136
- data/lib/rdl/types/finite_hash.rb +3 -2
- data/lib/rdl/types/generic.rb +7 -6
- data/lib/rdl/types/intersection.rb +3 -2
- data/lib/rdl/types/lexer.rex +2 -3
- data/lib/rdl/types/lexer.rex.rb +1 -4
- data/lib/rdl/types/method.rb +7 -6
- data/lib/rdl/types/nominal.rb +10 -1
- data/lib/rdl/types/parser.racc +7 -8
- data/lib/rdl/types/parser.tab.rb +108 -109
- data/lib/rdl/types/structural.rb +1 -0
- data/lib/rdl/types/tuple.rb +2 -2
- data/lib/rdl/types/type.rb +8 -8
- data/lib/rdl/types/type_inferencer.rb +1 -1
- data/lib/rdl/types/union.rb +2 -1
- data/lib/rdl/util.rb +28 -3
- data/lib/rdl/wrap.rb +216 -165
- data/lib/rdl_disable.rb +22 -15
- data/lib/types/core.rb +2 -4
- data/lib/types/core/_aliases.rb +14 -0
- data/lib/types/core/abbrev.rb +3 -0
- data/lib/types/core/array.rb +139 -0
- data/lib/types/core/base64.rb +8 -0
- data/lib/types/core/basic_object.rb +12 -0
- data/lib/types/core/benchmark.rb +9 -0
- data/lib/types/core/bigdecimal.rb +223 -0
- data/lib/types/core/bigmath.rb +10 -0
- data/lib/types/core/bignum.rb +214 -0
- data/lib/types/core/class.rb +15 -0
- data/lib/types/core/complex.rb +123 -0
- data/lib/types/core/coverage.rb +4 -0
- data/lib/types/core/csv.rb +3 -0
- data/lib/types/core/date.rb +4 -0
- data/lib/types/core/dir.rb +37 -0
- data/lib/types/core/encoding.rb +21 -0
- data/lib/types/core/enumerable.rb +96 -0
- data/lib/types/core/enumerator.rb +24 -0
- data/lib/types/core/exception.rb +15 -0
- data/lib/types/core/file.rb +125 -0
- data/lib/types/core/fileutils.rb +4 -0
- data/lib/types/core/fixnum.rb +213 -0
- data/lib/types/core/float.rb +199 -0
- data/lib/types/core/gem.rb +19 -0
- data/lib/types/core/hash.rb +72 -0
- data/lib/types/core/integer.rb +194 -0
- data/lib/types/core/io.rb +101 -0
- data/lib/types/core/kernel.rb +89 -0
- data/lib/types/core/marshal.rb +3 -0
- data/lib/types/core/matchdata.rb +24 -0
- data/lib/types/core/math.rb +50 -0
- data/lib/types/core/module.rb +81 -0
- data/lib/types/core/nil.rb +11 -0
- data/lib/types/core/numeric.rb +56 -0
- data/lib/types/core/object.rb +73 -0
- data/lib/types/core/pathname.rb +104 -0
- data/lib/types/core/proc.rb +12 -0
- data/lib/types/core/process.rb +110 -0
- data/lib/types/core/random.rb +13 -0
- data/lib/types/core/range.rb +37 -0
- data/lib/types/core/rational.rb +207 -0
- data/lib/types/core/regexp.rb +28 -0
- data/lib/types/core/set.rb +56 -0
- data/lib/types/core/string.rb +140 -0
- data/lib/types/core/strscan.rb +6 -0
- data/lib/types/core/symbol.rb +27 -0
- data/lib/types/core/time.rb +66 -0
- data/lib/types/core/uri.rb +18 -0
- data/lib/types/core/yaml.rb +3 -0
- data/lib/types/devise.rb +1 -0
- data/lib/types/devise/controller_helpers.rb +3 -0
- data/lib/types/devise/parameter_sanitizer.rb +2 -0
- data/lib/types/pundit.rb +2 -0
- data/lib/types/rails/_helpers.rb +50 -0
- data/lib/types/rails/abstract_controller/translation.rb +2 -0
- data/lib/types/rails/action_controller/base.rb +3 -0
- data/lib/types/rails/action_controller/instrumentation.rb +6 -0
- data/lib/types/rails/action_controller/metal.rb +3 -0
- data/lib/types/rails/action_controller/mime_responds.rb +13 -0
- data/lib/types/rails/action_controller/parameters.rb +3 -0
- data/lib/types/{rails-5.x → rails}/action_controller/strong_parameters.rb +4 -8
- data/lib/types/rails/action_dispatch/flashhash.rb +8 -0
- data/lib/types/rails/action_dispatch/routing.rb +10 -0
- data/lib/types/rails/action_mailer/base.rb +2 -0
- data/lib/types/rails/action_mailer/message_delivery.rb +2 -0
- data/lib/types/rails/action_view/helpers_sanitizehelper.rb +2 -0
- data/lib/types/rails/action_view/helpers_urlhelper.rb +5 -0
- data/lib/types/rails/active_model/errors.rb +14 -0
- data/lib/types/rails/active_model/validations.rb +2 -0
- data/lib/types/rails/active_record/associations.rb +208 -0
- data/lib/types/rails/active_record/base.rb +2 -0
- data/lib/types/rails/active_record/core.rb +2 -0
- data/lib/types/rails/active_record/finder_methods.rb +2 -0
- data/lib/types/rails/active_record/model_schema.rb +37 -0
- data/lib/types/rails/active_record/relation.rb +11 -0
- data/lib/types/rails/active_record/schema_types.rb +51 -0
- data/lib/types/rails/active_record/validations.rb +2 -0
- data/lib/types/rails/active_support/base.rb +2 -0
- data/lib/types/rails/active_support/logger.rb +3 -0
- data/lib/types/rails/active_support/tagged_logging.rb +2 -0
- data/lib/types/rails/active_support/time_with_zone.rb +13 -0
- data/lib/types/rails/active_support/time_zone.rb +2 -0
- data/lib/types/rails/fixnum.rb +2 -0
- data/lib/types/rails/integer.rb +2 -0
- data/lib/types/rails/rack/request.rb +2 -0
- data/lib/types/rails/string.rb +3 -0
- data/lib/types/rails/time.rb +1 -0
- data/rdl.gemspec +2 -2
- data/test/disabled_test_rdoc.rb +8 -8
- data/test/test_alias.rb +1 -0
- data/test/test_dsl.rb +4 -4
- data/test/test_generic.rb +45 -38
- data/test/test_intersection.rb +10 -10
- data/test/test_le.rb +103 -102
- data/test/test_member.rb +33 -33
- data/test/test_parser.rb +101 -96
- data/test/test_query.rb +84 -84
- data/test/test_rdl.rb +87 -52
- data/test/test_rdl_type.rb +26 -9
- data/test/test_type_contract.rb +32 -31
- data/test/test_typecheck.rb +802 -436
- data/test/test_types.rb +39 -39
- data/test/test_wrap.rb +3 -2
- metadata +91 -120
- data/extras/type_tests/%.rb +0 -171
- data/extras/type_tests/&.rb +0 -159
- data/extras/type_tests/**.rb +0 -222
- data/extras/type_tests/*.rb +0 -177
- data/extras/type_tests/+.rb +0 -170
- data/extras/type_tests/-.rb +0 -171
- data/extras/type_tests/1scomp.rb +0 -157
- data/extras/type_tests/<.rb +0 -170
- data/extras/type_tests/<<.rb +0 -159
- data/extras/type_tests/>>.rb +0 -159
- data/extras/type_tests/[].rb +0 -163
- data/extras/type_tests/^.rb +0 -159
- data/extras/type_tests/abs.rb +0 -155
- data/extras/type_tests/abs2.rb +0 -164
- data/extras/type_tests/angle.rb +0 -157
- data/extras/type_tests/arg.rb +0 -157
- data/extras/type_tests/bit_length.rb +0 -157
- data/extras/type_tests/ceil.rb +0 -157
- data/extras/type_tests/ceilRational.rb +0 -160
- data/extras/type_tests/conj.rb +0 -158
- data/extras/type_tests/defwhere.rb +0 -86
- data/extras/type_tests/denominator.rb +0 -157
- data/extras/type_tests/div.rb +0 -172
- data/extras/type_tests/divslash.rb +0 -179
- data/extras/type_tests/even?.rb +0 -157
- data/extras/type_tests/fdiv.rb +0 -244
- data/extras/type_tests/finite?.rb +0 -157
- data/extras/type_tests/floor.rb +0 -157
- data/extras/type_tests/floorRational.rb +0 -161
- data/extras/type_tests/hash.rb +0 -157
- data/extras/type_tests/imag.rb +0 -158
- data/extras/type_tests/infinite?.rb +0 -157
- data/extras/type_tests/modulo.rb +0 -171
- data/extras/type_tests/nan?.rb +0 -157
- data/extras/type_tests/neg.rb +0 -155
- data/extras/type_tests/next.rb +0 -157
- data/extras/type_tests/next_float.rb +0 -157
- data/extras/type_tests/numerator.rb +0 -157
- data/extras/type_tests/phase.rb +0 -157
- data/extras/type_tests/prev_float.rb +0 -157
- data/extras/type_tests/quo.rb +0 -179
- data/extras/type_tests/rationalize.rb +0 -157
- data/extras/type_tests/rationalizeArg.rb +0 -198
- data/extras/type_tests/real.rb +0 -157
- data/extras/type_tests/real?.rb +0 -157
- data/extras/type_tests/round.rb +0 -157
- data/extras/type_tests/roundArg.rb +0 -169
- data/extras/type_tests/size.rb +0 -157
- data/extras/type_tests/to_c.rb +0 -157
- data/extras/type_tests/to_f.rb +0 -155
- data/extras/type_tests/to_i.rb +0 -157
- data/extras/type_tests/to_r.rb +0 -157
- data/extras/type_tests/to_s.rb +0 -157
- data/extras/type_tests/truncate.rb +0 -157
- data/extras/type_tests/truncateArg.rb +0 -166
- data/extras/type_tests/type tests +0 -1
- data/extras/type_tests/zero?.rb +0 -155
- data/extras/type_tests/|.rb +0 -159
- data/lib/types/core-ruby-2.x/_aliases.rb +0 -15
- data/lib/types/core-ruby-2.x/abbrev.rb +0 -5
- data/lib/types/core-ruby-2.x/array.rb +0 -137
- data/lib/types/core-ruby-2.x/base64.rb +0 -10
- data/lib/types/core-ruby-2.x/basic_object.rb +0 -14
- data/lib/types/core-ruby-2.x/benchmark.rb +0 -11
- data/lib/types/core-ruby-2.x/bigdecimal.rb +0 -224
- data/lib/types/core-ruby-2.x/bigmath.rb +0 -12
- data/lib/types/core-ruby-2.x/bignum.rb +0 -214
- data/lib/types/core-ruby-2.x/class.rb +0 -17
- data/lib/types/core-ruby-2.x/complex.rb +0 -124
- data/lib/types/core-ruby-2.x/coverage.rb +0 -6
- data/lib/types/core-ruby-2.x/csv.rb +0 -5
- data/lib/types/core-ruby-2.x/date.rb +0 -6
- data/lib/types/core-ruby-2.x/dir.rb +0 -38
- data/lib/types/core-ruby-2.x/encoding.rb +0 -23
- data/lib/types/core-ruby-2.x/enumerable.rb +0 -98
- data/lib/types/core-ruby-2.x/enumerator.rb +0 -26
- data/lib/types/core-ruby-2.x/exception.rb +0 -17
- data/lib/types/core-ruby-2.x/file.rb +0 -126
- data/lib/types/core-ruby-2.x/fileutils.rb +0 -6
- data/lib/types/core-ruby-2.x/fixnum.rb +0 -213
- data/lib/types/core-ruby-2.x/float.rb +0 -199
- data/lib/types/core-ruby-2.x/gem.rb +0 -247
- data/lib/types/core-ruby-2.x/hash.rb +0 -72
- data/lib/types/core-ruby-2.x/integer.rb +0 -197
- data/lib/types/core-ruby-2.x/io.rb +0 -103
- data/lib/types/core-ruby-2.x/kernel.rb +0 -90
- data/lib/types/core-ruby-2.x/marshal.rb +0 -5
- data/lib/types/core-ruby-2.x/matchdata.rb +0 -26
- data/lib/types/core-ruby-2.x/math.rb +0 -53
- data/lib/types/core-ruby-2.x/module.rb +0 -83
- data/lib/types/core-ruby-2.x/nil.rb +0 -12
- data/lib/types/core-ruby-2.x/numeric.rb +0 -56
- data/lib/types/core-ruby-2.x/object.rb +0 -75
- data/lib/types/core-ruby-2.x/pathname.rb +0 -106
- data/lib/types/core-ruby-2.x/proc.rb +0 -16
- data/lib/types/core-ruby-2.x/process.rb +0 -127
- data/lib/types/core-ruby-2.x/random.rb +0 -17
- data/lib/types/core-ruby-2.x/range.rb +0 -39
- data/lib/types/core-ruby-2.x/rational.rb +0 -209
- data/lib/types/core-ruby-2.x/regexp.rb +0 -30
- data/lib/types/core-ruby-2.x/set.rb +0 -58
- data/lib/types/core-ruby-2.x/string.rb +0 -143
- data/lib/types/core-ruby-2.x/strscan.rb +0 -7
- data/lib/types/core-ruby-2.x/symbol.rb +0 -29
- data/lib/types/core-ruby-2.x/time.rb +0 -68
- data/lib/types/core-ruby-2.x/uri.rb +0 -20
- data/lib/types/core-ruby-2.x/yaml.rb +0 -5
- data/lib/types/rails-5.x/_helpers.rb +0 -52
- data/lib/types/rails-5.x/action_controller/mime_responds.rb +0 -11
- data/lib/types/rails-5.x/action_dispatch/routing.rb +0 -10
- data/lib/types/rails-5.x/active_model/errors.rb +0 -15
- data/lib/types/rails-5.x/active_model/validations.rb +0 -5
- data/lib/types/rails-5.x/active_record/associations.rb +0 -190
- data/lib/types/rails-5.x/active_record/core.rb +0 -3
- data/lib/types/rails-5.x/active_record/model_schema.rb +0 -39
- data/lib/types/rails-5.x/fixnum.rb +0 -3
data/test/test_rdl.rb
CHANGED
@@ -3,6 +3,7 @@ $LOAD_PATH << File.dirname(__FILE__) + "/../lib"
|
|
3
3
|
require 'rdl'
|
4
4
|
|
5
5
|
class TestRDL < Minitest::Test
|
6
|
+
extend RDL::Annotate
|
6
7
|
|
7
8
|
# Test wrapping with no types or contracts
|
8
9
|
def test_wrap
|
@@ -61,7 +62,7 @@ class TestRDL < Minitest::Test
|
|
61
62
|
def test_pre_contract
|
62
63
|
pos = RDL::Contract::FlatContract.new("Positive") { |x| x > 0 }
|
63
64
|
def m5(x) return x; end
|
64
|
-
pre TestRDL, :m5, pos
|
65
|
+
RDL.pre TestRDL, :m5, pos
|
65
66
|
assert_equal 3, m5(3)
|
66
67
|
assert_raises(RDL::Contract::ContractError) { m5(-1) }
|
67
68
|
end
|
@@ -69,7 +70,7 @@ class TestRDL < Minitest::Test
|
|
69
70
|
def test_post_contract
|
70
71
|
neg = RDL::Contract::FlatContract.new("Negative") { |x| x < 0 }
|
71
72
|
def m6(x) return 3; end
|
72
|
-
post TestRDL, :m6, neg
|
73
|
+
RDL.post TestRDL, :m6, neg
|
73
74
|
assert_raises(RDL::Contract::ContractError) { m6(42) }
|
74
75
|
end
|
75
76
|
|
@@ -77,8 +78,8 @@ class TestRDL < Minitest::Test
|
|
77
78
|
pos = RDL::Contract::FlatContract.new("Positive") { |x| x > 0 }
|
78
79
|
ppos = RDL::Contract::FlatContract.new("Positive") { |r, x| r > 0 }
|
79
80
|
def m7(x) return x; end
|
80
|
-
pre TestRDL, :m7, pos
|
81
|
-
post TestRDL, :m7, ppos
|
81
|
+
RDL.pre TestRDL, :m7, pos
|
82
|
+
RDL.post TestRDL, :m7, ppos
|
82
83
|
assert_equal 3, m7(3)
|
83
84
|
end
|
84
85
|
|
@@ -87,15 +88,15 @@ class TestRDL < Minitest::Test
|
|
87
88
|
five = RDL::Contract::FlatContract.new("Five") { |x| x == 5 }
|
88
89
|
gt = RDL::Contract::FlatContract.new("Greater Than 3") { |x| x > 3 }
|
89
90
|
def m8(x) return x; end
|
90
|
-
pre TestRDL, :m8, pos
|
91
|
-
pre TestRDL, :m8, gt
|
91
|
+
RDL.pre TestRDL, :m8, pos
|
92
|
+
RDL.pre TestRDL, :m8, gt
|
92
93
|
assert_equal 5, m8(5)
|
93
94
|
assert_equal 4, m8(4)
|
94
95
|
assert_raises(RDL::Contract::ContractError) { m8 3 }
|
95
96
|
def m9(x) return x; end
|
96
|
-
pre TestRDL, :m9, pos
|
97
|
-
pre TestRDL, :m9, gt
|
98
|
-
pre TestRDL, :m9, five
|
97
|
+
RDL.pre TestRDL, :m9, pos
|
98
|
+
RDL.pre TestRDL, :m9, gt
|
99
|
+
RDL.pre TestRDL, :m9, five
|
99
100
|
assert_equal 5, m9(5)
|
100
101
|
assert_raises(RDL::Contract::ContractError) { m9 4 }
|
101
102
|
assert_raises(RDL::Contract::ContractError) { m9 3 }
|
@@ -104,15 +105,15 @@ class TestRDL < Minitest::Test
|
|
104
105
|
pfive = RDL::Contract::FlatContract.new("Five") { |r, x| r == 5 }
|
105
106
|
pgt = RDL::Contract::FlatContract.new("Greater Than 3") { |r, x| r > 3 }
|
106
107
|
def m10(x) return x; end
|
107
|
-
post TestRDL, :m10, ppos
|
108
|
-
post TestRDL, :m10, pgt
|
108
|
+
RDL.post TestRDL, :m10, ppos
|
109
|
+
RDL.post TestRDL, :m10, pgt
|
109
110
|
assert_equal 5, m10(5)
|
110
111
|
assert_equal 4, m10(4)
|
111
112
|
assert_raises(RDL::Contract::ContractError) { m10 3 }
|
112
113
|
def m11(x) return x; end
|
113
|
-
post TestRDL, :m11, ppos
|
114
|
-
post TestRDL, :m11, pgt
|
115
|
-
post TestRDL, :m11, pfive
|
114
|
+
RDL.post TestRDL, :m11, ppos
|
115
|
+
RDL.post TestRDL, :m11, pgt
|
116
|
+
RDL.post TestRDL, :m11, pfive
|
116
117
|
assert_equal 5, m11(5)
|
117
118
|
assert_raises(RDL::Contract::ContractError) { m11 4 }
|
118
119
|
assert_raises(RDL::Contract::ContractError) { m11 3 }
|
@@ -120,13 +121,13 @@ class TestRDL < Minitest::Test
|
|
120
121
|
|
121
122
|
def test_deferred_wrap
|
122
123
|
pos = RDL::Contract::FlatContract.new("Positive") { |x| x > 0 }
|
123
|
-
pre TestRDL, :m12, pos
|
124
|
+
RDL.pre TestRDL, :m12, pos
|
124
125
|
def m12(x) return x; end
|
125
126
|
assert_equal 3, m12(3)
|
126
127
|
assert_raises(RDL::Contract::ContractError) { m12(-1) }
|
127
128
|
|
128
129
|
ppos = RDL::Contract::FlatContract.new("Positive") { |r, x| r > 0 }
|
129
|
-
post TestRDL, :m13, ppos
|
130
|
+
RDL.post TestRDL, :m13, ppos
|
130
131
|
def m13(x) return x; end
|
131
132
|
assert_equal 3, m13(3)
|
132
133
|
assert_raises(RDL::Contract::ContractError) { m13(-1) }
|
@@ -218,42 +219,43 @@ RUBY
|
|
218
219
|
end
|
219
220
|
|
220
221
|
def test_type_params
|
221
|
-
self.class.class_eval "class TP1; type_params [:t], :all? end"
|
222
|
+
self.class.class_eval "class TP1; extend RDL::Annotate; type_params [:t], :all? end"
|
222
223
|
assert_equal [[:t], [:~], :all?], RDL::Wrap.get_type_params(TestRDL::TP1)
|
223
|
-
self.class.class_eval "class TP2; type_params([:t], nil) { |t| true } end"
|
224
|
+
self.class.class_eval "class TP2; extend RDL::Annotate; type_params([:t], nil) { |t| true } end"
|
224
225
|
tp2 = RDL::Wrap.get_type_params(TestRDL::TP2)
|
225
226
|
assert_equal [:t], tp2[0]
|
226
227
|
assert_equal [:~], tp2[1]
|
227
|
-
assert_raises(RuntimeError) { self.class.class_eval "class TP1; type_params [:t], :all? end" }
|
228
|
-
self.class.class_eval "class TP3; type_params [:t, :u], :all? end"
|
228
|
+
assert_raises(RuntimeError) { self.class.class_eval "class TP1; extend RDL::Annotate; type_params [:t], :all? end" }
|
229
|
+
self.class.class_eval "class TP3; extend RDL::Annotate; type_params [:t, :u], :all? end"
|
229
230
|
assert_equal [[:t, :u], [:~, :~], :all?], RDL::Wrap.get_type_params(TestRDL::TP3)
|
230
231
|
|
231
|
-
self.class.class_eval "class TP4; type_params [:t, :u, :v], :all?, variance: [:+, :-, :~] end"
|
232
|
+
self.class.class_eval "class TP4; extend RDL::Annotate; type_params [:t, :u, :v], :all?, variance: [:+, :-, :~] end"
|
232
233
|
assert_equal [[:t, :u, :v], [:+, :-, :~], :all?], RDL::Wrap.get_type_params(TestRDL::TP4)
|
233
|
-
assert_raises(RuntimeError) { self.class.class_eval "class TP5; type_params([], :all?) { true } end" }
|
234
|
-
assert_raises(RuntimeError) { self.class.class_eval "class TP6; type_params [:t, :u], :all?, variance: [:+] end" }
|
235
|
-
assert_raises(RuntimeError) { self.class.class_eval "class TP7; type_params [:t, :u], :all?, variance: [:a, :b] end" }
|
236
|
-
assert_raises(RuntimeError) { self.class.class_eval "class TP8; type_params([:t], :all?) { |t| true } end" }
|
237
|
-
assert_raises(RuntimeError) { self.class.class_eval "class TP8; type_params [:t], 42 end" }
|
234
|
+
assert_raises(RuntimeError) { self.class.class_eval "class TP5; extend RDL::Annotate; type_params([], :all?) { true } end" }
|
235
|
+
assert_raises(RuntimeError) { self.class.class_eval "class TP6; extend RDL::Annotate; type_params [:t, :u], :all?, variance: [:+] end" }
|
236
|
+
assert_raises(RuntimeError) { self.class.class_eval "class TP7; extend RDL::Annotate; type_params [:t, :u], :all?, variance: [:a, :b] end" }
|
237
|
+
assert_raises(RuntimeError) { self.class.class_eval "class TP8; extend RDL::Annotate; type_params([:t], :all?) { |t| true } end" }
|
238
|
+
assert_raises(RuntimeError) { self.class.class_eval "class TP8; extend RDL::Annotate; type_params [:t], 42 end" }
|
238
239
|
end
|
239
240
|
|
240
241
|
def test_wrap_new
|
241
242
|
self.class.class_eval "class B; def initialize(x); @x = x end; def get(); return @x end end"
|
242
|
-
pre("TestRDL::B", "self.new") { |x| x > 0 }
|
243
|
+
RDL.pre("TestRDL::B", "self.new") { |x| x > 0 }
|
243
244
|
assert_equal 3, TestRDL::B.new(3).get
|
244
245
|
assert_raises(RDL::Contract::ContractError) { TestRDL::B.new(-3) }
|
245
246
|
|
246
|
-
self.class.class_eval "class C; pre { |x| x > 0 }; def initialize(x); @x = x end; def get(); return @x end end"
|
247
|
+
self.class.class_eval "class C; extend RDL::Annotate; pre { |x| x > 0 }; def initialize(x); @x = x end; def get(); return @x end end"
|
247
248
|
assert_equal 3, TestRDL::C.new(3).get
|
248
249
|
assert_raises(RDL::Contract::ContractError) { TestRDL::C.new(-3) }
|
249
250
|
|
250
251
|
self.class.class_eval "class D; def get(); return @x end end"
|
251
|
-
pre("TestRDL::D", "self.new") { |x| x > 0 }
|
252
|
+
RDL.pre("TestRDL::D", "self.new") { |x| x > 0 }
|
252
253
|
self.class.class_eval "class D; def initialize(x); @x = x end end"
|
253
254
|
assert_equal 3, TestRDL::D.new(3).get
|
254
255
|
assert_raises(RDL::Contract::ContractError) { TestRDL::D.new(-3) }
|
255
256
|
|
256
257
|
skip "Can't defer contracts on new yet"
|
258
|
+
RDL.
|
257
259
|
pre("TestRDL::E", "self.new") { |x| x > 0 }
|
258
260
|
self.class.class_eval "class E; def initialize(x); @x = x end end"
|
259
261
|
assert (TestRDL::E.new(3))
|
@@ -263,13 +265,13 @@ RUBY
|
|
263
265
|
def test_class_method
|
264
266
|
pos = RDL::Contract::FlatContract.new("Positive") { |x| x > 0 }
|
265
267
|
self.class.class_eval { def self.cm1(x) return x; end }
|
266
|
-
pre TestRDL, "self.cm1", pos
|
268
|
+
RDL.pre TestRDL, "self.cm1", pos
|
267
269
|
assert_equal 3, TestRDL.cm1(3)
|
268
270
|
assert_raises(RDL::Contract::ContractError) { TestRDL.cm1(-1) }
|
269
271
|
|
270
|
-
assert_raises(RuntimeError) { pre TestRDL, "TestRDL.cm1", pos }
|
272
|
+
assert_raises(RuntimeError) { RDL.pre TestRDL, "TestRDL.cm1", pos }
|
271
273
|
|
272
|
-
pre TestRDL, "self.cm2", pos
|
274
|
+
RDL.pre TestRDL, "self.cm2", pos
|
273
275
|
self.class.class_eval { def self.cm2(x) return x; end }
|
274
276
|
assert_equal 3, TestRDL.cm2(3)
|
275
277
|
assert_raises(RDL::Contract::ContractError) { TestRDL.cm2(-1) }
|
@@ -283,11 +285,11 @@ RUBY
|
|
283
285
|
end
|
284
286
|
|
285
287
|
def test_cast
|
286
|
-
obj1 =
|
287
|
-
assert (
|
288
|
-
obj2 =
|
289
|
-
assert (
|
290
|
-
assert_raises(RuntimeError) {
|
288
|
+
obj1 = RDL.type_cast(3, RDL::Globals.types[:nil], force: true)
|
289
|
+
assert (RDL::Globals.types[:nil].member? obj1)
|
290
|
+
obj2 = RDL.type_cast(3, 'nil', force: true)
|
291
|
+
assert (RDL::Globals.types[:nil].member? obj2)
|
292
|
+
assert_raises(RuntimeError) { RDL.type_cast(3, RDL::Globals.types[:nil]) }
|
291
293
|
end
|
292
294
|
|
293
295
|
def test_pre_post_self
|
@@ -300,34 +302,34 @@ RUBY
|
|
300
302
|
end
|
301
303
|
|
302
304
|
def test_nowrap
|
303
|
-
pre(TestRDL, :nwrap1) { true }
|
305
|
+
RDL.pre(TestRDL, :nwrap1) { true }
|
304
306
|
def nwrap1(x) return x; end
|
305
307
|
assert(RDL::Wrap.wrapped?(TestRDL, :nwrap1))
|
306
|
-
pre(TestRDL, :nwrap2, wrap: false) { true }
|
308
|
+
RDL.pre(TestRDL, :nwrap2, wrap: false) { true }
|
307
309
|
def nwrap2(x) return x; end
|
308
310
|
assert(not(RDL::Wrap.wrapped?(TestRDL, :nwrap2)))
|
309
311
|
|
310
|
-
post(TestRDL, :nwrap3) { true }
|
312
|
+
RDL.post(TestRDL, :nwrap3) { true }
|
311
313
|
def nwrap3(x) return x; end
|
312
314
|
assert(RDL::Wrap.wrapped?(TestRDL, :nwrap3))
|
313
|
-
post(TestRDL, :nwrap4, wrap: false) { true }
|
315
|
+
RDL.post(TestRDL, :nwrap4, wrap: false) { true }
|
314
316
|
def nwrap4(x) return x; end
|
315
317
|
assert(not(RDL::Wrap.wrapped?(TestRDL, :nwrap4)))
|
316
318
|
|
317
|
-
type TestRDL, :nwrap5, "(
|
319
|
+
RDL.type TestRDL, :nwrap5, "(Integer) -> Integer"
|
318
320
|
def nwrap5(x) return x; end
|
319
321
|
assert(RDL::Wrap.wrapped?(TestRDL, :nwrap5))
|
320
|
-
type TestRDL, :nwrap6, "(
|
322
|
+
RDL.type TestRDL, :nwrap6, "(Integer) -> Integer", wrap: false
|
321
323
|
def nwrap6(x) return x; end
|
322
324
|
assert(not(RDL::Wrap.wrapped?(TestRDL, :nwrap6)))
|
323
325
|
|
324
326
|
self.class.class_eval {
|
325
|
-
type "(
|
327
|
+
type "(Integer) -> Integer"
|
326
328
|
def nwrap7(x) return x; end
|
327
329
|
}
|
328
330
|
assert(RDL::Wrap.wrapped?(TestRDL, :nwrap7))
|
329
331
|
self.class.class_eval {
|
330
|
-
type "(
|
332
|
+
type "(Integer) -> Integer", wrap: false
|
331
333
|
def nwrap8(x) return x; end
|
332
334
|
}
|
333
335
|
assert(not(RDL::Wrap.wrapped?(TestRDL, :nwrap8)))
|
@@ -335,18 +337,18 @@ RUBY
|
|
335
337
|
|
336
338
|
def test_var_type
|
337
339
|
self.class.class_eval {
|
338
|
-
var_type :@foo, "
|
340
|
+
var_type :@foo, "Integer"
|
339
341
|
var_type :@@foo, "String"
|
340
342
|
var_type :$foo, "Symbol"
|
341
343
|
}
|
342
|
-
assert_equal
|
343
|
-
assert_equal
|
344
|
-
assert_equal
|
344
|
+
assert_equal RDL::Globals.types[:integer], RDL::Globals.info.get(TestRDL, :@foo, :type)
|
345
|
+
assert_equal RDL::Globals.types[:string], RDL::Globals.info.get(TestRDL, :@@foo, :type)
|
346
|
+
assert_equal RDL::Globals.types[:symbol], RDL::Globals.info.get(RDL::Util::GLOBAL_NAME, :$foo, :type)
|
345
347
|
assert_raises(RuntimeError) {
|
346
348
|
self.class.class_eval { var_type :@foo, "String" }
|
347
349
|
}
|
348
350
|
assert_raises(RuntimeError) {
|
349
|
-
self.class.class_eval { var_type :@@foo, "
|
351
|
+
self.class.class_eval { var_type :@@foo, "Integer" }
|
350
352
|
}
|
351
353
|
assert_raises(RuntimeError) {
|
352
354
|
self.class.class_eval { var_type :Foo, "String" }
|
@@ -358,7 +360,7 @@ RUBY
|
|
358
360
|
|
359
361
|
def test_inconsistent
|
360
362
|
self.class.class_eval {
|
361
|
-
type "(
|
363
|
+
type "(Integer) -> Integer"
|
362
364
|
pre { |x| true }
|
363
365
|
def inconsistent1(y) return y; end
|
364
366
|
}
|
@@ -370,8 +372,41 @@ RUBY
|
|
370
372
|
def remove1() return 42; end
|
371
373
|
}
|
372
374
|
assert_raises(RDL::Type::TypeError) { remove1 }
|
373
|
-
|
375
|
+
RDL.remove_type(self.class, :remove1)
|
374
376
|
assert_equal 42, remove1 # shouldn't raise type error with contract removed
|
375
377
|
end
|
376
378
|
|
379
|
+
def test_version
|
380
|
+
RDL.pre("TestRDL::TestVersion", "m1", version: Gem.ruby_version.to_s) { true }
|
381
|
+
assert (RDL::Globals.info.has? "TestRDL::TestVersion", "m1", :pre)
|
382
|
+
RDL.pre("TestRDL::TestVersion", "m2", version: Gem.ruby_version.bump.to_s) { true }
|
383
|
+
assert !(RDL::Globals.info.has? "TestRDL::TestVersion", "m2", :pre)
|
384
|
+
RDL.post("TestRDL::TestVersion", "m3", version: Gem.ruby_version.to_s) { true }
|
385
|
+
assert (RDL::Globals.info.has? "TestRDL::TestVersion", "m3", :post)
|
386
|
+
RDL.
|
387
|
+
pre("TestRDL::TestVersion", "m4", version: Gem.ruby_version.bump.to_s) { true }
|
388
|
+
assert !(RDL::Globals.info.has? "TestRDL::TestVersion", "m4", :post)
|
389
|
+
end
|
390
|
+
|
391
|
+
class TestRDLAnnotate
|
392
|
+
extend RDL::RDLAnnotate
|
393
|
+
|
394
|
+
rdl_pre { |x| x > 0 }
|
395
|
+
def m1(x) return x; end
|
396
|
+
|
397
|
+
rdl_post { |x| x < 0 }
|
398
|
+
def m2(x) return 3; end
|
399
|
+
|
400
|
+
rdl_type '(Integer) -> Integer'
|
401
|
+
def m3(x) return x; end
|
402
|
+
|
403
|
+
end
|
404
|
+
|
405
|
+
def test_pre_rdl_annotate_contract
|
406
|
+
assert_equal 3, TestRDLAnnotate.new.m1(3)
|
407
|
+
assert_raises(RDL::Contract::ContractError) { TestRDLAnnotate.new.m1(-1) }
|
408
|
+
assert_raises(RDL::Contract::ContractError) { TestRDLAnnotate.new.m2(42) }
|
409
|
+
assert_raises(RDL::Type::TypeError) { TestRDLAnnotate.new.m3('one') }
|
410
|
+
end
|
411
|
+
|
377
412
|
end
|
data/test/test_rdl_type.rb
CHANGED
@@ -3,21 +3,23 @@ $LOAD_PATH << File.dirname(__FILE__) + "/../lib"
|
|
3
3
|
require 'rdl'
|
4
4
|
|
5
5
|
class TestRDLType < Minitest::Test
|
6
|
+
extend RDL::Annotate
|
7
|
+
|
6
8
|
def test_single_type_contract
|
7
9
|
def m1(x) return x; end
|
8
|
-
type TestRDLType, :m1, "(
|
10
|
+
RDL.type TestRDLType, :m1, "(Integer) -> Integer"
|
9
11
|
assert_equal 5, m1(5)
|
10
12
|
assert_raises(RDL::Type::TypeError) { m1("foo") }
|
11
13
|
|
12
14
|
self.class.class_eval {
|
13
|
-
type :m2, "(
|
15
|
+
type :m2, "(Integer) -> Integer"
|
14
16
|
def m2(x) return x; end
|
15
17
|
}
|
16
18
|
assert_equal 5, m2(5)
|
17
19
|
assert_raises(RDL::Type::TypeError) { m2("foo") }
|
18
20
|
|
19
21
|
self.class.class_eval {
|
20
|
-
type "(
|
22
|
+
type "(Integer) -> Integer"
|
21
23
|
def m3(x) return x; end
|
22
24
|
}
|
23
25
|
assert_equal 5, m3(5)
|
@@ -26,7 +28,7 @@ class TestRDLType < Minitest::Test
|
|
26
28
|
|
27
29
|
def test_intersection_type_contract
|
28
30
|
self.class.class_eval {
|
29
|
-
type "(
|
31
|
+
type "(Integer) -> Integer"
|
30
32
|
type "(String) -> String"
|
31
33
|
def m4(x) return x; end
|
32
34
|
}
|
@@ -35,7 +37,7 @@ class TestRDLType < Minitest::Test
|
|
35
37
|
assert_raises(RDL::Type::TypeError) { m4(:foo) }
|
36
38
|
|
37
39
|
self.class.class_eval {
|
38
|
-
type "(
|
40
|
+
type "(Integer) -> Integer"
|
39
41
|
type "(String) -> String"
|
40
42
|
def m5(x) return 42; end
|
41
43
|
}
|
@@ -43,8 +45,8 @@ class TestRDLType < Minitest::Test
|
|
43
45
|
assert_raises(RDL::Type::TypeError) { m5("foo") }
|
44
46
|
|
45
47
|
self.class.class_eval {
|
46
|
-
type "(
|
47
|
-
type "(
|
48
|
+
type "(Integer) -> Integer"
|
49
|
+
type "(Integer) -> String"
|
48
50
|
def m6(x) if x > 10 then :oops elsif x > 5 then x else "small" end end
|
49
51
|
}
|
50
52
|
assert_equal 8, m6(8)
|
@@ -54,7 +56,7 @@ class TestRDLType < Minitest::Test
|
|
54
56
|
|
55
57
|
def test_fixnum_type_contract
|
56
58
|
self.class.class_eval {
|
57
|
-
type "(0) ->
|
59
|
+
type "(0) -> Integer"
|
58
60
|
def m7(x) return x; end
|
59
61
|
}
|
60
62
|
assert_equal 0, m7(0)
|
@@ -63,9 +65,24 @@ class TestRDLType < Minitest::Test
|
|
63
65
|
|
64
66
|
def test_wrap_new_inherited
|
65
67
|
self.class.class_eval "class NI_A; def initialize(x); @x = x; end; end; class NI_B < NI_A; end"
|
66
|
-
type "TestRDLType::NI_A", "self.new", "(
|
68
|
+
RDL.type "TestRDLType::NI_A", "self.new", "(Integer) -> TestRDLType::NI_A"
|
67
69
|
assert (TestRDLType::NI_B.new(3))
|
68
70
|
assert_raises(RDL::Type::TypeError) { TestRDLType::NI_B.new("3") }
|
69
71
|
end
|
70
72
|
|
73
|
+
def test_version
|
74
|
+
RDL.type "TestRDLType::TestVersion", "m1", "() -> nil", version: Gem.ruby_version.to_s
|
75
|
+
assert (RDL::Globals.info.has? "TestRDLType::TestVersion", "m1", :type)
|
76
|
+
RDL.type "TestRDLType::TestVersion", "m2", "() -> nil", version: Gem.ruby_version.bump.to_s
|
77
|
+
assert !(RDL::Globals.info.has? "TestRDLType::TestVersion", "m2", :type)
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_wrap_subclass_method
|
81
|
+
self.class.class_eval "class NI_C; def foo; :A; end; end"
|
82
|
+
self.class.class_eval "class NI_D < NI_C; def foo; :B; end; end"
|
83
|
+
RDL.type 'TestRDLType::NI_C', :foo, '() -> :A'
|
84
|
+
RDL.type 'TestRDLType::NI_D', :foo, '() -> :A'
|
85
|
+
assert TestRDLType::NI_C.new.foo
|
86
|
+
assert_raises(RDL::Type::TypeError) { TestRDLType::NI_D.new.foo}
|
87
|
+
end
|
71
88
|
end
|
data/test/test_type_contract.rb
CHANGED
@@ -5,16 +5,17 @@ require 'rdl'
|
|
5
5
|
class TestTypeContract < Minitest::Test
|
6
6
|
include RDL::Type
|
7
7
|
include RDL::Contract
|
8
|
+
extend RDL::Annotate
|
8
9
|
|
9
10
|
def setup
|
10
11
|
@p = Parser.new
|
11
12
|
end
|
12
13
|
|
13
14
|
def test_flat
|
14
|
-
cnil =
|
15
|
+
cnil = RDL::Globals.types[:nil].to_contract
|
15
16
|
assert (cnil.check self, nil)
|
16
17
|
assert_raises(TypeError) { cnil.check self, true }
|
17
|
-
tfixnum = NominalType.new :
|
18
|
+
tfixnum = NominalType.new :Integer
|
18
19
|
cfixnum = tfixnum.to_contract
|
19
20
|
assert (cfixnum.check self, 42)
|
20
21
|
assert (cfixnum.check self, nil)
|
@@ -29,7 +30,7 @@ class TestTypeContract < Minitest::Test
|
|
29
30
|
p1b = t1.to_contract.wrap(self) { |x| 42 }
|
30
31
|
assert_raises(TypeError) { p1b.call(nil) }
|
31
32
|
|
32
|
-
t2 = @p.scan_str "(
|
33
|
+
t2 = @p.scan_str "(Integer, Integer) -> Integer"
|
33
34
|
p2 = t2.to_contract.wrap(self) { |x, y| x }
|
34
35
|
assert_equal 42, p2.call(42, 43)
|
35
36
|
assert_equal 42, p2.call(42, nil)
|
@@ -43,14 +44,14 @@ class TestTypeContract < Minitest::Test
|
|
43
44
|
assert_nil p3.call
|
44
45
|
assert_raises(TypeError) { p3.call(42) }
|
45
46
|
|
46
|
-
t4 = @p.scan_str "(
|
47
|
+
t4 = @p.scan_str "(Integer, ?Integer) -> Integer"
|
47
48
|
p4 = t4.to_contract.wrap(self) { |x| x }
|
48
49
|
assert_equal 42, p4.call(42)
|
49
50
|
assert_equal 42, p4.call(42, 43)
|
50
51
|
assert_raises(TypeError) { p4.call(42, 43, 44) }
|
51
52
|
assert_raises(TypeError) { p4.call }
|
52
53
|
|
53
|
-
t5 = @p.scan_str "(
|
54
|
+
t5 = @p.scan_str "(Integer, *Integer) -> Integer"
|
54
55
|
p5 = t5.to_contract.wrap(self) { |x| x }
|
55
56
|
assert_equal 42, p5.call(42)
|
56
57
|
assert_equal 42, p5.call(42, 43)
|
@@ -62,7 +63,7 @@ class TestTypeContract < Minitest::Test
|
|
62
63
|
assert_raises(TypeError) { p5.call(42, 43, "44") }
|
63
64
|
assert_raises(TypeError) { p5.call(42, 43, 44, "45") }
|
64
65
|
|
65
|
-
t6 = @p.scan_str "(
|
66
|
+
t6 = @p.scan_str "(Integer, ?Integer, ?Integer, *Integer) -> Integer"
|
66
67
|
p6 = t6.to_contract.wrap(self) { |x| x }
|
67
68
|
assert_equal 42, p6.call(42)
|
68
69
|
assert_equal 42, p6.call(42, 43)
|
@@ -76,7 +77,7 @@ class TestTypeContract < Minitest::Test
|
|
76
77
|
assert_raises(TypeError) { p6.call(42, 43, 44, "45") }
|
77
78
|
assert_raises(TypeError) { p6.call(42, 43, 44, 45, "46") }
|
78
79
|
|
79
|
-
t7 = @p.scan_str "(?
|
80
|
+
t7 = @p.scan_str "(?Integer) -> nil"
|
80
81
|
p7 = t7.to_contract.wrap(self) { nil }
|
81
82
|
assert_nil p7.call
|
82
83
|
assert_nil p7.call(42)
|
@@ -84,7 +85,7 @@ class TestTypeContract < Minitest::Test
|
|
84
85
|
assert_raises(TypeError) { p7.call(42, 43) }
|
85
86
|
assert_raises(TypeError) { p7.call(42, 43, 44) }
|
86
87
|
|
87
|
-
t8 = @p.scan_str "(*
|
88
|
+
t8 = @p.scan_str "(*Integer) -> nil"
|
88
89
|
p8 = t8.to_contract.wrap(self) { nil }
|
89
90
|
assert_nil p8.call
|
90
91
|
assert_nil p8.call(42)
|
@@ -94,26 +95,26 @@ class TestTypeContract < Minitest::Test
|
|
94
95
|
assert_raises(TypeError) { p8.call(42, "43") }
|
95
96
|
assert_raises(TypeError) { p8.call(42, 43, "44") }
|
96
97
|
|
97
|
-
t9 = @p.scan_str "(
|
98
|
+
t9 = @p.scan_str "(Integer arg1, ?Integer arg2) -> Integer"
|
98
99
|
p9 = t9.to_contract.wrap(self) { |x| x }
|
99
100
|
assert_equal 42, p9.call(42)
|
100
101
|
assert_equal 42, p9.call(42, 43)
|
101
102
|
assert_raises(TypeError) { p9.call(42, 43, 44) }
|
102
103
|
assert_raises(TypeError) { p9.call }
|
103
104
|
|
104
|
-
t10 = @p.scan_str "(?
|
105
|
+
t10 = @p.scan_str "(?Integer, String) -> Integer"
|
105
106
|
p10 = t10.to_contract.wrap(self) { |*args| 42 }
|
106
107
|
assert_equal 42, p10.call("44")
|
107
108
|
assert_equal 42, p10.call(43, "44")
|
108
109
|
assert_raises(TypeError) { p10.call() }
|
109
110
|
assert_raises(TypeError) { p10.call(43, "44", 45) }
|
110
111
|
|
111
|
-
t11 = @p.scan_str "(
|
112
|
+
t11 = @p.scan_str "(Integer x {{ x > 42 }}) -> Integer"
|
112
113
|
p11 = t11.to_contract.wrap(self) { |x| x }
|
113
114
|
assert_equal 43, p11.call(43)
|
114
115
|
assert_raises(TypeError) { p11.call(42) }
|
115
116
|
|
116
|
-
t12 = @p.scan_str "(
|
117
|
+
t12 = @p.scan_str "(Integer x {{ x>10 }}, Integer y {{ y > x }}) -> Integer z {{z > (x+y) }}"
|
117
118
|
p12 = t12.to_contract.wrap(self) { |x,y| x+y+1 }
|
118
119
|
assert_equal 30, p12.call(14, 15)
|
119
120
|
assert_equal 50, p12.call(24, 25)
|
@@ -124,7 +125,7 @@ class TestTypeContract < Minitest::Test
|
|
124
125
|
assert_raises(TypeError) { p12b.call(11, 10) }
|
125
126
|
assert_raises(TypeError) { p12b.call(9, 10) }
|
126
127
|
|
127
|
-
t13 = @p.scan_str "(
|
128
|
+
t13 = @p.scan_str "(Integer, {(Integer x {{x>10}}) -> Integer}) -> Float"
|
128
129
|
p13 = t13.to_higher_contract(self) { |x,y| x+y.call(11)+0.5 }
|
129
130
|
assert_equal 53.5, p13.call(42, Proc.new { |x| x })
|
130
131
|
assert_raises(TypeError) { p13.call(42.5, Proc.new { |x| x} ) }
|
@@ -136,7 +137,7 @@ class TestTypeContract < Minitest::Test
|
|
136
137
|
p13d = t13.to_higher_contract(self) { |x,y| x+y.call(42) }
|
137
138
|
assert_raises(TypeError) { p13d.call(42, Proc.new { |x| x } ) }
|
138
139
|
|
139
|
-
t14 = @p.scan_str "(
|
140
|
+
t14 = @p.scan_str "(Integer, Integer) -> {(Integer) -> Integer}"
|
140
141
|
p14 = t14.to_higher_contract(self) { |x,y| Proc.new {|z| x+y+z} }
|
141
142
|
assert_raises(TypeError) { p14.call(42.5, 42) }
|
142
143
|
p14b = p14.call(42,42)
|
@@ -157,16 +158,16 @@ class TestTypeContract < Minitest::Test
|
|
157
158
|
assert_raises(TypeError) { block_contract_test4(40.5) }
|
158
159
|
assert_raises(TypeError) { block_contract_test4(42) {|x| x+1.5} }
|
159
160
|
|
160
|
-
t15 = @p.scan_str "(
|
161
|
+
t15 = @p.scan_str "(Integer x {{x>y}}, Integer y) -> Integer"
|
161
162
|
p15 = t15.to_contract.wrap(self) { |x, y| x+y }
|
162
163
|
assert_equal 21, p15.call(11, 10)
|
163
164
|
assert_raises(TypeError) { p15.call(10, 11) }
|
164
165
|
|
165
|
-
t16 = @p.scan_str "(
|
166
|
+
t16 = @p.scan_str "(Integer x {{x > undefvar}}, Integer) -> Integer"
|
166
167
|
p16 = t16.to_contract.wrap(self) { |x,y| x }
|
167
168
|
assert_raises(NameError) { p16.call(10,10) }
|
168
169
|
|
169
|
-
t17 = @p.scan_str "(
|
170
|
+
t17 = @p.scan_str "(Integer, *String, Integer) -> Integer"
|
170
171
|
p17 = t17.to_contract.wrap(self) { |x| x }
|
171
172
|
assert_equal 42, p17.call(42, 43)
|
172
173
|
assert_equal 42, p17.call(42, 'foo', 43)
|
@@ -177,7 +178,7 @@ class TestTypeContract < Minitest::Test
|
|
177
178
|
assert_raises(TypeError) { p17.call(42, '43') }
|
178
179
|
assert_raises(TypeError) { p17.call(42, 43, '44') }
|
179
180
|
|
180
|
-
t18 = @p.scan_str "(
|
181
|
+
t18 = @p.scan_str "(Integer, ?{(Integer) -> Integer}) -> Integer"
|
181
182
|
p18 = t18.to_higher_contract(self) { |x,p=nil| if p then p.call(x) else x end }
|
182
183
|
assert_equal 42, p18.call(41, Proc.new {|x| x+1})
|
183
184
|
assert_equal 42, p18.call(42)
|
@@ -190,29 +191,29 @@ class TestTypeContract < Minitest::Test
|
|
190
191
|
|
191
192
|
end
|
192
193
|
|
193
|
-
type '(
|
194
|
+
type '(Integer) { (Integer) -> Integer } -> Integer'
|
194
195
|
def block_contract_test1(x)
|
195
196
|
x+yield(5)
|
196
197
|
end
|
197
198
|
|
198
|
-
type '(
|
199
|
+
type '(Integer) { (Integer) -> Integer } -> Float'
|
199
200
|
def block_contract_test2(x)
|
200
201
|
x+yield(4.5)
|
201
202
|
end
|
202
203
|
|
203
|
-
type '(
|
204
|
+
type '(Integer) -> Integer'
|
204
205
|
def block_contract_test3(x)
|
205
206
|
42
|
206
207
|
end
|
207
208
|
|
208
|
-
type '(
|
209
|
+
type '(Integer) ?{(Integer) -> Integer} -> Integer'
|
209
210
|
def block_contract_test4(x,&blk)
|
210
211
|
return yield(x) if blk
|
211
212
|
return x
|
212
213
|
end
|
213
214
|
|
214
215
|
def test_proc_names
|
215
|
-
t1 = @p.scan_str "(x:
|
216
|
+
t1 = @p.scan_str "(x: Integer) -> Integer"
|
216
217
|
p1 = t1.to_contract.wrap(self) { |x:| x }
|
217
218
|
assert_equal 42, p1.call(x: 42)
|
218
219
|
assert_raises(TypeError) { p1.call(x: "42") }
|
@@ -221,7 +222,7 @@ class TestTypeContract < Minitest::Test
|
|
221
222
|
assert_raises(TypeError) { p1.call(y: 42) }
|
222
223
|
assert_raises(TypeError) { p1.call(42) }
|
223
224
|
assert_raises(TypeError) { p1.call(42, x: 42) }
|
224
|
-
t2 = @p.scan_str "(x:
|
225
|
+
t2 = @p.scan_str "(x: Integer, y: String) -> Integer"
|
225
226
|
p2 = t2.to_contract.wrap(self) { |x:,y:| x }
|
226
227
|
assert_equal 42, p2.call(x: 42, y: "33")
|
227
228
|
assert_raises(TypeError) { p2.call() }
|
@@ -230,7 +231,7 @@ class TestTypeContract < Minitest::Test
|
|
230
231
|
assert_raises(TypeError) { p2.call(42, "43") }
|
231
232
|
assert_raises(TypeError) { p2.call(42, x: 42, y: "33") }
|
232
233
|
assert_raises(TypeError) { p2.call(x: 42, y: "33", z: 44) }
|
233
|
-
t3 = @p.scan_str "(
|
234
|
+
t3 = @p.scan_str "(Integer, y: String) -> Integer"
|
234
235
|
p3 = t3.to_contract.wrap(self) { |x, y:| x }
|
235
236
|
assert_equal 42, p3.call(42, y:"43")
|
236
237
|
assert_raises(TypeError) { p3.call(42) }
|
@@ -238,7 +239,7 @@ class TestTypeContract < Minitest::Test
|
|
238
239
|
assert_raises(TypeError) { p3.call() }
|
239
240
|
assert_raises(TypeError) { p3.call(42, 43, y: 44) }
|
240
241
|
assert_raises(TypeError) { p3.call(42, y: 43, z: 44) }
|
241
|
-
t4 = @p.scan_str "(
|
242
|
+
t4 = @p.scan_str "(Integer, x: Integer, y: String) -> Integer"
|
242
243
|
p4 = t4.to_contract.wrap(self) { |a, x:, y:| a }
|
243
244
|
assert_equal 42, p4.call(42, x: 43, y: "44")
|
244
245
|
assert_raises(TypeError) { p4.call(42, x: 43) }
|
@@ -246,7 +247,7 @@ class TestTypeContract < Minitest::Test
|
|
246
247
|
assert_raises(TypeError) { p4.call() }
|
247
248
|
assert_raises(TypeError) { p4.call(42, 43, x: 44, y: "45") }
|
248
249
|
assert_raises(TypeError) { p4.call(42, x: 43, y: "44", z: 45) }
|
249
|
-
t5 = @p.scan_str "(x:
|
250
|
+
t5 = @p.scan_str "(x: Integer, y: ?String) -> Integer"
|
250
251
|
p5 = t5.to_contract.wrap(self) { |x:, **ys| x }
|
251
252
|
assert_equal 42, p5.call(x: 42, y: "43")
|
252
253
|
assert_equal 42, p5.call(x: 42)
|
@@ -255,7 +256,7 @@ class TestTypeContract < Minitest::Test
|
|
255
256
|
assert_raises(TypeError) { p5.call(x: 42, y: 43, z: 44) }
|
256
257
|
assert_raises(TypeError) { p5.call(3, x: 42, y: 43) }
|
257
258
|
assert_raises(TypeError) { p5.call(3, x: 42) }
|
258
|
-
t6 = @p.scan_str "(x: ?
|
259
|
+
t6 = @p.scan_str "(x: ?Integer, y: String) -> Integer"
|
259
260
|
p6 = t6.to_contract.wrap(self) { |y:, **xs| 42 }
|
260
261
|
assert_equal 42, p6.call(x: 43, y: "44")
|
261
262
|
assert_equal 42, p6.call(y: "44")
|
@@ -263,7 +264,7 @@ class TestTypeContract < Minitest::Test
|
|
263
264
|
assert_raises(TypeError) { p6.call(x: "43", y: "44") }
|
264
265
|
assert_raises(TypeError) { p6.call(42, x: 43, y: "44") }
|
265
266
|
assert_raises(TypeError) { p6.call(x: 43, y: "44", z: 45) }
|
266
|
-
t7 = @p.scan_str "(x: ?
|
267
|
+
t7 = @p.scan_str "(x: ?Integer, y: ?String) -> Integer"
|
267
268
|
p7 = t7.to_contract.wrap(self) { |**args| 42 }
|
268
269
|
assert_equal 42, p7.call
|
269
270
|
assert_equal 42, p7.call(x: 43)
|
@@ -272,7 +273,7 @@ class TestTypeContract < Minitest::Test
|
|
272
273
|
assert_raises(TypeError) { p7.call(x: "43", y: "44") }
|
273
274
|
assert_raises(TypeError) { p7.call(41, x: 43, y: "44") }
|
274
275
|
assert_raises(TypeError) { p7.call(x: 43, y: "44", z: 45) }
|
275
|
-
t8 = @p.scan_str "(?
|
276
|
+
t8 = @p.scan_str "(?Integer, x: ?Symbol, y: ?String) -> Integer"
|
276
277
|
p8 = t8.to_contract.wrap(self) { |*args| 42 }
|
277
278
|
assert_equal 42, p8.call
|
278
279
|
assert_equal 42, p8.call(43)
|
@@ -285,7 +286,7 @@ class TestTypeContract < Minitest::Test
|
|
285
286
|
assert_raises(TypeError) { p8.call(43, 44, x: :foo, y: "foo") }
|
286
287
|
assert_raises(TypeError) { p8.call(43, x: "foo", y: "foo") }
|
287
288
|
assert_raises(TypeError) { p8.call(43, x: :foo, y: "foo", z: 44) }
|
288
|
-
t9 = @p.scan_str "(
|
289
|
+
t9 = @p.scan_str "(Integer, x: String, y: Integer, **Float) -> Integer"
|
289
290
|
p9 = t9.to_contract.wrap(self) { |*args| 42 }
|
290
291
|
assert_raises(TypeError) { p9.call }
|
291
292
|
assert_raises(TypeError) { p9.call(43) }
|