chore(web_file_system): sync changes from open_xml including idb_block_store, getAsBlob, and tests
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
@TestOn('browser')
|
||||
import 'dart:convert';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:web_file_system/web_file_system.dart';
|
||||
|
||||
void main() {
|
||||
late WebFileSystem fs;
|
||||
|
||||
setUp(() async {
|
||||
// Tests run in parallel in browser often sharing context, so use unique paths.
|
||||
fs = WebFileSystem();
|
||||
});
|
||||
|
||||
group('Troubleshooting NotFoundError', () {
|
||||
test('Temp directory creation and persistence', () async {
|
||||
print('DEBUG: creating temp dir');
|
||||
final tempDir = await fs.systemTempDirectory.createTemp('debug_test_');
|
||||
print('DEBUG: Created temp dir at ${tempDir.path}');
|
||||
|
||||
expect(await tempDir.exists(), isTrue);
|
||||
|
||||
final file = tempDir.childFile('test.txt');
|
||||
await file.writeAsString('Persistence Check');
|
||||
|
||||
print('DEBUG: checking existence immediately');
|
||||
expect(await file.exists(), isTrue);
|
||||
expect(await file.readAsString(), equals('Persistence Check'));
|
||||
|
||||
// Wait a bit to simulate pipeline delays
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
|
||||
print('DEBUG: checking existence after delay');
|
||||
expect(await file.readAsString(), equals('Persistence Check'));
|
||||
|
||||
// Cleanup
|
||||
await tempDir.delete(recursive: true);
|
||||
print('DEBUG: deleted temp dir');
|
||||
expect(await file.exists(), isFalse);
|
||||
});
|
||||
|
||||
test('Deep copy behavior verification', () async {
|
||||
final srcDir = await fs.systemTempDirectory.createTemp('src_');
|
||||
final destDir = await fs.systemTempDirectory.createTemp('dest_');
|
||||
|
||||
final srcFile = srcDir.childFile('source.dat');
|
||||
// Write some substantial data
|
||||
final data = utf8.encode('Essential Data for Export');
|
||||
await srcFile.writeAsBytes(data);
|
||||
|
||||
print('DEBUG: Source file written to ${srcFile.path}');
|
||||
|
||||
final destPath = destDir.childFile('copy.dat').path;
|
||||
print('DEBUG: Copying to $destPath');
|
||||
|
||||
final copiedFile = await srcFile.copy(destPath);
|
||||
|
||||
print('DEBUG: Copy complete');
|
||||
expect(await copiedFile.exists(), isTrue);
|
||||
expect(await copiedFile.readAsBytes(), equals(data));
|
||||
|
||||
// Now delete source
|
||||
print('DEBUG: Deleting source file');
|
||||
await srcFile.delete();
|
||||
expect(await srcFile.exists(), isFalse);
|
||||
|
||||
// Verify copy still exists and is readable (Deep Copy Check)
|
||||
print('DEBUG: Verifying copy after source deletion');
|
||||
expect(await copiedFile.exists(), isTrue);
|
||||
try {
|
||||
final copyData = await copiedFile.readAsBytes();
|
||||
expect(copyData, equals(data));
|
||||
print('DEBUG: Deep copy verified!');
|
||||
} catch (e) {
|
||||
print('ERROR: Deep copy failed! Reading copy caused error: $e');
|
||||
rethrow;
|
||||
}
|
||||
});
|
||||
|
||||
test('Concurrent Write/Read stress', () async {
|
||||
final dir = await fs.systemTempDirectory.createTemp('stress_');
|
||||
final file = dir.childFile('stress.txt');
|
||||
|
||||
// Write
|
||||
await file.writeAsString('Initial');
|
||||
|
||||
// Rapidly update
|
||||
for (int i = 0; i < 10; i++) {
|
||||
await file.writeAsString('Update $i');
|
||||
final content = await file.readAsString();
|
||||
expect(content, equals('Update $i'));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
@TestOn('browser')
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:web_file_system/web_file_system.dart';
|
||||
|
||||
void main() {
|
||||
late WebFileSystem fs;
|
||||
|
||||
setUp(() async {
|
||||
fs = WebFileSystem();
|
||||
});
|
||||
|
||||
group('Robust Correctness Tests', () {
|
||||
test('Multiple files in a directory stress test', () async {
|
||||
final uniqueId = DateTime.now().millisecondsSinceEpoch;
|
||||
final dirPath = '/stress_$uniqueId';
|
||||
final dir = fs.directory(dirPath);
|
||||
await dir.create();
|
||||
|
||||
final fileCount = 50;
|
||||
final futures = <Future>[];
|
||||
|
||||
for (var i = 0; i < fileCount; i++) {
|
||||
futures.add(
|
||||
fs.file('$dirPath/file_$i.txt').writeAsString('Content of file $i'),
|
||||
);
|
||||
}
|
||||
await Future.wait(futures);
|
||||
|
||||
final entities = await dir.list().toList();
|
||||
expect(entities.length, equals(fileCount));
|
||||
|
||||
final names = entities.map((e) => fs.path.basename(e.path)).toSet();
|
||||
for (var i = 0; i < fileCount; i++) {
|
||||
expect(names, contains('file_$i.txt'));
|
||||
final content = await fs.file('$dirPath/file_$i.txt').readAsString();
|
||||
expect(content, equals('Content of file $i'));
|
||||
}
|
||||
});
|
||||
|
||||
test('Temporary directory usage', () async {
|
||||
final tempDir = await fs.systemTempDirectory.createTemp('my_prefix_');
|
||||
expect(tempDir.path, startsWith('/tmp/my_prefix_'));
|
||||
expect(await tempDir.exists(), isTrue);
|
||||
|
||||
final file = fs.file(fs.path.join(tempDir.path, 'test.txt'));
|
||||
await file.writeAsString('temp content');
|
||||
expect(await file.readAsString(), equals('temp content'));
|
||||
|
||||
await tempDir.delete(recursive: true);
|
||||
expect(await tempDir.exists(), isFalse);
|
||||
expect(await file.exists(), isFalse);
|
||||
});
|
||||
|
||||
test('Different files with the same bytes (deduplication/collision check)', () async {
|
||||
final uniqueId = DateTime.now().millisecondsSinceEpoch;
|
||||
final data = Uint8List.fromList([1, 2, 3, 4, 5]);
|
||||
|
||||
final file1 = fs.file('/file1_$uniqueId.bin');
|
||||
final file2 = fs.file('/file2_$uniqueId.bin');
|
||||
|
||||
await file1.writeAsBytes(data);
|
||||
await file2.writeAsBytes(data);
|
||||
|
||||
expect(await file1.readAsBytes(), equals(data));
|
||||
expect(await file2.readAsBytes(), equals(data));
|
||||
|
||||
// Update one, ensure other is unchanged
|
||||
final newData = Uint8List.fromList([6, 7, 8]);
|
||||
await file1.writeAsBytes(newData);
|
||||
|
||||
expect(await file1.readAsBytes(), equals(newData));
|
||||
expect(await file2.readAsBytes(), equals(data));
|
||||
|
||||
// Cleanup
|
||||
await file1.delete();
|
||||
await file2.delete();
|
||||
|
||||
expect(await file1.exists(), isFalse);
|
||||
expect(await file2.exists(), isFalse);
|
||||
});
|
||||
|
||||
test('Resource cleanup verification (Blob leak check)', () async {
|
||||
final uniqueId = DateTime.now().millisecondsSinceEpoch;
|
||||
final filePath = '/leak_test_$uniqueId.bin';
|
||||
final data = Uint8List.fromList(List.generate(100, (i) => i));
|
||||
|
||||
final file = fs.file(filePath);
|
||||
await file.writeAsBytes(data);
|
||||
|
||||
final inode = await fs.resolvepath(filePath);
|
||||
final blobId = inode.blobId;
|
||||
expect(blobId, isNotNull);
|
||||
|
||||
// Verify blob exists in store
|
||||
if (inode.storageType == 1) {
|
||||
expect(await fs.idbStore.getBlob(blobId!), isNotNull);
|
||||
} else {
|
||||
expect(await fs.opfs.getBlob(blobId!), isNotNull);
|
||||
}
|
||||
|
||||
await file.delete();
|
||||
|
||||
// Verify blob is gone
|
||||
if (inode.storageType == 1) {
|
||||
expect(() => fs.idbStore.getBlob(blobId!), throwsA(anything));
|
||||
} else {
|
||||
expect(() => fs.opfs.getBlob(blobId!), throwsA(anything));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user