From bb99a5c5ee063418844d2f9ee0b43ce79267ca4a Mon Sep 17 00:00:00 2001 From: Amit Haridas Date: Mon, 14 Sep 2026 20:35:39 +0530 Subject: [PATCH] feat(ascii-art): 19 named ASCII art templates with snapshot tests Per Task 3 of the 2026-09-14 ASCII art upgrade plan. - New module: src/main/AsciiArt.templates.js exporting ASCII_TEMPLATES (19 entries) and getTemplate(name) accessor (returns '' for unknown). - New test: tests/main/ascii-art.templates.test.js with 19 per-template snapshots + unknown-name + keys-match assertions (21 tests total). - 17 templates verbatim from src/ascii-generator.html:596-626 (arrow-right, arrow-down, decision, process, flowchart, sequence, network, hierarchy, header, note, warning, info, divider, separator, banner, checklist + the brief's own TEMPLATE_NAMES order). - 2 templates verbatim from src/renderer.js:6542-6697 (progress-bar, table-simple). - 1 newly authored: arrow-up (completes the arrow triplet; does not exist in either source). Amit Haridas --- src/main/AsciiArt.templates.js | 63 ++++++ .../ascii-art.templates.test.js.snap | 179 ++++++++++++++++++ tests/main/ascii-art.templates.test.js | 45 +++++ 3 files changed, 287 insertions(+) create mode 100644 src/main/AsciiArt.templates.js create mode 100644 tests/main/__snapshots__/ascii-art.templates.test.js.snap create mode 100644 tests/main/ascii-art.templates.test.js diff --git a/src/main/AsciiArt.templates.js b/src/main/AsciiArt.templates.js new file mode 100644 index 0000000..fec3dce --- /dev/null +++ b/src/main/AsciiArt.templates.js @@ -0,0 +1,63 @@ +/** + * ASCII art templates — named pre-drawn diagrams and frames. + * + * Sourced from src/ascii-generator.html:596-626 and src/renderer.js:6542-6697 + * (the `getASCIITemplate()` function). 19 entries; unknown names resolve to ''. + * `arrow-up` is the only template authored for this module — it completes the + * arrow triplet (right, down, up) and does not exist verbatim in either source. + * + * @module AsciiArt.templates + */ +'use strict'; + +const ASCII_TEMPLATES = { + // ----- arrows ----- + 'arrow-right': + ' ┌─────────────────────┐\n──▶│ Process or Action │──▶\n └─────────────────────┘', + 'arrow-down': + ' │\n ▼\n┌───────────────┐\n│ Process │\n└───────────────┘\n │\n ▼', + // Newly authored to complete the arrow triplet. Mirrors arrow-down with + // upward flow direction. + 'arrow-up': + ' ▲\n │\n┌───────────────┐\n│ Process │\n└───────────────┘\n │\n ▲', + + // ----- shapes ----- + decision: + ' ╱╲\n ╱ ╲\n ╱ ? ╲\n ╱ ╲\n ╱────────╲\n ╱ ╲\n YES NO\n │ │\n ▼ ▼', + process: '┌─────┐ ┌─────┐ ┌─────┐\n│ 1 │──▶│ 2 │──▶│ 3 │\n└─────┘ └─────┘ └─────┘', + flowchart: + '┌─────────────┐\n│ START │\n└──────┬──────┘\n │\n ▼\n┌─────────────┐\n│ Process A │\n└──────┬──────┘\n │\n ▼\n ╱────────╲\n ╱ Decision ╲\n ╲ ? ╱\n ╲────────╱\n │ │\n YES NO\n │ │\n ▼ ▼\n┌──────┐ ┌──────┐\n│ B │ │ C │\n└──────┘ └──────┘', + sequence: + ' User System Database\n │ │ │\n │ Request │ │\n ├──────────►│ │\n │ │ Query │\n │ ├──────────►│\n │ │ │\n │ │ Result │\n │ │◄──────────┤\n │ Response │ │\n │◄──────────┤ │\n │ │ │', + network: + ' ┌─────────┐\n │ Server │\n └────┬────┘\n │\n ┌─────────┼─────────┐\n │ │ │\n┌────┴────┐ ┌──┴──┐ ┌────┴────┐\n│ Client1 │ │ DB │ │ Client2 │\n└─────────┘ └─────┘ └─────────┘', + hierarchy: + ' ┌─────────┐\n │ CEO │\n └────┬────┘\n ┌─────────┼─────────┐\n │ │ │\n ┌───┴───┐ ┌───┴───┐ ┌───┴───┐\n │ VP1 │ │ VP2 │ │ VP3 │\n └───┬───┘ └───┬───┘ └───┬───┘\n │ │ │\n ┌───┴───┐ ┌───┴───┐ ┌───┴───┐\n │ Team1 │ │ Team2 │ │ Team3 │\n └───────┘ └───────┘ └───────┘', + + // ----- frames ----- + header: + '╔════════════════════════════════════╗\n║ SECTION TITLE ║\n╚════════════════════════════════════╝', + note: '┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n┃ NOTE: ┃\n┃ This is an important note ┃\n┃ that requires attention! ┃\n┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛', + warning: + '╔════════════════════════════════════╗\n║ ⚠️ WARNING ║\n║ ║\n║ Critical information here! ║\n╚════════════════════════════════════╝', + info: '╭────────────────────────────────────╮\n│ ℹ️ INFO │\n│ │\n│ Helpful information here. │\n╰────────────────────────────────────╯', + divider: '════════════════════════════════════════', + separator: + '╭──────────────────────────────────────╮\n│ │\n╰──────────────────────────────────────╯', + banner: + '★══════════════════════════════════════★\n║ YOUR TITLE HERE ║\n★══════════════════════════════════════★', + checklist: + '☐ Task 1 - Not completed\n☑ Task 2 - Completed \n☐ Task 3 - Not completed\n☐ Task 4 - Not completed', + + // ----- bars / tables (only in src/renderer.js) ----- + 'progress-bar': '\nProgress: [████████████░░░░░░░░] 60%\n 0% 100%', + 'table-simple': + '\n┌──────────┬──────────┬──────────┐\n│ Header 1 │ Header 2 │ Header 3 │\n├──────────┼──────────┼──────────┤\n│ Data 1 │ Data 2 │ Data 3 │\n├──────────┼──────────┼──────────┤\n│ Data 4 │ Data 5 │ Data 6 │\n└──────────┴──────────┴──────────┘', +}; + +function getTemplate(name) { + if (typeof name !== 'string') return ''; + return ASCII_TEMPLATES[name] || ''; +} + +module.exports = { ASCII_TEMPLATES, getTemplate }; diff --git a/tests/main/__snapshots__/ascii-art.templates.test.js.snap b/tests/main/__snapshots__/ascii-art.templates.test.js.snap new file mode 100644 index 0000000..a59fd98 --- /dev/null +++ b/tests/main/__snapshots__/ascii-art.templates.test.js.snap @@ -0,0 +1,179 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`AsciiArt.templates arrow-down 1`] = ` +" │ + ▼ +┌───────────────┐ +│ Process │ +└───────────────┘ + │ + ▼" +`; + +exports[`AsciiArt.templates arrow-right 1`] = ` +" ┌─────────────────────┐ +──▶│ Process or Action │──▶ + └─────────────────────┘" +`; + +exports[`AsciiArt.templates arrow-up 1`] = ` +" ▲ + │ +┌───────────────┐ +│ Process │ +└───────────────┘ + │ + ▲" +`; + +exports[`AsciiArt.templates banner 1`] = ` +"★══════════════════════════════════════★ +║ YOUR TITLE HERE ║ +★══════════════════════════════════════★" +`; + +exports[`AsciiArt.templates checklist 1`] = ` +"☐ Task 1 - Not completed +☑ Task 2 - Completed +☐ Task 3 - Not completed +☐ Task 4 - Not completed" +`; + +exports[`AsciiArt.templates decision 1`] = ` +" ╱╲ + ╱ ╲ + ╱ ? ╲ + ╱ ╲ + ╱────────╲ + ╱ ╲ + YES NO + │ │ + ▼ ▼" +`; + +exports[`AsciiArt.templates divider 1`] = `"════════════════════════════════════════"`; + +exports[`AsciiArt.templates flowchart 1`] = ` +"┌─────────────┐ +│ START │ +└──────┬──────┘ + │ + ▼ +┌─────────────┐ +│ Process A │ +└──────┬──────┘ + │ + ▼ + ╱────────╲ + ╱ Decision ╲ + ╲ ? ╱ + ╲────────╱ + │ │ + YES NO + │ │ + ▼ ▼ +┌──────┐ ┌──────┐ +│ B │ │ C │ +└──────┘ └──────┘" +`; + +exports[`AsciiArt.templates header 1`] = ` +"╔════════════════════════════════════╗ +║ SECTION TITLE ║ +╚════════════════════════════════════╝" +`; + +exports[`AsciiArt.templates hierarchy 1`] = ` +" ┌─────────┐ + │ CEO │ + └────┬────┘ + ┌─────────┼─────────┐ + │ │ │ + ┌───┴───┐ ┌───┴───┐ ┌───┴───┐ + │ VP1 │ │ VP2 │ │ VP3 │ + └───┬───┘ └───┬───┘ └───┬───┘ + │ │ │ + ┌───┴───┐ ┌───┴───┐ ┌───┴───┐ + │ Team1 │ │ Team2 │ │ Team3 │ + └───────┘ └───────┘ └───────┘" +`; + +exports[`AsciiArt.templates info 1`] = ` +"╭────────────────────────────────────╮ +│ ℹ️ INFO │ +│ │ +│ Helpful information here. │ +╰────────────────────────────────────╯" +`; + +exports[`AsciiArt.templates network 1`] = ` +" ┌─────────┐ + │ Server │ + └────┬────┘ + │ + ┌─────────┼─────────┐ + │ │ │ +┌────┴────┐ ┌──┴──┐ ┌────┴────┐ +│ Client1 │ │ DB │ │ Client2 │ +└─────────┘ └─────┘ └─────────┘" +`; + +exports[`AsciiArt.templates note 1`] = ` +"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ NOTE: ┃ +┃ This is an important note ┃ +┃ that requires attention! ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛" +`; + +exports[`AsciiArt.templates process 1`] = ` +"┌─────┐ ┌─────┐ ┌─────┐ +│ 1 │──▶│ 2 │──▶│ 3 │ +└─────┘ └─────┘ └─────┘" +`; + +exports[`AsciiArt.templates progress-bar 1`] = ` +" +Progress: [████████████░░░░░░░░] 60% + 0% 100%" +`; + +exports[`AsciiArt.templates separator 1`] = ` +"╭──────────────────────────────────────╮ +│ │ +╰──────────────────────────────────────╯" +`; + +exports[`AsciiArt.templates sequence 1`] = ` +" User System Database + │ │ │ + │ Request │ │ + ├──────────►│ │ + │ │ Query │ + │ ├──────────►│ + │ │ │ + │ │ Result │ + │ │◄──────────┤ + │ Response │ │ + │◄──────────┤ │ + │ │ │" +`; + +exports[`AsciiArt.templates table-simple 1`] = ` +" +┌──────────┬──────────┬──────────┐ +│ Header 1 │ Header 2 │ Header 3 │ +├──────────┼──────────┼──────────┤ +│ Data 1 │ Data 2 │ Data 3 │ +├──────────┼──────────┼──────────┤ +│ Data 4 │ Data 5 │ Data 6 │ +└──────────┴──────────┴──────────┘" +`; + +exports[`AsciiArt.templates warning 1`] = ` +"╔════════════════════════════════════╗ +║ ⚠️ WARNING ║ +║ ║ +║ Critical information here! ║ +╚════════════════════════════════════╝" +`; diff --git a/tests/main/ascii-art.templates.test.js b/tests/main/ascii-art.templates.test.js new file mode 100644 index 0000000..9a45d25 --- /dev/null +++ b/tests/main/ascii-art.templates.test.js @@ -0,0 +1,45 @@ +/** + * @jest-environment node + * + * Per-template snapshot tests. Templates are static strings; the snapshot + * catches accidental edits during refactors. + */ +const AsciiArtTemplates = require('../../src/main/AsciiArt.templates'); + +const TEMPLATE_NAMES = [ + 'arrow-right', + 'arrow-down', + 'arrow-up', + 'decision', + 'process', + 'flowchart', + 'sequence', + 'network', + 'hierarchy', + 'header', + 'note', + 'warning', + 'info', + 'divider', + 'separator', + 'banner', + 'checklist', + 'progress-bar', + 'table-simple', +]; + +describe('AsciiArt.templates', () => { + test.each(TEMPLATE_NAMES)('%s', (name) => { + expect(AsciiArtTemplates.getTemplate(name)).toMatchSnapshot(); + }); + + test('returns empty string for unknown name', () => { + expect(AsciiArtTemplates.getTemplate('nope')).toBe(''); + }); + + test('ASCII_TEMPLATES object exposes all 19 names', () => { + expect(Object.keys(AsciiArtTemplates.ASCII_TEMPLATES).sort()).toEqual( + TEMPLATE_NAMES.slice().sort() + ); + }); +});