117 lines
8.5 KiB
JavaScript
117 lines
8.5 KiB
JavaScript
const test=require('node:test'),assert=require('node:assert/strict'),fs=require('node:fs'),vm=require('node:vm'),ts=require('typescript');
|
|
|
|
test('continue prompt uses the shared artwork without a label or clock binding',()=>{
|
|
const a=JSON.parse(fs.readFileSync('assets/cloud_rise_home/prefab/CloudRise.prefab'));
|
|
const panel=a.find(o=>o.pages&&o.buttons),node=a[panel.continueHint.__id__];
|
|
const spriteRef=node._components.find(r=>a[r.__id__].__type__==='cc.Sprite'),sprite=a[spriteRef.__id__];
|
|
const meta=JSON.parse(fs.readFileSync('assets/cloud_rise/art/images/continue.png.meta'));
|
|
assert.equal(node._name,'ClickToContinue');
|
|
assert.equal(sprite._spriteFrame.__uuid__,meta.subMetas.continue.uuid);
|
|
assert.equal(node._components.length,1);
|
|
assert.equal(node._contentSize.width-4,224);
|
|
assert.equal(node._contentSize.height-4,43);
|
|
assert.equal(sprite._sizeMode,0,'custom size reserves the outline margin');
|
|
const material=JSON.parse(fs.readFileSync('assets/cloud_rise_home/images/continue_outline.mtl'));
|
|
assert.equal(sprite._materials[0].__uuid__,JSON.parse(fs.readFileSync('assets/cloud_rise_home/images/continue_outline.mtl.meta')).uuid);
|
|
assert.equal(material._techniqueData['0'].props.outlineWidth,2);
|
|
assert.deepEqual(material._techniqueData['0'].props.outlineColor,{__type__:'cc.Vec4',x:0,y:0,z:0,w:0.5});
|
|
assert.equal(meta.packable,false,'outline UVs require an independent texture');
|
|
assert(!panel.clocks.some(r=>r&&r.__id__===spriteRef.__id__));
|
|
});
|
|
|
|
test('matching and all stages share the continue prompt without stale legacy text or clock rebinding',()=>{
|
|
for(const name of ['home','matching','stage1','stage2','stage3']){
|
|
const a=JSON.parse(fs.readFileSync((name==='home'?'assets/cloud_rise_home':'assets/cloud_rise/'+name)+'/prefab/CloudRise.prefab'));
|
|
for(const label of a.filter(o=>o.__type__==='cc.Label')){
|
|
if(label._string!==undefined&&label['_N$string']!==undefined)
|
|
assert.equal(label['_N$string'],label._string,name+'/'+a[label.node.__id__]._name);
|
|
}
|
|
const bindings=a.find(o=>o.nodeKeys);
|
|
if(!bindings)continue;
|
|
assert(!bindings.nodeKeys.includes('continueHint'),name+' must keep the shared prompt');
|
|
bindings.componentKeys.forEach((key,i)=>{
|
|
if(!key.startsWith('clocks:'))return;
|
|
const label=a[bindings.components[i].__id__];
|
|
assert.equal(a[label.node.__id__]._name,'Clock',name+' must only bind its activity clock');
|
|
});
|
|
}
|
|
});
|
|
|
|
test('image fractions reuse seven glyphs, preserve slash artwork, and fit the counter width',()=>{
|
|
const exports={},cc={Component:class{},Sprite:class{},SpriteFrame:class{},_decorator:{ccclass:c=>c,executeInEditMode:c=>c,property:(...args)=>args.length>1?undefined:()=>{}}};
|
|
cc.Sprite.SizeMode={CUSTOM:0};
|
|
vm.runInNewContext(ts.transpileModule(fs.readFileSync('assets/cloud_rise_home/scripts/CloudRiseCounter.ts','utf8'),{compilerOptions:{module:ts.ModuleKind.CommonJS,target:ts.ScriptTarget.ES2017,experimentalDecorators:true}}).outputText,{exports,cc});
|
|
const counter=new exports.default();counter.frames=Array.from({length:11},(_,i)=>({id:i,getRect:()=>({width:i===10?18:29,height:39})}));
|
|
counter.node={width:300,children:Array.from({length:7},()=>({sprite:{},getComponent(){return this.sprite;},setContentSize(w,h){this.width=w;this.height=h;},setPosition(x,y){this.x=x;this.y=y;}}))};
|
|
for(const value of ['0/5','5/5','0/7','7/7','9/9','0/100','57/100','100/100']){
|
|
counter.string=value;const active=counter.node.children.filter(n=>n.active);
|
|
assert.equal(active.length,value.length);assert.equal(active.map(n=>n.sprite.spriteFrame.id===10?'/':n.sprite.spriteFrame.id).join(''),value);
|
|
assert(active.every(n=>Math.abs(n.x)+n.width/2<=150.0001));
|
|
assert(Math.abs(active[0].x-active[0].width/2+active.at(-1).x+active.at(-1).width/2)<.001);
|
|
}
|
|
counter.string='0/5';assert.equal(counter.node.children.length,7);
|
|
});
|
|
|
|
test('all stages bind image counters and the supplied hint without cross-stage dependencies',()=>{
|
|
const frameId=name=>Object.values(JSON.parse(fs.readFileSync('assets/cloud_rise_home/images/'+name+'.png.meta')).subMetas)[0].uuid;
|
|
const ids=Array.from({length:10},(_,i)=>frameId('stat_'+i)).concat(frameId('stat_slash'));
|
|
for(let i=1;i<=3;i++){
|
|
const a=JSON.parse(fs.readFileSync('assets/cloud_rise/stage'+i+'/prefab/CloudRise.prefab'));
|
|
const binding=a.find(o=>o.componentKeys),get=key=>a[binding.components[binding.componentKeys.indexOf(key)].__id__];
|
|
for(const key of ['progressCount','survivorCount']){
|
|
const c=get(key),n=a[c.node.__id__];assert.deepEqual(c.frames.map(f=>f.__uuid__),ids);assert.equal(n._children.length,7);
|
|
assert(!n._components.some(r=>a[r.__id__].__type__==='cc.Label'));
|
|
}
|
|
const hint=a.find(o=>o._name==='HintText');assert.equal(hint._active,false);
|
|
assert(a.some(o=>o._spriteFrame?.__uuid__===frameId('streak_hint')));
|
|
const button=a.find(o=>o._name==='ShowParticipants');assert.equal(button._active,false);
|
|
assert.equal(a[button._components.find(r=>a[r.__id__].__type__==='cc.Button').__id__]._enabled,false);
|
|
}
|
|
const matching=JSON.parse(fs.readFileSync('assets/cloud_rise/matching/prefab/CloudRise.prefab'));
|
|
assert(!matching.some(o=>o._name==='StreakHint'));assert(!matching.some(o=>o._spriteFrame?.__uuid__===frameId('streak_hint')));
|
|
});
|
|
|
|
test('authored counter layout survives changing survivor counts and showing slots again',()=>{
|
|
const exports={},cc={Component:class{},Sprite:class{},SpriteFrame:class{},_decorator:{ccclass:c=>c,executeInEditMode:c=>c,property:(...args)=>args.length>1?undefined:()=>{}}};
|
|
vm.runInNewContext(ts.transpileModule(fs.readFileSync('assets/cloud_rise_home/scripts/CloudRiseCounter.ts','utf8'),{compilerOptions:{module:ts.ModuleKind.CommonJS,target:ts.ScriptTarget.ES2017,experimentalDecorators:true}}).outputText,{exports,cc});
|
|
const a=JSON.parse(fs.readFileSync('assets/cloud_rise/stage1/prefab/CloudRise.prefab'));
|
|
const node=a.find(n=>n._name==='SurvivorsValue'),component=a[node._components[0].__id__],counter=new exports.default();
|
|
assert.equal(component.usePrefabLayout,true);counter.usePrefabLayout=component.usePrefabLayout;
|
|
counter.frames=Array.from({length:11},(_,id)=>({id}));
|
|
counter.node={children:node._children.map(r=>{const n=a[r.__id__],s=a[n._components[0].__id__];return {x:n._trs.array[0],y:n._trs.array[1],width:n._contentSize.width,height:n._contentSize.height,sprite:{sizeMode:s._sizeMode},getComponent(){return this.sprite;}};})};
|
|
const style=()=>counter.node.children.map(n=>[n.x,n.y,n.width,n.height,n.sprite.sizeMode]);const before=style();
|
|
for(const value of ['100/100','57/100','9/100','0/100','100/100']){
|
|
counter.string=value;assert.deepEqual(style(),before);
|
|
const active=counter.node.children.filter(n=>n.active);assert.equal(active.length,value.length);
|
|
assert.equal(active.map(n=>n.sprite.spriteFrame.id===10?'/':n.sprite.spriteFrame.id).join(''),value);
|
|
}
|
|
});
|
|
|
|
test('matching count and all victory counts bind sprite counters with complete digit sets',()=>{
|
|
for(const name of ['matching','stage1','stage2','stage3']){
|
|
const a=JSON.parse(fs.readFileSync('assets/cloud_rise/'+name+'/prefab/CloudRise.prefab'));
|
|
const b=a.find(o=>o.componentKeys),key=name==='matching'?'matchingCount':'victoryOthers';
|
|
const c=a[b.components[b.componentKeys.indexOf(key)].__id__],n=a[c.node.__id__];
|
|
assert.equal(c.frames.length,name==='matching'?11:10);assert.equal(n._children.length,name==='matching'?7:3);
|
|
assert(!n._components.some(r=>a[r.__id__].__type__==='cc.Label'));assert.equal(c.usePrefabLayout,false);
|
|
}
|
|
});
|
|
|
|
test('stage hints share stage1 size without bubble parents and guides share the home-owned icon',()=>{
|
|
const home=JSON.parse(fs.readFileSync('assets/cloud_rise_home/prefab/CloudRise.prefab')),b=home.find(o=>o.pages&&o.buttons);
|
|
const guide=home[b.activityGuide.__id__];assert.equal(guide._active,false);
|
|
const help=home[b.overviewHelp.__id__],sprite=home[help._components[0].__id__]._spriteFrame.__uuid__;
|
|
assert(home[b.guideShade.__id__]._components.some(r=>home[r.__id__].__type__==='cc.BlockInputEvents'));
|
|
assert.equal(b.guideClose,undefined);assert(!home.some(n=>n._name==='GuideClose'));
|
|
for(let i=1;i<=3;i++){
|
|
const a=JSON.parse(fs.readFileSync('assets/cloud_rise/stage'+i+'/prefab/CloudRise.prefab'));
|
|
const hint=a.find(n=>n._name==='HintText');
|
|
assert(!a.some(n=>n._name==='RewardHint'));
|
|
assert.equal(a[hint._parent.__id__]._name,'Progress');
|
|
assert.equal(hint._contentSize.width,328.4);assert.equal(hint._contentSize.height,39);
|
|
assert.equal(hint._active,false);
|
|
const binding=a.find(n=>n.nodeKeys),button=a[binding.nodes[binding.nodeKeys.indexOf('stageHelp')].__id__];
|
|
assert.equal(a[button._components[0].__id__]._spriteFrame.__uuid__,sprite);
|
|
}
|
|
});
|