mirror of
https://gitlab.com/veilid/veilid.git
synced 2024-12-23 14:40:02 -06:00
cleanup veilid-flutter
This commit is contained in:
parent
b948c53863
commit
439d2641f1
@ -1,4 +1,4 @@
|
|||||||
@Timeout(Duration(seconds: 60))
|
@Timeout(Duration(seconds: 120))
|
||||||
|
|
||||||
library veilid_flutter_integration_test;
|
library veilid_flutter_integration_test;
|
||||||
|
|
||||||
@ -7,10 +7,10 @@ import 'package:integration_test/integration_test.dart';
|
|||||||
import 'package:veilid_test/veilid_test.dart';
|
import 'package:veilid_test/veilid_test.dart';
|
||||||
|
|
||||||
import 'test_crypto.dart';
|
import 'test_crypto.dart';
|
||||||
|
import 'test_dht.dart';
|
||||||
import 'test_routing_context.dart';
|
import 'test_routing_context.dart';
|
||||||
import 'test_table_db.dart';
|
import 'test_table_db.dart';
|
||||||
import 'test_veilid_config.dart';
|
import 'test_veilid_config.dart';
|
||||||
import 'test_dht.dart';
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
@ -49,13 +49,13 @@ void main() {
|
|||||||
group('Routing Contexts', () {
|
group('Routing Contexts', () {
|
||||||
test('routing contexts', testRoutingContexts);
|
test('routing contexts', testRoutingContexts);
|
||||||
test('app message loopback',
|
test('app message loopback',
|
||||||
() => testAppMessageLoopback(fixture.updateStream));
|
() async => testAppMessageLoopback(fixture.updateStream));
|
||||||
test('app call loopback',
|
test('app call loopback',
|
||||||
() => testAppCallLoopback(fixture.updateStream));
|
() async => testAppCallLoopback(fixture.updateStream));
|
||||||
test('app message loopback big packets',
|
test('app message loopback big packets',
|
||||||
() => testAppMessageLoopbackBigPackets(fixture.updateStream));
|
() async => testAppMessageLoopbackBigPackets(fixture.updateStream));
|
||||||
test('app call loopback big packets',
|
test('app call loopback big packets',
|
||||||
() => testAppCallLoopbackBigPackets(fixture.updateStream));
|
() async => testAppCallLoopbackBigPackets(fixture.updateStream));
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Veilid DHT', () {
|
group('Veilid DHT', () {
|
||||||
@ -71,8 +71,8 @@ void main() {
|
|||||||
test('get dht value nonexistent', testGetDHTValueNonexistent);
|
test('get dht value nonexistent', testGetDHTValueNonexistent);
|
||||||
test('set get dht value', testSetGetDHTValue);
|
test('set get dht value', testSetGetDHTValue);
|
||||||
test('open writer dht value', testOpenWriterDHTValue);
|
test('open writer dht value', testOpenWriterDHTValue);
|
||||||
test(
|
test('watch dht values',
|
||||||
'watch dht values', () => testWatchDHTValues(fixture.updateStream));
|
() async => testWatchDHTValues(fixture.updateStream));
|
||||||
test('inspect dht record', testInspectDHTRecord);
|
test('inspect dht record', testInspectDHTRecord);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -14,8 +14,7 @@ Future<void> testGetCryptoSystem() async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> testGetCryptoSystemInvalid() async {
|
Future<void> testGetCryptoSystemInvalid() async {
|
||||||
await expectLater(
|
await expectLater(() async => Veilid.instance.getCryptoSystem(cryptoKindNONE),
|
||||||
() async => await Veilid.instance.getCryptoSystem(cryptoKindNONE),
|
|
||||||
throwsA(isA<VeilidAPIException>()));
|
throwsA(isA<VeilidAPIException>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,12 +24,12 @@ Future<void> testHashAndVerifyPassword() async {
|
|||||||
final salt = nonce.decode();
|
final salt = nonce.decode();
|
||||||
|
|
||||||
// Password match
|
// Password match
|
||||||
final phash = await cs.hashPassword(utf8.encode("abc123"), salt);
|
final phash = await cs.hashPassword(utf8.encode('abc123'), salt);
|
||||||
expect(await cs.verifyPassword(utf8.encode("abc123"), phash), isTrue);
|
expect(await cs.verifyPassword(utf8.encode('abc123'), phash), isTrue);
|
||||||
|
|
||||||
// Password mismatch
|
// Password mismatch
|
||||||
await cs.hashPassword(utf8.encode("abc1234"), salt);
|
await cs.hashPassword(utf8.encode('abc1234'), salt);
|
||||||
expect(await cs.verifyPassword(utf8.encode("abc1235"), phash), isFalse);
|
expect(await cs.verifyPassword(utf8.encode('abc1235'), phash), isFalse);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> testGenerateSharedSecret() async {
|
Future<void> testGenerateSharedSecret() async {
|
||||||
@ -41,19 +40,19 @@ Future<void> testGenerateSharedSecret() async {
|
|||||||
final kp3 = await cs.generateKeyPair();
|
final kp3 = await cs.generateKeyPair();
|
||||||
|
|
||||||
final ssA =
|
final ssA =
|
||||||
await cs.generateSharedSecret(kp1.key, kp2.secret, utf8.encode("abc123"));
|
await cs.generateSharedSecret(kp1.key, kp2.secret, utf8.encode('abc123'));
|
||||||
final ssB =
|
final ssB =
|
||||||
await cs.generateSharedSecret(kp2.key, kp1.secret, utf8.encode("abc123"));
|
await cs.generateSharedSecret(kp2.key, kp1.secret, utf8.encode('abc123'));
|
||||||
|
|
||||||
expect(ssA, equals(ssB));
|
expect(ssA, equals(ssB));
|
||||||
|
|
||||||
final ssC = await cs.generateSharedSecret(
|
final ssC = await cs.generateSharedSecret(
|
||||||
kp2.key, kp1.secret, utf8.encode("abc1234"));
|
kp2.key, kp1.secret, utf8.encode('abc1234'));
|
||||||
|
|
||||||
expect(ssA, isNot(equals(ssC)));
|
expect(ssA, isNot(equals(ssC)));
|
||||||
|
|
||||||
final ssD =
|
final ssD =
|
||||||
await cs.generateSharedSecret(kp3.key, kp1.secret, utf8.encode("abc123"));
|
await cs.generateSharedSecret(kp3.key, kp1.secret, utf8.encode('abc123'));
|
||||||
|
|
||||||
expect(ssA, isNot(equals(ssD)));
|
expect(ssA, isNot(equals(ssD)));
|
||||||
}
|
}
|
||||||
|
@ -5,13 +5,12 @@ import 'package:flutter_test/flutter_test.dart';
|
|||||||
import 'package:veilid/veilid.dart';
|
import 'package:veilid/veilid.dart';
|
||||||
|
|
||||||
final bogusKey =
|
final bogusKey =
|
||||||
TypedKey.fromString("VLD0:qD10lHHPD1_Qr23_Qy-1JnxTht12eaWwENVG_m2v7II");
|
TypedKey.fromString('VLD0:qD10lHHPD1_Qr23_Qy-1JnxTht12eaWwENVG_m2v7II');
|
||||||
|
|
||||||
Future<void> testGetDHTValueUnopened() async {
|
Future<void> testGetDHTValueUnopened() async {
|
||||||
final rc = await Veilid.instance.routingContext();
|
final rc = await Veilid.instance.routingContext();
|
||||||
try {
|
try {
|
||||||
await expectLater(
|
await expectLater(() async => rc.getDHTValue(bogusKey, 0),
|
||||||
() async => await rc.getDHTValue(bogusKey, 0, forceRefresh: false),
|
|
||||||
throwsA(isA<VeilidAPIException>()));
|
throwsA(isA<VeilidAPIException>()));
|
||||||
} finally {
|
} finally {
|
||||||
rc.close();
|
rc.close();
|
||||||
@ -21,7 +20,7 @@ Future<void> testGetDHTValueUnopened() async {
|
|||||||
Future<void> testOpenDHTRecordNonexistentNoWriter() async {
|
Future<void> testOpenDHTRecordNonexistentNoWriter() async {
|
||||||
final rc = await Veilid.instance.routingContext();
|
final rc = await Veilid.instance.routingContext();
|
||||||
try {
|
try {
|
||||||
await expectLater(() async => await rc.openDHTRecord(bogusKey),
|
await expectLater(() async => rc.openDHTRecord(bogusKey),
|
||||||
throwsA(isA<VeilidAPIException>()));
|
throwsA(isA<VeilidAPIException>()));
|
||||||
} finally {
|
} finally {
|
||||||
rc.close();
|
rc.close();
|
||||||
@ -31,7 +30,7 @@ Future<void> testOpenDHTRecordNonexistentNoWriter() async {
|
|||||||
Future<void> testCloseDHTRecordNonexistent() async {
|
Future<void> testCloseDHTRecordNonexistent() async {
|
||||||
final rc = await Veilid.instance.routingContext();
|
final rc = await Veilid.instance.routingContext();
|
||||||
try {
|
try {
|
||||||
await expectLater(() async => await rc.closeDHTRecord(bogusKey),
|
await expectLater(() async => rc.closeDHTRecord(bogusKey),
|
||||||
throwsA(isA<VeilidAPIException>()));
|
throwsA(isA<VeilidAPIException>()));
|
||||||
} finally {
|
} finally {
|
||||||
rc.close();
|
rc.close();
|
||||||
@ -41,7 +40,7 @@ Future<void> testCloseDHTRecordNonexistent() async {
|
|||||||
Future<void> testDeleteDHTRecordNonexistent() async {
|
Future<void> testDeleteDHTRecordNonexistent() async {
|
||||||
final rc = await Veilid.instance.routingContext();
|
final rc = await Veilid.instance.routingContext();
|
||||||
try {
|
try {
|
||||||
await expectLater(() async => await rc.deleteDHTRecord(bogusKey),
|
await expectLater(() async => rc.deleteDHTRecord(bogusKey),
|
||||||
throwsA(isA<VeilidAPIException>()));
|
throwsA(isA<VeilidAPIException>()));
|
||||||
} finally {
|
} finally {
|
||||||
rc.close();
|
rc.close();
|
||||||
@ -84,7 +83,7 @@ Future<void> testSetGetDHTValue() async {
|
|||||||
final rc = await Veilid.instance.routingContext();
|
final rc = await Veilid.instance.routingContext();
|
||||||
try {
|
try {
|
||||||
final rec = await rc.createDHTRecord(const DHTSchema.dflt(oCnt: 2));
|
final rec = await rc.createDHTRecord(const DHTSchema.dflt(oCnt: 2));
|
||||||
expect(await rc.setDHTValue(rec.key, 0, utf8.encode("BLAH BLAH BLAH")),
|
expect(await rc.setDHTValue(rec.key, 0, utf8.encode('BLAH BLAH BLAH')),
|
||||||
isNull);
|
isNull);
|
||||||
final vd2 = await rc.getDHTValue(rec.key, 0);
|
final vd2 = await rc.getDHTValue(rec.key, 0);
|
||||||
expect(vd2, isNotNull);
|
expect(vd2, isNotNull);
|
||||||
@ -115,9 +114,9 @@ Future<void> testOpenWriterDHTValue() async {
|
|||||||
expect(await cs.validateKeyPair(owner, secret), isTrue);
|
expect(await cs.validateKeyPair(owner, secret), isTrue);
|
||||||
final otherKeyPair = await cs.generateKeyPair();
|
final otherKeyPair = await cs.generateKeyPair();
|
||||||
|
|
||||||
final va = utf8.encode("Qwertyuiop Asdfghjkl Zxcvbnm");
|
final va = utf8.encode('Qwertyuiop Asdfghjkl Zxcvbnm');
|
||||||
final vb = utf8.encode("1234567890");
|
final vb = utf8.encode('1234567890');
|
||||||
final vc = utf8.encode("!@#\$%^&*()");
|
final vc = utf8.encode(r'!@#$%^&*()');
|
||||||
|
|
||||||
// Test subkey writes
|
// Test subkey writes
|
||||||
expect(await rc.setDHTValue(key, 1, va), isNull);
|
expect(await rc.setDHTValue(key, 1, va), isNull);
|
||||||
@ -179,7 +178,8 @@ Future<void> testOpenWriterDHTValue() async {
|
|||||||
expect(vdtemp.seq, equals(1));
|
expect(vdtemp.seq, equals(1));
|
||||||
expect(vdtemp.writer, equals(owner));
|
expect(vdtemp.writer, equals(owner));
|
||||||
|
|
||||||
// Verify subkey 1 can be set a second time and it updates because seq is newer
|
// Verify subkey 1 can be set a second time
|
||||||
|
// and it updates because seq is newer
|
||||||
expect(await rc.setDHTValue(key, 1, vc), isNull);
|
expect(await rc.setDHTValue(key, 1, vc), isNull);
|
||||||
|
|
||||||
// Verify the network got the subkey update with a refresh check
|
// Verify the network got the subkey update with a refresh check
|
||||||
@ -203,11 +203,11 @@ Future<void> testOpenWriterDHTValue() async {
|
|||||||
expect(rec.schema.oCnt, equals(2));
|
expect(rec.schema.oCnt, equals(2));
|
||||||
|
|
||||||
// Verify subkey 1 can NOT be set because we have the wrong writer
|
// Verify subkey 1 can NOT be set because we have the wrong writer
|
||||||
await expectLater(() async => await rc.setDHTValue(key, 1, va),
|
await expectLater(() async => rc.setDHTValue(key, 1, va),
|
||||||
throwsA(isA<VeilidAPIException>()));
|
throwsA(isA<VeilidAPIException>()));
|
||||||
|
|
||||||
// Verify subkey 0 can NOT be set because we have the wrong writer
|
// Verify subkey 0 can NOT be set because we have the wrong writer
|
||||||
await expectLater(() async => await rc.setDHTValue(key, 0, va),
|
await expectLater(() async => rc.setDHTValue(key, 0, va),
|
||||||
throwsA(isA<VeilidAPIException>()));
|
throwsA(isA<VeilidAPIException>()));
|
||||||
|
|
||||||
// Verify subkey 0 can be set because override with the right writer
|
// Verify subkey 0 can be set because override with the right writer
|
||||||
@ -250,7 +250,7 @@ Future<void> testWatchDHTValues(Stream<VeilidUpdate> updateStream) async {
|
|||||||
|
|
||||||
// Set some subkey we care about
|
// Set some subkey we care about
|
||||||
expect(
|
expect(
|
||||||
await rcWatch.setDHTValue(rec.key, 3, utf8.encode("BLAH BLAH BLAH")),
|
await rcWatch.setDHTValue(rec.key, 3, utf8.encode('BLAH BLAH BLAH')),
|
||||||
isNull);
|
isNull);
|
||||||
|
|
||||||
// Make a watch on that subkey
|
// Make a watch on that subkey
|
||||||
@ -261,24 +261,23 @@ Future<void> testWatchDHTValues(Stream<VeilidUpdate> updateStream) async {
|
|||||||
rec = await rcSet.openDHTRecord(rec.key, writer: rec.ownerKeyPair());
|
rec = await rcSet.openDHTRecord(rec.key, writer: rec.ownerKeyPair());
|
||||||
|
|
||||||
// Now set the subkey and trigger an update
|
// Now set the subkey and trigger an update
|
||||||
expect(await rcSet.setDHTValue(rec.key, 3, utf8.encode("BLAH")), isNull);
|
expect(await rcSet.setDHTValue(rec.key, 3, utf8.encode('BLAH')), isNull);
|
||||||
|
|
||||||
// Now we should NOT get an update because the update
|
// Now we should NOT get an update because the update
|
||||||
// is the same as our local copy
|
// is the same as our local copy
|
||||||
if (await valueChangeQueueIterator
|
if (await valueChangeQueueIterator
|
||||||
.moveNext()
|
.moveNext()
|
||||||
.timeout(const Duration(seconds: 5), onTimeout: () {
|
.timeout(const Duration(seconds: 5), onTimeout: () => false)) {
|
||||||
return false;
|
fail('should not have a change');
|
||||||
})) {
|
|
||||||
fail("should not have a change");
|
|
||||||
}
|
}
|
||||||
|
await valueChangeQueueIterator.cancel();
|
||||||
valueChangeQueueIterator = StreamIterator(valueChangeQueue.stream);
|
valueChangeQueueIterator = StreamIterator(valueChangeQueue.stream);
|
||||||
|
|
||||||
// Now set multiple subkeys and trigger an update
|
// Now set multiple subkeys and trigger an update
|
||||||
expect(
|
expect(
|
||||||
await [
|
await [
|
||||||
rcSet.setDHTValue(rec.key, 3, utf8.encode("BLAH BLAH")),
|
rcSet.setDHTValue(rec.key, 3, utf8.encode('BLAH BLAH')),
|
||||||
rcSet.setDHTValue(rec.key, 4, utf8.encode("BZORT"))
|
rcSet.setDHTValue(rec.key, 4, utf8.encode('BZORT'))
|
||||||
].wait,
|
].wait,
|
||||||
equals([null, null]));
|
equals([null, null]));
|
||||||
|
|
||||||
@ -286,7 +285,7 @@ Future<void> testWatchDHTValues(Stream<VeilidUpdate> updateStream) async {
|
|||||||
await valueChangeQueueIterator
|
await valueChangeQueueIterator
|
||||||
.moveNext()
|
.moveNext()
|
||||||
.timeout(const Duration(seconds: 5), onTimeout: () {
|
.timeout(const Duration(seconds: 5), onTimeout: () {
|
||||||
fail("should have a change");
|
fail('should have a change');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Verify the update
|
// Verify the update
|
||||||
@ -311,8 +310,8 @@ Future<void> testWatchDHTValues(Stream<VeilidUpdate> updateStream) async {
|
|||||||
// Now set multiple subkeys and trigger an update
|
// Now set multiple subkeys and trigger an update
|
||||||
expect(
|
expect(
|
||||||
await [
|
await [
|
||||||
rcSet.setDHTValue(rec.key, 3, utf8.encode("BLAH BLAH BLAH")),
|
rcSet.setDHTValue(rec.key, 3, utf8.encode('BLAH BLAH BLAH')),
|
||||||
rcSet.setDHTValue(rec.key, 5, utf8.encode("BZORT BZORT"))
|
rcSet.setDHTValue(rec.key, 5, utf8.encode('BZORT BZORT'))
|
||||||
].wait,
|
].wait,
|
||||||
equals([null, null]));
|
equals([null, null]));
|
||||||
|
|
||||||
@ -320,10 +319,11 @@ Future<void> testWatchDHTValues(Stream<VeilidUpdate> updateStream) async {
|
|||||||
await valueChangeQueueIterator
|
await valueChangeQueueIterator
|
||||||
.moveNext()
|
.moveNext()
|
||||||
.timeout(const Duration(seconds: 5), onTimeout: () {
|
.timeout(const Duration(seconds: 5), onTimeout: () {
|
||||||
fail("should have a change");
|
fail('should have a change');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Verify the update came back but we don't get a new value because the sequence number is the same
|
// Verify the update came back but we don't get a new value because the
|
||||||
|
// sequence number is the same
|
||||||
expect(valueChangeQueueIterator.current.key, equals(rec.key));
|
expect(valueChangeQueueIterator.current.key, equals(rec.key));
|
||||||
expect(valueChangeQueueIterator.current.count, equals(0xFFFFFFFC));
|
expect(valueChangeQueueIterator.current.count, equals(0xFFFFFFFC));
|
||||||
expect(valueChangeQueueIterator.current.subkeys,
|
expect(valueChangeQueueIterator.current.subkeys,
|
||||||
@ -345,18 +345,16 @@ Future<void> testWatchDHTValues(Stream<VeilidUpdate> updateStream) async {
|
|||||||
// Now set multiple subkeys and trigger an update
|
// Now set multiple subkeys and trigger an update
|
||||||
expect(
|
expect(
|
||||||
await [
|
await [
|
||||||
rcSet.setDHTValue(rec.key, 3, utf8.encode("BLAH BLAH BLAH BLAH")),
|
rcSet.setDHTValue(rec.key, 3, utf8.encode('BLAH BLAH BLAH BLAH')),
|
||||||
rcSet.setDHTValue(rec.key, 5, utf8.encode("BZORT BZORT BZORT"))
|
rcSet.setDHTValue(rec.key, 5, utf8.encode('BZORT BZORT BZORT'))
|
||||||
].wait,
|
].wait,
|
||||||
equals([null, null]));
|
equals([null, null]));
|
||||||
|
|
||||||
// Now we should NOT get an update
|
// Now we should NOT get an update
|
||||||
if (await valueChangeQueueIterator
|
if (await valueChangeQueueIterator
|
||||||
.moveNext()
|
.moveNext()
|
||||||
.timeout(const Duration(seconds: 5), onTimeout: () {
|
.timeout(const Duration(seconds: 5), onTimeout: () => false)) {
|
||||||
return false;
|
fail('should not have a change');
|
||||||
})) {
|
|
||||||
fail("should not have a change");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up
|
// Clean up
|
||||||
@ -367,16 +365,18 @@ Future<void> testWatchDHTValues(Stream<VeilidUpdate> updateStream) async {
|
|||||||
rcSet.close();
|
rcSet.close();
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
await valueChangeQueueIterator.cancel();
|
||||||
await valueChangeSubscription.cancel();
|
await valueChangeSubscription.cancel();
|
||||||
|
await valueChangeQueue.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> testInspectDHTRecord() async {
|
Future<void> testInspectDHTRecord() async {
|
||||||
final rc = await Veilid.instance.routingContext();
|
final rc = await Veilid.instance.routingContext();
|
||||||
try {
|
try {
|
||||||
var rec = await rc.createDHTRecord(const DHTSchema.dflt(oCnt: 2));
|
final rec = await rc.createDHTRecord(const DHTSchema.dflt(oCnt: 2));
|
||||||
|
|
||||||
expect(await rc.setDHTValue(rec.key, 0, utf8.encode("BLAH BLAH BLAH")),
|
expect(await rc.setDHTValue(rec.key, 0, utf8.encode('BLAH BLAH BLAH')),
|
||||||
isNull);
|
isNull);
|
||||||
|
|
||||||
final rr = await rc.inspectDHTRecord(rec.key);
|
final rr = await rc.inspectDHTRecord(rec.key);
|
||||||
|
@ -14,6 +14,7 @@ Future<void> testRoutingContexts() async {
|
|||||||
{
|
{
|
||||||
final rc = await Veilid.instance.routingContext();
|
final rc = await Veilid.instance.routingContext();
|
||||||
final rcp = rc.withDefaultSafety();
|
final rcp = rc.withDefaultSafety();
|
||||||
|
// ignore: cascade_invocations
|
||||||
rcp.close();
|
rcp.close();
|
||||||
rc.close();
|
rc.close();
|
||||||
}
|
}
|
||||||
@ -21,6 +22,7 @@ Future<void> testRoutingContexts() async {
|
|||||||
{
|
{
|
||||||
final rc = await Veilid.instance.routingContext();
|
final rc = await Veilid.instance.routingContext();
|
||||||
final rcp = rc.withSequencing(Sequencing.ensureOrdered);
|
final rcp = rc.withSequencing(Sequencing.ensureOrdered);
|
||||||
|
// ignore: cascade_invocations
|
||||||
rcp.close();
|
rcp.close();
|
||||||
rc.close();
|
rc.close();
|
||||||
}
|
}
|
||||||
@ -32,6 +34,7 @@ Future<void> testRoutingContexts() async {
|
|||||||
hopCount: 2,
|
hopCount: 2,
|
||||||
stability: Stability.lowLatency,
|
stability: Stability.lowLatency,
|
||||||
sequencing: Sequencing.noPreference)));
|
sequencing: Sequencing.noPreference)));
|
||||||
|
// ignore: cascade_invocations
|
||||||
rcp.close();
|
rcp.close();
|
||||||
rc.close();
|
rc.close();
|
||||||
}
|
}
|
||||||
@ -39,6 +42,7 @@ Future<void> testRoutingContexts() async {
|
|||||||
final rc = await Veilid.instance.routingContext();
|
final rc = await Veilid.instance.routingContext();
|
||||||
final rcp = rc.withSafety(
|
final rcp = rc.withSafety(
|
||||||
const SafetySelectionUnsafe(sequencing: Sequencing.preferOrdered));
|
const SafetySelectionUnsafe(sequencing: Sequencing.preferOrdered));
|
||||||
|
// ignore: cascade_invocations
|
||||||
rcp.close();
|
rcp.close();
|
||||||
rc.close();
|
rc.close();
|
||||||
}
|
}
|
||||||
@ -52,7 +56,7 @@ Future<void> testAppMessageLoopback(Stream<VeilidUpdate> updateStream) async {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
await Veilid.instance.debug("purge routes");
|
await Veilid.instance.debug('purge routes');
|
||||||
|
|
||||||
// make a routing context that uses a safety route
|
// make a routing context that uses a safety route
|
||||||
final rc = await Veilid.instance.routingContext();
|
final rc = await Veilid.instance.routingContext();
|
||||||
@ -64,7 +68,7 @@ Future<void> testAppMessageLoopback(Stream<VeilidUpdate> updateStream) async {
|
|||||||
final prr = await Veilid.instance.importRemotePrivateRoute(prl.blob);
|
final prr = await Veilid.instance.importRemotePrivateRoute(prl.blob);
|
||||||
try {
|
try {
|
||||||
// send an app message to our own private route
|
// send an app message to our own private route
|
||||||
final message = utf8.encode("abcd1234");
|
final message = utf8.encode('abcd1234');
|
||||||
await rc.appMessage(prr, message);
|
await rc.appMessage(prr, message);
|
||||||
|
|
||||||
// we should get the same message back
|
// we should get the same message back
|
||||||
@ -82,6 +86,7 @@ Future<void> testAppMessageLoopback(Stream<VeilidUpdate> updateStream) async {
|
|||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
await appMessageSubscription.cancel();
|
await appMessageSubscription.cancel();
|
||||||
|
await appMessageQueue.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +98,7 @@ Future<void> testAppCallLoopback(Stream<VeilidUpdate> updateStream) async {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
await Veilid.instance.debug("purge routes");
|
await Veilid.instance.debug('purge routes');
|
||||||
|
|
||||||
// make a routing context that uses a safety route
|
// make a routing context that uses a safety route
|
||||||
final rc = await Veilid.instance.routingContext();
|
final rc = await Veilid.instance.routingContext();
|
||||||
@ -105,7 +110,7 @@ Future<void> testAppCallLoopback(Stream<VeilidUpdate> updateStream) async {
|
|||||||
final prr = await Veilid.instance.importRemotePrivateRoute(prl.blob);
|
final prr = await Veilid.instance.importRemotePrivateRoute(prl.blob);
|
||||||
try {
|
try {
|
||||||
// send an app call to our own private route
|
// send an app call to our own private route
|
||||||
final message = utf8.encode("abcd1234");
|
final message = utf8.encode('abcd1234');
|
||||||
final appCallFuture = rc.appCall(prr, message);
|
final appCallFuture = rc.appCall(prr, message);
|
||||||
|
|
||||||
// we should get the same call back
|
// we should get the same call back
|
||||||
@ -116,7 +121,7 @@ Future<void> testAppCallLoopback(Stream<VeilidUpdate> updateStream) async {
|
|||||||
expect(update.routeId, isNotNull);
|
expect(update.routeId, isNotNull);
|
||||||
|
|
||||||
// now we reply to the request
|
// now we reply to the request
|
||||||
final reply = utf8.encode("qwer5678");
|
final reply = utf8.encode('qwer5678');
|
||||||
await Veilid.instance.appCallReply(appcallid, reply);
|
await Veilid.instance.appCallReply(appcallid, reply);
|
||||||
|
|
||||||
// now we should get the reply from the call
|
// now we should get the reply from the call
|
||||||
@ -133,6 +138,7 @@ Future<void> testAppCallLoopback(Stream<VeilidUpdate> updateStream) async {
|
|||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
await appMessageSubscription.cancel();
|
await appMessageSubscription.cancel();
|
||||||
|
await appCallQueue.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +156,7 @@ Future<void> testAppMessageLoopbackBigPackets(
|
|||||||
final cs = await Veilid.instance.bestCryptoSystem();
|
final cs = await Veilid.instance.bestCryptoSystem();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await Veilid.instance.debug("purge routes");
|
await Veilid.instance.debug('purge routes');
|
||||||
|
|
||||||
// make a routing context that uses a safety route
|
// make a routing context that uses a safety route
|
||||||
final rc = await Veilid.instance.routingContext();
|
final rc = await Veilid.instance.routingContext();
|
||||||
@ -160,6 +166,8 @@ Future<void> testAppMessageLoopbackBigPackets(
|
|||||||
try {
|
try {
|
||||||
// import it as a remote route as well so we can send to it
|
// import it as a remote route as well so we can send to it
|
||||||
final prr = await Veilid.instance.importRemotePrivateRoute(prl.blob);
|
final prr = await Veilid.instance.importRemotePrivateRoute(prl.blob);
|
||||||
|
|
||||||
|
final appMessageQueueIterator = StreamIterator(appMessageQueue.stream);
|
||||||
try {
|
try {
|
||||||
for (var i = 0; i < 5; i++) {
|
for (var i = 0; i < 5; i++) {
|
||||||
// send an app message to our own private route
|
// send an app message to our own private route
|
||||||
@ -168,9 +176,6 @@ Future<void> testAppMessageLoopbackBigPackets(
|
|||||||
sentMessages.add(base64Url.encode(message));
|
sentMessages.add(base64Url.encode(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
final appMessageQueueIterator =
|
|
||||||
StreamIterator(appMessageQueue.stream);
|
|
||||||
|
|
||||||
// we should get the same messages back
|
// we should get the same messages back
|
||||||
for (var i = 0; i < sentMessages.length; i++) {
|
for (var i = 0; i < sentMessages.length; i++) {
|
||||||
if (await appMessageQueueIterator.moveNext()) {
|
if (await appMessageQueueIterator.moveNext()) {
|
||||||
@ -178,10 +183,11 @@ Future<void> testAppMessageLoopbackBigPackets(
|
|||||||
expect(sentMessages.contains(base64Url.encode(update.message)),
|
expect(sentMessages.contains(base64Url.encode(update.message)),
|
||||||
isTrue);
|
isTrue);
|
||||||
} else {
|
} else {
|
||||||
fail("not enough messages in the queue");
|
fail('not enough messages in the queue');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
await appMessageQueueIterator.cancel();
|
||||||
await Veilid.instance.releasePrivateRoute(prr);
|
await Veilid.instance.releasePrivateRoute(prr);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@ -192,6 +198,7 @@ Future<void> testAppMessageLoopbackBigPackets(
|
|||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
await appMessageSubscription.cancel();
|
await appMessageSubscription.cancel();
|
||||||
|
await appMessageQueue.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,7 +221,7 @@ Future<void> testAppCallLoopbackBigPackets(
|
|||||||
final cs = await Veilid.instance.bestCryptoSystem();
|
final cs = await Veilid.instance.bestCryptoSystem();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await Veilid.instance.debug("purge routes");
|
await Veilid.instance.debug('purge routes');
|
||||||
|
|
||||||
// make a routing context that uses a safety route
|
// make a routing context that uses a safety route
|
||||||
final rc = await Veilid.instance.routingContext();
|
final rc = await Veilid.instance.routingContext();
|
||||||
@ -224,6 +231,8 @@ Future<void> testAppCallLoopbackBigPackets(
|
|||||||
try {
|
try {
|
||||||
// import it as a remote route as well so we can send to it
|
// import it as a remote route as well so we can send to it
|
||||||
final prr = await Veilid.instance.importRemotePrivateRoute(prl.blob);
|
final prr = await Veilid.instance.importRemotePrivateRoute(prl.blob);
|
||||||
|
final appMessageQueueIterator = StreamIterator(appCallQueue.stream);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (var i = 0; i < 5; i++) {
|
for (var i = 0; i < 5; i++) {
|
||||||
// send an app message to our own private route
|
// send an app message to our own private route
|
||||||
@ -232,8 +241,6 @@ Future<void> testAppCallLoopbackBigPackets(
|
|||||||
expect(message, equals(outmessage));
|
expect(message, equals(outmessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
final appMessageQueueIterator = StreamIterator(appCallQueue.stream);
|
|
||||||
|
|
||||||
// we should get the same messages back
|
// we should get the same messages back
|
||||||
for (var i = 0; i < sentMessages.length; i++) {
|
for (var i = 0; i < sentMessages.length; i++) {
|
||||||
if (await appMessageQueueIterator.moveNext()) {
|
if (await appMessageQueueIterator.moveNext()) {
|
||||||
@ -241,10 +248,11 @@ Future<void> testAppCallLoopbackBigPackets(
|
|||||||
expect(sentMessages.contains(base64Url.encode(update.message)),
|
expect(sentMessages.contains(base64Url.encode(update.message)),
|
||||||
isTrue);
|
isTrue);
|
||||||
} else {
|
} else {
|
||||||
fail("not enough messages in the queue");
|
fail('not enough messages in the queue');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
await appMessageQueueIterator.cancel();
|
||||||
await Veilid.instance.releasePrivateRoute(prr);
|
await Veilid.instance.releasePrivateRoute(prr);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -3,8 +3,8 @@ import 'dart:convert';
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:veilid/veilid.dart';
|
import 'package:veilid/veilid.dart';
|
||||||
|
|
||||||
const testDb = "__dart_test_db";
|
const testDb = '__dart_test_db';
|
||||||
const testNonexistentDb = "__dart_test_nonexistent_db";
|
const testNonexistentDb = '__dart_test_nonexistent_db';
|
||||||
|
|
||||||
Future<void> testDeleteTableDbNonExistent() async {
|
Future<void> testDeleteTableDbNonExistent() async {
|
||||||
expect(await Veilid.instance.deleteTableDB(testNonexistentDb), isFalse);
|
expect(await Veilid.instance.deleteTableDB(testNonexistentDb), isFalse);
|
||||||
@ -16,7 +16,7 @@ Future<void> testOpenDeleteTableDb() async {
|
|||||||
|
|
||||||
final tdb = await Veilid.instance.openTableDB(testDb, 1);
|
final tdb = await Veilid.instance.openTableDB(testDb, 1);
|
||||||
try {
|
try {
|
||||||
await expectLater(() async => await Veilid.instance.deleteTableDB(testDb),
|
await expectLater(() async => Veilid.instance.deleteTableDB(testDb),
|
||||||
throwsA(isA<VeilidAPIException>()));
|
throwsA(isA<VeilidAPIException>()));
|
||||||
} finally {
|
} finally {
|
||||||
tdb.close();
|
tdb.close();
|
||||||
@ -32,11 +32,11 @@ Future<void> testOpenTwiceTableDb() async {
|
|||||||
final tdb2 = await Veilid.instance.openTableDB(testDb, 1);
|
final tdb2 = await Veilid.instance.openTableDB(testDb, 1);
|
||||||
|
|
||||||
// delete should fail because open
|
// delete should fail because open
|
||||||
await expectLater(() async => await Veilid.instance.deleteTableDB(testDb),
|
await expectLater(() async => Veilid.instance.deleteTableDB(testDb),
|
||||||
throwsA(isA<VeilidAPIException>()));
|
throwsA(isA<VeilidAPIException>()));
|
||||||
tdb.close();
|
tdb.close();
|
||||||
// delete should fail because open
|
// delete should fail because open
|
||||||
await expectLater(() async => await Veilid.instance.deleteTableDB(testDb),
|
await expectLater(() async => Veilid.instance.deleteTableDB(testDb),
|
||||||
throwsA(isA<VeilidAPIException>()));
|
throwsA(isA<VeilidAPIException>()));
|
||||||
tdb2.close();
|
tdb2.close();
|
||||||
|
|
||||||
@ -53,10 +53,10 @@ Future<void> testOpenTwiceTableDbStoreLoad() async {
|
|||||||
final tdb2 = await Veilid.instance.openTableDB(testDb, 1);
|
final tdb2 = await Veilid.instance.openTableDB(testDb, 1);
|
||||||
try {
|
try {
|
||||||
// store into first db copy
|
// store into first db copy
|
||||||
await tdb.store(0, utf8.encode("asdf"), utf8.encode("1234"));
|
await tdb.store(0, utf8.encode('asdf'), utf8.encode('1234'));
|
||||||
// load from second db copy
|
// load from second db copy
|
||||||
expect(
|
expect(
|
||||||
await tdb2.load(0, utf8.encode("asdf")), equals(utf8.encode("1234")));
|
await tdb2.load(0, utf8.encode('asdf')), equals(utf8.encode('1234')));
|
||||||
} finally {
|
} finally {
|
||||||
tdb2.close();
|
tdb2.close();
|
||||||
}
|
}
|
||||||
@ -77,14 +77,14 @@ Future<void> testOpenTwiceTableDbStoreDeleteLoad() async {
|
|||||||
final tdb2 = await Veilid.instance.openTableDB(testDb, 1);
|
final tdb2 = await Veilid.instance.openTableDB(testDb, 1);
|
||||||
try {
|
try {
|
||||||
// store into first db copy
|
// store into first db copy
|
||||||
await tdb.store(0, utf8.encode("asdf"), utf8.encode("1234"));
|
await tdb.store(0, utf8.encode('asdf'), utf8.encode('1234'));
|
||||||
// delete from second db copy and clean up
|
// delete from second db copy and clean up
|
||||||
await tdb2.delete(0, utf8.encode("asdf"));
|
await tdb2.delete(0, utf8.encode('asdf'));
|
||||||
} finally {
|
} finally {
|
||||||
tdb2.close();
|
tdb2.close();
|
||||||
}
|
}
|
||||||
// load from first db copy
|
// load from first db copy
|
||||||
expect(await tdb.load(0, utf8.encode("asdf")), isNull);
|
expect(await tdb.load(0, utf8.encode('asdf')), isNull);
|
||||||
} finally {
|
} finally {
|
||||||
tdb.close();
|
tdb.close();
|
||||||
}
|
}
|
||||||
@ -100,7 +100,7 @@ Future<void> testResizeTableDb() async {
|
|||||||
final tdb = await Veilid.instance.openTableDB(testDb, 1);
|
final tdb = await Veilid.instance.openTableDB(testDb, 1);
|
||||||
try {
|
try {
|
||||||
// reopen the db with more columns should fail if it is already open
|
// reopen the db with more columns should fail if it is already open
|
||||||
await expectLater(() async => await Veilid.instance.openTableDB(testDb, 2),
|
await expectLater(() async => Veilid.instance.openTableDB(testDb, 2),
|
||||||
throwsA(isA<VeilidAPIException>()));
|
throwsA(isA<VeilidAPIException>()));
|
||||||
} finally {
|
} finally {
|
||||||
tdb.close();
|
tdb.close();
|
||||||
@ -109,18 +109,18 @@ Future<void> testResizeTableDb() async {
|
|||||||
final tdb2 = await Veilid.instance.openTableDB(testDb, 2);
|
final tdb2 = await Veilid.instance.openTableDB(testDb, 2);
|
||||||
try {
|
try {
|
||||||
// write something to second column
|
// write something to second column
|
||||||
await tdb2.store(1, utf8.encode("qwer"), utf8.encode("5678"));
|
await tdb2.store(1, utf8.encode('qwer'), utf8.encode('5678'));
|
||||||
|
|
||||||
// reopen the db with fewer columns
|
// reopen the db with fewer columns
|
||||||
final tdb3 = await Veilid.instance.openTableDB(testDb, 1);
|
final tdb3 = await Veilid.instance.openTableDB(testDb, 1);
|
||||||
try {
|
try {
|
||||||
// Should fail access to second column
|
// Should fail access to second column
|
||||||
await expectLater(() async => await tdb3.load(1, utf8.encode("qwer")),
|
await expectLater(() async => tdb3.load(1, utf8.encode('qwer')),
|
||||||
throwsA(isA<VeilidAPIException>()));
|
throwsA(isA<VeilidAPIException>()));
|
||||||
|
|
||||||
// Should succeed with access to second column
|
// Should succeed with access to second column
|
||||||
expect(
|
expect(
|
||||||
await tdb2.load(1, utf8.encode("qwer")), equals(utf8.encode("5678")));
|
await tdb2.load(1, utf8.encode('qwer')), equals(utf8.encode('5678')));
|
||||||
} finally {
|
} finally {
|
||||||
tdb3.close();
|
tdb3.close();
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,13 @@ import 'dart:convert';
|
|||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:veilid/veilid.dart';
|
|
||||||
import 'package:loggy/loggy.dart';
|
import 'package:loggy/loggy.dart';
|
||||||
import 'package:veilid_example/veilid_theme.dart';
|
import 'package:veilid/veilid.dart';
|
||||||
|
|
||||||
import 'log_terminal.dart';
|
|
||||||
import 'log.dart';
|
|
||||||
import 'history_wrapper.dart';
|
import 'history_wrapper.dart';
|
||||||
|
import 'log.dart';
|
||||||
|
import 'log_terminal.dart';
|
||||||
|
import 'veilid_theme.dart';
|
||||||
|
|
||||||
// Main App
|
// Main App
|
||||||
class MyApp extends StatefulWidget {
|
class MyApp extends StatefulWidget {
|
||||||
@ -31,7 +31,7 @@ class _MyAppState extends State<MyApp> with UiLoggy {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
initPlatformState();
|
unawaited(initPlatformState());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Platform messages are asynchronous, so we initialize in an async method.
|
// Platform messages are asynchronous, so we initialize in an async method.
|
||||||
@ -55,7 +55,9 @@ class _MyAppState extends State<MyApp> with UiLoggy {
|
|||||||
// If the widget was removed from the tree while the asynchronous platform
|
// If the widget was removed from the tree while the asynchronous platform
|
||||||
// message was in flight, we want to discard the reply rather than calling
|
// message was in flight, we want to discard the reply rather than calling
|
||||||
// setState to update our non-existent appearance.
|
// setState to update our non-existent appearance.
|
||||||
if (!mounted) return;
|
if (!mounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_veilidVersion = veilidVersion;
|
_veilidVersion = veilidVersion;
|
||||||
@ -67,8 +69,7 @@ class _MyAppState extends State<MyApp> with UiLoggy {
|
|||||||
Object? error;
|
Object? error;
|
||||||
final backtrace = log.backtrace;
|
final backtrace = log.backtrace;
|
||||||
if (backtrace != null) {
|
if (backtrace != null) {
|
||||||
stackTrace =
|
stackTrace = StackTrace.fromString('$backtrace\n${StackTrace.current}');
|
||||||
StackTrace.fromString("$backtrace\n${StackTrace.current.toString()}");
|
|
||||||
error = 'embedded stack trace for ${log.logLevel} ${log.message}';
|
error = 'embedded stack trace for ${log.logLevel} ${log.message}';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,17 +93,17 @@ class _MyAppState extends State<MyApp> with UiLoggy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> processUpdates() async {
|
Future<void> processUpdates() async {
|
||||||
var stream = _updateStream;
|
final stream = _updateStream;
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
await for (final update in stream) {
|
await for (final update in stream) {
|
||||||
if (update is VeilidLog) {
|
if (update is VeilidLog) {
|
||||||
await processLog(update);
|
await processLog(update);
|
||||||
} else if (update is VeilidAppMessage) {
|
} else if (update is VeilidAppMessage) {
|
||||||
loggy.info("AppMessage: ${jsonEncode(update)}");
|
loggy.info('AppMessage: ${jsonEncode(update)}');
|
||||||
} else if (update is VeilidAppCall) {
|
} else if (update is VeilidAppCall) {
|
||||||
loggy.info("AppCall: ${jsonEncode(update)}");
|
loggy.info('AppCall: ${jsonEncode(update)}');
|
||||||
} else {
|
} else {
|
||||||
loggy.trace("Update: ${jsonEncode(update)}");
|
loggy.trace('Update: ${jsonEncode(update)}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,21 +112,24 @@ class _MyAppState extends State<MyApp> with UiLoggy {
|
|||||||
Future<void> toggleStartup(bool startup) async {
|
Future<void> toggleStartup(bool startup) async {
|
||||||
if (startup && !_startedUp) {
|
if (startup && !_startedUp) {
|
||||||
var config = await getDefaultVeilidConfig(
|
var config = await getDefaultVeilidConfig(
|
||||||
isWeb: kIsWeb, programName: "Veilid Plugin Example");
|
isWeb: kIsWeb, programName: 'Veilid Plugin Example');
|
||||||
if (const String.fromEnvironment("DELETE_TABLE_STORE") == "1") {
|
// ignore: do_not_use_environment
|
||||||
|
if (const String.fromEnvironment('DELETE_TABLE_STORE') == '1') {
|
||||||
config = config.copyWith(
|
config = config.copyWith(
|
||||||
tableStore: config.tableStore.copyWith(delete: true));
|
tableStore: config.tableStore.copyWith(delete: true));
|
||||||
}
|
}
|
||||||
if (const String.fromEnvironment("DELETE_PROTECTED_STORE") == "1") {
|
// ignore: do_not_use_environment
|
||||||
|
if (const String.fromEnvironment('DELETE_PROTECTED_STORE') == '1') {
|
||||||
config = config.copyWith(
|
config = config.copyWith(
|
||||||
protectedStore: config.protectedStore.copyWith(delete: true));
|
protectedStore: config.protectedStore.copyWith(delete: true));
|
||||||
}
|
}
|
||||||
if (const String.fromEnvironment("DELETE_BLOCK_STORE") == "1") {
|
// ignore: do_not_use_environment
|
||||||
|
if (const String.fromEnvironment('DELETE_BLOCK_STORE') == '1') {
|
||||||
config = config.copyWith(
|
config = config.copyWith(
|
||||||
blockStore: config.blockStore.copyWith(delete: true));
|
blockStore: config.blockStore.copyWith(delete: true));
|
||||||
}
|
}
|
||||||
|
|
||||||
var updateStream = await Veilid.instance.startupVeilidCore(config);
|
final updateStream = await Veilid.instance.startupVeilidCore(config);
|
||||||
setState(() {
|
setState(() {
|
||||||
_updateStream = updateStream;
|
_updateStream = updateStream;
|
||||||
_updateProcessor = processUpdates();
|
_updateProcessor = processUpdates();
|
||||||
@ -149,8 +153,7 @@ class _MyAppState extends State<MyApp> with UiLoggy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) => Scaffold(
|
||||||
return Scaffold(
|
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text('Veilid Plugin Version $_veilidVersion'),
|
title: Text('Veilid Plugin Version $_veilidVersion'),
|
||||||
),
|
),
|
||||||
@ -166,7 +169,7 @@ class _MyAppState extends State<MyApp> with UiLoggy {
|
|||||||
blurRadius: 4,
|
blurRadius: 4,
|
||||||
)
|
)
|
||||||
]),
|
]),
|
||||||
padding: const EdgeInsets.all(5.0),
|
padding: const EdgeInsets.all(5),
|
||||||
child: Row(children: [
|
child: Row(children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: pad(_debugHistoryWrapper.wrap(
|
child: pad(_debugHistoryWrapper.wrap(
|
||||||
@ -182,12 +185,12 @@ class _MyAppState extends State<MyApp> with UiLoggy {
|
|||||||
_errorText = null;
|
_errorText = null;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onSubmitted: (String v) async {
|
onSubmitted: (v) async {
|
||||||
try {
|
try {
|
||||||
if (v.isEmpty) {
|
if (v.isEmpty) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var res = await Veilid.instance.debug(v);
|
final res = await Veilid.instance.debug(v);
|
||||||
loggy.info(res);
|
loggy.info(res);
|
||||||
setState(() {
|
setState(() {
|
||||||
_debugHistoryWrapper.submit(v);
|
_debugHistoryWrapper.submit(v);
|
||||||
@ -204,7 +207,7 @@ class _MyAppState extends State<MyApp> with UiLoggy {
|
|||||||
const Text('Startup'),
|
const Text('Startup'),
|
||||||
Switch(
|
Switch(
|
||||||
value: _startedUp,
|
value: _startedUp,
|
||||||
onChanged: (bool value) async {
|
onChanged: (value) async {
|
||||||
await toggleStartup(value);
|
await toggleStartup(value);
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
@ -213,28 +216,27 @@ class _MyAppState extends State<MyApp> with UiLoggy {
|
|||||||
const Text('Log Level'),
|
const Text('Log Level'),
|
||||||
DropdownButton<LogLevel>(
|
DropdownButton<LogLevel>(
|
||||||
value: loggy.level.logLevel,
|
value: loggy.level.logLevel,
|
||||||
onChanged: (LogLevel? newLevel) {
|
onChanged: (newLevel) {
|
||||||
setState(() {
|
setState(() {
|
||||||
setRootLogLevel(newLevel);
|
setRootLogLevel(newLevel);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
items: const [
|
items: const [
|
||||||
DropdownMenuItem<LogLevel>(
|
DropdownMenuItem<LogLevel>(
|
||||||
value: LogLevel.error, child: Text("Error")),
|
value: LogLevel.error, child: Text('Error')),
|
||||||
DropdownMenuItem<LogLevel>(
|
DropdownMenuItem<LogLevel>(
|
||||||
value: LogLevel.warning, child: Text("Warning")),
|
value: LogLevel.warning, child: Text('Warning')),
|
||||||
DropdownMenuItem<LogLevel>(
|
DropdownMenuItem<LogLevel>(
|
||||||
value: LogLevel.info, child: Text("Info")),
|
value: LogLevel.info, child: Text('Info')),
|
||||||
DropdownMenuItem<LogLevel>(
|
DropdownMenuItem<LogLevel>(
|
||||||
value: LogLevel.debug, child: Text("Debug")),
|
value: LogLevel.debug, child: Text('Debug')),
|
||||||
DropdownMenuItem<LogLevel>(
|
DropdownMenuItem<LogLevel>(
|
||||||
value: traceLevel, child: Text("Trace")),
|
value: traceLevel, child: Text('Trace')),
|
||||||
DropdownMenuItem<LogLevel>(
|
DropdownMenuItem<LogLevel>(
|
||||||
value: LogLevel.all, child: Text("All")),
|
value: LogLevel.all, child: Text('All')),
|
||||||
]),
|
]),
|
||||||
])),
|
])),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
]));
|
]));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,9 @@ class HistoryWrapper {
|
|||||||
final List<String> _history = [];
|
final List<String> _history = [];
|
||||||
int _historyPosition = 0;
|
int _historyPosition = 0;
|
||||||
final _historyTextEditingController = TextEditingController();
|
final _historyTextEditingController = TextEditingController();
|
||||||
String _historyCurrentEdit = "";
|
String _historyCurrentEdit = '';
|
||||||
|
|
||||||
TextEditingController get controller {
|
TextEditingController get controller => _historyTextEditingController;
|
||||||
return _historyTextEditingController;
|
|
||||||
}
|
|
||||||
|
|
||||||
void submit(String v) {
|
void submit(String v) {
|
||||||
// add to history
|
// add to history
|
||||||
@ -21,14 +19,14 @@ class HistoryWrapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_historyPosition = _history.length;
|
_historyPosition = _history.length;
|
||||||
_historyTextEditingController.text = "";
|
_historyTextEditingController.text = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget wrap(
|
Widget wrap(
|
||||||
void Function(void Function())? stateSetter, TextField textField) {
|
void Function(void Function())? stateSetter, TextField textField) {
|
||||||
void Function(void Function()) setState = stateSetter ?? (x) => x();
|
final setState = stateSetter ?? (x) => x();
|
||||||
return KeyboardListener(
|
return KeyboardListener(
|
||||||
onKeyEvent: (KeyEvent event) {
|
onKeyEvent: (event) {
|
||||||
setState(() {
|
setState(() {
|
||||||
if (event.runtimeType == KeyDownEvent &&
|
if (event.runtimeType == KeyDownEvent &&
|
||||||
event.logicalKey == LogicalKeyboardKey.arrowUp) {
|
event.logicalKey == LogicalKeyboardKey.arrowUp) {
|
||||||
@ -55,7 +53,7 @@ class HistoryWrapper {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
focusNode: FocusNode(onKeyEvent: (FocusNode node, KeyEvent event) {
|
focusNode: FocusNode(onKeyEvent: (node, event) {
|
||||||
if (event.logicalKey == LogicalKeyboardKey.arrowDown ||
|
if (event.logicalKey == LogicalKeyboardKey.arrowDown ||
|
||||||
event.logicalKey == LogicalKeyboardKey.arrowUp) {
|
event.logicalKey == LogicalKeyboardKey.arrowUp) {
|
||||||
return KeyEventResult.handled;
|
return KeyEventResult.handled;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// ignore_for_file: prefer_single_quotes
|
||||||
|
|
||||||
import 'package:ansicolor/ansicolor.dart';
|
import 'package:ansicolor/ansicolor.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -17,39 +17,39 @@ class LogTerminal extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _LogTerminalState extends State<LogTerminal> {
|
class _LogTerminalState extends State<LogTerminal> {
|
||||||
final terminal = Terminal(
|
final _terminal = Terminal(
|
||||||
maxLines: 10000,
|
maxLines: 10000,
|
||||||
);
|
);
|
||||||
|
|
||||||
final terminalController = TerminalController();
|
final _terminalController = TerminalController();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
terminal.setLineFeedMode(true);
|
_terminal.setLineFeedMode(true);
|
||||||
globalTerminalPrinter.setCallback((log) {
|
globalTerminalPrinter.setCallback((log) {
|
||||||
terminal.write('${log.pretty()}\n');
|
_terminal.write('${log.pretty()}\n');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => TerminalView(
|
Widget build(BuildContext context) => TerminalView(
|
||||||
terminal,
|
_terminal,
|
||||||
textStyle: kDefaultTerminalStyle,
|
textStyle: kDefaultTerminalStyle,
|
||||||
controller: terminalController,
|
controller: _terminalController,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
backgroundOpacity: 0.9,
|
backgroundOpacity: 0.9,
|
||||||
onSecondaryTapDown: (details, offset) async {
|
onSecondaryTapDown: (details, offset) async {
|
||||||
final selection = terminalController.selection;
|
final selection = _terminalController.selection;
|
||||||
if (selection != null) {
|
if (selection != null) {
|
||||||
final text = terminal.buffer.getText(selection);
|
final text = _terminal.buffer.getText(selection);
|
||||||
terminalController.clearSelection();
|
_terminalController.clearSelection();
|
||||||
await Clipboard.setData(ClipboardData(text: text));
|
await Clipboard.setData(ClipboardData(text: text));
|
||||||
} else {
|
} else {
|
||||||
final data = await Clipboard.getData('text/plain');
|
final data = await Clipboard.getData('text/plain');
|
||||||
final text = data?.text;
|
final text = data?.text;
|
||||||
if (text != null) {
|
if (text != null) {
|
||||||
terminal.paste(text);
|
_terminal.paste(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1,32 +1,9 @@
|
|||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter_acrylic/flutter_acrylic.dart';
|
|
||||||
|
|
||||||
import 'veilid_theme.dart';
|
|
||||||
import 'log.dart';
|
|
||||||
import 'app.dart';
|
import 'app.dart';
|
||||||
|
import 'log.dart';
|
||||||
import 'veilid_init.dart';
|
import 'veilid_init.dart';
|
||||||
|
import 'veilid_theme.dart';
|
||||||
/////////////////////////////// Acrylic
|
|
||||||
|
|
||||||
bool get isDesktop {
|
|
||||||
if (kIsWeb) return false;
|
|
||||||
return [
|
|
||||||
TargetPlatform.windows,
|
|
||||||
TargetPlatform.linux,
|
|
||||||
TargetPlatform.macOS,
|
|
||||||
].contains(defaultTargetPlatform);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> setupAcrylic() async {
|
|
||||||
await Window.initialize();
|
|
||||||
await Window.makeTitlebarTransparent();
|
|
||||||
await Window.setEffect(
|
|
||||||
effect: WindowEffect.aero, color: const Color(0xFFFFFFFF));
|
|
||||||
await Window.setBlurViewState(MacOSBlurViewState.active);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////// Entrypoint
|
/////////////////////////////// Entrypoint
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -5,7 +5,7 @@ import 'package:veilid/veilid.dart';
|
|||||||
// Call only once.
|
// Call only once.
|
||||||
void veilidInit() {
|
void veilidInit() {
|
||||||
if (kIsWeb) {
|
if (kIsWeb) {
|
||||||
var platformConfig = const VeilidWASMConfig(
|
const platformConfig = VeilidWASMConfig(
|
||||||
logging: VeilidWASMConfigLogging(
|
logging: VeilidWASMConfigLogging(
|
||||||
performance: VeilidWASMConfigLoggingPerformance(
|
performance: VeilidWASMConfigLoggingPerformance(
|
||||||
enabled: true,
|
enabled: true,
|
||||||
@ -16,7 +16,7 @@ void veilidInit() {
|
|||||||
enabled: true, level: VeilidConfigLogLevel.info)));
|
enabled: true, level: VeilidConfigLogLevel.info)));
|
||||||
Veilid.instance.initializeVeilidCore(platformConfig.toJson());
|
Veilid.instance.initializeVeilidCore(platformConfig.toJson());
|
||||||
} else {
|
} else {
|
||||||
var platformConfig = const VeilidFFIConfig(
|
const platformConfig = VeilidFFIConfig(
|
||||||
logging: VeilidFFIConfigLogging(
|
logging: VeilidFFIConfigLogging(
|
||||||
terminal: VeilidFFIConfigLoggingTerminal(
|
terminal: VeilidFFIConfigLoggingTerminal(
|
||||||
enabled: false,
|
enabled: false,
|
||||||
@ -25,8 +25,8 @@ void veilidInit() {
|
|||||||
otlp: VeilidFFIConfigLoggingOtlp(
|
otlp: VeilidFFIConfigLoggingOtlp(
|
||||||
enabled: false,
|
enabled: false,
|
||||||
level: VeilidConfigLogLevel.trace,
|
level: VeilidConfigLogLevel.trace,
|
||||||
grpcEndpoint: "localhost:4317",
|
grpcEndpoint: 'localhost:4317',
|
||||||
serviceName: "VeilidExample"),
|
serviceName: 'VeilidExample'),
|
||||||
api: VeilidFFIConfigLoggingApi(
|
api: VeilidFFIConfigLoggingApi(
|
||||||
enabled: true, level: VeilidConfigLogLevel.info)));
|
enabled: true, level: VeilidConfigLogLevel.info)));
|
||||||
Veilid.instance.initializeVeilidCore(platformConfig.toJson());
|
Veilid.instance.initializeVeilidCore(platformConfig.toJson());
|
||||||
|
@ -241,62 +241,49 @@ const MaterialColor materialPopComplementaryColor =
|
|||||||
|
|
||||||
const kDefaultSpacingFactor = 4.0;
|
const kDefaultSpacingFactor = 4.0;
|
||||||
|
|
||||||
const kDefaultMonoTerminalFontFamily = "Fira Code";
|
const kDefaultMonoTerminalFontFamily = 'Fira Code';
|
||||||
const kDefaultMonoTerminalFontHeight = 1.2;
|
const kDefaultMonoTerminalFontHeight = 1.2;
|
||||||
const kDefaultMonoTerminalFontSize = 12.0;
|
const kDefaultMonoTerminalFontSize = 12.0;
|
||||||
|
|
||||||
double spacingFactor(double multiplier) {
|
double spacingFactor(double multiplier) => multiplier * kDefaultSpacingFactor;
|
||||||
return multiplier * kDefaultSpacingFactor;
|
|
||||||
}
|
|
||||||
|
|
||||||
Padding pad(Widget child) {
|
Padding pad(Widget child) =>
|
||||||
return Padding(
|
Padding(padding: const EdgeInsets.all(kDefaultSpacingFactor), child: child);
|
||||||
padding: const EdgeInsets.all(kDefaultSpacingFactor), child: child);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
// Theme
|
// Theme
|
||||||
|
|
||||||
InputDecoration newInputDecoration(
|
InputDecoration newInputDecoration(
|
||||||
String labelText, String? errorText, bool enabled) {
|
String labelText, String? errorText, bool enabled) =>
|
||||||
return InputDecoration(
|
InputDecoration(
|
||||||
labelText: labelText,
|
labelText: labelText,
|
||||||
errorText: errorText,
|
errorText: errorText,
|
||||||
filled: !enabled,
|
filled: !enabled,
|
||||||
fillColor: materialPrimaryColor.shade300.withOpacity(0.1));
|
fillColor: materialPrimaryColor.shade300.withOpacity(0.1));
|
||||||
}
|
|
||||||
|
|
||||||
InputDecorationTheme newInputDecorationTheme() {
|
InputDecorationTheme newInputDecorationTheme() => InputDecorationTheme(
|
||||||
return InputDecorationTheme(
|
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderSide:
|
borderSide: BorderSide(color: materialPrimaryColor.shade300)),
|
||||||
BorderSide(color: materialPrimaryColor.shade300, width: 1.0)),
|
|
||||||
disabledBorder: OutlineInputBorder(
|
disabledBorder: OutlineInputBorder(
|
||||||
borderSide:
|
borderSide: BorderSide(color: materialPrimaryColor.shade600)),
|
||||||
BorderSide(color: materialPrimaryColor.shade600, width: 1.0)),
|
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderSide:
|
borderSide: BorderSide(color: materialPrimaryColor.shade900)),
|
||||||
BorderSide(color: materialPrimaryColor.shade900, width: 1.0)),
|
|
||||||
errorBorder: OutlineInputBorder(
|
errorBorder: OutlineInputBorder(
|
||||||
borderSide: BorderSide(color: materialPopColor.shade800, width: 1.0)),
|
borderSide: BorderSide(color: materialPopColor.shade800)),
|
||||||
focusedErrorBorder: OutlineInputBorder(
|
focusedErrorBorder: OutlineInputBorder(
|
||||||
borderSide: BorderSide(color: materialPopColor.shade600, width: 1.0)),
|
borderSide: BorderSide(color: materialPopColor.shade600)),
|
||||||
errorStyle: TextStyle(
|
errorStyle: TextStyle(
|
||||||
color: materialPopColor.shade600,
|
color: materialPopColor.shade600,
|
||||||
letterSpacing: 1.1,
|
letterSpacing: 1.1,
|
||||||
),
|
),
|
||||||
floatingLabelBehavior: FloatingLabelBehavior.auto,
|
|
||||||
floatingLabelStyle: TextStyle(
|
floatingLabelStyle: TextStyle(
|
||||||
color: materialPrimaryColor.shade900,
|
color: materialPrimaryColor.shade900,
|
||||||
letterSpacing: 1.1,
|
letterSpacing: 1.1,
|
||||||
));
|
));
|
||||||
}
|
|
||||||
|
|
||||||
ThemeData newVeilidTheme() {
|
ThemeData newVeilidTheme() => ThemeData(
|
||||||
return ThemeData(
|
|
||||||
primarySwatch: materialPrimaryColor,
|
primarySwatch: materialPrimaryColor,
|
||||||
secondaryHeaderColor: materialSecondaryColor,
|
secondaryHeaderColor: materialSecondaryColor,
|
||||||
visualDensity: VisualDensity.adaptivePlatformDensity,
|
visualDensity: VisualDensity.adaptivePlatformDensity,
|
||||||
inputDecorationTheme: newInputDecorationTheme(),
|
inputDecorationTheme: newInputDecorationTheme(),
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
@ -425,10 +425,10 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
|
||||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
|
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = XP5LBLT7M7;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@ -559,10 +559,10 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
|
||||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
|
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = XP5LBLT7M7;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@ -587,10 +587,10 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
|
||||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
|
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = XP5LBLT7M7;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
|
@ -6,11 +6,15 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>com.apple.security.cs.allow-jit</key>
|
<key>com.apple.security.cs.allow-jit</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>com.apple.security.network.server</key>
|
<key>com.apple.security.files.user-selected.read-write</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>com.apple.security.network.client</key>
|
<key>com.apple.security.network.client</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>com.apple.security.files.user-selected.read-write</key>
|
<key>com.apple.security.network.server</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>keychain-access-groups</key>
|
||||||
|
<array>
|
||||||
|
<string>$(AppIdentifierPrefix)com.veilid.example</string>
|
||||||
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
@ -4,11 +4,15 @@
|
|||||||
<dict>
|
<dict>
|
||||||
<key>com.apple.security.app-sandbox</key>
|
<key>com.apple.security.app-sandbox</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>com.apple.security.network.server</key>
|
<key>com.apple.security.files.user-selected.read-write</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>com.apple.security.network.client</key>
|
<key>com.apple.security.network.client</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>com.apple.security.files.user-selected.read-write</key>
|
<key>com.apple.security.network.server</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>keychain-access-groups</key>
|
||||||
|
<array>
|
||||||
|
<string>$(AppIdentifierPrefix)com.veilid.example</string>
|
||||||
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
@ -3,7 +3,8 @@ import 'dart:async';
|
|||||||
import 'package:async_tools/async_tools.dart';
|
import 'package:async_tools/async_tools.dart';
|
||||||
import 'package:veilid/veilid.dart';
|
import 'package:veilid/veilid.dart';
|
||||||
|
|
||||||
bool kIsWeb = bool.fromEnvironment('dart.library.js_util');
|
// ignore: do_not_use_environment
|
||||||
|
bool kIsWeb = const bool.fromEnvironment('dart.library.js_util');
|
||||||
|
|
||||||
abstract class VeilidFixture {
|
abstract class VeilidFixture {
|
||||||
Future<void> setUp();
|
Future<void> setUp();
|
||||||
@ -18,8 +19,7 @@ class DefaultVeilidFixture implements VeilidFixture {
|
|||||||
|
|
||||||
StreamSubscription<VeilidUpdate>? _veilidUpdateSubscription;
|
StreamSubscription<VeilidUpdate>? _veilidUpdateSubscription;
|
||||||
Stream<VeilidUpdate>? _veilidUpdateStream;
|
Stream<VeilidUpdate>? _veilidUpdateStream;
|
||||||
final StreamController<VeilidUpdate> _updateStreamController =
|
late final StreamController<VeilidUpdate> _updateStreamController;
|
||||||
StreamController.broadcast();
|
|
||||||
|
|
||||||
static final _fixtureMutex = Mutex();
|
static final _fixtureMutex = Mutex();
|
||||||
final String programName;
|
final String programName;
|
||||||
@ -27,9 +27,10 @@ class DefaultVeilidFixture implements VeilidFixture {
|
|||||||
@override
|
@override
|
||||||
Future<void> setUp() async {
|
Future<void> setUp() async {
|
||||||
await _fixtureMutex.acquire();
|
await _fixtureMutex.acquire();
|
||||||
|
|
||||||
assert(_veilidUpdateStream == null, 'should not set up fixture twice');
|
assert(_veilidUpdateStream == null, 'should not set up fixture twice');
|
||||||
|
|
||||||
|
_updateStreamController = StreamController.broadcast();
|
||||||
|
|
||||||
final ignoreLogTargetsStr =
|
final ignoreLogTargetsStr =
|
||||||
// ignore: do_not_use_environment
|
// ignore: do_not_use_environment
|
||||||
const String.fromEnvironment('IGNORE_LOG_TARGETS').trim();
|
const String.fromEnvironment('IGNORE_LOG_TARGETS').trim();
|
||||||
@ -163,6 +164,8 @@ class DefaultVeilidFixture implements VeilidFixture {
|
|||||||
await Veilid.instance.shutdownVeilidCore();
|
await Veilid.instance.shutdownVeilidCore();
|
||||||
await cancelFut;
|
await cancelFut;
|
||||||
|
|
||||||
|
await _updateStreamController.close();
|
||||||
|
|
||||||
_veilidUpdateSubscription = null;
|
_veilidUpdateSubscription = null;
|
||||||
_veilidUpdateStream = null;
|
_veilidUpdateStream = null;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user