typed.rb 0.0.14 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 10a8acbaa2e89eb19d043a4b29ccc1a9e9f58712
4
- data.tar.gz: 5cfd5c3ee30993b30d82558d168c675c2fe6b859
3
+ metadata.gz: bb42b861c759a6aaa03b52fd351f5a1615d5232a
4
+ data.tar.gz: 1d76b7a85bdd7758d28b54a1506734c123e2384c
5
5
  SHA512:
6
- metadata.gz: 3233c50ea7798b565d1b5a24ded1a608a5b018821e47b390788ceb3108d183970a726622c973e31f3fbbae64d33faf70fe3bc376888a134df62d2772500a19e7
7
- data.tar.gz: 8b0e4212b51a79d643e682618cbbee275a4dbeb2f762d9aeabc14c633f2a1e682e948a5a23c31ebe26a78d889bcf9f56f0a3304cadccd7c4a53d71e4f2e7ab27
6
+ metadata.gz: 133005549d678a09477e777dc944e6cc3300bd89fee267f529d92986e20757170d4005dfa0385b4ec4722507458f0b52d2315f6355dcbac2aea135c1ac09bd83
7
+ data.tar.gz: 6bcbbe9cb52ffd37a466fec62fae0a11d6e14c04f25e3c66e4b4918c283f4d70faed9eb2e43210cc7cec08fac76234c543989ade1933791eed743e47850fd331
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- #Typed.rb [![Build Status](https://circleci.com/gh/antoniogarrote/typed.rb.png?circle-token=:circle-token)](https://circleci.com/gh/antoniogarrote/typed.rb/tree/master)
1
+ #Typed.rb [![Build Status](https://circleci.com/gh/antoniogarrote/typed.rb.png?circle-token=:circle-token)](https://circleci.com/gh/antoniogarrote/typed.rb/tree/master) [![Coverage Status](https://coveralls.io/repos/github/antoniogarrote/typed.rb/badge.svg?branch=master)](https://coveralls.io/github/antoniogarrote/typed.rb?branch=master)
2
2
 
3
3
  Gradual type checker for Ruby.
4
4
 
@@ -15,7 +15,7 @@ module Monoid
15
15
 
16
16
  ts '#mempty / -> [T]'
17
17
  abstract(:mempty)
18
-
18
+
19
19
  end
20
20
 
21
21
 
@@ -53,3 +53,108 @@ end
53
53
  moncat([1,2,3], Sum.new)
54
54
  }
55
55
  ```
56
+
57
+
58
+ ## Introduction
59
+
60
+ Typed.rb is an attempt to build a gradual type checker for the Ruby programming language.
61
+
62
+ Typed.rb provides a mechanism to add type annotations to Ruby program's classes, modules and methods, and makes it possible to type-check the annotated code statically.
63
+ Types annotations has no impact on performance during the execution of the program. Typed ruby code is valid regular ruby code.
64
+ Typed.rb leverages gradual typing for Ruby, this means that typed and untyped code can be freely mixed.
65
+
66
+ In it's current implementation Typed.rb includes the following components:
67
+
68
+ - A type signature language to annotate classes, modules and methods.
69
+ - A small run-time library that introduces a few extensions to ruby core types, like the type annotations method or the application of type parameters, it introduces some new types like Boolean and Pair and the notion of abstract methods.
70
+ - Type annotations for the Ruby Standard Library.
71
+ - A gradual type checker that can be executed statically to check the provided annotations.
72
+
73
+ Typed.rb tries to typecheck most of the static subset of Ruby with as few type annotations as possible, however, due to the highly dynamic nature of Ruby some compromises need to be made and the whole dynamic set of the language, say, dynamically evaluated methods and classes cannot be type-checked.
74
+
75
+ Typed.rb is still an ongoing effort and should be considered pre-alpha.
76
+
77
+
78
+ ## Type system
79
+
80
+ Typed.rb type system's matches Ruby type system with a few exceptions:
81
+
82
+ - A ```unit``` matching the runtime ```NilClass``` class has been added to the type signature language. It is inhabited by a single instalce ```nil``` and it's a subclass of all other types. ```unit``` must always be used in type signatures
83
+ - A ```dynamic``` type that by-passes type checking will be generated byt the type-checker when no typing information is available for a given method or type. Type checking untyped code will produce the ```dynamic``` type as a result. ```dynamic``` must never diractely used in a type annotation.
84
+ - A ```Boolean ``` type has been added inhabited by only two values ```true``` and ```false``` and matching both run-time classes ```TrueClass``` and ```FalseClass``` has been added to the type signature language. ```Boolean``` must always be used in type signatures
85
+ - A polymorphic ```Pair[T][U]``` extending ```Array``` type has been added to the type signature language and to the runtime. Function and blocks receiving or returning arrays of two elements can be annotated as using the ```Pair``` type
86
+ - A ```Showable``` type with no methods has been added as mixin into the ```String``` and ```Symbol``` class and can be used to annotate methods receiving an instance of any of these two classes
87
+
88
+
89
+ ## Type annotations
90
+
91
+ To introduce a new type annotation, the ```BasicObject#ts``` method can be used. They can appear in any part of the source code without taking in cosideration the location of the method being annotated, however as a rule, we try to add the type annotation before the definition of the method being annotated.
92
+ The method receives a string with the type signature and returns unit. At run-time the method is a noop.
93
+
94
+ A type signature for a method is composed of the following parts:
95
+
96
+ ```
97
+ Type?(#/.)method[T]* / ArgumentType? (-> ArgumentType)* -> &BlockType? -> ReturnType
98
+ ```
99
+
100
+ For example, the type signature of the ```#ts``` method itself is ```BasicObject#ts / String -> unit```.
101
+
102
+ The main components of a type signature are:
103
+
104
+ - ```Type``` (optional), type the method belongs to. If the type part of the signature is ommitted, the current wrapping class or module is considered to be the target of the method
105
+ - ```(#/.)``` instance/class indicator. Instance level methods are prefixed with ```#```, class level methods are prefixed with ```.```
106
+ - ```method``` message this method is handling
107
+ - ```[T]*``` method type variables for polymorphic methods
108
+ - ```/``` signature separator, a fixed character ```/``` separating the method information from the actual type arguments and return type information
109
+ - ```ArgumentType? (-> ArgumentType)* -> ReturnType``` an arrow (```->```) separated list of types representing the types of the input arguments and the output type of the method
110
+
111
+ If the method has no input arguments, the only return type can be expressed with a type with an initial ```->```. For example, a method with no arguments and returning ```nil``` can be expressed as ```-> unit```.
112
+ Higher order methods accepting procs or lambdas as inputs can be expressed between parentheses ```(ArgumentType? (-> ArgumentType)* -> ReturnType)```. Methods yielding a block can be expressed with final input argument of function type prefixed with a ```&```.
113
+ For example, the ```Enumerable#map``` method from the Ruby Standard Library accepting a block and parametric on the return value of that block has the following type annotation:
114
+
115
+ ```
116
+ ts '#map[E] / &([T] -> [E]) -> Array[E]'
117
+ ```
118
+
119
+ Methods accepting a variable number of arguments can be expressed using a suffix ellipsis ```...``` after the type of the vararg type. For instance, a method adding any number of integers could be expressed with the following type annotation:
120
+
121
+ ```
122
+ ts '#my_sum / Integer... -> Integer'
123
+ ```
124
+
125
+ More than one type annotation can be provided for the same method, but the arity of the annotations must be unique. Optional blocks are taking into consideration to compute the arity of the annotation.
126
+
127
+ In order to annotate classes and modules, the ```BasicObject#ts``` method is also used. Again, the type annotation can appear in any location of the source code but by convention we try to locate them before the implementation of the type if it is available.
128
+
129
+ Type annotations are only required for polymorphic types.
130
+
131
+ The type signature for a class/module has the following components:
132
+
133
+ ```
134
+ type TypeName[T]? (super BaseType[U]*)?
135
+ ```
136
+
137
+ - ```type``` prefix for all type annotations
138
+ - ```TypeName``` name of the class/module
139
+ - ```[T]*``` type variables for the polymorphic type
140
+ - ```(super BaseType[U]*)?``` base polymorphic class/module for the type
141
+
142
+
143
+ ## Type inference and minimal typing
144
+
145
+ Typed.rb will try to perform automatic type inference for the following language constructs and don't need to be annotated:
146
+
147
+ - global variables
148
+ - instance variables
149
+ - local variables
150
+ - constants
151
+
152
+ To know more about the type inferance mechanism, check the implementation of the unification algorithm used by the type checker in ```lib/typed/types/polymorphism/unification.rb```.
153
+
154
+ Class and modules only need to be annotated if they are defined as polymorphic. All methods must be annotated.
155
+
156
+ ## Running the type-checker
157
+
158
+ To execute the type checker, the ```bin/typed.rb``` script can be used. The script accepts a list of options and path to the entry-point of the source code to be type-checked. Currently the only option available is ```--missing-type``` that will force the type-checker to produce a warning every single time a default dynamic type is introduced due to lack of typing information.
159
+
160
+ The script will produce some error report output and return an appropriate exit value according to the result of the the check.
@@ -87,6 +87,7 @@ module TypedRb
87
87
  TypingContext.clear(:top_level)
88
88
  check_result = nil
89
89
  errors = {}
90
+ errors_accum = {}
90
91
  ordered_files.each do |file|
91
92
  $TYPECHECK_FILE = file
92
93
  expr = File.open(file, 'r').read
@@ -95,9 +96,13 @@ module TypedRb
95
96
  print '.'.green
96
97
  rescue TypedRb::Types::UncomparableTypes, TypedRb::TypeCheckError => e
97
98
  print 'E'.red
98
- errors_for_file = errors[file] || []
99
- errors_for_file << e
100
- errors[file] = errors_for_file
99
+ hash = e.to_s.hash
100
+ unless errors_accum[hash]
101
+ errors_accum[hash] = true
102
+ errors_for_file = errors[file] || []
103
+ errors_for_file << e
104
+ errors[file] = errors_for_file
105
+ end
101
106
  end
102
107
  end
103
108
  top_level_errors = []
@@ -105,8 +110,12 @@ module TypedRb
105
110
  ::BasicObject::TypeRegistry.check_super_type_annotations
106
111
  @unification_result = run_unification
107
112
  rescue TypedRb::Types::UncomparableTypes, TypedRb::TypeCheckError => e
108
- print 'E'.red
109
- top_level_errors << e
113
+ hash = e.to_s.hash
114
+ unless errors_accum[hash]
115
+ errors_accum[hash] = true
116
+ print 'E'.red
117
+ top_level_errors << e
118
+ end
110
119
  end
111
120
  puts "\n"
112
121
  total_errors = all_errors(top_level_errors, errors)
@@ -134,8 +143,12 @@ module TypedRb
134
143
  puts error.message.red
135
144
  end
136
145
  warnings_for_file.each do |warning|
137
- puts "\n"
138
- puts warning.message.yellow
146
+ hash = warning.to_s.hash
147
+ unless errors_accum[hash]
148
+ errors_accum[hash] = true
149
+ puts "\n"
150
+ puts warning.message.yellow
151
+ end
139
152
  end
140
153
  end
141
154
  top_level_errors.each do |error|
@@ -87,7 +87,7 @@ module TypedRb
87
87
  function_arg_type = function_type.from[i]
88
88
  # Generic arguments are parsed by runtime without checking constraints since they are not available at parsing type.
89
89
  # We need to run unification in them before using the type to detect invalid type argument applications.
90
- function_arg_type = function_arg_type.self_materialize if function_arg_type.is_a?(Types::TyGenericSingletonObject)
90
+ function_arg_type = function_arg_type.self_materialize.as_object_type if function_arg_type.is_a?(Types::TyGenericSingletonObject)
91
91
  context = case arg.first
92
92
  when :arg, :restarg
93
93
  context.add_binding(arg[1], function_arg_type)
@@ -157,8 +157,9 @@ module TypedRb
157
157
  # TODO:
158
158
  # A TyObject(Symbol) should be returned not the function type
159
159
  # x = def id(x); x; end / => x == :id
160
- error_message = "Error type checking function type #{owner}##{name}: Wrong return type, expected #{function_type.to}, found #{body_return_type}."
161
- fail Types::UncomparableTypes.new(function_type.to, body_return_type, node)
160
+ error_message = ". Wrong return type, expected #{function_type.to}, found #{body_return_type}."
161
+ body_return_type.compatible?(function_type_to, :lt)
162
+ fail Types::UncomparableTypes.new(function_type.to, body_return_type, node, error_message)
162
163
  end
163
164
  end
164
165
  end
data/lib/typed/prelude.rb CHANGED
@@ -21,6 +21,7 @@ class BasicObject
21
21
  ts '#singleton_method_undefined / Symbol -> unit'
22
22
  ts '#ts / String -> unit'
23
23
  ts '#cast / BasicObject -> BasicObject -> BasicObject'
24
+ ts '#abstract / Symbol -> Symbol'
24
25
  end
25
26
 
26
27
  class Object
Binary file
data/lib/typed/runtime.rb CHANGED
@@ -24,7 +24,6 @@ class BasicObject
24
24
  from
25
25
  end
26
26
 
27
- ts '#abstract / Symbol -> Symbol'
28
27
  def abstract(name)
29
28
  define_method(name) { |*args| raise "Invoking abstract method #{name}"}
30
29
  end
@@ -44,8 +44,6 @@ module TypedRb
44
44
  def compatible?(type, relation = :lt)
45
45
  if @bound
46
46
  @bound.compatible?(type, relation)
47
- elsif incompatible_vars?(type)
48
- false
49
47
  else
50
48
  add_constraint(relation, type)
51
49
  true
@@ -117,21 +115,6 @@ module TypedRb
117
115
  def bound_to_generic?
118
116
  bound && bound.respond_to?(:generic?) && bound.generic?
119
117
  end
120
-
121
- private
122
-
123
- def incompatible_vars?(type)
124
- if type.is_a?(TypeVariable)
125
- left_var = bound || self
126
- right_var = type.bound || type
127
-
128
- left_var.is_a?(TypeVariable) &&
129
- right_var.is_a?(TypeVariable) &&
130
- left_var.variable != right_var.variable &&
131
- (TypingContext.bound_generic_type_var?(left_var) &&
132
- TypingContext.bound_generic_type_var?(right_var))
133
- end
134
- end
135
118
  end
136
119
  end
137
120
  end
@@ -161,10 +161,13 @@ module TypedRb
161
161
  var_constraints = @constraints[variable_name] || []
162
162
  var_constraints << [relation_type, type]
163
163
  @constraints[variable_name] = var_constraints
164
- elsif parent
164
+ elsif parent.include?(variable_name)
165
165
  parent.add_constraint(variable_name, relation_type, type)
166
166
  else
167
- fail StandardError, "Cannot find variable #{variable_name} to add a constraint"
167
+ key = [:local, nil, variable_name]
168
+ type_variables_register[key] = TypeVariable.new(variable_name, gen_name: false)
169
+ @constraints[variable_name] = [relation_type, type]
170
+ # fail StandardError, "Cannot find variable #{variable_name} to add a constraint"
168
171
  end
169
172
  end
170
173
 
@@ -47,7 +47,7 @@ module TypedRb
47
47
  begin
48
48
  value_l <= value_r ? value_l : fail(UnificationError, error_message)
49
49
  rescue ArgumentError
50
- raise(Types::UncomparableTypes.new(value_l, value_r))
50
+ raise(Types::UncomparableTypes.new(value_l, value_r, nil, ", #{value_l} is not a subtype of #{value_r}"))
51
51
  end
52
52
  end
53
53
 
@@ -7,6 +7,9 @@ module TypedRb
7
7
 
8
8
  def initialize(ruby_type, node = nil)
9
9
  super(ruby_type, node)
10
+ @hierarchy = [ruby_type] + Module.ancestors
11
+ @classes = @hierarchy.select { |klass| klass.instance_of?(Class) }
12
+ @modules = @hierarchy.select { |klass| klass.instance_of?(Module) }
10
13
  end
11
14
 
12
15
  def check_inclusion(self_type)
@@ -2,16 +2,16 @@ module TypedRb
2
2
  module Types
3
3
  class UncomparableTypes < TypeCheckError
4
4
  attr_reader :from, :to
5
- def initialize(from, to, node = nil)
5
+ def initialize(from, to, node = nil, msg='')
6
6
  nodes = [from.node, to.node].compact
7
7
  if node
8
- super("Cannot compare types #{from} <=> #{to}", node)
8
+ super("Cannot compare types #{from} <=> #{to}#{msg}", node)
9
9
  elsif nodes.size == 2
10
- super("Cannot compare types #{from} <=> #{to}", nodes)
10
+ super("Cannot compare types #{from} <=> #{to}#{msg}", nodes)
11
11
  elsif nodes.size == 1
12
- super("Cannot compare types #{from} <=> #{to}", nodes.first)
12
+ super("Cannot compare types #{from} <=> #{to}#{msg}", nodes.first)
13
13
  else
14
- super("Cannot compare types #{from} <=> #{to}", nil)
14
+ super("Cannot compare types #{from} <=> #{to}#{msg}", nil)
15
15
  end
16
16
  end
17
17
  end
data/lib/typed/version.rb CHANGED
@@ -1,3 +1,5 @@
1
1
  module TypedRb
2
- VERSION = '0.0.14'
2
+ unless defined?(VERSION)
3
+ VERSION = '0.0.15'
4
+ end
3
5
  end
@@ -0,0 +1,44 @@
1
+ ts 'type Monoid[T]'
2
+ module Monoid
3
+ ts '#mappend / [T] -> [T] -> [T]'
4
+ abstract(:mappend)
5
+
6
+ ts '#mempty / -> [T]'
7
+ abstract(:mempty)
8
+ end
9
+
10
+
11
+ ts 'type Sum[String] super Monoid[T]'
12
+ class Sum
13
+
14
+ include Monoid
15
+
16
+ def mappend(a,b)
17
+ a + b
18
+ end
19
+
20
+ def mempty
21
+ 0
22
+ end
23
+
24
+ end
25
+
26
+
27
+ ts '#sum / Array[Integer] -> Integer'
28
+ def sum(xs)
29
+ monoid = Sum.new
30
+ zero = monoid.mempty
31
+ xs.reduce(zero) { |a,b| monoid.mappend(a,b) }
32
+ end
33
+
34
+
35
+ ts '#moncat[T] / Array[T] -> Monoid[T] -> [T]'
36
+ def moncat(xs, m)
37
+ zero = m.mempty
38
+ xs.reduce(zero) { |a,b| m.mappend(a,b) }
39
+ end
40
+
41
+ ->() {
42
+ moncat([1,2,3], Sum.new)
43
+ }
44
+
@@ -0,0 +1,44 @@
1
+ ts 'type Monoid[T]'
2
+ module Monoid
3
+ ts '#mappend / [T] -> [T] -> [T]'
4
+ abstract(:mappend)
5
+
6
+ ts '#mempty / -> [T]'
7
+ abstract(:mempty)
8
+ end
9
+
10
+
11
+ ts 'type Sum[Integer] super Monoid[T]'
12
+ class Sum
13
+
14
+ include Monoid
15
+
16
+ def mappend(a,b)
17
+ a + b
18
+ end
19
+
20
+ def mempty
21
+ '0'
22
+ end
23
+
24
+ end
25
+
26
+
27
+ ts '#sum / Array[Integer] -> Integer'
28
+ def sum(xs)
29
+ monoid = Sum.new
30
+ zero = monoid.mempty
31
+ xs.reduce(zero) { |a,b| monoid.mappend(a,b) }
32
+ end
33
+
34
+
35
+ ts '#moncat[T] / Array[T] -> Monoid[T] -> [T]'
36
+ def moncat(xs, m)
37
+ zero = m.mempty
38
+ xs.reduce(zero) { |a,b| m.mappend(a,b) }
39
+ end
40
+
41
+ ->() {
42
+ moncat([1,2,3], Sum.new)
43
+ }
44
+
@@ -0,0 +1,44 @@
1
+ ts 'type Monoid[T]'
2
+ module Monoid
3
+ ts '#mappend / [T] -> [T] -> [T]'
4
+ abstract(:mappend)
5
+
6
+ ts '#mempty / -> [T]'
7
+ abstract(:mempty)
8
+ end
9
+
10
+
11
+ ts 'type Sum[Integer] super Monoid[T]'
12
+ class Sum
13
+
14
+ include Monoid
15
+
16
+ def mappend(a,b)
17
+ a + b
18
+ end
19
+
20
+ def mempty
21
+ 0
22
+ end
23
+
24
+ end
25
+
26
+
27
+ ts '#sum / Array[String] -> Integer'
28
+ def sum(xs)
29
+ monoid = Sum.new
30
+ zero = monoid.mempty
31
+ xs.reduce(zero) { |a,b| monoid.mappend(a,b) }
32
+ end
33
+
34
+
35
+ ts '#moncat[T] / Array[T] -> Monoid[T] -> [T]'
36
+ def moncat(xs, m)
37
+ zero = m.mempty
38
+ xs.reduce(zero) { |a,b| m.mappend(a,b) }
39
+ end
40
+
41
+ ->() {
42
+ moncat([1,2,3], Sum.new)
43
+ }
44
+
@@ -0,0 +1,44 @@
1
+ ts 'type Monoid[T]'
2
+ module Monoid
3
+ ts '#mappend / [T] -> [T] -> [T]'
4
+ abstract(:mappend)
5
+
6
+ ts '#mempty / -> [T]'
7
+ abstract(:mempty)
8
+ end
9
+
10
+
11
+ ts 'type Sum[Integer] super Monoid[T]'
12
+ class Sum
13
+
14
+ include Monoid
15
+
16
+ def mappend(a,b)
17
+ a + b
18
+ end
19
+
20
+ def mempty
21
+ 0
22
+ end
23
+
24
+ end
25
+
26
+
27
+ ts '#sum / Array[Integer] -> Integer'
28
+ def sum(xs)
29
+ monoid = Sum.new
30
+ zero = monoid.mempty
31
+ xs.reduce(zero) { |a,b| monoid.mappend(a,b) }
32
+ end
33
+
34
+
35
+ ts '#moncat[T] / Array[T] -> Monoid[T] -> [T]'
36
+ def moncat(xs, m)
37
+ zero = m.mempty
38
+ xs.reduce(zero) { |a,b| m.mappend(a,b) }
39
+ end
40
+
41
+ ->() {
42
+ moncat([1,'2',3], Sum.new)
43
+ }
44
+
@@ -50,7 +50,7 @@ describe TypedRb::Language do
50
50
  end
51
51
  end
52
52
 
53
- context 'with monoid eample' do
53
+ context 'with monoid example' do
54
54
  let(:example) { 'monoid.rb' }
55
55
 
56
56
  it 'should be possible to type check the example correctly' do
@@ -61,4 +61,52 @@ describe TypedRb::Language do
61
61
  }.not_to raise_error
62
62
  end
63
63
  end
64
+
65
+ context 'with monoid error example, inconsistent type annotation' do
66
+ let(:example) { 'monoid/monoid_error1.rb' }
67
+
68
+ it 'should be possible to type check the example correctly' do
69
+ expect {
70
+ silence_stream(STDOUT) do
71
+ language.check_file(file, true)
72
+ end
73
+ }.to raise_error(TypedRb::Types::UncomparableTypes)
74
+ end
75
+ end
76
+
77
+ context 'with monoid error example, inconsistent type annotation' do
78
+ let(:example) { 'monoid/monoid_error2.rb' }
79
+
80
+ it 'should be possible to type check the example correctly' do
81
+ expect {
82
+ silence_stream(STDOUT) do
83
+ language.check_file(file, true)
84
+ end
85
+ }.to raise_error(TypedRb::Types::UncomparableTypes)
86
+ end
87
+ end
88
+
89
+ context 'with monoid error example, inconsistent type annotation' do
90
+ let(:example) { 'monoid/monoid_error3.rb' }
91
+
92
+ it 'should be possible to type check the example correctly' do
93
+ expect {
94
+ silence_stream(STDOUT) do
95
+ language.check_file(file, true)
96
+ end
97
+ }.to raise_error(TypedRb::Types::UncomparableTypes)
98
+ end
99
+ end
100
+
101
+ context 'with monoid error example, inconsistent type annotation' do
102
+ let(:example) { 'monoid/monoid_error4.rb' }
103
+
104
+ it 'should be possible to type check the example correctly' do
105
+ expect {
106
+ silence_stream(STDOUT) do
107
+ language.check_file(file, true)
108
+ end
109
+ }.to raise_error(TypedRb::Types::Polymorphism::UnificationError)
110
+ end
111
+ end
64
112
  end
@@ -0,0 +1,19 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe TypedRb do
4
+
5
+ describe '#log_dynamic_warning' do
6
+ it 'stores a warning if the :dynamic_warnings flag is enabled' do
7
+ TypedRb.options = {:dynamic_warnings => true }
8
+ TypedRb.dynamic_warnings.clear
9
+ TypedRb.log_dynamic_warning(nil, nil, nil)
10
+ expect(TypedRb.dynamic_warnings.count).to eq(1)
11
+
12
+ TypedRb.options = {}
13
+ TypedRb.dynamic_warnings.clear
14
+ TypedRb.log_dynamic_warning(nil, nil, nil)
15
+ expect(TypedRb.dynamic_warnings.count).to eq(0)
16
+ end
17
+ end
18
+
19
+ end
@@ -1,6 +1,9 @@
1
1
  require_relative '../../spec_helper'
2
2
 
3
- describe 'generics use caes' do
3
+ describe 'generics use case
4
+ when
5
+
6
+ end' do
4
7
  let(:language) { TypedRb::Language.new }
5
8
 
6
9
  it 'applies arguments to generic types' do
@@ -108,8 +111,7 @@ __END
108
111
 
109
112
  expect do
110
113
  language.check(code)
111
- end.to raise_error(TypedRb::TypeCheckError,
112
- /TestGen2\:T\:\:\[\?,\?\] expected, TestGen2\:U\:\:\[\?,\?\]/)
114
+ end.to raise_error(TypedRb::TypeCheckError)
113
115
  end
114
116
 
115
117
  it 'type-checks correctly super type generics' do
@@ -46,7 +46,7 @@ __CODE
46
46
  context 'with not matching arg type in function definition' do
47
47
  let(:code) do
48
48
  text = <<__CODE
49
- class A
49
+ class ADefault
50
50
  ts '#f1 / Integer -> String'
51
51
  def f1(num='text')
52
52
  'String'
@@ -37,7 +37,7 @@ __CODE
37
37
  expect {
38
38
  language.check(code)
39
39
  }.to raise_error(TypedRb::Types::UncomparableTypes,
40
- 'Cannot compare types Integer <=> String')
40
+ /Cannot compare types Integer <=> String/)
41
41
  end
42
42
 
43
43
  it 'includes a module referencing instance variables in a class' do
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  require 'pry'
2
2
  require 'simplecov'
3
3
  require 'rspec-prof'
4
+ require 'coveralls'
5
+
6
+ Coveralls.wear!
4
7
 
5
8
  SimpleCov.start do
6
9
  add_filter "/spec/"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: typed.rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.14
4
+ version: 0.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Antonio Garrote
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-21 00:00:00.000000000 Z
11
+ date: 2016-01-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -148,6 +148,10 @@ files:
148
148
  - spec/lib/examples/counter.rb
149
149
  - spec/lib/examples/if.rb
150
150
  - spec/lib/examples/monoid.rb
151
+ - spec/lib/examples/monoid/monoid_error1.rb
152
+ - spec/lib/examples/monoid/monoid_error2.rb
153
+ - spec/lib/examples/monoid/monoid_error3.rb
154
+ - spec/lib/examples/monoid/monoid_error4.rb
151
155
  - spec/lib/language_spec.rb
152
156
  - spec/lib/model/tm_abs_spec.rb
153
157
  - spec/lib/model/tm_array_literal_spec.rb
@@ -183,6 +187,7 @@ files:
183
187
  - spec/lib/runtime/validations_spec.rb
184
188
  - spec/lib/runtime_spec.rb
185
189
  - spec/lib/type_signature/parser_spec.rb
190
+ - spec/lib/typed_spec.rb
186
191
  - spec/lib/types/comparisons_spec.rb
187
192
  - spec/lib/types/polymorphism/generic_comparisons_spec.rb
188
193
  - spec/lib/types/polymorphism/type_variable_register_spec.rb