mirror of https://github.com/AMT-Cheif/drift.git
Run drift web tests with WebAssembly
This commit is contained in:
parent
a721e896d3
commit
b56cf96b09
|
@ -15,19 +15,21 @@ dependencies:
|
|||
js: ^0.6.3
|
||||
meta: ^1.3.0
|
||||
stream_channel: ^2.1.0
|
||||
sqlite3: ^1.6.0
|
||||
sqlite3: ^1.6.2
|
||||
|
||||
dev_dependencies:
|
||||
build_test: ^2.0.0
|
||||
build_runner_core: ^7.0.0
|
||||
build_verify: ^3.0.0
|
||||
drift_dev: any
|
||||
http: ^0.13.4
|
||||
uuid: ^3.0.0
|
||||
path: ^1.8.0
|
||||
build_runner: ^2.0.0
|
||||
test: ^1.17.0
|
||||
mockito: ^5.0.7
|
||||
rxdart: ^0.27.0
|
||||
shelf: ^1.3.0
|
||||
|
||||
dependency_overrides:
|
||||
drift_dev:
|
||||
|
|
|
@ -164,7 +164,7 @@ void main() {
|
|||
await db
|
||||
.update(db.categories)
|
||||
.write(const CategoriesCompanion(description: Value('changed')));
|
||||
}, onPlatform: needsAdaptionForWeb());
|
||||
});
|
||||
|
||||
test('custom expressions can introduces new tables to watch', () async {
|
||||
final custom = CustomExpression<int>('1', watchedTables: [db.sharedTodos]);
|
||||
|
@ -174,5 +174,5 @@ void main() {
|
|||
|
||||
expect(stream, emitsInOrder([1, 1]));
|
||||
db.markTablesUpdated({db.sharedTodos});
|
||||
}, onPlatform: needsAdaptionForWeb());
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
@TestOn('vm') // because of skips.dart
|
||||
import 'package:drift/drift.dart' hide isNull;
|
||||
|
||||
import 'package:test/test.dart';
|
||||
|
@ -150,5 +149,5 @@ void main() {
|
|||
),
|
||||
);
|
||||
});
|
||||
}, skip: ifOlderThanSqlite335());
|
||||
}, skip: ifOlderThanSqlite335(sqlite3Version));
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
@TestOn('vm') // because of skips.dart
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
|
@ -112,5 +111,5 @@ void main() {
|
|||
descriptionInUpperCase: 'DESCRIPTION',
|
||||
),
|
||||
);
|
||||
}, skip: ifOlderThanSqlite335());
|
||||
}, skip: ifOlderThanSqlite335(sqlite3Version));
|
||||
}
|
||||
|
|
|
@ -27,5 +27,5 @@ void main() {
|
|||
updates: someTables, updateKind: UpdateKind.update);
|
||||
|
||||
expect(await watchValue().first, 2);
|
||||
}, onPlatform: needsAdaptionForWeb());
|
||||
});
|
||||
}
|
||||
|
|
|
@ -34,6 +34,6 @@ void main() {
|
|||
throwsA(isA<StateError>().having((e) => e.message, 'message',
|
||||
contains("Can't re-open a database after closing it."))),
|
||||
);
|
||||
}, onPlatform: needsAdaptionForWeb());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,5 +27,5 @@ void main() {
|
|||
..orderBy([(_) => OrderingTerm.random()]))
|
||||
.get();
|
||||
expect(rows.isSorted((a, b) => a.id.compareTo(b.id)), isFalse);
|
||||
}, onPlatform: needsAdaptionForWeb());
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:sqlite3/sqlite3.dart';
|
||||
import 'package:sqlite3/common.dart';
|
||||
|
||||
String? ifOlderThanSqlite335() => sqlite3.version.versionNumber > 3035000
|
||||
String? ifOlderThanSqlite335(Version version) => version.versionNumber > 3035000
|
||||
? null
|
||||
: 'RETURNING not supported by sqlite version ${sqlite3.version.libVersion}';
|
||||
: 'RETURNING not supported by sqlite version ${version.libVersion}';
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import 'package:drift/drift.dart';
|
||||
import 'package:sqlite3/common.dart';
|
||||
|
||||
Version get sqlite3Version {
|
||||
return throw UnsupportedError('Stub, should resolve to web or vm');
|
||||
}
|
||||
|
||||
DatabaseConnection testInMemoryDatabase() {
|
||||
throw UnsupportedError('Stub, should resolve to web or vm');
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
import 'package:drift/drift.dart';
|
||||
import 'package:drift/native.dart';
|
||||
import 'package:sqlite3/sqlite3.dart';
|
||||
|
||||
Version get sqlite3Version {
|
||||
return sqlite3.version;
|
||||
}
|
||||
|
||||
DatabaseConnection testInMemoryDatabase() {
|
||||
return DatabaseConnection.fromExecutor(NativeDatabase.memory());
|
||||
|
|
|
@ -1,10 +1,32 @@
|
|||
import 'package:drift/drift.dart';
|
||||
import 'package:drift/remote.dart';
|
||||
import 'package:drift/wasm.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:sqlite3/wasm.dart';
|
||||
import 'package:test/scaffolding.dart';
|
||||
|
||||
Version get sqlite3Version {
|
||||
return Version('3.38.2', 'stub', 3038200);
|
||||
}
|
||||
|
||||
Future<WasmSqlite3>? _loadedSqlite3;
|
||||
|
||||
Future<WasmSqlite3> get sqlite3 {
|
||||
return _loadedSqlite3 ??= Future.sync(() async {
|
||||
final channel = spawnHybridUri('/test/test_utils/sqlite_server.dart');
|
||||
final port = await channel.stream.first as int;
|
||||
|
||||
final response =
|
||||
await http.get(Uri.parse('http://localhost:$port/sqlite3.wasm'));
|
||||
return WasmSqlite3.load(response.bodyBytes);
|
||||
});
|
||||
}
|
||||
|
||||
// At some point, we should use a `WasmDatabase` here since it was compiled
|
||||
// in a reasonable way and will be must more reliable than proxying to a VM,
|
||||
// but this is the easiest setup for now.
|
||||
DatabaseConnection testInMemoryDatabase() {
|
||||
return remote(spawnHybridUri('/test/test_utils/sqlite_server.dart'));
|
||||
return DatabaseConnection.fromExecutor(LazyDatabase(() async {
|
||||
final sqlite = await sqlite3;
|
||||
return WasmDatabase.inMemory(sqlite);
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -1,21 +1,57 @@
|
|||
import 'package:drift/drift.dart';
|
||||
import 'package:drift/native.dart';
|
||||
import 'package:drift/remote.dart';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:shelf/shelf.dart';
|
||||
import 'package:shelf/shelf_io.dart' as io;
|
||||
import 'package:stream_channel/stream_channel.dart';
|
||||
|
||||
/// This function is used as a [hybrid test] call to use the system's sqlite
|
||||
/// in browser test.
|
||||
///
|
||||
/// To avoid excessive mocking, drift tests run against an actual sqlite3, but
|
||||
/// getting sqlite3 to run on the browser is a bit of a hassle and most tests
|
||||
/// exist to test core drift components, not the sqlite3 web implementation.
|
||||
///
|
||||
/// While we have separate integration tests to ensure drift works in the
|
||||
/// browser, unit tests just use a stream channel and a drift remote.
|
||||
///
|
||||
/// [hybrid test]: https://pub.dev/packages/test#browservm-hybrid-tests
|
||||
/// Spawns an HTTP server serving the sqlite WebAssembly module to use in web
|
||||
/// tests.
|
||||
Future<void> hybridMain(StreamChannel channel) async {
|
||||
final connection = DatabaseConnection.fromExecutor(NativeDatabase.memory());
|
||||
final server = DriftServer(connection);
|
||||
server.serve(channel);
|
||||
final wasmFile = File(p.join('..', 'extras', 'assets', 'sqlite3.wasm'));
|
||||
if (!await wasmFile.exists()) {
|
||||
throw UnsupportedError('Could not find sqlite3 WebAssembly module at '
|
||||
'${wasmFile.absolute.path}!');
|
||||
}
|
||||
|
||||
final server = await HttpServer.bind('localhost', 0);
|
||||
final handler =
|
||||
const Pipeline().addMiddleware(_cors()).addHandler(_serveFile(wasmFile));
|
||||
io.serveRequests(server, handler);
|
||||
|
||||
channel.sink.add(server.port);
|
||||
await channel.stream
|
||||
.listen(null)
|
||||
.asFuture<void>()
|
||||
.then<void>((_) => server.close());
|
||||
}
|
||||
|
||||
const _corsHeaders = {'Access-Control-Allow-Origin': '*'};
|
||||
|
||||
Middleware _cors() {
|
||||
Response? handleOptionsRequest(Request request) {
|
||||
if (request.method == 'OPTIONS') {
|
||||
return Response.ok(null, headers: _corsHeaders);
|
||||
} else {
|
||||
// Returning null will run the regular request handler
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Response addCorsHeaders(Response response) {
|
||||
return response.change(headers: _corsHeaders);
|
||||
}
|
||||
|
||||
return createMiddleware(
|
||||
requestHandler: handleOptionsRequest, responseHandler: addCorsHeaders);
|
||||
}
|
||||
|
||||
Handler _serveFile(File file) {
|
||||
return (request) {
|
||||
return Response(
|
||||
200,
|
||||
body: file.openRead(),
|
||||
headers: {'Content-Type': 'application/wasm'},
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,13 +1,5 @@
|
|||
import 'package:test/test.dart';
|
||||
|
||||
export 'database_stub.dart'
|
||||
if (dart.library.ffi) 'database_vm.dart'
|
||||
if (dart.library.js) 'database_web.dart';
|
||||
export 'matchers.dart';
|
||||
export 'mocks.dart';
|
||||
|
||||
Map<String, dynamic> needsAdaptionForWeb() {
|
||||
return const {
|
||||
'browser': Skip('TODO: This test needs adaptions to work on the web.')
|
||||
};
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
../../../extras/assets/sqlite3.wasm
|
Binary file not shown.
Loading…
Reference in New Issue