scarpe 0.2.2 → 0.4.0

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 (378) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +7 -1
  3. data/.yardopts +1 -0
  4. data/CHANGELOG.md +52 -6
  5. data/Gemfile +2 -1
  6. data/Gemfile.lock +20 -6
  7. data/LICENSE.txt +7 -1
  8. data/README.md +100 -21
  9. data/Rakefile +68 -1
  10. data/examples/Edit_box_Styles.rb +8 -0
  11. data/examples/Kerning.rb +7 -0
  12. data/examples/animate.rb +20 -0
  13. data/examples/arrow.rb +10 -0
  14. data/examples/border.rb +11 -0
  15. data/examples/btn_tooltip.rb +7 -0
  16. data/examples/button_style_changed.rb +7 -0
  17. data/examples/button_styles_default.rb +6 -0
  18. data/examples/check.rb +2 -0
  19. data/examples/download_and_show_image.rb +3 -0
  20. data/examples/flags/finland.rb +15 -0
  21. data/examples/flags/italy.rb +11 -0
  22. data/examples/flags/mauritius.rb +14 -0
  23. data/examples/font_family.rb +17 -0
  24. data/examples/font_shorthand.rb +9 -0
  25. data/examples/gen.rb +12 -8
  26. data/examples/highlander.rb +3 -3
  27. data/examples/legacy/README.md +6 -0
  28. data/examples/legacy/not_checked/shoes-contrib/basic/shoes-notes.rb +1 -1
  29. data/examples/legacy/not_checked/shoes-manual/append.rb +10 -0
  30. data/examples/legacy/not_checked/shoes-manual/background_change.rb +12 -0
  31. data/examples/legacy/not_checked/shoes-manual/background_pattern.rb +5 -0
  32. data/examples/legacy/not_checked/shoes-manual/basic_app.rb +8 -0
  33. data/examples/legacy/not_checked/shoes-manual/border.rb +9 -0
  34. data/examples/legacy/not_checked/shoes-manual/builtins/FONTS.rb +5 -0
  35. data/examples/legacy/not_checked/shoes-manual/builtins/ask.rb +2 -0
  36. data/examples/legacy/not_checked/shoes-manual/builtins/ask_color.rb +5 -0
  37. data/examples/legacy/not_checked/shoes-manual/builtins/ask_open_file.rb +5 -0
  38. data/examples/legacy/not_checked/shoes-manual/builtins/ask_save_folder.rb +2 -0
  39. data/examples/legacy/not_checked/shoes-manual/builtins/confirm.rb +4 -0
  40. data/examples/legacy/not_checked/shoes-manual/builtins/debug.rb +2 -0
  41. data/examples/legacy/not_checked/shoes-manual/builtins/info.rb +3 -0
  42. data/examples/legacy/not_checked/shoes-manual/button.rb +9 -0
  43. data/examples/legacy/not_checked/shoes-manual/clear.rb +7 -0
  44. data/examples/legacy/not_checked/shoes-manual/custom_header.rb +13 -0
  45. data/examples/legacy/not_checked/shoes-manual/displace.rb +14 -0
  46. data/examples/legacy/not_checked/shoes-manual/edit_box.rb +8 -0
  47. data/examples/legacy/not_checked/shoes-manual/fill_pattern.rb +5 -0
  48. data/examples/legacy/not_checked/shoes-manual/fonts.rb +7 -0
  49. data/examples/legacy/not_checked/shoes-manual/gutter.rb +6 -0
  50. data/examples/legacy/not_checked/shoes-manual/image_web.rb +4 -0
  51. data/examples/legacy/not_checked/shoes-manual/keypress.rb +7 -0
  52. data/examples/legacy/not_checked/shoes-manual/list_box.rb +10 -0
  53. data/examples/legacy/not_checked/shoes-manual/motion.rb +10 -0
  54. data/examples/legacy/not_checked/shoes-manual/mouse.rb +8 -0
  55. data/examples/legacy/not_checked/shoes-manual/move.rb +14 -0
  56. data/examples/legacy/not_checked/shoes-manual/nested_ovals.rb +8 -0
  57. data/examples/legacy/not_checked/shoes-manual/oval.rb +7 -0
  58. data/examples/legacy/not_checked/shoes-manual/ovals.rb +6 -0
  59. data/examples/legacy/not_checked/shoes-manual/ovals_image.rb +8 -0
  60. data/examples/legacy/not_checked/shoes-manual/prepend.rb +7 -0
  61. data/examples/legacy/not_checked/shoes-manual/progress_bar.rb +10 -0
  62. data/examples/legacy/not_checked/shoes-manual/radio.rb +18 -0
  63. data/examples/legacy/not_checked/shoes-manual/radio_alternative_1.rb +7 -0
  64. data/examples/legacy/not_checked/shoes-manual/radio_alternative_2.rb +9 -0
  65. data/examples/legacy/not_checked/shoes-manual/rotate_rectangle.rb +6 -0
  66. data/examples/legacy/not_checked/shoes-manual/shape.rb +11 -0
  67. data/examples/legacy/not_checked/shoes-manual/static/avatar.png +0 -0
  68. data/examples/legacy/not_checked/shoes-manual/stroke.rb +5 -0
  69. data/examples/legacy/not_checked/shoes-manual/style.rb +3 -0
  70. data/examples/legacy/not_checked/shoes-manual/style_alternative_1.rb +4 -0
  71. data/examples/legacy/not_checked/shoes-manual/style_alternative_2.rb +5 -0
  72. data/examples/legacy/not_checked/shoes-manual/style_length.rb +5 -0
  73. data/examples/legacy/not_checked/shoes-manual/timer.rb +6 -0
  74. data/examples/legacy/not_checked/shoes-manual/trigger_window.rb +8 -0
  75. data/examples/legacy/not_checked/shoes-manual/window_owner.rb +8 -0
  76. data/examples/legacy/not_checked/simple/anim-shapes.rb +1 -1
  77. data/examples/legacy/not_checked/speedometer_app.rb +55 -0
  78. data/examples/legacy/working/shoes_manual/alert_button.rb +2 -0
  79. data/examples/legacy/working/shoes_manual/animate.rb +7 -0
  80. data/examples/legacy/working/shoes_manual/background_para.rb +4 -0
  81. data/examples/legacy/working/shoes_manual/button_alternative.rb +7 -0
  82. data/examples/legacy/working/shoes_manual/checkbox.rb +17 -0
  83. data/examples/legacy/working/shoes_manual/download.rb +12 -0
  84. data/examples/legacy/working/shoes_manual/edit_box.rb +6 -0
  85. data/examples/legacy/working/shoes_manual/editline.rb +7 -0
  86. data/examples/legacy/working/shoes_manual/fixed_height.rb +8 -0
  87. data/examples/legacy/working/shoes_manual/fixed_width.rb +12 -0
  88. data/examples/legacy/working/shoes_manual/image.rb +5 -0
  89. data/examples/legacy/working/shoes_manual/instance_variable_check.rb +10 -0
  90. data/examples/legacy/working/shoes_manual/message.rb +18 -0
  91. data/examples/legacy/working/shoes_manual/rectangle.rb +6 -0
  92. data/examples/legacy/working/shoes_manual/save_download.rb +12 -0
  93. data/examples/legacy/working/shoes_manual/self_check.rb +10 -0
  94. data/examples/legacy/working/shoes_manual/stack.rb +7 -0
  95. data/examples/legacy/working/shoes_manual/style_info.rb +8 -0
  96. data/examples/legacy/working/shoes_manual/utf8_support.rb +8 -0
  97. data/examples/legacy/working/shoes_manual/width.rb +4 -0
  98. data/examples/legacy/working/simple/image-icon.rb +3 -0
  99. data/examples/legacy/{not_checked → working}/simple/image.rb +1 -1
  100. data/examples/list_box_choose.rb +17 -0
  101. data/examples/local_assets/local_file_server.rb +82 -0
  102. data/examples/local_assets/multi_image.rb +5 -0
  103. data/examples/local_assets/sample.gif +0 -0
  104. data/examples/local_assets/sample.mp4 +0 -0
  105. data/examples/local_assets/small.png +0 -0
  106. data/examples/local_fonts.rb +5 -2
  107. data/examples/local_images.rb +2 -3
  108. data/examples/margin.rb +13 -0
  109. data/examples/margin_check.rb +27 -0
  110. data/examples/oval-with-kwargs.rb +3 -0
  111. data/examples/oval.rb +26 -0
  112. data/examples/para/para_text.rb +14 -0
  113. data/examples/para_font_styles.rb +17 -0
  114. data/examples/para_font_variant.rb +6 -0
  115. data/examples/para_fontweight.rb +13 -0
  116. data/examples/parse_xl_funnies.rb +3 -0
  117. data/examples/progress.rb +31 -0
  118. data/examples/radio/radio_groups.rb +2 -2
  119. data/examples/rect.rb +4 -0
  120. data/examples/rotate_shapes.rb +17 -0
  121. data/examples/scarpe_ext.rb +3 -0
  122. data/examples/shapes/star.rb +1 -3
  123. data/examples/simpler-menu.rb +21 -0
  124. data/examples/spacing.rb +1 -1
  125. data/examples/span.rb +4 -2
  126. data/exe/scarpe +2 -1
  127. data/lacci/Gemfile +2 -0
  128. data/lacci/Gemfile.lock +8 -1
  129. data/lacci/lacci.gemspec +2 -2
  130. data/lacci/lib/lacci/scarpe_cli.rb +2 -2
  131. data/lacci/lib/lacci/scarpe_core.rb +2 -1
  132. data/lacci/lib/lacci/version.rb +1 -1
  133. data/lacci/lib/scarpe/niente/app.rb +23 -0
  134. data/lacci/lib/scarpe/niente/display_service.rb +66 -0
  135. data/lacci/lib/scarpe/niente/drawable.rb +59 -0
  136. data/lacci/lib/scarpe/niente/shoes_spec.rb +93 -0
  137. data/lacci/lib/scarpe/niente.rb +32 -0
  138. data/lacci/lib/shoes/app.rb +111 -72
  139. data/lacci/lib/shoes/background.rb +2 -2
  140. data/lacci/lib/shoes/border.rb +2 -2
  141. data/lacci/lib/shoes/builtins.rb +63 -0
  142. data/lacci/lib/shoes/changelog.rb +52 -0
  143. data/lacci/lib/shoes/colors.rb +3 -1
  144. data/lacci/lib/shoes/constants.rb +41 -2
  145. data/lacci/lib/shoes/display_service.rb +80 -18
  146. data/lacci/lib/shoes/download.rb +2 -2
  147. data/lacci/lib/shoes/drawable.rb +654 -0
  148. data/lacci/lib/shoes/drawables/arc.rb +27 -0
  149. data/lacci/lib/shoes/drawables/arrow.rb +21 -0
  150. data/lacci/lib/shoes/drawables/border.rb +28 -0
  151. data/lacci/lib/shoes/drawables/button.rb +57 -0
  152. data/lacci/lib/shoes/drawables/check.rb +33 -0
  153. data/lacci/lib/shoes/drawables/document_root.rb +20 -0
  154. data/lacci/lib/shoes/{widgets → drawables}/edit_box.rb +9 -8
  155. data/lacci/lib/shoes/{widgets → drawables}/edit_line.rb +8 -7
  156. data/lacci/lib/shoes/drawables/flow.rb +20 -0
  157. data/lacci/lib/shoes/drawables/font_helper.rb +62 -0
  158. data/lacci/lib/shoes/{widgets → drawables}/image.rb +7 -7
  159. data/lacci/lib/shoes/drawables/line.rb +17 -0
  160. data/lacci/lib/shoes/drawables/link.rb +31 -0
  161. data/lacci/lib/shoes/drawables/list_box.rb +59 -0
  162. data/lacci/lib/shoes/drawables/oval.rb +48 -0
  163. data/lacci/lib/shoes/drawables/para.rb +206 -0
  164. data/lacci/lib/shoes/drawables/progress.rb +15 -0
  165. data/lacci/lib/shoes/drawables/radio.rb +35 -0
  166. data/lacci/lib/shoes/drawables/rect.rb +18 -0
  167. data/lacci/lib/shoes/{widgets → drawables}/shape.rb +8 -8
  168. data/lacci/lib/shoes/drawables/slot.rb +178 -0
  169. data/lacci/lib/shoes/drawables/stack.rb +21 -0
  170. data/lacci/lib/shoes/drawables/star.rb +28 -0
  171. data/lacci/lib/shoes/drawables/subscription_item.rb +93 -0
  172. data/lacci/lib/shoes/drawables/text_drawable.rb +122 -0
  173. data/lacci/lib/shoes/drawables/video.rb +17 -0
  174. data/lacci/lib/shoes/drawables/widget.rb +74 -0
  175. data/lacci/lib/shoes/drawables.rb +32 -0
  176. data/lacci/lib/shoes/errors.rb +38 -0
  177. data/lacci/lib/shoes/log.rb +2 -2
  178. data/lacci/lib/shoes/margin_helper.rb +79 -0
  179. data/lacci/lib/shoes/ruby_extensions.rb +15 -0
  180. data/lacci/lib/shoes-spec.rb +93 -0
  181. data/lacci/lib/shoes.rb +31 -10
  182. data/lacci/test/.gitignore +1 -0
  183. data/lacci/test/test_draw_context.rb +167 -0
  184. data/lacci/test/test_font_helper.rb +57 -0
  185. data/lacci/test/test_helper.rb +81 -0
  186. data/lacci/test/test_lacci.rb +99 -3
  187. data/lacci/test/test_margin_helper.rb +82 -0
  188. data/lacci/test/test_niente_test_infra.rb +26 -0
  189. data/lacci/test/test_oval.rb +82 -0
  190. data/lacci/test/test_parenting.rb +140 -0
  191. data/lacci/test/test_shoes_errors.rb +49 -0
  192. data/lacci/test/test_text_drawables.rb +23 -0
  193. data/lib/scarpe/assets.rb +18 -0
  194. data/lib/scarpe/cats_cradle.rb +84 -103
  195. data/lib/scarpe/errors.rb +77 -0
  196. data/lib/scarpe/shoes_spec.rb +160 -0
  197. data/lib/scarpe/version.rb +2 -2
  198. data/lib/scarpe/wv/app.rb +21 -20
  199. data/lib/scarpe/wv/arc.rb +4 -51
  200. data/lib/scarpe/wv/arrow.rb +9 -0
  201. data/lib/scarpe/wv/border.rb +9 -18
  202. data/lib/scarpe/wv/button.rb +7 -35
  203. data/lib/scarpe/wv/check.rb +3 -5
  204. data/lib/scarpe/wv/control_interface.rb +20 -30
  205. data/lib/scarpe/wv/document_root.rb +81 -4
  206. data/lib/scarpe/wv/{widget.rb → drawable.rb} +71 -82
  207. data/lib/scarpe/wv/edit_box.rb +8 -18
  208. data/lib/scarpe/wv/edit_line.rb +9 -20
  209. data/lib/scarpe/wv/flow.rb +2 -18
  210. data/lib/scarpe/wv/image.rb +7 -30
  211. data/lib/scarpe/wv/line.rb +3 -25
  212. data/lib/scarpe/wv/link.rb +6 -17
  213. data/lib/scarpe/wv/list_box.rb +6 -29
  214. data/lib/scarpe/wv/oval.rb +13 -0
  215. data/lib/scarpe/wv/para.rb +12 -30
  216. data/lib/scarpe/wv/progress.rb +19 -0
  217. data/lib/scarpe/wv/radio.rb +9 -10
  218. data/lib/scarpe/wv/rect.rb +13 -0
  219. data/lib/scarpe/wv/scarpe_extensions.rb +8 -0
  220. data/lib/scarpe/wv/shape.rb +13 -13
  221. data/lib/scarpe/wv/slot.rb +8 -25
  222. data/lib/scarpe/wv/stack.rb +2 -18
  223. data/lib/scarpe/wv/star.rb +3 -53
  224. data/lib/scarpe/wv/subscription_item.rb +38 -4
  225. data/lib/scarpe/wv/text_drawable.rb +90 -0
  226. data/lib/scarpe/wv/video.rb +15 -15
  227. data/lib/scarpe/wv/web_wrangler.rb +320 -328
  228. data/lib/scarpe/wv/webview_local_display.rb +52 -33
  229. data/lib/scarpe/wv/webview_relay_display.rb +12 -12
  230. data/lib/scarpe/wv/webview_relay_util.rb +7 -10
  231. data/lib/scarpe/wv/wv_display_worker.rb +2 -2
  232. data/lib/scarpe/wv.rb +52 -12
  233. data/lib/scarpe/wv_local.rb +1 -1
  234. data/lib/scarpe/wv_relay.rb +1 -1
  235. data/lib/scarpe.rb +1 -0
  236. data/logger/debug_web_wrangler.json +1 -1
  237. data/logger/scarpe_wv_test.json +1 -1
  238. data/scarpe-components/Gemfile +4 -1
  239. data/scarpe-components/Gemfile.lock +85 -0
  240. data/scarpe-components/README.md +2 -2
  241. data/scarpe-components/assets/bootstrap-themes/bootstrap-cerulean.css +12229 -0
  242. data/scarpe-components/assets/bootstrap-themes/bootstrap-cosmo.css +11810 -0
  243. data/scarpe-components/assets/bootstrap-themes/bootstrap-cyborg.css +12210 -0
  244. data/scarpe-components/assets/bootstrap-themes/bootstrap-darkly.css +12153 -0
  245. data/scarpe-components/assets/bootstrap-themes/bootstrap-flatly.css +12126 -0
  246. data/scarpe-components/assets/bootstrap-themes/bootstrap-icons.min.css +5 -0
  247. data/scarpe-components/assets/bootstrap-themes/bootstrap-journal.css +12099 -0
  248. data/scarpe-components/assets/bootstrap-themes/bootstrap-litera.css +12211 -0
  249. data/scarpe-components/assets/bootstrap-themes/bootstrap-lumen.css +12369 -0
  250. data/scarpe-components/assets/bootstrap-themes/bootstrap-lux.css +11928 -0
  251. data/scarpe-components/assets/bootstrap-themes/bootstrap-materia.css +13184 -0
  252. data/scarpe-components/assets/bootstrap-themes/bootstrap-minty.css +12177 -0
  253. data/scarpe-components/assets/bootstrap-themes/bootstrap-morph.css +12750 -0
  254. data/scarpe-components/assets/bootstrap-themes/bootstrap-pulse.css +11890 -0
  255. data/scarpe-components/assets/bootstrap-themes/bootstrap-quartz.css +12622 -0
  256. data/scarpe-components/assets/bootstrap-themes/bootstrap-sandstone.css +12201 -0
  257. data/scarpe-components/assets/bootstrap-themes/bootstrap-simplex.css +12186 -0
  258. data/scarpe-components/assets/bootstrap-themes/bootstrap-sketchy.css +12451 -0
  259. data/scarpe-components/assets/bootstrap-themes/bootstrap-slate.css +12492 -0
  260. data/scarpe-components/assets/bootstrap-themes/bootstrap-solar.css +12149 -0
  261. data/scarpe-components/assets/bootstrap-themes/bootstrap-spacelab.css +12266 -0
  262. data/scarpe-components/assets/bootstrap-themes/bootstrap-superhero.css +12216 -0
  263. data/scarpe-components/assets/bootstrap-themes/bootstrap-united.css +12077 -0
  264. data/scarpe-components/assets/bootstrap-themes/bootstrap-vapor.css +12549 -0
  265. data/scarpe-components/assets/bootstrap-themes/bootstrap-yeti.css +12325 -0
  266. data/scarpe-components/assets/bootstrap-themes/bootstrap-zephyr.css +12283 -0
  267. data/scarpe-components/assets/bootstrap-themes/bootstrap.bundle.min.js +7 -0
  268. data/scarpe-components/lib/scarpe/components/asset_server.rb +219 -0
  269. data/scarpe-components/lib/scarpe/components/base64.rb +23 -5
  270. data/scarpe-components/lib/scarpe/components/calzini/alert.rb +49 -0
  271. data/scarpe-components/lib/scarpe/components/calzini/art_drawables.rb +227 -0
  272. data/scarpe-components/lib/scarpe/components/calzini/border.rb +38 -0
  273. data/scarpe-components/lib/scarpe/components/calzini/button.rb +37 -0
  274. data/scarpe-components/lib/scarpe/components/calzini/misc.rb +136 -0
  275. data/scarpe-components/lib/scarpe/components/calzini/para.rb +237 -0
  276. data/scarpe-components/lib/scarpe/components/calzini/slots.rb +109 -0
  277. data/scarpe-components/lib/scarpe/components/calzini.rb +236 -0
  278. data/scarpe-components/lib/scarpe/components/errors.rb +24 -0
  279. data/scarpe-components/lib/scarpe/components/file_helpers.rb +1 -0
  280. data/scarpe-components/lib/scarpe/components/html.rb +134 -0
  281. data/scarpe-components/lib/scarpe/components/minitest_export_reporter.rb +83 -0
  282. data/scarpe-components/lib/scarpe/components/minitest_import_runnable.rb +98 -0
  283. data/scarpe-components/lib/scarpe/components/minitest_result.rb +127 -0
  284. data/scarpe-components/lib/scarpe/components/modular_logger.rb +5 -5
  285. data/scarpe-components/lib/scarpe/components/print_logger.rb +22 -3
  286. data/scarpe-components/lib/scarpe/components/process_helpers.rb +37 -0
  287. data/scarpe-components/lib/scarpe/components/promises.rb +14 -14
  288. data/scarpe-components/lib/scarpe/components/segmented_file_loader.rb +36 -17
  289. data/scarpe-components/lib/scarpe/components/string_helpers.rb +10 -0
  290. data/scarpe-components/lib/scarpe/components/tiranti.rb +167 -0
  291. data/scarpe-components/lib/scarpe/components/unit_test_helpers.rb +48 -6
  292. data/scarpe-components/lib/scarpe/components/version.rb +2 -2
  293. data/scarpe-components/test/assets/big-image.png +0 -0
  294. data/scarpe-components/test/assets/big-stylesheet.css +497 -0
  295. data/scarpe-components/test/assets/little-image.png +0 -0
  296. data/scarpe-components/test/assets/little-stylesheet.css +1 -0
  297. data/scarpe-components/test/calzini/test_calzini_alert.rb +30 -0
  298. data/scarpe-components/test/calzini/test_calzini_art_drawables.rb +105 -0
  299. data/scarpe-components/test/calzini/test_calzini_button.rb +54 -0
  300. data/scarpe-components/test/calzini/test_calzini_misc.rb +115 -0
  301. data/scarpe-components/test/calzini/test_calzini_para.rb +34 -0
  302. data/scarpe-components/test/calzini/test_calzini_slots.rb +85 -0
  303. data/scarpe-components/test/calzini/test_calzini_text_drawables.rb +106 -0
  304. data/scarpe-components/test/calzini/test_various.rb +133 -0
  305. data/scarpe-components/test/mtr_data/exception.json +1 -0
  306. data/scarpe-components/test/mtr_data/fail_with_message.json +1 -0
  307. data/scarpe-components/test/mtr_data/skipped_no_message.json +1 -0
  308. data/scarpe-components/test/mtr_data/skipped_w_msg.json +1 -0
  309. data/scarpe-components/test/mtr_data/succeed_2_asserts.json +1 -0
  310. data/scarpe-components/test/test_asset_server.rb +72 -0
  311. data/scarpe-components/test/test_components.rb +31 -2
  312. data/scarpe-components/test/test_dimensions.rb +26 -0
  313. data/scarpe-components/test/test_helper.rb +20 -1
  314. data/scarpe-components/test/test_html.rb +65 -0
  315. data/scarpe-components/test/test_minitest_result.rb +68 -0
  316. data/scarpe-components/test/test_promises.rb +5 -4
  317. data/scarpe-components/test/test_segmented_app_files.rb +10 -6
  318. data/scarpegen.rb +14 -14
  319. data/sig/scarpe.rbs +1 -1
  320. data/tasks/check_html_fixtures.rb +140 -0
  321. data/tasks/regenerate_html_fixtures.rb +104 -0
  322. data/templates/basic_class_template.erb +13 -14
  323. data/templates/class_template_with_event_bind.erb +4 -4
  324. data/templates/class_template_with_shapes.erb +8 -28
  325. data/templates/example_template.erb +1 -1
  326. data/templates/module_template.erb +4 -4
  327. data/templates/webview_template.erb +3 -2
  328. metadata +286 -80
  329. data/examples/legacy/not_checked/shoes-contrib/elements/image-icon.rb +0 -3
  330. data/lacci/lib/shoes/spacing.rb +0 -9
  331. data/lacci/lib/shoes/widget.rb +0 -218
  332. data/lacci/lib/shoes/widgets/alert.rb +0 -19
  333. data/lacci/lib/shoes/widgets/arc.rb +0 -51
  334. data/lacci/lib/shoes/widgets/button.rb +0 -35
  335. data/lacci/lib/shoes/widgets/check.rb +0 -28
  336. data/lacci/lib/shoes/widgets/document_root.rb +0 -20
  337. data/lacci/lib/shoes/widgets/flow.rb +0 -22
  338. data/lacci/lib/shoes/widgets/font.rb +0 -14
  339. data/lacci/lib/shoes/widgets/line.rb +0 -18
  340. data/lacci/lib/shoes/widgets/link.rb +0 -25
  341. data/lacci/lib/shoes/widgets/list_box.rb +0 -25
  342. data/lacci/lib/shoes/widgets/para.rb +0 -68
  343. data/lacci/lib/shoes/widgets/radio.rb +0 -35
  344. data/lacci/lib/shoes/widgets/slot.rb +0 -75
  345. data/lacci/lib/shoes/widgets/span.rb +0 -26
  346. data/lacci/lib/shoes/widgets/stack.rb +0 -24
  347. data/lacci/lib/shoes/widgets/star.rb +0 -44
  348. data/lacci/lib/shoes/widgets/subscription_item.rb +0 -60
  349. data/lacci/lib/shoes/widgets/text_widget.rb +0 -51
  350. data/lacci/lib/shoes/widgets/video.rb +0 -15
  351. data/lacci/lib/shoes/widgets.rb +0 -29
  352. data/lib/scarpe/evented_assertions.rb +0 -88
  353. data/lib/scarpe/wv/alert.rb +0 -66
  354. data/lib/scarpe/wv/background.rb +0 -27
  355. data/lib/scarpe/wv/control_interface_test.rb +0 -238
  356. data/lib/scarpe/wv/dimensions.rb +0 -22
  357. data/lib/scarpe/wv/font.rb +0 -36
  358. data/lib/scarpe/wv/html.rb +0 -108
  359. data/lib/scarpe/wv/spacing.rb +0 -41
  360. data/lib/scarpe/wv/span.rb +0 -68
  361. data/lib/scarpe/wv/text_widget.rb +0 -30
  362. /data/examples/legacy/not_checked/{expert → shoes-contrib/basic}/definr.rb +0 -0
  363. /data/examples/legacy/not_checked/{expert → shoes-contrib/basic}/funnies.rb +0 -0
  364. /data/examples/legacy/not_checked/shoes-contrib/{elements → basic}/list_box-select-class.rb +0 -0
  365. /data/examples/legacy/{not_checked → working}/shoes3-tests/editline/editline.rb +0 -0
  366. /data/examples/legacy/{not_checked/shoes-contrib/basic → working/simple}/basic-edit-box.rb +0 -0
  367. /data/examples/legacy/{not_checked/shoes-contrib/elements → working/simple}/basic-fps.rb +0 -0
  368. /data/examples/legacy/{not_checked/shoes-contrib/elements → working/simple}/border-cat.rb +0 -0
  369. /data/examples/legacy/{not_checked/shoes-contrib/elements → working/simple}/check-mate.rb +0 -0
  370. /data/examples/legacy/{not_checked/shoes-contrib/manipulation → working/simple}/clear-slot.rb +0 -0
  371. /data/examples/legacy/{not_checked/shoes-contrib/basic → working/simple}/clock.rb +0 -0
  372. /data/examples/legacy/{not_checked/shoes-contrib/basic → working/simple}/gradient-shoes.rb +0 -0
  373. /data/examples/legacy/{not_checked/shoes-contrib/basic → working/simple}/list_box-shape-report.rb +0 -0
  374. /data/examples/legacy/{not_checked/shoes-contrib/elements → working/simple}/list_box.rb +0 -0
  375. /data/examples/legacy/{not_checked/shoes-contrib/elements → working/simple}/phat-button.rb +0 -0
  376. /data/examples/legacy/{not_checked/shoes-contrib → working}/simple/simple-calc.rb +0 -0
  377. /data/examples/legacy/{not_checked/shoes-contrib/position → working/simple}/stack-width.rb +0 -0
  378. /data/examples/legacy/{not_checked/shoes-contrib/elements → working/simple}/width-introspec.rb +0 -0
@@ -1,45 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "scarpe/components/unit_test_helpers"
4
- require "scarpe/evented_assertions"
5
4
 
6
5
  require "fiber"
7
6
 
8
- module Scarpe::Test
9
- # We'd like something we can call Shoes widget methods on, such as para.replace.
10
- # But we'd also like to be able to grab the corresponding display widget and
11
- # call some of *those* methods.
12
- class CCProxy
13
- attr_reader :display
14
- attr_reader :obj
15
-
16
- def initialize(obj)
17
- @obj = obj
18
- # TODO: how to do this with Webview relay? Proxy object to send a message, maybe?
19
- @display = ::Shoes::DisplayService.display_service.query_display_widget_for(obj.linkable_id)
20
- end
21
-
22
- def method_missing(method, ...)
23
- if @obj.respond_to?(method)
24
- self.singleton_class.define_method(method) do |*args, **kwargs, &block|
25
- @obj.send(method, *args, **kwargs, &block)
26
- end
27
- send(method, ...)
28
- else
29
- super # raise an exception
30
- end
31
- end
32
-
33
- def respond_to_missing?(method_name, include_private = false)
34
- @obj.respond_to_missing?(method_name, include_private)
35
- end
36
- end
37
-
7
+ module Scarpe
38
8
  # This class defines the CatsCradle DSL. It also holds a "bag of fibers"
39
9
  # with promises for when they should next resume.
40
10
  class CCInstance
41
11
  include Shoes::Log
42
- include Scarpe::Test::EventedAssertions
43
12
  include Scarpe::Test::Helpers
44
13
 
45
14
  def self.instance
@@ -49,20 +18,19 @@ module Scarpe::Test
49
18
  def initialize
50
19
  log_init("CatsCradle")
51
20
 
52
- @assertion_data = []
53
- @assertions_passed = 0
54
- @assertions_failed = []
55
-
56
21
  @waiting_fibers = []
57
22
  @event_promises = {}
23
+ @shutdown = false
58
24
 
59
25
  @manager_fiber = Fiber.new do
26
+ Fiber[:catscradle] = true
27
+
60
28
  loop do
61
29
  # A fiber can run briefly and then exit. It can run and then block on an API call.
62
30
  # These fibers return promises to indicate to CatsCradle when they can run again.
63
31
  # A fiber that is no longer #alive? is assumed to be successfully finished.
64
32
  @waiting_fibers.each do |fiber_data|
65
- next unless fiber_data[:promise].fulfilled?
33
+ next if !fiber_data[:promise].fulfilled? || !fiber_data[:fiber].alive? || @shutdown
66
34
 
67
35
  @log.debug("Resuming fiber with value #{fiber_data[:promise].returned_value.inspect}")
68
36
  result = fiber_data[:fiber].transfer fiber_data[:promise].returned_value
@@ -74,7 +42,7 @@ module Scarpe::Test
74
42
  when ::Scarpe::Promise
75
43
  fiber_data[:promise] = result
76
44
  else
77
- raise "Unexpected object returned from Fiber#transfer for still-living Fiber! #{result.inspect}"
45
+ raise Scarpe::UnexpectedFiberTransferError, "Unexpected object returned from Fiber#transfer for still-living Fiber! #{result.inspect}"
78
46
  end
79
47
  end
80
48
 
@@ -89,8 +57,19 @@ module Scarpe::Test
89
57
  end
90
58
  end
91
59
 
60
+ private
61
+
62
+ def cc_fiber(&block)
63
+ Fiber.new do
64
+ Fiber[:catscradle] = true
65
+ CCInstance.instance.instance_eval(&block)
66
+ end
67
+ end
68
+
69
+ public
70
+
92
71
  # If we add "every" events, that's likely to complicate timing and event_promise handling.
93
- EVENT_TYPES = [:next_heartbeat, :next_redraw]
72
+ EVENT_TYPES = [:init, :next_heartbeat, :next_redraw, :every_heartbeat, :every_redraw]
94
73
 
95
74
  # This needs to be called after the basic display service objects exist
96
75
  # and we can find the control interface.
@@ -109,9 +88,19 @@ module Scarpe::Test
109
88
  p = @event_promises.delete(:next_heartbeat)
110
89
  p&.fulfilled!
111
90
 
91
+ p = @event_promises.delete(:every_heartbeat)
92
+ p&.fulfilled!
93
+
94
+ # Reschedule on_every_heartbeat fibers for next heartbeat, too.
95
+ # This fiber won't be called again by a heartbeat, though it may
96
+ # continue if it waits on another promise.
97
+ @waiting_fibers.select { |f| f[:on_event] == :every_heartbeat }.each do |f|
98
+ on_event(:every_heartbeat, &f[:block])
99
+ end
100
+
112
101
  # Give every ready fiber a chance to run once.
113
- @manager_fiber.resume
114
- end
102
+ @manager_fiber.resume unless @shutdown
103
+ end unless @shutdown
115
104
  end
116
105
 
117
106
  @control_interface.on_event(:every_redraw) do
@@ -119,52 +108,56 @@ module Scarpe::Test
119
108
  p = @event_promises.delete(:next_redraw)
120
109
  p&.fulfilled!
121
110
 
111
+ p = @event_promises.delete(:every_redraw)
112
+ p&.fulfilled!
113
+
114
+ # Reschedule on_every_redraw fibers for next redraw, too.
115
+ @waiting_fibers.select { |f| f[:on_event] == :every_redraw }.each do |f|
116
+ on_event(:every_redraw, &f[:block])
117
+ end
118
+
122
119
  # Give every ready fiber a chance to run once.
123
- @manager_fiber.resume
124
- end
120
+ @manager_fiber.resume unless @shutdown
121
+ end unless @shutdown
125
122
  end
126
123
  end
127
124
 
125
+ def fiber_start
126
+ @manager_fiber.resume unless @shutdown
127
+ end
128
+
128
129
  def event_promise(event)
129
130
  @event_promises[event] ||= ::Scarpe::Promise.new
130
131
  end
131
132
 
132
133
  def on_event(event, &block)
133
- raise "Unknown event type: #{event.inspect}!" unless EVENT_TYPES.include?(event)
134
+ raise Scarpe::UnknownEventTypeError, "Unknown event type: #{event.inspect}!" unless EVENT_TYPES.include?(event)
135
+ return if @shutdown
134
136
 
135
- f = Fiber.new do
136
- CCInstance.instance.instance_eval(&block)
137
- end
138
- @waiting_fibers << { promise: event_promise(event), fiber: f }
137
+ @waiting_fibers << { promise: event_promise(event), fiber: cc_fiber(&block), on_event: event, block: }
139
138
  end
140
139
 
141
- # What to do about TextWidgets? Link, code, em, strong?
142
- # Also, wait, what's up with span? What *is* that?
143
- Shoes::Widget.widget_classes.each do |widget_class|
144
- finder_name = widget_class.dsl_name
145
-
146
- define_method(finder_name) do |*args|
147
- app = Shoes::App.instance
148
-
149
- widgets = app.find_widgets_by(widget_class, *args)
150
- raise "Found more than one #{finder_name} matching #{args.inspect}!" if widgets.size > 1
151
- raise "Found no #{finder_name} matching #{args.inspect}!" if widgets.empty?
152
-
153
- CCProxy.new(widgets[0])
154
- end
155
- end
140
+ def active_fiber(&block)
141
+ return if @shutdown
156
142
 
157
- def proxy_for(shoes_widget)
158
- CCProxy.new(shoes_widget)
143
+ p = ::Scarpe::Promise.new
144
+ p.fulfilled!
145
+ @waiting_fibers << { promise: p, fiber: cc_fiber(&block), on_event: nil, block: }
159
146
  end
160
147
 
161
148
  def wait(promise)
162
- raise("Must supply a promise to wait!") unless promise.is_a?(::Scarpe::Promise)
149
+ raise(Scarpe::InvalidPromiseError, "Must supply a promise to wait!") unless promise.is_a?(::Scarpe::Promise)
163
150
 
164
151
  # Wait until this promise is complete before running again
165
152
  @manager_fiber.transfer(promise)
166
153
  end
167
154
 
155
+ def yield
156
+ p = ::Scarpe::Promise.new
157
+ p.fulfilled!
158
+ @manager_fiber.transfer(p)
159
+ end
160
+
168
161
  # This returns a promise, which can be waited on using wait()
169
162
  def fully_updated
170
163
  @wrangler.promise_dom_fully_updated
@@ -181,42 +174,16 @@ module Scarpe::Test
181
174
  @manager_fiber.transfer(js_promise)
182
175
  end
183
176
 
184
- def assert(value, msg = nil)
185
- msg ||= "Assertion #{value ? "succeeded" : "failed"}"
186
- @assertion_data << [value ? true : false, msg]
187
- if value
188
- @assertions_passed += 1
189
- else
190
- @assertions_failed << msg
191
- end
192
- end
193
-
194
- def assert_equal(expected, actual, msg = nil)
195
- msg ||= "Expected #{actual.inspect} to equal #{expected.inspect}!"
196
- assert actual == expected, msg
177
+ def query_js_promise(js_code, timeout: 1.0)
178
+ @wrangler.eval_js_async(js_code, timeout:)
197
179
  end
198
180
 
199
- def assertion_data_as_a_struct
200
- {
201
- still_pending: 0,
202
- succeeded: @assertions_passed,
203
- failed: @assertions_failed.size,
204
- failures: @assertions_failed,
205
- }
206
- end
207
-
208
- def test_metadata
209
- {}
210
- end
211
-
212
- def test_finished
213
- if !@assertions_failed.empty?
214
- return_results(false, "Assertions failed", assertion_data_as_a_struct)
215
- elsif @assertions_passed > 0
216
- return_results(true, "All assertions passed", assertion_data_as_a_struct)
217
- else
218
- return_results(true, "Test finished successfully")
181
+ def shut_down_shoes_code
182
+ if @shutdown
183
+ exit 0
219
184
  end
185
+
186
+ @shutdown = true
220
187
  ::Shoes::DisplayService.dispatch_event("destroy", nil)
221
188
  end
222
189
  end
@@ -224,8 +191,8 @@ module Scarpe::Test
224
191
  # "Cat's Cradle" is a children's game where they interlace string between
225
192
  # their fingers to make beautiful complicated shapes. The interlacing
226
193
  # of fibers made it a good name for a prototype.
227
-
228
- # An attempt at an experimental Fiber-based testing system to deal with
194
+ #
195
+ # An attempt at an experimental Fiber-based control-flow system to deal with
229
196
  # Shoes, Display and JS all at the same time.
230
197
  #
231
198
  # In general, we'll use Fiber.transfer to bounce control back and forth
@@ -235,15 +202,29 @@ module Scarpe::Test
235
202
  #
236
203
  # Ruby Fiber basic docs: https://ruby-doc.org/core-3.0.0/Fiber.html
237
204
  #
238
- # This module is mixed into Shoes::App if we're running CatsCradle-based tests
205
+ # This module is mixed into an object to coordinate fibers app-wide.
239
206
  module CatsCradle
207
+ attr_reader :cc_instance
208
+
240
209
  def event_init
241
- @cc_instance = CCInstance.instance
210
+ @cc_instance ||= CCInstance.instance
242
211
  @cc_instance.event_init
243
212
  end
244
213
 
245
214
  def on_heartbeat(&block)
246
215
  @cc_instance.on_event(:next_heartbeat, &block)
247
216
  end
217
+
218
+ def on_every_heartbeat(&block)
219
+ @cc_instance.on_event(:every_heartbeat, &block)
220
+ end
221
+
222
+ def on_init(&block)
223
+ @cc_instance.on_event(:init, &block)
224
+ end
225
+
226
+ def on_next_redraw(&block)
227
+ @cc_instance.on_event(:next_redraw, &block)
228
+ end
248
229
  end
249
230
  end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Scarpe
4
+ class UnknownShoesEventAPIError < Scarpe::Error; end
5
+
6
+ class UnknownShapeCommandError < Scarpe::Error; end
7
+
8
+ class UnknownBuiltinCommandError < Scarpe::Error; end
9
+
10
+ class UnknownEventTypeError < Scarpe::Error; end
11
+
12
+ class UnexpectedFiberTransferError < Scarpe::Error; end
13
+
14
+ class InvalidPromiseError < Scarpe::Error; end
15
+
16
+ class MissingAppError < Scarpe::Error; end
17
+
18
+ class MissingDocRootError < Scarpe::Error; end
19
+
20
+ class MissingWranglerError < Scarpe::Error; end
21
+
22
+ class IllegalSubscribeEventError < Scarpe::Error; end
23
+
24
+ class IllegalDispatchEventError < Scarpe::Error; end
25
+
26
+ class MissingBlockError < Scarpe::Error; end
27
+
28
+ class DuplicateCallbackError < Scarpe::Error; end
29
+
30
+ class JSBindingError < Scarpe::Error; end
31
+
32
+ class JSInitError < Scarpe::Error; end
33
+
34
+ class PeriodicHandlerSetupError < Scarpe::Error; end
35
+
36
+ class WebWranglerNotRunningError < Scarpe::Error; end
37
+
38
+ class NonexistentEvalResultError < Scarpe::Error; end
39
+
40
+ class JSRedrawError < Scarpe::Error; end
41
+
42
+ class ConnectionError < Scarpe::Error; end
43
+
44
+ class DatagramSendError < Scarpe::Error; end
45
+
46
+ class InvalidOperationError < Scarpe::Error; end
47
+
48
+ class MissingAttributeError < Scarpe::Error; end
49
+
50
+ # This error indicates a problem when running ConfirmedEval
51
+ class JSEvalError < Scarpe::Error
52
+ def initialize(data)
53
+ @data = data
54
+ super(data[:msg] || (self.class.name + "!"))
55
+ end
56
+ end
57
+
58
+ # An error running the supplied JS code string in confirmed_eval
59
+ class JSRuntimeError < JSEvalError; end
60
+
61
+ # The code timed out for some reason
62
+ class JSTimeoutError < JSEvalError; end
63
+
64
+ # We got weird or nonsensical results that seem like an error on WebWrangler's part
65
+ class JSInternalError < JSEvalError; end
66
+
67
+ # An error occurred which would normally be handled by shutting down the app
68
+ class AppShutdownError < Scarpe::Error; end
69
+
70
+ class InvalidClassError < Scarpe::Error; end
71
+
72
+ class MissingClassError < Scarpe::Error; end
73
+
74
+ class EmptyPageNotSetError < Scarpe::Error; end
75
+
76
+ class BadDisplayClassType < Scarpe::Error; end
77
+ end
@@ -0,0 +1,160 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "minitest"
4
+ require "scarpe/cats_cradle"
5
+ require "scarpe/components/string_helpers"
6
+
7
+ require "scarpe/components/unit_test_helpers"
8
+
9
+ # Test framework code to allow Scarpe to execute Shoes-Spec test code.
10
+ # This will run inside the exe/scarpe child process, then send
11
+ # results back to the parent Minitest process.
12
+
13
+ module Scarpe::Test
14
+ # Is it at all reasonable to define more than one test to run in the same Shoes run? Probably not.
15
+ # They'll leave in-memory residue.
16
+ def self.run_shoes_spec_test_code(code, class_name: nil, test_name: nil)
17
+ if @shoes_spec_init
18
+ raise Shoes::Errors::MultipleShoesSpecRunsError, "Scarpe-Webview can only run a single Shoes spec per process!"
19
+ end
20
+
21
+ @shoes_spec_init = true
22
+
23
+ require "scarpe/components/minitest_export_reporter"
24
+ Minitest::Reporters::ShoesExportReporter.activate!
25
+
26
+ class_name ||= ENV["SHOES_MINITEST_CLASS_NAME"] || "TestShoesSpecCode"
27
+ test_name ||= ENV["SHOES_MINITEST_METHOD_NAME"] || "test_shoes_spec"
28
+
29
+ Scarpe::CCInstance.include Scarpe::ShoesSpecTest
30
+
31
+ Scarpe::CCInstance.instance.instance_eval do
32
+ event_init
33
+
34
+ t_timeout = ENV["SCARPE_SSPEC_TIMEOUT"] || "30"
35
+ timeout(t_timeout.to_f) unless t_timeout.downcase == "none"
36
+
37
+ on_event(:next_heartbeat) do
38
+ Minitest.run ARGV
39
+
40
+ wait_after = ENV["SCARPE_SSPEC_TIMEOUT_WAIT_AFTER_TEST"]
41
+ if !(wait_after && wait_after.downcase != "n" && wait_after.downcase != "no")
42
+ shut_down_shoes_code
43
+ end
44
+ end
45
+ end
46
+
47
+ test_class = Class.new(Minitest::Test)
48
+ test_class.include Scarpe::ShoesSpecTest
49
+ Object.const_set(Scarpe::Components::StringHelpers.camelize(class_name), test_class)
50
+ test_name = "test_" + test_name unless test_name.start_with?("test_")
51
+ test_class.define_method(test_name) do
52
+ eval(code)
53
+ end
54
+ end
55
+ end
56
+
57
+ class Scarpe::ShoesSpecProxy
58
+ attr_reader :obj
59
+ attr_reader :linkable_id
60
+ attr_reader :display
61
+
62
+ JS_EVENTS = [:click, :hover, :leave, :change]
63
+
64
+ def initialize(obj)
65
+ @obj = obj
66
+ @linkable_id = obj.linkable_id
67
+ @display = ::Shoes::DisplayService.display_service.query_display_drawable_for(obj.linkable_id)
68
+
69
+ unless @display
70
+ raise "Can't find display widget for #{obj.inspect}!"
71
+ end
72
+ end
73
+
74
+ def method_missing(method, ...)
75
+ if @obj.respond_to?(method)
76
+ self.singleton_class.define_method(method) do |*args, **kwargs, &block|
77
+ @obj.send(method, *args, **kwargs, &block)
78
+ end
79
+ send(method, ...)
80
+ else
81
+ super # raise an exception
82
+ end
83
+ end
84
+
85
+ def trigger(event_name, *args)
86
+ name = "#{@linkable_id}-#{event_name}"
87
+ Scarpe::Webview::DisplayService.instance.app.handle_callback(name, *args)
88
+ end
89
+
90
+ JS_EVENTS.each do |ev|
91
+ define_method "trigger_#{ev}" do |*args|
92
+ trigger(ev, *args)
93
+ end
94
+ end
95
+
96
+ def respond_to_missing?(method_name, include_private = false)
97
+ @obj.respond_to_missing?(method_name, include_private)
98
+ end
99
+ end
100
+
101
+ # When running ShoesSpec tests, we create a parent class for all of them
102
+ # with the appropriate convenience methods and accessors.
103
+ module Scarpe::ShoesSpecTest
104
+ include Scarpe::Test::HTMLAssertions
105
+
106
+ Shoes::Drawable.drawable_classes.each do |drawable_class|
107
+ finder_name = drawable_class.dsl_name
108
+
109
+ define_method(finder_name) do |*args|
110
+ app = Shoes::App.instance
111
+
112
+ drawables = app.find_drawables_by(drawable_class, *args)
113
+ raise Shoes::Errors::MultipleDrawablesFoundError, "Found more than one #{finder_name} matching #{args.inspect}!" if drawables.size > 1
114
+ raise Shoes::Errors::NoDrawablesFoundError, "Found no #{finder_name} matching #{args.inspect}!" if drawables.empty?
115
+
116
+ Scarpe::ShoesSpecProxy.new(drawables[0])
117
+ end
118
+ end
119
+ def drawable(*specs)
120
+ drawables = app.find_drawables_by(*specs)
121
+ raise Scarpe::MultipleDrawablesFoundError, "Found more than one #{finder_name} matching #{args.inspect}!" if drawables.size > 1
122
+ raise Scarpe::NoDrawablesFoundError, "Found no #{finder_name} matching #{args.inspect}!" if drawables.empty?
123
+
124
+ Scarpe::ShoesSpecProxy.new(drawables[0])
125
+ end
126
+
127
+ def catscradle_dsl(&block)
128
+ Scarpe::CCInstance.instance.instance_eval(&block)
129
+ end
130
+
131
+ def dom_html
132
+ catscradle_dsl do
133
+ wait fully_updated
134
+ dom_html
135
+ end
136
+ end
137
+
138
+ # A timeout won't cause an error by itself. If you want an error, make sure
139
+ # to check for a minimum number of assertions or otherwise look for progress.
140
+ def timeout(t_timeout = 5.0)
141
+ catscradle_dsl do
142
+ t0 = Time.now
143
+ on_event(:every_heartbeat) do
144
+ if Time.now - t0 >= t_timeout
145
+ @log.info "Timed out after #{t_timeout} seconds!"
146
+ shut_down_shoes_code
147
+ end
148
+ end
149
+ end
150
+ end
151
+
152
+ def exit_on_first_heartbeat
153
+ catscradle_dsl do
154
+ on_event(:next_heartbeat) do
155
+ @log.info "Exiting on first heartbeat (exit code #{exit_code})"
156
+ exit 0
157
+ end
158
+ end
159
+ end
160
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class Scarpe
4
- VERSION = "0.2.2"
3
+ module Scarpe
4
+ VERSION = "0.4.0"
5
5
  end
data/lib/scarpe/wv/app.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class Scarpe
4
- # Scarpe::WebviewApp must only be used from the main thread, due to GTK+ limitations.
5
- class WebviewApp < WebviewWidget
3
+ module Scarpe::Webview
4
+ # Scarpe::Webview::App must only be used from the main thread, due to GTK+ limitations.
5
+ class App < Drawable # App inherits from Drawable to set up linkable IDs and event methods
6
6
  attr_reader :control_interface
7
7
 
8
8
  attr_writer :shoes_linkable_id
@@ -10,22 +10,16 @@ class Scarpe
10
10
  def initialize(properties)
11
11
  super
12
12
 
13
- # It's possible to provide a Ruby script by setting
14
- # SCARPE_TEST_CONTROL to its file path. This can
15
- # allow pre-setting test options or otherwise
16
- # performing additional actions not written into
17
- # the Shoes app itself.
18
- #
19
- # The control interface is what lets these files see
20
- # events, specify overrides and so on.
13
+ # Scarpe's ControlInterface sets up event handlers
14
+ # for the display service that aren't sent to
15
+ # Lacci (Shoes). In general it's used for setup
16
+ # and additional control or testing, outside the
17
+ # Shoes app. This is how CatsCradle and Shoes-Spec
18
+ # set up testing, for instance.
21
19
  @control_interface = ControlInterface.new
22
- if ENV["SCARPE_TEST_CONTROL"]
23
- require "scarpe/components/unit_test_helpers"
24
- @control_interface.instance_eval File.read(ENV["SCARPE_TEST_CONTROL"])
25
- end
26
20
 
27
21
  # TODO: rename @view
28
- @view = Scarpe::WebWrangler.new title: @title,
22
+ @view = Scarpe::Webview::WebWrangler.new title: @title,
29
23
  width: @width,
30
24
  height: @height,
31
25
  resizable: @resizable
@@ -61,8 +55,11 @@ class Scarpe
61
55
  end
62
56
 
63
57
  def run
58
+ # This is run before the Webview event loop is up and running
64
59
  @control_interface.dispatch_event(:init)
65
60
 
61
+ @view.empty_page = empty_page_element
62
+
66
63
  # This takes control of the main thread and never returns. And it *must* be run from
67
64
  # the main thread. And it stops any Ruby background threads.
68
65
  # That's totally cool and normal, right?
@@ -80,14 +77,18 @@ class Scarpe
80
77
  end
81
78
  end
82
79
 
83
- # All JS callbacks to Scarpe widgets are dispatched
80
+ # All JS callbacks to Scarpe drawables are dispatched
84
81
  # via this handler
85
82
  def handle_callback(name, *args)
86
- @callbacks[name].call(*args)
83
+ if @callbacks.key?(name)
84
+ @callbacks[name].call(*args)
85
+ else
86
+ raise Scarpe::UnknownEventTypeError, "No such Webview callback: #{name.inspect}!"
87
+ end
87
88
  end
88
89
 
89
90
  # Bind a Scarpe callback name; see handle_callback above.
90
- # See Scarpe::Widget for how the naming is set up
91
+ # See Scarpe::Drawable for how the naming is set up
91
92
  def bind(name, &block)
92
93
  @callbacks[name] = block
93
94
  end
@@ -97,7 +98,7 @@ class Scarpe
97
98
  #
98
99
  # @return [void]
99
100
  def request_redraw!
100
- wrangler = WebviewDisplayService.instance.wrangler
101
+ wrangler = DisplayService.instance.wrangler
101
102
  if wrangler.is_running
102
103
  wrangler.replace(@document_root.to_html)
103
104
  end
data/lib/scarpe/wv/arc.rb CHANGED
@@ -1,56 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class Scarpe
4
- class WebviewArc < Scarpe::WebviewWidget
5
- def initialize(properties)
6
- super(properties)
7
- end
8
-
9
- def element(&block)
10
- HTML.render do |h|
11
- h.div(id: html_id, style: style) do
12
- h.svg(width: @width, height: @height) do
13
- h.path(d: arc_path)
14
- end
15
- block.call(h) if block_given?
16
- end
17
- end
18
- end
19
-
20
- protected
21
-
22
- def style
23
- super.merge({
24
- left: "#{@left}px",
25
- top: "#{@top}px",
26
- width: "#{@width}px",
27
- height: "#{@height}px",
28
- })
29
- end
30
-
31
- private
32
-
33
- def arc_path
34
- center_x = @width / 2
35
- center_y = @height / 2
36
- radius_x = @width / 2
37
- radius_y = @height / 2
38
- start_angle_degrees = radians_to_degrees(@angle1) % 360
39
- end_angle_degrees = radians_to_degrees(@angle2) % 360
40
- large_arc_flag = (end_angle_degrees - start_angle_degrees) % 360 > 180 ? 1 : 0
41
-
42
- "M#{center_x} #{center_y} L#{@width} #{center_y} " \
43
- "A#{radius_x} #{radius_y} 0 #{large_arc_flag} 0 " \
44
- "#{center_x + radius_x * Math.cos(degrees_to_radians(end_angle_degrees))} " \
45
- "#{center_y + radius_y * Math.sin(degrees_to_radians(end_angle_degrees))} Z"
46
- end
47
-
48
- def degrees_to_radians(degrees)
49
- degrees * Math::PI / 180
50
- end
51
-
52
- def radians_to_degrees(radians)
53
- radians * (180.0 / Math::PI)
3
+ module Scarpe::Webview
4
+ class Arc < Drawable
5
+ def element
6
+ render("arc")
54
7
  end
55
8
  end
56
9
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Scarpe::Webview
4
+ class Arrow < Drawable
5
+ def element
6
+ render("arrow")
7
+ end
8
+ end
9
+ end