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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 4b4c180986cc7160e2b3f76c23e37d23237cbaaf
4
- data.tar.gz: b26dd47b86792ad28524e5e8f8df0ab5d56d0071
2
+ SHA256:
3
+ metadata.gz: fb6a6dde74e450b0569a6f568d2f6e847a6f646b23cd815a3442e1a85dbdaedf
4
+ data.tar.gz: 26fd2339057cc212d2594d2d52ab66b5ae1ad6dc7db0294faa941f148406ac4a
5
5
  SHA512:
6
- metadata.gz: b19ef54ca53c5e463aa6b4557d0ecd6ea537e6cdaa9349f960356b1b31525908be7d1a196cc2be9ab4985f70eea4133d2c54c03d3ee57b14cf48175efe7aaf02
7
- data.tar.gz: 14d1db5a7285d522ce1ab093a5dc712f52b0c846b84e582e86fedbdfbd1320e6eafa7741b907f553aabdb29094bc7ebecf0b1a54a6358cc2ac9b761ae2289238
6
+ metadata.gz: f2e4bc1270b3169f3a9692473525693c90e5771c42fc01e3fdce89da676b1e6867d977fb9f29cc2603adcbdc15920dec9dde6133ccd96f50638e12614cf22eed
7
+ data.tar.gz: acd957a3ea361e715a17d27bb25baef4687f2ed6252a1289a8e4c660e8151c4ad2813488d9a8fbccda189903b95be5da99983b0f0a922e3590f316dd656c7371
@@ -1,3 +1,32 @@
1
+ # 0.9.0 - 2020/12/16
2
+
3
+ * Add Type#to_json_schema that converts Finitio types to JSON schema
4
+ representations. This first implementation skips all constraints on sub types,
5
+ though. You need to explicitly require 'finitio/json_schema' to use it.
6
+
7
+ # 0.8.0 - 2019/10/21
8
+
9
+ * Add `Type#unconstrained` that returns a super type with all user specific
10
+ constraints removed on sub types, recursively on all non scalar types.
11
+
12
+ * Add high-order types, such as `Collection<T> = [T]`
13
+
14
+ * Add support for random data generation through `Finitio::Generation`.
15
+ Please `require 'finitio/generation'` to use it.
16
+
17
+ # 0.7.0 / 2019-02-28
18
+
19
+ * Implement (basic) @import feature, working with relative paths
20
+ and a standard library. The standard library systems are memoized
21
+ to avoid unnecessary parsing and compilation.
22
+
23
+ * `System#check_and_warn` allows discovering warnings, infos and
24
+ errors in system definitions, such as duplicate type definitions
25
+ and import overrides.
26
+
27
+ * WARN: Finitio::DEFAULT_SYSTEM is deprecated. Use @import
28
+ finitio/data instead.
29
+
1
30
  # 0.6.1 / 2018-03-23
2
31
 
3
32
  * Fix support for typed extra attributes, a KeyError was raised when
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source 'http://rubygems.org'
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
@@ -1,59 +1,58 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- finitio (0.7.0.pre.rc2)
4
+ finitio (0.9.0)
5
5
  citrus (>= 2.4, < 4.0)
6
6
 
7
7
  GEM
8
- remote: http://rubygems.org/
8
+ remote: https://rubygems.org/
9
9
  specs:
10
- awesome_print (1.6.1)
11
- builder (3.2.2)
10
+ awesome_print (1.8.0)
11
+ builder (3.2.3)
12
12
  citrus (3.0.2)
13
- coveralls (0.7.2)
14
- multi_json (~> 1.3)
15
- rest-client (= 1.6.7)
16
- simplecov (>= 0.7)
17
- term-ansicolor (= 1.2.2)
18
- thor (= 0.18.1)
19
- cucumber (1.3.18)
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.1)
25
- diff-lcs (1.2.5)
26
- docile (1.1.5)
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
- mime-types (2.4.3)
30
- multi_json (1.10.1)
31
- multi_test (0.1.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.4.2)
34
- rest-client (1.6.7)
35
- mime-types (>= 1.16)
36
- rspec (3.1.0)
37
- rspec-core (~> 3.1.0)
38
- rspec-expectations (~> 3.1.0)
39
- rspec-mocks (~> 3.1.0)
40
- rspec-core (3.1.7)
41
- rspec-support (~> 3.1.0)
42
- rspec-expectations (3.1.2)
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.1.0)
45
- rspec-mocks (3.1.3)
46
- rspec-support (~> 3.1.0)
47
- rspec-support (3.1.2)
48
- simplecov (0.9.1)
49
- docile (~> 1.1.0)
50
- multi_json (~> 1.0)
51
- simplecov-html (~> 0.8.0)
52
- simplecov-html (0.8.0)
53
- term-ansicolor (1.2.2)
54
- tins (~> 0.8)
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
- 1.16.0
70
+ 2.0.2
data/README.md CHANGED
@@ -19,7 +19,9 @@ require 'finitio'
19
19
  require 'json'
20
20
 
21
21
  # Let load a schema
22
- schema = Finitio::DEFAULT_SYSTEM.parse <<-FIO
22
+ schema = Finitio.system <<-FIO
23
+ @import finitio/data
24
+
23
25
  {
24
26
  name: String( s | s.strip.size > 0 ),
25
27
  at: DateTime
@@ -98,6 +100,91 @@ module RgbContract
98
100
  end
99
101
  ```
100
102
 
103
+ ## Decompose complex system with imports
104
+
105
+ It is useful to decompose complex systems in many files using the import
106
+ feature. The latter works with relative file paths like this:
107
+
108
+ ```
109
+ # child.fio
110
+
111
+ Posint = .Integer(i | i >= 0)
112
+ ```
113
+
114
+ ```
115
+ # parent.fio
116
+ @import ./child.fio
117
+
118
+ # Child's types are available inside the system, but not outside it, that
119
+ # is, imported types are not themselves exported
120
+ Byte = Posint(i | i <= 255 )
121
+ ```
122
+
123
+ ```
124
+ @import ./parent.fio
125
+
126
+ # This will work
127
+ HalfByte = Byte(i | i <= 128)
128
+
129
+ # But this will not: Posint is not defined
130
+ Posint(i | i <= 128)
131
+ ```
132
+
133
+ See the next section about the standard library if you need to share types
134
+ without relying on relative paths.
135
+
136
+ ## Standard library
137
+
138
+ Usual type definitions are already defined for simple data types, forming
139
+ Finitio's default system:
140
+
141
+ * Most ruby native (data) classes are already aliased to avoid explicit use of
142
+ builtins. In particular, `Integer`, `String`, etc.
143
+
144
+ * A `Boolean` union type also hides the TrueClass and FalseClass distinction.
145
+
146
+ * Date, Time and DateTime ADTs are also provided that perform common
147
+ conversions from JSON strings, through iso8601.
148
+
149
+ This system is best used through Finitio's so-called "standard library", e.g.
150
+
151
+ ```
152
+ @import finitio/data
153
+
154
+ # String, Integer, Boolean, etc. are now available in this system
155
+ ```
156
+
157
+ See `lib/finitio/stdlib/*.fio` for the precise definition of the standard library.
158
+
159
+ ### Contributing to the standard library
160
+
161
+ Ruby gems may contribute to the standard library by specifying resolve paths.
162
+ We suggest the following system file structure inside your gem source code:
163
+
164
+ ```
165
+ lib
166
+ myrubygem
167
+ myrubygem.rb
168
+ finitio
169
+ myrubygem
170
+ base.fio
171
+ advanced.fio
172
+ ```
173
+
174
+ Registering the standard library path can then be done as follows:
175
+
176
+ ```
177
+ # inside myrubygem.rb
178
+ Finitio.stdlib_path(File.expand_path('../../finitio', __FILE__))
179
+ ```
180
+
181
+ Then, a Finitio schema will have access to the types defined in your extension:
182
+
183
+ ```
184
+ @import myrubygem/base
185
+ @import myrubygem/advanced
186
+ ```
187
+
101
188
  ## About representations
102
189
 
103
190
  The `Rep` representation function mapping *Finitio* types to ruby classes is
@@ -135,14 +222,3 @@ Rep({{Ai => Ti}}) = Set<Hash<Symbol => Rep(Ti)>>
135
222
  # specified. ADTs behave as Union types if no class is bound.
136
223
  Rep(.Builtin <rep> ...) = Builtin
137
224
  ```
138
-
139
- ## About the default system
140
-
141
- See `lib/finitio/Finitio/default.fio` for the precise definition of the default
142
- system. In summary,
143
-
144
- * Most ruby native (data) classes are already aliased to avoid explicit use of
145
- builtins. In particular, `Integer`, `String`, etc.
146
- * A `Boolean` union type also hides the TrueClass and FalseClass distinction.
147
- * Date, Time and DateTime ADTs are also provided that perform common
148
- conversions from JSON strings, through iso8601.
@@ -1,6 +1,7 @@
1
1
  require 'set'
2
2
  require 'time'
3
3
  require 'pathname'
4
+ require 'thread'
4
5
 
5
6
  module Finitio
6
7
 
@@ -9,34 +10,65 @@ module Finitio
9
10
  require_relative "finitio/support"
10
11
  require_relative 'finitio/type'
11
12
  require_relative 'finitio/system'
13
+ require_relative "finitio/syntax"
12
14
 
13
15
  IDENTITY = ->(object){ object }
14
16
 
15
17
  ANY_TYPE = AnyType.new
16
18
 
19
+ LOCK = Mutex.new
20
+
17
21
  STDLIB_PATHS = [
18
22
  File.expand_path('../finitio/stdlib', __FILE__)
19
23
  ]
20
24
 
25
+ MEMOIZED_SYSTEMS = {}
26
+
21
27
  def stdlib_path(path)
22
- STDLIB_PATHS << path
28
+ LOCK.synchronize {
29
+ STDLIB_PATHS << path
30
+ }
23
31
  end
24
32
 
25
33
  def parse(source)
26
- require "finitio/syntax"
27
34
  Syntax.parse(source)
28
35
  end
29
36
 
30
37
  def system(source)
31
- require "finitio/syntax"
32
- Syntax.compile(source)
38
+ LOCK.synchronize {
39
+ _system(source)
40
+ }
41
+ end
42
+
43
+ def _system(source)
44
+ if expanded = is_stdlib_source?(source)
45
+ MEMOIZED_SYSTEMS[expanded] ||= Syntax.compile(source)
46
+ else
47
+ Syntax.compile(source)
48
+ end
49
+ end
50
+ private :_system
51
+
52
+ def clear_saved_systems!
53
+ LOCK.synchronize {
54
+ MEMOIZED_SYSTEMS.clear
55
+ }
33
56
  end
34
57
 
35
58
  def ast(source)
36
- require "finitio/syntax"
37
59
  Syntax.ast(source)
38
60
  end
39
61
 
62
+ def is_stdlib_source?(source)
63
+ return false unless source.respond_to?(:to_path)
64
+ stdlib = STDLIB_PATHS.any?{|stdlib|
65
+ a_list = File.expand_path(source.to_path).split('/')
66
+ b_list = File.expand_path(stdlib).split('/')
67
+ a_list[0..b_list.size-1] == b_list
68
+ }
69
+ stdlib ? File.expand_path(source.to_path) : nil
70
+ end
71
+
40
72
  extend self
41
73
 
42
74
  DEFAULT_SYSTEM = system(File.read(
@@ -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'