Fix line numbers in error messages
This commit is contained in:
parent
09dfb13a07
commit
8da4c9a969
4 changed files with 35 additions and 19 deletions
|
@ -13,6 +13,11 @@ export default class SomeClass {
|
|||
* SomeClass.get() + 1 // => 43
|
||||
*
|
||||
* new OtherClass().doSomething(new SomeClass()) // => 5
|
||||
*
|
||||
* const abc = 42
|
||||
* SomeClass.get() // => abc
|
||||
* SomeClass.get() + 1 // => abc + 1
|
||||
*
|
||||
*/
|
||||
private static get() : number{
|
||||
// a comment
|
||||
|
|
|
@ -26,7 +26,7 @@ export default class ExtractComments {
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets the actual comments
|
||||
* Gets the actual comments and their context.
|
||||
*/
|
||||
public getComments(): { comment: string, context: Context }[] {
|
||||
return this.results
|
||||
|
|
|
@ -25,15 +25,24 @@ export class ScriptExtraction {
|
|||
return docstring.split("\n").filter(s => s.startsWith("import "));
|
||||
}
|
||||
|
||||
public static extractScripts(docstring: string): { script: Script, name?: string, line: number }[] {
|
||||
const out = [] as { script: Script, name?: string, line: number }[]
|
||||
|
||||
/**
|
||||
* Extracts the scripts from a comment
|
||||
*
|
||||
* // should have correct line numbers
|
||||
* const extr = ScriptExtraction.extractScripts("some actual comment\n\n42 // => 42\n\n43 // => 43\n44 // => 44\n\n // should be named\n45 // => 45\n")
|
||||
* extr[0] // => {script: [{lhs: "42", rhs: "42", tag: '==', line: 2}]}
|
||||
* extr[1] // => {script: [{lhs: "43", rhs: "43", tag: '==', line: 4},{lhs: "44", rhs: "44", tag: '==', line: 5}]}
|
||||
* extr[2] // => {name: "should be named", script: [{lhs: "45", rhs: "45", tag: '==', line: 8}]}
|
||||
*/
|
||||
public static extractScripts(docstring: string): { script: Script, name?: string }[] {
|
||||
const out = [] as { script: Script, name?: string }[]
|
||||
|
||||
function lineIndexOf(part: string): number {
|
||||
const index = docstring.indexOf(part)
|
||||
const before = docstring.slice(0, index)
|
||||
return before.split(/\r\n|\r|\n/).length - 1
|
||||
}
|
||||
|
||||
|
||||
for (const s of docstring.split(/\n\n+/m)) {
|
||||
|
||||
if (!ScriptExtraction.is_doctest(s)) {
|
||||
|
@ -42,12 +51,13 @@ export class ScriptExtraction {
|
|||
|
||||
const line = lineIndexOf(s)
|
||||
const script = ScriptExtraction.extractScript(s, line)
|
||||
let name = undefined
|
||||
const match = s.match(/^[ \t]*\/\/([^\n]*)/)
|
||||
if (match !== null) {
|
||||
name = match[1].trim()
|
||||
const name = match[1].trim()
|
||||
out.push({script, name})
|
||||
} else {
|
||||
out.push({script})
|
||||
}
|
||||
out.push({script, name, line})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
@ -55,25 +65,25 @@ export class ScriptExtraction {
|
|||
/**
|
||||
* ScriptExtraction.extractScript('s', 0) // => [{tag: 'Statement', stmt: 's;'}]
|
||||
* ScriptExtraction.extractScript('e // => 1', 0) // => [{tag: '==', lhs: 'e', rhs: '1', line: 0}]
|
||||
* ScriptExtraction.extractScript('s; e // => 1', 0) // => [{tag: 'Statement', stmt: 's;'}, {tag: '==', lhs: 'e', rhs: '1', line: 1}]
|
||||
* ScriptExtraction.extractScript('s;\n e // => 1', 0) // => [{tag: 'Statement', stmt: 's;'}, {tag: '==', lhs: 'e', rhs: '1', line: 1}]
|
||||
* ScriptExtraction.extractScript('s0\n e0 // => 0 \n e // => 1', 42) // => [{tag: 'Statement', stmt: 's0;'}, {tag: '==', lhs: 'e0', rhs: '0', line: 43}, {tag: '==', lhs: 'e', rhs: '1', line: 44}]
|
||||
*/
|
||||
private static extractScript(s: string, linestart: number): Script {
|
||||
function getLineNumber(pos: number) {
|
||||
let line = 0;
|
||||
for (let i = 0; i < pos; i++) {
|
||||
if (s === "\n") {
|
||||
for (let i = 0; i <= pos; i++) {
|
||||
if (s[i] === "\n") {
|
||||
line++
|
||||
}
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
const pwoc = ts.createPrinter({removeComments: true})
|
||||
const ast = ts.createSourceFile('_.ts', s, ts.ScriptTarget.Latest)
|
||||
return ast.statements.map((stmt, i): Statement | Equality => {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (ts.isExpressionStatement(stmt)) {
|
||||
const next = ast.statements[i + 1] // zip with next
|
||||
const [a, z] = next ? [next.pos, next.end] : [stmt.end, ast.end]
|
||||
|
@ -83,8 +93,8 @@ export class ScriptExtraction {
|
|||
const lhs = pwoc.printNode(ts.EmitHint.Expression, stmt.expression, ast)
|
||||
const rhs = m[1].trim()
|
||||
|
||||
|
||||
return {tag: '==', lhs, rhs, line: linestart + getLineNumber(stmt.pos)}
|
||||
|
||||
return {tag: '==', lhs, rhs, line: linestart + getLineNumber(a)}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,8 @@ export default class UnitTest {
|
|||
|
||||
public static FromComment(comment: string, context: Context): UnitTest[] {
|
||||
const imports = ScriptExtraction.extractImports(comment)
|
||||
return ScriptExtraction.extractScripts(comment).map(({script, line, name}, i) =>
|
||||
return ScriptExtraction.extractScripts(comment).map(
|
||||
({script, name}, i) =>
|
||||
new UnitTest(script, {
|
||||
...context,
|
||||
linenumber: (context.linenumber ?? 0) ,
|
||||
|
@ -63,7 +64,7 @@ export default class UnitTest {
|
|||
if (s.tag == 'Statement') {
|
||||
return s.stmt
|
||||
} else {
|
||||
return `__expect(${s.lhs}, "failed at ${this.context.functionname} (${this.context.filepath}:${s.line + (this.context.linenumber ?? 0)}:1)").to.deep.equal(${s.rhs})`
|
||||
return `__expect(${s.lhs}, "failed at ${this.context.functionname} (${this.context.filepath}:${1 + s.line + (this.context.linenumber ?? 0)}:1)").to.deep.equal(${s.rhs})`
|
||||
}
|
||||
})
|
||||
.map(x => '\n ' + x)
|
||||
|
|
Loading…
Add table
Reference in a new issue