honkster-friendly 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. data/.document +2 -0
  2. data/.gitignore +26 -0
  3. data/APACHE-LICENSE +202 -0
  4. data/CHANGELOG.md +28 -0
  5. data/CONTRIBUTORS.md +7 -0
  6. data/LICENSE +20 -0
  7. data/README.md +288 -0
  8. data/Rakefile +68 -0
  9. data/TODO.md +5 -0
  10. data/VERSION +1 -0
  11. data/examples/friendly.yml +7 -0
  12. data/friendly.gemspec +240 -0
  13. data/lib/friendly.rb +53 -0
  14. data/lib/friendly/associations.rb +7 -0
  15. data/lib/friendly/associations/association.rb +34 -0
  16. data/lib/friendly/associations/set.rb +37 -0
  17. data/lib/friendly/attribute.rb +98 -0
  18. data/lib/friendly/boolean.rb +10 -0
  19. data/lib/friendly/cache.rb +24 -0
  20. data/lib/friendly/cache/by_id.rb +33 -0
  21. data/lib/friendly/data_store.rb +73 -0
  22. data/lib/friendly/document.rb +70 -0
  23. data/lib/friendly/document/associations.rb +50 -0
  24. data/lib/friendly/document/attributes.rb +114 -0
  25. data/lib/friendly/document/convenience.rb +41 -0
  26. data/lib/friendly/document/mixin.rb +15 -0
  27. data/lib/friendly/document/scoping.rb +66 -0
  28. data/lib/friendly/document/storage.rb +63 -0
  29. data/lib/friendly/document_table.rb +56 -0
  30. data/lib/friendly/index.rb +73 -0
  31. data/lib/friendly/indexer.rb +50 -0
  32. data/lib/friendly/memcached.rb +48 -0
  33. data/lib/friendly/newrelic.rb +6 -0
  34. data/lib/friendly/query.rb +42 -0
  35. data/lib/friendly/scope.rb +100 -0
  36. data/lib/friendly/scope_proxy.rb +43 -0
  37. data/lib/friendly/sequel_monkey_patches.rb +34 -0
  38. data/lib/friendly/storage.rb +31 -0
  39. data/lib/friendly/storage_factory.rb +24 -0
  40. data/lib/friendly/storage_proxy.rb +111 -0
  41. data/lib/friendly/table.rb +15 -0
  42. data/lib/friendly/table_creator.rb +48 -0
  43. data/lib/friendly/time.rb +14 -0
  44. data/lib/friendly/translator.rb +33 -0
  45. data/lib/friendly/uuid.rb +148 -0
  46. data/lib/tasks/friendly.rake +7 -0
  47. data/rails/init.rb +6 -0
  48. data/spec/config.yml.example +7 -0
  49. data/spec/fakes/data_store_fake.rb +29 -0
  50. data/spec/fakes/database_fake.rb +12 -0
  51. data/spec/fakes/dataset_fake.rb +28 -0
  52. data/spec/fakes/document.rb +18 -0
  53. data/spec/fakes/serializer_fake.rb +12 -0
  54. data/spec/fakes/time_fake.rb +12 -0
  55. data/spec/integration/ad_hoc_scopes_spec.rb +42 -0
  56. data/spec/integration/basic_object_lifecycle_spec.rb +114 -0
  57. data/spec/integration/batch_insertion_spec.rb +29 -0
  58. data/spec/integration/convenience_api_spec.rb +25 -0
  59. data/spec/integration/count_spec.rb +12 -0
  60. data/spec/integration/default_value_spec.rb +30 -0
  61. data/spec/integration/dirty_tracking_spec.rb +43 -0
  62. data/spec/integration/find_via_cache_spec.rb +101 -0
  63. data/spec/integration/finder_spec.rb +71 -0
  64. data/spec/integration/has_many_spec.rb +18 -0
  65. data/spec/integration/index_spec.rb +57 -0
  66. data/spec/integration/named_scope_spec.rb +34 -0
  67. data/spec/integration/offline_indexing_spec.rb +53 -0
  68. data/spec/integration/pagination_spec.rb +63 -0
  69. data/spec/integration/scope_chaining_spec.rb +22 -0
  70. data/spec/integration/table_creator_spec.rb +64 -0
  71. data/spec/integration/write_through_cache_spec.rb +53 -0
  72. data/spec/spec.opts +1 -0
  73. data/spec/spec_helper.rb +105 -0
  74. data/spec/unit/associations/association_spec.rb +57 -0
  75. data/spec/unit/associations/set_spec.rb +43 -0
  76. data/spec/unit/attribute_spec.rb +125 -0
  77. data/spec/unit/cache_by_id_spec.rb +102 -0
  78. data/spec/unit/cache_spec.rb +21 -0
  79. data/spec/unit/data_store_spec.rb +201 -0
  80. data/spec/unit/document/attributes_spec.rb +130 -0
  81. data/spec/unit/document_spec.rb +318 -0
  82. data/spec/unit/document_table_spec.rb +126 -0
  83. data/spec/unit/friendly_spec.rb +25 -0
  84. data/spec/unit/index_spec.rb +196 -0
  85. data/spec/unit/memcached_spec.rb +114 -0
  86. data/spec/unit/query_spec.rb +104 -0
  87. data/spec/unit/scope_proxy_spec.rb +44 -0
  88. data/spec/unit/scope_spec.rb +113 -0
  89. data/spec/unit/storage_factory_spec.rb +59 -0
  90. data/spec/unit/storage_proxy_spec.rb +244 -0
  91. data/spec/unit/translator_spec.rb +91 -0
  92. data/website/index.html +210 -0
  93. data/website/scripts/clipboard.swf +0 -0
  94. data/website/scripts/shBrushAS3.js +61 -0
  95. data/website/scripts/shBrushBash.js +66 -0
  96. data/website/scripts/shBrushCSharp.js +67 -0
  97. data/website/scripts/shBrushColdFusion.js +102 -0
  98. data/website/scripts/shBrushCpp.js +99 -0
  99. data/website/scripts/shBrushCss.js +93 -0
  100. data/website/scripts/shBrushDelphi.js +57 -0
  101. data/website/scripts/shBrushDiff.js +43 -0
  102. data/website/scripts/shBrushErlang.js +54 -0
  103. data/website/scripts/shBrushGroovy.js +69 -0
  104. data/website/scripts/shBrushJScript.js +52 -0
  105. data/website/scripts/shBrushJava.js +59 -0
  106. data/website/scripts/shBrushJavaFX.js +60 -0
  107. data/website/scripts/shBrushPerl.js +74 -0
  108. data/website/scripts/shBrushPhp.js +91 -0
  109. data/website/scripts/shBrushPlain.js +35 -0
  110. data/website/scripts/shBrushPowerShell.js +76 -0
  111. data/website/scripts/shBrushPython.js +66 -0
  112. data/website/scripts/shBrushRuby.js +57 -0
  113. data/website/scripts/shBrushScala.js +53 -0
  114. data/website/scripts/shBrushSql.js +68 -0
  115. data/website/scripts/shBrushVb.js +58 -0
  116. data/website/scripts/shBrushXml.js +71 -0
  117. data/website/scripts/shCore.js +30 -0
  118. data/website/scripts/shLegacy.js +30 -0
  119. data/website/styles/friendly.css +103 -0
  120. data/website/styles/help.png +0 -0
  121. data/website/styles/ie.css +35 -0
  122. data/website/styles/magnifier.png +0 -0
  123. data/website/styles/page_white_code.png +0 -0
  124. data/website/styles/page_white_copy.png +0 -0
  125. data/website/styles/print.css +29 -0
  126. data/website/styles/printer.png +0 -0
  127. data/website/styles/screen.css +257 -0
  128. data/website/styles/shCore.css +330 -0
  129. data/website/styles/shThemeDefault.css +173 -0
  130. data/website/styles/shThemeDjango.css +176 -0
  131. data/website/styles/shThemeEclipse.css +190 -0
  132. data/website/styles/shThemeEmacs.css +175 -0
  133. data/website/styles/shThemeFadeToGrey.css +177 -0
  134. data/website/styles/shThemeMidnight.css +175 -0
  135. data/website/styles/shThemeRDark.css +175 -0
  136. metadata +337 -0
@@ -0,0 +1,113 @@
1
+ require File.expand_path("../../spec_helper", __FILE__)
2
+
3
+ describe "Friendly::Scope" do
4
+ before do
5
+ @klass = stub
6
+ @scope_parameters = {:name => "Quagmire", :order! => :created_at.desc}
7
+ @scope = Friendly::Scope.new(@klass, @scope_parameters)
8
+ end
9
+
10
+ describe "#all" do
11
+ before do
12
+ @documents = stub
13
+ end
14
+
15
+ it "delegates to klass with the scope parameters" do
16
+ @klass.stubs(:all).with(@scope_parameters).returns(@documents)
17
+ @scope.all.should == @documents
18
+ end
19
+
20
+ it "merges additional parameters" do
21
+ merged = @scope_parameters.merge(:name => "Joe")
22
+ @klass.stubs(:all).with(merged).returns(@documents)
23
+ @scope.all(:name => "Joe").should == @documents
24
+ end
25
+ end
26
+
27
+ describe "#first" do
28
+ before do
29
+ @document = stub
30
+ end
31
+
32
+ it "delegates to klass with the scope parameters" do
33
+ @klass.stubs(:first).with(@scope_parameters).returns(@document)
34
+ @scope.first.should == @document
35
+ end
36
+
37
+ it "merges additional parameters" do
38
+ merged = @scope_parameters.merge(:name => "Joe")
39
+ @klass.stubs(:first).with(merged).returns(@document)
40
+ @scope.first(:name => "Joe").should == @document
41
+ end
42
+ end
43
+
44
+ describe "#paginate" do
45
+ before do
46
+ @documents = stub
47
+ end
48
+
49
+ it "delegates to klass with the scope parameters" do
50
+ @klass.stubs(:paginate).with(@scope_parameters).returns(@documents)
51
+ @scope.paginate.should == @documents
52
+ end
53
+
54
+ it "merges additional parameters" do
55
+ merged = @scope_parameters.merge(:name => "Joe")
56
+ @klass.stubs(:paginate).with(merged).returns(@documents)
57
+ @scope.paginate(:name => "Joe").should == @documents
58
+ end
59
+ end
60
+
61
+ describe "#build" do
62
+ it "instantiates klass with the scope parameters (minus modifiers)" do
63
+ @doc = stub
64
+ @klass.stubs(:new).with(:name => "Quagmire").returns(@doc)
65
+ @scope.build.should == @doc
66
+ end
67
+
68
+ it "merges additional parameters" do
69
+ @doc = stub
70
+ @klass.stubs(:new).with(:name => "Fred").returns(@doc)
71
+ @scope.build(:name => "Fred").should == @doc
72
+ end
73
+ end
74
+
75
+ describe "#create" do
76
+ it "delegates to klass#create with the scope parameters (minus modifiers)" do
77
+ @doc = stub
78
+ @klass.stubs(:create).with(:name => "Quagmire").returns(@doc)
79
+ @scope.create.should == @doc
80
+ end
81
+
82
+ it "merges additional parameters" do
83
+ @doc = stub
84
+ @klass.stubs(:create).with(:name => "Fred").returns(@doc)
85
+ @scope.create(:name => "Fred").should == @doc
86
+ end
87
+ end
88
+
89
+ describe "chaining another named scope" do
90
+ before do
91
+ @recent_params = {:order! => :created_at.desc}
92
+ @recent = Friendly::Scope.new(@klass, @recent_params)
93
+ @klass.stubs(:has_named_scope?).with(:recent).returns(true)
94
+ @klass.stubs(:recent).returns(@recent)
95
+ @scope_params = {:name => "Joe"}
96
+ @scope = Friendly::Scope.new(@klass, @scope_params)
97
+ end
98
+
99
+ it "responds to the other scope method" do
100
+ @scope.should be_respond_to(:recent)
101
+ end
102
+
103
+ it "creates a new scope that merges the two scopes together" do
104
+ merged_parameters = @scope_params.merge(@recent_params)
105
+ @scope.recent.parameters.should == merged_parameters
106
+ end
107
+
108
+ it "gives precedence to scopes on the right" do
109
+ @quagmire = Friendly::Scope.new(@klass, :name => "Quagmire")
110
+ (@scope + @quagmire).parameters[:name].should == "Quagmire"
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,59 @@
1
+ require File.expand_path("../../spec_helper", __FILE__)
2
+
3
+ describe "Friendly::StorageFactory" do
4
+ before do
5
+ @doc_table = stub
6
+ @doc_table_klass = stub(:new => @doc_table)
7
+ @index = stub
8
+ @index_klass = stub(:new => @index)
9
+ @cache_by_id = stub
10
+ @cache_klass = stub(:cache_for => @cache_by_id)
11
+ @factory = Friendly::StorageFactory.new(@doc_table_klass, @index_klass,
12
+ @cache_klass)
13
+ end
14
+
15
+ describe "creating a document table" do
16
+ before do
17
+ @klass = stub
18
+ @returned = @factory.document_table(@klass)
19
+ end
20
+
21
+ it "returns the result of the constructor" do
22
+ @returned.should == @doc_table
23
+ end
24
+
25
+ it "passes along the arguments to the constructor" do
26
+ @doc_table_klass.should have_received(:new).with(@klass)
27
+ end
28
+ end
29
+
30
+ describe "creating an index table" do
31
+ before do
32
+ @klass = stub
33
+ @returned = @factory.index(@klass)
34
+ end
35
+
36
+ it "returns the result of the constructor" do
37
+ @returned.should == @index
38
+ end
39
+
40
+ it "passes along the arguments to the constructor" do
41
+ @index_klass.should have_received(:new).with(@klass)
42
+ end
43
+ end
44
+
45
+ describe "creating an id cache table" do
46
+ before do
47
+ @klass = stub
48
+ @returned = @factory.cache(@klass, [:id])
49
+ end
50
+
51
+ it "delegates to Cache.for" do
52
+ @returned.should == @cache_by_id
53
+ end
54
+
55
+ it "supplies arguments to Cache" do
56
+ @cache_klass.should have_received(:cache_for).with(@klass, [:id])
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,244 @@
1
+ require File.expand_path("../../spec_helper", __FILE__)
2
+
3
+ describe "Friendly::StorageProxy" do
4
+ before do
5
+ @klass = stub
6
+ @index = stub(:create => nil,
7
+ :update => nil,
8
+ :destroy => nil,
9
+ :satsifies? => nil)
10
+ @table = stub(:satisfies? => false, :create => nil,
11
+ :update => nil, :destroy => nil)
12
+ @storage_factory = stub(:index => @index)
13
+ @storage_factory.stubs(:document_table).with(@klass).returns(@table)
14
+ @storage = Friendly::StorageProxy.new(@klass, @storage_factory)
15
+ end
16
+
17
+ it "instantiates and adds a document table by default" do
18
+ @storage.tables.should include(@table)
19
+ end
20
+
21
+ describe "doing a `first`" do
22
+ before do
23
+ @id = stub
24
+ @index = stub(:satisfies? => true, :first => @id)
25
+ @storage.tables << @index
26
+ end
27
+
28
+ describe "when there's an index that matches the conditions" do
29
+ before do
30
+ @result = @storage.first(:name => "x")
31
+ end
32
+
33
+ it "delegates to the index that satisfies the conditions" do
34
+ @index.should have_received(:first).once
35
+ @index.should have_received(:first).with(:name => "x")
36
+ end
37
+
38
+ it "returns id" do
39
+ @result.should == @id
40
+ end
41
+ end
42
+
43
+ describe "when there's no index that matches" do
44
+ before do
45
+ @index.stubs(:satisfies?).returns(false)
46
+ end
47
+
48
+ it "raises MissingIndex" do
49
+ lambda {
50
+ @storage.first(:name => "x")
51
+ }.should raise_error(Friendly::MissingIndex)
52
+ end
53
+ end
54
+ end
55
+
56
+ describe "doing an `all`" do
57
+ before do
58
+ @ids = [stub]
59
+ @index = stub(:satisfies? => true, :all => @ids)
60
+ @storage.tables << @index
61
+ end
62
+
63
+ describe "when there's an index that matches the conditions" do
64
+ before do
65
+ @query = query(:name => "x")
66
+ @result = @storage.all(@query)
67
+ end
68
+
69
+ it "delegates to the index that satisfies the conditions" do
70
+ @index.should have_received(:all).once
71
+ @index.should have_received(:all).with(@query)
72
+ end
73
+
74
+ it "returns the results" do
75
+ @result.should == @ids
76
+ end
77
+ end
78
+
79
+ describe "when there's no index that matches" do
80
+ before do
81
+ @index.stubs(:satisfies?).returns(false)
82
+ end
83
+
84
+ it "raises MissingIndex" do
85
+ lambda {
86
+ @storage.all(:name => "x")
87
+ }.should raise_error(Friendly::MissingIndex)
88
+ end
89
+ end
90
+
91
+ describe "when :preserve_order is true" do
92
+ before do
93
+ @docs = [stub(:id => 4), stub(:id => 3), stub(:id => 2)]
94
+ @index.stubs(:all).returns(@docs)
95
+ @result = @storage.all(query(:id => [2,3,4], :preserve_order! => true))
96
+ end
97
+
98
+ it "sorts the results based on the order they're supplied in the query" do
99
+ @result.should == @docs.reverse
100
+ end
101
+ end
102
+ end
103
+
104
+ describe "adding an index to the set" do
105
+ before do
106
+ @storage.add(:name, :age)
107
+ end
108
+
109
+ it "creates an index" do
110
+ @storage_factory.should have_received(:index).once
111
+ @storage_factory.should have_received(:index).with(@klass, :name, :age)
112
+ end
113
+
114
+ it "adds the index to the set" do
115
+ @storage.tables.should include(@index)
116
+ end
117
+ end
118
+
119
+ describe "saving data" do
120
+ before do
121
+ @index_two = stub(:create => nil, :update => nil, :destroy => nil)
122
+ @storage_factory.stubs(:index).returns(@index).then.returns(@index_two)
123
+ @cache = stub(:create => nil, :update => nil, :destroy => nil)
124
+ @storage_factory.stubs(:cache).returns(@cache)
125
+ @storage.add(:name)
126
+ @storage.add(:age)
127
+ @storage.cache([:id])
128
+ @doc = stub
129
+ end
130
+
131
+ describe "on create" do
132
+ before do
133
+ @storage.create(@doc)
134
+ end
135
+
136
+ it "delegates to all of the storage including caches" do
137
+ @index.should have_received(:create).with(@doc)
138
+ @index_two.should have_received(:create).with(@doc)
139
+ @table.should have_received(:create).with(@doc)
140
+ @cache.should have_received(:create).with(@doc)
141
+ end
142
+ end
143
+
144
+ describe "on update" do
145
+ before do
146
+ @storage.update(@doc)
147
+ end
148
+
149
+ it "delegates to all of the storage including caches" do
150
+ @index.should have_received(:update).with(@doc)
151
+ @index_two.should have_received(:update).with(@doc)
152
+ @table.should have_received(:update).with(@doc)
153
+ @cache.should have_received(:update).with(@doc)
154
+ end
155
+ end
156
+
157
+ describe "on destroy" do
158
+ before do
159
+ @storage.destroy(@doc)
160
+ end
161
+
162
+ it "delegates to all of the storage including caches" do
163
+ @index.should have_received(:destroy).with(@doc)
164
+ @index_two.should have_received(:destroy).with(@doc)
165
+ @table.should have_received(:destroy).with(@doc)
166
+ @cache.should have_received(:destroy).with(@doc)
167
+ end
168
+ end
169
+ end
170
+
171
+ describe "adding a cache object" do
172
+ before do
173
+ @cache = stub
174
+ @storage_factory.stubs(:cache).returns(@cache)
175
+ @storage.cache([:id])
176
+ end
177
+
178
+ it "gets one from the storage_proxy" do
179
+ @storage_factory.should have_received(:cache).with(@klass, [:id], {})
180
+ end
181
+
182
+ it "adds it to its set of caches" do
183
+ @storage.caches.should include(@cache)
184
+ end
185
+ end
186
+
187
+ describe "finding with a matching cache" do
188
+ before do
189
+ @cache = stub(:satisfies? => true, :first => nil)
190
+ @storage_factory.stubs(:cache).returns(@cache)
191
+ @storage.cache([:id])
192
+ end
193
+
194
+ describe "when there's a hit" do
195
+ before do
196
+ @doc = stub
197
+ @cache.stubs(:first).returns(@doc)
198
+ end
199
+
200
+ it "returns the result from the cache" do
201
+ @storage.first(:id => "x").should == @doc
202
+ end
203
+ end
204
+ end
205
+
206
+ describe "counting objects" do
207
+ before do
208
+ @index = stub(:count => 10)
209
+ @index.stubs(:satisfies?).with(:x => 1).returns(true)
210
+ @storage_factory.stubs(:index).returns(@index)
211
+ @storage.add(:a)
212
+ end
213
+
214
+ it "delegates to a satisfying index" do
215
+ @storage.count(:x => 1).should == 10
216
+ end
217
+ end
218
+
219
+ describe "getting the index that matches a set of fields" do
220
+ before do
221
+ @storage_factory = stub(:document_table => @document_table)
222
+
223
+ [[:name, :created_at], [:name]].each do |fields|
224
+ @storage_factory.stubs(:index).
225
+ with(@klass, *fields).returns(stub(:fields => fields))
226
+ end
227
+
228
+ @storage = Friendly::StorageProxy.new(@klass, @storage_factory)
229
+ @storage.add(:name, :created_at)
230
+ @storage.add(:name)
231
+ end
232
+
233
+ it "matches if and only if all the fields are present and in order" do
234
+ @storage.index_for_fields([:name, :created_at]).fields.should ==
235
+ [:name, :created_at]
236
+ end
237
+
238
+ it "raises missing index if there's no matching index" do
239
+ lambda {
240
+ @storage.index_for_fields([:created_at, :name])
241
+ }.should raise_error(Friendly::MissingIndex)
242
+ end
243
+ end
244
+ end
@@ -0,0 +1,91 @@
1
+ require File.expand_path("../../spec_helper", __FILE__)
2
+ require 'ostruct'
3
+
4
+ describe "Friendly::Translator" do
5
+ before do
6
+ @serializer = stub
7
+ @time = stub
8
+ @translator = Friendly::Translator.new(@serializer, @time)
9
+ end
10
+
11
+ describe "translating a row to an object" do
12
+ before do
13
+ @serializer.stubs(:parse).with("THE JSON").returns(:name => "Stewie")
14
+ @time = Time.new
15
+ @row = {:added_id => 12345,
16
+ :created_at => @time,
17
+ :updated_at => @time,
18
+ :attributes => "THE JSON"}
19
+ @doc = stub
20
+ @klass = stub
21
+ @klass.stubs(:new_without_change_tracking).
22
+ with(:updated_at => @time, :new_record => false,
23
+ :name => "Stewie", :created_at => @time).returns(@doc)
24
+ end
25
+
26
+ it "creates a new object without change tracking" do
27
+ @translator.to_object(@klass, @row).should == @doc
28
+ end
29
+ end
30
+
31
+ describe "translating from a document in to a record" do
32
+ describe "when the document has yet to be saved" do
33
+ before do
34
+ @hash = {:name => "Stewie"}
35
+ @time.stubs(:new).returns(Time.new)
36
+ @serializer.stubs(:generate).with(@hash).returns("SOME JSON")
37
+ @document = stub(:to_hash => @hash,
38
+ :new_record? => true,
39
+ :created_at => nil,
40
+ :id => 12345)
41
+ @record = @translator.to_record(@document)
42
+ end
43
+
44
+ it "serializes the attributes" do
45
+ @record[:attributes].should == "SOME JSON"
46
+ end
47
+
48
+ it "sets updated_at" do
49
+ @record[:updated_at].should == @time.new
50
+ end
51
+
52
+ it "sets the id from the document" do
53
+ @record[:id].should == 12345
54
+ end
55
+ end
56
+
57
+ describe "when the document has already been saved" do
58
+ before do
59
+ @created_at = Time.new
60
+ @hash = {:name => "Stewie",
61
+ :id => 1,
62
+ :created_at => @created_at,
63
+ :updated_at => Time.new}
64
+ @time.stubs(:new).returns(Time.new + 5000)
65
+ @serializer.stubs(:generate).returns("SOME JSON")
66
+ @document = stub(:to_hash => @hash,
67
+ :created_at => @created_at,
68
+ :new_record? => false,
69
+ :id => 12345)
70
+ @record = @translator.to_record(@document)
71
+ end
72
+
73
+ it "serializes the attributes" do
74
+ @serializer.should have_received(:generate).with(:name => "Stewie")
75
+ @record[:attributes].should == "SOME JSON"
76
+ end
77
+
78
+ it "doesn't bump the created_at" do
79
+ @record[:created_at].should == @created_at
80
+ end
81
+
82
+ it "should bump the updated_at" do
83
+ @record[:updated_at].should == @time.new
84
+ end
85
+
86
+ it "takes the id from the documetn" do
87
+ @record[:id].should == 12345
88
+ end
89
+ end
90
+ end
91
+ end