spontaneous 0.2.0.beta1 → 0.2.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (335) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +24 -0
  3. data/.locat +42 -0
  4. data/.travis/gemfiles/Gemfile.empty +7 -0
  5. data/.travis.yml +18 -0
  6. data/Gemfile +12 -8
  7. data/LICENSE +1 -1
  8. data/Rakefile +15 -157
  9. data/Readme.markdown +1 -1
  10. data/application/css/core.css.scss +22 -146
  11. data/application/css/definitions.css.scss +7 -3
  12. data/application/css/dialogue.css.scss +26 -1
  13. data/application/css/editing.css.scss +70 -28
  14. data/application/css/font.css.scss +1 -1
  15. data/application/css/popover.css.scss +2 -0
  16. data/application/css/top.css.scss +231 -0
  17. data/application/js/add_alias_dialogue.js +1 -1
  18. data/application/js/add_home_dialogue.js +1 -1
  19. data/application/js/ajax.js +61 -31
  20. data/application/js/box.js +4 -4
  21. data/application/js/conflicted_field_dialogue.js +1 -1
  22. data/application/js/content.js +5 -5
  23. data/application/js/dom.js +5 -0
  24. data/application/js/edit_panel.js +1 -0
  25. data/application/js/editing.js +1 -1
  26. data/application/js/extensions.js +8 -0
  27. data/application/js/field/boolean.js +31 -0
  28. data/application/js/field/file.js +32 -4
  29. data/application/js/field/image.js +24 -9
  30. data/application/js/field/markdown.js +87 -59
  31. data/application/js/field/select.js +1 -1
  32. data/application/js/field/webvideo.js +6 -1
  33. data/application/js/init.js +2 -2
  34. data/application/js/jquery-selection-position.js +130 -0
  35. data/application/js/location.js +4 -25
  36. data/application/js/meta_view/user_admin.js +2 -2
  37. data/application/js/metadata.js +2 -2
  38. data/application/js/page_browser.js +1 -1
  39. data/application/js/panel/root_menu.js +0 -1
  40. data/application/js/popover.js +27 -12
  41. data/application/js/popover_view.js +20 -4
  42. data/application/js/preview.js +31 -16
  43. data/application/js/progress.js +22 -21
  44. data/application/js/publish.js +18 -7
  45. data/application/js/sharded_upload.js +9 -6
  46. data/application/js/spontaneous.js +3 -1
  47. data/application/js/top_bar.js +264 -173
  48. data/application/js/upload.js +12 -5
  49. data/application/js/upload_manager.js +4 -3
  50. data/application/js/user.js +1 -2
  51. data/application/js/views/box_view.js +1 -1
  52. data/application/js/views/page_view.js +16 -5
  53. data/application/js/views/piece_view.js +5 -4
  54. data/application/static/font/fontawesome-webfont-1c66a4738b40ef0f6b1abca0ba9a796d.ttf +0 -0
  55. data/application/views/index.erb +6 -14
  56. data/application/views/login.erb +6 -25
  57. data/application/views/schema_modification_error.html.erb +3 -7
  58. data/db/migrations/20130114120000_create_revision_tables.rb +2 -2
  59. data/db/migrations/20130813111009_increase_path_length.rb +14 -0
  60. data/gem-public_cert.pem +20 -0
  61. data/lib/spontaneous/asset/app_compiler.rb +44 -0
  62. data/lib/spontaneous/asset/environment.rb +225 -0
  63. data/lib/spontaneous/asset.rb +2 -67
  64. data/lib/spontaneous/box.rb +0 -1
  65. data/lib/spontaneous/capistrano/deploy.rb +2 -2
  66. data/lib/spontaneous/capistrano/sync.rb +1 -1
  67. data/lib/spontaneous/cli/init.rb +36 -13
  68. data/lib/spontaneous/cli/server.rb +0 -1
  69. data/lib/spontaneous/cli/site.rb +2 -1
  70. data/lib/spontaneous/cli.rb +3 -1
  71. data/lib/spontaneous/collections/entry_set.rb +4 -12
  72. data/lib/spontaneous/collections/hash_with_fallback.rb +20 -0
  73. data/lib/spontaneous/collections/prototype_set.rb +6 -5
  74. data/lib/spontaneous/crypt.rb +2 -2
  75. data/lib/spontaneous/data_mapper/content_model/associations.rb +115 -63
  76. data/lib/spontaneous/data_mapper.rb +1 -1
  77. data/lib/spontaneous/errors.rb +6 -0
  78. data/lib/spontaneous/extensions/object_space.rb +6 -0
  79. data/lib/spontaneous/facet.rb +1 -0
  80. data/lib/spontaneous/field/base.rb +86 -13
  81. data/lib/spontaneous/field/boolean.rb +65 -0
  82. data/lib/spontaneous/field/file.rb +17 -6
  83. data/lib/spontaneous/field/html.rb +13 -0
  84. data/lib/spontaneous/field/image/size.rb +76 -0
  85. data/lib/spontaneous/field/image.rb +99 -414
  86. data/lib/spontaneous/field/tags.rb +36 -0
  87. data/lib/spontaneous/field/update.rb +1 -1
  88. data/lib/spontaneous/field/webvideo/fallback.rb +41 -0
  89. data/lib/spontaneous/field/webvideo/vimeo.rb +113 -0
  90. data/lib/spontaneous/field/webvideo/vine.rb +94 -0
  91. data/lib/spontaneous/field/webvideo/youtube.rb +133 -0
  92. data/lib/spontaneous/field/webvideo.rb +100 -250
  93. data/lib/spontaneous/field.rb +1 -1
  94. data/lib/spontaneous/generators/site/Gemfile.tt +5 -14
  95. data/lib/spontaneous/generators/site/assets/README.md +20 -0
  96. data/lib/spontaneous/generators/site/assets/css/site.scss +8 -0
  97. data/lib/spontaneous/generators/site/assets/js/site.js +6 -0
  98. data/lib/spontaneous/generators/site/config/deploy.rb.tt +9 -0
  99. data/lib/spontaneous/generators/site/config/user_levels.yml +14 -3
  100. data/lib/spontaneous/generators/site/public/README.md +12 -0
  101. data/lib/spontaneous/generators/site/templates/layouts/standard.html.cut.tt +2 -2
  102. data/lib/spontaneous/generators/site.rb +77 -35
  103. data/lib/spontaneous/layout.rb +6 -7
  104. data/lib/spontaneous/loader.rb +21 -13
  105. data/lib/spontaneous/media/file.rb +22 -9
  106. data/lib/spontaneous/media/image/attributes.rb +33 -0
  107. data/lib/spontaneous/media/image/format/gif.rb +4 -0
  108. data/lib/spontaneous/media/image/format/jpg.rb +17 -0
  109. data/lib/spontaneous/media/image/format/png.rb +4 -0
  110. data/lib/spontaneous/media/image/format/webp.rb +26 -0
  111. data/lib/spontaneous/media/image/format.rb +79 -0
  112. data/lib/spontaneous/media/image/optimizer.rb +69 -0
  113. data/lib/spontaneous/media/image/processor.rb +17 -0
  114. data/lib/spontaneous/media/image/renderable.rb +52 -0
  115. data/lib/spontaneous/media/image/skeptick.rb +70 -0
  116. data/lib/spontaneous/media/image.rb +50 -0
  117. data/lib/spontaneous/media/temp_file.rb +4 -0
  118. data/lib/spontaneous/media.rb +1 -0
  119. data/lib/spontaneous/model/core/aliases.rb +14 -8
  120. data/lib/spontaneous/model/core/boxes.rb +5 -2
  121. data/lib/spontaneous/model/core/entries.rb +4 -0
  122. data/lib/spontaneous/model/core/entry.rb +1 -0
  123. data/lib/spontaneous/model/core/fields.rb +5 -2
  124. data/lib/spontaneous/model/core/locks.rb +16 -0
  125. data/lib/spontaneous/model/core/media.rb +1 -15
  126. data/lib/spontaneous/model/core.rb +31 -1
  127. data/lib/spontaneous/model/page/controllers.rb +2 -2
  128. data/lib/spontaneous/model/page/formats.rb +1 -4
  129. data/lib/spontaneous/model/page/layouts.rb +6 -2
  130. data/lib/spontaneous/model/page/locks.rb +8 -2
  131. data/lib/spontaneous/model/page/page_tree.rb +2 -2
  132. data/lib/spontaneous/model/page/paths.rb +74 -9
  133. data/lib/spontaneous/model/page.rb +11 -3
  134. data/lib/spontaneous/model.rb +6 -6
  135. data/lib/spontaneous/output/context/render_cache.rb +23 -0
  136. data/lib/spontaneous/output/context.rb +56 -30
  137. data/lib/spontaneous/output/helpers/script_helper.rb +9 -53
  138. data/lib/spontaneous/output/helpers/stylesheet_helper.rb +8 -40
  139. data/lib/spontaneous/output/template/renderer.rb +17 -5
  140. data/lib/spontaneous/output.rb +0 -1
  141. data/lib/spontaneous/paths.rb +6 -2
  142. data/lib/spontaneous/permissions/access_key.rb +18 -0
  143. data/lib/spontaneous/permissions/user.rb +1 -1
  144. data/lib/spontaneous/permissions.rb +4 -1
  145. data/lib/spontaneous/plugins/application/state.rb +19 -12
  146. data/lib/spontaneous/prototypes/field_prototype.rb +14 -8
  147. data/lib/spontaneous/published_revision.rb +7 -0
  148. data/lib/spontaneous/publishing/immediate.rb +43 -34
  149. data/lib/spontaneous/publishing/revision.rb +9 -6
  150. data/lib/spontaneous/rack/asset_server.rb +20 -0
  151. data/lib/spontaneous/rack/back/alias.rb +46 -0
  152. data/lib/spontaneous/rack/back/application_assets.rb +28 -0
  153. data/lib/spontaneous/rack/back/base.rb +34 -0
  154. data/lib/spontaneous/rack/back/changes.rb +19 -0
  155. data/lib/spontaneous/rack/back/content.rb +54 -0
  156. data/lib/spontaneous/rack/back/events.rb +38 -0
  157. data/lib/spontaneous/rack/back/field.rb +37 -0
  158. data/lib/spontaneous/rack/back/file.rb +118 -0
  159. data/lib/spontaneous/rack/back/helpers.rb +71 -0
  160. data/lib/spontaneous/rack/back/index.rb +16 -0
  161. data/lib/spontaneous/rack/back/login.rb +47 -0
  162. data/lib/spontaneous/rack/back/map.rb +24 -0
  163. data/lib/spontaneous/rack/back/page.rb +46 -0
  164. data/lib/spontaneous/rack/back/preview.rb +43 -0
  165. data/lib/spontaneous/rack/back/schema.rb +30 -0
  166. data/lib/spontaneous/rack/back/site.rb +25 -0
  167. data/lib/spontaneous/rack/back/site_assets.rb +13 -0
  168. data/lib/spontaneous/rack/back/unsupported_browser.rb +7 -0
  169. data/lib/spontaneous/rack/{user_admin.rb → back/user_admin.rb} +2 -5
  170. data/lib/spontaneous/rack/back.rb +85 -764
  171. data/lib/spontaneous/rack/cacheable_file.rb +3 -3
  172. data/lib/spontaneous/rack/front.rb +16 -9
  173. data/lib/spontaneous/rack/middleware/authenticate.rb +65 -0
  174. data/lib/spontaneous/rack/middleware/csrf.rb +66 -0
  175. data/lib/spontaneous/rack/middleware/reloader.rb +52 -0
  176. data/lib/spontaneous/rack/middleware/scope.rb +60 -0
  177. data/lib/spontaneous/rack/middleware.rb +6 -0
  178. data/lib/spontaneous/rack/page_controller.rb +18 -5
  179. data/lib/spontaneous/rack/public.rb +17 -11
  180. data/lib/spontaneous/rack.rb +34 -24
  181. data/lib/spontaneous/revision.rb +29 -2
  182. data/lib/spontaneous/schema/uid.rb +4 -3
  183. data/lib/spontaneous/schema/uid_map.rb +5 -24
  184. data/lib/spontaneous/schema.rb +1 -0
  185. data/lib/spontaneous/search/database.rb +8 -0
  186. data/lib/spontaneous/search/field.rb +1 -1
  187. data/lib/spontaneous/search/index.rb +3 -5
  188. data/lib/spontaneous/server.rb +1 -1
  189. data/lib/spontaneous/simultaneous.rb +1 -1
  190. data/lib/spontaneous/site/features.rb +4 -5
  191. data/lib/spontaneous/site/helpers.rb +22 -5
  192. data/lib/spontaneous/site/instance.rb +2 -2
  193. data/lib/spontaneous/site/selectors.rb +22 -3
  194. data/lib/spontaneous/storage/cloud.rb +13 -9
  195. data/lib/spontaneous/storage/local.rb +11 -6
  196. data/lib/spontaneous/style.rb +40 -23
  197. data/lib/spontaneous/utils/database/mysql_dumper.rb +1 -1
  198. data/lib/spontaneous/utils/smush_it.rb +1 -1
  199. data/lib/spontaneous/version.rb +1 -1
  200. data/lib/spontaneous.rb +35 -33
  201. data/spontaneous.gemspec +53 -787
  202. data/test/experimental/test_crypt.rb +56 -56
  203. data/test/experimental/test_features.rb +16 -27
  204. data/test/fixtures/assets/public1/css/data.css.scss +3 -0
  205. data/test/fixtures/assets/public1/css/image1.css.scss +4 -0
  206. data/test/fixtures/assets/public1/css/import.css.scss +1 -0
  207. data/test/fixtures/assets/public1/css/urlhash.css.scss +3 -0
  208. data/test/fixtures/assets/public1/js/a.js +1 -1
  209. data/test/fixtures/assets/public1/js/all.js +4 -0
  210. data/test/fixtures/assets/public1/js/{m.coffee → m.js.coffee} +1 -0
  211. data/test/fixtures/assets/public1/x.js +1 -0
  212. data/test/fixtures/assets/public2/css/all.css +4 -0
  213. data/test/fixtures/assets/public2/css/missing.css.scss +3 -0
  214. data/test/fixtures/assets/public2/i/y.png +0 -0
  215. data/test/fixtures/assets/public2/js/b.js +1 -1
  216. data/test/fixtures/assets/public2/js/c.js +1 -1
  217. data/test/fixtures/images/size.extended.webp +0 -0
  218. data/test/fixtures/images/size.lossless.webp +0 -0
  219. data/test/fixtures/images/size.lossy.webp +0 -0
  220. data/test/fixtures/schema/before.yml +4 -4
  221. data/test/fixtures/schema/schema.yml +1 -1
  222. data/test/fixtures/templates/aliases/aaa.html.cut +0 -0
  223. data/test/fixtures/templates/extended/partial_with_renderer.html.cut +1 -0
  224. data/test/fixtures/templates/extended/with_includes_and_renderer.html.cut +2 -0
  225. data/test/functional/test_application.rb +108 -106
  226. data/test/functional/test_back.rb +924 -930
  227. data/test/functional/test_front.rb +285 -238
  228. data/test/functional/test_user_manager.rb +75 -100
  229. data/test/integration/test_installation.rb +1 -1
  230. data/test/support/matchers.rb +12 -0
  231. data/test/support/minitest.rb +121 -0
  232. data/test/support/rack.rb +45 -0
  233. data/test/support/test_start_finish.rb +103 -0
  234. data/test/test_helper.rb +21 -68
  235. data/test/test_integration_helper.rb +1 -3
  236. data/test/unit/test_alias.rb +432 -408
  237. data/test/unit/test_asset_bundler.rb +58 -58
  238. data/test/unit/test_assets.rb +485 -155
  239. data/test/unit/test_async.rb +16 -37
  240. data/test/unit/test_authentication.rb +425 -457
  241. data/test/unit/test_boxes.rb +191 -191
  242. data/test/unit/test_changesets.rb +244 -254
  243. data/test/unit/test_config.rb +128 -142
  244. data/test/unit/test_content.rb +313 -359
  245. data/test/unit/test_content_inheritance.rb +29 -30
  246. data/test/unit/test_datamapper.rb +1205 -1080
  247. data/test/unit/test_datamapper_content.rb +49 -51
  248. data/test/unit/test_extensions.rb +23 -23
  249. data/test/unit/test_fields.rb +1488 -1180
  250. data/test/unit/test_formats.rb +158 -158
  251. data/test/unit/test_generators.rb +98 -40
  252. data/test/unit/test_helpers.rb +73 -76
  253. data/test/unit/test_image_size.rb +53 -22
  254. data/test/unit/test_images.rb +164 -165
  255. data/test/unit/test_layouts.rb +133 -122
  256. data/test/unit/test_logger.rb +14 -17
  257. data/test/unit/test_media.rb +69 -84
  258. data/test/unit/test_modifications.rb +513 -525
  259. data/test/unit/test_page.rb +462 -361
  260. data/test/unit/test_permissions.rb +379 -364
  261. data/test/unit/test_piece.rb +67 -75
  262. data/test/unit/test_plugins.rb +82 -89
  263. data/test/unit/test_prototype_set.rb +215 -216
  264. data/test/unit/test_prototypes.rb +114 -124
  265. data/test/unit/test_publishing.rb +252 -289
  266. data/test/unit/test_render.rb +167 -115
  267. data/test/unit/test_revisions.rb +436 -444
  268. data/test/unit/test_schema.rb +339 -309
  269. data/test/unit/test_search.rb +577 -574
  270. data/test/unit/test_serialisation.rb +136 -147
  271. data/test/unit/test_site.rb +252 -227
  272. data/test/unit/test_skeptick.rb +130 -0
  273. data/test/unit/test_storage.rb +46 -40
  274. data/test/unit/test_structure.rb +57 -66
  275. data/test/unit/test_styles.rb +104 -104
  276. data/test/unit/test_templates.rb +72 -57
  277. data/test/unit/test_type_hierarchy.rb +15 -16
  278. data/test/unit/test_visibility.rb +239 -257
  279. metadata +455 -326
  280. data/application/js/vendor/JS.Class-2.1.5/CHANGELOG +0 -283
  281. data/application/js/vendor/JS.Class-2.1.5/MIT-LICENSE +0 -30
  282. data/application/js/vendor/JS.Class-2.1.5/README +0 -30
  283. data/application/js/vendor/JS.Class-2.1.5/min/command.js +0 -1
  284. data/application/js/vendor/JS.Class-2.1.5/min/comparable.js +0 -1
  285. data/application/js/vendor/JS.Class-2.1.5/min/constant_scope.js +0 -1
  286. data/application/js/vendor/JS.Class-2.1.5/min/decorator.js +0 -1
  287. data/application/js/vendor/JS.Class-2.1.5/min/enumerable.js +0 -1
  288. data/application/js/vendor/JS.Class-2.1.5/min/forwardable.js +0 -1
  289. data/application/js/vendor/JS.Class-2.1.5/min/hash.js +0 -1
  290. data/application/js/vendor/JS.Class-2.1.5/min/linked_list.js +0 -1
  291. data/application/js/vendor/JS.Class-2.1.5/min/loader.js +0 -1
  292. data/application/js/vendor/JS.Class-2.1.5/min/method_chain.js +0 -1
  293. data/application/js/vendor/JS.Class-2.1.5/min/observable.js +0 -1
  294. data/application/js/vendor/JS.Class-2.1.5/min/package.js +0 -1
  295. data/application/js/vendor/JS.Class-2.1.5/min/proxy.js +0 -1
  296. data/application/js/vendor/JS.Class-2.1.5/min/ruby.js +0 -1
  297. data/application/js/vendor/JS.Class-2.1.5/min/set.js +0 -1
  298. data/application/js/vendor/JS.Class-2.1.5/min/stack_trace.js +0 -1
  299. data/application/js/vendor/JS.Class-2.1.5/min/state.js +0 -1
  300. data/application/js/vendor/JS.Class-2.1.5/min/stdlib.js +0 -16
  301. data/application/js/vendor/jquery-1.6.2.min.js +0 -18
  302. data/application/js/vendor/jquery-ui-1.8.16.custom.min.js +0 -791
  303. data/application/js/vendor/jquery-ui-1.8.9.custom.min.js +0 -415
  304. data/application/static/font/fontawesome-webfont-5c5c21100a346972a82c34c5e96ffcfe.ttf +0 -0
  305. data/application/static/select-arrow-6e7dd3745b00e934b0d7a3250c46558b.png +0 -0
  306. data/bin/limit-upload +0 -5
  307. data/bin/unlimit-upload +0 -3
  308. data/lib/spontaneous/asset/file.rb +0 -25
  309. data/lib/spontaneous/asset/source.rb +0 -28
  310. data/lib/spontaneous/image_size.rb +0 -123
  311. data/lib/spontaneous/output/assets/compression.rb +0 -58
  312. data/lib/spontaneous/output/assets.rb +0 -32
  313. data/lib/spontaneous/rack/around_back.rb +0 -20
  314. data/lib/spontaneous/rack/around_front.rb +0 -27
  315. data/lib/spontaneous/rack/around_preview.rb +0 -22
  316. data/lib/spontaneous/rack/assets.rb +0 -126
  317. data/lib/spontaneous/rack/authentication.rb +0 -20
  318. data/lib/spontaneous/rack/cookie_authentication.rb +0 -38
  319. data/lib/spontaneous/rack/helpers.rb +0 -52
  320. data/lib/spontaneous/rack/http.rb +0 -18
  321. data/lib/spontaneous/rack/media.rb +0 -30
  322. data/lib/spontaneous/rack/query_authentication.rb +0 -35
  323. data/lib/spontaneous/rack/reloader.rb +0 -45
  324. data/lib/spontaneous/rack/user_helpers.rb +0 -28
  325. /data/{README → application/js/field/markdown/text_command.js} +0 -0
  326. /data/application/js/vendor/{JS.Class-2.1.5/min/core.js → js.class-2.1.5.min.js} +0 -0
  327. /data/test/fixtures/assets/public1/css/{a.scss → a.css.scss} +0 -0
  328. /data/{lib/spontaneous/generators/site/public/css/site.scss → test/fixtures/assets/public1/x.css} +0 -0
  329. /data/{lib/spontaneous/generators/site/public/js/.empty_directory → test/fixtures/assets/public1/x.png} +0 -0
  330. /data/test/fixtures/assets/public2/css/{b.scss → b.css.scss} +0 -0
  331. /data/test/fixtures/assets/public2/js/{n.coffee → n.js.coffee} +0 -0
  332. /data/test/fixtures/back/{public → assets}/css/sass_include.scss +0 -0
  333. /data/test/fixtures/back/{public → assets}/css/sass_template.scss +0 -0
  334. /data/test/fixtures/back/{public → assets}/js/coffeescript.coffee +0 -0
  335. /data/{lib/spontaneous/generators/site/public/js/site.js → test/fixtures/templates/aliases/aa_alias.html.cut} +0 -0
@@ -3,14 +3,7 @@
3
3
  require File.expand_path('../../test_helper', __FILE__)
4
4
  require 'sequel'
5
5
 
6
- class DataMapperTest < MiniTest::Spec
7
- def setup
8
- @site = setup_site
9
- end
10
-
11
- def teardown
12
- teardown_site
13
- end
6
+ describe "DataMapper" do
14
7
 
15
8
  class NameMap
16
9
  def initialize(*args)
@@ -25,1306 +18,1438 @@ class DataMapperTest < MiniTest::Spec
25
18
  end
26
19
  end
27
20
 
28
- context "datamapper" do
29
- setup do
30
- @now = Spontaneous::DataMapper.timestamp
31
- @expected_columns = [:id, :type_sid, :label, :object1, :object2]
32
- @database = ::Sequel.mock(autoid: 1)
33
- @table = Spontaneous::DataMapper::ContentTable.new(:content, @database)
34
- @schema = Spontaneous::Schema.new(Dir.pwd, NameMap)
35
- @mapper = Spontaneous::DataMapper.new(@table, @schema)
36
- @database.columns = @expected_columns
37
- Spontaneous::DataMapper.stubs(:timestamp).returns(@now)
38
- MockContent = Spontaneous::DataMapper::Model(:content, @database, @schema) do
39
- serialize_columns :object1, :object2
40
- end
41
- # having timestamps on makes testing the sql very difficult/tedious
42
- MockContent2 = Class.new(MockContent)
43
- @database.sqls # clear sql log -- column introspection makes a query to the db
21
+ before do
22
+ @site = setup_site
23
+ @now = Spontaneous::DataMapper.timestamp
24
+ @expected_columns = [:id, :type_sid, :label, :object1, :object2]
25
+ @database = ::Sequel.mock(autoid: 1)
26
+ @table = Spontaneous::DataMapper::ContentTable.new(:content, @database)
27
+ @schema = Spontaneous::Schema.new(Dir.pwd, NameMap)
28
+ @mapper = Spontaneous::DataMapper.new(@table, @schema)
29
+ @database.columns = @expected_columns
30
+ Spontaneous::DataMapper.stubs(:timestamp).returns(@now)
31
+ MockContent = Spontaneous::DataMapper::Model(:content, @database, @schema) do
32
+ serialize_columns :object1, :object2
44
33
  end
34
+ # having timestamps on makes testing the sql very difficult/tedious
35
+ MockContent2 = Class.new(MockContent)
36
+ @database.sqls # clear sql log -- column introspection makes a query to the db
37
+ end
45
38
 
46
- teardown do
47
- DataMapperTest.send :remove_const, :MockContent rescue nil
48
- DataMapperTest.send :remove_const, :MockContent2 rescue nil
39
+ after do
40
+ Object.send :remove_const, :MockContent rescue nil
41
+ Object.send :remove_const, :MockContent2 rescue nil
42
+ teardown_site
43
+ end
44
+
45
+ it "be creatable from any table" do
46
+ table = Spontaneous::DataMapper::ContentTable.new(:content, @database)
47
+ mapper = Spontaneous::DataMapper.new(table, @schema)
48
+ mapper.must_be_instance_of Spontaneous::DataMapper::ScopingMapper
49
+ end
50
+
51
+ describe "instances" do
52
+ it "insert model data when saving a new model instance" do
53
+ @database.fetch = { id:1, label:"column1", type_sid:"MockContent" }
54
+ instance = MockContent.new(:label => "column1")
55
+ assert instance.new?
56
+ @mapper.create(instance)
57
+ @database.sqls.must_equal [
58
+ "INSERT INTO content (label, type_sid) VALUES ('column1', 'MockContent')",
59
+ "SELECT * FROM content WHERE (id = 1) LIMIT 1"
60
+ ]
61
+ refute instance.new?
62
+ instance.id.must_equal 1
49
63
  end
50
64
 
51
- should "be creatable from any table" do
52
- table = Spontaneous::DataMapper::ContentTable.new(:content, @database)
53
- mapper = Spontaneous::DataMapper.new(table, @schema)
54
- mapper.must_be_instance_of Spontaneous::DataMapper::ScopingMapper
65
+ it "insert models using the DataMapper.create method" do
66
+ @database.fetch = { id:1, label:"column1", type_sid:"MockContent" }
67
+ instance = @mapper.instance MockContent, :label => "column1"
68
+ @database.sqls.must_equal [
69
+ "INSERT INTO content (label, type_sid) VALUES ('column1', 'MockContent')",
70
+ "SELECT * FROM content WHERE (id = 1) LIMIT 1"
71
+ ]
72
+ refute instance.new?
73
+ instance.id.must_equal 1
55
74
  end
56
75
 
57
- context "instances" do
58
- should "insert model data when saving a new model instance" do
59
- @database.fetch = { id:1, label:"column1", type_sid:"DataMapperTest::MockContent" }
60
- instance = MockContent.new(:label => "column1")
61
- instance.new?.should be_true
62
- @mapper.create(instance)
63
- @database.sqls.should == [
64
- "INSERT INTO content (label, type_sid) VALUES ('column1', 'DataMapperTest::MockContent')",
65
- "SELECT * FROM content WHERE (id = 1) LIMIT 1"
66
- ]
67
- instance.new?.should be_false
68
- instance.id.should == 1
69
- end
76
+ it "update an existing model" do
77
+ @database.fetch = { id:1, label:"column1", type_sid:"MockContent" }
78
+ instance = @mapper.instance MockContent, :label => "column1"
79
+ instance.set label: "changed"
80
+ @mapper.save(instance)
81
+ @database.sqls.must_equal [
82
+ "INSERT INTO content (label, type_sid) VALUES ('column1', 'MockContent')",
83
+ "SELECT * FROM content WHERE (id = 1) LIMIT 1",
84
+ "UPDATE content SET label = 'changed' WHERE (id = 1)"
85
+ ]
86
+ end
70
87
 
71
- should "insert models using the DataMapper.create method" do
72
- @database.fetch = { id:1, label:"column1", type_sid:"DataMapperTest::MockContent" }
73
- instance = @mapper.instance MockContent, :label => "column1"
74
- @database.sqls.should == [
75
- "INSERT INTO content (label, type_sid) VALUES ('column1', 'DataMapperTest::MockContent')",
76
- "SELECT * FROM content WHERE (id = 1) LIMIT 1"
77
- ]
78
- instance.new?.should be_false
79
- instance.id.should == 1
80
- end
88
+ it "update model rows directly" do
89
+ @mapper.update([MockContent], label: "changed")
90
+ @database.sqls.must_equal [
91
+ "UPDATE content SET label = 'changed' WHERE (type_sid IN ('MockContent'))"
92
+ ]
93
+ end
81
94
 
82
- should "update an existing model" do
83
- @database.fetch = { id:1, label:"column1", type_sid:"DataMapperTest::MockContent" }
84
- instance = @mapper.instance MockContent, :label => "column1"
85
- instance.set label: "changed"
86
- @mapper.save(instance)
87
- @database.sqls.should == [
88
- "INSERT INTO content (label, type_sid) VALUES ('column1', 'DataMapperTest::MockContent')",
89
- "SELECT * FROM content WHERE (id = 1) LIMIT 1",
90
- "UPDATE content SET label = 'changed' WHERE (id = 1)"
91
- ]
92
- end
95
+ it "find an existing model" do
96
+ instance = @mapper.instance MockContent, :label => "column1"
97
+ @database.sqls # clear the sql log
98
+ @database.fetch = { id:1, label:"column1", type_sid:"MockContent" }
99
+ instance = @mapper.get(1)
100
+ @database.sqls.must_equal [
101
+ "SELECT * FROM content WHERE (id = 1) LIMIT 1"
102
+ ]
103
+ instance.must_be_instance_of MockContent
104
+ instance.id.must_equal 1
105
+ instance.attributes[:label].must_equal "column1"
106
+ end
93
107
 
94
- should "update model rows directly" do
95
- @mapper.update([MockContent], label: "changed")
96
- @database.sqls.should == [
97
- "UPDATE content SET label = 'changed' WHERE (type_sid IN ('DataMapperTest::MockContent'))"
98
- ]
99
- end
108
+ it "retirieve a list of objects in the specified order" do
109
+ instance = @mapper.instance MockContent, :label => "column1"
110
+ @database.sqls # clear the sql log
111
+ @database.fetch = [
112
+ { id:1, type_sid:"MockContent" },
113
+ { id:2, type_sid:"MockContent" },
114
+ { id:3, type_sid:"MockContent" },
115
+ { id:4, type_sid:"MockContent" }
116
+ ]
117
+ results = @mapper.get([2, 3, 4, 1])
118
+ results.map(&:id).must_equal [2, 3, 4, 1]
119
+ end
100
120
 
101
- should "find an existing model" do
102
- instance = @mapper.instance MockContent, :label => "column1"
103
- @database.sqls # clear the sql log
104
- @database.fetch = { id:1, label:"column1", type_sid:"DataMapperTest::MockContent" }
105
- instance = @mapper.get(1)
106
- @database.sqls.should == [
107
- "SELECT * FROM content WHERE (id = 1) LIMIT 1"
108
- ]
109
- instance.must_be_instance_of MockContent
110
- instance.id.should == 1
111
- instance.attributes[:label].should == "column1"
112
- end
121
+ it "allow for finding the first instance of a model" do
122
+ @database.fetch = { id:1, label:"column1", type_sid:"MockContent" }
123
+ instance = @mapper.first([MockContent], id: 1)
124
+ @database.sqls.must_equal [
125
+ "SELECT * FROM content WHERE ((type_sid IN ('MockContent')) AND (id = 1)) LIMIT 1"
126
+ ]
127
+ end
113
128
 
114
- should "retirieve a list of objects in the specified order" do
129
+ it "be scopable to a revision" do
130
+ @database.fetch = { id:1, label:"column1", type_sid:"MockContent" }
131
+ @mapper.revision(10) do
115
132
  instance = @mapper.instance MockContent, :label => "column1"
116
- @database.sqls # clear the sql log
117
- @database.fetch = [
118
- { id:1, type_sid:"DataMapperTest::MockContent" },
119
- { id:2, type_sid:"DataMapperTest::MockContent" },
120
- { id:3, type_sid:"DataMapperTest::MockContent" },
121
- { id:4, type_sid:"DataMapperTest::MockContent" }
122
- ]
123
- results = @mapper.get([2, 3, 4, 1])
124
- results.map(&:id).should == [2, 3, 4, 1]
125
- end
126
-
127
- should "allow for finding the first instance of a model" do
128
- @database.fetch = { id:1, label:"column1", type_sid:"DataMapperTest::MockContent" }
129
- instance = @mapper.first([MockContent], id: 1)
130
- @database.sqls.should == [
131
- "SELECT * FROM content WHERE ((type_sid IN ('DataMapperTest::MockContent')) AND (id = 1)) LIMIT 1"
133
+ instance.set label: "changed"
134
+ @mapper.save(instance)
135
+ @database.sqls.must_equal [
136
+ "INSERT INTO __r00010_content (label, type_sid) VALUES ('column1', 'MockContent')",
137
+ "SELECT * FROM __r00010_content WHERE (id = 1) LIMIT 1",
138
+ "UPDATE __r00010_content SET label = 'changed' WHERE (id = 1)"
132
139
  ]
133
140
  end
141
+ end
134
142
 
135
- should "be scopable to a revision" do
136
- @database.fetch = { id:1, label:"column1", type_sid:"DataMapperTest::MockContent" }
137
- @mapper.revision(10) do
138
- instance = @mapper.instance MockContent, :label => "column1"
139
- instance.set label: "changed"
140
- @mapper.save(instance)
141
- @database.sqls.should == [
142
- "INSERT INTO __r00010_content (label, type_sid) VALUES ('column1', 'DataMapperTest::MockContent')",
143
- "SELECT * FROM __r00010_content WHERE (id = 1) LIMIT 1",
144
- "UPDATE __r00010_content SET label = 'changed' WHERE (id = 1)"
145
- ]
146
- end
147
- end
148
-
149
- should "return the correct table name" do
150
- @mapper.table_name.should == :"content"
151
- @mapper.revision(10) do
152
- @mapper.table_name.should == :"__r00010_content"
153
- end
143
+ it "return the correct table name" do
144
+ @mapper.table_name.must_equal :"content"
145
+ @mapper.revision(10) do
146
+ @mapper.table_name.must_equal :"__r00010_content"
154
147
  end
148
+ end
155
149
 
156
- should "allow for retrieval of rows from a specific revision" do
157
- @database.fetch = { id:1, label:"column1", type_sid:"DataMapperTest::MockContent" }
158
- instance = @mapper.revision(20).get(1)
159
- @database.sqls.should == ["SELECT * FROM __r00020_content WHERE (id = 1) LIMIT 1"]
160
- instance.must_be_instance_of MockContent
161
- instance.id.should == 1
162
- instance.attributes[:label].should == "column1"
163
- end
150
+ it "allow for retrieval of rows from a specific revision" do
151
+ @database.fetch = { id:1, label:"column1", type_sid:"MockContent" }
152
+ instance = @mapper.revision(20).get(1)
153
+ @database.sqls.must_equal ["SELECT * FROM __r00020_content WHERE (id = 1) LIMIT 1"]
154
+ instance.must_be_instance_of MockContent
155
+ instance.id.must_equal 1
156
+ instance.attributes[:label].must_equal "column1"
157
+ end
164
158
 
165
- should "support nested revision scopes" do
166
- @database.fetch = { id:1, label:"column1", type_sid:"DataMapperTest::MockContent" }
167
- @mapper.revision(10) do
159
+ it "support nested revision scopes" do
160
+ @database.fetch = { id:1, label:"column1", type_sid:"MockContent" }
161
+ @mapper.revision(10) do
162
+ instance = @mapper.get(1)
163
+ instance.label = "changed1"
164
+ @mapper.save(instance)
165
+ @mapper.revision(20) do
168
166
  instance = @mapper.get(1)
169
- instance.label = "changed1"
167
+ instance.label = "changed2"
170
168
  @mapper.save(instance)
171
- @mapper.revision(20) do
172
- instance = @mapper.get(1)
173
- instance.label = "changed2"
174
- @mapper.save(instance)
175
- instance = @mapper.editable.get(3)
176
- end
169
+ instance = @mapper.editable.get(3)
177
170
  end
178
- @database.sqls.should == [
179
- "SELECT * FROM __r00010_content WHERE (id = 1) LIMIT 1",
180
- "UPDATE __r00010_content SET label = 'changed1' WHERE (id = 1)",
181
- "SELECT * FROM __r00020_content WHERE (id = 1) LIMIT 1",
182
- "UPDATE __r00020_content SET label = 'changed2' WHERE (id = 1)",
183
- "SELECT * FROM content WHERE (id = 3) LIMIT 1"
184
- ]
185
171
  end
172
+ @database.sqls.must_equal [
173
+ "SELECT * FROM __r00010_content WHERE (id = 1) LIMIT 1",
174
+ "UPDATE __r00010_content SET label = 'changed1' WHERE (id = 1)",
175
+ "SELECT * FROM __r00020_content WHERE (id = 1) LIMIT 1",
176
+ "UPDATE __r00020_content SET label = 'changed2' WHERE (id = 1)",
177
+ "SELECT * FROM content WHERE (id = 3) LIMIT 1"
178
+ ]
179
+ end
186
180
 
187
- should "allow for finding all instances of a class with DataMapper#all" do
188
- @database.fetch = [
189
- { id:1, label:"column1", type_sid:"DataMapperTest::MockContent" },
190
- { id:2, label:"column2", type_sid:"DataMapperTest::MockContent2" }
191
- ]
192
- results = @mapper.all([MockContent, MockContent2])
193
- @database.sqls.should == [
194
- "SELECT * FROM content WHERE (type_sid IN ('DataMapperTest::MockContent', 'DataMapperTest::MockContent2'))"
195
- ]
196
- results.map(&:class).should == [MockContent, MockContent2]
197
- results.map(&:id).should == [1, 2]
198
- end
181
+ it "allow for finding all instances of a class with DataMapper#all" do
182
+ @database.fetch = [
183
+ { id:1, label:"column1", type_sid:"MockContent" },
184
+ { id:2, label:"column2", type_sid:"MockContent2" }
185
+ ]
186
+ results = @mapper.all([MockContent, MockContent2])
187
+ @database.sqls.must_equal [
188
+ "SELECT * FROM content WHERE (type_sid IN ('MockContent', 'MockContent2'))"
189
+ ]
190
+ results.map(&:class).must_equal [MockContent, MockContent2]
191
+ results.map(&:id).must_equal [1, 2]
192
+ end
199
193
 
200
- should "allow for finding all instances of a class with DataMapper#types" do
201
- @database.fetch = [
202
- { id:1, label:"column1", type_sid:"DataMapperTest::MockContent" },
203
- { id:2, label:"column2", type_sid:"DataMapperTest::MockContent2" }
204
- ]
205
- results = @mapper.all([MockContent, MockContent2])
206
- @database.sqls.should == [
207
- "SELECT * FROM content WHERE (type_sid IN ('DataMapperTest::MockContent', 'DataMapperTest::MockContent2'))"
208
- ]
209
- results.map(&:class).should == [MockContent, MockContent2]
210
- results.map(&:id).should == [1, 2]
211
- end
194
+ it "allow for finding all instances of a class with DataMapper#types" do
195
+ @database.fetch = [
196
+ { id:1, label:"column1", type_sid:"MockContent" },
197
+ { id:2, label:"column2", type_sid:"MockContent2" }
198
+ ]
199
+ results = @mapper.all([MockContent, MockContent2])
200
+ @database.sqls.must_equal [
201
+ "SELECT * FROM content WHERE (type_sid IN ('MockContent', 'MockContent2'))"
202
+ ]
203
+ results.map(&:class).must_equal [MockContent, MockContent2]
204
+ results.map(&:id).must_equal [1, 2]
205
+ end
212
206
 
213
- should "allow for counting type rows" do
214
- @mapper.count([MockContent, MockContent2])
215
- @database.sqls.should == [
216
- "SELECT COUNT(*) AS count FROM content WHERE (type_sid IN ('DataMapperTest::MockContent', 'DataMapperTest::MockContent2')) LIMIT 1"
217
- ]
218
- end
207
+ it "allow for counting type rows" do
208
+ @mapper.count([MockContent, MockContent2])
209
+ @database.sqls.must_equal [
210
+ "SELECT COUNT(*) AS count FROM content WHERE (type_sid IN ('MockContent', 'MockContent2')) LIMIT 1"
211
+ ]
212
+ end
219
213
 
220
- should "allow for use of block iterator when loading all model instances" do
221
- ids = []
222
- @database.fetch = [
223
- { id:1, label:"column1", type_sid:"DataMapperTest::MockContent" },
224
- { id:2, label:"column2", type_sid:"DataMapperTest::MockContent2" }
225
- ]
226
- results = @mapper.all([MockContent, MockContent2]) do |i|
227
- ids << i.id
228
- end
229
- ids.should == [1, 2]
230
- results.map(&:class).should == [MockContent, MockContent2]
214
+ it "allow for use of block iterator when loading all model instances" do
215
+ ids = []
216
+ @database.fetch = [
217
+ { id:1, label:"column1", type_sid:"MockContent" },
218
+ { id:2, label:"column2", type_sid:"MockContent2" }
219
+ ]
220
+ results = @mapper.all([MockContent, MockContent2]) do |i|
221
+ ids << i.id
231
222
  end
223
+ ids.must_equal [1, 2]
224
+ results.map(&:class).must_equal [MockContent, MockContent2]
225
+ end
232
226
 
233
- should "allow for defining an order" do
234
- ds = @mapper.order([MockContent], "column1").all
235
- @database.sqls.should == [
236
- "SELECT * FROM content WHERE (type_sid IN ('DataMapperTest::MockContent')) ORDER BY 'column1'"
237
- ]
238
- end
227
+ it "allow for defining an order" do
228
+ ds = @mapper.order([MockContent], "column1").all
229
+ @database.sqls.must_equal [
230
+ "SELECT * FROM content WHERE (type_sid IN ('MockContent')) ORDER BY 'column1'"
231
+ ]
232
+ end
239
233
 
240
- should "allow for defining a limit" do
241
- ds = @mapper.limit([MockContent], 10...20).all
242
- ds = @mapper.filter([], label: "this").limit(10).all
243
- @database.sqls.should == [
244
- "SELECT * FROM content WHERE (type_sid IN ('DataMapperTest::MockContent')) LIMIT 10 OFFSET 10",
245
- "SELECT * FROM content WHERE (label = 'this') LIMIT 10"
246
- ]
247
- end
234
+ it "allow for defining a limit" do
235
+ ds = @mapper.limit([MockContent], 10...20).all
236
+ ds = @mapper.filter([], label: "this").limit(10).all
237
+ @database.sqls.must_equal [
238
+ "SELECT * FROM content WHERE (type_sid IN ('MockContent')) LIMIT 10 OFFSET 10",
239
+ "SELECT * FROM content WHERE (label = 'this') LIMIT 10"
240
+ ]
241
+ end
248
242
 
249
- should "support chained filters" do
250
- @database.fetch = [
251
- { id:1, label:"column1", type_sid:"DataMapperTest::MockContent" }
252
- ]
253
- ds = @mapper.filter([MockContent, MockContent2], id:1)
254
- results = ds.all
255
- results.map(&:class).should == [MockContent]
256
- results.map(&:id).should == [1]
257
- @database.sqls.should == [
258
- "SELECT * FROM content WHERE ((type_sid IN ('DataMapperTest::MockContent', 'DataMapperTest::MockContent2')) AND (id = 1))"
259
- ]
260
- end
243
+ it "support chained filters" do
244
+ @database.fetch = [
245
+ { id:1, label:"column1", type_sid:"MockContent" }
246
+ ]
247
+ ds = @mapper.filter([MockContent, MockContent2], id:1)
248
+ results = ds.all
249
+ results.map(&:class).must_equal [MockContent]
250
+ results.map(&:id).must_equal [1]
251
+ @database.sqls.must_equal [
252
+ "SELECT * FROM content WHERE ((type_sid IN ('MockContent', 'MockContent2')) AND (id = 1))"
253
+ ]
254
+ end
261
255
 
262
- should "support filtering using virtual rows" do
263
- @database.fetch = [
264
- { id:1, label:"column1", type_sid:"DataMapperTest::MockContent" },
265
- { id:2, label:"column2", type_sid:"DataMapperTest::MockContent2" }
266
- ]
267
- ds = @mapper.filter([MockContent, MockContent2]) { id > 0 }
268
- results = ds.all
269
- results.map(&:class).should == [MockContent, MockContent2]
270
- results.map(&:id).should == [1, 2]
271
- @database.sqls.should == [
272
- "SELECT * FROM content WHERE ((type_sid IN ('DataMapperTest::MockContent', 'DataMapperTest::MockContent2')) AND (id > 0))"
273
- ]
274
- end
256
+ it "support filtering using virtual rows" do
257
+ @database.fetch = [
258
+ { id:1, label:"column1", type_sid:"MockContent" },
259
+ { id:2, label:"column2", type_sid:"MockContent2" }
260
+ ]
261
+ ds = @mapper.filter([MockContent, MockContent2]) { id > 0 }
262
+ results = ds.all
263
+ results.map(&:class).must_equal [MockContent, MockContent2]
264
+ results.map(&:id).must_equal [1, 2]
265
+ @database.sqls.must_equal [
266
+ "SELECT * FROM content WHERE ((type_sid IN ('MockContent', 'MockContent2')) AND (id > 0))"
267
+ ]
268
+ end
275
269
 
276
- should "support multiple concurrent filters" do
277
- # want to be sure that each dataset is independent
278
- ds1 = @mapper.filter([MockContent], id: 1)
279
- ds2 = @mapper.filter([MockContent2])
270
+ it "support multiple concurrent filters" do
271
+ # want to be sure that each dataset is independent
272
+ ds1 = @mapper.filter([MockContent], id: 1)
273
+ ds2 = @mapper.filter([MockContent2])
280
274
 
281
- @database.fetch = { id:1, label:"column1", type_sid:"DataMapperTest::MockContent" }
282
- ds1.first([]).must_be_instance_of MockContent
275
+ @database.fetch = { id:1, label:"column1", type_sid:"MockContent" }
276
+ ds1.first([]).must_be_instance_of MockContent
283
277
 
284
- @database.fetch = { id:2, label:"column2", type_sid:"DataMapperTest::MockContent2" }
285
- ds2.first([]).must_be_instance_of MockContent2
278
+ @database.fetch = { id:2, label:"column2", type_sid:"MockContent2" }
279
+ ds2.first([]).must_be_instance_of MockContent2
286
280
 
287
- @database.sqls.should == [
288
- "SELECT * FROM content WHERE ((type_sid IN ('DataMapperTest::MockContent')) AND (id = 1)) LIMIT 1",
289
- "SELECT * FROM content WHERE (type_sid IN ('DataMapperTest::MockContent2')) LIMIT 1"
290
- ]
291
- end
281
+ @database.sqls.must_equal [
282
+ "SELECT * FROM content WHERE ((type_sid IN ('MockContent')) AND (id = 1)) LIMIT 1",
283
+ "SELECT * FROM content WHERE (type_sid IN ('MockContent2')) LIMIT 1"
284
+ ]
285
+ end
292
286
 
293
- should "allow you to delete datasets" do
294
- @mapper.delete([MockContent])
295
- @database.sqls.should == [
296
- "DELETE FROM content WHERE (type_sid IN ('DataMapperTest::MockContent'))"
297
- ]
298
- end
287
+ it "allow you to delete datasets" do
288
+ @mapper.delete([MockContent])
289
+ @database.sqls.must_equal [
290
+ "DELETE FROM content WHERE (type_sid IN ('MockContent'))"
291
+ ]
292
+ end
299
293
 
300
- should "allow you to delete instances" do
301
- @database.fetch = { id:1, label:"label", type_sid:"DataMapperTest::MockContent" }
302
- instance = @mapper.instance MockContent, label: "label"
303
- @database.sqls
294
+ it "allow you to delete instances" do
295
+ @database.fetch = { id:1, label:"label", type_sid:"MockContent" }
296
+ instance = @mapper.instance MockContent, label: "label"
297
+ @database.sqls
298
+ @mapper.delete_instance instance
299
+ @database.sqls.must_equal [
300
+ "DELETE FROM content WHERE (id = 1)"
301
+ ]
302
+ end
303
+
304
+ it "allow you to delete instances within a revision" do
305
+ @database.fetch = { id:1, label:"label", type_sid:"MockContent" }
306
+ instance = @mapper.instance MockContent, label: "label"
307
+ @database.sqls
308
+ @mapper.revision(20) do
304
309
  @mapper.delete_instance instance
305
- @database.sqls.should == [
306
- "DELETE FROM content WHERE (id = 1)"
307
- ]
308
310
  end
311
+ @database.sqls.must_equal [
312
+ "DELETE FROM __r00020_content WHERE (id = 1)"
313
+ ]
314
+ end
309
315
 
310
- should "allow you to delete instances within a revision" do
311
- @database.fetch = { id:1, label:"label", type_sid:"DataMapperTest::MockContent" }
312
- instance = @mapper.instance MockContent, label: "label"
313
- @database.sqls
314
- @mapper.revision(20) do
315
- @mapper.delete_instance instance
316
- end
317
- @database.sqls.should == [
318
- "DELETE FROM __r00020_content WHERE (id = 1)"
319
- ]
320
- end
316
+ it "allow you to destroy model instances" do
317
+ @database.fetch = { id:1, label:"column1", type_sid:"MockContent" }
318
+ instance = @mapper.instance MockContent, :label => "column1"
319
+ @database.sqls # clear sql log
320
+ @mapper.delete_instance instance
321
+ instance.id.must_equal 1
322
+ @database.sqls.must_equal [
323
+ "DELETE FROM content WHERE (id = 1)"
324
+ ]
325
+ end
321
326
 
322
- should "allow you to destroy model instances" do
323
- @database.fetch = { id:1, label:"column1", type_sid:"DataMapperTest::MockContent" }
324
- instance = @mapper.instance MockContent, :label => "column1"
325
- @database.sqls # clear sql log
326
- @mapper.delete_instance instance
327
- instance.id.should == 1
328
- @database.sqls.should == [
329
- "DELETE FROM content WHERE (id = 1)"
330
- ]
327
+ it "support visibility contexts" do
328
+ @database.fetch = { id:1, label:"column1", type_sid:"MockContent" }
329
+ @mapper.visible do
330
+ @mapper.get(1)
331
+ @mapper.visible(false) do
332
+ @mapper.get(1)
333
+ @mapper.visible.get(1)
334
+ end
331
335
  end
336
+ @database.sqls.must_equal [
337
+ "SELECT * FROM content WHERE ((hidden IS FALSE) AND (id = 1)) LIMIT 1",
338
+ "SELECT * FROM content WHERE (id = 1) LIMIT 1",
339
+ "SELECT * FROM content WHERE ((hidden IS FALSE) AND (id = 1)) LIMIT 1",
340
+ ]
341
+ end
332
342
 
333
- should "support visibility contexts" do
334
- @database.fetch = { id:1, label:"column1", type_sid:"DataMapperTest::MockContent" }
343
+ it "support mixed revision & visibility states" do
344
+ @database.fetch = { id:1, label:"column1", type_sid:"MockContent" }
345
+ @mapper.revision(25) do
335
346
  @mapper.visible do
336
347
  @mapper.get(1)
337
- @mapper.visible(false) do
338
- @mapper.get(1)
339
- @mapper.visible.get(1)
340
- end
341
348
  end
342
- @database.sqls.should == [
343
- "SELECT * FROM content WHERE ((hidden IS FALSE) AND (id = 1)) LIMIT 1",
344
- "SELECT * FROM content WHERE (id = 1) LIMIT 1",
345
- "SELECT * FROM content WHERE ((hidden IS FALSE) AND (id = 1)) LIMIT 1",
346
- ]
347
349
  end
350
+ @database.sqls.must_equal [
351
+ "SELECT * FROM __r00025_content WHERE ((hidden IS FALSE) AND (id = 1)) LIMIT 1",
352
+ ]
353
+ end
348
354
 
349
- should "support mixed revision & visibility states" do
350
- @database.fetch = { id:1, label:"column1", type_sid:"DataMapperTest::MockContent" }
351
- @mapper.revision(25) do
352
- @mapper.visible do
353
- @mapper.get(1)
354
- end
355
- end
356
- @database.sqls.should == [
357
- "SELECT * FROM __r00025_content WHERE ((hidden IS FALSE) AND (id = 1)) LIMIT 1",
358
- ]
355
+ it "ignore visibility filter for deletes" do
356
+ @database.fetch = { id:1, label:"label", type_sid:"MockContent" }
357
+ instance = @mapper.instance MockContent, label: "label"
358
+ @database.sqls
359
+ @mapper.visible do
360
+ @mapper.delete_instance(instance)
359
361
  end
362
+ @database.sqls.must_equal [
363
+ "DELETE FROM content WHERE (id = 1)",
364
+ ]
365
+ end
360
366
 
361
- should "ignore visibility filter for deletes" do
362
- @database.fetch = { id:1, label:"label", type_sid:"DataMapperTest::MockContent" }
363
- instance = @mapper.instance MockContent, label: "label"
364
- @database.sqls
365
- @mapper.visible do
366
- @mapper.delete_instance(instance)
367
+ it "ignore visibility setting for creates" do
368
+ @mapper.visible do
369
+ @mapper.revision(99) do
370
+ instance = @mapper.instance MockContent, :label => "column1"
367
371
  end
368
- @database.sqls.should == [
369
- "DELETE FROM content WHERE (id = 1)",
370
- ]
371
372
  end
373
+ @database.sqls.must_equal [
374
+ "INSERT INTO __r00099_content (label, type_sid) VALUES ('column1', 'MockContent')",
375
+ "SELECT * FROM __r00099_content WHERE (id = 1) LIMIT 1"
376
+ ]
377
+ end
372
378
 
373
- should "ignore visibility setting for creates" do
374
- @mapper.visible do
375
- @mapper.revision(99) do
376
- instance = @mapper.instance MockContent, :label => "column1"
377
- end
378
- end
379
- @database.sqls.should == [
380
- "INSERT INTO __r00099_content (label, type_sid) VALUES ('column1', 'DataMapperTest::MockContent')",
381
- "SELECT * FROM __r00099_content WHERE (id = 1) LIMIT 1"
382
- ]
383
- end
379
+ it "allow for inserting raw attributes" do
380
+ @mapper.insert type_sid: "MockContent", label: "label"
381
+ @database.sqls.must_equal [
382
+ "INSERT INTO content (type_sid, label) VALUES ('MockContent', 'label')"
383
+ ]
384
+ end
385
+ end
384
386
 
385
- should "allow for inserting raw attributes" do
386
- @mapper.insert type_sid: "MockContent", label: "label"
387
- @database.sqls.should == [
388
- "INSERT INTO content (type_sid, label) VALUES ('MockContent', 'label')"
389
- ]
390
- end
387
+ describe "models" do
388
+ it "be deletable" do
389
+ MockContent.delete
390
+ @database.sqls.must_equal [
391
+ "DELETE FROM content WHERE (type_sid IN ('MockContent'))"
392
+ ]
391
393
  end
392
394
 
393
- context "models" do
394
- should "be deletable" do
395
- MockContent.delete
396
- @database.sqls.should == [
397
- "DELETE FROM content WHERE (type_sid IN ('DataMapperTest::MockContent'))"
398
- ]
399
- end
395
+ it "be creatable using Model.create" do
396
+ @database.fetch = { id:1, label:"value", type_sid:"MockContent" }
397
+ instance = MockContent.create(label: "value")
398
+ @database.sqls.must_equal [
399
+ "INSERT INTO content (label, type_sid) VALUES ('value', 'MockContent')",
400
+ "SELECT * FROM content WHERE (id = 1) LIMIT 1"
401
+ ]
402
+ refute instance.new?
403
+ instance.id.must_equal 1
404
+ end
400
405
 
401
- should "be creatable using Model.create" do
402
- @database.fetch = { id:1, label:"value", type_sid:"DataMapperTest::MockContent" }
403
- instance = MockContent.create(label: "value")
404
- @database.sqls.should == [
405
- "INSERT INTO content (label, type_sid) VALUES ('value', 'DataMapperTest::MockContent')",
406
- "SELECT * FROM content WHERE (id = 1) LIMIT 1"
407
- ]
408
- instance.new?.should be_false
409
- instance.id.should == 1
410
- end
406
+ it "be instantiable using Model.new" do
407
+ instance = MockContent.new(label: "value")
408
+ assert instance.new?
409
+ end
411
410
 
412
- should "be instantiable using Model.new" do
413
- instance = MockContent.new(label: "value")
414
- instance.new?.should be_true
415
- end
411
+ it "be creatable using Model.new" do
412
+ @database.fetch = { id:1, label:"value", type_sid:"MockContent" }
413
+ instance = MockContent.new(label: "value")
414
+ instance.save
415
+ refute instance.new?
416
+ @database.sqls.must_equal [
417
+ "INSERT INTO content (label, type_sid) VALUES ('value', 'MockContent')",
418
+ "SELECT * FROM content WHERE (id = 1) LIMIT 1"
419
+ ]
420
+ instance.id.must_equal 1
421
+ end
416
422
 
417
- should "be creatable using Model.new" do
418
- @database.fetch = { id:1, label:"value", type_sid:"DataMapperTest::MockContent" }
419
- instance = MockContent.new(label: "value")
420
- instance.save
421
- instance.new?.should be_false
422
- @database.sqls.should == [
423
- "INSERT INTO content (label, type_sid) VALUES ('value', 'DataMapperTest::MockContent')",
424
- "SELECT * FROM content WHERE (id = 1) LIMIT 1"
425
- ]
426
- instance.id.should == 1
427
- end
423
+ it "be updatable" do
424
+ @database.fetch = { id:1, label:"value", type_sid:"MockContent" }
425
+ instance = MockContent.create(label: "value")
426
+ instance.update(label: "changed")
427
+ @database.sqls.must_equal [
428
+ "INSERT INTO content (label, type_sid) VALUES ('value', 'MockContent')",
429
+ "SELECT * FROM content WHERE (id = 1) LIMIT 1",
430
+ "UPDATE content SET label = 'changed' WHERE (id = 1)"
431
+ ]
432
+ end
428
433
 
429
- should "be updatable" do
430
- @database.fetch = { id:1, label:"value", type_sid:"DataMapperTest::MockContent" }
431
- instance = MockContent.create(label: "value")
432
- instance.update(label: "changed")
433
- @database.sqls.should == [
434
- "INSERT INTO content (label, type_sid) VALUES ('value', 'DataMapperTest::MockContent')",
435
- "SELECT * FROM content WHERE (id = 1) LIMIT 1",
436
- "UPDATE content SET label = 'changed' WHERE (id = 1)"
437
- ]
438
- end
434
+ it "exclude id column from updates" do
435
+ @database.fetch = { id:1, label:"value", type_sid:"MockContent" }
436
+ instance = MockContent.create(id: 103, label: "value")
437
+ instance.id.must_equal 1
438
+ instance.update(id: 99, label: "changed")
439
+ @database.sqls.must_equal [
440
+ "INSERT INTO content (label, type_sid) VALUES ('value', 'MockContent')",
441
+ "SELECT * FROM content WHERE (id = 1) LIMIT 1",
442
+ "UPDATE content SET label = 'changed' WHERE (id = 1)"
443
+ ]
444
+ instance.id.must_equal 1
445
+ end
439
446
 
440
- should "exclude id column from updates" do
441
- @database.fetch = { id:1, label:"value", type_sid:"DataMapperTest::MockContent" }
442
- instance = MockContent.create(id: 103, label: "value")
443
- instance.id.should == 1
444
- instance.update(id: 99, label: "changed")
445
- @database.sqls.should == [
446
- "INSERT INTO content (label, type_sid) VALUES ('value', 'DataMapperTest::MockContent')",
447
- "SELECT * FROM content WHERE (id = 1) LIMIT 1",
448
- "UPDATE content SET label = 'changed' WHERE (id = 1)"
449
- ]
450
- instance.id.should == 1
451
- end
447
+ it "exclude type_sid column from updates" do
448
+ @database.fetch = { id:1, label:"value", type_sid:"MockContent" }
449
+ instance = MockContent.create(type_sid: "Nothing", label: "value")
450
+ instance.update(type_sid: "Invalid", label: "changed")
451
+ @database.sqls.must_equal [
452
+ "INSERT INTO content (label, type_sid) VALUES ('value', 'MockContent')",
453
+ "SELECT * FROM content WHERE (id = 1) LIMIT 1",
454
+ "UPDATE content SET label = 'changed' WHERE (id = 1)"
455
+ ]
456
+ instance.id.must_equal 1
457
+ end
452
458
 
453
- should "exclude type_sid column from updates" do
454
- @database.fetch = { id:1, label:"value", type_sid:"DataMapperTest::MockContent" }
455
- instance = MockContent.create(type_sid: "Nothing", label: "value")
456
- instance.update(type_sid: "Invalid", label: "changed")
457
- @database.sqls.should == [
458
- "INSERT INTO content (label, type_sid) VALUES ('value', 'DataMapperTest::MockContent')",
459
- "SELECT * FROM content WHERE (id = 1) LIMIT 1",
460
- "UPDATE content SET label = 'changed' WHERE (id = 1)"
461
- ]
462
- instance.id.should == 1
463
- end
459
+ it "only update changed columns" do
460
+ @database.fetch = { id:1, label:"value", type_sid:"MockContent" }
461
+ instance = MockContent.create(label: "value")
462
+ @database.sqls
463
+ instance.changed_columns.must_equal []
464
+ instance.label = "changed"
465
+ instance.changed_columns.must_equal [:label]
466
+ instance.object1 = "updated"
467
+ instance.changed_columns.must_equal [:label, :object1]
468
+ instance.save
469
+ @database.sqls.must_equal [
470
+ "UPDATE content SET label = 'changed', object1 = '\"updated\"' WHERE (id = 1)"
471
+ ]
472
+ end
464
473
 
465
- should "only update changed columns" do
466
- @database.fetch = { id:1, label:"value", type_sid:"DataMapperTest::MockContent" }
467
- instance = MockContent.create(label: "value")
468
- @database.sqls
469
- instance.changed_columns.should == []
470
- instance.label = "changed"
471
- instance.changed_columns.should == [:label]
472
- instance.object1 = "updated"
473
- instance.changed_columns.should == [:label, :object1]
474
- instance.save
475
- @database.sqls.should == [
476
- "UPDATE content SET label = 'changed', object1 = '\"updated\"' WHERE (id = 1)"
477
- ]
478
- end
474
+ it "mark new instances as modified" do
475
+ instance = MockContent.new(label: "value")
476
+ assert instance.modified?
477
+ end
479
478
 
480
- should "mark new instances as modified" do
481
- instance = MockContent.new(label: "value")
482
- instance.modified?.should be_true
483
- end
479
+ it "updated modified flag after save" do
480
+ instance = MockContent.new(label: "value")
481
+ instance.save
482
+ refute instance.modified?
483
+ end
484
484
 
485
- should "updated modified flag after save" do
486
- instance = MockContent.new(label: "value")
487
- instance.save
488
- instance.modified?.should be_false
489
- end
485
+ it "have a modified flag if columns changed" do
486
+ @database.fetch = { id:1, label:"value", type_sid:"MockContent" }
487
+ instance = MockContent.create(label: "value")
488
+ refute instance.modified?
489
+ instance.label = "changed"
490
+ assert instance.modified?
491
+ end
490
492
 
491
- should "have a modified flag if columns changed" do
492
- @database.fetch = { id:1, label:"value", type_sid:"DataMapperTest::MockContent" }
493
- instance = MockContent.create(label: "value")
494
- instance.modified?.should be_false
495
- instance.label = "changed"
496
- instance.modified?.should be_true
497
- end
493
+ it "not make a db call if no values have been modified" do
494
+ @database.fetch = { id:1, label:"value", type_sid:"MockContent" }
495
+ instance = MockContent.create(label: "value")
496
+ @database.sqls
497
+ instance.save
498
+ @database.sqls.must_equal []
499
+ end
498
500
 
499
- should "not make a db call if no values have been modified" do
500
- @database.fetch = { id:1, label:"value", type_sid:"DataMapperTest::MockContent" }
501
- instance = MockContent.create(label: "value")
502
- @database.sqls
503
- instance.save
504
- @database.sqls.should == []
505
- end
501
+ it "allow you to force a save" do
502
+ @database.fetch = { id:1, label:"value", type_sid:"MockContent" }
503
+ instance = MockContent.create(label: "value")
504
+ @database.sqls
505
+ instance.mark_modified!
506
+ instance.save
507
+ @database.sqls.must_equal [
508
+ "UPDATE content SET label = 'value', type_sid = 'MockContent' WHERE (id = 1)"
509
+ ]
510
+ end
506
511
 
507
- should "allow you to force a save" do
508
- @database.fetch = { id:1, label:"value", type_sid:"DataMapperTest::MockContent" }
509
- instance = MockContent.create(label: "value")
510
- @database.sqls
511
- instance.mark_modified!
512
- instance.save
513
- @database.sqls.should == [
514
- "UPDATE content SET label = 'value', type_sid = 'DataMapperTest::MockContent' WHERE (id = 1)"
515
- ]
516
- end
512
+ it "allow you to force an update to a specific column" do
513
+ @database.fetch = { id:1, label:"value", type_sid:"MockContent" }
514
+ instance = MockContent.create(label: "value")
515
+ @database.sqls
516
+ instance.mark_modified!(:label)
517
+ instance.save
518
+ @database.sqls.must_equal [
519
+ "UPDATE content SET label = 'value' WHERE (id = 1)"
520
+ ]
521
+ end
517
522
 
518
- should "allow you to force an update to a specific column" do
519
- @database.fetch = { id:1, label:"value", type_sid:"DataMapperTest::MockContent" }
520
- instance = MockContent.create(label: "value")
521
- @database.sqls
522
- instance.mark_modified!(:label)
523
- instance.save
524
- @database.sqls.should == [
525
- "UPDATE content SET label = 'value' WHERE (id = 1)"
526
- ]
527
- end
523
+ it "be destroyable" do
524
+ @database.fetch = { id:1, label:"value", type_sid:"MockContent" }
525
+ instance = MockContent.create(label: "value")
526
+ instance.id.must_equal 1
527
+ instance.destroy
528
+ @database.sqls.must_equal [
529
+ "INSERT INTO content (label, type_sid) VALUES ('value', 'MockContent')",
530
+ "SELECT * FROM content WHERE (id = 1) LIMIT 1",
531
+ "DELETE FROM content WHERE (id = 1)"
532
+ ]
533
+ end
528
534
 
529
- should "be destroyable" do
530
- @database.fetch = { id:1, label:"value", type_sid:"DataMapperTest::MockContent" }
531
- instance = MockContent.create(label: "value")
532
- instance.id.should == 1
533
- instance.destroy
534
- @database.sqls.should == [
535
- "INSERT INTO content (label, type_sid) VALUES ('value', 'DataMapperTest::MockContent')",
536
- "SELECT * FROM content WHERE (id = 1) LIMIT 1",
537
- "DELETE FROM content WHERE (id = 1)"
538
- ]
539
- end
535
+ it "allow for searching for all instances of a class" do
536
+ @database.fetch = [
537
+ { id:1, label:"column1", type_sid:"MockContent" },
538
+ { id:2, label:"column2", type_sid:"MockContent" }
539
+ ]
540
+ results = MockContent.all
541
+ @database.sqls.must_equal [
542
+ "SELECT * FROM content WHERE (type_sid IN ('MockContent'))"
543
+ ]
544
+ results.length.must_equal 2
545
+ results.map(&:class).must_equal [MockContent, MockContent]
546
+ results.map(&:id).must_equal [1, 2]
547
+ end
540
548
 
541
- should "allow for searching for all instances of a class" do
542
- @database.fetch = [
543
- { id:1, label:"column1", type_sid:"DataMapperTest::MockContent" },
544
- { id:2, label:"column2", type_sid:"DataMapperTest::MockContent" }
545
- ]
546
- results = MockContent.all
547
- @database.sqls.should == [
548
- "SELECT * FROM content WHERE (type_sid IN ('DataMapperTest::MockContent'))"
549
- ]
550
- results.length.should == 2
551
- results.map(&:class).should == [MockContent, MockContent]
552
- results.map(&:id).should == [1, 2]
553
- end
549
+ it "allow for finding first instance of a type" do
550
+ @database.fetch = [
551
+ { id:1, label:"column1", type_sid:"MockContent" }
552
+ ]
553
+ instance = MockContent.first
554
+ MockContent.first(id: 1)
555
+ MockContent.first { id > 0}
556
+ @database.sqls.must_equal [
557
+ "SELECT * FROM content WHERE (type_sid IN ('MockContent')) LIMIT 1",
558
+ "SELECT * FROM content WHERE ((type_sid IN ('MockContent')) AND (id = 1)) LIMIT 1",
559
+ "SELECT * FROM content WHERE ((type_sid IN ('MockContent')) AND (id > 0)) LIMIT 1"
560
+ ]
561
+ instance.must_be_instance_of MockContent
562
+ instance.id.must_equal 1
563
+ end
554
564
 
555
- should "allow for finding first instance of a type" do
556
- @database.fetch = [
557
- { id:1, label:"column1", type_sid:"DataMapperTest::MockContent" }
558
- ]
559
- instance = MockContent.first
560
- MockContent.first(id: 1)
561
- MockContent.first { id > 0}
562
- @database.sqls.should == [
563
- "SELECT * FROM content WHERE (type_sid IN ('DataMapperTest::MockContent')) LIMIT 1",
564
- "SELECT * FROM content WHERE ((type_sid IN ('DataMapperTest::MockContent')) AND (id = 1)) LIMIT 1",
565
- "SELECT * FROM content WHERE ((type_sid IN ('DataMapperTest::MockContent')) AND (id > 0)) LIMIT 1"
566
- ]
567
- instance.must_be_instance_of MockContent
568
- instance.id.should == 1
569
- end
565
+ it "return nil if no instance matching filter is found" do
566
+ @database.fetch = []
567
+ instance = MockContent.first(id: 1)
568
+ instance.must_be_nil
569
+ end
570
570
 
571
- should "return nil if no instance matching filter is found" do
572
- @database.fetch = []
573
- instance = MockContent.first(id: 1)
574
- instance.should be_nil
575
- end
571
+ it "retrieve by primary key using []" do
572
+ instance = MockContent[1]
573
+ @database.sqls.must_equal [
574
+ "SELECT * FROM content WHERE (id = 1) LIMIT 1",
575
+ ]
576
+ end
576
577
 
577
- should "retrieve by primary key using []" do
578
- instance = MockContent[1]
579
- @database.sqls.should == [
580
- "SELECT * FROM content WHERE (id = 1) LIMIT 1",
581
- ]
582
- end
578
+ it "have correct equality test" do
579
+ @database.fetch = [
580
+ { id:1, label:"column1", type_sid:"MockContent" }
581
+ ]
582
+ a = MockContent[1]
583
+ b = MockContent[1]
584
+ a.must_equal b
583
585
 
584
- should "have correct equality test" do
585
- @database.fetch = [
586
- { id:1, label:"column1", type_sid:"DataMapperTest::MockContent" }
587
- ]
588
- a = MockContent[1]
589
- b = MockContent[1]
590
- a.should == b
586
+ a.label = "changed"
587
+ a.wont_equal b
588
+ end
591
589
 
592
- a.label = "changed"
593
- a.should_not == b
594
- end
590
+ it "allow for filtering model instances" do
591
+ @database.fetch = [
592
+ { id:100, label:"column1", type_sid:"MockContent" }
593
+ ]
594
+ results = MockContent.filter(hidden: false).all
595
+ @database.sqls.must_equal [
596
+ "SELECT * FROM content WHERE ((type_sid IN ('MockContent')) AND (hidden IS FALSE))"
597
+ ]
598
+ results.length.must_equal 1
599
+ results.map(&:class).must_equal [MockContent]
600
+ results.map(&:id).must_equal [100]
601
+ end
595
602
 
596
- should "allow for filtering model instances" do
597
- @database.fetch = [
598
- { id:100, label:"column1", type_sid:"DataMapperTest::MockContent" }
599
- ]
600
- results = MockContent.filter(hidden: false).all
601
- @database.sqls.should == [
602
- "SELECT * FROM content WHERE ((type_sid IN ('DataMapperTest::MockContent')) AND (hidden IS FALSE))"
603
- ]
604
- results.length.should == 1
605
- results.map(&:class).should == [MockContent]
606
- results.map(&:id).should == [100]
603
+ it "use the current mapper revision to save" do
604
+ @database.fetch = [
605
+ { id:100, label:"column1", type_sid:"MockContent" }
606
+ ]
607
+ instance = nil
608
+ @mapper.revision(99) do
609
+ instance = MockContent.first
607
610
  end
608
-
609
- should "use the current mapper revision to save" do
610
- @database.fetch = [
611
- { id:100, label:"column1", type_sid:"DataMapperTest::MockContent" }
612
- ]
613
- instance = nil
614
- @mapper.revision(99) do
615
- instance = MockContent.first
616
- end
617
- instance.update(label: "changed")
618
- @mapper.revision(99) do
619
- instance.update(label: "changed2")
620
- end
621
- @database.sqls.should == [
622
- "SELECT * FROM __r00099_content WHERE (type_sid IN ('DataMapperTest::MockContent')) LIMIT 1",
623
- "UPDATE content SET label = 'changed' WHERE (id = 100)",
624
- "UPDATE __r00099_content SET label = 'changed2' WHERE (id = 100)"
625
- ]
611
+ instance.update(label: "changed")
612
+ @mapper.revision(99) do
613
+ instance.update(label: "changed2")
626
614
  end
615
+ @database.sqls.must_equal [
616
+ "SELECT * FROM __r00099_content WHERE (type_sid IN ('MockContent')) LIMIT 1",
617
+ "UPDATE content SET label = 'changed' WHERE (id = 100)",
618
+ "UPDATE __r00099_content SET label = 'changed2' WHERE (id = 100)"
619
+ ]
620
+ end
627
621
 
628
- should "allow for reloading values from the db" do
629
- @database.fetch = { id:100, label:"column1", type_sid:"DataMapperTest::MockContent" }
630
- instance = MockContent.first
631
- instance.set(label:"changed")
632
- instance.attributes[:label].should == "changed"
633
- instance.changed_columns.should == [:label]
634
- instance.reload
635
- instance.attributes[:label].should == "column1"
636
- instance.changed_columns.should == []
637
- @database.sqls.should == [
638
- "SELECT * FROM content WHERE (type_sid IN ('DataMapperTest::MockContent')) LIMIT 1",
639
- "SELECT * FROM content WHERE (id = 100) LIMIT 1"
640
- ]
641
- end
622
+ it "allow for reloading values from the db" do
623
+ @database.fetch = { id:100, label:"column1", type_sid:"MockContent" }
624
+ instance = MockContent.first
625
+ instance.set(label:"changed")
626
+ instance.attributes[:label].must_equal "changed"
627
+ instance.changed_columns.must_equal [:label]
628
+ instance.reload
629
+ instance.attributes[:label].must_equal "column1"
630
+ instance.changed_columns.must_equal []
631
+ @database.sqls.must_equal [
632
+ "SELECT * FROM content WHERE (type_sid IN ('MockContent')) LIMIT 1",
633
+ "SELECT * FROM content WHERE (id = 100) LIMIT 1"
634
+ ]
635
+ end
642
636
 
643
637
 
644
- should "update model rows directly" do
645
- MockContent.update(label: "changed")
646
- @database.sqls.should == [
647
- "UPDATE content SET label = 'changed' WHERE (type_sid IN ('DataMapperTest::MockContent'))"
648
- ]
638
+ it "update model rows directly" do
639
+ MockContent.update(label: "changed")
640
+ @database.sqls.must_equal [
641
+ "UPDATE content SET label = 'changed' WHERE (type_sid IN ('MockContent'))"
642
+ ]
643
+ end
644
+
645
+ it "introspect columns" do
646
+ MockContent.columns.must_equal @expected_columns
647
+ end
648
+
649
+ it "create getters & setters for all columns except id & type_sid" do
650
+ columns = (@expected_columns - [:id, :type_sid])
651
+ attrs = Hash[columns.map { |c| [c, "#{c}_value"] } ]
652
+ c = MockContent.new attrs
653
+
654
+ columns.each do |column|
655
+ assert c.respond_to?(column), "Instance it respond to ##{column}"
656
+ assert c.respond_to?("#{column}="), "Instance it respond to ##{column}="
657
+ c.send(column).must_equal attrs[column]
658
+ c.send("#{column}=", "changed")
659
+ c.send(column).must_equal "changed"
649
660
  end
661
+ end
650
662
 
651
- should "introspect columns" do
652
- MockContent.columns.should == @expected_columns
663
+ it "set values using the setter methods" do
664
+ model = Class.new(MockContent) do
665
+ def label=(value); super(value + "!"); end
653
666
  end
667
+ instance = model.new label: "label1"
668
+ instance.set(label: "label2")
669
+ instance.label.must_equal "label2!"
670
+ end
654
671
 
655
- should "create getters & setters for all columns except id & type_sid" do
656
- columns = (@expected_columns - [:id, :type_sid])
657
- attrs = Hash[columns.map { |c| [c, "#{c}_value"] } ]
658
- c = MockContent.new attrs
659
-
660
- columns.each do |column|
661
- assert c.respond_to?(column), "Instance should respond to ##{column}"
662
- assert c.respond_to?("#{column}="), "Instance should respond to ##{column}="
663
- c.send(column).should == attrs[column]
664
- c.send("#{column}=", "changed")
665
- c.send(column).should == "changed"
672
+ it "support after_initialize hooks" do
673
+ model = Class.new(MockContent) do
674
+ attr_accessor :param
675
+ def after_initialize
676
+ self.param = true
666
677
  end
667
678
  end
679
+ instance = model.new
680
+ assert instance.param
681
+ end
668
682
 
669
- should "set values using the setter methods" do
670
- model = Class.new(MockContent) do
671
- def label=(value); super(value + "!"); end
683
+ it "support before create triggers" do
684
+ model = Class.new(MockContent) do
685
+ attr_accessor :param
686
+ def before_create
687
+ self.param = true
672
688
  end
673
- instance = model.new label: "label1"
674
- instance.set(label: "label2")
675
- instance.label.should == "label2!"
676
689
  end
690
+ instance = model.create
691
+ assert instance.param
692
+ end
677
693
 
678
- should "support after_initialize hooks" do
679
- model = Class.new(MockContent) do
680
- attr_accessor :param
681
- def after_initialize
682
- self.param = true
683
- end
694
+ it "support after create triggers" do
695
+ model = Class.new(MockContent) do
696
+ attr_accessor :param
697
+ def after_create
698
+ self.param = true
684
699
  end
685
- instance = model.new
686
- instance.param.should be_true
687
700
  end
701
+ instance = model.create
702
+ assert instance.param
703
+ end
688
704
 
689
- should "support before create triggers" do
690
- model = Class.new(MockContent) do
691
- attr_accessor :param
692
- def before_create
693
- self.param = true
694
- end
705
+ it "not insert instance & return nil if before_create throws :halt" do
706
+ model = Class.new(MockContent) do
707
+ attr_accessor :param
708
+ def before_create
709
+ throw :halt
695
710
  end
696
- instance = model.create
697
- instance.param.should be_true
698
711
  end
712
+ instance = model.create
713
+ instance.must_be_nil
714
+ @database.sqls.must_equal []
715
+ end
699
716
 
700
- should "support after create triggers" do
701
- model = Class.new(MockContent) do
702
- attr_accessor :param
703
- def after_create
704
- self.param = true
705
- end
717
+ it "call before save triggers on model create" do
718
+ model = Class.new(MockContent) do
719
+ attr_accessor :param
720
+ def before_save
721
+ self.param = true
706
722
  end
707
- instance = model.create
708
- instance.param.should be_true
709
723
  end
724
+ instance = model.create
725
+ assert instance.param
726
+ end
710
727
 
711
- should "not insert instance & return nil if before_create throws :halt" do
712
- model = Class.new(MockContent) do
713
- attr_accessor :param
714
- def before_create
715
- throw :halt
716
- end
728
+ it "call before save triggers on existing instances" do
729
+ @database.fetch = { id:1, label:"label", type_sid:"MockContent" }
730
+ model = Class.new(MockContent) do
731
+ attr_accessor :param
732
+ def before_save
733
+ self.param = true
717
734
  end
718
- instance = model.create
719
- instance.should be_nil
720
- @database.sqls.should == []
721
735
  end
736
+ instance = model.create
737
+ assert instance.param
738
+ instance.set label: "hello"
739
+ instance.param = false
740
+ instance.save
741
+ assert instance.param
742
+ end
722
743
 
723
- should "call before save triggers on model create" do
724
- model = Class.new(MockContent) do
725
- attr_accessor :param
726
- def before_save
727
- self.param = true
728
- end
744
+ it "call after save triggers after create" do
745
+ model = Class.new(MockContent) do
746
+ attr_accessor :param
747
+ def after_save
748
+ self.param = true
729
749
  end
730
- instance = model.create
731
- instance.param.should be_true
732
750
  end
751
+ instance = model.create
752
+ assert instance.param
753
+ end
733
754
 
734
- should "call before save triggers on existing instances" do
735
- @database.fetch = { id:1, label:"label", type_sid:"DataMapperTest::MockContent" }
736
- model = Class.new(MockContent) do
737
- attr_accessor :param
738
- def before_save
739
- self.param = true
740
- end
755
+ it "call after save triggers on existing instances" do
756
+ @database.fetch = { id:1, label:"label", type_sid:"MockContent" }
757
+ model = Class.new(MockContent) do
758
+ attr_accessor :param
759
+ def after_save
760
+ self.param = true
741
761
  end
742
- instance = model.create
743
- instance.param.should be_true
744
- instance.set label: "hello"
745
- instance.param = false
746
- instance.save
747
- instance.param.should be_true
748
762
  end
763
+ instance = model.create
764
+ assert instance.param
765
+ instance.set label: "hello"
766
+ instance.param = false
767
+ instance.save
768
+ assert instance.param
769
+ end
749
770
 
750
- should "call after save triggers after create" do
751
- model = Class.new(MockContent) do
752
- attr_accessor :param
753
- def after_save
754
- self.param = true
755
- end
771
+ it "support before_update triggers" do
772
+ @database.fetch = { id:1, label:"label", type_sid:"MockContent" }
773
+ model = Class.new(MockContent) do
774
+ attr_accessor :param
775
+ def before_update
776
+ self.param = true
756
777
  end
757
- instance = model.create
758
- instance.param.should be_true
759
778
  end
779
+ instance = model.create
780
+ instance.param.must_be_nil
781
+ instance.set label: "hello"
782
+ instance.save
783
+ assert instance.param
784
+ end
760
785
 
761
- should "call after save triggers on existing instances" do
762
- @database.fetch = { id:1, label:"label", type_sid:"DataMapperTest::MockContent" }
763
- model = Class.new(MockContent) do
764
- attr_accessor :param
765
- def after_save
766
- self.param = true
767
- end
786
+ it "fail to save instance if before_update throws halt" do
787
+ @database.fetch = { id:1, label:"label", type_sid:"MockContent" }
788
+ model = Class.new(MockContent) do
789
+ attr_accessor :param
790
+ def before_update
791
+ throw :halt
768
792
  end
769
- instance = model.create
770
- instance.param.should be_true
771
- instance.set label: "hello"
772
- instance.param = false
773
- instance.save
774
- instance.param.should be_true
775
793
  end
794
+ instance = model.create
795
+ @database.sqls
796
+ instance.set label: "hello"
797
+ result = instance.save
798
+ result.must_be_nil
799
+ @database.sqls.must_equal []
800
+ end
776
801
 
777
- should "support before_update triggers" do
778
- @database.fetch = { id:1, label:"label", type_sid:"DataMapperTest::MockContent" }
779
- model = Class.new(MockContent) do
780
- attr_accessor :param
781
- def before_update
782
- self.param = true
783
- end
802
+ it "support after update triggers" do
803
+ @database.fetch = { id:1, label:"label", type_sid:"MockContent" }
804
+ model = Class.new(MockContent) do
805
+ attr_accessor :param
806
+ def after_update
807
+ self.param = true
784
808
  end
785
- instance = model.create
786
- instance.param.should be_nil
787
- instance.set label: "hello"
788
- instance.save
789
- instance.param.should be_true
790
809
  end
810
+ instance = model.create
811
+ instance.param.must_be_nil
812
+ instance.set label: "hello"
813
+ instance.save
814
+ assert instance.param
815
+ end
791
816
 
792
- should "fail to save instance if before_update throws halt" do
793
- @database.fetch = { id:1, label:"label", type_sid:"DataMapperTest::MockContent" }
794
- model = Class.new(MockContent) do
795
- attr_accessor :param
796
- def before_update
797
- throw :halt
798
- end
817
+ it "support before destroy triggers" do
818
+ @database.fetch = { id:1, label:"label", type_sid:"MockContent" }
819
+ model = Class.new(MockContent) do
820
+ attr_accessor :param
821
+ def before_destroy
822
+ self.param = true
799
823
  end
800
- instance = model.create
801
- @database.sqls
802
- instance.set label: "hello"
803
- result = instance.save
804
- result.should be_nil
805
- @database.sqls.should == []
806
824
  end
825
+ instance = model.create
826
+ @database.sqls
827
+ instance.destroy
828
+ assert instance.param
829
+ @database.sqls.must_equal [
830
+ "DELETE FROM content WHERE (id = 1)"
831
+ ]
832
+ end
807
833
 
808
- should "support after update triggers" do
809
- @database.fetch = { id:1, label:"label", type_sid:"DataMapperTest::MockContent" }
810
- model = Class.new(MockContent) do
811
- attr_accessor :param
812
- def after_update
813
- self.param = true
814
- end
834
+ it "not delete an instance if before_destroy throws halt" do
835
+ @database.fetch = { id:1, label:"label", type_sid:"MockContent" }
836
+ model = Class.new(MockContent) do
837
+ attr_accessor :param
838
+ def before_destroy
839
+ throw :halt
815
840
  end
816
- instance = model.create
817
- instance.param.should be_nil
818
- instance.set label: "hello"
819
- instance.save
820
- instance.param.should be_true
821
841
  end
842
+ instance = model.create
843
+ @database.sqls
844
+ result = instance.destroy
845
+ @database.sqls.must_equal []
846
+ result.must_be_nil
847
+ end
822
848
 
823
- should "support before destroy triggers" do
824
- @database.fetch = { id:1, label:"label", type_sid:"DataMapperTest::MockContent" }
825
- model = Class.new(MockContent) do
826
- attr_accessor :param
827
- def before_destroy
828
- self.param = true
829
- end
849
+ it "support after destroy triggers" do
850
+ @database.fetch = { id:1, label:"label", type_sid:"MockContent" }
851
+ model = Class.new(MockContent) do
852
+ attr_accessor :param
853
+ def after_destroy
854
+ self.param = true
830
855
  end
831
- instance = model.create
832
- @database.sqls
833
- instance.destroy
834
- instance.param.should be_true
835
- @database.sqls.should == [
836
- "DELETE FROM content WHERE (id = 1)"
837
- ]
838
856
  end
857
+ instance = model.create
858
+ instance.param.must_be_nil
859
+ instance.destroy
860
+ assert instance.param
861
+ end
839
862
 
840
- should "not delete an instance if before_destroy throws halt" do
841
- @database.fetch = { id:1, label:"label", type_sid:"DataMapperTest::MockContent" }
842
- model = Class.new(MockContent) do
843
- attr_accessor :param
844
- def before_destroy
845
- throw :halt
846
- end
863
+ it "not trigger before destroy hooks when calling #delete" do
864
+ @database.fetch = { id:1, label:"label", type_sid:"MockContent" }
865
+ model = Class.new(MockContent) do
866
+ attr_accessor :param
867
+ def before_destroy
868
+ throw :halt
847
869
  end
848
- instance = model.create
849
- @database.sqls
850
- result = instance.destroy
851
- @database.sqls.should == []
852
- result.should be_nil
853
870
  end
871
+ instance = model.create
872
+ @database.sqls
873
+ instance.delete
874
+ @database.sqls.must_equal ["DELETE FROM content WHERE (id = 1)"]
875
+ end
854
876
 
855
- should "support after destroy triggers" do
856
- @database.fetch = { id:1, label:"label", type_sid:"DataMapperTest::MockContent" }
857
- model = Class.new(MockContent) do
858
- attr_accessor :param
859
- def after_destroy
860
- self.param = true
861
- end
862
- end
863
- instance = model.create
864
- instance.param.should be_nil
865
- instance.destroy
866
- instance.param.should be_true
877
+ it "serialize column to JSON" do
878
+ row = { id: 1, type_sid:"MockContent" }
879
+ object = {name:"value"}
880
+ serialized = Spontaneous::JSON.encode(object)
881
+ MockContent.serialized_columns.each do |column|
882
+ @database.fetch = row
883
+ instance = MockContent.create({column => object})
884
+ @database.sqls.first.must_equal "INSERT INTO content (#{column}, type_sid) VALUES ('#{serialized}', 'MockContent')"
867
885
  end
886
+ end
868
887
 
869
- should "not trigger before destroy hooks when calling #delete" do
870
- @database.fetch = { id:1, label:"label", type_sid:"DataMapperTest::MockContent" }
871
- model = Class.new(MockContent) do
872
- attr_accessor :param
873
- def before_destroy
874
- throw :halt
875
- end
876
- end
877
- instance = model.create
888
+ it "deserialize objects stored in the db" do
889
+ row = { id: 1, type_sid:"MockContent" }
890
+ object = {name:"value"}
891
+ serialized = Spontaneous::JSON.encode(object)
892
+ MockContent.serialized_columns.each do |column|
893
+ @database.fetch = row.merge(column => serialized)
894
+ instance = MockContent.first
895
+ instance.send(column).must_equal object
896
+ end
897
+ end
898
+ it "save updates to serialized columns" do
899
+ row = { id: 1, type_sid:"MockContent" }
900
+ object = {name:"value"}
901
+ serialized = Spontaneous::JSON.encode(object)
902
+ MockContent.serialized_columns.each do |column|
903
+ @database.fetch = row.merge(column => serialized)
904
+ instance = MockContent.first
878
905
  @database.sqls
879
- instance.delete
880
- @database.sqls.should == ["DELETE FROM content WHERE (id = 1)"]
906
+ instance.send(column).must_equal object
907
+ changed = {name:"it's different", value:[99, 100]}
908
+ instance.send "#{column}=", changed
909
+ instance.send(column).must_equal changed
910
+ instance.save
911
+ @database.sqls.first.must_equal "UPDATE content " +
912
+ "SET #{column} = '{\"name\":\"it''s different\",\"value\":[99,100]}' " +
913
+ "WHERE (id = 1)"
881
914
  end
915
+ end
882
916
 
883
- should "serialize column to JSON" do
884
- row = { id: 1, type_sid:"DataMapperTest::MockContent" }
885
- object = {name:"value"}
886
- serialized = Spontaneous::JSON.encode(object)
887
- MockContent.serialized_columns.each do |column|
888
- @database.fetch = row
889
- instance = MockContent.create({column => object})
890
- @database.sqls.first.should == "INSERT INTO content (#{column}, type_sid) VALUES ('#{serialized}', 'DataMapperTest::MockContent')"
891
- end
917
+ describe "timestamps" do
918
+ before do
919
+ @time = @table.dataset.send :format_timestamp, @now
920
+ @database.columns = @expected_columns + [:created_at, :modified_at]
921
+ TimestampedContent = Spontaneous::DataMapper::Model(:content, @database, @schema)
922
+ @database.sqls
892
923
  end
893
924
 
894
- should "deserialize objects stored in the db" do
895
- row = { id: 1, type_sid:"DataMapperTest::MockContent" }
896
- object = {name:"value"}
897
- serialized = Spontaneous::JSON.encode(object)
898
- MockContent.serialized_columns.each do |column|
899
- @database.fetch = row.merge(column => serialized)
900
- instance = MockContent.first
901
- instance.send(column).should == object
902
- end
925
+ after do
926
+ DataMapperTest.send :remove_const, :TimestampedContent rescue nil
903
927
  end
904
- should "save updates to serialized columns" do
905
- row = { id: 1, type_sid:"DataMapperTest::MockContent" }
906
- object = {name:"value"}
907
- serialized = Spontaneous::JSON.encode(object)
908
- MockContent.serialized_columns.each do |column|
909
- @database.fetch = row.merge(column => serialized)
910
- instance = MockContent.first
911
- @database.sqls
912
- instance.send(column).should == object
913
- changed = {name:"it's different", value:[99, 100]}
914
- instance.send "#{column}=", changed
915
- instance.send(column).should == changed
916
- instance.save
917
- @database.sqls.first.should == "UPDATE content " +
918
- "SET #{column} = '{\"name\":\"it''s different\",\"value\":[99,100]}' " +
919
- "WHERE (id = 1)"
920
- end
928
+
929
+ it "set created_at timestamp on creation" do
930
+ instance = TimestampedContent.create label: "something"
931
+ @database.sqls.first.must_equal "INSERT INTO content (label, created_at, type_sid) VALUES ('something', #{@time}, 'TimestampedContent')"
921
932
  end
922
933
 
923
- context "timestamps" do
924
- setup do
925
- @time = @table.dataset.send :format_timestamp, @now
926
- @database.columns = @expected_columns + [:created_at, :modified_at]
927
- TimestampedContent = Spontaneous::DataMapper::Model(:content, @database, @schema)
928
- @database.sqls
929
- end
934
+ # it "update the modified_at value on update" do
935
+ # @database.fetch = { id: 1, type_sid:"TimestampedContent" }
936
+ # instance = TimestampedContent.create label: "something"
937
+ # @database.sqls
938
+ # instance.set label: "changed"
939
+ # instance.save
940
+ # @database.sqls.first.must_equal "UPDATE content SET label = 'changed', modified_at = #{@time} WHERE (id = 1)"
941
+ # end
942
+ end
930
943
 
931
- teardown do
932
- DataMapperTest.send :remove_const, :TimestampedContent rescue nil
933
- end
944
+ describe "schema" do
945
+ before do
946
+ class A1 < MockContent; end
947
+ class A2 < MockContent; end
948
+ class B1 < A1; end
949
+ class B2 < A2; end
950
+ class C1 < B1; end
951
+ end
934
952
 
935
- should "set created_at timestamp on creation" do
936
- instance = TimestampedContent.create label: "something"
937
- @database.sqls.first.should == "INSERT INTO content (label, created_at, type_sid) VALUES ('something', #{@time}, 'DataMapperTest::TimestampedContent')"
953
+ after do
954
+ %w(A1 A2 B1 B2 C1).each do |klass|
955
+ DataMapperTest.send :remove_const, klass rescue nil
938
956
  end
957
+ end
939
958
 
940
- # should "update the modified_at value on update" do
941
- # @database.fetch = { id: 1, type_sid:"DataMapperTest::TimestampedContent" }
942
- # instance = TimestampedContent.create label: "something"
943
- # @database.sqls
944
- # instance.set label: "changed"
945
- # instance.save
946
- # @database.sqls.first.should == "UPDATE content SET label = 'changed', modified_at = #{@time} WHERE (id = 1)"
947
- # end
959
+ it "track subclasses" do
960
+ MockContent2.subclasses.must_equal []
961
+ Set.new(A1.subclasses).must_equal Set.new([B1, C1])
962
+ A2.subclasses.must_equal [B2]
963
+ C1.subclasses.must_equal []
964
+ Set.new(MockContent.subclasses).must_equal Set.new([MockContent2, A1, A2, B1, B2, C1])
948
965
  end
966
+ end
967
+ end
949
968
 
950
- context "schema" do
951
- setup do
952
- class A1 < MockContent; end
953
- class A2 < MockContent; end
954
- class B1 < A1; end
955
- class B2 < A2; end
956
- class C1 < B1; end
957
- end
969
+ it "allow for the creation of instance after save hooks" do
970
+ @database.fetch = { id: 1, type_sid:"MockContent" }
971
+ instance = MockContent.create label: "something"
972
+ test = false
973
+ instance.after_save_hook do
974
+ test = true
975
+ end
976
+ instance.save
977
+ test.must_equal true
978
+ end
958
979
 
959
- teardown do
960
- %w(A1 A2 B1 B2 C1).each do |klass|
961
- DataMapperTest.send :remove_const, klass rescue nil
962
- end
963
- end
980
+ it "let you count available instances" do
981
+ result = MockContent.count
982
+ @database.sqls.must_equal [
983
+ "SELECT COUNT(*) AS count FROM content WHERE (type_sid IN ('MockContent')) LIMIT 1"
984
+ ]
985
+ end
964
986
 
965
- should "track subclasses" do
966
- MockContent2.subclasses.should == []
967
- Set.new(A1.subclasses).should == Set.new([B1, C1])
968
- A2.subclasses.should == [B2]
969
- C1.subclasses.should == []
970
- Set.new(MockContent.subclasses).should == Set.new([MockContent2, A1, A2, B1, B2, C1])
971
- end
972
- end
987
+ describe "has_many associations" do
988
+ before do
989
+ @database.columns = @expected_columns + [:parent_id, :source_id]
990
+ AssocContent = Spontaneous::DataMapper::Model(:content, @database, @schema)
991
+ AssocContent.has_many_content :children, key: :parent_id#, model: AssocContent
992
+ @database.fetch = { id: 7, type_sid:"AssocContent" }
993
+ @parent = AssocContent.first
994
+ @database.sqls
973
995
  end
974
996
 
975
- should "allow for the creation of instance after save hooks" do
976
- @database.fetch = { id: 1, type_sid:"DataMapperTest::MockContent" }
977
- instance = MockContent.create label: "something"
978
- test = false
979
- instance.after_save_hook do
980
- test = true
981
- end
982
- instance.save
983
- test.should == true
997
+ after do
998
+ Object.send :remove_const, :AssocContent rescue nil
999
+ end
1000
+
1001
+ it "use the correct dataset" do
1002
+ @database.fetch = { id: 7, type_sid:"AssocContent" }
1003
+ parent = AssocContent.first
1004
+ @database.sqls
1005
+ @database.fetch = [
1006
+ { id: 8, type_sid:"MockContent" },
1007
+ { id: 9, type_sid:"AssocContent" }
1008
+ ]
1009
+ children = parent.children
1010
+ @database.sqls.must_equal [
1011
+ "SELECT * FROM content WHERE (content.parent_id = 7)"
1012
+ ]
1013
+ children.map(&:id).must_equal [8, 9]
1014
+ children.map(&:class).must_equal [MockContent, AssocContent]
984
1015
  end
985
1016
 
986
- should "let you count available instances" do
987
- result = MockContent.count
988
- @database.sqls.should == [
989
- "SELECT COUNT(*) AS count FROM content WHERE (type_sid IN ('DataMapperTest::MockContent')) LIMIT 1"
1017
+ it "cache the result" do
1018
+ children = @parent.children
1019
+ @database.sqls.must_equal [
1020
+ "SELECT * FROM content WHERE (content.parent_id = 7)"
990
1021
  ]
1022
+ children = @parent.children
1023
+ @database.sqls.must_equal [ ]
991
1024
  end
992
1025
 
993
- context "has_many associations" do
994
- setup do
995
- @database.columns = @expected_columns + [:parent_id, :source_id]
996
- AssocContent = Spontaneous::DataMapper::Model(:content, @database, @schema)
997
- AssocContent.has_many :children, key: :parent_id, model: AssocContent
998
- @database.fetch = { id: 7, type_sid:"DataMapperTest::AssocContent" }
999
- @parent = AssocContent.first
1000
- @database.sqls
1001
- end
1026
+ it "reload the result if forced" do
1027
+ children = @parent.children
1028
+ @database.sqls.must_equal [
1029
+ "SELECT * FROM content WHERE (content.parent_id = 7)"
1030
+ ]
1031
+ children = @parent.children(reload: true)
1032
+ @database.sqls.must_equal [
1033
+ "SELECT * FROM content WHERE (content.parent_id = 7)"
1034
+ ]
1035
+ end
1002
1036
 
1003
- teardown do
1004
- DataMapperTest.send :remove_const, :AssocContent rescue nil
1005
- end
1037
+ it "allow access to the relation dataset" do
1038
+ ds = @parent.children_dataset
1039
+ ds.filter { id > 3}.all
1040
+ @database.sqls.must_equal [
1041
+ "SELECT * FROM content WHERE ((content.parent_id = 7) AND (id > 3))"
1042
+ ]
1043
+ end
1006
1044
 
1007
- should "use the correct dataset" do
1008
- @database.fetch = { id: 7, type_sid:"DataMapperTest::AssocContent" }
1045
+ it "return correctly typed results" do
1046
+ @database.fetch = [
1047
+ { id: 8, type_sid:"MockContent" },
1048
+ { id: 9, type_sid:"AssocContent" }
1049
+ ]
1050
+ children = @parent.children
1051
+ children.map(&:id).must_equal [8, 9]
1052
+ children.map(&:class).must_equal [MockContent, AssocContent]
1053
+ end
1054
+
1055
+ it "correctly set the relation key when adding members" do
1056
+ instance = AssocContent.new
1057
+ @database.sqls
1058
+ @parent.add_child(instance)
1059
+ @database.sqls.first.must_equal \
1060
+ "INSERT INTO content (parent_id, type_sid) VALUES (7, 'AssocContent')"
1061
+ end
1062
+
1063
+ it "use versioned dataset" do
1064
+ parent = nil
1065
+ @mapper.revision(99) do
1066
+ @database.fetch = { id: 7, type_sid:"AssocContent" }
1009
1067
  parent = AssocContent.first
1010
1068
  @database.sqls
1011
- @database.fetch = [
1012
- { id: 8, type_sid:"DataMapperTest::MockContent" },
1013
- { id: 9, type_sid:"DataMapperTest::AssocContent" }
1014
- ]
1015
1069
  children = parent.children
1016
- @database.sqls.should == [
1017
- "SELECT * FROM content WHERE (content.parent_id = 7)"
1018
- ]
1019
- children.map(&:id).should == [8, 9]
1020
- children.map(&:class).should == [MockContent, AssocContent]
1021
1070
  end
1071
+ @database.sqls.must_equal [
1072
+ "SELECT * FROM __r00099_content WHERE (__r00099_content.parent_id = 7)"
1073
+ ]
1074
+ end
1022
1075
 
1023
- should "cache the result" do
1024
- children = @parent.children
1025
- @database.sqls.should == [
1026
- "SELECT * FROM content WHERE (content.parent_id = 7)"
1027
- ]
1028
- children = @parent.children
1029
- @database.sqls.should == [ ]
1076
+ it "use global dataset version" do
1077
+ parent = nil
1078
+ @mapper.revision(99) do
1079
+ @database.fetch = { id: 7, type_sid:"AssocContent" }
1080
+ parent = AssocContent.first
1081
+ @database.sqls
1082
+ @mapper.revision(11) do
1083
+ children = parent.children
1084
+ end
1030
1085
  end
1086
+ @database.sqls.must_equal [
1087
+ "SELECT * FROM __r00011_content WHERE (__r00011_content.parent_id = 7)"
1088
+ ]
1089
+ end
1031
1090
 
1032
- should "reload the result if forced" do
1033
- children = @parent.children
1034
- @database.sqls.should == [
1035
- "SELECT * FROM content WHERE (content.parent_id = 7)"
1036
- ]
1037
- children = @parent.children(reload: true)
1038
- @database.sqls.should == [
1039
- "SELECT * FROM content WHERE (content.parent_id = 7)"
1040
- ]
1041
- end
1091
+ it "destroy dependents if configured" do
1092
+ AssocContent.has_many_content :destinations, key: :source_id, dependent: :destroy
1093
+ @database.fetch = [
1094
+ [{ id: 8, type_sid:"AssocContent", source_id:7 }],
1095
+ [{ id: 9, type_sid:"AssocContent", source_id:7 }]
1096
+ ]
1097
+ @parent.destroy
1098
+ @database.sqls.must_equal [
1099
+ "SELECT * FROM content WHERE (content.source_id = 7)",
1100
+ "SELECT * FROM content WHERE (content.source_id = 8)",
1101
+ "SELECT * FROM content WHERE (content.source_id = 9)",
1102
+ "DELETE FROM content WHERE (id = 9)",
1103
+ "DELETE FROM content WHERE (id = 8)",
1104
+ "DELETE FROM content WHERE (id = 7)"
1105
+ ]
1106
+ end
1042
1107
 
1043
- should "allow access to the relation dataset" do
1044
- ds = @parent.children_dataset
1045
- ds.filter { id > 3}.all
1046
- @database.sqls.should == [
1047
- "SELECT * FROM content WHERE ((content.parent_id = 7) AND (id > 3))"
1048
- ]
1049
- end
1108
+ it "delete dependents if configured" do
1109
+ AssocContent.has_many_content :destinations, key: :source_id, dependent: :delete
1110
+ @database.fetch = [
1111
+ [{ id: 8, type_sid:"AssocContent", source_id:7 }],
1112
+ [{ id: 9, type_sid:"AssocContent", source_id:7 }]
1113
+ ]
1114
+ @parent.destroy
1115
+ @database.sqls.must_equal [
1116
+ "DELETE FROM content WHERE (content.source_id = 7)",
1117
+ "DELETE FROM content WHERE (id = 7)"
1118
+ ]
1119
+ end
1050
1120
 
1051
- should "return correctly typed results" do
1052
- @database.fetch = [
1053
- { id: 8, type_sid:"DataMapperTest::MockContent" },
1054
- { id: 9, type_sid:"DataMapperTest::AssocContent" }
1055
- ]
1056
- children = @parent.children
1057
- children.map(&:id).should == [8, 9]
1058
- children.map(&:class).should == [MockContent, AssocContent]
1121
+ describe "sequel models" do
1122
+ before do
1123
+ ::Other = Class.new(Sequel::Model(:other)) do ; end
1124
+ Other.db = @database
1125
+ AssocContent.one_to_many :others, key: :user_id
1126
+ @database.fetch = { id: 7, type_sid:"AssocContent", parent_id: nil }
1127
+ @instance = AssocContent.first
1128
+ @database.sqls
1059
1129
  end
1060
1130
 
1061
- should "correctly set the relation key when adding members" do
1062
- instance = AssocContent.new
1063
- @database.sqls
1064
- @parent.add_child(instance)
1065
- @database.sqls.first.should == \
1066
- "INSERT INTO content (parent_id, type_sid) VALUES (7, 'DataMapperTest::AssocContent')"
1131
+ after do
1132
+ Object.send :remove_const, :Other rescue nil
1067
1133
  end
1068
1134
 
1069
- should "use versioned dataset" do
1070
- parent = nil
1071
- @mapper.revision(99) do
1072
- @database.fetch = { id: 7, type_sid:"DataMapperTest::AssocContent" }
1073
- parent = AssocContent.first
1074
- @database.sqls
1075
- children = parent.children
1076
- end
1077
- @database.sqls.should == [
1078
- "SELECT * FROM __r00099_content WHERE (__r00099_content.parent_id = 7)"
1135
+ it "can load association members" do
1136
+ @instance.others
1137
+ @database.sqls.must_equal [
1138
+ "SELECT * FROM other WHERE (other.user_id = 7)"
1079
1139
  ]
1080
1140
  end
1081
1141
 
1082
- should "use global dataset version" do
1083
- parent = nil
1084
- @mapper.revision(99) do
1085
- @database.fetch = { id: 7, type_sid:"DataMapperTest::AssocContent" }
1086
- parent = AssocContent.first
1087
- @database.sqls
1088
- @mapper.revision(11) do
1089
- children = parent.children
1090
- end
1091
- end
1092
- @database.sqls.should == [
1093
- "SELECT * FROM __r00011_content WHERE (__r00011_content.parent_id = 7)"
1094
- ]
1142
+ it "can add new association members" do
1143
+ other = Other.new
1144
+ other.expects(:user_id=).with(7)
1145
+ @instance.add_other other
1095
1146
  end
1096
1147
 
1097
- should "destroy dependents if configured" do
1098
- AssocContent.has_many :destinations, key: :source_id, model: AssocContent, dependent: :destroy
1099
- @database.fetch = [
1100
- [{ id: 8, type_sid:"DataMapperTest::AssocContent", source_id:7 }],
1101
- [{ id: 9, type_sid:"DataMapperTest::AssocContent", source_id:7 }]
1102
- ]
1103
- @parent.destroy
1104
- @database.sqls.should == [
1105
- "SELECT * FROM content WHERE (content.source_id = 7)",
1106
- "SELECT * FROM content WHERE (content.source_id = 8)",
1107
- "SELECT * FROM content WHERE (content.source_id = 9)",
1108
- "DELETE FROM content WHERE (id = 9)",
1109
- "DELETE FROM content WHERE (id = 8)",
1110
- "DELETE FROM content WHERE (id = 7)"
1111
- ]
1148
+ it "can remove association members" do
1149
+ other = Other.new
1150
+ other.expects(:user_id=).with(nil)
1151
+ @instance.remove_other other
1112
1152
  end
1113
1153
 
1114
- should "delete dependents if configured" do
1115
- AssocContent.has_many :destinations, key: :source_id, model: AssocContent, dependent: :delete
1116
- @database.fetch = [
1117
- [{ id: 8, type_sid:"DataMapperTest::AssocContent", source_id:7 }],
1118
- [{ id: 9, type_sid:"DataMapperTest::AssocContent", source_id:7 }]
1119
- ]
1120
- @parent.destroy
1121
- @database.sqls.should == [
1122
- "DELETE FROM content WHERE (content.source_id = 7)",
1123
- "DELETE FROM content WHERE (id = 7)"
1154
+ it "can remove all members" do
1155
+ @instance.remove_all_others
1156
+ @database.sqls.must_equal [
1157
+ "UPDATE other SET user_id = NULL WHERE (user_id = 7)"
1124
1158
  ]
1125
1159
  end
1126
1160
 
1127
- should "work with non-mapped models" do
1128
- model = Class.new(Sequel::Model(:other)) do ; end
1129
- model.db = @database
1130
- AssocContent.has_many :others, model: model, key: :user_id
1131
- @database.fetch = { id: 7, type_sid:"DataMapperTest::AssocContent", parent_id: nil }
1132
- instance = AssocContent.first
1133
- @database.sqls
1134
- instance.others
1135
- @database.sqls.should == [
1136
- "SELECT * FROM other WHERE (user_id = 7)"
1137
- ]
1161
+ it "can access the association dataset" do
1162
+ @instance.others_dataset.sql.must_equal "SELECT * FROM other WHERE (other.user_id = 7)"
1138
1163
  end
1139
1164
  end
1165
+ end
1140
1166
 
1141
- context "belongs_to associations" do
1142
- setup do
1143
- @database.columns = @expected_columns + [:parent_id]
1144
- AssocContent = Spontaneous::DataMapper::Model(:content, @database, @schema)
1145
- AssocContent.has_many :children, key: :parent_id, model: AssocContent, reciprocal: :parent
1146
- AssocContent.belongs_to :parent, key: :parent_id, model: AssocContent, reciprocal: :children
1147
- @database.fetch = { id: 8, type_sid:"DataMapperTest::AssocContent", parent_id: 7 }
1167
+ describe "belongs_to associations" do
1168
+ before do
1169
+ @database.columns = @expected_columns + [:parent_id]
1170
+ AssocContent = Spontaneous::DataMapper::Model(:content, @database, @schema)
1171
+ AssocContent.has_many_content :children, key: :parent_id, reciprocal: :parent
1172
+ AssocContent.belongs_to_content :parent, key: :parent_id, reciprocal: :children
1173
+ @database.fetch = { id: 8, type_sid:"AssocContent", parent_id: 7 }
1148
1174
 
1149
- @child = AssocContent.first
1150
- @database.sqls
1151
- end
1175
+ @child = AssocContent.first
1176
+ @database.sqls
1177
+ end
1178
+
1179
+ after do
1180
+ Object.send :remove_const, :AssocContent rescue nil
1181
+ end
1182
+
1183
+ it "load the owner" do
1184
+ @database.fetch = { id: 7, type_sid:"AssocContent", parent_id: nil }
1185
+ parent = @child.parent
1186
+ @database.sqls.must_equal ["SELECT * FROM content WHERE (id = 7) LIMIT 1"]
1187
+ parent.must_be_instance_of AssocContent
1188
+ parent.id.must_equal 7
1189
+ end
1190
+
1191
+ it "cache the result" do
1192
+ parent = @child.parent
1193
+ @database.sqls.must_equal ["SELECT * FROM content WHERE (id = 7) LIMIT 1"]
1194
+ parent = @child.parent
1195
+ @database.sqls.must_equal [ ]
1196
+ end
1197
+
1198
+ it "reload the result if asked" do
1199
+ parent = @child.parent
1200
+ @database.sqls.must_equal ["SELECT * FROM content WHERE (id = 7) LIMIT 1"]
1201
+ parent = @child.parent(reload: true)
1202
+ @database.sqls.must_equal ["SELECT * FROM content WHERE (id = 7) LIMIT 1"]
1203
+ end
1204
+
1205
+ it "allow access to the relation dataset" do
1206
+ results = @child.parent_dataset.filter { id > 3 }.first
1207
+ @database.sqls.must_equal ["SELECT * FROM content WHERE ((content.id = 7) AND (id > 3)) LIMIT 1"]
1208
+ end
1152
1209
 
1153
- teardown do
1154
- DataMapperTest.send :remove_const, :AssocContent rescue nil
1210
+ it "allow setting of owner for instance" do
1211
+ instance = AssocContent.new
1212
+ @database.sqls
1213
+ instance.parent = @child
1214
+ instance.parent_id.must_equal 8
1215
+ instance.save
1216
+ @database.sqls.first.must_equal \
1217
+ "INSERT INTO content (parent_id, type_sid) VALUES (8, 'AssocContent')"
1218
+ end
1219
+
1220
+ it "set the reciprocal relation" do
1221
+ @database.fetch = { id: 7, type_sid:"AssocContent" }
1222
+ parent = AssocContent.first
1223
+ @database.sqls
1224
+ @database.fetch = [
1225
+ { id: 8, type_sid:"AssocContent", parent_id: 7 },
1226
+ { id: 9, type_sid:"AssocContent", parent_id: 7 }
1227
+ ]
1228
+ children = parent.children
1229
+ children.map { |c| c.parent.object_id }.uniq.must_equal [parent.object_id]
1230
+ @database.sqls.must_equal [
1231
+ "SELECT * FROM content WHERE (content.parent_id = 7)"
1232
+ ]
1233
+ end
1234
+
1235
+ describe "sequel models" do
1236
+ before do
1237
+ ::Other = Class.new(Sequel::Model(:other)) do ; end
1238
+ Other.db = @database
1239
+ AssocContent.many_to_one :other, class: Other, key: :parent_id
1240
+ @database.fetch = { id: 7, type_sid:"AssocContent", parent_id: 34 }
1241
+ @instance = AssocContent.first
1242
+ @database.sqls
1243
+ Other.any_instance.stubs(:parent_id).returns(7)
1244
+ @other = Other.new
1245
+ @other.stubs(:id).returns(34)
1246
+ @other.stubs(:pk).returns(34)
1155
1247
  end
1156
1248
 
1157
- should "load the owner" do
1158
- @database.fetch = { id: 7, type_sid:"DataMapperTest::AssocContent", parent_id: nil }
1159
- parent = @child.parent
1160
- @database.sqls.should == ["SELECT * FROM content WHERE (id = 7) LIMIT 1"]
1161
- parent.must_be_instance_of AssocContent
1162
- parent.id.should == 7
1249
+ after do
1250
+ Object.send :remove_const, :Other rescue nil
1163
1251
  end
1164
1252
 
1165
- should "cache the result" do
1166
- parent = @child.parent
1167
- @database.sqls.should == ["SELECT * FROM content WHERE (id = 7) LIMIT 1"]
1168
- parent = @child.parent
1169
- @database.sqls.should == [ ]
1253
+ it "can load association members" do
1254
+ @instance.other
1255
+ @database.sqls.must_equal [
1256
+ "SELECT * FROM other WHERE (other.id = 34) LIMIT 1"
1257
+ ]
1170
1258
  end
1171
1259
 
1172
- should "reload the result if asked" do
1173
- parent = @child.parent
1174
- @database.sqls.should == ["SELECT * FROM content WHERE (id = 7) LIMIT 1"]
1175
- parent = @child.parent(reload: true)
1176
- @database.sqls.should == ["SELECT * FROM content WHERE (id = 7) LIMIT 1"]
1260
+ it "can add new association members" do
1261
+ @database.fetch = { id: 7, type_sid:"AssocContent", parent_id: nil }
1262
+ instance = AssocContent.first
1263
+ instance.other = @other
1264
+ instance.parent_id.must_equal 34
1177
1265
  end
1178
1266
 
1179
- should "allow access to the relation dataset" do
1180
- results = @child.parent_dataset.filter { id > 3 }.first
1181
- @database.sqls.should == ["SELECT * FROM content WHERE ((content.id = 7) AND (id > 3)) LIMIT 1"]
1267
+ it "can remove association members" do
1268
+ @instance.other = nil
1269
+ @instance.parent_id.must_be_nil
1182
1270
  end
1183
1271
 
1184
- should "allow setting of owner for instance" do
1185
- instance = AssocContent.new
1186
- @database.sqls
1187
- instance.parent = @child
1188
- instance.parent_id.should == 8
1189
- instance.save
1190
- @database.sqls.first.should == \
1191
- "INSERT INTO content (parent_id, type_sid) VALUES (8, 'DataMapperTest::AssocContent')"
1272
+ it "can access the association dataset" do
1273
+ @instance.other_dataset.sql.must_equal "SELECT * FROM other WHERE (other.id = 34) LIMIT 1"
1192
1274
  end
1193
1275
 
1194
- should "set the reciprocal relation" do
1195
- @database.fetch = { id: 7, type_sid:"DataMapperTest::AssocContent" }
1196
- parent = AssocContent.first
1276
+ it "reloads the association" do
1277
+ @instance.other
1278
+ @instance.reload
1197
1279
  @database.sqls
1198
- @database.fetch = [
1199
- { id: 8, type_sid:"DataMapperTest::AssocContent", parent_id: 7 },
1200
- { id: 9, type_sid:"DataMapperTest::AssocContent", parent_id: 7 }
1201
- ]
1202
- children = parent.children
1203
- children.map { |c| c.parent.object_id }.uniq.should == [parent.object_id]
1204
- @database.sqls.should == [
1205
- "SELECT * FROM content WHERE (content.parent_id = 7)"
1280
+ @instance.other
1281
+ @database.sqls.must_equal [
1282
+ "SELECT * FROM other WHERE (other.id = 34) LIMIT 1"
1206
1283
  ]
1207
1284
  end
1208
1285
  end
1286
+ end
1287
+
1288
+ describe "one_to_one associations" do
1289
+ before do
1290
+ @database.columns = @expected_columns + [:parent_id]
1291
+ AssocContent = Spontaneous::DataMapper::Model(:content, @database, @schema)
1292
+ ::Other = Class.new(Sequel::Model(:other)) do ; end
1293
+ Other.db = @database
1294
+ AssocContent.one_to_one :other, class: Other, key: :parent_id
1295
+ @database.fetch = { id: 7, type_sid:"AssocContent", parent_id: 34 }
1296
+ @instance = AssocContent.first
1297
+ @database.sqls
1298
+ @other = Other.new
1299
+ @other.stubs(:id).returns(34)
1300
+ @other.stubs(:pk).returns(34)
1301
+ end
1209
1302
 
1210
- context "performance" do
1211
- should "use a cached version within revision blocks" do
1212
- @mapper.revision(20) do
1213
- assert @mapper.dataset.equal?(@mapper.dataset), "Dataset should be the same object"
1214
- end
1303
+ after do
1304
+ Object.send :remove_const, :Other rescue nil
1305
+ Object.send :remove_const, :AssocContent rescue nil
1306
+ end
1307
+
1308
+ it "can load association members" do
1309
+ @instance.other
1310
+ @database.sqls.must_equal [
1311
+ "SELECT * FROM other WHERE (other.parent_id = 7) LIMIT 1"
1312
+ ]
1313
+ end
1314
+
1315
+ it "can add new association members" do
1316
+ # @database.fetch = { id: 7, type_sid:"AssocContent", parent_id: nil }
1317
+ # instance = AssocContent.first
1318
+ @other.expects(:parent_id=).with(7)
1319
+ @instance.other = @other
1320
+ end
1321
+
1322
+ it "can remove the association target" do
1323
+ @instance.other = nil
1324
+ @database.sqls.must_equal [
1325
+ "BEGIN",
1326
+ "UPDATE other SET parent_id = NULL WHERE (parent_id = 7)",
1327
+ "COMMIT"
1328
+ ]
1329
+ end
1330
+
1331
+ it "can access the association dataset" do
1332
+ @instance.other_dataset.sql.must_equal "SELECT * FROM other WHERE (other.parent_id = 7) LIMIT 1"
1333
+ end
1334
+ end
1335
+
1336
+ describe "performance" do
1337
+ it "use a cached version within revision blocks" do
1338
+ @mapper.revision(20) do
1339
+ assert @mapper.dataset.equal?(@mapper.dataset), "Dataset it be the same object"
1215
1340
  end
1341
+ end
1216
1342
 
1217
- should "use an identity map within revision scopes" do
1218
- @database.fetch = [
1219
- { id: 7, type_sid:"DataMapperTest::MockContent", parent_id: 7 }
1220
- ]
1221
- @mapper.editable do
1222
- a = @mapper.first! :id => 7
1223
- b = @mapper.first! :id => 7
1224
- assert a.object_id == b.object_id, "a and b should be the same object"
1225
- end
1343
+ it "use an identity map within revision scopes" do
1344
+ @database.fetch = [
1345
+ { id: 7, type_sid:"MockContent", parent_id: 7 }
1346
+ ]
1347
+ @mapper.editable do
1348
+ a = @mapper.first! :id => 7
1349
+ b = @mapper.first! :id => 7
1350
+ assert a.object_id == b.object_id, "a and b it be the same object"
1226
1351
  end
1352
+ end
1227
1353
 
1228
- should "use an object cache for #get calls" do
1229
- @database.fetch = [
1230
- [{ id: 8, type_sid:"DataMapperTest::MockContent", parent_id: 7 }],
1231
- [{ id: 9, type_sid:"DataMapperTest::MockContent", parent_id: 7 }]
1232
- ]
1233
- @mapper.revision(20) do
1234
- a = @mapper.get(8)
1235
- b = @mapper.get(9)
1236
- @database.sqls
1237
- a = @mapper.get(8)
1238
- b = @mapper.get(9)
1239
- @database.sqls.should == []
1240
- end
1354
+ it "use an object cache for #get calls" do
1355
+ @database.fetch = [
1356
+ [{ id: 8, type_sid:"MockContent", parent_id: 7 }],
1357
+ [{ id: 9, type_sid:"MockContent", parent_id: 7 }]
1358
+ ]
1359
+ @mapper.revision(20) do
1360
+ a = @mapper.get(8)
1361
+ b = @mapper.get(9)
1362
+ @database.sqls
1363
+ a = @mapper.get(8)
1364
+ b = @mapper.get(9)
1365
+ @database.sqls.must_equal []
1241
1366
  end
1367
+ end
1242
1368
 
1243
- should "not create new scope if revisions are the same" do
1244
- a = b = nil
1369
+ it "not create new scope if revisions are the same" do
1370
+ a = b = nil
1371
+ @mapper.revision(20) do
1372
+ a = @mapper.dataset
1245
1373
  @mapper.revision(20) do
1246
- a = @mapper.dataset
1247
- @mapper.revision(20) do
1248
- b = @mapper.dataset
1249
- end
1374
+ b = @mapper.dataset
1250
1375
  end
1251
- assert a.object_id == b.object_id, "Mappers should be same object"
1252
1376
  end
1377
+ assert a.object_id == b.object_id, "Mappers it be same object"
1378
+ end
1253
1379
 
1254
- should "not create new scope if visibility are the same" do
1255
- a = b = nil
1256
- @mapper.scope(20, true) do
1257
- a = @mapper.dataset
1258
- @mapper.visible do
1259
- b = @mapper.dataset
1260
- end
1380
+ it "not create new scope if visibility are the same" do
1381
+ a = b = nil
1382
+ @mapper.scope(20, true) do
1383
+ a = @mapper.dataset
1384
+ @mapper.visible do
1385
+ b = @mapper.dataset
1261
1386
  end
1262
- assert a.object_id == b.object_id, "Mappers should be same object"
1263
1387
  end
1388
+ assert a.object_id == b.object_id, "Mappers it be same object"
1389
+ end
1264
1390
 
1265
- should "not create new scope if parameters are the same" do
1266
- a = b = nil
1391
+ it "not create new scope if parameters are the same" do
1392
+ a = b = nil
1393
+ @mapper.scope(20, true) do
1394
+ a = @mapper.dataset
1267
1395
  @mapper.scope(20, true) do
1268
- a = @mapper.dataset
1269
- @mapper.scope(20, true) do
1270
- b = @mapper.dataset
1271
- end
1396
+ b = @mapper.dataset
1272
1397
  end
1273
- assert a.object_id == b.object_id, "Mappers should be same object"
1274
1398
  end
1399
+ assert a.object_id == b.object_id, "Mappers it be same object"
1400
+ end
1275
1401
 
1276
- should "allow for using a custom cache key" do
1277
- @database.fetch = [
1278
- { id: 20, type_sid:"DataMapperTest::MockContent", parent_id: 7 }
1279
- ]
1280
- a = b = nil
1281
- @mapper.scope(20, false) do
1282
- a = @mapper.with_cache("key") { @mapper.filter(nil, label: "frog").first }
1283
- b = @mapper.with_cache("key") { @mapper.filter(nil, label: "frog").first }
1284
- end
1285
- @database.sqls.should == [
1286
- "SELECT * FROM __r00020_content WHERE (label = 'frog') LIMIT 1"
1287
- ]
1402
+ it "allow for using a custom cache key" do
1403
+ @database.fetch = [
1404
+ { id: 20, type_sid:"MockContent", parent_id: 7 }
1405
+ ]
1406
+ a = b = nil
1407
+ @mapper.scope(20, false) do
1408
+ a = @mapper.with_cache("key") { @mapper.filter(nil, label: "frog").first }
1409
+ b = @mapper.with_cache("key") { @mapper.filter(nil, label: "frog").first }
1288
1410
  end
1411
+ @database.sqls.must_equal [
1412
+ "SELECT * FROM __r00020_content WHERE (label = 'frog') LIMIT 1"
1413
+ ]
1414
+ end
1289
1415
 
1290
- should "allow for forcing the creation of a new scope to bypass the cache" do
1291
- @database.fetch = [
1292
- { id: 7, type_sid:"DataMapperTest::MockContent", parent_id: 7 }
1293
- ]
1294
- a = b = c = nil
1416
+ it "allow for forcing the creation of a new scope to bypass the cache" do
1417
+ @database.fetch = [
1418
+ { id: 7, type_sid:"MockContent", parent_id: 7 }
1419
+ ]
1420
+ a = b = c = nil
1295
1421
 
1422
+ @mapper.scope(nil, false) do
1423
+ a = @mapper.first! :id => 7
1296
1424
  @mapper.scope(nil, false) do
1297
- a = @mapper.first! :id => 7
1298
- @mapper.scope(nil, false) do
1299
- b = @mapper.first! :id => 7
1300
- @mapper.scope!(nil, false) do
1301
- c = @mapper.first! :id => 7
1302
- end
1425
+ b = @mapper.first! :id => 7
1426
+ @mapper.scope!(nil, false) do
1427
+ c = @mapper.first! :id => 7
1303
1428
  end
1304
1429
  end
1305
- assert a.object_id == b.object_id, "a and b should be the same object"
1306
- assert a.object_id != c.object_id
1307
1430
  end
1431
+ assert a.object_id == b.object_id, "a and b it be the same object"
1432
+ assert a.object_id != c.object_id
1433
+ end
1308
1434
 
1309
- should "update the instance cache with updated values after a reload" do
1310
- @database.fetch = [
1311
- [{ id: 7, type_sid:"DataMapperTest::MockContent", parent_id: 7, label: "a" }],
1312
- [{ id: 7, type_sid:"DataMapperTest::MockContent", parent_id: 7, label: "b" }],
1313
- [{ id: 7, type_sid:"DataMapperTest::MockContent", parent_id: 7, label: "b" }]
1314
- ]
1315
- a = b = c = nil
1316
- la = lb = lc = nil
1317
-
1318
- @mapper.scope(nil, false) do
1319
- a = @mapper.first! :id => 7
1320
- la = a.label
1321
- b = a.reload
1322
- lb = b.label
1323
- c = @mapper.get 7
1324
- lc = c.label
1325
- end
1326
- assert [la, lb, lc] == ["a", "b", "b"], "Incorrect labels #{[la, lb, lc].inspect}"
1327
- end
1435
+ it "update the instance cache with updated values after a reload" do
1436
+ @database.fetch = [
1437
+ [{ id: 7, type_sid:"MockContent", parent_id: 7, label: "a" }],
1438
+ [{ id: 7, type_sid:"MockContent", parent_id: 7, label: "b" }],
1439
+ [{ id: 7, type_sid:"MockContent", parent_id: 7, label: "b" }]
1440
+ ]
1441
+ a = b = c = nil
1442
+ la = lb = lc = nil
1443
+
1444
+ @mapper.scope(nil, false) do
1445
+ a = @mapper.first! :id => 7
1446
+ la = a.label
1447
+ b = a.reload
1448
+ lb = b.label
1449
+ c = @mapper.get 7
1450
+ lc = c.label
1451
+ end
1452
+ assert [la, lb, lc] == ["a", "b", "b"], "Incorrect labels #{[la, lb, lc].inspect}"
1328
1453
  end
1329
1454
  end
1330
1455
  end