finitio 0.7.0.pre.rc2 → 0.9.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 +5 -5
- data/CHANGELOG.md +29 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +40 -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 +19 -0
- data/lib/finitio/support/attribute.rb +8 -0
- data/lib/finitio/support/compilation.rb +18 -18
- data/lib/finitio/support/contract.rb +23 -0
- data/lib/finitio/support/fetch_scope.rb +19 -0
- data/lib/finitio/support/heading.rb +36 -1
- data/lib/finitio/support/proc_with_code.rb +34 -0
- 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/expression.rb +1 -2
- 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 +21 -0
- 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 -8
- 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/spec_helper.rb +32 -6
- data/spec/support/test_compare_attrs.rb +67 -0
- data/spec/support/test_proc_with_code.rb +27 -0
- data/spec/syntax/nodes/test_ad_type.rb +6 -0
- data/spec/syntax/nodes/test_contract.rb +5 -0
- data/spec/syntax/nodes/test_expression.rb +5 -0
- data/spec/syntax/nodes/test_sub_type.rb +5 -0
- data/spec/syntax/test_compile.rb +57 -0
- data/spec/system/fixtures/system.fio +2 -0
- data/spec/system/fixtures/with-duplicates.fio +6 -0
- 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 +230 -145
- data/spec/finitio/with-duplicates.fio +0 -3
- 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
|
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
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Finitio
|
3
|
+
describe ProcWithCode do
|
4
|
+
|
5
|
+
it 'acts like a proc' do
|
6
|
+
p = ProcWithCode.new{|t| t>0 }
|
7
|
+
expect(p).to be_a(Proc)
|
8
|
+
expect(p.call(2)).to eq(true)
|
9
|
+
expect(p.call(-2)).to eq(false)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'lets compile from source code' do
|
13
|
+
p = ProcWithCode.new("t", "t>0")
|
14
|
+
expect(p).to be_a(Proc)
|
15
|
+
expect(p.call(2)).to eq(true)
|
16
|
+
expect(p.call(-2)).to eq(false)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'yields equal procs for same source code' do
|
20
|
+
p1 = ProcWithCode.new("t", "t>0")
|
21
|
+
p2 = ProcWithCode.new("t", "t>0")
|
22
|
+
expect(p1).to eql(p2)
|
23
|
+
expect(p1.hash).to eql(p2.hash)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -43,6 +43,7 @@ module Finitio
|
|
43
43
|
]
|
44
44
|
])
|
45
45
|
end
|
46
|
+
|
46
47
|
end
|
47
48
|
|
48
49
|
context 'Two contracts' do
|
@@ -160,6 +161,11 @@ module Finitio
|
|
160
161
|
]
|
161
162
|
])
|
162
163
|
end
|
164
|
+
|
165
|
+
it 'is equal to itself' do
|
166
|
+
j = Syntax.parse(input, root: "ad_type").compile(type_factory)
|
167
|
+
expect(j).to eql(compiled)
|
168
|
+
end
|
163
169
|
end
|
164
170
|
|
165
171
|
end
|
@@ -21,6 +21,11 @@ module Finitio
|
|
21
21
|
expect(compiled.call(12)).to eq(true)
|
22
22
|
expect(compiled.call(9)).to eq(false)
|
23
23
|
end
|
24
|
+
|
25
|
+
it 'is equal to itself' do
|
26
|
+
j = Syntax.parse(input, root: "expression").compile("a")
|
27
|
+
expect(j).to eq(compiled)
|
28
|
+
end
|
24
29
|
end
|
25
30
|
|
26
31
|
context '(a >= 10)' do
|
@@ -30,6 +30,11 @@ module Finitio
|
|
30
30
|
[:constraint, "default", [:fn, [:parameters, "i"], [:source, "i >= 0"]]]
|
31
31
|
])
|
32
32
|
end
|
33
|
+
|
34
|
+
it 'is equal to the same type' do
|
35
|
+
j = Syntax.parse(input, root: "sub_type").compile(type_factory)
|
36
|
+
expect(j).to eq(compiled)
|
37
|
+
end
|
33
38
|
end
|
34
39
|
|
35
40
|
context '.Integer( i | positive: i >= 0 )' do
|
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
|