finitio 0.8.0 → 0.11.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.
Files changed (40) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +28 -0
  3. data/Gemfile +0 -10
  4. data/Gemfile.lock +84 -37
  5. data/README.md +1 -2
  6. data/finitio.gemspec +9 -157
  7. data/lib/finitio/json_schema/ad_type.rb +11 -0
  8. data/lib/finitio/json_schema/alias_type.rb +9 -0
  9. data/lib/finitio/json_schema/any_type.rb +9 -0
  10. data/lib/finitio/json_schema/builtin_type.rb +30 -0
  11. data/lib/finitio/json_schema/hash_based_type.rb +25 -0
  12. data/lib/finitio/json_schema/proxy_type.rb +9 -0
  13. data/lib/finitio/json_schema/rel_based_type.rb +13 -0
  14. data/lib/finitio/json_schema/seq_type.rb +12 -0
  15. data/lib/finitio/json_schema/set_type.rb +13 -0
  16. data/lib/finitio/json_schema/struct_type.rb +12 -0
  17. data/lib/finitio/json_schema/sub_type.rb +10 -0
  18. data/lib/finitio/json_schema/union_type.rb +23 -0
  19. data/lib/finitio/json_schema.rb +17 -0
  20. data/lib/finitio/support/heading.rb +8 -2
  21. data/lib/finitio/syntax/lexer.citrus +1 -1
  22. data/lib/finitio/version.rb +2 -2
  23. data/spec/inference/test_inference.rb +8 -8
  24. data/spec/json_schema/test_ad_type.rb +20 -0
  25. data/spec/json_schema/test_alias_type.rb +15 -0
  26. data/spec/json_schema/test_any_type.rb +11 -0
  27. data/spec/json_schema/test_builtin_type.rb +51 -0
  28. data/spec/json_schema/test_multi_relation_type.rb +58 -0
  29. data/spec/json_schema/test_multi_tuple_type.rb +50 -0
  30. data/spec/json_schema/test_relation_type.rb +30 -0
  31. data/spec/json_schema/test_seq_type.rb +18 -0
  32. data/spec/json_schema/test_set_type.rb +19 -0
  33. data/spec/json_schema/test_struct_type.rb +18 -0
  34. data/spec/json_schema/test_sub_type.rb +17 -0
  35. data/spec/json_schema/test_tuple_type.rb +26 -0
  36. data/spec/json_schema/test_union_type.rb +75 -0
  37. data/spec/regression/test_heading_extra_are_proxy_resolved.rb +41 -0
  38. data/spec/spec_helper.rb +2 -1
  39. data/spec/syntax/nodes/test_attribute.rb +13 -1
  40. metadata +301 -156
@@ -4,15 +4,15 @@ module Finitio
4
4
  describe Inference do
5
5
 
6
6
  let(:system) {
7
- Finitio.system <<-FIO
8
- @import finitio/data
7
+ Finitio.system <<~FIO
8
+ @import finitio/data
9
9
 
10
- Nil = .NilClass
11
- Boolean = .TrueClass|.FalseClass
12
- Integer = .Integer
13
- Date = .Date <iso8601> .String \\( s | Date.iso8601(s) )
14
- \\( d | d.iso8601 )
15
- String = .String
10
+ Nil = .NilClass
11
+ Boolean = .TrueClass|.FalseClass
12
+ Integer = .Integer
13
+ Date = .Date <iso8601> .String \\( s | Date.iso8601(s) )
14
+ \\( d | d.iso8601 )
15
+ String = .String
16
16
  FIO
17
17
  }
18
18
 
@@ -0,0 +1,20 @@
1
+ module Finitio
2
+ module JsonSchema
3
+ describe "AdType" do
4
+
5
+ let(:type) {
6
+ type = AdType.new(Color, [rgb_contract, hex_contract])
7
+ }
8
+
9
+ it 'works as expected' do
10
+ expect(type.to_json_schema).to eql({
11
+ anyOf: [
12
+ { type: "integer" },
13
+ { type: "string" }
14
+ ]
15
+ })
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ module Finitio
2
+ module JsonSchema
3
+ describe "AliasType" do
4
+
5
+ let(:alias_type) {
6
+ AliasType.new(anyType, "X")
7
+ }
8
+
9
+ it 'works as expected' do
10
+ expect(alias_type.to_json_schema).to eql({})
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ module Finitio
2
+ module JsonSchema
3
+ describe "AnyType" do
4
+
5
+ it 'works as expected' do
6
+ expect(anyType.to_json_schema).to eql({})
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,51 @@
1
+ module Finitio
2
+ module JsonSchema
3
+ describe "BuiltinType" do
4
+
5
+ let(:builtin_type) {
6
+ BuiltinType.new(ruby_type)
7
+ }
8
+
9
+ subject {
10
+ builtin_type.to_json_schema
11
+ }
12
+
13
+ context 'with NilClass' do
14
+ let(:ruby_type){ NilClass }
15
+
16
+ it 'works' do
17
+ expect(subject).to eql({ type: "null" })
18
+ end
19
+ end
20
+
21
+ context 'with String' do
22
+ let(:ruby_type){ String }
23
+
24
+ it 'works' do
25
+ expect(subject).to eql({ type: "string" })
26
+ end
27
+ end
28
+
29
+ [Fixnum, Bignum, Integer].each do |rt|
30
+ context "with #{rt}" do
31
+ let(:ruby_type){ rt }
32
+
33
+ it 'works' do
34
+ expect(subject).to eql({ type: "integer" })
35
+ end
36
+ end
37
+ end
38
+
39
+ [Float, Numeric].each do |rt|
40
+ context "with #{rt}" do
41
+ let(:ruby_type){ rt }
42
+
43
+ it 'works' do
44
+ expect(subject).to eql({ type: "number" })
45
+ end
46
+ end
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,58 @@
1
+ module Finitio
2
+ module JsonSchema
3
+ describe "MultiRelationType" do
4
+
5
+ context 'with a true allow extra and some optional attribute' do
6
+ let(:heading){
7
+ Heading.new([
8
+ Attribute.new(:a, anyType),
9
+ Attribute.new(:b, anyType, false),
10
+ ], allow_extra: true)
11
+ }
12
+
13
+ let(:multi_relation_type) {
14
+ MultiRelationType.new(heading)
15
+ }
16
+
17
+ it 'works as expected' do
18
+ expect(multi_relation_type.to_json_schema).to eql({
19
+ type: "array",
20
+ items: {
21
+ type: "object",
22
+ properties: {
23
+ a: {},
24
+ b: {}
25
+ },
26
+ required: [:a],
27
+ additionalProperties: {}
28
+ },
29
+ uniqueItems: true
30
+ })
31
+ end
32
+ end
33
+
34
+ context 'with a allow extra requiring Strings' do
35
+ let(:heading){
36
+ Heading.new([
37
+ ], allow_extra: BuiltinType.new(String))
38
+ }
39
+
40
+ let(:multi_relation_type) {
41
+ MultiRelationType.new(heading)
42
+ }
43
+
44
+ it 'works as expected' do
45
+ expect(multi_relation_type.to_json_schema).to eql({
46
+ type: "array",
47
+ items: {
48
+ type: "object",
49
+ additionalProperties: { type: "string" }
50
+ },
51
+ uniqueItems: true
52
+ })
53
+ end
54
+ end
55
+
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,50 @@
1
+ module Finitio
2
+ module JsonSchema
3
+ describe "MultiTupleType" do
4
+
5
+ context 'with a true allow extra and some optional attribute' do
6
+ let(:heading){
7
+ Heading.new([
8
+ Attribute.new(:a, anyType),
9
+ Attribute.new(:b, anyType, false),
10
+ ], allow_extra: true)
11
+ }
12
+
13
+ let(:multi_tuple_type) {
14
+ MultiTupleType.new(heading)
15
+ }
16
+
17
+ it 'works as expected' do
18
+ expect(multi_tuple_type.to_json_schema).to eql({
19
+ type: "object",
20
+ properties: {
21
+ a: {},
22
+ b: {}
23
+ },
24
+ required: [:a],
25
+ additionalProperties: {}
26
+ })
27
+ end
28
+ end
29
+
30
+ context 'with a allow extra requiring Strings' do
31
+ let(:heading){
32
+ Heading.new([
33
+ ], allow_extra: BuiltinType.new(String))
34
+ }
35
+
36
+ let(:multi_tuple_type) {
37
+ MultiTupleType.new(heading)
38
+ }
39
+
40
+ it 'works as expected' do
41
+ expect(multi_tuple_type.to_json_schema).to eql({
42
+ type: "object",
43
+ additionalProperties: { type: "string" }
44
+ })
45
+ end
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,30 @@
1
+ module Finitio
2
+ module JsonSchema
3
+ describe "RelationType" do
4
+
5
+ let(:heading){
6
+ Heading.new([Attribute.new(:a, anyType)])
7
+ }
8
+
9
+ let(:tuple_type) {
10
+ RelationType.new(heading)
11
+ }
12
+
13
+ it 'works as expected' do
14
+ expect(tuple_type.to_json_schema).to eql({
15
+ type: "array",
16
+ items: {
17
+ type: "object",
18
+ properties: {
19
+ a: {}
20
+ },
21
+ required: [:a],
22
+ additionalProperties: false
23
+ },
24
+ uniqueItems: true
25
+ })
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,18 @@
1
+ module Finitio
2
+ module JsonSchema
3
+ describe "SeqType" do
4
+
5
+ let(:type) {
6
+ SeqType.new(anyType)
7
+ }
8
+
9
+ it 'works as expected' do
10
+ expect(type.to_json_schema).to eql({
11
+ type: "array",
12
+ items: {}
13
+ })
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ module Finitio
2
+ module JsonSchema
3
+ describe "SetType" do
4
+
5
+ let(:type) {
6
+ SetType.new(anyType)
7
+ }
8
+
9
+ it 'works as expected' do
10
+ expect(type.to_json_schema).to eql({
11
+ type: "array",
12
+ items: {},
13
+ uniqueItems: true
14
+ })
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ module Finitio
2
+ module JsonSchema
3
+ describe "StructType" do
4
+
5
+ let(:type) {
6
+ StructType.new([anyType,anyType])
7
+ }
8
+
9
+ it 'works as expected' do
10
+ expect(type.to_json_schema).to eql({
11
+ type: "array",
12
+ items: [{},{}]
13
+ })
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -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,75 @@
1
+ module Finitio
2
+ module JsonSchema
3
+ describe "UnionType" do
4
+
5
+ let(:string_type) {
6
+ BuiltinType.new(String)
7
+ }
8
+
9
+ let(:int_type) {
10
+ BuiltinType.new(Integer)
11
+ }
12
+
13
+ let(:true_type) {
14
+ BuiltinType.new(TrueClass)
15
+ }
16
+
17
+ let(:false_type) {
18
+ BuiltinType.new(FalseClass)
19
+ }
20
+
21
+ let(:nil_type) {
22
+ BuiltinType.new(NilClass)
23
+ }
24
+
25
+ context 'when used with a single type' do
26
+ let(:union_type) {
27
+ UnionType.new([string_type])
28
+ }
29
+
30
+ it 'works as expected' do
31
+ expect(union_type.to_json_schema).to eql({
32
+ :type => "string"
33
+ })
34
+ end
35
+ end
36
+
37
+ context 'when used with two types' do
38
+ let(:union_type) {
39
+ UnionType.new([string_type, int_type])
40
+ }
41
+
42
+ it 'works as expected' do
43
+ expect(union_type.to_json_schema).to eql({
44
+ anyOf: [{:type => "string"}, {:type => "integer"}]
45
+ })
46
+ end
47
+ end
48
+
49
+ context 'when used with a |Nil' do
50
+ let(:union_type) {
51
+ UnionType.new([string_type, int_type, nil_type])
52
+ }
53
+
54
+ it 'works as expected' do
55
+ expect(union_type.to_json_schema).to eql({
56
+ anyOf: [{:type => "string"}, {:type => "integer"}]
57
+ })
58
+ end
59
+ end
60
+
61
+ context 'when used with a TrueClass|FalseClass' do
62
+ let(:union_type) {
63
+ UnionType.new([true_type, false_type])
64
+ }
65
+
66
+ it 'works as expected' do
67
+ expect(union_type.to_json_schema).to eql({
68
+ :type => "boolean"
69
+ })
70
+ end
71
+ end
72
+
73
+ end
74
+ end
75
+ 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
@@ -3,6 +3,7 @@ require 'path'
3
3
  require 'finitio'
4
4
  require 'finitio/syntax'
5
5
  require 'finitio/generation'
6
+ require 'finitio/json_schema'
6
7
 
7
8
  require 'coveralls'
8
9
  Coveralls.wear!
@@ -126,7 +127,7 @@ module SpecHelpers
126
127
  end
127
128
 
128
129
  def hex_contract
129
- @hex_contract ||= Finitio::Contract.new(floatType, Color.method(:hex), Finitio::IDENTITY, :hex)
130
+ @hex_contract ||= Finitio::Contract.new(stringType, Color.method(:hex), Finitio::IDENTITY, :hex)
130
131
  end
131
132
 
132
133
  end
@@ -34,6 +34,18 @@ module Finitio
34
34
  expect(compiled).not_to be_required
35
35
  end
36
36
  end
37
+
38
+ context 'when using dashes in attribute name' do
39
+ let(:input){ 'created-at : .Integer' }
40
+
41
+ it 'works' do
42
+ expect(compiled).to be_a(Attribute)
43
+ expect(compiled.name).to eq(:"created-at")
44
+ expect(compiled.type).to be_a(BuiltinType)
45
+ expect(compiled.type.ruby_type).to be(Integer)
46
+ expect(compiled).to be_required
47
+ end
48
+ end
37
49
  end
38
50
 
39
51
  describe 'AST' do
@@ -60,6 +72,6 @@ module Finitio
60
72
  end
61
73
 
62
74
  end
63
-
75
+
64
76
  end
65
77
  end