/spec/mongoid/query_cache_spec.rb

https://gitlab.com/vsailakshmi/mongoid · Ruby · 446 lines · 344 code · 102 blank · 0 comment · 1 complexity · e5c1cf8f3cae6beefd3f827fc2cefd84 MD5 · raw file

  1. require "spec_helper"
  2. describe Mongoid::QueryCache do
  3. around do |spec|
  4. Mongoid::QueryCache.clear_cache
  5. Mongoid::QueryCache.cache { spec.run }
  6. end
  7. context 'when iterating over objects sharing the same base' do
  8. let(:server) do
  9. relations.first.mongo_client.cluster.next_primary
  10. end
  11. before do
  12. person = Person.create
  13. 3.times do
  14. person.send(relation).create
  15. end
  16. person.save
  17. end
  18. let!(:relations) do
  19. Person.first.send(relation).to_a
  20. end
  21. context 'when the association is has-many' do
  22. let(:relation) do
  23. :posts
  24. end
  25. context 'when query cache is disabled' do
  26. before do
  27. Mongoid::QueryCache.enabled = false
  28. end
  29. it 'queries for each access to the base' do
  30. expect(server).to receive(:context).exactly(relations.size).times.and_call_original
  31. relations.each do |object|
  32. object.person
  33. end
  34. end
  35. end
  36. context 'when query cache is enabled' do
  37. before do
  38. Mongoid::QueryCache.enabled = true
  39. end
  40. it 'queries only once for the base' do
  41. expect(server).to receive(:context).exactly(1).times.and_call_original
  42. relations.each do |object|
  43. object.person
  44. end
  45. end
  46. end
  47. end
  48. context 'when the association is embeds-many' do
  49. let(:relation) do
  50. :symptoms
  51. end
  52. context 'when query cache is disabled' do
  53. before do
  54. Mongoid::QueryCache.enabled = false
  55. end
  56. it 'does not query for access to the base' do
  57. expect(server).to receive(:context).exactly(0).times.and_call_original
  58. relations.each do |object|
  59. object.person
  60. end
  61. end
  62. end
  63. context 'when query cache is enabled' do
  64. before do
  65. Mongoid::QueryCache.enabled = true
  66. end
  67. it 'does not query for access to the base' do
  68. expect(server).to receive(:context).exactly(0).times.and_call_original
  69. relations.each do |object|
  70. object.person
  71. end
  72. end
  73. end
  74. end
  75. end
  76. context "when querying for a single document" do
  77. [ :first, :one, :last ].each do |method|
  78. before do
  79. Band.all.send(method)
  80. end
  81. context "when query cache is disabled" do
  82. before do
  83. Mongoid::QueryCache.enabled = false
  84. end
  85. it "queries again" do
  86. expect_query(1) do
  87. Band.all.send(method)
  88. end
  89. end
  90. end
  91. context "with same selector" do
  92. it "does not query again" do
  93. expect_no_queries do
  94. Band.all.send(method)
  95. end
  96. end
  97. end
  98. context "with different selector" do
  99. it "queries again" do
  100. expect_query(1) do
  101. Band.where(id: 1).send(method)
  102. end
  103. end
  104. end
  105. end
  106. end
  107. context "when querying in the same collection" do
  108. before do
  109. Band.all.to_a
  110. end
  111. context "when query cache is disabled" do
  112. before do
  113. Mongoid::QueryCache.enabled = false
  114. end
  115. it "queries again" do
  116. expect_query(1) do
  117. Band.all.to_a
  118. end
  119. end
  120. end
  121. context "with same selector" do
  122. it "does not query again" do
  123. expect_no_queries do
  124. Band.all.to_a
  125. end
  126. end
  127. context "when the first query has no limit" do
  128. let(:game) do
  129. Game.create!(name: "2048")
  130. end
  131. before do
  132. game.ratings.where(:value.gt => 5).asc(:id).all.to_a
  133. end
  134. context "when the next query has a limit" do
  135. it "uses the cache" do
  136. expect_no_queries do
  137. game.ratings.where(:value.gt => 5).limit(2).asc(:id).to_a
  138. end
  139. end
  140. end
  141. end
  142. context "when the first query has a limit" do
  143. let(:game) do
  144. Game.create!(name: "2048")
  145. end
  146. before do
  147. game.ratings.where(:value.gt => 5).limit(3).asc(:id).all.to_a
  148. end
  149. context "when the next query has a limit" do
  150. it "queries again" do
  151. expect_query(1) do
  152. game.ratings.where(:value.gt => 5).limit(2).asc(:id).to_a
  153. end
  154. end
  155. end
  156. context "when the new query does not have a limit" do
  157. it "queries again" do
  158. expect_query(1) do
  159. game.ratings.where(:value.gt => 5).asc(:id).to_a
  160. end
  161. end
  162. end
  163. end
  164. context "when querying only the first" do
  165. let(:game) do
  166. Game.create!(name: "2048")
  167. end
  168. before do
  169. game.ratings.where(:value.gt => 5).asc(:id).all.to_a
  170. end
  171. it "does not query again" do
  172. expect_no_queries do
  173. game.ratings.where(:value.gt => 5).asc(:id).first
  174. end
  175. end
  176. end
  177. context "when limiting the result" do
  178. it "does not query again" do
  179. expect_query(0) do
  180. Band.limit(2).all.to_a
  181. end
  182. end
  183. end
  184. context "when specifying a different skip value" do
  185. before do
  186. Band.limit(2).skip(1).all.to_a
  187. end
  188. it "queries again" do
  189. expect_query(1) do
  190. Band.limit(2).skip(3).all.to_a
  191. end
  192. end
  193. end
  194. end
  195. context "with different selector" do
  196. it "queries again" do
  197. expect_query(1) do
  198. Band.where(id: 1).to_a
  199. end
  200. end
  201. end
  202. context "when sorting documents" do
  203. before do
  204. Band.asc(:id).to_a
  205. end
  206. context "with different selector" do
  207. it "queries again" do
  208. expect_query(1) do
  209. Band.desc(:id).to_a
  210. end
  211. end
  212. end
  213. it "does not query again" do
  214. expect_query(0) do
  215. Band.asc(:id).to_a
  216. end
  217. end
  218. end
  219. context "when query caching is enabled and the batch_size is set" do
  220. around(:each) do |example|
  221. query_cache_enabled = Mongoid::QueryCache.enabled?
  222. Mongoid::QueryCache.enabled = true
  223. example.run
  224. Mongoid::QueryCache.enabled = query_cache_enabled
  225. end
  226. it "does not raise an error when requesting the second batch" do
  227. expect {
  228. Band.batch_size(4).where(:views.gte => 0).each do |doc|
  229. doc.set(likes: Random.rand(100))
  230. end
  231. }.not_to raise_error
  232. end
  233. end
  234. end
  235. context "when querying in different collection" do
  236. before do
  237. Person.all.to_a
  238. end
  239. it "queries again" do
  240. expect_query(1) do
  241. Band.all.to_a
  242. end
  243. end
  244. end
  245. context "when inserting a new document" do
  246. before do
  247. Band.all.to_a
  248. Band.create!
  249. end
  250. it "queries again" do
  251. expect_query(1) do
  252. Band.all.to_a
  253. end
  254. end
  255. end
  256. context "when deleting all documents" do
  257. before do
  258. Band.create!
  259. Band.all.to_a
  260. Band.delete_all
  261. end
  262. it "queries again" do
  263. expect_query(1) do
  264. Band.all.to_a
  265. end
  266. end
  267. end
  268. context "when destroying all documents" do
  269. before do
  270. Band.create!
  271. Band.all.to_a
  272. Band.destroy_all
  273. end
  274. it "queries again" do
  275. expect_query(1) do
  276. Band.all.to_a
  277. end
  278. end
  279. end
  280. context "when querying a very large collection" do
  281. before do
  282. 123.times { Band.create! }
  283. end
  284. it "returns the right number of records" do
  285. expect(Band.all.to_a.length).to eq(123)
  286. end
  287. it "#pluck returns the same count of objects" do
  288. expect(Band.pluck(:name).length).to eq(123)
  289. end
  290. context "when loading all the documents" do
  291. before do
  292. Band.all.to_a
  293. end
  294. it "caches the complete result of the query" do
  295. expect_no_queries do
  296. expect(Band.all.to_a.length).to eq(123)
  297. end
  298. end
  299. it "returns the same count of objects when using #pluck" do
  300. expect(Band.pluck(:name).length).to eq(123)
  301. end
  302. end
  303. end
  304. context "when inserting an index" do
  305. it "does not cache the query" do
  306. expect(Mongoid::QueryCache).to receive(:cache_table).never
  307. Band.collection.indexes.create_one(name: 1)
  308. end
  309. end
  310. end
  311. describe Mongoid::QueryCache::Middleware do
  312. let :middleware do
  313. Mongoid::QueryCache::Middleware.new(app)
  314. end
  315. context "when not touching mongoid on the app" do
  316. let(:app) do
  317. ->(env) { @enabled = Mongoid::QueryCache.enabled?; [200, env, "app"] }
  318. end
  319. it "returns success" do
  320. code, _ = middleware.call({})
  321. expect(code).to eq(200)
  322. end
  323. it "enableds the query cache" do
  324. middleware.call({})
  325. expect(@enabled).to be true
  326. end
  327. end
  328. context "when querying on the app" do
  329. let(:app) do
  330. ->(env) {
  331. Band.all.to_a
  332. [200, env, "app"]
  333. }
  334. end
  335. it "returns success" do
  336. code, _ = middleware.call({})
  337. expect(code).to eq(200)
  338. end
  339. it "cleans the query cache after reponds" do
  340. middleware.call({})
  341. expect(Mongoid::QueryCache.cache_table).to be_empty
  342. end
  343. end
  344. end