3
.gitignore
vendido
3
.gitignore
vendido
@@ -60,8 +60,7 @@ tmp/
|
||||
test_*.i2m
|
||||
example_*.i2m
|
||||
*_extracted*
|
||||
*.test.js
|
||||
*.spec.js
|
||||
test/test_*
|
||||
|
||||
# Example generated files
|
||||
examples/risitas_with_chiquito.i2m
|
||||
|
||||
@@ -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
181
test/basic.test.js
Archivo normal
@@ -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();
|
||||
Referencia en una nueva incidencia
Block a user