const test = require('node:test'); const assert = require('node:assert/strict'); const filaments = require('../lib/filaments'); const spools = (...materials) => materials.map((m, i) => ({ id: i + 1, material: m, remaining_g: 500 })); test('one spool per slot: a four-colour print needs four spools', () => { // The case that caught this out: an AMS bookmark in four PLA colours, and one // spool of white on the shelf. Owning "PLA" is not enough. const fourColour = [ { type: 'PLA', colour: '#000000' }, { type: 'PLA', colour: '#586579' }, { type: 'PLA', colour: '#8E9089' }, { type: 'PLA', colour: '#FFFFFF' }, ]; assert.equal(filaments.isPrintable(fourColour, spools('PLA')), false); assert.deepEqual(filaments.shortfall(fourColour, spools('PLA')), [{ material: 'PLA', need: 4, have: 1 }]); assert.equal(filaments.isPrintable(fourColour, spools('PLA', 'PLA', 'PLA', 'PLA')), true); assert.deepEqual(filaments.shortfall(fourColour, spools('PLA', 'PLA', 'PLA', 'PLA')), []); }); test('a single-filament model prints from a single spool', () => { assert.equal(filaments.isPrintable([{ type: 'PLA', colour: '#FFF' }], spools('PLA')), true); }); test('slots are counted per material', () => { const mixed = [{ type: 'PLA' }, { type: 'PLA' }, { type: 'PETG' }]; assert.deepEqual(filaments.slotsNeeded(mixed), [{ material: 'PLA', count: 2 }, { material: 'PETG', count: 1 }]); assert.deepEqual(filaments.shortfall(mixed, spools('PLA', 'PETG')), [{ material: 'PLA', need: 2, have: 1 }]); assert.equal(filaments.isPrintable(mixed, spools('PLA', 'PLA', 'PETG')), true); }); test('colour is ignored — a different colour still prints', () => { const project = [{ type: 'PLA', colour: '#FF0000' }]; assert.equal(filaments.isPrintable(project, [{ material: 'PLA', colour_hex: '#0000FF', remaining_g: 200 }]), true); }); test('case and spacing don’t matter, but a different material does', () => { assert.equal(filaments.normalise(' pla basic '), 'PLA BASIC'); // PLA-CF is carbon filled: a plain PLA spool is not a substitute. assert.deepEqual(filaments.shortfall([{ type: 'PLA-CF' }], spools('PLA')), [{ material: 'PLA-CF', need: 1, have: 0 }]); assert.deepEqual(filaments.shortfall([{ type: 'pla' }], spools('PLA')), []); }); test('an empty spool doesn’t count, but an unweighed one does', () => { const project = [{ type: 'PLA' }]; assert.deepEqual(filaments.shortfall(project, [{ material: 'PLA', remaining_g: 0 }]), [{ material: 'PLA', need: 1, have: 0 }]); assert.deepEqual(filaments.shortfall(project, [{ material: 'PLA', remaining_g: null }]), []); assert.deepEqual(filaments.shortfall(project, [{ material: 'PLA' }]), []); }); test('a model we know nothing about is not claimed to be printable', () => { assert.equal(filaments.isPrintable(null, spools('PLA')), false); assert.equal(filaments.isPrintable([], spools('PLA')), false); assert.deepEqual(filaments.slotsNeeded(null), []); });