mirror of
https://github.com/svg/svgo.git
synced 2025-07-31 07:44:22 +03:00
Refactor basic cli tests (#1595)
Moved some tests to cli.test.js and got rid from mock-stdin dependency.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -10,6 +10,7 @@ node_modules
|
|||||||
dist
|
dist
|
||||||
test/regression-fixtures
|
test/regression-fixtures
|
||||||
test/regression-diffs
|
test/regression-diffs
|
||||||
|
test/cli/output
|
||||||
coverage
|
coverage
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*.log
|
*.log
|
||||||
|
@ -118,7 +118,6 @@
|
|||||||
"del": "^6.0.0",
|
"del": "^6.0.0",
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^7.32.0",
|
||||||
"jest": "^27.2.5",
|
"jest": "^27.2.5",
|
||||||
"mock-stdin": "^1.0.0",
|
|
||||||
"node-fetch": "^2.6.2",
|
"node-fetch": "^2.6.2",
|
||||||
"pixelmatch": "^5.2.1",
|
"pixelmatch": "^5.2.1",
|
||||||
"playwright": "^1.14.1",
|
"playwright": "^1.14.1",
|
||||||
|
@ -1,7 +1,90 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {import('child_process').ChildProcessWithoutNullStreams} ChildProcessWithoutNullStreams
|
||||||
|
*/
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
const { spawn } = require('child_process');
|
const { spawn } = require('child_process');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {(proc: ChildProcessWithoutNullStreams) => Promise<string>}
|
||||||
|
*/
|
||||||
|
const waitStdout = (proc) => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
proc.stdout.on('data', (data) => {
|
||||||
|
resolve(data.toString());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {(proc: ChildProcessWithoutNullStreams) => Promise<void>}
|
||||||
|
*/
|
||||||
|
const waitClose = (proc) => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
proc.on('close', () => {
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
test('shows plugins when flag specified', async () => {
|
||||||
|
const proc = spawn(
|
||||||
|
'node',
|
||||||
|
['../../bin/svgo', '--no-color', '--show-plugins'],
|
||||||
|
{ cwd: __dirname }
|
||||||
|
);
|
||||||
|
const stdout = await waitStdout(proc);
|
||||||
|
expect(stdout).toMatch(/Currently available plugins:/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('accepts svg as input stream', async () => {
|
||||||
|
const proc = spawn('node', ['../../bin/svgo', '--no-color', '-'], {
|
||||||
|
cwd: __dirname,
|
||||||
|
});
|
||||||
|
proc.stdin.write('<svg><title>stdin</title></svg>');
|
||||||
|
proc.stdin.end();
|
||||||
|
const stdout = await waitStdout(proc);
|
||||||
|
expect(stdout).toEqual('<svg/>\n');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('accepts svg as string', async () => {
|
||||||
|
const input = '<svg><title>string</title></svg>';
|
||||||
|
const proc = spawn(
|
||||||
|
'node',
|
||||||
|
['../../bin/svgo', '--no-color', '--string', input],
|
||||||
|
{ cwd: __dirname }
|
||||||
|
);
|
||||||
|
const stdout = await waitStdout(proc);
|
||||||
|
expect(stdout).toEqual('<svg/>\n');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('accepts svg as filename', async () => {
|
||||||
|
const proc = spawn(
|
||||||
|
'node',
|
||||||
|
['../../bin/svgo', '--no-color', 'single.svg', '-o', 'output/single.svg'],
|
||||||
|
{ cwd: __dirname }
|
||||||
|
);
|
||||||
|
await waitClose(proc);
|
||||||
|
const output = fs.readFileSync(
|
||||||
|
path.join(__dirname, 'output/single.svg'),
|
||||||
|
'utf-8'
|
||||||
|
);
|
||||||
|
expect(output).toEqual('<svg/>');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('output as stream when "-" is specified', async () => {
|
||||||
|
const proc = spawn(
|
||||||
|
'node',
|
||||||
|
['../../bin/svgo', '--no-color', 'single.svg', '-o', '-'],
|
||||||
|
{ cwd: __dirname }
|
||||||
|
);
|
||||||
|
const stdout = await waitStdout(proc);
|
||||||
|
expect(stdout).toEqual('<svg/>\n');
|
||||||
|
});
|
||||||
|
|
||||||
test('should exit with 1 code on syntax error', async () => {
|
test('should exit with 1 code on syntax error', async () => {
|
||||||
const proc = spawn('node', ['../../bin/svgo', '--no-color', 'invalid.svg'], {
|
const proc = spawn('node', ['../../bin/svgo', '--no-color', 'invalid.svg'], {
|
||||||
cwd: __dirname,
|
cwd: __dirname,
|
||||||
|
1
test/cli/single.svg
Normal file
1
test/cli/single.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg><title>input</title></svg>
|
After Width: | Height: | Size: 32 B |
@ -6,7 +6,6 @@ const del = require('del');
|
|||||||
const { Command } = require('commander');
|
const { Command } = require('commander');
|
||||||
const svgo = require('../../lib/svgo/coa.js');
|
const svgo = require('../../lib/svgo/coa.js');
|
||||||
|
|
||||||
const svgPath = path.resolve(__dirname, 'test.svg');
|
|
||||||
const svgFolderPath = path.resolve(__dirname, 'testSvg');
|
const svgFolderPath = path.resolve(__dirname, 'testSvg');
|
||||||
const svgFolderPathRecursively = path.resolve(__dirname, 'testSvgRecursively');
|
const svgFolderPathRecursively = path.resolve(__dirname, 'testSvgRecursively');
|
||||||
const svgFiles = [
|
const svgFiles = [
|
||||||
@ -28,10 +27,7 @@ function runProgram(args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe('coa', function () {
|
describe('coa', function () {
|
||||||
let output;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
output = '';
|
|
||||||
await del(tempFolder);
|
await del(tempFolder);
|
||||||
await fs.promises.mkdir(tempFolder);
|
await fs.promises.mkdir(tempFolder);
|
||||||
});
|
});
|
||||||
@ -40,25 +36,10 @@ describe('coa', function () {
|
|||||||
await del(tempFolder);
|
await del(tempFolder);
|
||||||
});
|
});
|
||||||
|
|
||||||
const initialConsoleLog = global.console.log;
|
|
||||||
|
|
||||||
function replaceConsoleLog() {
|
|
||||||
global.console.log = (message) => {
|
|
||||||
output += message;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function restoreConsoleLog() {
|
|
||||||
global.console.log = initialConsoleLog;
|
|
||||||
}
|
|
||||||
|
|
||||||
const initialConsoleError = global.console.error;
|
const initialConsoleError = global.console.error;
|
||||||
const initialProcessExit = global.process.exit;
|
const initialProcessExit = global.process.exit;
|
||||||
|
|
||||||
function replaceConsoleError() {
|
function replaceConsoleError() {
|
||||||
global.console.error = (message) => {
|
|
||||||
output += message;
|
|
||||||
};
|
|
||||||
global.process.exit = noop;
|
global.process.exit = noop;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,17 +64,6 @@ describe('coa', function () {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should work properly with string input', async () => {
|
|
||||||
await runProgram([
|
|
||||||
'--string',
|
|
||||||
fs.readFileSync(svgPath, 'utf8'),
|
|
||||||
'--output',
|
|
||||||
'temp.svg',
|
|
||||||
'--quiet',
|
|
||||||
]);
|
|
||||||
await del('temp.svg');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should optimize folder', async () => {
|
it('should optimize folder', async () => {
|
||||||
const initWeight = calcFolderSvgWeight(svgFolderPath);
|
const initWeight = calcFolderSvgWeight(svgFolderPath);
|
||||||
await runProgram([
|
await runProgram([
|
||||||
@ -123,16 +93,6 @@ describe('coa', function () {
|
|||||||
expect(initWeight).toBeLessThanOrEqual(optimizedWeight);
|
expect(initWeight).toBeLessThanOrEqual(optimizedWeight);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should optimize file', async () => {
|
|
||||||
const initialFileLength = fs.readFileSync(
|
|
||||||
path.resolve(__dirname, 'test.svg')
|
|
||||||
).length;
|
|
||||||
await runProgram(['--input', svgPath, '--output', 'temp.svg', '--quiet']);
|
|
||||||
const optimizedFileLength = fs.readFileSync('temp.svg').length;
|
|
||||||
expect(optimizedFileLength).toBeLessThanOrEqual(initialFileLength);
|
|
||||||
await del('temp.svg');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should optimize several files', async () => {
|
it('should optimize several files', async () => {
|
||||||
const initWeight = calcFolderSvgWeight(svgFolderPath);
|
const initWeight = calcFolderSvgWeight(svgFolderPath);
|
||||||
await runProgram([
|
await runProgram([
|
||||||
@ -148,29 +108,6 @@ describe('coa', function () {
|
|||||||
await del('temp.svg');
|
await del('temp.svg');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should optimize file from process.stdin', async () => {
|
|
||||||
const initialFile = fs.readFileSync(path.resolve(__dirname, 'test.svg'));
|
|
||||||
const stdin = require('mock-stdin').stdin();
|
|
||||||
setTimeout(() => {
|
|
||||||
stdin.send(initialFile, 'ascii').end();
|
|
||||||
}, 1000);
|
|
||||||
try {
|
|
||||||
await runProgram([
|
|
||||||
'--input',
|
|
||||||
'-',
|
|
||||||
'--output',
|
|
||||||
'temp.svg',
|
|
||||||
'--string',
|
|
||||||
fs.readFileSync(svgPath, 'utf8'),
|
|
||||||
'--quiet',
|
|
||||||
]);
|
|
||||||
} finally {
|
|
||||||
const optimizedFileLength = fs.readFileSync('temp.svg').length;
|
|
||||||
expect(optimizedFileLength).toBeLessThanOrEqual(initialFile.length);
|
|
||||||
await del('temp.svg');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should optimize folder, when it stated in input', async () => {
|
it('should optimize folder, when it stated in input', async () => {
|
||||||
const initWeight = calcFolderSvgWeight(svgFolderPath);
|
const initWeight = calcFolderSvgWeight(svgFolderPath);
|
||||||
await runProgram([
|
await runProgram([
|
||||||
@ -200,23 +137,6 @@ describe('coa', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('stdout', () => {
|
describe('stdout', () => {
|
||||||
it('should show file content when no output set', async () => {
|
|
||||||
replaceConsoleLog();
|
|
||||||
try {
|
|
||||||
await runProgram([
|
|
||||||
'--string',
|
|
||||||
fs.readFileSync(svgPath, 'utf8'),
|
|
||||||
'--output',
|
|
||||||
'-',
|
|
||||||
'--datauri',
|
|
||||||
'unenc',
|
|
||||||
]);
|
|
||||||
} finally {
|
|
||||||
restoreConsoleLog();
|
|
||||||
expect(output).toMatch(/www\.w3\.org\/2000\/svg/);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should show message when the folder is empty', async () => {
|
it('should show message when the folder is empty', async () => {
|
||||||
const emptyFolderPath = path.resolve(__dirname, 'testSvgEmpty');
|
const emptyFolderPath = path.resolve(__dirname, 'testSvgEmpty');
|
||||||
if (!fs.existsSync(emptyFolderPath)) {
|
if (!fs.existsSync(emptyFolderPath)) {
|
||||||
@ -240,15 +160,5 @@ describe('coa', function () {
|
|||||||
expect(error.message).toMatch(/No SVG files have been found/);
|
expect(error.message).toMatch(/No SVG files have been found/);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show plugins', async () => {
|
|
||||||
replaceConsoleLog();
|
|
||||||
try {
|
|
||||||
await runProgram(['--show-plugins']);
|
|
||||||
} finally {
|
|
||||||
restoreConsoleLog();
|
|
||||||
expect(output).toMatch(/Currently available plugins:/);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 23 KiB |
@ -3790,13 +3790,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"mock-stdin@npm:^1.0.0":
|
|
||||||
version: 1.0.0
|
|
||||||
resolution: "mock-stdin@npm:1.0.0"
|
|
||||||
checksum: 34d2affa0607813130118a62540c33c0d121f9d5bcdbaf1e2dde3dc91eb899b0e803221a591acdc4950b85271f5c04994efcead3631e63f19d04b4fb3d1e2da4
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"ms@npm:2.1.2":
|
"ms@npm:2.1.2":
|
||||||
version: 2.1.2
|
version: 2.1.2
|
||||||
resolution: "ms@npm:2.1.2"
|
resolution: "ms@npm:2.1.2"
|
||||||
@ -4829,7 +4822,6 @@ __metadata:
|
|||||||
del: ^6.0.0
|
del: ^6.0.0
|
||||||
eslint: ^7.32.0
|
eslint: ^7.32.0
|
||||||
jest: ^27.2.5
|
jest: ^27.2.5
|
||||||
mock-stdin: ^1.0.0
|
|
||||||
node-fetch: ^2.6.2
|
node-fetch: ^2.6.2
|
||||||
picocolors: ^1.0.0
|
picocolors: ^1.0.0
|
||||||
pixelmatch: ^5.2.1
|
pixelmatch: ^5.2.1
|
||||||
|
Reference in New Issue
Block a user