// 在项目根目录运行:node assets/test/tests/home-prop-panel.cjs const fs = require('fs'), vm = require('vm'), assert = require('assert'); const ts = require('./preview.cjs').loadTypeScript(); class Node { constructor(name) { this.name=name;this.children=[];this.components=[];this.events={};this.active=true; } set parent(n) { this._parent=n;n.children.push(this); } get parent() { return this._parent; } setPosition() {} setContentSize() {} addComponent(Type) { const c=new Type();c.node=this;this.components.push(c);return c; } on(name,callback,target) { this.events[name]=callback.bind(target); } } class Graphics { roundRect() {} fill() {} } class Label {} Label.HorizontalAlign={CENTER:1}; let saved={freezeAmount:90,hammerAmount:90,magicAmount:90,other:'preserved'}, writes=0, fail=false; const info={freezeAmount:2,hammerAmount:3,magicAmount:4}; const cc={Node,Graphics,Label,Color:class {},Widget:class {},Button:class {},BlockInputEvents:class {},Component:class {}, _decorator:{ccclass:C=>C},macro:{MAX_ZINDEX:32767},error(){},fx:{GameConfig:{GM_INFO:info},StorageMessage:{ getStorage(key){assert.equal(key,'prop');return saved;}, setStorage(key,value){assert.equal(key,'prop');if(fail)throw Error('full');saved=value;writes++;} }}}; const code=ts.transpileModule(fs.readFileSync('assets/test/script/HomePropTestPanel.ts','utf8'),{compilerOptions:{experimentalDecorators:true,module:ts.ModuleKind.CommonJS,target:ts.ScriptTarget.ES2017}}).outputText; function setup(debug){const exports={};vm.runInNewContext(code,{cc,exports,CC_DEBUG:debug});const c=new exports.default();c.node=new Node('HomePropTestPanel');c.node.parent=new Node('Canvas');c.onLoad();return c;} const panel=setup(true);assert.equal(writes,0);assert.equal(panel.panel.active,false);panel.open(); panel.grant(['freezeAmount'],1);assert.equal(info.freezeAmount,3);assert.equal(info.hammerAmount,3);assert.equal(saved.freezeAmount,3);assert.equal(saved.other,'preserved'); panel.grant(['freezeAmount'],10);assert.equal(info.freezeAmount,13); panel.grant(['freezeAmount','hammerAmount','magicAmount'],10);assert.equal(info.freezeAmount,23);assert.equal(info.hammerAmount,13);assert.equal(info.magicAmount,14);assert(saved.timestamp>0); panel.close();panel.open();assert.equal(writes,3);assert(panel.counts[0].string.includes('23')); fail=true;panel.grant(['freezeAmount'],10);assert.equal(info.freezeAmount,23);assert.equal(writes,3);fail=false; cc.fx.GameConfig.GM_INFO=null;panel.grant(['freezeAmount'],1);assert.equal(writes,3);assert(panel.message.string.includes('未准备好'));cc.fx.GameConfig.GM_INFO=info; assert.equal(setup(false).node.children.length,0); const scene=JSON.parse(fs.readFileSync('assets/Scene/HomeScene.fire','utf8'));assert.equal(scene.filter(n=>n.__type__==='cc.Node'&&n._name==='HomePropTestPanel').length,1); console.log('PASS: no automatic grant, single/all/repeated grants, local persistence, preserved fields, reopen, storage failure, unready data, release-build exclusion and scene mount.');