axiom 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (311) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +2 -1
  3. data/.rubocop.yml +7 -0
  4. data/.travis.yml +10 -7
  5. data/Gemfile +4 -0
  6. data/Gemfile.devtools +27 -13
  7. data/Guardfile +2 -2
  8. data/README.md +36 -30
  9. data/TODO +22 -24
  10. data/axiom.gemspec +9 -9
  11. data/benchmarks/memory.rb +1 -2
  12. data/benchmarks/speed.rb +7 -8
  13. data/config/flay.yml +1 -1
  14. data/config/reek.yml +19 -7
  15. data/config/rubocop.yml +6 -9
  16. data/lib/axiom.rb +28 -13
  17. data/lib/axiom/aggregate/mean.rb +4 -3
  18. data/lib/axiom/aggregate/sum.rb +1 -1
  19. data/lib/axiom/algebra/extension.rb +1 -1
  20. data/lib/axiom/algebra/join.rb +4 -27
  21. data/lib/axiom/algebra/product.rb +3 -3
  22. data/lib/axiom/algebra/projection.rb +2 -2
  23. data/lib/axiom/algebra/rename.rb +2 -2
  24. data/lib/axiom/algebra/rename/aliases.rb +3 -3
  25. data/lib/axiom/algebra/summarization.rb +3 -3
  26. data/lib/axiom/attribute.rb +5 -4
  27. data/lib/axiom/attribute/comparable.rb +15 -11
  28. data/lib/axiom/attribute/date.rb +1 -1
  29. data/lib/axiom/attribute/date_time.rb +1 -1
  30. data/lib/axiom/attribute/length_comparable.rb +39 -0
  31. data/lib/axiom/attribute/numeric.rb +1 -26
  32. data/lib/axiom/attribute/relation.rb +64 -0
  33. data/lib/axiom/attribute/string.rb +1 -28
  34. data/lib/axiom/attribute/time.rb +1 -1
  35. data/lib/axiom/attribute/tuple.rb +50 -0
  36. data/lib/axiom/attribute/value_comparable.rb +42 -0
  37. data/lib/axiom/function.rb +1 -1
  38. data/lib/axiom/function/binary.rb +4 -16
  39. data/lib/axiom/function/comparable.rb +1 -1
  40. data/lib/axiom/function/connective/conjunction.rb +1 -1
  41. data/lib/axiom/function/connective/disjunction.rb +1 -1
  42. data/lib/axiom/function/connective/negation.rb +1 -1
  43. data/lib/axiom/function/numeric/exponentiation.rb +1 -1
  44. data/lib/axiom/function/numeric/square_root.rb +1 -1
  45. data/lib/axiom/function/predicate/enumerable.rb +0 -14
  46. data/lib/axiom/function/predicate/exclusion.rb +1 -1
  47. data/lib/axiom/function/predicate/inclusion.rb +1 -1
  48. data/lib/axiom/function/proposition.rb +12 -25
  49. data/lib/axiom/function/unary.rb +92 -106
  50. data/lib/axiom/relation.rb +3 -3
  51. data/lib/axiom/relation/base.rb +15 -0
  52. data/lib/axiom/relation/header.rb +25 -22
  53. data/lib/axiom/relation/index.rb +91 -0
  54. data/lib/axiom/relation/keys.rb +3 -3
  55. data/lib/axiom/relation/materialized.rb +48 -4
  56. data/lib/axiom/relation/operation/binary.rb +5 -5
  57. data/lib/axiom/relation/operation/group.rb +95 -0
  58. data/lib/axiom/relation/operation/limit.rb +15 -15
  59. data/lib/axiom/relation/operation/offset.rb +12 -12
  60. data/lib/axiom/relation/operation/reverse.rb +9 -9
  61. data/lib/axiom/relation/operation/set.rb +1 -1
  62. data/lib/axiom/relation/operation/{order.rb → sorted.rb} +29 -28
  63. data/lib/axiom/relation/operation/{order → sorted}/direction.rb +4 -4
  64. data/lib/axiom/relation/operation/{order → sorted}/direction_set.rb +3 -3
  65. data/lib/axiom/relation/operation/ungroup.rb +82 -0
  66. data/lib/axiom/relation/operation/unwrap.rb +80 -0
  67. data/lib/axiom/relation/operation/wrap.rb +85 -0
  68. data/lib/axiom/relation/proxy.rb +5 -6
  69. data/lib/axiom/relation/variable.rb +1 -2
  70. data/lib/axiom/support/aliasable.rb +3 -5
  71. data/lib/axiom/support/equalizer.rb +10 -12
  72. data/lib/axiom/support/operation/binary.rb +3 -2
  73. data/lib/axiom/support/operation/unary.rb +1 -1
  74. data/lib/axiom/tuple.rb +76 -26
  75. data/lib/axiom/types/relation.rb +13 -0
  76. data/lib/axiom/types/tuple.rb +13 -0
  77. data/lib/axiom/version.rb +1 -1
  78. data/spec/integration/axiom/relation/efficient_enumerable_spec.rb +9 -9
  79. data/spec/integration/axiom/relation/writable_relations_spec.rb +12 -12
  80. data/spec/shared/invertible_method_behaviour.rb +1 -1
  81. data/spec/spec_helper.rb +8 -6
  82. data/spec/unit/axiom/aggregate/call_spec.rb +7 -12
  83. data/spec/unit/axiom/aggregate/class_methods/default_spec.rb +7 -2
  84. data/spec/unit/axiom/aggregate/default_spec.rb +1 -1
  85. data/spec/unit/axiom/aggregate/finalize_spec.rb +1 -1
  86. data/spec/unit/axiom/aggregate/maximum/type_spec.rb +2 -6
  87. data/spec/unit/axiom/aggregate/mean/class_methods/call_spec.rb +2 -2
  88. data/spec/unit/axiom/aggregate/mean/class_methods/finalize_spec.rb +10 -3
  89. data/spec/unit/axiom/aggregate/minimum/type_spec.rb +2 -6
  90. data/spec/unit/axiom/aggregate/sum/default_spec.rb +32 -6
  91. data/spec/unit/axiom/aggregate/sum/type_spec.rb +2 -6
  92. data/spec/unit/axiom/aggregate/variance/class_methods/call_spec.rb +6 -6
  93. data/spec/unit/axiom/algebra/difference/each_spec.rb +3 -3
  94. data/spec/unit/axiom/algebra/extension/class_methods/new_spec.rb +1 -1
  95. data/spec/unit/axiom/algebra/extension/each_spec.rb +2 -2
  96. data/spec/unit/axiom/algebra/intersection/each_spec.rb +3 -3
  97. data/spec/unit/axiom/algebra/join/each_spec.rb +6 -6
  98. data/spec/unit/axiom/algebra/product/each_spec.rb +2 -2
  99. data/spec/unit/axiom/algebra/projection/each_spec.rb +2 -2
  100. data/spec/unit/axiom/algebra/rename/directions_spec.rb +3 -3
  101. data/spec/unit/axiom/algebra/rename/each_spec.rb +2 -2
  102. data/spec/unit/axiom/algebra/restriction/delete_spec.rb +3 -3
  103. data/spec/unit/axiom/algebra/restriction/each_spec.rb +12 -11
  104. data/spec/unit/axiom/algebra/restriction/insert_spec.rb +3 -3
  105. data/spec/unit/axiom/algebra/restriction/methods/restrict_spec.rb +4 -4
  106. data/spec/unit/axiom/algebra/summarization/each_spec.rb +2 -2
  107. data/spec/unit/axiom/algebra/summarization/eql_spec.rb +1 -1
  108. data/spec/unit/axiom/algebra/summarization/summaries/summarize_by_spec.rb +4 -4
  109. data/spec/unit/axiom/algebra/summarization/summaries/to_hash_spec.rb +2 -2
  110. data/spec/unit/axiom/algebra/summarization/summary/summarize_by_spec.rb +1 -1
  111. data/spec/unit/axiom/algebra/union/each_spec.rb +4 -4
  112. data/spec/unit/axiom/aliasable/fixtures/classes.rb +3 -1
  113. data/spec/unit/axiom/aliasable/inheritable_alias_spec.rb +18 -27
  114. data/spec/unit/axiom/attribute/call_spec.rb +1 -1
  115. data/spec/unit/axiom/attribute/class_methods/coerce_spec.rb +57 -51
  116. data/spec/unit/axiom/attribute/class_methods/new_spec.rb +1 -1
  117. data/spec/unit/axiom/attribute/comparable/asc_spec.rb +4 -2
  118. data/spec/unit/axiom/attribute/comparable/desc_spec.rb +4 -2
  119. data/spec/unit/axiom/attribute/comparable/range_spec.rb +20 -0
  120. data/spec/unit/axiom/attribute/eql_spec.rb +1 -1
  121. data/spec/unit/axiom/attribute/equality_operator_spec.rb +1 -1
  122. data/spec/unit/axiom/attribute/include_predicate_spec.rb +1 -1
  123. data/spec/unit/axiom/attribute/name_spec.rb +1 -1
  124. data/spec/unit/axiom/attribute/optional_predicate_spec.rb +1 -1
  125. data/spec/unit/axiom/attribute/relation/class_methods/new_spec.rb +56 -0
  126. data/spec/unit/axiom/attribute/relation/class_methods/type_spec.rb +13 -0
  127. data/spec/unit/axiom/attribute/relation/header_spec.rb +13 -0
  128. data/spec/unit/axiom/attribute/relation/new_relation_spec.rb +15 -0
  129. data/spec/unit/axiom/attribute/rename_spec.rb +1 -1
  130. data/spec/unit/axiom/attribute/required_predicate_spec.rb +1 -1
  131. data/spec/unit/axiom/attribute/tuple/class_methods/new_spec.rb +56 -0
  132. data/spec/unit/axiom/attribute/tuple/class_methods/type_spec.rb +13 -0
  133. data/spec/unit/axiom/attribute/tuple/header_spec.rb +13 -0
  134. data/spec/unit/axiom/equalizer/class_method/new_spec.rb +24 -54
  135. data/spec/unit/axiom/evaluator/context/add_spec.rb +7 -7
  136. data/spec/unit/axiom/evaluator/context/element_reader_spec.rb +4 -4
  137. data/spec/unit/axiom/evaluator/context/functions_spec.rb +1 -1
  138. data/spec/unit/axiom/evaluator/context/method_missing_spec.rb +3 -3
  139. data/spec/unit/axiom/evaluator/context/respond_to_predicate_spec.rb +3 -3
  140. data/spec/unit/axiom/evaluator/context/send_spec.rb +8 -8
  141. data/spec/unit/axiom/function/binary/call_spec.rb +1 -1
  142. data/spec/unit/axiom/function/binary/type_spec.rb +12 -10
  143. data/spec/unit/axiom/function/comparable/class_methods/included_spec.rb +2 -2
  144. data/spec/unit/axiom/function/connective/negation/inverse_spec.rb +1 -1
  145. data/spec/unit/axiom/function/predicate/call_spec.rb +5 -4
  146. data/spec/unit/axiom/function/predicate/enumerable/call_spec.rb +12 -2
  147. data/spec/unit/axiom/function/predicate/eql_spec.rb +4 -3
  148. data/spec/unit/axiom/function/predicate/equality/methods/eq_spec.rb +5 -1
  149. data/spec/unit/axiom/function/predicate/exclusion/class_methods/call_spec.rb +37 -8
  150. data/spec/unit/axiom/function/predicate/exclusion/methods/exclude_spec.rb +6 -2
  151. data/spec/unit/axiom/function/predicate/greater_than/methods/gt_spec.rb +5 -1
  152. data/spec/unit/axiom/function/predicate/greater_than_or_equal_to/methods/gte_spec.rb +5 -1
  153. data/spec/unit/axiom/function/predicate/inclusion/class_methods/call_spec.rb +37 -8
  154. data/spec/unit/axiom/function/predicate/inclusion/methods/include_spec.rb +6 -2
  155. data/spec/unit/axiom/function/predicate/inequality/methods/ne_spec.rb +5 -1
  156. data/spec/unit/axiom/function/predicate/less_than/methods/lt_spec.rb +5 -1
  157. data/spec/unit/axiom/function/predicate/less_than_or_equal_to/methods/lte_spec.rb +5 -1
  158. data/spec/unit/axiom/function/predicate/match/methods/match_spec.rb +7 -3
  159. data/spec/unit/axiom/function/predicate/no_match/methods/no_match_spec.rb +6 -2
  160. data/spec/unit/axiom/function/proposition/call_spec.rb +6 -4
  161. data/spec/unit/axiom/function/proposition/class_methods/{new_spec.rb → coerce_spec.rb} +17 -17
  162. data/spec/unit/axiom/function/proposition/eql_spec.rb +4 -4
  163. data/spec/unit/axiom/function/proposition/equality_operator_spec.rb +3 -3
  164. data/spec/unit/axiom/function/proposition/inverse_spec.rb +4 -4
  165. data/spec/unit/axiom/function/proposition/rename_spec.rb +1 -1
  166. data/spec/unit/axiom/function/type_spec.rb +1 -1
  167. data/spec/unit/axiom/function/unary/call_spec.rb +1 -1
  168. data/spec/unit/axiom/function/unary/callable/call_spec.rb +3 -13
  169. data/spec/unit/axiom/function/unary/callable/included_spec.rb +2 -2
  170. data/spec/unit/axiom/function/unary/type_spec.rb +11 -1
  171. data/spec/unit/axiom/relation/base/eql_spec.rb +1 -1
  172. data/spec/unit/axiom/relation/base/equality_operator_spec.rb +138 -0
  173. data/spec/unit/axiom/relation/class_methods/new_spec.rb +7 -7
  174. data/spec/unit/axiom/relation/directions_spec.rb +2 -2
  175. data/spec/unit/axiom/relation/each_spec.rb +5 -5
  176. data/spec/unit/axiom/relation/element_reader_spec.rb +1 -1
  177. data/spec/unit/axiom/relation/empty/each_spec.rb +1 -1
  178. data/spec/unit/axiom/relation/empty_predicate_spec.rb +1 -1
  179. data/spec/unit/axiom/relation/eql_spec.rb +1 -1
  180. data/spec/unit/axiom/relation/equality_operator_spec.rb +1 -1
  181. data/spec/unit/axiom/relation/header/class_methods/coerce_spec.rb +2 -2
  182. data/spec/unit/axiom/relation/header/class_methods/new_spec.rb +3 -3
  183. data/spec/unit/axiom/relation/header/context_spec.rb +2 -2
  184. data/spec/unit/axiom/relation/header/each_spec.rb +2 -2
  185. data/spec/unit/axiom/relation/header/extend_spec.rb +1 -1
  186. data/spec/unit/axiom/relation/header/{call_spec.rb → fetch_spec.rb} +1 -1
  187. data/spec/unit/axiom/relation/header/project_spec.rb +1 -1
  188. data/spec/unit/axiom/relation/header/rename_spec.rb +19 -5
  189. data/spec/unit/axiom/relation/header/size_spec.rb +14 -0
  190. data/spec/unit/axiom/relation/header_spec.rb +1 -1
  191. data/spec/unit/axiom/relation/index/each_spec.rb +33 -0
  192. data/spec/unit/axiom/relation/index/element_reader_spec.rb +17 -0
  193. data/spec/unit/axiom/relation/index/left_shift_operator_spec.rb +23 -0
  194. data/spec/unit/axiom/relation/index/merge_spec.rb +19 -0
  195. data/spec/unit/axiom/relation/keys/class_methods/coerce_spec.rb +19 -2
  196. data/spec/unit/axiom/relation/keys/class_methods/new_spec.rb +1 -1
  197. data/spec/unit/axiom/relation/keys/each_spec.rb +2 -2
  198. data/spec/unit/axiom/relation/materialize_spec.rb +1 -1
  199. data/spec/unit/axiom/relation/materialized/class_methods/new_spec.rb +30 -4
  200. data/spec/unit/axiom/relation/materialized/directions_spec.rb +1 -1
  201. data/spec/unit/axiom/relation/materialized/materialized_predicate_spec.rb +1 -1
  202. data/spec/unit/axiom/relation/materialized_predicate_spec.rb +1 -1
  203. data/spec/unit/axiom/relation/operation/binary/class_methods/included_spec.rb +2 -2
  204. data/spec/unit/axiom/relation/operation/binary/class_methods/new_spec.rb +6 -6
  205. data/spec/unit/axiom/relation/operation/combination/class_methods/combine_tuples_spec.rb +4 -4
  206. data/spec/unit/axiom/relation/operation/group/each_spec.rb +33 -0
  207. data/spec/unit/axiom/relation/operation/group/header_spec.rb +22 -0
  208. data/spec/unit/axiom/relation/operation/group/methods/group_spec.rb +25 -0
  209. data/spec/unit/axiom/relation/operation/limit/class_methods/new_spec.rb +4 -4
  210. data/spec/unit/axiom/relation/operation/limit/directions_spec.rb +3 -3
  211. data/spec/unit/axiom/relation/operation/limit/each_spec.rb +4 -4
  212. data/spec/unit/axiom/relation/operation/limit/limit_spec.rb +2 -2
  213. data/spec/unit/axiom/relation/operation/offset/class_methods/new_spec.rb +4 -4
  214. data/spec/unit/axiom/relation/operation/offset/directions_spec.rb +3 -3
  215. data/spec/unit/axiom/relation/operation/offset/each_spec.rb +4 -4
  216. data/spec/unit/axiom/relation/operation/offset/offset_spec.rb +2 -2
  217. data/spec/unit/axiom/relation/operation/reverse/class_methods/new_spec.rb +6 -6
  218. data/spec/unit/axiom/relation/operation/reverse/directions_spec.rb +3 -3
  219. data/spec/unit/axiom/relation/operation/reverse/each_spec.rb +4 -4
  220. data/spec/unit/axiom/relation/operation/set/class_methods/included_spec.rb +2 -2
  221. data/spec/unit/axiom/relation/operation/{order → sorted}/ascending/class_methods/call_spec.rb +22 -1
  222. data/spec/unit/axiom/relation/operation/sorted/ascending/class_methods/reverse_spec.rb +11 -0
  223. data/spec/unit/axiom/relation/operation/{order/descending → sorted/ascending}/reverse_spec.rb +2 -2
  224. data/spec/unit/axiom/relation/operation/{order → sorted}/class_methods/new_spec.rb +4 -4
  225. data/spec/unit/axiom/relation/operation/{order → sorted}/delete_spec.rb +12 -6
  226. data/spec/unit/axiom/relation/operation/{order → sorted}/descending/class_methods/call_spec.rb +22 -1
  227. data/spec/unit/axiom/relation/operation/sorted/descending/class_methods/reverse_spec.rb +11 -0
  228. data/spec/unit/axiom/relation/operation/{order/ascending → sorted/descending}/reverse_spec.rb +2 -2
  229. data/spec/unit/axiom/relation/operation/{order → sorted}/direction/attribute_spec.rb +4 -4
  230. data/spec/unit/axiom/relation/operation/{order → sorted}/direction/call_spec.rb +7 -7
  231. data/spec/unit/axiom/relation/operation/{order → sorted}/direction/class_methods/coerce_spec.rb +2 -2
  232. data/spec/unit/axiom/relation/operation/{order → sorted}/direction/eql_predicate_spec.rb +4 -4
  233. data/spec/unit/axiom/relation/operation/{order → sorted}/direction/name_spec.rb +4 -4
  234. data/spec/unit/axiom/relation/operation/{order → sorted}/direction/rename_spec.rb +5 -5
  235. data/spec/unit/axiom/relation/operation/{order → sorted}/direction/reverse_spec.rb +9 -9
  236. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/attributes_spec.rb +1 -1
  237. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/class_methods/coerce_spec.rb +3 -3
  238. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/class_methods/new_spec.rb +1 -1
  239. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/eql_spec.rb +1 -1
  240. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/equality_operator_spec.rb +1 -1
  241. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/project_spec.rb +1 -1
  242. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/rename_spec.rb +1 -1
  243. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/reverse_spec.rb +2 -2
  244. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/sort_tuples_spec.rb +1 -1
  245. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/to_ary_spec.rb +1 -1
  246. data/spec/unit/axiom/relation/operation/{order → sorted}/directions_spec.rb +1 -1
  247. data/spec/unit/axiom/relation/operation/{order → sorted}/each_spec.rb +3 -3
  248. data/spec/unit/axiom/relation/operation/{order → sorted}/eql_spec.rb +1 -1
  249. data/spec/unit/axiom/relation/operation/{order → sorted}/header_spec.rb +1 -1
  250. data/spec/unit/axiom/relation/operation/{order → sorted}/insert_spec.rb +12 -6
  251. data/spec/unit/axiom/relation/operation/{order → sorted}/methods/sort_by_spec.rb +24 -24
  252. data/spec/unit/axiom/relation/operation/sorted/methods/sort_spec.rb +19 -0
  253. data/spec/unit/axiom/relation/operation/ungroup/each_spec.rb +33 -0
  254. data/spec/unit/axiom/relation/operation/ungroup/header_spec.rb +19 -0
  255. data/spec/unit/axiom/relation/operation/ungroup/methods/ungroup_spec.rb +21 -0
  256. data/spec/unit/axiom/relation/operation/unwrap/each_spec.rb +33 -0
  257. data/spec/unit/axiom/relation/operation/unwrap/header_spec.rb +19 -0
  258. data/spec/unit/axiom/relation/operation/unwrap/methods/unwrap_spec.rb +21 -0
  259. data/spec/unit/axiom/relation/operation/wrap/each_spec.rb +33 -0
  260. data/spec/unit/axiom/relation/operation/wrap/header_spec.rb +22 -0
  261. data/spec/unit/axiom/relation/operation/wrap/methods/wrap_spec.rb +25 -0
  262. data/spec/unit/axiom/relation/proxy/each_spec.rb +2 -2
  263. data/spec/unit/axiom/relation/proxy/respond_to_predicate_spec.rb +48 -12
  264. data/spec/unit/axiom/relation/replace_spec.rb +8 -8
  265. data/spec/unit/axiom/tuple/class_methods/coerce_spec.rb +7 -1
  266. data/spec/unit/axiom/tuple/{call_spec.rb → fetch_spec.rb} +1 -1
  267. data/spec/unit/axiom/tuple/inspect_spec.rb +14 -0
  268. data/spec/unit/axiom/tuple/rename_spec.rb +17 -0
  269. data/spec/unit/axiom/tuple/size_spec.rb +14 -0
  270. data/spec/unit/axiom/tuple/to_ary_spec.rb +22 -5
  271. data/spec/unit/axiom/tuple/to_hash_spec.rb +14 -0
  272. data/spec/unit/axiom/types/relation/class_methods/primitive_spec.rb +13 -0
  273. data/spec/unit/axiom/types/tuple/class_methods/primitive_spec.rb +13 -0
  274. data/spec/unit/axiom/visitable/accept_spec.rb +1 -1
  275. data/spec/unit/date/pred_spec.rb +1 -1
  276. data/spec/unit/time/pred_spec.rb +1 -1
  277. metadata +631 -107
  278. data/spec/unit/axiom/aggregate/hash_spec.rb +0 -15
  279. data/spec/unit/axiom/algebra/extension/hash_spec.rb +0 -15
  280. data/spec/unit/axiom/algebra/projection/hash_spec.rb +0 -16
  281. data/spec/unit/axiom/algebra/rename/aliases/hash_spec.rb +0 -15
  282. data/spec/unit/axiom/algebra/rename/hash_spec.rb +0 -15
  283. data/spec/unit/axiom/algebra/restriction/hash_spec.rb +0 -15
  284. data/spec/unit/axiom/algebra/summarization/hash_spec.rb +0 -16
  285. data/spec/unit/axiom/attribute/hash_spec.rb +0 -21
  286. data/spec/unit/axiom/attribute/numeric/hash_spec.rb +0 -17
  287. data/spec/unit/axiom/attribute/string/hash_spec.rb +0 -25
  288. data/spec/unit/axiom/equalizer/methods/eql_spec.rb +0 -49
  289. data/spec/unit/axiom/equalizer/methods/equality_operator_spec.rb +0 -85
  290. data/spec/unit/axiom/function/binary/invertible/class_methods/included_spec.rb +0 -29
  291. data/spec/unit/axiom/function/predicate/hash_spec.rb +0 -16
  292. data/spec/unit/axiom/function/predicate/inverse_spec.rb +0 -17
  293. data/spec/unit/axiom/function/proposition/hash_spec.rb +0 -14
  294. data/spec/unit/axiom/function/unary/hash_spec.rb +0 -18
  295. data/spec/unit/axiom/function/unary/invertible/class_methods/included_spec.rb +0 -29
  296. data/spec/unit/axiom/operation/binary/hash_spec.rb +0 -16
  297. data/spec/unit/axiom/operation/unary/hash_spec.rb +0 -15
  298. data/spec/unit/axiom/relation/base/hash_spec.rb +0 -16
  299. data/spec/unit/axiom/relation/hash_spec.rb +0 -19
  300. data/spec/unit/axiom/relation/header/hash_spec.rb +0 -15
  301. data/spec/unit/axiom/relation/operation/limit/hash_spec.rb +0 -16
  302. data/spec/unit/axiom/relation/operation/offset/hash_spec.rb +0 -16
  303. data/spec/unit/axiom/relation/operation/order/ascending/class_methods/reverse_spec.rb +0 -11
  304. data/spec/unit/axiom/relation/operation/order/descending/class_methods/reverse_spec.rb +0 -11
  305. data/spec/unit/axiom/relation/operation/order/direction/hash_spec.rb +0 -15
  306. data/spec/unit/axiom/relation/operation/order/direction_set/hash_spec.rb +0 -15
  307. data/spec/unit/axiom/relation/operation/order/hash_spec.rb +0 -15
  308. data/spec/unit/axiom/relation/operation/order/methods/sort_spec.rb +0 -19
  309. data/spec/unit/axiom/relation/proxy/hash_spec.rb +0 -26
  310. data/spec/unit/axiom/relation/proxy/method_missing_spec.rb +0 -24
  311. data/spec/unit/axiom/tuple/hash_spec.rb +0 -15
@@ -7,10 +7,10 @@ module Axiom
7
7
  module Proxy
8
8
  include Equalizer.new(:relation)
9
9
 
10
- # Relation methods to proxy
11
- ENUMERABLE_METHODS = Enumerable.public_instance_methods.map(&:to_s).freeze
12
10
  PROXY_METHODS = %w[header each empty? materialized?].freeze
13
- RELATION_METHODS = %w[take drop sort_by].freeze
11
+ ENUMERABLE_METHODS = Enumerable.public_instance_methods.map(&:to_s).freeze
12
+ RELATION_METHODS = Relation.public_instance_methods.map(&:to_s).freeze
13
+ REMOVE_METHODS = PROXY_METHODS | (ENUMERABLE_METHODS - RELATION_METHODS)
14
14
 
15
15
  # Hook called when module is included
16
16
  #
@@ -21,9 +21,8 @@ module Axiom
21
21
  #
22
22
  # @api private
23
23
  def self.included(descendant)
24
- descendant.class_eval do
25
- undef_method(*PROXY_METHODS | ENUMERABLE_METHODS - RELATION_METHODS)
26
- end
24
+ super
25
+ descendant.class_eval { undef_method(*REMOVE_METHODS) }
27
26
  end
28
27
 
29
28
  private_class_method :included
@@ -99,8 +99,6 @@ module Axiom
99
99
  # A materialized relation variable
100
100
  class Materialized < self
101
101
 
102
- private
103
-
104
102
  # Mutate and materialize the relation variable
105
103
  #
106
104
  # @return [undefined]
@@ -110,6 +108,7 @@ module Axiom
110
108
  super
111
109
  @relation = relation.materialize
112
110
  end
111
+ private :mutate_relation
113
112
 
114
113
  end # class Materialized
115
114
  end # class Variable
@@ -33,11 +33,9 @@ module Axiom
33
33
  #
34
34
  # @api private
35
35
  def define_inheritable_alias_method(new_method, original_method)
36
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
37
- def #{new_method}(*args, &block) # def |(*args, &block)
38
- self.#{original_method}(*args, &block) # self.union(*args, &block)
39
- end # end
40
- RUBY
36
+ define_method(new_method) do |*args, &block|
37
+ public_send(original_method, *args, &block)
38
+ end
41
39
  end
42
40
 
43
41
  end # module Aliasable
@@ -5,25 +5,23 @@ module Axiom
5
5
  # Define equality, equivalence and inspection methods
6
6
  class Equalizer < ::Equalizer
7
7
 
8
- # Include the #eql? and #== methods
8
+ # Hook called when module is included
9
9
  #
10
- # @return [undefined]
10
+ # @param [Module] descendant
11
+ # the module or class including Equalizer
11
12
  #
12
- # @api private
13
+ # @return [self]
13
14
  #
14
- # TODO: this monkey-patches equalizer and should be removed
15
- def initialize(*keys)
16
- @keys = keys
17
- define_methods
18
- include_comparison_methods
19
-
20
- module_eval do
15
+ # @api private
16
+ def included(descendant)
17
+ super
18
+ descendant.module_eval do
21
19
  include Adamantium
22
20
  memoize :hash
23
21
  end
24
-
25
- freeze
26
22
  end
27
23
 
24
+ private :included
25
+
28
26
  end # class Equalizer
29
27
  end # module Axiom
@@ -36,8 +36,9 @@ module Axiom
36
36
  #
37
37
  # @api private
38
38
  def initialize(left, right)
39
- @left = freeze_object(left)
40
- @right = freeze_object(right)
39
+ freezer = self.class.freezer
40
+ @left = freezer.call(left)
41
+ @right = freezer.call(right)
41
42
  end
42
43
 
43
44
  end # module Binary
@@ -24,7 +24,7 @@ module Axiom
24
24
  #
25
25
  # @api private
26
26
  def initialize(operand)
27
- @operand = freeze_object(operand)
27
+ @operand = self.class.freezer.call(operand)
28
28
  end
29
29
 
30
30
  end # module Unary
@@ -7,7 +7,7 @@ module Axiom
7
7
  extend Aliasable
8
8
  include Equalizer.new(:data)
9
9
 
10
- inheritable_alias(:[] => :call)
10
+ inheritable_alias(:[] => :fetch)
11
11
 
12
12
  # The tuple header
13
13
  #
@@ -23,6 +23,16 @@ module Axiom
23
23
  # @api private
24
24
  attr_reader :data
25
25
 
26
+ # Convert the Tuple into an Array
27
+ #
28
+ # @example
29
+ # array = tuple.to_ary
30
+ #
31
+ # @return [Array]
32
+ #
33
+ # @api public
34
+ attr_reader :to_ary
35
+
26
36
  # Initialize a Tuple
27
37
  #
28
38
  # @param [Header] header
@@ -35,7 +45,8 @@ module Axiom
35
45
  # @api private
36
46
  def initialize(header, data)
37
47
  @header = header
38
- @data = Hash[header.zip(data)]
48
+ @to_ary = self.class.freezer.call(data)
49
+ @data = Hash[header.zip(@to_ary)]
39
50
  end
40
51
 
41
52
  # Lookup a value in the tuple given an attribute
@@ -48,8 +59,8 @@ module Axiom
48
59
  # @return [Object]
49
60
  #
50
61
  # @api public
51
- def call(attribute)
52
- data.fetch(header.call(attribute))
62
+ def fetch(attribute)
63
+ data.fetch(header.fetch(attribute))
53
64
  end
54
65
 
55
66
  # Return a tuple with only the specified attributes
@@ -67,41 +78,55 @@ module Axiom
67
78
  self.class.new(header, data.values_at(*header))
68
79
  end
69
80
 
70
- # Append values to the tuple and return a new tuple
81
+ # Extend a tuple with function results
71
82
  #
72
83
  # @example
73
- # new_tuple = tuple.join(header, [1, 2, 3])
84
+ # new_tuple = tuple.extend(header, [func1, func2])
74
85
  #
75
86
  # @param [Header] header
76
87
  # the attributes to include in the tuple
77
- # @param [Array] values
78
- # the values to append
88
+ # @param [Array<Object>] extensions
89
+ # the functions to extend the tuple with
79
90
  #
80
91
  # @return [Tuple]
81
92
  #
82
93
  # @api public
83
- def join(header, values)
84
- self.class.new(header, to_ary + values)
94
+ def extend(header, extensions)
95
+ join(
96
+ header,
97
+ extensions.map { |extension| Function.extract_value(extension, self) }
98
+ )
85
99
  end
86
100
 
87
- # Extend a tuple with function results
101
+ # Rename a tuple to use a new header
88
102
  #
89
103
  # @example
90
- # new_tuple = tuple.extend(header, [func1, func2])
104
+ # new_tuple = tuple.rename(header)
105
+ #
106
+ # @param [Header] header
107
+ #
108
+ # @return [Tuple]
109
+ #
110
+ # @api public
111
+ def rename(header)
112
+ self.class.new(header, to_ary)
113
+ end
114
+
115
+ # Append values to the tuple and return a new tuple
116
+ #
117
+ # @example
118
+ # new_tuple = tuple.join(header, [1, 2, 3])
91
119
  #
92
120
  # @param [Header] header
93
121
  # the attributes to include in the tuple
94
- # @param [Array<Object>] extensions
95
- # the functions to extend the tuple with
122
+ # @param [Array] values
123
+ # the values to append
96
124
  #
97
125
  # @return [Tuple]
98
126
  #
99
127
  # @api public
100
- def extend(header, extensions)
101
- join(
102
- header,
103
- extensions.map { |extension| Function.extract_value(extension, self) }
104
- )
128
+ def join(header, values)
129
+ self.class.new(header, to_ary + values)
105
130
  end
106
131
 
107
132
  # Return the predicate matching the tuple
@@ -115,16 +140,37 @@ module Axiom
115
140
  end
116
141
  end
117
142
 
118
- # Convert the Tuple into an Array
143
+ # Coerce the tuple into a Hash
119
144
  #
120
145
  # @example
121
- # array = tuple.to_ary
146
+ # tuple.to_hash # => data as a Hash
122
147
  #
123
- # @return [Array]
148
+ # @return [Hash{Symbol => Object}]
149
+ #
150
+ # @api public
151
+ def to_hash
152
+ Hash[data.map { |attribute, value| [attribute.name, value] }]
153
+ end
154
+
155
+ # The number of attributes
156
+ #
157
+ # @return [Integer]
124
158
  #
125
159
  # @api public
126
- def to_ary
127
- data.values_at(*header).freeze
160
+ def size
161
+ header.size
162
+ end
163
+
164
+ # Display the tuple data in a human readable form
165
+ #
166
+ # @example
167
+ # tuple.inspect # => data as a String
168
+ #
169
+ # @return [String]
170
+ #
171
+ # @api public
172
+ def inspect
173
+ to_hash.inspect
128
174
  end
129
175
 
130
176
  private
@@ -152,10 +198,14 @@ module Axiom
152
198
  #
153
199
  # @api private
154
200
  def self.coerce(header, object)
155
- object.kind_of?(Tuple) ? object : new(header, object.to_ary)
201
+ if object.kind_of?(Tuple) || header.size != object.to_ary.size
202
+ object
203
+ else
204
+ new(header, object)
205
+ end
156
206
  end
157
207
 
158
- memoize :predicate, :to_ary
208
+ memoize :predicate, :to_hash, :inspect
159
209
 
160
210
  end # class Tuple
161
211
  end # module Axiom
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ module Types
5
+
6
+ # Represents a relation type
7
+ class Relation < Object
8
+
9
+ primitive Axiom::Relation
10
+
11
+ end # class Relation
12
+ end # module Types
13
+ end # module Axiom
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ module Types
5
+
6
+ # Represents a tuple type
7
+ class Tuple < Object
8
+
9
+ primitive Axiom::Tuple
10
+
11
+ end # class Tuple
12
+ end # module Types
13
+ end # module Axiom
@@ -3,6 +3,6 @@
3
3
  module Axiom
4
4
 
5
5
  # Gem version
6
- VERSION = '0.1.1'.freeze
6
+ VERSION = '0.2.0'.freeze
7
7
 
8
8
  end # module Axiom
@@ -26,17 +26,17 @@ describe Relation do
26
26
 
27
27
  it '#project should be efficient' do
28
28
  projected = relation.project([:id])
29
- sample(projected).should == [[0], [1], [2], [3], [4]]
29
+ expect(sample(projected)).to eq([[0], [1], [2], [3], [4]])
30
30
  end
31
31
 
32
32
  it '#restrict should be efficient' do
33
33
  restricted = relation.restrict { |r| r.id.gt(5) }
34
- sample(restricted).should == [[6], [7], [8], [9], [10]]
34
+ expect(sample(restricted)).to eq([[6], [7], [8], [9], [10]])
35
35
  end
36
36
 
37
37
  it '#rename should be efficient' do
38
38
  renamed = relation.rename(id: :other_id)
39
- sample(renamed).should == [[0], [1], [2], [3], [4]]
39
+ expect(sample(renamed)).to eq([[0], [1], [2], [3], [4]])
40
40
  end
41
41
 
42
42
  describe '#join should be efficient' do
@@ -45,13 +45,13 @@ describe Relation do
45
45
  it 'has an infinite left relation' do
46
46
  pending 'Change #join to handle infinite sets'
47
47
  join = other.join(relation)
48
- sample(join).should == [[1, 'Dan Kubb']]
48
+ expect(sample(join)).to eq([[1, 'Dan Kubb']])
49
49
  end
50
50
 
51
51
  it 'has an infinite right relation' do
52
52
  pending 'Change #join to handle infinite sets'
53
53
  join = relation.join(other)
54
- sample(join).should == [[1, 'Dan Kubb']]
54
+ expect(sample(join)).to eq([[1, 'Dan Kubb']])
55
55
  end
56
56
  end
57
57
 
@@ -60,24 +60,24 @@ describe Relation do
60
60
 
61
61
  it 'has an infinite left relation' do
62
62
  product = relation.product(other)
63
- sample(product).should == [[0, 'Dan Kubb'], [1, 'Dan Kubb'], [2, 'Dan Kubb'], [3, 'Dan Kubb'], [4, 'Dan Kubb']]
63
+ expect(sample(product)).to eq([[0, 'Dan Kubb'], [1, 'Dan Kubb'], [2, 'Dan Kubb'], [3, 'Dan Kubb'], [4, 'Dan Kubb']])
64
64
  end
65
65
 
66
66
  it 'has an infinite right relation' do
67
67
  pending 'Change #product to handle infinite sets'
68
68
  product = other.product(relation)
69
- sample(product).should == [[0, 'Dan Kubb'], [1, 'Dan Kubb'], [2, 'Dan Kubb'], [3, 'Dan Kubb'], [4, 'Dan Kubb']]
69
+ expect(sample(product)).to eq([[0, 'Dan Kubb'], [1, 'Dan Kubb'], [2, 'Dan Kubb'], [3, 'Dan Kubb'], [4, 'Dan Kubb']])
70
70
  end
71
71
  end
72
72
 
73
73
  it '#difference should be efficient' do
74
74
  difference = relation.difference(Relation.new(relation.header, [[1]]))
75
- sample(difference).should == [[0], [2], [3], [4], [5]]
75
+ expect(sample(difference)).to eq([[0], [2], [3], [4], [5]])
76
76
  end
77
77
 
78
78
  it '#union should be efficient' do
79
79
  union = relation.union(Relation.new(relation.header, [[1]]))
80
- sample(union).should == [[0], [1], [2], [3], [4]]
80
+ expect(sample(union)).to eq([[0], [1], [2], [3], [4]])
81
81
  end
82
82
  end
83
83
  end
@@ -14,55 +14,55 @@ describe Relation do
14
14
  it 'Rename#insert and #delete of a disjoint relation are symmetrical' do
15
15
  rename = relation.rename(id: :other_id)
16
16
  other = [[4, 'John Doe']]
17
- rename.insert(other).delete(other).should == rename
17
+ expect(rename.insert(other).delete(other)).to eq(rename)
18
18
  end
19
19
 
20
20
  it 'Projection#insert and #delete of a disjoint relation are symmetrical' do
21
21
  projection = relation.project([:id])
22
22
  other = [[4]]
23
- projection.insert(other).delete(other).should == projection
23
+ expect(projection.insert(other).delete(other)).to eq(projection)
24
24
  end
25
25
 
26
26
  it 'Extension#insert and #delete of a disjoint relation are symmetrical' do
27
27
  extension = relation.extend { |r| r.add(:age, 30) }
28
28
  other = Relation.new(relation.header, [[4, 'John Doe']]).extend(extension.extensions)
29
- extension.insert(other).delete(other).should == extension
29
+ expect(extension.insert(other).delete(other)).to eq(extension)
30
30
  end
31
31
 
32
32
  it 'Restriction#insert and #delete of a disjoint relation are symmetrical' do
33
33
  restriction = relation.restrict { |r| r.id.gte(1) }
34
34
  other = [[4, 'John Doe']]
35
- restriction.insert(other).delete(other).should == restriction
35
+ expect(restriction.insert(other).delete(other)).to eq(restriction)
36
36
  end
37
37
 
38
38
  it 'Join#insert and #delete of a disjoint relation are symmetrical' do
39
39
  join = relation + Relation.new([[:id, Integer]], [[1]])
40
40
  other = [[4, 'John Doe']]
41
- join.insert(other).delete(other).should == join
41
+ expect(join.insert(other).delete(other)).to eq(join)
42
42
  end
43
43
 
44
44
  it 'Difference#insert and #delete of a disjoint relation are symmetrical' do
45
45
  difference = relation - relation
46
46
  other = [[4, 'John Doe']]
47
- difference.insert(other).delete(other).should == difference
47
+ expect(difference.insert(other).delete(other)).to eq(difference)
48
48
  end
49
49
 
50
50
  it 'Union#insert and #delete of a disjoint relation are symmetrical' do
51
51
  union = relation | relation
52
52
  other = [[4, 'John Doe']]
53
- union.insert(other).delete(other).should == union
53
+ expect(union.insert(other).delete(other)).to eq(union)
54
54
  end
55
55
 
56
56
  it 'Intersection#insert and #delete of a disjoint relation are symmetrical' do
57
57
  intersection = relation & relation
58
58
  other = [[4, 'John Doe']]
59
- intersection.insert(other).delete(other).should == intersection
59
+ expect(intersection.insert(other).delete(other)).to eq(intersection)
60
60
  end
61
61
 
62
- it 'Order#insert and #delete of a disjoint relation are symmetrical' do
63
- order = relation.sort_by(relation.header)
64
- other = Relation.new(relation.header, [[4, 'John Doe']]).sort_by(relation.header)
65
- order.insert(other).delete(other).should == order
62
+ it 'Sorted#insert and #delete of a disjoint relation are symmetrical' do
63
+ sorted = relation.sort_by(relation.header)
64
+ other = Relation.new(relation.header, [[4, 'John Doe']]).sort_by(relation.header)
65
+ expect(sorted.insert(other).delete(other)).to eq(sorted)
66
66
  end
67
67
  end
68
68
  end