friendly_postgres 0.4.3

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 (129) hide show
  1. data/.document +2 -0
  2. data/.gitignore +26 -0
  3. data/APACHE-LICENSE +202 -0
  4. data/CHANGELOG.md +19 -0
  5. data/CONTRIBUTORS.md +7 -0
  6. data/LICENSE +20 -0
  7. data/README.md +265 -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 +232 -0
  13. data/lib/friendly.rb +54 -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 +91 -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/config.rb +5 -0
  22. data/lib/friendly/data_store.rb +72 -0
  23. data/lib/friendly/document.rb +257 -0
  24. data/lib/friendly/document_table.rb +56 -0
  25. data/lib/friendly/index.rb +73 -0
  26. data/lib/friendly/memcached.rb +48 -0
  27. data/lib/friendly/named_scope.rb +17 -0
  28. data/lib/friendly/newrelic.rb +6 -0
  29. data/lib/friendly/query.rb +42 -0
  30. data/lib/friendly/scope.rb +100 -0
  31. data/lib/friendly/scope_proxy.rb +45 -0
  32. data/lib/friendly/sequel_monkey_patches.rb +34 -0
  33. data/lib/friendly/storage.rb +31 -0
  34. data/lib/friendly/storage_factory.rb +24 -0
  35. data/lib/friendly/storage_proxy.rb +103 -0
  36. data/lib/friendly/table.rb +15 -0
  37. data/lib/friendly/table_creator.rb +48 -0
  38. data/lib/friendly/time.rb +14 -0
  39. data/lib/friendly/translator.rb +32 -0
  40. data/lib/friendly/uuid.rb +148 -0
  41. data/rails/init.rb +3 -0
  42. data/spec/config.yml.example +7 -0
  43. data/spec/fakes/data_store_fake.rb +29 -0
  44. data/spec/fakes/database_fake.rb +12 -0
  45. data/spec/fakes/dataset_fake.rb +28 -0
  46. data/spec/fakes/document.rb +18 -0
  47. data/spec/fakes/serializer_fake.rb +12 -0
  48. data/spec/fakes/time_fake.rb +12 -0
  49. data/spec/integration/ad_hoc_scopes_spec.rb +42 -0
  50. data/spec/integration/basic_object_lifecycle_spec.rb +114 -0
  51. data/spec/integration/batch_insertion_spec.rb +29 -0
  52. data/spec/integration/convenience_api_spec.rb +25 -0
  53. data/spec/integration/count_spec.rb +12 -0
  54. data/spec/integration/default_value_spec.rb +15 -0
  55. data/spec/integration/find_via_cache_spec.rb +101 -0
  56. data/spec/integration/finder_spec.rb +64 -0
  57. data/spec/integration/has_many_spec.rb +18 -0
  58. data/spec/integration/index_spec.rb +57 -0
  59. data/spec/integration/named_scope_spec.rb +34 -0
  60. data/spec/integration/pagination_spec.rb +63 -0
  61. data/spec/integration/scope_chaining_spec.rb +22 -0
  62. data/spec/integration/table_creator_spec.rb +64 -0
  63. data/spec/integration/write_through_cache_spec.rb +53 -0
  64. data/spec/spec.opts +1 -0
  65. data/spec/spec_helper.rb +103 -0
  66. data/spec/unit/associations/association_spec.rb +57 -0
  67. data/spec/unit/associations/set_spec.rb +43 -0
  68. data/spec/unit/attribute_spec.rb +105 -0
  69. data/spec/unit/cache_by_id_spec.rb +102 -0
  70. data/spec/unit/cache_spec.rb +21 -0
  71. data/spec/unit/config_spec.rb +4 -0
  72. data/spec/unit/data_store_spec.rb +188 -0
  73. data/spec/unit/document_spec.rb +358 -0
  74. data/spec/unit/document_table_spec.rb +126 -0
  75. data/spec/unit/friendly_spec.rb +25 -0
  76. data/spec/unit/index_spec.rb +196 -0
  77. data/spec/unit/memcached_spec.rb +114 -0
  78. data/spec/unit/named_scope_spec.rb +16 -0
  79. data/spec/unit/query_spec.rb +104 -0
  80. data/spec/unit/scope_proxy_spec.rb +44 -0
  81. data/spec/unit/scope_spec.rb +113 -0
  82. data/spec/unit/storage_factory_spec.rb +59 -0
  83. data/spec/unit/storage_proxy_spec.rb +218 -0
  84. data/spec/unit/translator_spec.rb +96 -0
  85. data/website/index.html +210 -0
  86. data/website/scripts/clipboard.swf +0 -0
  87. data/website/scripts/shBrushAS3.js +61 -0
  88. data/website/scripts/shBrushBash.js +66 -0
  89. data/website/scripts/shBrushCSharp.js +67 -0
  90. data/website/scripts/shBrushColdFusion.js +102 -0
  91. data/website/scripts/shBrushCpp.js +99 -0
  92. data/website/scripts/shBrushCss.js +93 -0
  93. data/website/scripts/shBrushDelphi.js +57 -0
  94. data/website/scripts/shBrushDiff.js +43 -0
  95. data/website/scripts/shBrushErlang.js +54 -0
  96. data/website/scripts/shBrushGroovy.js +69 -0
  97. data/website/scripts/shBrushJScript.js +52 -0
  98. data/website/scripts/shBrushJava.js +59 -0
  99. data/website/scripts/shBrushJavaFX.js +60 -0
  100. data/website/scripts/shBrushPerl.js +74 -0
  101. data/website/scripts/shBrushPhp.js +91 -0
  102. data/website/scripts/shBrushPlain.js +35 -0
  103. data/website/scripts/shBrushPowerShell.js +76 -0
  104. data/website/scripts/shBrushPython.js +66 -0
  105. data/website/scripts/shBrushRuby.js +57 -0
  106. data/website/scripts/shBrushScala.js +53 -0
  107. data/website/scripts/shBrushSql.js +68 -0
  108. data/website/scripts/shBrushVb.js +58 -0
  109. data/website/scripts/shBrushXml.js +71 -0
  110. data/website/scripts/shCore.js +30 -0
  111. data/website/scripts/shLegacy.js +30 -0
  112. data/website/styles/friendly.css +103 -0
  113. data/website/styles/help.png +0 -0
  114. data/website/styles/ie.css +35 -0
  115. data/website/styles/magnifier.png +0 -0
  116. data/website/styles/page_white_code.png +0 -0
  117. data/website/styles/page_white_copy.png +0 -0
  118. data/website/styles/print.css +29 -0
  119. data/website/styles/printer.png +0 -0
  120. data/website/styles/screen.css +257 -0
  121. data/website/styles/shCore.css +330 -0
  122. data/website/styles/shThemeDefault.css +173 -0
  123. data/website/styles/shThemeDjango.css +176 -0
  124. data/website/styles/shThemeEclipse.css +190 -0
  125. data/website/styles/shThemeEmacs.css +175 -0
  126. data/website/styles/shThemeFadeToGrey.css +177 -0
  127. data/website/styles/shThemeMidnight.css +175 -0
  128. data/website/styles/shThemeRDark.css +175 -0
  129. metadata +302 -0
@@ -0,0 +1,44 @@
1
+ require File.expand_path("../../spec_helper", __FILE__)
2
+
3
+ describe "Friendly::ScopeProxy" do
4
+ before do
5
+ @klass = Class.new
6
+ @scope = stub
7
+ @scope_klass = stub
8
+ @scope_proxy = Friendly::ScopeProxy.new(@klass, @scope_klass)
9
+ @params = {:order! => :created_at.desc}
10
+ @scope_klass.stubs(:new).with(@klass, @params).returns(@scope)
11
+ @klass.stubs(:scope_proxy).returns(@scope_proxy)
12
+ @scope_proxy.add_named(:recent, @params)
13
+ end
14
+
15
+ it "returns false for has_named_scope if it doesnt have one by that name" do
16
+ @scope_proxy.should_not be_has_named_scope(:whatever)
17
+ end
18
+
19
+ describe "adding a scope" do
20
+ it "adds a scope by that name to the set" do
21
+ @scope_proxy.get(:recent).should == @params
22
+ end
23
+
24
+ it "adds a method to the klass that returns an instance of the scope" do
25
+ @klass.recent.should == @scope
26
+ end
27
+
28
+ it "returns true for #has_named_scope?(name)" do
29
+ @scope_proxy.should be_has_named_scope(:recent)
30
+ end
31
+ end
32
+
33
+ describe "getting an instance of a scope" do
34
+ it "instantiates Scope" do
35
+ @scope_proxy.get_instance(:recent).should == @scope
36
+ end
37
+ end
38
+
39
+ describe "accessing an ad_hoc scope" do
40
+ it "instantiates Scope" do
41
+ @scope_proxy.ad_hoc(@params).should == @scope
42
+ end
43
+ end
44
+ end
@@ -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,218 @@
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
+ end
@@ -0,0 +1,96 @@
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
+ @klass = FakeDocument
20
+ @doc = @translator.to_object(@klass, @row)
21
+ end
22
+
23
+ it "creates a klass with the attributes from the json" do
24
+ @doc.name.should == "Stewie"
25
+ end
26
+
27
+ it "sets updated_at" do
28
+ @doc.updated_at.should == @time
29
+ end
30
+
31
+ it "sets new_record to false" do
32
+ @doc.new_record.should be_false
33
+ end
34
+ end
35
+
36
+ describe "translating from a document in to a record" do
37
+ describe "when the document has yet to be saved" do
38
+ before do
39
+ @hash = {:name => "Stewie"}
40
+ @time.stubs(:new).returns(Time.new)
41
+ @serializer.stubs(:generate).with(@hash).returns("SOME JSON")
42
+ @document = stub(:to_hash => @hash,
43
+ :new_record? => true,
44
+ :created_at => nil,
45
+ :id => 12345)
46
+ @record = @translator.to_record(@document)
47
+ end
48
+
49
+ it "serializes the attributes" do
50
+ @record[:attributes].should == "SOME JSON"
51
+ end
52
+
53
+ it "sets updated_at" do
54
+ @record[:updated_at].should == @time.new
55
+ end
56
+
57
+ it "sets the id from the document" do
58
+ @record[:id].should == 12345
59
+ end
60
+ end
61
+
62
+ describe "when the document has already been saved" do
63
+ before do
64
+ @created_at = Time.new
65
+ @hash = {:name => "Stewie",
66
+ :id => 1,
67
+ :created_at => @created_at,
68
+ :updated_at => Time.new}
69
+ @time.stubs(:new).returns(Time.new + 5000)
70
+ @serializer.stubs(:generate).returns("SOME JSON")
71
+ @document = stub(:to_hash => @hash,
72
+ :created_at => @created_at,
73
+ :new_record? => false,
74
+ :id => 12345)
75
+ @record = @translator.to_record(@document)
76
+ end
77
+
78
+ it "serializes the attributes" do
79
+ @serializer.should have_received(:generate).with(:name => "Stewie")
80
+ @record[:attributes].should == "SOME JSON"
81
+ end
82
+
83
+ it "doesn't bump the created_at" do
84
+ @record[:created_at].should == @created_at
85
+ end
86
+
87
+ it "should bump the updated_at" do
88
+ @record[:updated_at].should == @time.new
89
+ end
90
+
91
+ it "takes the id from the documetn" do
92
+ @record[:id].should == 12345
93
+ end
94
+ end
95
+ end
96
+ end