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,11 @@
|
|
1
|
+
module Finitio
|
2
|
+
class AnyType
|
3
|
+
|
4
|
+
def generate_data(generator, world = nil)
|
5
|
+
candidates = [NilClass, String, Integer, Float]
|
6
|
+
type = generator.flip_one_out_of(candidates)
|
7
|
+
generator.heuristic.call(type, generator, world)
|
8
|
+
end
|
9
|
+
|
10
|
+
end # class AnyType
|
11
|
+
end # module Finitio
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Finitio
|
2
|
+
module HashBasedType
|
3
|
+
|
4
|
+
def generate_data(generator, world = nil)
|
5
|
+
tuple = {}
|
6
|
+
heading.each do |a|
|
7
|
+
if a.required or generator.flip_coin
|
8
|
+
tuple[a.name.to_sym] = generator.call(a.type, world)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
tuple
|
12
|
+
end
|
13
|
+
|
14
|
+
end # class HashBasedType
|
15
|
+
end # module Finitio
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Finitio
|
2
|
+
class Generation
|
3
|
+
class Heuristic
|
4
|
+
class Constant < Heuristic
|
5
|
+
|
6
|
+
CONSTANTS = {
|
7
|
+
NilClass => nil,
|
8
|
+
TrueClass => true,
|
9
|
+
FalseClass => false,
|
10
|
+
Integer => 99,
|
11
|
+
Float => 99.99,
|
12
|
+
String => "Hello world",
|
13
|
+
Date => Date.today,
|
14
|
+
Time => Time.now,
|
15
|
+
DateTime => DateTime.now,
|
16
|
+
}
|
17
|
+
|
18
|
+
def call(ruby_type, generator, world = nil)
|
19
|
+
CONSTANTS.fetch(ruby_type) do
|
20
|
+
CONSTANTS.each_pair do |clazz, value|
|
21
|
+
return value if clazz >= ruby_type
|
22
|
+
end
|
23
|
+
throw :unfound
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end # class Constant
|
28
|
+
end # class Heuristic
|
29
|
+
end # class Generation
|
30
|
+
end # module Finition
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Finitio
|
2
|
+
class Generation
|
3
|
+
class Heuristic
|
4
|
+
class Random < Heuristic
|
5
|
+
|
6
|
+
RANDOMERS = {
|
7
|
+
NilClass => nil,
|
8
|
+
|
9
|
+
TrueClass => true,
|
10
|
+
|
11
|
+
FalseClass => false,
|
12
|
+
|
13
|
+
Integer => ->(_,g,_) {
|
14
|
+
g.flip_one_out_of(1_000_000)
|
15
|
+
},
|
16
|
+
|
17
|
+
Float => ->(_,g,_) {
|
18
|
+
g.flip_one_out_of(1_000_000)
|
19
|
+
},
|
20
|
+
|
21
|
+
String => ->(_,g,_) {
|
22
|
+
(1..3).map{ SecureRandom.hex(6) }.join(" ")
|
23
|
+
},
|
24
|
+
|
25
|
+
Date => ->(_,g,_) {
|
26
|
+
Time.at(rand * Time.now.to_i).to_date
|
27
|
+
},
|
28
|
+
|
29
|
+
Time => ->(_,g,_) {
|
30
|
+
Time.at(rand * Time.now.to_i)
|
31
|
+
},
|
32
|
+
|
33
|
+
DateTime => ->(_,g,_) {
|
34
|
+
Time.at(rand * Time.now.to_i).to_datetime
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
def call(ruby_type, generator, world = nil)
|
39
|
+
r = RANDOMERS.fetch(ruby_type) do
|
40
|
+
pair = RANDOMERS.find do |clazz, value|
|
41
|
+
clazz >= ruby_type
|
42
|
+
end
|
43
|
+
throw :unfound unless pair
|
44
|
+
pair.last
|
45
|
+
end
|
46
|
+
r.is_a?(Proc) ? r.call(ruby_type, generator, world) : r
|
47
|
+
end
|
48
|
+
|
49
|
+
end # class Random
|
50
|
+
end # class Heuristic
|
51
|
+
end # class Generation
|
52
|
+
end # module Finition
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Finitio
|
2
|
+
module RelBasedType
|
3
|
+
|
4
|
+
def generate_data(generator, world = nil)
|
5
|
+
coll = []
|
6
|
+
generator.collection_size.times do
|
7
|
+
coll << generator.call(tuple_type, world)
|
8
|
+
end
|
9
|
+
coll.uniq
|
10
|
+
end
|
11
|
+
|
12
|
+
end # module RelBasedType
|
13
|
+
end # module Finitio
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Finitio
|
2
|
+
class Inference
|
3
|
+
|
4
|
+
def initialize(system, options = {})
|
5
|
+
@system = system
|
6
|
+
@options = options
|
7
|
+
end
|
8
|
+
attr_reader :system
|
9
|
+
|
10
|
+
def call(input)
|
11
|
+
infer_type(input)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def infer_type(value)
|
17
|
+
case value
|
18
|
+
when Hash
|
19
|
+
attrs = value.map{|k,v|
|
20
|
+
Attribute.new(k.to_sym, infer_type(v))
|
21
|
+
}
|
22
|
+
heading = Heading.new(attrs)
|
23
|
+
TupleType.new(heading)
|
24
|
+
when Array
|
25
|
+
infered = value.inject(nil){|sup, value|
|
26
|
+
value_type = infer_type(value)
|
27
|
+
sup.nil? ? value_type : sup.suppremum(value_type)
|
28
|
+
}
|
29
|
+
SeqType.new(infered.nil? ? ANY_TYPE : infered)
|
30
|
+
else
|
31
|
+
found = self.system.types.values.find{|t|
|
32
|
+
try_dress(t, value)
|
33
|
+
}
|
34
|
+
found ? found : ANY_TYPE
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def try_dress(t, value)
|
39
|
+
raise "Type expected, got #{t}" unless t.is_a?(Type)
|
40
|
+
t.dress(value)
|
41
|
+
true
|
42
|
+
rescue Finitio::Error => ex
|
43
|
+
#puts %Q{[#{ex.class}] #{ex.message}}
|
44
|
+
nil
|
45
|
+
rescue => ex
|
46
|
+
puts %Q{[#{ex.class}] #{ex.message}\n#{ex.backtrace.join("\n")}}
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
|
50
|
+
end # class Inference
|
51
|
+
end # module Finitio
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Finitio
|
2
|
+
module JsonSchema
|
3
|
+
class Error < Finitio::Error; end
|
4
|
+
end # module JsonSchema
|
5
|
+
end # module Finitio
|
6
|
+
require_relative 'json_schema/ad_type'
|
7
|
+
require_relative 'json_schema/any_type'
|
8
|
+
require_relative 'json_schema/alias_type'
|
9
|
+
require_relative 'json_schema/builtin_type'
|
10
|
+
require_relative 'json_schema/hash_based_type'
|
11
|
+
require_relative 'json_schema/rel_based_type'
|
12
|
+
require_relative 'json_schema/seq_type'
|
13
|
+
require_relative 'json_schema/set_type'
|
14
|
+
require_relative 'json_schema/struct_type'
|
15
|
+
require_relative 'json_schema/sub_type'
|
16
|
+
require_relative 'json_schema/union_type'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Finitio
|
2
|
+
module JsonSchema
|
3
|
+
|
4
|
+
BUILTIN_MAPPING = {
|
5
|
+
NilClass => "null",
|
6
|
+
String => "string",
|
7
|
+
Integer => "integer",
|
8
|
+
Fixnum => "integer",
|
9
|
+
Bignum => "integer",
|
10
|
+
Float => "number",
|
11
|
+
Numeric => "number"
|
12
|
+
}
|
13
|
+
|
14
|
+
end
|
15
|
+
class BuiltinType
|
16
|
+
|
17
|
+
def to_json_schema(*args, &bl)
|
18
|
+
mapped = JsonSchema::BUILTIN_MAPPING[ruby_type]
|
19
|
+
if mapped
|
20
|
+
{ type: mapped }
|
21
|
+
else
|
22
|
+
raise JsonSchema::Error, "Unable to map #{ruby_type} to json-schema"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end # class BuiltinType
|
27
|
+
end # module Finitio
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Finitio
|
2
|
+
module HashBasedType
|
3
|
+
|
4
|
+
def to_json_schema(*args, &bl)
|
5
|
+
base = {
|
6
|
+
type: "object"
|
7
|
+
}
|
8
|
+
unless heading.empty?
|
9
|
+
base[:properties] = heading.inject({}){|ps,a|
|
10
|
+
ps.merge(a.name => a.type.to_json_schema(*args, &bl))
|
11
|
+
}
|
12
|
+
end
|
13
|
+
unless (reqs = heading.select{|a| a.required? }).empty?
|
14
|
+
base[:required] = reqs.map{|a| a.name }
|
15
|
+
end
|
16
|
+
base[:additionalProperties] = if heading.allow_extra?
|
17
|
+
heading.allow_extra.to_json_schema(*args, &bl)
|
18
|
+
else
|
19
|
+
false
|
20
|
+
end
|
21
|
+
base
|
22
|
+
end
|
23
|
+
|
24
|
+
end # module HashBasedType
|
25
|
+
end # module UnionType
|