Skip to content

Commit

Permalink
Add basic Oniguruma comparison tester
Browse files Browse the repository at this point in the history
  • Loading branch information
slevithan committed Nov 1, 2024
1 parent 2484fe2 commit ce83df9
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 9 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -591,10 +591,10 @@ Notice that nearly every feature below has at least subtle differences from Java
<td align="middle">✅</td>
<td align="middle">✅</td>
<td>
✔ Error for variable-length quantifiers within lookbehind (JS allows)<br>
✔ Error for variable-length quantifiers within lookbehind (allowed in JS)<br>
✔ Allows variable-length top-level alternatives<br>
✔ Allows following quantifier (unlike JS in any mode)<br>
✔ Values captured within min-0 quantified lookbehind remain referenceable (unlike JS)<br>
✔ Values captured within min-0 quantified lookbehind remain referenceable<br>
</td>
</tr>

Expand Down
10 changes: 9 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"build": "npm run bundle:global && npm run bundle:esm && npm run types",
"pretest": "npm run build",
"test": "jasmine",
"compare": "node spec/compare-oniguruma.js",
"prepare": "npm test"
},
"files": [
Expand All @@ -47,6 +48,7 @@
"devDependencies": {
"esbuild": "^0.24.0",
"jasmine": "^5.4.0",
"typescript": "^5.6.3"
"typescript": "^5.6.3",
"vscode-oniguruma": "^2.0.1"
}
}
74 changes: 74 additions & 0 deletions spec/compare-oniguruma.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import {toRegExp} from '../dist/index.mjs';
import {r} from '../src/utils.js';
import {readFileSync} from 'node:fs';
import path from 'node:path';
import oniguruma from 'vscode-oniguruma';

// Help with improving this tester or moving it into Jasmine specs would be very welcome!
// Note: vscode-oniguruma 2.0.1 uses Oniguruma 6.9.8

const tests = [
[r`\Aa`, 'a'],
];

async function compare() {
let numOk = 0;
let numErr = 0;
for (let i = 0; i < tests.length; i++) {
const [pattern, str] = tests[i];
const libMatch = toRegExp(pattern).exec(str);
const onigMatch = await onigurumaExec(pattern, str);
const libValue = libMatch && libMatch[0];
const libIndex = libMatch && libMatch.index;
const onigValue = onigMatch && onigMatch[0];
const onigIndex = onigMatch && onigMatch.index;
if (libValue !== onigValue) {
numErr++;
err(`${i}. Results differ ["${pattern}" with str "${str}"] lib: ${libMatch && `"${libValue}"`}, onig: ${onigMatch && `"${onigValue}"`}`);
} else if (libIndex !== onigIndex) {
numErr++;
err(`${i}. Positions differ ["${pattern}" with str "${str}"] lib: ${libIndex}, onig: ${onigIndex}`);
} else {
numOk++;
ok(`${i}. Results match ["${pattern}" with str "${str}"]`);
}
}
console.log(`\nFinished: ${numOk} OK, ${numErr} error${numErr === 1 ? '' : 's'}`);
}

compare();

async function loadOniguruma() {
const wasmPath = path.join(import.meta.dirname, '..', 'node_modules', 'vscode-oniguruma', 'release', 'onig.wasm');
const wasmBin = readFileSync(wasmPath).buffer;
await oniguruma.loadWASM(wasmBin);
}

async function onigurumaExec(pattern, str) {
await loadOniguruma();
// See https://github.com/microsoft/vscode-oniguruma/blob/main/main.d.ts
const re = new oniguruma.OnigScanner([pattern]);
const match = re.findNextMatchSync(str, 0);
if (!match) {
return null;
}
const m = match.captureIndices[0];
return {
'0': str.slice(m.start, m.end),
index: m.start,
};
}

function err(msg) {
console.log(ansiEscape.red, `❌ ${msg}`, ansiEscape.reset);
}

function ok(msg) {
console.log(ansiEscape.green, `🆗 ${msg}`, ansiEscape.reset);
}

const ansiEscape = {
green: '\x1b[32m',
red: '\x1b[31m',
reset: '\x1b[0m',
};
8 changes: 4 additions & 4 deletions spec/helpers/matchers.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function getArgs(actual, expected) {
};
}

function matchedFullStr(match, str) {
function wasFullStrMatch(match, str) {
return !!match && match.index === 0 && match[0].length === str.length;
}

Expand All @@ -30,12 +30,12 @@ function matchWithAllTargets({pattern, flags, strings, targets}, {exact, negate}
for (const target of targets) {
const re = toRegExp(pattern, flags, {target});
for (const str of strings) {
// In case `flags` included `y`
// In case `flags` includes `g` or `y`
re.lastIndex = 0;
const match = re.exec(str);
const failed = negate ?
((exact && matchedFullStr(match, str)) || (!exact && match)) :
((exact && !matchedFullStr(match, str)) || (!exact && !match));
((exact && wasFullStrMatch(match, str)) || (!exact && match)) :
((exact && !wasFullStrMatch(match, str)) || (!exact && !match));
if (failed) {
return {
pass: false,
Expand Down
2 changes: 1 addition & 1 deletion src/unicode.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ const PosixClassesMap = new Map([
['graph', r`[\P{space}&&\P{cntrl}&&\P{Cn}&&\P{Cs}]`],
['lower', r`\p{Lower}`],
['print', r`[[\P{space}&&\P{cntrl}&&\P{Cn}&&\P{Cs}]\p{Zs}]`],
['punct', r`[\p{P}\p{S}]`],
['punct', r`[\p{P}\p{S}]`], // New value from Oniguruma 6.9.9
['space', r`\p{space}`],
['upper', r`\p{Upper}`],
['word', r`[\p{Alpha}\p{M}\p{Nd}\p{Pc}]`],
Expand Down

0 comments on commit ce83df9

Please sign in to comment.