Finally! Compilation tests as part of the testsuite.

This commit is contained in:
Jonathan Protzenko 2015-11-09 16:33:01 -08:00
Родитель a007526ce8
Коммит 935ea21595
10 изменённых файлов: 664 добавлений и 540 удалений

Просмотреть файл

@ -165,6 +165,7 @@ mkSimpleTask('build/storage.js', [
], "storage/refs.ts");
mkSimpleTask('build/embedded.js', [
'build/ast.d.ts',
'build/storage.d.ts',
'embedded'
], "embedded/refs.ts");
mkSimpleTask('build/ast.js', [
@ -214,6 +215,7 @@ mkSimpleTask('build/nrunner.js', [
'build/browser.d.ts',
'rt/typings.d.ts',
'build/rt.d.ts',
'build/embedded.d.ts',
'build/ast.d.ts',
'build/libnode.d.ts',
'noderunner'
@ -240,6 +242,15 @@ mkSimpleTask('build/blockly-main.js', [
"ast/jsonInterfaces.ts"
], "www/blockly/refs.ts");
file('build/libraries.js', expand([
"build/client.js",
"microbit/libraries",
"microbit"]
), { async:true }, function () {
runAndComplete(['node build/client concatlibs'], this);
})
// Now come the rules for files that are obtained by concatenating multiple
// _js_ files into another one. The sequence exactly reproduces what happened
// previously, as there are ordering issues with initialization of global variables
@ -255,10 +266,13 @@ var concatMap = {
"build/browser",
"build/rt",
"build/ast",
"build/storage",
"build/embedded",
"build/api.js",
"generated/langs.js",
"build/libnode",
"build/pkgshell.js",
"build/libraries.js",
"build/nrunner.js",
],
"build/noderuntime.js": [
@ -379,7 +393,7 @@ task('default', [
'build/officemix.d.ts',
'build/ace-main.js',
'build/blockly-main.js',
'concat-libs',
'build/libraries.js',
'log'
].concat(Object.keys(concatMap)), {
parallelLimit: branchingFactor,
@ -409,7 +423,10 @@ desc('run local test suite')
task('test', [ 'info', 'build/client.js', 'default' ], { async: true }, function () {
var task = this;
console.log("[I] running tests")
runAndComplete(['node build/client.js buildtest'], this);
runAndComplete([
'node build/client.js buildtest',
'node build/noderunner.js compilertest'
], this);
});
// this task runs as a "after_success" step in the travis-ci automation
@ -527,11 +544,7 @@ task('cordova', [ 'default' ], {}, function () {
});
task('update-libs', ["build/client.js"], { async:true}, function () {
runAndComplete(['node build/client fetchlibraries'], this);
})
task('concat-libs', ["build/client.js"], { async:true}, function () {
runAndComplete(['node build/client concatlibs'], this);
runAndComplete(['node build/client fetchlibraries'], this);
})
// vim: ft=javascript

Просмотреть файл

@ -2092,7 +2092,7 @@ module TDev
ModalDialog.showText(
"Internal compilation error. "+
"Please file a bug and include the following information:\n" +
External.makeOutMbedErrorMsg(json),
Embedded.makeOutMbedErrorMsg(json),
lf("Compilation error"));
} else {
document.location.href = json.hexurl;

Просмотреть файл

@ -106,22 +106,6 @@ module TDev {
import J = AST.Json;
export function makeOutMbedErrorMsg(json: any) {
var errorMsg = "unknown error";
// This JSON format is *very* unstructured...
if (json.mbedresponse) {
if (json.messages) {
var messages = json.messages.filter(m =>
m.severity == "error" || m.type == "Error"
);
errorMsg = messages.map(m => m.message + "\n" + m.text).join("\n");
} else if (json.mbedresponse.result) {
errorMsg = json.mbedresponse.result.exception;
}
}
return errorMsg;
}
export function pullLatestLibraryVersion(pubId: string): Promise { // of string
var forced = ScriptCache.forcedUpdate(pubId)
if (forced) return Promise.as(forced.json.id)
@ -197,22 +181,6 @@ module TDev {
});
}
function parseScript(text: string): Promise { // of AST.App
return AST.loadScriptAsync((id: string) => {
if (id == "")
return Promise.as(text);
else
return World.getAnyScriptAsync(id);
}, "").then((resp: AST.LoadScriptResult) => {
// Otherwise, eventually, this will result in our script being
// saved in the TouchDevelop format...
var s = Script;
Script = null;
// The function writes its result in a global
return Promise.as(s);
});
}
// For compatibility with the old format
function fixupLibs(libs: { [i: string]: any }) {
Object.keys(libs).forEach((k: string) => {
@ -224,7 +192,7 @@ module TDev {
function roundtrip1(a: J.JApp, libs: { [i: string]: LibEntry }): Promise { // of AST.App
return addLibraries(a, libs).then(() => {
var text = J.serialize(a);
return parseScript(text).then((a: AST.App) => {
return Embedded.parseScript(text).then((a: AST.App) => {
if (AST.TypeChecker.tcApp(a) > 0) {
throw new Error("We received a script with errors and cannot compile it. " +
"Try converting then fixing the errors manually.");
@ -274,7 +242,7 @@ module TDev {
}
function typeCheckAndRun(text: string, mainName = "main") {
parseScript(text).then((a: AST.App) => {
Embedded.parseScript(text).then((a: AST.App) => {
J.setStableId(a);
// The call to [tcApp] also has the desired side-effect of resolving
// names.
@ -492,7 +460,7 @@ module TDev {
});
document.location.href = json.hexurl;
} else {
var errorMsg = makeOutMbedErrorMsg(json);
var errorMsg = Embedded.makeOutMbedErrorMsg(json);
this.post(<Message_CompileAck>{
type: MessageType.CompileAck,
status: Status.Error,

Просмотреть файл

@ -49,7 +49,6 @@
///<reference path='plugins.ts'/>
///<reference path='external.ts'/>
///<reference path='messages.ts'/>
///<reference path='embedded.ts'/>
///<reference path='literalEditor.ts'/>
///<reference path='abusereview.ts'/>
///<reference path='../intellitrain/train.ts'/>

Просмотреть файл

@ -15,6 +15,38 @@ module TDev {
[index: string]: T;
}
export function parseScript(text: string): Promise { // of AST.App
return AST.loadScriptAsync((id: string) => {
if (id == "")
return Promise.as(text);
else
return World.getAnyScriptAsync(id);
}, "").then((resp: AST.LoadScriptResult) => {
// Otherwise, eventually, this will result in our script being
// saved in the TouchDevelop format...
var s = Script;
Script = null;
// The function writes its result in a global
return Promise.as(s);
});
}
export function makeOutMbedErrorMsg(json: any) {
var errorMsg = "unknown error";
// This JSON format is *very* unstructured...
if (json.mbedresponse) {
if (json.messages) {
var messages = json.messages.filter(m =>
m.severity == "error" || m.type == "Error"
);
errorMsg = messages.map(m => m.message + "\n" + m.text).join("\n");
} else if (json.mbedresponse.result) {
errorMsg = json.mbedresponse.result.exception;
}
}
return errorMsg;
}
interface EmitterOutput {
prototypes: string;
code: string;

Просмотреть файл

@ -1,7 +1,9 @@
///<reference path='../build/ast.d.ts'/>
///<reference path='../build/storage.d.ts'/>
///<reference path='helpers.ts'/>
///<reference path='visitor.ts'/>
///<reference path='emitter.ts'/>
///<reference path='lambda_lifter.ts'/>
///<reference path='bytecode.ts'/>
///<reference path='thumb.ts'/>
///<reference path='driver.ts'/>

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -63,6 +63,7 @@ action \_libinit() {
#xVIOjGStCgdLjic6 code→update_axis;
#ByFADaJmirytJ02b code→background_animation;
#xmVrpXc8aqbE3dq6 `async` code→animation_worker;
#xkycDjt57DBUf4Xz `async` code→event_bus_worker;
#pNdJy7kyaeqKZhfS data→board→on_every_frame;
#xbsS9F4HXWsdVT8s where `implicit` \_body\_() {
#WF6Md7jUVLVAe3m4 code→update_board;
@ -553,12 +554,13 @@ action on_button_pressed(#M03fUuuX2m9eRu7n name: String, #LzMsXwEMSCmDzfWI body:
#bb2jhwAjjludGu2o // {weight:58}
#fm3i5OlTIzr9FGuU // {enum:name:A=MICROBIT_ID_BUTTON_A,B=MICROBIT_ID_BUTTON_B,A+B=MICROBIT_ID_BUTTON_AB}
#KwFDbs7Kr12Y7FTP // {shim:micro_bit::onButtonPressed}
#FMX7Dy8may7mfc7j code→notify_event_registration("on button pressed " ∥ $name);
#OzSnTzWiKXQk0HlQ $evid := "on button pressed " ∥ $name;
#FMX7Dy8may7mfc7j code→notify_event_registration($evid);
#h2x2L30VBbMGVNED $btn := code→button_from_id($name);
#xOIGjOLy2Zmt99MW code→clear_button_handler($name);
#F5Y2ciTtYo87uZSG $ev := $btn→on_touch_down($touch_up);
#j0K6jsuWQ4V0EcaI where touch_up(x: Number, y: Number) {
#UZ7doRhNRnR5s62g `async` $body→run;
#zvnW22u4MgaK24ge code→queue_event_bus($body, $evid);
}
#hijH5eY42toXLOFF code→store_button_handler($name, $ev);
meta sync;
@ -913,6 +915,10 @@ action test_buttons() {
#Rp8qiY1vzviZ2kWq where `implicit` \_body\_() {
#Wf7Z3Bn5plHJ78I1 code→show_string("B", 100);
}
#NO9PrQ5LFZfQfagg code→on_button_pressed("A+B");
#POC91PYG4214TJp0 where `implicit` \_body\_() {
#xYIv0xzaNMKmq0z3 code→show_string("A+B", 150);
}
meta private;
meta test;
}
@ -1631,11 +1637,12 @@ action on_pin_pressed(#xSs4Svf30EPMhoVj name: String, #BxKLhpiGqRcDwB1h body: Ac
#UZIoGA4CKSwhMxlf // {weight:57}
#OgqWJNwCulcyJT7l // {enum:name:P0=MICROBIT_ID_IO_P0,P1=MICROBIT_ID_IO_P1,P2=MICROBIT_ID_IO_P2}
#xZ0ArWZwbu4SBuBn // {shim:micro_bit::onPinPressed}
#nPpJQoCs8nAIigcE code→notify_event_registration("on pin pressed " ∥ $name);
#jDgDoJLo4kvbVPvk $evid := "on pin pressed " ∥ $name;
#nPpJQoCs8nAIigcE code→notify_event_registration($evid);
#h5fUFp7OQ9fEwJRv $btn := code→pin_by_name($name);
#GXVoxvPhWYd2tdDp $btn→on_touch_down($touch_down);
#TDcZdyD22Igf3vMo where touch_down(x: Number, y: Number) {
#xs5qVip6FU1jDpOm `async` $body→run;
#NbkK6P2y62Y9tOIt code→queue_event_bus($body, $evid);
}
meta sync;
}
@ -2431,3 +2438,49 @@ action show_frame(#so5UArm5bvzzbO7Q img: * Image, #wbgk1lJLlqXDa2l4 frame: Numbe
#xA18S6STfkQQmHSO // {help:functions/show-frame}
#RqxUSeIfDyXF0l5K $img→show_image($frame * 5);
}
#jK3Ut2qwQC0bZ07k
table Event_Bus {
// {shim:}
type = "Table";
persistent = false;
fields {
#kng9nuProLg6HpFo fn : Action
#lz2qarlZRUAVl0SD name : String
}
}
#xQHQZkhjqzpE4CRi
action event_bus_worker() {
#xDyM0UomTSCQXKSV // {shim:}
#HakK0IQSqWKY8zju while true do {
#FTMD9oKdw4fcscHD $ev := records→Event_Bus_table→row_at(0);
#xG44rWke0lFZ2GrH if `not` $ev→is_invalid then {
#qUZz8iwjSjiyyavq $ev→fn→run;
#E7aHvwM2U423dBK6 $ev→delete_row;
}
else {
#P594Nj69PCQ9z45m records→Event_Bus_table→wait_for_update;
}
}
meta private;
}
#uBLXg1puXSO4QzoW
action queue_event_bus(#ErQcVVIPwKO622FK body: Action, #x6jst5KZQ5V4sFOr name: String) {
#chlGhAEHEEsL01Wv // {shim:}
#NpFfWiYSSrNXvvQY $c := 0;
#kjMOASgzL4ThV4oE foreach eb in records→Event_Bus_table
do {
#xuKiuV4YTvIuJYLL if $eb→name→equals($name) then {
#eiPzA9GxYNRXmnAQ $c := $c + 1;
}
}
#xv0tUVTZQbNE3PW4 if $c < 5 then {
#mbqwhgLr24hPftS9 $ev := records→Event_Bus_table→add_row;
#Guj24KBD912FcSYv $ev→name := $name;
#OvyZqeICJJ2sQbR4 $ev→fn := $body;
}
else {
#SzvR3GyWF2k4aEW8 app→log("skipped event " ∥ $name ∥ ", bus full");
}
meta private;
meta sync;
}

Просмотреть файл

@ -3,6 +3,7 @@
///<reference path='../build/rt.d.ts'/>
///<reference path='../build/ast.d.ts'/>
///<reference path='../build/libnode.d.ts'/>
///<reference path='../build/embedded.d.ts'/>
///<reference path='../typings/node/node.d.ts'/>
///<reference path='jsonapi.ts'/>
@ -1967,6 +1968,57 @@ function getScriptAsync(id:string)
})
}
function compilerTest() {
console.log("COMPILER TEST");
var tests = {
bqutuo: {}, // pac man runaway
hixlrc: {}, // two-player pong (reversed)
rwadai: { skipBitVm: true }, // clock demo
xhfhgq: {}, // bitvm test1
};
window.localStorage.setItem("access_token", accessToken.replace("?access_token=", ""));
TDev.Cloud.config.rootUrl = apiEndpoint.replace("/api/", "");
Object.keys(tests).forEach((pubId: string) => {
var name;
var logMsg = (s: string) => name+" ("+pubId+"): "+s;
TDev.Cloud.getPublicApiAsync(pubId).then((j: TDev.JsonScript) => {
if (pubId != j.updateid)
console.log(logMsg("found newer version: "+j.updateid));
return TDev.Util.httpGetTextAsync(TDev.Cloud.getPublicApiUrl(j.updateid+"/text"));
}).then((text: string) => {
return TDev.Embedded.parseScript(text);
}).then((a: TDev.AST.App) => {
name = a.getName();
console.log(logMsg("parsing → touchdevelop ✓"));
if (tests[pubId].skipBitVm) {
console.log(logMsg("skipping bitvm"));
} else {
(new TDev.AST.Bytecode.Compiler(a)).run();
console.log(logMsg("touchdevelop → hex (bitvm) ✓"));
}
return TDev.Embedded.compile(TDev.AST.Json.dump(a))
}).then((cpp: string) => {
console.log(logMsg("touchdevelop → cpp ✓"));
var fakeGuid = "d9b98ebe-3bf9-4f73-9452-459e59f2dbf5";
return TDev.Cloud.postUserInstalledCompileAsync(fakeGuid, cpp, { name: name });
}).then(json => {
if (!json)
throw new Error(logMsg("no response from ARM cloud"));
if (!json.success) {
console.log(TDev.Embedded.makeOutMbedErrorMsg(json));
throw new Error(logMsg("compilation failure"));
}
console.log(logMsg("cpp → hex (arm cloud) ✓"));
}, (e) => {
console.log(logMsg("compilation failure"));
console.log(e.stack);
process.exit(1);
}).done();
});
}
export function globalInit()
{
TDev.Browser.isNodeJS = true;
@ -2057,6 +2109,8 @@ export function globalInit()
addIds(process.argv.slice(3))
} else if (process.argv[2] == "mergetest") {
mergetest(process.argv.slice(3))
} else if (process.argv[2] == "compilertest") {
compilerTest();
} else if (process.argv[2] == "ts") {
ts(process.argv.slice(3))
} else {

Просмотреть файл

@ -4494,3 +4494,4 @@ export function main()
}
main();