110 lines
5.8 KiB
JavaScript
110 lines
5.8 KiB
JavaScript
// Full browser simulation test
|
|
const fs = require('fs');
|
|
const vm = require('vm');
|
|
|
|
// Create browser context
|
|
const context = {
|
|
window: null,
|
|
document: {
|
|
currentScript: { src: '', getAttribute: function(a) { return null; } },
|
|
getElementsByTagName: function() { return []; },
|
|
},
|
|
location: { origin: 'http://localhost:3000' },
|
|
console: console,
|
|
Math: Math, JSON: JSON, Array: Array, Object: Object,
|
|
String: String, Number: Number, Function: Function,
|
|
Error: Error, RegExp: RegExp, Set: Set, Map: Map,
|
|
Promise: Promise, setTimeout: setTimeout,
|
|
localStorage: { getItem: () => null, setItem: () => {}, removeItem: () => {} },
|
|
};
|
|
context.window = context;
|
|
vm.createContext(context);
|
|
|
|
var results = [];
|
|
function assert(name, cond) { results.push((cond ? 'PASS' : 'FAIL') + ': ' + name); }
|
|
function setScript(src) { context.document.currentScript = { src: 'http://localhost:3000' + src, getAttribute: () => null }; }
|
|
|
|
function load(name, code) {
|
|
setScript(name);
|
|
try {
|
|
vm.runInContext(code, context);
|
|
console.log(' Loaded:', name);
|
|
} catch(e) {
|
|
console.error(' ERROR in', name + ':', e.message);
|
|
}
|
|
}
|
|
|
|
// Load all scripts in order
|
|
load('/src/browser-polyfill.js', fs.readFileSync('src/browser-polyfill.js', 'utf8'));
|
|
load('/src/core/constants.js', fs.readFileSync('src/core/constants.js', 'utf8'));
|
|
load('/src/core/rng.js', fs.readFileSync('src/core/rng.js', 'utf8'));
|
|
load('/src/core/utils.js', fs.readFileSync('src/core/utils.js', 'utf8'));
|
|
load('/src/data/themes.js', fs.readFileSync('src/data/themes.js', 'utf8'));
|
|
load('/src/data/dungeons.js', fs.readFileSync('src/data/dungeons.js', 'utf8'));
|
|
load('/src/data/enemies.js', fs.readFileSync('src/data/enemies.js', 'utf8'));
|
|
load('/src/data/weapons.js', fs.readFileSync('src/data/weapons.js', 'utf8'));
|
|
load('/src/data/bosses.js', fs.readFileSync('src/data/bosses.js', 'utf8'));
|
|
load('/src/data/items.js', fs.readFileSync('src/data/items.js', 'utf8'));
|
|
load('/src/generator/rooms.js', fs.readFileSync('src/generator/rooms.js', 'utf8'));
|
|
load('/src/generator/puzzles.js', fs.readFileSync('src/generator/puzzles.js', 'utf8'));
|
|
load('/src/generator/placement.js', fs.readFileSync('src/generator/placement.js', 'utf8'));
|
|
load('/src/generator/dungeon.js', fs.readFileSync('src/generator/dungeon.js', 'utf8'));
|
|
|
|
// Core tests
|
|
assert('module exists', typeof context.module !== 'undefined');
|
|
assert('require is function', typeof context.require === 'function');
|
|
assert('TILE=32', context.window.TILE === 32);
|
|
assert('COLS=32', context.window.COLS === 32);
|
|
assert('ROWS=24', context.window.ROWS === 24);
|
|
assert('TILE_TYPES object', context.window.TILE_TYPES && typeof context.window.TILE_TYPES === 'object');
|
|
assert('COLORS object', context.window.COLORS && typeof context.window.COLORS === 'object');
|
|
assert('createRNG function', typeof context.createRNG === 'function');
|
|
assert('createEmptyLayout function', typeof context.createEmptyLayout === 'function');
|
|
assert('createBorderLayout function', typeof context.createBorderLayout === 'function');
|
|
assert('isPassable function', typeof context.isPassable === 'function');
|
|
|
|
// Data tests
|
|
assert('THEMES object', context.window.THEMES && typeof context.window.THEMES === 'object');
|
|
assert('DUNGEONS array', Array.isArray(context.window.DUNGEONS));
|
|
assert('DUNGEONS count=100', context.window.DUNGEONS && context.window.DUNGEONS.length === 100);
|
|
assert('ENEMY_TYPES array', Array.isArray(context.window.ENEMY_TYPES));
|
|
assert('ENEMY_TYPES count=22', context.window.ENEMY_TYPES && context.window.ENEMY_TYPES.length === 22);
|
|
assert('WEAPONS array', Array.isArray(context.window.WEAPONS));
|
|
assert('WEAPONS count=12', context.window.WEAPONS && context.window.WEAPONS.length === 12);
|
|
assert('BOSS_TYPES array', Array.isArray(context.window.BOSS_TYPES));
|
|
assert('BOSS_TYPES count=100', context.window.BOSS_TYPES && context.window.BOSS_TYPES.length === 100);
|
|
assert('ITEMS array', Array.isArray(context.window.ITEMS));
|
|
assert('getItem function', typeof context.getItem === 'function');
|
|
assert('getEnemyType function', typeof context.getEnemyType === 'function');
|
|
assert('getBossType function', typeof context.getBossType === 'function');
|
|
assert('getWeapon function', typeof context.getWeapon === 'function');
|
|
|
|
// Generator tests
|
|
assert('generateDungeon function', typeof context.generateDungeon === 'function');
|
|
assert('generateRoomLayout function', typeof context.generateRoomLayout === 'function');
|
|
assert('generatePuzzles function', typeof context.generatePuzzles === 'function');
|
|
assert('generatePlacement function', typeof context.generatePlacement === 'function');
|
|
|
|
// Require resolution tests
|
|
context.document.currentScript = { src: 'http://localhost:3000/src/generator/placement.js', getAttribute: () => null };
|
|
var roomsMod = context.require('./rooms');
|
|
assert('require ./rooms generateRoomLayout', roomsMod.generateRoomLayout !== undefined);
|
|
var enemiesMod = context.require('../data/enemies');
|
|
assert('require ../data/enemies ENEMY_TYPES', Array.isArray(enemiesMod.ENEMY_TYPES));
|
|
|
|
// Dungeon generation test
|
|
var dungeon0 = context.window.DUNGEONS[0];
|
|
var rooms = context.generateDungeon(dungeon0);
|
|
assert('generateDungeon returns rooms', Array.isArray(rooms) && rooms.length > 0);
|
|
assert('dungeon #0 rooms ~20', rooms.length >= 17 && rooms.length <= 25);
|
|
assert('entrance assigned', rooms[0].type === 'entrance');
|
|
assert('boss assigned', rooms[rooms.length - 1].type === 'boss');
|
|
assert('all rooms connected', rooms.every(function(r) { return r.connections && r.connections.length >= 1; }));
|
|
assert('rooms have tiles', rooms.every(function(r) { return Array.isArray(r.tiles); }));
|
|
|
|
console.log('\n=== Results ===');
|
|
results.forEach(r => console.log(r));
|
|
var passed = results.filter(r => r.startsWith('PASS')).length;
|
|
var failed = results.filter(r => r.startsWith('FAIL')).length;
|
|
console.log('\n' + passed + ' passed, ' + failed + ' failed');
|
|
process.exit(failed > 0 ? 1 : 0); |