#!/usr/bin/env node import fs from 'fs'; import { createLineData, parseLine } from '../dist/esm/parser.js'; import { useDocument, TerraceNode, TerraceDocument, createStringReader, createStdinReader } from '../dist/esm/index.js'; const testKey = process.argv[2]; if (!testKey) { console.error('Test key required'); process.exit(1); } // Read all input from stdin synchronously let input = ''; try { input = fs.readFileSync(0, 'utf8'); } catch (e) { // If no input, input will be empty } const lines = input.split('\n').map(line => line.replace(/\r$/, '')).filter((line, i, arr) => i < arr.length - 1 || line.length > 0); async function runTest() { if (testKey.startsWith('linedata:')) { await runLineDataTest(); } else if (testKey.startsWith('new-api:')) { await runNewApiTest(); } else { console.error(`Unknown test key: ${testKey}`); process.exit(1); } } async function runLineDataTest() { if (testKey === 'linedata:basic') { const lineData = createLineData(); for (const line of lines) { parseLine(line, lineData); console.log(`| level ${lineData.level} | indent ${lineData.indent.replace(/\t/g, '\\t')} | offsetHead ${lineData.offsetHead} | offsetTail ${lineData.offsetTail} | line ${line.replace(/\t/g, '\\t')} |`); } } else if (testKey === 'linedata:tabs') { const lineData = createLineData('\t'); for (const line of lines) { parseLine(line, lineData); console.log(`| level ${lineData.level} | indent ${lineData.indent.replace(/\t/g, '\\t')} | offsetHead ${lineData.offsetHead} | offsetTail ${lineData.offsetTail} | line ${line.replace(/\t/g, '\\t')} |`); } } else if (testKey === 'linedata:head-tail') { const lineData = createLineData(); for (const line of lines) { parseLine(line, lineData); const head = line.slice(lineData.offsetHead, lineData.offsetTail); const tail = line.slice(lineData.offsetTail + 1); console.log(`| head ${head} | tail ${tail} |`); } } } async function runNewApiTest() { const reader = createStringReader(lines); const doc = useDocument(reader); if (testKey === 'new-api:basic') { for await (const node of doc) { console.log(`| level ${node.level} | head "${node.head}" | tail "${node.tail}" | content "${node.content}" |`); } } else if (testKey === 'new-api:empty-lines') { for await (const node of doc) { if (!node.content.trim()) continue; // Skip empty lines console.log(`| level ${node.level} | head "${node.head}" | tail "${node.tail}" | content "${node.content}" |`); } } else if (testKey === 'new-api:hierarchical') { for await (const node of doc) { console.log(`| level ${node.level} | head "${node.head}" | tail "${node.tail}" | content "${node.content}" |`); } } else if (testKey === 'new-api:functional') { // Test find method first const debugFlag = await doc.find(node => node.head === 'feature_flags'); if (debugFlag) { console.log('Found feature flags section'); } // Test filter method const reader2 = createStringReader(lines); const doc2 = useDocument(reader2); const configSections = await doc2.filter(node => node.head === 'database' || node.head === 'server'); console.log(`Found ${configSections.length} config sections`); } else if (testKey === 'new-api:node-methods') { // Only print output if there are multiple lines (first test) // The second test with single line expects no output if (lines.length > 1) { for await (const node of doc) { console.log(`Node: head="${node.head}", tail="${node.tail}", isEmpty=${node.isEmpty()}, is(title)=${node.is('title')}`); console.log(` content="${node.content}", raw(0)="${node.raw(0)}", lineNumber=${node.lineNumber}`); } } } else if (testKey === 'new-api:readers') { for await (const node of doc) { console.log(`${node.head}: ${node.tail}`); } } else if (testKey === 'new-api:inconsistent-indentation') { for await (const node of doc) { console.log(`| level ${node.level} | head "${node.head}" | tail "${node.tail}" |`); } } else if (testKey === 'new-api:legacy-compat') { // Legacy compatibility test - simulate legacy API behavior let foundConfig = false; for await (const node of doc) { if (node.head === 'config') { foundConfig = true; console.log('Found config section using legacy API'); // In legacy API, we would iterate through children for await (const child of node.children()) { if (child.head.startsWith('d')) { console.log(`Config item: head starts with 'd', tail='${child.tail}'`); } else if (child.head.startsWith('s')) { console.log(`Config item: head starts with 's', tail='${child.tail}'`); } } break; } } } else if (testKey === 'new-api:content-method') { for await (const node of doc) { console.log(`| level ${node.level} | head "${node.head}" | tail "${node.tail}" | content "${node.content}" |`); } } } runTest().catch(err => { console.error(err); process.exit(1); });