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.
Files changed (111) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +29 -0
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +40 -41
  5. data/README.md +88 -12
  6. data/lib/finitio.rb +37 -5
  7. data/lib/finitio/generation.rb +106 -0
  8. data/lib/finitio/generation/ad_type.rb +10 -0
  9. data/lib/finitio/generation/alias_type.rb +9 -0
  10. data/lib/finitio/generation/any_type.rb +11 -0
  11. data/lib/finitio/generation/builtin_type.rb +9 -0
  12. data/lib/finitio/generation/hash_based_type.rb +15 -0
  13. data/lib/finitio/generation/heuristic.rb +8 -0
  14. data/lib/finitio/generation/heuristic/constant.rb +30 -0
  15. data/lib/finitio/generation/heuristic/random.rb +52 -0
  16. data/lib/finitio/generation/rel_based_type.rb +13 -0
  17. data/lib/finitio/generation/seq_type.rb +13 -0
  18. data/lib/finitio/generation/set_type.rb +13 -0
  19. data/lib/finitio/generation/sub_type.rb +9 -0
  20. data/lib/finitio/generation/union_type.rb +10 -0
  21. data/lib/finitio/inference.rb +51 -0
  22. data/lib/finitio/json_schema.rb +16 -0
  23. data/lib/finitio/json_schema/ad_type.rb +11 -0
  24. data/lib/finitio/json_schema/alias_type.rb +9 -0
  25. data/lib/finitio/json_schema/any_type.rb +9 -0
  26. data/lib/finitio/json_schema/builtin_type.rb +27 -0
  27. data/lib/finitio/json_schema/hash_based_type.rb +25 -0
  28. data/lib/finitio/json_schema/rel_based_type.rb +13 -0
  29. data/lib/finitio/json_schema/seq_type.rb +12 -0
  30. data/lib/finitio/json_schema/set_type.rb +13 -0
  31. data/lib/finitio/json_schema/struct_type.rb +12 -0
  32. data/lib/finitio/json_schema/sub_type.rb +10 -0
  33. data/lib/finitio/json_schema/union_type.rb +11 -0
  34. data/lib/finitio/support.rb +19 -0
  35. data/lib/finitio/support/attribute.rb +8 -0
  36. data/lib/finitio/support/compilation.rb +18 -18
  37. data/lib/finitio/support/contract.rb +23 -0
  38. data/lib/finitio/support/fetch_scope.rb +19 -0
  39. data/lib/finitio/support/heading.rb +36 -1
  40. data/lib/finitio/support/proc_with_code.rb +34 -0
  41. data/lib/finitio/syntax.rb +1 -1
  42. data/lib/finitio/syntax/import.rb +1 -1
  43. data/lib/finitio/syntax/lexer.citrus +1 -1
  44. data/lib/finitio/syntax/type.rb +2 -0
  45. data/lib/finitio/syntax/type/expression.rb +1 -2
  46. data/lib/finitio/syntax/type/high_order_type_instantiation.rb +29 -0
  47. data/lib/finitio/syntax/type/high_order_vars.rb +16 -0
  48. data/lib/finitio/syntax/type/type_def.rb +11 -1
  49. data/lib/finitio/syntax/types.citrus +14 -1
  50. data/lib/finitio/system.rb +20 -4
  51. data/lib/finitio/type.rb +19 -0
  52. data/lib/finitio/type/ad_type.rb +21 -0
  53. data/lib/finitio/type/alias_type.rb +8 -0
  54. data/lib/finitio/type/any_type.rb +12 -0
  55. data/lib/finitio/type/builtin_type.rb +4 -0
  56. data/lib/finitio/type/collection_type.rb +15 -0
  57. data/lib/finitio/type/heading_based_type.rb +17 -0
  58. data/lib/finitio/type/high_order_type.rb +39 -0
  59. data/lib/finitio/type/multi_relation_type.rb +4 -0
  60. data/lib/finitio/type/multi_tuple_type.rb +4 -0
  61. data/lib/finitio/type/proxy_type.rb +10 -20
  62. data/lib/finitio/type/relation_type.rb +4 -0
  63. data/lib/finitio/type/seq_type.rb +1 -1
  64. data/lib/finitio/type/struct_type.rb +8 -0
  65. data/lib/finitio/type/sub_type.rb +8 -0
  66. data/lib/finitio/type/tuple_type.rb +4 -0
  67. data/lib/finitio/type/union_type.rb +19 -0
  68. data/lib/finitio/version.rb +2 -2
  69. data/spec/finitio/test_stdlib_memoization.rb +22 -0
  70. data/spec/finitio/test_system.rb +0 -8
  71. data/spec/generation/test_generation.rb +169 -0
  72. data/spec/heading/test_looks_similar.rb +45 -0
  73. data/spec/heading/test_suppremum.rb +56 -0
  74. data/spec/inference/test_inference.rb +42 -0
  75. data/spec/json_schema/test_ad_type.rb +20 -0
  76. data/spec/json_schema/test_alias_type.rb +15 -0
  77. data/spec/json_schema/test_any_type.rb +11 -0
  78. data/spec/json_schema/test_builtin_type.rb +51 -0
  79. data/spec/json_schema/test_multi_relation_type.rb +58 -0
  80. data/spec/json_schema/test_multi_tuple_type.rb +50 -0
  81. data/spec/json_schema/test_relation_type.rb +30 -0
  82. data/spec/json_schema/test_seq_type.rb +18 -0
  83. data/spec/json_schema/test_set_type.rb +19 -0
  84. data/spec/json_schema/test_struct_type.rb +18 -0
  85. data/spec/json_schema/test_sub_type.rb +17 -0
  86. data/spec/json_schema/test_tuple_type.rb +26 -0
  87. data/spec/json_schema/test_union_type.rb +17 -0
  88. data/spec/spec_helper.rb +32 -6
  89. data/spec/support/test_compare_attrs.rb +67 -0
  90. data/spec/support/test_proc_with_code.rb +27 -0
  91. data/spec/syntax/nodes/test_ad_type.rb +6 -0
  92. data/spec/syntax/nodes/test_contract.rb +5 -0
  93. data/spec/syntax/nodes/test_expression.rb +5 -0
  94. data/spec/syntax/nodes/test_sub_type.rb +5 -0
  95. data/spec/syntax/test_compile.rb +57 -0
  96. data/spec/system/fixtures/system.fio +2 -0
  97. data/spec/system/fixtures/with-duplicates.fio +6 -0
  98. data/spec/system/test_check_and_warn.rb +55 -0
  99. data/spec/type/ad_type/test_initialize.rb +1 -8
  100. data/spec/type/relation_type/test_suppremum.rb +104 -0
  101. data/spec/type/seq_type/test_suppremum.rb +54 -0
  102. data/spec/type/set_type/test_suppremum.rb +54 -0
  103. data/spec/type/test_suppremum.rb +49 -0
  104. data/spec/type/test_unconstrained.rb +150 -0
  105. data/spec/type/tuple_type/test_suppremum.rb +119 -0
  106. data/spec/type/union_type/test_suppremum.rb +51 -0
  107. data/tasks/test.rake +1 -1
  108. metadata +230 -145
  109. data/spec/finitio/with-duplicates.fio +0 -3
  110. data/spec/type/proxy_type/test_delegation.rb +0 -37
  111. data/spec/type/proxy_type/test_resolve.rb +0 -29
@@ -0,0 +1,17 @@
1
+ module Finitio
2
+ module JsonSchema
3
+ describe "SubType" do
4
+
5
+ let(:type) {
6
+ byte
7
+ }
8
+
9
+ it 'skips constraints (for now)' do
10
+ expect(byte.to_json_schema).to eql({
11
+ type: "integer"
12
+ })
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -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,17 @@
1
+ module Finitio
2
+ module JsonSchema
3
+ describe "UnionType" do
4
+
5
+ let(:union_type) {
6
+ UnionType.new([anyType])
7
+ }
8
+
9
+ it 'works as expected' do
10
+ expect(union_type.to_json_schema).to eql({
11
+ anyOf: [{}]
12
+ })
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -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
@@ -96,6 +96,11 @@ module Finitio
96
96
  ]
97
97
  ])
98
98
  end
99
+
100
+ it 'is equal to itself by code' do
101
+ j = Syntax.parse(input, root: "contract").compile(type_factory, nil)
102
+ expect(j).to eql(compiled)
103
+ end
99
104
  end
100
105
 
101
106
  context 'A contract with external dressers' do
@@ -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
@@ -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,2 @@
1
+ Posint = .Integer( i | i >= 0 )
2
+ Negint = .Integer( i | i < 0 )
@@ -0,0 +1,6 @@
1
+ @import finitio/data
2
+ @import ./system
3
+
4
+ NilClass = .NilClass
5
+ Posint = .Integer( i | i >= 0 )
6
+ Negint = .Integer( i | i <= 0 )
@@ -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, [rgb, hex])
7
+ AdType.new(Color, [rgb_contract, hex_contract])
15
8
  }
16
9
 
17
10
  context 'with valid arguments' do