fluid_cli 0.1.2

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 (329) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +1 -0
  3. data/dev.yml +5 -0
  4. data/exe/fluid +24 -0
  5. data/lib/fluid_cli/api.rb +135 -0
  6. data/lib/fluid_cli/assets/post_auth_page/index.html.erb +34 -0
  7. data/lib/fluid_cli/assets/post_auth_page/style.css +58 -0
  8. data/lib/fluid_cli/command.rb +55 -0
  9. data/lib/fluid_cli/commands/help.rb +21 -0
  10. data/lib/fluid_cli/commands/login.rb +30 -0
  11. data/lib/fluid_cli/commands/logout.rb +38 -0
  12. data/lib/fluid_cli/commands/switch.rb +23 -0
  13. data/lib/fluid_cli/commands/theme/common/company_helper.rb +15 -0
  14. data/lib/fluid_cli/commands/theme/common/root_helper.rb +95 -0
  15. data/lib/fluid_cli/commands/theme/dev.rb +61 -0
  16. data/lib/fluid_cli/commands/theme/help.rb +21 -0
  17. data/lib/fluid_cli/commands/theme/init.rb +46 -0
  18. data/lib/fluid_cli/commands/theme/pull.rb +68 -0
  19. data/lib/fluid_cli/commands/theme/push.rb +132 -0
  20. data/lib/fluid_cli/commands/theme.rb +23 -0
  21. data/lib/fluid_cli/commands/whoami.rb +23 -0
  22. data/lib/fluid_cli/commands.rb +19 -0
  23. data/lib/fluid_cli/company_switcher.rb +69 -0
  24. data/lib/fluid_cli/context.rb +691 -0
  25. data/lib/fluid_cli/db.rb +114 -0
  26. data/lib/fluid_cli/entry_point.rb +10 -0
  27. data/lib/fluid_cli/environment.rb +32 -0
  28. data/lib/fluid_cli/file_system_listener.rb +29 -0
  29. data/lib/fluid_cli/form.rb +42 -0
  30. data/lib/fluid_cli/git.rb +319 -0
  31. data/lib/fluid_cli/http_request.rb +54 -0
  32. data/lib/fluid_cli/identity_auth/servlet.rb +39 -0
  33. data/lib/fluid_cli/identity_auth.rb +126 -0
  34. data/lib/fluid_cli/options.rb +38 -0
  35. data/lib/fluid_cli/theme/dev_server/certificate_manager.rb +79 -0
  36. data/lib/fluid_cli/theme/dev_server/errors.rb +9 -0
  37. data/lib/fluid_cli/theme/dev_server/header_hash.rb +98 -0
  38. data/lib/fluid_cli/theme/dev_server/hooks/file_change_hook.rb +39 -0
  39. data/lib/fluid_cli/theme/dev_server/hot_reload/resources/hot-reload-no-script.html +27 -0
  40. data/lib/fluid_cli/theme/dev_server/hot_reload/resources/hot_reload.js +28 -0
  41. data/lib/fluid_cli/theme/dev_server/hot_reload/resources/sse_client.js +43 -0
  42. data/lib/fluid_cli/theme/dev_server/hot_reload/resources/theme.js +16 -0
  43. data/lib/fluid_cli/theme/dev_server/hot_reload/script_injector.rb +54 -0
  44. data/lib/fluid_cli/theme/dev_server/hot_reload.rb +75 -0
  45. data/lib/fluid_cli/theme/dev_server/local_assets.rb +92 -0
  46. data/lib/fluid_cli/theme/dev_server/proxy.rb +235 -0
  47. data/lib/fluid_cli/theme/dev_server/proxy_param_builder.rb +82 -0
  48. data/lib/fluid_cli/theme/dev_server/reload_mode.rb +34 -0
  49. data/lib/fluid_cli/theme/dev_server/sse.rb +75 -0
  50. data/lib/fluid_cli/theme/dev_server/watcher.rb +57 -0
  51. data/lib/fluid_cli/theme/dev_server/web_server.rb +140 -0
  52. data/lib/fluid_cli/theme/dev_server.rb +289 -0
  53. data/lib/fluid_cli/theme/development_theme.rb +101 -0
  54. data/lib/fluid_cli/theme/file.rb +105 -0
  55. data/lib/fluid_cli/theme/forms/select.rb +33 -0
  56. data/lib/fluid_cli/theme/mime_type.rb +34 -0
  57. data/lib/fluid_cli/theme/presenters/theme_presenter.rb +49 -0
  58. data/lib/fluid_cli/theme/presenters/themes_presenter.rb +31 -0
  59. data/lib/fluid_cli/theme/root.rb +62 -0
  60. data/lib/fluid_cli/theme/syncer/checksums.rb +66 -0
  61. data/lib/fluid_cli/theme/syncer/downloader.rb +54 -0
  62. data/lib/fluid_cli/theme/syncer/error_reporter.rb +45 -0
  63. data/lib/fluid_cli/theme/syncer/merger.rb +53 -0
  64. data/lib/fluid_cli/theme/syncer/operation.rb +58 -0
  65. data/lib/fluid_cli/theme/syncer/standard_reporter.rb +32 -0
  66. data/lib/fluid_cli/theme/syncer/unsupported_script_warning.rb +90 -0
  67. data/lib/fluid_cli/theme/syncer/uploader/forms/apply_to_all.rb +41 -0
  68. data/lib/fluid_cli/theme/syncer/uploader/forms/apply_to_all_form.rb +37 -0
  69. data/lib/fluid_cli/theme/syncer/uploader/forms/base_strategy_form.rb +64 -0
  70. data/lib/fluid_cli/theme/syncer/uploader/forms/select_delete_strategy.rb +29 -0
  71. data/lib/fluid_cli/theme/syncer/uploader/forms/select_update_strategy.rb +30 -0
  72. data/lib/fluid_cli/theme/syncer/uploader/json_delete_handler.rb +49 -0
  73. data/lib/fluid_cli/theme/syncer/uploader/json_update_handler.rb +71 -0
  74. data/lib/fluid_cli/theme/syncer/uploader.rb +105 -0
  75. data/lib/fluid_cli/theme/syncer.rb +412 -0
  76. data/lib/fluid_cli/theme/theme.rb +186 -0
  77. data/lib/fluid_cli/theme/ui/sync_progress_bar.rb +22 -0
  78. data/lib/fluid_cli/thread_pool/job.rb +35 -0
  79. data/lib/fluid_cli/thread_pool.rb +49 -0
  80. data/lib/fluid_cli/version.rb +3 -0
  81. data/lib/fluid_cli.rb +59 -0
  82. data/vendor/deps/base64/.document +5 -0
  83. data/vendor/deps/base64/.gitignore +9 -0
  84. data/vendor/deps/base64/BSDL +22 -0
  85. data/vendor/deps/base64/COPYING +56 -0
  86. data/vendor/deps/base64/Gemfile +9 -0
  87. data/vendor/deps/base64/LEGAL +60 -0
  88. data/vendor/deps/base64/README.md +48 -0
  89. data/vendor/deps/base64/Rakefile +31 -0
  90. data/vendor/deps/base64/base64.gemspec +28 -0
  91. data/vendor/deps/base64/bin/console +14 -0
  92. data/vendor/deps/base64/bin/setup +8 -0
  93. data/vendor/deps/base64/lib/base64.rb +382 -0
  94. data/vendor/deps/base64/sig/base64.rbs +358 -0
  95. data/vendor/deps/base64/test/base64/test_base64.rb +115 -0
  96. data/vendor/deps/base64/test_sig/test_base64.rb +44 -0
  97. data/vendor/deps/cli-kit/REVISION +1 -0
  98. data/vendor/deps/cli-kit/lib/cli/kit/args/definition.rb +286 -0
  99. data/vendor/deps/cli-kit/lib/cli/kit/args/evaluation.rb +215 -0
  100. data/vendor/deps/cli-kit/lib/cli/kit/args/parser/node.rb +128 -0
  101. data/vendor/deps/cli-kit/lib/cli/kit/args/parser.rb +125 -0
  102. data/vendor/deps/cli-kit/lib/cli/kit/args/tokenizer.rb +130 -0
  103. data/vendor/deps/cli-kit/lib/cli/kit/args.rb +16 -0
  104. data/vendor/deps/cli-kit/lib/cli/kit/base_command.rb +30 -0
  105. data/vendor/deps/cli-kit/lib/cli/kit/command_help.rb +268 -0
  106. data/vendor/deps/cli-kit/lib/cli/kit/command_registry.rb +150 -0
  107. data/vendor/deps/cli-kit/lib/cli/kit/config.rb +137 -0
  108. data/vendor/deps/cli-kit/lib/cli/kit/core_ext.rb +28 -0
  109. data/vendor/deps/cli-kit/lib/cli/kit/error_handler.rb +166 -0
  110. data/vendor/deps/cli-kit/lib/cli/kit/executor.rb +92 -0
  111. data/vendor/deps/cli-kit/lib/cli/kit/ini.rb +91 -0
  112. data/vendor/deps/cli-kit/lib/cli/kit/levenshtein.rb +92 -0
  113. data/vendor/deps/cli-kit/lib/cli/kit/logger.rb +94 -0
  114. data/vendor/deps/cli-kit/lib/cli/kit/opts.rb +248 -0
  115. data/vendor/deps/cli-kit/lib/cli/kit/parse_args.rb +55 -0
  116. data/vendor/deps/cli-kit/lib/cli/kit/resolver.rb +66 -0
  117. data/vendor/deps/cli-kit/lib/cli/kit/support/test_helper.rb +260 -0
  118. data/vendor/deps/cli-kit/lib/cli/kit/support.rb +11 -0
  119. data/vendor/deps/cli-kit/lib/cli/kit/system.rb +290 -0
  120. data/vendor/deps/cli-kit/lib/cli/kit/util.rb +118 -0
  121. data/vendor/deps/cli-kit/lib/cli/kit/version.rb +7 -0
  122. data/vendor/deps/cli-kit/lib/cli/kit.rb +139 -0
  123. data/vendor/deps/cli-ui/REVISION +1 -0
  124. data/vendor/deps/cli-ui/lib/cli/ui/ansi.rb +218 -0
  125. data/vendor/deps/cli-ui/lib/cli/ui/color.rb +101 -0
  126. data/vendor/deps/cli-ui/lib/cli/ui/formatter.rb +219 -0
  127. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_stack.rb +67 -0
  128. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style/box.rb +179 -0
  129. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style/bracket.rb +152 -0
  130. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style.rb +127 -0
  131. data/vendor/deps/cli-ui/lib/cli/ui/frame.rb +286 -0
  132. data/vendor/deps/cli-ui/lib/cli/ui/glyph.rb +92 -0
  133. data/vendor/deps/cli-ui/lib/cli/ui/os.rb +63 -0
  134. data/vendor/deps/cli-ui/lib/cli/ui/printer.rb +64 -0
  135. data/vendor/deps/cli-ui/lib/cli/ui/progress.rb +132 -0
  136. data/vendor/deps/cli-ui/lib/cli/ui/progress_reporter.rb +209 -0
  137. data/vendor/deps/cli-ui/lib/cli/ui/prompt/interactive_options.rb +583 -0
  138. data/vendor/deps/cli-ui/lib/cli/ui/prompt/options_handler.rb +36 -0
  139. data/vendor/deps/cli-ui/lib/cli/ui/prompt.rb +381 -0
  140. data/vendor/deps/cli-ui/lib/cli/ui/spinner/async.rb +48 -0
  141. data/vendor/deps/cli-ui/lib/cli/ui/spinner/spin_group.rb +602 -0
  142. data/vendor/deps/cli-ui/lib/cli/ui/spinner.rb +79 -0
  143. data/vendor/deps/cli-ui/lib/cli/ui/stdout_router.rb +399 -0
  144. data/vendor/deps/cli-ui/lib/cli/ui/table.rb +83 -0
  145. data/vendor/deps/cli-ui/lib/cli/ui/terminal.rb +55 -0
  146. data/vendor/deps/cli-ui/lib/cli/ui/truncater.rb +106 -0
  147. data/vendor/deps/cli-ui/lib/cli/ui/version.rb +8 -0
  148. data/vendor/deps/cli-ui/lib/cli/ui/widgets/base.rb +46 -0
  149. data/vendor/deps/cli-ui/lib/cli/ui/widgets/status.rb +79 -0
  150. data/vendor/deps/cli-ui/lib/cli/ui/widgets.rb +89 -0
  151. data/vendor/deps/cli-ui/lib/cli/ui/work_queue.rb +142 -0
  152. data/vendor/deps/cli-ui/lib/cli/ui/wrap.rb +61 -0
  153. data/vendor/deps/cli-ui/lib/cli/ui.rb +359 -0
  154. data/vendor/deps/cli-ui/vendor/reentrant_mutex.rb +78 -0
  155. data/vendor/deps/debug/CONTRIBUTING.md +573 -0
  156. data/vendor/deps/debug/Gemfile +10 -0
  157. data/vendor/deps/debug/LICENSE.txt +22 -0
  158. data/vendor/deps/debug/README.md +996 -0
  159. data/vendor/deps/debug/Rakefile +57 -0
  160. data/vendor/deps/debug/TODO.md +23 -0
  161. data/vendor/deps/debug/debug.gemspec +33 -0
  162. data/vendor/deps/debug/exe/rdbg +53 -0
  163. data/vendor/deps/debug/ext/debug/Makefile +273 -0
  164. data/vendor/deps/debug/ext/debug/debug.c +228 -0
  165. data/vendor/deps/debug/ext/debug/debug_version.h +1 -0
  166. data/vendor/deps/debug/ext/debug/extconf.rb +27 -0
  167. data/vendor/deps/debug/ext/debug/iseq_collector.c +93 -0
  168. data/vendor/deps/debug/lib/debug/abbrev_command.rb +77 -0
  169. data/vendor/deps/debug/lib/debug/breakpoint.rb +556 -0
  170. data/vendor/deps/debug/lib/debug/client.rb +263 -0
  171. data/vendor/deps/debug/lib/debug/color.rb +123 -0
  172. data/vendor/deps/debug/lib/debug/config.rb +592 -0
  173. data/vendor/deps/debug/lib/debug/console.rb +224 -0
  174. data/vendor/deps/debug/lib/debug/dap_custom/traceInspector.rb +336 -0
  175. data/vendor/deps/debug/lib/debug/debug.bundle +0 -0
  176. data/vendor/deps/debug/lib/debug/frame_info.rb +190 -0
  177. data/vendor/deps/debug/lib/debug/irb_integration.rb +37 -0
  178. data/vendor/deps/debug/lib/debug/local.rb +115 -0
  179. data/vendor/deps/debug/lib/debug/open.rb +13 -0
  180. data/vendor/deps/debug/lib/debug/open_nonstop.rb +15 -0
  181. data/vendor/deps/debug/lib/debug/prelude.rb +50 -0
  182. data/vendor/deps/debug/lib/debug/server.rb +534 -0
  183. data/vendor/deps/debug/lib/debug/server_cdp.rb +1348 -0
  184. data/vendor/deps/debug/lib/debug/server_dap.rb +1108 -0
  185. data/vendor/deps/debug/lib/debug/session.rb +2667 -0
  186. data/vendor/deps/debug/lib/debug/source_repository.rb +150 -0
  187. data/vendor/deps/debug/lib/debug/start.rb +5 -0
  188. data/vendor/deps/debug/lib/debug/thread_client.rb +1457 -0
  189. data/vendor/deps/debug/lib/debug/tracer.rb +241 -0
  190. data/vendor/deps/debug/lib/debug/version.rb +5 -0
  191. data/vendor/deps/debug/lib/debug.rb +9 -0
  192. data/vendor/deps/debug/misc/README.md.erb +660 -0
  193. data/vendor/deps/listen/.github/release-drafter.yml +17 -0
  194. data/vendor/deps/listen/.github/workflows/development.yml +67 -0
  195. data/vendor/deps/listen/.github/workflows/push.yml +12 -0
  196. data/vendor/deps/listen/.gitignore +28 -0
  197. data/vendor/deps/listen/.rspec +3 -0
  198. data/vendor/deps/listen/.rubocop.yml +283 -0
  199. data/vendor/deps/listen/.yardopts +11 -0
  200. data/vendor/deps/listen/CHANGELOG.md +1 -0
  201. data/vendor/deps/listen/CONTRIBUTING.md +45 -0
  202. data/vendor/deps/listen/Gemfile +33 -0
  203. data/vendor/deps/listen/Guardfile +26 -0
  204. data/vendor/deps/listen/LICENSE.txt +22 -0
  205. data/vendor/deps/listen/README.md +490 -0
  206. data/vendor/deps/listen/Rakefile +154 -0
  207. data/vendor/deps/listen/bin/listen +11 -0
  208. data/vendor/deps/listen/lib/listen/adapter/base.rb +129 -0
  209. data/vendor/deps/listen/lib/listen/adapter/bsd.rb +104 -0
  210. data/vendor/deps/listen/lib/listen/adapter/config.rb +31 -0
  211. data/vendor/deps/listen/lib/listen/adapter/darwin.rb +77 -0
  212. data/vendor/deps/listen/lib/listen/adapter/linux.rb +108 -0
  213. data/vendor/deps/listen/lib/listen/adapter/polling.rb +40 -0
  214. data/vendor/deps/listen/lib/listen/adapter/windows.rb +96 -0
  215. data/vendor/deps/listen/lib/listen/adapter.rb +43 -0
  216. data/vendor/deps/listen/lib/listen/backend.rb +40 -0
  217. data/vendor/deps/listen/lib/listen/change.rb +69 -0
  218. data/vendor/deps/listen/lib/listen/cli.rb +65 -0
  219. data/vendor/deps/listen/lib/listen/directory.rb +93 -0
  220. data/vendor/deps/listen/lib/listen/error.rb +11 -0
  221. data/vendor/deps/listen/lib/listen/event/config.rb +39 -0
  222. data/vendor/deps/listen/lib/listen/event/loop.rb +92 -0
  223. data/vendor/deps/listen/lib/listen/event/processor.rb +128 -0
  224. data/vendor/deps/listen/lib/listen/event/queue.rb +52 -0
  225. data/vendor/deps/listen/lib/listen/file.rb +95 -0
  226. data/vendor/deps/listen/lib/listen/fsm.rb +131 -0
  227. data/vendor/deps/listen/lib/listen/listener/config.rb +41 -0
  228. data/vendor/deps/listen/lib/listen/listener.rb +136 -0
  229. data/vendor/deps/listen/lib/listen/logger.rb +65 -0
  230. data/vendor/deps/listen/lib/listen/monotonic_time.rb +27 -0
  231. data/vendor/deps/listen/lib/listen/options.rb +24 -0
  232. data/vendor/deps/listen/lib/listen/queue_optimizer.rb +129 -0
  233. data/vendor/deps/listen/lib/listen/record/entry.rb +66 -0
  234. data/vendor/deps/listen/lib/listen/record/symlink_detector.rb +47 -0
  235. data/vendor/deps/listen/lib/listen/record.rb +122 -0
  236. data/vendor/deps/listen/lib/listen/silencer/controller.rb +50 -0
  237. data/vendor/deps/listen/lib/listen/silencer.rb +106 -0
  238. data/vendor/deps/listen/lib/listen/thread.rb +54 -0
  239. data/vendor/deps/listen/lib/listen/version.rb +5 -0
  240. data/vendor/deps/listen/lib/listen.rb +47 -0
  241. data/vendor/deps/listen/listen.gemspec +40 -0
  242. data/vendor/deps/listen/spec/acceptance/listen_spec.rb +320 -0
  243. data/vendor/deps/listen/spec/lib/listen/adapter/base_spec.rb +101 -0
  244. data/vendor/deps/listen/spec/lib/listen/adapter/bsd_spec.rb +13 -0
  245. data/vendor/deps/listen/spec/lib/listen/adapter/config_spec.rb +122 -0
  246. data/vendor/deps/listen/spec/lib/listen/adapter/darwin_spec.rb +82 -0
  247. data/vendor/deps/listen/spec/lib/listen/adapter/linux_spec.rb +199 -0
  248. data/vendor/deps/listen/spec/lib/listen/adapter/polling_spec.rb +83 -0
  249. data/vendor/deps/listen/spec/lib/listen/adapter/windows_spec.rb +13 -0
  250. data/vendor/deps/listen/spec/lib/listen/adapter_spec.rb +69 -0
  251. data/vendor/deps/listen/spec/lib/listen/backend_spec.rb +82 -0
  252. data/vendor/deps/listen/spec/lib/listen/change_spec.rb +102 -0
  253. data/vendor/deps/listen/spec/lib/listen/cli_spec.rb +116 -0
  254. data/vendor/deps/listen/spec/lib/listen/directory_spec.rb +284 -0
  255. data/vendor/deps/listen/spec/lib/listen/event/config_spec.rb +33 -0
  256. data/vendor/deps/listen/spec/lib/listen/event/loop_spec.rb +118 -0
  257. data/vendor/deps/listen/spec/lib/listen/event/processor_spec.rb +250 -0
  258. data/vendor/deps/listen/spec/lib/listen/event/queue_spec.rb +118 -0
  259. data/vendor/deps/listen/spec/lib/listen/file_spec.rb +254 -0
  260. data/vendor/deps/listen/spec/lib/listen/fsm_spec.rb +147 -0
  261. data/vendor/deps/listen/spec/lib/listen/listener/config_spec.rb +29 -0
  262. data/vendor/deps/listen/spec/lib/listen/listener_spec.rb +321 -0
  263. data/vendor/deps/listen/spec/lib/listen/logger_spec.rb +212 -0
  264. data/vendor/deps/listen/spec/lib/listen/monotonic_time_spec.rb +58 -0
  265. data/vendor/deps/listen/spec/lib/listen/queue_optimizer_spec.rb +111 -0
  266. data/vendor/deps/listen/spec/lib/listen/record_spec.rb +424 -0
  267. data/vendor/deps/listen/spec/lib/listen/silencer/controller_spec.rb +97 -0
  268. data/vendor/deps/listen/spec/lib/listen/silencer_spec.rb +109 -0
  269. data/vendor/deps/listen/spec/lib/listen/thread_spec.rb +133 -0
  270. data/vendor/deps/listen/spec/lib/listen_spec.rb +25 -0
  271. data/vendor/deps/listen/spec/spec_helper.rb +49 -0
  272. data/vendor/deps/listen/spec/support/acceptance_helper.rb +260 -0
  273. data/vendor/deps/listen/spec/support/fixtures_helper.rb +32 -0
  274. data/vendor/deps/listen/spec/support/platform_helper.rb +17 -0
  275. data/vendor/deps/observer/.github/dependabot.yml +6 -0
  276. data/vendor/deps/observer/.github/workflows/test.yml +33 -0
  277. data/vendor/deps/observer/.gitignore +8 -0
  278. data/vendor/deps/observer/BSDL +22 -0
  279. data/vendor/deps/observer/COPYING +56 -0
  280. data/vendor/deps/observer/Gemfile +9 -0
  281. data/vendor/deps/observer/README.md +139 -0
  282. data/vendor/deps/observer/Rakefile +10 -0
  283. data/vendor/deps/observer/bin/console +14 -0
  284. data/vendor/deps/observer/bin/setup +8 -0
  285. data/vendor/deps/observer/lib/observer.rb +229 -0
  286. data/vendor/deps/observer/observer.gemspec +32 -0
  287. data/vendor/deps/observer/test/test_observer.rb +66 -0
  288. data/vendor/deps/webrick/.gitignore +9 -0
  289. data/vendor/deps/webrick/Gemfile +3 -0
  290. data/vendor/deps/webrick/LICENSE.txt +22 -0
  291. data/vendor/deps/webrick/README.md +61 -0
  292. data/vendor/deps/webrick/Rakefile +10 -0
  293. data/vendor/deps/webrick/lib/webrick/accesslog.rb +157 -0
  294. data/vendor/deps/webrick/lib/webrick/cgi.rb +313 -0
  295. data/vendor/deps/webrick/lib/webrick/compat.rb +36 -0
  296. data/vendor/deps/webrick/lib/webrick/config.rb +158 -0
  297. data/vendor/deps/webrick/lib/webrick/cookie.rb +172 -0
  298. data/vendor/deps/webrick/lib/webrick/htmlutils.rb +30 -0
  299. data/vendor/deps/webrick/lib/webrick/httpauth/authenticator.rb +117 -0
  300. data/vendor/deps/webrick/lib/webrick/httpauth/basicauth.rb +116 -0
  301. data/vendor/deps/webrick/lib/webrick/httpauth/digestauth.rb +395 -0
  302. data/vendor/deps/webrick/lib/webrick/httpauth/htdigest.rb +132 -0
  303. data/vendor/deps/webrick/lib/webrick/httpauth/htgroup.rb +97 -0
  304. data/vendor/deps/webrick/lib/webrick/httpauth/htpasswd.rb +158 -0
  305. data/vendor/deps/webrick/lib/webrick/httpauth/userdb.rb +53 -0
  306. data/vendor/deps/webrick/lib/webrick/httpauth.rb +96 -0
  307. data/vendor/deps/webrick/lib/webrick/httpproxy.rb +354 -0
  308. data/vendor/deps/webrick/lib/webrick/httprequest.rb +636 -0
  309. data/vendor/deps/webrick/lib/webrick/httpresponse.rb +564 -0
  310. data/vendor/deps/webrick/lib/webrick/https.rb +152 -0
  311. data/vendor/deps/webrick/lib/webrick/httpserver.rb +294 -0
  312. data/vendor/deps/webrick/lib/webrick/httpservlet/abstract.rb +152 -0
  313. data/vendor/deps/webrick/lib/webrick/httpservlet/cgi_runner.rb +47 -0
  314. data/vendor/deps/webrick/lib/webrick/httpservlet/cgihandler.rb +126 -0
  315. data/vendor/deps/webrick/lib/webrick/httpservlet/erbhandler.rb +88 -0
  316. data/vendor/deps/webrick/lib/webrick/httpservlet/filehandler.rb +552 -0
  317. data/vendor/deps/webrick/lib/webrick/httpservlet/prochandler.rb +47 -0
  318. data/vendor/deps/webrick/lib/webrick/httpservlet.rb +23 -0
  319. data/vendor/deps/webrick/lib/webrick/httpstatus.rb +194 -0
  320. data/vendor/deps/webrick/lib/webrick/httputils.rb +512 -0
  321. data/vendor/deps/webrick/lib/webrick/httpversion.rb +76 -0
  322. data/vendor/deps/webrick/lib/webrick/log.rb +156 -0
  323. data/vendor/deps/webrick/lib/webrick/server.rb +381 -0
  324. data/vendor/deps/webrick/lib/webrick/ssl.rb +215 -0
  325. data/vendor/deps/webrick/lib/webrick/utils.rb +265 -0
  326. data/vendor/deps/webrick/lib/webrick/version.rb +18 -0
  327. data/vendor/deps/webrick/lib/webrick.rb +232 -0
  328. data/vendor/deps/webrick/webrick.gemspec +74 -0
  329. metadata +412 -0
@@ -0,0 +1,284 @@
1
+ # frozen_string_literal: true
2
+
3
+ include Listen
4
+
5
+ RSpec.describe Directory do
6
+ def fake_file_stat(name, options = {})
7
+ defaults = { directory?: false }
8
+ instance_double(::File::Stat, name, defaults.merge(options))
9
+ end
10
+
11
+ def fake_dir_stat(name, options = {})
12
+ defaults = { directory?: true }
13
+ instance_double(::File::Stat, name, defaults.merge(options))
14
+ end
15
+
16
+ def fake_children(exception, dir, *args, &block)
17
+ if block_given?
18
+ exception.send(:allow, dir).to receive(:children, &block)
19
+ else
20
+ exception.send(:allow, dir).to receive(:children).and_return(*args)
21
+ end
22
+ exception.send(:allow, dir).to receive(:exist?).and_return(true)
23
+ exception.send(:allow, dir).to receive(:directory?).and_return(true)
24
+ end
25
+
26
+ let(:dir) { double(:dir) }
27
+ let(:file) { fake_path('file.rb') }
28
+ let(:file2) { fake_path('file2.rb') }
29
+ let(:subdir) { fake_path('subdir') }
30
+
31
+ let(:record) do
32
+ instance_double(
33
+ Record,
34
+ root: 'some_dir',
35
+ dir_entries: record_entries,
36
+ add_dir: true,
37
+ unset_path: true)
38
+ end
39
+
40
+ let(:snapshot) { instance_double(Change, record: record, invalidate: nil) }
41
+
42
+ before do
43
+ allow(dir).to receive(:+).with('.') { dir }
44
+ allow(dir).to receive(:+).with('file.rb') { file }
45
+ allow(dir).to receive(:+).with('subdir') { subdir }
46
+
47
+ allow(file).to receive(:relative_path_from).with(dir) { 'file.rb' }
48
+ allow(file2).to receive(:relative_path_from).with(dir) { 'file2.rb' }
49
+ allow(subdir).to receive(:relative_path_from).with(dir) { 'subdir' }
50
+
51
+ allow(Pathname).to receive(:new).with('some_dir').and_return(dir)
52
+ allow(Pathname).to receive(:new).with('.').and_return(dir)
53
+
54
+ allow(::File).to receive(:lstat) do |*args|
55
+ fail "Not stubbed: File.lstat(#{args.map(&:inspect) * ','})"
56
+ end
57
+ end
58
+
59
+ context '#scan with recursive off' do
60
+ let(:options) { { recursive: false } }
61
+
62
+ context 'with file & subdir in record' do
63
+ let(:record_entries) do
64
+ { 'file.rb' => { mtime: 1.1 }, 'subdir' => {} }.freeze
65
+ end
66
+
67
+ context 'with empty dir' do
68
+ before { fake_children(self, dir, []) }
69
+
70
+ it 'sets record dir path' do
71
+ expect(record).to receive(:add_dir).with('.')
72
+ described_class.scan(snapshot, '.', options)
73
+ end
74
+
75
+ it "snapshots changes for file path and dir that doesn't exist" do
76
+ expect(snapshot).to receive(:invalidate).with(:file, 'file.rb', {})
77
+
78
+ expect(snapshot).to receive(:invalidate).
79
+ with(:dir, 'subdir', { recursive: false })
80
+
81
+ described_class.scan(snapshot, '.', options)
82
+ end
83
+ end
84
+
85
+ context 'when subdir is removed' do
86
+ before do
87
+ fake_children(self, dir, [file])
88
+ allow(::File).to receive(:lstat).with('file.rb').
89
+ and_return(fake_file_stat('file.rb'))
90
+ end
91
+
92
+ it 'notices subdir does not exist' do
93
+ expect(snapshot).to receive(:invalidate).
94
+ with(:dir, 'subdir', { recursive: false })
95
+
96
+ described_class.scan(snapshot, '.', options)
97
+ end
98
+ end
99
+
100
+ context 'when file.rb removed' do
101
+ before do
102
+ fake_children(self, dir, [subdir])
103
+
104
+ allow(::File).to receive(:lstat).with('subdir').
105
+ and_return(fake_dir_stat('subdir'))
106
+ end
107
+
108
+ it 'notices file was removed' do
109
+ expect(snapshot).to receive(:invalidate).with(:file, 'file.rb', {})
110
+ described_class.scan(snapshot, '.', options)
111
+ end
112
+ end
113
+
114
+ context 'when file.rb no longer exists after scan' do
115
+ before do
116
+ fake_children(self, dir, [file], [file2])
117
+
118
+ allow(::File).to receive(:lstat).with('file.rb').
119
+ and_raise(Errno::ENOENT)
120
+
121
+ allow(::File).to receive(:lstat).with('file2.rb').
122
+ and_return(fake_file_stat('file2.rb'))
123
+ end
124
+
125
+ it 'rescans' do
126
+ expect(snapshot).to receive(:invalidate).with(:file, 'file2.rb', {})
127
+ described_class.scan(snapshot, '.', options)
128
+ end
129
+ end
130
+
131
+ context 'when file2.rb is added' do
132
+ before do
133
+ fake_children(self, dir, [file, file2, subdir])
134
+
135
+ allow(::File).to receive(:lstat).with('file.rb').
136
+ and_return(fake_file_stat('file.rb'))
137
+
138
+ allow(::File).to receive(:lstat).with('file2.rb').
139
+ and_return(fake_file_stat('file2.rb'))
140
+
141
+ allow(::File).to receive(:lstat).with('subdir').
142
+ and_return(fake_dir_stat('subdir'))
143
+ end
144
+
145
+ it 'notices file removed and file2 changed' do
146
+ expect(snapshot).to receive(:invalidate).with(:file, 'file2.rb', {})
147
+ described_class.scan(snapshot, '.', options)
148
+ end
149
+ end
150
+ end
151
+
152
+ context 'with empty record' do
153
+ let(:record_entries) { {} }
154
+
155
+ context 'with non-existing dir path' do
156
+ before { fake_children(self, dir) { fail Errno::ENOENT } }
157
+
158
+ it 'reports no changes' do
159
+ expect(snapshot).to_not receive(:invalidate)
160
+ described_class.scan(snapshot, '.', options)
161
+ end
162
+
163
+ it 'unsets record dir path' do
164
+ expect(record).to receive(:unset_path).with('.')
165
+ described_class.scan(snapshot, '.', options)
166
+ end
167
+ end
168
+
169
+ context 'when network share is disconnected' do
170
+ before { fake_children(self, dir) { fail Errno::EHOSTDOWN } }
171
+
172
+ it 'reports no changes' do
173
+ expect(snapshot).to_not receive(:invalidate)
174
+ described_class.scan(snapshot, '.', options)
175
+ end
176
+
177
+ it 'unsets record dir path' do
178
+ expect(record).to receive(:unset_path).with('.')
179
+ described_class.scan(snapshot, '.', options)
180
+ end
181
+ end
182
+
183
+ context 'with file.rb in dir' do
184
+ before do
185
+ fake_children(self, dir, [file])
186
+
187
+ allow(::File).to receive(:lstat).with('file.rb').
188
+ and_return(fake_file_stat('file.rb'))
189
+ end
190
+
191
+ it 'snapshots changes for file & file2 paths' do
192
+ expect(snapshot).to receive(:invalidate).
193
+ with(:file, 'file.rb', {})
194
+
195
+ expect(snapshot).to_not receive(:invalidate).
196
+ with(:file, 'file2.rb', {})
197
+
198
+ expect(snapshot).to_not receive(:invalidate).
199
+ with(:dir, 'subdir', recursive: false)
200
+
201
+ described_class.scan(snapshot, '.', options)
202
+ end
203
+ end
204
+ end
205
+ end
206
+
207
+ context '#scan with recursive on' do
208
+ let(:options) { { recursive: true } }
209
+
210
+ context 'with file.rb & subdir in record' do
211
+ let(:record_entries) do
212
+ { 'file.rb' => { mtime: 1.1 }, 'subdir' => {} }
213
+ end
214
+
215
+ context 'with empty dir' do
216
+ before { fake_children(self, dir, []) }
217
+
218
+ it 'snapshots changes for file & subdir path' do
219
+ expect(snapshot).to receive(:invalidate).with(:file, 'file.rb', {})
220
+
221
+ expect(snapshot).to receive(:invalidate).
222
+ with(:dir, 'subdir', { recursive: true })
223
+
224
+ described_class.scan(snapshot, '.', options)
225
+ end
226
+ end
227
+
228
+ context 'with subdir2 path present' do
229
+ let(:subdir2) { fake_path('subdir2', children: []) }
230
+
231
+ before do
232
+ fake_children(self, dir, [subdir2])
233
+ allow(subdir2).to receive(:relative_path_from).with(dir) { 'subdir2' }
234
+
235
+ allow(::File).to receive(:lstat).with('subdir2').
236
+ and_return(fake_dir_stat('subdir2'))
237
+ end
238
+
239
+ it 'snapshots changes for file, file2 & subdir paths' do
240
+ expect(snapshot).to receive(:invalidate).with(:file, 'file.rb', {})
241
+
242
+ expect(snapshot).to receive(:invalidate).
243
+ with(:dir, 'subdir', { recursive: true })
244
+
245
+ expect(snapshot).to receive(:invalidate).
246
+ with(:dir, 'subdir2', { recursive: true })
247
+
248
+ described_class.scan(snapshot, '.', options)
249
+ end
250
+ end
251
+ end
252
+
253
+ context 'with empty record' do
254
+ let(:record_entries) { {} }
255
+
256
+ context 'with non-existing dir' do
257
+ before do
258
+ fake_children(self, dir) { fail Errno::ENOENT }
259
+ end
260
+
261
+ it 'reports no changes' do
262
+ expect(snapshot).to_not receive(:invalidate)
263
+ described_class.scan(snapshot, '.', options)
264
+ end
265
+ end
266
+
267
+ context 'with subdir present in dir' do
268
+ before do
269
+ fake_children(self, dir, [subdir])
270
+ fake_children(self, subdir, [])
271
+ allow(::File).to receive(:lstat).with('subdir').
272
+ and_return(fake_dir_stat('subdir'))
273
+ end
274
+
275
+ it 'snapshots changes for subdir' do
276
+ expect(snapshot).to receive(:invalidate).
277
+ with(:dir, 'subdir', { recursive: true })
278
+
279
+ described_class.scan(snapshot, '.', options)
280
+ end
281
+ end
282
+ end
283
+ end
284
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'listen/event/config'
4
+
5
+ RSpec.describe Listen::Event::Config do
6
+ let(:listener) { instance_double(Listen::Listener) }
7
+ let(:event_queue) { instance_double(Listen::Event::Queue) }
8
+ let(:queue_optimizer) { instance_double(Listen::QueueOptimizer) }
9
+ let(:wait_for_delay) { 1.234 }
10
+
11
+ context 'with a given block' do
12
+ let(:myblock) { instance_double(Proc) }
13
+
14
+ subject do
15
+ described_class.new(
16
+ listener,
17
+ event_queue,
18
+ queue_optimizer,
19
+ wait_for_delay) do |*args|
20
+ myblock.call(*args)
21
+ end
22
+ end
23
+
24
+ it 'calls the block' do
25
+ expect(myblock).to receive(:call).with(:foo, :bar)
26
+ subject.call(:foo, :bar)
27
+ end
28
+
29
+ it 'is callable' do
30
+ expect(subject).to be_callable
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thread'
4
+ require 'listen/event/config'
5
+ require 'listen/event/loop'
6
+
7
+ RSpec.describe Listen::Event::Loop do
8
+ let(:config) { instance_double(Listen::Event::Config, 'config') }
9
+ let(:processor) { instance_double(Listen::Event::Processor, 'processor') }
10
+ let(:thread) { instance_double(Thread, 'thread') }
11
+
12
+ let(:reasons) { instance_double(::Queue, 'reasons') }
13
+ let(:ready) { instance_double(::Queue, 'ready') }
14
+
15
+ let(:blocks) do
16
+ {
17
+ thread_block: proc { fail 'thread block stub called' },
18
+ }
19
+ end
20
+
21
+ subject { described_class.new(config) }
22
+
23
+ # TODO: this is hideous
24
+ before do
25
+ allow(::Queue).to receive(:new).and_return(reasons, ready)
26
+ allow(Listen::Event::Processor).to receive(:new).with(config, reasons).
27
+ and_return(processor)
28
+
29
+ allow(Thread).to receive(:new) do |*args, &block|
30
+ fail 'Unstubbed call:'\
31
+ " Thread.new(#{args.map(&:inspect) * ','},&#{block.inspect})"
32
+ end
33
+
34
+ allow(config).to receive(:min_delay_between_events).and_return(1.234)
35
+
36
+ allow(thread).to receive(:name=)
37
+ allow(Thread).to receive(:new) do |*_, &block|
38
+ blocks[:thread_block] = block
39
+ thread
40
+ end
41
+
42
+ allow(Kernel).to receive(:sleep) do |*args|
43
+ fail "stub called: sleep(#{args.map(&:inspect) * ','})"
44
+ end
45
+ end
46
+
47
+ describe '#start' do
48
+ it 'is started' do
49
+ expect(processor).to receive(:loop_for).with(1.234)
50
+ expect(Thread).to receive(:new) do |&block|
51
+ block.call
52
+ thread
53
+ end
54
+ subject.start
55
+ expect(subject).to be_started
56
+ end
57
+
58
+ context 'when start is called again' do
59
+ it 'returns silently' do
60
+ expect(processor).to receive(:loop_for).with(1.234)
61
+ expect(Thread).to receive(:new) do |&block|
62
+ block.call
63
+ thread
64
+ end
65
+ subject.start
66
+ expect { subject.start }.to_not raise_exception
67
+ end
68
+ end
69
+
70
+ context 'when state change to :started takes longer than 5 seconds' do
71
+ before do
72
+ expect(Thread).to receive(:new) { thread }
73
+ expect_any_instance_of(::ConditionVariable).to receive(:wait) { } # return immediately
74
+ end
75
+
76
+ it 'raises Error::NotStarted' do
77
+ expect do
78
+ subject.start
79
+ end.to raise_exception(::Listen::Error::NotStarted, "thread didn't start in 5.0 seconds (in state: :starting)")
80
+ end
81
+ end
82
+ end
83
+
84
+ context 'when set up / started' do
85
+ before do
86
+ allow(thread).to receive(:alive?).and_return(true)
87
+ allow(config).to receive(:min_delay_between_events).and_return(1.234)
88
+
89
+ allow(processor).to receive(:loop_for).with(1.234)
90
+
91
+ expect(Thread).to receive(:new) do |&block|
92
+ block.call
93
+ thread
94
+ end
95
+
96
+ subject.start
97
+ end
98
+
99
+ describe '#stop' do
100
+ before do
101
+ allow(thread).to receive(:join)
102
+ end
103
+
104
+ it 'frees the thread' do
105
+ subject.stop
106
+ end
107
+
108
+ it 'waits for the thread to finish' do
109
+ expect(thread).to receive(:join)
110
+ subject.stop
111
+ end
112
+
113
+ it 'sets the reason for waking up' do
114
+ subject.stop
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,250 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'listen/event/processor'
4
+ require 'listen/event/config'
5
+
6
+ RSpec.describe Listen::Event::Processor do
7
+ let(:event_queue) { instance_double(::Queue, 'event_queue') }
8
+ let(:event) { instance_double(::Array, 'event') }
9
+ let(:listener) { instance_double(Listen::Listener, 'listener') }
10
+ let(:config) { instance_double(Listen::Event::Config, 'config', listener: listener) }
11
+ let(:reasons) { instance_double(::Queue, 'reasons') }
12
+
13
+ subject { described_class.new(config, reasons) }
14
+
15
+ # This is to simulate events over various points in time
16
+ let(:sequence) do
17
+ {}
18
+ end
19
+
20
+ let(:state) do
21
+ { monotonic_time: 0.0 }
22
+ end
23
+
24
+ def status_for_time(time)
25
+ # find the status of the listener for a given point in time
26
+ previous_state_timestamps = sequence.keys.reject { |k| k > time }
27
+ last_state_before_given_time = previous_state_timestamps.max
28
+ sequence[last_state_before_given_time]
29
+ end
30
+
31
+ before do
32
+ allow(config).to receive(:event_queue).and_return(event_queue)
33
+
34
+ allow(listener).to receive(:stopped?) do
35
+ status_for_time(state[:monotonic_time]) == :stopped
36
+ end
37
+
38
+ allow(listener).to receive(:paused?) do
39
+ status_for_time(state[:monotonic_time]) == :paused
40
+ end
41
+
42
+ allow(Listen::MonotonicTime).to receive(:now) do
43
+ state[:monotonic_time]
44
+ end
45
+ end
46
+
47
+ describe '#loop_for' do
48
+ before do
49
+ allow(reasons).to receive(:empty?).and_return(true)
50
+ end
51
+
52
+ context 'when stopped' do
53
+ before do
54
+ sequence[0.0] = :stopped
55
+ end
56
+
57
+ context 'with pending changes' do
58
+ before do
59
+ allow(event_queue).to receive(:empty?).and_return(false)
60
+ end
61
+
62
+ it 'does not change the event queue' do
63
+ expect(event_queue).to receive(:pop).and_return(event)
64
+ subject.loop_for(1)
65
+ end
66
+
67
+ it 'does not sleep' do
68
+ expect(config).to_not receive(:sleep)
69
+ expect(event_queue).to receive(:pop).and_return(event)
70
+ t = Listen::MonotonicTime.now
71
+ subject.loop_for(1)
72
+ diff = Listen::MonotonicTime.now - t
73
+ expect(diff).to be < 0.02
74
+ end
75
+ end
76
+ end
77
+
78
+ context 'when not stopped' do
79
+ before do
80
+ allow(event_queue).to receive(:empty?).and_return(true)
81
+ end
82
+
83
+ context 'when initially paused' do
84
+ before do
85
+ sequence[0.0] = :paused
86
+ end
87
+
88
+ context 'when stopped after sleeping' do
89
+ before do
90
+ sequence[0.2] = :stopped
91
+ end
92
+
93
+ it 'sleeps, waiting to be woken up' do
94
+ expect(config).to receive(:sleep).once { state[:monotonic_time] = 0.6 }
95
+ expect(event_queue).to receive(:pop).and_return(event)
96
+ subject.loop_for(1)
97
+ end
98
+
99
+ it 'breaks' do
100
+ expect(event_queue).to receive(:pop).and_return(event)
101
+ allow(config).to receive(:sleep).once { state[:monotonic_time] = 0.6 }
102
+ expect(config).to_not receive(:call)
103
+ subject.loop_for(1)
104
+ end
105
+ end
106
+
107
+ context 'when still paused after sleeping' do
108
+ context 'when there were no events before' do
109
+ before do
110
+ sequence[1.0] = :stopped
111
+ end
112
+
113
+ it 'sleeps for latency to possibly later optimize some events' do
114
+ # pretend we were woken up at 0.6 seconds since start
115
+ allow(config).to receive(:sleep).
116
+ with(anything) { |*_args| state[:monotonic_time] += 0.6 }
117
+
118
+ # pretend we slept for latency (now: 1.6 seconds since start)
119
+ allow(config).to receive(:sleep).
120
+ with(1.0) { |*_args| state[:monotonic_time] += 1.0 }
121
+
122
+ expect(event_queue).to receive(:pop).and_return(event)
123
+ subject.loop_for(1)
124
+ end
125
+ end
126
+
127
+ context 'when there were no events for ages' do
128
+ before do
129
+ sequence[3.5] = :stopped # in the future to break from the loop
130
+ end
131
+
132
+ it 'still does not process events because it is paused' do
133
+ # pretend we were woken up at 0.6 seconds since start
134
+ allow(config).to receive(:sleep).
135
+ with(anything) { |*_args| state[:monotonic_time] += 2.0 }
136
+
137
+ # second loop starts here (no sleep, coz recent events, but no
138
+ # processing coz paused
139
+
140
+ # pretend we were woken up at 3.6 seconds since start
141
+ allow(listener).to receive(:wait_for_state).
142
+ with(:initializing, :backend_started, :processing_events, :stopped) do |*_args|
143
+ state[:monotonic_time] += 3.0
144
+ raise ScriptError, 'done'
145
+ end
146
+
147
+ expect(event_queue).to receive(:pop).and_return(event)
148
+ expect { subject.loop_for(1) }.to raise_exception(ScriptError, 'done')
149
+ end
150
+ end
151
+ end
152
+ end
153
+
154
+ context 'when initially processing' do
155
+ before do
156
+ sequence[0.0] = :processing
157
+ end
158
+
159
+ context 'when event queue is empty' do
160
+ before do
161
+ allow(event_queue).to receive(:empty?).and_return(true)
162
+ end
163
+
164
+ context 'when stopped after sleeping' do
165
+ before do
166
+ sequence[0.2] = :stopped
167
+ end
168
+
169
+ it 'sleeps, waiting to be woken up' do
170
+ expect(event_queue).to receive(:pop).and_return(event)
171
+ expect(config).to receive(:sleep).
172
+ once { |*_args| state[:monotonic_time] = 0.6 }
173
+
174
+ subject.loop_for(1)
175
+ end
176
+
177
+ it 'breaks' do
178
+ allow(config).to receive(:sleep).
179
+ once { |*_args| state[:monotonic_time] = 0.6 }
180
+
181
+ expect(config).to_not receive(:call)
182
+ expect(event_queue).to receive(:pop).and_return(event)
183
+ subject.loop_for(1)
184
+ end
185
+ end
186
+ end
187
+
188
+ context 'when event queue has events' do
189
+ context 'when there were events ages ago' do
190
+ before do
191
+ sequence[3.5] = :stopped # in the future to break from the loop
192
+ end
193
+
194
+ it 'processes events' do
195
+ allow(event_queue).to receive(:empty?).
196
+ and_return(false, false, true)
197
+
198
+ # resets latency check
199
+ expect(config).to receive(:callable?).and_return(true)
200
+
201
+ change = [:file, :modified, 'foo', 'bar']
202
+ resulting_changes = { modified: ['foo'], added: [], removed: [] }
203
+ allow(event_queue).to receive(:pop).and_return(change).exactly(4)
204
+
205
+ allow(config).to receive(:optimize_changes).with([change, change, change]).
206
+ and_return(resulting_changes)
207
+
208
+ final_changes = [['foo'], [], []]
209
+ allow(config).to receive(:call) do |*changes|
210
+ state[:monotonic_time] = 4.0 # stopped
211
+ expect(changes).to eq(final_changes)
212
+ end
213
+
214
+ allow(listener).to receive(:wait_for_state).
215
+ with(:initializing, :backend_started, :processing_events, :stopped)
216
+
217
+ subject.instance_variable_set(:@_remember_time_of_first_unprocessed_event, -3)
218
+ subject.loop_for(1)
219
+ end
220
+ end
221
+ end
222
+ end
223
+ end
224
+ end
225
+
226
+ describe '_process_changes' do
227
+ context 'when it raises an exception derived from StandardError' do
228
+ before do
229
+ allow(event_queue).to receive(:empty?).and_return(true)
230
+ allow(config).to receive(:callable?).and_return(true)
231
+ resulting_changes = { modified: ['foo'], added: [], removed: [] }
232
+ allow(config).to receive(:optimize_changes).with(anything).and_return(resulting_changes)
233
+ expect(config).to receive(:call).and_raise(ArgumentError, "bang!")
234
+ expect(config).to receive(:call).and_return(nil)
235
+ expect(config).to receive(:call).and_raise("error!")
236
+ end
237
+
238
+ it 'rescues and logs exception and continues' do
239
+ expect(Listen.logger).to receive(:error).with(/Exception rescued in _process_changes:\nArgumentError: bang!/)
240
+ expect(Listen.logger).to receive(:error).with(/Exception rescued in _process_changes:\nRuntimeError: error!/)
241
+ expect(Listen.logger).to receive(:debug).with(/Callback \(exception\) took/)
242
+ expect(Listen.logger).to receive(:debug).with(/Callback took/)
243
+ expect(Listen.logger).to receive(:debug).with(/Callback \(exception\) took/)
244
+ subject.send(:_process_changes, event)
245
+ subject.send(:_process_changes, event)
246
+ subject.send(:_process_changes, event)
247
+ end
248
+ end
249
+ end
250
+ end