blob: 44ed7a9b110443472db0885364435832599f597d [file] [log] [blame]
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:typed_data';
import 'package:async/async.dart';
import 'package:stream_channel/stream_channel.dart';
import 'package:test/test.dart';
import 'package:web_socket/web_socket.dart';
import 'package:web_socket_channel/adapter_web_socket_channel.dart';
import 'package:web_socket_channel/src/exception.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
import 'echo_server_vm.dart'
if (dart.library.js_interop) 'echo_server_web.dart';
void main() {
group('AdapterWebSocketChannel', () {
late Uri uri;
late StreamChannel<Object?> httpServerChannel;
late StreamQueue<Object?> httpServerQueue;
setUp(() async {
httpServerChannel = await startServer();
httpServerQueue = StreamQueue(httpServerChannel.stream);
// When run under dart2wasm, JSON numbers are always returned as [double].
final port = ((await httpServerQueue.next) as num).toInt();
uri = Uri.parse('ws://localhost:$port');
});
tearDown(() async {
httpServerChannel.sink.add(null);
});
test('failed connect', () async {
final channel =
AdapterWebSocketChannel.connect(Uri.parse('ws://notahost'));
await expectLater(
channel.ready, throwsA(isA<WebSocketChannelException>()));
});
test('good connect', () async {
final channel = AdapterWebSocketChannel.connect(uri);
await expectLater(channel.ready, completes);
await channel.sink.close();
});
test('echo empty text', () async {
final channel = AdapterWebSocketChannel.connect(uri);
await expectLater(channel.ready, completes);
channel.sink.add('');
expect(await channel.stream.first, '');
await channel.sink.close();
});
test('echo empty binary', () async {
final channel = AdapterWebSocketChannel.connect(uri);
await expectLater(channel.ready, completes);
channel.sink.add(Uint8List.fromList(<int>[]));
expect(await channel.stream.first, isEmpty);
await channel.sink.close();
});
test('echo hello', () async {
final channel = AdapterWebSocketChannel.connect(uri);
await expectLater(channel.ready, completes);
channel.sink.add('hello');
expect(await channel.stream.first, 'hello');
await channel.sink.close();
});
test('echo [1,2,3]', () async {
final channel = AdapterWebSocketChannel.connect(uri);
await expectLater(channel.ready, completes);
channel.sink.add([1, 2, 3]);
expect(await channel.stream.first, [1, 2, 3]);
await channel.sink.close();
});
test('alternative string and binary request and response', () async {
final channel = AdapterWebSocketChannel.connect(uri);
await expectLater(channel.ready, completes);
channel.sink.add('This count says:');
channel.sink.add([1, 2, 3]);
channel.sink.add('And then:');
channel.sink.add([4, 5, 6]);
expect(await channel.stream.take(4).toList(), [
'This count says:',
[1, 2, 3],
'And then:',
[4, 5, 6]
]);
});
test('remote close', () async {
final channel = AdapterWebSocketChannel.connect(uri);
await expectLater(channel.ready, completes);
channel.sink.add('close'); // Asks the peer to close.
// Give the server time to send a close frame.
await Future<void>.delayed(const Duration(seconds: 1));
expect(channel.closeCode, 3001);
expect(channel.closeReason, 'you asked me to');
await channel.sink.close();
});
test('local close', () async {
final channel = AdapterWebSocketChannel.connect(uri);
await expectLater(channel.ready, completes);
await channel.sink.close(3005, 'please close');
expect(channel.closeCode, null);
expect(channel.closeReason, null);
});
test('constructor with WebSocket', () async {
final webSocket = await WebSocket.connect(uri);
final channel = AdapterWebSocketChannel(webSocket);
await expectLater(channel.ready, completes);
channel.sink.add('This count says:');
channel.sink.add([1, 2, 3]);
channel.sink.add('And then:');
channel.sink.add([4, 5, 6]);
expect(await channel.stream.take(4).toList(), [
'This count says:',
[1, 2, 3],
'And then:',
[4, 5, 6]
]);
});
test('constructor with Future<WebSocket>', () async {
final webSocketFuture = WebSocket.connect(uri);
final channel = AdapterWebSocketChannel(webSocketFuture);
await expectLater(channel.ready, completes);
channel.sink.add('This count says:');
channel.sink.add([1, 2, 3]);
channel.sink.add('And then:');
channel.sink.add([4, 5, 6]);
expect(await channel.stream.take(4).toList(), [
'This count says:',
[1, 2, 3],
'And then:',
[4, 5, 6]
]);
});
});
}