improvements

This commit is contained in:
2026-09-28 23:22:53 +02:00
parent 3206b1b3f1
commit 2bae0c3946
4 changed files with 196 additions and 45 deletions
+53 -13
View File
@@ -11,8 +11,8 @@ function harness() {
' Plugin.register(PLUGIN_ID, {', `globalThis.props = { indexPropZip, propResourcePath, openPropSource,
loadPropAsset, resolvePropModel, propTextureId, propDisplayTransform, manualPropModel,
writePropDefinition, effectivePropEntry, effectivePropItem, propEntryKey, extrudePropPixels, discoverPropSources,
buildPropMesh, refreshPropPreviews, clearPropMeshes, propFaceVertices, propDefaultUv, propItemOptions,
applyPropPreview, createPropDialog, showPropDialog, readPropPreviews };
buildPropMesh, refreshPropPreviews, clearPropMeshes, propFaceVertices, propDefaultUv,
applyPropPreview, createPropDialog, showPropDialog, readPropPreviews, importPropPreviews };
Plugin.register(PLUGIN_ID, {`);
const context = { Buffer, requireNativeModule: require, console, Plugin: { register() {} },
Project: { uuid: 'test' }, Group: { all: [] }, Animation: { all: [] }, localStorage: { getItem() { return null; } } };
@@ -161,16 +161,6 @@ test('asset discovery reuses Asset Browser cache without requiring the plugin',
assert.equal(sources[0].label,'Asset Browser: 1.21.11');
});
test('item picker includes entries after the first hundred and filters the full source list', () => {
const h = harness();
const items = Array.from({ length: 1505 }, (_, index) => `minecraft:item_${String(index).padStart(4, '0')}`);
const all = h.propItemOptions(items, '');
assert.equal(Object.keys(all).length, 1506);
assert.equal(all['minecraft:item_1504'], 'minecraft:item_1504');
const searched = h.propItemOptions(items, ' ITEM_1504 ');
assert.deepEqual(Object.keys(searched), ['', 'minecraft:item_1504']);
});
test('Item Props uses native dialog form fields and Apply/Cancel actions', () => {
const h = harness();
let configuration;
@@ -189,7 +179,57 @@ test('Item Props uses native dialog form fields and Apply/Cancel actions', () =>
assert.equal(configuration.form.jar.type,'file');
assert.equal(configuration.form.folder.type,'folder');
assert.equal(configuration.form.texture.type,'file');
assert.equal(typeof configuration.form.item_choice.options,'function');
assert.equal(configuration.form.item_search,undefined);
assert.equal(configuration.form.item_choice.type,'select');
});
test('item dropdown includes the entire asset source alongside editable Item ID', (t) => {
const h = harness(), root = fs.mkdtempSync(path.join(os.tmpdir(),'ad-item-picker-'));
t.after(() => fs.rmSync(root,{recursive:true,force:true}));
const items = path.join(root,'assets','minecraft','items');
fs.mkdirSync(items,{recursive:true});
for(let index=0;index<105;index++) fs.writeFileSync(path.join(items,`item_${String(index).padStart(3,'0')}.json`),'{}');
h.context.Animation.selected = { name:'test.p1' };
h.context.localStorage = { getItem() { return root; } };
let configuration;
h.context.Dialog = class {
constructor(options){ configuration=options; }
};
h.createPropDialog();
const options = configuration.form.item_choice.options();
assert.equal(Object.keys(options).length,106);
assert.equal(options['minecraft:item_104'],'minecraft:item_104');
assert.equal(configuration.form.item.value,'minecraft:carrot');
});
test('imported definitions create default and stage item previews without losing hidden overrides', (t) => {
const h = harness(), root = fs.mkdtempSync(path.join(os.tmpdir(),'ad-imported-props-'));
t.after(() => fs.rmSync(root,{recursive:true,force:true}));
for (const item of ['carrot','stick']) {
const write = (relative,data) => {
const file=path.join(root,relative); fs.mkdirSync(path.dirname(file),{recursive:true});
fs.writeFileSync(file,typeof data==='string'?data:JSON.stringify(data));
};
write(`assets/minecraft/items/${item}.json`,{model:{type:'minecraft:model',model:`minecraft:item/${item}`}});
write(`assets/minecraft/models/item/${item}.json`,{parent:'minecraft:builtin/generated',textures:{layer0:`minecraft:item/${item}`}});
write(`assets/minecraft/textures/item/${item}.png`,'png bytes');
}
const definition={actors:[{label:'player',prop_right:'minecraft:carrot'}],stages:[
{stage:1},{stage:2,props:{player:{prop_right:'minecraft:stick'}}},{stage:3,props:{player:{prop_right:null}}}]};
const oldKey=h.propEntryKey('other','player','left',0);
const result=h.importPropPreviews('example',definition,[root],{[oldKey]:{animation:'other'}});
assert.equal(result.warnings.length,0);
assert.equal(result.entries[oldKey].animation,'other');
const get=(stage)=>result.entries[h.propEntryKey('example','player','right',stage)];
assert.equal(get(0).item,'minecraft:carrot');
assert.equal(get(0).asset.parts[0].generated,true);
assert.equal(get(1),undefined);
assert.equal(get(2).item,'minecraft:stick');
assert.equal(get(3).mode,'hidden');
const missing=h.importPropPreviews('example',{actors:[{label:'player',prop_left:'minecraft:missing'}],stages:[{stage:1}]},[root],result.entries);
assert.match(missing.warnings[0],/minecraft:missing/);
assert.equal(missing.entries[h.propEntryKey('example','player','left',0)],undefined);
assert.equal(missing.entries[oldKey].animation,'other');
});
module.exports = { harness };