1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-11-26 10:49:17 +00:00
8bitworkshop/test/cli/testworker.js

315 lines
12 KiB
JavaScript
Raw Normal View History

2017-01-12 02:02:23 +00:00
var assert = require('assert');
var fs = require('fs');
2017-11-22 14:42:07 +00:00
var wtu = require('./workertestutils.js');
2018-07-11 03:17:39 +00:00
var heapdump = require('heapdump');
2017-01-12 02:02:23 +00:00
2018-07-11 00:58:46 +00:00
// TODO: why memory leak?
CACHE_WASM_MODULES = false;
2018-06-23 23:25:37 +00:00
global.onmessage({data:{preload:'cc65', platform:'nes'}});
2018-06-25 23:47:40 +00:00
global.onmessage({data:{preload:'ca65', platform:'nes'}});
2018-08-06 20:23:19 +00:00
global.onmessage({data:{preload:'cc65', platform:'apple2'}});
global.onmessage({data:{preload:'ca65', platform:'apple2'}});
global.onmessage({data:{preload:'sdcc'}});
// TODO: check msg against spec
function compile(tool, code, platform, callback, outlen, nlines, nerrors, options) {
var msgs = [{code:code, platform:platform, tool:tool, path:'src.'+tool}];
doBuild(msgs, callback, outlen, nlines, nerrors, options);
}
function compileFiles(tool, files, platform, callback, outlen, nlines, nerrors, options) {
2018-07-02 22:48:17 +00:00
var msg = {updates:[], buildsteps:[]};
for (var fn of files) {
var text = ab2str(fs.readFileSync('presets/'+platform+'/'+fn));
msg.updates.push({path:fn, data:text});
msg.buildsteps.push({path:fn, platform:platform, tool:tool});
}
doBuild([msg], callback, outlen, nlines, nerrors, options);
2018-07-02 22:48:17 +00:00
}
function doBuild(msgs, callback, outlen, nlines, nerrors, options) {
2018-06-25 16:35:55 +00:00
var msgcount = msgs.length;
2017-01-12 02:02:23 +00:00
global.postMessage = function(msg) {
2018-06-25 16:35:55 +00:00
if (!msg.unchanged) {
2017-01-15 03:46:12 +00:00
if (msg.errors && msg.errors.length) {
for (var err of msg.errors) {
console.log(err);
assert.ok(err.line >= 0);
if (options && !options.ignoreErrorPath) {
assert.equal(msgs[0].path, err.path);
}
assert.ok(err.msg);
}
2017-01-15 03:46:12 +00:00
assert.equal(nerrors, msg.errors.length, "errors");
} else {
assert.equal(nerrors||0, 0, "errors");
2017-11-20 01:32:58 +00:00
assert.equal(msg.output.code?msg.output.code.length:msg.output.length, outlen, "output binary");
2018-07-08 14:07:19 +00:00
assert.ok(msg.output.code || msg.output instanceof Uint8Array);
if (nlines) {
if (typeof nlines === 'number')
nlines = [nlines];
//console.log(msg.listings, nlines);
var i = 0;
2018-07-02 22:48:17 +00:00
var lstkeys = Object.keys(msg.listings);
lstkeys.sort();
for (var key of lstkeys) {
var listing = msg.listings[key];
assert.equal(listing.lines.length, nlines[i++], "listing lines");
}
}
}
2018-06-25 16:35:55 +00:00
}
2018-07-11 03:17:39 +00:00
if (--msgcount == 0) {
2017-01-12 02:02:23 +00:00
callback(null, msg);
2018-07-11 03:17:39 +00:00
//heapdump.writeSnapshot();
} else
2018-06-25 16:35:55 +00:00
console.log(msgcount + ' msgs left');
2017-01-12 02:02:23 +00:00
};
global.onmessage({data:{reset:true}});
for (var i=0; i<msgs.length; i++) {
global.onmessage({data:msgs[i]});
}
2017-01-12 02:02:23 +00:00
}
describe('Worker', function() {
2017-01-13 02:21:35 +00:00
it('should assemble DASM', function(done) {
2017-01-15 03:46:12 +00:00
compile('dasm', '\tprocessor 6502\n\torg $f000\nfoo lda #0\n', 'vcs', done, 2, 1);
});
it('should NOT assemble DASM', function(done) {
compile('dasm', '\tprocessor 6502\n\torg $f000\nfoo xxx #0\n', 'vcs', done, 0, 0, 1);
});
/*
2017-01-15 03:46:12 +00:00
it('should assemble ACME', function(done) {
compile('acme', 'foo: lda #0\n', 'vcs', done, 2, 0); // TODO
2017-01-12 02:02:23 +00:00
});
it('should NOT assemble ACME', function(done) {
compile('acme', 'foo: xxx #0\n', 'vcs', done, 0, 0, 2); // TODO
});
2017-01-12 02:02:23 +00:00
it('should compile PLASMA', function(done) {
2017-01-15 03:46:12 +00:00
compile('plasm', 'word x = 0', 'apple2', done, 5, 0);
2017-01-12 02:02:23 +00:00
});
it('should NOT compile PLASMA', function(done) {
compile('plasm', 'word x = ', 'apple2', done, 0, 0, 1);
});
*/
2017-01-12 02:02:23 +00:00
it('should compile CC65', function(done) {
compile('cc65', 'int main() {\nint x=1;\nreturn x+2;\n}', 'nes-conio', done, 40976, 3);
});
2018-07-03 03:55:38 +00:00
it('should NOT compile CC65 (compile error)', function(done) {
compile('cc65', 'int main() {\nint x=1;\nprintf("%d",x);\nreturn x+2;\n}', 'nes-conio', done, 0, 0, 1);
2017-01-12 02:02:23 +00:00
});
2018-07-03 03:55:38 +00:00
it('should NOT compile CC65 (link error)', function(done) {
compile('cc65', 'extern void bad();\nint main() {\nbad();\nreturn 0;\n}', 'nes-conio', done, 0, 0, 1, {ignoreErrorPath:true});
});
it('should NOT compile CC65 (preproc error)', function(done) {
compile('cc65', '#include "NOSUCH.file"\n', 'nes-conio', done, 0, 0, 1, {ignoreErrorPath:true});
2018-07-03 03:55:38 +00:00
});
2018-06-25 23:47:40 +00:00
it('should assemble CA65', function(done) {
compile('ca65', '\t.segment "HEADER"\n\t.segment "STARTUP"\n\t.segment "CHARS"\n\t.segment "VECTORS"\n\tlda #0\n\tsta $1\n', 'nes-conio', done, 40976, 2);
});
/*
2017-01-13 02:21:35 +00:00
it('should assemble Z80ASM', function(done) {
2018-06-24 05:01:38 +00:00
compile('z80asm', '\tMODULE test\n\tEXTERN _puts\n\tld hl,$0000\n\tret\n', 'mw8080bw', done, 4, 2, 0);
2017-01-15 03:46:12 +00:00
});
it('should NOT assemble Z80ASM', function(done) {
2018-06-24 05:01:38 +00:00
compile('z80asm', 'ddwiuweq', 'mw8080bw', done, 0, 0, 1);
2017-01-15 18:31:52 +00:00
});
*/
2017-01-15 18:31:52 +00:00
it('should assemble SDASZ80', function(done) {
2017-01-21 13:13:36 +00:00
compile('sdasz80', '\tld hl,#0\n\tret\n', 'mw8080bw', done, 8192, 2);
});
it('should NOT assemble SDASZ80', function(done) {
2017-01-21 13:13:36 +00:00
compile('sdasz80', '\txxx hl,#0\n\tret\n', 'mw8080bw', done, 0, 0, 1);
2017-01-13 02:21:35 +00:00
});
it('should NOT link SDASZ80', function(done) {
compile('sdasz80', '\tcall divxxx\n', 'mw8080bw', done, 0, 0, 1, {ignoreErrorPath:true});
});
2017-01-13 02:21:35 +00:00
it('should compile SDCC', function(done) {
compile('sdcc', 'int foo=0; // comment\nint main(int argc) {\nint x=1;\nint y=2+argc;\nreturn x+y+argc;\n}\n', 'mw8080bw', done, 8192, 3, 0);
});
it('should compile SDCC w/ include', function(done) {
compile('sdcc', '#include <string.h>\nvoid main() {\nstrlen(0);\n}\n', 'mw8080bw', done, 8192, 2, 0);
2017-01-13 02:21:35 +00:00
});
2018-07-02 22:48:17 +00:00
/*
2017-04-19 18:26:46 +00:00
it('should compile vicdual skeleton', function(done) {
var csource = ab2str(fs.readFileSync('presets/vicdual/skeleton.sdcc'));
compile('sdcc', csource, 'vicdual', done, 16416, 45, 0);
});
2018-07-02 22:48:17 +00:00
*/
2017-04-19 18:26:46 +00:00
it('should compile mw8080 skeleton', function(done) {
var csource = ab2str(fs.readFileSync('presets/mw8080bw/skeleton.sdcc'));
compile('sdcc', csource, 'mw8080bw', done, 8192, 84, 0);
});
it('should compile galaxian skeleton', function(done) {
var csource = ab2str(fs.readFileSync('presets/galaxian-scramble/skeleton.sdcc'));
compile('sdcc', csource, 'galaxian-scramble', done, 20512, 29, 0);
});
it('should compile vector skeleton', function(done) {
var csource = ab2str(fs.readFileSync('presets/vector-z80color/skeleton.sdcc'));
compile('sdcc', csource, 'vector-z80color', done, 32768, 23, 0);
2017-04-19 18:26:46 +00:00
});
it('should compile williams skeleton', function(done) {
var csource = ab2str(fs.readFileSync('presets/williams-z80/skeleton.sdcc'));
compile('sdcc', csource, 'williams-z80', done, 38912, 38, 0);
2017-04-19 18:26:46 +00:00
});
it('should compile williams_sound skeleton', function(done) {
var csource = ab2str(fs.readFileSync('presets/sound_williams-z80/skeleton.sdcc'));
compile('sdcc', csource, 'sound_williams-z80', done, 16384, 6, 0);
});
it('should compile coleco skeleton', function(done) {
// TODO: can't do skeleton b/c of dependencies
var csource = ab2str(fs.readFileSync('presets/coleco/text.c'));
compile('sdcc', csource, 'coleco', done, 32768, 14, 0);
});
2017-11-20 01:32:58 +00:00
it('should compile verilog example', function(done) {
var csource = ab2str(fs.readFileSync('presets/verilog/lfsr.v'));
2018-07-10 01:58:24 +00:00
var msgs = [{code:csource, platform:"verilog", tool:"verilator", dependencies:[], path:'main.v'}];
var done2 = function(err, msg) {
var jscode = msg.output.code;
var fn = new Function(jscode);
assert.ok(fn);
done(err, msg);
};
2018-08-29 17:43:46 +00:00
doBuild(msgs, done2, 2781, 0, 0);
});
it('should NOT compile verilog example', function(done) {
var csource = "foobar";
var msgs = [{code:csource, platform:"verilog", tool:"verilator", dependencies:[], path:'foomain.v'}];
doBuild(msgs, done, 0, 0, 1);
});
it('should compile verilog inline assembler (JSASM)', function(done) {
2018-07-12 04:59:35 +00:00
var csource = ab2str(fs.readFileSync('presets/verilog/racing_game_cpu.v'));
var dependfiles = ["hvsync_generator.v", "sprite_bitmap.v", "sprite_renderer.v", "cpu8.v"];
var depends = [];
for (var dfile of dependfiles) {
var code = ab2str(fs.readFileSync('presets/verilog/' + dfile));
depends.push({filename:dfile, data:code, prefix:"verilog"});
}
var msgs = [{code:csource, platform:"verilog", tool:"verilator", dependencies:depends, path:'racing_game_cpu.v'}];
var done2 = function(err, msg) {
var jscode = msg.output.code;
var fn = new Function(jscode);
assert.ok(fn);
done(err, msg);
};
2018-08-29 17:43:46 +00:00
doBuild(msgs, done2, 49339, 0, 0);
2018-07-12 04:59:35 +00:00
});
it('should compile verilog assembler file (JSASM)', function(done) {
var csource = ab2str(fs.readFileSync('presets/verilog/test2.asm'));
var dependfiles = ["hvsync_generator.v", "font_cp437_8x8.v", "ram.v", "tile_renderer.v", "sprite_scanline_renderer.v", "lfsr.v", "sound_generator.v", "cpu16.v", "cpu_platform.v"];
var depends = [];
for (var dfile of dependfiles) {
var code = ab2str(fs.readFileSync('presets/verilog/' + dfile));
depends.push({filename:dfile, data:code, prefix:"verilog"});
}
2018-07-10 01:58:24 +00:00
var msgs = [{code:csource, platform:"verilog", tool:"jsasm", dependencies:depends, path:'main.asm'}];
var done2 = function(err, msg) {
var jscode = msg.output.code;
var fn = new Function(jscode);
assert.ok(fn);
done(err, msg);
};
2018-08-29 17:43:46 +00:00
doBuild(msgs, done2, 1997609, 0, 0);
2017-01-21 13:13:36 +00:00
});
it('should NOT preprocess SDCC', function(done) {
compile('sdcc', 'int x=0\n#bah\n', 'mw8080bw', done, 0, 0, 1);
});
/*
2017-01-21 13:13:36 +00:00
it('should compile XASM6809', function(done) {
compile('xasm6809', '\tasld\n\tasld\n', 'mw8080bw', done, 4, 2, 0);
});
*/
it('should link two files with SDCC', function(done) {
var msgs = [
{
"updates":[
{"path":"main.c", "data":"extern int mul2(int x);\nint main() { return mul2(2); }\n"},
{"path":"fn.c", "data":"int mul2(int x) { return x*x; }\n"}
],
"buildsteps":[
{"path":"main.c", "platform":"mw8080bw", "tool":"sdcc"},
{"path":"fn.c", "platform":"mw8080bw", "tool":"sdcc"}
]
}
];
doBuild(msgs, done, 8192, [1,1], 0);
});
2018-07-03 04:21:08 +00:00
// TODO: tests don't fail if too many compile steps
2018-06-25 14:43:15 +00:00
it('should not build unchanged files with CC65', function(done) {
var m = {
"updates":[
{"path":"main.c", "data":"extern int mul2(int x);\n int main() { return mul2(2); }\n"},
{"path":"fn.c", "data":"int mul2(int x) { return x*x; }\n"}
],
"buildsteps":[
{"path":"main.c", "platform":"nes-conio", "tool":"cc65"},
{"path":"fn.c", "platform":"nes-conio", "tool":"cc65"}
]
};
var m2 = {
"updates":[
{"path":"main.c", "data":"extern int mul2(int x); \nint main() { return mul2(2); }\n"}
],
"buildsteps":[
{"path":"main.c", "platform":"nes-conio", "tool":"cc65"},
{"path":"fn.c", "platform":"nes-conio", "tool":"cc65"}
]
};
2018-06-25 16:35:55 +00:00
var msgs = [m, m, m2];
doBuild(msgs, done, 40976, [1,1], 0);
2018-06-25 14:43:15 +00:00
});
it('should not build unchanged files with SDCC', function(done) {
var m = {
"updates":[
{"path":"main.c", "data":"extern int mul2(int x);\n int main() { return mul2(2); }\n"},
{"path":"fn.c", "data":"int mul2(int x) { return x*x; }\n"}
],
"buildsteps":[
{"path":"main.c", "platform":"mw8080bw", "tool":"sdcc"},
{"path":"fn.c", "platform":"mw8080bw", "tool":"sdcc"}
]
};
var m2 = {
"updates":[
{"path":"main.c", "data":"extern int mul2(int x); \nint main() { return mul2(2); }\n"}
],
"buildsteps":[
{"path":"main.c", "platform":"mw8080bw", "tool":"sdcc"},
{"path":"fn.c", "platform":"mw8080bw", "tool":"sdcc"}
]
};
2018-06-25 16:35:55 +00:00
var msgs = [m, m, m2];
doBuild(msgs, done, 8192, [1,1], 0);
2018-06-25 14:43:15 +00:00
});
2018-07-03 04:21:08 +00:00
it('should include filename in compile errors', function(done) {
var m = {
"updates":[
{"path":"main.c", "data":"extern int mul2(int x);\n int main() { return mul2(2); }\n"},
{"path":"fn.c", "data":"void int mul2(int x) { return x*x; }\n"}
],
"buildsteps":[
{"path":"main.c", "platform":"mw8080bw", "tool":"sdcc"},
{"path":"fn.c", "platform":"mw8080bw", "tool":"sdcc"}
],
"path":"fn.c"
2018-07-03 04:21:08 +00:00
};
var msgs = [m];
doBuild(msgs, done, 8192, [1,1], 2); // TODO: check error file
2018-07-03 04:21:08 +00:00
});
2018-07-02 22:48:17 +00:00
it('should compile vicdual skeleton', function(done) {
var files = ['skeleton.sdcc', 'cp437.c'];
2018-07-03 04:21:08 +00:00
compileFiles('sdcc', files, 'vicdual', done, 16416, [0,45], 0); // TODO?
2018-07-02 22:48:17 +00:00
});
2018-08-06 20:23:19 +00:00
it('should compile apple2 skeleton with CC65', function(done) {
var csource = ab2str(fs.readFileSync('presets/apple2/skeleton.cc65'));
compile('cc65', csource, 'apple2', done, 17349, 4, 0);
});
// TODO: test if compile, errors, then compile same file
2017-01-12 02:02:23 +00:00
});