finitio 0.7.0 → 0.8.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 +10 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +40 -41
- 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/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 +8 -0
- data/lib/finitio/support/fetch_scope.rb +19 -0
- data/lib/finitio/support/heading.rb +36 -1
- data/lib/finitio/syntax.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 +11 -1
- data/lib/finitio/type.rb +19 -0
- data/lib/finitio/type/ad_type.rb +8 -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 +1 -1
- 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/spec_helper.rb +31 -6
- data/spec/support/test_compare_attrs.rb +67 -0
- data/spec/syntax/test_compile.rb +57 -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 +183 -144
- data/spec/type/proxy_type/test_delegation.rb +0 -37
- data/spec/type/proxy_type/test_resolve.rb +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 467a7c5d8dd70fe9b5de2154217a5594182150d6e9c9996ec85c861980c02ecc
|
4
|
+
data.tar.gz: cadb1b56c039b7a88456f803733d9c0da9f7d879393674de0fc067c2fb71679b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4606b1f8de1df5a7712f8c6546252683928066a18e5e2ed91a96af2e68be552f66e3ccea26d8b6760e9ac5c073fffa416f06ae0ca8001bbac5ca4f2532469f1e
|
7
|
+
data.tar.gz: 1d9436c52479abab152422d471b559724e72ea7d933ec8538cf2877e1fa14bebccfc6219dcf662c76758d167653cf47fe10b0332ee2cc118b6e18229826d5eed
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
# 0.8.0 - 2019/10/21
|
2
|
+
|
3
|
+
* Add `Type#unconstrained` that returns a super type with all user specific
|
4
|
+
constraints removed on sub types, recursively on all non scalar types.
|
5
|
+
|
6
|
+
* Add high-order types, such as `Collection<T> = [T]`
|
7
|
+
|
8
|
+
* Add support for random data generation through `Finitio::Generation`.
|
9
|
+
Please `require 'finitio/generation'` to use it.
|
10
|
+
|
1
11
|
# 0.7.0 / 2019-02-28
|
2
12
|
|
3
13
|
* Implement (basic) @import feature, working with relative paths
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,59 +1,58 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
finitio (0.
|
4
|
+
finitio (0.8.0)
|
5
5
|
citrus (>= 2.4, < 4.0)
|
6
6
|
|
7
7
|
GEM
|
8
|
-
remote:
|
8
|
+
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
awesome_print (1.
|
11
|
-
builder (3.2.
|
10
|
+
awesome_print (1.8.0)
|
11
|
+
builder (3.2.3)
|
12
12
|
citrus (3.0.2)
|
13
|
-
coveralls (0.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
cucumber (1.3.
|
13
|
+
coveralls (0.8.23)
|
14
|
+
json (>= 1.8, < 3)
|
15
|
+
simplecov (~> 0.16.1)
|
16
|
+
term-ansicolor (~> 1.3)
|
17
|
+
thor (>= 0.19.4, < 2.0)
|
18
|
+
tins (~> 1.6)
|
19
|
+
cucumber (1.3.20)
|
20
20
|
builder (>= 2.1.2)
|
21
21
|
diff-lcs (>= 1.1.3)
|
22
22
|
gherkin (~> 2.12)
|
23
23
|
multi_json (>= 1.7.5, < 2.0)
|
24
|
-
multi_test (>= 0.1.
|
25
|
-
diff-lcs (1.
|
26
|
-
docile (1.1
|
24
|
+
multi_test (>= 0.1.2)
|
25
|
+
diff-lcs (1.3)
|
26
|
+
docile (1.3.1)
|
27
27
|
gherkin (2.12.2)
|
28
28
|
multi_json (~> 1.3)
|
29
|
-
|
30
|
-
multi_json (1.
|
31
|
-
multi_test (0.1.
|
29
|
+
json (2.2.0)
|
30
|
+
multi_json (1.13.1)
|
31
|
+
multi_test (0.1.2)
|
32
32
|
path (1.3.3)
|
33
|
-
rake (10.
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
rspec-
|
38
|
-
|
39
|
-
rspec-
|
40
|
-
rspec-
|
41
|
-
|
42
|
-
|
33
|
+
rake (10.5.0)
|
34
|
+
rspec (3.8.0)
|
35
|
+
rspec-core (~> 3.8.0)
|
36
|
+
rspec-expectations (~> 3.8.0)
|
37
|
+
rspec-mocks (~> 3.8.0)
|
38
|
+
rspec-core (3.8.0)
|
39
|
+
rspec-support (~> 3.8.0)
|
40
|
+
rspec-expectations (3.8.3)
|
41
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
42
|
+
rspec-support (~> 3.8.0)
|
43
|
+
rspec-mocks (3.8.0)
|
43
44
|
diff-lcs (>= 1.2.0, < 2.0)
|
44
|
-
rspec-support (~> 3.
|
45
|
-
rspec-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
thor (0.18.1)
|
56
|
-
tins (0.13.2)
|
45
|
+
rspec-support (~> 3.8.0)
|
46
|
+
rspec-support (3.8.0)
|
47
|
+
simplecov (0.16.1)
|
48
|
+
docile (~> 1.1)
|
49
|
+
json (>= 1.8, < 3)
|
50
|
+
simplecov-html (~> 0.10.0)
|
51
|
+
simplecov-html (0.10.2)
|
52
|
+
term-ansicolor (1.7.1)
|
53
|
+
tins (~> 1.0)
|
54
|
+
thor (0.20.3)
|
55
|
+
tins (1.20.2)
|
57
56
|
|
58
57
|
PLATFORMS
|
59
58
|
ruby
|
@@ -68,4 +67,4 @@ DEPENDENCIES
|
|
68
67
|
rspec (~> 3.0)
|
69
68
|
|
70
69
|
BUNDLED WITH
|
71
|
-
|
70
|
+
2.0.1
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
require_relative 'generation/heuristic'
|
3
|
+
module Finitio
|
4
|
+
#
|
5
|
+
# This class helps generating random data for a given Finitio type.
|
6
|
+
#
|
7
|
+
# Example
|
8
|
+
#
|
9
|
+
# type = Finitio.system(<<-FIO)
|
10
|
+
# .Integer
|
11
|
+
# FIO
|
12
|
+
# gen = Finitio::Generation.new
|
13
|
+
# gen.call(type)
|
14
|
+
#
|
15
|
+
# Random data is generated for most ruby builtin types, tuples and all sorts
|
16
|
+
# of collections (seq, set, relations).
|
17
|
+
#
|
18
|
+
# You can fine-tune the random data generation through the following means
|
19
|
+
# (the first one wins):
|
20
|
+
#
|
21
|
+
# * By passing generators by type name at construction:
|
22
|
+
#
|
23
|
+
# Finition::Generation.new({
|
24
|
+
# generators: {
|
25
|
+
# "Name" => ->(type, g, world) { "Bernard" }
|
26
|
+
# }
|
27
|
+
# })
|
28
|
+
#
|
29
|
+
# * Through `examples` metadata put on type definitions:
|
30
|
+
#
|
31
|
+
# /- examples: {"Bernard"} -/
|
32
|
+
# Name = .String
|
33
|
+
#
|
34
|
+
class Generation
|
35
|
+
|
36
|
+
DEFAULT_OPTIONS = {
|
37
|
+
|
38
|
+
heuristic: Heuristic::Random.new,
|
39
|
+
|
40
|
+
collection_size: 1..10,
|
41
|
+
|
42
|
+
generators: {
|
43
|
+
"Date" => ->(t,g,w) { g.heuristic.call(Date, g, w) },
|
44
|
+
"Time" => ->(t,g,w) { g.heuristic.call(Time, g, w) },
|
45
|
+
"DateTime" => ->(t,g,w) { g.heuristic.call(DateTime, g, w) }
|
46
|
+
}
|
47
|
+
|
48
|
+
}
|
49
|
+
|
50
|
+
def initialize(options = {})
|
51
|
+
@options = DEFAULT_OPTIONS.merge(options){|k,v1,v2|
|
52
|
+
v1.is_a?(Hash) ? v1.merge(v2) : v2
|
53
|
+
}
|
54
|
+
end
|
55
|
+
attr_reader :options
|
56
|
+
|
57
|
+
def heuristic
|
58
|
+
options[:heuristic]
|
59
|
+
end
|
60
|
+
|
61
|
+
def generators
|
62
|
+
options[:generators]
|
63
|
+
end
|
64
|
+
|
65
|
+
def flip_coin
|
66
|
+
flip_one_out_of(2) == 1
|
67
|
+
end
|
68
|
+
|
69
|
+
def flip_one_out_of(n)
|
70
|
+
case n
|
71
|
+
when Integer then Kernel.rand(n)
|
72
|
+
when Range then Kernel.rand(n)
|
73
|
+
when Enumerable then n[flip_one_out_of(n.size)]
|
74
|
+
else
|
75
|
+
raise "Cannot flip one on #{n}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def collection_size
|
80
|
+
size = options[:collection_size]
|
81
|
+
size = size.is_a?(Proc) ? size.call : size
|
82
|
+
flip_one_out_of(size)
|
83
|
+
end
|
84
|
+
|
85
|
+
def call(type, world = nil)
|
86
|
+
if gen = generators[type.name]
|
87
|
+
gen.call(type, self, world)
|
88
|
+
elsif exs = type.metadata && type.metadata[:examples]
|
89
|
+
flip_one_out_of(exs)
|
90
|
+
else
|
91
|
+
type.generate_data(self, world)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end # class Generation
|
96
|
+
end # module Finitio
|
97
|
+
require_relative 'generation/any_type'
|
98
|
+
require_relative 'generation/builtin_type'
|
99
|
+
require_relative 'generation/seq_type'
|
100
|
+
require_relative 'generation/set_type'
|
101
|
+
require_relative 'generation/hash_based_type'
|
102
|
+
require_relative 'generation/rel_based_type'
|
103
|
+
require_relative 'generation/union_type'
|
104
|
+
require_relative 'generation/alias_type'
|
105
|
+
require_relative 'generation/sub_type'
|
106
|
+
require_relative 'generation/ad_type'
|
@@ -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
|