import { readFileSync } from 'node:fs'; import { strictEqual, ok, throws } from 'node:assert'; import { describe, it } from 'node:test'; import { findLib, init, free, loadBundleDefault, loadBundle, reduce, app, ofString, ofNumber, toBool, toString, decode, decodeType, } from '../src/lib.js'; const fixtureDir = '../../test/fixtures'; const libPath = findLib(); describe('run bundle — booleans', () => { it('true.arboricx evaluates to true', () => { const ctx = init(libPath); try { const bundle = readFileSync(`${fixtureDir}/true.arboricx`); const root = loadBundleDefault(ctx, bundle); const result = reduce(ctx, root); strictEqual(toBool(ctx, result), true); strictEqual(decodeType(ctx, result), 'bool'); strictEqual(decode(ctx, result), 'true'); } finally { free(ctx); } }); it('false.arboricx evaluates to false', () => { const ctx = init(libPath); try { const bundle = readFileSync(`${fixtureDir}/false.arboricx`); const root = loadBundleDefault(ctx, bundle); const result = reduce(ctx, root); strictEqual(toBool(ctx, result), false); strictEqual(decodeType(ctx, result), 'bool'); strictEqual(decode(ctx, result), 'false'); } finally { free(ctx); } }); }); describe('run bundle — id', () => { it('id applied to string returns the string', () => { const ctx = init(libPath); try { const bundle = readFileSync(`${fixtureDir}/id.arboricx`); const idRoot = loadBundleDefault(ctx, bundle); const arg = ofString(ctx, 'hello'); const applied = app(ctx, idRoot, arg); const result = reduce(ctx, applied); strictEqual(toString(ctx, result), 'hello'); strictEqual(decodeType(ctx, result), 'string'); } finally { free(ctx); } }); }); describe('run bundle — append', () => { it('append "hello " "world" = "hello world"', () => { const ctx = init(libPath); try { const bundle = readFileSync(`${fixtureDir}/append.arboricx`); let term = loadBundleDefault(ctx, bundle); term = app(ctx, term, ofString(ctx, 'hello ')); term = app(ctx, term, ofString(ctx, 'world')); const result = reduce(ctx, term); strictEqual(toString(ctx, result), 'hello world'); } finally { free(ctx); } }); }); describe('run bundle — notQ', () => { it('notQ loads and reduces without error', () => { const ctx = init(libPath); try { const bundle = readFileSync(`${fixtureDir}/notQ.arboricx`); const root = loadBundleDefault(ctx, bundle); const result = reduce(ctx, root); ok(result > 0); } finally { free(ctx); } }); }); describe('run bundle — named export', () => { it('loadBundle selects named export', () => { const ctx = init(libPath); try { const bundle = readFileSync(`${fixtureDir}/id.arboricx`); const root = loadBundle(ctx, bundle, 'id'); ok(root > 0); // id is a function; apply it before reducing const applied = app(ctx, root, ofString(ctx, 'test')); const result = reduce(ctx, applied); strictEqual(toString(ctx, result), 'test'); } finally { free(ctx); } }); it('missing export throws', () => { const ctx = init(libPath); try { const bundle = readFileSync(`${fixtureDir}/id.arboricx`); throws(() => loadBundle(ctx, bundle, 'nonexistent'), /failed/); } finally { free(ctx); } }); });