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,218 @@
1
+ require 'spec_helper'
2
+
3
+ module JsonSerialization
4
+ describe "JsonSerialization" do
5
+
6
+ # Helper function in case things change in the future
7
+ # - replacing all those to_json calls was a nightmare
8
+ def convert_to_json(object, options={})
9
+ ActiveSupport::JSON.encode(object, options)
10
+ end
11
+
12
+ class Tag
13
+ include MarkMapper::EmbeddedDocument
14
+ key :name, String
15
+ end
16
+
17
+ class Contact
18
+ include MarkMapper::Document
19
+ key :name, String
20
+ key :age, Integer
21
+ key :created_at, Time
22
+ key :awesome, Boolean
23
+ key :preferences, Hash
24
+
25
+ many :tags, :class_name => 'JsonSerialization::Tag'
26
+ end
27
+
28
+ before do
29
+ Kernel.const_set('TopLevelContact', Doc('TopLevelContact'))
30
+ TopLevelContact.key :name, String
31
+
32
+ Contact.include_root_in_json = false
33
+ @contact = Contact.new(
34
+ :name => 'Konata Izumi',
35
+ :age => 16,
36
+ :created_at => Time.utc(2006, 8, 1),
37
+ :awesome => true,
38
+ :preferences => { :shows => 'anime' }
39
+ )
40
+ @top_level_contact = TopLevelContact.new(
41
+ :name => 'Konata Izumi'
42
+ )
43
+ end
44
+
45
+ after do
46
+ Kernel.send(:remove_const, 'TopLevelContact') if Object.const_defined?('TopLevelContact')
47
+ end
48
+
49
+ it "should include root for class with no module" do
50
+ TopLevelContact.include_root_in_json = true
51
+ convert_to_json(@top_level_contact).should match %r{^\{"top_level_contact":\s?\{}
52
+ end
53
+
54
+ it "should include demodulized root" do
55
+ Contact.include_root_in_json = true
56
+ convert_to_json(@contact).should match %r{^\{"contact":\s?\{}
57
+ end
58
+
59
+ it "should encode all encodable attributes" do
60
+ json = convert_to_json(@contact)
61
+
62
+ json.should_not match %r{"_id"}
63
+ json.should match %r{"name":"Konata Izumi"}
64
+ json.should match %r{"age":16}
65
+ json.should include(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
66
+ json.should match %r{"awesome":true}
67
+ json.should match %r{"preferences":\{"shows":"anime"\}}
68
+ end
69
+
70
+ it "should allow attribute filtering with only" do
71
+ json = convert_to_json(@contact, :only => [:name, :age])
72
+
73
+ json.should_not match %r{"_id"}
74
+ json.should match %r{"name":"Konata Izumi"}
75
+ json.should match %r{"age":16}
76
+ json.should_not match %r{"awesome"}
77
+ json.should_not match %r{"created_at"}
78
+ json.should_not match %r{"preferences"}
79
+ end
80
+
81
+ it "should allow attribute filtering with except" do
82
+ json = convert_to_json(@contact, :except => [:name, :age])
83
+
84
+ json.should_not match %r{"_id"}
85
+ json.should_not match %r{"name"}
86
+ json.should_not match %r{"age"}
87
+ json.should match %r{"awesome"}
88
+ json.should match %r{"created_at"}
89
+ json.should match %r{"preferences"}
90
+ end
91
+
92
+ context "_id key" do
93
+ it "should not be included by default" do
94
+ json = convert_to_json(@contact)
95
+ json.should_not match %r{"_id":}
96
+ end
97
+
98
+ it "should not be included even if :except is used" do
99
+ json = convert_to_json(@contact, :except => :name)
100
+ json.should_not match %r{"_id":}
101
+ end
102
+ end
103
+
104
+ context "id method" do
105
+ before do
106
+ def @contact.label; "Has cheezburger"; end
107
+ def @contact.favorite_quote; "Constraints are liberating"; end
108
+ end
109
+
110
+ it "should be included by default" do
111
+ json = convert_to_json(@contact)
112
+ json.should match %r{"id"}
113
+ end
114
+
115
+ it "should be included when single method included" do
116
+ json = convert_to_json(@contact, :methods => :label)
117
+ json.should match %r{"id"}
118
+ json.should match %r{"label":"Has cheezburger"}
119
+ json.should match %r{"name":"Konata Izumi"}
120
+ json.should_not match %r{"favorite_quote":"Constraints are liberating"}
121
+ end
122
+
123
+ it "should be included when multiple methods included" do
124
+ json = convert_to_json(@contact, :methods => [:label, :favorite_quote])
125
+ json.should match %r{"id"}
126
+ json.should match %r{"label":"Has cheezburger"}
127
+ json.should match %r{"favorite_quote":"Constraints are liberating"}
128
+ json.should match %r{"name":"Konata Izumi"}
129
+ end
130
+
131
+ it "should not be included if :only is present" do
132
+ json = convert_to_json(@contact, :only => :name)
133
+ json.should_not match %r{"id":}
134
+ end
135
+
136
+ it "should be represented by a string" do
137
+ json = convert_to_json(@contact)
138
+ json.should match %r{"id":"}
139
+ end
140
+ end
141
+
142
+ context "including methods" do
143
+ before do
144
+ def @contact.label; "Has cheezburger"; end
145
+ def @contact.favorite_quote; "Constraints are liberating"; end
146
+ end
147
+
148
+ it "should include single method" do
149
+ json = convert_to_json(@contact, :methods => :label)
150
+ json.should match %r{"label":"Has cheezburger"}
151
+ end
152
+
153
+ it "should include multiple methods" do
154
+ json = convert_to_json(@contact, :only => :name, :methods => [:label, :favorite_quote])
155
+ json.should match %r{"label":"Has cheezburger"}
156
+ json.should match %r{"favorite_quote":"Constraints are liberating"}
157
+ json.should match %r{"name":"Konata Izumi"}
158
+ json.should_not match %r{"age":16}
159
+ json.should_not match %r{"awesome"}
160
+ json.should_not match %r{"created_at"}
161
+ json.should_not match %r{"preferences"}
162
+ end
163
+ end
164
+
165
+ context "array of records" do
166
+ before do
167
+ @contacts = [
168
+ Contact.new(:name => 'David', :age => 39),
169
+ Contact.new(:name => 'Mary', :age => 14)
170
+ ]
171
+ end
172
+
173
+ it "should allow attribute filtering with only" do
174
+ json =convert_to_json(@contacts, :only => :name)
175
+ json.should match %r{\{"name":"David"\}}
176
+ json.should match %r{\{"name":"Mary"\}}
177
+ end
178
+
179
+ it "should allow attribute filtering with except" do
180
+ json = convert_to_json(@contacts, :except => [:name, :preferences, :awesome, :created_at, :updated_at])
181
+ json.should match %r{"age":39}
182
+ json.should match %r{"age":14}
183
+ json.should_not match %r{"name":}
184
+ json.should_not match %r{"preferences":}
185
+ json.should_not match %r{"awesome":}
186
+ json.should_not match %r{"created_at":}
187
+ json.should_not match %r{"updated_at":}
188
+ end
189
+ end
190
+
191
+ it "should allow options for hash of records" do
192
+ contacts = {
193
+ 1 => Contact.new(:name => 'David', :age => 39),
194
+ 2 => Contact.new(:name => 'Mary', :age => 14)
195
+ }
196
+ json = convert_to_json(contacts, :only => [1, :name])
197
+ json.should match %r{"1":}
198
+ json.should match %r{\{"name":"David"\}}
199
+ json.should_not match %r{"2":}
200
+ end
201
+
202
+ it "should include embedded attributes" do
203
+ contact = Contact.new(:name => 'John', :age => 27)
204
+ contact.tags = [Tag.new(:name => 'awesome'), Tag.new(:name => 'ruby')]
205
+ json = convert_to_json(contact)
206
+ json.should match %r{"tags":}
207
+ json.should match %r{"name":"awesome"}
208
+ json.should match %r{"name":"ruby"}
209
+ end
210
+
211
+ it "should include dynamic attributes" do
212
+ contact = Contact.new(:name => 'John', :age => 27, :foo => 'bar')
213
+ contact['smell'] = 'stinky'
214
+ json = convert_to_json(contact)
215
+ json.should match %r{"smell":"stinky"}
216
+ end
217
+ end
218
+ end
@@ -0,0 +1,198 @@
1
+ require 'spec_helper'
2
+
3
+ module XmlSerialization
4
+ describe "XmlSerialization" do
5
+ class Tag
6
+ include MarkMapper::EmbeddedDocument
7
+ key :name, String
8
+ end
9
+
10
+ class Contact
11
+ include MarkMapper::Document
12
+ key :name, String
13
+ key :age, Integer
14
+ key :created_at, Time
15
+ key :awesome, Boolean
16
+ key :preferences, Hash
17
+
18
+ many :tags, :class_name => 'XmlSerialization::Tag'
19
+ end
20
+
21
+ before do
22
+ Kernel.const_set('TopLevelContact', Doc('TopLevelContact'))
23
+ TopLevelContact.key :name, String
24
+
25
+ Contact.include_root_in_json = false
26
+ @contact = Contact.new(
27
+ :name => 'Konata Izumi',
28
+ :age => 16,
29
+ :created_at => Time.utc(2006, 8, 1),
30
+ :awesome => true,
31
+ :preferences => { :shows => 'anime' }
32
+ )
33
+ @top_level_contact = TopLevelContact.new(
34
+ :name => 'Konata Izumi'
35
+ )
36
+ end
37
+
38
+ after do
39
+ Kernel.send(:remove_const, 'TopLevelContact') if Object.const_defined?('TopLevelContact')
40
+ end
41
+
42
+ it "should include root for class with no module" do
43
+ @top_level_contact.to_xml.should match %r{<top-level-contact>}
44
+ end
45
+
46
+ it "should include demodulized root" do
47
+ @contact.to_xml.should match %r{<contact>}
48
+ end
49
+
50
+ it "should encode all encodable attributes" do
51
+ xml = @contact.to_xml
52
+
53
+ xml.should_not match %r{_id}
54
+ xml.should match %r{<id>#{@contact.id}</id>}
55
+ xml.should match %r{<name>Konata Izumi</name>}
56
+ xml.should match %r{<age.*>16</age>}
57
+ xml.should match %r(<created-at type="date[tT]ime">)
58
+ xml.should match %r{<awesome type="boolean">true</awesome>}
59
+ xml.should match %r{<preferences>}
60
+ xml.should match %r{<shows>anime</shows>}
61
+ end
62
+
63
+ it "should allow attribute filtering with only" do
64
+ xml = @contact.to_xml(:only => [:name, :age])
65
+
66
+ xml.should match %r{<name>Konata Izumi</name>}
67
+ xml.should match %r{<age type="integer">16</age>}
68
+ xml.should_not match %r{<id>}
69
+ xml.should_not match %r{awesome}
70
+ xml.should_not match %r{created-at}
71
+ xml.should_not match %r{preferences}
72
+ end
73
+
74
+ it "should allow attribute filtering with except" do
75
+ xml = @contact.to_xml(:except => [:name, :age])
76
+
77
+ xml.should_not match %r{<name>Konata Izumi</name>}
78
+ xml.should_not match %r{<age type="integer">16</age>}
79
+ xml.should match %r{<id>}
80
+ xml.should match %r{awesome}
81
+ xml.should match %r{created-at}
82
+ xml.should match %r{preferences}
83
+ end
84
+
85
+ context "_id key" do
86
+ it "should not be included by default" do
87
+ @contact.to_xml.should_not match %r{_id}
88
+ end
89
+
90
+ it "should not be included even if :except is used" do
91
+ @contact.to_xml(:except => :name).should_not match %r{_id}
92
+ end
93
+ end
94
+
95
+ context "id method" do
96
+ before do
97
+ def @contact.label; "Has cheezburger"; end
98
+ def @contact.favorite_quote; "Constraints are liberating"; end
99
+ end
100
+
101
+ it "should be included by default" do
102
+ @contact.to_xml.should match %r{<id>#{@contact.id}</id>}
103
+ end
104
+
105
+ it "should be included when single method included" do
106
+ xml = @contact.to_xml(:methods => :label)
107
+ xml.should match %r{<id>}
108
+ xml.should match %r{<label>Has cheezburger</label>}
109
+ xml.should match %r{<name>Konata Izumi</name>}
110
+ xml.should_not match %r{favorite_quote}
111
+ end
112
+
113
+ it "should be included when multiple methods included" do
114
+ xml = @contact.to_xml(:methods => [:label, :favorite_quote])
115
+ xml.should match %r{<id>}
116
+ xml.should match %r{<label>Has cheezburger</label>}
117
+ xml.should match %r{<name>Konata Izumi</name>}
118
+ xml.should match %r{<favorite-quote>Constraints are liberating</favorite-quote>}
119
+ end
120
+
121
+ it "should not be included if :only is present" do
122
+ @contact.to_xml(:only => :name).should_not match %r{<id}
123
+ end
124
+
125
+ it "should be represented by a string" do
126
+ @contact.to_xml.should match %r{<id>}
127
+ end
128
+ end
129
+
130
+ context "including methods" do
131
+ before do
132
+ def @contact.label; "Has cheezburger"; end
133
+ def @contact.favorite_quote; "Constraints are liberating"; end
134
+ end
135
+
136
+ it "should include single method" do
137
+ @contact.to_xml(:methods => :label).should match %r{<label>Has cheezburger</label>}
138
+ end
139
+
140
+ it "should include multiple methods" do
141
+ xml = @contact.to_xml(:only => :name, :methods => [:label, :favorite_quote])
142
+ xml.should match %r{<label>Has cheezburger</label>}
143
+ xml.should match %r{<favorite-quote>Constraints are liberating</favorite-quote>}
144
+ xml.should match %r{<name>Konata Izumi</name>}
145
+ xml.should_not match %r{age}
146
+ xml.should_not match %r{awesome}
147
+ xml.should_not match %r{created-at}
148
+ xml.should_not match %r{preferences}
149
+
150
+ # Assert only one tag is created
151
+ xml.scan(/favorite-quote/).size.should == 2
152
+ end
153
+ end
154
+
155
+ context "array of records" do
156
+ before do
157
+ @contacts = [
158
+ Contact.new(:name => 'David', :age => 39),
159
+ Contact.new(:name => 'Mary', :age => 14)
160
+ ]
161
+ end
162
+
163
+ it "should allow attribute filtering with only" do
164
+ xml = @contacts.to_xml(:only => :name)
165
+ xml.should match %r{<name>David</name>}
166
+ xml.should match %r{<name>Mary</name>}
167
+ end
168
+
169
+ it "should allow attribute filtering with except" do
170
+ xml = @contacts.to_xml(:except => [:name, :preferences, :awesome, :created_at, :updated_at])
171
+ xml.should match %r{<age type="integer">14</age>}
172
+ xml.should match %r{<age type="integer">39</age>}
173
+ xml.should_not match %r{name}
174
+ xml.should_not match %r{preferences}
175
+ xml.should_not match %r{awesome}
176
+ xml.should_not match %r{created-at}
177
+ xml.should_not match %r{updated-at}
178
+ end
179
+ end
180
+
181
+ it "should include embedded attributes" do
182
+ contact = Contact.new(:name => 'John', :age => 27)
183
+ contact.tags = [Tag.new(:name => 'awesome'), Tag.new(:name => 'ruby')]
184
+ xml = contact.to_xml
185
+ xml.should match %r{<tags type="array">}
186
+ xml.should match %r{<id>#{contact.tags[0].id}</id>}
187
+ xml.should match %r{<id>#{contact.tags[1].id}</id>}
188
+ xml.should match %r{<name>awesome</name>}
189
+ xml.should match %r{<name>ruby</name>}
190
+ end
191
+
192
+ it "should include dynamic attributes" do
193
+ contact = Contact.new(:name => 'John', :age => 27, :foo => 'bar')
194
+ contact['smell'] = 'stinky'
195
+ contact.to_xml.should match %r{<smell>stinky</smell>}
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe "TimeZones" do
4
+ context "An instance of an embedded document" do
5
+ before do
6
+ @document = EDoc do
7
+ key :name, String
8
+ key :created_at, Time
9
+ end
10
+ end
11
+
12
+ # it "should preserve milliseconds" do
13
+ # doc = @document.new(:created_at => '2011-02-12 16:01:02.543Z')
14
+ # doc.created_at.should be_within(0.0000001).of(Time.parse('2011-02-12 16:01:02.543Z'))
15
+ # end
16
+
17
+ it "should work without Time.zone" do
18
+ Time.zone = nil
19
+
20
+ doc = @document.new(:created_at => "2009-08-15 14:00:00")
21
+ doc.created_at.should == Time.local(2009, 8, 15, 14, 0, 0).utc
22
+ end
23
+
24
+ it "should work with Time.zone set to the (default) UTC" do
25
+ Time.zone = 'UTC'
26
+
27
+ doc = @document.new(:created_at => "2009-08-15 14:00:00")
28
+ doc.created_at.is_a?(ActiveSupport::TimeWithZone).should be_truthy
29
+ doc.created_at.should == Time.utc(2009, 8, 15, 14)
30
+
31
+ Time.zone = nil
32
+ end
33
+
34
+ it "should work with timezones that are not UTC" do
35
+ Time.zone = 'Hawaii'
36
+
37
+ doc = @document.new(:created_at => "2009-08-15 14:00:00")
38
+ doc.created_at.is_a?(ActiveSupport::TimeWithZone).should be_truthy
39
+ doc.created_at.should == Time.utc(2009, 8, 16)
40
+
41
+ Time.zone = nil
42
+ end
43
+ end
44
+ end