UNPKG

ace-code-editor

Version:

Ajax.org Code Editor is a full featured source code highlighting editor that powers the Cloud9 IDE

250 lines (219 loc) 8.16 kB
var fs = require("fs"); var path = require("path"); if (!fs.existsSync) fs.existsSync = path.existsSync; require("amd-loader"); var cwd = __dirname + "/"; var root = path.normalize(cwd + Array(5).join("../")); function jsFileList(path, filter) { if (!filter) filter = /_test/; return fs.readdirSync(path).map(function(x) { if (x.slice(-3) == ".js" && !filter.test(x) && !/\s/.test(x)) return x.slice(0, -3); }).filter(Boolean); } function modeList() { return jsFileList(cwd + "../", /_highlight_rules|_test|_worker|xml_util|_outdent|behaviour|completions/); } function checkModes() { modeList().forEach(function(modeName, i) { console.log(padNumber(i+1, 3) + ") check: \u001b[33m" + modeName + "\u001b[0m"); try { var Mode = require("../" + modeName).Mode; } catch(e) { console.warn("Can't load mode :" + modeName, e); return; } var m = new Mode(); if (!("lineCommentStart" in m) && !("blockComment" in m)) console.warn("missing comment in " + modeName); if (!m.$id) console.warn("missing id in " + modeName); var tokenizer = (new Mode).getTokenizer(); testComments(m.lineCommentStart, testLineComment, tokenizer, modeName); testComments(m.blockComment, testBlockComment, tokenizer, modeName); }); function testComments(desc, fn, tokenizer, modeName) { if (desc) { if (Array.isArray(desc)) { desc.forEach(function(x) { fn(tokenizer, x, modeName) }); } else { fn(tokenizer, desc, modeName) } } } function testBlockComment(tokenizer, blockComment, modeName) { if (blockComment.lineStartOnly) return; // TODO test var str = blockComment.start + " " + blockComment.end; str = blockComment.start + str; if (blockComment.nestable) str += blockComment.end; var data = tokenizer.getLineTokens(str, "start"); var isBroken = data.tokens.some(function(t) { return !/comment/.test(t.type) }); if (isBroken) console.warn("broken blockComment in " + modeName, data); if (!/start/.test(data.state)) console.warn("broken state after blockComment in " + modeName, data); } function testLineComment(tokenizer, commentStart, modeName) { var tokens = tokenizer.getLineTokens(commentStart + " ", "start").tokens; if (!/comment/.test(tokens[0].type)) console.warn("broken lineCommentStart in " + modeName); } } function generateTestData(names, force) { var docRoot = root + "/demo/kitchen-sink/docs"; var docs = fs.readdirSync(docRoot); var specialDocs = fs.readdirSync(cwd); var modes = modeList(); // console.log("Docs:", docs); // console.log("Modes:", modes); docs.forEach(function(docName) { var p = docName.toLowerCase().split("."); if (!p[1]) return; var modeName; if (modes.indexOf(p[0]) != -1) modeName = p[0]; else if (modes.indexOf(p[1]) != -1) modeName = p[1]; else modeName = {"txt": "text", cpp: "c_cpp"}[p[1]]; if (names && names.length && names.indexOf(modeName) == -1) return; var outputPath = cwd + "tokens_" + modeName + ".json"; try { var oldOutput = require(outputPath); } catch(e) {} if (oldOutput && !force) { var oldText = oldOutput.map(function(x) { if (x.length > 1 && typeof x[x.length - 1] == "string") return x[x.length - 1]; return x.slice(1).map(function(tok) { return tok[1]; }).join(""); }).join("\n"); } var filePath = "text_" + modeName + ".txt"; if (specialDocs.indexOf(filePath) !== -1) { filePath = cwd + filePath; } else { filePath = docRoot + "/" + docName; // oldText = ""; } var text = oldText ||fs.readFileSync(filePath, "utf8"); try { var Mode = require("../" + modeName).Mode; } catch(e) { console.warn("Can't load mode :" + modeName, p, e); return; } console.log(modeName); var tokenizer = new Mode().getTokenizer(); var state = "start"; var data = text.split(/\r\n|\r|\n/).map(function(line) { var data = tokenizer.getLineTokens(line, state); var tmp = []; tmp.push(JSON.stringify(data.state)); var tokenizedLine = ""; data.tokens.forEach(function(x) { tokenizedLine += x.value; tmp.push(JSON.stringify([x.type, x.value])); }); if (tokenizedLine != line) tmp.push(JSON.stringify(line)); state = data.state; return tmp.join(",\n "); }); var jsonStr = "[[\n " + data.join("\n],[\n ") + "\n]]"; if (oldOutput && JSON.stringify(JSON.parse(jsonStr)) == JSON.stringify(oldOutput)) return; fs.writeFileSync(outputPath, jsonStr, "utf8"); }); } function test(startAt) { var modes = fs.readdirSync(cwd).map(function(x) { return (x.match(/tokens_(.*).json/) || {})[1]; }).filter(function(x){return !!x}); for (var i = Math.max(0, startAt||0); i < modes.length; i++) testMode(modes[i], i); console.log("\u001b[32m" + "all ok" + "\u001b[0m"); } function testMode(modeName, i) { console.log(padNumber(i+1, 3) + ") testing: \u001b[33m" + modeName + "\u001b[0m"); var text = fs.readFileSync(cwd + "tokens_" + modeName + ".json", "utf8"); var data = JSON.parse(text); var Mode = require("../" + modeName).Mode; var tokenizer = new Mode().getTokenizer(); var state = "start"; data.forEach(function(lineData) { lineData.values = []; lineData.types = []; lineData.state = lineData.shift(); var line = null; if (typeof lineData[lineData.length - 1] == "string") line = lineData.pop(); lineData.forEach(function(x) { lineData.types.push(x[0]); lineData.values.push(x[1]); }); if (typeof line != "string") line = lineData.values.join(""); var tokens = tokenizer.getLineTokens(line, state); var values = tokens.tokens.map(function(x) {return x.value;}); var types = tokens.tokens.map(function(x) {return x.type;}); var err = testEqual([ JSON.stringify(lineData.state), JSON.stringify(tokens.state), lineData.types, types, lineData.values, values]); if (err) { console.log(line); throw "error"; } state = tokens.state; }); } function testEqual(a) { var err; if (a[0] + "" !== a[1] + "") { console.log(a[0],a[1]); err = 1; } if ( a[2] + "" !== a[3] + "" || a[4] + "" !== a[5] + "") { arrayDiff(a[2],a[3]); arrayDiff(a[4],a[5]); err = 1; } return err; } function arrayDiff(a1, a2) { var l = Math.max(a1.length, a2.length); var out = []; for (var i = 0; i < l; i++) { out.push("\n", padNumber(i+1, 3), ") "); if (a1[i] !== a2[i]) out.push("\u001b[31m", a1[i], "\u001b[0m != \u001b[32m", a2[i], "\u001b[0m"); else out.push(a1[i]); } console.log(out.join("")); } function padNumber(num, digits) { return (" " + num).slice(-digits); } // cli var arg = process.argv[2]; if (!arg) { test(); checkModes(); } else if (/--?g(en)?/.test(arg)) generateTestData(process.argv.splice(3)); else if (/--?c(heck)?/.test(arg)) checkModes(process.argv.splice(3)); else if (/\d+/.test(arg)) test(parseInt(process.argv[2],10) || 0); else testMode(arg, -1);