A Bambu Studio or OrcaSlicer 3MF names the filaments its plates use, but reading that means shelling out to Python, so it can't be done per page load. A background pass — in the same loop as thumbnails and fingerprints — reads it once per model into models.filaments, which turns "what can I print now" into a comparison of two lists. Adds a Filament page for the spools on hand: material, colour, brand and grams left, edited in place. Matching is on material only; a project's exact colours would make almost nothing printable, and a different colour still prints. Measured on the dev library: 10 models read with no errors, the two Bambu projects resolving to four PLA colours each, and no plate images written because the reader skips --images and queues behind anything interactive. Not done yet: nothing in the library view uses this — no "printable now" badge or filter — and the Filament page itself has not been seen rendered, because the local preview browser has no session. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
46 lines
2.3 KiB
JavaScript
46 lines
2.3 KiB
JavaScript
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('a model is printable when every filament it names is on a spool', () => {
|
||
const project = [{ type: 'PLA', colour: '#00AE42' }, { type: 'PETG', colour: '#000000' }];
|
||
assert.equal(filaments.isPrintable(project, spools('PLA', 'PETG', 'ABS')), true);
|
||
assert.deepEqual(filaments.missingMaterials(project, spools('PLA', 'PETG')), []);
|
||
});
|
||
|
||
test('what is missing is named, not just refused', () => {
|
||
const project = [{ type: 'PLA' }, { type: 'PETG' }, { type: 'TPU' }];
|
||
assert.deepEqual(filaments.missingMaterials(project, spools('PLA')), ['PETG', 'TPU']);
|
||
assert.equal(filaments.isPrintable(project, spools('PLA')), false);
|
||
});
|
||
|
||
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.missingMaterials([{ type: 'PLA-CF' }], spools('PLA')), ['PLA-CF']);
|
||
assert.deepEqual(filaments.missingMaterials([{ type: 'pla' }], spools('PLA')), []);
|
||
});
|
||
|
||
test('an empty spool doesn’t count, but an unweighed one does', () => {
|
||
const project = [{ type: 'PLA' }];
|
||
assert.deepEqual(filaments.missingMaterials(project, [{ material: 'PLA', remaining_g: 0 }]), ['PLA']);
|
||
assert.deepEqual(filaments.missingMaterials(project, [{ material: 'PLA', remaining_g: null }]), []);
|
||
assert.deepEqual(filaments.missingMaterials(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);
|
||
});
|
||
|
||
test('the same material twice is asked for once', () => {
|
||
const project = [{ type: 'PLA', colour: '#FFF' }, { type: 'PLA', colour: '#000' }];
|
||
assert.deepEqual(filaments.missingMaterials(project, []), ['PLA']);
|
||
});
|