Signed-off-by: ale <ale@manalejandro.com>
Este commit está contenido en:
ale
2025-09-06 19:38:51 +02:00
padre 4c62e5032f
commit b7d0552533
Se han modificado 3 ficheros con 185 adiciones y 5 borrados

3
.gitignore vendido
Ver fichero

@@ -60,8 +60,7 @@ tmp/
test_*.i2m
example_*.i2m
*_extracted*
*.test.js
*.spec.js
test/test_*
# Example generated files
examples/risitas_with_chiquito.i2m

Ver fichero

@@ -5,11 +5,11 @@
"main": "src/index.js",
"types": "index.d.ts",
"bin": {
"img2mp3": "./bin/cli.js"
"img2mp3": "bin/cli.js"
},
"scripts": {
"start": "node src/index.js",
"test": "echo \"Error: no test specified\" && exit 1",
"test": "node test/basic.test.js",
"prepublishOnly": "npm run test",
"example": "node examples/basic_usage.js"
},
@@ -41,7 +41,7 @@
},
"repository": {
"type": "git",
"url": "https://github.com/ale/img2mp3.git"
"url": "git+https://github.com/ale/img2mp3.git"
},
"bugs": {
"url": "https://github.com/ale/img2mp3/issues"

181
test/basic.test.js Archivo normal
Ver fichero

@@ -0,0 +1,181 @@
const assert = require('assert');
const fs = require('fs');
const path = require('path');
const { IMG2MP3, MP3ImageEncoder, I2MPlayer } = require('../src/index');
// Test files paths
const testImagePath = path.join(__dirname, '..', 'examples', 'risitas.jpg');
const testMp3Path = path.join(__dirname, '..', 'examples', 'chiquito-cobarde.mp3');
const testOutputPath = path.join(__dirname, 'test_output.i2m');
const testExtractedImagePath = path.join(__dirname, 'test_extracted_image.png');
const testExtractedMp3Path = path.join(__dirname, 'test_extracted.mp3');
console.log('🧪 Running IMG2MP3 Test Suite...\n');
async function runAllTests() {
const img2mp3 = new IMG2MP3();
let testsPassed = 0;
let totalTests = 0;
function test(name, testFn) {
totalTests++;
try {
return Promise.resolve(testFn()).then(() => {
console.log(`${name}`);
testsPassed++;
});
} catch (error) {
console.error(`${name}: ${error.message}`);
throw error;
}
}
try {
// Test 1: Class Instantiation
await test('IMG2MP3 class instantiation', () => {
assert(img2mp3 instanceof IMG2MP3, 'Should create IMG2MP3 instance');
});
await test('MP3ImageEncoder class instantiation', () => {
const encoder = new MP3ImageEncoder();
assert(encoder instanceof MP3ImageEncoder, 'Should create MP3ImageEncoder instance');
});
await test('I2MPlayer class instantiation', () => {
const player = new I2MPlayer();
assert(player instanceof I2MPlayer, 'Should create I2MPlayer instance');
});
// Test 2: File Validation
await test('Test files existence', () => {
assert(fs.existsSync(testImagePath), 'Test image file should exist');
assert(fs.existsSync(testMp3Path), 'Test MP3 file should exist');
});
// Test 3: Encoding
await test('MP3 encoding into image', async () => {
const result = await img2mp3.encode(testImagePath, testMp3Path, testOutputPath);
assert(result.success === true, 'Encoding should be successful');
assert(typeof result.originalImageSize === 'number', 'Should return original image size');
assert(typeof result.mp3Size === 'number', 'Should return MP3 size');
assert(typeof result.outputSize === 'number', 'Should return output size');
assert(typeof result.imageSize === 'string', 'Should return image dimensions');
assert(fs.existsSync(testOutputPath), 'Output .i2m file should be created');
});
// Test 4: File Information
await test('Get .i2m file information', async () => {
const info = await img2mp3.getInfo(testOutputPath);
assert(info.isValid === true, 'File should be valid');
assert(typeof info.mp3Size === 'number', 'Should return MP3 size');
assert(typeof info.originalImageSize === 'number', 'Should return original image size');
assert(typeof info.containerSize === 'number', 'Should return container size');
assert(typeof info.format === 'string', 'Should return format');
assert(typeof info.dimensions === 'string', 'Should return dimensions');
});
// Test 5: Invalid file handling
await test('Invalid file detection', async () => {
const info = await img2mp3.getInfo(testImagePath);
assert(info.isValid === false, 'Non-.i2m file should be invalid');
assert(typeof info.error === 'string', 'Should return error message');
});
// Test 6: Decoding
await test('.i2m file decoding', async () => {
const result = await img2mp3.decode(testOutputPath, testExtractedImagePath, testExtractedMp3Path);
assert(result.success === true, 'Decoding should be successful');
assert(typeof result.extractedImageSize === 'number', 'Should return extracted image size');
assert(typeof result.extractedMp3Size === 'number', 'Should return extracted MP3 size');
assert(fs.existsSync(testExtractedImagePath), 'Extracted image should exist');
assert(fs.existsSync(testExtractedMp3Path), 'Extracted MP3 should exist');
});
// Test 7: File integrity
await test('File size preservation', () => {
const originalImageSize = fs.statSync(testImagePath).size;
const originalMp3Size = fs.statSync(testMp3Path).size;
const extractedImageSize = fs.statSync(testExtractedImagePath).size;
const extractedMp3Size = fs.statSync(testExtractedMp3Path).size;
assert(originalImageSize === extractedImageSize, 'Image size should be preserved');
assert(originalMp3Size === extractedMp3Size, 'MP3 size should be preserved');
});
// Test 8: Player status
await test('Player status check', () => {
const status = img2mp3.getPlaybackStatus();
assert(typeof status.isPlaying === 'boolean', 'Should return playing status');
assert(typeof status.hasActiveProcess === 'boolean', 'Should return process status');
});
// Test 9: Stop function
await test('Stop playback function', () => {
// This should not throw an error even if nothing is playing
assert.doesNotThrow(() => {
img2mp3.stop();
}, 'Stop function should not throw error');
});
// Test 10: Convenience functions
await test('Convenience functions export', () => {
const { encode, decode, getInfo, play } = require('../src/index');
assert(typeof encode === 'function', 'Should export encode function');
assert(typeof decode === 'function', 'Should export decode function');
assert(typeof getInfo === 'function', 'Should export getInfo function');
assert(typeof play === 'function', 'Should export play function');
});
// Test 11: Error handling for non-existent files
await test('Error handling for missing files', async () => {
try {
await img2mp3.encode('nonexistent.jpg', testMp3Path, 'test.i2m');
assert.fail('Should have thrown an error for missing image file');
} catch (error) {
assert(error.message.includes('ENOENT') || error.message.includes('not found'),
'Should throw file not found error');
}
try {
await img2mp3.encode(testImagePath, 'nonexistent.mp3', 'test.i2m');
assert.fail('Should have thrown an error for missing MP3 file');
} catch (error) {
assert(error.message.includes('ENOENT') || error.message.includes('not found'),
'Should throw file not found error');
}
});
console.log(`\n🎉 All tests passed! (${testsPassed}/${totalTests})`);
console.log('✅ IMG2MP3 is ready for publication');
} catch (error) {
console.error(`\n❌ Test failed: ${error.message}`);
console.log(`📊 Tests passed: ${testsPassed}/${totalTests}`);
process.exit(1);
} finally {
// Cleanup test files
const filesToClean = [
testOutputPath,
testExtractedImagePath,
testExtractedMp3Path
];
filesToClean.forEach(file => {
try {
if (fs.existsSync(file)) {
fs.unlinkSync(file);
}
} catch (error) {
console.warn(`Warning: Could not delete ${file}`);
}
});
img2mp3.cleanup();
}
}
// Run all tests
runAllTests();