droonga-engine 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (341) hide show
  1. data/.dir-locals.el +3 -0
  2. data/.gitignore +6 -0
  3. data/.travis.yml +15 -0
  4. data/.yardopts +7 -0
  5. data/Gemfile +66 -0
  6. data/LICENSE.txt +14 -0
  7. data/README.md +17 -0
  8. data/Rakefile +64 -0
  9. data/benchmark/benchmark.rb +123 -0
  10. data/benchmark/utils.rb +246 -0
  11. data/benchmark/watch/benchmark-notify.rb +143 -0
  12. data/benchmark/watch/benchmark-notify.sh +20 -0
  13. data/benchmark/watch/benchmark-publish.rb +120 -0
  14. data/benchmark/watch/benchmark-scan.rb +213 -0
  15. data/bin/droonga-catalog-generate +103 -0
  16. data/bin/droonga-engine +20 -0
  17. data/bin/droonga-engine-service +20 -0
  18. data/doc/text/news.md +106 -0
  19. data/droonga-engine.gemspec +52 -0
  20. data/lib/droonga/adapter.rb +48 -0
  21. data/lib/droonga/adapter_runner.rb +104 -0
  22. data/lib/droonga/catalog/base.rb +41 -0
  23. data/lib/droonga/catalog/collection_volume.rb +106 -0
  24. data/lib/droonga/catalog/dataset.rb +69 -0
  25. data/lib/droonga/catalog/errors.rb +113 -0
  26. data/lib/droonga/catalog/schema.rb +186 -0
  27. data/lib/droonga/catalog/single_volume.rb +28 -0
  28. data/lib/droonga/catalog/slice.rb +41 -0
  29. data/lib/droonga/catalog/version1.rb +427 -0
  30. data/lib/droonga/catalog/version2.rb +96 -0
  31. data/lib/droonga/catalog/version2_validator.rb +63 -0
  32. data/lib/droonga/catalog/volume.rb +33 -0
  33. data/lib/droonga/catalog/volume_collection.rb +56 -0
  34. data/lib/droonga/catalog_generator.rb +156 -0
  35. data/lib/droonga/catalog_loader.rb +56 -0
  36. data/lib/droonga/catalog_observer.rb +83 -0
  37. data/lib/droonga/collector.rb +38 -0
  38. data/lib/droonga/collector_message.rb +71 -0
  39. data/lib/droonga/collector_runner.rb +64 -0
  40. data/lib/droonga/collectors/and.rb +26 -0
  41. data/lib/droonga/collectors/or.rb +26 -0
  42. data/lib/droonga/collectors/sum.rb +26 -0
  43. data/lib/droonga/collectors.rb +18 -0
  44. data/lib/droonga/dispatcher.rb +326 -0
  45. data/lib/droonga/distributed_command_planner.rb +179 -0
  46. data/lib/droonga/distributor.rb +87 -0
  47. data/lib/droonga/engine/command/droonga_engine.rb +441 -0
  48. data/lib/droonga/engine/version.rb +20 -0
  49. data/lib/droonga/engine.rb +80 -0
  50. data/lib/droonga/engine_state.rb +79 -0
  51. data/lib/droonga/error.rb +73 -0
  52. data/lib/droonga/error_messages.rb +33 -0
  53. data/lib/droonga/event_loop.rb +46 -0
  54. data/lib/droonga/farm.rb +58 -0
  55. data/lib/droonga/fluent_message_receiver.rb +191 -0
  56. data/lib/droonga/fluent_message_sender.rb +140 -0
  57. data/lib/droonga/forwarder.rb +119 -0
  58. data/lib/droonga/handler.rb +49 -0
  59. data/lib/droonga/handler_message.rb +61 -0
  60. data/lib/droonga/handler_messenger.rb +119 -0
  61. data/lib/droonga/handler_runner.rb +125 -0
  62. data/lib/droonga/input_message.rb +51 -0
  63. data/lib/droonga/job_protocol.rb +20 -0
  64. data/lib/droonga/job_pusher.rb +179 -0
  65. data/lib/droonga/job_receiver.rb +70 -0
  66. data/lib/droonga/loggable.rb +29 -0
  67. data/lib/droonga/logger.rb +142 -0
  68. data/lib/droonga/message_matcher.rb +109 -0
  69. data/lib/droonga/output_message.rb +55 -0
  70. data/lib/droonga/planner.rb +47 -0
  71. data/lib/droonga/pluggable.rb +31 -0
  72. data/lib/droonga/plugin/metadata/adapter_input_message.rb +39 -0
  73. data/lib/droonga/plugin/metadata/adapter_output_message.rb +39 -0
  74. data/lib/droonga/plugin/metadata/collector_message.rb +39 -0
  75. data/lib/droonga/plugin/metadata/handler_action.rb +39 -0
  76. data/lib/droonga/plugin/metadata/input_message.rb +54 -0
  77. data/lib/droonga/plugin.rb +43 -0
  78. data/lib/droonga/plugin_loader.rb +63 -0
  79. data/lib/droonga/plugin_registry.rb +66 -0
  80. data/lib/droonga/plugins/basic.rb +54 -0
  81. data/lib/droonga/plugins/crud.rb +145 -0
  82. data/lib/droonga/plugins/dump.rb +97 -0
  83. data/lib/droonga/plugins/error.rb +51 -0
  84. data/lib/droonga/plugins/groonga/column_create.rb +123 -0
  85. data/lib/droonga/plugins/groonga/column_list.rb +124 -0
  86. data/lib/droonga/plugins/groonga/column_remove.rb +65 -0
  87. data/lib/droonga/plugins/groonga/column_rename.rb +67 -0
  88. data/lib/droonga/plugins/groonga/delete.rb +117 -0
  89. data/lib/droonga/plugins/groonga/generic_command.rb +105 -0
  90. data/lib/droonga/plugins/groonga/generic_response.rb +43 -0
  91. data/lib/droonga/plugins/groonga/select.rb +236 -0
  92. data/lib/droonga/plugins/groonga/table_create.rb +111 -0
  93. data/lib/droonga/plugins/groonga/table_list.rb +120 -0
  94. data/lib/droonga/plugins/groonga/table_remove.rb +57 -0
  95. data/lib/droonga/plugins/groonga.rb +37 -0
  96. data/lib/droonga/plugins/search/distributed_search_planner.rb +407 -0
  97. data/lib/droonga/plugins/search.rb +146 -0
  98. data/lib/droonga/plugins/watch.rb +178 -0
  99. data/lib/droonga/processor.rb +63 -0
  100. data/lib/droonga/reducer.rb +169 -0
  101. data/lib/droonga/replier.rb +49 -0
  102. data/lib/droonga/schema_applier.rb +167 -0
  103. data/lib/droonga/searcher/mecab_filter.rb +67 -0
  104. data/lib/droonga/searcher.rb +733 -0
  105. data/lib/droonga/server.rb +45 -0
  106. data/lib/droonga/session.rb +99 -0
  107. data/lib/droonga/single_step.rb +68 -0
  108. data/lib/droonga/single_step_definition.rb +54 -0
  109. data/lib/droonga/slice.rb +122 -0
  110. data/lib/droonga/status_code.rb +25 -0
  111. data/lib/droonga/step_runner.rb +64 -0
  112. data/lib/droonga/sweeper.rb +42 -0
  113. data/lib/droonga/test/stub_handler.rb +37 -0
  114. data/lib/droonga/test/stub_handler_message.rb +35 -0
  115. data/lib/droonga/test/stub_handler_messenger.rb +34 -0
  116. data/lib/droonga/test/stub_planner.rb +31 -0
  117. data/lib/droonga/test.rb +21 -0
  118. data/lib/droonga/watch_schema.rb +92 -0
  119. data/lib/droonga/watcher.rb +257 -0
  120. data/lib/droonga/worker.rb +61 -0
  121. data/sample/cluster/catalog.json +42 -0
  122. data/sample/mecab_filter/data.grn +7 -0
  123. data/sample/mecab_filter/ddl.grn +7 -0
  124. data/sample/mecab_filter/search_with_mecab_filter.json +21 -0
  125. data/sample/mecab_filter/search_without_mecab_filter.json +21 -0
  126. data/test/command/config/default/catalog.json +85 -0
  127. data/test/command/config/default/fluentd.conf +11 -0
  128. data/test/command/config/version1/catalog.json +68 -0
  129. data/test/command/config/version1/fluentd.conf +11 -0
  130. data/test/command/fixture/documents.jsons +208 -0
  131. data/test/command/fixture/event.jsons +41 -0
  132. data/test/command/fixture/user-table-array.jsons +38 -0
  133. data/test/command/fixture/user-table.jsons +47 -0
  134. data/test/command/run-test.rb +34 -0
  135. data/test/command/suite/add/dimension/column.catalog.json +28 -0
  136. data/test/command/suite/add/dimension/column.expected +41 -0
  137. data/test/command/suite/add/dimension/column.test +51 -0
  138. data/test/command/suite/add/dimension/integer.catalog.json +19 -0
  139. data/test/command/suite/add/dimension/integer.expected +41 -0
  140. data/test/command/suite/add/dimension/integer.test +51 -0
  141. data/test/command/suite/add/error/invalid-integer.expected +46 -0
  142. data/test/command/suite/add/error/invalid-integer.test +12 -0
  143. data/test/command/suite/add/error/invalid-time.expected +46 -0
  144. data/test/command/suite/add/error/invalid-time.test +12 -0
  145. data/test/command/suite/add/error/missing-key.expected +25 -0
  146. data/test/command/suite/add/error/missing-key.test +16 -0
  147. data/test/command/suite/add/error/missing-table.expected +25 -0
  148. data/test/command/suite/add/error/missing-table.test +16 -0
  149. data/test/command/suite/add/error/unknown-column.expected +46 -0
  150. data/test/command/suite/add/error/unknown-column.test +12 -0
  151. data/test/command/suite/add/error/unknown-table.expected +25 -0
  152. data/test/command/suite/add/error/unknown-table.test +17 -0
  153. data/test/command/suite/add/minimum.expected +6 -0
  154. data/test/command/suite/add/minimum.test +11 -0
  155. data/test/command/suite/add/with-values.expected +6 -0
  156. data/test/command/suite/add/with-values.test +17 -0
  157. data/test/command/suite/add/without-key.expected +6 -0
  158. data/test/command/suite/add/without-key.test +16 -0
  159. data/test/command/suite/groonga/column_create/scalar.expected +26 -0
  160. data/test/command/suite/groonga/column_create/scalar.test +17 -0
  161. data/test/command/suite/groonga/column_create/unknown-table.expected +14 -0
  162. data/test/command/suite/groonga/column_create/unknown-table.test +7 -0
  163. data/test/command/suite/groonga/column_create/vector.expected +26 -0
  164. data/test/command/suite/groonga/column_create/vector.test +18 -0
  165. data/test/command/suite/groonga/column_list/success.expected +86 -0
  166. data/test/command/suite/groonga/column_list/success.test +24 -0
  167. data/test/command/suite/groonga/column_list/unknown-table.expected +13 -0
  168. data/test/command/suite/groonga/column_list/unknown-table.test +7 -0
  169. data/test/command/suite/groonga/column_remove/success.expected +39 -0
  170. data/test/command/suite/groonga/column_remove/success.test +25 -0
  171. data/test/command/suite/groonga/column_remove/unknown-column.expected +27 -0
  172. data/test/command/suite/groonga/column_remove/unknown-column.test +16 -0
  173. data/test/command/suite/groonga/column_remove/unknown-table.expected +14 -0
  174. data/test/command/suite/groonga/column_remove/unknown-table.test +7 -0
  175. data/test/command/suite/groonga/column_rename/success.expected +39 -0
  176. data/test/command/suite/groonga/column_rename/success.test +26 -0
  177. data/test/command/suite/groonga/column_rename/unknown-column.expected +27 -0
  178. data/test/command/suite/groonga/column_rename/unknown-column.test +16 -0
  179. data/test/command/suite/groonga/column_rename/unknown-table.expected +14 -0
  180. data/test/command/suite/groonga/column_rename/unknown-table.test +7 -0
  181. data/test/command/suite/groonga/delete/duplicated-identifiers.expected +27 -0
  182. data/test/command/suite/groonga/delete/duplicated-identifiers.test +17 -0
  183. data/test/command/suite/groonga/delete/filter.expected +19 -0
  184. data/test/command/suite/groonga/delete/filter.test +19 -0
  185. data/test/command/suite/groonga/delete/invalid-filter.expected +14 -0
  186. data/test/command/suite/groonga/delete/invalid-filter.test +9 -0
  187. data/test/command/suite/groonga/delete/no-identifier.expected +27 -0
  188. data/test/command/suite/groonga/delete/no-identifier.test +15 -0
  189. data/test/command/suite/groonga/delete/success.expected +19 -0
  190. data/test/command/suite/groonga/delete/success.test +19 -0
  191. data/test/command/suite/groonga/delete/unknown-table.expected +14 -0
  192. data/test/command/suite/groonga/delete/unknown-table.test +7 -0
  193. data/test/command/suite/groonga/select/minimum.expected +22 -0
  194. data/test/command/suite/groonga/select/minimum.test +8 -0
  195. data/test/command/suite/groonga/table_create/array.expected +14 -0
  196. data/test/command/suite/groonga/table_create/array.test +8 -0
  197. data/test/command/suite/groonga/table_create/hash.expected +13 -0
  198. data/test/command/suite/groonga/table_create/hash.test +8 -0
  199. data/test/command/suite/groonga/table_list/success.expected +71 -0
  200. data/test/command/suite/groonga/table_list/success.test +15 -0
  201. data/test/command/suite/groonga/table_remove/success.expected +13 -0
  202. data/test/command/suite/groonga/table_remove/success.test +8 -0
  203. data/test/command/suite/groonga/table_remove/unknown-table.expected +14 -0
  204. data/test/command/suite/groonga/table_remove/unknown-table.test +7 -0
  205. data/test/command/suite/message/error/missing-dataset.expected +9 -0
  206. data/test/command/suite/message/error/missing-dataset.test +5 -0
  207. data/test/command/suite/message/error/unknown-dataset.expected +9 -0
  208. data/test/command/suite/message/error/unknown-dataset.test +6 -0
  209. data/test/command/suite/message/error/unknown-type.expected +9 -0
  210. data/test/command/suite/message/error/unknown-type.test +6 -0
  211. data/test/command/suite/search/adjusters/multiple.catalog.json +38 -0
  212. data/test/command/suite/search/adjusters/multiple.expected +19 -0
  213. data/test/command/suite/search/adjusters/multiple.test +75 -0
  214. data/test/command/suite/search/adjusters/one.catalog.json +38 -0
  215. data/test/command/suite/search/adjusters/one.expected +19 -0
  216. data/test/command/suite/search/adjusters/one.test +66 -0
  217. data/test/command/suite/search/attributes/array.expected +21 -0
  218. data/test/command/suite/search/attributes/array.test +28 -0
  219. data/test/command/suite/search/attributes/hash.expected +30 -0
  220. data/test/command/suite/search/attributes/hash.test +36 -0
  221. data/test/command/suite/search/complex.expected +48 -0
  222. data/test/command/suite/search/complex.test +23 -0
  223. data/test/command/suite/search/condition/nested.expected +15 -0
  224. data/test/command/suite/search/condition/nested.test +27 -0
  225. data/test/command/suite/search/condition/query/nonexistent_column.catalog.json +37 -0
  226. data/test/command/suite/search/condition/query/nonexistent_column.expected +48 -0
  227. data/test/command/suite/search/condition/query/nonexistent_column.test +33 -0
  228. data/test/command/suite/search/condition/query/syntax_error.catalog.json +36 -0
  229. data/test/command/suite/search/condition/query/syntax_error.expected +48 -0
  230. data/test/command/suite/search/condition/query/syntax_error.test +33 -0
  231. data/test/command/suite/search/condition/query.expected +24 -0
  232. data/test/command/suite/search/condition/query.test +23 -0
  233. data/test/command/suite/search/condition/script.expected +24 -0
  234. data/test/command/suite/search/condition/script.test +26 -0
  235. data/test/command/suite/search/error/cyclic-source.expected +14 -0
  236. data/test/command/suite/search/error/cyclic-source.test +12 -0
  237. data/test/command/suite/search/error/deeply-cyclic-source.expected +17 -0
  238. data/test/command/suite/search/error/deeply-cyclic-source.test +15 -0
  239. data/test/command/suite/search/error/missing-source-parameter.expected +13 -0
  240. data/test/command/suite/search/error/missing-source-parameter.test +11 -0
  241. data/test/command/suite/search/error/no-query.expected +9 -0
  242. data/test/command/suite/search/error/no-query.test +7 -0
  243. data/test/command/suite/search/error/unknown-source.expected +52 -0
  244. data/test/command/suite/search/error/unknown-source.test +12 -0
  245. data/test/command/suite/search/group/count.expected +10 -0
  246. data/test/command/suite/search/group/count.test +18 -0
  247. data/test/command/suite/search/group/limit.expected +15 -0
  248. data/test/command/suite/search/group/limit.test +20 -0
  249. data/test/command/suite/search/group/string.expected +32 -0
  250. data/test/command/suite/search/group/string.test +40 -0
  251. data/test/command/suite/search/group/subrecord/with-sort.catalog.json +33 -0
  252. data/test/command/suite/search/group/subrecord/with-sort.expected +30 -0
  253. data/test/command/suite/search/group/subrecord/with-sort.test +81 -0
  254. data/test/command/suite/search/multiple/chained.expected +41 -0
  255. data/test/command/suite/search/multiple/chained.test +39 -0
  256. data/test/command/suite/search/multiple/parallel.expected +35 -0
  257. data/test/command/suite/search/multiple/parallel.test +35 -0
  258. data/test/command/suite/search/output/attributes/invalid.catalog.json +13 -0
  259. data/test/command/suite/search/output/attributes/invalid.expected +44 -0
  260. data/test/command/suite/search/output/attributes/invalid.test +28 -0
  261. data/test/command/suite/search/range/only-output.expected +24 -0
  262. data/test/command/suite/search/range/only-output.test +23 -0
  263. data/test/command/suite/search/range/only-sort.expected +24 -0
  264. data/test/command/suite/search/range/only-sort.test +26 -0
  265. data/test/command/suite/search/range/sort-and-output.expected +21 -0
  266. data/test/command/suite/search/range/sort-and-output.test +27 -0
  267. data/test/command/suite/search/range/too-large-output-offset.expected +12 -0
  268. data/test/command/suite/search/range/too-large-output-offset.test +23 -0
  269. data/test/command/suite/search/range/too-large-sort-offset.expected +12 -0
  270. data/test/command/suite/search/range/too-large-sort-offset.test +26 -0
  271. data/test/command/suite/search/response/elapsed_time.catalog.json +13 -0
  272. data/test/command/suite/search/response/elapsed_time.expected +11 -0
  273. data/test/command/suite/search/response/elapsed_time.test +26 -0
  274. data/test/command/suite/search/response/records/value/time.expected +20 -0
  275. data/test/command/suite/search/response/records/value/time.test +22 -0
  276. data/test/command/suite/search/simple.expected +48 -0
  277. data/test/command/suite/search/simple.test +22 -0
  278. data/test/command/suite/search/sort/default-offset-limit.expected +39 -0
  279. data/test/command/suite/search/sort/default-offset-limit.test +24 -0
  280. data/test/command/suite/search/sort/invisible-column.expected +24 -0
  281. data/test/command/suite/search/sort/invisible-column.test +26 -0
  282. data/test/command/suite/watch/subscribe.expected +6 -0
  283. data/test/command/suite/watch/subscribe.test +9 -0
  284. data/test/command/suite/watch/unsubscribe.expected +6 -0
  285. data/test/command/suite/watch/unsubscribe.test +9 -0
  286. data/test/performance/run-test.rb +56 -0
  287. data/test/performance/watch/catalog.json +33 -0
  288. data/test/performance/watch/feed.json +9 -0
  289. data/test/performance/watch/fluentd.conf +11 -0
  290. data/test/performance/watch/subscribe.json +3 -0
  291. data/test/unit/catalog/test_collection_volume.rb +103 -0
  292. data/test/unit/catalog/test_dataset.rb +104 -0
  293. data/test/unit/catalog/test_schema.rb +226 -0
  294. data/test/unit/catalog/test_single_volume.rb +31 -0
  295. data/test/unit/catalog/test_slice.rb +92 -0
  296. data/test/unit/catalog/test_version1.rb +361 -0
  297. data/test/unit/catalog/test_version2.rb +124 -0
  298. data/test/unit/catalog/test_version2_validator.rb +66 -0
  299. data/test/unit/catalog/test_volume_collection.rb +50 -0
  300. data/test/unit/fixtures/array.grn +18 -0
  301. data/test/unit/fixtures/catalog/version1.json +40 -0
  302. data/test/unit/fixtures/catalog/version2.json +62 -0
  303. data/test/unit/fixtures/document.grn +34 -0
  304. data/test/unit/fixtures/reference/array.grn +11 -0
  305. data/test/unit/fixtures/reference/hash.grn +7 -0
  306. data/test/unit/helper/distributed_search_planner_helper.rb +83 -0
  307. data/test/unit/helper/fixture.rb +28 -0
  308. data/test/unit/helper/plugin_helper.rb +38 -0
  309. data/test/unit/helper/sandbox.rb +86 -0
  310. data/test/unit/helper/stub_worker.rb +27 -0
  311. data/test/unit/helper/watch_helper.rb +23 -0
  312. data/test/unit/helper.rb +28 -0
  313. data/test/unit/plugins/crud/test_add.rb +190 -0
  314. data/test/unit/plugins/groonga/select/test_adapter_input.rb +510 -0
  315. data/test/unit/plugins/groonga/select/test_adapter_output.rb +201 -0
  316. data/test/unit/plugins/groonga/test_column_create.rb +171 -0
  317. data/test/unit/plugins/groonga/test_column_list.rb +170 -0
  318. data/test/unit/plugins/groonga/test_column_remove.rb +98 -0
  319. data/test/unit/plugins/groonga/test_column_rename.rb +105 -0
  320. data/test/unit/plugins/groonga/test_delete.rb +127 -0
  321. data/test/unit/plugins/groonga/test_table_create.rb +147 -0
  322. data/test/unit/plugins/groonga/test_table_list.rb +184 -0
  323. data/test/unit/plugins/groonga/test_table_remove.rb +61 -0
  324. data/test/unit/plugins/search/planner/test_basic.rb +120 -0
  325. data/test/unit/plugins/search/planner/test_group_by.rb +573 -0
  326. data/test/unit/plugins/search/planner/test_output.rb +388 -0
  327. data/test/unit/plugins/search/planner/test_sort_by.rb +938 -0
  328. data/test/unit/plugins/search/test_collector.rb +806 -0
  329. data/test/unit/plugins/search/test_handler.rb +930 -0
  330. data/test/unit/plugins/search/test_planner.rb +174 -0
  331. data/test/unit/plugins/test_basic.rb +510 -0
  332. data/test/unit/plugins/test_groonga.rb +70 -0
  333. data/test/unit/plugins/test_watch.rb +211 -0
  334. data/test/unit/run-test.rb +56 -0
  335. data/test/unit/test_catalog_generator.rb +93 -0
  336. data/test/unit/test_message_matcher.rb +160 -0
  337. data/test/unit/test_schema_applier.rb +59 -0
  338. data/test/unit/test_sweeper.rb +95 -0
  339. data/test/unit/test_watch_schema.rb +57 -0
  340. data/test/unit/test_watcher.rb +336 -0
  341. metadata +759 -0
@@ -0,0 +1,938 @@
1
+ # Copyright (C) 2013-2014 Droonga Project
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
+
16
+ class DistributedSearchPlannerSortByTest < Test::Unit::TestCase
17
+ include DistributedSearchPlannerHelper
18
+
19
+ class SimpleTest < self
20
+ def setup
21
+ @output = {
22
+ "elements" => ["records"],
23
+ "attributes" => ["_key"],
24
+ "limit" => 1,
25
+ }
26
+ @request = {
27
+ "type" => "search",
28
+ "dataset" => "Droonga",
29
+ "body" => {
30
+ "queries" => {
31
+ "users" => {
32
+ "source" => "User",
33
+ "sortBy" => ["_key"],
34
+ "output" => @output,
35
+ },
36
+ },
37
+ },
38
+ }
39
+ end
40
+
41
+ def test_dependencies
42
+ reduce_inputs = ["errors", "users"]
43
+ gather_inputs = ["errors_reduced", "users_reduced"]
44
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
45
+ dependencies)
46
+ end
47
+
48
+ def test_broadcast_body
49
+ assert_equal({
50
+ "queries" => {
51
+ "users" => {
52
+ "source" => "User",
53
+ "sortBy" => ["_key"],
54
+ "output" => @output,
55
+ },
56
+ },
57
+ },
58
+ broadcast_message["body"])
59
+ end
60
+
61
+ def test_reduce_body
62
+ assert_equal({
63
+ "users_reduced" => {
64
+ "records" => {
65
+ "type" => "sort",
66
+ "operators" => [
67
+ { "column" => 0, "operator" => "<" },
68
+ ],
69
+ "limit" => 1,
70
+ },
71
+ },
72
+ },
73
+ reduce_message["body"]["users"])
74
+ end
75
+
76
+ def test_gather_records
77
+ assert_equal({
78
+ "elements" => {
79
+ "records" => {
80
+ "attributes" => ["_key"],
81
+ "limit" => 1,
82
+ },
83
+ },
84
+ "output" => "users",
85
+ },
86
+ gather_message["body"]["users_reduced"])
87
+ end
88
+ end
89
+
90
+ class SimpleHiddenColumnTest < self
91
+ def setup
92
+ @output = {
93
+ "elements" => ["records"],
94
+ "attributes" => ["_key"],
95
+ "limit" => 1,
96
+ }
97
+ @request = {
98
+ "type" => "search",
99
+ "dataset" => "Droonga",
100
+ "body" => {
101
+ "queries" => {
102
+ "users" => {
103
+ "source" => "User",
104
+ "sortBy" => ["name"],
105
+ "output" => @output,
106
+ },
107
+ },
108
+ },
109
+ }
110
+ end
111
+
112
+ def test_dependencies
113
+ reduce_inputs = ["errors", "users"]
114
+ gather_inputs = ["errors_reduced", "users_reduced"]
115
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
116
+ dependencies)
117
+ end
118
+
119
+ def test_broadcast_body
120
+ changed_output_parameters = {
121
+ "attributes" => ["_key", "name"],
122
+ }
123
+ assert_equal({
124
+ "queries" => {
125
+ "users" => {
126
+ "source" => "User",
127
+ "sortBy" => ["name"],
128
+ "output" => @output.merge(changed_output_parameters),
129
+ },
130
+ },
131
+ },
132
+ broadcast_message["body"])
133
+ end
134
+
135
+ def test_reduce_body
136
+ assert_equal({
137
+ "users_reduced" => {
138
+ "records" => {
139
+ "type" => "sort",
140
+ "operators" => [
141
+ { "column" => 1, "operator" => "<" },
142
+ ],
143
+ "limit" => 1,
144
+ },
145
+ },
146
+ },
147
+ reduce_message["body"]["users"])
148
+ end
149
+
150
+ def test_gather_records
151
+ assert_equal({
152
+ "elements" => {
153
+ "records" => {
154
+ "attributes" => ["_key"],
155
+ "limit" => 1,
156
+ },
157
+ },
158
+ "output" => "users",
159
+ },
160
+ gather_message["body"]["users_reduced"])
161
+ end
162
+ end
163
+
164
+ class ComplexTest < self
165
+ def setup
166
+ @output = {
167
+ "elements" => ["records"],
168
+ "attributes" => ["_key"],
169
+ "limit" => 1,
170
+ }
171
+ @sort_by = {
172
+ "keys" => ["_key"],
173
+ }
174
+ @request = {
175
+ "type" => "search",
176
+ "dataset" => "Droonga",
177
+ "body" => {
178
+ "queries" => {
179
+ "users" => {
180
+ "source" => "User",
181
+ "sortBy" => @sort_by,
182
+ "output" => @output,
183
+ },
184
+ },
185
+ },
186
+ }
187
+ end
188
+
189
+ def test_dependencies
190
+ reduce_inputs = ["errors", "users"]
191
+ gather_inputs = ["errors_reduced", "users_reduced"]
192
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
193
+ dependencies)
194
+ end
195
+
196
+ def test_broadcast_body
197
+ changed_sort_by_parameters = {
198
+ "offset" => 0,
199
+ "limit" => 1,
200
+ }
201
+ assert_equal({
202
+ "queries" => {
203
+ "users" => {
204
+ "source" => "User",
205
+ "sortBy" => @sort_by.merge(changed_sort_by_parameters),
206
+ "output" => @output,
207
+ },
208
+ },
209
+ },
210
+ broadcast_message["body"])
211
+ end
212
+
213
+ def test_reduce_body
214
+ assert_equal({
215
+ "users_reduced" => {
216
+ "records" => {
217
+ "type" => "sort",
218
+ "operators" => [
219
+ { "column" => 0, "operator" => "<" },
220
+ ],
221
+ "limit" => 1,
222
+ },
223
+ },
224
+ },
225
+ reduce_message["body"]["users"])
226
+ end
227
+
228
+ def test_gather_records
229
+ assert_equal({
230
+ "elements" => {
231
+ "records" => {
232
+ "attributes" => ["_key"],
233
+ "limit" => 1,
234
+ },
235
+ },
236
+ "output" => "users",
237
+ },
238
+ gather_message["body"]["users_reduced"])
239
+ end
240
+ end
241
+
242
+ class ComplexHiddenColumnTest < self
243
+ def setup
244
+ @output = {
245
+ "elements" => ["records"],
246
+ "attributes" => ["_key"],
247
+ "limit" => 1,
248
+ }
249
+ @sort_by = {
250
+ "keys" => ["name"],
251
+ }
252
+ @request = {
253
+ "type" => "search",
254
+ "dataset" => "Droonga",
255
+ "body" => {
256
+ "queries" => {
257
+ "users" => {
258
+ "source" => "User",
259
+ "sortBy" => @sort_by,
260
+ "output" => @output,
261
+ },
262
+ },
263
+ },
264
+ }
265
+ end
266
+
267
+ def test_dependencies
268
+ reduce_inputs = ["errors", "users"]
269
+ gather_inputs = ["errors_reduced", "users_reduced"]
270
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
271
+ dependencies)
272
+ end
273
+
274
+ def test_broadcast_body
275
+ changed_sort_by_parameters = {
276
+ "offset" => 0,
277
+ "limit" => 1,
278
+ }
279
+ changed_output_parameters = {
280
+ "attributes" => ["_key", "name"],
281
+ }
282
+ assert_equal({
283
+ "queries" => {
284
+ "users" => {
285
+ "source" => "User",
286
+ "sortBy" => @sort_by.merge(changed_sort_by_parameters),
287
+ "output" => @output.merge(changed_output_parameters),
288
+ },
289
+ },
290
+ },
291
+ broadcast_message["body"])
292
+ end
293
+
294
+ def test_reduce_body
295
+ assert_equal({
296
+ "users_reduced" => {
297
+ "records" => {
298
+ "type" => "sort",
299
+ "operators" => [
300
+ { "column" => 1, "operator" => "<" },
301
+ ],
302
+ "limit" => 1,
303
+ },
304
+ },
305
+ },
306
+ reduce_message["body"]["users"])
307
+ end
308
+
309
+ def test_gather_records
310
+ assert_equal({
311
+ "elements" => {
312
+ "records" => {
313
+ "attributes" => ["_key"],
314
+ "limit" => 1,
315
+ },
316
+ },
317
+ "output" => "users",
318
+ },
319
+ gather_message["body"]["users_reduced"])
320
+ end
321
+ end
322
+
323
+ class WithHashAttributesTest < self
324
+ def setup
325
+ @output = {
326
+ "elements" => ["records"],
327
+ "attributes" => {
328
+ "id" => "_key",
329
+ "name" => { "source" => "name" },
330
+ },
331
+ "limit" => 1,
332
+ }
333
+ @sort_by = {
334
+ "keys" => ["hidden"],
335
+ }
336
+ @request = {
337
+ "type" => "search",
338
+ "dataset" => "Droonga",
339
+ "body" => {
340
+ "queries" => {
341
+ "users" => {
342
+ "source" => "User",
343
+ "sortBy" => @sort_by,
344
+ "output" => @output,
345
+ },
346
+ },
347
+ },
348
+ }
349
+ end
350
+
351
+ def test_dependencies
352
+ reduce_inputs = ["errors", "users"]
353
+ gather_inputs = ["errors_reduced", "users_reduced"]
354
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
355
+ dependencies)
356
+ end
357
+
358
+ def test_broadcast_body
359
+ changed_sort_by_parameters = {
360
+ "offset" => 0,
361
+ "limit" => 1,
362
+ }
363
+ changed_output_parameters = {
364
+ "attributes" => [
365
+ { "label" => "id", "source" => "_key" },
366
+ { "label" => "name", "source" => "name" },
367
+ "hidden",
368
+ ],
369
+ }
370
+ assert_equal({
371
+ "queries" => {
372
+ "users" => {
373
+ "source" => "User",
374
+ "sortBy" => @sort_by.merge(changed_sort_by_parameters),
375
+ "output" => @output.merge(changed_output_parameters),
376
+ },
377
+ },
378
+ },
379
+ broadcast_message["body"])
380
+ end
381
+
382
+ def test_reduce_body
383
+ assert_equal({
384
+ "users_reduced" => {
385
+ "records" => {
386
+ "type" => "sort",
387
+ "operators" => [
388
+ { "column" => 2, "operator" => "<" },
389
+ ],
390
+ "limit" => 1,
391
+ },
392
+ },
393
+ },
394
+ reduce_message["body"]["users"])
395
+ end
396
+
397
+ def test_gather_records
398
+ assert_equal({
399
+ "elements" => {
400
+ "records" => {
401
+ "attributes" => ["id", "name"],
402
+ "limit" => 1,
403
+ },
404
+ },
405
+ "output" => "users",
406
+ },
407
+ gather_message["body"]["users_reduced"])
408
+ end
409
+ end
410
+
411
+ class WithComplexAttributesArrayTest < self
412
+ def setup
413
+ @output = {
414
+ "elements" => ["records"],
415
+ "attributes" => [
416
+ { "label" => "id", "source" => "_key" },
417
+ { "label" => "real_name", "source" => "name" },
418
+ ],
419
+ "limit" => 1,
420
+ }
421
+ @sort_by = {
422
+ "keys" => ["name"],
423
+ }
424
+ @request = {
425
+ "type" => "search",
426
+ "dataset" => "Droonga",
427
+ "body" => {
428
+ "queries" => {
429
+ "users" => {
430
+ "source" => "User",
431
+ "sortBy" => @sort_by,
432
+ "output" => @output,
433
+ },
434
+ },
435
+ },
436
+ }
437
+ end
438
+
439
+ def test_dependencies
440
+ reduce_inputs = ["errors", "users"]
441
+ gather_inputs = ["errors_reduced", "users_reduced"]
442
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
443
+ dependencies)
444
+ end
445
+
446
+ def test_broadcast_body
447
+ changed_sort_by_parameters = {
448
+ "offset" => 0,
449
+ "limit" => 1,
450
+ }
451
+ changed_output_parameters = {
452
+ "attributes" => [
453
+ { "label" => "id", "source" => "_key" },
454
+ { "label" => "real_name", "source" => "name" },
455
+ ],
456
+ }
457
+ assert_equal({
458
+ "queries" => {
459
+ "users" => {
460
+ "source" => "User",
461
+ "sortBy" => @sort_by.merge(changed_sort_by_parameters),
462
+ "output" => @output.merge(changed_output_parameters),
463
+ },
464
+ },
465
+ },
466
+ broadcast_message["body"])
467
+ end
468
+
469
+ def test_reduce_body
470
+ assert_equal({
471
+ "users_reduced" => {
472
+ "records" => {
473
+ "type" => "sort",
474
+ "operators" => [
475
+ { "column" => 1, "operator" => "<" },
476
+ ],
477
+ "limit" => 1,
478
+ },
479
+ },
480
+ },
481
+ reduce_message["body"]["users"])
482
+ end
483
+
484
+ def test_gather_records
485
+ assert_equal({
486
+ "elements" => {
487
+ "records" => {
488
+ "attributes" => ["id", "real_name"],
489
+ "limit" => 1,
490
+ },
491
+ },
492
+ "output" => "users",
493
+ },
494
+ gather_message["body"]["users_reduced"])
495
+ end
496
+ end
497
+
498
+ class MultipleColumnsTest < self
499
+ def setup
500
+ @output = {
501
+ "elements" => ["records"],
502
+ "attributes" => ["_key"],
503
+ "limit" => 1,
504
+ }
505
+ @sort_by = {
506
+ "keys" => ["-age", "name", "_key"],
507
+ }
508
+ @request = {
509
+ "type" => "search",
510
+ "dataset" => "Droonga",
511
+ "body" => {
512
+ "queries" => {
513
+ "users" => {
514
+ "source" => "User",
515
+ "sortBy" => @sort_by,
516
+ "output" => @output,
517
+ },
518
+ },
519
+ },
520
+ }
521
+ end
522
+
523
+ def test_dependencies
524
+ reduce_inputs = ["errors", "users"]
525
+ gather_inputs = ["errors_reduced", "users_reduced"]
526
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
527
+ dependencies)
528
+ end
529
+
530
+ def test_broadcast_body
531
+ changed_sort_by_parameters = {
532
+ "offset" => 0,
533
+ "limit" => 1,
534
+ }
535
+ changed_output_parameters = {
536
+ "attributes" => ["_key", "age", "name"],
537
+ }
538
+ assert_equal({
539
+ "queries" => {
540
+ "users" => {
541
+ "source" => "User",
542
+ "sortBy" => @sort_by.merge(changed_sort_by_parameters),
543
+ "output" => @output.merge(changed_output_parameters),
544
+ },
545
+ },
546
+ },
547
+ broadcast_message["body"])
548
+ end
549
+
550
+ def test_reduce_body
551
+ assert_equal({
552
+ "users_reduced" => {
553
+ "records" => {
554
+ "type" => "sort",
555
+ "operators" => [
556
+ { "column" => 1, "operator" => ">" },
557
+ { "column" => 2, "operator" => "<" },
558
+ { "column" => 0, "operator" => "<" },
559
+ ],
560
+ "limit" => 1,
561
+ },
562
+ },
563
+ },
564
+ reduce_message["body"]["users"])
565
+ end
566
+
567
+ def test_gather_records
568
+ assert_equal({
569
+ "elements" => {
570
+ "records" => {
571
+ "attributes" => ["_key"],
572
+ "limit" => 1,
573
+ },
574
+ },
575
+ "output" => "users",
576
+ },
577
+ gather_message["body"]["users_reduced"])
578
+ end
579
+ end
580
+
581
+ class OffsetLimitTest < self
582
+ def max_limit
583
+ [@sort_by["limit"], @output["limit"]].max
584
+ end
585
+
586
+ def min_limit
587
+ [@sort_by["limit"], @output["limit"]].min
588
+ end
589
+
590
+ def total_offset
591
+ @sort_by["offset"] + @output["offset"]
592
+ end
593
+
594
+ class RegularRangeTest < self
595
+ def setup
596
+ @output = {
597
+ "elements" => ["records"],
598
+ "attributes" => ["_key"],
599
+ "offset" => 4,
600
+ "limit" => 8,
601
+ }
602
+ @sort_by = {
603
+ "keys" => ["_key"],
604
+ "offset" => 1,
605
+ "limit" => 2,
606
+ }
607
+ @request = {
608
+ "type" => "search",
609
+ "dataset" => "Droonga",
610
+ "body" => {
611
+ "queries" => {
612
+ "users" => {
613
+ "source" => "User",
614
+ "sortBy" => @sort_by,
615
+ "output" => @output,
616
+ },
617
+ },
618
+ },
619
+ }
620
+ end
621
+
622
+ def test_dependencies
623
+ reduce_inputs = ["errors", "users"]
624
+ gather_inputs = ["errors_reduced", "users_reduced"]
625
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
626
+ dependencies)
627
+ end
628
+
629
+ def test_broadcast_body
630
+ changed_sort_by_parameters = {
631
+ "offset" => 0,
632
+ "limit" => total_offset + max_limit,
633
+ }
634
+ changed_output_parameters = {
635
+ "offset" => 0,
636
+ "limit" => total_offset + min_limit,
637
+ }
638
+ assert_equal({
639
+ "queries" => {
640
+ "users" => {
641
+ "source" => "User",
642
+ "sortBy" => @sort_by.merge(changed_sort_by_parameters),
643
+ "output" => @output.merge(changed_output_parameters),
644
+ },
645
+ },
646
+ },
647
+ broadcast_message["body"])
648
+ end
649
+
650
+ def test_reduce_body
651
+ assert_equal({
652
+ "users_reduced" => {
653
+ "records" => {
654
+ "type" => "sort",
655
+ "operators" => [
656
+ { "column" => 0, "operator" => "<" },
657
+ ],
658
+ "limit" => total_offset + min_limit,
659
+ },
660
+ },
661
+ },
662
+ reduce_message["body"]["users"])
663
+ end
664
+
665
+ def test_gather_records
666
+ assert_equal({
667
+ "elements" => {
668
+ "records" => {
669
+ "attributes" => ["_key"],
670
+ "offset" => total_offset,
671
+ "limit" => min_limit,
672
+ },
673
+ },
674
+ "output" => "users",
675
+ },
676
+ gather_message["body"]["users_reduced"])
677
+ end
678
+ end
679
+
680
+ class InfinitOutputLimitTest < self
681
+ def setup
682
+ @output = {
683
+ "elements" => ["records"],
684
+ "attributes" => ["_key"],
685
+ "offset" => 4,
686
+ "limit" => -1,
687
+ }
688
+ @sort_by = {
689
+ "keys" => ["_key"],
690
+ "offset" => 1,
691
+ "limit" => 2,
692
+ }
693
+ @request = {
694
+ "type" => "search",
695
+ "dataset" => "Droonga",
696
+ "body" => {
697
+ "queries" => {
698
+ "users" => {
699
+ "source" => "User",
700
+ "sortBy" => @sort_by,
701
+ "output" => @output,
702
+ },
703
+ },
704
+ },
705
+ }
706
+ end
707
+
708
+ def test_dependencies
709
+ reduce_inputs = ["errors", "users"]
710
+ gather_inputs = ["errors_reduced", "users_reduced"]
711
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
712
+ dependencies)
713
+ end
714
+
715
+ def test_broadcast_body
716
+ changed_sort_by_parameters = {
717
+ "offset" => 0,
718
+ "limit" => total_offset + max_limit,
719
+ }
720
+ changed_output_parameters = {
721
+ "offset" => 0,
722
+ "limit" => total_offset + max_limit,
723
+ }
724
+ assert_equal({
725
+ "queries" => {
726
+ "users" => {
727
+ "source" => "User",
728
+ "sortBy" => @sort_by.merge(changed_sort_by_parameters),
729
+ "output" => @output.merge(changed_output_parameters),
730
+ },
731
+ },
732
+ },
733
+ broadcast_message["body"])
734
+ end
735
+
736
+ def test_reduce_body
737
+ assert_equal({
738
+ "users_reduced" => {
739
+ "records" => {
740
+ "type" => "sort",
741
+ "operators" => [
742
+ { "column" => 0, "operator" => "<" },
743
+ ],
744
+ "limit" => total_offset + max_limit,
745
+ },
746
+ },
747
+ },
748
+ reduce_message["body"]["users"])
749
+ end
750
+
751
+ def test_gather_records
752
+ assert_equal({
753
+ "elements" => {
754
+ "records" => {
755
+ "attributes" => ["_key"],
756
+ "offset" => total_offset,
757
+ "limit" => max_limit,
758
+ },
759
+ },
760
+ "output" => "users",
761
+ },
762
+ gather_message["body"]["users_reduced"])
763
+ end
764
+ end
765
+
766
+ class InifinitSortLimitTest < self
767
+ def setup
768
+ @output = {
769
+ "elements" => ["records"],
770
+ "attributes" => ["_key"],
771
+ "offset" => 4,
772
+ "limit" => 8,
773
+ }
774
+ @sort_by = {
775
+ "keys" => ["_key"],
776
+ "offset" => 1,
777
+ "limit" => -1,
778
+ }
779
+ @request = {
780
+ "type" => "search",
781
+ "dataset" => "Droonga",
782
+ "body" => {
783
+ "queries" => {
784
+ "users" => {
785
+ "source" => "User",
786
+ "sortBy" => @sort_by,
787
+ "output" => @output,
788
+ },
789
+ },
790
+ },
791
+ }
792
+ end
793
+
794
+ def test_dependencies
795
+ reduce_inputs = ["errors", "users"]
796
+ gather_inputs = ["errors_reduced", "users_reduced"]
797
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
798
+ dependencies)
799
+ end
800
+
801
+ def test_broadcast_body
802
+ changed_sort_by_parameters = {
803
+ "offset" => 0,
804
+ "limit" => total_offset + max_limit,
805
+ }
806
+ changed_output_parameters = {
807
+ "offset" => 0,
808
+ "limit" => total_offset + max_limit,
809
+ }
810
+ assert_equal({
811
+ "queries" => {
812
+ "users" => {
813
+ "source" => "User",
814
+ "sortBy" => @sort_by.merge(changed_sort_by_parameters),
815
+ "output" => @output.merge(changed_output_parameters),
816
+ },
817
+ },
818
+ },
819
+ broadcast_message["body"])
820
+ end
821
+
822
+ def test_reduce_body
823
+ assert_equal({
824
+ "users_reduced" => {
825
+ "records" => {
826
+ "type" => "sort",
827
+ "operators" => [
828
+ { "column" => 0, "operator" => "<" },
829
+ ],
830
+ "limit" => total_offset + max_limit,
831
+ },
832
+ },
833
+ },
834
+ reduce_message["body"]["users"])
835
+ end
836
+
837
+ def test_gather_records
838
+ assert_equal({
839
+ "elements" => {
840
+ "records" => {
841
+ "attributes" => ["_key"],
842
+ "offset" => total_offset,
843
+ "limit" => max_limit,
844
+ },
845
+ },
846
+ "output" => "users",
847
+ },
848
+ gather_message["body"]["users_reduced"])
849
+ end
850
+ end
851
+
852
+ class InifinitBothLimitTest < self
853
+ def setup
854
+ @output = {
855
+ "elements" => ["records"],
856
+ "attributes" => ["_key"],
857
+ "offset" => 4,
858
+ "limit" => -1,
859
+ }
860
+ @sort_by = {
861
+ "keys" => ["_key"],
862
+ "offset" => 1,
863
+ "limit" => -1,
864
+ }
865
+ @request = {
866
+ "type" => "search",
867
+ "dataset" => "Droonga",
868
+ "body" => {
869
+ "queries" => {
870
+ "users" => {
871
+ "source" => "User",
872
+ "sortBy" => @sort_by,
873
+ "output" => @output,
874
+ },
875
+ },
876
+ },
877
+ }
878
+ end
879
+
880
+ def test_dependencies
881
+ reduce_inputs = ["errors", "users"]
882
+ gather_inputs = ["errors_reduced", "users_reduced"]
883
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
884
+ dependencies)
885
+ end
886
+
887
+ def test_broadcast_body
888
+ changed_sort_by_parameters = {
889
+ "offset" => 0,
890
+ "limit" => min_limit,
891
+ }
892
+ changed_output_parameters = {
893
+ "offset" => 0,
894
+ "limit" => min_limit,
895
+ }
896
+ assert_equal({
897
+ "queries" => {
898
+ "users" => {
899
+ "source" => "User",
900
+ "sortBy" => @sort_by.merge(changed_sort_by_parameters),
901
+ "output" => @output.merge(changed_output_parameters),
902
+ },
903
+ },
904
+ },
905
+ broadcast_message["body"])
906
+ end
907
+
908
+ def test_reduce_body
909
+ assert_equal({
910
+ "users_reduced" => {
911
+ "records" => {
912
+ "type" => "sort",
913
+ "operators" => [
914
+ { "column" => 0, "operator" => "<" },
915
+ ],
916
+ "limit" => min_limit,
917
+ },
918
+ },
919
+ },
920
+ reduce_message["body"]["users"])
921
+ end
922
+
923
+ def test_gather_records
924
+ assert_equal({
925
+ "elements" => {
926
+ "records" => {
927
+ "attributes" => ["_key"],
928
+ "offset" => total_offset,
929
+ "limit" => min_limit,
930
+ },
931
+ },
932
+ "output" => "users",
933
+ },
934
+ gather_message["body"]["users_reduced"])
935
+ end
936
+ end
937
+ end
938
+ end