Skip to content

Commit

Permalink
[bugfix] Executing tests on folder with a space on the name doesn't w…
Browse files Browse the repository at this point in the history
…ork (#893)

On windows it requires escaping,

Based on https://www.robvanderwoude.com/escapechars.php#:~:text=In%20batch%20files%2C%20the%20percent,instead%20of%20being%20further%20interpreted.

Before merging this requires checking that it is correct
  • Loading branch information
alexrecuenco authored Sep 6, 2024
1 parent 572e9cb commit 7e48b9f
Showing 1 changed file with 43 additions and 4 deletions.
47 changes: 43 additions & 4 deletions packages/vscode/test/grammar/test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,40 @@ const grammars = readdirSync(grammarDir)

const allGrammars = [...grammars, ...dummyGrammars];

/**
* Escapes command line arguments for Windows
* @param {string} arg
* @returns {string}
*
* Escaping sequences obtained trusting https://www.robvanderwoude.com/escapechars.php#:~:text=In%20batch%20files%2C%20the%20percent,instead%20of%20being%20further%20interpreted.
*/
function escapeWindowsArg(arg) {
// If the argument doesn't contain spaces or special characters, return it as is
const single_charac_escape = /(['`,;=()<>|&^])/g;
const double_carat_escape = /(!)/g;
const percentage_escape = /(%)/g;
const backlash_escape = /([\\"[\].*?])/g;
if (
![single_charac_escape, double_carat_escape, percentage_escape, backlash_escape].some((regex) =>
regex.test(arg),
)
) {
return arg;
}

// This one must go first, since it would otherwise conflict with the ! rule
arg = arg.replace(single_charac_escape, '^$1');
arg = arg.replace(double_carat_escape, '^^$1');
arg = arg.replace(percentage_escape, '%$1');
arg = arg.replace(backlash_escape, '\\$1');

// Wrap the entire argument in double quotes
return `"${arg}"`;
}

/**
* @param {Parameters<typeof spawn>} arg
* @returns {Promise<number | null>}
*/
function promisifySpawn(...arg) {
const childProcess = spawn(...arg);
Expand All @@ -34,21 +66,28 @@ function promisifySpawn(...arg) {

async function snapShotTest() {
const extraArgs = process.argv.slice(2);
const isWindows = process.platform === 'win32';

const args = [
'vscode-tmgrammar-snap',
'-s',
'source.astro',
'./test/grammar/fixtures/**/*.astro',
...allGrammars.reduce((/** @type string[] */ previous, path) => [...previous, '-g', path], []),
...extraArgs,
];
].map((arg) => {
if (isWindows) return escapeWindowsArg(arg);
return arg;
});

const code = await promisifySpawn(process.platform === 'win32' ? 'pnpm.cmd' : 'pnpm', args, {
const code = await promisifySpawn(isWindows ? 'pnpm.cmd' : 'pnpm', args, {
stdio: 'inherit',
shell: true,
// windows shell escaping on nodejs doesn't work
// See https://github.com/nodejs/node/issues/52554 and https://github.com/withastro/language-tools/pull/893
shell: isWindows,
});

if (code > 0) {
if (code && code > 0) {
process.exit(code);
}
}
Expand Down

0 comments on commit 7e48b9f

Please sign in to comment.