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.
- checksums.yaml +4 -4
- data/assets/icons/social/reddit.png +0 -0
- data/assets/icons/social/x-logo.png +0 -0
- data/assets/imagenotfound.jpg +0 -0
- data/bin/sblog +84 -5
- data/bin/scriptorium +1 -0
- data/doc/anti-amnesia/20250727-054000-scriptorium-overview.md +0 -1
- data/doc/anti-amnesia/20250727-123000-anti-amnesia-conventions.md +0 -29
- data/doc/anti-amnesia/20250727-172600-cursor-rbenv-ruby-version-mystery.md +0 -19
- data/doc/anti-amnesia/20250727-172900-ai-cognitive-assessment-capabilities.md +1 -1
- data/doc/anti-amnesia/20250728-124243-aaa-syntax-clarification.md +1 -1
- data/doc/anti-amnesia/20250729-210000-reddit-autopost-integration-complete.md +1 -1
- data/doc/anti-amnesia/20250804-190500-cognitive-loop-bug.md +0 -10
- data/doc/anti-amnesia/20250804-190700-anti-amnesia-timestamping-fix.md +1 -4
- data/doc/anti-amnesia/20250901-211714-codemirror-integration-and-web-tests.md +172 -0
- data/doc/anti-amnesia/20250902-002402-backup-restore-system.md +126 -0
- data/doc/anti-amnesia/20250907-203339-backup-metadata-implementation.md +66 -0
- data/doc/imported/0001-elixir-conf-2014/metadata.txt +7 -0
- data/doc/imported/0001-elixir-conf-2014/post.html +37 -0
- data/doc/imported/0001-elixir-conf-2014/source.lt3 +22 -0
- data/doc/imported/0002-programmers-and-word-processing/metadata.txt +7 -0
- data/doc/imported/0002-programmers-and-word-processing/post.html +192 -0
- data/doc/imported/0002-programmers-and-word-processing/source.lt3 +146 -0
- data/doc/imported/0003-how-to-turn-your-brain-sideways/metadata.txt +7 -0
- data/doc/imported/0003-how-to-turn-your-brain-sideways/post.html +60 -0
- data/doc/imported/0003-how-to-turn-your-brain-sideways/source.lt3 +40 -0
- data/doc/imported/0004-upcoming-lone-star-ruby-conference/metadata.txt +7 -0
- data/doc/imported/0004-upcoming-lone-star-ruby-conference/post.html +42 -0
- data/doc/imported/0004-upcoming-lone-star-ruby-conference/source.lt3 +24 -0
- data/doc/imported/0005-elixir-conf-2015-announced/metadata.txt +7 -0
- data/doc/imported/0005-elixir-conf-2015-announced/post.html +30 -0
- data/doc/imported/0005-elixir-conf-2015-announced/source.lt3 +16 -0
- data/doc/imported/0006-ruby-for-dinosaurs/metadata.txt +7 -0
- data/doc/imported/0006-ruby-for-dinosaurs/post.html +43 -0
- data/doc/imported/0006-ruby-for-dinosaurs/source.lt3 +27 -0
- data/doc/imported/0007-phoenix-isnt-rails/metadata.txt +7 -0
- data/doc/imported/0007-phoenix-isnt-rails/post.html +116 -0
- data/doc/imported/0007-phoenix-isnt-rails/source.lt3 +87 -0
- data/doc/imported/0008-concerning-the-term-monkeypatching/metadata.txt +7 -0
- data/doc/imported/0008-concerning-the-term-monkeypatching/post.html +129 -0
- data/doc/imported/0008-concerning-the-term-monkeypatching/source.lt3 +92 -0
- data/doc/imported/0009-announcement-coming-soon/metadata.txt +7 -0
- data/doc/imported/0009-announcement-coming-soon/post.html +33 -0
- data/doc/imported/0009-announcement-coming-soon/source.lt3 +19 -0
- data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/metadata.txt +7 -0
- data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/post.html +175 -0
- data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/source.lt3 +139 -0
- data/doc/imported/0011-computer-science-as-a-lost-art/metadata.txt +7 -0
- data/doc/imported/0011-computer-science-as-a-lost-art/post.html +139 -0
- data/doc/imported/0011-computer-science-as-a-lost-art/source.lt3 +104 -0
- data/doc/imported/0012-ruby-day-in-turin-italy/metadata.txt +7 -0
- data/doc/imported/0012-ruby-day-in-turin-italy/post.html +42 -0
- data/doc/imported/0012-ruby-day-in-turin-italy/source.lt3 +24 -0
- data/doc/imported/0013-rubyday-was-a-success/metadata.txt +7 -0
- data/doc/imported/0013-rubyday-was-a-success/post.html +44 -0
- data/doc/imported/0013-rubyday-was-a-success/source.lt3 +27 -0
- data/doc/imported/0014-working-on-the-blogging-software/metadata.txt +7 -0
- data/doc/imported/0014-working-on-the-blogging-software/post.html +63 -0
- data/doc/imported/0014-working-on-the-blogging-software/source.lt3 +41 -0
- data/doc/imported/0015-ok-its-not-really-a-lost-art/metadata.txt +7 -0
- data/doc/imported/0015-ok-its-not-really-a-lost-art/post.html +172 -0
- data/doc/imported/0015-ok-its-not-really-a-lost-art/source.lt3 +134 -0
- data/doc/imported/0016-an-in-operator-for-ruby/metadata.txt +7 -0
- data/doc/imported/0016-an-in-operator-for-ruby/post.html +155 -0
- data/doc/imported/0016-an-in-operator-for-ruby/source.lt3 +106 -0
- data/doc/imported/0017-the-forgotten-mathematician/metadata.txt +7 -0
- data/doc/imported/0017-the-forgotten-mathematician/post.html +161 -0
- data/doc/imported/0017-the-forgotten-mathematician/source.lt3 +119 -0
- data/doc/imported/0018-ruby-puns/metadata.txt +7 -0
- data/doc/imported/0018-ruby-puns/post.html +46 -0
- data/doc/imported/0018-ruby-puns/source.lt3 +28 -0
- data/doc/imported/0019-custom-exceptions-via-metaprogramming/metadata.txt +7 -0
- data/doc/imported/0019-custom-exceptions-via-metaprogramming/post.html +138 -0
- data/doc/imported/0019-custom-exceptions-via-metaprogramming/source.lt3 +101 -0
- data/doc/imported/0020-fffff/metadata.txt +7 -0
- data/doc/imported/0020-fffff/post.html +24 -0
- data/doc/imported/0020-fffff/source.lt3 +12 -0
- data/doc/imported/0021-trying-ror-yet-again/metadata.txt +7 -0
- data/doc/imported/0021-trying-ror-yet-again/post.html +26 -0
- data/doc/imported/0021-trying-ror-yet-again/source.lt3 +12 -0
- data/doc/imported/0023-doctor-sleep/metadata.txt +7 -0
- data/doc/imported/0023-doctor-sleep/post.html +63 -0
- data/doc/imported/0023-doctor-sleep/source.lt3 +44 -0
- data/doc/imported/0024-just-a-test/metadata.txt +7 -0
- data/doc/imported/0024-just-a-test/post.html +24 -0
- data/doc/imported/0024-just-a-test/source.lt3 +12 -0
- data/doc/imported/import_summary.txt +98 -0
- data/doc/livetext-informal-spec.txt +65 -0
- data/doc/myuserdoc/ch-0.lt3 +31 -0
- data/doc/myuserdoc/ch-1.lt3 +37 -0
- data/doc/myuserdoc/ch-10.lt3 +22 -0
- data/doc/myuserdoc/ch-2.lt3 +37 -0
- data/doc/myuserdoc/ch-3.lt3 +19 -0
- data/doc/myuserdoc/ch-4.lt3 +43 -0
- data/doc/myuserdoc/ch-5.lt3 +22 -0
- data/doc/myuserdoc/ch-6.lt3 +19 -0
- data/doc/myuserdoc/ch-7.lt3 +16 -0
- data/doc/myuserdoc/ch-8.lt3 +13 -0
- data/doc/myuserdoc/ch-9.lt3 +19 -0
- data/doc/myuserdoc/tweak.rb +18 -0
- data/doc/{userdoc-toc.txt → myuserdoc/userdoc-toc.txt} +27 -27
- data/doc/old-posts/0001-elixir-conf-2014.lt3 +24 -0
- data/doc/old-posts/0002-programmers-and-word-processing.lt3 +150 -0
- data/doc/old-posts/0003-how-to-turn-your-brain-sideways.lt3 +43 -0
- data/doc/old-posts/0004-upcoming-lone-star-ruby-conference.lt3 +26 -0
- data/doc/old-posts/0005-elixir-conf-2015-announced.lt3 +17 -0
- data/doc/old-posts/0006-ruby-for-dinosaurs.lt3 +30 -0
- data/doc/old-posts/0007-phoenix-isnt-rails.lt3 +90 -0
- data/doc/old-posts/0008-concerning-the-term-monkeypatching.lt3 +105 -0
- data/doc/old-posts/0009-announcement-coming-soon.lt3 +20 -0
- data/doc/old-posts/0010-immutable-data-ditching-the-wax-tablet.lt3 +142 -0
- data/doc/old-posts/0011-computer-science-as-a-lost-art.lt3 +117 -0
- data/doc/old-posts/0012-ruby-day-in-turin-italy.lt3 +26 -0
- data/doc/old-posts/0013-rubyday-was-a-success.lt3 +28 -0
- data/doc/old-posts/0014-working-on-the-blogging-software.lt3 +42 -0
- data/doc/old-posts/0015-ok-its-not-really-a-lost-art.lt3 +137 -0
- data/doc/old-posts/0016-an-in-operator-for-ruby.lt3 +142 -0
- data/doc/old-posts/0017-the-forgotten-mathematician.lt3 +129 -0
- data/doc/old-posts/0018-ruby-puns.lt3 +31 -0
- data/doc/old-posts/0019-custom-exceptions-via-metaprogramming.lt3 +116 -0
- data/doc/old-posts/0021-trying-ror-yet-again.lt3 +35 -0
- data/doc/old-posts/0023-doctor-sleep.lt3 +43 -0
- data/doc/old-posts/0024-just-a-test.lt3 +12 -0
- data/doc/old-posts/0025-trying-another-post.lt3 +12 -0
- data/doc/old-repo +1 -0
- data/doc/reddit_integration.md +2 -2
- data/doc/user.lt3 +0 -3
- data/lib/scriptorium/api.rb +1811 -78
- data/lib/scriptorium/banner_svg.rb +55 -68
- data/lib/scriptorium/contract.rb +3 -2
- data/lib/scriptorium/exceptions.rb +133 -102
- data/lib/scriptorium/helpers.rb +282 -82
- data/lib/scriptorium/post.rb +81 -17
- data/lib/scriptorium/reddit.rb +1 -1
- data/lib/scriptorium/repo.rb +478 -164
- data/lib/scriptorium/standard_files.rb +30 -396
- data/lib/scriptorium/support/common_js/clipboard.js +35 -0
- data/lib/scriptorium/support/common_js/content-loader.js +187 -0
- data/lib/scriptorium/support/common_js/navigation.js +52 -0
- data/lib/scriptorium/support/common_js/syntax-highlighting.js +27 -0
- data/lib/scriptorium/support/config/reddit_template.txt +17 -0
- data/{test/scriptorium-TEST-1754622690-146/views/sample → lib/scriptorium/support}/config/social.txt +1 -0
- data/lib/scriptorium/support/highlight/css.txt +2 -0
- data/lib/scriptorium/support/highlight/custom.css +119 -0
- data/lib/scriptorium/support/highlight/js.txt +1 -0
- data/lib/scriptorium/support/post_index/config.txt +15 -0
- data/lib/scriptorium/support/post_index/style.css +55 -0
- data/lib/scriptorium/support/templates/index_entry.lt3 +16 -0
- data/{test/scriptorium-TEST-1754622690-146/themes/standard/initial/post.lt3 → lib/scriptorium/support/templates/initial_post.lt3} +5 -5
- data/lib/scriptorium/support/templates/post.lt3 +104 -0
- data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/header.txt → lib/scriptorium/support/theme/header.lt3} +1 -1
- data/lib/scriptorium/theme.rb +83 -70
- data/lib/scriptorium/version.rb +2 -2
- data/lib/scriptorium/view.rb +194 -149
- data/lib/scriptorium.rb +24 -1
- data/lib/skeleton.rb +4 -1
- data/scriptorium.gemspec +2 -1
- data/test/WEB_INTEGRATION_README.md +196 -0
- data/test/all +40 -0
- data/test/banner_svg/unit.rb +267 -35
- data/test/config/deployment.txt +5 -0
- data/test/integration/integration_test.rb +7 -7
- data/test/integration/preview_flow_test.rb +94 -0
- data/test/livetext_plugin_test.rb +453 -182
- data/test/manual/banner-tests/test01.html +82 -18
- data/test/manual/banner-tests/test02.html +82 -18
- data/test/manual/banner-tests/test03.html +82 -18
- data/test/manual/banner-tests/test04.html +89 -25
- data/test/manual/banner-tests/test05.html +89 -25
- data/test/manual/banner-tests/test06.html +89 -25
- data/test/manual/banner-tests/test07.html +89 -25
- data/test/manual/banner-tests/test08.html +82 -18
- data/test/manual/banner-tests/test09.html +82 -18
- data/test/manual/banner-tests/test10.html +82 -18
- data/test/manual/banner-tests/test11.html +82 -18
- data/test/manual/banner-tests/test12.html +82 -18
- data/test/manual/banner-tests/test13.html +82 -18
- data/test/manual/banner-tests/test14.html +82 -18
- data/test/manual/banner-tests/test15.html +82 -18
- data/test/manual/banner-tests/test16.html +82 -18
- data/test/manual/banner-tests/test17.html +82 -18
- data/test/manual/banner-tests/test18.html +90 -26
- data/test/manual/banner-tests/test19.html +90 -26
- data/test/manual/banner-tests/test20.html +90 -26
- data/test/manual/banner-tests/test21.html +90 -26
- data/test/manual/banner-tests/test22.html +90 -26
- data/test/manual/banner-tests/test23.html +90 -26
- data/test/manual/banner-tests/test24.html +90 -26
- data/test/manual/banner-tests/test25.html +89 -25
- data/test/manual/banner_environment.rb +15 -2
- data/test/manual/codemirror_demo.html +773 -0
- data/test/manual/create_posts_for_web.rb +114 -0
- data/test/manual/preview_manual_test.rb +129 -0
- data/test/manual/test_banner_features.rb +14 -14
- data/test/manual/test_banner_integration.rb +115 -0
- data/test/manual/test_banner_radial.rb +87 -0
- data/test/manual/test_syntax_highlighting.rb +60 -40
- data/test/support/preview_utils.rb +88 -0
- data/test/test_gem_assets.rb +48 -0
- data/test/test_helpers.rb +10 -0
- data/test/tui_editor_integration_test.rb +15 -15
- data/test/tui_integration_test.rb +687 -441
- data/test/unit/api.rb +757 -37
- data/test/unit/asset_management.rb +195 -221
- data/test/unit/backup_test.rb +451 -0
- data/test/unit/contract_test.rb +1 -23
- data/test/unit/core.rb +415 -61
- data/test/unit/deploy_config_test.rb +248 -0
- data/test/unit/deploy_test.rb +312 -21
- data/test/unit/edit_post_test.rb +168 -0
- data/test/unit/gem_asset_management.rb +36 -42
- data/test/unit/livetext_basic.rb +23 -35
- data/test/unit/livetext_compatibility.rb +7 -14
- data/test/unit/parse_cmd_test.rb +260 -0
- data/test/unit/{symlink_test.rb → permalink_copy_test.rb} +47 -49
- data/test/unit/post.rb +91 -26
- data/test/unit/post_index_config_test.rb +258 -0
- data/test/unit/post_state_helpers_test.rb +137 -0
- data/test/unit/read_commented_file_test.rb +8 -6
- data/test/unit/repo.rb +75 -54
- data/test/unit/social_test.rb +41 -44
- data/test/unit/syntax_highlighting.rb +70 -0
- data/test/unit/theme_management_test.rb +91 -0
- data/test/unit/view.rb +79 -12
- data/test/unit/widgets.rb +8 -8
- data/test/web_integration_test.rb +231 -0
- data/test/web_test_helper.rb +218 -0
- data/test/web_workflow_test.rb +527 -0
- data/ui/tui/bin/scriptorium +885 -415
- data/ui/web/app/app.rb +1398 -176
- data/ui/web/app/assets/livetext_mode.js +244 -0
- data/ui/web/app/error_helpers.rb +16 -16
- data/ui/web/app/views/advanced_config.erb +8 -2
- data/ui/web/app/views/asset_management.erb +56 -0
- data/ui/web/app/views/backup_management.erb +238 -0
- data/ui/web/app/views/config_widget.erb +232 -0
- data/ui/web/app/views/dashboard.erb +64 -72
- data/ui/web/app/views/deploy_config.erb +3 -0
- data/ui/web/app/views/edit_pages.erb +170 -2
- data/ui/web/app/views/edit_post.erb +130 -9
- data/ui/web/app/views/edit_theme.erb +73 -0
- data/ui/web/app/views/edit_theme_file.erb +74 -0
- data/ui/web/app/views/theme_management.erb +130 -0
- data/ui/web/app/views/view_dashboard.erb +666 -25
- data/ui/web/app/views/widgets.erb +249 -0
- data/ui/web/bin/scriptorium-web +35 -24
- data/ui/web/tmp/timing.log +17 -0
- data/ui/web/tmp/web_server.log +0 -5
- metadata +190 -116
- data/assets/back-icon.png +0 -0
- data/assets/icons/facebook.svg +0 -1
- data/assets/icons/github.svg +0 -1
- data/assets/icons/instagram.svg +0 -1
- data/assets/icons/reddit.svg +0 -1
- data/assets/icons/x.svg +0 -1
- data/assets/icons/youtube.svg +0 -1
- data/bin/scriptorium +0 -1511
- data/doc/anti-amnesia/20250727-060000-api-design-tui-planning.md +0 -34
- data/doc/anti-amnesia/20250727-061000-runeblog-tui-analysis.md +0 -50
- data/doc/anti-amnesia/20250727-154000-livetext-plugin-file-stats.md +0 -73
- data/doc/anti-amnesia/20250727-172600-unified-minitest-framework.md +0 -70
- data/doc/anti-amnesia/20250727-173000-widget-testing-achievement.md +0 -110
- data/doc/anti-amnesia/20250727-180000-post-id-num-refactoring.md +0 -73
- data/doc/anti-amnesia/20250728-124421-conversation-summary-concise.md +0 -124
- data/doc/anti-amnesia/20250729-190000-scriptorium-tui-testing-complete.md +0 -46
- data/doc/anti-amnesia/20250729-200000-scriptorium-tui-testing-edit-file-workflow.md +0 -97
- data/doc/anti-amnesia/20250729-211500-dependency-management-system.md +0 -211
- data/doc/anti-amnesia/20250729-213000-python-virtual-environment-setup.md +0 -141
- data/doc/anti-amnesia/20250729-214500-theme-management-commands.md +0 -211
- data/doc/anti-amnesia/20250729-215000-version-update-to-0.6.0.md +0 -134
- data/doc/anti-amnesia/20250729-220000-user-guide-complete.md +0 -41
- data/doc/anti-amnesia/20250804-213700-publishing-test-fix.md +0 -49
- data/doc/anti-amnesia/20250804-214400-additional-test-fixes.md +0 -46
- data/doc/anti-amnesia/20250804-220000-asset-function-logic-clarification.md +0 -41
- data/doc/anti-amnesia/20250806-202032-asset-function-logic-clarification.md +0 -41
- data/doc/anti-amnesia/20250813-082428-syntax-highlighting-and-navigation-improvements.md +0 -256
- data/lib/scriptorium/syntax_highlighter.rb +0 -234
- data/test/manual/deploy_symlink_demo.rb +0 -142
- data/test/manual/symlink_demo.rb +0 -117
- data/test/manual/test2.rb +0 -12
- data/test/manual/test_banner_from_file.rb +0 -150
- data/test/manual/test_banner_in_header.rb +0 -35
- data/test/manual/test_code_highlighting.rb +0 -68
- data/test/manual/test_complex_header.rb +0 -74
- data/test/manual/test_empty_header.rb +0 -32
- data/test/manual/test_radial_custom.rb +0 -58
- data/test/manual/test_radial_large_radius.rb +0 -52
- data/test/manual/test_svg_debug.rb +0 -47
- data/test/pages-demo/config/currentview.txt +0 -1
- data/test/pages-demo/views/demo/config/common.js +0 -57
- data/test/pages-demo/views/demo/config/footer.txt +0 -1
- data/test/pages-demo/views/demo/config/global-head.txt +0 -8
- data/test/pages-demo/views/demo/config/header.txt +0 -1
- data/test/pages-demo/views/demo/config/layout.txt +0 -1
- data/test/pages-demo/views/demo/config/left.txt +0 -1
- data/test/pages-demo/views/demo/config/main.txt +0 -1
- data/test/pages-demo/views/demo/config/right.txt +0 -1
- data/test/pages-demo/views/demo/config.txt +0 -3
- data/test/pages-demo/views/demo/output/panes/footer.html +0 -1
- data/test/pages-demo/views/demo/output/panes/header.html +0 -1
- data/test/pages-demo/views/demo/output/panes/left.html +0 -1
- data/test/pages-demo/views/demo/output/panes/main.html +0 -1
- data/test/pages-demo/views/demo/output/panes/right.html +0 -1
- data/test/scriptorium-TEST-1754622690-146/config/bootstrap_css.txt +0 -5
- data/test/scriptorium-TEST-1754622690-146/config/bootstrap_js.txt +0 -4
- data/test/scriptorium-TEST-1754622690-146/config/common.js +0 -57
- data/test/scriptorium-TEST-1754622690-146/config/currentview.txt +0 -1
- data/test/scriptorium-TEST-1754622690-146/config/global-head.txt +0 -9
- data/test/scriptorium-TEST-1754622690-146/config/last_post_num.txt +0 -1
- data/test/scriptorium-TEST-1754622690-146/config/os_helpers.rb +0 -4
- data/test/scriptorium-TEST-1754622690-146/config/widgets.txt +0 -3
- data/test/scriptorium-TEST-1754622690-146/posts/0001/meta.txt +0 -8
- data/test/scriptorium-TEST-1754622690-146/posts/0001/source.lt3 +0 -6
- data/test/scriptorium-TEST-1754622690-146/themes/standard/README.txt +0 -1
- data/test/scriptorium-TEST-1754622690-146/themes/standard/config.txt +0 -1
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/gen/text.css +0 -1
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/index.lt3 +0 -1
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/index_entry.lt3 +0 -14
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/post.lt3 +0 -13
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/widget.lt3 +0 -1
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/bootstrap_css.txt +0 -5
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/bootstrap_js.txt +0 -4
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/common.js +0 -57
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/deploy.txt +0 -5
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/footer.txt +0 -2
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/global-head.txt +0 -9
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/header.txt +0 -4
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/layout.txt +0 -5
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/left.txt +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/main.txt +0 -5
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/right.txt +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/status.txt +0 -7
- data/test/scriptorium-TEST-1754622690-146/views/sample/config.txt +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/footer.html +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/header.html +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/left.html +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/main.html +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/right.html +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/footer.html +0 -1
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/header.html +0 -1
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/left.html +0 -1
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/main.html +0 -1
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/right.html +0 -1
- data/ui/web/tmp/web_server.pid +0 -1
- /data/{test/pages-demo/views/demo/config/bootstrap_css.txt → lib/scriptorium/support/bootstrap/css.txt} +0 -0
- /data/{test/pages-demo/views/demo/config/bootstrap_js.txt → lib/scriptorium/support/bootstrap/js.txt} +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/views/sample → lib/scriptorium/support}/config/reddit.txt +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout → lib/scriptorium/support/templates}/layout.txt +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/footer.txt → lib/scriptorium/support/theme/footer.lt3} +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/left.txt → lib/scriptorium/support/theme/left.lt3} +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/main.txt → lib/scriptorium/support/theme/main.lt3} +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/right.txt → lib/scriptorium/support/theme/right.lt3} +0 -0
- /data/test/manual/banner-tests/{config.txt → svg.txt} +0 -0
- /data/test/manual/{test6.rb → test_advanced_widgets.rb} +0 -0
- /data/test/manual/{test1.rb → test_basic_posts.rb} +0 -0
- /data/test/manual/{test4.rb → test_layout_widgets.rb} +0 -0
- /data/test/manual/{test5.rb → test_pagination.rb} +0 -0
- /data/test/manual/{test3.rb → test_random_posts.rb} +0 -0
data/test/unit/core.rb
CHANGED
@@ -29,7 +29,7 @@ class TestReadWrite < Minitest::Test
|
|
29
29
|
|
30
30
|
def test_001_need_file_basic_functionality
|
31
31
|
file_path = "#{@test_dir}/test_file.txt"
|
32
|
-
|
32
|
+
write_file(file_path, "test content")
|
33
33
|
|
34
34
|
result = need(:file, file_path)
|
35
35
|
assert_equal file_path, result
|
@@ -62,19 +62,19 @@ class TestReadWrite < Minitest::Test
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def test_004_need_nil_path_raises_error
|
65
|
-
assert_raises(
|
65
|
+
assert_raises(RequirePathNil) do
|
66
66
|
need(:file, nil)
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
70
|
def test_005_need_empty_path_raises_error
|
71
|
-
assert_raises(
|
71
|
+
assert_raises(RequirePathEmpty) do
|
72
72
|
need(:file, "")
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
76
|
def test_006_need_whitespace_path_raises_error
|
77
|
-
assert_raises(
|
77
|
+
assert_raises(RequirePathEmpty) do
|
78
78
|
need(:file, " ")
|
79
79
|
end
|
80
80
|
end
|
@@ -113,29 +113,27 @@ class TestReadWrite < Minitest::Test
|
|
113
113
|
|
114
114
|
def test_011_system_with_description
|
115
115
|
# Test that description is included in error message
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
assert_match /Command failed/, e.message
|
122
|
-
end
|
116
|
+
system!("false", "testing failure")
|
117
|
+
flunk "Expected system! to raise an error"
|
118
|
+
rescue CommandFailedWithDesc => e
|
119
|
+
assert_match /testing failure/, e.message
|
120
|
+
assert_match /Command failed/, e.message
|
123
121
|
end
|
124
122
|
|
125
123
|
def test_012_system_nil_command_raises_error
|
126
|
-
assert_raises(
|
124
|
+
assert_raises(CommandNil) do
|
127
125
|
system!(nil)
|
128
126
|
end
|
129
127
|
end
|
130
128
|
|
131
129
|
def test_013_system_empty_command_raises_error
|
132
|
-
assert_raises(
|
130
|
+
assert_raises(CommandEmpty) do
|
133
131
|
system!("")
|
134
132
|
end
|
135
133
|
end
|
136
134
|
|
137
135
|
def test_014_system_whitespace_command_raises_error
|
138
|
-
assert_raises(
|
136
|
+
assert_raises(CommandEmpty) do
|
139
137
|
system!(" ")
|
140
138
|
end
|
141
139
|
end
|
@@ -185,19 +183,19 @@ class TestReadWrite < Minitest::Test
|
|
185
183
|
end
|
186
184
|
|
187
185
|
def test_020_make_dir_nil_path_raises_error
|
188
|
-
assert_raises(
|
186
|
+
assert_raises(DirectoryPathNil) do
|
189
187
|
make_dir(nil)
|
190
188
|
end
|
191
189
|
end
|
192
190
|
|
193
191
|
def test_021_make_dir_empty_path_raises_error
|
194
|
-
assert_raises(
|
192
|
+
assert_raises(DirectoryPathEmpty) do
|
195
193
|
make_dir("")
|
196
194
|
end
|
197
195
|
end
|
198
196
|
|
199
197
|
def test_022_make_dir_whitespace_path_raises_error
|
200
|
-
assert_raises(
|
198
|
+
assert_raises(DirectoryPathEmpty) do
|
201
199
|
make_dir(" ")
|
202
200
|
end
|
203
201
|
end
|
@@ -211,7 +209,7 @@ class TestReadWrite < Minitest::Test
|
|
211
209
|
file_path = "#{read_only_dir}/test_dir"
|
212
210
|
|
213
211
|
# This should raise a permission denied error
|
214
|
-
assert_raises(
|
212
|
+
assert_raises(DirectoryPermissionDenied) do
|
215
213
|
make_dir(file_path)
|
216
214
|
end
|
217
215
|
|
@@ -230,7 +228,7 @@ class TestReadWrite < Minitest::Test
|
|
230
228
|
write_file(file_path, content.join("\n"))
|
231
229
|
|
232
230
|
assert File.exist?(file_path)
|
233
|
-
assert_equal content.join("\n") + "\n",
|
231
|
+
assert_equal content.join("\n") + "\n", read_file(file_path)
|
234
232
|
end
|
235
233
|
|
236
234
|
def test_025_write_file_creates_parent_directories
|
@@ -249,7 +247,7 @@ class TestReadWrite < Minitest::Test
|
|
249
247
|
write_file(file_path, "")
|
250
248
|
|
251
249
|
assert File.exist?(file_path)
|
252
|
-
assert_equal "\n",
|
250
|
+
assert_equal "\n", read_file(file_path)
|
253
251
|
end
|
254
252
|
|
255
253
|
def test_027_write_file_single_line
|
@@ -259,7 +257,7 @@ class TestReadWrite < Minitest::Test
|
|
259
257
|
write_file(file_path, content)
|
260
258
|
|
261
259
|
assert File.exist?(file_path)
|
262
|
-
assert_equal content + "\n",
|
260
|
+
assert_equal content + "\n", read_file(file_path)
|
263
261
|
end
|
264
262
|
|
265
263
|
def test_028_write_file_multiple_lines
|
@@ -270,23 +268,23 @@ class TestReadWrite < Minitest::Test
|
|
270
268
|
|
271
269
|
assert File.exist?(file_path)
|
272
270
|
expected = content.join("\n") + "\n"
|
273
|
-
assert_equal expected,
|
271
|
+
assert_equal expected, read_file(file_path)
|
274
272
|
end
|
275
273
|
|
276
274
|
def test_029_write_file_nil_path_raises_error
|
277
|
-
assert_raises(
|
275
|
+
assert_raises(FilePathNil) do
|
278
276
|
write_file(nil, "content")
|
279
277
|
end
|
280
278
|
end
|
281
279
|
|
282
280
|
def test_030_write_file_empty_path_raises_error
|
283
|
-
assert_raises(
|
281
|
+
assert_raises(FilePathEmpty) do
|
284
282
|
write_file("", "content")
|
285
283
|
end
|
286
284
|
end
|
287
285
|
|
288
286
|
def test_031_write_file_whitespace_path_raises_error
|
289
|
-
assert_raises(
|
287
|
+
assert_raises(FilePathEmpty) do
|
290
288
|
write_file(" ", "content")
|
291
289
|
end
|
292
290
|
end
|
@@ -300,7 +298,7 @@ class TestReadWrite < Minitest::Test
|
|
300
298
|
file_path = "#{read_only_dir}/test.txt"
|
301
299
|
|
302
300
|
# This should raise a permission denied error
|
303
|
-
assert_raises(
|
301
|
+
assert_raises(FilePermissionDenied) do
|
304
302
|
write_file(file_path, "content")
|
305
303
|
end
|
306
304
|
|
@@ -308,6 +306,115 @@ class TestReadWrite < Minitest::Test
|
|
308
306
|
FileUtils.chmod(0755, read_only_dir)
|
309
307
|
end
|
310
308
|
|
309
|
+
def test_033_write_file_empty_true_creates_file
|
310
|
+
file_path = "#{@test_dir}/empty_true.txt"
|
311
|
+
|
312
|
+
# Should create file with empty: true even for empty content
|
313
|
+
write_file(file_path, "", empty: true)
|
314
|
+
|
315
|
+
assert File.exist?(file_path)
|
316
|
+
assert_equal "", read_file(file_path) # No newline added
|
317
|
+
end
|
318
|
+
|
319
|
+
def test_034_write_file_empty_true_nil_content
|
320
|
+
file_path = "#{@test_dir}/empty_true_nil.txt"
|
321
|
+
|
322
|
+
# Should create file with empty: true even for nil content
|
323
|
+
write_file(file_path, nil, empty: true)
|
324
|
+
|
325
|
+
assert File.exist?(file_path)
|
326
|
+
assert_equal "", read_file(file_path) # No newline added
|
327
|
+
end
|
328
|
+
|
329
|
+
def test_035_write_file_empty_true_whitespace_content
|
330
|
+
file_path = "#{@test_dir}/empty_true_whitespace.txt"
|
331
|
+
|
332
|
+
# Should create file with empty: true for whitespace-only content
|
333
|
+
write_file(file_path, " ", empty: true)
|
334
|
+
|
335
|
+
assert File.exist?(file_path)
|
336
|
+
assert_equal "", read_file(file_path) # No newline added
|
337
|
+
end
|
338
|
+
|
339
|
+
def test_036_write_file_empty_true_existing_file
|
340
|
+
file_path = "#{@test_dir}/empty_true_existing.txt"
|
341
|
+
|
342
|
+
# Create file with content first
|
343
|
+
write_file(file_path, "original content")
|
344
|
+
original_size = File.size(file_path)
|
345
|
+
|
346
|
+
# Now write empty content with empty: true
|
347
|
+
write_file(file_path, "", empty: true)
|
348
|
+
|
349
|
+
assert File.exist?(file_path)
|
350
|
+
assert_equal "original content\n", read_file(file_path) # File should preserve original content
|
351
|
+
assert_equal original_size, File.size(file_path) # File size should be unchanged
|
352
|
+
end
|
353
|
+
|
354
|
+
def test_037_write_file_empty_true_with_content
|
355
|
+
file_path = "#{@test_dir}/empty_true_with_content.txt"
|
356
|
+
content = "some content"
|
357
|
+
|
358
|
+
# empty: true should be ignored when there's actual content
|
359
|
+
write_file(file_path, content, empty: true)
|
360
|
+
|
361
|
+
assert File.exist?(file_path)
|
362
|
+
assert_equal content + "\n", read_file(file_path) # Normal behavior
|
363
|
+
end
|
364
|
+
|
365
|
+
# ========================================
|
366
|
+
# write_file! tests
|
367
|
+
# ========================================
|
368
|
+
|
369
|
+
def test_038_write_file_bang_basic_functionality
|
370
|
+
file_path = "#{@test_dir}/bang_basic.txt"
|
371
|
+
|
372
|
+
write_file!(file_path, "line1", "line2", "line3")
|
373
|
+
|
374
|
+
assert File.exist?(file_path)
|
375
|
+
assert_equal "line1\nline2\nline3\n", read_file(file_path)
|
376
|
+
end
|
377
|
+
|
378
|
+
def test_039_write_file_bang_empty_true_no_lines
|
379
|
+
file_path = "#{@test_dir}/bang_empty_true.txt"
|
380
|
+
|
381
|
+
# Should create file with empty: true when no lines provided
|
382
|
+
write_file!(file_path, empty: true)
|
383
|
+
|
384
|
+
assert File.exist?(file_path)
|
385
|
+
assert_equal "", read_file(file_path) # No newline added
|
386
|
+
end
|
387
|
+
|
388
|
+
def test_040_write_file_bang_empty_true_nil_lines
|
389
|
+
file_path = "#{@test_dir}/bang_empty_true_nil.txt"
|
390
|
+
|
391
|
+
# Should create file with empty: true when all lines are nil
|
392
|
+
write_file!(file_path, nil, nil, nil, empty: true)
|
393
|
+
|
394
|
+
assert File.exist?(file_path)
|
395
|
+
assert_equal "", read_file(file_path) # No newline added
|
396
|
+
end
|
397
|
+
|
398
|
+
def test_041_write_file_bang_empty_true_whitespace_lines
|
399
|
+
file_path = "#{@test_dir}/bang_empty_true_whitespace.txt"
|
400
|
+
|
401
|
+
# Should create file with empty: true when all lines are whitespace
|
402
|
+
write_file!(file_path, "", " ", "", empty: true)
|
403
|
+
|
404
|
+
assert File.exist?(file_path)
|
405
|
+
assert_equal "", read_file(file_path) # No newline added
|
406
|
+
end
|
407
|
+
|
408
|
+
def test_042_write_file_bang_empty_true_with_content
|
409
|
+
file_path = "#{@test_dir}/bang_empty_true_with_content.txt"
|
410
|
+
|
411
|
+
# empty: true should be ignored when there's actual content
|
412
|
+
write_file!(file_path, "line1", "", "line3", empty: true)
|
413
|
+
|
414
|
+
assert File.exist?(file_path)
|
415
|
+
assert_equal "line1\n\nline3\n", read_file(file_path) # Normal behavior
|
416
|
+
end
|
417
|
+
|
311
418
|
# ========================================
|
312
419
|
# read_file tests
|
313
420
|
# ========================================
|
@@ -315,27 +422,27 @@ class TestReadWrite < Minitest::Test
|
|
315
422
|
def test_033_read_file_basic_functionality
|
316
423
|
file_path = "#{@test_dir}/read_test.txt"
|
317
424
|
content = "line1\nline2\nline3"
|
318
|
-
|
425
|
+
write_file(file_path, content)
|
319
426
|
|
320
427
|
result = read_file(file_path)
|
321
428
|
|
322
|
-
assert_equal content, result
|
429
|
+
assert_equal content + "\n", result
|
323
430
|
end
|
324
431
|
|
325
432
|
def test_034_read_file_as_lines
|
326
433
|
file_path = "#{@test_dir}/lines_test.txt"
|
327
434
|
content = "line1\nline2\nline3"
|
328
|
-
|
435
|
+
write_file(file_path, content)
|
329
436
|
|
330
437
|
result = read_file(file_path, lines: true)
|
331
438
|
|
332
|
-
assert_equal ["line1\n", "line2\n", "line3"], result
|
439
|
+
assert_equal ["line1\n", "line2\n", "line3\n"], result
|
333
440
|
end
|
334
441
|
|
335
442
|
def test_035_read_file_as_lines_with_chomp
|
336
443
|
file_path = "#{@test_dir}/chomp_test.txt"
|
337
444
|
content = "line1\nline2\nline3\n"
|
338
|
-
|
445
|
+
write_file(file_path, content)
|
339
446
|
|
340
447
|
result = read_file(file_path, lines: true, chomp: true)
|
341
448
|
|
@@ -345,7 +452,7 @@ class TestReadWrite < Minitest::Test
|
|
345
452
|
def test_036_read_file_as_lines_without_chomp
|
346
453
|
file_path = "#{@test_dir}/no_chomp_test.txt"
|
347
454
|
content = "line1\nline2\nline3\n"
|
348
|
-
|
455
|
+
write_file(file_path, content)
|
349
456
|
|
350
457
|
result = read_file(file_path, lines: true, chomp: false)
|
351
458
|
|
@@ -364,25 +471,25 @@ class TestReadWrite < Minitest::Test
|
|
364
471
|
def test_038_read_file_missing_file_without_fallback_raises_error
|
365
472
|
file_path = "#{@test_dir}/nonexistent.txt"
|
366
473
|
|
367
|
-
assert_raises(
|
474
|
+
assert_raises(ReadFileNotFound) do
|
368
475
|
read_file(file_path)
|
369
476
|
end
|
370
477
|
end
|
371
478
|
|
372
479
|
def test_039_read_file_nil_path_raises_error
|
373
|
-
assert_raises(
|
480
|
+
assert_raises(ReadFilePathNil) do
|
374
481
|
read_file(nil)
|
375
482
|
end
|
376
483
|
end
|
377
484
|
|
378
485
|
def test_040_read_file_empty_path_raises_error
|
379
|
-
assert_raises(
|
486
|
+
assert_raises(ReadFilePathEmpty) do
|
380
487
|
read_file("")
|
381
488
|
end
|
382
489
|
end
|
383
490
|
|
384
491
|
def test_041_read_file_whitespace_path_raises_error
|
385
|
-
assert_raises(
|
492
|
+
assert_raises(ReadFilePathEmpty) do
|
386
493
|
read_file(" ")
|
387
494
|
end
|
388
495
|
end
|
@@ -390,10 +497,10 @@ class TestReadWrite < Minitest::Test
|
|
390
497
|
def test_042_read_file_permission_denied_simulation
|
391
498
|
# Create a file and make it unreadable
|
392
499
|
file_path = "#{@test_dir}/unreadable.txt"
|
393
|
-
|
500
|
+
write_file(file_path, "content")
|
394
501
|
FileUtils.chmod(0000, file_path)
|
395
502
|
|
396
|
-
assert_raises(
|
503
|
+
assert_raises(ReadFilePermissionDenied) do
|
397
504
|
read_file(file_path)
|
398
505
|
end
|
399
506
|
|
@@ -403,46 +510,46 @@ class TestReadWrite < Minitest::Test
|
|
403
510
|
|
404
511
|
def test_043_read_file_empty_file
|
405
512
|
file_path = "#{@test_dir}/empty.txt"
|
406
|
-
|
513
|
+
write_file(file_path, "")
|
407
514
|
|
408
515
|
result = read_file(file_path)
|
409
516
|
|
410
|
-
assert_equal "", result
|
517
|
+
assert_equal "\n", result
|
411
518
|
end
|
412
519
|
|
413
520
|
def test_044_read_file_empty_file_as_lines
|
414
521
|
file_path = "#{@test_dir}/empty_lines.txt"
|
415
|
-
|
522
|
+
write_file(file_path, "")
|
416
523
|
|
417
524
|
result = read_file(file_path, lines: true)
|
418
525
|
|
419
|
-
assert_equal [], result
|
526
|
+
assert_equal ["\n"], result
|
420
527
|
end
|
421
528
|
|
422
529
|
def test_045_read_file_single_line
|
423
530
|
file_path = "#{@test_dir}/single_line.txt"
|
424
531
|
content = "single line"
|
425
|
-
|
532
|
+
write_file(file_path, content)
|
426
533
|
|
427
534
|
result = read_file(file_path)
|
428
535
|
|
429
|
-
assert_equal content, result
|
536
|
+
assert_equal content + "\n", result
|
430
537
|
end
|
431
538
|
|
432
539
|
def test_046_read_file_single_line_as_lines
|
433
540
|
file_path = "#{@test_dir}/single_line.txt"
|
434
541
|
content = "single line"
|
435
|
-
|
542
|
+
write_file(file_path, content)
|
436
543
|
|
437
544
|
result = read_file(file_path, lines: true)
|
438
545
|
|
439
|
-
assert_equal [content], result
|
546
|
+
assert_equal [content + "\n"], result
|
440
547
|
end
|
441
548
|
|
442
549
|
def test_047_read_file_with_trailing_newline
|
443
550
|
file_path = "#{@test_dir}/trailing_newline.txt"
|
444
551
|
content = "line1\nline2\n"
|
445
|
-
|
552
|
+
write_file(file_path, content)
|
446
553
|
|
447
554
|
result = read_file(file_path)
|
448
555
|
|
@@ -452,7 +559,7 @@ class TestReadWrite < Minitest::Test
|
|
452
559
|
def test_048_read_file_with_trailing_newline_as_lines
|
453
560
|
file_path = "#{@test_dir}/trailing_newline.txt"
|
454
561
|
content = "line1\nline2\n"
|
455
|
-
|
562
|
+
write_file(file_path, content)
|
456
563
|
|
457
564
|
result = read_file(file_path, lines: true)
|
458
565
|
|
@@ -462,7 +569,7 @@ class TestReadWrite < Minitest::Test
|
|
462
569
|
def test_049_read_file_with_trailing_newline_as_lines_no_chomp
|
463
570
|
file_path = "#{@test_dir}/trailing_newline.txt"
|
464
571
|
content = "line1\nline2\n"
|
465
|
-
|
572
|
+
write_file(file_path, content)
|
466
573
|
|
467
574
|
result = read_file(file_path, lines: true, chomp: false)
|
468
575
|
|
@@ -507,11 +614,11 @@ class TestReadWrite < Minitest::Test
|
|
507
614
|
|
508
615
|
# First write
|
509
616
|
write_file(file_path, "first content")
|
510
|
-
assert_equal "first content\n",
|
617
|
+
assert_equal "first content\n", read_file(file_path)
|
511
618
|
|
512
619
|
# Second write (should overwrite)
|
513
620
|
write_file(file_path, "second content")
|
514
|
-
assert_equal "second content\n",
|
621
|
+
assert_equal "second content\n", read_file(file_path)
|
515
622
|
end
|
516
623
|
|
517
624
|
def test_053_write_file_with_special_characters
|
@@ -638,9 +745,9 @@ class TestReadWrite < Minitest::Test
|
|
638
745
|
end
|
639
746
|
|
640
747
|
def test_063_get_asset_path
|
641
|
-
name = "back
|
748
|
+
name = "back.png"
|
642
749
|
result = get_asset_path(name)
|
643
|
-
assert result == "assets/#{name}", "Expected #{name} to be
|
750
|
+
assert result == "assets/icons/ui/#{name}", "Expected #{name} to be found recursively (got #{result})"
|
644
751
|
assert_raises(AssetNotFound) { get_asset_path("nonexistent.png") }
|
645
752
|
end
|
646
753
|
|
@@ -734,7 +841,7 @@ class TestReadWrite < Minitest::Test
|
|
734
841
|
|
735
842
|
def test_073_getvars_basic
|
736
843
|
config_file = "#{@test_dir}/config.txt"
|
737
|
-
|
844
|
+
write_file(config_file, <<~EOS)
|
738
845
|
title My Blog
|
739
846
|
subtitle A test blog
|
740
847
|
theme standard
|
@@ -748,7 +855,7 @@ class TestReadWrite < Minitest::Test
|
|
748
855
|
|
749
856
|
def test_074_getvars_with_comments
|
750
857
|
config_file = "#{@test_dir}/config_with_comments.txt"
|
751
|
-
|
858
|
+
write_file(config_file, <<~EOS)
|
752
859
|
# This is a comment
|
753
860
|
title My Blog # Another comment
|
754
861
|
subtitle A test blog
|
@@ -766,7 +873,7 @@ class TestReadWrite < Minitest::Test
|
|
766
873
|
|
767
874
|
def test_075_getvars_with_empty_values
|
768
875
|
config_file = "#{@test_dir}/config_empty.txt"
|
769
|
-
|
876
|
+
write_file(config_file, <<~EOS)
|
770
877
|
title My Blog
|
771
878
|
subtitle
|
772
879
|
theme standard
|
@@ -774,7 +881,7 @@ class TestReadWrite < Minitest::Test
|
|
774
881
|
|
775
882
|
result = getvars(config_file)
|
776
883
|
assert_equal "My Blog", result[:title]
|
777
|
-
|
884
|
+
assert_equal "", result[:subtitle] # When no value after key, split returns empty string
|
778
885
|
assert_equal "standard", result[:theme]
|
779
886
|
end
|
780
887
|
|
@@ -822,7 +929,7 @@ class TestReadWrite < Minitest::Test
|
|
822
929
|
|
823
930
|
def test_081_make_tree_basic
|
824
931
|
tree_text = <<~EOS
|
825
|
-
|
932
|
+
.
|
826
933
|
├── file1.txt
|
827
934
|
├── dir1/
|
828
935
|
│ ├── file2.txt
|
@@ -831,7 +938,7 @@ class TestReadWrite < Minitest::Test
|
|
831
938
|
└── file4.txt
|
832
939
|
EOS
|
833
940
|
|
834
|
-
make_tree(@test_dir, tree_text)
|
941
|
+
make_tree("#{@test_dir}/test_tree", tree_text)
|
835
942
|
|
836
943
|
assert File.exist?("#{@test_dir}/test_tree/file1.txt")
|
837
944
|
assert File.exist?("#{@test_dir}/test_tree/dir1/file2.txt")
|
@@ -841,17 +948,264 @@ class TestReadWrite < Minitest::Test
|
|
841
948
|
|
842
949
|
def test_082_make_tree_with_comments
|
843
950
|
tree_text = <<~EOS
|
844
|
-
|
951
|
+
.
|
845
952
|
├── file1.txt # This is a comment
|
846
953
|
├── dir1/ # Another comment
|
847
954
|
│ └── file2.txt
|
848
955
|
└── file3.txt
|
849
956
|
EOS
|
850
957
|
|
851
|
-
make_tree(@test_dir, tree_text)
|
958
|
+
make_tree("#{@test_dir}/test_tree_with_comments", tree_text)
|
852
959
|
|
853
960
|
assert File.exist?("#{@test_dir}/test_tree_with_comments/file1.txt")
|
854
961
|
assert File.exist?("#{@test_dir}/test_tree_with_comments/dir1/file2.txt")
|
855
962
|
assert File.exist?("#{@test_dir}/test_tree_with_comments/file3.txt")
|
856
963
|
end
|
964
|
+
|
965
|
+
def test_083_make_tree_simplified
|
966
|
+
tree_text = <<~EOS
|
967
|
+
.
|
968
|
+
├── config/
|
969
|
+
├── views/
|
970
|
+
├── drafts/
|
971
|
+
├── posts/
|
972
|
+
├── assets/
|
973
|
+
│ └── library/
|
974
|
+
└── themes/
|
975
|
+
EOS
|
976
|
+
|
977
|
+
target_dir = "#{@test_dir}/simplified_tree"
|
978
|
+
make_tree(target_dir, tree_text)
|
979
|
+
|
980
|
+
assert File.exist?("#{target_dir}/config")
|
981
|
+
assert File.exist?("#{target_dir}/views")
|
982
|
+
assert File.exist?("#{target_dir}/drafts")
|
983
|
+
assert File.exist?("#{target_dir}/posts")
|
984
|
+
assert File.exist?("#{target_dir}/assets/library")
|
985
|
+
assert File.exist?("#{target_dir}/themes")
|
986
|
+
end
|
987
|
+
|
988
|
+
# ========================================
|
989
|
+
# Additional exception tests for untested exceptions
|
990
|
+
# ========================================
|
991
|
+
|
992
|
+
def test_093_general_validation_exceptions
|
993
|
+
# Test that exception classes exist
|
994
|
+
assert NilValueError
|
995
|
+
assert EmptyValueError
|
996
|
+
assert InvalidFormatError
|
997
|
+
|
998
|
+
# Test actual exception raising for some that we can trigger
|
999
|
+
assert_raises(InvalidType) do
|
1000
|
+
need(:invalid_type, "some/path")
|
1001
|
+
end
|
1002
|
+
|
1003
|
+
# Test require path exceptions
|
1004
|
+
assert_raises(RequirePathNil) do
|
1005
|
+
need(:file, nil)
|
1006
|
+
end
|
1007
|
+
|
1008
|
+
assert_raises(RequirePathEmpty) do
|
1009
|
+
need(:file, "")
|
1010
|
+
end
|
1011
|
+
end
|
1012
|
+
|
1013
|
+
def test_094_repository_exceptions
|
1014
|
+
# Test RepoDirAlreadyExists
|
1015
|
+
assert RepoDirAlreadyExists
|
1016
|
+
|
1017
|
+
# Test ViewDirDoesntExist
|
1018
|
+
assert ViewDirDoesntExist
|
1019
|
+
|
1020
|
+
# Test ThemeFileNotFound
|
1021
|
+
assert ThemeFileNotFound
|
1022
|
+
|
1023
|
+
# Test NoGemPath
|
1024
|
+
assert NoGemPath
|
1025
|
+
end
|
1026
|
+
|
1027
|
+
def test_095_file_io_exceptions
|
1028
|
+
# Test that exception classes exist
|
1029
|
+
assert FileNotFoundError
|
1030
|
+
assert DirectoryNotFoundError
|
1031
|
+
assert FileDiskFull
|
1032
|
+
assert FileDirectoryNotFound
|
1033
|
+
assert CannotWriteFileError
|
1034
|
+
assert DirectoryParentNotFound
|
1035
|
+
assert DirectoryDiskFull
|
1036
|
+
assert DirectoryError
|
1037
|
+
assert ReadFileError
|
1038
|
+
|
1039
|
+
# Test actual exception raising for some that we can trigger
|
1040
|
+
assert_raises(ReadFilePathNil) do
|
1041
|
+
read_file(nil)
|
1042
|
+
end
|
1043
|
+
|
1044
|
+
assert_raises(ReadFilePathEmpty) do
|
1045
|
+
read_file("")
|
1046
|
+
end
|
1047
|
+
|
1048
|
+
assert_raises(FilePathNil) do
|
1049
|
+
write_file(nil, "content")
|
1050
|
+
end
|
1051
|
+
|
1052
|
+
assert_raises(FilePathEmpty) do
|
1053
|
+
write_file("", "content")
|
1054
|
+
end
|
1055
|
+
|
1056
|
+
# Test directory-related exceptions
|
1057
|
+
assert_raises(DirectoryPathNil) do
|
1058
|
+
make_dir(nil)
|
1059
|
+
end
|
1060
|
+
|
1061
|
+
assert_raises(DirectoryPathEmpty) do
|
1062
|
+
make_dir("")
|
1063
|
+
end
|
1064
|
+
end
|
1065
|
+
|
1066
|
+
def test_096_command_system_exceptions
|
1067
|
+
# Test that exception classes exist
|
1068
|
+
assert CommandFailed
|
1069
|
+
assert CannotExecuteCommand
|
1070
|
+
assert SectionOutputError
|
1071
|
+
assert WriteFrontPageError
|
1072
|
+
|
1073
|
+
# Test actual exception raising for some that we can trigger
|
1074
|
+
assert_raises(CommandNil) do
|
1075
|
+
system!(nil)
|
1076
|
+
end
|
1077
|
+
|
1078
|
+
assert_raises(CommandEmpty) do
|
1079
|
+
system!("")
|
1080
|
+
end
|
1081
|
+
end
|
1082
|
+
|
1083
|
+
def test_097_validation_exceptions
|
1084
|
+
# Test ViewTargetNil
|
1085
|
+
assert ViewTargetNil
|
1086
|
+
|
1087
|
+
# Test ViewTargetEmpty
|
1088
|
+
assert ViewTargetEmpty
|
1089
|
+
|
1090
|
+
# Test ViewTargetInvalid
|
1091
|
+
assert ViewTargetInvalid
|
1092
|
+
|
1093
|
+
# Test PostIdNil
|
1094
|
+
assert PostIdNil
|
1095
|
+
|
1096
|
+
# Test PostIdEmpty
|
1097
|
+
assert PostIdEmpty
|
1098
|
+
|
1099
|
+
# Test PostIdInvalid
|
1100
|
+
assert PostIdInvalid
|
1101
|
+
|
1102
|
+
# Test CannotCreateView
|
1103
|
+
assert CannotCreateView
|
1104
|
+
|
1105
|
+
# Test CannotBuildWidget
|
1106
|
+
assert CannotBuildWidget
|
1107
|
+
|
1108
|
+
# Test CannotGetPost
|
1109
|
+
assert CannotGetPost
|
1110
|
+
|
1111
|
+
# Test CannotSetPubdate
|
1112
|
+
assert CannotSetPubdate
|
1113
|
+
end
|
1114
|
+
|
1115
|
+
# ========================================
|
1116
|
+
# format_date() tests
|
1117
|
+
# ========================================
|
1118
|
+
|
1119
|
+
def test_001_format_date_basic_functionality
|
1120
|
+
# Test basic date formatting
|
1121
|
+
result = format_date("month dd yyyy", Date.new(2025, 2, 22))
|
1122
|
+
assert_equal "February 22 2025", result
|
1123
|
+
end
|
1124
|
+
|
1125
|
+
def test_002_format_date_with_ordinal
|
1126
|
+
# Test ordinal day formatting
|
1127
|
+
result = format_date("month day, yyyy", Date.new(2025, 2, 22))
|
1128
|
+
assert_equal "February 22nd, 2025", result
|
1129
|
+
end
|
1130
|
+
|
1131
|
+
def test_003_format_date_with_break
|
1132
|
+
# Test line break formatting
|
1133
|
+
result = format_date("month dd break yyyy", Date.new(2025, 2, 22))
|
1134
|
+
assert_equal "February 22<br>2025", result
|
1135
|
+
end
|
1136
|
+
|
1137
|
+
def test_004_format_date_string_input
|
1138
|
+
# Test string date input
|
1139
|
+
result = format_date("dd month yyyy", "2025-02-22")
|
1140
|
+
assert_equal "22 February 2025", result
|
1141
|
+
end
|
1142
|
+
|
1143
|
+
def test_005_format_date_nil_input
|
1144
|
+
# Test nil date input (should return original format)
|
1145
|
+
result = format_date("month dd yyyy", nil)
|
1146
|
+
assert_equal "month dd yyyy", result
|
1147
|
+
end
|
1148
|
+
|
1149
|
+
def test_006_format_date_invalid_string
|
1150
|
+
# Test invalid date string (should return original format)
|
1151
|
+
result = format_date("month dd yyyy", "invalid-date")
|
1152
|
+
assert_equal "month dd yyyy", result
|
1153
|
+
end
|
1154
|
+
|
1155
|
+
def test_007_format_date_ordinal_edge_cases
|
1156
|
+
# Test ordinal edge cases
|
1157
|
+
assert_equal "1st", ordinalize(1)
|
1158
|
+
assert_equal "2nd", ordinalize(2)
|
1159
|
+
assert_equal "3rd", ordinalize(3)
|
1160
|
+
assert_equal "4th", ordinalize(4)
|
1161
|
+
assert_equal "11th", ordinalize(11)
|
1162
|
+
assert_equal "12th", ordinalize(12)
|
1163
|
+
assert_equal "13th", ordinalize(13)
|
1164
|
+
assert_equal "21st", ordinalize(21)
|
1165
|
+
assert_equal "22nd", ordinalize(22)
|
1166
|
+
assert_equal "23rd", ordinalize(23)
|
1167
|
+
end
|
1168
|
+
|
1169
|
+
def test_008_format_date_various_formats
|
1170
|
+
# Test various format combinations
|
1171
|
+
date = Date.new(2025, 2, 22)
|
1172
|
+
|
1173
|
+
assert_equal "02/22/2025", format_date("mm/dd/yyyy", date)
|
1174
|
+
assert_equal "22/02/25", format_date("dd/mm/yy", date)
|
1175
|
+
assert_equal "February 22nd, 2025", format_date("month day, yyyy", date)
|
1176
|
+
assert_equal "22 February 2025", format_date("dd month yyyy", date)
|
1177
|
+
assert_equal "February 22<br>2025", format_date("month dd break yyyy", date)
|
1178
|
+
end
|
1179
|
+
|
1180
|
+
def test_009_format_date_smart_padding
|
1181
|
+
# Test smart padding logic
|
1182
|
+
date = Date.new(2025, 7, 4)
|
1183
|
+
|
1184
|
+
# Should pad when surrounded by punctuation
|
1185
|
+
assert_equal "04/07/2025", format_date("dd/mm/yyyy", date)
|
1186
|
+
assert_equal "07/04/2025", format_date("mm/dd/yyyy", date)
|
1187
|
+
assert_equal "2025-07-04", format_date("yyyy-mm-dd", date)
|
1188
|
+
assert_equal "04.07.2025", format_date("dd.mm.yyyy", date)
|
1189
|
+
|
1190
|
+
# Should not pad when surrounded by spaces
|
1191
|
+
assert_equal "July 4, 2025", format_date("month dd, yyyy", date)
|
1192
|
+
assert_equal "4 July 2025", format_date("dd month yyyy", date)
|
1193
|
+
assert_equal "July 4 2025", format_date("month dd yyyy", date)
|
1194
|
+
end
|
1195
|
+
|
1196
|
+
private
|
1197
|
+
|
1198
|
+
def ordinalize(number)
|
1199
|
+
case number % 100
|
1200
|
+
when 11, 12, 13
|
1201
|
+
"#{number}th"
|
1202
|
+
else
|
1203
|
+
case number % 10
|
1204
|
+
when 1 then "#{number}st"
|
1205
|
+
when 2 then "#{number}nd"
|
1206
|
+
when 3 then "#{number}rd"
|
1207
|
+
else "#{number}th"
|
1208
|
+
end
|
1209
|
+
end
|
1210
|
+
end
|
857
1211
|
end
|