axiom-optimizer 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 (345) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/.gitignore +37 -0
  4. data/.rspec +4 -0
  5. data/.rvmrc +1 -0
  6. data/.travis.yml +35 -0
  7. data/CONTRIBUTING.md +11 -0
  8. data/Gemfile +10 -0
  9. data/Gemfile.devtools +57 -0
  10. data/Guardfile +23 -0
  11. data/LICENSE +20 -0
  12. data/README.md +111 -0
  13. data/Rakefile +5 -0
  14. data/TODO +144 -0
  15. data/axiom-optimizer.gemspec +25 -0
  16. data/config/flay.yml +3 -0
  17. data/config/flog.yml +2 -0
  18. data/config/mutant.yml +3 -0
  19. data/config/reek.yml +162 -0
  20. data/config/roodi.yml +16 -0
  21. data/config/yardstick.yml +2 -0
  22. data/lib/axiom-optimizer.rb +3 -0
  23. data/lib/axiom/optimizer.rb +168 -0
  24. data/lib/axiom/optimizer/aggregate.rb +16 -0
  25. data/lib/axiom/optimizer/aggregate/count.rb +17 -0
  26. data/lib/axiom/optimizer/aggregate/maximum.rb +17 -0
  27. data/lib/axiom/optimizer/aggregate/mean.rb +17 -0
  28. data/lib/axiom/optimizer/aggregate/minimum.rb +17 -0
  29. data/lib/axiom/optimizer/aggregate/standard_deviation.rb +17 -0
  30. data/lib/axiom/optimizer/aggregate/sum.rb +17 -0
  31. data/lib/axiom/optimizer/aggregate/variance.rb +17 -0
  32. data/lib/axiom/optimizer/algebra/difference.rb +68 -0
  33. data/lib/axiom/optimizer/algebra/extension.rb +97 -0
  34. data/lib/axiom/optimizer/algebra/intersection.rb +68 -0
  35. data/lib/axiom/optimizer/algebra/join.rb +184 -0
  36. data/lib/axiom/optimizer/algebra/product.rb +70 -0
  37. data/lib/axiom/optimizer/algebra/projection.rb +212 -0
  38. data/lib/axiom/optimizer/algebra/rename.rb +381 -0
  39. data/lib/axiom/optimizer/algebra/restriction.rb +373 -0
  40. data/lib/axiom/optimizer/algebra/summarization.rb +200 -0
  41. data/lib/axiom/optimizer/algebra/union.rb +68 -0
  42. data/lib/axiom/optimizer/function.rb +87 -0
  43. data/lib/axiom/optimizer/function/binary.rb +124 -0
  44. data/lib/axiom/optimizer/function/connective/binary.rb +245 -0
  45. data/lib/axiom/optimizer/function/connective/conjunction.rb +122 -0
  46. data/lib/axiom/optimizer/function/connective/disjunction.rb +122 -0
  47. data/lib/axiom/optimizer/function/connective/negation.rb +65 -0
  48. data/lib/axiom/optimizer/function/numeric.rb +34 -0
  49. data/lib/axiom/optimizer/function/numeric/absolute.rb +20 -0
  50. data/lib/axiom/optimizer/function/numeric/addition.rb +20 -0
  51. data/lib/axiom/optimizer/function/numeric/division.rb +20 -0
  52. data/lib/axiom/optimizer/function/numeric/exponentiation.rb +20 -0
  53. data/lib/axiom/optimizer/function/numeric/modulo.rb +20 -0
  54. data/lib/axiom/optimizer/function/numeric/multiplication.rb +20 -0
  55. data/lib/axiom/optimizer/function/numeric/square_root.rb +20 -0
  56. data/lib/axiom/optimizer/function/numeric/subtraction.rb +20 -0
  57. data/lib/axiom/optimizer/function/numeric/unary_minus.rb +20 -0
  58. data/lib/axiom/optimizer/function/numeric/unary_plus.rb +20 -0
  59. data/lib/axiom/optimizer/function/predicate.rb +61 -0
  60. data/lib/axiom/optimizer/function/predicate/comparable.rb +144 -0
  61. data/lib/axiom/optimizer/function/predicate/enumerable.rb +138 -0
  62. data/lib/axiom/optimizer/function/predicate/equality.rb +44 -0
  63. data/lib/axiom/optimizer/function/predicate/exclusion.rb +43 -0
  64. data/lib/axiom/optimizer/function/predicate/greater_than.rb +55 -0
  65. data/lib/axiom/optimizer/function/predicate/greater_than_or_equal_to.rb +55 -0
  66. data/lib/axiom/optimizer/function/predicate/inclusion.rb +43 -0
  67. data/lib/axiom/optimizer/function/predicate/inequality.rb +44 -0
  68. data/lib/axiom/optimizer/function/predicate/less_than.rb +55 -0
  69. data/lib/axiom/optimizer/function/predicate/less_than_or_equal_to.rb +55 -0
  70. data/lib/axiom/optimizer/function/predicate/match.rb +20 -0
  71. data/lib/axiom/optimizer/function/predicate/no_match.rb +20 -0
  72. data/lib/axiom/optimizer/function/string/length.rb +31 -0
  73. data/lib/axiom/optimizer/function/unary.rb +86 -0
  74. data/lib/axiom/optimizer/optimizable.rb +60 -0
  75. data/lib/axiom/optimizer/relation/materialized.rb +40 -0
  76. data/lib/axiom/optimizer/relation/operation/binary.rb +134 -0
  77. data/lib/axiom/optimizer/relation/operation/combination.rb +33 -0
  78. data/lib/axiom/optimizer/relation/operation/deletion.rb +20 -0
  79. data/lib/axiom/optimizer/relation/operation/insertion.rb +20 -0
  80. data/lib/axiom/optimizer/relation/operation/limit.rb +141 -0
  81. data/lib/axiom/optimizer/relation/operation/offset.rb +106 -0
  82. data/lib/axiom/optimizer/relation/operation/order.rb +85 -0
  83. data/lib/axiom/optimizer/relation/operation/reverse.rb +85 -0
  84. data/lib/axiom/optimizer/relation/operation/unary.rb +124 -0
  85. data/lib/axiom/optimizer/support/predicate_partition.rb +184 -0
  86. data/lib/axiom/optimizer/version.rb +10 -0
  87. data/spec/integration/axiom/algebra/difference/optimize_spec.rb +160 -0
  88. data/spec/integration/axiom/algebra/intersection/optimize_spec.rb +160 -0
  89. data/spec/integration/axiom/algebra/join/optimize_spec.rb +112 -0
  90. data/spec/integration/axiom/algebra/product/optimize_spec.rb +178 -0
  91. data/spec/integration/axiom/algebra/projection/optimize_spec.rb +250 -0
  92. data/spec/integration/axiom/algebra/rename/optimize_spec.rb +442 -0
  93. data/spec/integration/axiom/algebra/restriction/optimize_spec.rb +218 -0
  94. data/spec/integration/axiom/algebra/summarization/optimize_spec.rb +49 -0
  95. data/spec/integration/axiom/algebra/union/optimize_spec.rb +200 -0
  96. data/spec/integration/axiom/function/connective/conjunction/optimize_spec.rb +236 -0
  97. data/spec/integration/axiom/function/connective/disjunction/optimize_spec.rb +237 -0
  98. data/spec/integration/axiom/function/connective/negation/optimize_spec.rb +43 -0
  99. data/spec/integration/axiom/function/optimize_spec.rb +30 -0
  100. data/spec/integration/axiom/function/predicate/equality/optimize_spec.rb +92 -0
  101. data/spec/integration/axiom/function/predicate/exclusion/optimize_spec.rb +133 -0
  102. data/spec/integration/axiom/function/predicate/greater_than/optimize_spec.rb +102 -0
  103. data/spec/integration/axiom/function/predicate/greater_than_or_equal_to/optimize_spec.rb +102 -0
  104. data/spec/integration/axiom/function/predicate/inclusion/optimize_spec.rb +133 -0
  105. data/spec/integration/axiom/function/predicate/inequality/optimize_spec.rb +92 -0
  106. data/spec/integration/axiom/function/predicate/less_than/optimize_spec.rb +102 -0
  107. data/spec/integration/axiom/function/predicate/less_than_or_equal_to/optimize_spec.rb +102 -0
  108. data/spec/integration/axiom/relation/empty/optimize_spec.rb +13 -0
  109. data/spec/integration/axiom/relation/materialized/optimize_spec.rb +29 -0
  110. data/spec/integration/axiom/relation/operation/limit/optimize_spec.rb +142 -0
  111. data/spec/integration/axiom/relation/operation/offset/optimize_spec.rb +100 -0
  112. data/spec/integration/axiom/relation/operation/order/optimize_spec.rb +105 -0
  113. data/spec/integration/axiom/relation/operation/reverse/optimize_spec.rb +115 -0
  114. data/spec/integration/axiom/relation/optimize_spec.rb +23 -0
  115. data/spec/rcov.opts +7 -0
  116. data/spec/shared/function_connective_binary_optimize_behavior.rb +102 -0
  117. data/spec/shared/optimize_method_behavior.rb +16 -0
  118. data/spec/spec_helper.rb +38 -0
  119. data/spec/support/add_method_missing.rb +15 -0
  120. data/spec/support/config_alias.rb +3 -0
  121. data/spec/support/ice_nine_config.rb +6 -0
  122. data/spec/support/lazy_enumerable.rb +18 -0
  123. data/spec/unit/axiom/optimizer/algebra/difference/empty_left/optimize_spec.rb +19 -0
  124. data/spec/unit/axiom/optimizer/algebra/difference/empty_right/optimize_spec.rb +19 -0
  125. data/spec/unit/axiom/optimizer/algebra/difference/equal_operands/optimize_spec.rb +23 -0
  126. data/spec/unit/axiom/optimizer/algebra/extension/extensions_spec.rb +31 -0
  127. data/spec/unit/axiom/optimizer/algebra/extension/order_operand/optimizable_predicate_spec.rb +23 -0
  128. data/spec/unit/axiom/optimizer/algebra/extension/order_operand/optimize_spec.rb +22 -0
  129. data/spec/unit/axiom/optimizer/algebra/extension/unoptimized_operand/optimizable_predicate_spec.rb +37 -0
  130. data/spec/unit/axiom/optimizer/algebra/extension/unoptimized_operand/optimize_spec.rb +27 -0
  131. data/spec/unit/axiom/optimizer/algebra/intersection/empty_left/optimize_spec.rb +19 -0
  132. data/spec/unit/axiom/optimizer/algebra/intersection/empty_right/optimize_spec.rb +19 -0
  133. data/spec/unit/axiom/optimizer/algebra/intersection/equal_operands/optimize_spec.rb +19 -0
  134. data/spec/unit/axiom/optimizer/algebra/join/disjoint_headers/optimizable_predicate_spec.rb +29 -0
  135. data/spec/unit/axiom/optimizer/algebra/join/disjoint_headers/optimize_spec.rb +22 -0
  136. data/spec/unit/axiom/optimizer/algebra/join/equal_headers/optimizable_predicate_spec.rb +29 -0
  137. data/spec/unit/axiom/optimizer/algebra/join/equal_headers/optimize_spec.rb +23 -0
  138. data/spec/unit/axiom/optimizer/algebra/join/materialized_left/optimizable_predicate_spec.rb +42 -0
  139. data/spec/unit/axiom/optimizer/algebra/join/materialized_left/optimize_spec.rb +55 -0
  140. data/spec/unit/axiom/optimizer/algebra/join/materialized_right/optimizable_predicate_spec.rb +42 -0
  141. data/spec/unit/axiom/optimizer/algebra/join/materialized_right/optimize_spec.rb +55 -0
  142. data/spec/unit/axiom/optimizer/algebra/product/table_dee_left/optimizable_predicate_spec.rb +27 -0
  143. data/spec/unit/axiom/optimizer/algebra/product/table_dee_left/optimize_spec.rb +18 -0
  144. data/spec/unit/axiom/optimizer/algebra/product/table_dee_right/optimizable_predicate_spec.rb +27 -0
  145. data/spec/unit/axiom/optimizer/algebra/product/table_dee_right/optimize_spec.rb +18 -0
  146. data/spec/unit/axiom/optimizer/algebra/projection/empty_operand/optimizable_predicate_spec.rb +27 -0
  147. data/spec/unit/axiom/optimizer/algebra/projection/empty_operand/optimize_spec.rb +22 -0
  148. data/spec/unit/axiom/optimizer/algebra/projection/extension_operand/optimizable_predicate_spec.rb +35 -0
  149. data/spec/unit/axiom/optimizer/algebra/projection/extension_operand/optimize_spec.rb +22 -0
  150. data/spec/unit/axiom/optimizer/algebra/projection/projection_operand/optimizable_predicate_spec.rb +28 -0
  151. data/spec/unit/axiom/optimizer/algebra/projection/projection_operand/optimize_spec.rb +22 -0
  152. data/spec/unit/axiom/optimizer/algebra/projection/union_operand/optimizable_predicate_spec.rb +29 -0
  153. data/spec/unit/axiom/optimizer/algebra/projection/union_operand/optimize_spec.rb +25 -0
  154. data/spec/unit/axiom/optimizer/algebra/projection/unoptimized_operand/optimizable_predicate_spec.rb +28 -0
  155. data/spec/unit/axiom/optimizer/algebra/projection/unoptimized_operand/optimize_spec.rb +22 -0
  156. data/spec/unit/axiom/optimizer/algebra/rename/aliases_spec.rb +23 -0
  157. data/spec/unit/axiom/optimizer/algebra/rename/empty_operand/optimizable_predicate_spec.rb +27 -0
  158. data/spec/unit/axiom/optimizer/algebra/rename/empty_operand/optimize_spec.rb +21 -0
  159. data/spec/unit/axiom/optimizer/algebra/rename/limit_operand/optimizable_predicate_spec.rb +28 -0
  160. data/spec/unit/axiom/optimizer/algebra/rename/limit_operand/optimize_spec.rb +23 -0
  161. data/spec/unit/axiom/optimizer/algebra/rename/offset_operand/optimizable_predicate_spec.rb +28 -0
  162. data/spec/unit/axiom/optimizer/algebra/rename/offset_operand/optimize_spec.rb +23 -0
  163. data/spec/unit/axiom/optimizer/algebra/rename/order_operand/optimizable_predicate_spec.rb +28 -0
  164. data/spec/unit/axiom/optimizer/algebra/rename/order_operand/optimize_spec.rb +22 -0
  165. data/spec/unit/axiom/optimizer/algebra/rename/projection_operand/optimizable_predicate_spec.rb +43 -0
  166. data/spec/unit/axiom/optimizer/algebra/rename/projection_operand/optimize_spec.rb +22 -0
  167. data/spec/unit/axiom/optimizer/algebra/rename/rename_operand/optimizable_predicate_spec.rb +30 -0
  168. data/spec/unit/axiom/optimizer/algebra/rename/rename_operand/optimize_spec.rb +22 -0
  169. data/spec/unit/axiom/optimizer/algebra/rename/rename_operand_and_empty_aliases/optimizable_predicate_spec.rb +37 -0
  170. data/spec/unit/axiom/optimizer/algebra/rename/rename_operand_and_empty_aliases/optimize_spec.rb +18 -0
  171. data/spec/unit/axiom/optimizer/algebra/rename/restriction_operand/optimizable_predicate_spec.rb +29 -0
  172. data/spec/unit/axiom/optimizer/algebra/rename/restriction_operand/optimize_spec.rb +23 -0
  173. data/spec/unit/axiom/optimizer/algebra/rename/reverse_operand/optimizable_predicate_spec.rb +27 -0
  174. data/spec/unit/axiom/optimizer/algebra/rename/reverse_operand/optimize_spec.rb +23 -0
  175. data/spec/unit/axiom/optimizer/algebra/rename/set_operand/optimizable_predicate_spec.rb +29 -0
  176. data/spec/unit/axiom/optimizer/algebra/rename/set_operand/optimize_spec.rb +23 -0
  177. data/spec/unit/axiom/optimizer/algebra/rename/unoptimized_operand/optimizable_predicate_spec.rb +29 -0
  178. data/spec/unit/axiom/optimizer/algebra/rename/unoptimized_operand/optimize_spec.rb +23 -0
  179. data/spec/unit/axiom/optimizer/algebra/restriction/combination_operand/optimizable_predicate_spec.rb +41 -0
  180. data/spec/unit/axiom/optimizer/algebra/restriction/combination_operand/optimize_spec.rb +35 -0
  181. data/spec/unit/axiom/optimizer/algebra/restriction/contradiction/optimizable_predicate_spec.rb +46 -0
  182. data/spec/unit/axiom/optimizer/algebra/restriction/contradiction/optimize_spec.rb +23 -0
  183. data/spec/unit/axiom/optimizer/algebra/restriction/join_operand/optimizable_predicate_spec.rb +51 -0
  184. data/spec/unit/axiom/optimizer/algebra/restriction/join_operand/optimize_spec.rb +48 -0
  185. data/spec/unit/axiom/optimizer/algebra/restriction/order_operand/optimizable_predicate_spec.rb +28 -0
  186. data/spec/unit/axiom/optimizer/algebra/restriction/order_operand/optimize_spec.rb +22 -0
  187. data/spec/unit/axiom/optimizer/algebra/restriction/predicate_spec.rb +18 -0
  188. data/spec/unit/axiom/optimizer/algebra/restriction/product_operand/optimizable_predicate_spec.rb +44 -0
  189. data/spec/unit/axiom/optimizer/algebra/restriction/product_operand/optimize_spec.rb +48 -0
  190. data/spec/unit/axiom/optimizer/algebra/restriction/restriction_operand/optimizable_predicate_spec.rb +30 -0
  191. data/spec/unit/axiom/optimizer/algebra/restriction/restriction_operand/optimize_spec.rb +24 -0
  192. data/spec/unit/axiom/optimizer/algebra/restriction/set_operand/optimizable_predicate_spec.rb +30 -0
  193. data/spec/unit/axiom/optimizer/algebra/restriction/set_operand/optimize_spec.rb +24 -0
  194. data/spec/unit/axiom/optimizer/algebra/restriction/tautology/optimizable_predicate_spec.rb +33 -0
  195. data/spec/unit/axiom/optimizer/algebra/restriction/tautology/optimize_spec.rb +19 -0
  196. data/spec/unit/axiom/optimizer/algebra/restriction/unoptimized_operand/optimizable_predicate_spec.rb +44 -0
  197. data/spec/unit/axiom/optimizer/algebra/restriction/unoptimized_operand/optimize_spec.rb +24 -0
  198. data/spec/unit/axiom/optimizer/algebra/summarization/empty_operand/class_methods/extension_default_spec.rb +22 -0
  199. data/spec/unit/axiom/optimizer/algebra/summarization/empty_operand/optimizable_predicate_spec.rb +29 -0
  200. data/spec/unit/axiom/optimizer/algebra/summarization/empty_operand/optimize_spec.rb +47 -0
  201. data/spec/unit/axiom/optimizer/algebra/summarization/empty_summarize_per/optimizable_predicate_spec.rb +29 -0
  202. data/spec/unit/axiom/optimizer/algebra/summarization/empty_summarize_per/optimize_spec.rb +25 -0
  203. data/spec/unit/axiom/optimizer/algebra/summarization/order_operand/optimizable_predicate_spec.rb +23 -0
  204. data/spec/unit/axiom/optimizer/algebra/summarization/order_operand/optimize_spec.rb +22 -0
  205. data/spec/unit/axiom/optimizer/algebra/summarization/summarize_per_spec.rb +29 -0
  206. data/spec/unit/axiom/optimizer/algebra/summarization/summarizers_spec.rb +31 -0
  207. data/spec/unit/axiom/optimizer/algebra/summarization/unoptimized_operand/optimizable_predicate_spec.rb +49 -0
  208. data/spec/unit/axiom/optimizer/algebra/summarization/unoptimized_operand/optimize_spec.rb +30 -0
  209. data/spec/unit/axiom/optimizer/algebra/union/empty_left/optimize_spec.rb +19 -0
  210. data/spec/unit/axiom/optimizer/algebra/union/empty_right/optimize_spec.rb +19 -0
  211. data/spec/unit/axiom/optimizer/algebra/union/equal_operands/optimize_spec.rb +19 -0
  212. data/spec/unit/axiom/optimizer/class_methods/chain_spec.rb +56 -0
  213. data/spec/unit/axiom/optimizer/function/binary/constant_operands/optimizable_predicate_spec.rb +36 -0
  214. data/spec/unit/axiom/optimizer/function/binary/constant_operands/optimize_spec.rb +18 -0
  215. data/spec/unit/axiom/optimizer/function/binary/left_spec.rb +28 -0
  216. data/spec/unit/axiom/optimizer/function/binary/right_spec.rb +28 -0
  217. data/spec/unit/axiom/optimizer/function/binary/unoptimized_operands/optimizable_predicate_spec.rb +37 -0
  218. data/spec/unit/axiom/optimizer/function/binary/unoptimized_operands/optimize_spec.rb +23 -0
  219. data/spec/unit/axiom/optimizer/function/class_methods/optimize_functions_spec.rb +26 -0
  220. data/spec/unit/axiom/optimizer/function/class_methods/optimize_operand_spec.rb +22 -0
  221. data/spec/unit/axiom/optimizer/function/connective/binary/constant_operands/optimize_spec.rb +16 -0
  222. data/spec/unit/axiom/optimizer/function/connective/binary/equal_operands/optimizable_predicate_spec.rb +29 -0
  223. data/spec/unit/axiom/optimizer/function/connective/binary/equal_operands/optimize_spec.rb +19 -0
  224. data/spec/unit/axiom/optimizer/function/connective/binary/left_spec.rb +16 -0
  225. data/spec/unit/axiom/optimizer/function/connective/binary/redundant_left/optimizable_predicate_spec.rb +28 -0
  226. data/spec/unit/axiom/optimizer/function/connective/binary/redundant_left/optimize_spec.rb +23 -0
  227. data/spec/unit/axiom/optimizer/function/connective/binary/redundant_right/optimizable_predicate_spec.rb +28 -0
  228. data/spec/unit/axiom/optimizer/function/connective/binary/redundant_right/optimize_spec.rb +23 -0
  229. data/spec/unit/axiom/optimizer/function/connective/binary/right_spec.rb +16 -0
  230. data/spec/unit/axiom/optimizer/function/connective/conjunction/contradiction/optimizable_predicate_spec.rb +64 -0
  231. data/spec/unit/axiom/optimizer/function/connective/conjunction/contradiction/optimize_spec.rb +19 -0
  232. data/spec/unit/axiom/optimizer/function/connective/conjunction/optimizable_to_exclusion/optimizable_predicate_spec.rb +61 -0
  233. data/spec/unit/axiom/optimizer/function/connective/conjunction/optimizable_to_exclusion/optimize_spec.rb +76 -0
  234. data/spec/unit/axiom/optimizer/function/connective/conjunction/tautology_left/optimizable_predicate_spec.rb +29 -0
  235. data/spec/unit/axiom/optimizer/function/connective/conjunction/tautology_left/optimize_spec.rb +19 -0
  236. data/spec/unit/axiom/optimizer/function/connective/conjunction/tautology_right/optimizable_predicate_spec.rb +29 -0
  237. data/spec/unit/axiom/optimizer/function/connective/conjunction/tautology_right/optimize_spec.rb +19 -0
  238. data/spec/unit/axiom/optimizer/function/connective/disjunction/contradiction_left/optimizable_predicate_spec.rb +29 -0
  239. data/spec/unit/axiom/optimizer/function/connective/disjunction/contradiction_left/optimize_spec.rb +19 -0
  240. data/spec/unit/axiom/optimizer/function/connective/disjunction/contradiction_right/optimizable_predicate_spec.rb +29 -0
  241. data/spec/unit/axiom/optimizer/function/connective/disjunction/contradiction_right/optimize_spec.rb +19 -0
  242. data/spec/unit/axiom/optimizer/function/connective/disjunction/optimizable_to_inclusion/optimizable_predicate_spec.rb +61 -0
  243. data/spec/unit/axiom/optimizer/function/connective/disjunction/optimizable_to_inclusion/optimize_spec.rb +76 -0
  244. data/spec/unit/axiom/optimizer/function/connective/disjunction/tautology/optimizable_predicate_spec.rb +64 -0
  245. data/spec/unit/axiom/optimizer/function/connective/disjunction/tautology/optimize_spec.rb +19 -0
  246. data/spec/unit/axiom/optimizer/function/connective/negation/constant_operand/optimize_spec.rb +16 -0
  247. data/spec/unit/axiom/optimizer/function/connective/negation/invertible_operand/optimizable_predicate_spec.rb +28 -0
  248. data/spec/unit/axiom/optimizer/function/connective/negation/invertible_operand/optimize_spec.rb +22 -0
  249. data/spec/unit/axiom/optimizer/function/connective/negation/operand_spec.rb +14 -0
  250. data/spec/unit/axiom/optimizer/function/predicate/comparable/never_comparable/optimizable_predicate_spec.rb +74 -0
  251. data/spec/unit/axiom/optimizer/function/predicate/comparable/never_equivalent/optimizable_predicate_spec.rb +74 -0
  252. data/spec/unit/axiom/optimizer/function/predicate/comparable/normalizable_operands/optimizable_predicate_spec.rb +43 -0
  253. data/spec/unit/axiom/optimizer/function/predicate/comparable/normalizable_operands/optimize_spec.rb +21 -0
  254. data/spec/unit/axiom/optimizer/function/predicate/constant_operands/optimize_spec.rb +16 -0
  255. data/spec/unit/axiom/optimizer/function/predicate/contradiction/optimize_spec.rb +18 -0
  256. data/spec/unit/axiom/optimizer/function/predicate/enumerable/class_methods/sort_by_value_spec.rb +27 -0
  257. data/spec/unit/axiom/optimizer/function/predicate/enumerable/empty_right/optimizable_predicate_spec.rb +78 -0
  258. data/spec/unit/axiom/optimizer/function/predicate/enumerable/one_right/optimizable_predicate_spec.rb +78 -0
  259. data/spec/unit/axiom/optimizer/function/predicate/enumerable/unoptimized_operands/optimizable_predicate_spec.rb +51 -0
  260. data/spec/unit/axiom/optimizer/function/predicate/enumerable/unoptimized_operands/optimize_spec.rb +66 -0
  261. data/spec/unit/axiom/optimizer/function/predicate/equality/tautology/optimizable_predicate_spec.rb +29 -0
  262. data/spec/unit/axiom/optimizer/function/predicate/exclusion/empty_right/optimize_spec.rb +45 -0
  263. data/spec/unit/axiom/optimizer/function/predicate/exclusion/one_right/optimize_spec.rb +65 -0
  264. data/spec/unit/axiom/optimizer/function/predicate/greater_than/contradiction/optimizable_predicate_spec.rb +43 -0
  265. data/spec/unit/axiom/optimizer/function/predicate/greater_than/tautology/optimizable_predicate_spec.rb +28 -0
  266. data/spec/unit/axiom/optimizer/function/predicate/greater_than_or_equal_to/contradiction/optimizable_predicate_spec.rb +43 -0
  267. data/spec/unit/axiom/optimizer/function/predicate/greater_than_or_equal_to/tautology/optimizable_predicate_spec.rb +43 -0
  268. data/spec/unit/axiom/optimizer/function/predicate/inclusion/empty_right/optimize_spec.rb +45 -0
  269. data/spec/unit/axiom/optimizer/function/predicate/inclusion/one_right/optimize_spec.rb +66 -0
  270. data/spec/unit/axiom/optimizer/function/predicate/inequality/contradiction/optimizable_predicate_spec.rb +29 -0
  271. data/spec/unit/axiom/optimizer/function/predicate/less_than/contradiction/optimizable_predicate_spec.rb +43 -0
  272. data/spec/unit/axiom/optimizer/function/predicate/less_than/tautology/optimizable_predicate_spec.rb +28 -0
  273. data/spec/unit/axiom/optimizer/function/predicate/less_than_or_equal_to/contradiction/optimizable_predicate_spec.rb +43 -0
  274. data/spec/unit/axiom/optimizer/function/predicate/less_than_or_equal_to/tautology/optimizable_predicate_spec.rb +43 -0
  275. data/spec/unit/axiom/optimizer/function/predicate/tautology/optimize_spec.rb +18 -0
  276. data/spec/unit/axiom/optimizer/function/unary/constant_operand/optimizable_predicate_spec.rb +27 -0
  277. data/spec/unit/axiom/optimizer/function/unary/constant_operand/optimize_spec.rb +18 -0
  278. data/spec/unit/axiom/optimizer/function/unary/operand_spec.rb +27 -0
  279. data/spec/unit/axiom/optimizer/function/unary/unoptimized_operand/optimizable_predicate_spec.rb +27 -0
  280. data/spec/unit/axiom/optimizer/function/unary/unoptimized_operand/optimize_spec.rb +18 -0
  281. data/spec/unit/axiom/optimizer/function/util/class_methods/attribute_spec.rb +21 -0
  282. data/spec/unit/axiom/optimizer/function/util/class_methods/constant_spec.rb +27 -0
  283. data/spec/unit/axiom/optimizer/function/util/class_methods/max_spec.rb +27 -0
  284. data/spec/unit/axiom/optimizer/function/util/class_methods/min_spec.rb +27 -0
  285. data/spec/unit/axiom/optimizer/operation_spec.rb +13 -0
  286. data/spec/unit/axiom/optimizer/optimizable/class_methods/optimizer_spec.rb +34 -0
  287. data/spec/unit/axiom/optimizer/optimizable/optimize_spec.rb +38 -0
  288. data/spec/unit/axiom/optimizer/optimizable_predicate_spec.rb +17 -0
  289. data/spec/unit/axiom/optimizer/optimize_spec.rb +17 -0
  290. data/spec/unit/axiom/optimizer/predicate_partition/left_spec.rb +149 -0
  291. data/spec/unit/axiom/optimizer/predicate_partition/remainder_spec.rb +149 -0
  292. data/spec/unit/axiom/optimizer/predicate_partition/right_spec.rb +149 -0
  293. data/spec/unit/axiom/optimizer/relation/materialized/empty_operand/optimizable_predicate_spec.rb +22 -0
  294. data/spec/unit/axiom/optimizer/relation/materialized/empty_operand/optimize_spec.rb +21 -0
  295. data/spec/unit/axiom/optimizer/relation/operation/binary/empty_left/optimizable_predicate_spec.rb +28 -0
  296. data/spec/unit/axiom/optimizer/relation/operation/binary/empty_right/optimizable_predicate_spec.rb +28 -0
  297. data/spec/unit/axiom/optimizer/relation/operation/binary/equal_operands/optimizable_predicate_spec.rb +31 -0
  298. data/spec/unit/axiom/optimizer/relation/operation/binary/left_spec.rb +15 -0
  299. data/spec/unit/axiom/optimizer/relation/operation/binary/materialized_operands/optimizable_predicate_spec.rb +37 -0
  300. data/spec/unit/axiom/optimizer/relation/operation/binary/materialized_operands/optimize_spec.rb +22 -0
  301. data/spec/unit/axiom/optimizer/relation/operation/binary/order_left/optimizable_predicate_spec.rb +23 -0
  302. data/spec/unit/axiom/optimizer/relation/operation/binary/order_left/optimize_spec.rb +23 -0
  303. data/spec/unit/axiom/optimizer/relation/operation/binary/order_right/optimizable_predicate_spec.rb +23 -0
  304. data/spec/unit/axiom/optimizer/relation/operation/binary/order_right/optimize_spec.rb +23 -0
  305. data/spec/unit/axiom/optimizer/relation/operation/binary/right_spec.rb +15 -0
  306. data/spec/unit/axiom/optimizer/relation/operation/binary/unoptimized_operands/optimizable_predicate_spec.rb +40 -0
  307. data/spec/unit/axiom/optimizer/relation/operation/binary/unoptimized_operands/optimize_spec.rb +24 -0
  308. data/spec/unit/axiom/optimizer/relation/operation/combination/optimize_spec.rb +18 -0
  309. data/spec/unit/axiom/optimizer/relation/operation/limit/equal_limit_operand/optimizable_predicate_spec.rb +33 -0
  310. data/spec/unit/axiom/optimizer/relation/operation/limit/equal_limit_operand/optimize_spec.rb +18 -0
  311. data/spec/unit/axiom/optimizer/relation/operation/limit/limit_operand/optimizable_predicate_spec.rb +27 -0
  312. data/spec/unit/axiom/optimizer/relation/operation/limit/limit_operand/optimize_spec.rb +35 -0
  313. data/spec/unit/axiom/optimizer/relation/operation/limit/unoptimized_operand/optimizable_predicate_spec.rb +28 -0
  314. data/spec/unit/axiom/optimizer/relation/operation/limit/unoptimized_operand/optimize_spec.rb +22 -0
  315. data/spec/unit/axiom/optimizer/relation/operation/limit/zero_limit/optimizable_predicate_spec.rb +27 -0
  316. data/spec/unit/axiom/optimizer/relation/operation/limit/zero_limit/optimize_spec.rb +22 -0
  317. data/spec/unit/axiom/optimizer/relation/operation/offset/offset_operand/optimizable_predicate_spec.rb +27 -0
  318. data/spec/unit/axiom/optimizer/relation/operation/offset/offset_operand/optimize_spec.rb +21 -0
  319. data/spec/unit/axiom/optimizer/relation/operation/offset/unoptimized_operand/optimizable_predicate_spec.rb +28 -0
  320. data/spec/unit/axiom/optimizer/relation/operation/offset/unoptimized_operand/optimize_spec.rb +22 -0
  321. data/spec/unit/axiom/optimizer/relation/operation/offset/zero_offset/optimizable_predicate_spec.rb +27 -0
  322. data/spec/unit/axiom/optimizer/relation/operation/offset/zero_offset/optimize_spec.rb +17 -0
  323. data/spec/unit/axiom/optimizer/relation/operation/order/one_limit_operand/optimizable_predicate_spec.rb +33 -0
  324. data/spec/unit/axiom/optimizer/relation/operation/order/one_limit_operand/optimize_spec.rb +18 -0
  325. data/spec/unit/axiom/optimizer/relation/operation/order/order_operand/optimizable_predicate_spec.rb +27 -0
  326. data/spec/unit/axiom/optimizer/relation/operation/order/order_operand/optimize_spec.rb +22 -0
  327. data/spec/unit/axiom/optimizer/relation/operation/order/unoptimized_operand/optimizable_predicate_spec.rb +28 -0
  328. data/spec/unit/axiom/optimizer/relation/operation/order/unoptimized_operand/optimize_spec.rb +23 -0
  329. data/spec/unit/axiom/optimizer/relation/operation/reverse/order_operand/optimizable_predicate_spec.rb +27 -0
  330. data/spec/unit/axiom/optimizer/relation/operation/reverse/order_operand/optimize_spec.rb +22 -0
  331. data/spec/unit/axiom/optimizer/relation/operation/reverse/reverse_operand/optimizable_predicate_spec.rb +27 -0
  332. data/spec/unit/axiom/optimizer/relation/operation/reverse/reverse_operand/optimize_spec.rb +19 -0
  333. data/spec/unit/axiom/optimizer/relation/operation/reverse/unoptimized_operand/optimizable_predicate_spec.rb +27 -0
  334. data/spec/unit/axiom/optimizer/relation/operation/reverse/unoptimized_operand/optimize_spec.rb +24 -0
  335. data/spec/unit/axiom/optimizer/relation/operation/unary/empty_operand/optimizable_predicate_spec.rb +23 -0
  336. data/spec/unit/axiom/optimizer/relation/operation/unary/empty_operand/optimize_spec.rb +17 -0
  337. data/spec/unit/axiom/optimizer/relation/operation/unary/header_spec.rb +15 -0
  338. data/spec/unit/axiom/optimizer/relation/operation/unary/materialized_operand/optimizable_predicate_spec.rb +23 -0
  339. data/spec/unit/axiom/optimizer/relation/operation/unary/materialized_operand/optimize_spec.rb +20 -0
  340. data/spec/unit/axiom/optimizer/relation/operation/unary/operand_spec.rb +16 -0
  341. data/spec/unit/axiom/optimizer/relation/operation/unary/order_operand/optimizable_predicate_spec.rb +28 -0
  342. data/spec/unit/axiom/optimizer/relation/operation/unary/order_operand/optimize_spec.rb +27 -0
  343. data/spec/unit/axiom/optimizer/relation/operation/unary/unchanged_header/optimizable_predicate_spec.rb +24 -0
  344. data/spec/unit/axiom/optimizer/relation/operation/unary/unchanged_header/optimize_spec.rb +14 -0
  345. metadata +697 -0
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Optimizer::Function::Util, '.max' do
6
+ subject { object.max(operand) }
7
+
8
+ let(:object) { Optimizer::Function::Util }
9
+
10
+ context 'with an Integer attribute' do
11
+ let(:operand) { Attribute::Integer.new(:id, :size => 1..10) }
12
+
13
+ it { should == 10 }
14
+ end
15
+
16
+ context 'with a String attribute' do
17
+ let(:operand) { Attribute::String.new(:id, :min_length => 1, :max_length => 10) }
18
+
19
+ it { should == 10 }
20
+ end
21
+
22
+ context 'with a constant' do
23
+ let(:operand) { 1 }
24
+
25
+ it { should == 1 }
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Optimizer::Function::Util, '.min' do
6
+ subject { object.min(operand) }
7
+
8
+ let(:object) { Optimizer::Function::Util }
9
+
10
+ context 'with an Integer attribute' do
11
+ let(:operand) { Attribute::Integer.new(:id, :size => 1..10) }
12
+
13
+ it { should == 1 }
14
+ end
15
+
16
+ context 'with a String attribute' do
17
+ let(:operand) { Attribute::String.new(:id, :min_length => 1, :max_length => 10) }
18
+
19
+ it { should == 1 }
20
+ end
21
+
22
+ context 'with a constat' do
23
+ let(:operand) { 1 }
24
+
25
+ it { should == 1 }
26
+ end
27
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Optimizer, '#operation' do
6
+ subject { object.operation }
7
+
8
+ let(:described_class) { Class.new(Optimizer) }
9
+ let(:operation) { mock('Operation') }
10
+ let(:object) { described_class.new(operation) }
11
+
12
+ it { should equal(operation) }
13
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Optimizer::Optimizable::ClassMethods, '#optimizer' do
6
+ subject { object.optimizer }
7
+
8
+ let(:object) { Class.new { include Optimizer::Optimizable, Adamantium } }
9
+
10
+ context 'when the optimizer is not set' do
11
+ it { should be_nil }
12
+ end
13
+
14
+ context 'when the optimizer is set' do
15
+ let(:optimizer) { mock('Optimizer') }
16
+
17
+ before do
18
+ object.optimizer = optimizer
19
+ end
20
+
21
+ it { should equal(optimizer) }
22
+ end
23
+ end
24
+
25
+ describe Optimizer::Optimizable::ClassMethods, '#optimizer=' do
26
+ subject { object.optimizer = optimizer }
27
+
28
+ let(:optimizer) { mock('Optimizer') }
29
+ let(:object) { Class.new { include Optimizer::Optimizable, Adamantium } }
30
+
31
+ it 'sets the optimizer' do
32
+ expect { subject }.to change { object.optimizer }.from(nil).to(optimizer)
33
+ end
34
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Optimizer::Optimizable, '#optimize' do
6
+ subject { object.optimize }
7
+
8
+ let(:described_class) { Class.new { include Optimizer::Optimizable, Adamantium } }
9
+ let(:object) { described_class.new }
10
+
11
+ context 'when there is no optimizer for the class' do
12
+ it { should equal(object) }
13
+
14
+ it_should_behave_like 'an optimize method'
15
+ end
16
+
17
+ context 'when there is an optimizer for the class' do
18
+ let(:optimized) { mock('Optimized', :frozen? => true) }
19
+ let(:optimizer) { mock('Optimizer', :call => optimized) }
20
+
21
+ before do
22
+ described_class.optimizer = optimizer
23
+ optimized.stub!(:optimize).and_return(optimized)
24
+ end
25
+
26
+ it { should equal(optimized) }
27
+
28
+ it 'calls the optimizer with the object' do
29
+ optimizer.should_receive(:call).with(object).and_return(optimized)
30
+ should equal(optimized)
31
+ end
32
+
33
+ it '#optimize the optimized object' do
34
+ optimized.should_receive(:optimize).with(no_args).and_return(optimized)
35
+ should equal(optimized)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Optimizer, '#optimizable?' do
6
+ subject { object.optimizable? }
7
+
8
+ let(:described_class) { Class.new(Optimizer) }
9
+ let(:operation) { mock('Operation') }
10
+ let(:object) { described_class.new(operation) }
11
+
12
+ before do
13
+ described_class.stub!(:to_s).and_return('Optimizer')
14
+ end
15
+
16
+ specify { expect { subject }.to raise_error(NotImplementedError, 'Optimizer#optimizable? must be implemented') }
17
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Optimizer, '#optimize' do
6
+ subject { object.optimize }
7
+
8
+ let(:described_class) { Class.new(Optimizer) }
9
+ let(:operation) { mock('Operation') }
10
+ let(:object) { described_class.new(operation) }
11
+
12
+ before do
13
+ described_class.stub!(:to_s).and_return('Optimizer')
14
+ end
15
+
16
+ specify { expect { subject }.to raise_error(NotImplementedError, 'Optimizer#optimize must be implemented') }
17
+ end
@@ -0,0 +1,149 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Optimizer::PredicatePartition, '#left' do
6
+ subject { object.left }
7
+
8
+ let(:left_header) { Relation::Header.coerce([ [ :id, Integer ], [ :user_name, String ], Attribute::Boolean.new(:active_user), Attribute::Boolean.new(:active) ]) }
9
+ let(:right_header) { Relation::Header.coerce([ [ :id, Integer ], [ :employee_name, String ], Attribute::Boolean.new(:active_employee), Attribute::Boolean.new(:active) ]) }
10
+ let(:object) { described_class.new(predicate, left_header, right_header) }
11
+
12
+ context 'when the predicate is a tautology' do
13
+ let(:predicate) { Function::Proposition::Tautology.instance }
14
+
15
+ it 'partitions the predicate to the left' do
16
+ should equal(Function::Proposition::Tautology.instance)
17
+ end
18
+ end
19
+
20
+ context 'when the predicate is a contradiction' do
21
+ let(:predicate) { Function::Proposition::Contradiction.instance }
22
+
23
+ it 'partitions the predicate to the left' do
24
+ should equal(Function::Proposition::Contradiction.instance)
25
+ end
26
+ end
27
+
28
+ context 'when the predicate is an attribute' do
29
+ context 'with an attribute from the left header, but not the right header' do
30
+ let(:predicate) { left_header[:active_user] }
31
+
32
+ it 'partitions the predicate to the left' do
33
+ should equal(predicate)
34
+ end
35
+ end
36
+
37
+ context 'with an attribute from the right header, but not the left header' do
38
+ let(:predicate) { right_header[:active_employee] }
39
+
40
+ it 'does not partition the predicate to the left' do
41
+ should equal(Function::Proposition::Tautology.instance)
42
+ end
43
+ end
44
+
45
+ context 'with an attribute from the left and right header' do
46
+ let(:predicate) { left_header[:active] }
47
+
48
+ it 'partitions the predicate to the left' do
49
+ should equal(predicate)
50
+ end
51
+ end
52
+ end
53
+
54
+ context 'when the predicate is a binary predicate' do
55
+ context 'with an attribute from the left header, but not the right header' do
56
+ let(:predicate) { left_header[:user_name].eq('Dan Kubb') }
57
+
58
+ it 'partitions the predicate to the left' do
59
+ should equal(predicate)
60
+ end
61
+ end
62
+
63
+ context 'with an attribute from the right header, but not the left header' do
64
+ let(:predicate) { right_header[:employee_name].eq('Dan Kubb') }
65
+
66
+ it 'does not partition the predicate to the left' do
67
+ should equal(Function::Proposition::Tautology.instance)
68
+ end
69
+ end
70
+
71
+ context 'with an attribute from the left and right header' do
72
+ let(:predicate) { left_header[:id].eq(1) }
73
+
74
+ it 'partitions the predicate to the left' do
75
+ should equal(predicate)
76
+ end
77
+ end
78
+
79
+ context 'with an attribute from the left header, and an attribute from the left and right header' do
80
+ let(:predicate) { left_header[:active_user].eq(left_header[:active]) }
81
+
82
+ it 'partitions the predicate to the left' do
83
+ should equal(predicate)
84
+ end
85
+ end
86
+
87
+ context 'with an attribute from the right header, and an attribute from the left and right header' do
88
+ let(:predicate) { right_header[:active_employee].eq(left_header[:active]) }
89
+
90
+ it 'partitions the predicate to the left' do
91
+ should equal(predicate)
92
+ end
93
+ end
94
+
95
+ context 'with disjoint attributes from the left and right header' do
96
+ let(:predicate) { left_header[:user_name].eq(right_header[:employee_name]) }
97
+
98
+ it 'does not partition the predicate to the left' do
99
+ should equal(Function::Proposition::Tautology.instance)
100
+ end
101
+ end
102
+ end
103
+
104
+ context 'when the predicate is a negation' do
105
+ context 'with an attribute from the left header, but not the right header' do
106
+ let(:predicate) { Function::Connective::Negation.new(left_header[:active_user]) }
107
+
108
+ it 'partitions the predicate to the left' do
109
+ should equal(predicate)
110
+ end
111
+ end
112
+
113
+ context 'with an attribute from the right header, but not the left header' do
114
+ let(:predicate) { Function::Connective::Negation.new(right_header[:active_employee]) }
115
+
116
+ it 'does not partition the predicate to the left' do
117
+ should equal(Function::Proposition::Tautology.instance)
118
+ end
119
+ end
120
+
121
+ context 'with an attribute from the left and right header' do
122
+ let(:predicate) { Function::Connective::Negation.new(left_header[:active]) }
123
+
124
+ it 'partitions the predicate to the left' do
125
+ should equal(predicate)
126
+ end
127
+ end
128
+ end
129
+
130
+ context 'when the predicate is a conjunction' do
131
+ let(:left_predicate) { left_header[:user_name].eq('Dan Kubb') }
132
+ let(:right_predicate) { right_header[:employee_name].eq('Dan Kubb') }
133
+ let(:predicate) { left_predicate.and(right_predicate) }
134
+
135
+ it 'partitions the predicate to the left that reference the left header' do
136
+ should equal(left_predicate)
137
+ end
138
+ end
139
+
140
+ context 'when the predicate is a disjunction' do
141
+ let(:left_predicate) { left_header[:user_name].eq('Dan Kubb') }
142
+ let(:right_predicate) { right_header[:employee_name].eq('Dan Kubb') }
143
+ let(:predicate) { left_predicate.or(right_predicate) }
144
+
145
+ it 'partitions the predicate to the left that reference the left header, transforming it with De Morgan\'s Law' do
146
+ should eql(left_header[:user_name].ne('Dan Kubb'))
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,149 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Optimizer::PredicatePartition, '#remainder' do
6
+ subject { object.remainder }
7
+
8
+ let(:left_header) { Relation::Header.coerce([ [ :id, Integer ], [ :user_name, String ], Attribute::Boolean.new(:active_user), Attribute::Boolean.new(:active) ]) }
9
+ let(:right_header) { Relation::Header.coerce([ [ :id, Integer ], [ :employee_name, String ], Attribute::Boolean.new(:active_employee), Attribute::Boolean.new(:active) ]) }
10
+ let(:object) { described_class.new(predicate, left_header, right_header) }
11
+
12
+ context 'when the predicate is a tautology' do
13
+ let(:predicate) { Function::Proposition::Tautology.instance }
14
+
15
+ it 'partitions the predicate to the remainder' do
16
+ should equal(Function::Proposition::Tautology.instance)
17
+ end
18
+ end
19
+
20
+ context 'when the predicate is a contradiction' do
21
+ let(:predicate) { Function::Proposition::Contradiction.instance }
22
+
23
+ it 'partitions the predicate to the remainder' do
24
+ should equal(Function::Proposition::Contradiction.instance)
25
+ end
26
+ end
27
+
28
+ context 'when the predicate is an attribute' do
29
+ context 'with an attribute from the left header, but not the right header' do
30
+ let(:predicate) { left_header[:active_user] }
31
+
32
+ it 'does not partition the predicate to the remainder' do
33
+ should equal(Function::Proposition::Tautology.instance)
34
+ end
35
+ end
36
+
37
+ context 'with an attribute from the right header, but not the left header' do
38
+ let(:predicate) { right_header[:active_employee] }
39
+
40
+ it 'does not partition the predicate to the remainder' do
41
+ should equal(Function::Proposition::Tautology.instance)
42
+ end
43
+ end
44
+
45
+ context 'with an attribute from the left and right header' do
46
+ let(:predicate) { left_header[:active] }
47
+
48
+ it 'does not partition the predicate to the remainder' do
49
+ should equal(Function::Proposition::Tautology.instance)
50
+ end
51
+ end
52
+ end
53
+
54
+ context 'when the predicate is a binary predicate' do
55
+ context 'with an attribute from the left header, but not the right header' do
56
+ let(:predicate) { left_header[:user_name].eq('Dan Kubb') }
57
+
58
+ it 'does not partition the predicate to the remainder' do
59
+ should equal(Function::Proposition::Tautology.instance)
60
+ end
61
+ end
62
+
63
+ context 'with an attribute from the right header, but not the left header' do
64
+ let(:predicate) { right_header[:employee_name].eq('Dan Kubb') }
65
+
66
+ it 'does not partition the predicate to the remainder' do
67
+ should equal(Function::Proposition::Tautology.instance)
68
+ end
69
+ end
70
+
71
+ context 'with an attribute from the left and right header' do
72
+ let(:predicate) { left_header[:id].eq(1) }
73
+
74
+ it 'does not partition the predicate to the remainder' do
75
+ should equal(Function::Proposition::Tautology.instance)
76
+ end
77
+ end
78
+
79
+ context 'with an attribute from the left header, and an attribute from the left and right header' do
80
+ let(:predicate) { left_header[:active_user].eq(left_header[:active]) }
81
+
82
+ it 'does not partition the predicate to the remainder' do
83
+ should equal(Function::Proposition::Tautology.instance)
84
+ end
85
+ end
86
+
87
+ context 'with an attribute from the right header, and an attribute from the left and right header' do
88
+ let(:predicate) { right_header[:active_employee].eq(left_header[:active]) }
89
+
90
+ it 'does not partition the predicate to the remainder' do
91
+ should equal(Function::Proposition::Tautology.instance)
92
+ end
93
+ end
94
+
95
+ context 'with disjoint attributes from the left and right header' do
96
+ let(:predicate) { left_header[:user_name].eq(right_header[:employee_name]) }
97
+
98
+ it 'partitions the predicate to the remainder' do
99
+ should equal(predicate)
100
+ end
101
+ end
102
+ end
103
+
104
+ context 'when the predicate is a negation' do
105
+ context 'with an attribute from the left header, but not the right header' do
106
+ let(:predicate) { Function::Connective::Negation.new(left_header[:active_user]) }
107
+
108
+ it 'does not partition the predicate to the remainder' do
109
+ should equal(Function::Proposition::Tautology.instance)
110
+ end
111
+ end
112
+
113
+ context 'with an attribute from the right header, but not the left header' do
114
+ let(:predicate) { Function::Connective::Negation.new(right_header[:active_employee]) }
115
+
116
+ it 'does not partition the predicate to the remainder' do
117
+ should equal(Function::Proposition::Tautology.instance)
118
+ end
119
+ end
120
+
121
+ context 'with an attribute from the left and right header' do
122
+ let(:predicate) { Function::Connective::Negation.new(left_header[:active]) }
123
+
124
+ it 'does not partition the predicate to the remainder' do
125
+ should equal(Function::Proposition::Tautology.instance)
126
+ end
127
+ end
128
+ end
129
+
130
+ context 'when the predicate is a conjunction' do
131
+ let(:left_predicate) { left_header[:user_name].eq('Dan Kubb') }
132
+ let(:right_predicate) { right_header[:employee_name].eq('Dan Kubb') }
133
+ let(:predicate) { left_predicate.and(right_predicate) }
134
+
135
+ it 'does not partition the predicate to the remainder' do
136
+ should equal(Function::Proposition::Tautology.instance)
137
+ end
138
+ end
139
+
140
+ context 'when the predicate is a disjunction' do
141
+ let(:left_predicate) { left_header[:user_name].eq('Dan Kubb') }
142
+ let(:right_predicate) { right_header[:employee_name].eq('Dan Kubb') }
143
+ let(:predicate) { left_predicate.or(right_predicate) }
144
+
145
+ it 'does not partition the predicate to the remainder' do
146
+ should equal(Function::Proposition::Tautology.instance)
147
+ end
148
+ end
149
+ end