rdl 1.1.0 → 1.1.1.rc1
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 +1 -0
- data/CHANGES.md +25 -0
- data/README.md +104 -64
- data/extras/type_tests/%.rb +171 -0
- data/extras/type_tests/&.rb +159 -0
- data/extras/type_tests/**.rb +222 -0
- data/extras/type_tests/*.rb +177 -0
- data/extras/type_tests/+.rb +170 -0
- data/extras/type_tests/-.rb +171 -0
- data/extras/type_tests/1scomp.rb +157 -0
- data/extras/type_tests/<.rb +170 -0
- data/extras/type_tests/<<.rb +159 -0
- data/extras/type_tests/>>.rb +159 -0
- data/extras/type_tests/[].rb +163 -0
- data/extras/type_tests/^.rb +159 -0
- data/extras/type_tests/abs.rb +155 -0
- data/extras/type_tests/abs2.rb +164 -0
- data/extras/type_tests/angle.rb +157 -0
- data/extras/type_tests/arg.rb +157 -0
- data/extras/type_tests/bit_length.rb +157 -0
- data/extras/type_tests/ceil.rb +157 -0
- data/extras/type_tests/ceilRational.rb +160 -0
- data/extras/type_tests/conj.rb +158 -0
- data/extras/type_tests/defwhere.rb +86 -0
- data/extras/type_tests/denominator.rb +157 -0
- data/extras/type_tests/div.rb +172 -0
- data/extras/type_tests/divslash.rb +179 -0
- data/extras/type_tests/even?.rb +157 -0
- data/extras/type_tests/fdiv.rb +244 -0
- data/extras/type_tests/finite?.rb +157 -0
- data/extras/type_tests/floor.rb +157 -0
- data/extras/type_tests/floorRational.rb +161 -0
- data/extras/type_tests/hash.rb +157 -0
- data/extras/type_tests/imag.rb +158 -0
- data/extras/type_tests/infinite?.rb +157 -0
- data/extras/type_tests/modulo.rb +171 -0
- data/extras/type_tests/nan?.rb +157 -0
- data/extras/type_tests/neg.rb +155 -0
- data/extras/type_tests/next.rb +157 -0
- data/extras/type_tests/next_float.rb +157 -0
- data/extras/type_tests/numerator.rb +157 -0
- data/extras/type_tests/phase.rb +157 -0
- data/extras/type_tests/prev_float.rb +157 -0
- data/extras/type_tests/quo.rb +179 -0
- data/extras/type_tests/rationalize.rb +157 -0
- data/extras/type_tests/rationalizeArg.rb +198 -0
- data/extras/type_tests/real.rb +157 -0
- data/extras/type_tests/real?.rb +157 -0
- data/extras/type_tests/round.rb +157 -0
- data/extras/type_tests/roundArg.rb +169 -0
- data/extras/type_tests/size.rb +157 -0
- data/extras/type_tests/to_c.rb +157 -0
- data/extras/type_tests/to_f.rb +155 -0
- data/extras/type_tests/to_i.rb +157 -0
- data/extras/type_tests/to_r.rb +157 -0
- data/extras/type_tests/to_s.rb +157 -0
- data/extras/type_tests/truncate.rb +157 -0
- data/extras/type_tests/truncateArg.rb +166 -0
- data/extras/type_tests/type tests +1 -0
- data/extras/type_tests/zero?.rb +155 -0
- data/extras/type_tests/|.rb +159 -0
- data/lib/rdl/contracts/and.rb +1 -1
- data/lib/rdl/contracts/flat.rb +2 -2
- data/lib/rdl/contracts/proc.rb +2 -1
- data/lib/rdl/types/.#lexer.rex +1 -0
- data/lib/rdl/types/dependent_arg.rb +47 -0
- data/lib/rdl/types/finitehash.rb +5 -5
- data/lib/rdl/types/generic.rb +3 -3
- data/lib/rdl/types/lexer.rex +5 -2
- data/lib/rdl/types/lexer.rex.rb +3 -0
- data/lib/rdl/types/method.rb +144 -15
- data/lib/rdl/types/nominal.rb +1 -1
- data/lib/rdl/types/parser.racc +6 -1
- data/lib/rdl/types/parser.tab.rb +272 -245
- data/lib/rdl/types/tuple.rb +1 -1
- data/lib/rdl/types/type_inferencer.rb +7 -7
- data/lib/rdl/wrap.rb +16 -11
- data/rdl.gemspec +3 -3
- data/test/test_dsl.rb +4 -5
- data/test/test_le.rb +5 -5
- data/test/test_lib_types.rb +34 -34
- data/test/test_member.rb +3 -3
- data/test/test_type_contract.rb +63 -1
- data/test/test_types.rb +2 -0
- data/types/ruby-2.x/_aliases.rb +2 -2
- data/types/ruby-2.x/bigdecimal.rb +246 -12
- data/types/ruby-2.x/bignum.rb +253 -0
- data/types/ruby-2.x/complex.rb +111 -22
- data/types/ruby-2.x/fixnum.rb +238 -31
- data/types/ruby-2.x/float.rb +217 -35
- data/types/ruby-2.x/integer.rb +17 -16
- data/types/ruby-2.x/numeric.rb +31 -21
- data/types/ruby-2.x/rational.rb +196 -18
- metadata +67 -4
data/lib/rdl/types/tuple.rb
CHANGED
@@ -20,14 +20,14 @@ module RDL
|
|
20
20
|
end
|
21
21
|
|
22
22
|
private
|
23
|
-
|
23
|
+
|
24
24
|
def self.extract_types(param_type)
|
25
25
|
param_type.instance_of?(RDL::Type::UnionType) ? param_type.types.to_a : [param_type]
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
# Unifies i.e. #<Set: {Array<String>, Array<Array<String>>}> into
|
29
29
|
# Array<(Array<String> or String)>
|
30
|
-
# If this step is not called, then infer_type for
|
30
|
+
# If this step is not called, then infer_type for
|
31
31
|
# [["a", "b"], [["c"]]].rdl_type would return
|
32
32
|
# (Array<Array<String>> or Array<String>) instead of
|
33
33
|
# (Array<(Array<String> or String)>)
|
@@ -49,7 +49,7 @@ module RDL
|
|
49
49
|
type_parameters = cls.instance_variable_get :@__cls_params
|
50
50
|
((0..(type_parameters.size - 1)).map {|tparam_index|
|
51
51
|
extract_types(member_type.params[tparam_index])
|
52
|
-
}).each_with_index {|type_parameter,index|
|
52
|
+
}).each_with_index {|type_parameter,index|
|
53
53
|
tparam_set[index]+=type_parameter
|
54
54
|
}
|
55
55
|
|
@@ -59,12 +59,12 @@ module RDL
|
|
59
59
|
end
|
60
60
|
}
|
61
61
|
|
62
|
-
parameterized_classes.each {|nominal,
|
63
|
-
|
62
|
+
parameterized_classes.each {|nominal, ts|
|
63
|
+
nt = ts.map {|unioned_type_parameter|
|
64
64
|
RDL::Type::UnionType.new(*unify_param_types(unioned_type_parameter))
|
65
65
|
}
|
66
66
|
|
67
|
-
non_param_classes << RDL::Type::GenericType.new(nominal, *
|
67
|
+
non_param_classes << RDL::Type::GenericType.new(nominal, *nt)
|
68
68
|
}
|
69
69
|
|
70
70
|
non_param_classes
|
data/lib/rdl/wrap.rb
CHANGED
@@ -70,10 +70,13 @@ class RDL::Wrap
|
|
70
70
|
def #{meth}(*args, &blk)
|
71
71
|
klass = "#{klass_str}"
|
72
72
|
meth = types = matches = nil
|
73
|
+
bind = binding
|
73
74
|
inst = nil
|
75
|
+
|
74
76
|
$__rdl_wrap_switch.off {
|
75
77
|
$__rdl_wrapped_calls["#{full_method_name}"] += 1 if RDL::Config.instance.gather_stats
|
76
|
-
inst =
|
78
|
+
inst = nil
|
79
|
+
inst = @__rdl_inst if defined? @__rdl_inst
|
77
80
|
inst = Hash[$__rdl_type_params[klass][0].zip []] if (not(inst) && $__rdl_type_params[klass])
|
78
81
|
inst = {} if not inst
|
79
82
|
#{if not(is_singleton_method) then "inst[:self] = RDL::Type::SingletonType.new(self)" end}
|
@@ -85,17 +88,17 @@ class RDL::Wrap
|
|
85
88
|
end
|
86
89
|
if RDL::Wrap.has_contracts?(klass, meth, :type)
|
87
90
|
types = RDL::Wrap.get_contracts(klass, meth, :type)
|
88
|
-
matches = RDL::Type::MethodType.check_arg_types("#{full_method_name}", types, inst, *args, &blk)
|
91
|
+
matches,args,blk,bind = RDL::Type::MethodType.check_arg_types("#{full_method_name}", self, bind, types, inst, *args, &blk)
|
89
92
|
end
|
90
93
|
}
|
91
|
-
|
94
|
+
ret = send(#{meth_old.inspect}, *args, &blk)
|
92
95
|
$__rdl_wrap_switch.off {
|
93
96
|
if RDL::Wrap.has_contracts?(klass, meth, :post)
|
94
97
|
posts = RDL::Wrap.get_contracts(klass, meth, :post)
|
95
98
|
RDL::Contract::AndContract.check_array(posts, self, ret, *args, &blk)
|
96
99
|
end
|
97
100
|
if matches
|
98
|
-
RDL::Type::MethodType.check_ret_types("#{full_method_name}", types, inst, matches, ret, *args, &blk)
|
101
|
+
ret = RDL::Type::MethodType.check_ret_types(self, "#{full_method_name}", types, inst, matches, ret, bind, *args, &blk)
|
99
102
|
end
|
100
103
|
}
|
101
104
|
return ret
|
@@ -414,21 +417,21 @@ class Object
|
|
414
417
|
$__rdl_contract_switch.off {
|
415
418
|
klass = self.class.to_s
|
416
419
|
klass = "Object" if (klass.is_a? Object) && (klass.to_s == "main")
|
417
|
-
formals,
|
420
|
+
formals, _, all = $__rdl_type_params[klass]
|
418
421
|
raise RuntimeError, "Receiver is of class #{klass}, which is not parameterized" unless formals
|
419
422
|
raise RuntimeError, "Expecting #{params.size} type parameters, got #{typs.size}" unless formals.size == typs.size
|
420
|
-
raise RuntimeError, "Instance already has type instantiation" if @__rdl_type
|
423
|
+
raise RuntimeError, "Instance already has type instantiation" if (defined? @__rdl_type) && @rdl_type
|
421
424
|
new_typs = typs.map { |t| if t.is_a? RDL::Type::Type then t else $__rdl_parser.scan_str "#T #{t}" end }
|
422
425
|
t = RDL::Type::GenericType.new(RDL::Type::NominalType.new(klass), *new_typs)
|
423
426
|
if all.instance_of? Symbol
|
424
427
|
self.send(all) { |*objs|
|
425
|
-
new_typs.zip(objs).each { |
|
426
|
-
if
|
428
|
+
new_typs.zip(objs).each { |nt, obj|
|
429
|
+
if nt.instance_of? RDL::Type::GenericType # require obj to be instantiated
|
427
430
|
t_obj = RDL::Util.rdl_type(obj)
|
428
|
-
raise RDL::Type::TypeError, "Expecting element of type #{
|
429
|
-
raise RDL::Type::TypeError, "Expecting type #{
|
431
|
+
raise RDL::Type::TypeError, "Expecting element of type #{nt.to_s}, but got uninstantiated object #{obj.inspect}" unless t_obj
|
432
|
+
raise RDL::Type::TypeError, "Expecting type #{nt.to_s}, got type #{t_obj.to_s}" unless t_obj <= nt
|
430
433
|
else
|
431
|
-
raise RDL::Type::TypeError, "Expecting type #{
|
434
|
+
raise RDL::Type::TypeError, "Expecting type #{nt.to_s}, got #{obj.inspect}" unless nt.member? obj
|
432
435
|
end
|
433
436
|
}
|
434
437
|
}
|
@@ -476,4 +479,6 @@ class Object
|
|
476
479
|
end
|
477
480
|
}
|
478
481
|
end
|
482
|
+
|
483
|
+
|
479
484
|
end
|
data/rdl.gemspec
CHANGED
@@ -4,8 +4,8 @@
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = 'rdl'
|
7
|
-
s.version = '1.1.
|
8
|
-
s.date = '2016-
|
7
|
+
s.version = '1.1.1.rc1'
|
8
|
+
s.date = '2016-05-21'
|
9
9
|
s.summary = 'Ruby type and contract system'
|
10
10
|
s.description = <<-EOF
|
11
11
|
RDL is a gem that allows contracts (pre- and postconditions) to be added to methods.
|
@@ -14,7 +14,7 @@ postconditions are checked at run time when the method returns.
|
|
14
14
|
RDL also includes extensive support for type contracts, which check the types of arguments and returns
|
15
15
|
when the method is called and when it returns, respectively.
|
16
16
|
EOF
|
17
|
-
s.authors = ['Jeffrey S. Foster', 'Brianna M. Ren', 'T. Stephen Strickland', 'Alexander T. Yu']
|
17
|
+
s.authors = ['Jeffrey S. Foster', 'Brianna M. Ren', 'T. Stephen Strickland', 'Alexander T. Yu', 'Milod Kazerounian']
|
18
18
|
s.email = ['rdl-users@googlegroups.com']
|
19
19
|
s.files = `git ls-files`.split($/)
|
20
20
|
s.executables << 'rdl_query'
|
data/test/test_dsl.rb
CHANGED
@@ -61,16 +61,16 @@ class TestDsl < Minitest::Test
|
|
61
61
|
[@val, l, r]
|
62
62
|
end
|
63
63
|
end
|
64
|
-
|
65
|
-
def test_pair
|
66
|
-
|
64
|
+
|
65
|
+
def test_pair
|
66
|
+
_ = Pair.new.entry {
|
67
67
|
left 3
|
68
68
|
right 4
|
69
69
|
}
|
70
70
|
end
|
71
71
|
|
72
72
|
def test_tree
|
73
|
-
|
73
|
+
_ = Tree.new.entry(2) {
|
74
74
|
left(3)
|
75
75
|
right(4) {
|
76
76
|
left(5) {
|
@@ -82,4 +82,3 @@ class TestDsl < Minitest::Test
|
|
82
82
|
}
|
83
83
|
end
|
84
84
|
end
|
85
|
-
|
data/test/test_le.rb
CHANGED
@@ -12,7 +12,7 @@ class TestLe < Minitest::Test
|
|
12
12
|
|
13
13
|
class C < B
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def setup
|
17
17
|
@tnil = NilType.new
|
18
18
|
@ttop = TopType.new
|
@@ -26,7 +26,7 @@ class TestLe < Minitest::Test
|
|
26
26
|
@tc = NominalType.new C
|
27
27
|
@tfixnum = NominalType.new "Fixnum"
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
def test_nil
|
31
31
|
assert (@tnil <= @ttop)
|
32
32
|
assert (@tnil <= @tstring)
|
@@ -85,7 +85,7 @@ class TestLe < Minitest::Test
|
|
85
85
|
def test_union
|
86
86
|
tstring_or_sym = UnionType.new(@tstring, @tsym)
|
87
87
|
assert (tstring_or_sym <= @tobject)
|
88
|
-
assert (not (@tobject <=
|
88
|
+
assert (not (@tobject <= tstring_or_sym))
|
89
89
|
end
|
90
90
|
|
91
91
|
def test_tuple
|
@@ -182,12 +182,12 @@ class TestLe < Minitest::Test
|
|
182
182
|
assert (tnom <= ts4) # types don't matter, only methods
|
183
183
|
assert (not (tnomt <= ts4))
|
184
184
|
end
|
185
|
-
|
185
|
+
|
186
186
|
# def test_intersection
|
187
187
|
# skip "<= not defined on intersection"
|
188
188
|
# tobject_and_basicobject = IntersectionType.new(@tobject, @tbasicobject)
|
189
189
|
# assert (not (tobject_and_basicobject <= @tobject))
|
190
190
|
# assert (@tobject <= tobject_and_basicobject)
|
191
191
|
# end
|
192
|
-
|
192
|
+
|
193
193
|
end
|
data/test/test_lib_types.rb
CHANGED
@@ -22,26 +22,26 @@ class TestStdlibTypes < Minitest::Test
|
|
22
22
|
|
23
23
|
def test_abbrev
|
24
24
|
skip "Skip when nowrap is enabled"
|
25
|
-
assert_raises(RDL::Type::TypeError) {
|
25
|
+
assert_raises(RDL::Type::TypeError) { Abbrev.abbrev 5}
|
26
26
|
# From the Ruby stdlib documentation
|
27
27
|
s1 = Abbrev.abbrev(['ruby']) # -> {"ruby"=>"ruby", "rub"=>"ruby", "ru"=>"ruby", "r"=>"ruby"}
|
28
28
|
ev = {"ruby"=>"ruby", "rub"=>"ruby", "ru"=>"ruby", "r"=>"ruby"}
|
29
|
-
assert_equal(s1,ev)
|
29
|
+
assert_equal(s1, ev)
|
30
30
|
# Other tests
|
31
|
-
assert_raises(RDL::Type::TypeError) {
|
31
|
+
assert_raises(RDL::Type::TypeError) { Abbrev.abbrev Dummy.new }
|
32
32
|
end
|
33
33
|
|
34
34
|
def test_base64
|
35
35
|
skip "Skip when nowrap is enabled"
|
36
36
|
# From the Ruby stdlib documentation
|
37
37
|
e0 = Base64.encode64('Send reinforcements') # -> "U2VuZCByZWluZm9yY2VtZW50cw==\n"
|
38
|
-
|
38
|
+
Base64.decode64(e0) # -> "Send reinforcements"
|
39
39
|
#assert_equal(e0,d0)
|
40
40
|
e1 = Base64.strict_encode64('Send reinforcements')
|
41
|
-
|
41
|
+
Base64.strict_decode64(e1)
|
42
42
|
#assert_equal(e1,d1)
|
43
43
|
e2 = Base64.urlsafe_encode64('Send reinforcements')
|
44
|
-
|
44
|
+
Base64.urlsafe_decode64(e2)
|
45
45
|
#assert_equal(e2,d2)
|
46
46
|
end
|
47
47
|
|
@@ -51,24 +51,24 @@ class TestStdlibTypes < Minitest::Test
|
|
51
51
|
Benchmark.measure { "a"*1_000_000_000 }
|
52
52
|
n = 5000000
|
53
53
|
Benchmark.bm do |x|
|
54
|
-
x.report { for i in 1..n; a =
|
55
|
-
x.report { n.times do ; a = "1"; end }
|
56
|
-
x.report { 1.upto(n) do ; a = "1"; end }
|
54
|
+
x.report { for i in 1..n; a = i; a; end }
|
55
|
+
x.report { n.times do ; a = "1"; a; end }
|
56
|
+
x.report { 1.upto(n) do ; a = "1"; a; end }
|
57
57
|
end
|
58
58
|
Benchmark.bm(7) do |x|
|
59
|
-
x.report("for:") { for i in 1..n; a =
|
60
|
-
x.report("times:") { n.times do ; a = "1"; end }
|
61
|
-
x.report("upto:") { 1.upto(n) do ; a = "1"; end }
|
59
|
+
x.report("for:") { for i in 1..n; a = i; a; end }
|
60
|
+
x.report("times:") { n.times do ; a = "1"; a; end }
|
61
|
+
x.report("upto:") { 1.upto(n) do ; a = "1"; a; end }
|
62
62
|
end
|
63
|
-
|
63
|
+
_ = (1..1000000).map { rand }
|
64
64
|
Benchmark.bmbm do |x|
|
65
65
|
#x.report("sort!") { array.dup.sort! } # TODO this causes a hang
|
66
66
|
#x.report("sort") { array.dup.sort }
|
67
67
|
end
|
68
68
|
Benchmark.benchmark(Benchmark::CAPTION, 7, Benchmark::FORMAT, ">total:", ">avg:") do |x|
|
69
|
-
tf = x.report("for:") { for i in 1..n; a =
|
70
|
-
tt = x.report("times:") { n.times do ; a = "1"; end }
|
71
|
-
tu = x.report("upto:") { 1.upto(n) do ; a = "1"; end }
|
69
|
+
tf = x.report("for:") { for i in 1..n; a = i; a; end }
|
70
|
+
tt = x.report("times:") { n.times do ; a = "1"; a; end }
|
71
|
+
tu = x.report("upto:") { 1.upto(n) do ; a = "1"; a; end }
|
72
72
|
[tf+tt+tu, (tf+tt+tu)/3]
|
73
73
|
end
|
74
74
|
end
|
@@ -97,7 +97,7 @@ class TestStdlibTypes < Minitest::Test
|
|
97
97
|
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
98
98
|
BigDecimal.mode(BigDecimal::EXCEPTION_NaN)
|
99
99
|
BigDecimal.ver
|
100
|
-
|
100
|
+
|
101
101
|
# TODO
|
102
102
|
end
|
103
103
|
|
@@ -110,7 +110,7 @@ class TestStdlibTypes < Minitest::Test
|
|
110
110
|
BigMath.sin(BigMath.PI(5)/4, 5)
|
111
111
|
BigMath.sqrt(BigDecimal.new('2'), 16)
|
112
112
|
end
|
113
|
-
|
113
|
+
|
114
114
|
def test_class
|
115
115
|
Dummy.allocate
|
116
116
|
Dummy.new
|
@@ -123,10 +123,10 @@ class TestStdlibTypes < Minitest::Test
|
|
123
123
|
Coverage.result
|
124
124
|
#Coverage.result # TODO This cannot be typechecked
|
125
125
|
end
|
126
|
-
|
126
|
+
|
127
127
|
def test_exception
|
128
128
|
e1 = Exception.new
|
129
|
-
e1 == 5
|
129
|
+
_ = (e1 == 5)
|
130
130
|
tmp = e1.backtrace
|
131
131
|
e1.backtrace_locations
|
132
132
|
e1.cause
|
@@ -136,14 +136,14 @@ class TestStdlibTypes < Minitest::Test
|
|
136
136
|
e1.set_backtrace(tmp)
|
137
137
|
e1.to_s
|
138
138
|
end
|
139
|
-
|
139
|
+
|
140
140
|
def test_set
|
141
141
|
skip "Skip when nowrap is enabled"
|
142
|
-
assert_raises(RDL::Type::TypeError) {
|
142
|
+
assert_raises(RDL::Type::TypeError) { _ = Set.new(1,2) }
|
143
143
|
# From the Ruby stdlib documentation
|
144
144
|
s1 = Set.new [1, 2] # -> #<Set: {1, 2}>
|
145
145
|
s2 = [1, 2].to_set # -> #<Set: {1, 2}>
|
146
|
-
s1 == s2
|
146
|
+
_ = (s1 == s2) # -> true
|
147
147
|
s1.add("foo") # -> #<Set: {1, 2, "foo"}>
|
148
148
|
s1.merge([2, 6]) # -> #<Set: {1, 2, "foo", 6}>
|
149
149
|
s1.subset? s2 # -> false
|
@@ -151,18 +151,18 @@ class TestStdlibTypes < Minitest::Test
|
|
151
151
|
Set[1, 2, 3].disjoint? Set[3, 4] # => false
|
152
152
|
Set[1, 2, 3].disjoint? Set[4, 5] # => true
|
153
153
|
numbers = Set[1, 3, 4, 6, 9, 10, 11]
|
154
|
-
|
154
|
+
_ = numbers.divide { |i,j| (i - j).abs == 1 }
|
155
155
|
Set[1, 2, 3].intersect? Set[4, 5] # => false
|
156
156
|
Set[1, 2, 3].intersect? Set[3, 4] # => true
|
157
157
|
# Some more tests, just to make sure type checking doesn't cause crashes
|
158
|
-
|
158
|
+
_ = s1 - s2
|
159
159
|
s1.proper_subset? s2
|
160
160
|
s1.superset? s2
|
161
|
-
s1 ^ s2
|
161
|
+
_ = s1 ^ s2
|
162
162
|
s1.add?("bar")
|
163
|
-
|
163
|
+
_ = s1.classify { |x| x.size }
|
164
164
|
s2.clear
|
165
|
-
|
165
|
+
_ = s1.map { |x| 42 }
|
166
166
|
s1.delete "foo"
|
167
167
|
s1.delete? "bar"
|
168
168
|
s1.delete_if { |x| false }
|
@@ -174,21 +174,21 @@ class TestStdlibTypes < Minitest::Test
|
|
174
174
|
s1.size
|
175
175
|
s1.difference [1,2,3]
|
176
176
|
s1.to_a
|
177
|
-
|
177
|
+
_ = s1 + s2
|
178
178
|
end
|
179
|
-
|
179
|
+
|
180
180
|
def test_uri
|
181
181
|
URI.decode_www_form("a=1&a=2&b=3")
|
182
182
|
URI.encode_www_form([["q", "ruby"], ["lang", "en"]]) # Internally uses _component
|
183
183
|
URI.encode_www_form("q" => "ruby", "lang" => "en")
|
184
184
|
URI.encode_www_form("q" => ["ruby", "perl"], "lang" => "en")
|
185
185
|
URI.encode_www_form([["q", "ruby"], ["q", "perl"], ["lang", "en"]])
|
186
|
-
URI.extract("text here http://foo.example.org/bla and here mailto:test@example.com and here also.")
|
186
|
+
# URI.extract("text here http://foo.example.org/bla and here mailto:test@example.com and here also.")
|
187
187
|
URI.join("http://example.com/","main.rbx")
|
188
188
|
URI.parse("http://www.ruby-lang.org/")
|
189
189
|
URI.scheme_list
|
190
190
|
URI.split("http://www.ruby-lang.org/")
|
191
|
-
enc_uri = URI.escape("http://example.com/?a=\11\15")
|
192
|
-
URI.unescape(enc_uri)
|
191
|
+
# enc_uri = URI.escape("http://example.com/?a=\11\15")
|
192
|
+
# URI.unescape(enc_uri)
|
193
193
|
end
|
194
|
-
end
|
194
|
+
end
|
data/test/test_member.rb
CHANGED
@@ -12,7 +12,7 @@ class TestMember < Minitest::Test
|
|
12
12
|
|
13
13
|
class C < B
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def setup
|
17
17
|
@tnil = NilType.new
|
18
18
|
@ttop = TopType.new
|
@@ -72,7 +72,7 @@ class TestMember < Minitest::Test
|
|
72
72
|
assert (@tkernel.member? "Foo")
|
73
73
|
assert (@tkernel.member? :Foo)
|
74
74
|
assert (@tkernel.member? o)
|
75
|
-
|
75
|
+
|
76
76
|
a = A.new
|
77
77
|
b = B.new
|
78
78
|
c = C.new
|
@@ -88,7 +88,7 @@ class TestMember < Minitest::Test
|
|
88
88
|
|
89
89
|
assert (@tstring.member? nil)
|
90
90
|
assert (@tobject.member? nil)
|
91
|
-
end
|
91
|
+
end
|
92
92
|
|
93
93
|
def test_symbol
|
94
94
|
assert (@tsym.member? :foo)
|
data/test/test_type_contract.rb
CHANGED
@@ -107,6 +107,68 @@ class TestTypeContract < Minitest::Test
|
|
107
107
|
assert_equal 42, p10.call(43, "44")
|
108
108
|
assert_raises(TypeError) { p10.call() }
|
109
109
|
assert_raises(TypeError) { p10.call(43, "44", 45) }
|
110
|
+
|
111
|
+
t11 = @p.scan_str "(Fixnum x {{ x > 42 }}) -> Fixnum"
|
112
|
+
p11 = t11.to_contract.wrap(self) { |x| x }
|
113
|
+
assert_equal 43, p11.call(43)
|
114
|
+
assert_raises(TypeError) { p11.call(42) }
|
115
|
+
|
116
|
+
t12 = @p.scan_str "(Fixnum x {{ x>10 }}, Fixnum y {{ y > x }}) -> Fixnum z {{z > (x+y) }}"
|
117
|
+
p12 = t12.to_contract.wrap(self) { |x,y| x+y+1 }
|
118
|
+
assert_equal 30, p12.call(14, 15)
|
119
|
+
assert_equal 50, p12.call(24, 25)
|
120
|
+
assert_raises(TypeError) { p12.call(9,10) }
|
121
|
+
assert_raises(TypeError) { p12.call(20,19) }
|
122
|
+
p12b = t12.to_contract.wrap(self) { |x,y| x+y }
|
123
|
+
assert_raises(TypeError) { p12b.call(42, 43) }
|
124
|
+
assert_raises(TypeError) { p12b.call(11, 10) }
|
125
|
+
assert_raises(TypeError) { p12b.call(9, 10) }
|
126
|
+
|
127
|
+
t13 = @p.scan_str "(Fixnum, {(Fixnum x {{x>10}}) -> Fixnum}) -> Float"
|
128
|
+
p13 = t13.to_higher_contract(self) { |x,y| x+y.call(11)+0.5 }
|
129
|
+
assert_equal 53.5, p13.call(42, Proc.new { |x| x })
|
130
|
+
assert_raises(TypeError) { p13.call(42.5, Proc.new { |x| x} ) }
|
131
|
+
assert_raises(TypeError) { p13.call(42, Proc.new { |x| 0.5 } ) }
|
132
|
+
p13b = t13.to_higher_contract(self) { |x,y| x+y.call(10)+0.5 }
|
133
|
+
assert_raises(TypeError) { p13b.call(42, Proc.new { |x| x } ) }
|
134
|
+
p13c = t13.to_higher_contract(self) { |x,y| x+y.call(11.5)+0.5 }
|
135
|
+
assert_raises(TypeError) { p13c.call(42, Proc.new { |x| x } ) }
|
136
|
+
p13d = t13.to_higher_contract(self) { |x,y| x+y.call(42) }
|
137
|
+
assert_raises(TypeError) { p13d.call(42, Proc.new { |x| x } ) }
|
138
|
+
|
139
|
+
t14 = @p.scan_str "(Fixnum, Fixnum) -> {(Fixnum) -> Fixnum}"
|
140
|
+
p14 = t14.to_higher_contract(self) { |x,y| Proc.new {|z| x+y+z} }
|
141
|
+
assert_raises(TypeError) { p14.call(42.5, 42) }
|
142
|
+
p14b = p14.call(42,42)
|
143
|
+
assert_equal 126, p14b.call(42)
|
144
|
+
assert_raises(TypeError) { p14b.call(42.5) }
|
145
|
+
p14c = t14.to_higher_contract(self) { |x,y| Proc.new {|z| x+y+z+0.5} }
|
146
|
+
p14d = p14c.call(42,42)
|
147
|
+
assert_raises(TypeError) { p14d.call(42) }
|
148
|
+
|
149
|
+
assert_equal 47, block_contract_test1(42) {|z| z}
|
150
|
+
assert_raises(TypeError) { block_contract_test1(42) {|z| 0.5} }
|
151
|
+
assert_raises(TypeError) { block_contract_test2(42) {|z| z} }
|
152
|
+
|
153
|
+
|
154
|
+
t15 = @p.scan_str "(Fixnum x {{x>y}}, Fixnum y) -> Fixnum"
|
155
|
+
p15 = t15.to_contract.wrap(self) { |x, y| x+y }
|
156
|
+
assert_equal 21, p15.call(11, 10)
|
157
|
+
assert_raises(TypeError) { p15.call(10, 11) }
|
158
|
+
|
159
|
+
t16 = @p.scan_str "(Fixnum x {{x > undefvar}}, Fixnum) -> Fixnum"
|
160
|
+
p16 = t16.to_contract.wrap(self) { |x,y| x }
|
161
|
+
assert_raises(NameError) { p16.call(10,10) }
|
162
|
+
end
|
163
|
+
|
164
|
+
type '(Fixnum) { (Fixnum) -> Fixnum } -> Fixnum'
|
165
|
+
def block_contract_test1(x)
|
166
|
+
x+yield(5)
|
167
|
+
end
|
168
|
+
|
169
|
+
type '(Fixnum) { (Fixnum) -> Fixnum } -> Float'
|
170
|
+
def block_contract_test2(x)
|
171
|
+
x+yield(4.5)
|
110
172
|
end
|
111
173
|
|
112
174
|
def test_proc_names
|
@@ -184,4 +246,4 @@ class TestTypeContract < Minitest::Test
|
|
184
246
|
assert_raises(TypeError) { p8.call(43, x: "foo", y: "foo") }
|
185
247
|
assert_raises(TypeError) { p8.call(43, x: :foo, y: "foo", z: 44) }
|
186
248
|
end
|
187
|
-
end
|
249
|
+
end
|