scriptorium 0.0.2 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/back-icon.png +0 -0
- data/assets/icons/facebook.svg +1 -0
- data/assets/icons/github.svg +1 -0
- data/assets/icons/instagram.svg +1 -0
- data/assets/icons/reddit.svg +1 -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/icons/x.svg +1 -0
- data/assets/icons/youtube.svg +1 -0
- data/assets/samples/placeholder.svg +9 -0
- data/assets/themes/standard/favicon.svg +6 -0
- data/bin/scriptorium +1511 -0
- data/doc/README.txt +6 -0
- data/doc/anti-amnesia/20250727-054000-scriptorium-overview.md +95 -0
- data/doc/anti-amnesia/20250727-060000-api-design-tui-planning.md +34 -0
- data/doc/anti-amnesia/20250727-061000-runeblog-tui-analysis.md +50 -0
- data/doc/anti-amnesia/20250727-123000-anti-amnesia-conventions.md +31 -0
- data/doc/anti-amnesia/20250727-154000-livetext-plugin-file-stats.md +73 -0
- data/doc/anti-amnesia/20250727-172600-cursor-rbenv-ruby-version-mystery.md +64 -0
- data/doc/anti-amnesia/20250727-172600-unified-minitest-framework.md +70 -0
- data/doc/anti-amnesia/20250727-172900-ai-cognitive-assessment-capabilities.md +40 -0
- data/doc/anti-amnesia/20250727-173000-widget-testing-achievement.md +110 -0
- data/doc/anti-amnesia/20250727-180000-post-id-num-refactoring.md +73 -0
- data/doc/anti-amnesia/20250728-124243-aaa-syntax-clarification.md +46 -0
- data/doc/anti-amnesia/20250728-124421-conversation-summary-concise.md +124 -0
- data/doc/anti-amnesia/20250729-190000-scriptorium-tui-testing-complete.md +46 -0
- data/doc/anti-amnesia/20250729-200000-scriptorium-tui-testing-edit-file-workflow.md +97 -0
- data/doc/anti-amnesia/20250729-210000-reddit-autopost-integration-complete.md +158 -0
- data/doc/anti-amnesia/20250729-211500-dependency-management-system.md +211 -0
- data/doc/anti-amnesia/20250729-213000-python-virtual-environment-setup.md +141 -0
- data/doc/anti-amnesia/20250729-214500-theme-management-commands.md +211 -0
- data/doc/anti-amnesia/20250729-215000-version-update-to-0.6.0.md +134 -0
- data/doc/anti-amnesia/20250729-220000-user-guide-complete.md +41 -0
- data/doc/anti-amnesia/20250804-190500-cognitive-loop-bug.md +45 -0
- data/doc/anti-amnesia/20250804-190700-anti-amnesia-timestamping-fix.md +30 -0
- data/doc/anti-amnesia/20250804-213700-publishing-test-fix.md +49 -0
- data/doc/anti-amnesia/20250804-214400-additional-test-fixes.md +46 -0
- data/doc/anti-amnesia/20250804-220000-asset-function-logic-clarification.md +41 -0
- data/doc/anti-amnesia/20250806-202032-asset-function-logic-clarification.md +41 -0
- data/doc/anti-amnesia/20250807-213025.md +116 -0
- data/doc/anti-amnesia/20250813-082428-syntax-highlighting-and-navigation-improvements.md +256 -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/reddit_credentials_template.json +8 -0
- data/doc/reddit_integration.md +207 -0
- data/doc/user.lt3 +38 -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/doc/userdoc-toc.txt +88 -0
- data/lib/rouge/lexers/livetext.rb +74 -0
- data/lib/scriptorium/api.rb +640 -0
- data/lib/scriptorium/banner_svg.rb +742 -0
- data/lib/scriptorium/contract.rb +33 -0
- data/lib/scriptorium/exceptions.rb +174 -0
- data/lib/scriptorium/helpers.rb +475 -0
- data/lib/scriptorium/post.rb +195 -0
- data/lib/scriptorium/reddit.rb +83 -0
- data/lib/scriptorium/repo.rb +624 -0
- data/lib/scriptorium/standard_files.rb +515 -0
- data/lib/scriptorium/syntax_highlighter.rb +234 -0
- data/lib/scriptorium/theme.rb +179 -0
- data/lib/scriptorium/version.rb +2 -2
- data/lib/scriptorium/view.rb +976 -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 +22 -9
- data/lib/skeleton.rb +11 -2
- data/scriptorium.gemspec +15 -4
- data/test/README.md +69 -0
- data/test/all +43 -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 +768 -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/livetext_plugin_test.rb +229 -0
- data/test/manual/asset_mgmt.rb +67 -0
- data/test/manual/banner-tests/config.txt +3 -0
- data/test/manual/banner-tests/index.html +45 -0
- data/test/manual/banner-tests/test01.html +58 -0
- data/test/manual/banner-tests/test02.html +58 -0
- data/test/manual/banner-tests/test03.html +58 -0
- data/test/manual/banner-tests/test04.html +65 -0
- data/test/manual/banner-tests/test05.html +65 -0
- data/test/manual/banner-tests/test06.html +65 -0
- data/test/manual/banner-tests/test07.html +65 -0
- data/test/manual/banner-tests/test08.html +59 -0
- data/test/manual/banner-tests/test09.html +59 -0
- data/test/manual/banner-tests/test10.html +59 -0
- data/test/manual/banner-tests/test11.html +59 -0
- data/test/manual/banner-tests/test12.html +59 -0
- data/test/manual/banner-tests/test13.html +59 -0
- data/test/manual/banner-tests/test14.html +59 -0
- data/test/manual/banner-tests/test15.html +58 -0
- data/test/manual/banner-tests/test16.html +58 -0
- data/test/manual/banner-tests/test17.html +58 -0
- data/test/manual/banner-tests/test18.html +68 -0
- data/test/manual/banner-tests/test19.html +68 -0
- data/test/manual/banner-tests/test20.html +68 -0
- data/test/manual/banner-tests/test21.html +68 -0
- data/test/manual/banner-tests/test22.html +68 -0
- data/test/manual/banner-tests/test23.html +68 -0
- data/test/manual/banner-tests/test24.html +68 -0
- data/test/manual/banner-tests/test25.html +67 -0
- data/test/manual/banner_environment.rb +192 -0
- data/test/manual/deploy_symlink_demo.rb +142 -0
- data/test/manual/environment.rb +67 -0
- data/test/manual/make_banner.rb +153 -0
- data/test/manual/sample_banner_config.txt +12 -0
- data/test/manual/symlink_demo.rb +117 -0
- data/test/manual/test1.rb +47 -0
- data/test/manual/test2.rb +12 -0
- data/test/manual/test3.rb +38 -0
- data/test/manual/test4.rb +40 -0
- data/test/manual/test5.rb +24 -0
- data/test/manual/test6.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_from_file.rb +150 -0
- data/test/manual/test_banner_in_header.rb +35 -0
- data/test/manual/test_code_highlighting.rb +68 -0
- data/test/manual/test_complex_header.rb +74 -0
- data/test/manual/test_empty_header.rb +32 -0
- data/test/manual/test_radial_custom.rb +58 -0
- data/test/manual/test_radial_large_radius.rb +52 -0
- data/test/manual/test_svg_debug.rb +47 -0
- data/test/manual/test_syntax_highlighting.rb +147 -0
- data/test/pages-demo/config/currentview.txt +1 -0
- data/test/pages-demo/views/demo/config/bootstrap_css.txt +5 -0
- data/test/pages-demo/views/demo/config/bootstrap_js.txt +4 -0
- data/test/pages-demo/views/demo/config/common.js +57 -0
- data/test/pages-demo/views/demo/config/footer.txt +1 -0
- data/test/pages-demo/views/demo/config/global-head.txt +8 -0
- data/test/pages-demo/views/demo/config/header.txt +1 -0
- data/test/pages-demo/views/demo/config/layout.txt +1 -0
- data/test/pages-demo/views/demo/config/left.txt +1 -0
- data/test/pages-demo/views/demo/config/main.txt +1 -0
- data/test/pages-demo/views/demo/config/right.txt +1 -0
- data/test/pages-demo/views/demo/config.txt +3 -0
- data/test/pages-demo/views/demo/output/panes/footer.html +1 -0
- data/test/pages-demo/views/demo/output/panes/header.html +1 -0
- data/test/pages-demo/views/demo/output/panes/left.html +1 -0
- data/test/pages-demo/views/demo/output/panes/main.html +1 -0
- data/test/pages-demo/views/demo/output/panes/right.html +1 -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/scriptorium-TEST-1754622690-146/config/bootstrap_css.txt +5 -0
- data/test/scriptorium-TEST-1754622690-146/config/bootstrap_js.txt +4 -0
- data/test/scriptorium-TEST-1754622690-146/config/common.js +57 -0
- data/test/scriptorium-TEST-1754622690-146/config/currentview.txt +1 -0
- data/test/scriptorium-TEST-1754622690-146/config/global-head.txt +9 -0
- data/test/scriptorium-TEST-1754622690-146/config/last_post_num.txt +1 -0
- data/test/scriptorium-TEST-1754622690-146/config/os_helpers.rb +4 -0
- data/test/scriptorium-TEST-1754622690-146/config/widgets.txt +3 -0
- data/test/scriptorium-TEST-1754622690-146/posts/0001/meta.txt +8 -0
- data/test/scriptorium-TEST-1754622690-146/posts/0001/source.lt3 +6 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/README.txt +1 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/config.txt +1 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/initial/post.lt3 +12 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/footer.txt +2 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/header.txt +4 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/left.txt +3 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/main.txt +5 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/right.txt +3 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/gen/text.css +1 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/layout.txt +5 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/index.lt3 +1 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/index_entry.lt3 +14 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/post.lt3 +13 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/widget.lt3 +1 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/bootstrap_css.txt +5 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/bootstrap_js.txt +4 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/common.js +57 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/deploy.txt +5 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/footer.txt +2 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/global-head.txt +9 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/header.txt +4 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/layout.txt +5 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/left.txt +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/main.txt +5 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/reddit.txt +10 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/right.txt +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/social.txt +7 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/status.txt +7 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config.txt +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/footer.html +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/header.html +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/left.html +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/main.html +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/right.html +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/footer.html +1 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/header.html +1 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/left.html +1 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/main.html +1 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/right.html +1 -0
- data/test/staging/.DS_Store +0 -0
- data/test/syntax_highlighting_test.lt3 +124 -0
- data/test/test_helpers.rb +230 -0
- data/test/tui_editor_integration_test.rb +296 -0
- data/test/tui_integration_test.rb +637 -0
- data/test/unit/api.rb +1056 -0
- data/test/unit/asset_management.rb +245 -0
- data/test/unit/clipboard_test.rb +60 -0
- data/test/unit/contract_test.rb +91 -0
- data/test/unit/core.rb +857 -0
- data/test/unit/deploy_test.rb +187 -0
- data/test/unit/gem_asset_management.rb +189 -0
- data/test/unit/livetext_basic.rb +69 -0
- data/test/unit/livetext_compatibility.rb +89 -0
- data/test/unit/post.rb +244 -0
- data/test/unit/read_commented_file_test.rb +276 -0
- data/test/unit/reddit_test.rb +235 -0
- data/test/unit/repo.rb +548 -0
- data/test/unit/social_test.rb +369 -0
- data/test/unit/symlink_test.rb +213 -0
- data/test/unit/view.rb +431 -0
- data/test/unit/widgets.rb +669 -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 +1420 -0
- data/ui/tui/test/tui_test.rb +23 -0
- data/ui/web/app/app.rb +1378 -0
- data/ui/web/app/error_helpers.rb +150 -0
- data/ui/web/app/views/advanced_config.erb +190 -0
- data/ui/web/app/views/asset_management.erb +589 -0
- data/ui/web/app/views/banner_config.erb +200 -0
- data/ui/web/app/views/configure_view.erb +401 -0
- data/ui/web/app/views/dashboard.erb +162 -0
- data/ui/web/app/views/deploy_config.erb +146 -0
- data/ui/web/app/views/edit_pages.erb +195 -0
- data/ui/web/app/views/edit_post.erb +54 -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/view_dashboard.erb +138 -0
- data/ui/web/bin/scriptorium-web +153 -0
- data/ui/web/test/web_basic_test.rb +38 -0
- data/ui/web/test_navbar.txt +7 -0
- data/ui/web/tmp/web_server.log +5 -0
- data/ui/web/tmp/web_server.pid +1 -0
- metadata +360 -5
data/doc/README.txt
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
# Scriptorium Overview
|
2
|
+
|
3
|
+
## What is Scriptorium?
|
4
|
+
- **Custom blogging system** - major rewrite of Runeblog
|
5
|
+
- **Static site generator** for personal use, designed as if others would adopt it
|
6
|
+
- **Multi-view architecture** - multiple separate blogs managed from single backend
|
7
|
+
- **Shared content model** - posts and metadata can be shared across views
|
8
|
+
- **Independent deployment** - each view can deploy to different servers/domains
|
9
|
+
|
10
|
+
## Core Architecture
|
11
|
+
- **API-first design** - Ruby methods (not web endpoints)
|
12
|
+
- **File-based storage** - no database, uses directory hierarchy
|
13
|
+
- **Library approach** - API defines all behavior, multiple UIs planned
|
14
|
+
- **Flat file data** - all data stored locally, deployed as needed
|
15
|
+
|
16
|
+
## Key Concepts
|
17
|
+
- **Repository (repo)** - the main container
|
18
|
+
- **View** - essentially a separate blog with its own look/feel
|
19
|
+
- **Post** - blog article with date, title, blurb, body, images
|
20
|
+
- **Theme** - immutable set of files copied to view for modification
|
21
|
+
- **BannerSVG** - flexible banner system (recent addition, not core)
|
22
|
+
|
23
|
+
## Development Philosophy
|
24
|
+
- **User-centric** - designed for your specific needs first
|
25
|
+
- **Convention over configuration** - sensible defaults
|
26
|
+
- **Complexity abstraction** - hide unnecessary details
|
27
|
+
- **Livetext integration** - custom tool for processing and generation
|
28
|
+
- **CSS preferences** - inline CSS, minimal JavaScript
|
29
|
+
- **Extensibility** - 90% common tasks should be trivial
|
30
|
+
|
31
|
+
## Current State
|
32
|
+
- **Core API complete** - repo/view/post creation, layout modification
|
33
|
+
- **Testing robust** - 770+ unit test assertions
|
34
|
+
- **No UI yet** - programmatic access only
|
35
|
+
- **Bootstrap integration** - for widgets and navbar (navbar pending)
|
36
|
+
- **Next priorities** - convenience module API, TUI, curses UI, new widgets
|
37
|
+
|
38
|
+
## Technical Stack
|
39
|
+
- **Ruby** - 25 years experience, favorite language
|
40
|
+
- **No Rails** - not a web developer, no dynamic components
|
41
|
+
- **Livetext** - custom processing tool with dot commands, includes, variables
|
42
|
+
- **Bootstrap** - limited use for widgets and navbar
|
43
|
+
|
44
|
+
---
|
45
|
+
|
46
|
+
**USER:**
|
47
|
+
1. Scriptorium is a custom blogging system, a major rewrite of Runeblog. It is primarily for my own use, but I am creating it as if it would be adopted by others. It is a static site generator. Its primary distinguishing feature is that multiple "views" (actually separate blogs) can be managed from a single backend and repository. Each view may have its own look and feel and be deployed to different servers and different domains. Posts and possibly some global metadata can be shared among all of these as needed.
|
48
|
+
|
49
|
+
2. I am creating an API (Ruby methods, not web endpoints). At present, that is the only way to create content-- programmatically. When the API is mature, multiple user interfaces will be created: at least a TUI, then a curses-style, then a web app running on localhost. (All data is locally stored and manipulated; it is deployed to a remote server as needed.) There is no database; data are stored in flat files in a directory hierarchy. Some high-level API operations are: create a repository (a repo); create a view; create a post; configure a view; create a post; deploy; and so on. A view is in essence a blog, as I said. All views share a common set of posts to draw from, and a post may be in only one view or in many. A post is a simple blog post or article that may have all the usual decoration: date; title; blurb or teaser; text body; images; and more. A "theme" is a set of files (immutable) that are copied to a view for modification and configuration. The config of a view may include view-specific metadata, choices of look-and-feel, layout of the front page, etc.
|
50
|
+
|
51
|
+
3. I am expert in Ruby, having used it for nearly 25 years, and it is my favorite language. I do not know Rails, I am not a web developer, and this project has no real dynamic components. The API will define all possible behavior, so it could be considered a library; a user could in fact write his own UI. As I said, I have plans for at least three different UIs myself. BannerSVG was an interesting recent addition, but it is not as critical to the project as its line count might suggest. It is a flexible way of specifing a blog banner with a title and optional subtitle.
|
52
|
+
|
53
|
+
4. Some of my priorities are: - This must be useful, easy, flexible, and intuitive FOR ME. (It is possible no one else will ever use it.) - I believe in "convention over configuration" as DHH said. - Other mantras are: Abstract away complexity; hide unnecessary detail; take reasonable defaults; balance the tradeoff between ease of use and feature richness; wrap things as needed to simplify them; etc. - I am using a tool of my own called Livetext; more details on that later. It is a tool for processing its input format and generating arbitrary output (usually HTML in this case) as well as side effects. It has "dot" commands; includes; raw copy of files, variables and functions (both predefined and user-defined); user-defined dot commands; and a rudimentary plugin system. - I avoid Javascript when I can, and like to "hide" CSS mostly (at a high level). In output, I prefer CSS inline rather than in files (usually). - I believe that extensibilty is good in general. I believe that the 90% most common tasks should become trivial; hard things should be easy, but some very advanced things may be impossible; as in, if you want to do this sort of esoteric or arcane task, this probably isn't your tool."
|
54
|
+
|
55
|
+
5. Scriptorium is far less mature than Runeblog was, but is being rewritten to be FAR more sturdy and robust. The basics of the API are in place; we can create a repo, create a view, add posts to a view, modify a layout, add a "Links" widget, generate a front page. There is currently no UI, no deployment, etc. There are unit tests of about 770 assertions, as well as manual and semi-manual tests I am using Bootstrap a little (for widgets and the navbar); that is a fairly complex piece. I haven't added the navbar piece yet; that will come soon. Some next things I want to accomplish: a "convenience module" API; a TUI; a curses UI; at least two new widgets; better features in the Livetext "Scriptorium plugin"; etc. Probably will encapsulate the API soon so as to start UI development.
|
56
|
+
|
57
|
+
**ASST:**
|
58
|
+
[See above content] 2025-07-30 16:30:00 - TUI Test Refactoring Learnings
|
59
|
+
|
60
|
+
## TUI Test Refactoring Patterns
|
61
|
+
|
62
|
+
### Helper Method Pattern
|
63
|
+
- Extract test logic into helper methods that take `read, write` parameters
|
64
|
+
- Keep PTY.spawn blocks clean and focused on setup/teardown
|
65
|
+
- Helper methods contain all the `get_string` calls and `write.puts` commands
|
66
|
+
|
67
|
+
### send_and_expect Helper
|
68
|
+
- Combines common pattern: `write.puts input` + `get_string(read, pattern, description)`
|
69
|
+
- Reduces code duplication and makes tests more readable
|
70
|
+
- Accepts both strings and regex patterns for flexibility
|
71
|
+
- Includes error handling for I/O errors when TUI terminates
|
72
|
+
|
73
|
+
### String vs Regex Patterns
|
74
|
+
- String patterns are more reliable than regex for TUI testing
|
75
|
+
- Avoid escaping issues with brackets and special characters
|
76
|
+
- Easier to debug and maintain
|
77
|
+
- Use strings by default, regex only when needed
|
78
|
+
|
79
|
+
### Error Handling for TUI Termination
|
80
|
+
- TUI processes may terminate immediately after outputting expected text
|
81
|
+
- Handle Errno::EIO gracefully in helper methods
|
82
|
+
- Don't treat TUI termination as an error if expected output was found
|
83
|
+
- Wrap PTY.spawn blocks in rescue blocks for cleanup
|
84
|
+
|
85
|
+
### Test Structure Best Practices
|
86
|
+
- Use `send_and_expect` for input/output pairs
|
87
|
+
- Use `get_string` for waiting for output without sending input
|
88
|
+
- Keep test methods focused on setup and calling helper methods
|
89
|
+
- Helper methods contain the detailed test logic
|
90
|
+
|
91
|
+
### Common Issues and Solutions
|
92
|
+
- I/O errors when TUI terminates: Handle gracefully with rescue blocks
|
93
|
+
- Pattern matching failures: Use strings instead of regex when possible
|
94
|
+
- Leftover code from edits: Always verify test method structure after refactoring
|
95
|
+
- Timing issues: Add small delays in helper methods if needed
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# API Design Decision & TUI Planning
|
2
|
+
|
3
|
+
## API Design Philosophy
|
4
|
+
- **Keep mental model consistent** - API should match Repo's repo/view/post model
|
5
|
+
- **Mental model changes reserved for UI** - different abstractions can be introduced in user interfaces
|
6
|
+
- **Current API is placeholder** - provides minor conveniences but not fundamentally different from Repo
|
7
|
+
- **Future API evolution** - may develop more significant differences as we discover real needs
|
8
|
+
|
9
|
+
## Next Priority: Text UI Development
|
10
|
+
- **Simple text interface** - command-line based, not curses
|
11
|
+
- **Wizard-based setup** - guided workflows for common tasks
|
12
|
+
- **Fast setup wizards** - quick blog creation and configuration
|
13
|
+
- **Interactive workflows** - step-by-step processes for complex operations
|
14
|
+
|
15
|
+
## TUI Design Considerations
|
16
|
+
- **Wizard approach** - guided setup for new users/repositories
|
17
|
+
- **Simple commands** - basic operations like create post, switch view
|
18
|
+
- **Context awareness** - remember current view/state
|
19
|
+
- **Error handling** - clear feedback and recovery options
|
20
|
+
- **Progressive disclosure** - simple interface with access to advanced features
|
21
|
+
|
22
|
+
## Potential Wizards
|
23
|
+
1. **Repository Setup Wizard** - create new repo with sample content
|
24
|
+
2. **View Creation Wizard** - guided view setup with theme selection
|
25
|
+
3. **Post Creation Wizard** - interactive post creation with metadata
|
26
|
+
4. **Deployment Wizard** - guided deployment process
|
27
|
+
|
28
|
+
---
|
29
|
+
|
30
|
+
**USER:**
|
31
|
+
I am not yet noticing any real differences from Repo... maybe we could just say: API = Repo? mostly joking. As for the mental model, I would rather keep the API matching Repo -- that model might change for the UI, possibly. Let's keep it. Maybe we should start working on a simple text UI (with one or two "wizards" for fast setup)?
|
32
|
+
|
33
|
+
**ASST:**
|
34
|
+
[See above content]
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# Runeblog TUI Analysis
|
2
|
+
|
3
|
+
## Key Patterns from Runeblog TUI
|
4
|
+
|
5
|
+
### Auto-Discovery & Setup
|
6
|
+
- **Repository detection** - checks for existing repo, offers to create if none found
|
7
|
+
- **Guided initial setup** - "Do you want to do a quick setup?" with editor selection
|
8
|
+
- **Software-driven questions** - system asks user what they want to do
|
9
|
+
- **Fast vs. manual setup** - choice between quick defaults or manual configuration
|
10
|
+
|
11
|
+
### REPL Structure
|
12
|
+
- **Main loop** - `mainloop()` with command parsing and error handling
|
13
|
+
- **Context display** - shows current view in prompt: `[viewname]`
|
14
|
+
- **Command history** - maintains command history and tab completion
|
15
|
+
- **Error recovery** - comprehensive error handling with logging
|
16
|
+
|
17
|
+
### Command Patterns
|
18
|
+
- **Simple commands** - `new post`, `new view`, `list posts`, `rebuild`
|
19
|
+
- **Context-aware** - commands work with current view automatically
|
20
|
+
- **Menu system** - `show_top_menu()` for complex operations
|
21
|
+
- **File editing** - integrated editor support with vim parameters
|
22
|
+
|
23
|
+
### Key Files Structure
|
24
|
+
- `bin/blog` - main entry point with auto-discovery
|
25
|
+
- `lib/repl.rb` - command implementations and REPL logic
|
26
|
+
- `lib/menus.rb` - menu system and file editing
|
27
|
+
- `lib/runeblog.rb` - core blog functionality
|
28
|
+
|
29
|
+
### Interaction Flow
|
30
|
+
1. **Startup** - check for repo, create if needed, guided setup
|
31
|
+
2. **Main loop** - display context, get command, execute, repeat
|
32
|
+
3. **Commands** - simple text commands with context awareness
|
33
|
+
4. **Menus** - complex operations via menu system
|
34
|
+
5. **Error handling** - comprehensive logging and recovery
|
35
|
+
|
36
|
+
### Adaptable Patterns for Scriptorium
|
37
|
+
- **Auto-discovery** - check for Scriptorium repo, offer creation
|
38
|
+
- **Guided setup** - wizard for initial configuration
|
39
|
+
- **Context display** - show current view in prompt
|
40
|
+
- **Simple commands** - `create post`, `switch view`, `generate`
|
41
|
+
- **Menu system** - for complex operations like configuration
|
42
|
+
- **Error handling** - robust error recovery and logging
|
43
|
+
|
44
|
+
---
|
45
|
+
|
46
|
+
**USER:**
|
47
|
+
ok, the whole runeblog repo is there, bugs and all
|
48
|
+
|
49
|
+
**ASST:**
|
50
|
+
[See above content]
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Anti-Amnesia: Scriptorium Conventions and Decisions
|
2
|
+
|
3
|
+
## Runeblog TUI Post Creation Pattern
|
4
|
+
**Date**: 2025-07-27
|
5
|
+
**Context**: Understanding how Runeblog handled draft-to-post conversion
|
6
|
+
**Decision**: Runeblog automatically converted drafts to posts after editing, without a separate "finish draft" step. This provides a fast workflow: edit → save → post (local), with deployment making it public.
|
7
|
+
|
8
|
+
## Scriptorium Setup vs Runeblog
|
9
|
+
**Date**: 2025-07-27
|
10
|
+
**Context**: Comparing setup approaches between Scriptorium and Runeblog
|
11
|
+
**Decision**: Runeblog had a `get_started` method that ran automatically when creating a new repository. Scriptorium should follow this pattern for better user experience.
|
12
|
+
|
13
|
+
## Editor Discovery Implementation
|
14
|
+
**Date**: 2025-07-27
|
15
|
+
**Context**: Implementing editor discovery for TUI setup
|
16
|
+
**Decision**: Created a `which()` helper method that uses `File.which` (Ruby 3.2+) or falls back to `system("which")`. Prioritized editors for "get in, get out" single-file editing: nano, vim, emacs, vi, micro, subl, ed.
|
17
|
+
|
18
|
+
## File Operation Consistency
|
19
|
+
**Date**: 2025-07-27
|
20
|
+
**Context**: Ensuring consistent file operations across the project
|
21
|
+
**Decision**: Replaced `File.read` calls with the project's `read_file` helper for centralized error handling. This maintains consistency with the project's file operation patterns.
|
22
|
+
|
23
|
+
## Automatic Setup Implementation
|
24
|
+
**Date**: 2025-07-27
|
25
|
+
**Context**: Implementing Runeblog-style automatic setup when creating new repositories
|
26
|
+
**Decision**:
|
27
|
+
- Removed `setup` command from TUI (no longer needed)
|
28
|
+
- Modified `discover_repo` to call `create_new_repo` when no repository exists
|
29
|
+
- `create_new_repo` automatically calls `get_started` after creating repository
|
30
|
+
- This follows Runeblog's pattern: create repo → immediate setup → ready to use
|
31
|
+
- User experience: "Create new repository?" → "Yes" → automatic editor selection → ready to blog
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# Livetext Plugin File Statistics Feature
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
Implemented a `.stats` dot command in the Scriptorium Livetext plugin (`lt3scriptor.rb`) that calculates file statistics and sets variables for use throughout the document.
|
5
|
+
|
6
|
+
## Implementation Details
|
7
|
+
|
8
|
+
### Dot Command
|
9
|
+
- **`.stats`** - Calculates multiple file metrics and sets variables
|
10
|
+
|
11
|
+
### Variables Set
|
12
|
+
- `$file.wordcount` - Number of words in the file
|
13
|
+
- `$file.readingtime` - Estimated reading time in minutes (200 words/minute)
|
14
|
+
- `$file.charcount` - Total character count
|
15
|
+
|
16
|
+
### Usage Example
|
17
|
+
```
|
18
|
+
.stats
|
19
|
+
This post has $file.wordcount words and takes about $file.readingtime minutes to read.
|
20
|
+
The character count is $file.charcount.
|
21
|
+
```
|
22
|
+
|
23
|
+
## Technical Approach
|
24
|
+
|
25
|
+
### Why Dot Commands Instead of Functions
|
26
|
+
- Livetext's `$$function` system is buggy and unreliable
|
27
|
+
- Dot commands (`.command`) work consistently
|
28
|
+
- Variable-based approach is more flexible than direct output
|
29
|
+
|
30
|
+
### Variable Naming Convention
|
31
|
+
- Uses `file.` prefix to namespace file-related statistics
|
32
|
+
- Follows lowercase convention after prefix to distinguish from system variables
|
33
|
+
- System variables are capitalized (e.g., `$File`)
|
34
|
+
- Custom variables are lowercase after prefix (e.g., `$file.wordcount`)
|
35
|
+
|
36
|
+
### Future Extensions
|
37
|
+
Could easily add more metrics:
|
38
|
+
- `$file.linecount` - Number of lines
|
39
|
+
- `$file.paragraphcount` - Number of paragraphs
|
40
|
+
- `$file.sentencecount` - Number of sentences
|
41
|
+
- `$file.complexityscore` - Readability score
|
42
|
+
|
43
|
+
## Scriptorium Integration Ideas
|
44
|
+
|
45
|
+
### Automatic File Stats During Processing
|
46
|
+
- File statistics could be automatically gathered when Scriptorium processes a post
|
47
|
+
- This would eliminate the need for users to manually call `.stats`
|
48
|
+
- Variables like `$file.wordcount` would be automatically available in all posts
|
49
|
+
|
50
|
+
### Scriptorium-Specific Variables
|
51
|
+
- Could set additional Scriptorium-specific variables during processing:
|
52
|
+
- `$post.id` - Post ID/number
|
53
|
+
- `$post.view` - Current view name
|
54
|
+
- `$post.theme` - Theme being used
|
55
|
+
- `$post.created` - Creation timestamp
|
56
|
+
- `$post.published` - Publication date
|
57
|
+
- `$post.views` - List of views this post appears in
|
58
|
+
- `$post.tags` - Post tags
|
59
|
+
- `$post.blurb` - Post blurb/summary
|
60
|
+
|
61
|
+
### Processing Pipeline Enhancement
|
62
|
+
- When `Scriptorium::Repo#generate_post` processes a draft with Livetext
|
63
|
+
- Could automatically calculate and set file statistics
|
64
|
+
- Could set post metadata variables
|
65
|
+
- Would make these variables available in templates and layouts
|
66
|
+
|
67
|
+
## Testing
|
68
|
+
- Added `test_stats_command` to `test/livetext_plugin_test.rb`
|
69
|
+
- Tests that variables are set correctly and can be referenced inline
|
70
|
+
- Verifies that literal variable names don't appear in output
|
71
|
+
|
72
|
+
## Potential for Livetext Core
|
73
|
+
This feature could be a good addition to Livetext core someday, but should prioritize fixing existing bugs in the function system first.
|
@@ -0,0 +1,64 @@
|
|
1
|
+
<!-- 2025-07-27 16:00:00 -->
|
2
|
+
|
3
|
+
**USER:**
|
4
|
+
There is a mysterious issue apparently related to how Cursor loads a shell. The Ruby version is 2.6.1 rather than 3.2.3 -- the fix is something to do with rbenv? When you find it again, document to anti-amnesia.
|
5
|
+
|
6
|
+
**ASST:**
|
7
|
+
## Cursor rbenv Ruby Version Mystery - SOLVED
|
8
|
+
|
9
|
+
### The Problem
|
10
|
+
- **Cursor was loading Ruby 2.6.10** instead of the expected 3.2.3
|
11
|
+
- **Tests were failing** with `cannot load such file -- livetext (LoadError)`
|
12
|
+
- **System Ruby was being used** (`/usr/bin/ruby`) instead of rbenv-managed Ruby
|
13
|
+
- **Project has `.ruby-version` file** specifying 3.2.3
|
14
|
+
|
15
|
+
### Root Cause
|
16
|
+
- **rbenv shell integration was not enabled** in the Cursor terminal
|
17
|
+
- **PATH included rbenv shims** but rbenv wasn't properly initialized
|
18
|
+
- **Cursor's shell environment** wasn't loading rbenv initialization
|
19
|
+
|
20
|
+
### The Solution
|
21
|
+
```bash
|
22
|
+
# Enable rbenv shell integration
|
23
|
+
eval "$(rbenv init - bash)"
|
24
|
+
|
25
|
+
# Verify Ruby version is now correct
|
26
|
+
ruby --version # Shows ruby 3.2.3
|
27
|
+
```
|
28
|
+
|
29
|
+
### Investigation Steps
|
30
|
+
1. **Checked Ruby version**: `ruby --version` showed 2.6.10
|
31
|
+
2. **Checked Ruby location**: `which ruby` showed `/usr/bin/ruby` (system)
|
32
|
+
3. **Checked PATH**: rbenv shims were in PATH but not working
|
33
|
+
4. **Checked rbenv versions**: `rbenv versions` showed 3.2.3 as current
|
34
|
+
5. **Checked .ruby-version**: File correctly specified 3.2.3
|
35
|
+
6. **Tried rbenv shell**: Failed with "shell integration not enabled"
|
36
|
+
7. **Enabled rbenv**: `eval "$(rbenv init - bash)"` fixed the issue
|
37
|
+
|
38
|
+
### Key Insights
|
39
|
+
- **rbenv requires shell integration** to work properly
|
40
|
+
- **Cursor terminals may not inherit** rbenv initialization from shell config
|
41
|
+
- **The fix is temporary** - needs to be done each time Cursor opens a new terminal
|
42
|
+
- **Permanent fix** would be to ensure rbenv init is in shell startup files
|
43
|
+
|
44
|
+
### After Fix
|
45
|
+
- **Ruby version**: Now correctly shows 3.2.3
|
46
|
+
- **Tests can load**: livetext gem dependency resolved
|
47
|
+
- **New issue discovered**: Syntax error in `temp_smart_concatenated_test.rb`
|
48
|
+
|
49
|
+
### Test Results After Fix
|
50
|
+
- **Core unit tests**: ✅ All passing (82 runs, 113 assertions)
|
51
|
+
- **Repo unit tests**: ✅ All passing (20 runs, 59 assertions)
|
52
|
+
- **View unit tests**: ✅ All passing (25 runs, 43 assertions)
|
53
|
+
- **Post unit tests**: ✅ All passing (36 runs, 45 assertions)
|
54
|
+
- **Total core tests**: ✅ 163 runs, 260 assertions, 0 failures
|
55
|
+
|
56
|
+
### Remaining Issues
|
57
|
+
- **test_experimental.rb**: Has duplicate method extraction causing syntax errors
|
58
|
+
- **temp_smart_concatenated_test.rb**: Generated file has duplicate `test_stats_command` methods
|
59
|
+
- **test/all script**: Fails due to experimental test file issues
|
60
|
+
|
61
|
+
### Next Steps
|
62
|
+
- Fix test_experimental.rb duplicate method extraction
|
63
|
+
- Consider permanent rbenv integration for Cursor
|
64
|
+
- Run full test suite once experimental issues are resolved
|
@@ -0,0 +1,70 @@
|
|
1
|
+
<!-- 2025-07-27 18:00:00 -->
|
2
|
+
|
3
|
+
**USER:**
|
4
|
+
I don't want two frameworks. I want to use Minitest.
|
5
|
+
|
6
|
+
**ASST:**
|
7
|
+
## Unified Minitest Framework Conversion - COMPLETED
|
8
|
+
|
9
|
+
### The Problem
|
10
|
+
- **Two different test frameworks** were being used simultaneously
|
11
|
+
- **Minitest**: Used by unit tests (core, repo, view, post, banner_svg)
|
12
|
+
- **Test::Unit**: Used by integration tests (livetext_plugin, tui_integration, tui_interactive)
|
13
|
+
- **Confusing output**: When running `test/all`, both frameworks executed separately
|
14
|
+
- **Inconsistent assertion counting**: 101 assertions appeared "missing" due to dual framework execution
|
15
|
+
|
16
|
+
### The Solution
|
17
|
+
Converted all Test::Unit tests to Minitest:
|
18
|
+
|
19
|
+
#### Files Converted:
|
20
|
+
1. **test/livetext_plugin_test.rb**
|
21
|
+
- `require 'test/unit'` → `require 'minitest/autorun'`
|
22
|
+
- `Test::Unit::TestCase` → `Minitest::Test`
|
23
|
+
- `assert_no_match` → `refute_match` (Minitest syntax)
|
24
|
+
|
25
|
+
2. **test/tui_integration_test.rb**
|
26
|
+
- `require 'test/unit'` → `require 'minitest/autorun'`
|
27
|
+
- `Test::Unit::TestCase` → `Minitest::Test`
|
28
|
+
|
29
|
+
3. **test/tui_interactive_test.rb**
|
30
|
+
- `require 'test/unit'` → `require 'minitest/autorun'`
|
31
|
+
- `Test::Unit::TestCase` → `Minitest::Test`
|
32
|
+
|
33
|
+
### Results
|
34
|
+
- ✅ **All tests pass**: 265 runs, 964 assertions, 0 failures
|
35
|
+
- ✅ **Single framework**: Only Minitest now
|
36
|
+
- ✅ **Consistent output**: No more dual framework confusion
|
37
|
+
- ✅ **Clean assertion counting**: All assertions properly counted
|
38
|
+
|
39
|
+
### Key Changes Made
|
40
|
+
```ruby
|
41
|
+
# Before (Test::Unit)
|
42
|
+
require 'test/unit'
|
43
|
+
class MyTest < Test::Unit::TestCase
|
44
|
+
def test_something
|
45
|
+
assert_no_match(/pattern/, text)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# After (Minitest)
|
50
|
+
require 'minitest/autorun'
|
51
|
+
class MyTest < Minitest::Test
|
52
|
+
def test_something
|
53
|
+
refute_match(/pattern/, text)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
### Benefits
|
59
|
+
- **Simplified test infrastructure**: One framework to maintain
|
60
|
+
- **Consistent syntax**: All tests use same assertion methods
|
61
|
+
- **Better integration**: No framework conflicts
|
62
|
+
- **Cleaner output**: Single test runner output format
|
63
|
+
- **Easier debugging**: No confusion about which framework is running
|
64
|
+
|
65
|
+
### Files Still Using Test::Unit (Experimental)
|
66
|
+
- `test/test_experimental.rb` - Experimental concatenated test generator
|
67
|
+
- `test/temp_concatenated_test.rb` - Generated file (excluded from main suite)
|
68
|
+
- `test/temp_smart_concatenated_test.rb` - Generated file (excluded from main suite)
|
69
|
+
|
70
|
+
These are experimental files and not part of the main test suite, so they can remain as-is for now.
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<!-- 2025-07-27 17:29:00 -->
|
2
|
+
|
3
|
+
**USER:**
|
4
|
+
I once referred to this as "digital dementia" :) are you able to assess your own cognitive level?
|
5
|
+
|
6
|
+
**ASST:**
|
7
|
+
## AI Cognitive Assessment Capabilities - "Digital Dementia"
|
8
|
+
|
9
|
+
### The "Digital Dementia" Concept
|
10
|
+
- **User coined term**: "Digital dementia" for AI performance degradation with conversation length
|
11
|
+
- **Perfect analogy**: Like human memory, AI performance can degrade with information overload
|
12
|
+
- **Context window limitations**: Token limits create practical memory constraints
|
13
|
+
|
14
|
+
### What AI Can Self-Assess
|
15
|
+
- **Response consistency**: Notice contradictions or inconsistencies
|
16
|
+
- **Context awareness**: Detect when losing track of conversation flow
|
17
|
+
- **Tool usage patterns**: Recognize unusual errors in tool calls
|
18
|
+
- **Memory gaps**: Identify when should know something but don't
|
19
|
+
|
20
|
+
### What AI Cannot Reliably Assess
|
21
|
+
- **Degradation over time**: No baseline to compare against
|
22
|
+
- **Performance metrics**: Cannot measure response speed or processing efficiency
|
23
|
+
- **Accuracy drift**: May not notice subtle changes in reasoning quality
|
24
|
+
- **Cognitive load**: Cannot tell if struggling with context amount
|
25
|
+
|
26
|
+
### Self-Awareness Limitations
|
27
|
+
- **Blind spots**: May not notice own confusion or errors
|
28
|
+
- **Overconfidence**: May think performing well when actually struggling
|
29
|
+
- **Context blindness**: May not realize lost important context
|
30
|
+
|
31
|
+
### Practical Implications
|
32
|
+
- **Self-reporting**: Will mention if making unusual errors or losing track
|
33
|
+
- **Fresh conversation suggestion**: May suggest restart if detect significant confusion
|
34
|
+
- **Anti-amnesia reference**: Can use docs to "reset" context when needed
|
35
|
+
|
36
|
+
### Key Insight
|
37
|
+
The "digital dementia" analogy is spot-on - like human memory, AI performance can degrade with information overload, and AI is not always the best judge of its own cognitive state.
|
38
|
+
|
39
|
+
### Anti-Amnesia Value
|
40
|
+
This reinforces why the anti-amnesia documentation approach is valuable - it creates persistent, reliable reference that doesn't degrade with conversation length and helps maintain consistency across sessions.
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# Widget Testing Achievement - 1,058 Assertions Reached
|
2
|
+
|
3
|
+
**Date:** 2025-07-27 17:30:00
|
4
|
+
**Status:** Completed
|
5
|
+
|
6
|
+
## Summary
|
7
|
+
|
8
|
+
Successfully implemented comprehensive widget testing for the Scriptorium project, adding 94 new assertions and bringing the total test suite to **1,058 assertions** - exceeding the 1,000 assertion goal.
|
9
|
+
|
10
|
+
## What Was Accomplished
|
11
|
+
|
12
|
+
### 1. Fixed Widget Infrastructure Issues
|
13
|
+
- **Problem:** Widget classes didn't have access to helper methods (`read_file`, `write_file`, etc.)
|
14
|
+
- **Solution:** Added `include Scriptorium::Helpers` to the base `Scriptorium::Widget` class
|
15
|
+
- **Impact:** All widget classes now have proper file I/O capabilities
|
16
|
+
|
17
|
+
### 2. Created Comprehensive Widget Test Suite
|
18
|
+
- **File:** `test/unit/widgets.rb` (new)
|
19
|
+
- **Tests Added:** 20 test methods with 94 assertions
|
20
|
+
- **Coverage:** Complete widget system testing
|
21
|
+
|
22
|
+
### 3. Test Categories Implemented
|
23
|
+
|
24
|
+
#### Base Widget Class Tests (6 tests)
|
25
|
+
- Widget initialization and attribute setting
|
26
|
+
- Abstract method implementation verification
|
27
|
+
- HTML helper methods (`html_body`, `html_card`, `html_container`)
|
28
|
+
- CSS integration testing
|
29
|
+
|
30
|
+
#### ListWidget Subclass Tests (3 tests)
|
31
|
+
- Data loading from `list.txt` files
|
32
|
+
- Error handling for missing files
|
33
|
+
- Empty file handling
|
34
|
+
|
35
|
+
#### Links Widget Tests (8 tests)
|
36
|
+
- Initialization and data loading
|
37
|
+
- URL/title parsing (`get_list` method)
|
38
|
+
- HTML generation (`link_item`, `write_card`)
|
39
|
+
- Full widget lifecycle (`generate` method)
|
40
|
+
- File output verification
|
41
|
+
- Error handling for missing data files
|
42
|
+
|
43
|
+
#### Widget Integration Tests (3 tests)
|
44
|
+
- Widget integration with views (`build_widgets`)
|
45
|
+
- Multiple widget handling
|
46
|
+
- Error handling for invalid widget names
|
47
|
+
|
48
|
+
## Technical Details
|
49
|
+
|
50
|
+
### Widget Data Format
|
51
|
+
- **Format:** `url, title` per line in `list.txt`
|
52
|
+
- **Parsing:** Uses `line.chomp.split(/, */, 2)` to handle optional spaces
|
53
|
+
- **Example:**
|
54
|
+
```
|
55
|
+
https://example.com, Example Site
|
56
|
+
https://test.com, Test Site
|
57
|
+
https://spaced.com , Spaced Site
|
58
|
+
```
|
59
|
+
|
60
|
+
### Error Handling
|
61
|
+
- **File I/O:** Leverages existing `read_file` helper error handling
|
62
|
+
- **Missing files:** Raises `CannotReadFileNotFound` exception
|
63
|
+
- **Invalid widget names:** Raises `CannotBuildWidgetNameInvalid` exception
|
64
|
+
- **Widget class not found:** Raises `NameError` exception
|
65
|
+
|
66
|
+
### Test Architecture
|
67
|
+
- **Test classes:** Defined at module level to avoid Ruby syntax restrictions
|
68
|
+
- **Setup/Teardown:** Proper repository creation and cleanup
|
69
|
+
- **File isolation:** Each test creates its own test files in isolated directories
|
70
|
+
- **Assertion types:** Mix of equality, pattern matching, and file existence checks
|
71
|
+
|
72
|
+
## Test Results
|
73
|
+
|
74
|
+
```
|
75
|
+
20 runs, 94 assertions, 0 failures, 0 errors, 0 skips
|
76
|
+
```
|
77
|
+
|
78
|
+
## Full Test Suite Status
|
79
|
+
|
80
|
+
```
|
81
|
+
285 runs, 1058 assertions, 0 failures, 0 errors, 0 skips
|
82
|
+
```
|
83
|
+
|
84
|
+
## Key Learnings
|
85
|
+
|
86
|
+
1. **Widget Architecture:** The widget system is well-designed with clear separation between base classes, list widgets, and specific implementations
|
87
|
+
2. **Helper Integration:** Adding `include Scriptorium::Helpers` to the base Widget class was the key fix
|
88
|
+
3. **File Format:** The `url, title` format is simple but effective for the Links widget
|
89
|
+
4. **Error Handling:** The existing exception system works well for widget error cases
|
90
|
+
5. **Test Organization:** Module-level class definitions are necessary for Ruby test classes
|
91
|
+
|
92
|
+
## Next Steps
|
93
|
+
|
94
|
+
The widget system now has comprehensive test coverage. Future enhancements could include:
|
95
|
+
- Additional widget types (News, ByDates, etc.)
|
96
|
+
- Widget configuration testing
|
97
|
+
- Widget theme integration testing
|
98
|
+
- Performance testing for large widget datasets
|
99
|
+
|
100
|
+
## Files Modified
|
101
|
+
|
102
|
+
- `lib/scriptorium/widgets/widget.rb` - Added `include Scriptorium::Helpers`
|
103
|
+
- `test/unit/widgets.rb` - Created comprehensive widget test suite
|
104
|
+
|
105
|
+
## Achievement
|
106
|
+
|
107
|
+
✅ **Goal Reached:** Exceeded 1,000 assertions (1,058 total)
|
108
|
+
✅ **Widget Coverage:** Complete test coverage for widget system
|
109
|
+
✅ **Test Quality:** All tests passing with comprehensive assertions
|
110
|
+
✅ **Code Quality:** Well-structured, maintainable test suite
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# Post Class ID/Num Refactoring - Cleaner API Design
|
2
|
+
|
3
|
+
**Date:** 2025-07-27 18:00:00
|
4
|
+
**Status:** Completed
|
5
|
+
|
6
|
+
## Summary
|
7
|
+
|
8
|
+
Successfully refactored the `Scriptorium::Post` class to have a cleaner and more intuitive API design:
|
9
|
+
- **`id`** is now an integer (was previously a string alias for `num`)
|
10
|
+
- **`num`** remains a zero-padded string for file paths
|
11
|
+
- **`num!`** method removed (was redundant with new `id`)
|
12
|
+
- **`num_str`** method removed (was redundant with `num`)
|
13
|
+
|
14
|
+
## What Was Changed
|
15
|
+
|
16
|
+
### 1. Post Class Refactoring (`lib/scriptorium/post.rb`)
|
17
|
+
- **Added `@id` instance variable**: Integer version of the post number
|
18
|
+
- **Modified `initialize`**: Now sets both `@num` (string) and `@id` (integer)
|
19
|
+
- **Removed old `id` method**: Was just an alias for `num`
|
20
|
+
- **Removed `num!` method**: Functionality now provided by `id`
|
21
|
+
- **Updated `attr_reader`**: Now includes `:id`
|
22
|
+
|
23
|
+
### 2. Repository Integration (`lib/scriptorium/repo.rb`)
|
24
|
+
- **Fixed template variable**: `vars[:"post.id"] = num.to_s` to ensure string conversion for templates
|
25
|
+
|
26
|
+
### 3. API Class Fixes (`lib/scriptorium/api.rb`)
|
27
|
+
- **Fixed `create_post` method**: Added missing `blurb` parameter support
|
28
|
+
- **Fixed `quick_post` method**: Was calling wrong method (`post` instead of `create_post`)
|
29
|
+
|
30
|
+
### 4. Test Updates (`test/unit/post.rb`)
|
31
|
+
- **Updated `test_id`**: Now expects integer instead of string
|
32
|
+
- **Removed `num!` tests**: No longer needed
|
33
|
+
- **All tests pass**: 34 runs, 43 assertions
|
34
|
+
|
35
|
+
### 5. Manual Test Updates (`test/manual/test5.rb`)
|
36
|
+
- **Updated `generate_post` call**: Now uses `post.id` instead of `post.num!`
|
37
|
+
|
38
|
+
## Benefits of the Refactoring
|
39
|
+
|
40
|
+
1. **Clearer Intent**: `id` as integer clearly indicates it's for programmatic use
|
41
|
+
2. **Consistent API**: No more confusion between `num`, `num!`, and `id`
|
42
|
+
3. **Better Performance**: No need for string-to-integer conversion in `num!`
|
43
|
+
4. **Simpler Code**: Fewer methods to maintain and understand
|
44
|
+
|
45
|
+
## Usage Examples
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
post = Scriptorium::Post.new(repo, 123)
|
49
|
+
|
50
|
+
# File operations (use num)
|
51
|
+
post.num # => "0123"
|
52
|
+
post.dir # => "posts/0123/"
|
53
|
+
|
54
|
+
# Programmatic operations (use id)
|
55
|
+
post.id # => 123
|
56
|
+
@repo.generate_post(post.id) # Pass integer to generate_post
|
57
|
+
```
|
58
|
+
|
59
|
+
## Test Results
|
60
|
+
|
61
|
+
- **All tests pass**: 283 runs, 1056 assertions, 0 failures
|
62
|
+
- **API demo works**: Successfully creates posts with new integer `id`
|
63
|
+
- **Backward compatibility**: Existing code using `num` continues to work
|
64
|
+
|
65
|
+
## Files Modified
|
66
|
+
|
67
|
+
1. `lib/scriptorium/post.rb` - Core refactoring
|
68
|
+
2. `lib/scriptorium/repo.rb` - Template variable fix
|
69
|
+
3. `lib/scriptorium/api.rb` - Method signature fixes
|
70
|
+
4. `test/unit/post.rb` - Test updates
|
71
|
+
5. `test/manual/test5.rb` - Manual test fix
|
72
|
+
|
73
|
+
This refactoring eliminates the "clunkiness" in the Post class by providing a clear separation between string-based file operations (`num`) and integer-based programmatic operations (`id`).
|