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,37 @@
1
+ require 'spec_helper'
2
+
3
+ class Address; end
4
+
5
+ describe "MarkMapper" do
6
+ it "should be able to write and read connection" do
7
+ conn = MarkLogic::Connection.new(HOST, PORT)
8
+ MarkMapper.connection = conn
9
+ MarkMapper.connection.should == conn
10
+ end
11
+
12
+ it "should default connection to new marklogic ruby driver" do
13
+ MarkMapper.connection = nil
14
+ MarkMapper.connection.should be_instance_of(MarkLogic::Connection)
15
+ end
16
+
17
+ it "should be able to write and read default database" do
18
+ MarkMapper.database = 'test'
19
+ MarkMapper.database.should be_instance_of(MarkLogic::Database)
20
+ MarkMapper.database.database_name.should == 'test'
21
+ end
22
+
23
+ it "should have document not found error" do
24
+ lambda {
25
+ MarkMapper::DocumentNotFound
26
+ }.should_not raise_error
27
+ end
28
+
29
+ it "should be able to read/write config" do
30
+ config = {
31
+ 'development' => {'host' => '127.0.0.1', 'port' => 8006, 'database' => 'test'},
32
+ 'production' => {'host' => '127.0.0.1', 'port' => 8006, 'database' => 'test-prod'}
33
+ }
34
+ MarkMapper.config = config
35
+ MarkMapper.config.should == config
36
+ end
37
+ end
@@ -0,0 +1,45 @@
1
+ # require 'spec_helper'
2
+ # require 'rails/generators'
3
+ # require 'rails/generators/test_case'
4
+ # require 'rails/generators/mark_mapper/model/model_generator'
5
+
6
+ # describe MarkMapper::Generators::ModelGenerator do
7
+ # include GeneratorSpec::TestCase
8
+ # destination File.expand_path('../../tmp', File.dirname(__FILE__))
9
+
10
+ # before do
11
+ # prepare_destination
12
+ # end
13
+
14
+ # it 'help shows MarkMapper options' do
15
+ # content = run_generator ['--help']
16
+ # assert_match(/rails generate mark_mapper:model/, content)
17
+ # end
18
+
19
+ # it 'model are properly created' do
20
+ # run_generator ['Color']
21
+ # assert_file 'app/models/color.rb', /class Color/
22
+ # assert_file 'app/models/color.rb', /include MarkMapper::Document/
23
+ # end
24
+
25
+ # it 'model are properly created with attributes' do
26
+ # run_generator ['Color', 'name:string', 'saturation:integer']
27
+ # assert_file 'app/models/color.rb', /class Color/
28
+ # assert_file 'app/models/color.rb', /include MarkMapper::Document/
29
+ # assert_file 'app/models/color.rb', /key :name, String/
30
+ # assert_file 'app/models/color.rb', /key :saturation, Integer/
31
+ # end
32
+
33
+ # it 'model are properly created with timestamps option' do
34
+ # run_generator ['Color', '--timestamps']
35
+ # assert_file 'app/models/color.rb', /class Color/
36
+ # assert_file 'app/models/color.rb', /include MarkMapper::Document/
37
+ # assert_file 'app/models/color.rb', /timestamps/
38
+ # end
39
+
40
+ # it 'model are properly created with parent option' do
41
+ # run_generator ['Green', '--parent', 'Color']
42
+ # assert_file 'app/models/green.rb', /class Green < Color/
43
+ # end
44
+
45
+ # end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe MarkMapper::Normalizers::CriteriaHashKey do
4
+ subject {
5
+ described_class.new
6
+ }
7
+
8
+ context "with a string" do
9
+ it "returns symbol" do
10
+ subject.call('foo').should eq(:foo)
11
+ end
12
+ end
13
+
14
+ context "with a symbol" do
15
+ it "returns symbol" do
16
+ subject.call(:foo).should eq(:foo)
17
+ end
18
+ end
19
+
20
+ context "with :id" do
21
+ it "returns :_id" do
22
+ subject.call(:id).should eq(:_id)
23
+ end
24
+ end
25
+
26
+ it "returns key if something weird" do
27
+ subject.call(['crazytown']).should eq(['crazytown'])
28
+ end
29
+
30
+ SymbolOperators.each do |operator|
31
+ context "with #{operator} symbol operator" do
32
+ it "returns field" do
33
+ subject.call(:age.send(operator)).should eq(:age)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,200 @@
1
+ require 'spec_helper'
2
+ require 'securerandom'
3
+
4
+ describe MarkMapper::Normalizers::CriteriaHashValue do
5
+ let(:criteria_hash) { MarkMapper::CriteriaHash.new }
6
+
7
+ subject {
8
+ described_class.new(criteria_hash)
9
+ }
10
+
11
+ context "with a string" do
12
+ it "leaves string values for string keys alone" do
13
+ subject.call(:foo, :foo, 'bar').should eq('bar')
14
+ end
15
+
16
+ context "that is actually an object id" do
17
+ it "converts string values to object ids for object id keys" do
18
+ criteria_hash.object_ids = [:_id]
19
+ id = SecureRandom.hex
20
+ subject.call(:_id, :_id, id.to_s).should eq(id)
21
+ end
22
+ end
23
+ end
24
+
25
+ context "with a time" do
26
+ it "converts times to utc" do
27
+ time = Time.now
28
+ actual = time
29
+ expected = time.utc
30
+ result = subject.call(:foo, :foo, actual)
31
+ result.should be_utc
32
+ result.should eq(expected)
33
+ end
34
+
35
+ it "leaves utc times alone" do
36
+ time = Time.now
37
+ actual = time.utc
38
+ expected = time.utc
39
+ result = subject.call(:foo, :foo, actual)
40
+ result.should be_utc
41
+ result.should eq(expected)
42
+ end
43
+ end
44
+
45
+ context "with an array" do
46
+ it "defaults to $eq" do
47
+ actual = [1,2,3]
48
+ expected = {:$eq => [1,2,3]}
49
+ subject.call(:foo, :foo, actual).should eq(expected)
50
+ end
51
+
52
+ it "does not double up $eq" do
53
+ actual = [1, 2, 3]
54
+ expected = [1, 2, 3]
55
+ subject.call(:$eq, :$eq, actual).should eq(expected)
56
+ end
57
+
58
+ it "uses existing modifier if present" do
59
+ actual = {'$all' => [1,2,3]}
60
+ expected = {'$all' => [1,2,3]}
61
+ subject.call(:foo, :foo, actual).should eq(expected)
62
+
63
+ actual = {'$any' => [1,2,3]}
64
+ expected = {'$any' => [1,2,3]}
65
+ subject.call(:foo, :foo, actual).should eq(expected)
66
+ end
67
+
68
+ it "does not turn value to $eq with an empty array value" do
69
+ actual = []
70
+ expected = []
71
+ subject.call(:foo, :foo, actual).should eq(expected)
72
+ end
73
+
74
+ it "does not turn value to $eq with $or key" do
75
+ actual = [{:numbers => 1}, {:numbers => 2}]
76
+ expected = [{:numbers => 1}, {:numbers => 2}]
77
+ subject.call(:$or, :$or, actual).should eq(expected)
78
+ end
79
+
80
+ it "does not turn value to $eq with $and key" do
81
+ actual = [{:numbers => 1}, {:numbers => 2}]
82
+ expected = [{:numbers => 1}, {:numbers => 2}]
83
+ subject.call(:$and, :$and, actual).should eq(expected)
84
+ end
85
+
86
+ it "does not turn value to $eq with $nor key" do
87
+ actual = [{:numbers => 1}, {:numbers => 2}]
88
+ expected = [{:numbers => 1}, {:numbers => 2}]
89
+ subject.call(:$nor, :$nor, actual).should eq(expected)
90
+ end
91
+
92
+ it "defaults to $eq even with ObjectId keys" do
93
+ actual = [1,2,3]
94
+ expected = {:$eq => [1,2,3]}
95
+ criteria_hash.object_ids = [:mistake_id]
96
+ subject.call(:mistake_id, :mistake_id, actual).should eq(expected)
97
+ end
98
+ end
99
+
100
+ context "with a set" do
101
+ it "defaults to $eq and convert to array" do
102
+ actual = [1,2,3].to_set
103
+ expected = {:$eq => [1,2,3]}
104
+ subject.call(:numbers, :numbers, actual).should eq(expected)
105
+ end
106
+
107
+ it "uses existing modifier if present and convert to array" do
108
+ actual = {'$all' => [1,2,3].to_set}
109
+ expected = {'$all' => [1,2,3]}
110
+ subject.call(:foo, :foo, actual).should eq(expected)
111
+
112
+ actual = {'$any' => [1,2,3].to_set}
113
+ expected = {'$any' => [1,2,3]}
114
+ subject.call(:foo, :foo, actual).should eq(expected)
115
+ end
116
+ end
117
+
118
+ context "with string object ids for string keys" do
119
+ let(:object_id) { SecureRandom.hex }
120
+
121
+ it "leaves string ids as strings" do
122
+ subject.call(:_id, :_id, object_id.to_s).should eq(object_id.to_s)
123
+ subject.call(:room_id, :room_id, object_id.to_s).should eq(object_id.to_s)
124
+ end
125
+ end
126
+
127
+ context "with string object ids for object id keys" do
128
+ let(:object_id) { SecureRandom.hex }
129
+
130
+ before do
131
+ criteria_hash.object_ids = [:_id, :room_id]
132
+ end
133
+
134
+ it "converts strings to object ids" do
135
+ subject.call(:_id, :_id, object_id.to_s).should eq(object_id)
136
+ subject.call(:room_id, :room_id, object_id.to_s).should eq(object_id)
137
+ end
138
+
139
+ context "nested with modifier" do
140
+ let(:oid1) { SecureRandom.hex }
141
+ let(:oid2) { SecureRandom.hex }
142
+ let(:oids) { [oid1.to_s, oid2.to_s] }
143
+
144
+ it "converts strings to object ids" do
145
+ actual = {:$eq => oids}
146
+ expected = {:$eq => [oid1, oid2]}
147
+ subject.call(:_id, :_id, actual).should eq(expected)
148
+ end
149
+
150
+ it "does not modify original array of string ids" do
151
+ subject.call(:_id, :_id, {:$eq => oids})
152
+ oids.should == [oid1.to_s, oid2.to_s]
153
+ end
154
+ end
155
+ end
156
+
157
+ context "nested clauses" do
158
+ it "knows constant array of operators that take nested queries" do
159
+ described_class::NestingOperators.should == [:$or, :$and, :$nor]
160
+ end
161
+
162
+ described_class::NestingOperators.each do |operator|
163
+ context "with #{operator}" do
164
+ it "works with symbol operators" do
165
+ nested1 = {:age.gt => 12, :age.lt => 20}
166
+ translated1 = {:age => {:$gt => 12, :$lt => 20 }}
167
+ nested2 = {:type.eq => ['friend', 'enemy']}
168
+ translated2 = {:type => {:$eq => ['friend', 'enemy']}}
169
+ value = [nested1, nested2]
170
+ expected = [translated1, translated2]
171
+
172
+ subject.call(operator, operator, value).should eq(expected)
173
+ end
174
+
175
+ it "honors criteria hash options" do
176
+ nested = [{:post_id => '4f5ead6378fca23a13000001'}]
177
+ translated = [{:post_id => '4f5ead6378fca23a13000001'}]
178
+ given = {operator.to_s => [nested]}
179
+
180
+ criteria_hash.object_ids = [:post_id]
181
+ subject.call(operator, operator, nested).should eq(translated)
182
+ end
183
+ end
184
+ end
185
+
186
+ context "doubly nested" do
187
+ it "works with symbol operators" do
188
+ nested1 = {:age.gt => 12, :age.lt => 20}
189
+ translated1 = {:age => {:$gt => 12, :$lt => 20}}
190
+ nested2 = {:type.eq => ['friend', 'enemy']}
191
+ translated2 = {:type => {:$eq => ['friend', 'enemy']}}
192
+ nested3 = {'$and' => [nested2]}
193
+ translated3 = {:$and => [translated2]}
194
+ expected = [translated1, translated3]
195
+
196
+ subject.call(:$or, :$or, [nested1, nested3]).should eq(expected)
197
+ end
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+ require 'mark_mapper/normalizers/fields_value'
3
+
4
+ describe MarkMapper::Normalizers::FieldsValue do
5
+ it "defaults to nil" do
6
+ subject.call(nil).should be_nil
7
+ end
8
+
9
+ it "returns nil if empty string" do
10
+ subject.call('').should be_nil
11
+ end
12
+
13
+ it "returns nil if empty array" do
14
+ subject.call([]).should be_nil
15
+ end
16
+
17
+ it "works with array" do
18
+ subject.call(['one', 'two']).should eq(['one', 'two'])
19
+ end
20
+
21
+ # Ruby 1.9.x was sending array [{:age => 20}], instead of hash.
22
+ it "works with array that has one hash" do
23
+ subject.call([{:age => 20}]).should eq({:age => 20})
24
+ end
25
+
26
+ it "flattens multi-dimensional array" do
27
+ subject.call([[:one, :two]]).should eq([:one, :two])
28
+ end
29
+
30
+ it "works with symbol" do
31
+ subject.call(:one).should eq([:one])
32
+ end
33
+
34
+ it "works with array of symbols" do
35
+ subject.call([:one, :two]).should eq([:one, :two])
36
+ end
37
+
38
+ it "works with hash" do
39
+ subject.call({:one => 1, :two => -1}).should eq({:one => 1, :two => -1})
40
+ end
41
+
42
+ it "converts comma separated list to array" do
43
+ subject.call('one, two').should eq(['one', 'two'])
44
+ end
45
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe MarkMapper::Normalizers::HashKey do
4
+ subject {
5
+ described_class.new(:bacon => :sizzle)
6
+ }
7
+
8
+ it "changes defined fields" do
9
+ subject.call(:bacon).should eq(:sizzle)
10
+ end
11
+
12
+ it "does not change undefined fields" do
13
+ subject.call(:sausage).should eq(:sausage)
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ require 'mark_mapper/normalizers/integer'
3
+
4
+ describe MarkMapper::Normalizers::Integer do
5
+ context "with nil" do
6
+ it "returns nil" do
7
+ subject.call(nil).should be_nil
8
+ end
9
+ end
10
+
11
+ context "with an integer" do
12
+ it "returns an integer" do
13
+ subject.call(1).should be(1)
14
+ subject.call(3232).should be(3232)
15
+ end
16
+ end
17
+
18
+ context "with a string" do
19
+ it "returns a string" do
20
+ subject.call('1').should be(1)
21
+ subject.call('3232').should be(3232)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,99 @@
1
+ require 'spec_helper'
2
+
3
+ describe MarkMapper::Normalizers::OptionsHashValue do
4
+ let(:key_normalizer) {
5
+ lambda { |key|
6
+ if key == :id
7
+ :_id
8
+ else
9
+ key.to_sym
10
+ end
11
+ }
12
+ }
13
+
14
+ let(:upcasing_normalizer) {
15
+ lambda { |value| value.to_s.upcase }
16
+ }
17
+
18
+ let(:default_arguments) {
19
+ {
20
+ :key_normalizer => key_normalizer,
21
+ }
22
+ }
23
+
24
+ subject {
25
+ described_class.new(default_arguments)
26
+ }
27
+
28
+ it "raises exception if missing key normalizer" do
29
+ expect {
30
+ described_class.new
31
+ }.to raise_error(ArgumentError, "Missing required key :key_normalizer")
32
+ end
33
+
34
+ it "allows injecting a new value normalizer" do
35
+ instance = described_class.new(default_arguments.merge({
36
+ :value_normalizers => {
37
+ :some_field => upcasing_normalizer,
38
+ }
39
+ }))
40
+
41
+ instance.call(:some_field, 'upcase me').should eq('UPCASE ME')
42
+ end
43
+
44
+ context "with :fields key" do
45
+ subject {
46
+ described_class.new(default_arguments.merge({
47
+ :value_normalizers => {
48
+ :fields => upcasing_normalizer
49
+ },
50
+ }))
51
+ }
52
+
53
+ it "calls the fields value normalizer" do
54
+ subject.call(:fields, :foo).should eq('FOO')
55
+ end
56
+ end
57
+
58
+ context "with :sort key" do
59
+ subject {
60
+ described_class.new(default_arguments.merge({
61
+ :value_normalizers => {
62
+ :sort => upcasing_normalizer
63
+ },
64
+ }))
65
+ }
66
+
67
+ it "calls the sort value normalizer" do
68
+ subject.call(:sort, :foo).should eq('FOO')
69
+ end
70
+ end
71
+
72
+ context "with :limit key" do
73
+ subject {
74
+ described_class.new(default_arguments.merge({
75
+ :value_normalizers => {
76
+ :limit => upcasing_normalizer
77
+ },
78
+ }))
79
+ }
80
+
81
+ it "calls the limit value normalizer" do
82
+ subject.call(:limit, :foo).should eq('FOO')
83
+ end
84
+ end
85
+
86
+ context "with :skip key" do
87
+ subject {
88
+ described_class.new(default_arguments.merge({
89
+ :value_normalizers => {
90
+ :skip => upcasing_normalizer
91
+ },
92
+ }))
93
+ }
94
+
95
+ it "calls the skip value normalizer" do
96
+ subject.call(:skip, :foo).should eq('FOO')
97
+ end
98
+ end
99
+ end