Comparing version 0.1.0 to 0.2.0
{ | ||
"name": "slither", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "Quick testing for short scripts", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
import * as inquirer from "inquirer"; | ||
import * as fs from "fs"; | ||
import * as fs from "mz/fs"; | ||
import * as path from "path"; | ||
@@ -12,3 +13,3 @@ const RED = "\x1b[31m"; | ||
const TEMPLATES: { [key: string]: any } = { | ||
const DEFAULT_TEMPLATES: { [key: string]: any } = { | ||
"java": { | ||
@@ -45,3 +46,3 @@ limits: { | ||
const questions: inquirer.Questions = [ | ||
const questions = (templates: { [key: string]: any }) => [ | ||
{ | ||
@@ -56,4 +57,4 @@ type: "input", | ||
message: "Template", | ||
choices: ["Java", "Python", "JS", "None"], | ||
filter: (val) => val.toLowerCase() | ||
choices: Object.keys(templates).concat(["none"]), | ||
filter: (val: string) => val.toLowerCase() | ||
}, | ||
@@ -64,3 +65,3 @@ { | ||
message: "Timeout", | ||
default: ({ template }: Answers) => template === "none" ? undefined : TEMPLATES[template].limits.timeout, | ||
default: ({ template }: Answers) => template === "none" ? undefined : templates[template].limits.timeout, | ||
filter: parseFloat | ||
@@ -72,3 +73,3 @@ }, | ||
message: "Memory Limit", | ||
default: ({ template }: Answers) => template === "none" ? undefined : TEMPLATES[template].limits.memory, | ||
default: ({ template }: Answers) => template === "none" ? undefined : templates[template].limits.memory, | ||
filter: parseFloat | ||
@@ -92,3 +93,3 @@ }, | ||
message: "Compile Command", | ||
default: ({ template }: Answers) => template === "none" ? undefined : TEMPLATES[template].scripts.compile, | ||
default: ({ template }: Answers) => template === "none" ? undefined : templates[template].scripts.compile, | ||
}, | ||
@@ -99,3 +100,3 @@ { | ||
message: "Build Command", | ||
default: ({ template }: Answers) => template === "none" ? undefined : TEMPLATES[template].scripts.run, | ||
default: ({ template }: Answers) => template === "none" ? undefined : templates[template].scripts.run, | ||
}, | ||
@@ -106,3 +107,3 @@ { | ||
message: "Cleanup Command", | ||
default: ({ template }: Answers) => template === "none" ? undefined : TEMPLATES[template].scripts.cleanup, | ||
default: ({ template }: Answers) => template === "none" ? undefined : templates[template].scripts.cleanup, | ||
}, | ||
@@ -114,3 +115,3 @@ { | ||
choices: ["Exact Match" /*, "1e-3 Error", "1e-4 Error", "1e-6 Error" */], | ||
filter: (val) => { | ||
filter: (val: string) => { | ||
switch (val) { | ||
@@ -130,3 +131,3 @@ case "Exact Match": return { type: "lines" }; | ||
} | ||
] as inquirer.Questions; // ugh | ||
]; | ||
@@ -137,46 +138,51 @@ interface Answers extends Testset { | ||
fs.readFile(".slither/config.json", (err, data) => { | ||
if (err) { | ||
let templatesPrm = | ||
fs.readFile(path.join(process.env["HOME"], ".slither_templates")) | ||
.then((templatesBuf) => JSON.parse(templatesBuf.toString())) | ||
.catch((err) => DEFAULT_TEMPLATES); | ||
Promise.all([fs.readFile(".slither/config.json"), templatesPrm]) | ||
.catch((err) => { | ||
console.error(`${RED}No Slither configuration found in the current directory. Run ${WHITE}${BOLD}slither init${RED} first.${CLEAR}`); | ||
return; | ||
} | ||
process.exit(1); | ||
}) | ||
.then(([configBuf, templates]: [Buffer, { [key: string]: any }]) => { | ||
let config = JSON.parse(configBuf.toString()) as Config; | ||
let config = JSON.parse(data.toString()) as Config; | ||
inquirer.prompt(questions(templates) as inquirer.Questions) | ||
.then((answers: Answers) => { | ||
delete answers.template; | ||
let name = answers.name; | ||
delete answers.name; | ||
inquirer.prompt(questions) | ||
.then((answers: Answers) => { | ||
delete answers.template; | ||
let name = answers.name; | ||
delete answers.name; | ||
answers.io.input = answers.io.input.replace("{name}", name); | ||
answers.io.output = answers.io.output.replace("{name}", name); | ||
answers.scripts.compile = answers.scripts.compile.replace("{name}", name); | ||
answers.scripts.run = answers.scripts.run.replace("{name}", name); | ||
answers.scripts.cleanup = answers.scripts.cleanup.replace("{name}", name); | ||
answers.io.input = answers.io.input.replace("{name}", name); | ||
answers.io.output = answers.io.output.replace("{name}", name); | ||
answers.scripts.compile = answers.scripts.compile.replace("{name}", name); | ||
answers.scripts.run = answers.scripts.run.replace("{name}", name); | ||
answers.scripts.cleanup = answers.scripts.cleanup.replace("{name}", name); | ||
if (name in config) { | ||
console.error(`${RED}A testset with the name ${name} already exists.${CLEAR}`); | ||
return; | ||
} | ||
config[name] = answers as Testset; | ||
fs.writeFile(".slither/config.json", JSON.stringify(config, null, "\t"), (err) => { | ||
if (err) { | ||
console.error(`${RED}File system error:`, err, `${CLEAR}`); | ||
if (name in config) { | ||
console.error(`${RED}A testset with the name ${name} already exists.${CLEAR}`); | ||
return; | ||
} | ||
fs.mkdir(`.slither/${name}`, (err) => { | ||
config[name] = answers as Testset; | ||
fs.writeFile(".slither/config.json", JSON.stringify(config, null, "\t"), (err) => { | ||
if (err) { | ||
console.warn(`${YELLOW}File system error:`, err.message, `${CLEAR}`); | ||
console.warn(`${YELLOW}Continuing anyway...${CLEAR}`); | ||
console.error(`${RED}File system error:`, err, `${CLEAR}`); | ||
return; | ||
} | ||
console.log(`${GREEN}Added test set ${name} to Slither.${CLEAR} ${SNEK}`); | ||
fs.mkdir(`.slither/${name}`, (err) => { | ||
if (err) { | ||
console.warn(`${YELLOW}File system error:`, err.message, `${CLEAR}`); | ||
console.warn(`${YELLOW}Continuing anyway...${CLEAR}`); | ||
} | ||
console.log(`${GREEN}Added test set ${name} to Slither.${CLEAR} ${SNEK}`); | ||
}); | ||
}); | ||
}); | ||
}) | ||
.catch((err) => console.log(err)); | ||
}); | ||
}) | ||
.catch((err) => console.log(err)); | ||
}); |
@@ -58,2 +58,7 @@ import * as commander from "commander"; | ||
function exit(message: string): any { | ||
console.error(message); | ||
process.exit(1); | ||
} | ||
let name: string; | ||
@@ -65,2 +70,3 @@ | ||
.option("-i, --inspect", "Inspect tests after running") | ||
.option("-r, --raw", "Get raw output from a single test") | ||
.action((set: string) => { | ||
@@ -74,57 +80,74 @@ name = set; | ||
} else { | ||
let configPrm = fs.readFile(".slither/config.json"); | ||
fs.readFile(".slither/config.json") | ||
.catch(() => exit(`${RED}No Slither configuration found in the current directory. Run ${WHITE}${BOLD}slither init${RED}${CLEAR}${RED} first.${CLEAR}`)) | ||
.then((data: Buffer) => { | ||
let config = JSON.parse(data.toString()) as Config; | ||
let testset: Testset = config[name]; | ||
configPrm.catch((err) => | ||
console.error(`${RED}No Slither configuration found in the current directory. Run ${WHITE}${BOLD}slither init${RED} first.${CLEAR}`)); | ||
if (!testset) { | ||
return Promise.reject(`${RED}No testset with the name "${name}" was found.${CLEAR}`); | ||
} | ||
configPrm.then((data) => { | ||
let config = JSON.parse(data.toString()) as Config; | ||
let testset: Testset = config[name]; | ||
let tests = (commander as any).tests; | ||
if (!testset) { | ||
console.error(`${RED}No testset with the name "${name}" was found.${CLEAR}`); | ||
} | ||
let tests = (commander as any).tests; | ||
if (Array.isArray(tests)) { | ||
if (Array.isArray(tests)) { | ||
return { testset, tests }; | ||
} else { | ||
return getAllTests(name).then((tests) => ({ testset, tests })); | ||
} | ||
}) | ||
.catch(exit) | ||
.then(({ testset, tests }: { testset: Testset, tests: number[] }) => { | ||
if ((commander as any).raw && tests.length != 1) { | ||
return Promise.reject(`${BOLD}${RED}Error: -r/--raw can only be used with a single test${CLEAR}${SHOW_CURSOR}`); | ||
} else if ((commander as any).raw && (commander as any).inspect) { | ||
return Promise.reject(`${BOLD}${RED}Error: -r/--raw can't be used with -i/--inspect${SHOW_CURSOR}`); | ||
} | ||
return Promise.resolve({ testset, tests }); | ||
} else { | ||
return getAllTests(name).then((tests) => ({ testset, tests })); | ||
} | ||
}).then(({ testset, tests }) => { | ||
let compilePrm = exec(testset.scripts.compile); | ||
}) | ||
.catch(exit) | ||
.then(({ testset, tests }: { testset: Testset, tests: number[] }) => { | ||
return Promise.all([ | ||
testset, | ||
tests, | ||
exec(testset.scripts.compile) | ||
]) as Promise<[Testset, number[], { stdout: string, stderr: string }]>; | ||
}) | ||
.catch(({ stderr }: { stderr: string }) => exit(`${BOLD}${RED}Compile error:${CLEAR}\n\n${stderr}${SHOW_CURSOR}`)) | ||
.then(([testset, tests]: [Testset, number[]]) => { | ||
process.stdout.write(HIDE_CURSOR); | ||
compilePrm.catch(({ stdout, stderr }) => console.error(`${RED}Compile error:${CLEAR} ${stderr}`)); | ||
let prm: Promise<Results> = Promise.resolve({ | ||
results: tests.map((index: number) => ({ index, state: State.WAITING } as IncompleteTestResult)) | ||
}); | ||
process.stdout.write(HIDE_CURSOR); | ||
for (let i = 0; i < tests.length; i++) { | ||
prm.then((results) => { | ||
results.results[i].state = State.RUNNING; | ||
update(results); | ||
}).catch((error) => console.error(`${RED}Error: ${error}${CLEAR}`)); | ||
let prm: Promise<Results> = compilePrm.then(() => ({ | ||
results: tests.map((index: number) => ({ index, state: State.WAITING } as IncompleteTestResult)) | ||
})); | ||
prm = prm.then((results) => { | ||
return test(results, name, testset, tests[i], i); | ||
}); | ||
} | ||
for (let i = 0; i < tests.length; i++) { | ||
prm.then((results) => { | ||
results.results[i].state = State.RUNNING; | ||
return prm.then((results) => { | ||
update(results); | ||
}).catch((error) => console.error(`${RED}Error: ${error}${CLEAR}`)); | ||
prm = prm.then((results) => { | ||
return test(results, name, testset, tests[i], i); | ||
process.stdout.write(DOWN(results.results.length)); | ||
exec(testset.scripts.cleanup); | ||
return results; | ||
}); | ||
} | ||
return prm.then((results) => { | ||
update(results); | ||
process.stdout.write(DOWN(results.results.length)); | ||
exec(testset.scripts.cleanup); | ||
return results; | ||
}); | ||
}).then((results) => { | ||
if ((commander as any).inspect) { | ||
new Inspector(results); | ||
} else { | ||
process.stdout.write(SHOW_CURSOR); | ||
} | ||
}).catch((err) => { console.error(`${RED}Error:`, err, SHOW_CURSOR, CLEAR); }); | ||
}) | ||
.then((results: Results) => { | ||
if ((commander as any).raw) { | ||
process.stdout.write((results.results[0] as CompleteTestResult).output.actual); | ||
process.stdout.write(SHOW_CURSOR); | ||
} else if ((commander as any).inspect) { | ||
new Inspector(results); | ||
} else { | ||
process.stdout.write(SHOW_CURSOR); | ||
} | ||
}) | ||
.catch((err: any) => exit(`${RED}Error:${err}${SHOW_CURSOR}${CLEAR}`)); | ||
} | ||
@@ -158,7 +181,3 @@ | ||
// let interval = setInterval(() => fs.readFile(`/proc/${child.pid}/stat`).then(console.log), 20); | ||
child.on("close", (code) => { | ||
// clearInterval(interval); | ||
if (timer) { | ||
@@ -261,2 +280,4 @@ clearTimeout(timer); | ||
function printTestResult(result: TestResult): void { | ||
process.stdout.write(BOLD); | ||
switch (result.state) { | ||
@@ -293,2 +314,3 @@ case State.OK: | ||
process.stdout.write(" "); | ||
process.stdout.write(CLEAR); | ||
process.stdout.write(WHITE); | ||
@@ -311,5 +333,5 @@ process.stdout.write(result.index.toString()); | ||
process.stdout.write("[ "); | ||
process.stdout.write(result.time.toFixed(0)); | ||
process.stdout.write(leftPad(result.time.toFixed(0), 4)); | ||
process.stdout.write(" ms / "); | ||
process.stdout.write((result.memory / 1048576).toFixed(3)); | ||
process.stdout.write(leftPad((result.memory / 1048576).toFixed(3), 8)); | ||
process.stdout.write(" MB ]"); | ||
@@ -321,2 +343,6 @@ break; | ||
function update(results: Results): void { | ||
if ((commander as any).raw) { | ||
return; | ||
} | ||
for (let result of results.results) { | ||
@@ -371,2 +397,6 @@ printTestResult(result); | ||
break; | ||
case "q": | ||
process.stdout.write(SHOW_CURSOR); | ||
process.stdin.pause(); | ||
} | ||
@@ -427,2 +457,4 @@ }); | ||
let actual = ""; | ||
let expectedCount = 0; | ||
let actualCount = 0; | ||
@@ -434,2 +466,4 @@ switch (current.state) { | ||
actual = (current as CompleteTestResult).output.displayActual; | ||
expectedCount = dropTrailingNewlines((current as CompleteTestResult).output.expected.split("\n")).length; | ||
actualCount = dropTrailingNewlines((current as CompleteTestResult).output.actual.split("\n")).length; | ||
break; | ||
@@ -442,2 +476,4 @@ | ||
actual = numberLines(current.output.actual); | ||
expectedCount = dropTrailingNewlines(current.output.expected.split("\n")).length; | ||
actualCount = dropTrailingNewlines(current.output.actual.split("\n")).length; | ||
break; | ||
@@ -448,10 +484,10 @@ } | ||
let expectedLines = formatDisplayLines(expected, size); | ||
let actualLines = formatDisplayLines(actual, size); | ||
let expectedLines = expected.split("\n").slice(0, 20); | ||
let actualLines = actual.split("\n").slice(0, 20); | ||
let expectedHeader = rightPad(`${BOLD}${WHITE} Expected ${CLEAR}${GRAY}(${expectedLines.length} lines)${CLEAR}`, size); | ||
let actualHeader = rightPad(`${BOLD}${WHITE} Actual ${CLEAR}${GRAY}(${actualLines.length} lines)${CLEAR}`, size); | ||
expectedLines = formatDisplayLines(expectedLines, size); | ||
actualLines = formatDisplayLines(actualLines, size); | ||
expectedLines = expectedLines.slice(0, 20); | ||
actualLines = actualLines.slice(0, 20); | ||
let expectedHeader = rightPad(`${BOLD}${WHITE} Expected ${CLEAR}${GRAY}(${expectedCount} lines)${CLEAR}`, size); | ||
let actualHeader = rightPad(`${BOLD}${WHITE} Actual ${CLEAR}${GRAY}(${actualCount} lines)${CLEAR}`, size); | ||
@@ -470,5 +506,3 @@ process.stdout.write(`${expectedHeader} ${CLEAR}| ${actualHeader}\n`); | ||
function numberLines(str: string): string { | ||
let lines = str.split(/\n/g); | ||
function dropTrailingNewlines(lines: string[]): string[] { | ||
while (lines[lines.length - 1] === "") { | ||
@@ -478,2 +512,7 @@ lines.pop(); | ||
return lines; | ||
} | ||
function numberLines(str: string): string { | ||
let lines = dropTrailingNewlines(str.split(/\n/g)); | ||
let padWidth = lines.length.toString().length; | ||
@@ -486,5 +525,3 @@ | ||
function formatDisplayLines(str: string, size: number): string[] { | ||
let lines = str.split(/\n/g); | ||
function formatDisplayLines(lines: string[], size: number): string[] { | ||
while (lines[lines.length - 1] === "") { | ||
@@ -491,0 +528,0 @@ lines.pop(); |
@@ -5,7 +5,9 @@ import * as commander from "commander"; | ||
commander | ||
.version("0.0.1") | ||
.version("0.2.0") | ||
.command("init", "initialize slither in a directory") | ||
.command("addset", "add a new test set") | ||
.command("addtest <set>", "add a new test case to a testset") | ||
.command("edittest <set> <number>", "edit a test case for a testset") | ||
.command("cattest <set> <number>", "print a test case for a testset") | ||
.command("test <name>", "run a test set") | ||
.parse(process.argv); |
@@ -11,3 +11,4 @@ { | ||
"outDir": "bin", | ||
"pretty": true | ||
"pretty": true, | ||
"noErrorTruncation": true | ||
}, | ||
@@ -14,0 +15,0 @@ "exclude": [ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
81665
27
1127
1
29