Skip to content

Commit 2929f7a

Browse files
committed
add test cases
1 parent fba381d commit 2929f7a

14 files changed

+328
-48
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ dio/.dart_tool/
1717
dio/.pub/
1818
dio/.idea/
1919
dio/.exampl
20+
dio/coverage
2021

2122
# plugins
2223
plugins/cookie_manager/.packages
@@ -29,4 +30,4 @@ plugins/http2_adapter/.packages
2930
plugins/http2_adapter/.dart_tool/
3031
plugins/http2_adapter/.pub/
3132
plugins/http2_adapter/.idea/
32-
plugins/http2_adapter/.exampl
33+
plugins/http2_adapter/.exampl

dio/lib/src/adapters/io_adapter.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class DefaultHttpClientAdapter implements HttpClientAdapter {
8686
stream,
8787
responseStream.statusCode,
8888
headers: headers,
89-
isRedirect: responseStream.isRedirect,
89+
isRedirect: responseStream.isRedirect||responseStream.redirects.isNotEmpty,
9090
redirects: responseStream.redirects
9191
.map((e) => RedirectRecord(e.statusCode, e.method, e.location))
9292
.toList(),

dio/lib/src/form_data.dart

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ class FormData {
1010
static const String _BOUNDARY_PRE_TAG = '--dio-boundary-';
1111
static const _BOUNDARY_LENGTH = _BOUNDARY_PRE_TAG.length + 10;
1212

13-
/// The boundary of FormData, it consists of a constant prefix and a random
14-
/// postfix to assure the the boundary unpredictable and unique, each FormData
15-
/// instance will be different. And you can custom it by yourself.
1613
String _boundary;
1714

15+
/// The boundary of FormData, it consists of a constant prefix and a random
16+
/// postfix to assure the the boundary unpredictable and unique, each FormData
17+
/// instance will be different.
1818
String get boundary => _boundary;
1919

2020
final _newlineRegExp = RegExp(r'\r\n|\r|\n');
@@ -154,6 +154,6 @@ class FormData {
154154

155155
///Transform the entire FormData contents as a list of bytes asynchronously.
156156
Future<List<int>> readAsBytes() {
157-
return finalize().reduce((a, b) => [...a, ...b]);
157+
return Future(()=>finalize().reduce((a, b) => [...a, ...b]));
158158
}
159159
}

dio/lib/src/headers.dart

-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ class Headers {
4949
var arr = this[name];
5050
if (arr == null) return set(name, value);
5151
arr.add(value);
52-
set(name, arr.join(','));
5352
}
5453

5554
/// Sets a header. The header named [name] will have all its values

dio/lib/src/options.dart

+4-4
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,8 @@ class RequestOptions extends Options {
220220
ResponseType responseType,
221221
String contentType,
222222
ValidateStatus validateStatus,
223-
bool receiveDataWhenStatusError = true,
224-
bool followRedirects = true,
223+
bool receiveDataWhenStatusError,
224+
bool followRedirects,
225225
int maxRedirects,
226226
RequestEncoder requestEncoder,
227227
ResponseDecoder responseDecoder,
@@ -260,8 +260,8 @@ class RequestOptions extends Options {
260260
ResponseType responseType,
261261
String contentType,
262262
ValidateStatus validateStatus,
263-
bool receiveDataWhenStatusError = true,
264-
bool followRedirects = true,
263+
bool receiveDataWhenStatusError,
264+
bool followRedirects,
265265
int maxRedirects,
266266
RequestEncoder requestEncoder,
267267
ResponseDecoder responseDecoder,

dio/pubspec.yaml

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: dio
22
description: A powerful Http client for Dart, which supports Interceptors, FormData, Request Cancellation, File Downloading, Timeout etc.
3-
version: 3.0.9
3+
version: 3.0.10
44
homepage: https://github.com/flutterchina/dio
55

66
environment:
@@ -12,5 +12,8 @@ dependencies:
1212

1313
dev_dependencies:
1414
test: ^1.5.1
15-
pedantic: '1.1.0'
15+
pedantic: ^1.8.0
16+
test_coverage: ^0.4.1
17+
flutter_test:
18+
sdk: flutter
1619

dio/test/basic_test.dart

+115-2
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,136 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44
@TestOn('vm')
5-
65
import 'dart:async';
76
import 'dart:io';
87
import 'package:dio/dio.dart';
98
import 'package:test/test.dart';
109

1110
void main() {
11+
test('#test options', () {
12+
var map = {'a': '5'};
13+
var mapOverride = {'b': '6'};
14+
var baseOptions = BaseOptions(
15+
connectTimeout: 2000,
16+
receiveTimeout: 2000,
17+
sendTimeout: 2000,
18+
baseUrl: 'http://localhost',
19+
queryParameters: map,
20+
extra: map,
21+
headers: map,
22+
contentType: "application/json",
23+
followRedirects: false,
24+
);
25+
var opt1 = baseOptions.merge(
26+
method: 'post',
27+
receiveTimeout: 3000,
28+
sendTimeout: 3000,
29+
baseUrl: 'https://flutterchina.club',
30+
extra: mapOverride,
31+
headers: mapOverride,
32+
contentType: 'text/html',
33+
);
34+
assert(opt1.method == "post");
35+
assert(opt1.receiveTimeout == 3000);
36+
assert(opt1.connectTimeout == 2000);
37+
assert(opt1.followRedirects == false);
38+
assert(opt1.baseUrl == 'https://flutterchina.club');
39+
assert(opt1.headers['b'] == '6');
40+
assert(opt1.extra['b'] == '6');
41+
assert(opt1.queryParameters['b'] == null);
42+
assert(opt1.contentType == 'text/html');
43+
44+
var opt2 = Options(
45+
method: 'get',
46+
receiveTimeout: 2000,
47+
sendTimeout: 2000,
48+
extra: map,
49+
headers: map,
50+
contentType: "application/json",
51+
followRedirects: false,
52+
);
53+
var opt3 = opt2.merge(
54+
method: 'post',
55+
receiveTimeout: 3000,
56+
sendTimeout: 3000,
57+
extra: mapOverride,
58+
headers: mapOverride,
59+
contentType: 'text/html',
60+
);
61+
assert(opt3.method == "post");
62+
assert(opt3.receiveTimeout == 3000);
63+
assert(opt3.followRedirects == false);
64+
assert(opt3.headers['b'] == '6');
65+
assert(opt3.extra['b'] == '6');
66+
assert(opt3.contentType == 'text/html');
67+
68+
var opt4 = RequestOptions(
69+
sendTimeout: 2000,
70+
followRedirects: false,
71+
);
72+
var opt5 = opt4.merge(
73+
method: 'post',
74+
receiveTimeout: 3000,
75+
sendTimeout: 3000,
76+
extra: mapOverride,
77+
headers: mapOverride,
78+
data: "xx=5",
79+
path: '/',
80+
contentType: 'text/html',
81+
);
82+
assert(opt5.method == "post");
83+
assert(opt5.receiveTimeout == 3000);
84+
assert(opt5.followRedirects == false);
85+
assert(opt5.contentType == 'text/html');
86+
assert(opt5.headers['b'] == '6');
87+
assert(opt5.extra['b'] == '6');
88+
assert(opt5.data == 'xx=5');
89+
assert(opt5.path == '/');
90+
});
91+
92+
test('#test headers', () {
93+
var headers = Headers.fromMap({
94+
"set-cookie": ['k=v', 'k1=v1'],
95+
'content-length': ['200'],
96+
'test': ['1', '2'],
97+
});
98+
headers.add('SET-COOKIE', 'k2=v2');
99+
assert(headers.value('content-length') == '200');
100+
expect(Future(() => headers.value('test')), throwsException);
101+
assert(headers['set-cookie'].length == 3);
102+
headers.remove("set-cookie", 'k=v');
103+
assert(headers['set-cookie'].length == 2);
104+
headers.removeAll('set-cookie');
105+
assert(headers['set-cookie'] == null);
106+
var ls = [];
107+
headers.forEach((k, list) {
108+
ls.addAll(list);
109+
});
110+
assert(ls.length == 3);
111+
assert(headers.toString() == "content-length: 200\ntest: 1\ntest: 2\n");
112+
headers.set('content-length', '300');
113+
assert(headers.value('content-length') == '300');
114+
headers.set('content-length', ['400']);
115+
assert(headers.value('content-length') == '400');
116+
117+
var headers1 = Headers();
118+
headers1.set('xx', 'v');
119+
assert(headers1.value('xx') == 'v');
120+
headers1.clear();
121+
assert(headers1.map.isEmpty == true);
122+
});
123+
12124
test('#send with an invalid URL', () {
13125
expect(Dio().get('http://http.invalid').catchError((e) => throw e.error),
14126
throwsA(const TypeMatcher<SocketException>()));
15127
});
128+
16129
test('#cancellation', () async {
17130
var dio = Dio();
18131
CancelToken token = CancelToken();
19132
Timer(Duration(milliseconds: 10), () {
20133
token.cancel('cancelled');
134+
dio.httpClientAdapter.close(force: true);
21135
});
22136

23137
var url = 'https://accounts.google.com';
@@ -28,7 +142,6 @@ void main() {
28142
throwsA(isTrue));
29143
});
30144

31-
32145
test('#url encode ', () {
33146
var data = {
34147
'a': '你好',

dio/test/download_test.dart

+69-8
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,80 @@ import 'utils.dart';
1212
void main() {
1313
setUp(startServer);
1414
tearDown(stopServer);
15-
test('#test download', () async {
15+
test('#test download1', () async {
1616
const savePath = '../_download_test.md';
1717
var dio = Dio();
1818
dio.options.baseUrl = serverUrl.toString();
19-
await dio.download('/download', savePath, // disable gzip
20-
onReceiveProgress: (received, total) {
21-
if (total != -1) {
22-
print((received / total * 100).toStringAsFixed(0) + '%');
23-
}
24-
});
19+
await dio.download(
20+
'/download', savePath, // disable gzip
21+
onReceiveProgress: (received, total) {
22+
// ignore progress
23+
},
24+
);
2525

2626
var f = File(savePath);
2727
expect(f.readAsStringSync(), equals('I am a text file'));
28-
f.delete(recursive: false);
28+
f.deleteSync(recursive: false);
29+
});
30+
31+
test('#test download2', () async {
32+
const savePath = '../_download_test.md';
33+
var dio = Dio();
34+
dio.options.baseUrl = serverUrl.toString();
35+
await dio.downloadUri(
36+
serverUrl.replace(path: '/download'),
37+
(header) => savePath, // disable gzip
38+
);
39+
40+
var f = File(savePath);
41+
expect(f.readAsStringSync(), equals('I am a text file'));
42+
f.deleteSync(recursive: false);
43+
});
44+
45+
test('#test download error', () async {
46+
const savePath = '../_download_test.md';
47+
var dio = Dio();
48+
dio.options.baseUrl = serverUrl.toString();
49+
Response r =
50+
await dio.download('/error', savePath).catchError((e) => e.response);
51+
assert(r.data == 'error');
52+
r = await dio
53+
.download(
54+
'/error',
55+
savePath,
56+
options: Options(receiveDataWhenStatusError: false),
57+
)
58+
.catchError((e) => e.response);
59+
assert(r.data == null);
60+
});
61+
62+
test('#test download timeout', () async {
63+
const savePath = '../_download_test.md';
64+
var dio = Dio(BaseOptions(
65+
receiveTimeout: 100,
66+
baseUrl: serverUrl.toString(),
67+
));
68+
expect(dio.download('/download', savePath).catchError((e) => throw e.type),
69+
throwsA(DioErrorType.RECEIVE_TIMEOUT));
70+
//print(r);
71+
});
72+
73+
test('#test download cancellation', () async {
74+
const savePath = '../_download_test.md';
75+
var cancelToken = CancelToken();
76+
Future.delayed(Duration(milliseconds: 100), () {
77+
cancelToken.cancel();
78+
});
79+
expect(
80+
Dio()
81+
.download(
82+
serverUrl.toString() + '/download',
83+
savePath,
84+
cancelToken: cancelToken,
85+
)
86+
.catchError((e) => throw e.type),
87+
throwsA(DioErrorType.CANCEL),
88+
);
89+
//print(r);
2990
});
3091
}

dio/test/formdata_test.dart

+28-16
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,42 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44
@TestOn('vm')
5-
65
import 'dart:convert';
76
import 'dart:io';
87
import 'package:dio/dio.dart';
98
import 'package:test/test.dart';
109

1110
void main() {
1211
test('#test FormData', () async {
13-
var fm=FormData.fromMap({
14-
"name": "wendux",
15-
"age": 25,
16-
"file": MultipartFile.fromString("hellow world."),
17-
"files": [
18-
await MultipartFile.fromFile("../dio/test/_testfile",
19-
filename: "1.txt"),
20-
MultipartFile.fromFileSync("../dio/test/_testfile",
21-
filename: "2.txt"),
12+
var fm = FormData.fromMap({
13+
'name': 'wendux',
14+
'age': 25,
15+
'file': MultipartFile.fromString('hellow world.'),
16+
'files': [
17+
await MultipartFile.fromFile('../dio/test/_testfile',
18+
filename: '1.txt'),
19+
MultipartFile.fromFileSync('../dio/test/_testfile', filename: '2.txt'),
2220
]
2321
});
24-
var fmStr=await fm.readAsBytes();
25-
var f=File("../dio/test/_formdata") ;
26-
var content=f.readAsStringSync();
27-
content=content.replaceAll("--dio-boundary-3788753558",fm.boundary);
28-
assert(utf8.decode(fmStr,allowMalformed: true)==content);
29-
});
22+
var fmStr = await fm.readAsBytes();
23+
var f = File('../dio/test/_formdata');
24+
var content = f.readAsStringSync();
25+
content = content.replaceAll('--dio-boundary-3788753558', fm.boundary);
26+
assert(utf8.decode(fmStr, allowMalformed: true) == content);
27+
expect(fm.readAsBytes(),throwsA(const TypeMatcher<StateError>()));
3028

29+
var fm1 = FormData();
30+
fm1.fields.add(MapEntry('name', 'wendux'));
31+
fm1.fields.add(MapEntry('age', '25'));
32+
fm1.files.add(MapEntry('file', MultipartFile.fromString('hellow world.')));
33+
fm1.files.add(MapEntry(
34+
'files[]',
35+
await MultipartFile.fromFile('../dio/test/_testfile', filename: '1.txt'),
36+
));
37+
fm1.files.add(MapEntry(
38+
'files[]',
39+
await MultipartFile.fromFile('../dio/test/_testfile', filename: '2.txt'),
40+
));
41+
assert(fmStr.length==fm1.length);
42+
});
3143
}

0 commit comments

Comments
 (0)