scarpe 0.3.0 → 0.5.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 (297) hide show
  1. checksums.yaml +4 -4
  2. data/.cursor/rules/commit-style-preferences.mdc +72 -0
  3. data/.cursor/rules/component_context.mdc +82 -0
  4. data/.cursor/rules/debug-failed-tests.mdc +100 -0
  5. data/.cursor/rules/display_service_context.mdc +80 -0
  6. data/.cursor/rules/event_handling_context.mdc +100 -0
  7. data/.cursor/rules/git-pager-handling.mdc +64 -0
  8. data/.cursor/rules/lacci-context.mdc +52 -0
  9. data/.cursor/rules/scarpe_design_context.mdc +46 -0
  10. data/.cursor/rules/shoes_compatibility_context.mdc +75 -0
  11. data/.cursor/rules/timeout_context.mdc +78 -0
  12. data/.cursor/rules/update_lacci_and_wv.mdc +8 -0
  13. data/.cursor/rules/what_is_scarpe.mdc +22 -0
  14. data/.cursor/rules/writing-new-rules.mdc +73 -0
  15. data/CHANGELOG.md +46 -5
  16. data/CLAUDE.md +223 -0
  17. data/Gemfile +2 -2
  18. data/Gemfile.lock +85 -55
  19. data/LICENSE.txt +7 -1
  20. data/README.md +80 -20
  21. data/Rakefile +73 -14
  22. data/docs/SCARPE_FEATURES.md +38 -0
  23. data/docs/_config.yml +13 -0
  24. data/docs/calzini_components_and_updates.md +78 -0
  25. data/docs/display_service_separation.md +39 -0
  26. data/docs/documentation.md +43 -0
  27. data/docs/event_loops.md +66 -0
  28. data/docs/image.png +0 -0
  29. data/docs/index.md +118 -0
  30. data/docs/lacci.md +121 -0
  31. data/docs/scarpe_shoes_incompatibilities.md +71 -0
  32. data/docs/shoes_and_display_events.md +55 -0
  33. data/docs/shoes_implementations.md +79 -0
  34. data/docs/static/manual.md +5 -0
  35. data/docs/static/scarpe-logo.png +0 -0
  36. data/docs/timeouts_and_handlers.md +66 -0
  37. data/docs/web_archaeology.md +76 -0
  38. data/examples/Edit_box_Styles.rb +8 -0
  39. data/examples/Kerning.rb +7 -0
  40. data/examples/background_with_image.rb +14 -5
  41. data/examples/bloopsaphone/working/feepogram.rb +1 -1
  42. data/examples/bloopsaphone/working/le_dance_des_rubis.rb +135 -0
  43. data/examples/bloopsaphone/working/pixel_dreams_in_ruby.rb +131 -0
  44. data/examples/bloopsaphone/working/type_rebellion.rb +157 -0
  45. data/examples/border.rb +11 -0
  46. data/examples/check.rb +2 -0
  47. data/examples/download_and_show_image.rb +3 -0
  48. data/examples/flags/finland.rb +15 -0
  49. data/examples/flags/italy.rb +11 -0
  50. data/examples/flags/mauritius.rb +14 -0
  51. data/examples/font_family.rb +17 -0
  52. data/examples/font_shorthand.rb +9 -0
  53. data/examples/gen.rb +4 -0
  54. data/examples/internal_link_navigation.rb +19 -0
  55. data/examples/legacy/not_checked/shoes-manual/append.rb +10 -0
  56. data/examples/legacy/not_checked/shoes-manual/background_change.rb +12 -0
  57. data/examples/legacy/not_checked/shoes-manual/background_pattern.rb +5 -0
  58. data/examples/legacy/not_checked/shoes-manual/basic_app.rb +8 -0
  59. data/examples/legacy/not_checked/shoes-manual/border.rb +9 -0
  60. data/examples/legacy/not_checked/shoes-manual/builtins/FONTS.rb +5 -0
  61. data/examples/legacy/not_checked/shoes-manual/builtins/ask.rb +2 -0
  62. data/examples/legacy/not_checked/shoes-manual/builtins/ask_color.rb +5 -0
  63. data/examples/legacy/not_checked/shoes-manual/builtins/ask_open_file.rb +5 -0
  64. data/examples/legacy/not_checked/shoes-manual/builtins/ask_save_folder.rb +2 -0
  65. data/examples/legacy/not_checked/shoes-manual/builtins/confirm.rb +4 -0
  66. data/examples/legacy/not_checked/shoes-manual/builtins/debug.rb +2 -0
  67. data/examples/legacy/not_checked/shoes-manual/builtins/info.rb +3 -0
  68. data/examples/legacy/not_checked/shoes-manual/button.rb +9 -0
  69. data/examples/legacy/not_checked/shoes-manual/clear.rb +7 -0
  70. data/examples/legacy/not_checked/shoes-manual/custom_header.rb +13 -0
  71. data/examples/legacy/not_checked/shoes-manual/displace.rb +14 -0
  72. data/examples/legacy/not_checked/shoes-manual/edit_box.rb +8 -0
  73. data/examples/legacy/not_checked/shoes-manual/fill_pattern.rb +5 -0
  74. data/examples/legacy/not_checked/shoes-manual/fonts.rb +7 -0
  75. data/examples/legacy/not_checked/shoes-manual/gutter.rb +6 -0
  76. data/examples/legacy/not_checked/shoes-manual/image_web.rb +4 -0
  77. data/examples/legacy/not_checked/shoes-manual/keypress.rb +7 -0
  78. data/examples/legacy/not_checked/shoes-manual/list_box.rb +10 -0
  79. data/examples/legacy/not_checked/shoes-manual/motion.rb +10 -0
  80. data/examples/legacy/not_checked/shoes-manual/mouse.rb +8 -0
  81. data/examples/legacy/not_checked/shoes-manual/move.rb +14 -0
  82. data/examples/legacy/not_checked/shoes-manual/nested_ovals.rb +8 -0
  83. data/examples/legacy/not_checked/shoes-manual/oval.rb +7 -0
  84. data/examples/legacy/not_checked/shoes-manual/ovals.rb +6 -0
  85. data/examples/legacy/not_checked/shoes-manual/ovals_image.rb +8 -0
  86. data/examples/legacy/not_checked/shoes-manual/prepend.rb +7 -0
  87. data/examples/legacy/not_checked/shoes-manual/progress_bar.rb +10 -0
  88. data/examples/legacy/not_checked/shoes-manual/radio.rb +18 -0
  89. data/examples/legacy/not_checked/shoes-manual/radio_alternative_1.rb +7 -0
  90. data/examples/legacy/not_checked/shoes-manual/radio_alternative_2.rb +9 -0
  91. data/examples/legacy/not_checked/shoes-manual/rotate_rectangle.rb +6 -0
  92. data/examples/legacy/not_checked/shoes-manual/shape.rb +11 -0
  93. data/examples/legacy/not_checked/shoes-manual/static/avatar.png +0 -0
  94. data/examples/legacy/not_checked/shoes-manual/stroke.rb +5 -0
  95. data/examples/legacy/not_checked/shoes-manual/style.rb +3 -0
  96. data/examples/legacy/not_checked/shoes-manual/style_alternative_1.rb +4 -0
  97. data/examples/legacy/not_checked/shoes-manual/style_alternative_2.rb +5 -0
  98. data/examples/legacy/not_checked/shoes-manual/style_length.rb +5 -0
  99. data/examples/legacy/not_checked/shoes-manual/timer.rb +6 -0
  100. data/examples/legacy/not_checked/shoes-manual/trigger_window.rb +8 -0
  101. data/examples/legacy/not_checked/shoes-manual/window_owner.rb +8 -0
  102. data/examples/legacy/working/shoes_manual/alert_button.rb +2 -0
  103. data/examples/legacy/working/shoes_manual/animate.rb +7 -0
  104. data/examples/legacy/working/shoes_manual/background_para.rb +4 -0
  105. data/examples/legacy/working/shoes_manual/button_alternative.rb +7 -0
  106. data/examples/legacy/working/shoes_manual/checkbox.rb +17 -0
  107. data/examples/legacy/working/shoes_manual/download.rb +12 -0
  108. data/examples/legacy/working/shoes_manual/edit_box.rb +6 -0
  109. data/examples/legacy/working/shoes_manual/editline.rb +7 -0
  110. data/examples/legacy/working/shoes_manual/fixed_height.rb +8 -0
  111. data/examples/legacy/working/shoes_manual/fixed_width.rb +12 -0
  112. data/examples/legacy/working/shoes_manual/image.rb +5 -0
  113. data/examples/legacy/working/shoes_manual/instance_variable_check.rb +10 -0
  114. data/examples/legacy/working/shoes_manual/message.rb +18 -0
  115. data/examples/legacy/working/shoes_manual/rectangle.rb +6 -0
  116. data/examples/legacy/working/shoes_manual/save_download.rb +12 -0
  117. data/examples/legacy/working/shoes_manual/self_check.rb +10 -0
  118. data/examples/legacy/working/shoes_manual/stack.rb +7 -0
  119. data/examples/legacy/working/shoes_manual/style_info.rb +8 -0
  120. data/examples/legacy/working/shoes_manual/utf8_support.rb +8 -0
  121. data/examples/legacy/working/shoes_manual/width.rb +4 -0
  122. data/examples/local_assets/multi_image.rb +5 -0
  123. data/examples/local_assets/small.png +0 -0
  124. data/examples/local_fonts.rb +3 -0
  125. data/examples/margin.rb +13 -0
  126. data/examples/margin_check.rb +27 -0
  127. data/examples/oval-with-kwargs.rb +3 -0
  128. data/examples/oval.rb +26 -0
  129. data/examples/page_navigation_single_app.rb +42 -0
  130. data/examples/para_font_styles.rb +17 -0
  131. data/examples/para_font_variant.rb +6 -0
  132. data/examples/para_fontweight.rb +13 -0
  133. data/examples/parse_xl_funnies.rb +3 -0
  134. data/examples/rect.rb +1 -1
  135. data/examples/scarpe_ext.rb +3 -0
  136. data/examples/shapes/star.rb +1 -3
  137. data/examples/shoes_subclass_app.rb +25 -0
  138. data/examples/spacing.rb +1 -1
  139. data/examples/span.rb +4 -2
  140. data/examples/url_routing_example.rb +67 -0
  141. data/lacci/Gemfile +0 -2
  142. data/lacci/Gemfile.lock +4 -32
  143. data/lacci/lacci.gemspec +3 -3
  144. data/lacci/lib/lacci/scarpe_cli.rb +0 -1
  145. data/lacci/lib/lacci/version.rb +1 -1
  146. data/lacci/lib/scarpe/niente/app.rb +12 -1
  147. data/lacci/lib/scarpe/niente/display_service.rb +5 -1
  148. data/lacci/lib/scarpe/niente/drawable.rb +2 -0
  149. data/lacci/lib/scarpe/niente/shoes_spec.rb +10 -5
  150. data/lacci/lib/scarpe/niente.rb +15 -2
  151. data/lacci/lib/shoes/app.rb +204 -105
  152. data/lacci/lib/shoes/constants.rb +24 -2
  153. data/lacci/lib/shoes/display_service.rb +43 -4
  154. data/lacci/lib/shoes/drawable.rb +326 -36
  155. data/lacci/lib/shoes/drawables/arc.rb +4 -26
  156. data/lacci/lib/shoes/drawables/arrow.rb +3 -23
  157. data/lacci/lib/shoes/drawables/border.rb +28 -0
  158. data/lacci/lib/shoes/drawables/button.rb +5 -21
  159. data/lacci/lib/shoes/drawables/check.rb +7 -3
  160. data/lacci/lib/shoes/drawables/document_root.rb +4 -4
  161. data/lacci/lib/shoes/drawables/edit_box.rb +6 -5
  162. data/lacci/lib/shoes/drawables/edit_line.rb +5 -4
  163. data/lacci/lib/shoes/drawables/flow.rb +4 -6
  164. data/lacci/lib/shoes/drawables/font_helper.rb +62 -0
  165. data/lacci/lib/shoes/drawables/image.rb +2 -2
  166. data/lacci/lib/shoes/drawables/line.rb +3 -6
  167. data/lacci/lib/shoes/drawables/link.rb +16 -9
  168. data/lacci/lib/shoes/drawables/list_box.rb +8 -5
  169. data/lacci/lib/shoes/drawables/oval.rb +48 -0
  170. data/lacci/lib/shoes/drawables/para.rb +106 -18
  171. data/lacci/lib/shoes/drawables/progress.rb +2 -1
  172. data/lacci/lib/shoes/drawables/radio.rb +5 -3
  173. data/lacci/lib/shoes/drawables/rect.rb +7 -6
  174. data/lacci/lib/shoes/drawables/shape.rb +4 -3
  175. data/lacci/lib/shoes/drawables/slot.rb +102 -9
  176. data/lacci/lib/shoes/drawables/stack.rb +7 -12
  177. data/lacci/lib/shoes/drawables/star.rb +9 -31
  178. data/lacci/lib/shoes/drawables/text_drawable.rb +93 -34
  179. data/lacci/lib/shoes/drawables/video.rb +3 -2
  180. data/lacci/lib/shoes/drawables/widget.rb +9 -4
  181. data/lacci/lib/shoes/drawables.rb +2 -1
  182. data/lacci/lib/shoes/errors.rb +13 -3
  183. data/lacci/lib/shoes/margin_helper.rb +79 -0
  184. data/lacci/lib/shoes.rb +98 -20
  185. data/lacci/test/.gitignore +1 -0
  186. data/lacci/test/test_draw_context.rb +167 -0
  187. data/lacci/test/test_font_helper.rb +57 -0
  188. data/lacci/test/test_helper.rb +31 -4
  189. data/lacci/test/test_lacci.rb +93 -6
  190. data/lacci/test/test_margin_helper.rb +82 -0
  191. data/lacci/test/test_niente_test_infra.rb +40 -0
  192. data/lacci/test/test_oval.rb +82 -0
  193. data/lacci/test/test_parenting.rb +140 -0
  194. data/lacci/test/test_shoes_errors.rb +15 -13
  195. data/lacci/test/test_text_drawables.rb +23 -0
  196. data/lib/scarpe/assets.rb +19 -0
  197. data/lib/scarpe/cats_cradle.rb +57 -98
  198. data/lib/scarpe/shoes_spec.rb +24 -44
  199. data/lib/scarpe/version.rb +1 -1
  200. data/lib/scarpe/wv/app.rb +1 -0
  201. data/lib/scarpe/wv/arc.rb +0 -4
  202. data/lib/scarpe/wv/border.rb +15 -0
  203. data/lib/scarpe/wv/control_interface.rb +2 -10
  204. data/lib/scarpe/wv/document_root.rb +2 -2
  205. data/lib/scarpe/wv/drawable.rb +6 -40
  206. data/lib/scarpe/wv/edit_box.rb +4 -1
  207. data/lib/scarpe/wv/edit_line.rb +4 -1
  208. data/lib/scarpe/wv/image.rb +2 -5
  209. data/lib/scarpe/wv/link.rb +4 -2
  210. data/lib/scarpe/wv/oval.rb +13 -0
  211. data/lib/scarpe/wv/para.rb +1 -0
  212. data/lib/scarpe/wv/scarpe_extensions.rb +8 -0
  213. data/lib/scarpe/wv/shape.rb +10 -5
  214. data/lib/scarpe/wv/text_drawable.rb +72 -14
  215. data/lib/scarpe/wv/web_wrangler.rb +33 -11
  216. data/lib/scarpe/wv/webview_local_display.rb +6 -2
  217. data/lib/scarpe/wv.rb +16 -2
  218. data/scarpe-components/Gemfile +4 -3
  219. data/scarpe-components/Gemfile.lock +6 -37
  220. data/scarpe-components/README.md +2 -2
  221. data/scarpe-components/assets/bootstrap-themes/bootstrap-cerulean.css +12229 -0
  222. data/scarpe-components/assets/bootstrap-themes/bootstrap-cosmo.css +11810 -0
  223. data/scarpe-components/assets/bootstrap-themes/bootstrap-cyborg.css +12210 -0
  224. data/scarpe-components/assets/bootstrap-themes/bootstrap-darkly.css +12153 -0
  225. data/scarpe-components/assets/bootstrap-themes/bootstrap-flatly.css +12126 -0
  226. data/scarpe-components/assets/bootstrap-themes/bootstrap-icons.min.css +5 -0
  227. data/scarpe-components/assets/bootstrap-themes/bootstrap-journal.css +12099 -0
  228. data/scarpe-components/assets/bootstrap-themes/bootstrap-litera.css +12211 -0
  229. data/scarpe-components/assets/bootstrap-themes/bootstrap-lumen.css +12369 -0
  230. data/scarpe-components/assets/bootstrap-themes/bootstrap-lux.css +11928 -0
  231. data/scarpe-components/assets/bootstrap-themes/bootstrap-materia.css +13184 -0
  232. data/scarpe-components/assets/bootstrap-themes/bootstrap-minty.css +12177 -0
  233. data/scarpe-components/assets/bootstrap-themes/bootstrap-morph.css +12750 -0
  234. data/scarpe-components/assets/bootstrap-themes/bootstrap-pulse.css +11890 -0
  235. data/scarpe-components/assets/bootstrap-themes/bootstrap-quartz.css +12622 -0
  236. data/scarpe-components/assets/bootstrap-themes/bootstrap-sandstone.css +12201 -0
  237. data/scarpe-components/assets/bootstrap-themes/bootstrap-simplex.css +12186 -0
  238. data/scarpe-components/assets/bootstrap-themes/bootstrap-sketchy.css +12451 -0
  239. data/scarpe-components/assets/bootstrap-themes/bootstrap-slate.css +12492 -0
  240. data/scarpe-components/assets/bootstrap-themes/bootstrap-solar.css +12149 -0
  241. data/scarpe-components/assets/bootstrap-themes/bootstrap-spacelab.css +12266 -0
  242. data/scarpe-components/assets/bootstrap-themes/bootstrap-superhero.css +12216 -0
  243. data/scarpe-components/assets/bootstrap-themes/bootstrap-united.css +12077 -0
  244. data/scarpe-components/assets/bootstrap-themes/bootstrap-vapor.css +12549 -0
  245. data/scarpe-components/assets/bootstrap-themes/bootstrap-yeti.css +12325 -0
  246. data/scarpe-components/assets/bootstrap-themes/bootstrap-zephyr.css +12283 -0
  247. data/scarpe-components/assets/bootstrap-themes/bootstrap.bundle.min.js +7 -0
  248. data/scarpe-components/lib/scarpe/components/asset_server.rb +219 -0
  249. data/scarpe-components/lib/scarpe/components/base64.rb +22 -0
  250. data/scarpe-components/lib/scarpe/components/calzini/{art_widgets.rb → art_drawables.rb} +42 -18
  251. data/scarpe-components/lib/scarpe/components/calzini/border.rb +38 -0
  252. data/scarpe-components/lib/scarpe/components/calzini/button.rb +6 -8
  253. data/scarpe-components/lib/scarpe/components/calzini/misc.rb +14 -16
  254. data/scarpe-components/lib/scarpe/components/calzini/para.rb +218 -11
  255. data/scarpe-components/lib/scarpe/components/calzini/slots.rb +16 -60
  256. data/scarpe-components/lib/scarpe/components/calzini.rb +88 -1
  257. data/scarpe-components/lib/scarpe/components/errors.rb +4 -0
  258. data/scarpe-components/lib/scarpe/components/html.rb +4 -1
  259. data/scarpe-components/lib/scarpe/components/minitest_export_reporter.rb +11 -3
  260. data/scarpe-components/lib/scarpe/components/minitest_result.rb +41 -0
  261. data/scarpe-components/lib/scarpe/components/port_helpers.rb +30 -0
  262. data/scarpe-components/lib/scarpe/components/print_logger.rb +17 -2
  263. data/scarpe-components/lib/scarpe/components/process_helpers.rb +37 -0
  264. data/scarpe-components/lib/scarpe/components/segmented_file_loader.rb +1 -1
  265. data/scarpe-components/lib/scarpe/components/tiranti.rb +42 -100
  266. data/scarpe-components/lib/scarpe/components/unit_test_helpers.rb +3 -1
  267. data/scarpe-components/lib/scarpe/components/version.rb +1 -1
  268. data/scarpe-components/scarpe-components.gemspec +1 -1
  269. data/scarpe-components/test/assets/big-image.png +0 -0
  270. data/scarpe-components/test/assets/big-stylesheet.css +497 -0
  271. data/scarpe-components/test/assets/little-image.png +0 -0
  272. data/scarpe-components/test/assets/little-stylesheet.css +1 -0
  273. data/scarpe-components/test/calzini/test_calzini_art_drawables.rb +7 -7
  274. data/scarpe-components/test/calzini/test_calzini_button.rb +7 -5
  275. data/scarpe-components/test/calzini/test_calzini_misc.rb +9 -9
  276. data/scarpe-components/test/calzini/test_calzini_para.rb +6 -9
  277. data/scarpe-components/test/calzini/test_calzini_slots.rb +12 -57
  278. data/scarpe-components/test/calzini/test_calzini_text_drawables.rb +83 -18
  279. data/scarpe-components/test/calzini/test_various.rb +133 -0
  280. data/scarpe-components/test/test_asset_server.rb +72 -0
  281. data/scarpe-components/test/test_components.rb +31 -2
  282. data/scarpe-components/test/test_helper.rb +0 -1
  283. data/scarpe-components/test/test_minitest_result.rb +7 -0
  284. data/scarpe-components/test/test_port_helpers.rb +12 -0
  285. data/scarpe-components/test/test_segmented_app_files.rb +2 -0
  286. data/tasks/check_html_fixtures.rb +140 -0
  287. data/tasks/regenerate_html_fixtures.rb +104 -0
  288. data/templates/class_template_with_shapes.erb +0 -11
  289. metadata +225 -39
  290. data/.rubocop.yml +0 -88
  291. data/lacci/lib/scarpe/niente/logger.rb +0 -29
  292. data/lacci/lib/shoes/drawables/span.rb +0 -27
  293. data/lacci/lib/shoes/spacing.rb +0 -9
  294. data/lib/scarpe/evented_assertions.rb +0 -121
  295. data/lib/scarpe/wv/span.rb +0 -44
  296. data/scarpe-components/lib/scarpe/components/calzini/text_widgets.rb +0 -65
  297. /data/examples/legacy/{not_checked → working}/shoes3-tests/editline/editline.rb +0 -0
@@ -7,15 +7,19 @@ class TestCalziniPara < Minitest::Test
7
7
  @calzini = CalziniRenderer.new
8
8
  end
9
9
 
10
- # Note that Calzini doesn't render the text items for itself.
11
10
  def test_para_simple
12
11
  assert_equal %{<p id="elt-1">OK</p>},
13
12
  @calzini.render("para", {}) { "OK" }
14
13
  end
15
14
 
15
+ def test_para_with_align
16
+ assert_equal %{<div id=\"elt-1\" style=\"text-align:right;width:100%\"><p>OK</p></div>},
17
+ @calzini.render("para", { "align" => "right" }) { "OK" }
18
+ end
19
+
16
20
  def test_para_with_stroke_and_font
17
21
  assert_equal %{<p id="elt-1" style="color:#FF0000;font-family:Lucida">OK</p>},
18
- @calzini.render("para", { "stroke" => [1.0, 0.0, 0.0], "font" => "Lucida" }) { "OK" }
22
+ @calzini.render("para", { "stroke" => [1.0, 0.0, 0.0], "family" => "Lucida" }) { "OK" }
19
23
  end
20
24
 
21
25
  def test_para_with_string_banner
@@ -27,11 +31,4 @@ class TestCalziniPara < Minitest::Test
27
31
  assert_equal %{<p id="elt-1" style="font-size:48px"></p>},
28
32
  @calzini.render("para", { "size" => :banner })
29
33
  end
30
-
31
- # Eventually this should probably need to be marked as a Scarpe extension, here or
32
- # elsewhere.
33
- def test_para_with_html_attributes
34
- assert_equal %{<p avocado="true" class="avocado_bearing" id="elt-1"></p>},
35
- @calzini.render("para", { "html_attributes" => { "avocado" => true, "class" => "avocado_bearing" } })
36
- end
37
34
  end
@@ -7,124 +7,79 @@ class TestCalziniSlots < Minitest::Test
7
7
  @calzini = CalziniRenderer.new
8
8
  @stack_default_style = %{display:flex;flex-direction:column;align-content:flex-start;justify-content:flex-start;align-items:flex-start}
9
9
  @flow_default_style = %{display:flex;flex-direction:row;flex-wrap:wrap;align-content:flex-start;justify-content:flex-start;align-items:flex-start}
10
+ @inner_div_tag = %{<div style="height:100%;width:100%;position:relative">}
10
11
  end
11
12
 
12
13
  def test_stack_simple
13
14
  assert_equal %{<div id="elt-1" } +
14
15
  %{style="#{@stack_default_style}">} +
15
- %{contents</div>},
16
+ %{#{@inner_div_tag}contents</div></div>},
16
17
  @calzini.render("stack", {}) { "contents" }
17
18
  end
18
19
 
19
20
  def test_flow_simple
20
21
  assert_equal %{<div id="elt-1" } +
21
22
  %{style="#{@flow_default_style}">} +
22
- %{contents</div>},
23
+ %{#{@inner_div_tag}contents</div></div>},
23
24
  @calzini.render("flow", {}) { "contents" }
24
25
  end
25
26
 
26
27
  def test_docroot_simple
27
28
  assert_equal %{<div id="elt-1" } +
28
29
  %{style="#{@flow_default_style}">} +
29
- %{contents</div>},
30
+ %{#{@inner_div_tag}contents</div></div>},
30
31
  @calzini.render("documentroot", {}) { "contents" }
31
32
  end
32
33
 
33
34
  def test_stack_border_plain_color
34
35
  assert_equal %{<div id="elt-1" } +
35
36
  %{style="#{@stack_default_style};border-style:solid;border-width:1px;border-radius:0px;border-color:red">} +
36
- %{contents</div>},
37
+ %{#{@inner_div_tag}contents</div></div>},
37
38
  @calzini.render("stack", { "border_color" => "red" }) { "contents" }
38
39
  end
39
40
 
40
41
  def test_stack_border_gradient
41
42
  assert_equal %{<div id="elt-1" } +
42
43
  %{style="#{@stack_default_style};border-style:solid;border-width:1px;border-radius:0px;border-image:linear-gradient(45deg, red, green)">} +
43
- %{contents</div>},
44
+ %{#{@inner_div_tag}contents</div></div>},
44
45
  @calzini.render("stack", { "border_color" => ("red".."green") }) { "contents" }
45
46
  end
46
47
 
47
48
  def test_stack_border_rgba
48
49
  assert_equal %{<div id="elt-1" } +
49
50
  %{style="#{@stack_default_style};border-style:solid;border-width:1px;border-radius:0px;border-color:rgba(1.0, 0.0, 0.0, 1.0)">} +
50
- %{contents</div>},
51
+ %{#{@inner_div_tag}contents</div></div>},
51
52
  @calzini.render("stack", { "border_color" => [1.0, 0.0, 0.0, 1.0] }) { "contents" }
52
53
  end
53
54
 
54
55
  def test_stack_border_attrs
55
56
  assert_equal %{<div id="elt-1" } +
56
57
  %{style="#{@stack_default_style};border-style:solid;border-width:3px;border-radius:2px;border-color:red">} +
57
- %{contents</div>},
58
+ %{#{@inner_div_tag}contents</div></div>},
58
59
  @calzini.render("stack", { "border_color" => "red", "options" => { "strokewidth" => 3, "curve" => 2 } }) { "contents" }
59
60
  end
60
61
 
61
- def test_stack_margin
62
- assert_equal %{<div id="elt-1" } +
63
- %{style="#{@stack_default_style};margin:25px">} +
64
- %{contents</div>},
65
- @calzini.render("stack", { "margin" => 25 }) { "contents" }
66
- end
67
-
68
- def test_stack_options_margin
69
- assert_equal %{<div id="elt-1" } +
70
- %{style="#{@stack_default_style};margin:15px">} +
71
- %{contents</div>},
72
- @calzini.render("stack", { "options" => { "margin" => 15 } }) { "contents" }
73
- end
74
-
75
- def test_stack_margin_overrides_options
76
- assert_equal %{<div id="elt-1" } +
77
- %{style="#{@stack_default_style};margin:25px">} +
78
- %{contents</div>},
79
- @calzini.render("stack", { "margin" => 25, "options" => { "margin" => 15 } }) { "contents" }
80
- end
81
62
 
82
63
  def test_stack_padding
83
64
  assert_equal %{<div id="elt-1" } +
84
65
  %{style="#{@stack_default_style};padding:25px">} +
85
- %{contents</div>},
66
+ %{#{@inner_div_tag}contents</div></div>},
86
67
  @calzini.render("stack", { "padding" => 25 }) { "contents" }
87
68
  end
88
69
 
89
70
  def test_stack_options_padding
90
71
  assert_equal %{<div id="elt-1" } +
91
72
  %{style="#{@stack_default_style};padding:15px">} +
92
- %{contents</div>},
73
+ %{#{@inner_div_tag}contents</div></div>},
93
74
  @calzini.render("stack", { "options" => { "padding" => 15 } }) { "contents" }
94
75
  end
95
76
 
96
77
  def test_stack_padding_overrides_options
97
78
  assert_equal %{<div id="elt-1" } +
98
79
  %{style="#{@stack_default_style};padding:25px">} +
99
- %{contents</div>},
80
+ %{#{@inner_div_tag}contents</div></div>},
100
81
  @calzini.render("stack", { "padding" => 25, "options" => { "padding" => 15 } }) { "contents" }
101
82
  end
102
83
 
103
- def test_stack_options_hash_margin
104
- assert_equal %{<div id="elt-1" } +
105
- %{style="#{@stack_default_style};margin-left:5px;margin-right:10px;margin-top:15px;margin-bottom:20px">} +
106
- %{contents</div>},
107
- @calzini.render("stack", { "margin" => { left: 5, right: 10, top: 15, bottom: 20 } }) { "contents" }
108
- end
109
-
110
- def test_stack_options_array_margin
111
- assert_equal %{<div id="elt-1" } +
112
- %{style="#{@stack_default_style};margin-left:5px;margin-right:10px;margin-top:15px;margin-bottom:20px">} +
113
- %{contents</div>},
114
- @calzini.render("stack", { "margin" => [5, 10, 15, 20] }) { "contents" }
115
- end
116
-
117
- def test_stack_options_margin_left_overrides_options
118
- assert_equal %{<div id="elt-1" } +
119
- %{style="#{@stack_default_style};margin-left:25px">} +
120
- %{contents</div>},
121
- @calzini.render("stack", { "margin_left" => 25, "options" => { "margin" => 15 } }) { "contents" }
122
- end
123
-
124
- def test_stack_margin_left_overrides_margin
125
- assert_equal %{<div id="elt-1" } +
126
- %{style="#{@stack_default_style};margin:25px;margin-left:15px">} +
127
- %{contents</div>},
128
- @calzini.render("stack", { "margin" => 25, "margin_left" => 15 }) { "contents" }
129
- end
84
+
130
85
  end
@@ -7,35 +7,100 @@ class TestCalziniTextDrawables < Minitest::Test
7
7
  @calzini = CalziniRenderer.new
8
8
  end
9
9
 
10
- def test_link_simple
11
- assert_equal %{<a id="elt-1" href="https://google.com">click here</a>},
12
- @calzini.render("link", { "click" => "https://google.com", "text" => "click here" })
10
+ def trim_html_ids(s)
11
+ s.gsub(/ class="id_\d+"/, "")
13
12
  end
14
13
 
15
- def test_link_block
16
- assert_equal %{<a id="elt-1" onclick="handle('click')">click here</a>},
17
- @calzini.render("link", { "has_block" => true, "text" => "click here" })
14
+ def test_text_only_drawable
15
+ assert_equal %{this is text},
16
+ @calzini.render("text_drawable", ["this ", "is", " text"])
18
17
  end
19
18
 
20
- def test_span_simple
21
- assert_equal %{<span id="elt-1" style="color:red;font-size:48px;font-family:Lucida">big red</span>},
22
- @calzini.render("span", { "stroke" => "red", "size" => :banner, "font" => "Lucida" }) { "big red" }
19
+ def test_simple_text_drawable_with_em
20
+ assert_equal %{this <em class="id_1">is</em> text},
21
+ @calzini.render("text_drawable",
22
+ ["this ", { tag: "em", html_id: "1", items: ["is"], props: {}}, " text"])
23
23
  end
24
24
 
25
- def test_span_html_attributes
26
- assert_equal %{<span class="biggreen" id="elt-1" style="color:green;font-size:48px">big green</span>},
27
- @calzini.render("span", { "stroke" => "green", "size" => "banner", "html_attributes" => { "class" => "biggreen" } }) { "big green" }
25
+ # Span doesn't have default properties, so it's good for testing how a property is rendered
26
+ def test_simple_text_drawable_with_span_styles
27
+ assert_equal %{this <span style="color:#FF00FF;background-color:#0000FF;font-size:13px;font-family:Lucida">is</span> text},
28
+ trim_html_ids(@calzini.render("text_drawable",
29
+ ["this ", {
30
+ tag: "span",
31
+ html_id: "1",
32
+ items: ["is"],
33
+ props: {
34
+ "family" => "Lucida",
35
+ "size" => 13,
36
+ "stroke" => "#FF00FF",
37
+ "fill" => "#0000FF"
38
+ }
39
+ }, " text"]))
28
40
  end
29
41
 
30
- def test_code_simple
31
- assert_equal %{<code>Hello</code>}, @calzini.render("code", {}) { "Hello" }
42
+ def test_link_with_has_block
43
+ assert_equal %{this <a onclick="handle('click')">is</a> text},
44
+ trim_html_ids(@calzini.render("text_drawable",
45
+ ["this ", {
46
+ tag: "a",
47
+ html_id: "1",
48
+ items: ["is"],
49
+ props: {
50
+ "has_block" => true,
51
+ }
52
+ }, " text"]))
32
53
  end
33
54
 
34
- def test_em_simple
35
- assert_equal %{<em>Hello</em>}, @calzini.render("em", {}) { "Hello" }
55
+ def test_link_with_click
56
+ assert_equal %{this <a href="#" onclick="handle('click')">is</a> text},
57
+ trim_html_ids(@calzini.render("text_drawable",
58
+ ["this ", {
59
+ tag: "a",
60
+ html_id: "1",
61
+ items: ["is"],
62
+ props: {
63
+ "has_block" => true,
64
+ "click" => "#",
65
+ }
66
+ }, " text"]))
36
67
  end
37
68
 
38
- def test_strong_simple
39
- assert_equal %{<strong>Hello</strong>}, @calzini.render("strong", {}) { "Hello" }
69
+ def test_del_tag
70
+ assert_equal %{this <del>is</del> text},
71
+ trim_html_ids(@calzini.render("text_drawable",
72
+ ["this ", {
73
+ tag: "del",
74
+ html_id: "1",
75
+ items: ["is"],
76
+ props: {
77
+ }
78
+ }, " text"]))
79
+ end
80
+
81
+ def test_single_strikethrough
82
+ assert_equal %{this <span style="text-decoration-line:line-through">is</span> text},
83
+ trim_html_ids(@calzini.render("text_drawable",
84
+ ["this ", {
85
+ tag: "span",
86
+ html_id: "1",
87
+ items: ["is"],
88
+ props: {
89
+ "strikethrough" => "single",
90
+ }
91
+ }, " text"]))
92
+ end
93
+
94
+ def test_single_strikethrough_none
95
+ assert_equal %{this <span>is</span> text},
96
+ trim_html_ids(@calzini.render("text_drawable",
97
+ ["this ", {
98
+ tag: "span",
99
+ html_id: "1",
100
+ items: ["is"],
101
+ props: {
102
+ "strikethrough" => "none",
103
+ }
104
+ }, " text"]))
40
105
  end
41
106
  end
@@ -0,0 +1,133 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../test_helper"
4
+
5
+ # Some tests don't cover just a single drawable.
6
+ class TestVariousCalzini < Minitest::Test
7
+ def setup
8
+ @calzini = CalziniRenderer.new
9
+ end
10
+
11
+ # Test data. For each drawable, include
12
+ # a minimal set of properties to create something
13
+ # basic and default. Then we can add to it and
14
+ # test the resulting HTML.
15
+ #
16
+ # In Shoes3, the vast majority of drawables support
17
+ # both stroke and fill. Here's the list from the
18
+ # Shoes manual minus the ones we already test here:
19
+ #
20
+ # background, banner, caption,
21
+ # code, del, em, flow, image, ins, inscription,
22
+ # link, mask, para, shape, span, stack,
23
+ # strong, sub, sup, subtitle, tagline, title
24
+ #
25
+ # Scarpe doesn't yet support the property on everything.
26
+ # but as we support it, we should add the drawables
27
+ # here.
28
+ #
29
+ CALZINI_ART_DRAWABLES = {
30
+ arc: {
31
+ has_stroke: false,
32
+ has_fill: false,
33
+ props: {
34
+ "width" => 200,
35
+ "height" => 150,
36
+ "left" => 17,
37
+ "top" => 42,
38
+ "angle1" => 3.14 / 2,
39
+ "angle2" => 3.14 / 4,
40
+ },
41
+ },
42
+ arrow: {
43
+ has_stroke: true,
44
+ has_fill: true,
45
+ props: {
46
+ "left" => 10,
47
+ "top" => 20,
48
+ "width" => 5,
49
+ },
50
+ },
51
+ line: {
52
+ has_stroke: true,
53
+ has_fill: false,
54
+ props: {
55
+ "top" => "4",
56
+ "left" => "7",
57
+ "x1" => "20",
58
+ "y1" => "17",
59
+ "x2" => "100",
60
+ "y2" => "104",
61
+ },
62
+ },
63
+ rect: {
64
+ has_stroke: true,
65
+ has_fill: true,
66
+ props: {
67
+ "top" => "9",
68
+ "left" => "12",
69
+ "width" => "147",
70
+ "height" => "91",
71
+ "draw_context" => {},
72
+ },
73
+ },
74
+ star: {
75
+ has_stroke: true,
76
+ has_fill: true,
77
+ props: {
78
+ "points" => 5,
79
+ "outer" => 2.0,
80
+ "inner" => 1.0,
81
+ },
82
+ },
83
+ oval: {
84
+ has_stroke: true,
85
+ has_fill: true,
86
+ props: {
87
+ "left" => 10,
88
+ "top" => 7,
89
+ "radius" => 5,
90
+ },
91
+ },
92
+ }
93
+
94
+ # This method tests some basic ways of setting strokes and fills and makes sure they
95
+ # work for different drawables. TODO: add more drawables. TODO: either add testing for
96
+ # setting stroke and fill directly vs. draw-context, or remove draw-context.
97
+ def test_color_conversion
98
+ CALZINI_ART_DRAWABLES.each do |name, h|
99
+ basic = @calzini.render(name.to_s, h[:props])
100
+ assert !basic.include?("#FF0000"), "Un-colored #{name} shouldn't already have red or we'll get a false positive!"
101
+
102
+ if h[:has_stroke]
103
+ red_stroke = @calzini.render(name.to_s, h[:props].merge("stroke" => [255, 0, 0, 255]))
104
+ assert_includes red_stroke, "#FF0000", "With integer-array red stroke, #{name} should contain red color!"
105
+
106
+ red_stroke = @calzini.render(name.to_s, h[:props].merge("draw_context" => { "stroke" => [255, 0, 0, 255] }))
107
+ assert_includes red_stroke, "#FF0000", "With integer-array red stroke, #{name} should contain red color!"
108
+
109
+ red_stroke = @calzini.render(name.to_s, h[:props].merge("stroke" => [255, 0, 0, 255], "draw_context" => { "stroke" => [0, 255, 0, 255] }))
110
+ assert_includes red_stroke, "#FF0000", "Red stroke should take precedence over green, #{name} should contain red color!"
111
+
112
+ # TODO: later, after issue #504 is fixed, colors should turn into their hex equivalent
113
+ red_stroke = @calzini.render(name.to_s, h[:props].merge("stroke" => "red"))
114
+ assert_includes red_stroke, "red", "With integer-array red stroke, #{name} should contain red color!"
115
+ end
116
+
117
+ if h[:has_fill]
118
+ red_fill = @calzini.render(name.to_s, h[:props].merge("fill" => [255, 0, 0, 255]))
119
+ assert_includes red_fill, "#FF0000", "With integer-array red fill, #{name} should contain red color!"
120
+
121
+ red_fill = @calzini.render(name.to_s, h[:props].merge("draw_context" => { "fill" => [255, 0, 0, 255] }))
122
+ assert_includes red_fill, "#FF0000", "With integer-array red fill, #{name} should contain red color!"
123
+
124
+ red_fill = @calzini.render(name.to_s, h[:props].merge("fill" => [255, 0, 0, 255], "draw_context" => { "fill" => [0, 255, 0, 255] }))
125
+ assert_includes red_fill, "#FF0000", "Red fill should take precedence over green, #{name} should contain red color!"
126
+
127
+ # TODO: later, after issue #504 is fixed, colors should turn into their hex equivalent
128
+ red_fill = @calzini.render(name.to_s, h[:props].merge("fill" => "red"))
129
+ assert_includes red_fill, "red", "With integer-array red fill, #{name} should contain red color!"
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "test_helper"
4
+
5
+ require "scarpe/components/asset_server"
6
+
7
+ class TestAssetServer < Minitest::Test
8
+ def teardown
9
+ @server = nil # Don't keep the same server object from run to run, just in case
10
+ end
11
+
12
+ def fake_server
13
+ # We don't need to check HTTP connections, we just want to generate URLs
14
+ @server ||= Scarpe::Components::AssetServer.new port: 4444, app_dir: __dir__, never_start_server: true
15
+ end
16
+
17
+ def weird_dir_server
18
+ # Use a deeper app root to test files outside the app's directory
19
+ @server ||= Scarpe::Components::AssetServer.new port: 4444, app_dir: "#{__dir__}/subdir", never_start_server: true
20
+ end
21
+
22
+ def test_small_image_explicit_data_url
23
+ url = fake_server.asset_url("#{__dir__}/assets/little-image.png", url_type: :data)
24
+ assert url.start_with?("data:image/png;base64,"), "Data URL for image should start with image/png! #{url.inspect}"
25
+ end
26
+
27
+ def test_small_css_explicit_data_url
28
+ url = fake_server.asset_url("#{__dir__}/assets/little-stylesheet.css", url_type: :data)
29
+ assert url.start_with?("data:text/css;base64,"), "Data URL for CSS should start with text/css! #{url.inspect}"
30
+ end
31
+
32
+ def test_small_css_auto_data_url
33
+ url = fake_server.asset_url("#{__dir__}/assets/little-stylesheet.css")
34
+ assert url.start_with?("data:text/css;base64,"), "Small CSS files should get a data URL by default! #{url.inspect}"
35
+ end
36
+
37
+ def test_small_css_explicit_app_dir_asset_url
38
+ url = fake_server.asset_url("#{__dir__}/assets/little-stylesheet.css", url_type: :asset)
39
+ assert_equal "http://127.0.0.1:4444/app/assets/little-stylesheet.css", url, "Small CSS files should get an asset URL by request!"
40
+ end
41
+
42
+ def test_small_css_explicit_component_asset_url
43
+ url = weird_dir_server.asset_url("#{__dir__}/assets/little-stylesheet.css", url_type: :asset)
44
+ assert_equal "http://127.0.0.1:4444/comp/test/assets/little-stylesheet.css", url, "Small CSS files should get an asset URL by request!"
45
+ end
46
+
47
+ def test_large_app_file_auto_asset_url
48
+ url = fake_server.asset_url("#{__dir__}/assets/big-image.png")
49
+ assert_equal "http://127.0.0.1:4444/app/assets/big-image.png", url, "Big image files should get an asset URL by default!"
50
+ end
51
+
52
+ def test_large_app_file_explicit_asset_url
53
+ url = fake_server.asset_url("#{__dir__}/assets/big-image.png", url_type: :asset)
54
+ assert_equal "http://127.0.0.1:4444/app/assets/big-image.png", url, "Big image files should get an asset URL by default!"
55
+ end
56
+
57
+ def test_large_app_file_explicit_data_url
58
+ url = fake_server.asset_url("#{__dir__}/assets/big-image.png", url_type: :data)
59
+ assert url.start_with?("data:image/png;base64,"), "Big image files should get a data URL by request! #{url.inspect}"
60
+ end
61
+
62
+ def test_large_file_outside_dirs
63
+ url = fake_server.asset_url("#{__dir__}/../../docs/static/man-builds.png")
64
+ assert url.start_with?("data:image/png;base64,"), "Large files outside dirs should still use data URLs"
65
+ end
66
+
67
+ def test_large_file_outside_dirs_with_exception
68
+ assert_raises Scarpe::OperationNotAllowedError do
69
+ url = fake_server.asset_url("#{__dir__}/../../docs/static/man-builds.png", url_type: :asset)
70
+ end
71
+ end
72
+ end
@@ -3,7 +3,36 @@
3
3
  require_relative "test_helper"
4
4
 
5
5
  class TestScarpeComponents < Minitest::Test
6
- def test_truth
7
- assert_equal true, true
6
+ # Top-level tests go here?
7
+ end
8
+
9
+ require "scarpe/components/process_helpers"
10
+ class TestComponentHelpers < Minitest::Test
11
+ include Scarpe::Components::ProcessHelpers
12
+
13
+ def test_process_runner_stdout
14
+ out, err, success = run_out_err_result("echo ok")
15
+ assert success, "Echoing okay should succeed!"
16
+ assert_equal "", err
17
+ assert_includes out, "ok"
18
+ end
19
+
20
+ def test_process_runner_stderr
21
+ out, err, success = run_out_err_result("echo ok 1>&2")
22
+ assert success, "Echoing okay to stderr should succeed!"
23
+ assert_equal "", out
24
+ assert_includes err, "ok"
25
+ end
26
+
27
+ def test_process_runner_fail
28
+ out, err, success = run_out_err_result("ls no_such_file_exists")
29
+ assert !success, "ls on nonexistent file should return failure!"
30
+ assert_equal "", out
31
+ assert err != "", "ls on nonexistent file should give non-empty error output"
32
+ end
33
+
34
+ def test_process_runner_command_array
35
+ out, err, success = run_out_err_result(["echo", "ok"])
36
+ assert success, "Echoing okay via command array should succeed!"
8
37
  end
9
38
  end
@@ -39,5 +39,4 @@ class CalziniRenderer
39
39
  end
40
40
 
41
41
  class Minitest::Test
42
- include Scarpe::Test::Helpers
43
42
  end
@@ -58,4 +58,11 @@ class TestMinitestResult < Minitest::Test
58
58
  refute res.passed?
59
59
  assert_equal "Just skipping", res.skip_message
60
60
  end
61
+
62
+ def test_mtr_console_summary
63
+ path = File.join __dir__, "mtr_data/skipped_w_msg.json"
64
+ res = Scarpe::Components::MinitestResult.new(path)
65
+
66
+ assert res.console_summary.include?("Skip:")
67
+ end
61
68
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "test_helper"
4
+
5
+ require "scarpe/components/port_helpers"
6
+ class TestPortHelpers < Minitest::Test
7
+ include Scarpe::Components::PortHelpers
8
+
9
+ def test_port_finder
10
+ assert_equal false, port_working?("127.0.0.1", 9832), "Port 9832 should be unused!"
11
+ end
12
+ end
@@ -7,6 +7,8 @@ require "scarpe/components/segmented_file_loader"
7
7
  SEG_TEST_DATA = {}
8
8
 
9
9
  class TestSegmentedAppFiles < Minitest::Test
10
+ include Scarpe::Test::Helpers
11
+
10
12
  def setup
11
13
  @orig_file_loaders = Shoes.file_loaders
12
14
  Shoes.reset_file_loaders # create new loaders array with no overlap with @orig_file_loaders