axiom 0.1.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 (648) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +37 -0
  3. data/.rspec +4 -0
  4. data/.rvmrc +1 -0
  5. data/.travis.yml +35 -0
  6. data/.yardopts +4 -0
  7. data/CONTRIBUTING.md +11 -0
  8. data/Gemfile +8 -0
  9. data/Gemfile.devtools +57 -0
  10. data/Guardfile +23 -0
  11. data/LICENSE +20 -0
  12. data/README.md +187 -0
  13. data/Rakefile +5 -0
  14. data/TODO +107 -0
  15. data/axiom.gemspec +28 -0
  16. data/benchmarks/memory.rb +173 -0
  17. data/benchmarks/speed.rb +100 -0
  18. data/config/flay.yml +3 -0
  19. data/config/flog.yml +2 -0
  20. data/config/mutant.yml +3 -0
  21. data/config/reek.yml +171 -0
  22. data/config/roodi.yml +18 -0
  23. data/config/yardstick.yml +2 -0
  24. data/lib/axiom.rb +216 -0
  25. data/lib/axiom/aggregate.rb +94 -0
  26. data/lib/axiom/aggregate/count.rb +58 -0
  27. data/lib/axiom/aggregate/maximum.rb +62 -0
  28. data/lib/axiom/aggregate/mean.rb +84 -0
  29. data/lib/axiom/aggregate/minimum.rb +62 -0
  30. data/lib/axiom/aggregate/standard_deviation.rb +61 -0
  31. data/lib/axiom/aggregate/sum.rb +83 -0
  32. data/lib/axiom/aggregate/variance.rb +84 -0
  33. data/lib/axiom/algebra/difference.rb +89 -0
  34. data/lib/axiom/algebra/extension.rb +174 -0
  35. data/lib/axiom/algebra/intersection.rb +83 -0
  36. data/lib/axiom/algebra/join.rb +204 -0
  37. data/lib/axiom/algebra/product.rb +124 -0
  38. data/lib/axiom/algebra/projection.rb +196 -0
  39. data/lib/axiom/algebra/rename.rb +115 -0
  40. data/lib/axiom/algebra/rename/aliases.rb +221 -0
  41. data/lib/axiom/algebra/restriction.rb +166 -0
  42. data/lib/axiom/algebra/summarization.rb +244 -0
  43. data/lib/axiom/algebra/summarization/summaries.rb +60 -0
  44. data/lib/axiom/algebra/summarization/summary.rb +83 -0
  45. data/lib/axiom/algebra/union.rb +85 -0
  46. data/lib/axiom/attribute.rb +207 -0
  47. data/lib/axiom/attribute/boolean.rb +41 -0
  48. data/lib/axiom/attribute/class.rb +23 -0
  49. data/lib/axiom/attribute/comparable.rb +44 -0
  50. data/lib/axiom/attribute/date.rb +38 -0
  51. data/lib/axiom/attribute/date_time.rb +38 -0
  52. data/lib/axiom/attribute/decimal.rb +23 -0
  53. data/lib/axiom/attribute/float.rb +25 -0
  54. data/lib/axiom/attribute/integer.rb +23 -0
  55. data/lib/axiom/attribute/numeric.rb +74 -0
  56. data/lib/axiom/attribute/object.rb +28 -0
  57. data/lib/axiom/attribute/string.rb +100 -0
  58. data/lib/axiom/attribute/time.rb +38 -0
  59. data/lib/axiom/core_ext/date.rb +20 -0
  60. data/lib/axiom/core_ext/range.rb +41 -0
  61. data/lib/axiom/core_ext/time.rb +20 -0
  62. data/lib/axiom/function.rb +46 -0
  63. data/lib/axiom/function/binary.rb +90 -0
  64. data/lib/axiom/function/comparable.rb +44 -0
  65. data/lib/axiom/function/connective.rb +21 -0
  66. data/lib/axiom/function/connective/conjunction.rb +78 -0
  67. data/lib/axiom/function/connective/disjunction.rb +78 -0
  68. data/lib/axiom/function/connective/negation.rb +103 -0
  69. data/lib/axiom/function/numeric.rb +11 -0
  70. data/lib/axiom/function/numeric/absolute.rb +48 -0
  71. data/lib/axiom/function/numeric/addition.rb +62 -0
  72. data/lib/axiom/function/numeric/binary.rb +26 -0
  73. data/lib/axiom/function/numeric/division.rb +71 -0
  74. data/lib/axiom/function/numeric/exponentiation.rb +69 -0
  75. data/lib/axiom/function/numeric/modulo.rb +53 -0
  76. data/lib/axiom/function/numeric/multiplication.rb +62 -0
  77. data/lib/axiom/function/numeric/square_root.rb +75 -0
  78. data/lib/axiom/function/numeric/subtraction.rb +62 -0
  79. data/lib/axiom/function/numeric/unary.rb +26 -0
  80. data/lib/axiom/function/numeric/unary_minus.rb +60 -0
  81. data/lib/axiom/function/numeric/unary_plus.rb +60 -0
  82. data/lib/axiom/function/predicate.rb +26 -0
  83. data/lib/axiom/function/predicate/enumerable.rb +57 -0
  84. data/lib/axiom/function/predicate/equality.rb +67 -0
  85. data/lib/axiom/function/predicate/exclusion.rb +60 -0
  86. data/lib/axiom/function/predicate/greater_than.rb +67 -0
  87. data/lib/axiom/function/predicate/greater_than_or_equal_to.rb +67 -0
  88. data/lib/axiom/function/predicate/inclusion.rb +60 -0
  89. data/lib/axiom/function/predicate/inequality.rb +82 -0
  90. data/lib/axiom/function/predicate/less_than.rb +67 -0
  91. data/lib/axiom/function/predicate/less_than_or_equal_to.rb +67 -0
  92. data/lib/axiom/function/predicate/match.rb +67 -0
  93. data/lib/axiom/function/predicate/no_match.rb +70 -0
  94. data/lib/axiom/function/proposition.rb +97 -0
  95. data/lib/axiom/function/proposition/contradiction.rb +66 -0
  96. data/lib/axiom/function/proposition/tautology.rb +66 -0
  97. data/lib/axiom/function/string/length.rb +55 -0
  98. data/lib/axiom/function/unary.rb +124 -0
  99. data/lib/axiom/relation.rb +268 -0
  100. data/lib/axiom/relation/base.rb +39 -0
  101. data/lib/axiom/relation/empty.rb +52 -0
  102. data/lib/axiom/relation/header.rb +349 -0
  103. data/lib/axiom/relation/keys.rb +282 -0
  104. data/lib/axiom/relation/materialized.rb +71 -0
  105. data/lib/axiom/relation/operation/binary.rb +77 -0
  106. data/lib/axiom/relation/operation/combination.rb +37 -0
  107. data/lib/axiom/relation/operation/deletion.rb +45 -0
  108. data/lib/axiom/relation/operation/insertion.rb +45 -0
  109. data/lib/axiom/relation/operation/limit.rb +211 -0
  110. data/lib/axiom/relation/operation/offset.rb +174 -0
  111. data/lib/axiom/relation/operation/order.rb +204 -0
  112. data/lib/axiom/relation/operation/order/direction.rb +182 -0
  113. data/lib/axiom/relation/operation/order/direction_set.rb +107 -0
  114. data/lib/axiom/relation/operation/reverse.rb +86 -0
  115. data/lib/axiom/relation/operation/set.rb +79 -0
  116. data/lib/axiom/relation/operation/unary.rb +24 -0
  117. data/lib/axiom/relation/proxy.rb +84 -0
  118. data/lib/axiom/support/aliasable.rb +44 -0
  119. data/lib/axiom/support/equalizer.rb +22 -0
  120. data/lib/axiom/support/evaluator.rb +122 -0
  121. data/lib/axiom/support/operation/binary.rb +45 -0
  122. data/lib/axiom/support/operation/unary.rb +32 -0
  123. data/lib/axiom/support/visitable.rb +25 -0
  124. data/lib/axiom/tuple.rb +161 -0
  125. data/lib/axiom/version.rb +8 -0
  126. data/spec/integration/axiom/algebra/join_spec.rb +16 -0
  127. data/spec/integration/axiom/algebra/product_spec.rb +16 -0
  128. data/spec/integration/axiom/algebra/projection_spec.rb +18 -0
  129. data/spec/integration/axiom/algebra/summarization_spec.rb +35 -0
  130. data/spec/integration/axiom/relation/efficient_enumerable_spec.rb +83 -0
  131. data/spec/integration/axiom/relation/writable_relations_spec.rb +68 -0
  132. data/spec/shared/invertible_method_behaviour.rb +9 -0
  133. data/spec/spec_helper.rb +46 -0
  134. data/spec/support/config_alias.rb +3 -0
  135. data/spec/support/ice_nine_config.rb +6 -0
  136. data/spec/support/lazy_enumerable.rb +18 -0
  137. data/spec/unit/axiom/aggregate/call_spec.rb +43 -0
  138. data/spec/unit/axiom/aggregate/class_methods/call_spec.rb +11 -0
  139. data/spec/unit/axiom/aggregate/class_methods/default_spec.rb +11 -0
  140. data/spec/unit/axiom/aggregate/class_methods/finalize_spec.rb +12 -0
  141. data/spec/unit/axiom/aggregate/count/class_methods/call_spec.rb +30 -0
  142. data/spec/unit/axiom/aggregate/count/class_methods/default_spec.rb +13 -0
  143. data/spec/unit/axiom/aggregate/count/methods/count_spec.rb +14 -0
  144. data/spec/unit/axiom/aggregate/count/type_spec.rb +12 -0
  145. data/spec/unit/axiom/aggregate/default_spec.rb +17 -0
  146. data/spec/unit/axiom/aggregate/equality_operator_spec.rb +52 -0
  147. data/spec/unit/axiom/aggregate/finalize_spec.rb +18 -0
  148. data/spec/unit/axiom/aggregate/hash_spec.rb +15 -0
  149. data/spec/unit/axiom/aggregate/maximum/class_methods/call_spec.rb +36 -0
  150. data/spec/unit/axiom/aggregate/maximum/class_methods/default_spec.rb +13 -0
  151. data/spec/unit/axiom/aggregate/maximum/methods/maximum_spec.rb +16 -0
  152. data/spec/unit/axiom/aggregate/maximum/type_spec.rb +20 -0
  153. data/spec/unit/axiom/aggregate/mean/class_methods/call_spec.rb +38 -0
  154. data/spec/unit/axiom/aggregate/mean/class_methods/default_spec.rb +15 -0
  155. data/spec/unit/axiom/aggregate/mean/class_methods/finalize_spec.rb +16 -0
  156. data/spec/unit/axiom/aggregate/mean/methods/mean_spec.rb +16 -0
  157. data/spec/unit/axiom/aggregate/mean/type_spec.rb +12 -0
  158. data/spec/unit/axiom/aggregate/minimum/class_methods/call_spec.rb +36 -0
  159. data/spec/unit/axiom/aggregate/minimum/class_methods/default_spec.rb +13 -0
  160. data/spec/unit/axiom/aggregate/minimum/methods/minimum_spec.rb +16 -0
  161. data/spec/unit/axiom/aggregate/minimum/type_spec.rb +20 -0
  162. data/spec/unit/axiom/aggregate/standard_deviation/class_methods/finalize_spec.rb +34 -0
  163. data/spec/unit/axiom/aggregate/standard_deviation/methods/standard_deviation_spec.rb +16 -0
  164. data/spec/unit/axiom/aggregate/standard_deviation/type_spec.rb +12 -0
  165. data/spec/unit/axiom/aggregate/sum/class_methods/call_spec.rb +30 -0
  166. data/spec/unit/axiom/aggregate/sum/class_methods/default_spec.rb +13 -0
  167. data/spec/unit/axiom/aggregate/sum/default_spec.rb +33 -0
  168. data/spec/unit/axiom/aggregate/sum/methods/sum_spec.rb +14 -0
  169. data/spec/unit/axiom/aggregate/sum/type_spec.rb +20 -0
  170. data/spec/unit/axiom/aggregate/type_spec.rb +13 -0
  171. data/spec/unit/axiom/aggregate/variance/class_methods/call_spec.rb +52 -0
  172. data/spec/unit/axiom/aggregate/variance/class_methods/default_spec.rb +15 -0
  173. data/spec/unit/axiom/aggregate/variance/class_methods/finalize_spec.rb +26 -0
  174. data/spec/unit/axiom/aggregate/variance/methods/variance_spec.rb +16 -0
  175. data/spec/unit/axiom/aggregate/variance/type_spec.rb +12 -0
  176. data/spec/unit/axiom/algebra/difference/delete_spec.rb +44 -0
  177. data/spec/unit/axiom/algebra/difference/each_spec.rb +45 -0
  178. data/spec/unit/axiom/algebra/difference/insert_spec.rb +44 -0
  179. data/spec/unit/axiom/algebra/difference/methods/difference_spec.rb +20 -0
  180. data/spec/unit/axiom/algebra/extension/class_methods/new_spec.rb +22 -0
  181. data/spec/unit/axiom/algebra/extension/delete_spec.rb +47 -0
  182. data/spec/unit/axiom/algebra/extension/each_spec.rb +30 -0
  183. data/spec/unit/axiom/algebra/extension/eql_spec.rb +65 -0
  184. data/spec/unit/axiom/algebra/extension/extensions_spec.rb +15 -0
  185. data/spec/unit/axiom/algebra/extension/hash_spec.rb +15 -0
  186. data/spec/unit/axiom/algebra/extension/header_spec.rb +17 -0
  187. data/spec/unit/axiom/algebra/extension/insert_spec.rb +47 -0
  188. data/spec/unit/axiom/algebra/extension/methods/extend_spec.rb +34 -0
  189. data/spec/unit/axiom/algebra/extension/operand_spec.rb +15 -0
  190. data/spec/unit/axiom/algebra/intersection/delete_spec.rb +44 -0
  191. data/spec/unit/axiom/algebra/intersection/each_spec.rb +45 -0
  192. data/spec/unit/axiom/algebra/intersection/insert_spec.rb +44 -0
  193. data/spec/unit/axiom/algebra/intersection/methods/intersect_spec.rb +20 -0
  194. data/spec/unit/axiom/algebra/join/class_methods/new_spec.rb +29 -0
  195. data/spec/unit/axiom/algebra/join/delete_spec.rb +43 -0
  196. data/spec/unit/axiom/algebra/join/each_spec.rb +77 -0
  197. data/spec/unit/axiom/algebra/join/insert_spec.rb +43 -0
  198. data/spec/unit/axiom/algebra/join/join_header_spec.rb +17 -0
  199. data/spec/unit/axiom/algebra/join/methods/join_spec.rb +35 -0
  200. data/spec/unit/axiom/algebra/product/class_methods/new_spec.rb +29 -0
  201. data/spec/unit/axiom/algebra/product/delete_spec.rb +14 -0
  202. data/spec/unit/axiom/algebra/product/each_spec.rb +31 -0
  203. data/spec/unit/axiom/algebra/product/insert_spec.rb +14 -0
  204. data/spec/unit/axiom/algebra/product/methods/product_spec.rb +15 -0
  205. data/spec/unit/axiom/algebra/projection/delete_spec.rb +58 -0
  206. data/spec/unit/axiom/algebra/projection/each_spec.rb +30 -0
  207. data/spec/unit/axiom/algebra/projection/eql_spec.rb +66 -0
  208. data/spec/unit/axiom/algebra/projection/hash_spec.rb +16 -0
  209. data/spec/unit/axiom/algebra/projection/header_spec.rb +16 -0
  210. data/spec/unit/axiom/algebra/projection/insert_spec.rb +66 -0
  211. data/spec/unit/axiom/algebra/projection/methods/project_spec.rb +19 -0
  212. data/spec/unit/axiom/algebra/projection/methods/remove_spec.rb +19 -0
  213. data/spec/unit/axiom/algebra/rename/aliases/class_methods/coerce_spec.rb +59 -0
  214. data/spec/unit/axiom/algebra/rename/aliases/class_methods/new_spec.rb +23 -0
  215. data/spec/unit/axiom/algebra/rename/aliases/each_spec.rb +20 -0
  216. data/spec/unit/axiom/algebra/rename/aliases/element_reader_spec.rb +23 -0
  217. data/spec/unit/axiom/algebra/rename/aliases/empty_predicate_spec.rb +22 -0
  218. data/spec/unit/axiom/algebra/rename/aliases/eql_spec.rb +52 -0
  219. data/spec/unit/axiom/algebra/rename/aliases/equality_operator_spec.rb +52 -0
  220. data/spec/unit/axiom/algebra/rename/aliases/hash_spec.rb +15 -0
  221. data/spec/unit/axiom/algebra/rename/aliases/inverse_spec.rb +30 -0
  222. data/spec/unit/axiom/algebra/rename/aliases/to_hash_spec.rb +32 -0
  223. data/spec/unit/axiom/algebra/rename/aliases/union_spec.rb +66 -0
  224. data/spec/unit/axiom/algebra/rename/aliases_spec.rb +13 -0
  225. data/spec/unit/axiom/algebra/rename/delete_spec.rb +45 -0
  226. data/spec/unit/axiom/algebra/rename/directions_spec.rb +30 -0
  227. data/spec/unit/axiom/algebra/rename/each_spec.rb +29 -0
  228. data/spec/unit/axiom/algebra/rename/eql_spec.rb +65 -0
  229. data/spec/unit/axiom/algebra/rename/hash_spec.rb +15 -0
  230. data/spec/unit/axiom/algebra/rename/header_spec.rb +16 -0
  231. data/spec/unit/axiom/algebra/rename/insert_spec.rb +45 -0
  232. data/spec/unit/axiom/algebra/rename/methods/rename_spec.rb +14 -0
  233. data/spec/unit/axiom/algebra/restriction/delete_spec.rb +50 -0
  234. data/spec/unit/axiom/algebra/restriction/each_spec.rb +88 -0
  235. data/spec/unit/axiom/algebra/restriction/eql_spec.rb +65 -0
  236. data/spec/unit/axiom/algebra/restriction/hash_spec.rb +15 -0
  237. data/spec/unit/axiom/algebra/restriction/insert_spec.rb +50 -0
  238. data/spec/unit/axiom/algebra/restriction/methods/restrict_spec.rb +78 -0
  239. data/spec/unit/axiom/algebra/restriction/predicate_spec.rb +15 -0
  240. data/spec/unit/axiom/algebra/summarization/class_methods/new_spec.rb +30 -0
  241. data/spec/unit/axiom/algebra/summarization/delete_spec.rb +15 -0
  242. data/spec/unit/axiom/algebra/summarization/each_spec.rb +30 -0
  243. data/spec/unit/axiom/algebra/summarization/eql_spec.rb +81 -0
  244. data/spec/unit/axiom/algebra/summarization/hash_spec.rb +16 -0
  245. data/spec/unit/axiom/algebra/summarization/header_spec.rb +17 -0
  246. data/spec/unit/axiom/algebra/summarization/insert_spec.rb +15 -0
  247. data/spec/unit/axiom/algebra/summarization/methods/summarize_spec.rb +81 -0
  248. data/spec/unit/axiom/algebra/summarization/summaries/summarize_by_spec.rb +28 -0
  249. data/spec/unit/axiom/algebra/summarization/summaries/to_hash_spec.rb +17 -0
  250. data/spec/unit/axiom/algebra/summarization/summarize_per_spec.rb +15 -0
  251. data/spec/unit/axiom/algebra/summarization/summarizers_spec.rb +15 -0
  252. data/spec/unit/axiom/algebra/summarization/summary/call_spec.rb +43 -0
  253. data/spec/unit/axiom/algebra/summarization/summary/summarize_by_spec.rb +20 -0
  254. data/spec/unit/axiom/algebra/union/delete_spec.rb +44 -0
  255. data/spec/unit/axiom/algebra/union/each_spec.rb +56 -0
  256. data/spec/unit/axiom/algebra/union/insert_spec.rb +44 -0
  257. data/spec/unit/axiom/algebra/union/methods/union_spec.rb +20 -0
  258. data/spec/unit/axiom/aliasable/fixtures/classes.rb +9 -0
  259. data/spec/unit/axiom/aliasable/inheritable_alias_spec.rb +50 -0
  260. data/spec/unit/axiom/attribute/boolean/class_methods/primitive_spec.rb +13 -0
  261. data/spec/unit/axiom/attribute/boolean/valid_value_predicate_spec.rb +27 -0
  262. data/spec/unit/axiom/attribute/call_spec.rb +14 -0
  263. data/spec/unit/axiom/attribute/class/class_methods/primitive_spec.rb +13 -0
  264. data/spec/unit/axiom/attribute/class_methods/coerce_spec.rb +91 -0
  265. data/spec/unit/axiom/attribute/class_methods/infer_type_spec.rb +121 -0
  266. data/spec/unit/axiom/attribute/class_methods/name_from_spec.rb +33 -0
  267. data/spec/unit/axiom/attribute/class_methods/new_spec.rb +41 -0
  268. data/spec/unit/axiom/attribute/comparable/asc_spec.rb +13 -0
  269. data/spec/unit/axiom/attribute/comparable/desc_spec.rb +13 -0
  270. data/spec/unit/axiom/attribute/comparable/fixtures/classes.rb +7 -0
  271. data/spec/unit/axiom/attribute/date/class_methods/primitive_spec.rb +13 -0
  272. data/spec/unit/axiom/attribute/date/range_spec.rb +11 -0
  273. data/spec/unit/axiom/attribute/date_time/class_methods/primitive_spec.rb +13 -0
  274. data/spec/unit/axiom/attribute/date_time/range_spec.rb +11 -0
  275. data/spec/unit/axiom/attribute/decimal/class_methods/primitive_spec.rb +13 -0
  276. data/spec/unit/axiom/attribute/eql_spec.rb +61 -0
  277. data/spec/unit/axiom/attribute/equality_operator_spec.rb +61 -0
  278. data/spec/unit/axiom/attribute/float/class_methods/primitive_spec.rb +13 -0
  279. data/spec/unit/axiom/attribute/float/size_spec.rb +21 -0
  280. data/spec/unit/axiom/attribute/hash_spec.rb +17 -0
  281. data/spec/unit/axiom/attribute/integer/class_methods/primitive_spec.rb +13 -0
  282. data/spec/unit/axiom/attribute/name_spec.rb +24 -0
  283. data/spec/unit/axiom/attribute/numeric/class_methods/primitive_spec.rb +13 -0
  284. data/spec/unit/axiom/attribute/numeric/eql_spec.rb +71 -0
  285. data/spec/unit/axiom/attribute/numeric/equality_operator_spec.rb +71 -0
  286. data/spec/unit/axiom/attribute/numeric/hash_spec.rb +17 -0
  287. data/spec/unit/axiom/attribute/numeric/size_spec.rb +33 -0
  288. data/spec/unit/axiom/attribute/numeric/valid_value_predicate_spec.rb +35 -0
  289. data/spec/unit/axiom/attribute/object/class_methods/primitive_spec.rb +13 -0
  290. data/spec/unit/axiom/attribute/rename_spec.rb +28 -0
  291. data/spec/unit/axiom/attribute/required_predicate_spec.rb +27 -0
  292. data/spec/unit/axiom/attribute/string/class_methods/primitive_spec.rb +13 -0
  293. data/spec/unit/axiom/attribute/string/eql_spec.rb +81 -0
  294. data/spec/unit/axiom/attribute/string/equality_operator_spec.rb +81 -0
  295. data/spec/unit/axiom/attribute/string/hash_spec.rb +25 -0
  296. data/spec/unit/axiom/attribute/string/max_length_spec.rb +20 -0
  297. data/spec/unit/axiom/attribute/string/min_length_spec.rb +20 -0
  298. data/spec/unit/axiom/attribute/string/valid_value_predicate_spec.rb +35 -0
  299. data/spec/unit/axiom/attribute/time/class_methods/primitive_spec.rb +13 -0
  300. data/spec/unit/axiom/attribute/time/range_spec.rb +11 -0
  301. data/spec/unit/axiom/attribute/type_spec.rb +12 -0
  302. data/spec/unit/axiom/attribute/valid_primitive_predicate_spec.rb +30 -0
  303. data/spec/unit/axiom/attribute/valid_value_predicate_spec.rb +47 -0
  304. data/spec/unit/axiom/equalizer/class_method/new_spec.rb +137 -0
  305. data/spec/unit/axiom/equalizer/methods/eql_spec.rb +49 -0
  306. data/spec/unit/axiom/equalizer/methods/equality_operator_spec.rb +85 -0
  307. data/spec/unit/axiom/evaluator/context/add_spec.rb +66 -0
  308. data/spec/unit/axiom/evaluator/context/element_reader_spec.rb +14 -0
  309. data/spec/unit/axiom/evaluator/context/functions_spec.rb +16 -0
  310. data/spec/unit/axiom/evaluator/context/method_missing_spec.rb +29 -0
  311. data/spec/unit/axiom/evaluator/context/respond_to_predicate_spec.rb +39 -0
  312. data/spec/unit/axiom/evaluator/context/send_spec.rb +28 -0
  313. data/spec/unit/axiom/evaluator/context/yield_spec.rb +14 -0
  314. data/spec/unit/axiom/function/binary/call_spec.rb +22 -0
  315. data/spec/unit/axiom/function/binary/equality_operator_spec.rb +67 -0
  316. data/spec/unit/axiom/function/binary/fixtures/classes.rb +12 -0
  317. data/spec/unit/axiom/function/binary/invertible/class_methods/included_spec.rb +29 -0
  318. data/spec/unit/axiom/function/binary/invertible/inverse_spec.rb +47 -0
  319. data/spec/unit/axiom/function/binary/rename_spec.rb +55 -0
  320. data/spec/unit/axiom/function/class_methods/call_spec.rb +11 -0
  321. data/spec/unit/axiom/function/class_methods/extract_value_spec.rb +23 -0
  322. data/spec/unit/axiom/function/class_methods/rename_attributes_spec.rb +29 -0
  323. data/spec/unit/axiom/function/comparable/class_methods/call_spec.rb +14 -0
  324. data/spec/unit/axiom/function/comparable/class_methods/included_spec.rb +26 -0
  325. data/spec/unit/axiom/function/comparable/fixtures/classes.rb +23 -0
  326. data/spec/unit/axiom/function/connective/conjunction/class_methods/call_spec.rb +37 -0
  327. data/spec/unit/axiom/function/connective/conjunction/inverse_spec.rb +20 -0
  328. data/spec/unit/axiom/function/connective/conjunction/methods/and_spec.rb +19 -0
  329. data/spec/unit/axiom/function/connective/conjunction/methods/fixtures/classes.rb +7 -0
  330. data/spec/unit/axiom/function/connective/disjunction/class_methods/call_spec.rb +37 -0
  331. data/spec/unit/axiom/function/connective/disjunction/inverse_spec.rb +20 -0
  332. data/spec/unit/axiom/function/connective/disjunction/methods/fixtures/classes.rb +7 -0
  333. data/spec/unit/axiom/function/connective/disjunction/methods/or_spec.rb +19 -0
  334. data/spec/unit/axiom/function/connective/negation/class_methods/call_spec.rb +21 -0
  335. data/spec/unit/axiom/function/connective/negation/class_methods/operation_spec.rb +11 -0
  336. data/spec/unit/axiom/function/connective/negation/inverse_spec.rb +21 -0
  337. data/spec/unit/axiom/function/connective/negation/methods/fixtures/classes.rb +8 -0
  338. data/spec/unit/axiom/function/connective/negation/methods/not_spec.rb +39 -0
  339. data/spec/unit/axiom/function/connective/type_spec.rb +12 -0
  340. data/spec/unit/axiom/function/fixtures/classes.rb +6 -0
  341. data/spec/unit/axiom/function/numeric/absolute/class_methods/call_spec.rb +21 -0
  342. data/spec/unit/axiom/function/numeric/absolute/class_methods/operation_spec.rb +11 -0
  343. data/spec/unit/axiom/function/numeric/absolute/methods/absolute_spec.rb +16 -0
  344. data/spec/unit/axiom/function/numeric/addition/class_methods/call_spec.rb +13 -0
  345. data/spec/unit/axiom/function/numeric/addition/class_methods/inverse_spec.rb +13 -0
  346. data/spec/unit/axiom/function/numeric/addition/class_methods/operation_spec.rb +11 -0
  347. data/spec/unit/axiom/function/numeric/addition/methods/add_spec.rb +19 -0
  348. data/spec/unit/axiom/function/numeric/binary/type_spec.rb +33 -0
  349. data/spec/unit/axiom/function/numeric/division/class_methods/call_spec.rb +13 -0
  350. data/spec/unit/axiom/function/numeric/division/class_methods/inverse_spec.rb +13 -0
  351. data/spec/unit/axiom/function/numeric/division/class_methods/operation_spec.rb +11 -0
  352. data/spec/unit/axiom/function/numeric/division/methods/divide_spec.rb +19 -0
  353. data/spec/unit/axiom/function/numeric/division/type_spec.rb +11 -0
  354. data/spec/unit/axiom/function/numeric/exponentiation/class_methods/call_spec.rb +13 -0
  355. data/spec/unit/axiom/function/numeric/exponentiation/class_methods/operation_spec.rb +11 -0
  356. data/spec/unit/axiom/function/numeric/exponentiation/inverse_spec.rb +18 -0
  357. data/spec/unit/axiom/function/numeric/exponentiation/methods/exponent_spec.rb +19 -0
  358. data/spec/unit/axiom/function/numeric/modulo/class_methods/call_spec.rb +13 -0
  359. data/spec/unit/axiom/function/numeric/modulo/class_methods/operation_spec.rb +11 -0
  360. data/spec/unit/axiom/function/numeric/modulo/methods/modulo_spec.rb +19 -0
  361. data/spec/unit/axiom/function/numeric/multiplication/class_methods/call_spec.rb +13 -0
  362. data/spec/unit/axiom/function/numeric/multiplication/class_methods/inverse_spec.rb +13 -0
  363. data/spec/unit/axiom/function/numeric/multiplication/class_methods/operation_spec.rb +11 -0
  364. data/spec/unit/axiom/function/numeric/multiplication/methods/multiply_spec.rb +19 -0
  365. data/spec/unit/axiom/function/numeric/square_root/class_methods/call_spec.rb +12 -0
  366. data/spec/unit/axiom/function/numeric/square_root/inverse_spec.rb +18 -0
  367. data/spec/unit/axiom/function/numeric/square_root/methods/square_root_spec.rb +16 -0
  368. data/spec/unit/axiom/function/numeric/square_root/type_spec.rb +11 -0
  369. data/spec/unit/axiom/function/numeric/subtraction/class_methods/call_spec.rb +13 -0
  370. data/spec/unit/axiom/function/numeric/subtraction/class_methods/inverse_spec.rb +13 -0
  371. data/spec/unit/axiom/function/numeric/subtraction/class_methods/operation_spec.rb +11 -0
  372. data/spec/unit/axiom/function/numeric/subtraction/methods/subtract_spec.rb +19 -0
  373. data/spec/unit/axiom/function/numeric/unary/type_spec.rb +21 -0
  374. data/spec/unit/axiom/function/numeric/unary_minus/class_methods/call_spec.rb +21 -0
  375. data/spec/unit/axiom/function/numeric/unary_minus/class_methods/inverse_spec.rb +13 -0
  376. data/spec/unit/axiom/function/numeric/unary_minus/class_methods/operation_spec.rb +11 -0
  377. data/spec/unit/axiom/function/numeric/unary_minus/methods/unary_minus_spec.rb +16 -0
  378. data/spec/unit/axiom/function/numeric/unary_plus/class_methods/call_spec.rb +21 -0
  379. data/spec/unit/axiom/function/numeric/unary_plus/class_methods/inverse_spec.rb +13 -0
  380. data/spec/unit/axiom/function/numeric/unary_plus/class_methods/operation_spec.rb +11 -0
  381. data/spec/unit/axiom/function/numeric/unary_plus/methods/unary_plus_spec.rb +16 -0
  382. data/spec/unit/axiom/function/predicate/call_spec.rb +18 -0
  383. data/spec/unit/axiom/function/predicate/class_methods/call_spec.rb +13 -0
  384. data/spec/unit/axiom/function/predicate/enumerable/call_spec.rb +36 -0
  385. data/spec/unit/axiom/function/predicate/enumerable/class_methods/compare_method_spec.rb +21 -0
  386. data/spec/unit/axiom/function/predicate/eql_spec.rb +66 -0
  387. data/spec/unit/axiom/function/predicate/equality/class_methods/call_spec.rb +23 -0
  388. data/spec/unit/axiom/function/predicate/equality/class_methods/inverse_spec.rb +13 -0
  389. data/spec/unit/axiom/function/predicate/equality/class_methods/operation_spec.rb +11 -0
  390. data/spec/unit/axiom/function/predicate/equality/class_methods/reverse_spec.rb +11 -0
  391. data/spec/unit/axiom/function/predicate/equality/inverse_spec.rb +18 -0
  392. data/spec/unit/axiom/function/predicate/equality/methods/eq_spec.rb +14 -0
  393. data/spec/unit/axiom/function/predicate/equality/methods/fixtures/classes.rb +7 -0
  394. data/spec/unit/axiom/function/predicate/exclusion/class_methods/call_spec.rb +23 -0
  395. data/spec/unit/axiom/function/predicate/exclusion/class_methods/inverse_spec.rb +13 -0
  396. data/spec/unit/axiom/function/predicate/exclusion/inverse_spec.rb +19 -0
  397. data/spec/unit/axiom/function/predicate/exclusion/methods/exclude_spec.rb +14 -0
  398. data/spec/unit/axiom/function/predicate/exclusion/methods/fixtures/classes.rb +7 -0
  399. data/spec/unit/axiom/function/predicate/fixtures/classes.rb +10 -0
  400. data/spec/unit/axiom/function/predicate/greater_than/class_methods/call_spec.rb +30 -0
  401. data/spec/unit/axiom/function/predicate/greater_than/class_methods/inverse_spec.rb +13 -0
  402. data/spec/unit/axiom/function/predicate/greater_than/class_methods/operation_spec.rb +11 -0
  403. data/spec/unit/axiom/function/predicate/greater_than/class_methods/reverse_spec.rb +11 -0
  404. data/spec/unit/axiom/function/predicate/greater_than/inverse_spec.rb +18 -0
  405. data/spec/unit/axiom/function/predicate/greater_than/methods/fixtures/classes.rb +7 -0
  406. data/spec/unit/axiom/function/predicate/greater_than/methods/gt_spec.rb +14 -0
  407. data/spec/unit/axiom/function/predicate/greater_than_or_equal_to/class_methods/call_spec.rb +30 -0
  408. data/spec/unit/axiom/function/predicate/greater_than_or_equal_to/class_methods/inverse_spec.rb +13 -0
  409. data/spec/unit/axiom/function/predicate/greater_than_or_equal_to/class_methods/operation_spec.rb +11 -0
  410. data/spec/unit/axiom/function/predicate/greater_than_or_equal_to/class_methods/reverse_spec.rb +11 -0
  411. data/spec/unit/axiom/function/predicate/greater_than_or_equal_to/inverse_spec.rb +18 -0
  412. data/spec/unit/axiom/function/predicate/greater_than_or_equal_to/methods/fixtures/classes.rb +7 -0
  413. data/spec/unit/axiom/function/predicate/greater_than_or_equal_to/methods/gte_spec.rb +14 -0
  414. data/spec/unit/axiom/function/predicate/hash_spec.rb +16 -0
  415. data/spec/unit/axiom/function/predicate/inclusion/class_methods/call_spec.rb +23 -0
  416. data/spec/unit/axiom/function/predicate/inclusion/class_methods/inverse_spec.rb +13 -0
  417. data/spec/unit/axiom/function/predicate/inclusion/inverse_spec.rb +19 -0
  418. data/spec/unit/axiom/function/predicate/inclusion/methods/fixtures/classes.rb +7 -0
  419. data/spec/unit/axiom/function/predicate/inclusion/methods/include_spec.rb +14 -0
  420. data/spec/unit/axiom/function/predicate/inequality/class_methods/call_spec.rb +23 -0
  421. data/spec/unit/axiom/function/predicate/inequality/class_methods/inverse_spec.rb +13 -0
  422. data/spec/unit/axiom/function/predicate/inequality/class_methods/operation_spec.rb +11 -0
  423. data/spec/unit/axiom/function/predicate/inequality/class_methods/reverse_spec.rb +11 -0
  424. data/spec/unit/axiom/function/predicate/inequality/inverse_spec.rb +18 -0
  425. data/spec/unit/axiom/function/predicate/inequality/methods/fixtures/classes.rb +7 -0
  426. data/spec/unit/axiom/function/predicate/inequality/methods/ne_spec.rb +14 -0
  427. data/spec/unit/axiom/function/predicate/inverse_spec.rb +17 -0
  428. data/spec/unit/axiom/function/predicate/less_than/class_methods/call_spec.rb +30 -0
  429. data/spec/unit/axiom/function/predicate/less_than/class_methods/inverse_spec.rb +13 -0
  430. data/spec/unit/axiom/function/predicate/less_than/class_methods/operation_spec.rb +11 -0
  431. data/spec/unit/axiom/function/predicate/less_than/class_methods/reverse_spec.rb +11 -0
  432. data/spec/unit/axiom/function/predicate/less_than/inverse_spec.rb +18 -0
  433. data/spec/unit/axiom/function/predicate/less_than/methods/fixtures/classes.rb +7 -0
  434. data/spec/unit/axiom/function/predicate/less_than/methods/lt_spec.rb +14 -0
  435. data/spec/unit/axiom/function/predicate/less_than_or_equal_to/class_methods/call_spec.rb +30 -0
  436. data/spec/unit/axiom/function/predicate/less_than_or_equal_to/class_methods/inverse_spec.rb +13 -0
  437. data/spec/unit/axiom/function/predicate/less_than_or_equal_to/class_methods/operation_spec.rb +11 -0
  438. data/spec/unit/axiom/function/predicate/less_than_or_equal_to/class_methods/reverse_spec.rb +11 -0
  439. data/spec/unit/axiom/function/predicate/less_than_or_equal_to/inverse_spec.rb +18 -0
  440. data/spec/unit/axiom/function/predicate/less_than_or_equal_to/methods/fixtures/classes.rb +7 -0
  441. data/spec/unit/axiom/function/predicate/less_than_or_equal_to/methods/lte_spec.rb +14 -0
  442. data/spec/unit/axiom/function/predicate/match/class_methods/call_spec.rb +23 -0
  443. data/spec/unit/axiom/function/predicate/match/class_methods/inverse_spec.rb +13 -0
  444. data/spec/unit/axiom/function/predicate/match/class_methods/operation_spec.rb +11 -0
  445. data/spec/unit/axiom/function/predicate/match/inverse_spec.rb +19 -0
  446. data/spec/unit/axiom/function/predicate/match/methods/fixtures/classes.rb +7 -0
  447. data/spec/unit/axiom/function/predicate/match/methods/match_spec.rb +14 -0
  448. data/spec/unit/axiom/function/predicate/no_match/class_methods/call_spec.rb +23 -0
  449. data/spec/unit/axiom/function/predicate/no_match/class_methods/inverse_spec.rb +13 -0
  450. data/spec/unit/axiom/function/predicate/no_match/class_methods/operation_spec.rb +11 -0
  451. data/spec/unit/axiom/function/predicate/no_match/inverse_spec.rb +19 -0
  452. data/spec/unit/axiom/function/predicate/no_match/methods/fixtures/classes.rb +7 -0
  453. data/spec/unit/axiom/function/predicate/no_match/methods/no_match_spec.rb +14 -0
  454. data/spec/unit/axiom/function/predicate/type_spec.rb +14 -0
  455. data/spec/unit/axiom/function/proposition/call_spec.rb +16 -0
  456. data/spec/unit/axiom/function/proposition/class_methods/call_spec.rb +11 -0
  457. data/spec/unit/axiom/function/proposition/class_methods/new_spec.rb +45 -0
  458. data/spec/unit/axiom/function/proposition/contradiction/and_spec.rb +12 -0
  459. data/spec/unit/axiom/function/proposition/contradiction/class_methods/call_spec.rb +11 -0
  460. data/spec/unit/axiom/function/proposition/contradiction/class_methods/inverse_spec.rb +13 -0
  461. data/spec/unit/axiom/function/proposition/contradiction/inverse_spec.rb +13 -0
  462. data/spec/unit/axiom/function/proposition/contradiction/or_spec.rb +12 -0
  463. data/spec/unit/axiom/function/proposition/eql_spec.rb +40 -0
  464. data/spec/unit/axiom/function/proposition/equality_operator_spec.rb +40 -0
  465. data/spec/unit/axiom/function/proposition/hash_spec.rb +14 -0
  466. data/spec/unit/axiom/function/proposition/inverse_spec.rb +28 -0
  467. data/spec/unit/axiom/function/proposition/rename_spec.rb +16 -0
  468. data/spec/unit/axiom/function/proposition/tautology/and_spec.rb +12 -0
  469. data/spec/unit/axiom/function/proposition/tautology/class_methods/call_spec.rb +11 -0
  470. data/spec/unit/axiom/function/proposition/tautology/class_methods/inverse_spec.rb +13 -0
  471. data/spec/unit/axiom/function/proposition/tautology/inverse_spec.rb +13 -0
  472. data/spec/unit/axiom/function/proposition/tautology/or_spec.rb +12 -0
  473. data/spec/unit/axiom/function/proposition/type_spec.rb +12 -0
  474. data/spec/unit/axiom/function/rename_spec.rb +14 -0
  475. data/spec/unit/axiom/function/string/length/class_methods/call_spec.rb +12 -0
  476. data/spec/unit/axiom/function/string/length/methods/length_spec.rb +14 -0
  477. data/spec/unit/axiom/function/string/length/type_spec.rb +11 -0
  478. data/spec/unit/axiom/function/type_spec.rb +13 -0
  479. data/spec/unit/axiom/function/unary/call_spec.rb +21 -0
  480. data/spec/unit/axiom/function/unary/callable/call_spec.rb +23 -0
  481. data/spec/unit/axiom/function/unary/callable/included_spec.rb +23 -0
  482. data/spec/unit/axiom/function/unary/equality_operator_spec.rb +55 -0
  483. data/spec/unit/axiom/function/unary/fixtures/classes.rb +12 -0
  484. data/spec/unit/axiom/function/unary/hash_spec.rb +18 -0
  485. data/spec/unit/axiom/function/unary/invertible/class_methods/included_spec.rb +29 -0
  486. data/spec/unit/axiom/function/unary/invertible/inverse_spec.rb +45 -0
  487. data/spec/unit/axiom/function/unary/rename_spec.rb +29 -0
  488. data/spec/unit/axiom/operation/binary/eql_spec.rb +66 -0
  489. data/spec/unit/axiom/operation/binary/hash_spec.rb +16 -0
  490. data/spec/unit/axiom/operation/binary/left_spec.rb +27 -0
  491. data/spec/unit/axiom/operation/binary/right_spec.rb +27 -0
  492. data/spec/unit/axiom/operation/unary/eql_spec.rb +52 -0
  493. data/spec/unit/axiom/operation/unary/hash_spec.rb +15 -0
  494. data/spec/unit/axiom/operation/unary/operand_spec.rb +26 -0
  495. data/spec/unit/axiom/relation/base/class_methods/new_spec.rb +35 -0
  496. data/spec/unit/axiom/relation/base/eql_spec.rb +100 -0
  497. data/spec/unit/axiom/relation/base/hash_spec.rb +16 -0
  498. data/spec/unit/axiom/relation/base/name_spec.rb +45 -0
  499. data/spec/unit/axiom/relation/class_methods/coerce_spec.rb +23 -0
  500. data/spec/unit/axiom/relation/class_methods/new_spec.rb +69 -0
  501. data/spec/unit/axiom/relation/directions_spec.rb +20 -0
  502. data/spec/unit/axiom/relation/each_spec.rb +52 -0
  503. data/spec/unit/axiom/relation/element_reader_spec.rb +17 -0
  504. data/spec/unit/axiom/relation/empty/class_methods/new_spec.rb +30 -0
  505. data/spec/unit/axiom/relation/empty/each_spec.rb +33 -0
  506. data/spec/unit/axiom/relation/empty/empty_predicate_spec.rb +11 -0
  507. data/spec/unit/axiom/relation/empty/header_spec.rb +14 -0
  508. data/spec/unit/axiom/relation/empty/size_spec.rb +11 -0
  509. data/spec/unit/axiom/relation/empty_predicate_spec.rb +26 -0
  510. data/spec/unit/axiom/relation/eql_spec.rb +84 -0
  511. data/spec/unit/axiom/relation/equality_operator_spec.rb +118 -0
  512. data/spec/unit/axiom/relation/hash_spec.rb +19 -0
  513. data/spec/unit/axiom/relation/header/call_spec.rb +36 -0
  514. data/spec/unit/axiom/relation/header/class_methods/coerce_spec.rb +101 -0
  515. data/spec/unit/axiom/relation/header/class_methods/new_spec.rb +66 -0
  516. data/spec/unit/axiom/relation/header/difference_spec.rb +100 -0
  517. data/spec/unit/axiom/relation/header/each_spec.rb +36 -0
  518. data/spec/unit/axiom/relation/header/empty_predicate_spec.rb +21 -0
  519. data/spec/unit/axiom/relation/header/eql_spec.rb +64 -0
  520. data/spec/unit/axiom/relation/header/equality_operator_spec.rb +94 -0
  521. data/spec/unit/axiom/relation/header/extend_spec.rb +35 -0
  522. data/spec/unit/axiom/relation/header/hash_spec.rb +15 -0
  523. data/spec/unit/axiom/relation/header/intersect_spec.rb +100 -0
  524. data/spec/unit/axiom/relation/header/keys_spec.rb +35 -0
  525. data/spec/unit/axiom/relation/header/project_spec.rb +46 -0
  526. data/spec/unit/axiom/relation/header/rename_spec.rb +19 -0
  527. data/spec/unit/axiom/relation/header/to_ary_spec.rb +16 -0
  528. data/spec/unit/axiom/relation/header/union_spec.rb +100 -0
  529. data/spec/unit/axiom/relation/header_spec.rb +18 -0
  530. data/spec/unit/axiom/relation/include_predicate_spec.rb +22 -0
  531. data/spec/unit/axiom/relation/keys/class_methods/coerce_spec.rb +29 -0
  532. data/spec/unit/axiom/relation/keys/class_methods/new_spec.rb +46 -0
  533. data/spec/unit/axiom/relation/keys/difference_spec.rb +27 -0
  534. data/spec/unit/axiom/relation/keys/each_spec.rb +36 -0
  535. data/spec/unit/axiom/relation/keys/empty_predicate_spec.rb +21 -0
  536. data/spec/unit/axiom/relation/keys/extend_spec.rb +33 -0
  537. data/spec/unit/axiom/relation/keys/intersect_spec.rb +27 -0
  538. data/spec/unit/axiom/relation/keys/project_spec.rb +34 -0
  539. data/spec/unit/axiom/relation/keys/rename_spec.rb +16 -0
  540. data/spec/unit/axiom/relation/keys/to_ary_spec.rb +16 -0
  541. data/spec/unit/axiom/relation/keys/union_spec.rb +27 -0
  542. data/spec/unit/axiom/relation/materialize_spec.rb +24 -0
  543. data/spec/unit/axiom/relation/materialized/class_methods/new_spec.rb +38 -0
  544. data/spec/unit/axiom/relation/materialized/directions_spec.rb +27 -0
  545. data/spec/unit/axiom/relation/materialized/empty_predicate_spec.rb +22 -0
  546. data/spec/unit/axiom/relation/materialized/materialize_spec.rb +11 -0
  547. data/spec/unit/axiom/relation/materialized/materialized_predicate_spec.rb +15 -0
  548. data/spec/unit/axiom/relation/materialized/size_spec.rb +13 -0
  549. data/spec/unit/axiom/relation/materialized_predicate_spec.rb +15 -0
  550. data/spec/unit/axiom/relation/one_spec.rb +36 -0
  551. data/spec/unit/axiom/relation/operation/binary/class_methods/included_spec.rb +26 -0
  552. data/spec/unit/axiom/relation/operation/binary/class_methods/new_spec.rb +40 -0
  553. data/spec/unit/axiom/relation/operation/binary/fixtures/classes.rb +14 -0
  554. data/spec/unit/axiom/relation/operation/binary/header_spec.rb +19 -0
  555. data/spec/unit/axiom/relation/operation/combination/class_methods/combine_tuples_spec.rb +21 -0
  556. data/spec/unit/axiom/relation/operation/combination/fixtures/classes.rb +14 -0
  557. data/spec/unit/axiom/relation/operation/combination/header_spec.rb +21 -0
  558. data/spec/unit/axiom/relation/operation/deletion/initialize_spec.rb +16 -0
  559. data/spec/unit/axiom/relation/operation/deletion/methods/delete_spec.rb +42 -0
  560. data/spec/unit/axiom/relation/operation/insertion/initialize_spec.rb +16 -0
  561. data/spec/unit/axiom/relation/operation/insertion/methods/insert_spec.rb +42 -0
  562. data/spec/unit/axiom/relation/operation/limit/class_methods/new_spec.rb +45 -0
  563. data/spec/unit/axiom/relation/operation/limit/delete_spec.rb +14 -0
  564. data/spec/unit/axiom/relation/operation/limit/directions_spec.rb +15 -0
  565. data/spec/unit/axiom/relation/operation/limit/each_spec.rb +30 -0
  566. data/spec/unit/axiom/relation/operation/limit/eql_spec.rb +65 -0
  567. data/spec/unit/axiom/relation/operation/limit/hash_spec.rb +16 -0
  568. data/spec/unit/axiom/relation/operation/limit/insert_spec.rb +14 -0
  569. data/spec/unit/axiom/relation/operation/limit/limit_spec.rb +14 -0
  570. data/spec/unit/axiom/relation/operation/limit/methods/first_spec.rb +43 -0
  571. data/spec/unit/axiom/relation/operation/limit/methods/last_spec.rb +39 -0
  572. data/spec/unit/axiom/relation/operation/limit/methods/take_spec.rb +20 -0
  573. data/spec/unit/axiom/relation/operation/offset/class_methods/new_spec.rb +45 -0
  574. data/spec/unit/axiom/relation/operation/offset/delete_spec.rb +14 -0
  575. data/spec/unit/axiom/relation/operation/offset/directions_spec.rb +15 -0
  576. data/spec/unit/axiom/relation/operation/offset/each_spec.rb +30 -0
  577. data/spec/unit/axiom/relation/operation/offset/eql_spec.rb +65 -0
  578. data/spec/unit/axiom/relation/operation/offset/hash_spec.rb +16 -0
  579. data/spec/unit/axiom/relation/operation/offset/insert_spec.rb +14 -0
  580. data/spec/unit/axiom/relation/operation/offset/methods/drop_spec.rb +20 -0
  581. data/spec/unit/axiom/relation/operation/offset/offset_spec.rb +14 -0
  582. data/spec/unit/axiom/relation/operation/order/ascending/class_methods/call_spec.rb +30 -0
  583. data/spec/unit/axiom/relation/operation/order/ascending/class_methods/reverse_spec.rb +11 -0
  584. data/spec/unit/axiom/relation/operation/order/ascending/reverse_spec.rb +14 -0
  585. data/spec/unit/axiom/relation/operation/order/class_methods/new_spec.rb +34 -0
  586. data/spec/unit/axiom/relation/operation/order/delete_spec.rb +45 -0
  587. data/spec/unit/axiom/relation/operation/order/descending/class_methods/call_spec.rb +30 -0
  588. data/spec/unit/axiom/relation/operation/order/descending/class_methods/reverse_spec.rb +11 -0
  589. data/spec/unit/axiom/relation/operation/order/descending/reverse_spec.rb +14 -0
  590. data/spec/unit/axiom/relation/operation/order/direction/attribute_spec.rb +13 -0
  591. data/spec/unit/axiom/relation/operation/order/direction/call_spec.rb +19 -0
  592. data/spec/unit/axiom/relation/operation/order/direction/class_methods/coerce_spec.rb +32 -0
  593. data/spec/unit/axiom/relation/operation/order/direction/eql_predicate_spec.rb +54 -0
  594. data/spec/unit/axiom/relation/operation/order/direction/hash_spec.rb +15 -0
  595. data/spec/unit/axiom/relation/operation/order/direction/name_spec.rb +13 -0
  596. data/spec/unit/axiom/relation/operation/order/direction/rename_spec.rb +28 -0
  597. data/spec/unit/axiom/relation/operation/order/direction/reverse_spec.rb +29 -0
  598. data/spec/unit/axiom/relation/operation/order/direction_set/attributes_spec.rb +14 -0
  599. data/spec/unit/axiom/relation/operation/order/direction_set/class_methods/coerce_spec.rb +76 -0
  600. data/spec/unit/axiom/relation/operation/order/direction_set/class_methods/new_spec.rb +26 -0
  601. data/spec/unit/axiom/relation/operation/order/direction_set/eql_spec.rb +51 -0
  602. data/spec/unit/axiom/relation/operation/order/direction_set/equality_operator_spec.rb +84 -0
  603. data/spec/unit/axiom/relation/operation/order/direction_set/hash_spec.rb +15 -0
  604. data/spec/unit/axiom/relation/operation/order/direction_set/project_spec.rb +17 -0
  605. data/spec/unit/axiom/relation/operation/order/direction_set/rename_spec.rb +18 -0
  606. data/spec/unit/axiom/relation/operation/order/direction_set/reverse_spec.rb +23 -0
  607. data/spec/unit/axiom/relation/operation/order/direction_set/sort_tuples_spec.rb +44 -0
  608. data/spec/unit/axiom/relation/operation/order/direction_set/to_ary_spec.rb +14 -0
  609. data/spec/unit/axiom/relation/operation/order/directions_spec.rb +15 -0
  610. data/spec/unit/axiom/relation/operation/order/each_spec.rb +30 -0
  611. data/spec/unit/axiom/relation/operation/order/eql_spec.rb +65 -0
  612. data/spec/unit/axiom/relation/operation/order/hash_spec.rb +15 -0
  613. data/spec/unit/axiom/relation/operation/order/header_spec.rb +15 -0
  614. data/spec/unit/axiom/relation/operation/order/insert_spec.rb +45 -0
  615. data/spec/unit/axiom/relation/operation/order/methods/sort_by_spec.rb +42 -0
  616. data/spec/unit/axiom/relation/operation/reverse/class_methods/new_spec.rb +36 -0
  617. data/spec/unit/axiom/relation/operation/reverse/directions_spec.rb +17 -0
  618. data/spec/unit/axiom/relation/operation/reverse/each_spec.rb +30 -0
  619. data/spec/unit/axiom/relation/operation/reverse/methods/reverse_spec.rb +17 -0
  620. data/spec/unit/axiom/relation/operation/set/class_methods/included_spec.rb +26 -0
  621. data/spec/unit/axiom/relation/operation/set/class_methods/new_spec.rb +30 -0
  622. data/spec/unit/axiom/relation/operation/set/fixtures/classes.rb +14 -0
  623. data/spec/unit/axiom/relation/operation/set/header_spec.rb +17 -0
  624. data/spec/unit/axiom/relation/operation/unary/fixtures/classes.rb +17 -0
  625. data/spec/unit/axiom/relation/operation/unary/header_spec.rb +17 -0
  626. data/spec/unit/axiom/relation/proxy/each_spec.rb +41 -0
  627. data/spec/unit/axiom/relation/proxy/hash_spec.rb +26 -0
  628. data/spec/unit/axiom/relation/proxy/method_missing_spec.rb +24 -0
  629. data/spec/unit/axiom/relation/proxy/respond_to_predicate_spec.rb +40 -0
  630. data/spec/unit/axiom/relation/replace_spec.rb +55 -0
  631. data/spec/unit/axiom/tuple/call_spec.rb +25 -0
  632. data/spec/unit/axiom/tuple/class_methods/coerce_spec.rb +31 -0
  633. data/spec/unit/axiom/tuple/data_spec.rb +16 -0
  634. data/spec/unit/axiom/tuple/eql_spec.rb +65 -0
  635. data/spec/unit/axiom/tuple/equality_operator_spec.rb +85 -0
  636. data/spec/unit/axiom/tuple/extend_spec.rb +41 -0
  637. data/spec/unit/axiom/tuple/hash_spec.rb +15 -0
  638. data/spec/unit/axiom/tuple/header_spec.rb +14 -0
  639. data/spec/unit/axiom/tuple/join_spec.rb +18 -0
  640. data/spec/unit/axiom/tuple/predicate_spec.rb +44 -0
  641. data/spec/unit/axiom/tuple/project_spec.rb +17 -0
  642. data/spec/unit/axiom/tuple/to_ary_spec.rb +18 -0
  643. data/spec/unit/axiom/visitable/accept_spec.rb +18 -0
  644. data/spec/unit/date/pred_spec.rb +19 -0
  645. data/spec/unit/range/overlaps_spec.rb +192 -0
  646. data/spec/unit/range/to_inclusive_spec.rb +41 -0
  647. data/spec/unit/time/pred_spec.rb +19 -0
  648. metadata +1327 -0
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Relation
5
+
6
+ # A class that represents a base relation
7
+ class Base < Relation
8
+ include Equalizer.new(:header, :to_set, :name)
9
+
10
+ # The base relation name
11
+ #
12
+ # @example
13
+ # name = base.name
14
+ #
15
+ # @return [#to_s]
16
+ #
17
+ # @api public
18
+ attr_reader :name
19
+
20
+ # Initialize a base relation
21
+ #
22
+ # @param [#to_s] name
23
+ # the relation name
24
+ # @param [Header, #to_ary] header
25
+ # the relation header
26
+ # @param [Enumerable] tuples
27
+ # the relation tuples
28
+ #
29
+ # @return [undefined]
30
+ #
31
+ # @api private
32
+ def initialize(name, header, tuples = Empty::ZERO_TUPLE)
33
+ super(header, tuples)
34
+ @name = freeze_object(name.to_s)
35
+ end
36
+
37
+ end # class Base
38
+ end # class Relation
39
+ end # module Axiom
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Relation
5
+
6
+ # An empty relation
7
+ class Empty < Materialized
8
+ ZERO_TUPLE = EMPTY_ARRAY
9
+
10
+ # Initialize an empty Relation
11
+ #
12
+ # @param [Header] _header
13
+ # the header for the empty relation
14
+ # @param [#each] _tuples
15
+ # optional original tuples
16
+ #
17
+ # @return [undefined]
18
+ #
19
+ # @api public
20
+ def initialize(_header, _tuples = ZERO_TUPLE)
21
+ super
22
+ end
23
+
24
+ # Noop #each method
25
+ #
26
+ # @example
27
+ # empty = Empty.new(header)
28
+ # empty.each { ... }
29
+ #
30
+ # @return [self]
31
+ #
32
+ # @api public
33
+ def each
34
+ return to_enum unless block_given?
35
+ self
36
+ end
37
+
38
+ # Return the number of tuples
39
+ #
40
+ # @example
41
+ # empty.size # => 0
42
+ #
43
+ # @return [0]
44
+ #
45
+ # @api public
46
+ def size
47
+ 0
48
+ end
49
+
50
+ end # class Empty
51
+ end # class Relation
52
+ end # module Axiom
@@ -0,0 +1,349 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Relation
5
+
6
+ # A set of attributes that correspond to values in each tuple
7
+ class Header
8
+ extend Aliasable
9
+ include Enumerable
10
+ include Equalizer.new(:to_set, :keys)
11
+
12
+ inheritable_alias(
13
+ :[] => :call,
14
+ :& => :intersect,
15
+ :| => :union,
16
+ :- => :difference
17
+ )
18
+
19
+ # The header keys
20
+ #
21
+ # @return [Keys]
22
+ #
23
+ # @api private
24
+ attr_reader :keys
25
+
26
+ # Coerce an Array-like object into a Header
27
+ #
28
+ # @param [Header, #to_ary] object
29
+ # the header or attributes
30
+ # @param [Hash] options
31
+ #
32
+ # @yield [attribute]
33
+ #
34
+ # @yieldparam [Attribute, Array] attribute
35
+ #
36
+ # @return [Header]
37
+ #
38
+ # @api private
39
+ def self.coerce(object, options = EMPTY_HASH)
40
+ if object.kind_of?(self)
41
+ object
42
+ else
43
+ # Find the attribute with the block if possible, then fallback
44
+ # to the default coercion method.
45
+ block = lambda do |attribute|
46
+ block_given? and yield(attribute) or coerce_attribute(attribute)
47
+ end
48
+ new(Array(object).map(&block), options)
49
+ end
50
+ end
51
+
52
+ # Instantiate a Header
53
+ #
54
+ # @example
55
+ # header = Header.new(attributes)
56
+ #
57
+ # @param [Array<Attribute>] attributes
58
+ # optional attributes
59
+ # @param [Hash] _options
60
+ #
61
+ # @return [Header]
62
+ #
63
+ # @api public
64
+ def self.new(attributes = EMPTY_ARRAY, _options = EMPTY_HASH)
65
+ assert_unique_names(attributes.map(&:name))
66
+ super
67
+ end
68
+
69
+ # Coerce the attribute into an Attribute
70
+ #
71
+ # @param [Object] attribute
72
+ #
73
+ # @return [Attribute]
74
+ #
75
+ # @api private
76
+ def self.coerce_attribute(attribute)
77
+ Attribute.coerce(attribute)
78
+ end
79
+
80
+ # Assert the names are unique
81
+ #
82
+ # @param [Array<Symbol>] names
83
+ #
84
+ # @return [undefined]
85
+ #
86
+ # @raise [DuplicateNameError]
87
+ # raised if the names are not unique
88
+ #
89
+ # @api private
90
+ def self.assert_unique_names(names)
91
+ duplicates = duplicate_names(names)
92
+ if duplicates
93
+ raise DuplicateNameError, "duplicate names: #{duplicates.inspect}"
94
+ end
95
+ end
96
+
97
+ # Returns the duplicate names, if any
98
+ #
99
+ # @param [Array<Symbol>] names
100
+ #
101
+ # @return [Array<Symbol>]
102
+ # returns an array of duplicate names
103
+ #
104
+ # @return [nil]
105
+ # returns nil if there are no duplicate names
106
+ #
107
+ # @api private
108
+ def self.duplicate_names(names)
109
+ names.select { |name| names.count(name) > 1 }.uniq!
110
+ end
111
+
112
+ private_class_method :coerce_attribute, :assert_unique_names, :duplicate_names
113
+
114
+ # Initialize a Header
115
+ #
116
+ # @example
117
+ # header = Header.new(attributes, :keys => [ [ :id ] ])
118
+ #
119
+ # @param [Array] attributes
120
+ #
121
+ # @param [Hash] options
122
+ #
123
+ # @return [undefined]
124
+ #
125
+ # @api public
126
+ def initialize(attributes, options)
127
+ @attributes = freeze_object(attributes)
128
+ @options = freeze_object(options)
129
+ @attribute_for = Hash[@attributes.map(&:name).zip(@attributes)]
130
+ @keys = coerce_keys
131
+ end
132
+
133
+ # Iterate over each attribute in the header
134
+ #
135
+ # @example
136
+ # header = Header.new(attributes)
137
+ # header.each { |attribute| ... }
138
+ #
139
+ # @yield [attribute]
140
+ #
141
+ # @yieldparam [Attribute] attribute
142
+ # each attribute in the header
143
+ #
144
+ # @return [self]
145
+ #
146
+ # @api public
147
+ def each
148
+ return to_enum unless block_given?
149
+ to_ary.each { |attribute| yield attribute }
150
+ self
151
+ end
152
+
153
+ # Lookup an attribute in the header given a name
154
+ #
155
+ # @example
156
+ # attribute = header.call(:id)
157
+ #
158
+ # @param [Attribute, #to_ary, #to_sym] name
159
+ #
160
+ # @return [Attribute]
161
+ # the attribute when the name is known
162
+ #
163
+ # @api public
164
+ def call(name)
165
+ @attribute_for.fetch(Attribute.name_from(name)) do |attribute_name|
166
+ raise UnknownAttributeError,
167
+ "the attribute #{attribute_name} is unknown"
168
+ end
169
+ end
170
+
171
+ # Return a header with only the attributes specified
172
+ #
173
+ # The unique keys intersected with the attributes become the new keys
174
+ # because a projection strengthens key constraints.
175
+ #
176
+ # @example
177
+ # projected = header.project(attributes)
178
+ #
179
+ # @param [#map] attributes
180
+ # the attributes to keep in the header
181
+ #
182
+ # @return [Header]
183
+ #
184
+ # @api public
185
+ def project(attributes)
186
+ coerce(attributes, :keys => keys.project(attributes))
187
+ end
188
+
189
+ # Return a header with the new attributes added
190
+ #
191
+ # The original keys from the header are reused because
192
+ # an extension does not affect key constraints.
193
+ #
194
+ # @example
195
+ # extended = header.extend(attributes)
196
+ #
197
+ # @param [#to_ary] attributes
198
+ # the attributes to add to the header
199
+ #
200
+ # @return [Header]
201
+ #
202
+ # @api public
203
+ def extend(attributes)
204
+ new(to_ary + coerce(attributes), :keys => keys)
205
+ end
206
+
207
+ # Return a header with the attributes renamed
208
+ #
209
+ # The attributes in the original keys are renamed, but
210
+ # a rename does not otherwise affect the key constraints.
211
+ #
212
+ # @example
213
+ # renamed = header.rename(aliases)
214
+ #
215
+ # @param [Aliases] aliases
216
+ # the old and new attribute names
217
+ #
218
+ # @return [Header]
219
+ #
220
+ # @api public
221
+ def rename(aliases)
222
+ new(
223
+ map { |attribute| aliases[attribute] },
224
+ :keys => keys.rename(aliases)
225
+ )
226
+ end
227
+
228
+ # Return the intersection of the header with another header
229
+ #
230
+ # The unique keys from the headers become the new keys because
231
+ # an intersection strengthens key constraints.
232
+ #
233
+ # @example
234
+ # intersection = header.intersect(other)
235
+ #
236
+ # @param [Header] other
237
+ #
238
+ # @return [Header]
239
+ #
240
+ # @api public
241
+ def intersect(other)
242
+ other = coerce(other)
243
+ attributes = to_ary & other
244
+ new(attributes, :keys => (keys | other.keys).project(attributes))
245
+ end
246
+
247
+ # Return the union of the header with another header
248
+ #
249
+ # The common keys from the headers become the new keys because
250
+ # a union weakens key constraints.
251
+ #
252
+ # @example
253
+ # union = header.union(other)
254
+ #
255
+ # @param [Header] other
256
+ #
257
+ # @return [Header]
258
+ #
259
+ # @api public
260
+ def union(other)
261
+ other = coerce(other)
262
+ new(to_ary | other, :keys => keys & other.keys)
263
+ end
264
+
265
+ # Return the difference of the header with another header
266
+ #
267
+ # The original keys from the header are reused because
268
+ # a difference does not affect key constraints.
269
+ #
270
+ # @example
271
+ # difference = header.difference(other)
272
+ #
273
+ # @param [Header] other
274
+ #
275
+ # @return [Header]
276
+ #
277
+ # @api public
278
+ def difference(other)
279
+ other = coerce(other)
280
+ new(to_ary - other, :keys => keys - other.keys)
281
+ end
282
+
283
+ # Convert the Header into an Array
284
+ #
285
+ # @example
286
+ # array = header.to_ary
287
+ #
288
+ # @return [Array]
289
+ #
290
+ # @api public
291
+ def to_ary
292
+ @attributes
293
+ end
294
+
295
+ # Test if there are no attributes
296
+ #
297
+ # @example
298
+ # header.empty? # => true or false
299
+ #
300
+ # @return [Boolean]
301
+ #
302
+ # @api public
303
+ def empty?
304
+ to_ary.empty?
305
+ end
306
+
307
+ private
308
+
309
+ # Utility method to instantiate a Header
310
+ #
311
+ # @param [Array] args
312
+ #
313
+ # @return [Header]
314
+ #
315
+ # @api private
316
+ def new(*args)
317
+ self.class.new(*args)
318
+ end
319
+
320
+ # Coerce the keys into an Array of Headers
321
+ #
322
+ # @return [Array<Header>]
323
+ #
324
+ # @api private
325
+ def coerce_keys
326
+ Keys.coerce(@options.fetch(:keys, EMPTY_ARRAY)) do |attributes|
327
+ coerce(attributes)
328
+ end
329
+ end
330
+
331
+ # Coerce the object into a Header
332
+ #
333
+ # @param [Array] args
334
+ #
335
+ # @return [Header]
336
+ #
337
+ # @api private
338
+ def coerce(*args)
339
+ self.class.coerce(*args) do |attribute|
340
+ @attribute_for[attribute]
341
+ end
342
+ end
343
+
344
+ # Represent an empty set of attributes
345
+ EMPTY = new
346
+
347
+ end # class Header
348
+ end # class Relation
349
+ end # module Axiom
@@ -0,0 +1,282 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Relation
5
+
6
+ # A set of keys in a Header
7
+ class Keys
8
+ extend Aliasable
9
+ include Enumerable
10
+ include Equalizer.new(:to_set)
11
+
12
+ inheritable_alias(
13
+ :& => :intersect,
14
+ :| => :union,
15
+ :- => :difference
16
+ )
17
+
18
+ # Coerce an Array-like object into Keys
19
+ #
20
+ # @param [Keys, #to_ary] object
21
+ #
22
+ # @yield [attributes]
23
+ #
24
+ # @yieldparam [Header, Array] attributes
25
+ # the attributes in each key
26
+ #
27
+ # @return [Keys]
28
+ #
29
+ # @api private
30
+ def self.coerce(object, &block)
31
+ if object.kind_of?(self)
32
+ object
33
+ else
34
+ block ||= lambda { |attributes| coerce_attributes(attributes) }
35
+ new(object.map(&block))
36
+ end
37
+ end
38
+
39
+ # Instantiate Keys
40
+ #
41
+ # @example
42
+ # keys = Keys.new(keys)
43
+ #
44
+ # @param [Array<Header>] keys
45
+ #
46
+ # @return [Keys]
47
+ #
48
+ # @api public
49
+ def self.new(keys = EMPTY_ARRAY)
50
+ assert_irreducible_keys(keys.map(&:to_set))
51
+ super
52
+ end
53
+
54
+ # Coerce the attributes into a Header
55
+ #
56
+ # @param [Object] attributes
57
+ #
58
+ # @return [Header]
59
+ #
60
+ # @api private
61
+ def self.coerce_attributes(attributes)
62
+ Header.coerce(attributes)
63
+ end
64
+
65
+ # Assert the keys are irreducible
66
+ #
67
+ # In a relation a candidate key must be irreducible, which means that
68
+ # there can't exist another key that is a proper subset of it. If this
69
+ # occurs, we should raise an exception because it means there is a
70
+ # specification error in the system.
71
+ #
72
+ # @param [Array<Set>] keys
73
+ #
74
+ # @return [undefined]
75
+ #
76
+ # @raise [ReducibleKeyError]
77
+ # raised if a key can be reduced
78
+ #
79
+ # @api private
80
+ def self.assert_irreducible_keys(keys)
81
+ reducible_keys = reducible_keys(keys)
82
+ if reducible_keys
83
+ raise ReducibleKeyError, "reducible keys: #{reducible_keys.inspect}"
84
+ end
85
+ end
86
+
87
+ # The keys that can be reduced
88
+ #
89
+ # @param [Array<Header>] keys
90
+ #
91
+ # @return [Boolean]
92
+ #
93
+ # @api private
94
+ def self.reducible_keys(keys)
95
+ keys.permutation(2).select { |key, other| key.proper_superset?(other) }.
96
+ transpose.first
97
+ end
98
+
99
+ private_class_method :coerce_attributes, :assert_irreducible_keys, :reducible_keys
100
+
101
+ # Initialize Keys
102
+ #
103
+ # @example
104
+ # keys = Keys.new([ [ :id ] ])
105
+ #
106
+ # @param [Array<Header>] keys
107
+ #
108
+ # @return [undefined]
109
+ #
110
+ # @api public
111
+ def initialize(keys)
112
+ @keys = freeze_object(keys)
113
+ end
114
+
115
+ # Iterate over each key in the Keys
116
+ #
117
+ # @example
118
+ # keys = Keys.new(keys)
119
+ # keys.each { |key| ... }
120
+ #
121
+ # @yield [key]
122
+ #
123
+ # @yieldparam [Header] key
124
+ #
125
+ # @return [self]
126
+ #
127
+ # @api public
128
+ def each
129
+ return to_enum unless block_given?
130
+ to_ary.each { |key| yield key }
131
+ self
132
+ end
133
+
134
+ # Return keys with only the attributes specified
135
+ #
136
+ # When the attributes do not match any attributes in an existing
137
+ # key, then the key should be removed because it means the attributes
138
+ # it applied against no longer exist in the new header.
139
+ #
140
+ # @example
141
+ # projected = keys.project(attributes)
142
+ #
143
+ # @param [#map] attributes
144
+ # the attributes to keep in the keys
145
+ #
146
+ # @return [Keys]
147
+ #
148
+ # @api public
149
+ def project(attributes)
150
+ new(map { |key| key & attributes }.delete_if(&:empty?))
151
+ end
152
+
153
+ # Return keys with the new attributes added
154
+ #
155
+ # @example
156
+ # extended = keys.extend(attributes)
157
+ #
158
+ # @param [#to_ary] attributes
159
+ # the attributes to add to the keys
160
+ #
161
+ # @return [Keys]
162
+ #
163
+ # @api public
164
+ def extend(attributes)
165
+ if empty?
166
+ coerce(attributes)
167
+ else
168
+ new(map { |key| key | attributes })
169
+ end
170
+ end
171
+
172
+ # Return keys with the attributes renamed
173
+ #
174
+ # @example
175
+ # renamed = keys.rename(aliases)
176
+ #
177
+ # @param [Aliases] aliases
178
+ # the old and new attribute names
179
+ #
180
+ # @return [Keys]
181
+ #
182
+ # @api public
183
+ def rename(aliases)
184
+ new(map { |key| key.rename(aliases) })
185
+ end
186
+
187
+ # Return the intersection of the keys with other keys
188
+ #
189
+ # @example
190
+ # intersection = keys.intersect(other)
191
+ #
192
+ # @param [Keys] other
193
+ #
194
+ # @return [Keys]
195
+ #
196
+ # @api public
197
+ def intersect(other)
198
+ new(to_ary & other)
199
+ end
200
+
201
+ # Return the union of the keys with other keys
202
+ #
203
+ # @example
204
+ # union = keys.union(other)
205
+ #
206
+ # @param [Keys] other
207
+ #
208
+ # @return [Keys]
209
+ #
210
+ # @api public
211
+ def union(other)
212
+ new(to_ary | other)
213
+ end
214
+
215
+ # Return the difference of the keys with other keys
216
+ #
217
+ # @example
218
+ # difference = keys.difference(other)
219
+ #
220
+ # @param [Keys] other
221
+ #
222
+ # @return [Keys]
223
+ #
224
+ # @api public
225
+ def difference(other)
226
+ new(to_ary - other)
227
+ end
228
+
229
+ # Convert the Keys into an Array
230
+ #
231
+ # @example
232
+ # array = keys.to_ary
233
+ #
234
+ # @return [Array]
235
+ #
236
+ # @api public
237
+ def to_ary
238
+ @keys
239
+ end
240
+
241
+ # Test if there are no keys
242
+ #
243
+ # @example
244
+ # keys.empty? # => true or false
245
+ #
246
+ # @return [Boolean]
247
+ #
248
+ # @api public
249
+ def empty?
250
+ to_ary.empty?
251
+ end
252
+
253
+ private
254
+
255
+ # Utility method to instantiate Keys
256
+ #
257
+ # @param [Array] keys
258
+ #
259
+ # @return [Keys]
260
+ #
261
+ # @api private
262
+ def new(keys)
263
+ to_ary == keys ? self : self.class.new(keys)
264
+ end
265
+
266
+ # Coerce the object into Keys
267
+ #
268
+ # @param [Keys, #to_ary] object
269
+ #
270
+ # @return [Keys]
271
+ #
272
+ # @api private
273
+ def coerce(object)
274
+ self.class.coerce(object)
275
+ end
276
+
277
+ # Represent an empty set of keys
278
+ EMPTY = new
279
+
280
+ end # class Keys
281
+ end # class Relation
282
+ end # module Axiom