All files / blong-gogo/src lib.test.ts

0% Statements 0/102
0% Branches 0/1
0% Functions 0/1
0% Lines 0/102

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103                                                                                                                                                                                                             
/**
 * Unit tests for lib.ts utilities — parseAnnotatedKey and camelToSentence.
 *
 * These functions drive the annotation syntax and sub-property destructuring
 * naming features of the handler proxy (layerProxy.ts):
 *
 *  - `parseAnnotatedKey("@name bill payment testFn")`
 *      → Mode A: injects `$meta.name = "bill payment"` on testFn
 *  - `parseAnnotatedKey("@cache ttl=10 testFn")`
 *      → Mode B: merges config.handler.cache into $meta, then sets cache.ttl = "10"
 *  - `camelToSentence("bulkOrder")`
 *      → Returns "bulk order" — used for $meta.name in sub-property destructuring
 */

import {test} from 'tap';

import {camelToSentence, parseAnnotatedKey} from './lib.ts';

// ---------------------------------------------------------------------------
// parseAnnotatedKey — valid inputs
// ---------------------------------------------------------------------------

test('parseAnnotatedKey — single annotation with params (Mode A)', async t => {
    const result = parseAnnotatedKey('@name bill payment testFn');
    t.equal(result.handlerName, 'testFn');
    t.equal(result.annotations.length, 1);
    t.equal(result.annotations[0].name, 'name');
    t.same(result.annotations[0].params, ['bill', 'payment']);
});

test('parseAnnotatedKey — annotation with key=value params (Mode B)', async t => {
    const result = parseAnnotatedKey('@cache ttl=10 testFn');
    t.equal(result.handlerName, 'testFn');
    t.equal(result.annotations.length, 1);
    t.equal(result.annotations[0].name, 'cache');
    t.same(result.annotations[0].params, ['ttl=10']);
});

test('parseAnnotatedKey — annotation with no params (Mode B, no overrides)', async t => {
    const result = parseAnnotatedKey('@cache testFn');
    t.equal(result.handlerName, 'testFn');
    t.equal(result.annotations.length, 1);
    t.equal(result.annotations[0].name, 'cache');
    t.same(result.annotations[0].params, []);
});

test('parseAnnotatedKey — multiple annotations stack correctly', async t => {
    const result = parseAnnotatedKey('@name bill payment @timeout 5000 testFn');
    t.equal(result.handlerName, 'testFn');
    t.equal(result.annotations.length, 2);
    t.equal(result.annotations[0].name, 'name');
    t.same(result.annotations[0].params, ['bill', 'payment']);
    t.equal(result.annotations[1].name, 'timeout');
    t.same(result.annotations[1].params, ['5000']);
});

test('parseAnnotatedKey — no annotations, handler name only', async t => {
    const result = parseAnnotatedKey('testFn');
    t.equal(result.handlerName, 'testFn');
    t.equal(result.annotations.length, 0);
});

test('parseAnnotatedKey — trims extra whitespace', async t => {
    const result = parseAnnotatedKey('  @name foo  testFn  ');
    t.equal(result.handlerName, 'testFn');
    t.equal(result.annotations.length, 1);
    t.same(result.annotations[0].params, ['foo']);
});

// ---------------------------------------------------------------------------
// parseAnnotatedKey — malformed inputs throw
// ---------------------------------------------------------------------------

test('parseAnnotatedKey — throws when key is empty', async t => {
    t.throws(() => parseAnnotatedKey(''), /Malformed annotated key/);
});

test('parseAnnotatedKey — throws when last token starts with @', async t => {
    t.throws(() => parseAnnotatedKey('@name @cache'), /Malformed annotated key/);
});

test('parseAnnotatedKey — throws when only whitespace', async t => {
    t.throws(() => parseAnnotatedKey('   '), /Malformed annotated key/);
});

// ---------------------------------------------------------------------------
// camelToSentence — used for sub-property destructuring name injection
// ---------------------------------------------------------------------------

test('camelToSentence — converts camelCase to sentence', async t => {
    t.equal(camelToSentence('bulkOrder'), 'bulk order');
    t.equal(camelToSentence('billPayment'), 'bill payment');
    t.equal(camelToSentence('orderOrderCreate'), 'order order create');
});

test('camelToSentence — leaves lowercase unchanged', async t => {
    t.equal(camelToSentence('order'), 'order');
});

test('camelToSentence — handles consecutive capitals (e.g. acronyms)', async t => {
    t.equal(camelToSentence('parseXMLDocument'), 'parse xml document');
});