Skip to content

Commit

Permalink
feat: add more extension support (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
dhemeira authored Aug 17, 2023
1 parent c5e60c6 commit d42d4f4
Show file tree
Hide file tree
Showing 26 changed files with 107 additions and 134 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# convert-image

This is a package for converting `.jpg` and `.png` files to `.webp` and/or to resize them to a given width and/or height.
This is a package for converting image files to `.webp` and/or to resize them to a given width and/or height.
The results are placed inside the specified folder.

[![npm](https://img.shields.io/npm/dw/%40dhemeira/convert-image?style=for-the-badge&logo=npm)](https://www.npmjs.com/package/@dhemeira/convert-image)
Expand Down Expand Up @@ -70,7 +70,7 @@ Output:
```
Usage: convert-image [options] <input_directory>
converts .jpg and .png files to .webp or resizes them and puts them into the specified output folder.
Converts image files to .webp or resizes them and puts them into the specified output folder. Supported formats: .jpg, .png, .svg, .tiff, .gif and .webp
Arguments:
input_directory the input directory
Expand Down
9 changes: 8 additions & 1 deletion functions/handleChecks.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@ function isOptionMissingValue(option) {
}

function isSupportedFormat(file) {
return file.includes('.jpg') || file.includes('.png');
return (
file.includes('.jpg') ||
file.includes('.png') ||
file.includes('.svg') ||
file.includes('.tiff') ||
file.includes('.gif') ||
file.includes('.webp')
);
}

function handleDimension(dimension, type) {
Expand Down
11 changes: 10 additions & 1 deletion functions/handleFiles.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,16 @@ function fileConverter(
converting
.webp()
.toFile(
`${path.join(outputDirectory, file.replace('.jpg', '').replace('.png', ''))}.webp`
`${path.join(
outputDirectory,
file
.replace('.jpg', '')
.replace('.png', '')
.replace('.svg', '')
.replace('.tiff', '')
.replace('.gif', '')
.replace('.webp', '')
)}.webp`
);
else converting.toFile(`${path.join(outputDirectory, file)}`);
}
Expand Down
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ try {
program
.name('convert-image')
.description(
'converts .jpg and .png files to .webp or resizes them and puts them into the specified output folder.'
'Converts image files to .webp or resizes them and puts them into the specified output folder. Supported formats: .jpg, .png, .svg, .tiff, .gif and .webp'
)
.argument('<input_directory>', 'the input directory')
.option(
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@dhemeira/convert-image",
"version": "1.4.0",
"description": "An npm package to mass convert .jpg and .png files to .webp or resize them.",
"version": "1.5.0",
"description": "An npm package to mass convert image files to .webp or resize them.",
"main": "index.js",
"scripts": {
"test": "jest",
Expand Down
43 changes: 25 additions & 18 deletions test/fit.spec.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
const del = require('del');
const { existsSync } = require('fs');
const { cli, tmp, createTestFiles } = require('./helpers');
const { cli, tmp, fixtures } = require('./helpers');
const path = require('path');
const { validFiles, invalidFiles } = require('./fixtures');

describe('The convert-image with --output option', () => {
it('should show error when --fit arg missing', async () => {
const sandbox = await tmp();

let result = await cli([sandbox, '--fit'], sandbox);
let result = await cli([fixtures, '--fit'], sandbox);

expect(result.code).toBe(1);

Expand All @@ -20,7 +21,7 @@ describe('The convert-image with --output option', () => {
it('should show error for invalid argument', async () => {
const sandbox = await tmp();

let result = await cli([sandbox, '--fit', 'test'], sandbox);
let result = await cli([fixtures, '--fit', 'test'], sandbox);

expect(result.code).toBe(1);

Expand All @@ -32,57 +33,63 @@ describe('The convert-image with --output option', () => {

it('should resize the images to contain fit', async () => {
const sandbox = await tmp();
let [filenames, foldernames] = createTestFiles(sandbox);

let result = await cli([sandbox, '--fit', 'contain', '--width', '1', '--height', '1'], sandbox);
let result = await cli(
[fixtures, '--output', 'converted', '--fit', 'contain', '--width', '1', '--height', '1'],
sandbox
);

expect(result.code).toBe(0);
expect(existsSync(`${path.join(sandbox, 'converted')}`)).toBe(true);
filenames.forEach((element) => {
validFiles.forEach((element) => {
expect(existsSync(`${path.join(sandbox, 'converted', element)}`)).toBe(true);
});
foldernames.forEach((element) => {
invalidFiles.forEach((element) => {
expect(existsSync(`${path.join(sandbox, 'converted', element)}`)).toBe(false);
});
expect(result.stdout).toContain('Files converted: 8');
expect(result.stdout).toContain('Files converted: 10');

del.sync(sandbox);
});

it('should resize the images to cover fit', async () => {
const sandbox = await tmp();
let [filenames, foldernames] = createTestFiles(sandbox);

let result = await cli([sandbox, '--fit', 'cover', '--width', '1', '--height', '1'], sandbox);
let result = await cli(
[fixtures, '--output', 'converted', '--fit', 'cover', '--width', '1', '--height', '1'],
sandbox
);

expect(result.code).toBe(0);
expect(existsSync(`${path.join(sandbox, 'converted')}`)).toBe(true);
filenames.forEach((element) => {
validFiles.forEach((element) => {
expect(existsSync(`${path.join(sandbox, 'converted', element)}`)).toBe(true);
});
foldernames.forEach((element) => {
invalidFiles.forEach((element) => {
expect(existsSync(`${path.join(sandbox, 'converted', element)}`)).toBe(false);
});
expect(result.stdout).toContain('Files converted: 8');
expect(result.stdout).toContain('Files converted: 10');

del.sync(sandbox);
});

it('should resize the images to fill fit', async () => {
const sandbox = await tmp();
let [filenames, foldernames] = createTestFiles(sandbox);

let result = await cli([sandbox, '--fit', 'fill', '--width', '1', '--height', '1'], sandbox);
let result = await cli(
[fixtures, '--output', 'converted', '--fit', 'fill', '--width', '1', '--height', '1'],
sandbox
);

expect(result.code).toBe(0);
expect(existsSync(`${path.join(sandbox, 'converted')}`)).toBe(true);
filenames.forEach((element) => {
validFiles.forEach((element) => {
expect(existsSync(`${path.join(sandbox, 'converted', element)}`)).toBe(true);
});
foldernames.forEach((element) => {
invalidFiles.forEach((element) => {
expect(existsSync(`${path.join(sandbox, 'converted', element)}`)).toBe(false);
});
expect(result.stdout).toContain('Files converted: 8');
expect(result.stdout).toContain('Files converted: 10');

del.sync(sandbox);
});
Expand Down
Empty file.
Empty file.
Empty file.
15 changes: 15 additions & 0 deletions test/fixtures/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const validFiles = [
'test_image_0.jpg',
'test_image_1.png',
'test_image_2.svg',
'test_image_3.tiff',
'test_image_4.gif',
'test_image_5.webp',
'test_image_6.jpg',
'test_image_7.png',
'test_image_8.gif',
'test_image_9.webp',
];
const invalidFiles = ['folder_1', 'folder_2', 'folder_3', 'index.js', 'test_text_1.txt'];

module.exports = { validFiles, invalidFiles };
Binary file added test/fixtures/test_image_0.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/fixtures/test_image_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/fixtures/test_image_2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/fixtures/test_image_3.tiff
Binary file not shown.
Binary file added test/fixtures/test_image_4.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/fixtures/test_image_5.webp
Binary file not shown.
Binary file added test/fixtures/test_image_6.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/fixtures/test_image_7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/fixtures/test_image_8.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/fixtures/test_image_9.webp
Binary file not shown.
1 change: 1 addition & 0 deletions test/fixtures/test_text_1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
These are the fixtures used to test the image processing.
51 changes: 2 additions & 49 deletions test/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ const path = require('path');
const exec = require('child_process').exec;
const uuid = require('uuid').v4;
const mkdirp = require('mkdirp');
const { writeFile } = require('fs');

const SANDBOX = path.resolve('./test/sandbox/');
const fixtures = path.resolve('./test/fixtures/');

function cli(args, cwd) {
return new Promise((resolve) => {
Expand All @@ -26,51 +26,4 @@ async function tmp(ext) {
return _path;
}

function createImage(text = 'Test image') {
const { createCanvas } = require('canvas');
const canvas = createCanvas(500, 500);
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, 500, 500);

ctx.font = '30px Sans';

ctx.fillStyle = 'black';

let textString = text,
textWidth = ctx.measureText(textString).width;
ctx.fillText(textString, canvas.width / 2 - textWidth / 2, canvas.width / 2);

return canvas.toDataURL();
}

function writeImage(sandbox, img, ext, file_name = 'test_image') {
//https://stackoverflow.com/questions/43487543/writing-binary-data-using-node-js-fs-writefile-to-create-an-image-file
var data = img.replace(/^data:image\/\w+;base64,/, '');
var buf = Buffer.from(data, 'base64');
writeFile(`${path.join(sandbox, file_name)}.${ext}`, buf, function (err) {
if (err) throw err;
});
return `${file_name}.${ext}`;
}

function createTestFiles(sandbox) {
let filenames = [];
let foldernames = [];
for (let index = 0; index < 10; index++) {
if (index % 2 == 0)
filenames.push(
writeImage(sandbox, createImage(`Test image ${index}`), 'jpg', `test_image_${index}`)
);
else if (index % 3 == 0) {
mkdirp.mkdirp(path.join(sandbox, `folder_${index}`));
foldernames.push(`folder_${index}`);
} else
filenames.push(
writeImage(sandbox, createImage(`Test image ${index}`), 'png', `test_image_${index}`)
);
}
return [filenames, foldernames];
}

module.exports = { cli, tmp, createImage, writeImage, createTestFiles };
module.exports = { cli, tmp, fixtures };
18 changes: 10 additions & 8 deletions test/only.spec.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
const del = require('del');
const { existsSync } = require('fs');
const { cli, tmp, createTestFiles } = require('./helpers');
const { cli, tmp, fixtures } = require('./helpers');
const path = require('path');
const { invalidFiles } = require('./fixtures');

describe('The convert-image with --only option', () => {
it('should show error when --only arg missing', async () => {
const sandbox = await tmp();

let result = await cli([sandbox, '--only'], sandbox);
let result = await cli([fixtures, '--only'], sandbox);

expect(result.code).toBe(1);

Expand All @@ -19,11 +20,10 @@ describe('The convert-image with --only option', () => {

it('should only convert 1 image', async () => {
const sandbox = await tmp();
let foldernames = createTestFiles(sandbox)[1];

let result = await cli(
[
sandbox,
fixtures,
'--output',
'test_folder',
'-w',
Expand All @@ -39,8 +39,9 @@ describe('The convert-image with --only option', () => {

expect(result.code).toBe(0);
expect(existsSync(`${path.join(sandbox, 'test_folder')}`)).toBe(true);
expect(existsSync(`${path.join(sandbox, 'test_folder', 'test_image_0.webp')}`)).toBe(true);

foldernames.forEach((element) => {
invalidFiles.forEach((element) => {
expect(existsSync(`${path.join(sandbox, 'test_folder', element)}`)).toBe(false);
});
expect(result.stdout).toContain('Files converted: 1');
Expand All @@ -50,11 +51,10 @@ describe('The convert-image with --only option', () => {

it('should only convert 2 images', async () => {
const sandbox = await tmp();
let foldernames = createTestFiles(sandbox)[1];

let result = await cli(
[
sandbox,
fixtures,
'--output',
'test_folder',
'-w',
Expand All @@ -71,8 +71,10 @@ describe('The convert-image with --only option', () => {

expect(result.code).toBe(0);
expect(existsSync(`${path.join(sandbox, 'test_folder')}`)).toBe(true);
expect(existsSync(`${path.join(sandbox, 'test_folder', 'test_image_0.webp')}`)).toBe(true);
expect(existsSync(`${path.join(sandbox, 'test_folder', 'test_image_1.webp')}`)).toBe(true);

foldernames.forEach((element) => {
invalidFiles.forEach((element) => {
expect(existsSync(`${path.join(sandbox, 'test_folder', element)}`)).toBe(false);
});
expect(result.stdout).toContain('Files converted: 2');
Expand Down
33 changes: 7 additions & 26 deletions test/output.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const del = require('del');
const { existsSync } = require('fs');
const { cli, tmp, createTestFiles } = require('./helpers');
const { cli, tmp, fixtures } = require('./helpers');
const path = require('path');
const { validFiles, invalidFiles } = require('./fixtures');

describe('The convert-image with --output option', () => {
it('should show error when <input_directory> arg missing', async () => {
Expand All @@ -20,7 +21,7 @@ describe('The convert-image with --output option', () => {
it('should show error when --output arg missing', async () => {
const sandbox = await tmp();

let result = await cli([sandbox, '--output'], sandbox);
let result = await cli([fixtures, '--output'], sandbox);

expect(result.code).toBe(1);

Expand All @@ -42,43 +43,23 @@ describe('The convert-image with --output option', () => {
del.sync(sandbox);
});

it('should copy images to converted folder', async () => {
const sandbox = await tmp();
let [filenames, foldernames] = createTestFiles(sandbox);

let result = await cli([sandbox, '--width', '1', '--height', '1'], sandbox);

expect(result.code).toBe(0);
expect(existsSync(`${path.join(sandbox, 'converted')}`)).toBe(true);
filenames.forEach((element) => {
expect(existsSync(`${path.join(sandbox, 'converted', element)}`)).toBe(true);
});
foldernames.forEach((element) => {
expect(existsSync(`${path.join(sandbox, 'converted', element)}`)).toBe(false);
});
expect(result.stdout).toContain('Files converted: 8');

del.sync(sandbox);
});

it('should copy images to test_folder folder', async () => {
const sandbox = await tmp();
let [filenames, foldernames] = createTestFiles(sandbox);

let result = await cli(
[sandbox, '--output', 'test_folder', '--width', '1', '--height', '1'],
[fixtures, '--output', 'test_folder', '--width', '1', '--height', '1'],
sandbox
);

expect(result.code).toBe(0);
expect(existsSync(`${path.join(sandbox, 'test_folder')}`)).toBe(true);
filenames.forEach((element) => {
validFiles.forEach((element) => {
expect(existsSync(`${path.join(sandbox, 'test_folder', element)}`)).toBe(true);
});
foldernames.forEach((element) => {
invalidFiles.forEach((element) => {
expect(existsSync(`${path.join(sandbox, 'test_folder', element)}`)).toBe(false);
});
expect(result.stdout).toContain('Files converted: 8');
expect(result.stdout).toContain('Files converted: 10');

del.sync(sandbox);
});
Expand Down
Loading

0 comments on commit d42d4f4

Please sign in to comment.