UNPKG

string-looks-like

Version:

An assert function that is used to compare multiline string. Support placeholders.

102 lines (90 loc) 2.45 kB
const {AssertionError} = require("assert"); const {codeFrameColumns} = require("@babel/code-frame"); const stringPos = require("string-pos"); const matchers = [ matchWhitespace, matchPlacehold, matchToken ]; function looksLike(actual, expect) { let i = 0, j = 0; const output = []; while (i < actual.length && j < expect.length) { let match; for (const test of matchers) { match = test(expect, j); if (!match) continue; j = match.lastIndex; i = match.eat(actual, i); if (match.output) { output.push(match.output()); } break; } if (!match) { throw new Error(`no matcher found\n\n${drawFrame(expect, j)}`); } } return output; } function drawFrame(s, index) { const loc = stringPos(s, index); loc.column++; return codeFrameColumns(s, {start: loc}); } function matchWhitespace(input, index) { const rx = /\s+/y; rx.lastIndex = index; const match = rx.exec(input); if (!match) { return; } return {eat, lastIndex: rx.lastIndex}; function eat(s, index) { rx.lastIndex = index; const match = rx.exec(s); return match ? rx.lastIndex : index; } } function matchToken(input, index) { const rx = /\d+|\w+|./y; rx.lastIndex = index; const match = rx.exec(input); if (!match) { return; } return {eat, lastIndex: rx.lastIndex}; function eat(s, index) { if (s.slice(index, index + match[0].length) === match[0]) { return index + match[0].length; } throw new AssertionError({ message: `Expect '${match[0]}' at pos ${index}\n\n${drawFrame(s, index)}`, stackStartFn: looksLike }); } } function matchPlacehold(input, index) { const rx = /\{\{([\s\S]+?)\}\}/y; rx.lastIndex = index; const match = rx.exec(input); if (!match) { return; } const pattern = new RegExp(match[1].trim(), "y"); let matchObj; return {eat, lastIndex: rx.lastIndex, output: () => matchObj}; function eat(s, index) { pattern.lastIndex = index; const match = pattern.exec(s); if (match) { matchObj = 1 in match ? match : match[0]; return pattern.lastIndex; } throw new AssertionError({ message: `Expect ${pattern.source} at pos ${index}\n\n${drawFrame(s, index)}`, stackStartFn: looksLike }); } } module.exports = {looksLike};