player/tests/rbxl-lua-tween.test.js
min a5e1558c2d
All checks were successful
CI / Lint (push) Successful in 54s
CI / Build (push) Successful in 1m30s
CI / Secret scan (push) Successful in 20s
CI / PR size check (push) Has been skipped
CI / Deploy to S1 + S2 (push) Successful in 2m56s
feat(player): ������������� �� ������� (Lua + JS-API + Roblox-������ + LoadingOverlay)
2026-06-09 22:01:51 +00:00

90 lines
3.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* rbxl-lua-tween.test.js — тесты TweenService.
*/
import { LuaFactory } from 'wasmoon';
import { registerRobloxApi } from '../src/engine/roblox-shim.js';
import { RobloxScheduler } from '../src/engine/roblox-scheduler.js';
import { RobloxTweenManager } from '../src/engine/roblox-tween.js';
const SCENE = {
primitives: {
1: { id: 1, type: 'cube', name: 'Movable', x: 0, y: 5, z: 0, sx: 1, sy: 1, sz: 1,
color: '#ffffff', material: 'glossy', anchored: false, canCollide: true, opacity: 1 },
},
};
async function run(luaSource, ticks = []) {
const factory = new LuaFactory();
const lua = await factory.createEngine();
const sent = [];
const send = (cmd, payload) => sent.push({ cmd, payload });
registerRobloxApi(lua, { getSceneSnap: () => SCENE, targetPrimitiveId: 1, send });
const sched = new RobloxScheduler(lua);
sched.install();
const tweenMgr = new RobloxTweenManager();
tweenMgr.install(lua);
await sched.spawnMain(luaSource);
for (const dt of ticks) {
await sched.tick(dt);
tweenMgr.tick(dt);
}
lua.global.close();
return { logs: sent.filter(s => s.cmd === 'log').map(s => s.payload),
partSets: sent.filter(s => s.cmd === 'partSet').map(s => s.payload) };
}
const TESTS = [
{
name: 'TweenInfo создаётся',
lua: `
local info = TweenInfo.new(2, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)
print("time:", info.Time, "style:", info.EasingStyle)
`,
ticks: [],
expectLogs: [{ level: 'info', text: 'time:\t2\tstyle:\tLinear' }],
},
{
name: 'TweenService:Create + Play (Linear)',
lua: `
local TS = game:GetService("TweenService")
local p = workspace:FindFirstChild("Movable")
local info = TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)
local tw = TS:Create(p, info, { Position = Vector3.new(10, 5, 0) })
tw:Play()
print("started")
`,
ticks: [0.5, 0.5, 0.1], // больше 1 сек — должен завершиться
// Ожидаем что хотя бы один partSet с prop=position
expectPartSet: { primId: 1, prop: 'position' },
},
];
(async () => {
let passed = 0, failed = 0;
for (const t of TESTS) {
try {
const r = await run(t.lua, t.ticks);
let ok = true;
let reason = '';
for (const exp of (t.expectLogs || [])) {
const found = r.logs.find(l => l.level === exp.level && l.text === exp.text);
if (!found) { ok = false; reason = `missing log: ${exp.text}`; break; }
}
if (t.expectPartSet) {
const found = r.partSets.find(p => p.primId === t.expectPartSet.primId && p.prop === t.expectPartSet.prop);
if (!found) {
ok = false; reason = `missing partSet: ${JSON.stringify(t.expectPartSet)}; got: ${JSON.stringify(r.partSets.slice(0,3))}`;
}
}
if (ok) { console.log(`${t.name}`); passed++; }
else { console.log(`${t.name}${reason}`); failed++; }
} catch (e) {
console.log(`${t.name} — exception: ${e}`);
failed++;
}
}
console.log(`\n${passed} passed, ${failed} failed`);
process.exit(failed > 0 ? 1 : 0);
})();