scriptorium 0.0.3 → 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/README.lt3 +324 -0
- data/README.md +3155 -1
- data/assets/.DS_Store +0 -0
- data/assets/README.md +44 -0
- data/assets/icons/social/reddit.png +0 -0
- data/assets/icons/social/x-logo.png +0 -0
- data/assets/icons/ui/.DS_Store +0 -0
- data/assets/icons/ui/back.png +0 -0
- data/assets/icons/ui/copy.png +0 -0
- data/assets/icons/ui/down.png +0 -0
- data/assets/icons/ui/end.png +0 -0
- data/assets/icons/ui/exit.png +0 -0
- data/assets/icons/ui/foo +10 -0
- data/assets/icons/ui/home.png +0 -0
- data/assets/icons/ui/left.png +0 -0
- data/assets/icons/ui/next.png +0 -0
- data/assets/icons/ui/right.png +0 -0
- data/assets/icons/ui/start.png +0 -0
- data/assets/icons/ui/up.png +0 -0
- data/assets/imagenotfound.jpg +0 -0
- data/assets/samples/placeholder.svg +9 -0
- data/assets/themes/standard/favicon.svg +6 -0
- data/bin/sblog +84 -5
- data/bin/scriptorium +1 -0
- data/doc/README.txt +6 -0
- data/doc/anti-amnesia/20250727-054000-scriptorium-overview.md +94 -0
- data/doc/anti-amnesia/20250727-123000-anti-amnesia-conventions.md +2 -0
- data/doc/anti-amnesia/20250727-172600-cursor-rbenv-ruby-version-mystery.md +45 -0
- data/doc/anti-amnesia/20250727-172900-ai-cognitive-assessment-capabilities.md +40 -0
- data/doc/anti-amnesia/20250728-124243-aaa-syntax-clarification.md +46 -0
- data/doc/anti-amnesia/20250729-210000-reddit-autopost-integration-complete.md +158 -0
- data/doc/anti-amnesia/20250804-190500-cognitive-loop-bug.md +35 -0
- data/doc/anti-amnesia/20250804-190700-anti-amnesia-timestamping-fix.md +27 -0
- data/doc/anti-amnesia/20250807-213025.md +116 -0
- 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/banner_svg_config.md +114 -0
- data/doc/contrib.lt3 +8 -0
- data/doc/dependencies.md +281 -0
- data/doc/hacker.lt3 +5 -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/myuserdoc/userdoc-toc.txt +88 -0
- 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_credentials_template.json +8 -0
- data/doc/reddit_integration.md +207 -0
- data/doc/user.lt3 +35 -0
- data/doc/user_guide_section_1.md +137 -0
- data/doc/user_guide_section_10.md +515 -0
- data/doc/user_guide_section_11.md +708 -0
- data/doc/user_guide_section_2.md +233 -0
- data/doc/user_guide_section_3.md +5 -0
- data/doc/user_guide_section_4.md +221 -0
- data/doc/user_guide_section_5.md +243 -0
- data/doc/user_guide_section_6.md +147 -0
- data/doc/user_guide_section_7.md +311 -0
- data/doc/user_guide_section_8.md +224 -0
- data/doc/user_guide_section_9.md +375 -0
- data/lib/rouge/lexers/livetext.rb +74 -0
- data/lib/scriptorium/api.rb +2373 -0
- data/lib/scriptorium/banner_svg.rb +729 -0
- data/lib/scriptorium/contract.rb +34 -0
- data/lib/scriptorium/exceptions.rb +201 -1
- data/lib/scriptorium/helpers.rb +675 -0
- data/lib/scriptorium/post.rb +259 -0
- data/lib/scriptorium/reddit.rb +83 -0
- data/lib/scriptorium/repo.rb +938 -0
- data/lib/scriptorium/standard_files.rb +149 -0
- data/lib/scriptorium/support/bootstrap/css.txt +5 -0
- data/lib/scriptorium/support/bootstrap/js.txt +4 -0
- 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.txt +10 -0
- data/lib/scriptorium/support/config/reddit_template.txt +17 -0
- data/lib/scriptorium/support/config/social.txt +8 -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/lib/scriptorium/support/templates/initial_post.lt3 +12 -0
- data/lib/scriptorium/support/templates/layout.txt +5 -0
- data/lib/scriptorium/support/templates/post.lt3 +104 -0
- data/lib/scriptorium/support/theme/footer.lt3 +2 -0
- data/lib/scriptorium/support/theme/header.lt3 +4 -0
- data/lib/scriptorium/support/theme/left.lt3 +3 -0
- data/lib/scriptorium/support/theme/main.lt3 +5 -0
- data/lib/scriptorium/support/theme/right.lt3 +3 -0
- data/lib/scriptorium/theme.rb +192 -0
- data/lib/scriptorium/version.rb +1 -1
- data/lib/scriptorium/view.rb +1021 -0
- data/lib/scriptorium/widgets/featured_posts.rb +149 -0
- data/lib/scriptorium/widgets/links.rb +112 -0
- data/lib/scriptorium/widgets/pages.rb +133 -0
- data/lib/scriptorium/widgets/widget.rb +133 -0
- data/lib/scriptorium.rb +38 -34
- data/lib/skeleton.rb +10 -1
- data/scriptorium.gemspec +17 -5
- data/test/README.md +69 -0
- data/test/WEB_INTEGRATION_README.md +196 -0
- data/test/all +83 -0
- data/test/api_demo.rb +99 -0
- data/test/assets/imagenotfound.jpg +0 -0
- data/test/assets/images/.DS_Store +0 -0
- data/test/assets/images/README.md +27 -0
- data/test/assets/images/odd_aspect.png +0 -0
- data/test/assets/images/perfect.png +0 -0
- data/test/assets/images/small.png +0 -0
- data/test/assets/images/tall.png +0 -0
- data/test/assets/images/very_tall.png +0 -0
- data/test/assets/images/very_wide.png +0 -0
- data/test/assets/images/wide.png +0 -0
- data/test/assets/testbanner.jpg +0 -0
- data/test/banner_svg/simple_helpers.rb +13 -0
- data/test/banner_svg/unit.rb +1000 -0
- data/test/config/deployment.txt +5 -0
- data/test/ed_test.rb +204 -0
- data/test/integration/cursor_banner_combinations.rb +193 -0
- data/test/integration/cursor_banner_features.rb +374 -0
- data/test/integration/integration_test.rb +326 -0
- data/test/integration/preview_flow_test.rb +94 -0
- data/test/livetext_plugin_test.rb +500 -0
- data/test/manual/asset_mgmt.rb +67 -0
- data/test/manual/banner-tests/index.html +45 -0
- data/test/manual/banner-tests/svg.txt +3 -0
- data/test/manual/banner-tests/test01.html +122 -0
- data/test/manual/banner-tests/test02.html +122 -0
- data/test/manual/banner-tests/test03.html +122 -0
- data/test/manual/banner-tests/test04.html +129 -0
- data/test/manual/banner-tests/test05.html +129 -0
- data/test/manual/banner-tests/test06.html +129 -0
- data/test/manual/banner-tests/test07.html +129 -0
- data/test/manual/banner-tests/test08.html +123 -0
- data/test/manual/banner-tests/test09.html +123 -0
- data/test/manual/banner-tests/test10.html +123 -0
- data/test/manual/banner-tests/test11.html +123 -0
- data/test/manual/banner-tests/test12.html +123 -0
- data/test/manual/banner-tests/test13.html +123 -0
- data/test/manual/banner-tests/test14.html +123 -0
- data/test/manual/banner-tests/test15.html +122 -0
- data/test/manual/banner-tests/test16.html +122 -0
- data/test/manual/banner-tests/test17.html +122 -0
- data/test/manual/banner-tests/test18.html +132 -0
- data/test/manual/banner-tests/test19.html +132 -0
- data/test/manual/banner-tests/test20.html +132 -0
- data/test/manual/banner-tests/test21.html +132 -0
- data/test/manual/banner-tests/test22.html +132 -0
- data/test/manual/banner-tests/test23.html +132 -0
- data/test/manual/banner-tests/test24.html +132 -0
- data/test/manual/banner-tests/test25.html +131 -0
- data/test/manual/banner_environment.rb +205 -0
- data/test/manual/codemirror_demo.html +773 -0
- data/test/manual/create_posts_for_web.rb +114 -0
- data/test/manual/environment.rb +67 -0
- data/test/manual/make_banner.rb +153 -0
- data/test/manual/preview_manual_test.rb +129 -0
- data/test/manual/sample_banner_config.txt +12 -0
- data/test/manual/test_advanced_widgets.rb +73 -0
- data/test/manual/test_banner_combinations.rb +120 -0
- data/test/manual/test_banner_features.rb +306 -0
- data/test/manual/test_banner_integration.rb +115 -0
- data/test/manual/test_banner_radial.rb +87 -0
- data/test/manual/test_basic_posts.rb +47 -0
- data/test/manual/test_layout_widgets.rb +40 -0
- data/test/manual/test_pagination.rb +24 -0
- data/test/manual/test_random_posts.rb +38 -0
- data/test/manual/test_syntax_highlighting.rb +167 -0
- data/test/rubytext/rubytext_comprehensive_test.rb +307 -0
- data/test/rubytext/rubytext_demo_test.rb +42 -0
- data/test/rubytext/rubytext_testing_guide.md +277 -0
- data/test/run_automated_tests.rb +45 -0
- data/test/staging/.DS_Store +0 -0
- data/test/support/preview_utils.rb +88 -0
- data/test/syntax_highlighting_test.lt3 +124 -0
- data/test/test_gem_assets.rb +48 -0
- data/test/test_helpers.rb +240 -0
- data/test/tui_editor_integration_test.rb +296 -0
- data/test/tui_integration_test.rb +883 -0
- data/test/unit/api.rb +1776 -0
- data/test/unit/asset_management.rb +219 -0
- data/test/unit/backup_test.rb +451 -0
- data/test/unit/clipboard_test.rb +60 -0
- data/test/unit/contract_test.rb +69 -0
- data/test/unit/core.rb +1211 -0
- data/test/unit/deploy_config_test.rb +248 -0
- data/test/unit/deploy_test.rb +478 -0
- data/test/unit/edit_post_test.rb +168 -0
- data/test/unit/gem_asset_management.rb +183 -0
- data/test/unit/livetext_basic.rb +57 -0
- data/test/unit/livetext_compatibility.rb +82 -0
- data/test/unit/parse_cmd_test.rb +260 -0
- data/test/unit/permalink_copy_test.rb +211 -0
- data/test/unit/post.rb +309 -0
- 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 +278 -0
- data/test/unit/reddit_test.rb +235 -0
- data/test/unit/repo.rb +569 -0
- data/test/unit/social_test.rb +366 -0
- data/test/unit/syntax_highlighting.rb +70 -0
- data/test/unit/theme_management_test.rb +91 -0
- data/test/unit/view.rb +498 -0
- data/test/unit/widgets.rb +669 -0
- 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/test/wizard_test.rb +123 -0
- data/ui/README.md +67 -0
- data/ui/common/lib/ui_common.rb +8 -0
- data/ui/rubytext/README.md +191 -0
- data/ui/rubytext/bin/scriptorium-rubytext +402 -0
- data/ui/rubytext/lib/rubytext_ui.rb +300 -0
- data/ui/tui/bin/scriptorium +1890 -0
- data/ui/tui/test/tui_test.rb +23 -0
- data/ui/web/app/app.rb +2600 -0
- data/ui/web/app/assets/livetext_mode.js +244 -0
- data/ui/web/app/error_helpers.rb +150 -0
- data/ui/web/app/views/advanced_config.erb +196 -0
- data/ui/web/app/views/asset_management.erb +645 -0
- data/ui/web/app/views/backup_management.erb +238 -0
- data/ui/web/app/views/banner_config.erb +200 -0
- data/ui/web/app/views/config_widget.erb +232 -0
- data/ui/web/app/views/configure_view.erb +401 -0
- data/ui/web/app/views/dashboard.erb +154 -0
- data/ui/web/app/views/deploy_config.erb +149 -0
- data/ui/web/app/views/edit_pages.erb +363 -0
- data/ui/web/app/views/edit_post.erb +175 -0
- 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/error_page.erb +29 -0
- data/ui/web/app/views/header_config.erb +155 -0
- data/ui/web/app/views/layout_config.erb +147 -0
- data/ui/web/app/views/navbar_config.erb +411 -0
- data/ui/web/app/views/theme_management.erb +130 -0
- data/ui/web/app/views/view_dashboard.erb +779 -0
- data/ui/web/app/views/widgets.erb +249 -0
- data/ui/web/bin/scriptorium-web +164 -0
- data/ui/web/test/web_basic_test.rb +38 -0
- data/ui/web/test_navbar.txt +7 -0
- data/ui/web/tmp/timing.log +17 -0
- data/ui/web/tmp/web_server.log +0 -0
- metadata +434 -8
- data/lib/scriptorium/engine.rb +0 -22
- data/test/engine/unit.rb +0 -44
@@ -0,0 +1,211 @@
|
|
1
|
+
# Test file for permalink copy functionality
|
2
|
+
# Tests the clean URL copy generation for posts
|
3
|
+
|
4
|
+
require 'minitest/autorun'
|
5
|
+
require_relative '../../lib/scriptorium'
|
6
|
+
require_relative '../test_helpers'
|
7
|
+
require 'fileutils'
|
8
|
+
|
9
|
+
class TestPermalinkCopy < Minitest::Test
|
10
|
+
include Scriptorium::Helpers
|
11
|
+
include TestHelpers
|
12
|
+
|
13
|
+
def setup
|
14
|
+
@test_dir = "test/symlink_test_files"
|
15
|
+
FileUtils.mkdir_p(@test_dir)
|
16
|
+
Scriptorium::Repo.testing = true
|
17
|
+
|
18
|
+
# Create test repository
|
19
|
+
@repo = Scriptorium::Repo.create("test/scriptorium-TEST", testmode: true)
|
20
|
+
@view = @repo.create_view("test_view", "Test View", "Test Subtitle")
|
21
|
+
end
|
22
|
+
|
23
|
+
def teardown
|
24
|
+
FileUtils.rm_rf(@test_dir) if File.exist?(@test_dir)
|
25
|
+
FileUtils.rm_rf("test/scriptorium-TEST") if File.exist?("test/scriptorium-TEST")
|
26
|
+
end
|
27
|
+
|
28
|
+
# ========================================
|
29
|
+
# clean_slugify function tests
|
30
|
+
# ========================================
|
31
|
+
|
32
|
+
def test_001_clean_slugify_basic
|
33
|
+
result = clean_slugify("My Test Post")
|
34
|
+
assert_equal "my-test-post", result
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_002_clean_slugify_with_special_characters
|
38
|
+
result = clean_slugify("Post with & < > \" ' characters!")
|
39
|
+
assert_equal "post-with-characters", result
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_003_clean_slugify_with_underscores_and_hyphens
|
43
|
+
result = clean_slugify("Post with_underscores-and-hyphens")
|
44
|
+
assert_equal "post-with-underscores-and-hyphens", result
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_004_clean_slugify_with_multiple_spaces
|
48
|
+
result = clean_slugify("Post with multiple spaces")
|
49
|
+
assert_equal "post-with-multiple-spaces", result
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_005_clean_slugify_with_leading_trailing_hyphens
|
53
|
+
result = clean_slugify("-Post with leading/trailing hyphens-")
|
54
|
+
assert_equal "post-with-leadingtrailing-hyphens", result
|
55
|
+
end
|
56
|
+
|
57
|
+
# ========================================
|
58
|
+
# Permalink copy generation tests
|
59
|
+
# ========================================
|
60
|
+
|
61
|
+
def test_006_permalink_copy_creation_for_post
|
62
|
+
# Create a test post
|
63
|
+
post_title = "My First Test Post"
|
64
|
+
post_body = "This is the body of my test post."
|
65
|
+
|
66
|
+
# Create draft and finish it
|
67
|
+
draft_name = @repo.create_draft(title: post_title, body: post_body)
|
68
|
+
post_num = @repo.finish_draft(draft_name)
|
69
|
+
|
70
|
+
# Generate the post
|
71
|
+
@repo.generate_post(post_num)
|
72
|
+
|
73
|
+
# Check that both files exist
|
74
|
+
numbered_slug = slugify(post_num, post_title) + ".html"
|
75
|
+
clean_slug = clean_slugify(post_title) + ".html"
|
76
|
+
|
77
|
+
numbered_path = @view.dir/:output/:permalink/numbered_slug
|
78
|
+
clean_symlink_path = @view.dir/:output/:permalink/clean_slug
|
79
|
+
|
80
|
+
# Both files should exist
|
81
|
+
assert File.exist?(numbered_path), "Numbered post file should exist: #{numbered_path}"
|
82
|
+
assert File.exist?(clean_symlink_path), "Clean symlink should exist: #{clean_symlink_path}"
|
83
|
+
|
84
|
+
# Clean copy should exist
|
85
|
+
assert File.exist?(clean_symlink_path), "Clean copy should exist"
|
86
|
+
|
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
|
+
end
|
92
|
+
|
93
|
+
def test_007_permalink_copy_has_correct_content
|
94
|
+
# Create a test post with a specific title
|
95
|
+
post_title = "Another Test Post"
|
96
|
+
post_body = "This is another test post."
|
97
|
+
|
98
|
+
# Create draft and finish it
|
99
|
+
draft_name = @repo.create_draft(title: post_title, body: post_body)
|
100
|
+
post_num = @repo.finish_draft(draft_name)
|
101
|
+
|
102
|
+
# Generate the post
|
103
|
+
@repo.generate_post(post_num)
|
104
|
+
|
105
|
+
# Check symlink target
|
106
|
+
clean_slug = clean_slugify(post_title) + ".html"
|
107
|
+
clean_symlink_path = @view.dir/:output/:permalink/clean_slug
|
108
|
+
|
109
|
+
assert File.exist?(clean_symlink_path), "Should be a copy"
|
110
|
+
|
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")
|
114
|
+
|
115
|
+
# Expected content should match the numbered file
|
116
|
+
assert_equal target_content, copy_content, "Copy should have same content as numbered file"
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_008_permalink_copy_overwrites_existing
|
120
|
+
# Create a test post
|
121
|
+
post_title = "Duplicate Test Post"
|
122
|
+
post_body = "This is a test post."
|
123
|
+
|
124
|
+
# Create draft and finish it
|
125
|
+
draft_name = @repo.create_draft(title: post_title, body: post_body)
|
126
|
+
post_num = @repo.finish_draft(draft_name)
|
127
|
+
|
128
|
+
# Generate the post (should create copy)
|
129
|
+
@repo.generate_post(post_num)
|
130
|
+
|
131
|
+
# Check that copy exists
|
132
|
+
clean_slug = clean_slugify(post_title) + ".html"
|
133
|
+
clean_symlink_path = @view.dir/:output/:permalink/clean_slug
|
134
|
+
|
135
|
+
assert File.exist?(clean_symlink_path), "Copy should exist"
|
136
|
+
|
137
|
+
# Get the original content
|
138
|
+
original_content = File.read(clean_symlink_path)
|
139
|
+
|
140
|
+
# Now create another post with the same clean slug (different numbered slug)
|
141
|
+
post_title2 = "Duplicate Test Post" # Same title, different post
|
142
|
+
post_body2 = "This is another test post with same title."
|
143
|
+
|
144
|
+
draft_name2 = @repo.create_draft(title: post_title2, body: post_body2)
|
145
|
+
post_num2 = @repo.finish_draft(draft_name2)
|
146
|
+
|
147
|
+
# Generate the second post (should overwrite copy)
|
148
|
+
@repo.generate_post(post_num2)
|
149
|
+
|
150
|
+
# Check that copy still exists and has new content
|
151
|
+
assert File.exist?(clean_symlink_path), "Copy should still exist"
|
152
|
+
|
153
|
+
new_content = File.read(clean_symlink_path)
|
154
|
+
expected_content = File.read(@view.dir/:output/:permalink/slugify(post_num2, post_title2) + ".html")
|
155
|
+
|
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
|
+
end
|
159
|
+
|
160
|
+
def test_009_permalink_copy_with_special_characters_in_title
|
161
|
+
# Test with a title that has special characters
|
162
|
+
post_title = "Post with Special Characters: & < > \" ' !"
|
163
|
+
post_body = "This post has special characters in the title."
|
164
|
+
|
165
|
+
# Create draft and finish it
|
166
|
+
draft_name = @repo.create_draft(title: post_title, body: post_body)
|
167
|
+
post_num = @repo.finish_draft(draft_name)
|
168
|
+
|
169
|
+
# Generate the post
|
170
|
+
@repo.generate_post(post_num)
|
171
|
+
|
172
|
+
# Check that copy exists with cleaned slug
|
173
|
+
clean_slug = clean_slugify(post_title) + ".html"
|
174
|
+
clean_symlink_path = @view.dir/:output/:permalink/clean_slug
|
175
|
+
|
176
|
+
assert File.exist?(clean_symlink_path), "Copy should exist for cleaned title"
|
177
|
+
|
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"
|
182
|
+
end
|
183
|
+
|
184
|
+
def test_010_permalink_copy_deployment_ready
|
185
|
+
# Test that permalink copies are created in the correct location for deployment
|
186
|
+
post_title = "Deployment Test Post"
|
187
|
+
post_body = "This post tests deployment readiness."
|
188
|
+
|
189
|
+
# Create draft and finish it
|
190
|
+
draft_name = @repo.create_draft(title: post_title, body: post_body)
|
191
|
+
post_num = @repo.finish_draft(draft_name)
|
192
|
+
|
193
|
+
# Generate the post
|
194
|
+
@repo.generate_post(post_num)
|
195
|
+
|
196
|
+
# Check that copy is in the correct deployment location
|
197
|
+
clean_slug = clean_slugify(post_title) + ".html"
|
198
|
+
clean_symlink_path = @view.dir/:output/:permalink/clean_slug
|
199
|
+
|
200
|
+
# Verify the path structure
|
201
|
+
assert_equal @view.dir/:output/:permalink/clean_slug, clean_symlink_path
|
202
|
+
assert File.exist?(clean_symlink_path), "Copy should exist in deployment location"
|
203
|
+
|
204
|
+
# Verify it's a copy (not a symlink)
|
205
|
+
assert !File.symlink?(clean_symlink_path), "Should not be a symlink"
|
206
|
+
|
207
|
+
# Verify the copy has content
|
208
|
+
copy_content = File.read(clean_symlink_path)
|
209
|
+
assert copy_content.length > 0, "Copy should have content"
|
210
|
+
end
|
211
|
+
end
|
data/test/unit/post.rb
ADDED
@@ -0,0 +1,309 @@
|
|
1
|
+
# test/unit/post.rb
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require_relative '../../lib/scriptorium'
|
5
|
+
require_relative '../test_helpers'
|
6
|
+
require_relative '../../lib/scriptorium/post'
|
7
|
+
|
8
|
+
class TestScriptoriumPost < Minitest::Test
|
9
|
+
include Scriptorium::Exceptions
|
10
|
+
include Scriptorium::Helpers
|
11
|
+
|
12
|
+
def setup
|
13
|
+
@test_dir = "test/scriptorium-TEST"
|
14
|
+
# Clean up any existing test repository
|
15
|
+
FileUtils.rm_rf(@test_dir) if Dir.exist?(@test_dir)
|
16
|
+
|
17
|
+
# Create API and use it to create repo
|
18
|
+
@api = Scriptorium::API.new(testmode: true)
|
19
|
+
@api.create_repo(@test_dir)
|
20
|
+
|
21
|
+
# Keep @repo available for constructor tests
|
22
|
+
@repo = @api.repo
|
23
|
+
|
24
|
+
# Create a basic Post object for constructor tests (no directories yet)
|
25
|
+
@post = Scriptorium::Post.new(@repo, 1)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Helper method for tests that need a real post with directories
|
29
|
+
def create_real_post
|
30
|
+
@api.create_view("test_view", "Test View", "A test view")
|
31
|
+
@api.create_post("Test Post", "Test body", views: "test_view")
|
32
|
+
end
|
33
|
+
|
34
|
+
def teardown
|
35
|
+
FileUtils.rm_rf(@test_dir) if Dir.exist?(@test_dir)
|
36
|
+
Scriptorium::Repo.destroy if Scriptorium::Repo.testing
|
37
|
+
end
|
38
|
+
|
39
|
+
# Constructor validation tests
|
40
|
+
def test_001_initialize_with_valid_params
|
41
|
+
post = Scriptorium::Post.new(@repo, 123)
|
42
|
+
assert_equal @repo, post.repo
|
43
|
+
assert_equal "0123", post.num
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_002_initialize_with_nil_repo
|
47
|
+
assert_raises(PostRepoNil) do
|
48
|
+
Scriptorium::Post.new(nil, 1)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_003_initialize_with_nil_num
|
53
|
+
assert_raises(PostNumNil) do
|
54
|
+
Scriptorium::Post.new(@repo, nil)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_004_initialize_with_empty_num
|
59
|
+
assert_raises(PostNumEmpty) do
|
60
|
+
Scriptorium::Post.new(@repo, "")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_005_initialize_with_whitespace_num
|
65
|
+
assert_raises(PostNumEmpty) do
|
66
|
+
Scriptorium::Post.new(@repo, " ")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_006_initialize_with_invalid_num_format
|
71
|
+
assert_raises(PostNumInvalid) do
|
72
|
+
Scriptorium::Post.new(@repo, "abc")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_007_initialize_with_negative_num
|
77
|
+
assert_raises(PostNumInvalid) do
|
78
|
+
Scriptorium::Post.new(@repo, -1)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Basic property tests
|
83
|
+
def test_008_dir
|
84
|
+
create_real_post
|
85
|
+
expected_dir = @repo.root/:posts/"0001"
|
86
|
+
assert_equal expected_dir, @post.dir
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_009_meta_file
|
90
|
+
create_real_post
|
91
|
+
expected_file = @repo.root/:posts/"0001"/"meta.txt"
|
92
|
+
assert_equal expected_file, @post.meta_file
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_010_id
|
96
|
+
create_real_post
|
97
|
+
assert_equal 1, @post.id
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_011_num_with_leading_zeros
|
101
|
+
post = Scriptorium::Post.new(@repo, 1)
|
102
|
+
assert_equal "0001", post.num
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_012_num_without_leading_zeros
|
106
|
+
post = Scriptorium::Post.new(@repo, 123)
|
107
|
+
assert_equal "0123", post.num
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_013_num_with_existing_zeros
|
111
|
+
post = Scriptorium::Post.new(@repo, 0001)
|
112
|
+
assert_equal "0001", post.num
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
|
117
|
+
# Metadata tests
|
118
|
+
def test_014_meta_without_file
|
119
|
+
# Create a real post for this test
|
120
|
+
create_real_post
|
121
|
+
# Clear the metadata file to test empty case
|
122
|
+
File.delete(@post.meta_file) if File.exist?(@post.meta_file)
|
123
|
+
# When meta file doesn't exist, should return empty hash
|
124
|
+
assert_equal({}, @post.meta)
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_015_meta_with_file
|
128
|
+
# Create a real post for this test
|
129
|
+
create_real_post
|
130
|
+
# Create a meta file
|
131
|
+
meta_content = "post.title Test Post\npost.blurb Test blurb\npost.slug test-post\npost.pubdate 2023-01-01 12:00:00"
|
132
|
+
write_file(@post.meta_file, meta_content)
|
133
|
+
|
134
|
+
meta = @post.meta
|
135
|
+
assert_equal "Test Post", meta["post.title"]
|
136
|
+
assert_equal "Test blurb", meta["post.blurb"]
|
137
|
+
assert_equal "test-post", meta["post.slug"]
|
138
|
+
assert_equal "2023-01-01 12:00:00", meta["post.pubdate"]
|
139
|
+
end
|
140
|
+
|
141
|
+
# Individual metadata field tests
|
142
|
+
def test_016_title
|
143
|
+
create_real_post
|
144
|
+
write_file(@post.meta_file, "post.title Test Post")
|
145
|
+
assert_equal "Test Post", @post.title
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_017_blurb
|
149
|
+
create_real_post
|
150
|
+
write_file(@post.meta_file, "post.blurb Test blurb")
|
151
|
+
assert_equal "Test blurb", @post.blurb
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_018_slug
|
155
|
+
create_real_post
|
156
|
+
write_file(@post.meta_file, "post.slug test-post")
|
157
|
+
assert_equal "test-post", @post.slug
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_019_pubdate
|
161
|
+
create_real_post
|
162
|
+
write_file(@post.meta_file, "post.pubdate 2023-01-01 12:00:00")
|
163
|
+
assert_equal "2023-01-01 12:00:00", @post.pubdate
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_020_views
|
167
|
+
create_real_post
|
168
|
+
write_file(@post.meta_file, "post.views view1 view2")
|
169
|
+
assert_equal "view1 view2", @post.views
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_021_tags
|
173
|
+
create_real_post
|
174
|
+
write_file(@post.meta_file, "post.tags tag1,tag2")
|
175
|
+
assert_equal "tag1,tag2", @post.tags
|
176
|
+
end
|
177
|
+
|
178
|
+
# set_pubdate tests
|
179
|
+
def test_022_set_pubdate_with_valid_date
|
180
|
+
create_real_post
|
181
|
+
Scriptorium::Repo.testing = true
|
182
|
+
@post.set_pubdate("2023-01-15")
|
183
|
+
|
184
|
+
meta = @post.meta
|
185
|
+
assert_equal "2023-01-15 00:00:00", meta["post.pubdate"]
|
186
|
+
assert_equal "January", meta["post.pubdate.month"]
|
187
|
+
assert_equal "15", meta["post.pubdate.day"]
|
188
|
+
assert_equal "2023", meta["post.pubdate.year"]
|
189
|
+
end
|
190
|
+
|
191
|
+
def test_023_set_pubdate_with_nil_date
|
192
|
+
Scriptorium::Repo.testing = true
|
193
|
+
assert_raises(PubdateYmdNil) do
|
194
|
+
@post.set_pubdate(nil)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_024_set_pubdate_with_empty_date
|
199
|
+
Scriptorium::Repo.testing = true
|
200
|
+
assert_raises(PubdateYmdEmpty) do
|
201
|
+
@post.set_pubdate("")
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_025_set_pubdate_with_invalid_format
|
206
|
+
Scriptorium::Repo.testing = true
|
207
|
+
assert_raises(PubdateInvalidFormat) do
|
208
|
+
@post.set_pubdate("2023/01/15")
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def test_026_set_pubdate_with_invalid_date
|
213
|
+
Scriptorium::Repo.testing = true
|
214
|
+
assert_raises(ArgumentError) do
|
215
|
+
@post.set_pubdate("2023-13-45")
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def test_027_set_pubdate_without_testing_mode
|
220
|
+
Scriptorium::Repo.testing = false
|
221
|
+
assert_raises(TestModeOnly) do
|
222
|
+
@post.set_pubdate("2023-01-15")
|
223
|
+
end
|
224
|
+
Scriptorium::Repo.testing = true
|
225
|
+
end
|
226
|
+
|
227
|
+
def test_028_set_pubdate_with_seconds
|
228
|
+
create_real_post
|
229
|
+
Scriptorium::Repo.testing = true
|
230
|
+
@post.set_pubdate_with_seconds("2023-01-15", 30)
|
231
|
+
|
232
|
+
meta = @post.meta
|
233
|
+
assert_equal "2023-01-15 12:00:30", meta["post.pubdate"]
|
234
|
+
assert_equal "January", meta["post.pubdate.month"]
|
235
|
+
assert_equal "15", meta["post.pubdate.day"]
|
236
|
+
assert_equal "2023", meta["post.pubdate.year"]
|
237
|
+
end
|
238
|
+
|
239
|
+
def test_029_pubdate_month_day_year
|
240
|
+
create_real_post
|
241
|
+
# Write metadata with the specific fields this test expects
|
242
|
+
meta_content = "post.pubdate 2023-01-15 12:00:00\npost.pubdate.month January\npost.pubdate.day 15\npost.pubdate.year 2023"
|
243
|
+
write_file(@post.meta_file, meta_content)
|
244
|
+
assert_equal ["January", "15", "2023"], @post.pubdate_month_day_year
|
245
|
+
end
|
246
|
+
|
247
|
+
# attrs tests
|
248
|
+
def test_030_attrs_single
|
249
|
+
create_real_post
|
250
|
+
result = @post.attrs(:title)
|
251
|
+
assert_equal ["Test Post"], result
|
252
|
+
end
|
253
|
+
|
254
|
+
def test_031_attrs_multiple
|
255
|
+
create_real_post
|
256
|
+
result = @post.attrs(:title, :blurb)
|
257
|
+
assert_equal ["Test Post", "ADD BLURB HERE"], result
|
258
|
+
end
|
259
|
+
|
260
|
+
# vars tests
|
261
|
+
def test_032_vars
|
262
|
+
create_real_post
|
263
|
+
vars = @post.vars
|
264
|
+
assert_equal "Test Post", vars[:"post.title"]
|
265
|
+
assert_equal "ADD BLURB HERE", vars[:"post.blurb"]
|
266
|
+
end
|
267
|
+
|
268
|
+
def test_033_vars_default_behavior
|
269
|
+
create_real_post
|
270
|
+
vars = @post.vars
|
271
|
+
assert_equal "", vars[:nonexistent_field]
|
272
|
+
end
|
273
|
+
|
274
|
+
# Class method tests
|
275
|
+
def test_034_read
|
276
|
+
create_real_post
|
277
|
+
post = Scriptorium::Post.read(@repo, 1)
|
278
|
+
assert_equal "Test Post", post.title
|
279
|
+
assert_equal "ADD BLURB HERE", post.blurb
|
280
|
+
end
|
281
|
+
|
282
|
+
# ========================================
|
283
|
+
# Post Validation Error Tests
|
284
|
+
# ========================================
|
285
|
+
|
286
|
+
def test_035_post_id_validation_exceptions
|
287
|
+
# Test that exception classes exist
|
288
|
+
assert PostIdNil
|
289
|
+
assert PostIdEmpty
|
290
|
+
assert PostIdInvalid
|
291
|
+
end
|
292
|
+
|
293
|
+
def test_036_post_creation_exceptions
|
294
|
+
# Test that exception classes exist
|
295
|
+
assert CannotCreatePost
|
296
|
+
assert CannotGetPost
|
297
|
+
assert CannotSetPubdate
|
298
|
+
end
|
299
|
+
|
300
|
+
def test_037_post_id_validation_scenarios
|
301
|
+
# Test actual exception raising for post ID validation
|
302
|
+
# These would need methods that actually raise these exceptions
|
303
|
+
# For now, just verify the classes exist
|
304
|
+
assert PostIdNil
|
305
|
+
assert PostIdEmpty
|
306
|
+
assert PostIdInvalid
|
307
|
+
end
|
308
|
+
|
309
|
+
end
|