Files
loongyan/test/unit/util/vips_test.dart
lzw-723 4886951e6f
Some checks failed
Dart CI / build (push) Failing after 10s
格式化代码
2026-04-04 14:40:16 +08:00

191 lines
6.3 KiB
Dart

import 'dart:io';
import 'package:path/path.dart' as p;
import 'package:test/test.dart';
import '../../../bin/util/vips.dart';
void main() {
late Directory tempDir;
late Directory cacheDir;
setUp(() async {
tempDir = await Directory.systemTemp.createTemp('vips_test_');
cacheDir = await Directory.systemTemp.createTemp('vips_cache_');
});
tearDown(() async {
if (await tempDir.exists()) {
await tempDir.delete(recursive: true);
}
if (await cacheDir.exists()) {
await cacheDir.delete(recursive: true);
}
});
group('Vips', () {
test('should construct with required parameters', () {
final v = Vips(cacheDir: '/some/cache/path');
expect(v.cacheDir, '/some/cache/path');
expect(v.vipsExecuteFile, isNull);
});
test('should construct with custom vips executable', () {
final v = Vips(
vipsExecuteFile: '/custom/path/vips',
cacheDir: '/some/cache/path',
);
expect(v.vipsExecuteFile, '/custom/path/vips');
expect(v.cacheDir, '/some/cache/path');
});
});
group('generatePreview', () {
test('should throw when source file does not exist', () async {
final v = Vips(cacheDir: cacheDir.path);
expect(
() => v.generatePreview('/nonexistent/file.jpg'),
throwsA(isA<Exception>()),
);
});
test('should throw when vips is not installed', () async {
final v = Vips(cacheDir: cacheDir.path);
// Create a dummy file but vips likely isn't installed in test env
final dummyFile = File(p.join(tempDir.path, 'dummy.jpg'));
dummyFile.writeAsBytesSync(List.filled(100, 0));
expect(
() => v.generatePreview(dummyFile.path),
throwsA(isA<Exception>()),
);
});
test('should create cache directory if it does not exist', () async {
final customCacheDir = p.join(tempDir.path, 'new_cache');
final previewDirPath = p.join(customCacheDir, 'preview');
final v = Vips(cacheDir: customCacheDir);
final dummyFile = File(p.join(tempDir.path, 'test.png'));
dummyFile.writeAsBytesSync(List.filled(100, 0));
// This will likely fail due to missing vips, but we verify
// the cache directory creation attempt happens before the process call
try {
await v.generatePreview(dummyFile.path);
} catch (_) {
// Expected - vips not installed
}
// The preview subdirectory should have been created
expect(Directory(previewDirPath).existsSync(), isTrue);
});
});
group('caching behavior', () {
test('should return cached file when it already exists', () async {
final v = Vips(cacheDir: cacheDir.path);
// Create source file
final sourceFile = File(p.join(tempDir.path, 'test_image.jpg'));
sourceFile.writeAsBytesSync(List.filled(100, 0));
// Pre-create the expected cached file
final baseName = sourceFile.path.hashCode.toString();
final cachedFile = File(
p.join(cacheDir.path, 'preview', '${baseName}_100x100.webp'),
);
cachedFile.parent.createSync(recursive: true);
cachedFile.writeAsBytesSync([0x52, 0x49, 0x46, 0x46]); // RIFF header
// Now call generatePreview - it should return the cached file
final result = await v.generatePreview(sourceFile.path, w: 100, h: 100);
expect(p.normalize(result.path), p.normalize(cachedFile.path));
expect(result.existsSync(), isTrue);
});
test('should not call vips when cache hit', () async {
final v = Vips(cacheDir: cacheDir.path);
// Create source file
final sourceFile = File(p.join(tempDir.path, 'cached.jpg'));
sourceFile.writeAsBytesSync(List.filled(100, 0));
// Create the expected cached file
final baseName = sourceFile.path.hashCode.toString();
final cachedFile = File(
p.join(cacheDir.path, 'preview', '${baseName}_200x100.webp'),
);
cachedFile.parent.createSync(recursive: true);
cachedFile.writeAsBytesSync([0x01, 0x02, 0x03]);
final result = await v.generatePreview(sourceFile.path, w: 200, h: 100);
// Should return the cached file without calling vips
expect(p.normalize(result.path), p.normalize(cachedFile.path));
expect(result.existsSync(), isTrue);
});
test(
'should use correct cache filename format for different sizes',
() async {
final v = Vips(cacheDir: cacheDir.path);
// Create source file
final sourceFile = File(p.join(tempDir.path, 'sizing.jpg'));
sourceFile.writeAsBytesSync(List.filled(100, 0));
// Create cached file for 400x300
final baseName = sourceFile.path.hashCode.toString();
final cachedFile = File(
p.join(cacheDir.path, 'preview', '${baseName}_400x300.webp'),
);
cachedFile.parent.createSync(recursive: true);
cachedFile.writeAsBytesSync([0xAA]);
final result = await v.generatePreview(sourceFile.path, w: 400, h: 300);
expect(p.normalize(result.path), p.normalize(cachedFile.path));
},
);
test('should use correct cache filename format for width only', () async {
final v = Vips(cacheDir: cacheDir.path);
final sourceFile = File(p.join(tempDir.path, 'width_only.jpg'));
sourceFile.writeAsBytesSync(List.filled(100, 0));
final baseName = sourceFile.path.hashCode.toString();
final cachedFile = File(
p.join(cacheDir.path, 'preview', '${baseName}_500x0.webp'),
);
cachedFile.parent.createSync(recursive: true);
cachedFile.writeAsBytesSync([0xBB]);
final result = await v.generatePreview(sourceFile.path, w: 500);
expect(p.normalize(result.path), p.normalize(cachedFile.path));
});
test('should use correct cache filename format for height only', () async {
final v = Vips(cacheDir: cacheDir.path);
final sourceFile = File(p.join(tempDir.path, 'height_only.jpg'));
sourceFile.writeAsBytesSync(List.filled(100, 0));
final baseName = sourceFile.path.hashCode.toString();
final cachedFile = File(
p.join(cacheDir.path, 'preview', '${baseName}_0x600.webp'),
);
cachedFile.parent.createSync(recursive: true);
cachedFile.writeAsBytesSync([0xCC]);
final result = await v.generatePreview(sourceFile.path, h: 600);
expect(p.normalize(result.path), p.normalize(cachedFile.path));
});
});
}