rules 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (231) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +79 -0
  3. data/Rakefile +38 -0
  4. data/db/migrate/20120831163952_create_rules.rb +11 -0
  5. data/db/migrate/20120831173835_create_rule_sets.rb +10 -0
  6. data/lib/rules.rb +18 -0
  7. data/lib/rules/engine.rb +11 -0
  8. data/lib/rules/evaluators.rb +18 -0
  9. data/lib/rules/evaluators/definitions.rb +73 -0
  10. data/lib/rules/evaluators/evaluator.rb +25 -0
  11. data/lib/rules/extensions/active_admin/dsl.rb +31 -0
  12. data/lib/rules/has_rules.rb +24 -0
  13. data/lib/rules/parameters.rb +20 -0
  14. data/lib/rules/parameters/attribute.rb +16 -0
  15. data/lib/rules/parameters/constant.rb +25 -0
  16. data/lib/rules/parameters/constant_definitions.rb +15 -0
  17. data/lib/rules/parameters/parameter.rb +13 -0
  18. data/lib/rules/rule.rb +52 -0
  19. data/lib/rules/rule_set.rb +50 -0
  20. data/lib/rules/version.rb +3 -0
  21. data/lib/tasks/rules_tasks.rake +4 -0
  22. data/spec/dummy/README.rdoc +261 -0
  23. data/spec/dummy/Rakefile +7 -0
  24. data/spec/dummy/app/admin/dashboards.rb +33 -0
  25. data/spec/dummy/app/admin/orders.rb +30 -0
  26. data/spec/dummy/app/assets/images/edit_example.png +0 -0
  27. data/spec/dummy/app/assets/javascripts/active_admin.js +1 -0
  28. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  29. data/spec/dummy/app/assets/stylesheets/active_admin.css.scss +29 -0
  30. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  31. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  32. data/spec/dummy/app/controllers/orders_controller.rb +8 -0
  33. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  34. data/spec/dummy/app/models/admin_user.rb +11 -0
  35. data/spec/dummy/app/models/order.rb +20 -0
  36. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  37. data/spec/dummy/app/views/orders/show.html.haml +2 -0
  38. data/spec/dummy/config.ru +4 -0
  39. data/spec/dummy/config/application.rb +65 -0
  40. data/spec/dummy/config/boot.rb +10 -0
  41. data/spec/dummy/config/database.yml +25 -0
  42. data/spec/dummy/config/environment.rb +5 -0
  43. data/spec/dummy/config/environments/development.rb +37 -0
  44. data/spec/dummy/config/environments/production.rb +67 -0
  45. data/spec/dummy/config/environments/test.rb +37 -0
  46. data/spec/dummy/config/initializers/active_admin.rb +149 -0
  47. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  48. data/spec/dummy/config/initializers/devise.rb +232 -0
  49. data/spec/dummy/config/initializers/inflections.rb +15 -0
  50. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  51. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  52. data/spec/dummy/config/initializers/session_store.rb +8 -0
  53. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  54. data/spec/dummy/config/locales/devise.en.yml +58 -0
  55. data/spec/dummy/config/locales/en.yml +5 -0
  56. data/spec/dummy/config/routes.rb +9 -0
  57. data/spec/dummy/db/development.sqlite3 +0 -0
  58. data/spec/dummy/db/migrate/20120821181654_create_orders.rb +13 -0
  59. data/spec/dummy/db/migrate/20120831163952_create_rules.rb +11 -0
  60. data/spec/dummy/db/migrate/20120831173835_create_rule_sets.rb +10 -0
  61. data/spec/dummy/db/migrate/20120901044842_devise_create_admin_users.rb +52 -0
  62. data/spec/dummy/db/migrate/20120901044906_create_admin_notes.rb +17 -0
  63. data/spec/dummy/db/migrate/20120901044907_move_admin_notes_to_comments.rb +25 -0
  64. data/spec/dummy/db/production.sqlite3 +0 -0
  65. data/spec/dummy/db/schema.rb +75 -0
  66. data/spec/dummy/db/seeds.rb +1 -0
  67. data/spec/dummy/db/test.sqlite3 +0 -0
  68. data/spec/dummy/log/development.log +8764 -0
  69. data/spec/dummy/log/production.log +74 -0
  70. data/spec/dummy/log/test.log +1573 -0
  71. data/spec/dummy/public/404.html +26 -0
  72. data/spec/dummy/public/422.html +26 -0
  73. data/spec/dummy/public/500.html +25 -0
  74. data/spec/dummy/public/favicon.ico +0 -0
  75. data/spec/dummy/script/rails +6 -0
  76. data/spec/dummy/tmp/cache/assets/C58/950/sprockets%2F615625588c137a1529206d80ee81fe93 +0 -0
  77. data/spec/dummy/tmp/cache/assets/C83/FF0/sprockets%2F75b536e9b6927c15b60310fa867e3613 +0 -0
  78. data/spec/dummy/tmp/cache/assets/C88/FD0/sprockets%2F6c558405457e9b59062515dc86bfa252 +0 -0
  79. data/spec/dummy/tmp/cache/assets/C99/A50/sprockets%2Ffd135176f584f5f5658ef48f41187352 +0 -0
  80. data/spec/dummy/tmp/cache/assets/C9B/B40/sprockets%2F29dc70cbda38311141464e041655de41 +0 -0
  81. data/spec/dummy/tmp/cache/assets/C9F/2F0/sprockets%2Faf814c1513450b5466432d2a565ca5c6 +0 -0
  82. data/spec/dummy/tmp/cache/assets/CA2/8F0/sprockets%2Fa283030e028b24b4ba4084e067888c3e +0 -0
  83. data/spec/dummy/tmp/cache/assets/CA7/860/sprockets%2F0b1c90a9344b3c3989fc2153d0d63193 +0 -0
  84. data/spec/dummy/tmp/cache/assets/CAC/4A0/sprockets%2F3d00565c9e04f1bd481d33b4f1985706 +0 -0
  85. data/spec/dummy/tmp/cache/assets/CAD/F70/sprockets%2F5a1855f4cda19a255ffc802226735517 +0 -0
  86. data/spec/dummy/tmp/cache/assets/CAE/DA0/sprockets%2F9a133e6ab132f569c40b5e82188f4290 +0 -0
  87. data/spec/dummy/tmp/cache/assets/CB2/140/sprockets%2F035ac84d6c64495d0067b926533f8bc3 +0 -0
  88. data/spec/dummy/tmp/cache/assets/CB2/920/sprockets%2F2db5288c0689b237264d0fb22b74d981 +0 -0
  89. data/spec/dummy/tmp/cache/assets/CB8/A30/sprockets%2Ff35759652c08bb7b3921c434d9ee1654 +0 -0
  90. data/spec/dummy/tmp/cache/assets/CCA/AE0/sprockets%2Ff80b892078268a51ddf973986035bf9d +0 -0
  91. data/spec/dummy/tmp/cache/assets/CD0/AC0/sprockets%2F6f2c1b921c2b86e16aee3245772240c1 +0 -0
  92. data/spec/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
  93. data/spec/dummy/tmp/cache/assets/CDB/040/sprockets%2Fc732474e67003a4eb840eb44c5ca9385 +0 -0
  94. data/spec/dummy/tmp/cache/assets/CE0/300/sprockets%2F79b0286bc0a316d639ed5f83b1d33763 +0 -0
  95. data/spec/dummy/tmp/cache/assets/CE4/D80/sprockets%2Fd7f4b155b13ea1d8578693e62b0e6463 +0 -0
  96. data/spec/dummy/tmp/cache/assets/CF9/580/sprockets%2F9b6f302133d13906b7d823b4ae14f0aa +0 -0
  97. data/spec/dummy/tmp/cache/assets/CFD/B50/sprockets%2Fb21fb4d7213b3bf64d6317b3f22584b1 +0 -0
  98. data/spec/dummy/tmp/cache/assets/CFE/450/sprockets%2F088e843f7fffd845821822c7668a4d7e +0 -0
  99. data/spec/dummy/tmp/cache/assets/CFE/5D0/sprockets%2F5e63c7f47b86e8916fe1b8f88f470370 +0 -0
  100. data/spec/dummy/tmp/cache/assets/CFE/D50/sprockets%2Fc912074248a7b0bdc219a5eac3c52348 +0 -0
  101. data/spec/dummy/tmp/cache/assets/D0B/650/sprockets%2Fb66b60c6b42330849f5b7449bbe108bd +0 -0
  102. data/spec/dummy/tmp/cache/assets/D0B/EB0/sprockets%2Fa18a9144dadd3f628d2f061f91190d65 +0 -0
  103. data/spec/dummy/tmp/cache/assets/D0E/820/sprockets%2F1611a9cc354f4e02c97d26b3c6ce7466 +0 -0
  104. data/spec/dummy/tmp/cache/assets/D11/FD0/sprockets%2Ff7129bbf85d84e8bc056543e20281e3b +0 -0
  105. data/spec/dummy/tmp/cache/assets/D24/B00/sprockets%2F671d6f261d89a29e918b1ec7818db6a9 +0 -0
  106. data/spec/dummy/tmp/cache/assets/D29/AE0/sprockets%2Fb62ea1b010afb027501b4f18b8dd3689 +0 -0
  107. data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  108. data/spec/dummy/tmp/cache/assets/D38/540/sprockets%2F86e1ad844bc9df4491a2a52b870421db +0 -0
  109. data/spec/dummy/tmp/cache/assets/D38/5F0/sprockets%2F0c09a45e38408ec6e0e9caf206d5028d +0 -0
  110. data/spec/dummy/tmp/cache/assets/D3A/CE0/sprockets%2F238bf80bfbe1e2a5bb9280e62162584f +0 -0
  111. data/spec/dummy/tmp/cache/assets/D3B/000/sprockets%2F961758db39c6223d18ea6b7aeac400d5 +0 -0
  112. data/spec/dummy/tmp/cache/assets/D3B/F60/sprockets%2Ffd56cbfde039018718a0933340af6ef2 +0 -0
  113. data/spec/dummy/tmp/cache/assets/D41/AB0/sprockets%2Fd112ea59edbe4b7335549d814cb1d848 +0 -0
  114. data/spec/dummy/tmp/cache/assets/D47/050/sprockets%2F237eeefd847c43be2e7810a77e80841b +0 -0
  115. data/spec/dummy/tmp/cache/assets/D48/0D0/sprockets%2F1ef4ab19f690478ac62ad77fcb284447 +0 -0
  116. data/spec/dummy/tmp/cache/assets/D48/640/sprockets%2F9f4f18d910b678b1d0777e04cdaf6f24 +0 -0
  117. data/spec/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
  118. data/spec/dummy/tmp/cache/assets/D59/D70/sprockets%2Fed9f0de1b65ae8d7ef89087c83728461 +0 -0
  119. data/spec/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
  120. data/spec/dummy/tmp/cache/assets/D60/6C0/sprockets%2Fd7ef2595e5c50eb96e9d3c3d8698f481 +0 -0
  121. data/spec/dummy/tmp/cache/assets/D65/B10/sprockets%2Fca02dba972b587d3a69b8c32c7200fc6 +0 -0
  122. data/spec/dummy/tmp/cache/assets/D65/EE0/sprockets%2Fd9062d87143bb5c1d9d73c3ea02d7eb1 +0 -0
  123. data/spec/dummy/tmp/cache/assets/D66/2A0/sprockets%2F7b7cb56109acc9205fbbb792187ad04b +0 -0
  124. data/spec/dummy/tmp/cache/assets/D72/9E0/sprockets%2Fdf58dccde6a5e1266ba5c386149108c6 +0 -0
  125. data/spec/dummy/tmp/cache/assets/D84/0C0/sprockets%2Fe48907efa9d3370f9a2f687a1a7b8d8d +0 -0
  126. data/spec/dummy/tmp/cache/assets/D93/4C0/sprockets%2F857ecd2092cee11f740b3cf2e373ad2a +0 -0
  127. data/spec/dummy/tmp/cache/assets/D94/FA0/sprockets%2F8b190b3f72af75f09bfab1f354a0c37b +0 -0
  128. data/spec/dummy/tmp/cache/assets/D98/550/sprockets%2F69a91a7b4aca241c17daf6a78ac6845a +0 -0
  129. data/spec/dummy/tmp/cache/assets/D9E/530/sprockets%2F8dbb0027bd9ce6b96c81b82bdec17814 +0 -0
  130. data/spec/dummy/tmp/cache/assets/DAA/990/sprockets%2F8e0ca45c660183bfe809afc1f69bf9a9 +0 -0
  131. data/spec/dummy/tmp/cache/assets/DC1/C40/sprockets%2Fa8cbeabf3ef2d34b43be61671536f2a2 +0 -0
  132. data/spec/dummy/tmp/cache/assets/DC7/8B0/sprockets%2Ffad93382facdc50f097e26ebf19010ea +0 -0
  133. data/spec/dummy/tmp/cache/assets/DCE/350/sprockets%2F812b6c1998c5ad61096ae7b16cdaeeea +0 -0
  134. data/spec/dummy/tmp/cache/assets/DD3/370/sprockets%2Ff23609d51b09058fdd08daeecfd7e5e3 +0 -0
  135. data/spec/dummy/tmp/cache/assets/DD7/6A0/sprockets%2Fd5b1cca8d0835fbe9957aa4ee5f8333e +0 -0
  136. data/spec/dummy/tmp/cache/assets/DD8/440/sprockets%2F7edf42cfb3ac43c7cd4f63c3980d7c86 +0 -0
  137. data/spec/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
  138. data/spec/dummy/tmp/cache/assets/DDE/420/sprockets%2Ffb8b186d5bf0307f86f65fc787d2adeb +0 -0
  139. data/spec/dummy/tmp/cache/assets/DF5/270/sprockets%2Fc7f64f609aceac43da16557daacc421f +0 -0
  140. data/spec/dummy/tmp/cache/assets/DF5/410/sprockets%2Fd6efccfb4bfeb13ed0125e8c53424a65 +0 -0
  141. data/spec/dummy/tmp/cache/assets/DFF/180/sprockets%2Fdc24014f1fcc77f40c5e7de188ad8ebd +0 -0
  142. data/spec/dummy/tmp/cache/assets/E03/290/sprockets%2Fd469f86939a1cbd52d9b9aaf1db22dae +0 -0
  143. data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  144. data/spec/dummy/tmp/cache/assets/E07/7C0/sprockets%2Fcc5def6ed69cb6a1b7f6084992ed3ca1 +0 -0
  145. data/spec/dummy/tmp/cache/assets/ECA/140/sprockets%2Fd8ebea8564753ddfde91fadbdacc9f5b +0 -0
  146. data/spec/dummy/tmp/cache/sass/1a9fc2ebd62e6e7cb58441dc0293552ac07c99a9/_bourbon.scssc +0 -0
  147. data/spec/dummy/tmp/cache/sass/40a0b76d82cd847e80571abbfe75b703bdb6b77f/active_admin.css.scssc +0 -0
  148. data/spec/dummy/tmp/cache/sass/597823364192c14f6a72ee20d1a1496a722ab1f2/_all.css.scssc +0 -0
  149. data/spec/dummy/tmp/cache/sass/597823364192c14f6a72ee20d1a1496a722ab1f2/_buttons.css.scssc +0 -0
  150. data/spec/dummy/tmp/cache/sass/597823364192c14f6a72ee20d1a1496a722ab1f2/_gradients.css.scssc +0 -0
  151. data/spec/dummy/tmp/cache/sass/597823364192c14f6a72ee20d1a1496a722ab1f2/_icons.css.scssc +0 -0
  152. data/spec/dummy/tmp/cache/sass/597823364192c14f6a72ee20d1a1496a722ab1f2/_reset.css.scssc +0 -0
  153. data/spec/dummy/tmp/cache/sass/597823364192c14f6a72ee20d1a1496a722ab1f2/_rounded.css.scssc +0 -0
  154. data/spec/dummy/tmp/cache/sass/597823364192c14f6a72ee20d1a1496a722ab1f2/_sections.css.scssc +0 -0
  155. data/spec/dummy/tmp/cache/sass/597823364192c14f6a72ee20d1a1496a722ab1f2/_shadows.css.scssc +0 -0
  156. data/spec/dummy/tmp/cache/sass/597823364192c14f6a72ee20d1a1496a722ab1f2/_typography.scssc +0 -0
  157. data/spec/dummy/tmp/cache/sass/597823364192c14f6a72ee20d1a1496a722ab1f2/_utilities.scssc +0 -0
  158. data/spec/dummy/tmp/cache/sass/597823364192c14f6a72ee20d1a1496a722ab1f2/_variables.css.scssc +0 -0
  159. data/spec/dummy/tmp/cache/sass/6d594ee297c7ebeecae08432451ce722569d1a35/_footer.scssc +0 -0
  160. data/spec/dummy/tmp/cache/sass/6d594ee297c7ebeecae08432451ce722569d1a35/_main_structure.scssc +0 -0
  161. data/spec/dummy/tmp/cache/sass/6d594ee297c7ebeecae08432451ce722569d1a35/_title_bar.scssc +0 -0
  162. data/spec/dummy/tmp/cache/sass/7f31076cc0ed50f35bd0098f8e2a34720ee15633/_batch_actions.css.scssc +0 -0
  163. data/spec/dummy/tmp/cache/sass/7f31076cc0ed50f35bd0098f8e2a34720ee15633/_blank_slates.scssc +0 -0
  164. data/spec/dummy/tmp/cache/sass/7f31076cc0ed50f35bd0098f8e2a34720ee15633/_breadcrumbs.scssc +0 -0
  165. data/spec/dummy/tmp/cache/sass/7f31076cc0ed50f35bd0098f8e2a34720ee15633/_buttons.scssc +0 -0
  166. data/spec/dummy/tmp/cache/sass/7f31076cc0ed50f35bd0098f8e2a34720ee15633/_columns.scssc +0 -0
  167. data/spec/dummy/tmp/cache/sass/7f31076cc0ed50f35bd0098f8e2a34720ee15633/_comments.css.scssc +0 -0
  168. data/spec/dummy/tmp/cache/sass/7f31076cc0ed50f35bd0098f8e2a34720ee15633/_date_picker.css.scssc +0 -0
  169. data/spec/dummy/tmp/cache/sass/7f31076cc0ed50f35bd0098f8e2a34720ee15633/_dropdown_menu.scssc +0 -0
  170. data/spec/dummy/tmp/cache/sass/7f31076cc0ed50f35bd0098f8e2a34720ee15633/_flash_messages.css.scssc +0 -0
  171. data/spec/dummy/tmp/cache/sass/7f31076cc0ed50f35bd0098f8e2a34720ee15633/_grid.scssc +0 -0
  172. data/spec/dummy/tmp/cache/sass/7f31076cc0ed50f35bd0098f8e2a34720ee15633/_links.scssc +0 -0
  173. data/spec/dummy/tmp/cache/sass/7f31076cc0ed50f35bd0098f8e2a34720ee15633/_pagination.scssc +0 -0
  174. data/spec/dummy/tmp/cache/sass/7f31076cc0ed50f35bd0098f8e2a34720ee15633/_panels.scssc +0 -0
  175. data/spec/dummy/tmp/cache/sass/7f31076cc0ed50f35bd0098f8e2a34720ee15633/_popovers.css.scssc +0 -0
  176. data/spec/dummy/tmp/cache/sass/7f31076cc0ed50f35bd0098f8e2a34720ee15633/_scopes.scssc +0 -0
  177. data/spec/dummy/tmp/cache/sass/7f31076cc0ed50f35bd0098f8e2a34720ee15633/_status_tags.scssc +0 -0
  178. data/spec/dummy/tmp/cache/sass/7f31076cc0ed50f35bd0098f8e2a34720ee15633/_table_tools.css.scssc +0 -0
  179. data/spec/dummy/tmp/cache/sass/7f31076cc0ed50f35bd0098f8e2a34720ee15633/_tables.css.scssc +0 -0
  180. data/spec/dummy/tmp/cache/sass/89a136914378618e18c0f75bc8c0f78e84403b0f/_base.css.scssc +0 -0
  181. data/spec/dummy/tmp/cache/sass/89a136914378618e18c0f75bc8c0f78e84403b0f/_forms.css.scssc +0 -0
  182. data/spec/dummy/tmp/cache/sass/89a136914378618e18c0f75bc8c0f78e84403b0f/_header.css.scssc +0 -0
  183. data/spec/dummy/tmp/cache/sass/89a136914378618e18c0f75bc8c0f78e84403b0f/_mixins.css.scssc +0 -0
  184. data/spec/dummy/tmp/cache/sass/89a136914378618e18c0f75bc8c0f78e84403b0f/_typography.css.scssc +0 -0
  185. data/spec/dummy/tmp/cache/sass/89a136914378618e18c0f75bc8c0f78e84403b0f/print.css.scssc +0 -0
  186. data/spec/dummy/tmp/cache/sass/a28435efd4cb26f8ebc9e55bbaf23e3537a13190/_button.scssc +0 -0
  187. data/spec/dummy/tmp/cache/sass/a28435efd4cb26f8ebc9e55bbaf23e3537a13190/_clearfix.scssc +0 -0
  188. data/spec/dummy/tmp/cache/sass/a28435efd4cb26f8ebc9e55bbaf23e3537a13190/_font-face.scssc +0 -0
  189. data/spec/dummy/tmp/cache/sass/a28435efd4cb26f8ebc9e55bbaf23e3537a13190/_font-family.scssc +0 -0
  190. data/spec/dummy/tmp/cache/sass/a28435efd4cb26f8ebc9e55bbaf23e3537a13190/_hide-text.scssc +0 -0
  191. data/spec/dummy/tmp/cache/sass/a28435efd4cb26f8ebc9e55bbaf23e3537a13190/_html5-input-types.scssc +0 -0
  192. data/spec/dummy/tmp/cache/sass/a28435efd4cb26f8ebc9e55bbaf23e3537a13190/_position.scssc +0 -0
  193. data/spec/dummy/tmp/cache/sass/a28435efd4cb26f8ebc9e55bbaf23e3537a13190/_timing-functions.scssc +0 -0
  194. data/spec/dummy/tmp/cache/sass/bb2f93296c9b1e89237438ea63572f38aae290c3/_deprecated-webkit-gradient.scssc +0 -0
  195. data/spec/dummy/tmp/cache/sass/bb2f93296c9b1e89237438ea63572f38aae290c3/_flex-grid.scssc +0 -0
  196. data/spec/dummy/tmp/cache/sass/bb2f93296c9b1e89237438ea63572f38aae290c3/_grid-width.scssc +0 -0
  197. data/spec/dummy/tmp/cache/sass/bb2f93296c9b1e89237438ea63572f38aae290c3/_linear-gradient.scssc +0 -0
  198. data/spec/dummy/tmp/cache/sass/bb2f93296c9b1e89237438ea63572f38aae290c3/_modular-scale.scssc +0 -0
  199. data/spec/dummy/tmp/cache/sass/bb2f93296c9b1e89237438ea63572f38aae290c3/_radial-gradient.scssc +0 -0
  200. data/spec/dummy/tmp/cache/sass/bb2f93296c9b1e89237438ea63572f38aae290c3/_render-gradients.scssc +0 -0
  201. data/spec/dummy/tmp/cache/sass/bb2f93296c9b1e89237438ea63572f38aae290c3/_tint-shade.scssc +0 -0
  202. data/spec/dummy/tmp/cache/sass/bb2f93296c9b1e89237438ea63572f38aae290c3/_transition-property-name.scssc +0 -0
  203. data/spec/dummy/tmp/cache/sass/da77e6f9a782ec4d4cbe7e3a439e89684c300b51/_animation.scssc +0 -0
  204. data/spec/dummy/tmp/cache/sass/da77e6f9a782ec4d4cbe7e3a439e89684c300b51/_appearance.scssc +0 -0
  205. data/spec/dummy/tmp/cache/sass/da77e6f9a782ec4d4cbe7e3a439e89684c300b51/_background-image.scssc +0 -0
  206. data/spec/dummy/tmp/cache/sass/da77e6f9a782ec4d4cbe7e3a439e89684c300b51/_background-size.scssc +0 -0
  207. data/spec/dummy/tmp/cache/sass/da77e6f9a782ec4d4cbe7e3a439e89684c300b51/_background.scssc +0 -0
  208. data/spec/dummy/tmp/cache/sass/da77e6f9a782ec4d4cbe7e3a439e89684c300b51/_border-image.scssc +0 -0
  209. data/spec/dummy/tmp/cache/sass/da77e6f9a782ec4d4cbe7e3a439e89684c300b51/_border-radius.scssc +0 -0
  210. data/spec/dummy/tmp/cache/sass/da77e6f9a782ec4d4cbe7e3a439e89684c300b51/_box-shadow.scssc +0 -0
  211. data/spec/dummy/tmp/cache/sass/da77e6f9a782ec4d4cbe7e3a439e89684c300b51/_box-sizing.scssc +0 -0
  212. data/spec/dummy/tmp/cache/sass/da77e6f9a782ec4d4cbe7e3a439e89684c300b51/_columns.scssc +0 -0
  213. data/spec/dummy/tmp/cache/sass/da77e6f9a782ec4d4cbe7e3a439e89684c300b51/_flex-box.scssc +0 -0
  214. data/spec/dummy/tmp/cache/sass/da77e6f9a782ec4d4cbe7e3a439e89684c300b51/_inline-block.scssc +0 -0
  215. data/spec/dummy/tmp/cache/sass/da77e6f9a782ec4d4cbe7e3a439e89684c300b51/_linear-gradient.scssc +0 -0
  216. data/spec/dummy/tmp/cache/sass/da77e6f9a782ec4d4cbe7e3a439e89684c300b51/_prefixer.scssc +0 -0
  217. data/spec/dummy/tmp/cache/sass/da77e6f9a782ec4d4cbe7e3a439e89684c300b51/_radial-gradient.scssc +0 -0
  218. data/spec/dummy/tmp/cache/sass/da77e6f9a782ec4d4cbe7e3a439e89684c300b51/_transform.scssc +0 -0
  219. data/spec/dummy/tmp/cache/sass/da77e6f9a782ec4d4cbe7e3a439e89684c300b51/_transition.scssc +0 -0
  220. data/spec/dummy/tmp/cache/sass/da77e6f9a782ec4d4cbe7e3a439e89684c300b51/_user-select.scssc +0 -0
  221. data/spec/dummy/tmp/cache/sass/ee5b745f862b39ff22bf2068a6582c3ee05d1a79/_dashboard.scssc +0 -0
  222. data/spec/dummy/tmp/cache/sass/ee5b745f862b39ff22bf2068a6582c3ee05d1a79/_logged_out.scssc +0 -0
  223. data/spec/dummy/tmp/pids/server.pid +1 -0
  224. data/spec/rules/evaluators/definitions_spec.rb +41 -0
  225. data/spec/rules/evaluators_spec.rb +32 -0
  226. data/spec/rules/parameters/attribute_spec.rb +12 -0
  227. data/spec/rules/parameters_spec.rb +5 -0
  228. data/spec/rules/rule_set_spec.rb +90 -0
  229. data/spec/rules/rule_spec.rb +188 -0
  230. data/spec/spec_helper.rb +38 -0
  231. metadata +519 -0
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2012 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,79 @@
1
+ AR Rules
2
+ =========
3
+
4
+ A Ruby gem engine that allows you to add customizable business rules to any ActiveRecord model. Rules integrates with ActiveAdmin to make it trivial to allow admin users to create rules on the fly for your models.
5
+
6
+ Installation
7
+ ------------
8
+ Add it to your Gemfile:
9
+
10
+ ```ruby
11
+ gem "rules", :github => 'azach/rules'
12
+ ```
13
+
14
+ Update your schema:
15
+
16
+ ```ruby
17
+ rake rules:install:migrations
18
+ rake db:migrate
19
+ ```
20
+
21
+ to create the required tables to store your rules.
22
+
23
+ Setting Up Rules
24
+ ------------
25
+ To use rules on a model, include ```Rules::HasRules```. You can also optionally define any attributes that are available for that model using ```has_rule_attributes```.
26
+
27
+ This will allow the user to build rules against this attribute. For example, you may want to allow users to build rules against the email address in the order. In this case, your model would look like:
28
+
29
+ ```ruby
30
+ class Order < ActiveRecord::Base
31
+ include Rules::HasRules
32
+
33
+ has_rule_attributes({
34
+ customer_email: {
35
+ name: "customer email address"
36
+ }
37
+ })
38
+ end
39
+ ```
40
+
41
+ To evaluate a set of a rules, use the ```rules_pass?``` method on the instance. You may also pass the values of the attributes that you allowed users to define rules against at this point.
42
+
43
+ For example:
44
+
45
+ ```ruby
46
+ order = Order.new
47
+ order.email_address = "morbo@example.com"
48
+ order.evaluate(customer_email: order.email_address)
49
+ ```
50
+
51
+ Defining Rules
52
+ ------------
53
+ Rules are meant to be defined by business users using an admin interface. For this reason, the gem provides integration with ActiveAdmin to make this easier.
54
+
55
+ There are two helper methods you can use, one for your show action and one for your form.
56
+
57
+ For the show action:
58
+
59
+ ```ruby
60
+ show_rules
61
+ ```
62
+
63
+ For the form action:
64
+
65
+ ```ruby
66
+ f.has_rules
67
+ ```
68
+
69
+ This will give you something like:
70
+
71
+ ![ActiveAdmin form for editing rules](https://github.com/azach/rules/raw/master/spec/dummy/app/assets/images/edit_example.png)
72
+
73
+ Default Constants
74
+ ------------
75
+ TODO
76
+
77
+ Default Evaluators
78
+ ------------
79
+ TODO
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'Rules'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+
24
+
25
+
26
+ Bundler::GemHelper.install_tasks
27
+
28
+ require 'rake/testtask'
29
+
30
+ Rake::TestTask.new(:test) do |t|
31
+ t.libs << 'lib'
32
+ t.libs << 'spec'
33
+ t.pattern = 'spec/**/*_spec.rb'
34
+ t.verbose = false
35
+ end
36
+
37
+
38
+ task :default => :spec
@@ -0,0 +1,11 @@
1
+ class CreateRules < ActiveRecord::Migration
2
+ def change
3
+ create_table :rules_rules do |t|
4
+ t.belongs_to :rule_set
5
+ t.string :evaluator
6
+ t.text :parameters
7
+
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ class CreateRuleSets < ActiveRecord::Migration
2
+ def change
3
+ create_table :rules_rule_sets do |t|
4
+ t.belongs_to :source, polymorphic: true
5
+ t.string :evaluation_logic
6
+
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
data/lib/rules.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rules/engine'
2
+ require 'rules/evaluators'
3
+ require 'rules/evaluators/definitions'
4
+ require 'rules/has_rules'
5
+ require 'rules/parameters'
6
+ require 'rules/parameters/constant_definitions'
7
+ require 'rules/rule'
8
+ require 'rules/rule_set'
9
+
10
+ module Rules
11
+ def self.evaluators
12
+ @evaluators ||= Evaluators.list
13
+ end
14
+
15
+ def self.constants
16
+ @constants ||= Parameters.constants
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ module Rules
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace Rules
4
+
5
+ initializer :active_admin do
6
+ if defined? ActiveAdmin
7
+ require 'rules/extensions/active_admin/dsl'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,18 @@
1
+ module Rules
2
+ module Evaluators
3
+ require 'rules/evaluators/evaluator'
4
+
5
+ @@list ||= {}
6
+
7
+ def self.list
8
+ @@list
9
+ end
10
+
11
+ def self.define_evaluator(key, &block)
12
+ raise 'Evaluator already exists' if @@list[key]
13
+ evaluator = Evaluator.new(key)
14
+ evaluator.instance_eval(&block) if block_given?
15
+ @@list[key] = evaluator
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,73 @@
1
+ module Rules
2
+ module Evaluators
3
+ define_evaluator :equals do
4
+ self.evaluation_method = ->(lhs, rhs) { lhs == rhs }
5
+ self.requires_rhs = true
6
+ end
7
+
8
+ define_evaluator :not_equals do
9
+ self.evaluation_method = ->(lhs, rhs) { lhs != rhs }
10
+ self.name = 'does not equal'
11
+ self.requires_rhs = true
12
+ end
13
+
14
+ define_evaluator :contains do
15
+ self.evaluation_method = ->(lhs, rhs) { lhs.include?(rhs) }
16
+ self.name = 'contains'
17
+ self.requires_rhs = true
18
+ end
19
+
20
+ define_evaluator :not_contains do
21
+ self.evaluation_method = ->(lhs, rhs) { !lhs.include?(rhs) }
22
+ self.name = 'does not contain'
23
+ end
24
+
25
+ define_evaluator :nil do
26
+ self.evaluation_method = ->(lhs) { lhs.nil? }
27
+ self.name = 'exists'
28
+ self.requires_rhs = false
29
+ end
30
+
31
+ define_evaluator :not_nil do
32
+ self.evaluation_method = ->(lhs) { !lhs.nil? }
33
+ self.name = 'does not exist'
34
+ self.requires_rhs = false
35
+ end
36
+
37
+ define_evaluator :matches do
38
+ self.evaluation_method = ->(lhs, rhs) { !!(lhs =~ Regexp.new(rhs)) }
39
+ self.name = 'matches'
40
+ self.requires_rhs = true
41
+ end
42
+
43
+ define_evaluator :not_matches do
44
+ self.evaluation_method = ->(lhs, rhs) { !(lhs =~ Regexp.new(rhs)) }
45
+ self.name = 'does not match'
46
+ self.requires_rhs = true
47
+ end
48
+
49
+ define_evaluator :less_than do
50
+ self.evaluation_method = ->(lhs, rhs) { lhs < rhs }
51
+ self.name = 'less than'
52
+ self.requires_rhs = true
53
+ end
54
+
55
+ define_evaluator :less_than_or_equal_to do
56
+ self.evaluation_method = ->(lhs, rhs) { lhs <= rhs }
57
+ self.name = 'less than or equal to'
58
+ self.requires_rhs = true
59
+ end
60
+
61
+ define_evaluator :greater_than do
62
+ self.evaluation_method = ->(lhs, rhs) { lhs > rhs }
63
+ self.name = 'greater than'
64
+ self.requires_rhs = true
65
+ end
66
+
67
+ define_evaluator :greater_than_or_equal_to do
68
+ self.evaluation_method = ->(lhs, rhs) { lhs >= rhs }
69
+ self.name = 'greater than or equal to'
70
+ self.requires_rhs = true
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,25 @@
1
+ module Rules
2
+ module Evaluators
3
+ class Evaluator
4
+ attr_accessor :evaluation_method, :requires_rhs, :name
5
+
6
+ def initialize(key)
7
+ @name = key.to_s
8
+ @requires_rhs = true
9
+ end
10
+
11
+ def evaluate(lhs, rhs = nil)
12
+ raise 'Unknown evaluation method' unless evaluation_method
13
+ requires_rhs? ? evaluation_method.call(lhs, rhs) : evaluation_method.call(lhs)
14
+ end
15
+
16
+ def requires_rhs?
17
+ @requires_rhs
18
+ end
19
+
20
+ def to_s
21
+ @name
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,31 @@
1
+ ActiveAdmin::FormBuilder.class_eval do
2
+ def has_rules
3
+ self.inputs 'Rules' do
4
+ self.semantic_fields_for :rule_set do |rules_rule_set_form|
5
+ rules_rule_set_form.has_many :rules do |rules_rule_form|
6
+ rules_rule_form.input :lhs_parameter, :label => 'Left hand side', collection: rules_parameter_collection(rules_rule_form.object.rule_set)
7
+ rules_rule_form.input :evaluator, :as => :select, :collection => Rules.evaluators.map {|key, evaluator| [evaluator.name, key] }.sort_by {|name, key| name }
8
+ rules_rule_form.input :rhs_parameter, :label => 'Right hand side'
9
+ end
10
+ rules_rule_set_form.input :evaluation_logic, :as => :select, :label => 'Must match', collection: [['All Rules', 'all'], ['Any Rules', 'any']]
11
+ end
12
+ end
13
+ end
14
+
15
+ def rules_parameter_collection(rule_set)
16
+ @rules_parameter_collection ||= Rules.constants.merge(rule_set.try(:attributes) || {}).map {|key, const| [const.name, key] }
17
+ end
18
+ end
19
+
20
+ ActiveAdmin::Views::Pages::Show.class_eval do
21
+ def show_rules
22
+ panel "Rules" do
23
+ div resource.rule_set.evaluation_logic == 'any' ? 'Must match any rule' : 'Must match all rules'
24
+ table_for resource.rule_set.rules do |rule|
25
+ column('Left hand side') { |rule| rule.lhs_parameter_object.to_s.titleize }
26
+ column('Condition') { |rule| rule.get_evaluator }
27
+ column('Right hand side') { |rule| rule.rhs_parameter_value.to_s }
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,24 @@
1
+ module Rules
2
+ module HasRules
3
+ def self.included(base)
4
+ base.instance_eval do
5
+ has_one :rule_set, class_name: 'Rules::RuleSet', as: :source, dependent: :destroy
6
+
7
+ attr_accessible :rule_set_attributes
8
+ accepts_nested_attributes_for :rule_set, allow_destroy: true
9
+
10
+ def has_rule_attributes(attributes = {})
11
+ Rules::RuleSet.set_attributes_for(self, attributes)
12
+ end
13
+ end
14
+ end
15
+
16
+ def rule_set
17
+ super || Rules::RuleSet.new
18
+ end
19
+
20
+ def rules_pass?(options = {})
21
+ rule_set.nil? || rule_set.evaluate(options)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ module Rules
2
+ module Parameters
3
+ require 'rules/parameters/parameter'
4
+ require 'rules/parameters/attribute'
5
+ require 'rules/parameters/constant'
6
+
7
+ @@constants ||= {}
8
+
9
+ def self.constants
10
+ @@constants
11
+ end
12
+
13
+ def self.define_constant(key, &block)
14
+ raise "Constant #{key} already exists" if @@constants[key]
15
+ constant = Constant.new(key)
16
+ constant.instance_eval(&block) if block_given?
17
+ @@constants[key] = constant
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ require 'rules/parameters/parameter'
2
+
3
+ module Rules::Parameters
4
+ class Attribute < Parameter
5
+ attr_reader :key
6
+
7
+ def initialize(options = {})
8
+ @name = options[:name]
9
+ @key = options[:key].to_sym
10
+ end
11
+
12
+ def evaluate(attributes = {})
13
+ attributes.fetch(key)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ require 'rules/parameters/parameter'
2
+
3
+ module Rules::Parameters
4
+ class Constant < Parameter
5
+ attr_accessor :evaluation_method, :casting_method, :input_type
6
+
7
+ def initialize(key)
8
+ self.name = key.to_s
9
+ end
10
+
11
+ def evaluate(attributes = {})
12
+ raise 'Unknown evaluation method' unless evaluation_method
13
+ evaluation_method.call
14
+ end
15
+
16
+ def input_type
17
+ @input_type || :string
18
+ end
19
+
20
+ def cast(value)
21
+ return value unless casting_method
22
+ casting_method.call(value)
23
+ end
24
+ end
25
+ end