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,167 @@
|
|
1
|
+
require_relative "./environment"
|
2
|
+
|
3
|
+
manual_setup
|
4
|
+
|
5
|
+
@repo.create_view("testview", "Test View", "A test view for manual inspection")
|
6
|
+
|
7
|
+
# Ensure Highlight.js is enabled via global-head.txt
|
8
|
+
global_head_file = "test/scriptorium-TEST/views/testview/config/global-head.txt"
|
9
|
+
head_contents = File.exist?(global_head_file) ? File.read(global_head_file) : ""
|
10
|
+
add_lines = []
|
11
|
+
add_lines << "highlight # Enable Highlight.js assets" unless head_contents.include?("\nhighlight")
|
12
|
+
add_lines << "highlight_custom # Optional Highlight.js CSS overrides" unless head_contents.include?("\nhighlight_custom")
|
13
|
+
unless add_lines.empty?
|
14
|
+
File.open(global_head_file, "a") { |f| add_lines.each { |ln| f.puts ln } }
|
15
|
+
end
|
16
|
+
|
17
|
+
# Post with comprehensive syntax highlighting tests
|
18
|
+
draft_body = <<~'BODY'
|
19
|
+
.blurb
|
20
|
+
Testing Highlight.js syntax highlighting with multiple languages.
|
21
|
+
.end
|
22
|
+
This post tests the integrated syntax highlighters with Ruby, Elixir, JavaScript, and plain text.
|
23
|
+
|
24
|
+
## Ruby Code Example (Rouge)
|
25
|
+
|
26
|
+
.code ruby
|
27
|
+
class User
|
28
|
+
attr_accessor :name, :email
|
29
|
+
|
30
|
+
def initialize(name, email)
|
31
|
+
@name = name
|
32
|
+
@email = email
|
33
|
+
end
|
34
|
+
|
35
|
+
def greet
|
36
|
+
puts "Hello, #{@name}!"
|
37
|
+
end
|
38
|
+
|
39
|
+
def valid_email?
|
40
|
+
email.match?(/\\A[\\w+\\-.]+@[a-z\\d\\-]+(\\.[a-z\\d\\-]+)*\\.[a-z]+\\z/i)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
user = User.new("Alice", "alice@example.com")
|
45
|
+
user.greet
|
46
|
+
.end
|
47
|
+
|
48
|
+
## Elixir Code Example (Rouge)
|
49
|
+
|
50
|
+
.code elixir
|
51
|
+
defmodule Calculator do
|
52
|
+
def add(a, b), do: a + b
|
53
|
+
def subtract(a, b), do: a - b
|
54
|
+
def multiply(a, b), do: a * b
|
55
|
+
def divide(a, b) when b != 0, do: a / b
|
56
|
+
def divide(_, 0), do: {:error, "Division by zero"}
|
57
|
+
|
58
|
+
def calculate(operation, a, b) do
|
59
|
+
case operation do
|
60
|
+
:add -> add(a, b)
|
61
|
+
:subtract -> subtract(a, b)
|
62
|
+
:multiply -> multiply(a, b)
|
63
|
+
:divide -> divide(a, b)
|
64
|
+
_ -> {:error, "Unknown operation"}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Test the calculator
|
70
|
+
IO.puts("5 + 3 = 8")
|
71
|
+
.end
|
72
|
+
|
73
|
+
## JavaScript Code Example (Highlight.js)
|
74
|
+
|
75
|
+
.code javascript
|
76
|
+
class TodoList {
|
77
|
+
constructor() {
|
78
|
+
this.todos = [];
|
79
|
+
this.nextId = 1;
|
80
|
+
}
|
81
|
+
|
82
|
+
addTodo(text, completed = false) {
|
83
|
+
const todo = {
|
84
|
+
id: this.nextId++,
|
85
|
+
text: text,
|
86
|
+
completed: completed,
|
87
|
+
createdAt: new Date()
|
88
|
+
};
|
89
|
+
|
90
|
+
this.todos.push(todo);
|
91
|
+
return todo;
|
92
|
+
}
|
93
|
+
|
94
|
+
toggleTodo(id) {
|
95
|
+
const todo = this.todos.find(t => t.id === id);
|
96
|
+
if (todo) {
|
97
|
+
todo.completed = !todo.completed;
|
98
|
+
}
|
99
|
+
return todo;
|
100
|
+
}
|
101
|
+
}
|
102
|
+
|
103
|
+
// Usage example
|
104
|
+
const todoList = new TodoList();
|
105
|
+
todoList.addTodo("Learn syntax highlighting");
|
106
|
+
todoList.addTodo("Test multiple languages");
|
107
|
+
.end
|
108
|
+
|
109
|
+
## Simple Ruby Example
|
110
|
+
|
111
|
+
.code ruby
|
112
|
+
def hello_world
|
113
|
+
puts "Hello, World!"
|
114
|
+
@greeting = "Welcome to Scriptorium"
|
115
|
+
return @greeting
|
116
|
+
end
|
117
|
+
.end
|
118
|
+
|
119
|
+
## Plain Text Example
|
120
|
+
|
121
|
+
.code text
|
122
|
+
This is just plain text
|
123
|
+
No syntax highlighting needed
|
124
|
+
But it should still be in a code block
|
125
|
+
.end
|
126
|
+
|
127
|
+
## Test Results
|
128
|
+
|
129
|
+
Each code block above should display with proper syntax highlighting:
|
130
|
+
|
131
|
+
- **Ruby (Rouge)**: Keywords in red, strings in blue, variables in orange
|
132
|
+
- **Elixir (Rouge)**: Functions in purple, atoms in green, strings in blue
|
133
|
+
- **JavaScript (Highlight.js)**: Keywords in red, functions in purple, strings in blue
|
134
|
+
- **Plain text**: No highlighting, just code block formatting
|
135
|
+
|
136
|
+
Rouge and Highlight.js highlighting should work automatically!
|
137
|
+
BODY
|
138
|
+
|
139
|
+
name = @repo.create_draft(title: "Comprehensive Syntax Highlighting Test", views: ["testview"], body: draft_body)
|
140
|
+
num = @repo.finish_draft(name)
|
141
|
+
@repo.generate_post(num)
|
142
|
+
|
143
|
+
@repo.generate_front_page("testview")
|
144
|
+
|
145
|
+
# Open the generated post directly (works under simple httpd without SPA)
|
146
|
+
unless ARGV.include?("--automated")
|
147
|
+
post_url = "http://127.0.0.1:8000/scriptorium-TEST/views/testview/output/posts/0001-comprehensive-syntax-highlighting-test.html"
|
148
|
+
puts "Press Enter to open the post directly to verify highlighting."
|
149
|
+
STDIN.gets
|
150
|
+
system("open #{post_url}")
|
151
|
+
end
|
152
|
+
|
153
|
+
instruct <<~EOS
|
154
|
+
Front page should have one post with comprehensive syntax highlighting.
|
155
|
+
|
156
|
+
Highlight.js (Ruby, Elixir, JavaScript):
|
157
|
+
- Ruby/Elixir/JS: Token colors applied client-side
|
158
|
+
|
159
|
+
Plain text: No highlighting, just code block formatting
|
160
|
+
|
161
|
+
Check that Highlight.js CSS/JS are included in the generated HTML.
|
162
|
+
All code blocks should have proper token classes and syntax highlighting.
|
163
|
+
Then open the post directly to verify:
|
164
|
+
http://127.0.0.1:8000/scriptorium-TEST/views/testview/output/posts/0001-comprehensive-syntax-highlighting-test.html
|
165
|
+
EOS
|
166
|
+
|
167
|
+
examine("testview")
|
@@ -0,0 +1,307 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'pty'
|
5
|
+
require 'expect'
|
6
|
+
require 'timeout'
|
7
|
+
require 'tempfile'
|
8
|
+
|
9
|
+
class RubyTextComprehensiveTest < Minitest::Test
|
10
|
+
# Test categories for RubyText
|
11
|
+
|
12
|
+
def test_001_basic_initialization
|
13
|
+
# Test that RubyText can start without errors
|
14
|
+
PTY.spawn('ruby -e "require \"rubytext\"; RubyText.start { puts \"Hello\"; gets }"') do |read, write, pid|
|
15
|
+
begin
|
16
|
+
# Wait for RubyText to start
|
17
|
+
result = read.expect(/Hello/, 5)
|
18
|
+
assert result, "RubyText should start and display 'Hello'"
|
19
|
+
|
20
|
+
# Send quit command
|
21
|
+
write.puts "q"
|
22
|
+
Process.wait(pid)
|
23
|
+
assert_equal 0, $?.exitstatus
|
24
|
+
ensure
|
25
|
+
Process.kill('TERM', pid) rescue nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_002_menu_functionality
|
31
|
+
# Test menu creation and interaction
|
32
|
+
menu_script = <<~RUBY
|
33
|
+
require 'rubytext'
|
34
|
+
RubyText.start do
|
35
|
+
menu = RubyText::Menu.new(["Option 1", "Option 2", "Option 3"])
|
36
|
+
result = menu.show
|
37
|
+
puts "Selected: #{result}"
|
38
|
+
gets
|
39
|
+
end
|
40
|
+
RUBY
|
41
|
+
|
42
|
+
PTY.spawn("ruby -e \"#{menu_script}\"") do |read, write, pid|
|
43
|
+
begin
|
44
|
+
# Wait for menu to appear
|
45
|
+
read.expect(/Option 1/, 5)
|
46
|
+
|
47
|
+
# Navigate and select
|
48
|
+
write.puts "\e[B" # Down arrow
|
49
|
+
sleep 0.1
|
50
|
+
write.puts "\r" # Enter
|
51
|
+
|
52
|
+
# Check result
|
53
|
+
result = read.expect(/Selected: Option 2/, 5)
|
54
|
+
assert result, "Menu should return selected option"
|
55
|
+
|
56
|
+
write.puts "q"
|
57
|
+
Process.wait(pid)
|
58
|
+
ensure
|
59
|
+
Process.kill('TERM', pid) rescue nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_003_screen_rendering
|
65
|
+
# Test screen rendering and layout
|
66
|
+
screen_script = <<~RUBY
|
67
|
+
require 'rubytext'
|
68
|
+
RubyText.start do
|
69
|
+
screen = RubyText::Screen.new(80, 24)
|
70
|
+
screen.puts("Test content")
|
71
|
+
screen.refresh
|
72
|
+
gets
|
73
|
+
end
|
74
|
+
RUBY
|
75
|
+
|
76
|
+
PTY.spawn("ruby -e \"#{screen_script}\"") do |read, write, pid|
|
77
|
+
begin
|
78
|
+
# Wait for content to appear
|
79
|
+
result = read.expect(/Test content/, 5)
|
80
|
+
assert result, "Screen should display content"
|
81
|
+
|
82
|
+
write.puts "q"
|
83
|
+
Process.wait(pid)
|
84
|
+
ensure
|
85
|
+
Process.kill('TERM', pid) rescue nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_004_input_handling
|
91
|
+
# Test various input methods
|
92
|
+
input_script = <<~RUBY
|
93
|
+
require 'rubytext'
|
94
|
+
RubyText.start do
|
95
|
+
puts "Press any key..."
|
96
|
+
key = RubyText.getch
|
97
|
+
puts "Key pressed: #{key.inspect}"
|
98
|
+
gets
|
99
|
+
end
|
100
|
+
RUBY
|
101
|
+
|
102
|
+
PTY.spawn("ruby -e \"#{input_script}\"") do |read, write, pid|
|
103
|
+
begin
|
104
|
+
read.expect(/Press any key/, 5)
|
105
|
+
|
106
|
+
# Send a key
|
107
|
+
write.puts "a"
|
108
|
+
|
109
|
+
result = read.expect(/Key pressed/, 5)
|
110
|
+
assert result, "Should detect key press"
|
111
|
+
|
112
|
+
write.puts "q"
|
113
|
+
Process.wait(pid)
|
114
|
+
ensure
|
115
|
+
Process.kill('TERM', pid) rescue nil
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_005_color_and_style
|
121
|
+
# Test color and style functionality
|
122
|
+
color_script = <<~RUBY
|
123
|
+
require 'rubytext'
|
124
|
+
RubyText.start do
|
125
|
+
RubyText.color(:red) { puts "Red text" }
|
126
|
+
RubyText.color(:blue) { puts "Blue text" }
|
127
|
+
RubyText.bold { puts "Bold text" }
|
128
|
+
gets
|
129
|
+
end
|
130
|
+
RUBY
|
131
|
+
|
132
|
+
PTY.spawn("ruby -e \"#{color_script}\"") do |read, write, pid|
|
133
|
+
begin
|
134
|
+
# Check for colored output (this might be hard to test in PTY)
|
135
|
+
result = read.expect(/Red text|Blue text|Bold text/, 5)
|
136
|
+
assert result, "Should display styled text"
|
137
|
+
|
138
|
+
write.puts "q"
|
139
|
+
Process.wait(pid)
|
140
|
+
ensure
|
141
|
+
Process.kill('TERM', pid) rescue nil
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_006_window_management
|
147
|
+
# Test window creation and management
|
148
|
+
window_script = <<~RUBY
|
149
|
+
require 'rubytext'
|
150
|
+
RubyText.start do
|
151
|
+
window = RubyText::Window.new(10, 5, 5, 5)
|
152
|
+
window.puts("Window content")
|
153
|
+
window.refresh
|
154
|
+
gets
|
155
|
+
end
|
156
|
+
RUBY
|
157
|
+
|
158
|
+
PTY.spawn("ruby -e \"#{window_script}\"") do |read, write, pid|
|
159
|
+
begin
|
160
|
+
result = read.expect(/Window content/, 5)
|
161
|
+
assert result, "Window should display content"
|
162
|
+
|
163
|
+
write.puts "q"
|
164
|
+
Process.wait(pid)
|
165
|
+
ensure
|
166
|
+
Process.kill('TERM', pid) rescue nil
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_007_error_handling
|
172
|
+
# Test error handling and recovery
|
173
|
+
error_script = <<~RUBY
|
174
|
+
require 'rubytext'
|
175
|
+
begin
|
176
|
+
RubyText.start do
|
177
|
+
# Try to do something that might cause an error
|
178
|
+
RubyText::Screen.new(-1, -1) # Invalid dimensions
|
179
|
+
end
|
180
|
+
rescue => e
|
181
|
+
puts "Error caught: #{e.class}"
|
182
|
+
exit 0
|
183
|
+
end
|
184
|
+
RUBY
|
185
|
+
|
186
|
+
PTY.spawn("ruby -e \"#{error_script}\"") do |read, write, pid|
|
187
|
+
begin
|
188
|
+
result = read.expect(/Error caught/, 5)
|
189
|
+
assert result, "Should handle errors gracefully"
|
190
|
+
|
191
|
+
Process.wait(pid)
|
192
|
+
assert_equal 0, $?.exitstatus
|
193
|
+
ensure
|
194
|
+
Process.kill('TERM', pid) rescue nil
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def test_008_performance
|
200
|
+
# Test performance with large content
|
201
|
+
performance_script = <<~RUBY
|
202
|
+
require 'rubytext'
|
203
|
+
require 'benchmark'
|
204
|
+
|
205
|
+
RubyText.start do
|
206
|
+
time = Benchmark.measure do
|
207
|
+
100.times do |i|
|
208
|
+
puts "Line #{i}: " + "x" * 50
|
209
|
+
end
|
210
|
+
end
|
211
|
+
puts "Rendering time: #{time.real}s"
|
212
|
+
gets
|
213
|
+
end
|
214
|
+
RUBY
|
215
|
+
|
216
|
+
PTY.spawn("ruby -e \"#{performance_script}\"") do |read, write, pid|
|
217
|
+
begin
|
218
|
+
result = read.expect(/Rendering time/, 10)
|
219
|
+
assert result, "Should complete performance test"
|
220
|
+
|
221
|
+
write.puts "q"
|
222
|
+
Process.wait(pid)
|
223
|
+
ensure
|
224
|
+
Process.kill('TERM', pid) rescue nil
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def test_009_integration_scenarios
|
230
|
+
# Test real-world usage scenarios
|
231
|
+
scenarios = [
|
232
|
+
{
|
233
|
+
name: "Simple menu navigation",
|
234
|
+
script: <<~RUBY,
|
235
|
+
require 'rubytext'
|
236
|
+
RubyText.start do
|
237
|
+
menu = RubyText::Menu.new(["Edit", "View", "Quit"])
|
238
|
+
result = menu.show
|
239
|
+
puts "Selected: #{result}"
|
240
|
+
gets
|
241
|
+
end
|
242
|
+
RUBY
|
243
|
+
expected: /Selected: (Edit|View|Quit)/
|
244
|
+
},
|
245
|
+
{
|
246
|
+
name: "Form input",
|
247
|
+
script: <<~RUBY,
|
248
|
+
require 'rubytext'
|
249
|
+
RubyText.start do
|
250
|
+
puts "Enter your name:"
|
251
|
+
name = gets.chomp
|
252
|
+
puts "Hello, #{name}!"
|
253
|
+
gets
|
254
|
+
end
|
255
|
+
RUBY
|
256
|
+
expected: /Hello, TestUser!/
|
257
|
+
}
|
258
|
+
]
|
259
|
+
|
260
|
+
scenarios.each do |scenario|
|
261
|
+
PTY.spawn("ruby -e \"#{scenario[:script]}\"") do |read, write, pid|
|
262
|
+
begin
|
263
|
+
# Wait for prompt
|
264
|
+
read.expect(/Enter your name:|Menu/, 5)
|
265
|
+
|
266
|
+
# Send input
|
267
|
+
if scenario[:name].include?("menu")
|
268
|
+
write.puts "\r" # Select first option
|
269
|
+
else
|
270
|
+
write.puts "TestUser"
|
271
|
+
write.puts "\r"
|
272
|
+
end
|
273
|
+
|
274
|
+
# Check result
|
275
|
+
result = read.expect(scenario[:expected], 5)
|
276
|
+
assert result, "Scenario '#{scenario[:name]}' should work"
|
277
|
+
|
278
|
+
write.puts "q"
|
279
|
+
Process.wait(pid)
|
280
|
+
ensure
|
281
|
+
Process.kill('TERM', pid) rescue nil
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
private
|
288
|
+
|
289
|
+
def load_expected_screens
|
290
|
+
# Load expected screen states from fixtures
|
291
|
+
screens = []
|
292
|
+
fixture_dir = "test/fixtures/rubytext_screens"
|
293
|
+
if Dir.exist?(fixture_dir)
|
294
|
+
Dir.glob("#{fixture_dir}/*.txt").sort.each do |file|
|
295
|
+
screens << File.read(file)
|
296
|
+
end
|
297
|
+
end
|
298
|
+
screens
|
299
|
+
end
|
300
|
+
|
301
|
+
def capture_current_screens
|
302
|
+
# Capture current screen states for comparison
|
303
|
+
screens = []
|
304
|
+
# Implementation would depend on RubyText's screen capture capabilities
|
305
|
+
screens
|
306
|
+
end
|
307
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'pty'
|
5
|
+
require 'expect'
|
6
|
+
require 'timeout'
|
7
|
+
|
8
|
+
class RubyTextDemoTest < Minitest::Test
|
9
|
+
# Test the demo/slideshow functionality
|
10
|
+
def test_001_demo_automation
|
11
|
+
# Run the demo in automated mode
|
12
|
+
PTY.spawn('ruby -e "require \"rubytext\"; RubyText.start { demo_mode }"') do |read, write, pid|
|
13
|
+
begin
|
14
|
+
# Wait for demo to start
|
15
|
+
read.expect(/Demo/, 10)
|
16
|
+
|
17
|
+
# Send navigation commands
|
18
|
+
write.puts "n" # next slide
|
19
|
+
sleep 0.5
|
20
|
+
write.puts "n" # next slide
|
21
|
+
sleep 0.5
|
22
|
+
write.puts "q" # quit
|
23
|
+
|
24
|
+
# Should exit cleanly
|
25
|
+
Process.wait(pid)
|
26
|
+
assert_equal 0, $?.exitstatus
|
27
|
+
ensure
|
28
|
+
Process.kill('TERM', pid) rescue nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_002_slideshow_regression
|
34
|
+
# Capture expected screen states and compare
|
35
|
+
expected_screens = load_expected_screens
|
36
|
+
current_screens = capture_current_screens
|
37
|
+
|
38
|
+
expected_screens.each_with_index do |expected, index|
|
39
|
+
assert_equal expected, current_screens[index], "Screen #{index} doesn't match expected"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|