LCOV - code coverage report
Current view: top level - Users/duwen/Documents/code/dio/dio/test - utils.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 66 85 77.6 %
Date: 2021-11-28 14:37:50 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
       2             : // for details. All rights reserved. Use of this source code is governed by a
       3             : // BSD-style license that can be found in the LICENSE file.
       4             : 
       5             : import 'dart:async';
       6             : import 'dart:convert';
       7             : import 'dart:io';
       8             : import 'dart:typed_data';
       9             : import 'package:test/test.dart';
      10             : 
      11             : /// The current server instance.
      12             : HttpServer? _server;
      13             : 
      14           1 : Encoding requiredEncodingForCharset(String charset) =>
      15           1 :     Encoding.getByName(charset) ??
      16           0 :     (throw FormatException('Unsupported encoding "$charset".'));
      17             : 
      18             : /// The URL for the current server instance.
      19           8 : Uri get serverUrl => Uri.parse('http://localhost:${_server?.port}');
      20             : 
      21             : /// Starts a new HTTP server.
      22           2 : Future<void> startServer() async {
      23           4 :   _server = (await HttpServer.bind('localhost', 0))
      24           4 :     ..listen((request) async {
      25           4 :       var path = request.uri.path;
      26           2 :       var response = request.response;
      27             : 
      28           2 :       if (path == '/error') {
      29             :         const content = 'error';
      30             :         response
      31           2 :           ..statusCode = 400
      32           4 :           ..contentLength = content.length
      33           2 :           ..write(content);
      34           2 :         response.close();
      35             :         return;
      36             :       }
      37             : 
      38           2 :       if (path == '/loop') {
      39           0 :         var n = int.parse(request.uri.query);
      40             :         response
      41           0 :           ..statusCode = 302
      42           0 :           ..headers
      43           0 :               .set('location', serverUrl.resolve('/loop?${n + 1}').toString())
      44           0 :           ..contentLength = 0;
      45           0 :         response.close();
      46             :         return;
      47             :       }
      48             : 
      49           2 :       if (path == '/redirect') {
      50             :         response
      51           1 :           ..statusCode = 302
      52           5 :           ..headers.set('location', serverUrl.resolve('/').toString())
      53           1 :           ..contentLength = 0;
      54           1 :         response.close();
      55             :         return;
      56             :       }
      57             : 
      58           2 :       if (path == '/no-content-length') {
      59             :         response
      60           0 :           ..statusCode = 200
      61           0 :           ..contentLength = -1
      62           0 :           ..write('body');
      63           0 :         response.close();
      64             :         return;
      65             :       }
      66             : 
      67           2 :       if (path == '/list') {
      68           3 :         response.headers.contentType = ContentType('application', 'json');
      69             :         response
      70           1 :           ..statusCode = 200
      71           2 :           ..contentLength = -1
      72           1 :           ..write('[1,2,3]');
      73           1 :         response.close();
      74             :         return;
      75             :       }
      76             : 
      77           2 :       if (path == '/download') {
      78             :         const content = 'I am a text file';
      79           2 :         response.headers.set('content-encoding', 'plain');
      80             :         response
      81           1 :           ..statusCode = 200
      82           2 :           ..contentLength = content.length
      83           1 :           ..write(content);
      84             : 
      85           3 :         Future.delayed(Duration(milliseconds: 300), () {
      86           1 :           response.close();
      87             :         });
      88             :         return;
      89             :       }
      90             : 
      91           3 :       var requestBodyBytes = await ByteStream(request).toBytes();
      92           3 :       var encodingName = request.uri.queryParameters['response-encoding'];
      93             :       var outputEncoding = encodingName == null
      94             :           ? ascii
      95           0 :           : requiredEncodingForCharset(encodingName);
      96             : 
      97           2 :       response.headers.contentType =
      98           2 :           ContentType('application', 'json', charset: outputEncoding.name);
      99           2 :       response.headers.set('single', 'value');
     100             : 
     101             :       dynamic requestBody;
     102           1 :       if (requestBodyBytes.isEmpty) {
     103             :         requestBody = null;
     104           3 :       } else if (request.headers.contentType?.charset != null) {
     105             :         var encoding =
     106           4 :             requiredEncodingForCharset(request.headers.contentType!.charset!);
     107           1 :         requestBody = encoding.decode(requestBodyBytes);
     108             :       } else {
     109             :         requestBody = requestBodyBytes;
     110             :       }
     111             : 
     112           1 :       var content = <String, dynamic>{
     113           1 :         'method': request.method,
     114           2 :         'path': request.uri.path,
     115           2 :         'query': request.uri.query,
     116           1 :         'headers': {}
     117             :       };
     118           1 :       if (requestBody != null) content['body'] = requestBody;
     119           3 :       request.headers.forEach((name, values) {
     120             :         // These headers are automatically generated by dart:io, so we don't
     121             :         // want to test them here.
     122           2 :         if (name == 'cookie' || name == 'host') return;
     123             : 
     124           2 :         content['headers'][name] = values;
     125             :       });
     126             : 
     127           1 :       var body = json.encode(content);
     128             :       response
     129           2 :         ..contentLength = body.length
     130           1 :         ..write(body);
     131           1 :       response.close();
     132             :     });
     133             : }
     134             : 
     135             : /// Stops the current HTTP server.
     136           2 : void stopServer() {
     137             :   if (_server != null) {
     138           2 :     _server!.close();
     139             :     _server = null;
     140             :   }
     141             : }
     142             : 
     143             : /// A matcher for functions that throw SocketException.
     144           0 : final Matcher throwsSocketException =
     145             :     throwsA(const TypeMatcher<SocketException>());
     146             : 
     147             : /// A stream of chunks of bytes representing a single piece of data.
     148             : class ByteStream extends StreamView<List<int>> {
     149           2 :   ByteStream(Stream<List<int>> stream) : super(stream);
     150             : 
     151             :   /// Returns a single-subscription byte stream that will emit the given bytes
     152             :   /// in a single chunk.
     153           0 :   factory ByteStream.fromBytes(List<int> bytes) =>
     154           0 :       ByteStream(Stream.fromIterable([bytes]));
     155             : 
     156             :   /// Collects the data of this stream in a [Uint8List].
     157           1 :   Future<Uint8List> toBytes() {
     158           1 :     var completer = Completer<Uint8List>();
     159           1 :     var sink = ByteConversionSink.withCallback(
     160           3 :         (bytes) => completer.complete(Uint8List.fromList(bytes)));
     161           2 :     listen(sink.add,
     162           1 :         onError: completer.completeError,
     163           1 :         onDone: sink.close,
     164             :         cancelOnError: true);
     165           1 :     return completer.future;
     166             :   }
     167             : 
     168             :   /// Collect the data of this stream in a [String], decoded according to
     169             :   /// [encoding], which defaults to `UTF8`.
     170           0 :   Future<String> bytesToString([Encoding encoding = utf8]) =>
     171           0 :       encoding.decodeStream(this);
     172             : 
     173           0 :   Stream<String> toStringStream([Encoding encoding = utf8]) =>
     174           0 :       encoding.decoder.bind(this);
     175             : }

Generated by: LCOV version 1.14