| 33 | }; |
| 34 | |
| 35 | export function loadTestFile(root: string, relFile: string): LoadResult { |
| 36 | const problems: Problem[] = []; |
| 37 | const errors: LoadResult['errors'] = []; |
| 38 | const lines = fs |
| 39 | .readFileSync(path.join(root, relFile), 'utf8') |
| 40 | .split('\n'); |
| 41 | let index = 0; |
| 42 | for (let i = 0; i < lines.length; i++) { |
| 43 | const line = lines[i].trim(); |
| 44 | if (!line.startsWith('{')) continue; |
| 45 | index++; |
| 46 | try { |
| 47 | const parsed = parseWL(line); |
| 48 | if (!Array.isArray(parsed) || parsed[0] !== 'List' || parsed.length < 5) |
| 49 | throw new Error('not a 4-element problem list'); |
| 50 | const [, integrand, variable, steps, antiderivative, ...alternates] = |
| 51 | parsed as Json[]; |
| 52 | if (typeof variable !== 'string') |
| 53 | throw new Error('non-symbol integration variable'); |
| 54 | problems.push({ |
| 55 | file: relFile, |
| 56 | index, |
| 57 | source: line, |
| 58 | integrand, |
| 59 | variable, |
| 60 | steps: typeof steps === 'number' ? steps : NaN, |
| 61 | antiderivative, |
| 62 | alternates, |
| 63 | }); |
| 64 | } catch (e) { |
| 65 | errors.push({ file: relFile, line: i + 1, error: String(e) }); |
| 66 | } |
| 67 | } |
| 68 | return { problems, errors }; |
| 69 | } |
| 70 | |
| 71 | /** Recursively list test-suite `.m` files under `root/subdir`. */ |
| 72 | export function listTestFiles(root: string, subdir = ''): string[] { |