41 lines
3.3 KiB
JavaScript
41 lines
3.3 KiB
JavaScript
// Exercise the real GSC identity adapter under a small VM shim; native policy tests are separate.
|
|
import assert from 'node:assert/strict';
|
|
import {readFileSync} from 'node:fs';
|
|
import vm from 'node:vm';
|
|
for (const game of ['t5','t6']) {
|
|
const source=readFileSync(new URL(`../${game}/scripts/tws_${game}_moderation.gsc`,import.meta.url),'utf8');
|
|
assert.equal((source.match(/level waittill\("connected"/g)??[]).length,0,'must use the shared connection dispatcher');
|
|
assert(source.includes('register_connect_handler(::moderation_connected)'));
|
|
assert(!source.includes('executeCommand'),'all effects belong to the native synchronous adapter');
|
|
const start=source.indexOf('moderation_observe(player)\n{');
|
|
const end=source.indexOf('\nmoderation_loop()',start);
|
|
let body=source.slice(start,end).replace('moderation_observe(player)','function observe(player)');
|
|
body=body.replace(' guid =',' var guid =').replace(' name =',' var name =');
|
|
body=body.replace('player getGuid()','getGuid(player)').replaceAll('typeof(', 'kind(').replace('player moderationObserve(guid, name)', 'record(player,guid,name)');
|
|
const calls=[];
|
|
const c=vm.createContext({isDefined:v=>v!==null&&v!==undefined,kind:v=>typeof v==='number'?(Number.isInteger(v)?'int':'float'):typeof v,
|
|
getGuid:p=>p.identity,record:(...args)=>calls.push(args)});
|
|
vm.runInContext(body,c);
|
|
const player=identity=>({identity,guid:identity,name:'same name'});
|
|
c.observe(player('18446744073709551615')); assert.equal(calls.at(-1)[1],'18446744073709551615');
|
|
c.observe(player(2741626)); assert.equal(calls.at(-1)[1],'2741626');
|
|
c.observe(player('0000123')); assert.equal(calls.at(-1)[1],'0000123');
|
|
const count=calls.length; for(const value of [undefined,null,1.5,{},[]])c.observe(player(value)); assert.equal(calls.length,count);
|
|
c.observe(undefined); assert.equal(calls.length,count);
|
|
c.observe({...player('abc'),name:undefined}); assert.equal(calls.at(-1)[2],'Unknown player');
|
|
let loop=source.slice(source.indexOf('moderation_loop()\n{'))
|
|
.replace('moderation_loop()', 'function* loop()').replaceAll(/wait ([0-9.]+);/g, 'yield $1;')
|
|
.replace('players = getPlayers();', 'var players = getPlayers();').replace('for (i = 0;', 'for (var i = 0;').replace('players.size', 'players.length');
|
|
let enabled=true, configured=false, stopped=0, pumped=0, observed=0;
|
|
const level={moderation_ready:false};
|
|
const runtime=vm.createContext({level,GetDvar:key=>key==='tws_moderation_enabled'?(enabled?'1':'0'):'configured',GetDvarInt:()=>1,
|
|
moderationConfigure:()=>configured,moderationStop:()=>++stopped,moderationPump:()=>++pumped,getPlayers:()=>[{guid:'123'}],moderation_observe:()=>++observed});
|
|
vm.runInContext(loop,runtime); const poll=runtime.loop();
|
|
assert.equal(poll.next().value,3); assert.equal(level.moderation_ready,false);
|
|
configured=true; assert.equal(poll.next().value,0.5); assert.equal(level.moderation_ready,true);
|
|
assert.equal(pumped,1); assert.equal(observed,1);
|
|
enabled=false; assert.equal(poll.next().value,3); assert.equal(level.moderation_ready,false); assert.equal(stopped,1);
|
|
enabled=true; assert.equal(poll.next().value,0.5); assert.equal(pumped,2);
|
|
console.log(`PASS ${game}: actual moderation identity, retry/disable/resume loop and shared dispatcher integration`);
|
|
}
|