rdl 2.0.1 → 2.1.0
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/.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) }
|