scriptorium 0.6.1 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (358) hide show
  1. checksums.yaml +4 -4
  2. data/assets/icons/social/reddit.png +0 -0
  3. data/assets/icons/social/x-logo.png +0 -0
  4. data/assets/imagenotfound.jpg +0 -0
  5. data/bin/sblog +84 -5
  6. data/bin/scriptorium +1 -0
  7. data/doc/anti-amnesia/20250727-054000-scriptorium-overview.md +0 -1
  8. data/doc/anti-amnesia/20250727-123000-anti-amnesia-conventions.md +0 -29
  9. data/doc/anti-amnesia/20250727-172600-cursor-rbenv-ruby-version-mystery.md +0 -19
  10. data/doc/anti-amnesia/20250727-172900-ai-cognitive-assessment-capabilities.md +1 -1
  11. data/doc/anti-amnesia/20250728-124243-aaa-syntax-clarification.md +1 -1
  12. data/doc/anti-amnesia/20250729-210000-reddit-autopost-integration-complete.md +1 -1
  13. data/doc/anti-amnesia/20250804-190500-cognitive-loop-bug.md +0 -10
  14. data/doc/anti-amnesia/20250804-190700-anti-amnesia-timestamping-fix.md +1 -4
  15. data/doc/anti-amnesia/20250901-211714-codemirror-integration-and-web-tests.md +172 -0
  16. data/doc/anti-amnesia/20250902-002402-backup-restore-system.md +126 -0
  17. data/doc/anti-amnesia/20250907-203339-backup-metadata-implementation.md +66 -0
  18. data/doc/imported/0001-elixir-conf-2014/metadata.txt +7 -0
  19. data/doc/imported/0001-elixir-conf-2014/post.html +37 -0
  20. data/doc/imported/0001-elixir-conf-2014/source.lt3 +22 -0
  21. data/doc/imported/0002-programmers-and-word-processing/metadata.txt +7 -0
  22. data/doc/imported/0002-programmers-and-word-processing/post.html +192 -0
  23. data/doc/imported/0002-programmers-and-word-processing/source.lt3 +146 -0
  24. data/doc/imported/0003-how-to-turn-your-brain-sideways/metadata.txt +7 -0
  25. data/doc/imported/0003-how-to-turn-your-brain-sideways/post.html +60 -0
  26. data/doc/imported/0003-how-to-turn-your-brain-sideways/source.lt3 +40 -0
  27. data/doc/imported/0004-upcoming-lone-star-ruby-conference/metadata.txt +7 -0
  28. data/doc/imported/0004-upcoming-lone-star-ruby-conference/post.html +42 -0
  29. data/doc/imported/0004-upcoming-lone-star-ruby-conference/source.lt3 +24 -0
  30. data/doc/imported/0005-elixir-conf-2015-announced/metadata.txt +7 -0
  31. data/doc/imported/0005-elixir-conf-2015-announced/post.html +30 -0
  32. data/doc/imported/0005-elixir-conf-2015-announced/source.lt3 +16 -0
  33. data/doc/imported/0006-ruby-for-dinosaurs/metadata.txt +7 -0
  34. data/doc/imported/0006-ruby-for-dinosaurs/post.html +43 -0
  35. data/doc/imported/0006-ruby-for-dinosaurs/source.lt3 +27 -0
  36. data/doc/imported/0007-phoenix-isnt-rails/metadata.txt +7 -0
  37. data/doc/imported/0007-phoenix-isnt-rails/post.html +116 -0
  38. data/doc/imported/0007-phoenix-isnt-rails/source.lt3 +87 -0
  39. data/doc/imported/0008-concerning-the-term-monkeypatching/metadata.txt +7 -0
  40. data/doc/imported/0008-concerning-the-term-monkeypatching/post.html +129 -0
  41. data/doc/imported/0008-concerning-the-term-monkeypatching/source.lt3 +92 -0
  42. data/doc/imported/0009-announcement-coming-soon/metadata.txt +7 -0
  43. data/doc/imported/0009-announcement-coming-soon/post.html +33 -0
  44. data/doc/imported/0009-announcement-coming-soon/source.lt3 +19 -0
  45. data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/metadata.txt +7 -0
  46. data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/post.html +175 -0
  47. data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/source.lt3 +139 -0
  48. data/doc/imported/0011-computer-science-as-a-lost-art/metadata.txt +7 -0
  49. data/doc/imported/0011-computer-science-as-a-lost-art/post.html +139 -0
  50. data/doc/imported/0011-computer-science-as-a-lost-art/source.lt3 +104 -0
  51. data/doc/imported/0012-ruby-day-in-turin-italy/metadata.txt +7 -0
  52. data/doc/imported/0012-ruby-day-in-turin-italy/post.html +42 -0
  53. data/doc/imported/0012-ruby-day-in-turin-italy/source.lt3 +24 -0
  54. data/doc/imported/0013-rubyday-was-a-success/metadata.txt +7 -0
  55. data/doc/imported/0013-rubyday-was-a-success/post.html +44 -0
  56. data/doc/imported/0013-rubyday-was-a-success/source.lt3 +27 -0
  57. data/doc/imported/0014-working-on-the-blogging-software/metadata.txt +7 -0
  58. data/doc/imported/0014-working-on-the-blogging-software/post.html +63 -0
  59. data/doc/imported/0014-working-on-the-blogging-software/source.lt3 +41 -0
  60. data/doc/imported/0015-ok-its-not-really-a-lost-art/metadata.txt +7 -0
  61. data/doc/imported/0015-ok-its-not-really-a-lost-art/post.html +172 -0
  62. data/doc/imported/0015-ok-its-not-really-a-lost-art/source.lt3 +134 -0
  63. data/doc/imported/0016-an-in-operator-for-ruby/metadata.txt +7 -0
  64. data/doc/imported/0016-an-in-operator-for-ruby/post.html +155 -0
  65. data/doc/imported/0016-an-in-operator-for-ruby/source.lt3 +106 -0
  66. data/doc/imported/0017-the-forgotten-mathematician/metadata.txt +7 -0
  67. data/doc/imported/0017-the-forgotten-mathematician/post.html +161 -0
  68. data/doc/imported/0017-the-forgotten-mathematician/source.lt3 +119 -0
  69. data/doc/imported/0018-ruby-puns/metadata.txt +7 -0
  70. data/doc/imported/0018-ruby-puns/post.html +46 -0
  71. data/doc/imported/0018-ruby-puns/source.lt3 +28 -0
  72. data/doc/imported/0019-custom-exceptions-via-metaprogramming/metadata.txt +7 -0
  73. data/doc/imported/0019-custom-exceptions-via-metaprogramming/post.html +138 -0
  74. data/doc/imported/0019-custom-exceptions-via-metaprogramming/source.lt3 +101 -0
  75. data/doc/imported/0020-fffff/metadata.txt +7 -0
  76. data/doc/imported/0020-fffff/post.html +24 -0
  77. data/doc/imported/0020-fffff/source.lt3 +12 -0
  78. data/doc/imported/0021-trying-ror-yet-again/metadata.txt +7 -0
  79. data/doc/imported/0021-trying-ror-yet-again/post.html +26 -0
  80. data/doc/imported/0021-trying-ror-yet-again/source.lt3 +12 -0
  81. data/doc/imported/0023-doctor-sleep/metadata.txt +7 -0
  82. data/doc/imported/0023-doctor-sleep/post.html +63 -0
  83. data/doc/imported/0023-doctor-sleep/source.lt3 +44 -0
  84. data/doc/imported/0024-just-a-test/metadata.txt +7 -0
  85. data/doc/imported/0024-just-a-test/post.html +24 -0
  86. data/doc/imported/0024-just-a-test/source.lt3 +12 -0
  87. data/doc/imported/import_summary.txt +98 -0
  88. data/doc/livetext-informal-spec.txt +65 -0
  89. data/doc/myuserdoc/ch-0.lt3 +31 -0
  90. data/doc/myuserdoc/ch-1.lt3 +37 -0
  91. data/doc/myuserdoc/ch-10.lt3 +22 -0
  92. data/doc/myuserdoc/ch-2.lt3 +37 -0
  93. data/doc/myuserdoc/ch-3.lt3 +19 -0
  94. data/doc/myuserdoc/ch-4.lt3 +43 -0
  95. data/doc/myuserdoc/ch-5.lt3 +22 -0
  96. data/doc/myuserdoc/ch-6.lt3 +19 -0
  97. data/doc/myuserdoc/ch-7.lt3 +16 -0
  98. data/doc/myuserdoc/ch-8.lt3 +13 -0
  99. data/doc/myuserdoc/ch-9.lt3 +19 -0
  100. data/doc/myuserdoc/tweak.rb +18 -0
  101. data/doc/{userdoc-toc.txt → myuserdoc/userdoc-toc.txt} +27 -27
  102. data/doc/old-posts/0001-elixir-conf-2014.lt3 +24 -0
  103. data/doc/old-posts/0002-programmers-and-word-processing.lt3 +150 -0
  104. data/doc/old-posts/0003-how-to-turn-your-brain-sideways.lt3 +43 -0
  105. data/doc/old-posts/0004-upcoming-lone-star-ruby-conference.lt3 +26 -0
  106. data/doc/old-posts/0005-elixir-conf-2015-announced.lt3 +17 -0
  107. data/doc/old-posts/0006-ruby-for-dinosaurs.lt3 +30 -0
  108. data/doc/old-posts/0007-phoenix-isnt-rails.lt3 +90 -0
  109. data/doc/old-posts/0008-concerning-the-term-monkeypatching.lt3 +105 -0
  110. data/doc/old-posts/0009-announcement-coming-soon.lt3 +20 -0
  111. data/doc/old-posts/0010-immutable-data-ditching-the-wax-tablet.lt3 +142 -0
  112. data/doc/old-posts/0011-computer-science-as-a-lost-art.lt3 +117 -0
  113. data/doc/old-posts/0012-ruby-day-in-turin-italy.lt3 +26 -0
  114. data/doc/old-posts/0013-rubyday-was-a-success.lt3 +28 -0
  115. data/doc/old-posts/0014-working-on-the-blogging-software.lt3 +42 -0
  116. data/doc/old-posts/0015-ok-its-not-really-a-lost-art.lt3 +137 -0
  117. data/doc/old-posts/0016-an-in-operator-for-ruby.lt3 +142 -0
  118. data/doc/old-posts/0017-the-forgotten-mathematician.lt3 +129 -0
  119. data/doc/old-posts/0018-ruby-puns.lt3 +31 -0
  120. data/doc/old-posts/0019-custom-exceptions-via-metaprogramming.lt3 +116 -0
  121. data/doc/old-posts/0021-trying-ror-yet-again.lt3 +35 -0
  122. data/doc/old-posts/0023-doctor-sleep.lt3 +43 -0
  123. data/doc/old-posts/0024-just-a-test.lt3 +12 -0
  124. data/doc/old-posts/0025-trying-another-post.lt3 +12 -0
  125. data/doc/old-repo +1 -0
  126. data/doc/reddit_integration.md +2 -2
  127. data/doc/user.lt3 +0 -3
  128. data/lib/scriptorium/api.rb +1811 -78
  129. data/lib/scriptorium/banner_svg.rb +55 -68
  130. data/lib/scriptorium/contract.rb +3 -2
  131. data/lib/scriptorium/exceptions.rb +133 -102
  132. data/lib/scriptorium/helpers.rb +282 -82
  133. data/lib/scriptorium/post.rb +81 -17
  134. data/lib/scriptorium/reddit.rb +1 -1
  135. data/lib/scriptorium/repo.rb +478 -164
  136. data/lib/scriptorium/standard_files.rb +30 -396
  137. data/lib/scriptorium/support/common_js/clipboard.js +35 -0
  138. data/lib/scriptorium/support/common_js/content-loader.js +187 -0
  139. data/lib/scriptorium/support/common_js/navigation.js +52 -0
  140. data/lib/scriptorium/support/common_js/syntax-highlighting.js +27 -0
  141. data/lib/scriptorium/support/config/reddit_template.txt +17 -0
  142. data/{test/scriptorium-TEST-1754622690-146/views/sample → lib/scriptorium/support}/config/social.txt +1 -0
  143. data/lib/scriptorium/support/highlight/css.txt +2 -0
  144. data/lib/scriptorium/support/highlight/custom.css +119 -0
  145. data/lib/scriptorium/support/highlight/js.txt +1 -0
  146. data/lib/scriptorium/support/post_index/config.txt +15 -0
  147. data/lib/scriptorium/support/post_index/style.css +55 -0
  148. data/lib/scriptorium/support/templates/index_entry.lt3 +16 -0
  149. data/{test/scriptorium-TEST-1754622690-146/themes/standard/initial/post.lt3 → lib/scriptorium/support/templates/initial_post.lt3} +5 -5
  150. data/lib/scriptorium/support/templates/post.lt3 +104 -0
  151. data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/header.txt → lib/scriptorium/support/theme/header.lt3} +1 -1
  152. data/lib/scriptorium/theme.rb +83 -70
  153. data/lib/scriptorium/version.rb +2 -2
  154. data/lib/scriptorium/view.rb +194 -149
  155. data/lib/scriptorium.rb +24 -1
  156. data/lib/skeleton.rb +4 -1
  157. data/scriptorium.gemspec +2 -1
  158. data/test/WEB_INTEGRATION_README.md +196 -0
  159. data/test/all +40 -0
  160. data/test/banner_svg/unit.rb +267 -35
  161. data/test/config/deployment.txt +5 -0
  162. data/test/integration/integration_test.rb +7 -7
  163. data/test/integration/preview_flow_test.rb +94 -0
  164. data/test/livetext_plugin_test.rb +453 -182
  165. data/test/manual/banner-tests/test01.html +82 -18
  166. data/test/manual/banner-tests/test02.html +82 -18
  167. data/test/manual/banner-tests/test03.html +82 -18
  168. data/test/manual/banner-tests/test04.html +89 -25
  169. data/test/manual/banner-tests/test05.html +89 -25
  170. data/test/manual/banner-tests/test06.html +89 -25
  171. data/test/manual/banner-tests/test07.html +89 -25
  172. data/test/manual/banner-tests/test08.html +82 -18
  173. data/test/manual/banner-tests/test09.html +82 -18
  174. data/test/manual/banner-tests/test10.html +82 -18
  175. data/test/manual/banner-tests/test11.html +82 -18
  176. data/test/manual/banner-tests/test12.html +82 -18
  177. data/test/manual/banner-tests/test13.html +82 -18
  178. data/test/manual/banner-tests/test14.html +82 -18
  179. data/test/manual/banner-tests/test15.html +82 -18
  180. data/test/manual/banner-tests/test16.html +82 -18
  181. data/test/manual/banner-tests/test17.html +82 -18
  182. data/test/manual/banner-tests/test18.html +90 -26
  183. data/test/manual/banner-tests/test19.html +90 -26
  184. data/test/manual/banner-tests/test20.html +90 -26
  185. data/test/manual/banner-tests/test21.html +90 -26
  186. data/test/manual/banner-tests/test22.html +90 -26
  187. data/test/manual/banner-tests/test23.html +90 -26
  188. data/test/manual/banner-tests/test24.html +90 -26
  189. data/test/manual/banner-tests/test25.html +89 -25
  190. data/test/manual/banner_environment.rb +15 -2
  191. data/test/manual/codemirror_demo.html +773 -0
  192. data/test/manual/create_posts_for_web.rb +114 -0
  193. data/test/manual/preview_manual_test.rb +129 -0
  194. data/test/manual/test_banner_features.rb +14 -14
  195. data/test/manual/test_banner_integration.rb +115 -0
  196. data/test/manual/test_banner_radial.rb +87 -0
  197. data/test/manual/test_syntax_highlighting.rb +60 -40
  198. data/test/support/preview_utils.rb +88 -0
  199. data/test/test_gem_assets.rb +48 -0
  200. data/test/test_helpers.rb +10 -0
  201. data/test/tui_editor_integration_test.rb +15 -15
  202. data/test/tui_integration_test.rb +687 -441
  203. data/test/unit/api.rb +757 -37
  204. data/test/unit/asset_management.rb +195 -221
  205. data/test/unit/backup_test.rb +451 -0
  206. data/test/unit/contract_test.rb +1 -23
  207. data/test/unit/core.rb +415 -61
  208. data/test/unit/deploy_config_test.rb +248 -0
  209. data/test/unit/deploy_test.rb +312 -21
  210. data/test/unit/edit_post_test.rb +168 -0
  211. data/test/unit/gem_asset_management.rb +36 -42
  212. data/test/unit/livetext_basic.rb +23 -35
  213. data/test/unit/livetext_compatibility.rb +7 -14
  214. data/test/unit/parse_cmd_test.rb +260 -0
  215. data/test/unit/{symlink_test.rb → permalink_copy_test.rb} +47 -49
  216. data/test/unit/post.rb +91 -26
  217. data/test/unit/post_index_config_test.rb +258 -0
  218. data/test/unit/post_state_helpers_test.rb +137 -0
  219. data/test/unit/read_commented_file_test.rb +8 -6
  220. data/test/unit/repo.rb +75 -54
  221. data/test/unit/social_test.rb +41 -44
  222. data/test/unit/syntax_highlighting.rb +70 -0
  223. data/test/unit/theme_management_test.rb +91 -0
  224. data/test/unit/view.rb +79 -12
  225. data/test/unit/widgets.rb +8 -8
  226. data/test/web_integration_test.rb +231 -0
  227. data/test/web_test_helper.rb +218 -0
  228. data/test/web_workflow_test.rb +527 -0
  229. data/ui/tui/bin/scriptorium +885 -415
  230. data/ui/web/app/app.rb +1398 -176
  231. data/ui/web/app/assets/livetext_mode.js +244 -0
  232. data/ui/web/app/error_helpers.rb +16 -16
  233. data/ui/web/app/views/advanced_config.erb +8 -2
  234. data/ui/web/app/views/asset_management.erb +56 -0
  235. data/ui/web/app/views/backup_management.erb +238 -0
  236. data/ui/web/app/views/config_widget.erb +232 -0
  237. data/ui/web/app/views/dashboard.erb +64 -72
  238. data/ui/web/app/views/deploy_config.erb +3 -0
  239. data/ui/web/app/views/edit_pages.erb +170 -2
  240. data/ui/web/app/views/edit_post.erb +130 -9
  241. data/ui/web/app/views/edit_theme.erb +73 -0
  242. data/ui/web/app/views/edit_theme_file.erb +74 -0
  243. data/ui/web/app/views/theme_management.erb +130 -0
  244. data/ui/web/app/views/view_dashboard.erb +666 -25
  245. data/ui/web/app/views/widgets.erb +249 -0
  246. data/ui/web/bin/scriptorium-web +35 -24
  247. data/ui/web/tmp/timing.log +17 -0
  248. data/ui/web/tmp/web_server.log +0 -5
  249. metadata +190 -116
  250. data/assets/back-icon.png +0 -0
  251. data/assets/icons/facebook.svg +0 -1
  252. data/assets/icons/github.svg +0 -1
  253. data/assets/icons/instagram.svg +0 -1
  254. data/assets/icons/reddit.svg +0 -1
  255. data/assets/icons/x.svg +0 -1
  256. data/assets/icons/youtube.svg +0 -1
  257. data/bin/scriptorium +0 -1511
  258. data/doc/anti-amnesia/20250727-060000-api-design-tui-planning.md +0 -34
  259. data/doc/anti-amnesia/20250727-061000-runeblog-tui-analysis.md +0 -50
  260. data/doc/anti-amnesia/20250727-154000-livetext-plugin-file-stats.md +0 -73
  261. data/doc/anti-amnesia/20250727-172600-unified-minitest-framework.md +0 -70
  262. data/doc/anti-amnesia/20250727-173000-widget-testing-achievement.md +0 -110
  263. data/doc/anti-amnesia/20250727-180000-post-id-num-refactoring.md +0 -73
  264. data/doc/anti-amnesia/20250728-124421-conversation-summary-concise.md +0 -124
  265. data/doc/anti-amnesia/20250729-190000-scriptorium-tui-testing-complete.md +0 -46
  266. data/doc/anti-amnesia/20250729-200000-scriptorium-tui-testing-edit-file-workflow.md +0 -97
  267. data/doc/anti-amnesia/20250729-211500-dependency-management-system.md +0 -211
  268. data/doc/anti-amnesia/20250729-213000-python-virtual-environment-setup.md +0 -141
  269. data/doc/anti-amnesia/20250729-214500-theme-management-commands.md +0 -211
  270. data/doc/anti-amnesia/20250729-215000-version-update-to-0.6.0.md +0 -134
  271. data/doc/anti-amnesia/20250729-220000-user-guide-complete.md +0 -41
  272. data/doc/anti-amnesia/20250804-213700-publishing-test-fix.md +0 -49
  273. data/doc/anti-amnesia/20250804-214400-additional-test-fixes.md +0 -46
  274. data/doc/anti-amnesia/20250804-220000-asset-function-logic-clarification.md +0 -41
  275. data/doc/anti-amnesia/20250806-202032-asset-function-logic-clarification.md +0 -41
  276. data/doc/anti-amnesia/20250813-082428-syntax-highlighting-and-navigation-improvements.md +0 -256
  277. data/lib/scriptorium/syntax_highlighter.rb +0 -234
  278. data/test/manual/deploy_symlink_demo.rb +0 -142
  279. data/test/manual/symlink_demo.rb +0 -117
  280. data/test/manual/test2.rb +0 -12
  281. data/test/manual/test_banner_from_file.rb +0 -150
  282. data/test/manual/test_banner_in_header.rb +0 -35
  283. data/test/manual/test_code_highlighting.rb +0 -68
  284. data/test/manual/test_complex_header.rb +0 -74
  285. data/test/manual/test_empty_header.rb +0 -32
  286. data/test/manual/test_radial_custom.rb +0 -58
  287. data/test/manual/test_radial_large_radius.rb +0 -52
  288. data/test/manual/test_svg_debug.rb +0 -47
  289. data/test/pages-demo/config/currentview.txt +0 -1
  290. data/test/pages-demo/views/demo/config/common.js +0 -57
  291. data/test/pages-demo/views/demo/config/footer.txt +0 -1
  292. data/test/pages-demo/views/demo/config/global-head.txt +0 -8
  293. data/test/pages-demo/views/demo/config/header.txt +0 -1
  294. data/test/pages-demo/views/demo/config/layout.txt +0 -1
  295. data/test/pages-demo/views/demo/config/left.txt +0 -1
  296. data/test/pages-demo/views/demo/config/main.txt +0 -1
  297. data/test/pages-demo/views/demo/config/right.txt +0 -1
  298. data/test/pages-demo/views/demo/config.txt +0 -3
  299. data/test/pages-demo/views/demo/output/panes/footer.html +0 -1
  300. data/test/pages-demo/views/demo/output/panes/header.html +0 -1
  301. data/test/pages-demo/views/demo/output/panes/left.html +0 -1
  302. data/test/pages-demo/views/demo/output/panes/main.html +0 -1
  303. data/test/pages-demo/views/demo/output/panes/right.html +0 -1
  304. data/test/scriptorium-TEST-1754622690-146/config/bootstrap_css.txt +0 -5
  305. data/test/scriptorium-TEST-1754622690-146/config/bootstrap_js.txt +0 -4
  306. data/test/scriptorium-TEST-1754622690-146/config/common.js +0 -57
  307. data/test/scriptorium-TEST-1754622690-146/config/currentview.txt +0 -1
  308. data/test/scriptorium-TEST-1754622690-146/config/global-head.txt +0 -9
  309. data/test/scriptorium-TEST-1754622690-146/config/last_post_num.txt +0 -1
  310. data/test/scriptorium-TEST-1754622690-146/config/os_helpers.rb +0 -4
  311. data/test/scriptorium-TEST-1754622690-146/config/widgets.txt +0 -3
  312. data/test/scriptorium-TEST-1754622690-146/posts/0001/meta.txt +0 -8
  313. data/test/scriptorium-TEST-1754622690-146/posts/0001/source.lt3 +0 -6
  314. data/test/scriptorium-TEST-1754622690-146/themes/standard/README.txt +0 -1
  315. data/test/scriptorium-TEST-1754622690-146/themes/standard/config.txt +0 -1
  316. data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/gen/text.css +0 -1
  317. data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/index.lt3 +0 -1
  318. data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/index_entry.lt3 +0 -14
  319. data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/post.lt3 +0 -13
  320. data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/widget.lt3 +0 -1
  321. data/test/scriptorium-TEST-1754622690-146/views/sample/config/bootstrap_css.txt +0 -5
  322. data/test/scriptorium-TEST-1754622690-146/views/sample/config/bootstrap_js.txt +0 -4
  323. data/test/scriptorium-TEST-1754622690-146/views/sample/config/common.js +0 -57
  324. data/test/scriptorium-TEST-1754622690-146/views/sample/config/deploy.txt +0 -5
  325. data/test/scriptorium-TEST-1754622690-146/views/sample/config/footer.txt +0 -2
  326. data/test/scriptorium-TEST-1754622690-146/views/sample/config/global-head.txt +0 -9
  327. data/test/scriptorium-TEST-1754622690-146/views/sample/config/header.txt +0 -4
  328. data/test/scriptorium-TEST-1754622690-146/views/sample/config/layout.txt +0 -5
  329. data/test/scriptorium-TEST-1754622690-146/views/sample/config/left.txt +0 -3
  330. data/test/scriptorium-TEST-1754622690-146/views/sample/config/main.txt +0 -5
  331. data/test/scriptorium-TEST-1754622690-146/views/sample/config/right.txt +0 -3
  332. data/test/scriptorium-TEST-1754622690-146/views/sample/config/status.txt +0 -7
  333. data/test/scriptorium-TEST-1754622690-146/views/sample/config.txt +0 -3
  334. data/test/scriptorium-TEST-1754622690-146/views/sample/layout/footer.html +0 -3
  335. data/test/scriptorium-TEST-1754622690-146/views/sample/layout/header.html +0 -3
  336. data/test/scriptorium-TEST-1754622690-146/views/sample/layout/left.html +0 -3
  337. data/test/scriptorium-TEST-1754622690-146/views/sample/layout/main.html +0 -3
  338. data/test/scriptorium-TEST-1754622690-146/views/sample/layout/right.html +0 -3
  339. data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/footer.html +0 -1
  340. data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/header.html +0 -1
  341. data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/left.html +0 -1
  342. data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/main.html +0 -1
  343. data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/right.html +0 -1
  344. data/ui/web/tmp/web_server.pid +0 -1
  345. /data/{test/pages-demo/views/demo/config/bootstrap_css.txt → lib/scriptorium/support/bootstrap/css.txt} +0 -0
  346. /data/{test/pages-demo/views/demo/config/bootstrap_js.txt → lib/scriptorium/support/bootstrap/js.txt} +0 -0
  347. /data/{test/scriptorium-TEST-1754622690-146/views/sample → lib/scriptorium/support}/config/reddit.txt +0 -0
  348. /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout → lib/scriptorium/support/templates}/layout.txt +0 -0
  349. /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/footer.txt → lib/scriptorium/support/theme/footer.lt3} +0 -0
  350. /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/left.txt → lib/scriptorium/support/theme/left.lt3} +0 -0
  351. /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/main.txt → lib/scriptorium/support/theme/main.lt3} +0 -0
  352. /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/right.txt → lib/scriptorium/support/theme/right.lt3} +0 -0
  353. /data/test/manual/banner-tests/{config.txt → svg.txt} +0 -0
  354. /data/test/manual/{test6.rb → test_advanced_widgets.rb} +0 -0
  355. /data/test/manual/{test1.rb → test_basic_posts.rb} +0 -0
  356. /data/test/manual/{test4.rb → test_layout_widgets.rb} +0 -0
  357. /data/test/manual/{test5.rb → test_pagination.rb} +0 -0
  358. /data/test/manual/{test3.rb → test_random_posts.rb} +0 -0
@@ -0,0 +1,260 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../../lib/scriptorium'
3
+ require_relative '../test_helpers'
4
+
5
+ class ParseCmdTest < Minitest::Test
6
+ # Extract the parse_cmd method from the TUI class for testing
7
+ private def parse_cmd(cmdstr)
8
+ parts = cmdstr.split
9
+ return [:unknown_command, ""] if parts.empty?
10
+
11
+ # Handle 2-word commands and single-word commands with arguments
12
+ if parts.length >= 2
13
+ # Check if first two words form a known 2-word command
14
+ two_word_cmd = parts[0..1].join(" ")
15
+ case two_word_cmd.downcase
16
+ when "list views", "list posts", "list drafts", "list assets", "list widgets", "list themes", "list backups",
17
+ "change view", "new view", "new post", "upload asset", "copy asset", "delete asset",
18
+ "delete theme", "delete backup", "asset info", "configure deployment", "add widget", "config widget",
19
+ "config social", "config reddit", "clone theme"
20
+ cmd = two_word_cmd
21
+ args = parts[2..-1]
22
+ else
23
+ # Check if first word is a single-word command that can take parameters
24
+ first_word = parts[0].downcase
25
+ case first_word
26
+ when "cv", "backup", "restore" # Single-word commands that take parameters
27
+ # First word can take parameters, rest are arguments
28
+ cmd = first_word
29
+ args = parts[1..-1]
30
+ else
31
+ # Unknown command - treat as unknown 2-word command
32
+ cmd = two_word_cmd
33
+ args = parts[2..-1]
34
+ end
35
+ end
36
+ else
37
+ cmd = parts[0]
38
+ args = []
39
+ end
40
+
41
+ cmd = cmd.downcase
42
+
43
+ case cmd
44
+ when "help", "h"
45
+ [:show_help]
46
+ when "view"
47
+ [:show_current_view]
48
+ when "cv"
49
+ [:change_view, args]
50
+ when "lsv"
51
+ [:list_views]
52
+ when "lsp"
53
+ [:list_posts]
54
+ when "lsd"
55
+ [:list_drafts]
56
+ when "version", "v"
57
+ [:show_version]
58
+ when "deploy"
59
+ [:deploy_current_view]
60
+ when "preview"
61
+ [:preview_current_view]
62
+ when "browse"
63
+ [:browse_deployed_view]
64
+ when "generate"
65
+ [:generate_current_view]
66
+ when "quit", "q"
67
+ [:exit, 0]
68
+ when "list views"
69
+ [:list_views]
70
+ when "list posts"
71
+ [:list_posts]
72
+ when "list drafts"
73
+ [:list_drafts]
74
+ when "list assets"
75
+ [:list_assets, args]
76
+ when "list widgets"
77
+ [:list_widgets]
78
+ when "list themes"
79
+ [:list_themes]
80
+ when "list backups"
81
+ [:list_backups]
82
+ when "change view"
83
+ [:change_view, args]
84
+ when "new view"
85
+ args.empty? ? [:create_view] : [:create_view, args]
86
+ when "new post"
87
+ [:create_post, args]
88
+ when "upload asset"
89
+ [:upload_asset, args]
90
+ when "copy asset"
91
+ [:copy_asset, args]
92
+ when "delete asset"
93
+ [:delete_asset, args]
94
+ when "delete theme"
95
+ [:delete_theme, args]
96
+ when "delete backup"
97
+ [:delete_backup, args]
98
+ when "asset info"
99
+ [:asset_info, args]
100
+ when "configure deployment"
101
+ [:configure_deployment, args]
102
+ when "add widget"
103
+ [:add_widget, args]
104
+ when "config widget"
105
+ [:config_widget, args]
106
+ when "config social"
107
+ [:config_social]
108
+ when "config reddit"
109
+ [:config_reddit]
110
+ when "clone theme"
111
+ [:clone_theme, args]
112
+ when "backup"
113
+ [:create_backup, args]
114
+ when "restore"
115
+ [:restore_backup, args]
116
+ else
117
+ [:unknown_command, cmd]
118
+ end
119
+ end
120
+
121
+ def test_001_parse_cmd_basic_commands
122
+ # Test basic single-word commands
123
+ assert_equal [:show_help], parse_cmd("help")
124
+ assert_equal [:show_help], parse_cmd("h")
125
+ assert_equal [:show_current_view], parse_cmd("view")
126
+ assert_equal [:list_views], parse_cmd("lsv")
127
+ assert_equal [:list_posts], parse_cmd("lsp")
128
+ assert_equal [:list_drafts], parse_cmd("lsd")
129
+ assert_equal [:show_version], parse_cmd("version")
130
+ assert_equal [:show_version], parse_cmd("v")
131
+ assert_equal [:deploy_current_view], parse_cmd("deploy")
132
+ assert_equal [:preview_current_view], parse_cmd("preview")
133
+ assert_equal [:browse_deployed_view], parse_cmd("browse")
134
+ assert_equal [:generate_current_view], parse_cmd("generate")
135
+ assert_equal [:exit, 0], parse_cmd("quit")
136
+ assert_equal [:exit, 0], parse_cmd("q")
137
+ end
138
+
139
+ def test_002_parse_cmd_list_commands
140
+ # Test list commands
141
+ assert_equal [:list_views], parse_cmd("list views")
142
+ assert_equal [:list_posts], parse_cmd("list posts")
143
+ assert_equal [:list_drafts], parse_cmd("list drafts")
144
+ assert_equal [:list_assets, ["assets", "global"]], parse_cmd("list assets assets global")
145
+ assert_equal [:list_widgets], parse_cmd("list widgets")
146
+ assert_equal [:list_themes], parse_cmd("list themes")
147
+ assert_equal [:list_backups], parse_cmd("list backups")
148
+ end
149
+
150
+ def test_003_parse_cmd_change_commands
151
+ # Test change commands
152
+ assert_equal [:change_view, ["myview"]], parse_cmd("change view myview")
153
+ end
154
+
155
+ def test_004_parse_cmd_new_commands
156
+ # Test new commands
157
+ assert_equal [:create_view], parse_cmd("new view")
158
+ assert_equal [:create_view, ["myview"]], parse_cmd("new view myview")
159
+ assert_equal [:create_post, ["mypost"]], parse_cmd("new post mypost")
160
+ end
161
+
162
+ def test_005_parse_cmd_asset_commands
163
+ # Test asset commands
164
+ assert_equal [:upload_asset, ["myfile", "global"]], parse_cmd("upload asset myfile global")
165
+ assert_equal [:copy_asset, ["myfile", "from", "to"]], parse_cmd("copy asset myfile from to")
166
+ assert_equal [:delete_asset, ["myfile", "global"]], parse_cmd("delete asset myfile global")
167
+ assert_equal [:asset_info, ["myfile", "global"]], parse_cmd("asset info myfile global")
168
+ end
169
+
170
+ def test_006_parse_cmd_configure_commands
171
+ # Test configure commands
172
+ assert_equal [:configure_deployment, ["myview"]], parse_cmd("configure deployment myview")
173
+ end
174
+
175
+ def test_007_parse_cmd_widget_commands
176
+ # Test widget commands
177
+ assert_equal [:add_widget, ["mywidget"]], parse_cmd("add widget mywidget")
178
+ assert_equal [:config_widget, ["mywidget"]], parse_cmd("config widget mywidget")
179
+ end
180
+
181
+ def test_008_parse_cmd_config_commands
182
+ # Test config commands
183
+ assert_equal [:config_social], parse_cmd("config social")
184
+ assert_equal [:config_reddit], parse_cmd("config reddit")
185
+ end
186
+
187
+ def test_009_parse_cmd_clone_commands
188
+ # Test clone commands
189
+ assert_equal [:clone_theme, ["mytheme"]], parse_cmd("clone theme mytheme")
190
+ end
191
+
192
+ def test_010_parse_cmd_theme_commands
193
+ # Test theme commands
194
+ assert_equal [:delete_theme, ["mytheme"]], parse_cmd("delete theme mytheme")
195
+ end
196
+
197
+ def test_015_parse_cmd_backup_commands
198
+ # Test backup commands
199
+ assert_equal [:create_backup, []], parse_cmd("backup")
200
+ assert_equal [:create_backup, ["full"]], parse_cmd("backup full")
201
+ assert_equal [:create_backup, ["incr"]], parse_cmd("backup incr")
202
+ assert_equal [:create_backup, ["full", "Before", "major", "changes"]], parse_cmd("backup full Before major changes")
203
+ assert_equal [:create_backup, ["incr", "Added", "new", "post"]], parse_cmd("backup incr Added new post")
204
+ end
205
+
206
+ def test_016_parse_cmd_restore_commands
207
+ # Test restore commands
208
+ assert_equal [:restore_backup, []], parse_cmd("restore")
209
+ assert_equal [:restore_backup, ["20250902-120000-full"]], parse_cmd("restore 20250902-120000-full")
210
+ assert_equal [:restore_backup, ["20250902-120000-full", "safe"]], parse_cmd("restore 20250902-120000-full safe")
211
+ assert_equal [:restore_backup, ["20250902-130000-incr", "merge"]], parse_cmd("restore 20250902-130000-incr merge")
212
+ assert_equal [:restore_backup, ["20250902-140000-incr", "destroy"]], parse_cmd("restore 20250902-140000-incr destroy")
213
+ end
214
+
215
+ def test_017_parse_cmd_delete_backup_commands
216
+ # Test delete backup commands
217
+ assert_equal [:delete_backup, []], parse_cmd("delete backup")
218
+ assert_equal [:delete_backup, ["20250902-120000-full"]], parse_cmd("delete backup 20250902-120000-full")
219
+ assert_equal [:delete_backup, ["20250902-130000-incr"]], parse_cmd("delete backup 20250902-130000-incr")
220
+ end
221
+
222
+ def test_011_parse_cmd_edge_cases
223
+ # Test edge cases
224
+ assert_equal [:unknown_command, "invalid"], parse_cmd("invalid")
225
+ assert_equal [:unknown_command, ""], parse_cmd("")
226
+ assert_equal [:unknown_command, ""], parse_cmd(" ") # split() removes whitespace
227
+ assert_equal [:show_help], parse_cmd("help")
228
+ assert_equal [:show_help], parse_cmd(" help ")
229
+ end
230
+
231
+ def test_012_parse_cmd_complex_args
232
+ # Test commands with complex arguments
233
+ assert_equal [:change_view, ["my", "view", "with", "spaces"]], parse_cmd("change view my view with spaces")
234
+ assert_equal [:create_view, ["my", "view", "with", "spaces"]], parse_cmd("new view my view with spaces")
235
+ assert_equal [:list_assets, ["global", "with", "spaces"]], parse_cmd("list assets global with spaces")
236
+ end
237
+
238
+ def test_013_parse_cmd_abbreviated_commands
239
+ # Test abbreviated commands
240
+ assert_equal [:change_view, ["myview"]], parse_cmd("cv myview")
241
+ assert_equal [:list_views], parse_cmd("lsv")
242
+ assert_equal [:list_posts], parse_cmd("lsp")
243
+ assert_equal [:list_drafts], parse_cmd("lsd")
244
+ end
245
+
246
+ def test_014_parse_cmd_unknown_commands
247
+ # Test unknown commands
248
+ assert_equal [:unknown_command, "list invalid"], parse_cmd("list invalid")
249
+ assert_equal [:unknown_command, "change invalid"], parse_cmd("change invalid")
250
+ assert_equal [:unknown_command, "new invalid"], parse_cmd("new invalid")
251
+ assert_equal [:unknown_command, "upload invalid"], parse_cmd("upload invalid")
252
+ assert_equal [:unknown_command, "copy invalid"], parse_cmd("copy invalid")
253
+ assert_equal [:unknown_command, "delete invalid"], parse_cmd("delete invalid")
254
+ assert_equal [:unknown_command, "asset invalid"], parse_cmd("asset invalid")
255
+ assert_equal [:unknown_command, "configure invalid"], parse_cmd("configure invalid")
256
+ assert_equal [:unknown_command, "add invalid"], parse_cmd("add invalid")
257
+ assert_equal [:unknown_command, "config invalid"], parse_cmd("config invalid")
258
+ assert_equal [:unknown_command, "clone invalid"], parse_cmd("clone invalid")
259
+ end
260
+ end
@@ -1,12 +1,12 @@
1
- # Test file for symlink functionality
2
- # Tests the clean URL symlink generation for posts
1
+ # Test file for permalink copy functionality
2
+ # Tests the clean URL copy generation for posts
3
3
 
4
4
  require 'minitest/autorun'
5
5
  require_relative '../../lib/scriptorium'
6
6
  require_relative '../test_helpers'
7
7
  require 'fileutils'
8
8
 
9
- class TestSymlinkFunctionality < Minitest::Test
9
+ class TestPermalinkCopy < Minitest::Test
10
10
  include Scriptorium::Helpers
11
11
  include TestHelpers
12
12
 
@@ -55,10 +55,10 @@ class TestSymlinkFunctionality < Minitest::Test
55
55
  end
56
56
 
57
57
  # ========================================
58
- # Symlink generation tests
58
+ # Permalink copy generation tests
59
59
  # ========================================
60
60
 
61
- def test_006_symlink_creation_for_post
61
+ def test_006_permalink_copy_creation_for_post
62
62
  # Create a test post
63
63
  post_title = "My First Test Post"
64
64
  post_body = "This is the body of my test post."
@@ -81,16 +81,16 @@ class TestSymlinkFunctionality < Minitest::Test
81
81
  assert File.exist?(numbered_path), "Numbered post file should exist: #{numbered_path}"
82
82
  assert File.exist?(clean_symlink_path), "Clean symlink should exist: #{clean_symlink_path}"
83
83
 
84
- # Clean symlink should be a symlink
85
- assert File.symlink?(clean_symlink_path), "Clean symlink should be a symlink"
84
+ # Clean copy should exist
85
+ assert File.exist?(clean_symlink_path), "Clean copy should exist"
86
86
 
87
- # Symlink should point to the numbered file
88
- symlink_target = File.readlink(clean_symlink_path)
89
- expected_target = numbered_slug
90
- assert_equal expected_target, symlink_target, "Symlink should point to numbered file"
87
+ # Copy should have same content as numbered file
88
+ copy_content = File.read(clean_symlink_path)
89
+ numbered_content = File.read(numbered_path)
90
+ assert_equal numbered_content, copy_content, "Copy should have same content as numbered file"
91
91
  end
92
92
 
93
- def test_007_symlink_points_to_correct_file
93
+ def test_007_permalink_copy_has_correct_content
94
94
  # Create a test post with a specific title
95
95
  post_title = "Another Test Post"
96
96
  post_body = "This is another test post."
@@ -106,17 +106,17 @@ class TestSymlinkFunctionality < Minitest::Test
106
106
  clean_slug = clean_slugify(post_title) + ".html"
107
107
  clean_symlink_path = @view.dir/:output/:permalink/clean_slug
108
108
 
109
- assert File.symlink?(clean_symlink_path), "Should be a symlink"
109
+ assert File.exist?(clean_symlink_path), "Should be a copy"
110
110
 
111
- # Get the actual target
112
- symlink_target = File.readlink(clean_symlink_path)
111
+ # Get the actual content to verify it's a copy
112
+ copy_content = File.read(clean_symlink_path)
113
+ target_content = File.read(@view.dir/:output/:permalink/slugify(post_num, post_title) + ".html")
113
114
 
114
- # Expected target should be the numbered slug
115
- expected_slug = slugify(post_num, post_title) + ".html"
116
- assert_equal expected_slug, symlink_target, "Symlink should point to correct numbered file"
115
+ # Expected content should match the numbered file
116
+ assert_equal target_content, copy_content, "Copy should have same content as numbered file"
117
117
  end
118
118
 
119
- def test_008_symlink_overwrites_existing
119
+ def test_008_permalink_copy_overwrites_existing
120
120
  # Create a test post
121
121
  post_title = "Duplicate Test Post"
122
122
  post_body = "This is a test post."
@@ -125,17 +125,17 @@ class TestSymlinkFunctionality < Minitest::Test
125
125
  draft_name = @repo.create_draft(title: post_title, body: post_body)
126
126
  post_num = @repo.finish_draft(draft_name)
127
127
 
128
- # Generate the post (should create symlink)
128
+ # Generate the post (should create copy)
129
129
  @repo.generate_post(post_num)
130
130
 
131
- # Check that symlink exists
131
+ # Check that copy exists
132
132
  clean_slug = clean_slugify(post_title) + ".html"
133
133
  clean_symlink_path = @view.dir/:output/:permalink/clean_slug
134
134
 
135
- assert File.symlink?(clean_symlink_path), "Symlink should exist"
135
+ assert File.exist?(clean_symlink_path), "Copy should exist"
136
136
 
137
- # Get the target
138
- original_target = File.readlink(clean_symlink_path)
137
+ # Get the original content
138
+ original_content = File.read(clean_symlink_path)
139
139
 
140
140
  # Now create another post with the same clean slug (different numbered slug)
141
141
  post_title2 = "Duplicate Test Post" # Same title, different post
@@ -144,20 +144,20 @@ class TestSymlinkFunctionality < Minitest::Test
144
144
  draft_name2 = @repo.create_draft(title: post_title2, body: post_body2)
145
145
  post_num2 = @repo.finish_draft(draft_name2)
146
146
 
147
- # Generate the second post (should overwrite symlink)
147
+ # Generate the second post (should overwrite copy)
148
148
  @repo.generate_post(post_num2)
149
149
 
150
- # Check that symlink still exists and points to the new target
151
- assert File.symlink?(clean_symlink_path), "Symlink should still exist"
150
+ # Check that copy still exists and has new content
151
+ assert File.exist?(clean_symlink_path), "Copy should still exist"
152
152
 
153
- new_target = File.readlink(clean_symlink_path)
154
- expected_target = slugify(post_num2, post_title2) + ".html"
153
+ new_content = File.read(clean_symlink_path)
154
+ expected_content = File.read(@view.dir/:output/:permalink/slugify(post_num2, post_title2) + ".html")
155
155
 
156
- assert_equal expected_target, new_target, "Symlink should point to new target"
157
- refute_equal original_target, new_target, "Symlink should have been updated"
156
+ assert_equal expected_content, new_content, "Copy should have new content"
157
+ refute_equal original_content, new_content, "Copy should have been updated"
158
158
  end
159
159
 
160
- def test_009_symlink_with_special_characters_in_title
160
+ def test_009_permalink_copy_with_special_characters_in_title
161
161
  # Test with a title that has special characters
162
162
  post_title = "Post with Special Characters: & < > \" ' !"
163
163
  post_body = "This post has special characters in the title."
@@ -169,21 +169,20 @@ class TestSymlinkFunctionality < Minitest::Test
169
169
  # Generate the post
170
170
  @repo.generate_post(post_num)
171
171
 
172
- # Check that symlink exists with cleaned slug
172
+ # Check that copy exists with cleaned slug
173
173
  clean_slug = clean_slugify(post_title) + ".html"
174
174
  clean_symlink_path = @view.dir/:output/:permalink/clean_slug
175
175
 
176
- assert File.exist?(clean_symlink_path), "Symlink should exist for cleaned title"
177
- assert File.symlink?(clean_symlink_path), "Should be a symlink"
176
+ assert File.exist?(clean_symlink_path), "Copy should exist for cleaned title"
178
177
 
179
- # Check that the symlink points to the correct numbered file
180
- symlink_target = File.readlink(clean_symlink_path)
181
- expected_target = slugify(post_num, post_title) + ".html"
182
- assert_equal expected_target, symlink_target, "Symlink should point to correct numbered file"
178
+ # Check that the copy has the same content as the numbered file
179
+ copy_content = File.read(clean_symlink_path)
180
+ expected_content = File.read(@view.dir/:output/:permalink/slugify(post_num, post_title) + ".html")
181
+ assert_equal expected_content, copy_content, "Copy should have same content as numbered file"
183
182
  end
184
183
 
185
- def test_010_symlink_deployment_ready
186
- # Test that symlinks are created in the correct location for deployment
184
+ def test_010_permalink_copy_deployment_ready
185
+ # Test that permalink copies are created in the correct location for deployment
187
186
  post_title = "Deployment Test Post"
188
187
  post_body = "This post tests deployment readiness."
189
188
 
@@ -194,20 +193,19 @@ class TestSymlinkFunctionality < Minitest::Test
194
193
  # Generate the post
195
194
  @repo.generate_post(post_num)
196
195
 
197
- # Check that symlink is in the correct deployment location
196
+ # Check that copy is in the correct deployment location
198
197
  clean_slug = clean_slugify(post_title) + ".html"
199
198
  clean_symlink_path = @view.dir/:output/:permalink/clean_slug
200
199
 
201
200
  # Verify the path structure
202
201
  assert_equal @view.dir/:output/:permalink/clean_slug, clean_symlink_path
203
- assert File.exist?(clean_symlink_path), "Symlink should exist in deployment location"
202
+ assert File.exist?(clean_symlink_path), "Copy should exist in deployment location"
204
203
 
205
- # Verify it's a symlink
206
- assert File.symlink?(clean_symlink_path), "Should be a symlink"
204
+ # Verify it's a copy (not a symlink)
205
+ assert !File.symlink?(clean_symlink_path), "Should not be a symlink"
207
206
 
208
- # Verify the target exists and is accessible
209
- symlink_target = File.readlink(clean_symlink_path)
210
- target_path = @view.dir/:output/:permalink/symlink_target
211
- assert File.exist?(target_path), "Symlink target should exist"
207
+ # Verify the copy has content
208
+ copy_content = File.read(clean_symlink_path)
209
+ assert copy_content.length > 0, "Copy should have content"
212
210
  end
213
211
  end