finitio 0.7.0.pre.rc3 → 0.9.1
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 +5 -5
- data/CHANGELOG.md +34 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +41 -41
- data/README.md +88 -12
- data/lib/finitio.rb +37 -5
- data/lib/finitio/generation.rb +106 -0
- data/lib/finitio/generation/ad_type.rb +10 -0
- data/lib/finitio/generation/alias_type.rb +9 -0
- data/lib/finitio/generation/any_type.rb +11 -0
- data/lib/finitio/generation/builtin_type.rb +9 -0
- data/lib/finitio/generation/hash_based_type.rb +15 -0
- data/lib/finitio/generation/heuristic.rb +8 -0
- data/lib/finitio/generation/heuristic/constant.rb +30 -0
- data/lib/finitio/generation/heuristic/random.rb +52 -0
- data/lib/finitio/generation/rel_based_type.rb +13 -0
- data/lib/finitio/generation/seq_type.rb +13 -0
- data/lib/finitio/generation/set_type.rb +13 -0
- data/lib/finitio/generation/sub_type.rb +9 -0
- data/lib/finitio/generation/union_type.rb +10 -0
- data/lib/finitio/inference.rb +51 -0
- data/lib/finitio/json_schema.rb +16 -0
- data/lib/finitio/json_schema/ad_type.rb +11 -0
- data/lib/finitio/json_schema/alias_type.rb +9 -0
- data/lib/finitio/json_schema/any_type.rb +9 -0
- data/lib/finitio/json_schema/builtin_type.rb +27 -0
- data/lib/finitio/json_schema/hash_based_type.rb +25 -0
- data/lib/finitio/json_schema/rel_based_type.rb +13 -0
- data/lib/finitio/json_schema/seq_type.rb +12 -0
- data/lib/finitio/json_schema/set_type.rb +13 -0
- data/lib/finitio/json_schema/struct_type.rb +12 -0
- data/lib/finitio/json_schema/sub_type.rb +10 -0
- data/lib/finitio/json_schema/union_type.rb +11 -0
- data/lib/finitio/support.rb +18 -0
- data/lib/finitio/support/attribute.rb +8 -0
- data/lib/finitio/support/compilation.rb +18 -18
- data/lib/finitio/support/contract.rb +10 -2
- data/lib/finitio/support/fetch_scope.rb +19 -0
- data/lib/finitio/support/heading.rb +42 -1
- data/lib/finitio/syntax.rb +1 -1
- data/lib/finitio/syntax/import.rb +1 -1
- data/lib/finitio/syntax/lexer.citrus +1 -1
- data/lib/finitio/syntax/type.rb +2 -0
- data/lib/finitio/syntax/type/high_order_type_instantiation.rb +29 -0
- data/lib/finitio/syntax/type/high_order_vars.rb +16 -0
- data/lib/finitio/syntax/type/type_def.rb +11 -1
- data/lib/finitio/syntax/types.citrus +14 -1
- data/lib/finitio/system.rb +20 -4
- data/lib/finitio/type.rb +19 -0
- data/lib/finitio/type/ad_type.rb +9 -1
- data/lib/finitio/type/alias_type.rb +8 -0
- data/lib/finitio/type/any_type.rb +12 -0
- data/lib/finitio/type/builtin_type.rb +4 -0
- data/lib/finitio/type/collection_type.rb +15 -0
- data/lib/finitio/type/heading_based_type.rb +17 -0
- data/lib/finitio/type/high_order_type.rb +39 -0
- data/lib/finitio/type/multi_relation_type.rb +4 -0
- data/lib/finitio/type/multi_tuple_type.rb +4 -0
- data/lib/finitio/type/proxy_type.rb +10 -20
- data/lib/finitio/type/relation_type.rb +4 -0
- data/lib/finitio/type/seq_type.rb +1 -1
- data/lib/finitio/type/struct_type.rb +8 -0
- data/lib/finitio/type/sub_type.rb +8 -0
- data/lib/finitio/type/tuple_type.rb +4 -0
- data/lib/finitio/type/union_type.rb +19 -0
- data/lib/finitio/version.rb +2 -2
- data/spec/finitio/test_stdlib_memoization.rb +22 -0
- data/spec/finitio/test_system.rb +0 -11
- data/spec/generation/test_generation.rb +169 -0
- data/spec/heading/test_looks_similar.rb +45 -0
- data/spec/heading/test_suppremum.rb +56 -0
- data/spec/inference/test_inference.rb +42 -0
- data/spec/json_schema/test_ad_type.rb +20 -0
- data/spec/json_schema/test_alias_type.rb +15 -0
- data/spec/json_schema/test_any_type.rb +11 -0
- data/spec/json_schema/test_builtin_type.rb +51 -0
- data/spec/json_schema/test_multi_relation_type.rb +58 -0
- data/spec/json_schema/test_multi_tuple_type.rb +50 -0
- data/spec/json_schema/test_relation_type.rb +30 -0
- data/spec/json_schema/test_seq_type.rb +18 -0
- data/spec/json_schema/test_set_type.rb +19 -0
- data/spec/json_schema/test_struct_type.rb +18 -0
- data/spec/json_schema/test_sub_type.rb +17 -0
- data/spec/json_schema/test_tuple_type.rb +26 -0
- data/spec/json_schema/test_union_type.rb +17 -0
- data/spec/regression/test_heading_extra_are_proxy_resolved.rb +41 -0
- data/spec/spec_helper.rb +32 -6
- data/spec/support/test_compare_attrs.rb +67 -0
- data/spec/syntax/test_compile.rb +57 -0
- data/spec/system/fixtures/system.fio +2 -0
- data/spec/{finitio → system/fixtures}/with-duplicates.fio +2 -1
- data/spec/system/test_check_and_warn.rb +55 -0
- data/spec/type/ad_type/test_initialize.rb +1 -8
- data/spec/type/relation_type/test_suppremum.rb +104 -0
- data/spec/type/seq_type/test_suppremum.rb +54 -0
- data/spec/type/set_type/test_suppremum.rb +54 -0
- data/spec/type/test_suppremum.rb +49 -0
- data/spec/type/test_unconstrained.rb +150 -0
- data/spec/type/tuple_type/test_suppremum.rb +119 -0
- data/spec/type/union_type/test_suppremum.rb +51 -0
- data/tasks/test.rake +1 -1
- metadata +99 -15
- data/spec/type/proxy_type/test_delegation.rb +0 -37
- data/spec/type/proxy_type/test_resolve.rb +0 -29
@@ -0,0 +1,26 @@
|
|
1
|
+
module Finitio
|
2
|
+
module JsonSchema
|
3
|
+
describe "TupleType" do
|
4
|
+
|
5
|
+
let(:heading){
|
6
|
+
Heading.new([Attribute.new(:a, anyType)])
|
7
|
+
}
|
8
|
+
|
9
|
+
let(:tuple_type) {
|
10
|
+
TupleType.new(heading)
|
11
|
+
}
|
12
|
+
|
13
|
+
it 'works as expected' do
|
14
|
+
expect(tuple_type.to_json_schema).to eql({
|
15
|
+
type: "object",
|
16
|
+
properties: {
|
17
|
+
a: {}
|
18
|
+
},
|
19
|
+
required: [:a],
|
20
|
+
additionalProperties: false
|
21
|
+
})
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Heading extra are properly resolved" do
|
4
|
+
|
5
|
+
describe "When the extra map to a type" do
|
6
|
+
let(:schema){
|
7
|
+
Finitio.system <<~F
|
8
|
+
Type = { ... : World }
|
9
|
+
World = .String
|
10
|
+
Type
|
11
|
+
F
|
12
|
+
}
|
13
|
+
|
14
|
+
it 'works' do
|
15
|
+
expect(schema.dress("hello" => "World")).to eql(hello: "World")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "When the extra maps to nothing" do
|
20
|
+
let(:schema){
|
21
|
+
Finitio.system <<~F
|
22
|
+
{
|
23
|
+
hello: .String
|
24
|
+
...
|
25
|
+
}
|
26
|
+
F
|
27
|
+
}
|
28
|
+
|
29
|
+
it 'works' do
|
30
|
+
expect(schema.dress("hello" => "World")).to eql(hello: "World")
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'supports extra' do
|
34
|
+
expect(schema.dress({
|
35
|
+
"hello" => "World",
|
36
|
+
"extra" => "Foo"
|
37
|
+
})).to eql(hello: "World")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,6 +2,8 @@ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
|
2
2
|
require 'path'
|
3
3
|
require 'finitio'
|
4
4
|
require 'finitio/syntax'
|
5
|
+
require 'finitio/generation'
|
6
|
+
require 'finitio/json_schema'
|
5
7
|
|
6
8
|
require 'coveralls'
|
7
9
|
Coveralls.wear!
|
@@ -49,15 +51,27 @@ module SpecHelpers
|
|
49
51
|
end
|
50
52
|
|
51
53
|
def intType
|
52
|
-
Finitio::BuiltinType.new(Integer, "intType")
|
54
|
+
@intType ||= Finitio::BuiltinType.new(Integer, "intType")
|
53
55
|
end
|
54
56
|
|
55
57
|
def floatType
|
56
|
-
Finitio::BuiltinType.new(Float, "floatType")
|
58
|
+
@floatType ||= Finitio::BuiltinType.new(Float, "floatType")
|
57
59
|
end
|
58
60
|
|
59
61
|
def nilType
|
60
|
-
Finitio::BuiltinType.new(NilClass, "nilType")
|
62
|
+
@nilType ||= Finitio::BuiltinType.new(NilClass, "nilType")
|
63
|
+
end
|
64
|
+
|
65
|
+
def trueType
|
66
|
+
@trueType ||= Finitio::BuiltinType.new(TrueClass, "trueType")
|
67
|
+
end
|
68
|
+
|
69
|
+
def falseType
|
70
|
+
@falseType ||= Finitio::BuiltinType.new(FalseClass, "falseType")
|
71
|
+
end
|
72
|
+
|
73
|
+
def stringType
|
74
|
+
@stringType ||= Finitio::BuiltinType.new(String, "stringType")
|
61
75
|
end
|
62
76
|
|
63
77
|
def byte_full
|
@@ -81,15 +95,19 @@ module SpecHelpers
|
|
81
95
|
end
|
82
96
|
|
83
97
|
def byte
|
84
|
-
Finitio::SubType.new(intType, [byte_full])
|
98
|
+
@byte ||= Finitio::SubType.new(intType, [byte_full])
|
99
|
+
end
|
100
|
+
|
101
|
+
def pos_byte
|
102
|
+
@pos_byte ||= Finitio::SubType.new(byte, [positive])
|
85
103
|
end
|
86
104
|
|
87
105
|
def posInt
|
88
|
-
Finitio::SubType.new(intType, [positive])
|
106
|
+
@posInt ||= Finitio::SubType.new(intType, [positive])
|
89
107
|
end
|
90
108
|
|
91
109
|
def negInt
|
92
|
-
Finitio::SubType.new(intType, [negative])
|
110
|
+
@negInt ||= Finitio::SubType.new(intType, [negative])
|
93
111
|
end
|
94
112
|
|
95
113
|
def type_factory
|
@@ -104,6 +122,14 @@ module SpecHelpers
|
|
104
122
|
Color.new(138, 43, 226)
|
105
123
|
end
|
106
124
|
|
125
|
+
def rgb_contract
|
126
|
+
@rgb_contract ||= Finitio::Contract.new(byte, Color.method(:rgb), Finitio::IDENTITY, :rgb)
|
127
|
+
end
|
128
|
+
|
129
|
+
def hex_contract
|
130
|
+
@hex_contract ||= Finitio::Contract.new(stringType, Color.method(:hex), Finitio::IDENTITY, :hex)
|
131
|
+
end
|
132
|
+
|
107
133
|
end
|
108
134
|
|
109
135
|
RSpec.configure do |c|
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Finitio
|
3
|
+
describe Support, "compare_attrs" do
|
4
|
+
include Support
|
5
|
+
|
6
|
+
context 'with arrays' do
|
7
|
+
it 'works on same attrs' do
|
8
|
+
h1 = [:a, :b]
|
9
|
+
h2 = [:b, :a]
|
10
|
+
shared, mine, yours = compare_attrs(h1, h2)
|
11
|
+
expect(shared).to eql([:a, :b])
|
12
|
+
expect(mine).to eql([])
|
13
|
+
expect(yours).to eql([])
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'works on not same attrs' do
|
17
|
+
h1 = [ :a, :b ]
|
18
|
+
h2 = [ :c, :a ]
|
19
|
+
shared, mine, yours = compare_attrs(h1, h2)
|
20
|
+
expect(shared).to eql([:a])
|
21
|
+
expect(mine).to eql([:b])
|
22
|
+
expect(yours).to eql([:c])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with hashes' do
|
27
|
+
it 'works on same attrs' do
|
28
|
+
h1 = { a: 1, b: 2 }
|
29
|
+
h2 = { a: 1, b: 2 }
|
30
|
+
shared, mine, yours = compare_attrs(h1, h2)
|
31
|
+
expect(shared).to eql([:a, :b])
|
32
|
+
expect(mine).to eql([])
|
33
|
+
expect(yours).to eql([])
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'works on not same attrs' do
|
37
|
+
h1 = { a: 1, b: 2 }
|
38
|
+
h2 = { a: 1, c: 2 }
|
39
|
+
shared, mine, yours = compare_attrs(h1, h2)
|
40
|
+
expect(shared).to eql([:a])
|
41
|
+
expect(mine).to eql([:b])
|
42
|
+
expect(yours).to eql([:c])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'with a block' do
|
47
|
+
it 'works on same attrs' do
|
48
|
+
h1 = [{:name => :a}, {:name => :b}]
|
49
|
+
h2 = [{:name => :b}, {:name => :a}]
|
50
|
+
shared, mine, yours = compare_attrs(h1, h2){|a| a[:name] }
|
51
|
+
expect(shared).to eql([:a, :b])
|
52
|
+
expect(mine).to eql([])
|
53
|
+
expect(yours).to eql([])
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'works on not same attrs' do
|
57
|
+
h1 = [{:name => :a}, {:name => :b}]
|
58
|
+
h2 = [{:name => :c}, {:name => :a}]
|
59
|
+
shared, mine, yours = compare_attrs(h1, h2){|a| a[:name] }
|
60
|
+
expect(shared).to eql([:a])
|
61
|
+
expect(mine).to eql([:b])
|
62
|
+
expect(yours).to eql([:c])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
data/spec/syntax/test_compile.rb
CHANGED
@@ -37,5 +37,62 @@ module Finitio
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
+
context 'with lots of proxies to resolve' do
|
41
|
+
let(:source){
|
42
|
+
<<-EOF.strip
|
43
|
+
Deep = .String
|
44
|
+
Obj = { i: Deep }
|
45
|
+
Objs = [Obj]
|
46
|
+
EOF
|
47
|
+
}
|
48
|
+
|
49
|
+
it{ should be_a(System) }
|
50
|
+
|
51
|
+
it 'should work fine' do
|
52
|
+
expect {
|
53
|
+
subject['Objs'].dress([{i: "hello"}])
|
54
|
+
}.not_to raise_error
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'with a recursive def' do
|
59
|
+
let(:source){
|
60
|
+
<<-EOF.strip
|
61
|
+
S = .String
|
62
|
+
NodeLabel = S
|
63
|
+
Tree = { label: NodeLabel, children: [Tree] }
|
64
|
+
EOF
|
65
|
+
}
|
66
|
+
|
67
|
+
it{ should be_a(System) }
|
68
|
+
|
69
|
+
it 'should work ine' do
|
70
|
+
expect {
|
71
|
+
subject['Tree'].dress({ label: "Root", children: [
|
72
|
+
{ label: "Child1", children: [] },
|
73
|
+
{ label: "Child2", children: [] }
|
74
|
+
]})
|
75
|
+
}.not_to raise_error
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'with AD types' do
|
80
|
+
let(:source){
|
81
|
+
<<-EOF.strip
|
82
|
+
Colors = [Color]
|
83
|
+
Color = .Color <rgb> { r: Byte, g: Byte, b: Byte }
|
84
|
+
Byte = Int(i | i>0)
|
85
|
+
Int = .Integer
|
86
|
+
EOF
|
87
|
+
}
|
88
|
+
|
89
|
+
it{ should be_a(System) }
|
90
|
+
|
91
|
+
it 'should work ine' do
|
92
|
+
got = subject['Colors'].dress([{ r: 10, g: 15, b: 20 }])
|
93
|
+
expect(got.first).to be_a(Color)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
40
97
|
end
|
41
98
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Finitio
|
3
|
+
describe System, "check_and_warn" do
|
4
|
+
|
5
|
+
before {
|
6
|
+
Finitio.stdlib_path(Path.dir)
|
7
|
+
}
|
8
|
+
|
9
|
+
subject{
|
10
|
+
Finitio.system(Path.dir/"fixtures/with-duplicates.fio").check_and_warn(logger)
|
11
|
+
}
|
12
|
+
|
13
|
+
let(:logger){
|
14
|
+
TestLogger.new
|
15
|
+
}
|
16
|
+
|
17
|
+
it {
|
18
|
+
should be_a(Finitio::System)
|
19
|
+
}
|
20
|
+
|
21
|
+
it 'detects duplicate types as expected' do
|
22
|
+
subject
|
23
|
+
expect(logger.infos).to eql([
|
24
|
+
"Duplicate type def `NilClass`",
|
25
|
+
"Duplicate type def `Posint`"
|
26
|
+
])
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'detects type erasures as expected' do
|
30
|
+
subject
|
31
|
+
expect(logger.warns).to eql([
|
32
|
+
"Type erasure `Negint`",
|
33
|
+
])
|
34
|
+
end
|
35
|
+
|
36
|
+
class TestLogger
|
37
|
+
|
38
|
+
def initialize
|
39
|
+
@warns = []
|
40
|
+
@infos = []
|
41
|
+
end
|
42
|
+
attr_reader :warns, :infos
|
43
|
+
|
44
|
+
def warn(msg)
|
45
|
+
@warns << msg
|
46
|
+
end
|
47
|
+
|
48
|
+
def info(msg)
|
49
|
+
@infos << msg
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -2,16 +2,9 @@ require 'spec_helper'
|
|
2
2
|
module Finitio
|
3
3
|
describe AdType, 'initialize' do
|
4
4
|
|
5
|
-
let(:rgb){
|
6
|
-
Contract.new(intType, Color.method(:rgb), Finitio::IDENTITY, :rgb)
|
7
|
-
}
|
8
|
-
|
9
|
-
let(:hex){
|
10
|
-
Contract.new(floatType, Color.method(:hex), Finitio::IDENTITY, :hex)
|
11
|
-
}
|
12
5
|
|
13
6
|
subject{
|
14
|
-
AdType.new(Color, [
|
7
|
+
AdType.new(Color, [rgb_contract, hex_contract])
|
15
8
|
}
|
16
9
|
|
17
10
|
context 'with valid arguments' do
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Finitio
|
3
|
+
describe RelationType, "suppremum" do
|
4
|
+
|
5
|
+
subject{
|
6
|
+
left.suppremum(right)
|
7
|
+
}
|
8
|
+
|
9
|
+
let(:heading){
|
10
|
+
Heading.new([Attribute.new(:a, intType),
|
11
|
+
Attribute.new(:b, stringType)])
|
12
|
+
}
|
13
|
+
|
14
|
+
let(:left){
|
15
|
+
RelationType.new(heading)
|
16
|
+
}
|
17
|
+
|
18
|
+
context 'when right is not a tuple type' do
|
19
|
+
let(:right){
|
20
|
+
stringType
|
21
|
+
}
|
22
|
+
|
23
|
+
it 'builds a union type' do
|
24
|
+
expect(subject).to be_a(UnionType)
|
25
|
+
expect(subject.candidates).to eql([left, right])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when right is an equal tuple type' do
|
30
|
+
let(:right){
|
31
|
+
RelationType.new(heading)
|
32
|
+
}
|
33
|
+
|
34
|
+
it 'keeps left' do
|
35
|
+
expect(subject).to be(left)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'when right is an non-equal tuple type but compatible with RelationType' do
|
40
|
+
let(:heading2){
|
41
|
+
Heading.new([Attribute.new(:a, nilType),
|
42
|
+
Attribute.new(:b, stringType)])
|
43
|
+
}
|
44
|
+
|
45
|
+
let(:right){
|
46
|
+
RelationType.new(heading2)
|
47
|
+
}
|
48
|
+
|
49
|
+
it 'builds the suppremum as expected' do
|
50
|
+
expect(subject).to be_a(RelationType)
|
51
|
+
expect(subject.heading[:a].type).to eql(UnionType.new [intType,nilType])
|
52
|
+
expect(subject.heading[:b].type).to eql(stringType)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when right is an non-equal tuple type yielding a MultiRelationType' do
|
57
|
+
let(:heading2){
|
58
|
+
Heading.new([Attribute.new(:c, nilType),
|
59
|
+
Attribute.new(:b, stringType)])
|
60
|
+
}
|
61
|
+
|
62
|
+
let(:right){
|
63
|
+
RelationType.new(heading2)
|
64
|
+
}
|
65
|
+
|
66
|
+
it 'builds the suppremum as expected' do
|
67
|
+
expect(subject).to be_a(MultiRelationType)
|
68
|
+
expect(subject.heading[:a].type).to eql(intType)
|
69
|
+
expect(subject.heading[:a].required).to eql(false)
|
70
|
+
expect(subject.heading[:b].type).to eql(stringType)
|
71
|
+
expect(subject.heading[:b].required).to eql(true)
|
72
|
+
expect(subject.heading[:c].type).to eql(nilType)
|
73
|
+
expect(subject.heading[:c].required).to eql(false)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'when right is an non-equal tuple type yielding a MultiRelationType II' do
|
78
|
+
let(:heading2){
|
79
|
+
Heading.new([Attribute.new(:a, nilType, false),
|
80
|
+
Attribute.new(:b, stringType)])
|
81
|
+
}
|
82
|
+
|
83
|
+
let(:right){
|
84
|
+
MultiRelationType.new(heading2)
|
85
|
+
}
|
86
|
+
|
87
|
+
it 'builds the suppremum as expected' do
|
88
|
+
expect(subject).to be_a(MultiRelationType)
|
89
|
+
expect(subject.heading[:a].type).to eql(UnionType.new [intType,nilType])
|
90
|
+
expect(subject.heading[:a].required).to eql(false)
|
91
|
+
expect(subject.heading[:b].type).to eql(stringType)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'works the other way round too' do
|
95
|
+
subject = right.suppremum(left)
|
96
|
+
expect(subject).to be_a(MultiRelationType)
|
97
|
+
expect(subject.heading[:a].type).to eql(UnionType.new [intType,nilType])
|
98
|
+
expect(subject.heading[:a].required).to eql(false)
|
99
|
+
expect(subject.heading[:b].type).to eql(stringType)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|