Convert tests to Typescript

This commit is contained in:
Will Scullin 2023-08-06 06:20:11 -07:00
parent f2dd9b96a3
commit 3f6cfd67b7
15 changed files with 2248 additions and 29684 deletions

29
jest.config.js Normal file
View File

@ -0,0 +1,29 @@
module.exports = {
'moduleNameMapper': {
'^js/(.*)': '<rootDir>/js/$1',
'^test/(.*)': '<rootDir>/test/$1',
'\\.css$': 'identity-obj-proxy',
'\\.scss$': 'identity-obj-proxy',
},
'roots': [
'js/',
'test/',
],
'testMatch': [
'**/?(*.)+(spec|test).+(ts|js|tsx)'
],
'transform': {
'^.+\\.js$': 'babel-jest',
'^.+\\.ts$': 'ts-jest',
'^.*\\.tsx$': 'ts-jest',
},
'transformIgnorePatterns': [
'/node_modules/(?!(@testing-library/preact/dist/esm)/)',
],
'coveragePathIgnorePatterns': [
'/node_modules/',
'/js/roms/',
'/test/',
],
'preset': 'ts-jest',
};

14683
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -30,10 +30,11 @@
"@babel/preset-env": "^7.4.2",
"@types/micromodal": "^0.3.3",
"ajv": "^6.9.2",
"babel-jest": "^26.3.0",
"babel-jest": "^29.5.0",
"eslint": "^8.3.0",
"jest": "^27.3.1",
"jest": "^29.5.0",
"node-forge": "^1.3.0",
"ts-jest": "^29.1.1",
"ts-loader": "^9.4.4",
"typescript": "^5.1.6",
"webpack": "^5.64.4",
@ -41,6 +42,7 @@
"webpack-dev-server": "^4.6.0"
},
"dependencies": {
"@types/jest": "^29.5.3",
"micromodal": "^0.4.9"
}
}

View File

@ -1,25 +1,25 @@
import CPU6502 from '../js/cpu6502';
import CPU6502, { FLAVOR_ROCKWELL_65C02 } from '../js/cpu6502';
// From https://github.com/Klaus2m5/6502_65C02_functional_tests
import Test6502 from './roms/6502test';
import Test65C02 from './roms/65C02test';
import { toHex } from '../js/util';
describe.skip('CPU', function () {
var cpu;
var lastPC = 0;
var done = false;
describe('CPU', function () {
let cpu: CPU6502;
let lastPC = 0;
let done = false;
function traceCB() {
var pc = cpu.getPC();
done = lastPC == pc;
const pc = cpu.getPC();
done = lastPC === pc;
lastPC = pc;
}
describe('6502', function () {
it('completes the test ROM', function () {
cpu = new CPU6502();
var test = new Test6502();
const test = new Test6502();
cpu.addPageHandler(test);
cpu.setPC(0x400);
@ -33,8 +33,8 @@ describe.skip('CPU', function () {
describe('65C02', function () {
it('completes the test ROM', function () {
cpu = new CPU6502({'65C02': true});
var test = new Test65C02();
cpu = new CPU6502({ flavor: FLAVOR_ROCKWELL_65C02 });
const test = new Test65C02();
cpu.addPageHandler(test);
cpu.setPC(0x400);

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

29
test/roms/6502test.ts Normal file
View File

@ -0,0 +1,29 @@
// From https://github.com/Klaus2m5/6502_65C02_functional_tests
import fs from 'fs';
import path from 'path';
import { MemoryPages, byte } from '../../js/types';
export default class Test6502 implements MemoryPages {
private data: Buffer;
constructor() {
this.data = fs.readFileSync(path.join(__dirname, '6502_functional_test.bin'));
}
start = () => {
return 0x00;
};
end = () => {
return 0xff;
};
read = (page: byte, off: byte) => {
return this.data[page << 8 | off];
};
write = (page: byte, off: byte, val: byte) => {
this.data[page << 8 | off] = val;
};
}

Binary file not shown.

File diff suppressed because it is too large Load Diff

29
test/roms/65C02test.ts Normal file
View File

@ -0,0 +1,29 @@
// From https://github.com/Klaus2m5/6502_65C02_functional_tests
import fs from 'fs';
import path from 'path';
import { MemoryPages, byte } from '../../js/types';
export default class Test65C02 implements MemoryPages {
private data: Buffer;
constructor() {
this.data = fs.readFileSync(path.join(__dirname, '65C02_extended_opcodes_test.bin'));
}
start = () => {
return 0x00;
};
end = () => {
return 0xff;
};
read = (page: byte, off: byte) => {
return this.data[page << 8 | off];
};
write = (page: byte, off: byte, val: byte) => {
this.data[page << 8 | off] = val;
};
}

6
test/util/asserts.ts Normal file
View File

@ -0,0 +1,6 @@
import { byte } from '../../js/types';
export const assertByte = (b: byte) => {
expect(b <= 0xFF).toEqual(true);
expect(b >= 0x00).toEqual(true);
};

63
test/util/bios.ts Normal file
View File

@ -0,0 +1,63 @@
import { MemoryPages, byte } from '../../js/types';
import { assertByte } from './asserts';
export class Program implements MemoryPages {
private data: Buffer;
constructor(private page: byte, code: byte[]) {
this.data = Buffer.from(code);
}
start() {
return this.page;
}
end() {
return this.page;
}
read(page: byte, off: byte) {
assertByte(page);
assertByte(off);
return this.data[off];
}
write(_page: byte, _off: byte, _val: byte) {
// do nothing
}
}
export const bios = new Program(0xff, [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x48, 0x45, 0x4C, 0x4C, 0x4F, 0x0D, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00, 0xff
]);

34
test/util/cpu.ts Normal file
View File

@ -0,0 +1,34 @@
import { flags, CpuState } from "js/cpu6502";
import { byte } from "js/types";
import { toHex } from "js/util";
export const dumpStatusRegister = (sr: byte) =>
[
sr & flags.N ? "N" : "-",
sr & flags.V ? "V" : "-",
sr & flags.X ? "X" : "-",
sr & flags.B ? "B" : "-",
sr & flags.D ? "D" : "-",
sr & flags.I ? "I" : "-",
sr & flags.Z ? "Z" : "-",
sr & flags.C ? "C" : "-",
].join("");
const detail = !!process.env.JEST_DETAIL;
export function toReadableState(state: CpuState) {
if (detail) {
const { pc, sp, a, x, y, s } = state;
return {
pc: toHex(pc, 4),
sp: toHex(sp),
a: toHex(a),
x: toHex(x),
y: toHex(y),
s: dumpStatusRegister(s),
};
} else {
return state;
}
}

61
test/util/memory.ts Normal file
View File

@ -0,0 +1,61 @@
import { MemoryPages, byte, word } from 'js/types';
import { assertByte } from './asserts';
export type Log = [address: word, value: byte, types: 'read'|'write'];
export class TestMemory implements MemoryPages {
private data: Buffer;
private logging: boolean = false;
private log: Log[] = [];
constructor(private size: number) {
this.data = Buffer.alloc(size << 8);
}
start() {
return 0;
}
end() {
return this.size - 1;
}
read(page: byte, off: byte) {
assertByte(page);
assertByte(off);
const val = this.data[(page << 8) | off];
if (this.logging) {
this.log.push([page << 8 | off, val, 'read']);
}
return val;
}
write(page: byte, off: byte, val: byte) {
assertByte(page);
assertByte(off);
assertByte(val);
if (this.logging) {
this.log.push([page << 8 | off, val, 'write']);
}
this.data[(page << 8) | off] = val;
}
reset() {
this.log = [];
}
logStart() {
this.log = [];
this.logging = true;
}
logStop() {
this.logging = false;
}
getLog() {
return this.log;
}
}