nsr-nodejs 0.3.0

Node.js bindings for the NSR (Neuro-Symbolic Recursive) AI framework
Documentation
/**
 * NSR Node.js Bindings Test
 */

const nsr = require('./index.js');

console.log('='.repeat(60));
console.log('NSR NODE.JS BINDINGS - PROOF OF FUNCTIONALITY');
console.log('='.repeat(60));

let testsPassed = 0;
let testsTotal = 0;

function test(name, condition) {
    testsTotal++;
    const status = condition ? '✓ PASS' : '✗ FAIL';
    if (condition) testsPassed++;
    console.log(`  ${status}: ${name}`);
    return condition;
}

// Test 1: Module imports
console.log('\n1. Module Import');
test('nsr module imported', nsr !== undefined);
test('version exists', typeof nsr.version === 'function');
console.log(`   Version: ${nsr.version()}`);

// Test 2: Types exist
console.log('\n2. Core Types Exist');
test('NSRMachine', typeof nsr.NSRMachine === 'function');
test('NSRMachineBuilder', typeof nsr.NSRMachineBuilder === 'function');
test('GroundedInput', typeof nsr.GroundedInput === 'function');
test('SemanticValue', typeof nsr.SemanticValue === 'function');
test('Program', typeof nsr.Program === 'function');
test('TrainingExample', typeof nsr.TrainingExample === 'function');

// Test 3: Preset functions
console.log('\n3. Preset Functions');
test('scanMachine()', typeof nsr.scanMachine === 'function');
test('pcfgMachine()', typeof nsr.pcfgMachine === 'function');
test('hintMachine()', typeof nsr.hintMachine === 'function');
test('cogsMachine()', typeof nsr.cogsMachine === 'function');

// Test 4: Create machine
console.log('\n4. Machine Creation');
const machine = new nsr.NSRMachine();
test('NSRMachine() creates instance', machine !== null);
test('vocabularySize property', machine.vocabularySize >= 0);

// Test 5: Builder pattern
console.log('\n5. Builder Pattern');
const builder = new nsr.NSRMachineBuilder();
test('Builder created', builder !== null);
const built = builder.embeddingDim(64).addSymbol('test').build();
test('Builder.build() returns machine', built !== null);
test('Built machine has symbol', built.vocabularySize >= 1);

// Test 6: Input types
console.log('\n6. Input Types');
const textInput = nsr.GroundedInput.text('hello');
test('GroundedInput.text()', textInput !== null);
test('isText() returns true', textInput.isText());
test('asText() returns value', textInput.asText() === 'hello');

const numInput = nsr.GroundedInput.number(42.0);
test('GroundedInput.number()', numInput !== null);
test('isNumber() returns true', numInput.isNumber());

// Test 7: Semantic values
console.log('\n7. Semantic Values');
const intVal = nsr.SemanticValue.integer(42);
test('SemanticValue.integer()', intVal !== null);
test('asInteger() returns 42', intVal.asInteger() === 42);

const strVal = nsr.SemanticValue.string('hello');
test('SemanticValue.string()', strVal !== null);
test('asString() returns hello', strVal.asString() === 'hello');

// Test 8: Programs
console.log('\n8. Programs');
const constProg = nsr.Program.constant(nsr.SemanticValue.integer(1));
test('Program.constant()', constProg !== null);
test('depth() returns 1', constProg.depth() === 1);

const childProg = nsr.Program.child(0);
test('Program.child()', childProg !== null);

// Test 9: Training
console.log('\n9. Training');
const example = new nsr.TrainingExample(
    [nsr.GroundedInput.text('x')],
    nsr.SemanticValue.integer(1)
);
test('TrainingExample created', example !== null);
test('inputCount property', example.inputCount === 1);

// Test 10: Preset machine and inference
console.log('\n10. Inference');
const scan = nsr.scanMachine();
test('scanMachine() returns machine', scan !== null);
test('scan vocabularySize > 0', scan.vocabularySize > 0);

const result = scan.infer([nsr.GroundedInput.text('walk')]);
test('infer() returns result', result !== null);
test('result.confidence() > 0', result.confidence() > 0);
test('result.symbols() returns array', Array.isArray(result.symbols()));

// Test 11: Training flow
console.log('\n11. Full Training Flow');
const m = new nsr.NSRMachineBuilder()
    .embeddingDim(32)
    .addSymbol('a')
    .addSymbol('b')
    .build();

const examples = [
    nsr.TrainingExample.fromText('a', nsr.SemanticValue.integer(1)),
    nsr.TrainingExample.fromText('b', nsr.SemanticValue.integer(2)),
];
const stats = m.train(examples);
test('train() returns stats', stats !== null);
test('stats.totalExamples === 2', stats.totalExamples === 2);
test('stats.trainingTimeMs >= 0', stats.trainingTimeMs >= 0);

// Test 12: Evaluation
console.log('\n12. Evaluation');
const evalResult = m.evaluate(examples);
test('evaluate() returns result', evalResult !== null);
test('accuracy property exists', typeof evalResult.accuracy === 'number');
test('total === 2', evalResult.total === 2);

// Test 13: Statistics
console.log('\n13. Statistics');
const machineStats = m.statistics;
test('statistics property', machineStats !== null);
test('trainingExamples tracked', machineStats.trainingExamples === 2);

// Test 14: Symbol operations
console.log('\n14. Symbol Operations');
test('getAllSymbols() works', Array.isArray(m.getAllSymbols()));
test('getSymbolName(0) works', m.getSymbolName(0) === 'a');
test('getSymbolId("a") works', m.getSymbolId('a') === 0);

// Summary
console.log('\n' + '='.repeat(60));
console.log(`RESULTS: ${testsPassed}/${testsTotal} tests passed`);
console.log('='.repeat(60));

if (testsPassed === testsTotal) {
    console.log('\n🎉 ALL TESTS PASSED - NSR Node.js Bindings are FULLY FUNCTIONAL!');
    process.exit(0);
} else {
    console.log(`\n  ${testsTotal - testsPassed} tests failed`);
    process.exit(1);
}