scriptorium 0.0.3 → 0.6.1

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 (292) hide show
  1. checksums.yaml +4 -4
  2. data/README.lt3 +324 -0
  3. data/README.md +3155 -1
  4. data/assets/.DS_Store +0 -0
  5. data/assets/README.md +44 -0
  6. data/assets/back-icon.png +0 -0
  7. data/assets/icons/facebook.svg +1 -0
  8. data/assets/icons/github.svg +1 -0
  9. data/assets/icons/instagram.svg +1 -0
  10. data/assets/icons/reddit.svg +1 -0
  11. data/assets/icons/ui/.DS_Store +0 -0
  12. data/assets/icons/ui/back.png +0 -0
  13. data/assets/icons/ui/copy.png +0 -0
  14. data/assets/icons/ui/down.png +0 -0
  15. data/assets/icons/ui/end.png +0 -0
  16. data/assets/icons/ui/exit.png +0 -0
  17. data/assets/icons/ui/foo +10 -0
  18. data/assets/icons/ui/home.png +0 -0
  19. data/assets/icons/ui/left.png +0 -0
  20. data/assets/icons/ui/next.png +0 -0
  21. data/assets/icons/ui/right.png +0 -0
  22. data/assets/icons/ui/start.png +0 -0
  23. data/assets/icons/ui/up.png +0 -0
  24. data/assets/icons/x.svg +1 -0
  25. data/assets/icons/youtube.svg +1 -0
  26. data/assets/samples/placeholder.svg +9 -0
  27. data/assets/themes/standard/favicon.svg +6 -0
  28. data/bin/scriptorium +1511 -0
  29. data/doc/README.txt +6 -0
  30. data/doc/anti-amnesia/20250727-054000-scriptorium-overview.md +95 -0
  31. data/doc/anti-amnesia/20250727-060000-api-design-tui-planning.md +34 -0
  32. data/doc/anti-amnesia/20250727-061000-runeblog-tui-analysis.md +50 -0
  33. data/doc/anti-amnesia/20250727-123000-anti-amnesia-conventions.md +31 -0
  34. data/doc/anti-amnesia/20250727-154000-livetext-plugin-file-stats.md +73 -0
  35. data/doc/anti-amnesia/20250727-172600-cursor-rbenv-ruby-version-mystery.md +64 -0
  36. data/doc/anti-amnesia/20250727-172600-unified-minitest-framework.md +70 -0
  37. data/doc/anti-amnesia/20250727-172900-ai-cognitive-assessment-capabilities.md +40 -0
  38. data/doc/anti-amnesia/20250727-173000-widget-testing-achievement.md +110 -0
  39. data/doc/anti-amnesia/20250727-180000-post-id-num-refactoring.md +73 -0
  40. data/doc/anti-amnesia/20250728-124243-aaa-syntax-clarification.md +46 -0
  41. data/doc/anti-amnesia/20250728-124421-conversation-summary-concise.md +124 -0
  42. data/doc/anti-amnesia/20250729-190000-scriptorium-tui-testing-complete.md +46 -0
  43. data/doc/anti-amnesia/20250729-200000-scriptorium-tui-testing-edit-file-workflow.md +97 -0
  44. data/doc/anti-amnesia/20250729-210000-reddit-autopost-integration-complete.md +158 -0
  45. data/doc/anti-amnesia/20250729-211500-dependency-management-system.md +211 -0
  46. data/doc/anti-amnesia/20250729-213000-python-virtual-environment-setup.md +141 -0
  47. data/doc/anti-amnesia/20250729-214500-theme-management-commands.md +211 -0
  48. data/doc/anti-amnesia/20250729-215000-version-update-to-0.6.0.md +134 -0
  49. data/doc/anti-amnesia/20250729-220000-user-guide-complete.md +41 -0
  50. data/doc/anti-amnesia/20250804-190500-cognitive-loop-bug.md +45 -0
  51. data/doc/anti-amnesia/20250804-190700-anti-amnesia-timestamping-fix.md +30 -0
  52. data/doc/anti-amnesia/20250804-213700-publishing-test-fix.md +49 -0
  53. data/doc/anti-amnesia/20250804-214400-additional-test-fixes.md +46 -0
  54. data/doc/anti-amnesia/20250804-220000-asset-function-logic-clarification.md +41 -0
  55. data/doc/anti-amnesia/20250806-202032-asset-function-logic-clarification.md +41 -0
  56. data/doc/anti-amnesia/20250807-213025.md +116 -0
  57. data/doc/anti-amnesia/20250813-082428-syntax-highlighting-and-navigation-improvements.md +256 -0
  58. data/doc/banner_svg_config.md +114 -0
  59. data/doc/contrib.lt3 +8 -0
  60. data/doc/dependencies.md +281 -0
  61. data/doc/hacker.lt3 +5 -0
  62. data/doc/reddit_credentials_template.json +8 -0
  63. data/doc/reddit_integration.md +207 -0
  64. data/doc/user.lt3 +38 -0
  65. data/doc/user_guide_section_1.md +137 -0
  66. data/doc/user_guide_section_10.md +515 -0
  67. data/doc/user_guide_section_11.md +708 -0
  68. data/doc/user_guide_section_2.md +233 -0
  69. data/doc/user_guide_section_3.md +5 -0
  70. data/doc/user_guide_section_4.md +221 -0
  71. data/doc/user_guide_section_5.md +243 -0
  72. data/doc/user_guide_section_6.md +147 -0
  73. data/doc/user_guide_section_7.md +311 -0
  74. data/doc/user_guide_section_8.md +224 -0
  75. data/doc/user_guide_section_9.md +375 -0
  76. data/doc/userdoc-toc.txt +88 -0
  77. data/lib/rouge/lexers/livetext.rb +74 -0
  78. data/lib/scriptorium/api.rb +640 -0
  79. data/lib/scriptorium/banner_svg.rb +742 -0
  80. data/lib/scriptorium/contract.rb +33 -0
  81. data/lib/scriptorium/exceptions.rb +170 -1
  82. data/lib/scriptorium/helpers.rb +475 -0
  83. data/lib/scriptorium/post.rb +195 -0
  84. data/lib/scriptorium/reddit.rb +83 -0
  85. data/lib/scriptorium/repo.rb +624 -0
  86. data/lib/scriptorium/standard_files.rb +515 -0
  87. data/lib/scriptorium/syntax_highlighter.rb +234 -0
  88. data/lib/scriptorium/theme.rb +179 -0
  89. data/lib/scriptorium/version.rb +2 -2
  90. data/lib/scriptorium/view.rb +976 -0
  91. data/lib/scriptorium/widgets/featured_posts.rb +149 -0
  92. data/lib/scriptorium/widgets/links.rb +112 -0
  93. data/lib/scriptorium/widgets/pages.rb +133 -0
  94. data/lib/scriptorium/widgets/widget.rb +133 -0
  95. data/lib/scriptorium.rb +21 -40
  96. data/lib/skeleton.rb +8 -2
  97. data/scriptorium.gemspec +15 -4
  98. data/test/README.md +69 -0
  99. data/test/all +43 -0
  100. data/test/api_demo.rb +99 -0
  101. data/test/assets/imagenotfound.jpg +0 -0
  102. data/test/assets/images/.DS_Store +0 -0
  103. data/test/assets/images/README.md +27 -0
  104. data/test/assets/images/odd_aspect.png +0 -0
  105. data/test/assets/images/perfect.png +0 -0
  106. data/test/assets/images/small.png +0 -0
  107. data/test/assets/images/tall.png +0 -0
  108. data/test/assets/images/very_tall.png +0 -0
  109. data/test/assets/images/very_wide.png +0 -0
  110. data/test/assets/images/wide.png +0 -0
  111. data/test/assets/testbanner.jpg +0 -0
  112. data/test/banner_svg/simple_helpers.rb +13 -0
  113. data/test/banner_svg/unit.rb +768 -0
  114. data/test/ed_test.rb +204 -0
  115. data/test/integration/cursor_banner_combinations.rb +193 -0
  116. data/test/integration/cursor_banner_features.rb +374 -0
  117. data/test/integration/integration_test.rb +326 -0
  118. data/test/livetext_plugin_test.rb +229 -0
  119. data/test/manual/asset_mgmt.rb +67 -0
  120. data/test/manual/banner-tests/config.txt +3 -0
  121. data/test/manual/banner-tests/index.html +45 -0
  122. data/test/manual/banner-tests/test01.html +58 -0
  123. data/test/manual/banner-tests/test02.html +58 -0
  124. data/test/manual/banner-tests/test03.html +58 -0
  125. data/test/manual/banner-tests/test04.html +65 -0
  126. data/test/manual/banner-tests/test05.html +65 -0
  127. data/test/manual/banner-tests/test06.html +65 -0
  128. data/test/manual/banner-tests/test07.html +65 -0
  129. data/test/manual/banner-tests/test08.html +59 -0
  130. data/test/manual/banner-tests/test09.html +59 -0
  131. data/test/manual/banner-tests/test10.html +59 -0
  132. data/test/manual/banner-tests/test11.html +59 -0
  133. data/test/manual/banner-tests/test12.html +59 -0
  134. data/test/manual/banner-tests/test13.html +59 -0
  135. data/test/manual/banner-tests/test14.html +59 -0
  136. data/test/manual/banner-tests/test15.html +58 -0
  137. data/test/manual/banner-tests/test16.html +58 -0
  138. data/test/manual/banner-tests/test17.html +58 -0
  139. data/test/manual/banner-tests/test18.html +68 -0
  140. data/test/manual/banner-tests/test19.html +68 -0
  141. data/test/manual/banner-tests/test20.html +68 -0
  142. data/test/manual/banner-tests/test21.html +68 -0
  143. data/test/manual/banner-tests/test22.html +68 -0
  144. data/test/manual/banner-tests/test23.html +68 -0
  145. data/test/manual/banner-tests/test24.html +68 -0
  146. data/test/manual/banner-tests/test25.html +67 -0
  147. data/test/manual/banner_environment.rb +192 -0
  148. data/test/manual/deploy_symlink_demo.rb +142 -0
  149. data/test/manual/environment.rb +67 -0
  150. data/test/manual/make_banner.rb +153 -0
  151. data/test/manual/sample_banner_config.txt +12 -0
  152. data/test/manual/symlink_demo.rb +117 -0
  153. data/test/manual/test1.rb +47 -0
  154. data/test/manual/test2.rb +12 -0
  155. data/test/manual/test3.rb +38 -0
  156. data/test/manual/test4.rb +40 -0
  157. data/test/manual/test5.rb +24 -0
  158. data/test/manual/test6.rb +73 -0
  159. data/test/manual/test_banner_combinations.rb +120 -0
  160. data/test/manual/test_banner_features.rb +306 -0
  161. data/test/manual/test_banner_from_file.rb +150 -0
  162. data/test/manual/test_banner_in_header.rb +35 -0
  163. data/test/manual/test_code_highlighting.rb +68 -0
  164. data/test/manual/test_complex_header.rb +74 -0
  165. data/test/manual/test_empty_header.rb +32 -0
  166. data/test/manual/test_radial_custom.rb +58 -0
  167. data/test/manual/test_radial_large_radius.rb +52 -0
  168. data/test/manual/test_svg_debug.rb +47 -0
  169. data/test/manual/test_syntax_highlighting.rb +147 -0
  170. data/test/pages-demo/config/currentview.txt +1 -0
  171. data/test/pages-demo/views/demo/config/bootstrap_css.txt +5 -0
  172. data/test/pages-demo/views/demo/config/bootstrap_js.txt +4 -0
  173. data/test/pages-demo/views/demo/config/common.js +57 -0
  174. data/test/pages-demo/views/demo/config/footer.txt +1 -0
  175. data/test/pages-demo/views/demo/config/global-head.txt +8 -0
  176. data/test/pages-demo/views/demo/config/header.txt +1 -0
  177. data/test/pages-demo/views/demo/config/layout.txt +1 -0
  178. data/test/pages-demo/views/demo/config/left.txt +1 -0
  179. data/test/pages-demo/views/demo/config/main.txt +1 -0
  180. data/test/pages-demo/views/demo/config/right.txt +1 -0
  181. data/test/pages-demo/views/demo/config.txt +3 -0
  182. data/test/pages-demo/views/demo/output/panes/footer.html +1 -0
  183. data/test/pages-demo/views/demo/output/panes/header.html +1 -0
  184. data/test/pages-demo/views/demo/output/panes/left.html +1 -0
  185. data/test/pages-demo/views/demo/output/panes/main.html +1 -0
  186. data/test/pages-demo/views/demo/output/panes/right.html +1 -0
  187. data/test/rubytext/rubytext_comprehensive_test.rb +307 -0
  188. data/test/rubytext/rubytext_demo_test.rb +42 -0
  189. data/test/rubytext/rubytext_testing_guide.md +277 -0
  190. data/test/run_automated_tests.rb +45 -0
  191. data/test/scriptorium-TEST-1754622690-146/config/bootstrap_css.txt +5 -0
  192. data/test/scriptorium-TEST-1754622690-146/config/bootstrap_js.txt +4 -0
  193. data/test/scriptorium-TEST-1754622690-146/config/common.js +57 -0
  194. data/test/scriptorium-TEST-1754622690-146/config/currentview.txt +1 -0
  195. data/test/scriptorium-TEST-1754622690-146/config/global-head.txt +9 -0
  196. data/test/scriptorium-TEST-1754622690-146/config/last_post_num.txt +1 -0
  197. data/test/scriptorium-TEST-1754622690-146/config/os_helpers.rb +4 -0
  198. data/test/scriptorium-TEST-1754622690-146/config/widgets.txt +3 -0
  199. data/test/scriptorium-TEST-1754622690-146/posts/0001/meta.txt +8 -0
  200. data/test/scriptorium-TEST-1754622690-146/posts/0001/source.lt3 +6 -0
  201. data/test/scriptorium-TEST-1754622690-146/themes/standard/README.txt +1 -0
  202. data/test/scriptorium-TEST-1754622690-146/themes/standard/config.txt +1 -0
  203. data/test/scriptorium-TEST-1754622690-146/themes/standard/initial/post.lt3 +12 -0
  204. data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/footer.txt +2 -0
  205. data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/header.txt +4 -0
  206. data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/left.txt +3 -0
  207. data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/main.txt +5 -0
  208. data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/right.txt +3 -0
  209. data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/gen/text.css +1 -0
  210. data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/layout.txt +5 -0
  211. data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/index.lt3 +1 -0
  212. data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/index_entry.lt3 +14 -0
  213. data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/post.lt3 +13 -0
  214. data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/widget.lt3 +1 -0
  215. data/test/scriptorium-TEST-1754622690-146/views/sample/config/bootstrap_css.txt +5 -0
  216. data/test/scriptorium-TEST-1754622690-146/views/sample/config/bootstrap_js.txt +4 -0
  217. data/test/scriptorium-TEST-1754622690-146/views/sample/config/common.js +57 -0
  218. data/test/scriptorium-TEST-1754622690-146/views/sample/config/deploy.txt +5 -0
  219. data/test/scriptorium-TEST-1754622690-146/views/sample/config/footer.txt +2 -0
  220. data/test/scriptorium-TEST-1754622690-146/views/sample/config/global-head.txt +9 -0
  221. data/test/scriptorium-TEST-1754622690-146/views/sample/config/header.txt +4 -0
  222. data/test/scriptorium-TEST-1754622690-146/views/sample/config/layout.txt +5 -0
  223. data/test/scriptorium-TEST-1754622690-146/views/sample/config/left.txt +3 -0
  224. data/test/scriptorium-TEST-1754622690-146/views/sample/config/main.txt +5 -0
  225. data/test/scriptorium-TEST-1754622690-146/views/sample/config/reddit.txt +10 -0
  226. data/test/scriptorium-TEST-1754622690-146/views/sample/config/right.txt +3 -0
  227. data/test/scriptorium-TEST-1754622690-146/views/sample/config/social.txt +7 -0
  228. data/test/scriptorium-TEST-1754622690-146/views/sample/config/status.txt +7 -0
  229. data/test/scriptorium-TEST-1754622690-146/views/sample/config.txt +3 -0
  230. data/test/scriptorium-TEST-1754622690-146/views/sample/layout/footer.html +3 -0
  231. data/test/scriptorium-TEST-1754622690-146/views/sample/layout/header.html +3 -0
  232. data/test/scriptorium-TEST-1754622690-146/views/sample/layout/left.html +3 -0
  233. data/test/scriptorium-TEST-1754622690-146/views/sample/layout/main.html +3 -0
  234. data/test/scriptorium-TEST-1754622690-146/views/sample/layout/right.html +3 -0
  235. data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/footer.html +1 -0
  236. data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/header.html +1 -0
  237. data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/left.html +1 -0
  238. data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/main.html +1 -0
  239. data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/right.html +1 -0
  240. data/test/staging/.DS_Store +0 -0
  241. data/test/syntax_highlighting_test.lt3 +124 -0
  242. data/test/test_helpers.rb +230 -0
  243. data/test/tui_editor_integration_test.rb +296 -0
  244. data/test/tui_integration_test.rb +637 -0
  245. data/test/unit/api.rb +1056 -0
  246. data/test/unit/asset_management.rb +245 -0
  247. data/test/unit/clipboard_test.rb +60 -0
  248. data/test/unit/contract_test.rb +91 -0
  249. data/test/unit/core.rb +857 -0
  250. data/test/unit/deploy_test.rb +187 -0
  251. data/test/unit/gem_asset_management.rb +189 -0
  252. data/test/unit/livetext_basic.rb +69 -0
  253. data/test/unit/livetext_compatibility.rb +89 -0
  254. data/test/unit/post.rb +244 -0
  255. data/test/unit/read_commented_file_test.rb +276 -0
  256. data/test/unit/reddit_test.rb +235 -0
  257. data/test/unit/repo.rb +548 -0
  258. data/test/unit/social_test.rb +369 -0
  259. data/test/unit/symlink_test.rb +213 -0
  260. data/test/unit/view.rb +431 -0
  261. data/test/unit/widgets.rb +669 -0
  262. data/test/wizard_test.rb +123 -0
  263. data/ui/README.md +67 -0
  264. data/ui/common/lib/ui_common.rb +8 -0
  265. data/ui/rubytext/README.md +191 -0
  266. data/ui/rubytext/bin/scriptorium-rubytext +402 -0
  267. data/ui/rubytext/lib/rubytext_ui.rb +300 -0
  268. data/ui/tui/bin/scriptorium +1420 -0
  269. data/ui/tui/test/tui_test.rb +23 -0
  270. data/ui/web/app/app.rb +1378 -0
  271. data/ui/web/app/error_helpers.rb +150 -0
  272. data/ui/web/app/views/advanced_config.erb +190 -0
  273. data/ui/web/app/views/asset_management.erb +589 -0
  274. data/ui/web/app/views/banner_config.erb +200 -0
  275. data/ui/web/app/views/configure_view.erb +401 -0
  276. data/ui/web/app/views/dashboard.erb +162 -0
  277. data/ui/web/app/views/deploy_config.erb +146 -0
  278. data/ui/web/app/views/edit_pages.erb +195 -0
  279. data/ui/web/app/views/edit_post.erb +54 -0
  280. data/ui/web/app/views/error_page.erb +29 -0
  281. data/ui/web/app/views/header_config.erb +155 -0
  282. data/ui/web/app/views/layout_config.erb +147 -0
  283. data/ui/web/app/views/navbar_config.erb +411 -0
  284. data/ui/web/app/views/view_dashboard.erb +138 -0
  285. data/ui/web/bin/scriptorium-web +153 -0
  286. data/ui/web/test/web_basic_test.rb +38 -0
  287. data/ui/web/test_navbar.txt +7 -0
  288. data/ui/web/tmp/web_server.log +5 -0
  289. data/ui/web/tmp/web_server.pid +1 -0
  290. metadata +359 -7
  291. data/lib/scriptorium/engine.rb +0 -22
  292. data/test/engine/unit.rb +0 -44
@@ -0,0 +1,57 @@
1
+ // Handle the back button (or JavaScript history.go(-1))
2
+ window.onpopstate = function(event) {
3
+ console.log('onpopstate event:', event); // Log the event object
4
+ if (event.state && event.state.slug) {
5
+ console.log('Navigating to slug:', event.state.slug); // Log the slug
6
+ load_main(event.state.slug); // Load the post for the previous history state
7
+ }
8
+ };
9
+
10
+ // Initialize with the front page when navigating via the back button or similar
11
+ window.onload = function() {
12
+ // Check if the initial state exists, if not, set it
13
+ if (!history.state) {
14
+ // Don't try to load post_index.html if there are no posts
15
+ // The "No posts yet!" message is already in the main container
16
+ history.replaceState({ slug: "index.html" }, "", "index.html");
17
+ }
18
+ };
19
+
20
+ // Load the main content and other page containers (header, footer, left, right)
21
+ function load_main(slug) {
22
+ // Get all container elements (header, footer, left, right, and main)
23
+ const contentDiv = document.getElementById("main");
24
+ const headerDiv = document.querySelector("header");
25
+ const footerDiv = document.querySelector("footer");
26
+ const leftDiv = document.querySelector(".left");
27
+ const rightDiv = document.querySelector(".right");
28
+ console.log('Loading main with slug:', slug); // Log the slug
29
+
30
+ fetch(slug)
31
+ .then(response => {
32
+ if (response.ok) {
33
+ console.log('Response is ok');
34
+ return response.text();
35
+ } else {
36
+ console.error('Failed to load:', response.status); // Log the failed response
37
+ }
38
+ })
39
+ .then(content => {
40
+ console.log('Loaded content into div'); // Log successful content insertion
41
+
42
+ // Now, reload the content into the respective containers:
43
+ // Main section
44
+ contentDiv.innerHTML = content;
45
+
46
+ // Re-insert header, footer, left, and right (if necessary)
47
+ // If you want the static layout to be kept, you can preserve these parts
48
+ // with additional logic or predefined structure (here it's assumed
49
+ // that header/footer/left/right are already statically included).
50
+
51
+ // You can also replace the other parts (left, right, header, footer) if needed.
52
+ history.pushState({slug: slug}, "", slug); // Update browser history
53
+ })
54
+ .catch(error => {
55
+ console.log("Error loading content:", error); // Log any errors during fetch
56
+ });
57
+ }
@@ -0,0 +1 @@
1
+ Empty file generated at 2025-07-28 14:13:03 -0500
@@ -0,0 +1,8 @@
1
+ # This view-specific file supplies the default values for this view.
2
+ # title is omitted - filled in at generation
3
+ charset UTF-8
4
+ desc A blog powered by Scriptorium. This is default text intended to be changed by the user.
5
+ viewport width=device-width initial-scale=1.0
6
+ robots index follow
7
+ javascript # See common.js
8
+ bootstrap # See bootstrap.txt
@@ -0,0 +1 @@
1
+ Empty file generated at 2025-07-28 14:13:03 -0500
@@ -0,0 +1 @@
1
+ Empty file generated at 2025-07-28 14:13:03 -0500
@@ -0,0 +1 @@
1
+ Empty file generated at 2025-07-28 14:13:03 -0500
@@ -0,0 +1 @@
1
+ Empty file generated at 2025-07-28 14:13:03 -0500
@@ -0,0 +1 @@
1
+ Empty file generated at 2025-07-28 14:13:03 -0500
@@ -0,0 +1,3 @@
1
+ title Demo View
2
+ subtitle Testing Pages Widget
3
+ theme standard
@@ -0,0 +1 @@
1
+ Empty file generated at 2025-07-28 14:13:03 -0500
@@ -0,0 +1 @@
1
+ Empty file generated at 2025-07-28 14:13:03 -0500
@@ -0,0 +1 @@
1
+ Empty file generated at 2025-07-28 14:13:03 -0500
@@ -0,0 +1 @@
1
+ Empty file generated at 2025-07-28 14:13:03 -0500
@@ -0,0 +1 @@
1
+ Empty file generated at 2025-07-28 14:13:03 -0500
@@ -0,0 +1,307 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'minitest/autorun'
4
+ require 'pty'
5
+ require 'expect'
6
+ require 'timeout'
7
+ require 'tempfile'
8
+
9
+ class RubyTextComprehensiveTest < Minitest::Test
10
+ # Test categories for RubyText
11
+
12
+ def test_001_basic_initialization
13
+ # Test that RubyText can start without errors
14
+ PTY.spawn('ruby -e "require \"rubytext\"; RubyText.start { puts \"Hello\"; gets }"') do |read, write, pid|
15
+ begin
16
+ # Wait for RubyText to start
17
+ result = read.expect(/Hello/, 5)
18
+ assert result, "RubyText should start and display 'Hello'"
19
+
20
+ # Send quit command
21
+ write.puts "q"
22
+ Process.wait(pid)
23
+ assert_equal 0, $?.exitstatus
24
+ ensure
25
+ Process.kill('TERM', pid) rescue nil
26
+ end
27
+ end
28
+ end
29
+
30
+ def test_002_menu_functionality
31
+ # Test menu creation and interaction
32
+ menu_script = <<~RUBY
33
+ require 'rubytext'
34
+ RubyText.start do
35
+ menu = RubyText::Menu.new(["Option 1", "Option 2", "Option 3"])
36
+ result = menu.show
37
+ puts "Selected: #{result}"
38
+ gets
39
+ end
40
+ RUBY
41
+
42
+ PTY.spawn("ruby -e \"#{menu_script}\"") do |read, write, pid|
43
+ begin
44
+ # Wait for menu to appear
45
+ read.expect(/Option 1/, 5)
46
+
47
+ # Navigate and select
48
+ write.puts "\e[B" # Down arrow
49
+ sleep 0.1
50
+ write.puts "\r" # Enter
51
+
52
+ # Check result
53
+ result = read.expect(/Selected: Option 2/, 5)
54
+ assert result, "Menu should return selected option"
55
+
56
+ write.puts "q"
57
+ Process.wait(pid)
58
+ ensure
59
+ Process.kill('TERM', pid) rescue nil
60
+ end
61
+ end
62
+ end
63
+
64
+ def test_003_screen_rendering
65
+ # Test screen rendering and layout
66
+ screen_script = <<~RUBY
67
+ require 'rubytext'
68
+ RubyText.start do
69
+ screen = RubyText::Screen.new(80, 24)
70
+ screen.puts("Test content")
71
+ screen.refresh
72
+ gets
73
+ end
74
+ RUBY
75
+
76
+ PTY.spawn("ruby -e \"#{screen_script}\"") do |read, write, pid|
77
+ begin
78
+ # Wait for content to appear
79
+ result = read.expect(/Test content/, 5)
80
+ assert result, "Screen should display content"
81
+
82
+ write.puts "q"
83
+ Process.wait(pid)
84
+ ensure
85
+ Process.kill('TERM', pid) rescue nil
86
+ end
87
+ end
88
+ end
89
+
90
+ def test_004_input_handling
91
+ # Test various input methods
92
+ input_script = <<~RUBY
93
+ require 'rubytext'
94
+ RubyText.start do
95
+ puts "Press any key..."
96
+ key = RubyText.getch
97
+ puts "Key pressed: #{key.inspect}"
98
+ gets
99
+ end
100
+ RUBY
101
+
102
+ PTY.spawn("ruby -e \"#{input_script}\"") do |read, write, pid|
103
+ begin
104
+ read.expect(/Press any key/, 5)
105
+
106
+ # Send a key
107
+ write.puts "a"
108
+
109
+ result = read.expect(/Key pressed/, 5)
110
+ assert result, "Should detect key press"
111
+
112
+ write.puts "q"
113
+ Process.wait(pid)
114
+ ensure
115
+ Process.kill('TERM', pid) rescue nil
116
+ end
117
+ end
118
+ end
119
+
120
+ def test_005_color_and_style
121
+ # Test color and style functionality
122
+ color_script = <<~RUBY
123
+ require 'rubytext'
124
+ RubyText.start do
125
+ RubyText.color(:red) { puts "Red text" }
126
+ RubyText.color(:blue) { puts "Blue text" }
127
+ RubyText.bold { puts "Bold text" }
128
+ gets
129
+ end
130
+ RUBY
131
+
132
+ PTY.spawn("ruby -e \"#{color_script}\"") do |read, write, pid|
133
+ begin
134
+ # Check for colored output (this might be hard to test in PTY)
135
+ result = read.expect(/Red text|Blue text|Bold text/, 5)
136
+ assert result, "Should display styled text"
137
+
138
+ write.puts "q"
139
+ Process.wait(pid)
140
+ ensure
141
+ Process.kill('TERM', pid) rescue nil
142
+ end
143
+ end
144
+ end
145
+
146
+ def test_006_window_management
147
+ # Test window creation and management
148
+ window_script = <<~RUBY
149
+ require 'rubytext'
150
+ RubyText.start do
151
+ window = RubyText::Window.new(10, 5, 5, 5)
152
+ window.puts("Window content")
153
+ window.refresh
154
+ gets
155
+ end
156
+ RUBY
157
+
158
+ PTY.spawn("ruby -e \"#{window_script}\"") do |read, write, pid|
159
+ begin
160
+ result = read.expect(/Window content/, 5)
161
+ assert result, "Window should display content"
162
+
163
+ write.puts "q"
164
+ Process.wait(pid)
165
+ ensure
166
+ Process.kill('TERM', pid) rescue nil
167
+ end
168
+ end
169
+ end
170
+
171
+ def test_007_error_handling
172
+ # Test error handling and recovery
173
+ error_script = <<~RUBY
174
+ require 'rubytext'
175
+ begin
176
+ RubyText.start do
177
+ # Try to do something that might cause an error
178
+ RubyText::Screen.new(-1, -1) # Invalid dimensions
179
+ end
180
+ rescue => e
181
+ puts "Error caught: #{e.class}"
182
+ exit 0
183
+ end
184
+ RUBY
185
+
186
+ PTY.spawn("ruby -e \"#{error_script}\"") do |read, write, pid|
187
+ begin
188
+ result = read.expect(/Error caught/, 5)
189
+ assert result, "Should handle errors gracefully"
190
+
191
+ Process.wait(pid)
192
+ assert_equal 0, $?.exitstatus
193
+ ensure
194
+ Process.kill('TERM', pid) rescue nil
195
+ end
196
+ end
197
+ end
198
+
199
+ def test_008_performance
200
+ # Test performance with large content
201
+ performance_script = <<~RUBY
202
+ require 'rubytext'
203
+ require 'benchmark'
204
+
205
+ RubyText.start do
206
+ time = Benchmark.measure do
207
+ 100.times do |i|
208
+ puts "Line #{i}: " + "x" * 50
209
+ end
210
+ end
211
+ puts "Rendering time: #{time.real}s"
212
+ gets
213
+ end
214
+ RUBY
215
+
216
+ PTY.spawn("ruby -e \"#{performance_script}\"") do |read, write, pid|
217
+ begin
218
+ result = read.expect(/Rendering time/, 10)
219
+ assert result, "Should complete performance test"
220
+
221
+ write.puts "q"
222
+ Process.wait(pid)
223
+ ensure
224
+ Process.kill('TERM', pid) rescue nil
225
+ end
226
+ end
227
+ end
228
+
229
+ def test_009_integration_scenarios
230
+ # Test real-world usage scenarios
231
+ scenarios = [
232
+ {
233
+ name: "Simple menu navigation",
234
+ script: <<~RUBY,
235
+ require 'rubytext'
236
+ RubyText.start do
237
+ menu = RubyText::Menu.new(["Edit", "View", "Quit"])
238
+ result = menu.show
239
+ puts "Selected: #{result}"
240
+ gets
241
+ end
242
+ RUBY
243
+ expected: /Selected: (Edit|View|Quit)/
244
+ },
245
+ {
246
+ name: "Form input",
247
+ script: <<~RUBY,
248
+ require 'rubytext'
249
+ RubyText.start do
250
+ puts "Enter your name:"
251
+ name = gets.chomp
252
+ puts "Hello, #{name}!"
253
+ gets
254
+ end
255
+ RUBY
256
+ expected: /Hello, TestUser!/
257
+ }
258
+ ]
259
+
260
+ scenarios.each do |scenario|
261
+ PTY.spawn("ruby -e \"#{scenario[:script]}\"") do |read, write, pid|
262
+ begin
263
+ # Wait for prompt
264
+ read.expect(/Enter your name:|Menu/, 5)
265
+
266
+ # Send input
267
+ if scenario[:name].include?("menu")
268
+ write.puts "\r" # Select first option
269
+ else
270
+ write.puts "TestUser"
271
+ write.puts "\r"
272
+ end
273
+
274
+ # Check result
275
+ result = read.expect(scenario[:expected], 5)
276
+ assert result, "Scenario '#{scenario[:name]}' should work"
277
+
278
+ write.puts "q"
279
+ Process.wait(pid)
280
+ ensure
281
+ Process.kill('TERM', pid) rescue nil
282
+ end
283
+ end
284
+ end
285
+ end
286
+
287
+ private
288
+
289
+ def load_expected_screens
290
+ # Load expected screen states from fixtures
291
+ screens = []
292
+ fixture_dir = "test/fixtures/rubytext_screens"
293
+ if Dir.exist?(fixture_dir)
294
+ Dir.glob("#{fixture_dir}/*.txt").sort.each do |file|
295
+ screens << File.read(file)
296
+ end
297
+ end
298
+ screens
299
+ end
300
+
301
+ def capture_current_screens
302
+ # Capture current screen states for comparison
303
+ screens = []
304
+ # Implementation would depend on RubyText's screen capture capabilities
305
+ screens
306
+ end
307
+ end
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'minitest/autorun'
4
+ require 'pty'
5
+ require 'expect'
6
+ require 'timeout'
7
+
8
+ class RubyTextDemoTest < Minitest::Test
9
+ # Test the demo/slideshow functionality
10
+ def test_001_demo_automation
11
+ # Run the demo in automated mode
12
+ PTY.spawn('ruby -e "require \"rubytext\"; RubyText.start { demo_mode }"') do |read, write, pid|
13
+ begin
14
+ # Wait for demo to start
15
+ read.expect(/Demo/, 10)
16
+
17
+ # Send navigation commands
18
+ write.puts "n" # next slide
19
+ sleep 0.5
20
+ write.puts "n" # next slide
21
+ sleep 0.5
22
+ write.puts "q" # quit
23
+
24
+ # Should exit cleanly
25
+ Process.wait(pid)
26
+ assert_equal 0, $?.exitstatus
27
+ ensure
28
+ Process.kill('TERM', pid) rescue nil
29
+ end
30
+ end
31
+ end
32
+
33
+ def test_002_slideshow_regression
34
+ # Capture expected screen states and compare
35
+ expected_screens = load_expected_screens
36
+ current_screens = capture_current_screens
37
+
38
+ expected_screens.each_with_index do |expected, index|
39
+ assert_equal expected, current_screens[index], "Screen #{index} doesn't match expected"
40
+ end
41
+ end
42
+ end