finitio 0.4.1 → 0.5.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 (270) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +66 -0
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +34 -30
  5. data/finitio.gemspec +1 -1
  6. data/lib/finitio.rb +7 -39
  7. data/lib/finitio/errors.rb +14 -0
  8. data/lib/finitio/support.rb +4 -1
  9. data/lib/finitio/support/attribute.rb +13 -7
  10. data/lib/finitio/support/compilation.rb +55 -0
  11. data/lib/finitio/support/constraint.rb +46 -0
  12. data/lib/finitio/support/contract.rb +33 -0
  13. data/lib/finitio/support/dress_helper.rb +3 -2
  14. data/lib/finitio/support/heading.rb +57 -17
  15. data/lib/finitio/support/metadata.rb +20 -0
  16. data/lib/finitio/support/type_factory.rb +154 -41
  17. data/lib/finitio/syntax.rb +16 -31
  18. data/lib/finitio/syntax/expr.rb +56 -0
  19. data/lib/finitio/syntax/expr/arith_op.rb +22 -0
  20. data/lib/finitio/syntax/expr/comparison.rb +22 -0
  21. data/lib/finitio/syntax/expr/fn_call.rb +24 -0
  22. data/lib/finitio/syntax/expr/identifier.rb +18 -0
  23. data/lib/finitio/syntax/expr/literal.rb +19 -0
  24. data/lib/finitio/syntax/expr/logic_dyadic.rb +22 -0
  25. data/lib/finitio/syntax/expr/logic_not.rb +21 -0
  26. data/lib/finitio/syntax/expr/oo_call.rb +24 -0
  27. data/lib/finitio/syntax/expr/parenthesized.rb +20 -0
  28. data/lib/finitio/syntax/expr/unary_minus_op.rb +21 -0
  29. data/lib/finitio/syntax/expressions.citrus +129 -0
  30. data/lib/finitio/syntax/finitio.citrus +10 -208
  31. data/lib/finitio/syntax/finitio.sexp +5 -1
  32. data/lib/finitio/syntax/lexer.citrus +91 -0
  33. data/lib/finitio/syntax/literal.rb +16 -0
  34. data/lib/finitio/syntax/literal/boolean.rb +22 -0
  35. data/lib/finitio/syntax/literal/integer.rb +14 -0
  36. data/lib/finitio/syntax/literal/real.rb +14 -0
  37. data/lib/finitio/syntax/literal/string.rb +14 -0
  38. data/lib/finitio/syntax/literals.citrus +44 -0
  39. data/lib/finitio/syntax/node.rb +53 -0
  40. data/lib/finitio/syntax/type.rb +28 -0
  41. data/lib/finitio/syntax/type/ad_type.rb +29 -0
  42. data/lib/finitio/syntax/{any_type.rb → type/any_type.rb} +1 -1
  43. data/lib/finitio/syntax/type/attribute.rb +33 -0
  44. data/lib/finitio/syntax/{builtin_type.rb → type/builtin_type.rb} +3 -1
  45. data/lib/finitio/syntax/{constraint_def.rb → type/constraint_def.rb} +4 -3
  46. data/lib/finitio/syntax/type/constraints.rb +17 -0
  47. data/lib/finitio/syntax/{contract.rb → type/contract.rb} +9 -3
  48. data/lib/finitio/syntax/{definitions.rb → type/definitions.rb} +1 -0
  49. data/lib/finitio/syntax/{expression.rb → type/expression.rb} +2 -1
  50. data/lib/finitio/syntax/{external_pair.rb → type/external_pair.rb} +3 -1
  51. data/lib/finitio/syntax/type/heading.rb +30 -0
  52. data/lib/finitio/syntax/{inline_pair.rb → type/inline_pair.rb} +3 -1
  53. data/lib/finitio/syntax/{lambda_expr.rb → type/lambda_expr.rb} +3 -0
  54. data/lib/finitio/syntax/type/main_type.rb +18 -0
  55. data/lib/finitio/syntax/type/metadata.rb +18 -0
  56. data/lib/finitio/syntax/type/metadata_attr.rb +15 -0
  57. data/lib/finitio/syntax/{named_constraint.rb → type/named_constraint.rb} +10 -3
  58. data/lib/finitio/syntax/type/relation_type.rb +24 -0
  59. data/lib/finitio/syntax/{seq_type.rb → type/seq_type.rb} +3 -0
  60. data/lib/finitio/syntax/{set_type.rb → type/set_type.rb} +3 -0
  61. data/lib/finitio/syntax/type/struct_type.rb +17 -0
  62. data/lib/finitio/syntax/{sub_type.rb → type/sub_type.rb} +3 -0
  63. data/lib/finitio/syntax/{system.rb → type/system.rb} +5 -4
  64. data/lib/finitio/syntax/type/tuple_type.rb +24 -0
  65. data/lib/finitio/syntax/{type_def.rb → type/type_def.rb} +8 -3
  66. data/lib/finitio/syntax/{type_ref.rb → type/type_ref.rb} +4 -1
  67. data/lib/finitio/syntax/{union_type.rb → type/union_type.rb} +1 -0
  68. data/lib/finitio/syntax/{unnamed_constraint.rb → type/unnamed_constraint.rb} +7 -1
  69. data/lib/finitio/syntax/types.citrus +196 -0
  70. data/lib/finitio/system.rb +15 -15
  71. data/lib/finitio/type.rb +38 -6
  72. data/lib/finitio/type/ad_type.rb +41 -18
  73. data/lib/finitio/type/alias_type.rb +37 -0
  74. data/lib/finitio/type/any_type.rb +7 -3
  75. data/lib/finitio/type/builtin_type.rb +5 -4
  76. data/lib/finitio/{support → type}/collection_type.rb +3 -4
  77. data/lib/finitio/type/hash_based_type.rb +91 -0
  78. data/lib/finitio/type/heading_based_type.rb +28 -0
  79. data/lib/finitio/type/multi_relation_type.rb +34 -0
  80. data/lib/finitio/type/multi_tuple_type.rb +29 -0
  81. data/lib/finitio/type/proxy_type.rb +40 -0
  82. data/lib/finitio/type/rel_based_type.rb +42 -0
  83. data/lib/finitio/type/relation_type.rb +6 -47
  84. data/lib/finitio/type/seq_type.rb +4 -0
  85. data/lib/finitio/type/set_type.rb +4 -0
  86. data/lib/finitio/type/struct_type.rb +84 -0
  87. data/lib/finitio/type/sub_type.rb +25 -22
  88. data/lib/finitio/type/tuple_type.rb +6 -57
  89. data/lib/finitio/type/union_type.rb +12 -5
  90. data/lib/finitio/version.rb +2 -2
  91. data/spec/{unit/attribute → attribute}/test_equality.rb +8 -5
  92. data/spec/{unit/attribute → attribute}/test_fetch_on.rb +5 -5
  93. data/spec/attribute/test_initialize.rb +26 -0
  94. data/spec/attribute/test_optional.rb +18 -0
  95. data/spec/attribute/test_required.rb +18 -0
  96. data/spec/attribute/test_to_name.rb +20 -0
  97. data/spec/constraint/test_anonymous.rb +20 -0
  98. data/spec/constraint/test_equality.rb +39 -0
  99. data/spec/constraint/test_name.rb +20 -0
  100. data/spec/constraint/test_named.rb +20 -0
  101. data/spec/constraint/test_triple_equal.rb +13 -0
  102. data/spec/{unit/qrb/system.q → finitio/system.fio} +0 -0
  103. data/spec/{unit/qrb → finitio}/test_ast.rb +0 -0
  104. data/spec/finitio/test_parse.rb +23 -0
  105. data/spec/{unit/qrb/test_parse.rb → finitio/test_system.rb} +6 -6
  106. data/spec/heading/test_allow_extra.rb +24 -0
  107. data/spec/{unit/heading → heading}/test_each.rb +2 -2
  108. data/spec/heading/test_equality.rb +38 -0
  109. data/spec/heading/test_hash.rb +38 -0
  110. data/spec/heading/test_hash_get.rb +17 -0
  111. data/spec/{unit/heading → heading}/test_initialize.rb +2 -2
  112. data/spec/heading/test_multi.rb +57 -0
  113. data/spec/{unit/heading → heading}/test_size.rb +0 -0
  114. data/spec/heading/test_to_name.rb +58 -0
  115. data/spec/spec_helper.rb +17 -1
  116. data/spec/syntax/expr/test_free_variables.rb +46 -0
  117. data/spec/syntax/expr/test_to_proc_source.rb +43 -0
  118. data/spec/{unit/syntax → syntax}/nodes/test_ad_type.rb +26 -26
  119. data/spec/{unit/syntax → syntax}/nodes/test_any_type.rb +2 -2
  120. data/spec/syntax/nodes/test_attribute.rb +65 -0
  121. data/spec/{unit/syntax → syntax}/nodes/test_builtin_type.rb +5 -5
  122. data/spec/{unit/syntax → syntax}/nodes/test_comment.rb +1 -1
  123. data/spec/{unit/syntax → syntax}/nodes/test_constraint_def.rb +3 -8
  124. data/spec/{unit/syntax → syntax}/nodes/test_constraints.rb +21 -16
  125. data/spec/{unit/syntax → syntax}/nodes/test_contract.rb +28 -35
  126. data/spec/{unit/syntax → syntax}/nodes/test_expression.rb +13 -5
  127. data/spec/{unit/syntax → syntax}/nodes/test_heading.rb +25 -7
  128. data/spec/syntax/nodes/test_metadata.rb +28 -0
  129. data/spec/{unit/syntax → syntax}/nodes/test_named_constraint.rb +8 -8
  130. data/spec/syntax/nodes/test_relation_type.rb +84 -0
  131. data/spec/{unit/syntax → syntax}/nodes/test_seq_type.rb +4 -4
  132. data/spec/{unit/syntax → syntax}/nodes/test_set_type.rb +4 -4
  133. data/spec/{unit/syntax → syntax}/nodes/test_spacing.rb +1 -1
  134. data/spec/syntax/nodes/test_struct_type.rb +38 -0
  135. data/spec/{unit/syntax → syntax}/nodes/test_sub_type.rb +14 -14
  136. data/spec/{unit/syntax → syntax}/nodes/test_system.rb +3 -3
  137. data/spec/syntax/nodes/test_tuple_type.rb +94 -0
  138. data/spec/syntax/nodes/test_type_def.rb +57 -0
  139. data/spec/{unit/syntax → syntax}/nodes/test_type_ref.rb +3 -3
  140. data/spec/{unit/syntax → syntax}/nodes/test_union_type.rb +3 -3
  141. data/spec/{unit/syntax → syntax}/nodes/test_unnamed_constraint.rb +7 -7
  142. data/spec/syntax/test_compile.rb +41 -0
  143. data/spec/{unit/syntax → syntax}/test_compile_type.rb +1 -1
  144. data/spec/{unit/system → system}/test_add_type.rb +6 -6
  145. data/spec/{unit/system → system}/test_dsl.rb +2 -2
  146. data/spec/{unit/system → system}/test_dup.rb +4 -4
  147. data/spec/{unit/system → system}/test_fetch.rb +4 -4
  148. data/spec/{unit/system → system}/test_get_type.rb +2 -2
  149. data/spec/{unit/system → system}/test_initialize.rb +0 -0
  150. data/spec/test_finitio.rb +8 -0
  151. data/spec/{unit/type → type}/ad_type/test_default_name.rb +1 -2
  152. data/spec/{unit/type → type}/ad_type/test_dress.rb +19 -9
  153. data/spec/{unit/type → type}/ad_type/test_include.rb +3 -3
  154. data/spec/{unit/type → type}/ad_type/test_initialize.rb +15 -8
  155. data/spec/{unit/type → type}/ad_type/test_name.rb +2 -2
  156. data/spec/type/alias_type/test_default_name.rb +10 -0
  157. data/spec/type/alias_type/test_delegation.rb +29 -0
  158. data/spec/type/alias_type/test_name.rb +10 -0
  159. data/spec/{unit/type → type}/any_type/test_default_name.rb +1 -1
  160. data/spec/{unit/type → type}/any_type/test_dress.rb +0 -0
  161. data/spec/{unit/type → type}/any_type/test_equality.rb +4 -4
  162. data/spec/{unit/type → type}/any_type/test_include.rb +2 -2
  163. data/spec/{unit/type → type}/any_type/test_initialize.rb +0 -0
  164. data/spec/{unit/type → type}/any_type/test_name.rb +2 -2
  165. data/spec/{unit/type → type}/builtin_type/test_default_name.rb +1 -1
  166. data/spec/{unit/type → type}/builtin_type/test_dress.rb +3 -3
  167. data/spec/{unit/type → type}/builtin_type/test_equality.rb +4 -4
  168. data/spec/{unit/type → type}/builtin_type/test_include.rb +2 -2
  169. data/spec/{unit/type → type}/builtin_type/test_initialize.rb +1 -1
  170. data/spec/{unit/type → type}/builtin_type/test_name.rb +2 -2
  171. data/spec/type/multi_relation_type/test_default_name.rb +19 -0
  172. data/spec/type/multi_relation_type/test_dress.rb +206 -0
  173. data/spec/type/multi_relation_type/test_equality.rb +36 -0
  174. data/spec/type/multi_relation_type/test_include.rb +89 -0
  175. data/spec/type/multi_relation_type/test_initialize.rb +29 -0
  176. data/spec/type/multi_relation_type/test_name.rb +27 -0
  177. data/spec/type/multi_tuple_type/test_default_name.rb +17 -0
  178. data/spec/type/multi_tuple_type/test_dress.rb +146 -0
  179. data/spec/type/multi_tuple_type/test_equality.rb +32 -0
  180. data/spec/type/multi_tuple_type/test_include.rb +73 -0
  181. data/spec/type/multi_tuple_type/test_initialize.rb +30 -0
  182. data/spec/type/multi_tuple_type/test_name.rb +24 -0
  183. data/spec/type/proxy_type/test_delegation.rb +37 -0
  184. data/spec/type/proxy_type/test_resolve.rb +29 -0
  185. data/spec/{unit/type → type}/relation_type/test_default_name.rb +0 -0
  186. data/spec/{unit/type → type}/relation_type/test_dress.rb +24 -24
  187. data/spec/{unit/type → type}/relation_type/test_equality.rb +6 -6
  188. data/spec/{unit/type → type}/relation_type/test_include.rb +4 -4
  189. data/spec/{unit/type → type}/relation_type/test_initialize.rb +2 -2
  190. data/spec/{unit/type → type}/relation_type/test_name.rb +0 -0
  191. data/spec/{unit/type → type}/seq_type/test_default_name.rb +0 -0
  192. data/spec/{unit/type → type}/seq_type/test_dress.rb +5 -5
  193. data/spec/{unit/type → type}/seq_type/test_equality.rb +4 -4
  194. data/spec/{unit/type → type}/seq_type/test_include.rb +4 -4
  195. data/spec/{unit/type → type}/seq_type/test_initialize.rb +3 -3
  196. data/spec/{unit/type → type}/seq_type/test_name.rb +0 -0
  197. data/spec/{unit/type → type}/set_type/test_default_name.rb +0 -0
  198. data/spec/{unit/type → type}/set_type/test_dress.rb +8 -8
  199. data/spec/{unit/type → type}/set_type/test_equality.rb +4 -4
  200. data/spec/{unit/type → type}/set_type/test_include.rb +4 -4
  201. data/spec/{unit/type → type}/set_type/test_initialize.rb +3 -3
  202. data/spec/{unit/type → type}/set_type/test_name.rb +0 -0
  203. data/spec/type/struct_type/test_default_name.rb +10 -0
  204. data/spec/type/struct_type/test_dress.rb +105 -0
  205. data/spec/type/struct_type/test_equality.rb +28 -0
  206. data/spec/type/struct_type/test_include.rb +40 -0
  207. data/spec/type/struct_type/test_initialize.rb +22 -0
  208. data/spec/type/struct_type/test_name.rb +20 -0
  209. data/spec/{unit/type → type}/sub_type/test_default_name.rb +2 -2
  210. data/spec/{unit/type → type}/sub_type/test_dress.rb +14 -14
  211. data/spec/type/sub_type/test_equality.rb +46 -0
  212. data/spec/{unit/type → type}/sub_type/test_include.rb +6 -6
  213. data/spec/type/sub_type/test_initialize.rb +13 -0
  214. data/spec/{unit/type → type}/sub_type/test_name.rb +4 -4
  215. data/spec/{unit/type → type}/tuple_type/test_default_name.rb +0 -0
  216. data/spec/{unit/type → type}/tuple_type/test_dress.rb +18 -18
  217. data/spec/{unit/type → type}/tuple_type/test_equality.rb +6 -6
  218. data/spec/{unit/type → type}/tuple_type/test_include.rb +4 -4
  219. data/spec/{unit/type → type}/tuple_type/test_initialize.rb +4 -4
  220. data/spec/{unit/type → type}/tuple_type/test_name.rb +0 -0
  221. data/spec/{unit/type → type}/union_type/test_default_name.rb +0 -0
  222. data/spec/{unit/type → type}/union_type/test_dress.rb +7 -6
  223. data/spec/{unit/type → type}/union_type/test_equality.rb +7 -7
  224. data/spec/{unit/type → type}/union_type/test_include.rb +3 -3
  225. data/spec/{unit/type → type}/union_type/test_initialize.rb +3 -3
  226. data/spec/{unit/type → type}/union_type/test_name.rb +0 -0
  227. data/spec/{unit/type_factory → type_factory}/dsl/test_adt.rb +4 -4
  228. data/spec/{unit/type_factory → type_factory}/dsl/test_any.rb +1 -1
  229. data/spec/{unit/type_factory → type_factory}/dsl/test_attribute.rb +16 -2
  230. data/spec/{unit/type_factory → type_factory}/dsl/test_attributes.rb +1 -1
  231. data/spec/{unit/type_factory → type_factory}/dsl/test_builtin.rb +3 -3
  232. data/spec/type_factory/dsl/test_multi_relation.rb +39 -0
  233. data/spec/type_factory/dsl/test_multi_tuple.rb +37 -0
  234. data/spec/{unit/type_factory → type_factory}/dsl/test_relation.rb +6 -6
  235. data/spec/{unit/type_factory → type_factory}/dsl/test_seq.rb +4 -4
  236. data/spec/{unit/type_factory → type_factory}/dsl/test_set.rb +4 -4
  237. data/spec/type_factory/dsl/test_struct.rb +45 -0
  238. data/spec/{unit/type_factory → type_factory}/dsl/test_subtype.rb +10 -8
  239. data/spec/{unit/type_factory → type_factory}/dsl/test_tuple.rb +5 -5
  240. data/spec/{unit/type_factory → type_factory}/dsl/test_union.rb +6 -6
  241. data/spec/{unit/type_factory → type_factory}/factory/test_builtin.rb +1 -1
  242. data/spec/{unit/type_factory → type_factory}/factory/test_seq_type.rb +2 -2
  243. data/spec/{unit/type_factory → type_factory}/factory/test_set_type.rb +2 -2
  244. data/spec/type_factory/factory/test_struct_type.rb +18 -0
  245. data/spec/{unit/type_factory → type_factory}/factory/test_sub_type.rb +7 -7
  246. data/spec/{unit/type_factory → type_factory}/factory/test_tuple_type.rb +4 -4
  247. metadata +398 -286
  248. data/lib/finitio/data_type.rb +0 -29
  249. data/lib/finitio/syntax/ad_type.rb +0 -32
  250. data/lib/finitio/syntax/attribute.rb +0 -15
  251. data/lib/finitio/syntax/constraints.rb +0 -22
  252. data/lib/finitio/syntax/heading.rb +0 -19
  253. data/lib/finitio/syntax/relation_type.rb +0 -15
  254. data/lib/finitio/syntax/support.rb +0 -13
  255. data/lib/finitio/syntax/tuple_type.rb +0 -15
  256. data/spec/acceptance/Finitio/test_default.rb +0 -96
  257. data/spec/acceptance/Finitio/test_parsing.rb +0 -15
  258. data/spec/acceptance/ad_type/test_in_finitio.rb +0 -82
  259. data/spec/acceptance/ad_type/test_in_ruby.rb +0 -60
  260. data/spec/unit/attribute/test_initialize.rb +0 -13
  261. data/spec/unit/attribute/test_to_name.rb +0 -10
  262. data/spec/unit/heading/test_equality.rb +0 -28
  263. data/spec/unit/heading/test_to_name.rb +0 -32
  264. data/spec/unit/syntax/nodes/test_attribute.rb +0 -38
  265. data/spec/unit/syntax/nodes/test_relation_type.rb +0 -59
  266. data/spec/unit/syntax/nodes/test_tuple_type.rb +0 -59
  267. data/spec/unit/syntax/nodes/test_type_def.rb +0 -33
  268. data/spec/unit/test_finitio.rb +0 -15
  269. data/spec/unit/type/sub_type/test_equality.rb +0 -34
  270. data/spec/unit/type/sub_type/test_initialize.rb +0 -16
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ module Finitio
3
+ describe MultiRelationType, "equality" do
4
+
5
+ let(:h1){ Heading.new([Attribute.new(:r, intType), Attribute.new(:b, intType, false)]) }
6
+ let(:h2){ Heading.new([Attribute.new(:b, intType, false), Attribute.new(:r, intType)]) }
7
+ let(:h3){ Heading.new([Attribute.new(:b, intType)]) }
8
+ let(:h4){ Heading.new([Attribute.new(:b, intType), Attribute.new(:r, intType)]) }
9
+
10
+ let(:type1) { MultiRelationType.new(h1) }
11
+ let(:type2) { MultiRelationType.new(h2) }
12
+ let(:type3) { MultiRelationType.new(h3) }
13
+ let(:type4) { MultiRelationType.new(h4) }
14
+
15
+ it 'should apply structural equality' do
16
+ expect(type1 == type2).to eq(true)
17
+ expect(type2 == type1).to eq(true)
18
+ end
19
+
20
+ it 'should apply distinguish different types' do
21
+ expect(type1 == type3).to eq(false)
22
+ expect(type2 == type3).to eq(false)
23
+ expect(type1 == type4).to eq(false)
24
+ end
25
+
26
+ it 'should be a total function, with false for non types' do
27
+ expect(type1 == 12).to eq(false)
28
+ end
29
+
30
+ it 'should implement hash accordingly' do
31
+ expect([type1, type2].map(&:hash).uniq.size).to eq(1)
32
+ expect(type1.hash).not_to eq(type4.hash)
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+ module Finitio
3
+ describe MultiRelationType, "include?" do
4
+
5
+ let(:heading){
6
+ Heading.new([
7
+ Attribute.new(:a, intType),
8
+ Attribute.new(:b, intType, false)
9
+ ])
10
+ }
11
+
12
+ let(:type){ MultiRelationType.new(heading) }
13
+
14
+ subject{ type.include?(arg) }
15
+
16
+ context 'when a empty set' do
17
+ let(:arg){ Set.new }
18
+
19
+ it{ should eq(true) }
20
+ end
21
+
22
+ context 'when a valid, non empty set' do
23
+ let(:arg){ Set.new }
24
+
25
+ before do
26
+ arg << {a: 12, b: 15} << {a: 15, b: 16}
27
+ end
28
+
29
+ it{ should eq(true) }
30
+ end
31
+
32
+ context 'when a valid, non empty set but missing optionals' do
33
+ let(:arg){ Set.new }
34
+
35
+ before do
36
+ arg << {a: 12} << {a: 15, b: 16}
37
+ end
38
+
39
+ it{ should eq(true) }
40
+ end
41
+
42
+ context 'when not a set' do
43
+ let(:arg){ "foo" }
44
+
45
+ it{ should eq(false) }
46
+ end
47
+
48
+ context 'when a set containing invalid tuples' do
49
+ let(:arg){ Set.new }
50
+
51
+ before do
52
+ arg << {a: 12.0}
53
+ end
54
+
55
+ it{ should eq(false) }
56
+ end
57
+
58
+ context 'when a set containing tuples with missing required' do
59
+ let(:arg){ Set.new }
60
+
61
+ before do
62
+ arg << {b: 12}
63
+ end
64
+
65
+ it{ should eq(false) }
66
+ end
67
+
68
+ context 'when a set containing tuples with extra' do
69
+ let(:arg){ Set.new }
70
+
71
+ before do
72
+ arg << {a: 12, b: 12, c: 15}
73
+ end
74
+
75
+ it{ should eq(false) }
76
+ end
77
+
78
+ context 'when a set containing tuples with invalid optional' do
79
+ let(:arg){ Set.new }
80
+
81
+ before do
82
+ arg << {a: 12, b: 12.5}
83
+ end
84
+
85
+ it{ should eq(false) }
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+ module Finitio
3
+ describe MultiRelationType, "initialize" do
4
+
5
+ let(:heading){
6
+ Heading.new([
7
+ Attribute.new(:a, intType),
8
+ Attribute.new(:b, intType, false)
9
+ ])
10
+ }
11
+
12
+ context 'with a valid heading' do
13
+ subject{ MultiRelationType.new(heading) }
14
+
15
+ it{ should be_a(MultiRelationType) }
16
+ end
17
+
18
+ context 'with an invalid heading' do
19
+ subject{ MultiRelationType.new("foo", "bar") }
20
+
21
+ it 'should raise an error' do
22
+ expect{
23
+ subject
24
+ }.to raise_error(ArgumentError, "Heading expected, got `foo`")
25
+ end
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+ module Finitio
3
+ describe MultiRelationType, "name" do
4
+
5
+ let(:heading){
6
+ Heading.new([
7
+ Attribute.new(:a, byte),
8
+ Attribute.new(:b, byte, false)
9
+ ])
10
+ }
11
+
12
+ subject{ type.name }
13
+
14
+ context 'when not provided' do
15
+ let(:type){ MultiRelationType.new(heading) }
16
+
17
+ it{ should eq("{{a: Byte, b :? Byte}}") }
18
+ end
19
+
20
+ context 'when provided' do
21
+ let(:type){ MultiRelationType.new(heading, "colors") }
22
+
23
+ it{ should eq("colors") }
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+ module Finitio
3
+ describe MultiTupleType, "default_name" do
4
+
5
+ let(:heading){
6
+ Heading.new([
7
+ Attribute.new(:a, byte, true),
8
+ Attribute.new(:b, byte, false)
9
+ ])
10
+ }
11
+
12
+ subject{ MultiTupleType.new(heading).default_name }
13
+
14
+ it{ should eq("{a: Byte, b :? Byte}") }
15
+
16
+ end
17
+ end
@@ -0,0 +1,146 @@
1
+ require 'spec_helper'
2
+ module Finitio
3
+ describe MultiTupleType, "dress" do
4
+
5
+ let(:r) { Attribute.new(:r, byte) }
6
+ let(:g) { Attribute.new(:g, byte) }
7
+ let(:maybe_b){ Attribute.new(:b, byte, false) }
8
+
9
+ let(:type){
10
+ MultiTupleType.new(heading, "color")
11
+ }
12
+
13
+ subject{ type.dress(arg) }
14
+
15
+ context 'when not allowing extra' do
16
+ let(:heading){
17
+ Heading.new([r, g, maybe_b])
18
+ }
19
+
20
+ context 'with a valid Hash' do
21
+ let(:arg){
22
+ { "r" => 12, "g" => 13, "b" => 255 }
23
+ }
24
+
25
+ it 'should coerce to a tuple' do
26
+ expect(subject).to eq(r: 12, g: 13, b: 255)
27
+ end
28
+ end
29
+
30
+ context 'with a valid Hash and no optional' do
31
+ let(:arg){
32
+ { "r" => 12, "g" => 13 }
33
+ }
34
+
35
+ it 'should coerce to a tuple' do
36
+ expect(subject).to eq(r: 12, g: 13)
37
+ end
38
+ end
39
+
40
+ context 'when raising an error' do
41
+
42
+ subject do
43
+ type.dress(arg) rescue $!
44
+ end
45
+
46
+ context 'with something else than a Hash' do
47
+ let(:arg){
48
+ "foo"
49
+ }
50
+
51
+ it 'should raise a TypeError' do
52
+ expect(subject).to be_a(TypeError)
53
+ expect(subject.message).to eq("Invalid color `foo`")
54
+ end
55
+
56
+ it 'should have no cause' do
57
+ expect(subject.cause).to be_nil
58
+ end
59
+
60
+ it 'should have an empty location' do
61
+ expect(subject.location).to eq('')
62
+ end
63
+ end
64
+
65
+ context 'with a missing attribute' do
66
+ let(:arg){
67
+ { "r" => 12, "b" => 13 }
68
+ }
69
+
70
+ it 'should raise a TypeError' do
71
+ expect(subject).to be_a(TypeError)
72
+ expect(subject.message).to eq("Missing attribute `g`")
73
+ end
74
+
75
+ it 'should have no cause' do
76
+ expect(subject.cause).to be_nil
77
+ end
78
+
79
+ it 'should have an empty location' do
80
+ expect(subject.location).to eq('')
81
+ end
82
+ end
83
+
84
+ context 'with an extra attribute' do
85
+ let(:arg){
86
+ { "r" => 12, "g" => 13, "extr" => 165 }
87
+ }
88
+
89
+ it 'should raise a TypeError' do
90
+ expect(subject).to be_a(TypeError)
91
+ expect(subject.message).to eq("Unrecognized attribute `extr`")
92
+ end
93
+
94
+ it 'should have no cause' do
95
+ expect(subject.cause).to be_nil
96
+ end
97
+
98
+ it 'should have an empty location' do
99
+ expect(subject.location).to eq('')
100
+ end
101
+ end
102
+
103
+ context 'with an invalid attribute' do
104
+ let(:arg){
105
+ { "r" => 12, "g" => 13, "b" => 255.0 }
106
+ }
107
+
108
+ it 'should raise a TypeError' do
109
+ expect(subject).to be_a(TypeError)
110
+ expect(subject.message).to eq("Invalid Byte `255.0`")
111
+ end
112
+
113
+ it 'should have the correct cause' do
114
+ expect(subject.cause).to be_a(TypeError)
115
+ expect(subject.cause.message).to eq("Invalid intType `255.0`")
116
+ end
117
+
118
+ it 'should have the correct location' do
119
+ expect(subject.location).to eq("b")
120
+ end
121
+ end
122
+ end
123
+ end
124
+
125
+ context 'when not allowing extra' do
126
+ let(:heading){
127
+ Heading.new([r, g, maybe_b], allow_extra: true)
128
+ }
129
+
130
+ context 'with an extra attribute' do
131
+ let(:arg){
132
+ { "r" => 12, "g" => 13, "extr" => 165 }
133
+ }
134
+
135
+ it 'should not raise a TypeError' do
136
+ expect(subject).not_to be_a(TypeError)
137
+ end
138
+
139
+ it 'should return a coerced/projection' do
140
+ expect(subject).to eq(r: 12, g: 13)
141
+ end
142
+ end
143
+ end
144
+
145
+ end
146
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ module Finitio
3
+ describe MultiTupleType, "equality" do
4
+
5
+ let(:h1){ Heading.new([Attribute.new(:r, intType, false), Attribute.new(:b, intType)]) }
6
+ let(:h2){ Heading.new([Attribute.new(:b, intType), Attribute.new(:r, intType, false)]) }
7
+ let(:h3){ Heading.new([Attribute.new(:b, intType)]) }
8
+
9
+ let(:type1) { MultiTupleType.new(h1) }
10
+ let(:type2) { MultiTupleType.new(h2) }
11
+ let(:type3) { MultiTupleType.new(h3) }
12
+
13
+ it 'should apply structural equality' do
14
+ expect(type1 == type2).to eq(true)
15
+ expect(type2 == type1).to eq(true)
16
+ end
17
+
18
+ it 'should apply distinguish different types' do
19
+ expect(type1 == type3).to eq(false)
20
+ expect(type2 == type3).to eq(false)
21
+ end
22
+
23
+ it 'should be a total function, with nil for non types' do
24
+ expect(type1 == 12).to eq(false)
25
+ end
26
+
27
+ it 'should implement hash accordingly' do
28
+ expect([type1, type2].map(&:hash).uniq.size).to eq(1)
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+ module Finitio
3
+ describe MultiTupleType, "include?" do
4
+
5
+ let(:a) { Attribute.new(:a, intType) }
6
+ let(:maybe_b){ Attribute.new(:b, intType, false) }
7
+
8
+ let(:type){ MultiTupleType.new(heading) }
9
+
10
+ subject{ type.include?(arg) }
11
+
12
+ context 'without extra allowed' do
13
+ let(:heading){
14
+ Heading.new([a, maybe_b])
15
+ }
16
+
17
+ context 'when a valid hash and both attributes' do
18
+ let(:arg){ {a: 12, b: 14} }
19
+
20
+ it{ should eq(true) }
21
+ end
22
+
23
+ context 'when a valid hash but no optional attribute' do
24
+ let(:arg){ {a: 12} }
25
+
26
+ it{ should eq(true) }
27
+ end
28
+
29
+ context 'when an invalid hash (too many attributes)' do
30
+ let(:arg){ {a: 12, c: 15} }
31
+
32
+ it{ should eq(false) }
33
+ end
34
+
35
+ context 'when an invalid hash (too few attributes)' do
36
+ let(:arg){ {b: 12} }
37
+
38
+ it{ should eq(false) }
39
+ end
40
+
41
+ context 'when an invalid hash (wrong type)' do
42
+ let(:arg){ {a: 12, b: 15.0} }
43
+
44
+ it{ should eq(false) }
45
+ end
46
+
47
+ context 'when an invalid hash (wrong type II)' do
48
+ let(:arg){ {a: 12.0, b: 15} }
49
+
50
+ it{ should eq(false) }
51
+ end
52
+ end
53
+
54
+ context 'with extra allowed' do
55
+ let(:heading){
56
+ Heading.new([a, maybe_b], allow_extra: true)
57
+ }
58
+
59
+ context 'when valid hash, yet with no extra attribute' do
60
+ let(:arg){ {a: 12} }
61
+
62
+ it{ should eq(true) }
63
+ end
64
+
65
+ context 'when valid hash, yet with extra attributes' do
66
+ let(:arg){ {a: 12, c: 15} }
67
+
68
+ it{ should eq(true) }
69
+ end
70
+ end
71
+
72
+ end
73
+ end