PageRenderTime 53ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/spec/examples/model/dictionary_spec.rb

https://github.com/fairfaxmedia/cequel
Ruby | 290 lines | 254 code | 36 blank | 0 comment | 10 complexity | c13850bfa7db8f956aa28bff8a0eda8d MD5 | raw file
  1. require File.expand_path('../spec_helper', __FILE__)
  2. describe Cequel::Model::Dictionary do
  3. let(:uuid1) { uuid }
  4. let(:uuid2) { uuid }
  5. let(:uuid3) { uuid }
  6. let(:dictionary) { BlogPosts[1] }
  7. it_behaves_like 'readable dictionary'
  8. describe '#save' do
  9. before do
  10. connection.stub(:execute).
  11. with('SELECT FIRST 2 * FROM blog_posts WHERE ? = ? LIMIT 1', :blog_id, 1).
  12. and_return result_stub('blog_id' => 1, uuid1 => 1, uuid2 => 2)
  13. connection.stub(:execute).
  14. with('SELECT FIRST 2 ?..? FROM blog_posts WHERE ? = ? LIMIT 1', uuid2, '', :blog_id, 1).
  15. and_return result_stub('blog_id' => 1)
  16. end
  17. it 'should write to row' do
  18. dictionary[uuid1] = 1
  19. dictionary[uuid2] = 2
  20. connection.should_receive(:execute).
  21. with('UPDATE blog_posts SET ? = ?, ? = ? WHERE ? = ?', uuid1, 1, uuid2, 2, :blog_id, 1)
  22. dictionary.save
  23. end
  24. it 'should update changed columns' do
  25. dictionary.load
  26. dictionary[uuid1] = 2
  27. connection.should_receive(:execute).
  28. with('UPDATE blog_posts SET ? = ? WHERE ? = ?', uuid1, 2, :blog_id, 1)
  29. dictionary.save
  30. end
  31. it 'should write new columns' do
  32. dictionary.load
  33. dictionary[uuid3] = 3
  34. connection.should_receive(:execute).
  35. with('UPDATE blog_posts SET ? = ? WHERE ? = ?', uuid3, 3, :blog_id, 1)
  36. dictionary.save
  37. end
  38. it 'should delete removed columns' do
  39. dictionary.load
  40. dictionary[uuid1] = nil
  41. connection.should_receive(:execute).
  42. with('DELETE ? FROM blog_posts WHERE ? = ?', [uuid1], :blog_id, 1)
  43. dictionary.save
  44. end
  45. it 'should not update a row if it should be deleted' do
  46. dictionary.load
  47. dictionary[uuid1] = 1
  48. dictionary[uuid1] = nil
  49. connection.should_receive(:execute).once.
  50. with('DELETE ? FROM blog_posts WHERE ? = ?', [uuid1], :blog_id, 1)
  51. dictionary.save
  52. end
  53. it 'should not delete a row if it was subsequently updated' do
  54. dictionary.load
  55. dictionary[uuid1] = nil
  56. dictionary[uuid1] = 1
  57. connection.should_receive(:execute).once.
  58. with('UPDATE blog_posts SET ? = ? WHERE ? = ?', uuid1, 1, :blog_id, 1)
  59. dictionary.save
  60. end
  61. it 'should not save columns that have been saved previously' do
  62. dictionary.load
  63. dictionary[uuid3] = 3
  64. connection.should_receive(:execute).once.
  65. with('UPDATE blog_posts SET ? = ? WHERE ? = ?', uuid3, 3, :blog_id, 1)
  66. 2.times { dictionary.save }
  67. end
  68. it 'should not delete columns that have been deleted previously' do
  69. dictionary.load
  70. dictionary[uuid1] = nil
  71. connection.should_receive(:execute).once.
  72. with('DELETE ? FROM blog_posts WHERE ? = ?', [uuid1], :blog_id, 1)
  73. 2.times { dictionary.save }
  74. end
  75. end
  76. describe '#destroy' do
  77. before do
  78. connection.stub(:execute).
  79. with('SELECT FIRST 2 * FROM blog_posts WHERE ? = ? LIMIT 1', :blog_id, 1).
  80. and_return result_stub('blog_id' => 1, uuid1 => 1, uuid2 => 2)
  81. connection.stub(:execute).
  82. with('SELECT FIRST 2 ?..? FROM blog_posts WHERE ? = ? LIMIT 1', uuid2, '', :blog_id, 1).
  83. and_return result_stub({'blog_id' => 1})
  84. dictionary.load
  85. connection.should_receive(:execute).
  86. with('DELETE FROM blog_posts WHERE ? = ?', :blog_id, 1)
  87. end
  88. it 'should delete row from cassandra' do
  89. dictionary.destroy
  90. end
  91. it 'should remove all properties from memory' do
  92. dictionary.destroy
  93. connection.stub(:execute).
  94. with('SELECT ? FROM blog_posts WHERE ? = ? LIMIT 1', [uuid1], :blog_id, 1).
  95. and_return result_stub({})
  96. dictionary[uuid1].should be_nil
  97. end
  98. it 'should not save previously updated properties when saved' do
  99. dictionary[uuid1] = 5
  100. dictionary.destroy
  101. connection.should_not_receive(:execute)
  102. dictionary.save
  103. end
  104. it 'should not delete previously deleted properties when saved' do
  105. dictionary[uuid1] = nil
  106. dictionary.destroy
  107. connection.should_not_receive(:execute)
  108. dictionary.save
  109. end
  110. end
  111. context 'with data modified but not loaded in memory' do
  112. let(:uuid4) { uuid }
  113. before do
  114. dictionary[uuid1] = -1
  115. dictionary[uuid3] = nil
  116. dictionary[uuid4] = 4
  117. end
  118. describe '#each_pair' do
  119. it 'should override persisted data with unsaved changes' do
  120. connection.stub(:execute).
  121. with('SELECT FIRST 2 * FROM blog_posts WHERE ? = ? LIMIT 1', :blog_id, 1).
  122. and_return result_stub('blog_id' => 1, uuid1 => 1, uuid2 => 2)
  123. connection.stub(:execute).
  124. with('SELECT FIRST 2 ?..? FROM blog_posts WHERE ? = ? LIMIT 1', uuid2, '', :blog_id, 1).
  125. and_return result_stub('blog_id' => 1, uuid2 => 2, uuid3 => 3)
  126. connection.stub(:execute).
  127. with('SELECT FIRST 2 ?..? FROM blog_posts WHERE ? = ? LIMIT 1', uuid3, '', :blog_id, 1).
  128. and_return result_stub({'blog_id' => 1})
  129. hash = {}
  130. dictionary.each_pair do |key, value|
  131. hash[key] = value
  132. end
  133. hash.should == {uuid1 => -1, uuid2 => 2, uuid4 => 4}
  134. end
  135. end
  136. describe '#[]' do
  137. it 'should return unsaved changed value' do
  138. dictionary[uuid1].should == -1
  139. end
  140. it 'should return nil if value removed' do
  141. dictionary[uuid3].should be_nil
  142. end
  143. it 'should return unsaved new value' do
  144. dictionary[uuid4].should == 4
  145. end
  146. end
  147. describe '#slice' do
  148. it 'should override loaded slice with unsaved data in memory' do
  149. connection.stub(:execute).
  150. with('SELECT ? FROM blog_posts WHERE ? = ? LIMIT 1', [uuid1,uuid2,uuid3,uuid4], :blog_id, 1).
  151. and_return result_stub(uuid1 => 1, uuid2 => 2, uuid3 => 3)
  152. dictionary.slice(uuid1, uuid2, uuid3, uuid4).should ==
  153. {uuid1 => -1, uuid2 => 2, uuid4 => 4}
  154. end
  155. end
  156. describe '#keys' do
  157. it 'should override keys that have been added or removed' do
  158. connection.should_receive(:execute).
  159. with('SELECT FIRST 2 * FROM blog_posts WHERE ? = ? LIMIT 1', :blog_id, 1).
  160. and_return result_stub('blog_id' => 1, uuid1 => 1, uuid2 => 2)
  161. connection.should_receive(:execute).
  162. with('SELECT FIRST 2 ?..? FROM blog_posts WHERE ? = ? LIMIT 1', uuid2, '', :blog_id, 1).
  163. and_return result_stub('blog_id' => 1, uuid2 => 2, uuid3 => 3)
  164. connection.should_receive(:execute).
  165. with('SELECT FIRST 2 ?..? FROM blog_posts WHERE ? = ? LIMIT 1', uuid3, '', :blog_id, 1).
  166. and_return result_stub({'blog_id' => 1})
  167. dictionary.keys.should == [uuid1, uuid2, uuid4]
  168. end
  169. end
  170. describe '#values' do
  171. it 'should override values that have been added or removed' do
  172. connection.should_receive(:execute).
  173. with('SELECT FIRST 2 * FROM blog_posts WHERE ? = ? LIMIT 1', :blog_id, 1).
  174. and_return result_stub('blog_id' => 1, uuid1 => 1, uuid2 => 2)
  175. connection.should_receive(:execute).
  176. with('SELECT FIRST 2 ?..? FROM blog_posts WHERE ? = ? LIMIT 1', uuid2, '', :blog_id, 1).
  177. and_return result_stub('blog_id' => 1, uuid2 => 2, uuid3 => 3)
  178. connection.should_receive(:execute).
  179. with('SELECT FIRST 2 ?..? FROM blog_posts WHERE ? = ? LIMIT 1', uuid3, '', :blog_id, 1).
  180. and_return result_stub({'blog_id' => 1})
  181. dictionary.values.should == [-1, 2, 4]
  182. end
  183. end
  184. end
  185. context 'with serializer/deserializer defined' do
  186. let(:dictionary) { PostComments[1] }
  187. let(:comment) { {'user' => 'Mat Brown', 'comment' => 'I like big data.'} }
  188. describe '#save' do
  189. it 'should serialize data' do
  190. dictionary[4] = comment
  191. connection.should_receive(:execute).
  192. with(
  193. 'UPDATE post_comments SET ? = ? WHERE ? = ?',
  194. 4, comment.to_json, :post_id, 1
  195. )
  196. dictionary.save
  197. end
  198. end
  199. describe '#[]' do
  200. it 'should return deserialized data' do
  201. connection.stub(:execute).with(
  202. 'SELECT ? FROM post_comments WHERE ? = ? LIMIT 1',
  203. [4], :post_id, 1
  204. ).and_return result_stub(4 => comment.to_json)
  205. dictionary[4].should == comment
  206. end
  207. end
  208. describe '#slice' do
  209. it 'should return deserialized values' do
  210. connection.stub(:execute).with(
  211. 'SELECT ? FROM post_comments WHERE ? = ? LIMIT 1',
  212. [4, 5], :post_id, 1
  213. ).and_return result_stub(4 => comment.to_json)
  214. dictionary.slice(4, 5).should == {4 => comment}
  215. end
  216. end
  217. describe '#load' do
  218. it 'should retain deserialized values in memory' do
  219. connection.stub(:execute).with(
  220. 'SELECT FIRST 1000 * FROM post_comments WHERE ? = ? LIMIT 1',
  221. :post_id, 1
  222. ).and_return result_stub(4 => comment.to_json)
  223. dictionary.load
  224. connection.should_not_receive(:execute)
  225. dictionary[4].should == comment
  226. end
  227. end
  228. describe '#each_pair' do
  229. it 'should yield deserialized values' do
  230. connection.stub(:execute).
  231. with(
  232. 'SELECT FIRST 1000 * FROM post_comments WHERE ? = ? LIMIT 1',
  233. :post_id, 1
  234. ).and_return result_stub('post_id' => 1, 4 => comment.to_json)
  235. dictionary.each_pair.map { |column, comment| comment }.first.
  236. should == comment
  237. end
  238. end
  239. describe '#values' do
  240. it 'should return deserialized values' do
  241. connection.stub(:execute).
  242. with(
  243. 'SELECT FIRST 1000 * FROM post_comments WHERE ? = ? LIMIT 1',
  244. :post_id, 1
  245. ).and_return result_stub('post_id' => 1, 4 => comment.to_json)
  246. dictionary.values.should == [comment]
  247. end
  248. end
  249. end
  250. private
  251. def uuid
  252. SimpleUUID::UUID.new.to_guid
  253. end
  254. end