hyper-mesh 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (469) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +27 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +11 -0
  5. data/.travis.yml +4 -0
  6. data/CODE_OF_CONDUCT.md +13 -0
  7. data/Gemfile +5 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +396 -0
  10. data/Rakefile +6 -0
  11. data/app/controllers/reactive_record/application_controller.rb +4 -0
  12. data/app/controllers/reactive_record/reactive_record_controller.rb +49 -0
  13. data/bin/console +14 -0
  14. data/bin/setup +7 -0
  15. data/codeship.database.yml +18 -0
  16. data/config/routes.rb +7 -0
  17. data/docs/action_cable_quickstart.md +151 -0
  18. data/docs/authorization-policies.md +449 -0
  19. data/docs/client_side_scoping.md +103 -0
  20. data/docs/pusher_quickstart.md +0 -0
  21. data/docs/simple_poller_quickstart.md +121 -0
  22. data/docs/todo-example.md +116 -0
  23. data/docs/words-example.md +65 -0
  24. data/examples/action-cable/.gitignore +21 -0
  25. data/examples/action-cable/Gemfile +58 -0
  26. data/examples/action-cable/Gemfile.lock +247 -0
  27. data/examples/action-cable/README.md +24 -0
  28. data/examples/action-cable/Rakefile +6 -0
  29. data/examples/action-cable/app/assets/config/manifest.js +3 -0
  30. data/examples/action-cable/app/assets/javascripts/application.js +18 -0
  31. data/examples/action-cable/app/assets/stylesheets/application.css +15 -0
  32. data/examples/action-cable/app/controllers/application_controller.rb +3 -0
  33. data/examples/action-cable/app/controllers/test_controller.rb +6 -0
  34. data/examples/action-cable/app/models/models.rb +2 -0
  35. data/examples/action-cable/app/models/public/application_record.rb +3 -0
  36. data/examples/action-cable/app/models/public/word.rb +2 -0
  37. data/examples/action-cable/app/policies/application_policy.rb +6 -0
  38. data/examples/action-cable/app/views/components.rb +17 -0
  39. data/examples/action-cable/app/views/components/app.rb +18 -0
  40. data/examples/action-cable/app/views/layouts/application.html.erb +14 -0
  41. data/examples/action-cable/app/views/layouts/mailer.html.erb +13 -0
  42. data/examples/action-cable/app/views/layouts/mailer.text.erb +1 -0
  43. data/examples/action-cable/bin/bundle +3 -0
  44. data/examples/action-cable/bin/rails +9 -0
  45. data/examples/action-cable/bin/rake +9 -0
  46. data/examples/action-cable/bin/setup +34 -0
  47. data/examples/action-cable/bin/spring +15 -0
  48. data/examples/action-cable/bin/update +29 -0
  49. data/examples/action-cable/config.ru +5 -0
  50. data/examples/action-cable/config/application.rb +30 -0
  51. data/examples/action-cable/config/boot.rb +3 -0
  52. data/examples/action-cable/config/cable.yml +9 -0
  53. data/examples/action-cable/config/database.yml +25 -0
  54. data/examples/action-cable/config/environment.rb +5 -0
  55. data/examples/action-cable/config/environments/development.rb +45 -0
  56. data/examples/action-cable/config/environments/production.rb +86 -0
  57. data/examples/action-cable/config/environments/test.rb +42 -0
  58. data/examples/action-cable/config/initializers/application_controller_renderer.rb +6 -0
  59. data/examples/action-cable/config/initializers/assets.rb +11 -0
  60. data/examples/action-cable/config/initializers/backtrace_silencers.rb +7 -0
  61. data/examples/action-cable/config/initializers/cookies_serializer.rb +5 -0
  62. data/examples/action-cable/config/initializers/filter_parameter_logging.rb +4 -0
  63. data/examples/action-cable/config/initializers/inflections.rb +16 -0
  64. data/examples/action-cable/config/initializers/mime_types.rb +4 -0
  65. data/examples/action-cable/config/initializers/new_framework_defaults.rb +24 -0
  66. data/examples/action-cable/config/initializers/session_store.rb +3 -0
  67. data/examples/action-cable/config/initializers/synchromesh.rb +5 -0
  68. data/examples/action-cable/config/initializers/wrap_parameters.rb +14 -0
  69. data/examples/action-cable/config/locales/en.yml +23 -0
  70. data/examples/action-cable/config/puma.rb +47 -0
  71. data/examples/action-cable/config/routes.rb +5 -0
  72. data/examples/action-cable/config/secrets.yml +22 -0
  73. data/examples/action-cable/config/spring.rb +6 -0
  74. data/examples/action-cable/db/migrate/20160921223808_create_words.rb +9 -0
  75. data/examples/action-cable/db/schema.rb +21 -0
  76. data/examples/action-cable/log/.keep +0 -0
  77. data/examples/action-cable/public/404.html +67 -0
  78. data/examples/action-cable/public/422.html +67 -0
  79. data/examples/action-cable/public/500.html +66 -0
  80. data/examples/action-cable/public/apple-touch-icon-precomposed.png +0 -0
  81. data/examples/action-cable/public/apple-touch-icon.png +0 -0
  82. data/examples/action-cable/public/favicon.ico +0 -0
  83. data/examples/action-cable/public/robots.txt +5 -0
  84. data/examples/action-cable/rails_cache_dir2/C91/480/synchromesh_active_connections +0 -0
  85. data/examples/action-cable/tmp/.keep +0 -0
  86. data/examples/action-cable/vendor/assets/javascripts/.keep +0 -0
  87. data/examples/action-cable/vendor/assets/stylesheets/.keep +0 -0
  88. data/examples/simple-poller/.gitignore +21 -0
  89. data/examples/simple-poller/Gemfile +64 -0
  90. data/examples/simple-poller/Gemfile.lock +272 -0
  91. data/examples/simple-poller/README.md +24 -0
  92. data/examples/simple-poller/Rakefile +6 -0
  93. data/examples/simple-poller/app/assets/config/manifest.js +3 -0
  94. data/examples/simple-poller/app/assets/images/.keep +0 -0
  95. data/examples/simple-poller/app/assets/javascripts/application.js +20 -0
  96. data/examples/simple-poller/app/assets/javascripts/channels/.keep +0 -0
  97. data/examples/simple-poller/app/assets/stylesheets/application.css +15 -0
  98. data/examples/simple-poller/app/channels/application_cable/channel.rb +4 -0
  99. data/examples/simple-poller/app/channels/application_cable/connection.rb +4 -0
  100. data/examples/simple-poller/app/controllers/application_controller.rb +3 -0
  101. data/examples/simple-poller/app/controllers/concerns/.keep +0 -0
  102. data/examples/simple-poller/app/controllers/test_controller.rb +6 -0
  103. data/examples/simple-poller/app/helpers/application_helper.rb +2 -0
  104. data/examples/simple-poller/app/jobs/application_job.rb +2 -0
  105. data/examples/simple-poller/app/mailers/application_mailer.rb +4 -0
  106. data/examples/simple-poller/app/models/concerns/.keep +0 -0
  107. data/examples/simple-poller/app/models/models.rb +2 -0
  108. data/examples/simple-poller/app/models/public/.keep +0 -0
  109. data/examples/simple-poller/app/models/public/application_record.rb +3 -0
  110. data/examples/simple-poller/app/models/public/word.rb +2 -0
  111. data/examples/simple-poller/app/policies/application_policy.rb +5 -0
  112. data/examples/simple-poller/app/views/components.rb +18 -0
  113. data/examples/simple-poller/app/views/components/.keep +0 -0
  114. data/examples/simple-poller/app/views/components/app.rb +40 -0
  115. data/examples/simple-poller/app/views/layouts/application.html.erb +14 -0
  116. data/examples/simple-poller/app/views/layouts/mailer.html.erb +13 -0
  117. data/examples/simple-poller/app/views/layouts/mailer.text.erb +1 -0
  118. data/examples/simple-poller/bin/bundle +3 -0
  119. data/examples/simple-poller/bin/rails +9 -0
  120. data/examples/simple-poller/bin/rake +9 -0
  121. data/examples/simple-poller/bin/setup +34 -0
  122. data/examples/simple-poller/bin/spring +16 -0
  123. data/examples/simple-poller/bin/update +29 -0
  124. data/examples/simple-poller/config.ru +5 -0
  125. data/examples/simple-poller/config/application.rb +20 -0
  126. data/examples/simple-poller/config/boot.rb +3 -0
  127. data/examples/simple-poller/config/cable.yml +9 -0
  128. data/examples/simple-poller/config/database.yml +25 -0
  129. data/examples/simple-poller/config/environment.rb +5 -0
  130. data/examples/simple-poller/config/environments/development.rb +44 -0
  131. data/examples/simple-poller/config/environments/production.rb +86 -0
  132. data/examples/simple-poller/config/environments/test.rb +42 -0
  133. data/examples/simple-poller/config/initializers/application_controller_renderer.rb +6 -0
  134. data/examples/simple-poller/config/initializers/assets.rb +11 -0
  135. data/examples/simple-poller/config/initializers/backtrace_silencers.rb +7 -0
  136. data/examples/simple-poller/config/initializers/cookies_serializer.rb +5 -0
  137. data/examples/simple-poller/config/initializers/filter_parameter_logging.rb +4 -0
  138. data/examples/simple-poller/config/initializers/inflections.rb +16 -0
  139. data/examples/simple-poller/config/initializers/mime_types.rb +4 -0
  140. data/examples/simple-poller/config/initializers/new_framework_defaults.rb +24 -0
  141. data/examples/simple-poller/config/initializers/session_store.rb +3 -0
  142. data/examples/simple-poller/config/initializers/synchromesh.rb +15 -0
  143. data/examples/simple-poller/config/initializers/wrap_parameters.rb +14 -0
  144. data/examples/simple-poller/config/locales/en.yml +23 -0
  145. data/examples/simple-poller/config/puma.rb +47 -0
  146. data/examples/simple-poller/config/routes.rb +5 -0
  147. data/examples/simple-poller/config/secrets.yml +22 -0
  148. data/examples/simple-poller/config/spring.rb +6 -0
  149. data/examples/simple-poller/db/migrate/20161013220135_create_words.rb +9 -0
  150. data/examples/simple-poller/db/schema.rb +21 -0
  151. data/examples/simple-poller/db/seeds.rb +7 -0
  152. data/examples/simple-poller/lib/assets/.keep +0 -0
  153. data/examples/simple-poller/lib/tasks/.keep +0 -0
  154. data/examples/simple-poller/log/.keep +0 -0
  155. data/examples/simple-poller/public/404.html +67 -0
  156. data/examples/simple-poller/public/422.html +67 -0
  157. data/examples/simple-poller/public/500.html +66 -0
  158. data/examples/simple-poller/public/apple-touch-icon-precomposed.png +0 -0
  159. data/examples/simple-poller/public/apple-touch-icon.png +0 -0
  160. data/examples/simple-poller/public/favicon.ico +0 -0
  161. data/examples/simple-poller/public/robots.txt +5 -0
  162. data/examples/simple-poller/test/controllers/.keep +0 -0
  163. data/examples/simple-poller/test/fixtures/.keep +0 -0
  164. data/examples/simple-poller/test/fixtures/files/.keep +0 -0
  165. data/examples/simple-poller/test/fixtures/words.yml +7 -0
  166. data/examples/simple-poller/test/helpers/.keep +0 -0
  167. data/examples/simple-poller/test/integration/.keep +0 -0
  168. data/examples/simple-poller/test/mailers/.keep +0 -0
  169. data/examples/simple-poller/test/models/.keep +0 -0
  170. data/examples/simple-poller/test/models/word_test.rb +7 -0
  171. data/examples/simple-poller/test/test_helper.rb +10 -0
  172. data/examples/simple-poller/tmp/.keep +0 -0
  173. data/examples/simple-poller/vendor/assets/javascripts/.keep +0 -0
  174. data/examples/simple-poller/vendor/assets/stylesheets/.keep +0 -0
  175. data/examples/words/.gitignore +21 -0
  176. data/examples/words/Gemfile +58 -0
  177. data/examples/words/Gemfile.lock +247 -0
  178. data/examples/words/README.md +24 -0
  179. data/examples/words/Rakefile +6 -0
  180. data/examples/words/app/assets/config/manifest.js +3 -0
  181. data/examples/words/app/assets/javascripts/application.js +18 -0
  182. data/examples/words/app/assets/stylesheets/application.css +15 -0
  183. data/examples/words/app/controllers/application_controller.rb +3 -0
  184. data/examples/words/app/controllers/test_controller.rb +6 -0
  185. data/examples/words/app/models/models.rb +2 -0
  186. data/examples/words/app/models/public/application_record.rb +3 -0
  187. data/examples/words/app/models/public/word.rb +10 -0
  188. data/examples/words/app/policies/application_policy.rb +6 -0
  189. data/examples/words/app/views/components.rb +16 -0
  190. data/examples/words/app/views/components/app.rb +31 -0
  191. data/examples/words/app/views/layouts/application.html.erb +14 -0
  192. data/examples/words/app/views/layouts/mailer.html.erb +13 -0
  193. data/examples/words/app/views/layouts/mailer.text.erb +1 -0
  194. data/examples/words/bin/bundle +3 -0
  195. data/examples/words/bin/rails +9 -0
  196. data/examples/words/bin/rake +9 -0
  197. data/examples/words/bin/setup +34 -0
  198. data/examples/words/bin/spring +15 -0
  199. data/examples/words/bin/update +29 -0
  200. data/examples/words/config.ru +5 -0
  201. data/examples/words/config/application.rb +30 -0
  202. data/examples/words/config/boot.rb +3 -0
  203. data/examples/words/config/cable.yml +9 -0
  204. data/examples/words/config/database.yml +25 -0
  205. data/examples/words/config/environment.rb +5 -0
  206. data/examples/words/config/environments/development.rb +45 -0
  207. data/examples/words/config/environments/production.rb +86 -0
  208. data/examples/words/config/environments/test.rb +42 -0
  209. data/examples/words/config/initializers/application_controller_renderer.rb +6 -0
  210. data/examples/words/config/initializers/assets.rb +11 -0
  211. data/examples/words/config/initializers/backtrace_silencers.rb +7 -0
  212. data/examples/words/config/initializers/cookies_serializer.rb +5 -0
  213. data/examples/words/config/initializers/filter_parameter_logging.rb +4 -0
  214. data/examples/words/config/initializers/inflections.rb +16 -0
  215. data/examples/words/config/initializers/mime_types.rb +4 -0
  216. data/examples/words/config/initializers/new_framework_defaults.rb +24 -0
  217. data/examples/words/config/initializers/session_store.rb +3 -0
  218. data/examples/words/config/initializers/synchromesh.rb +5 -0
  219. data/examples/words/config/initializers/wrap_parameters.rb +14 -0
  220. data/examples/words/config/locales/en.yml +23 -0
  221. data/examples/words/config/puma.rb +47 -0
  222. data/examples/words/config/routes.rb +5 -0
  223. data/examples/words/config/secrets.yml +22 -0
  224. data/examples/words/config/spring.rb +6 -0
  225. data/examples/words/db/migrate/20160921223808_create_words.rb +9 -0
  226. data/examples/words/db/schema.rb +28 -0
  227. data/examples/words/log/.keep +0 -0
  228. data/examples/words/public/404.html +67 -0
  229. data/examples/words/public/422.html +67 -0
  230. data/examples/words/public/500.html +66 -0
  231. data/examples/words/public/apple-touch-icon-precomposed.png +0 -0
  232. data/examples/words/public/apple-touch-icon.png +0 -0
  233. data/examples/words/public/favicon.ico +0 -0
  234. data/examples/words/public/robots.txt +5 -0
  235. data/examples/words/tmp/.keep +0 -0
  236. data/examples/words/vendor/assets/javascripts/.keep +0 -0
  237. data/examples/words/vendor/assets/stylesheets/.keep +0 -0
  238. data/hyper-mesh.gemspec +82 -0
  239. data/lib/active_record_base.rb +152 -0
  240. data/lib/enumerable/pluck.rb +6 -0
  241. data/lib/hyper-mesh.rb +62 -0
  242. data/lib/hypermesh/version.rb +3 -0
  243. data/lib/opal/equality_patches.rb +15 -0
  244. data/lib/opal/parse_patch.rb +14 -0
  245. data/lib/opal/set_patches.rb +8 -0
  246. data/lib/reactive_record/active_record/aggregations.rb +69 -0
  247. data/lib/reactive_record/active_record/associations.rb +111 -0
  248. data/lib/reactive_record/active_record/base.rb +9 -0
  249. data/lib/reactive_record/active_record/class_methods.rb +177 -0
  250. data/lib/reactive_record/active_record/error.rb +26 -0
  251. data/lib/reactive_record/active_record/instance_methods.rb +129 -0
  252. data/lib/reactive_record/active_record/public_columns_hash.rb +19 -0
  253. data/lib/reactive_record/active_record/reactive_record/base.rb +520 -0
  254. data/lib/reactive_record/active_record/reactive_record/collection.rb +517 -0
  255. data/lib/reactive_record/active_record/reactive_record/column_types.rb +67 -0
  256. data/lib/reactive_record/active_record/reactive_record/dummy_value.rb +218 -0
  257. data/lib/reactive_record/active_record/reactive_record/isomorphic_base.rb +532 -0
  258. data/lib/reactive_record/active_record/reactive_record/reactive_set_relationship_helpers.rb +189 -0
  259. data/lib/reactive_record/active_record/reactive_record/scoped_collection.rb +62 -0
  260. data/lib/reactive_record/active_record/reactive_record/unscoped_collection.rb +16 -0
  261. data/lib/reactive_record/active_record/reactive_record/while_loading.rb +299 -0
  262. data/lib/reactive_record/engine.rb +13 -0
  263. data/lib/reactive_record/interval.rb +190 -0
  264. data/lib/reactive_record/permissions.rb +102 -0
  265. data/lib/reactive_record/pry.rb +13 -0
  266. data/lib/reactive_record/reactive_scope.rb +18 -0
  267. data/lib/reactive_record/scope_description.rb +108 -0
  268. data/lib/reactive_record/serializers.rb +7 -0
  269. data/lib/reactive_record/server_data_cache.rb +347 -0
  270. data/lib/reactive_record/version.rb +3 -0
  271. data/lib/sources/hyper-mesh/pusher.js +98 -0
  272. data/lib/synchromesh/action_cable.rb +39 -0
  273. data/lib/synchromesh/client_drivers.rb +357 -0
  274. data/lib/synchromesh/configuration.rb +40 -0
  275. data/lib/synchromesh/connection.rb +144 -0
  276. data/lib/synchromesh/policy.rb +504 -0
  277. data/lib/synchromesh/reactive_record/permission_patches.rb +43 -0
  278. data/lib/synchromesh/synchromesh.rb +155 -0
  279. data/lib/synchromesh/synchromesh_controller.rb +154 -0
  280. data/logo.jpg +0 -0
  281. data/path_release_steps.md +0 -0
  282. data/reactive_record_test_app/Gemfile +15 -0
  283. data/reactive_record_test_app/Gemfile.lock +209 -0
  284. data/reactive_record_test_app/README.rdoc +261 -0
  285. data/reactive_record_test_app/Rakefile +7 -0
  286. data/reactive_record_test_app/app/assets/javascripts/application.rb +5 -0
  287. data/reactive_record_test_app/app/assets/javascripts/components/another_component.rb +24 -0
  288. data/reactive_record_test_app/app/assets/javascripts/components/empty_component.rb +6 -0
  289. data/reactive_record_test_app/app/assets/javascripts/components/todo_item_component.js.rb +16 -0
  290. data/reactive_record_test_app/app/assets/javascripts/components/todos_component.js.rb +42 -0
  291. data/reactive_record_test_app/app/assets/javascripts/components/todos_main_component.rb +49 -0
  292. data/reactive_record_test_app/app/assets/javascripts/react_js_test_only.js +21618 -0
  293. data/reactive_record_test_app/app/assets/javascripts/reactive_record_config.js +2 -0
  294. data/reactive_record_test_app/app/assets/javascripts/spec/reactive_record_xspec.js.rb +42 -0
  295. data/reactive_record_test_app/app/assets/stylesheets/application.css +13 -0
  296. data/reactive_record_test_app/app/controllers/application_controller.rb +8 -0
  297. data/reactive_record_test_app/app/controllers/home_controller.rb +7 -0
  298. data/reactive_record_test_app/app/controllers/test_controller.rb +7 -0
  299. data/reactive_record_test_app/app/helpers/application_helper.rb +2 -0
  300. data/reactive_record_test_app/app/mailers/.gitkeep +0 -0
  301. data/reactive_record_test_app/app/models/.gitkeep +0 -0
  302. data/reactive_record_test_app/app/policies/application_policy.rb +5 -0
  303. data/reactive_record_test_app/app/views/components.rb +4 -0
  304. data/reactive_record_test_app/app/views/components/test.rb +18 -0
  305. data/reactive_record_test_app/app/views/home/index.html.erb +1 -0
  306. data/reactive_record_test_app/app/views/layouts/application.html.erb +17 -0
  307. data/reactive_record_test_app/app/views/models.rb +1 -0
  308. data/reactive_record_test_app/app/views/models/address.rb +13 -0
  309. data/reactive_record_test_app/app/views/models/comment.rb +19 -0
  310. data/reactive_record_test_app/app/views/models/todo_item.rb +36 -0
  311. data/reactive_record_test_app/app/views/models/user.rb +78 -0
  312. data/reactive_record_test_app/config.ru +33 -0
  313. data/reactive_record_test_app/config/application.rb +73 -0
  314. data/reactive_record_test_app/config/boot.rb +10 -0
  315. data/reactive_record_test_app/config/database.yml +25 -0
  316. data/reactive_record_test_app/config/environment.rb +5 -0
  317. data/reactive_record_test_app/config/environments/development.rb +43 -0
  318. data/reactive_record_test_app/config/environments/production.rb +70 -0
  319. data/reactive_record_test_app/config/environments/test.rb +41 -0
  320. data/reactive_record_test_app/config/initializers/backtrace_silencers.rb +7 -0
  321. data/reactive_record_test_app/config/initializers/inflections.rb +15 -0
  322. data/reactive_record_test_app/config/initializers/mime_types.rb +5 -0
  323. data/reactive_record_test_app/config/initializers/secret_token.rb +7 -0
  324. data/reactive_record_test_app/config/initializers/session_store.rb +8 -0
  325. data/reactive_record_test_app/config/initializers/wrap_parameters.rb +14 -0
  326. data/reactive_record_test_app/config/locales/en.yml +5 -0
  327. data/reactive_record_test_app/config/routes.rb +7 -0
  328. data/reactive_record_test_app/db/migrate/20150617002932_create_todo_items.rb +11 -0
  329. data/reactive_record_test_app/db/migrate/20150617134028_create_users.rb +14 -0
  330. data/reactive_record_test_app/db/migrate/20150729195556_add_address_to_user.rb +20 -0
  331. data/reactive_record_test_app/db/migrate/20150826142045_create_comments.rb +10 -0
  332. data/reactive_record_test_app/db/migrate/20150828172008_add_single_comment_to_todo_item.rb +5 -0
  333. data/reactive_record_test_app/db/migrate/20150908184118_add_address_id_to_user.rb +5 -0
  334. data/reactive_record_test_app/db/migrate/20150917220236_add_second_address_to_user.rb +10 -0
  335. data/reactive_record_test_app/db/migrate/20151009000111_add_test_data_attributes_to_user.rb +6 -0
  336. data/reactive_record_test_app/db/migrate/20160129182544_add_test_enum_to_user.rb +5 -0
  337. data/reactive_record_test_app/db/schema.rb +63 -0
  338. data/reactive_record_test_app/db/seeds.rb +60 -0
  339. data/reactive_record_test_app/public/404.html +26 -0
  340. data/reactive_record_test_app/public/422.html +26 -0
  341. data/reactive_record_test_app/public/500.html +25 -0
  342. data/reactive_record_test_app/public/favicon.ico +0 -0
  343. data/reactive_record_test_app/script/rails +6 -0
  344. data/reactive_record_test_app/spec-opal/active-record/aggregations_spec.rb +41 -0
  345. data/reactive_record_test_app/spec-opal/active-record/associations_spec.rb +75 -0
  346. data/reactive_record_test_app/spec-opal/active-record/base_spec.rb +126 -0
  347. data/reactive_record_test_app/spec-opal/active-record/dummy_value_spec.rb +27 -0
  348. data/reactive_record_test_app/spec-opal/active-record/edge_cases_spec.rb +116 -0
  349. data/reactive_record_test_app/spec-opal/active-record/enum_spec.rb +43 -0
  350. data/reactive_record_test_app/spec-opal/active-record/instance_methods_spec.rb +53 -0
  351. data/reactive_record_test_app/spec-opal/active-record/non_ar_aggregations_spec.rb +74 -0
  352. data/reactive_record_test_app/spec-opal/active-record/permissions_spec.rb +170 -0
  353. data/reactive_record_test_app/spec-opal/active-record/prerendering_spec.rb +49 -0
  354. data/reactive_record_test_app/spec-opal/active-record/reactive_record_load_spec.rb +23 -0
  355. data/reactive_record_test_app/spec-opal/active-record/rendering_spec.rb +221 -0
  356. data/reactive_record_test_app/spec-opal/active-record/save_spec.rb +125 -0
  357. data/reactive_record_test_app/spec-opal/active-record/scope_spec.rb +85 -0
  358. data/reactive_record_test_app/spec-opal/active-record/update_aggregations_spec.rb +76 -0
  359. data/reactive_record_test_app/spec-opal/active-record/update_attributes_spec.rb +186 -0
  360. data/reactive_record_test_app/spec-opal/active-record/virtual_methods_spec.rb +71 -0
  361. data/reactive_record_test_app/spec-opal/index.html.erb +11 -0
  362. data/reactive_record_test_app/spec-opal/spec_helper.js.rb +268 -0
  363. data/reactive_record_test_app/spec-opal/vendor/es5-shim.min.js +6 -0
  364. data/reactive_record_test_app/spec_dont_run/README.md +26 -0
  365. data/reactive_record_test_app/spec_dont_run/moved_to_main_spec_dir/zzzmany_to_many_spec_moved_to_main_suite.rb +30 -0
  366. data/reactive_record_test_app/spec_dont_run/moved_to_main_spec_dir/zzzrevert_record_spec_moved.rb +78 -0
  367. data/reactive_record_test_app/spec_dont_run/moved_to_main_spec_dir/zzzupdate_associations_spec_moved.rb +142 -0
  368. data/reactive_record_test_app/spec_dont_run/moved_to_main_spec_dir/zzzupdate_scopes_movedspec.rb +48 -0
  369. data/remote.md +115 -0
  370. data/spec/bin/firebug-2.0.13-fx.xpi +0 -0
  371. data/spec/component_helpers_xspec.rb +49 -0
  372. data/spec/factories/child_model.rb +5 -0
  373. data/spec/factories/comment.rb +5 -0
  374. data/spec/factories/test_models.rb +5 -0
  375. data/spec/factories/todo.rb +5 -0
  376. data/spec/factories/user.rb +5 -0
  377. data/spec/reactive_record/edge_cases_spec.rb +31 -0
  378. data/spec/reactive_record/factory.rb +62 -0
  379. data/spec/reactive_record/many_to_many_spec.rb +50 -0
  380. data/spec/reactive_record/play.rb +64 -0
  381. data/spec/reactive_record/pry_rescue_xspec.rb +48 -0
  382. data/spec/reactive_record/revert_spec.rb +112 -0
  383. data/spec/reactive_record/update_associations_spec.rb +189 -0
  384. data/spec/reactive_record/update_scopes_spec.rb +53 -0
  385. data/spec/spec_helper.rb +366 -0
  386. data/spec/support/component_helpers.rb +351 -0
  387. data/spec/synchromesh/column_types/column_type_spec.rb +302 -0
  388. data/spec/synchromesh/connection_spec.rb +144 -0
  389. data/spec/synchromesh/crud_access_regulation/broadcast_controls_access_spec.rb +105 -0
  390. data/spec/synchromesh/crud_access_regulation/model_policies_spec.rb +131 -0
  391. data/spec/synchromesh/examples/dictionary.rb +239 -0
  392. data/spec/synchromesh/examples/dictionary_with_client_scopes.rb +196 -0
  393. data/spec/synchromesh/examples/random_examples.rb +100 -0
  394. data/spec/synchromesh/examples/scoped_todos_spec.rb +167 -0
  395. data/spec/synchromesh/integration/authorization_spec.rb +111 -0
  396. data/spec/synchromesh/integration/default_scope_spec.rb +121 -0
  397. data/spec/synchromesh/integration/has_many_through_spec.rb +173 -0
  398. data/spec/synchromesh/integration/relationships_spec.rb +263 -0
  399. data/spec/synchromesh/integration/scope_spec.rb +553 -0
  400. data/spec/synchromesh/integration/synchromesh_spec.rb +80 -0
  401. data/spec/synchromesh/integration/test_components.rb +18 -0
  402. data/spec/synchromesh/integration/transports_spec.rb +308 -0
  403. data/spec/synchromesh/policies/auto_connect_spec.rb +60 -0
  404. data/spec/synchromesh/policies/auto_loader_spec.rb +34 -0
  405. data/spec/synchromesh/policies/policy_methods_spec.rb +85 -0
  406. data/spec/synchromesh/policies/regulate_all_broadcasts_spec.rb +315 -0
  407. data/spec/synchromesh/policies/regulate_broadcast_spec.rb +370 -0
  408. data/spec/synchromesh/policies/regulate_class_connection_spec.rb +50 -0
  409. data/spec/synchromesh/policies/regulate_instance_connection_spec.rb +66 -0
  410. data/spec/test_app/Gemfile +61 -0
  411. data/spec/test_app/Gemfile.lock +253 -0
  412. data/spec/test_app/Rakefile +6 -0
  413. data/spec/test_app/app/assets/javascripts/application.js +6 -0
  414. data/spec/test_app/app/assets/stylesheets/application.css +15 -0
  415. data/spec/test_app/app/controllers/application_controller.rb +13 -0
  416. data/spec/test_app/app/controllers/test_controller.rb +5 -0
  417. data/spec/test_app/app/models/_react_public_models.rb +2 -0
  418. data/spec/test_app/app/models/public/address.rb +13 -0
  419. data/spec/test_app/app/models/public/child_model.rb +3 -0
  420. data/spec/test_app/app/models/public/comment.rb +25 -0
  421. data/spec/test_app/app/models/public/test_model.rb +5 -0
  422. data/spec/test_app/app/models/public/todo.rb +6 -0
  423. data/spec/test_app/app/models/public/todo_item.rb +36 -0
  424. data/spec/test_app/app/models/public/user.rb +88 -0
  425. data/spec/test_app/app/policies/auto_loader_test_classa_policy.rb +3 -0
  426. data/spec/test_app/app/policies/auto_loader_test_classb_policy.rb +3 -0
  427. data/spec/test_app/app/policies/auto_loader_test_classc_policy.rb +3 -0
  428. data/spec/test_app/app/policies/auto_loader_test_classd_policy.rb +3 -0
  429. data/spec/test_app/app/views/components.rb +14 -0
  430. data/spec/test_app/app/views/components/show.rb +5 -0
  431. data/spec/test_app/app/views/layouts/application.html.erb +14 -0
  432. data/spec/test_app/bin/bundle +3 -0
  433. data/spec/test_app/bin/rails +4 -0
  434. data/spec/test_app/bin/rake +4 -0
  435. data/spec/test_app/bin/setup +29 -0
  436. data/spec/test_app/config.ru +4 -0
  437. data/spec/test_app/config/application.rb +42 -0
  438. data/spec/test_app/config/boot.rb +6 -0
  439. data/spec/test_app/config/cable.yml +10 -0
  440. data/spec/test_app/config/database.yml +47 -0
  441. data/spec/test_app/config/environment.rb +5 -0
  442. data/spec/test_app/config/environments/development.rb +41 -0
  443. data/spec/test_app/config/environments/production.rb +79 -0
  444. data/spec/test_app/config/environments/test.rb +42 -0
  445. data/spec/test_app/config/initializers/assets.rb +11 -0
  446. data/spec/test_app/config/initializers/backtrace_silencers.rb +7 -0
  447. data/spec/test_app/config/initializers/cookies_serializer.rb +3 -0
  448. data/spec/test_app/config/initializers/filter_parameter_logging.rb +4 -0
  449. data/spec/test_app/config/initializers/inflections.rb +16 -0
  450. data/spec/test_app/config/initializers/mime_types.rb +4 -0
  451. data/spec/test_app/config/initializers/session_store.rb +3 -0
  452. data/spec/test_app/config/initializers/synchromesh.rb +11 -0
  453. data/spec/test_app/config/initializers/wrap_parameters.rb +14 -0
  454. data/spec/test_app/config/locales/en.yml +23 -0
  455. data/spec/test_app/config/routes.rb +61 -0
  456. data/spec/test_app/config/secrets.yml +22 -0
  457. data/spec/test_app/db/development.sqlite3 +0 -0
  458. data/spec/test_app/db/migrate/20160731182106_create_test_models.rb +75 -0
  459. data/spec/test_app/db/schema.rb +88 -0
  460. data/spec/test_app/db/seeds.rb +7 -0
  461. data/spec/test_app/lib/assets/.keep +0 -0
  462. data/spec/test_app/log/.keep +0 -0
  463. data/spec/test_app/public/404.html +67 -0
  464. data/spec/test_app/public/422.html +67 -0
  465. data/spec/test_app/public/500.html +66 -0
  466. data/spec/test_app/public/favicon.ico +0 -0
  467. data/spec/vendor/es5-shim.min.js +6 -0
  468. data/terminal.md +66 -0
  469. metadata +1175 -0
@@ -0,0 +1,142 @@
1
+ require 'spec_helper'
2
+
3
+ describe "updating associations" do
4
+
5
+ before(:all) do
6
+ React::IsomorphicHelpers.load_context
7
+ User.new({first_name: "Jon", last_name: "Weaver"})
8
+ end
9
+
10
+ it "a new model will have empty has_many assocation" do
11
+ jon = User.find_by_first_name("Jon")
12
+ expect(jon.todo_items).to be_empty
13
+ end
14
+
15
+ it "an item can be added to a has_many association" do
16
+ jon = User.find_by_first_name("Jon")
17
+ result = (jon.todo_items << (item = TodoItem.new({title: "Jon's first todo!"})))
18
+ expect(result).to be(jon.todo_items)
19
+ expect(jon.todo_items.count).to be(1)
20
+ end
21
+
22
+ async "it will persist the new has_many association" do
23
+ User.find_by_first_name("Jon").save do
24
+ React::IsomorphicHelpers.load_context
25
+ ReactiveRecord.load do
26
+ User.find_by_first_name("Jon").todo_items.count
27
+ end.then do | count |
28
+ async { expect(count).to be(1) }
29
+ end
30
+ end
31
+ end
32
+
33
+ it "and will reconstruct the association and values on reloading" do
34
+ ReactiveRecord.load do
35
+ User.find_by_first_name("Jon").todo_items.collect { | todo | todo.title }
36
+ end.then do | titles |
37
+ expect(titles).to eq(["Jon's first todo!"])
38
+ end
39
+ end # BROKEN BROKEN
40
+
41
+ it "the inverse belongs_to association will be set" do
42
+ todo = TodoItem.find_by_title("Jon's first todo!")
43
+ expect(todo.user.first_name).to eq("Jon")
44
+ end
45
+
46
+ it "a model can be moved to a new owner, and will be removed from the old owner" do
47
+ TodoItem.find_by_title("Jon's first todo!").user = User.new({first_name: "Jan", last_name: "VanDuyn"})
48
+ expect(User.find_by_first_name("Jon").todo_items).to be_empty
49
+ end
50
+
51
+ it "and will belong to the new owner" do
52
+ expect(User.find_by_first_name("Jan").todo_items.all == [TodoItem.find_by_title("Jon's first todo!")]).to be_truthy
53
+ end
54
+
55
+ async "and can be saved and it will remember its new owner" do
56
+ TodoItem.find_by_title("Jon's first todo!").save do
57
+ React::IsomorphicHelpers.load_context
58
+ ReactiveRecord.load do
59
+ TodoItem.find_by_title("Jon's first todo!").user.first_name
60
+ end.then do | first_name |
61
+ async { expect(first_name).to be("Jan") }
62
+ end
63
+ end
64
+ end # MAYBE BROKEN PREVIOUS BREAK CAUSING????
65
+
66
+ it "and after saving will have been removed from original owners association" do
67
+ ReactiveRecord.load do
68
+ User.find_by_first_name("Jon").todo_items.all
69
+ end.then do | todos |
70
+ expect(todos).to be_empty
71
+ end
72
+ end
73
+
74
+ it "a belongs to association can be set to nil and the model saved" do
75
+ todo = TodoItem.find_by_title("Jon's first todo!")
76
+ todo.user = nil
77
+ todo.save.then do | response |
78
+ expect(response[:success]).to be_truthy
79
+ end
80
+ end
81
+
82
+ it "and will not belong to the previous owner anymore" do
83
+ React::IsomorphicHelpers.load_context
84
+ ReactiveRecord.load do
85
+ TodoItem.find_by_title("Jon's first todo!").user # load the todo in prep for the next test
86
+ User.find_by_first_name("Jan").todo_items.all.count
87
+ end.then do |count|
88
+ expect(count).to be(0)
89
+ end
90
+ end
91
+
92
+ it "but can be reassigned to the previous owner" do
93
+ todo = TodoItem.find_by_title("Jon's first todo!")
94
+ todo.user = User.find_by_first_name("Jan")
95
+ todo.save.then do | response |
96
+ expect(response[:success]).to be_truthy
97
+ end
98
+ end
99
+
100
+ it "and a model in a belongs_to relationship can be deleted" do
101
+ User.find_by_first_name("Jan").todo_items.first.destroy.then do
102
+ expect(User.find_by_first_name("Jan").todo_items).to be_empty
103
+ end
104
+ end
105
+
106
+ it "and it won't exist" do
107
+ React::IsomorphicHelpers.load_context
108
+ ReactiveRecord.load do
109
+ TodoItem.find_by_title("Jon's first todo!").id
110
+ end.then do | id |
111
+ expect(id).to be_nil
112
+ end
113
+ end
114
+
115
+ it "an item in a belongs_to relationship can be created without belonging to anybody" do
116
+ nobodys_business = TodoItem.new({title: "round to it"})
117
+ nobodys_business.save.then do |saved|
118
+ expect(saved).to be_truthy
119
+ end
120
+ end
121
+
122
+ it "and can be reloaded" do
123
+ React::IsomorphicHelpers.load_context
124
+ ReactiveRecord.load do
125
+ TodoItem.find_by_title("round to it").id
126
+ end.then do |id|
127
+ expect(id).not_to be_nil
128
+ end
129
+ end
130
+
131
+ it "and can be deleted" do
132
+ TodoItem.find_by_title("round to it").destroy.then do
133
+ expect(TodoItem.find_by_title("round to it")).to be_destroyed
134
+ end
135
+ end
136
+
137
+ after(:all) do
138
+ Promise.when(User.find_by_first_name("Jan").destroy, User.find_by_first_name("Jon").destroy)
139
+ end
140
+
141
+
142
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe "updating scopes" do
4
+
5
+ # this spec needs some massive cleanup... the rendering tests continue to run... that needs to be fixed
6
+
7
+ # the tests depend on each other.
8
+
9
+ # there are no test for nested scopes like User.todos.active for example which will certainly fail
10
+
11
+ rendering("saving a new record will update .all and cause a rerender") do
12
+ unless @starting_count
13
+ TodoItem.all.last.title
14
+ unless TodoItem.all.count == 1
15
+ @starting_count = TodoItem.all.count
16
+
17
+ after(0.1) do
18
+ TodoItem.new(title: "play it again sam").save
19
+ end
20
+ end
21
+ end
22
+ (TodoItem.all.count - (@starting_count || 100)).to_s
23
+ end.should_generate do
24
+ html == "1"
25
+ end
26
+
27
+ rendering("destroying records will cause a re-render") do
28
+ unless @starting_count
29
+ TodoItem.all.last.title
30
+ unless TodoItem.all.count == 1
31
+ @starting_count = TodoItem.all.count
32
+ after(0.1) do
33
+ TodoItem.all.last.destroy do
34
+ TodoItem.all.last.destroy do
35
+ TodoItem.all.last.destroy do
36
+ TodoItem.all.last.destroy
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ (TodoItem.all.count - (@starting_count || 100)).to_s
44
+ end.should_generate do
45
+ html == "-3"
46
+ end
47
+
48
+ end
data/remote.md ADDED
@@ -0,0 +1,115 @@
1
+ ```ruby
2
+ class Model < ActiveRecord::Base
3
+
4
+ def <=>(other)
5
+ self.text.downcase <=> other.text.downcase
6
+ end
7
+
8
+ scope :sorted, -> { order('lower(text) ASC')}, client: -> { sort }
9
+
10
+ scope :proper_nouns, -> { where('lower(text) <> text ')}, client: -> (r) { r.text.downcase != r.text }
11
+ end
12
+ ```
13
+
14
+ if the remote proc takes a param it is given each record to check (i.e. its wrapped in a select)
15
+
16
+ if there is no param the proc is executed in context of a collection which it can return a modified version of.
17
+
18
+ How:
19
+
20
+ three kinds of scopes:
21
+
22
+ Base collections (i.e. has_many, all, and unscoped)
23
+
24
+ outer scopes (i.e. directly following a base collection Model.sorted === Model.all.sorted parent.children.proper_nouns )
25
+
26
+ inner scopes (i.e. other scopes that follow outer scopes)
27
+
28
+
29
+ First we need to update the base collections based on the changed models. By definition everything we need to know to update the base scopes is available in the changed record.
30
+
31
+ + has_many collections get updated by the load_from_json method
32
+ + all, and unscoped get updated by a new method on the class: update_base_scopes (maybe not needed? )
33
+
34
+ Then we need to find all the outer scopes in the world.
35
+
36
+ To do this whenever an scope is applied, if it is being applied to a base collection (or to a Model itself which is equivilent to applying it Model.all) then it is added to a list, along with its parent base scope.
37
+
38
+ We can then iterate through this list.
39
+
40
+ During the iteration we do this:
41
+
42
+ ```ruby
43
+ def update_collections(updated_record, base_collection, local_updates)
44
+ if this scope is joined with the updated_record
45
+ if local_updates && updated_record.class = self.class && my_client_proc
46
+ local_updates << self
47
+ else
48
+ update_from_server
49
+ client_procs = nil
50
+ end
51
+ end
52
+ if children_collections
53
+ children_collections.each { |child| child.update_collections(udpated_record, base_collection, client_procs)}
54
+ elsif client_procs
55
+ client_procs.inject(base_collection) do |collection, scope|
56
+ dup collection into scope.all
57
+ either call scope.proc with each record in a select
58
+ or just call the proc in the context of scope
59
+ end
60
+ end
61
+ end
62
+ ```
63
+
64
+ how about initial load?
65
+
66
+
67
+ 1) if there is client_proc then run it on first load...
68
+
69
+ filter_most_out_on_server.filter_a_few_out_on_client <- good
70
+ filter_a_few_out_on_client.filter_most_out_on_server <- blah
71
+
72
+ fix later...
73
+ or
74
+ as each scope is applied... of course we go back through all parent scopes and clear a filter flag (proc?)
75
+
76
+
77
+ then on a load as we add each scope in, we can do the initial filter right then... which is okay because
78
+ we don't have that data yet!!!
79
+
80
+ or don't even bother, just run the filter as things are replaced from the server...
81
+
82
+ its static... can always know if something should be filtered
83
+
84
+
85
+ arghhh...
86
+
87
+ Model.filter1.filter2...
88
+
89
+ its still true that to filter, all scopes in chain must be client filters.
90
+
91
+ but what is the diff between
92
+
93
+ Model.inc_filter1.coll_filter1.inc_filter2.coll_filter2
94
+
95
+ vs.
96
+
97
+ Model.coll_filter
98
+
99
+ right because this implies:
100
+
101
+ Model.all.coll_filter, which means we have to do Model.all.each
102
+
103
+ but Model.all.inc_filter should just pass any new/changed entries to inc_filter, and then update the collection
104
+
105
+ Model.inc_filter1.inc_filter2
106
+
107
+ is okay because we should not have inc_filter1's collection all updated.
108
+
109
+ but really? what if we are doing this:
110
+
111
+ Model.inc_minor_filter.inc_major_filter.count
112
+
113
+ We do not have to fetch all inc_minor_filter's collection ever.
114
+
115
+ We do not have to
Binary file
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'component helpers', js: true do
4
+
5
+ it "can mount" do
6
+
7
+ mount "MyComponent" do
8
+ class MyComponent < React::Component::Base
9
+ class << self
10
+ attr_accessor :foo
11
+ end
12
+ after_mount do
13
+ self.class.foo = 12
14
+ end
15
+ render do
16
+ "hello"
17
+ end
18
+ end
19
+ end
20
+ page.evaluate_ruby("MyComponent.foo").should eq(12)
21
+ page.evaluate_ruby("TestModel").should eq("TestModel")
22
+ end
23
+
24
+ it "can instrument some methods" do
25
+ mount "MyComponent" do
26
+ class MyComponent < React::Component::Base
27
+ def some_method
28
+ "fact(5) = #{SomeClass.new.fact(5)}"
29
+ end
30
+ def render
31
+ some_method
32
+ end
33
+ end
34
+ class SomeClass
35
+ def fact(n)
36
+ n == 1 ? n : fact(n-1) * n
37
+ end
38
+ end
39
+ SomeClass.hypertrace do
40
+ instrument :all
41
+ break_on_exit? :fact do |_r, n|
42
+ puts "self = #{self}"; n == 1
43
+ end
44
+ end
45
+ MyComponent.hypertrace instrument: :all, break_on_exit: [:some_method, :render]
46
+ end
47
+ pause
48
+ end
49
+ end
@@ -0,0 +1,5 @@
1
+ FactoryGirl.define do
2
+
3
+ factory :child_model
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ FactoryGirl.define do
2
+
3
+ factory :comment
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ FactoryGirl.define do
2
+
3
+ factory :test_model
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ FactoryGirl.define do
2
+
3
+ factory :todo
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ FactoryGirl.define do
2
+
3
+ factory :user
4
+
5
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+ require 'synchromesh/integration/test_components'
3
+
4
+ describe "reactive-record edge cases", js: true do
5
+
6
+ before(:each) do
7
+ # spec_helper resets the policy system after each test so we have to setup
8
+ # before each test
9
+ stub_const 'TestApplication', Class.new
10
+ stub_const 'TestApplicationPolicy', Class.new
11
+ TestApplicationPolicy.class_eval do
12
+ regulate_all_broadcasts { |policy| policy.send_all }
13
+ allow_change(to: :all, on: [:create, :update, :destroy]) { true }
14
+ end
15
+ size_window(:small, :portrait)
16
+ end
17
+
18
+ it "trims the association tree" do
19
+ 5.times do |i|
20
+ user = FactoryGirl.create(:user, first_name: i) unless i == 3
21
+ FactoryGirl.create(:todo, title: "User #{i}'s todo", owner: user)
22
+ end
23
+ expect_promise do
24
+ ReactiveRecord.load do
25
+ Todo.all.collect do |todo|
26
+ todo.owner && todo.owner.first_name
27
+ end.compact
28
+ end
29
+ end.to contain_exactly('0', '1', '2', '4')
30
+ end
31
+ end
@@ -0,0 +1,62 @@
1
+ def seed_database
2
+ users = [
3
+ ["Mitch", "VanDuyn", "mitch@catprint.com"],
4
+ ["Todd", "Russell", "todd@catprint.com"],
5
+ ["Adam", "George", "adamg@catprint.com"],
6
+ ["Test1", "Test1", "test1@catprint.com"]
7
+ ]
8
+
9
+ users.each do |first_name, last_name, email|
10
+ User.create({
11
+ first_name: first_name, last_name: last_name, email: email,
12
+ address_street: "4348 Culver Road", address_city: "Rochester", address_state: "NY", address_zip: "14617"
13
+ }
14
+ #without_protection: true
15
+ )
16
+ end
17
+
18
+ todo_items = [
19
+ {
20
+ title: "a todo for mitch",
21
+ description: "mitch has a big fat todo to do!",
22
+ user: User.find_by_email("mitch@catprint.com"),
23
+ comments: [{user: User.find_by_email("adamg@catprint.com"), comment: "get it done mitch"}]
24
+ },
25
+ {
26
+ title: "another todo for mitch",
27
+ description: "mitch has too many todos",
28
+ user: User.find_by_email("mitch@catprint.com")
29
+ },
30
+ {
31
+ title: "do it again Todd",
32
+ description: "Todd please do that great thing you did again",
33
+ user: User.find_by_email("todd@catprint.com")
34
+ },
35
+ {
36
+ title: "no user todo",
37
+ description: "the description"
38
+ },
39
+ {
40
+ title: "test 1 todo 1", description: "test 1 todo 1", user: User.find_by_email("test1@catprint.com"),
41
+ comments: [
42
+ {user: User.find_by_email("mitch@catprint.com"), comment: "test 1 todo 1 comment 1"},
43
+ {user: User.find_by_email("mitch@catprint.com"), comment: "test 1 todo 1 comment 2"}
44
+ ]
45
+ },
46
+ {
47
+ title: "test 1 todo 2", description: "test 1 todo 2", user: User.find_by_email("test1@catprint.com"),
48
+ comments: [
49
+ {user: User.find_by_email("mitch@catprint.com"), comment: "test 1 todo 2 comment 1"},
50
+ {user: User.find_by_email("mitch@catprint.com"), comment: "test 1 todo 2 comment 2"}
51
+ ]
52
+ }
53
+ ]
54
+
55
+ todo_items.each do |attributes|
56
+ comments = attributes.delete(:comments) || []
57
+ todo = TodoItem.create(attributes) #, without_protection: true)
58
+ comments.each do |attributes|
59
+ Comment.create(attributes.merge(todo_item: todo))
60
+ end
61
+ end
62
+ end