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.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/CHANGES.md +25 -0
  4. data/README.md +104 -64
  5. data/extras/type_tests/%.rb +171 -0
  6. data/extras/type_tests/&.rb +159 -0
  7. data/extras/type_tests/**.rb +222 -0
  8. data/extras/type_tests/*.rb +177 -0
  9. data/extras/type_tests/+.rb +170 -0
  10. data/extras/type_tests/-.rb +171 -0
  11. data/extras/type_tests/1scomp.rb +157 -0
  12. data/extras/type_tests/<.rb +170 -0
  13. data/extras/type_tests/<<.rb +159 -0
  14. data/extras/type_tests/>>.rb +159 -0
  15. data/extras/type_tests/[].rb +163 -0
  16. data/extras/type_tests/^.rb +159 -0
  17. data/extras/type_tests/abs.rb +155 -0
  18. data/extras/type_tests/abs2.rb +164 -0
  19. data/extras/type_tests/angle.rb +157 -0
  20. data/extras/type_tests/arg.rb +157 -0
  21. data/extras/type_tests/bit_length.rb +157 -0
  22. data/extras/type_tests/ceil.rb +157 -0
  23. data/extras/type_tests/ceilRational.rb +160 -0
  24. data/extras/type_tests/conj.rb +158 -0
  25. data/extras/type_tests/defwhere.rb +86 -0
  26. data/extras/type_tests/denominator.rb +157 -0
  27. data/extras/type_tests/div.rb +172 -0
  28. data/extras/type_tests/divslash.rb +179 -0
  29. data/extras/type_tests/even?.rb +157 -0
  30. data/extras/type_tests/fdiv.rb +244 -0
  31. data/extras/type_tests/finite?.rb +157 -0
  32. data/extras/type_tests/floor.rb +157 -0
  33. data/extras/type_tests/floorRational.rb +161 -0
  34. data/extras/type_tests/hash.rb +157 -0
  35. data/extras/type_tests/imag.rb +158 -0
  36. data/extras/type_tests/infinite?.rb +157 -0
  37. data/extras/type_tests/modulo.rb +171 -0
  38. data/extras/type_tests/nan?.rb +157 -0
  39. data/extras/type_tests/neg.rb +155 -0
  40. data/extras/type_tests/next.rb +157 -0
  41. data/extras/type_tests/next_float.rb +157 -0
  42. data/extras/type_tests/numerator.rb +157 -0
  43. data/extras/type_tests/phase.rb +157 -0
  44. data/extras/type_tests/prev_float.rb +157 -0
  45. data/extras/type_tests/quo.rb +179 -0
  46. data/extras/type_tests/rationalize.rb +157 -0
  47. data/extras/type_tests/rationalizeArg.rb +198 -0
  48. data/extras/type_tests/real.rb +157 -0
  49. data/extras/type_tests/real?.rb +157 -0
  50. data/extras/type_tests/round.rb +157 -0
  51. data/extras/type_tests/roundArg.rb +169 -0
  52. data/extras/type_tests/size.rb +157 -0
  53. data/extras/type_tests/to_c.rb +157 -0
  54. data/extras/type_tests/to_f.rb +155 -0
  55. data/extras/type_tests/to_i.rb +157 -0
  56. data/extras/type_tests/to_r.rb +157 -0
  57. data/extras/type_tests/to_s.rb +157 -0
  58. data/extras/type_tests/truncate.rb +157 -0
  59. data/extras/type_tests/truncateArg.rb +166 -0
  60. data/extras/type_tests/type tests +1 -0
  61. data/extras/type_tests/zero?.rb +155 -0
  62. data/extras/type_tests/|.rb +159 -0
  63. data/lib/rdl/contracts/and.rb +1 -1
  64. data/lib/rdl/contracts/flat.rb +2 -2
  65. data/lib/rdl/contracts/proc.rb +2 -1
  66. data/lib/rdl/types/.#lexer.rex +1 -0
  67. data/lib/rdl/types/dependent_arg.rb +47 -0
  68. data/lib/rdl/types/finitehash.rb +5 -5
  69. data/lib/rdl/types/generic.rb +3 -3
  70. data/lib/rdl/types/lexer.rex +5 -2
  71. data/lib/rdl/types/lexer.rex.rb +3 -0
  72. data/lib/rdl/types/method.rb +144 -15
  73. data/lib/rdl/types/nominal.rb +1 -1
  74. data/lib/rdl/types/parser.racc +6 -1
  75. data/lib/rdl/types/parser.tab.rb +272 -245
  76. data/lib/rdl/types/tuple.rb +1 -1
  77. data/lib/rdl/types/type_inferencer.rb +7 -7
  78. data/lib/rdl/wrap.rb +16 -11
  79. data/rdl.gemspec +3 -3
  80. data/test/test_dsl.rb +4 -5
  81. data/test/test_le.rb +5 -5
  82. data/test/test_lib_types.rb +34 -34
  83. data/test/test_member.rb +3 -3
  84. data/test/test_type_contract.rb +63 -1
  85. data/test/test_types.rb +2 -0
  86. data/types/ruby-2.x/_aliases.rb +2 -2
  87. data/types/ruby-2.x/bigdecimal.rb +246 -12
  88. data/types/ruby-2.x/bignum.rb +253 -0
  89. data/types/ruby-2.x/complex.rb +111 -22
  90. data/types/ruby-2.x/fixnum.rb +238 -31
  91. data/types/ruby-2.x/float.rb +217 -35
  92. data/types/ruby-2.x/integer.rb +17 -16
  93. data/types/ruby-2.x/numeric.rb +31 -21
  94. data/types/ruby-2.x/rational.rb +196 -18
  95. metadata +67 -4
@@ -61,7 +61,7 @@ module RDL::Type
61
61
  end
62
62
 
63
63
  def hash
64
- h = 73 * @params.hash
64
+ 73 * @params.hash
65
65
  end
66
66
  end
67
67
  end
@@ -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, type_set|
63
- t = type_set.map {|unioned_type_parameter|
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, *t)
67
+ non_param_classes << RDL::Type::GenericType.new(nominal, *nt)
68
68
  }
69
69
 
70
70
  non_param_classes
@@ -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 = @__rdl_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
- ret = send(#{meth_old.inspect}, *args, &blk)
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, variance, all = $__rdl_type_params[klass]
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 { |t, obj|
426
- if t.instance_of? RDL::Type::GenericType # require obj to be instantiated
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 #{t.to_s}, but got uninstantiated object #{obj.inspect}" unless t_obj
429
- raise RDL::Type::TypeError, "Expecting type #{t.to_s}, got type #{t_obj.to_s}" unless t_obj <= t
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 #{t.to_s}, got #{obj.inspect}" unless t.member? obj
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
@@ -4,8 +4,8 @@
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = 'rdl'
7
- s.version = '1.1.0'
8
- s.date = '2016-01-03'
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'
@@ -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
- p = Pair.new.entry {
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
- t = Tree.new.entry(2) {
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
-
@@ -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 <= @tstring_or_sym))
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
@@ -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) { s0 = Abbrev.abbrev 5}
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) { s2 = Abbrev.abbrev Dummy.new }
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
- d0 = Base64.decode64(e0) # -> "Send reinforcements"
38
+ Base64.decode64(e0) # -> "Send reinforcements"
39
39
  #assert_equal(e0,d0)
40
40
  e1 = Base64.strict_encode64('Send reinforcements')
41
- d1 = Base64.strict_decode64(e1)
41
+ Base64.strict_decode64(e1)
42
42
  #assert_equal(e1,d1)
43
43
  e2 = Base64.urlsafe_encode64('Send reinforcements')
44
- d2 = Base64.urlsafe_decode64(e2)
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 = "1"; end }
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 = "1"; end }
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
- array = (1..1000000).map { rand }
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 = "1"; end }
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) { s6 = Set.new(1,2) }
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 # -> true
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
- set = numbers.divide { |i,j| (i - j).abs == 1 }
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
- s3 = s1 - s2
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
- h = s1.classify { |x| x.size }
163
+ _ = s1.classify { |x| x.size }
164
164
  s2.clear
165
- s4 = s1.map { |x| 42 }
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
- s5 = s1 + s2
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
@@ -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)
@@ -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