mark_mapper 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.rdoc +39 -0
  4. data/examples/attr_accessible.rb +24 -0
  5. data/examples/attr_protected.rb +24 -0
  6. data/examples/cache_key.rb +26 -0
  7. data/examples/custom_types.rb +26 -0
  8. data/examples/identity_map.rb +30 -0
  9. data/examples/identity_map/automatic.rb +2 -0
  10. data/examples/keys.rb +42 -0
  11. data/examples/modifiers/set.rb +27 -0
  12. data/examples/plugins.rb +40 -0
  13. data/examples/querying.rb +39 -0
  14. data/examples/sample_app.rb +43 -0
  15. data/examples/scopes.rb +56 -0
  16. data/examples/validating/embedded_docs.rb +31 -0
  17. data/lib/mark_mapper.rb +125 -0
  18. data/lib/mark_mapper/config.rb +90 -0
  19. data/lib/mark_mapper/connection.rb +60 -0
  20. data/lib/mark_mapper/criteria_hash.rb +194 -0
  21. data/lib/mark_mapper/document.rb +46 -0
  22. data/lib/mark_mapper/embedded_document.rb +32 -0
  23. data/lib/mark_mapper/exceptions.rb +33 -0
  24. data/lib/mark_mapper/extensions/array.rb +27 -0
  25. data/lib/mark_mapper/extensions/boolean.rb +45 -0
  26. data/lib/mark_mapper/extensions/date.rb +29 -0
  27. data/lib/mark_mapper/extensions/duplicable.rb +86 -0
  28. data/lib/mark_mapper/extensions/float.rb +18 -0
  29. data/lib/mark_mapper/extensions/hash.rb +26 -0
  30. data/lib/mark_mapper/extensions/integer.rb +27 -0
  31. data/lib/mark_mapper/extensions/kernel.rb +11 -0
  32. data/lib/mark_mapper/extensions/nil_class.rb +18 -0
  33. data/lib/mark_mapper/extensions/object.rb +30 -0
  34. data/lib/mark_mapper/extensions/object_id.rb +18 -0
  35. data/lib/mark_mapper/extensions/set.rb +20 -0
  36. data/lib/mark_mapper/extensions/string.rb +31 -0
  37. data/lib/mark_mapper/extensions/symbol.rb +87 -0
  38. data/lib/mark_mapper/extensions/time.rb +29 -0
  39. data/lib/mark_mapper/locale/en.yml +5 -0
  40. data/lib/mark_mapper/middleware/identity_map.rb +41 -0
  41. data/lib/mark_mapper/normalizers/criteria_hash_key.rb +17 -0
  42. data/lib/mark_mapper/normalizers/criteria_hash_value.rb +66 -0
  43. data/lib/mark_mapper/normalizers/fields_value.rb +26 -0
  44. data/lib/mark_mapper/normalizers/hash_key.rb +19 -0
  45. data/lib/mark_mapper/normalizers/integer.rb +19 -0
  46. data/lib/mark_mapper/normalizers/options_hash_value.rb +83 -0
  47. data/lib/mark_mapper/normalizers/sort_value.rb +55 -0
  48. data/lib/mark_mapper/options_hash.rb +103 -0
  49. data/lib/mark_mapper/pagination.rb +6 -0
  50. data/lib/mark_mapper/pagination/collection.rb +32 -0
  51. data/lib/mark_mapper/pagination/paginator.rb +46 -0
  52. data/lib/mark_mapper/plugins.rb +22 -0
  53. data/lib/mark_mapper/plugins/accessible.rb +61 -0
  54. data/lib/mark_mapper/plugins/active_model.rb +18 -0
  55. data/lib/mark_mapper/plugins/associations.rb +96 -0
  56. data/lib/mark_mapper/plugins/associations/base.rb +98 -0
  57. data/lib/mark_mapper/plugins/associations/belongs_to_association.rb +63 -0
  58. data/lib/mark_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +35 -0
  59. data/lib/mark_mapper/plugins/associations/belongs_to_proxy.rb +52 -0
  60. data/lib/mark_mapper/plugins/associations/collection.rb +29 -0
  61. data/lib/mark_mapper/plugins/associations/embedded_collection.rb +44 -0
  62. data/lib/mark_mapper/plugins/associations/in_array_proxy.rb +133 -0
  63. data/lib/mark_mapper/plugins/associations/many_association.rb +63 -0
  64. data/lib/mark_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  65. data/lib/mark_mapper/plugins/associations/many_documents_proxy.rb +142 -0
  66. data/lib/mark_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +32 -0
  67. data/lib/mark_mapper/plugins/associations/many_embedded_proxy.rb +24 -0
  68. data/lib/mark_mapper/plugins/associations/many_polymorphic_proxy.rb +14 -0
  69. data/lib/mark_mapper/plugins/associations/one_as_proxy.rb +22 -0
  70. data/lib/mark_mapper/plugins/associations/one_association.rb +48 -0
  71. data/lib/mark_mapper/plugins/associations/one_embedded_polymorphic_proxy.rb +30 -0
  72. data/lib/mark_mapper/plugins/associations/one_embedded_proxy.rb +44 -0
  73. data/lib/mark_mapper/plugins/associations/one_proxy.rb +95 -0
  74. data/lib/mark_mapper/plugins/associations/proxy.rb +138 -0
  75. data/lib/mark_mapper/plugins/associations/single_association.rb +46 -0
  76. data/lib/mark_mapper/plugins/caching.rb +21 -0
  77. data/lib/mark_mapper/plugins/callbacks.rb +42 -0
  78. data/lib/mark_mapper/plugins/clone.rb +24 -0
  79. data/lib/mark_mapper/plugins/counter_cache.rb +97 -0
  80. data/lib/mark_mapper/plugins/dirty.rb +61 -0
  81. data/lib/mark_mapper/plugins/document.rb +41 -0
  82. data/lib/mark_mapper/plugins/dumpable.rb +22 -0
  83. data/lib/mark_mapper/plugins/dynamic_querying.rb +45 -0
  84. data/lib/mark_mapper/plugins/dynamic_querying/dynamic_finder.rb +44 -0
  85. data/lib/mark_mapper/plugins/embedded_callbacks.rb +81 -0
  86. data/lib/mark_mapper/plugins/embedded_document.rb +53 -0
  87. data/lib/mark_mapper/plugins/equality.rb +23 -0
  88. data/lib/mark_mapper/plugins/identity_map.rb +144 -0
  89. data/lib/mark_mapper/plugins/indexable.rb +86 -0
  90. data/lib/mark_mapper/plugins/inspect.rb +16 -0
  91. data/lib/mark_mapper/plugins/keys.rb +470 -0
  92. data/lib/mark_mapper/plugins/keys/key.rb +134 -0
  93. data/lib/mark_mapper/plugins/keys/static.rb +45 -0
  94. data/lib/mark_mapper/plugins/logger.rb +18 -0
  95. data/lib/mark_mapper/plugins/modifiers.rb +140 -0
  96. data/lib/mark_mapper/plugins/pagination.rb +16 -0
  97. data/lib/mark_mapper/plugins/partial_updates.rb +77 -0
  98. data/lib/mark_mapper/plugins/persistence.rb +79 -0
  99. data/lib/mark_mapper/plugins/protected.rb +45 -0
  100. data/lib/mark_mapper/plugins/querying.rb +173 -0
  101. data/lib/mark_mapper/plugins/querying/decorated_markmapper_query.rb +75 -0
  102. data/lib/mark_mapper/plugins/rails.rb +79 -0
  103. data/lib/mark_mapper/plugins/rails/active_record_association_adapter.rb +33 -0
  104. data/lib/mark_mapper/plugins/sci.rb +82 -0
  105. data/lib/mark_mapper/plugins/scopes.rb +28 -0
  106. data/lib/mark_mapper/plugins/serialization.rb +109 -0
  107. data/lib/mark_mapper/plugins/timestamps.rb +29 -0
  108. data/lib/mark_mapper/plugins/touch.rb +18 -0
  109. data/lib/mark_mapper/plugins/userstamps.rb +18 -0
  110. data/lib/mark_mapper/plugins/validations.rb +96 -0
  111. data/lib/mark_mapper/query.rb +278 -0
  112. data/lib/mark_mapper/railtie.rb +52 -0
  113. data/lib/mark_mapper/railtie/database.rake +65 -0
  114. data/lib/mark_mapper/translation.rb +10 -0
  115. data/lib/mark_mapper/version.rb +4 -0
  116. data/lib/rails/generators/mark_mapper/config/config_generator.rb +37 -0
  117. data/lib/rails/generators/mark_mapper/config/templates/marklogic.yml +19 -0
  118. data/lib/rails/generators/mark_mapper/model/model_generator.rb +40 -0
  119. data/lib/rails/generators/mark_mapper/model/templates/model.rb +17 -0
  120. data/spec/config/mark_mapper.yml +6 -0
  121. data/spec/examples_spec.rb +25 -0
  122. data/spec/functional/accessible_spec.rb +198 -0
  123. data/spec/functional/associations/belongs_to_polymorphic_proxy_spec.rb +64 -0
  124. data/spec/functional/associations/belongs_to_proxy_spec.rb +255 -0
  125. data/spec/functional/associations/in_array_proxy_spec.rb +349 -0
  126. data/spec/functional/associations/many_documents_as_proxy_spec.rb +230 -0
  127. data/spec/functional/associations/many_documents_proxy_spec.rb +968 -0
  128. data/spec/functional/associations/many_embedded_polymorphic_proxy_spec.rb +238 -0
  129. data/spec/functional/associations/many_embedded_proxy_spec.rb +288 -0
  130. data/spec/functional/associations/many_polymorphic_proxy_spec.rb +302 -0
  131. data/spec/functional/associations/one_as_proxy_spec.rb +489 -0
  132. data/spec/functional/associations/one_embedded_polymorphic_proxy_spec.rb +207 -0
  133. data/spec/functional/associations/one_embedded_proxy_spec.rb +100 -0
  134. data/spec/functional/associations/one_proxy_spec.rb +406 -0
  135. data/spec/functional/associations_spec.rb +48 -0
  136. data/spec/functional/caching_spec.rb +75 -0
  137. data/spec/functional/callbacks_spec.rb +330 -0
  138. data/spec/functional/counter_cache_spec.rb +235 -0
  139. data/spec/functional/dirty_spec.rb +316 -0
  140. data/spec/functional/document_spec.rb +310 -0
  141. data/spec/functional/dumpable_spec.rb +24 -0
  142. data/spec/functional/dynamic_querying_spec.rb +75 -0
  143. data/spec/functional/embedded_document_spec.rb +316 -0
  144. data/spec/functional/equality_spec.rb +20 -0
  145. data/spec/functional/extensions_spec.rb +16 -0
  146. data/spec/functional/identity_map_spec.rb +483 -0
  147. data/spec/functional/keys_spec.rb +339 -0
  148. data/spec/functional/logger_spec.rb +20 -0
  149. data/spec/functional/modifiers_spec.rb +446 -0
  150. data/spec/functional/options_hash_spec.rb +41 -0
  151. data/spec/functional/pagination_spec.rb +89 -0
  152. data/spec/functional/partial_updates_spec.rb +530 -0
  153. data/spec/functional/protected_spec.rb +199 -0
  154. data/spec/functional/querying_spec.rb +984 -0
  155. data/spec/functional/rails_spec.rb +55 -0
  156. data/spec/functional/sci_spec.rb +374 -0
  157. data/spec/functional/scopes_spec.rb +204 -0
  158. data/spec/functional/static_keys_spec.rb +153 -0
  159. data/spec/functional/timestamps_spec.rb +97 -0
  160. data/spec/functional/touch_spec.rb +125 -0
  161. data/spec/functional/userstamps_spec.rb +46 -0
  162. data/spec/functional/validations_spec.rb +416 -0
  163. data/spec/quality_spec.rb +51 -0
  164. data/spec/spec_helper.rb +150 -0
  165. data/spec/support/matchers.rb +15 -0
  166. data/spec/support/models.rb +256 -0
  167. data/spec/symbol_operator_spec.rb +70 -0
  168. data/spec/symbol_spec.rb +9 -0
  169. data/spec/unit/associations/base_spec.rb +146 -0
  170. data/spec/unit/associations/belongs_to_association_spec.rb +30 -0
  171. data/spec/unit/associations/many_association_spec.rb +64 -0
  172. data/spec/unit/associations/one_association_spec.rb +48 -0
  173. data/spec/unit/associations/proxy_spec.rb +103 -0
  174. data/spec/unit/clone_spec.rb +79 -0
  175. data/spec/unit/config_generator_spec.rb +24 -0
  176. data/spec/unit/criteria_hash_spec.rb +218 -0
  177. data/spec/unit/document_spec.rb +251 -0
  178. data/spec/unit/dynamic_finder_spec.rb +125 -0
  179. data/spec/unit/embedded_document_spec.rb +676 -0
  180. data/spec/unit/equality_spec.rb +38 -0
  181. data/spec/unit/exceptions_spec.rb +12 -0
  182. data/spec/unit/extensions_spec.rb +368 -0
  183. data/spec/unit/identity_map_middleware_spec.rb +134 -0
  184. data/spec/unit/inspect_spec.rb +47 -0
  185. data/spec/unit/key_spec.rb +276 -0
  186. data/spec/unit/keys_spec.rb +155 -0
  187. data/spec/unit/mark_mapper_spec.rb +37 -0
  188. data/spec/unit/model_generator_spec.rb +45 -0
  189. data/spec/unit/normalizers/criteria_hash_key_spec.rb +37 -0
  190. data/spec/unit/normalizers/criteria_hash_value_spec.rb +200 -0
  191. data/spec/unit/normalizers/fields_value_spec.rb +45 -0
  192. data/spec/unit/normalizers/hash_key_spec.rb +15 -0
  193. data/spec/unit/normalizers/integer_spec.rb +24 -0
  194. data/spec/unit/normalizers/options_hash_value_spec.rb +99 -0
  195. data/spec/unit/normalizers/sort_value_spec.rb +98 -0
  196. data/spec/unit/options_hash_spec.rb +64 -0
  197. data/spec/unit/pagination/collection_spec.rb +30 -0
  198. data/spec/unit/pagination/paginator_spec.rb +118 -0
  199. data/spec/unit/pagination_spec.rb +11 -0
  200. data/spec/unit/plugins_spec.rb +89 -0
  201. data/spec/unit/query_spec.rb +837 -0
  202. data/spec/unit/rails_compatibility_spec.rb +40 -0
  203. data/spec/unit/rails_reflect_on_association_spec.rb +118 -0
  204. data/spec/unit/rails_spec.rb +188 -0
  205. data/spec/unit/serialization_spec.rb +169 -0
  206. data/spec/unit/serializers/json_serializer_spec.rb +218 -0
  207. data/spec/unit/serializers/xml_serializer_spec.rb +198 -0
  208. data/spec/unit/time_zones_spec.rb +44 -0
  209. data/spec/unit/translation_spec.rb +27 -0
  210. data/spec/unit/validations_spec.rb +588 -0
  211. metadata +307 -0
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Rails Compatibility" do
4
+ module EmbeddedDocuments
5
+ class Item
6
+ include MarkMapper::EmbeddedDocument
7
+ key :for_all, String
8
+ end
9
+
10
+ class FirstItem < Item
11
+ key :first_only, String
12
+ many :second_items
13
+ end
14
+
15
+ class SecondItem < Item
16
+ key :second_only, String
17
+ end
18
+ end
19
+
20
+ context "EmbeddedDocument" do
21
+ it "should alias many to has_many" do
22
+ EmbeddedDocuments::FirstItem.should respond_to(:has_many)
23
+ end
24
+
25
+ it "should alias one to has_one" do
26
+ EmbeddedDocuments::FirstItem.should respond_to(:has_one)
27
+ end
28
+
29
+ it "should have column names" do
30
+ EmbeddedDocuments::Item.column_names.sort.should == ['_id', '_type', 'for_all']
31
+ EmbeddedDocuments::FirstItem.column_names.sort.should == ['_id', '_type', 'first_only', 'for_all']
32
+ EmbeddedDocuments::SecondItem.column_names.sort.should == ['_id', '_type', 'for_all', 'second_only']
33
+ end
34
+
35
+ it "should alias new to new_record?" do
36
+ instance = EmbeddedDocuments::Item.new
37
+ instance.new_record?.should == instance.new?
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,118 @@
1
+ require 'spec_helper'
2
+
3
+ module ReflectOnAssociationTestModels
4
+ class Tree
5
+ include MarkMapper::Document
6
+ many :birds, :class_name => "ReflectOnAssociationTestModels::Bird"
7
+ end
8
+
9
+ class Bird
10
+ include MarkMapper::Document
11
+ belongs_to :tree, :class_name => "ReflectOnAssociationTestModels::Tree"
12
+ end
13
+
14
+ class Book
15
+ include MarkMapper::Document
16
+ many :authors, :class_name => "ReflectOnAssociationTestModels::Author", :in => :author_ids
17
+ end
18
+
19
+ class Author
20
+ include MarkMapper::Document
21
+ end
22
+
23
+ class Employee
24
+ include MarkMapper::Document
25
+ one :desk, :class_name => "ReflectOnAssociationTestModels::Desk"
26
+ end
27
+
28
+ class Desk
29
+ include MarkMapper::Document
30
+ belongs_to :employee, :class_name => "ReflectOnAssociationTestModels::Employee"
31
+ end
32
+
33
+ class Order
34
+ include MarkMapper::Document
35
+ many :line_items, :class_name => "ReflectOnAssociationTestModels::LineItem"
36
+ end
37
+
38
+ class LineItem
39
+ include MarkMapper::EmbeddedDocument
40
+ end
41
+
42
+ class Body
43
+ include MarkMapper::Document
44
+ one :heart, :class_name => "ReflectOnAssociationTestModels::Heart"
45
+ end
46
+
47
+ class Heart
48
+ include MarkMapper::EmbeddedDocument
49
+ end
50
+ end
51
+
52
+ describe "ReflectOnAssociation" do
53
+ context "one-to-many association" do
54
+ it "should return :has_many association for Tree#birds" do
55
+ association = ReflectOnAssociationTestModels::Tree.reflect_on_association(:birds)
56
+ association.klass.should == ReflectOnAssociationTestModels::Bird
57
+ association.macro.should == :has_many
58
+ association.name.should == :birds
59
+ association.options.should == {}
60
+ end
61
+
62
+ it "should return :belongs_to association for Bird#tree" do
63
+ association = ReflectOnAssociationTestModels::Bird.reflect_on_association(:tree)
64
+ association.klass.should == ReflectOnAssociationTestModels::Tree
65
+ association.macro.should == :belongs_to
66
+ association.name.should == :tree
67
+ association.options.should == {}
68
+ end
69
+ end
70
+
71
+ context "many-to-many association" do
72
+ it "should return :has_many association for Book#authors" do
73
+ association = ReflectOnAssociationTestModels::Book.reflect_on_association(:authors)
74
+ association.klass.should == ReflectOnAssociationTestModels::Author
75
+ association.macro.should == :has_many
76
+ association.name.should == :authors
77
+ association.options.should == {}
78
+ end
79
+ end
80
+
81
+ context "one-to-one association" do
82
+ it "should return :has_one association for Employee#desk" do
83
+ association = ReflectOnAssociationTestModels::Employee.reflect_on_association(:desk)
84
+ association.klass.should == ReflectOnAssociationTestModels::Desk
85
+ association.macro.should == :has_one
86
+ association.name.should == :desk
87
+ association.options.should == {}
88
+ end
89
+
90
+ it "should return :belongs_to association for Desk#employee" do
91
+ association = ReflectOnAssociationTestModels::Desk.reflect_on_association(:employee)
92
+ association.klass.should == ReflectOnAssociationTestModels::Employee
93
+ association.macro.should == :belongs_to
94
+ association.name.should == :employee
95
+ association.options.should == {}
96
+ end
97
+ end
98
+
99
+ context "embeds one" do
100
+ it "should return :has_one association for Body#heart" do
101
+ association = ReflectOnAssociationTestModels::Body.reflect_on_association(:heart)
102
+ association.klass.should == ReflectOnAssociationTestModels::Heart
103
+ association.macro.should == :has_one
104
+ association.name.should == :heart
105
+ association.options.should == {}
106
+ end
107
+ end
108
+
109
+ context "embeds many" do
110
+ it "should return :has_many association for Order#line_items" do
111
+ association = ReflectOnAssociationTestModels::Order.reflect_on_association(:line_items)
112
+ association.klass.should == ReflectOnAssociationTestModels::LineItem
113
+ association.macro.should == :has_many
114
+ association.name.should == :line_items
115
+ association.options.should == {}
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,188 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Rails integration" do
4
+ context "Document" do
5
+ before do
6
+ @klass = Doc('Post') do
7
+ key :foo, String
8
+ end
9
+ end
10
+
11
+ context "Class methods" do
12
+ it "should alias has_many to many" do
13
+ @klass.should respond_to(:has_many)
14
+ end
15
+
16
+ it 'should pass on block given in has_many' do
17
+ @klass.class_eval do
18
+ has_many :posts do
19
+ def foo_bars; true; end
20
+ end
21
+ end
22
+
23
+ expect(@klass.new.posts.respond_to?(:foo_bars)).to eq(true)
24
+ end
25
+
26
+ it "should alias has_one to one" do
27
+ @klass.should respond_to(:has_one)
28
+ end
29
+
30
+ it "should have column names" do
31
+ @klass.column_names.sort.should == ['_id', 'foo']
32
+ end
33
+ end
34
+
35
+ context "Instance methods" do
36
+ before do
37
+ @klass.class_eval do
38
+ def bar=(value)
39
+ write_attribute(:foo, value)
40
+ end
41
+
42
+ def bar_before_type_cast
43
+ read_attribute_before_type_cast(:foo)
44
+ end
45
+
46
+ def bar
47
+ read_attribute(:foo)
48
+ end
49
+ end
50
+ end
51
+
52
+ it "should alias new_record? to new?" do
53
+ @klass.new.should be_new_record
54
+ end
55
+
56
+ it "should be able to read key with read_attribute" do
57
+ @klass.new(:foo => 'Bar').bar.should == 'Bar'
58
+ end
59
+
60
+ it "should be able to read key before type cast with read_attribute_before_type_cast" do
61
+ @klass.new(:foo => 21).bar_before_type_cast.should == 21
62
+ @klass.new(:foo => 21).bar.should == '21'
63
+ end
64
+
65
+ it "should be able to write key with write_attribute" do
66
+ @klass.new(:bar => 'Setting Foo').foo.should == 'Setting Foo'
67
+ end
68
+
69
+ it "should return the type casted value from write attribute" do
70
+ obj = @klass.new
71
+ obj.write_attribute(:foo, true).should == "true"
72
+ end
73
+
74
+ context '#to_param' do
75
+ it "should be nil if not persisted" do
76
+ @klass.new.tap do |doc|
77
+ doc.to_param.should be_nil
78
+ end
79
+ end
80
+
81
+ it "should array representation of id if persisted" do
82
+ @klass.create.tap do |doc|
83
+ doc.to_param.should == doc.id.to_s
84
+ end
85
+ end
86
+ end
87
+
88
+ context '#to_key' do
89
+ it "should be nil if not persisted" do
90
+ @klass.new.tap do |doc|
91
+ doc.to_key.should be_nil
92
+ end
93
+ end
94
+
95
+ it "should array representation of id if persisted" do
96
+ @klass.create.tap do |doc|
97
+ doc.to_key.should == [doc.id]
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ context "EmbeddedDocument" do
105
+ before do
106
+ @klass = EDoc('Post') { key :foo, String }
107
+ end
108
+
109
+ context "Class methods" do
110
+ it "should alias has_many to many" do
111
+ @klass.should respond_to(:has_many)
112
+ end
113
+
114
+ it "should alias has_one to one" do
115
+ @klass.should respond_to(:has_one)
116
+ end
117
+
118
+ it "should have column names" do
119
+ @klass.column_names.sort.should == ['_id', 'foo']
120
+ end
121
+ end
122
+
123
+ context "Instance methods" do
124
+ before do
125
+ @klass.class_eval do
126
+ def bar=(value)
127
+ write_attribute(:foo, value)
128
+ end
129
+
130
+ def bar_before_type_cast
131
+ read_attribute_before_type_cast(:foo)
132
+ end
133
+
134
+ def bar
135
+ read_attribute(:foo)
136
+ end
137
+ end
138
+ end
139
+
140
+ it "should alias new_record? to new?" do
141
+ @klass.new.should be_new_record
142
+ end
143
+
144
+ it "should be able to read key with read_attribute" do
145
+ @klass.new(:foo => 'Bar').bar.should == 'Bar'
146
+ end
147
+
148
+ it "should be able to read key before type cast with read_attribute_before_type_cast" do
149
+ @klass.new(:foo => 21).bar_before_type_cast.should == 21
150
+ @klass.new(:foo => 21).bar.should == '21'
151
+ end
152
+
153
+ it "should be able to write key with write_attribute" do
154
+ @klass.new(:bar => 'Setting Foo').foo.should == 'Setting Foo'
155
+ end
156
+
157
+ context '#to_param' do
158
+ it "should be nil if not persisted" do
159
+ @klass.new.tap do |doc|
160
+ doc.to_param.should be_nil
161
+ end
162
+ end
163
+
164
+ it "should array representation of id if persisted" do
165
+ @klass.new.tap do |doc|
166
+ expect(doc).to receive(:persisted?).and_return(true)
167
+ doc.to_param.should == doc.id.to_s
168
+ end
169
+ end
170
+ end
171
+
172
+ context '#to_key' do
173
+ it "should be nil if not persisted" do
174
+ @klass.new.tap do |doc|
175
+ doc.to_key.should be_nil
176
+ end
177
+ end
178
+
179
+ it "should array representation of id if persisted" do
180
+ @klass.new.tap do |doc|
181
+ expect(doc).to receive(:persisted?).and_return(true)
182
+ doc.to_key.should == [doc.id]
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,169 @@
1
+ require 'spec_helper'
2
+
3
+ module Serialization
4
+ class List
5
+ include MarkMapper::Document
6
+ key :name
7
+ many :items, :class_name => 'Serialization::Item'
8
+ belongs_to :creator, :class_name => 'Serialization::User'
9
+ end
10
+
11
+ class Assignment
12
+ include MarkMapper::EmbeddedDocument
13
+ belongs_to :assigned_by, :class_name => 'Serialization::User'
14
+ belongs_to :user, :class_name => 'Serialization::User'
15
+
16
+ def serializable_hash(options = {})
17
+ super({:only => :user_id}.merge(options))
18
+ end
19
+ end
20
+
21
+ class Item
22
+ include MarkMapper::Document
23
+
24
+ key :title
25
+ key :description
26
+ many :assignments, :class_name => 'Serialization::Assignment'
27
+
28
+ def a_method
29
+ 1
30
+ end
31
+ end
32
+
33
+
34
+ class User
35
+ include MarkMapper::Document
36
+ key :name, String
37
+ end
38
+
39
+ describe "Serialization" do
40
+ before do
41
+ @document = EDoc do
42
+ key :name, String
43
+ key :age, Integer
44
+ key :awesome, Boolean
45
+ key :preferences, Hash
46
+ key :created_at, Time
47
+ end
48
+
49
+ @instance = @document.new(
50
+ :name => 'John Doe',
51
+ :age => 25,
52
+ :awesome => true,
53
+ :preferences => {:language => 'Ruby'},
54
+ :created_at => Time.now.change(:usec => 0)
55
+ )
56
+ end
57
+
58
+ context "#serializable_hash" do
59
+ before do
60
+ @user1 = User.new(:name => 'Brandon')
61
+ @user2 = User.new(:name => 'John')
62
+ @item = Item.new(
63
+ :title => 'Serialization',
64
+ :description => 'Make it work like magic!',
65
+ :assignments => [
66
+ Assignment.new(:assigned_by => @user1, :user => @user2)
67
+ ]
68
+ )
69
+ end
70
+
71
+ it "should only include specified attributes with :only option" do
72
+ @item.serializable_hash(:only => :title).should == {'title' => 'Serialization'}
73
+ end
74
+
75
+ it "should exclude attributes specified with :except option" do
76
+ hash = @item.serializable_hash(:except => :description)
77
+ hash['title'].should_not be_nil
78
+ hash['description'].should be_nil
79
+ end
80
+
81
+ it "should add :methods with :only option" do
82
+ @item.serializable_hash(:only => :title, :methods => :a_method).should == {
83
+ 'title' => 'Serialization',
84
+ 'a_method' => 1
85
+ }
86
+ end
87
+
88
+ it "should call #serializable_hash on embedded many docs" do
89
+ @item.serializable_hash.should == {
90
+ 'id' => @item.id,
91
+ 'title' => 'Serialization',
92
+ 'description' => 'Make it work like magic!',
93
+ 'assignments' => [{'user_id' => @user2.id}]
94
+ }
95
+ end
96
+
97
+ context "with :include" do
98
+ before do
99
+ @list = List.new(:title => 'MarkMapper', :items => [@item], :creator => @user1)
100
+ end
101
+
102
+ it "should add many association" do
103
+ hash = @list.serializable_hash(:include => :items)
104
+ hash['items'].should be_instance_of(Array)
105
+ hash['items'].first['title'].should == 'Serialization'
106
+ end
107
+
108
+ it "should add belongs_to association" do
109
+ hash = @list.serializable_hash(:include => :creator)
110
+ hash['creator'].should == @user1.serializable_hash
111
+ end
112
+
113
+ it "should add one association" do
114
+ author_class = Doc do
115
+ key :post_id, ObjectId
116
+ end
117
+ post_class = Doc('Post') do
118
+ one :author, :class => author_class
119
+ end
120
+
121
+ author = author_class.new
122
+ hash = post_class.new(:author => author).serializable_hash(:include => :author)
123
+ hash['author'].should == author.serializable_hash
124
+ end
125
+
126
+ it "should include multiple associations" do
127
+ hash = @list.serializable_hash(:include => [:items, :creator])
128
+ hash['items'].should be_instance_of(Array)
129
+ hash['creator'].should == @user1.serializable_hash
130
+ end
131
+
132
+ it "should include multiple associations with options" do
133
+ hash = @list.serializable_hash(:include => {:creator => {:only => :name}})
134
+ hash['creator'].should == @user1.serializable_hash(:only => :name)
135
+ end
136
+ end
137
+ end
138
+
139
+ [:json, :xml].each do |format|
140
+ context format do
141
+ it "should be reversable" do
142
+ serialized = @instance.send("to_#{format}")
143
+ unserialized = @document.send("from_#{format}", serialized)
144
+
145
+ @instance.should == unserialized
146
+ end
147
+
148
+ it "should allow attribute only filtering" do
149
+ serialized = @instance.send("to_#{format}", :only => [ :age, :name ])
150
+ unserialized = @document.send("from_#{format}", serialized)
151
+
152
+ @instance.name.should == unserialized.name
153
+ @instance.age.should == unserialized.age
154
+ unserialized.awesome.should be_falsey
155
+ unserialized.created_at.should be_nil
156
+ end
157
+
158
+ it "should allow attribute except filtering" do
159
+ serialized = @instance.send("to_#{format}", :except => [ :age, :name ])
160
+ unserialized = @document.send("from_#{format}", serialized)
161
+
162
+ unserialized.name.should be_nil
163
+ unserialized.age.should be_nil
164
+ @instance.awesome.should == unserialized.awesome
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end