Format tests/standalone/ using 3.8 style.

Change-Id: I4d492a63a41880ef8cd69321372a4853825b9efd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/426321
Reviewed-by: Liam Appelbe <liama@google.com>
Auto-Submit: Bob Nystrom <rnystrom@google.com>
Commit-Queue: Liam Appelbe <liama@google.com>
This commit is contained in:
Robert Nystrom
2025-05-04 17:45:09 -07:00
committed by Commit Queue
parent 81ab0dab3c
commit a323c55162
253 changed files with 10472 additions and 6868 deletions
@@ -13,69 +13,71 @@ main() {
final buildDir = path.dirname(Platform.executable);
final sdkDir = path.dirname(path.dirname(buildDir));
final platformDill = path.join(buildDir, 'vm_platform_strong.dill');
final genKernel =
path.join(sdkDir, 'pkg', 'vm', 'tool', 'gen_kernel$_batchSuffix');
Expect.isTrue(File(genKernel).existsSync(),
"Can't locate gen_kernel$_batchSuffix on this platform");
Expect.isTrue(File(genKernel).existsSync(),
"Can't locate gen_kernel$_batchSuffix on this platform");
final genKernel = path.join(
sdkDir,
'pkg',
'vm',
'tool',
'gen_kernel$_batchSuffix',
);
Expect.isTrue(
File(genKernel).existsSync(),
"Can't locate gen_kernel$_batchSuffix on this platform",
);
Expect.isTrue(
File(genKernel).existsSync(),
"Can't locate gen_kernel$_batchSuffix on this platform",
);
final genSnapshot = path.join(buildDir, 'gen_snapshot$_execSuffix');
Expect.isTrue(File(genSnapshot).existsSync(),
"Can't locate gen_snapshot$_execSuffix on this platform");
Expect.isTrue(
File(genSnapshot).existsSync(),
"Can't locate gen_snapshot$_execSuffix on this platform",
);
final exePath = path.join(buildDir, 'dart$_execSuffix');
Expect.isTrue(File(exePath).existsSync(),
"Can't locate dart$_execSuffix on this platform");
Expect.isTrue(
File(exePath).existsSync(),
"Can't locate dart$_execSuffix on this platform",
);
final powTest = path.join(sdkDir, 'tests', 'standalone', 'pow_test.dart');
Expect.isTrue(File(powTest).existsSync(),
"Can't locate dart$_execSuffix on this platform");
Expect.isTrue(
File(powTest).existsSync(),
"Can't locate dart$_execSuffix on this platform",
);
final d = Directory.systemTemp.createTempSync('aot_tmp');
final kernelOutput = File.fromUri(d.uri.resolve('pow_test.dill')).path;
final aotOutput = File.fromUri(d.uri.resolve('pow_test.aot')).path;
final genKernelResult = runAndPrintOutput(
genKernel,
[
'--aot',
'--platform=$platformDill',
'-o',
kernelOutput,
powTest,
],
);
final genKernelResult = runAndPrintOutput(genKernel, [
'--aot',
'--platform=$platformDill',
'-o',
kernelOutput,
powTest,
]);
Expect.equals(genKernelResult.exitCode, 0);
print("Ran successfully.\n");
final genAotResult = runAndPrintOutput(
genSnapshot,
[
'--snapshot_kind=app-aot-elf',
'--elf=$aotOutput',
kernelOutput,
],
);
final genAotResult = runAndPrintOutput(genSnapshot, [
'--snapshot_kind=app-aot-elf',
'--elf=$aotOutput',
kernelOutput,
]);
Expect.equals(genAotResult.exitCode, 0);
print("Ran successfully.\n");
final runAotDirectlyResult = runAndPrintOutput(
exePath,
[
aotOutput,
],
);
final runAotDirectlyResult = runAndPrintOutput(exePath, [aotOutput]);
Expect.equals(runAotDirectlyResult.exitCode, 255);
Expect.contains(
"pow_test.aot is an AOT snapshot and should be run with 'dartaotruntime'",
runAotDirectlyResult.stderr);
"pow_test.aot is an AOT snapshot and should be run with 'dartaotruntime'",
runAotDirectlyResult.stderr,
);
print('Got expected error result.');
final runAotUsingCommandResult = runAndPrintOutput(
exePath,
[
'run',
aotOutput,
],
);
final runAotUsingCommandResult = runAndPrintOutput(exePath, [
'run',
aotOutput,
]);
Expect.equals(runAotUsingCommandResult.exitCode, 255);
Expect.containsAny(<String>[
"pow_test.aot is an AOT snapshot and should be run with 'dartaotruntime'",
@@ -22,7 +22,7 @@ const int LINE_E = 57;
bar() {
// Keep the 'throw' and its argument on separate lines.
throw // force linebreak with dart format // LINE_A
"Hello, Dwarf!";
"Hello, Dwarf!";
}
@pragma("vm:never-inline")
@@ -67,12 +67,18 @@ Future<void> main() async {
return; // Generated dwarf.so not available on the test device.
}
final dwarf = Dwarf.fromFile(path.join(
final dwarf = Dwarf.fromFile(
path.join(
Platform.environment["TEST_COMPILATION_DIR"]!,
"dwarf_invisible_functions.so"))!;
"dwarf_invisible_functions.so",
),
)!;
await dwarf_stack_trace_test.checkStackTrace(
rawStack, dwarf, expectedCallsInfo);
rawStack,
dwarf,
expectedCallsInfo,
);
}
final expectedCallsInfo = <List<DartCallInfo>>[
@@ -80,44 +86,49 @@ final expectedCallsInfo = <List<DartCallInfo>>[
// into foo (so we'll get information for two calls for that PC address).
[
DartCallInfo(
function: "bar",
filename: "dwarf_stack_trace_invisible_functions_test.dart",
line: LINE_A,
column: 3,
inlined: true),
function: "bar",
filename: "dwarf_stack_trace_invisible_functions_test.dart",
line: LINE_A,
column: 3,
inlined: true,
),
DartCallInfo(
function: "foo",
filename: "dwarf_stack_trace_invisible_functions_test.dart",
line: LINE_B,
column: 3,
inlined: false)
function: "foo",
filename: "dwarf_stack_trace_invisible_functions_test.dart",
line: LINE_B,
column: 3,
inlined: false,
),
],
// Frame 2: call to foo in bazz.
[
DartCallInfo(
function: "bazz",
filename: "dwarf_stack_trace_invisible_functions_test.dart",
line: LINE_C,
column: 3,
inlined: false)
function: "bazz",
filename: "dwarf_stack_trace_invisible_functions_test.dart",
line: LINE_C,
column: 3,
inlined: false,
),
],
// Frame 3: call to bazz in A.method.
[
DartCallInfo(
function: "A.add",
filename: "dwarf_stack_trace_invisible_functions_test.dart",
line: LINE_D,
column: 5,
inlined: false)
function: "A.add",
filename: "dwarf_stack_trace_invisible_functions_test.dart",
line: LINE_D,
column: 5,
inlined: false,
),
],
// Frame 4: the call to foo in main.
[
DartCallInfo(
function: "main",
filename: "dwarf_stack_trace_invisible_functions_test.dart",
line: LINE_E,
column: 8,
inlined: false)
function: "main",
filename: "dwarf_stack_trace_invisible_functions_test.dart",
line: LINE_E,
column: 8,
inlined: false,
),
],
// Don't assume anything about any of the frames below the main,
// as this makes the test too brittle.
@@ -16,7 +16,7 @@ import 'dwarf_stack_trace_test.dart' as base;
bar() {
// Keep the 'throw' and its argument on separate lines.
throw // force linebreak with dart format
"Hello, Dwarf!";
"Hello, Dwarf!";
}
@pragma("vm:never-inline")
@@ -40,8 +40,12 @@ Future<void> main() async {
return; // Generated dwarf.so not available on the test device.
}
final dwarf = Dwarf.fromFile(path.join(
Platform.environment['TEST_COMPILATION_DIR']!, "dwarf_obfuscate.so"))!;
final dwarf = Dwarf.fromFile(
path.join(
Platform.environment['TEST_COMPILATION_DIR']!,
"dwarf_obfuscate.so",
),
)!;
await base.checkStackTrace(rawStack, dwarf, expectedCallsInfo);
}
@@ -51,26 +55,29 @@ final expectedCallsInfo = <List<DartCallInfo>>[
// into foo (so we'll get information for two calls for that PC address).
[
DartCallInfo(
function: "bar",
filename: "dwarf_stack_trace_obfuscate_test.dart",
line: 18,
column: 3,
inlined: true),
function: "bar",
filename: "dwarf_stack_trace_obfuscate_test.dart",
line: 18,
column: 3,
inlined: true,
),
DartCallInfo(
function: "foo",
filename: "dwarf_stack_trace_obfuscate_test.dart",
line: 24,
column: 3,
inlined: false)
function: "foo",
filename: "dwarf_stack_trace_obfuscate_test.dart",
line: 24,
column: 3,
inlined: false,
),
],
// The second frame corresponds to call to foo in main.
[
DartCallInfo(
function: "main",
filename: "dwarf_stack_trace_obfuscate_test.dart",
line: 30,
column: 5,
inlined: false)
function: "main",
filename: "dwarf_stack_trace_obfuscate_test.dart",
line: 30,
column: 5,
inlined: false,
),
],
// Don't assume anything about any of the frames below the call to foo
// in main, as this makes the test too brittle.
+57 -36
View File
@@ -16,7 +16,7 @@ import 'package:path/path.dart' as path;
bar() {
// Keep the 'throw' and its argument on separate lines.
throw // force linebreak with dart format
"Hello, Dwarf!";
"Hello, Dwarf!";
}
@pragma("vm:never-inline")
@@ -41,19 +41,24 @@ Future<void> main() async {
}
final dwarf = Dwarf.fromFile(
path.join(Platform.environment["TEST_COMPILATION_DIR"]!, "dwarf.so"))!;
path.join(Platform.environment["TEST_COMPILATION_DIR"]!, "dwarf.so"),
)!;
await checkStackTrace(rawStack, dwarf, expectedCallsInfo);
}
Future<void> checkStackTrace(String rawStack, Dwarf dwarf,
List<List<DartCallInfo>> expectedCallsInfo) async {
Future<void> checkStackTrace(
String rawStack,
Dwarf dwarf,
List<List<DartCallInfo>> expectedCallsInfo,
) async {
print("");
print("Raw stack trace:");
print(rawStack);
final rawLines =
await Stream.value(rawStack).transform(const LineSplitter()).toList();
final rawLines = await Stream.value(
rawStack,
).transform(const LineSplitter()).toList();
final pcOffsets = collectPCOffsets(rawLines).toList();
Expect.isNotEmpty(pcOffsets);
@@ -73,8 +78,9 @@ Future<void> checkStackTrace(String rawStack, Dwarf dwarf,
print('Isolate start offset: 0x${isolateStart!.toRadixString(16)}');
// The addresses of the stack frames in the separate DWARF debugging info.
final virtualAddresses =
pcOffsets.map((o) => dwarf.virtualAddressOf(o)).toList();
final virtualAddresses = pcOffsets
.map((o) => dwarf.virtualAddressOf(o))
.toList();
print('Virtual addresses from PCOffsets:');
for (final address in virtualAddresses) {
@@ -87,8 +93,10 @@ Future<void> checkStackTrace(String rawStack, Dwarf dwarf,
print('DSO base address: 0x${dsoBase.toRadixString(16)}');
final absoluteIsolateStart = isolateStartAddresses(rawLines).single;
print('Absolute isolate start address: '
'0x${absoluteIsolateStart.toRadixString(16)}');
print(
'Absolute isolate start address: '
'0x${absoluteIsolateStart.toRadixString(16)}',
);
final absolutes = absoluteAddresses(rawLines);
// The relocated addresses of the stack frames in the loaded DSO. These is
@@ -125,19 +133,25 @@ Future<void> checkStackTrace(String rawStack, Dwarf dwarf,
for (final offset in pcOffsets) {
final externalCallInfo = dwarf.callInfoForPCOffset(offset);
Expect.isNotNull(externalCallInfo);
final allCallInfo =
dwarf.callInfoForPCOffset(offset, includeInternalFrames: true);
final allCallInfo = dwarf.callInfoForPCOffset(
offset,
includeInternalFrames: true,
);
Expect.isNotNull(allCallInfo);
for (final call in externalCallInfo!) {
Expect.isTrue(call is DartCallInfo, "got non-Dart call info ${call}");
Expect.isFalse(call.isInternal);
Expect.isTrue(allCallInfo!.contains(call),
"External call info ${call} is not among all calls");
Expect.isTrue(
allCallInfo!.contains(call),
"External call info ${call} is not among all calls",
);
}
for (final call in allCallInfo!) {
if (!call.isInternal) {
Expect.isTrue(externalCallInfo.contains(call),
"External call info ${call} is not among external calls");
Expect.isTrue(
externalCallInfo.contains(call),
"External call info ${call} is not among external calls",
);
}
}
gotCallsInfo.add(externalCallInfo.cast<DartCallInfo>().toList());
@@ -160,8 +174,9 @@ Future<void> checkStackTrace(String rawStack, Dwarf dwarf,
.transform(DwarfStackTraceDecoder(dwarf, includeInternalFrames: false))
.toList();
final gotSymbolizedCalls =
gotSymbolizedLines.where((s) => s.startsWith('#')).toList();
final gotSymbolizedCalls = gotSymbolizedLines
.where((s) => s.startsWith('#'))
.toList();
print("");
print("Symbolized stack trace:");
@@ -178,8 +193,9 @@ Future<void> checkStackTrace(String rawStack, Dwarf dwarf,
// Strip off any unexpected lines, so we can also make sure we didn't get
// unexpected calls prior to those calls we expect.
final gotCallsTrace =
gotSymbolizedCalls.sublist(0, expectedCallCount).join('\n');
final gotCallsTrace = gotSymbolizedCalls
.sublist(0, expectedCallCount)
.join('\n');
Expect.containsInOrder(expectedStrings, gotCallsTrace);
}
@@ -189,33 +205,38 @@ final expectedCallsInfo = <List<DartCallInfo>>[
// into foo (so we'll get information for two calls for that PC address).
[
DartCallInfo(
function: "bar",
filename: "dwarf_stack_trace_test.dart",
line: 17,
column: 3,
inlined: true),
function: "bar",
filename: "dwarf_stack_trace_test.dart",
line: 17,
column: 3,
inlined: true,
),
DartCallInfo(
function: "foo",
filename: "dwarf_stack_trace_test.dart",
line: 23,
column: 3,
inlined: false)
function: "foo",
filename: "dwarf_stack_trace_test.dart",
line: 23,
column: 3,
inlined: false,
),
],
// The second frame corresponds to call to foo in main.
[
DartCallInfo(
function: "main",
filename: "dwarf_stack_trace_test.dart",
line: 29,
column: 5,
inlined: false)
function: "main",
filename: "dwarf_stack_trace_test.dart",
line: 29,
column: 5,
inlined: false,
),
],
// Don't assume anything about any of the frames below the call to foo
// in main, as this makes the test too brittle.
];
void checkFrames(
List<List<DartCallInfo>> gotInfo, List<List<DartCallInfo>> expectedInfo) {
List<List<DartCallInfo>> gotInfo,
List<List<DartCallInfo>> expectedInfo,
) {
// There may be frames below those we check.
Expect.isTrue(gotInfo.length >= expectedInfo.length);
+55 -25
View File
@@ -13,12 +13,16 @@ import "package:expect/expect.dart";
main() {
// User string entry, const.
Expect.isTrue(const bool.hasEnvironment("testFlag"));
Expect.equals("testValue",
const String.fromEnvironment("testFlag", defaultValue: "nonce"));
Expect.equals(
"testValue",
const String.fromEnvironment("testFlag", defaultValue: "nonce"),
);
// User string entry, runtime.
Expect.isTrue(bool.hasEnvironment("testFlag"));
Expect.equals(
"testValue", String.fromEnvironment("testFlag", defaultValue: "nonce"));
"testValue",
String.fromEnvironment("testFlag", defaultValue: "nonce"),
);
// User number entry, const.
Expect.isTrue(const bool.hasEnvironment("numFlag"));
@@ -33,7 +37,9 @@ main() {
Expect.isTrue(const bool.hasEnvironment("boolFlag"));
Expect.equals("false", const String.fromEnvironment("boolFlag"));
Expect.equals(
false, const bool.fromEnvironment("boolFlag", defaultValue: true));
false,
const bool.fromEnvironment("boolFlag", defaultValue: true),
);
// User bool entry, runtime.
Expect.isTrue(bool.hasEnvironment("boolFlag"));
Expect.equals("false", String.fromEnvironment("boolFlag"));
@@ -43,7 +49,9 @@ main() {
Expect.isFalse(const bool.hasEnvironment("noEntry"));
Expect.equals("", const String.fromEnvironment("noEntry"));
Expect.equals(
"nonce", const String.fromEnvironment("noEntry", defaultValue: "nonce"));
"nonce",
const String.fromEnvironment("noEntry", defaultValue: "nonce"),
);
Expect.equals(0, const int.fromEnvironment("noEntry"));
Expect.equals(42, const int.fromEnvironment("noEntry", defaultValue: 42));
Expect.isFalse(const bool.fromEnvironment("noEntry"));
@@ -52,7 +60,9 @@ main() {
Expect.isFalse(bool.hasEnvironment("noEntry"));
Expect.equals("", String.fromEnvironment("noEntry"));
Expect.equals(
"nonce", String.fromEnvironment("noEntry", defaultValue: "nonce"));
"nonce",
String.fromEnvironment("noEntry", defaultValue: "nonce"),
);
Expect.equals(0, int.fromEnvironment("noEntry"));
Expect.equals(42, int.fromEnvironment("noEntry", defaultValue: 42));
Expect.isFalse(bool.fromEnvironment("noEntry"));
@@ -60,57 +70,77 @@ main() {
// General platform library entry, const.
Expect.isTrue(const bool.hasEnvironment("dart.library.core"));
Expect.equals("true",
const String.fromEnvironment("dart.library.core", defaultValue: "nonce"));
Expect.equals(
"true",
const String.fromEnvironment("dart.library.core", defaultValue: "nonce"),
);
Expect.isTrue(
const bool.fromEnvironment("dart.library.core", defaultValue: false));
const bool.fromEnvironment("dart.library.core", defaultValue: false),
);
// General platform library entry, runtime.
Expect.isTrue(bool.hasEnvironment("dart.library.core"));
Expect.equals("true",
String.fromEnvironment("dart.library.core", defaultValue: "nonce"));
Expect.equals(
"true",
String.fromEnvironment("dart.library.core", defaultValue: "nonce"),
);
Expect.isTrue(bool.fromEnvironment("dart.library.core", defaultValue: false));
// Standalone VM-specific library, const.
Expect.isTrue(const bool.hasEnvironment("dart.library.io"));
Expect.equals("true",
const String.fromEnvironment("dart.library.io", defaultValue: "nonce"));
Expect.equals(
"true",
const String.fromEnvironment("dart.library.io", defaultValue: "nonce"),
);
Expect.isTrue(
const bool.fromEnvironment("dart.library.io", defaultValue: false));
const bool.fromEnvironment("dart.library.io", defaultValue: false),
);
// Standalone VM-specific library, runtime.
Expect.isTrue(bool.hasEnvironment("dart.library.io"));
Expect.equals(
"true", String.fromEnvironment("dart.library.io", defaultValue: "nonce"));
"true",
String.fromEnvironment("dart.library.io", defaultValue: "nonce"),
);
Expect.isTrue(bool.fromEnvironment("dart.library.io", defaultValue: false));
// Web-specific library, not available here, const.
Expect.isFalse(const bool.hasEnvironment("dart.library.html"));
Expect.equals("", const String.fromEnvironment("dart.library.html"));
Expect.equals("nonce",
const String.fromEnvironment("dart.library.html", defaultValue: "nonce"));
Expect.equals(
"nonce",
const String.fromEnvironment("dart.library.html", defaultValue: "nonce"),
);
Expect.isFalse(const bool.fromEnvironment("dart.library.html"));
Expect.isTrue(
const bool.fromEnvironment("dart.library.html", defaultValue: true));
const bool.fromEnvironment("dart.library.html", defaultValue: true),
);
// Web-specific library, not available here, runtime.
Expect.isFalse(bool.hasEnvironment("dart.library.html"));
Expect.equals("", String.fromEnvironment("dart.library.html"));
Expect.equals("nonce",
String.fromEnvironment("dart.library.html", defaultValue: "nonce"));
Expect.equals(
"nonce",
String.fromEnvironment("dart.library.html", defaultValue: "nonce"),
);
Expect.isFalse(bool.fromEnvironment("dart.library.html"));
Expect.isTrue(bool.fromEnvironment("dart.library.html", defaultValue: true));
// Non-existing library, const.
Expect.isFalse(const bool.hasEnvironment("dart.library.not"));
Expect.equals("", const String.fromEnvironment("dart.library.not"));
Expect.equals("nonce",
const String.fromEnvironment("dart.library.not", defaultValue: "nonce"));
Expect.equals(
"nonce",
const String.fromEnvironment("dart.library.not", defaultValue: "nonce"),
);
Expect.isFalse(const bool.fromEnvironment("dart.library.not"));
Expect.isTrue(
const bool.fromEnvironment("dart.library.not", defaultValue: true));
const bool.fromEnvironment("dart.library.not", defaultValue: true),
);
// Non-existing library, runtime.
Expect.isFalse(bool.hasEnvironment("dart.library.not"));
Expect.equals("", String.fromEnvironment("dart.library.not"));
Expect.equals("nonce",
String.fromEnvironment("dart.library.not", defaultValue: "nonce"));
Expect.equals(
"nonce",
String.fromEnvironment("dart.library.not", defaultValue: "nonce"),
);
Expect.isFalse(bool.fromEnvironment("dart.library.not"));
Expect.isTrue(bool.fromEnvironment("dart.library.not", defaultValue: true));
}
@@ -10,8 +10,11 @@ import 'dart:io';
main(List<String> arguments) {
int port = int.parse(arguments[0]);
ReceivePort receivePort = new ReceivePort();
Isolate.spawnUri(Uri.parse('http://127.0.0.1:$port/http_isolate_main.dart'),
['hello'], receivePort.sendPort);
Isolate.spawnUri(
Uri.parse('http://127.0.0.1:$port/http_isolate_main.dart'),
['hello'],
receivePort.sendPort,
);
receivePort.first.then((response) {
print(response);
});
+30 -22
View File
@@ -55,31 +55,39 @@ serverRunning(HttpServer server) {
port = server.port;
server.listen(handleRequest);
Future<ProcessResult> no_http_run = Process.run(
pathToExecutable,
[]
..add('--verbosity=warning')
..addAll(executableArguments)
..add(pathOfData.resolve('http_launch_main.dart').toFilePath()));
pathToExecutable,
[]
..add('--verbosity=warning')
..addAll(executableArguments)
..add(pathOfData.resolve('http_launch_main.dart').toFilePath()),
);
Future<ProcessResult> http_run = Process.run(
pathToExecutable,
[]
..add('--verbosity=warning')
..addAll(executableArguments)
..add('http://127.0.0.1:$port/http_launch_main.dart'));
pathToExecutable,
[]
..add('--verbosity=warning')
..addAll(executableArguments)
..add('http://127.0.0.1:$port/http_launch_main.dart'),
);
Future<ProcessResult> http_pkg_root_run = Process.run(
pathToExecutable,
[]
..add('--verbosity=warning')
..addAll(executableArguments)
..addAll(['http://127.0.0.1:$port/http_launch_main.dart']));
pathToExecutable,
[]
..add('--verbosity=warning')
..addAll(executableArguments)
..addAll(['http://127.0.0.1:$port/http_launch_main.dart']),
);
Future<ProcessResult> isolate_run = Process.run(
pathToExecutable,
[]
..add('--verbosity=warning')
..addAll(executableArguments)
..addAll(['http://127.0.0.1:$port/http_spawn_main.dart', '$port']));
Future<List<ProcessResult>> results =
Future.wait([no_http_run, http_run, http_pkg_root_run, isolate_run]);
pathToExecutable,
[]
..add('--verbosity=warning')
..addAll(executableArguments)
..addAll(['http://127.0.0.1:$port/http_spawn_main.dart', '$port']),
);
Future<List<ProcessResult>> results = Future.wait([
no_http_run,
http_run,
http_pkg_root_run,
isolate_run,
]);
results.then((results) {
// Close server.
server.close();
+2 -2
View File
@@ -94,7 +94,7 @@ testSameHash(String tmpDirPath) {
path.join(dartRootPath, "tools", "addlatexhash.dart"),
tmpPar8timesPath,
hashPath,
listPath
listPath,
]);
return Process.runSync(dartExecutable, args);
}
@@ -167,7 +167,7 @@ testSameDVI(String tmpDirPath) {
path.join(dartRootPath, "tools", "addlatexhash.dart"),
tmpSpecPath,
hashPath,
listPath
listPath,
]);
return Process.runSync(dartExecutable, args);
}
+5 -2
View File
@@ -14,8 +14,11 @@ void main() async {
asyncStart();
final result = <InternetAddress>[];
try {
result.addAll(await InternetAddress.lookup("some.bad.host.name.7654321")
.timeout(const Duration(milliseconds: 1), onTimeout: () => []));
result.addAll(
await InternetAddress.lookup(
"some.bad.host.name.7654321",
).timeout(const Duration(milliseconds: 1), onTimeout: () => []),
);
} catch (e) {
print('managed to fail with $e lookup before timeout');
}
@@ -12,27 +12,33 @@ var events = [];
Future testSocketException() {
var completer = new Completer();
runZonedGuarded(() {
Socket.connect("4", 1, timeout: Duration(seconds: 5)).then((Socket s) {
Expect.fail("Socket should not be able to connect");
});
}, (err, s) {
if (err is! SocketException) Expect.fail("Not expected error: $err");
completer.complete("socket test, ok.");
events.add("SocketException");
});
runZonedGuarded(
() {
Socket.connect("4", 1, timeout: Duration(seconds: 5)).then((Socket s) {
Expect.fail("Socket should not be able to connect");
});
},
(err, s) {
if (err is! SocketException) Expect.fail("Not expected error: $err");
completer.complete("socket test, ok.");
events.add("SocketException");
},
);
return completer.future;
}
Future testFileSystemException() {
var completer = new Completer();
runZonedGuarded(() {
new File("lol it's not a file\n").openRead().listen(null);
}, (err, s) {
if (err is! FileSystemException) Expect.fail("Not expected error: $err");
completer.complete("file test, ok.");
events.add("FileSystemException");
});
runZonedGuarded(
() {
new File("lol it's not a file\n").openRead().listen(null);
},
(err, s) {
if (err is! FileSystemException) Expect.fail("Not expected error: $err");
completer.complete("file test, ok.");
events.add("FileSystemException");
},
);
return completer.future;
}
@@ -20,26 +20,33 @@ void clientSocketAddCloseErrorTest() {
Socket.connect("127.0.0.1", server.port).then((client) {
const int SIZE = 1024 * 1024;
int errors = 0;
client.listen((data) => Expect.fail("Unexpected data"), onError: (error) {
Expect.isTrue(error is SocketException);
errors++;
}, onDone: () {
// We get either a close or an error followed by a close
// on the socket. Whether we get both depends on
// whether the system notices the error for the read
// event or only for the write event.
Expect.isTrue(errors <= 1);
server.close();
});
client.listen(
(data) => Expect.fail("Unexpected data"),
onError: (error) {
Expect.isTrue(error is SocketException);
errors++;
},
onDone: () {
// We get either a close or an error followed by a close
// on the socket. Whether we get both depends on
// whether the system notices the error for the read
// event or only for the write event.
Expect.isTrue(errors <= 1);
server.close();
},
);
client.add(new List.filled(SIZE, 0));
// Destroy other socket now.
completer.complete(null);
client.done.then((_) {
Expect.fail("Expected error");
}, onError: (error) {
Expect.isTrue(error is SocketException);
asyncEnd();
});
client.done.then(
(_) {
Expect.fail("Expected error");
},
onError: (error) {
Expect.isTrue(error is SocketException);
asyncEnd();
},
);
});
});
}
@@ -20,10 +20,13 @@ void clientSocketAddCloseNoErrorTest() {
Socket.connect("127.0.0.1", server.port).then((client) {
const int SIZE = 1024 * 1024;
int count = 0;
client.listen((data) => count += data.length, onDone: () {
Expect.equals(SIZE, count);
server.close();
});
client.listen(
(data) => count += data.length,
onDone: () {
Expect.equals(SIZE, count);
server.close();
},
);
client.add(new List.filled(SIZE, 0));
client.close();
// Start piping now.
@@ -28,8 +28,10 @@ void main() async {
client.listen((data) {}, onDone: server.close);
client.add(new List.filled(1024 * 1024, 0));
client.destroy();
await client.addStream(Stream.fromIterable([
[1, 2, 3, 4]
]));
await client.addStream(
Stream.fromIterable([
[1, 2, 3, 4],
]),
);
asyncEnd();
}
+11 -5
View File
@@ -78,8 +78,9 @@ Future expectFutureIsTrue(Future future) =>
Future expectFileSystemException(Function f, String message) {
return f().then(
(_) => Expect.fail('Expected a FileSystemException: $message'),
onError: (e) => Expect.isTrue(e is FileSystemException));
(_) => Expect.fail('Expected a FileSystemException: $message'),
onError: (e) => Expect.isTrue(e is FileSystemException),
);
}
testCreateDirectoryRecursive() {
@@ -123,16 +124,21 @@ testCreateLinkRecursive() {
Directory.systemTemp.createTemp('dart_directory').then((temp) {
var link = new Link(join(temp.path, 'a', 'b', 'c'));
return expectFileSystemException(
() => link.create(temp.path), 'link.create')
() => link.create(temp.path),
'link.create',
)
.then((_) => link.create(temp.path, recursive: true))
.then((_) => expectFutureIsTrue(link.exists()))
// Test cases where the link or parent directory already exists.
.then((_) => link.delete())
.then((_) => link.create(temp.path, recursive: true))
.then((_) => expectFutureIsTrue(link.exists()))
.then((_) => expectFileSystemException(
.then(
(_) => expectFileSystemException(
() => link.create(temp.path, recursive: true),
'existing link.create'))
'existing link.create',
),
)
.then((_) => expectFutureIsTrue(link.exists()))
.then((_) => asyncEnd())
.whenComplete(() => temp.delete(recursive: true));
@@ -27,7 +27,7 @@ void testCreateRecursiveRace() {
d.create(recursive: true),
d.create(recursive: true),
d.create(recursive: true),
d.create(recursive: true)
d.create(recursive: true),
]).then((_) {
Expect.isTrue(new Directory('${temp.path}/a').existsSync());
Expect.isTrue(new Directory('${temp.path}/a/b').existsSync());
+45 -29
View File
@@ -31,8 +31,10 @@ bool checkCreateInNonExistentFileSystemException(e) {
void testCreateInNonExistent(Directory temp, Function done) {
Directory inNonExistent = new Directory("${temp.path}/nonExistent/xxx");
Expect.throws(() => inNonExistent.createSync(),
(e) => checkCreateInNonExistentFileSystemException(e));
Expect.throws(
() => inNonExistent.createSync(),
(e) => checkCreateInNonExistentFileSystemException(e),
);
Future<Directory?>.value(inNonExistent.create()).catchError((error) {
checkCreateInNonExistentFileSystemException(error);
@@ -56,11 +58,14 @@ bool checkCreateTempInNonExistentFileSystemException(e) {
void testCreateTempInNonExistent(Directory temp, Function done) {
Directory nonExistent = new Directory("${temp.path}/nonExistent/xxx");
Expect.throws(() => nonExistent.createTempSync('tempdir'),
(e) => checkCreateTempInNonExistentFileSystemException(e));
Expect.throws(
() => nonExistent.createTempSync('tempdir'),
(e) => checkCreateTempInNonExistentFileSystemException(e),
);
Future<Directory?>.value(nonExistent.createTemp('tempdir'))
.catchError((error) {
Future<Directory?>.value(nonExistent.createTemp('tempdir')).catchError((
error,
) {
checkCreateTempInNonExistentFileSystemException(error);
done();
});
@@ -77,8 +82,10 @@ bool checkDeleteNonExistentFileSystemException(e) {
void testDeleteNonExistent(Directory temp, Function done) {
Directory nonExistent = new Directory("${temp.path}/nonExistent");
Expect.throws(() => nonExistent.deleteSync(),
(e) => checkDeleteNonExistentFileSystemException(e));
Expect.throws(
() => nonExistent.deleteSync(),
(e) => checkDeleteNonExistentFileSystemException(e),
);
Future<FileSystemEntity?>.value(nonExistent.delete()).catchError((error) {
checkDeleteNonExistentFileSystemException(error);
@@ -98,11 +105,14 @@ bool checkDeleteRecursivelyNonExistentFileSystemException(e) {
void testDeleteRecursivelyNonExistent(Directory temp, Function done) {
Directory nonExistent = new Directory("${temp.path}/nonExistent");
Expect.throws(() => nonExistent.deleteSync(recursive: true),
(e) => checkDeleteRecursivelyNonExistentFileSystemException(e));
Expect.throws(
() => nonExistent.deleteSync(recursive: true),
(e) => checkDeleteRecursivelyNonExistentFileSystemException(e),
);
Future<FileSystemEntity?>.value(nonExistent.delete(recursive: true))
.catchError((error) {
Future<FileSystemEntity?>.value(
nonExistent.delete(recursive: true),
).catchError((error) {
checkDeleteRecursivelyNonExistentFileSystemException(error);
done();
});
@@ -130,22 +140,26 @@ bool checkAsyncListNonExistentFileSystemException(error) {
void testListNonExistent(Directory temp, Function done) {
Directory nonExistent = new Directory("${temp.path}/nonExistent");
Expect.throws(() => nonExistent.listSync(), (e) => e is FileSystemException);
nonExistent.list().listen((_) => Expect.fail("listing should not succeed"),
onError: (e) {
checkAsyncListNonExistentFileSystemException(e);
done();
});
nonExistent.list().listen(
(_) => Expect.fail("listing should not succeed"),
onError: (e) {
checkAsyncListNonExistentFileSystemException(e);
done();
},
);
}
void testRenameNonExistent(Directory temp, Function done) {
Directory nonExistent = new Directory("${temp.path}/nonExistent");
var newPath = "${temp.path}/nonExistent2";
Expect.throws(
() => nonExistent.renameSync(newPath), (e) => e is PathNotFoundException);
() => nonExistent.renameSync(newPath),
(e) => e is PathNotFoundException,
);
var renameDone = nonExistent.rename(newPath);
renameDone
.then((ignore) => Expect.fail('rename non existent'))
.catchError((error) {
renameDone.then((ignore) => Expect.fail('rename non existent')).catchError((
error,
) {
Expect.isTrue(error is PathNotFoundException);
done();
});
@@ -161,9 +175,9 @@ void testRenameFileAsDirectory(Directory temp, Function done) {
renameDone
.then((ignore) => Expect.fail('rename file as directory'))
.catchError((error) {
Expect.isTrue(error is FileSystemException);
done();
});
Expect.isTrue(error is FileSystemException);
done();
});
}
testRenameOverwriteFile(Directory temp, Function done) {
@@ -171,15 +185,17 @@ testRenameOverwriteFile(Directory temp, Function done) {
var fileName = '${temp.path}/x';
new File(fileName).createSync();
Expect.throws(
() => temp1.renameSync(fileName), (e) => e is FileSystemException);
() => temp1.renameSync(fileName),
(e) => e is FileSystemException,
);
var renameDone = temp1.rename(fileName);
renameDone
.then((ignore) => Expect.fail('rename dir overwrite file'))
.catchError((error) {
Expect.isTrue(error is FileSystemException);
temp1.deleteSync(recursive: true);
done();
});
Expect.isTrue(error is FileSystemException);
temp1.deleteSync(recursive: true);
done();
});
}
void runTest(Function test) {
+27 -19
View File
@@ -51,11 +51,13 @@ fuzzAsyncMethods() async {
await withTempDir('dart_directory_fuzz', (temp) async {
final futures = <Future>[];
typeMapping.forEach((k, v) {
futures.add(doItAsync(() {
Directory.systemTemp
.createTempSync("${temp.path}/${v as String}")
.deleteSync();
}));
futures.add(
doItAsync(() {
Directory.systemTemp
.createTempSync("${temp.path}/${v as String}")
.deleteSync();
}),
);
if (v is! String) {
return;
}
@@ -63,22 +65,28 @@ fuzzAsyncMethods() async {
futures.add(doItAsync(d.exists));
futures.add(doItAsync(d.create));
futures.add(doItAsync(d.delete));
futures.add(doItAsync(() {
return d.createTemp('tempdir').then((temp) {
return temp.delete();
});
}));
futures.add(doItAsync(() {
return d.exists().then((res) {
if (!res) return d.delete(recursive: true);
return new Future.value(true);
});
}));
futures.add(
doItAsync(() {
return d.createTemp('tempdir').then((temp) {
return temp.delete();
});
}),
);
futures.add(
doItAsync(() {
return d.exists().then((res) {
if (!res) return d.delete(recursive: true);
return new Future.value(true);
});
}),
);
typeMapping.forEach((k2, v2) {
futures.add(doItAsync(() => d.rename(v2 as String)));
futures.add(doItAsync(() {
d.list(recursive: v2 as bool).listen((_) {}, onError: (e) => null);
}));
futures.add(
doItAsync(() {
d.list(recursive: v2 as bool).listen((_) {}, onError: (e) => null);
}),
);
});
});
await Future.wait(futures).then((_) => asyncEnd());
@@ -18,7 +18,9 @@ void testListNonExistent() {
d.delete().then((ignore) {
Expect.throws(() => d.listSync(), (e) => e is PathNotFoundException);
Expect.throws(
() => d.listSync(recursive: true), (e) => e is PathNotFoundException);
() => d.listSync(recursive: true),
(e) => e is PathNotFoundException,
);
asyncEnd();
});
});
@@ -39,8 +41,10 @@ void testListTooLongName() {
}
var long = new Directory("${buffer.toString()}");
Expect.throws(() => long.listSync(), (e) => e is FileSystemException);
Expect.throws(() => long.listSync(recursive: true),
(e) => e is FileSystemException);
Expect.throws(
() => long.listSync(recursive: true),
(e) => e is FileSystemException,
);
d.deleteSync(recursive: true);
asyncEnd();
});
@@ -20,25 +20,30 @@ void testPauseList() {
bool first = true;
var subscription;
int count = 0;
subscription = d.list(recursive: true).listen((file) {
if (file is File) {
if (first) {
first = false;
subscription.pause();
Timer.run(() {
for (int i = 0; i < TOTAL; i++) {
new File("${d.path}/$i/file").deleteSync();
subscription = d
.list(recursive: true)
.listen(
(file) {
if (file is File) {
if (first) {
first = false;
subscription.pause();
Timer.run(() {
for (int i = 0; i < TOTAL; i++) {
new File("${d.path}/$i/file").deleteSync();
}
subscription.resume();
});
}
count++;
}
subscription.resume();
});
}
count++;
}
}, onDone: () {
Expect.notEquals(TOTAL, count);
Expect.isTrue(count > 0);
d.delete(recursive: true).then((ignore) => asyncEnd());
});
},
onDone: () {
Expect.notEquals(TOTAL, count);
Expect.isTrue(count > 0);
d.delete(recursive: true).then((ignore) => asyncEnd());
},
);
});
}
@@ -52,23 +57,28 @@ void testPauseResumeCancelList() {
new File("${d.path}/$i/file").createSync();
}
var subscription;
subscription = d.list(recursive: true).listen((entity) {
subscription.pause();
subscription.resume();
void close() {
d.deleteSync(recursive: true);
asyncEnd();
}
subscription = d
.list(recursive: true)
.listen(
(entity) {
subscription.pause();
subscription.resume();
void close() {
d.deleteSync(recursive: true);
asyncEnd();
}
var future = subscription.cancel();
if (future != null) {
future.whenComplete(close);
} else {
close();
}
}, onDone: () {
Expect.fail('the stream was canceled, onDone should not happen');
});
var future = subscription.cancel();
if (future != null) {
future.whenComplete(close);
} else {
close();
}
},
onDone: () {
Expect.fail('the stream was canceled, onDone should not happen');
},
);
});
}
@@ -7,11 +7,14 @@ import 'dart:io';
import 'package:path/path.dart' as path;
void testList() {
final startingDir =
Directory(path.normalize(path.join(Platform.executable, '../../../')));
final startingDir = Directory(
path.normalize(path.join(Platform.executable, '../../../')),
);
print("Recursively listing entries in directory ${startingDir.path} ...");
List<FileSystemEntity> each =
startingDir.listSync(recursive: true, followLinks: false);
List<FileSystemEntity> each = startingDir.listSync(
recursive: true,
followLinks: false,
);
print("Found: ${each.length} entities");
}
@@ -6,8 +6,9 @@ import "package:expect/expect.dart";
import 'dart:io';
main() {
Directory tempDir =
Directory.systemTemp.createTempSync('dart_directory_non_ascii_sync');
Directory tempDir = Directory.systemTemp.createTempSync(
'dart_directory_non_ascii_sync',
);
var nonAsciiDir = new Directory("${tempDir.path}/æøå");
// On MacOS you get the decomposed utf8 form of file and directory
// names from the system. Therefore, we have to check for both here.
@@ -18,11 +19,13 @@ main() {
Expect.isTrue(nonAsciiDir.existsSync());
var temp = new Directory("${tempDir.path}/æøå").createTempSync('tempdir');
Expect.isTrue(
temp.path.contains(precomposed) || temp.path.contains(decomposed));
temp.path.contains(precomposed) || temp.path.contains(decomposed),
);
temp.deleteSync();
temp = tempDir.createTempSync('æøå');
Expect.isTrue(
temp.path.contains(precomposed) || temp.path.contains(decomposed));
temp.path.contains(precomposed) || temp.path.contains(decomposed),
);
temp.deleteSync();
tempDir.deleteSync(recursive: true);
Expect.isFalse(nonAsciiDir.existsSync());
@@ -25,14 +25,16 @@ main() {
.then((e) => Expect.isTrue(e))
.then((_) => new Directory("${tempDir.path}/æøå").createTemp('temp'))
.then((temp) {
Expect.isTrue(temp.path.contains(precomposed) ||
temp.path.contains(decomposed));
Expect.isTrue(
temp.path.contains(precomposed) || temp.path.contains(decomposed),
);
return temp.delete();
})
.then((_) => tempDir.createTemp('æøå'))
.then((temp) {
Expect.isTrue(temp.path.contains(precomposed) ||
temp.path.contains(decomposed));
Expect.isTrue(
temp.path.contains(precomposed) || temp.path.contains(decomposed),
);
return temp.delete();
})
.then((temp) => Expect.isFalse(temp.existsSync()))
+46 -26
View File
@@ -28,13 +28,15 @@ testRenamePath() async {
final newDir = oldDir.renameSync("${tempDir.path}/dir2");
Expect.isTrue(
oldDir.path == "${tempDir.path}/dir1",
"${oldDir.path} != '${tempDir.path}/dir1'"
"- path should not be updated");
oldDir.path == "${tempDir.path}/dir1",
"${oldDir.path} != '${tempDir.path}/dir1'"
"- path should not be updated",
);
Expect.isTrue(
newDir.path == "${tempDir.path}/dir2",
"${newDir.path} != '${tempDir.path}/dir2'"
"- path should be updated");
newDir.path == "${tempDir.path}/dir2",
"${newDir.path} != '${tempDir.path}/dir2'"
"- path should be updated",
);
});
}
@@ -63,19 +65,24 @@ testRenameToExistingFile() async {
Expect.fail('Directory.rename should fail to rename a non-directory');
} on FileSystemException catch (e) {
if (Platform.isWindows) {
Expect.isTrue(e.osError!.message.contains('file already exists'),
'Unexpected error: $e');
Expect.isTrue(
e.osError!.message.contains('file already exists'),
'Unexpected error: $e',
);
} else if (Platform.isLinux || Platform.isMacOS) {
Expect.isTrue(e.osError!.message.contains('Not a directory'),
'Unexpected error: $e');
Expect.isTrue(
e.osError!.message.contains('Not a directory'),
'Unexpected error: $e',
);
}
}
});
}
testRenameToExistingEmptyDirectory() async {
await withTempDir('testRenameToExistingEmptyDirectory',
(Directory tempDir) async {
await withTempDir('testRenameToExistingEmptyDirectory', (
Directory tempDir,
) async {
final dir1 = Directory("${tempDir.path}/dir1");
dir1.createSync();
File("${dir1.path}/file").createSync();
@@ -88,8 +95,9 @@ testRenameToExistingEmptyDirectory() async {
// Verify that the file contained in dir1 has been moved.
if (Platform.isWindows) {
Expect.fail(
'Directory.rename should fail to rename over an existing directory '
'on Windows');
'Directory.rename should fail to rename over an existing directory '
'on Windows',
);
} else {
Expect.isTrue(File("${dir2.path}/file").existsSync());
}
@@ -104,8 +112,9 @@ testRenameToExistingEmptyDirectory() async {
}
testRenameToExistingNonEmptyDirectory() async {
await withTempDir('testRenameToExistingNonEmptyDirectory',
(Directory tempDir) async {
await withTempDir('testRenameToExistingNonEmptyDirectory', (
Directory tempDir,
) async {
final dir1 = Directory("${tempDir.path}/dir1");
dir1.createSync();
File("${dir1.path}/file1").createSync();
@@ -117,14 +126,19 @@ testRenameToExistingNonEmptyDirectory() async {
try {
dir1.renameSync(dir2.path);
Expect.fail(
'Directory.rename should fail to rename a non-empty directory');
'Directory.rename should fail to rename a non-empty directory',
);
} on FileSystemException catch (e) {
if (Platform.isWindows) {
Expect.isTrue(e.osError!.message.contains('file already exists'),
'Unexpected error: $e');
Expect.isTrue(
e.osError!.message.contains('file already exists'),
'Unexpected error: $e',
);
} else if (Platform.isLinux || Platform.isMacOS) {
Expect.isTrue(e.osError!.message.contains('Directory not empty'),
'Unexpected error: $e');
Expect.isTrue(
e.osError!.message.contains('Directory not empty'),
'Unexpected error: $e',
);
}
}
});
@@ -140,13 +154,19 @@ testRenameButActuallyFile() async {
Expect.fail("Expected a failure to rename the file.");
} on FileSystemException catch (e) {
Expect.isTrue(
e.message.contains('Rename failed'), 'Unexpected error: $e');
e.message.contains('Rename failed'),
'Unexpected error: $e',
);
if (Platform.isWindows) {
Expect.isTrue(e.osError!.message.contains('cannot find the file'),
'Unexpected error: $e');
Expect.isTrue(
e.osError!.message.contains('cannot find the file'),
'Unexpected error: $e',
);
} else if (Platform.isLinux || Platform.isMacOS) {
Expect.isTrue(e.osError!.message.contains('Not a directory'),
'Unexpected error: $e');
Expect.isTrue(
e.osError!.message.contains('Not a directory'),
'Unexpected error: $e',
);
}
}
});
+129 -90
View File
@@ -15,8 +15,9 @@ class DirectoryTest {
bool listedDir = false;
bool listedFile = false;
Directory directory =
Directory.systemTemp.createTempSync('dart_directory_test');
Directory directory = Directory.systemTemp.createTempSync(
'dart_directory_test',
);
Directory subDirectory = new Directory("${directory.path}/subdir");
Expect.isTrue('$directory'.contains(directory.path));
Expect.isFalse(subDirectory.existsSync());
@@ -52,33 +53,40 @@ class DirectoryTest {
testSyncListing(true);
testSyncListing(false);
Expect.equals(
f.resolveSymbolicLinksSync(), fLong.resolveSymbolicLinksSync());
f.resolveSymbolicLinksSync(),
fLong.resolveSymbolicLinksSync(),
);
asyncStart();
directory.list(recursive: true).listen((FileSystemEntity entity) {
if (entity is File) {
var path = entity.path;
listedFile = true;
Expect.isTrue(path.contains(directory.path));
Expect.isTrue(path.contains('subdir'));
Expect.isTrue(path.contains('file.txt'));
} else {
var path = entity.path;
Expect.isTrue(entity is Directory);
listedDir = true;
Expect.isTrue(path.contains(directory.path));
Expect.isTrue(path.contains('subdir'));
}
}, onDone: () {
Expect.isTrue(listedDir, "directory not found");
Expect.isTrue(listedFile, "file not found");
directory.delete(recursive: true).then((ignore) {
f.exists().then((exists) => Expect.isFalse(exists));
directory.exists().then((exists) => Expect.isFalse(exists));
subDirectory.exists().then((exists) => Expect.isFalse(exists));
asyncEnd();
});
});
directory
.list(recursive: true)
.listen(
(FileSystemEntity entity) {
if (entity is File) {
var path = entity.path;
listedFile = true;
Expect.isTrue(path.contains(directory.path));
Expect.isTrue(path.contains('subdir'));
Expect.isTrue(path.contains('file.txt'));
} else {
var path = entity.path;
Expect.isTrue(entity is Directory);
listedDir = true;
Expect.isTrue(path.contains(directory.path));
Expect.isTrue(path.contains('subdir'));
}
},
onDone: () {
Expect.isTrue(listedDir, "directory not found");
Expect.isTrue(listedFile, "file not found");
directory.delete(recursive: true).then((ignore) {
f.exists().then((exists) => Expect.isFalse(exists));
directory.exists().then((exists) => Expect.isFalse(exists));
subDirectory.exists().then((exists) => Expect.isFalse(exists));
asyncEnd();
});
},
);
// Listing is asynchronous, so nothing should be listed at this
// point.
@@ -87,8 +95,9 @@ class DirectoryTest {
}
static void testListingTailingPaths() {
Directory directory =
Directory.systemTemp.createTempSync('dart_directory_test');
Directory directory = Directory.systemTemp.createTempSync(
'dart_directory_test',
);
Directory subDirectory = new Directory("${directory.path}/subdir/");
subDirectory.createSync();
File f = new File('${subDirectory.path}/file.txt');
@@ -100,18 +109,22 @@ class DirectoryTest {
subDirectory.listSync().forEach(test);
subDirectory.list().listen(test, onDone: () {
directory.deleteSync(recursive: true);
});
subDirectory.list().listen(
test,
onDone: () {
directory.deleteSync(recursive: true);
},
);
}
static void testListNonExistent() {
setupListerHandlers(Stream<FileSystemEntity> stream) {
stream.listen(
(_) => Expect.fail("Listing of non-existing directory should fail"),
onError: (error) {
Expect.isTrue(error is FileSystemException);
});
(_) => Expect.fail("Listing of non-existing directory should fail"),
onError: (error) {
Expect.isTrue(error is FileSystemException);
},
);
}
Directory.systemTemp.createTemp('dart_directory').then((d) {
@@ -128,15 +141,16 @@ class DirectoryTest {
var errors = 0;
setupListHandlers(Stream<FileSystemEntity> stream) {
stream.listen(
(_) => Expect.fail("Listing of non-existing directory should fail"),
onError: (error) {
Expect.isTrue(error is FileSystemException);
if (++errors == 2) {
d.delete(recursive: true).then((_) {
asyncEnd();
});
}
});
(_) => Expect.fail("Listing of non-existing directory should fail"),
onError: (error) {
Expect.isTrue(error is FileSystemException);
if (++errors == 2) {
d.delete(recursive: true).then((_) {
asyncEnd();
});
}
},
);
}
var subDirName = 'subdir';
@@ -159,11 +173,13 @@ class DirectoryTest {
static void testDeleteNonExistent() {
// Test that deleting a non-existing directory fails.
setupFutureHandlers(future) {
future.then((ignore) {
Expect.fail("Deletion of non-existing directory should fail");
}).catchError((error) {
Expect.isTrue(error is PathNotFoundException);
});
future
.then((ignore) {
Expect.fail("Deletion of non-existing directory should fail");
})
.catchError((error) {
Expect.isTrue(error is PathNotFoundException);
});
}
Directory.systemTemp.createTemp('dart_directory').then((d) {
@@ -221,15 +237,20 @@ class DirectoryTest {
}
var long = new Directory("${buffer.toString()}");
// Works only on Windows.
long.delete(recursive: true).then((_) {
if (Platform.isWindows) {
asyncEnd();
}
}, onError: ((_) {
if (!Platform.isWindows) {
asyncEnd();
}
}));
long
.delete(recursive: true)
.then(
(_) {
if (Platform.isWindows) {
asyncEnd();
}
},
onError: ((_) {
if (!Platform.isWindows) {
asyncEnd();
}
}),
);
});
});
}
@@ -411,14 +432,19 @@ class DirectoryTest {
l.createSync("${path}target");
d.deleteSync();
int count = 0;
tmp.list(followLinks: true).listen((file) {
count++;
Expect.isTrue(file is Link);
}, onDone: () {
Expect.equals(1, count);
l.deleteSync();
tmp.deleteSync();
});
tmp
.list(followLinks: true)
.listen(
(file) {
count++;
Expect.isTrue(file is Link);
},
onDone: () {
Expect.equals(1, count);
l.deleteSync();
tmp.deleteSync();
},
);
}
static void testListLinkSync() {
@@ -429,15 +455,20 @@ class DirectoryTest {
Link l = new Link("${path}symlink");
l.createSync("${path}target");
int count = 0;
tmp.list(followLinks: true).listen((file) {
count++;
Expect.isTrue(file is Directory);
}, onDone: () {
Expect.equals(2, count);
l.deleteSync();
d.deleteSync();
tmp.deleteSync();
});
tmp
.list(followLinks: true)
.listen(
(file) {
count++;
Expect.isTrue(file is Directory);
},
onDone: () {
Expect.equals(2, count);
l.deleteSync();
d.deleteSync();
tmp.deleteSync();
},
);
}
static void testCreateTemp() {
@@ -445,8 +476,9 @@ class DirectoryTest {
String template = 'dart_temp_dir';
if (base.existsSync()) {
asyncStart();
Future.wait([base.createTemp(template), base.createTemp(template)])
.then((tempDirs) {
Future.wait([base.createTemp(template), base.createTemp(template)]).then((
tempDirs,
) {
Expect.notEquals(tempDirs[0].path, tempDirs[1].path);
for (Directory t in tempDirs) {
Expect.isTrue(t.existsSync());
@@ -463,7 +495,7 @@ class DirectoryTest {
asyncStart();
Future.wait([
Directory.systemTemp.createTemp(template),
Directory.systemTemp.createTemp(template)
Directory.systemTemp.createTemp(template),
]).then((tempDirs) {
Expect.notEquals(tempDirs[0].path, tempDirs[1].path);
for (Directory t in tempDirs) {
@@ -589,8 +621,10 @@ String? illegalTempDirectoryLocation() {
testCreateTempErrorSync() {
var location = illegalTempDirectoryLocation();
if (location != null) {
Expect.throws(() => new Directory(location).createTempSync('dart_tempdir'),
(e) => e is FileSystemException);
Expect.throws(
() => new Directory(location).createTempSync('dart_tempdir'),
(e) => e is FileSystemException,
);
}
}
@@ -647,7 +681,9 @@ testCreateDirExistingFileSync() {
file.createSync();
Expect.isTrue(file.existsSync());
Expect.throws(
new Directory(path).createSync, (e) => e is FileSystemException);
new Directory(path).createSync,
(e) => e is FileSystemException,
);
temp.deleteSync(recursive: true);
}
@@ -659,14 +695,17 @@ testCreateDirExistingFile() {
var file = new File(path);
var subDir = new Directory(path);
file.create().then((_) {
subDir.create().then((_) {
Expect.fail("dir create should fail on existing file");
}).catchError((error) {
Expect.isTrue(error is FileSystemException);
temp.delete(recursive: true).then((_) {
asyncEnd();
});
});
subDir
.create()
.then((_) {
Expect.fail("dir create should fail on existing file");
})
.catchError((error) {
Expect.isTrue(error is FileSystemException);
temp.delete(recursive: true).then((_) {
asyncEnd();
});
});
});
});
}
+11 -6
View File
@@ -19,11 +19,13 @@ void testFromUri() {
dir.createSync();
Expect.isTrue(new Directory.fromUri(dirUri).existsSync());
Expect.isTrue(
new Directory.fromUri(Uri.base.resolveUri(dirUri)).existsSync());
new Directory.fromUri(Uri.base.resolveUri(dirUri)).existsSync(),
);
Directory.current = temp.path;
Expect.isTrue(new Directory.fromUri(Uri.parse('from_uri')).existsSync());
Expect.isTrue(
new Directory.fromUri(Uri.base.resolve('from_uri')).existsSync());
new Directory.fromUri(Uri.base.resolve('from_uri')).existsSync(),
);
Directory.current = originalWorkingDirectory;
dir.deleteSync();
temp.deleteSync(recursive: true);
@@ -32,12 +34,15 @@ void testFromUri() {
}
void testFromUriUnsupported() {
Expect.throwsUnsupportedError(() =>
new Directory.fromUri(Uri.parse('http://localhost:8080/index.html')));
Expect.throwsUnsupportedError(
() => new Directory.fromUri(Uri.parse('ftp://localhost/tmp/xxx')));
() => new Directory.fromUri(Uri.parse('http://localhost:8080/index.html')),
);
Expect.throwsUnsupportedError(
() => new Directory.fromUri(Uri.parse('name#fragment')));
() => new Directory.fromUri(Uri.parse('ftp://localhost/tmp/xxx')),
);
Expect.throwsUnsupportedError(
() => new Directory.fromUri(Uri.parse('name#fragment')),
);
}
void main() {
@@ -5,8 +5,9 @@
import "dart:io";
import "dart:isolate";
final bool isAppJitTrainingRun =
Platform.executableArguments.any((arg) => arg == '--snapshot-kind=app-jit');
final bool isAppJitTrainingRun = Platform.executableArguments.any(
(arg) => arg == '--snapshot-kind=app-jit',
);
child(msg) {
// This should work even though the parent isolate is blocked and won't
@@ -39,7 +39,7 @@ testWindows() {
'c:/abd',
'D:\\rf',
'\\\\a_share\\folder',
'\\\\?\\c:\\prefixed\path\\'
'\\\\?\\c:\\prefixed\path\\',
]) {
Expect.isTrue(new File(absolute).absolute.path == absolute);
Expect.isTrue(new File(absolute).absolute.isAbsolute);
@@ -55,8 +55,10 @@ testPosix() {
Expect.equals(new File(relative).absolute.path, '$current/$relative');
}
Expect.isTrue(new File(relative).absolute.isAbsolute);
Expect.equals(new Directory(relative).absolute.path,
new Link(relative).absolute.path);
Expect.equals(
new Directory(relative).absolute.path,
new Link(relative).absolute.path,
);
Expect.isTrue(new File(relative).absolute is File);
Expect.isTrue(new Directory(relative).absolute is Directory);
Expect.isTrue(new Link(relative).absolute is Link);
@@ -21,8 +21,9 @@ import "package:path/path.dart";
// Check whether the file is locked or not.
runPeer(String path, int len, FileLock mode) {
var script =
Platform.script.resolve('file_blocking_lock_script.dart').toFilePath();
var script = Platform.script
.resolve('file_blocking_lock_script.dart')
.toFilePath();
var arguments = <String>[]
..addAll(Platform.executableArguments)
..add(script)
+23 -20
View File
@@ -83,30 +83,33 @@ void testCopy() {
Expect.equals(FILE_CONTENT1, file1.readAsStringSync());
// Copy to new file works.
file1.copy('${tmp.path}/file2').then((file2) {
Expect.equals(FILE_CONTENT1, file1.readAsStringSync());
Expect.equals(FILE_CONTENT1, file2.readAsStringSync());
file1
.copy('${tmp.path}/file2')
.then((file2) {
Expect.equals(FILE_CONTENT1, file1.readAsStringSync());
Expect.equals(FILE_CONTENT1, file2.readAsStringSync());
// Override works for files.
file2.writeAsStringSync(FILE_CONTENT2);
return file2.copy(file1.path).then((_) {
Expect.equals(FILE_CONTENT2, file1.readAsStringSync());
Expect.equals(FILE_CONTENT2, file2.readAsStringSync());
// Override works for files.
file2.writeAsStringSync(FILE_CONTENT2);
return file2.copy(file1.path).then((_) {
Expect.equals(FILE_CONTENT2, file1.readAsStringSync());
Expect.equals(FILE_CONTENT2, file2.readAsStringSync());
// Fail when coping to directory.
var dir = new Directory('${tmp.path}/dir')..createSync();
// Fail when coping to directory.
var dir = new Directory('${tmp.path}/dir')..createSync();
return file1
.copy(dir.path)
.then((_) => Expect.fail('expected error'), onError: (_) {})
.then((_) {
Expect.equals(FILE_CONTENT2, file1.readAsStringSync());
return file1
.copy(dir.path)
.then((_) => Expect.fail('expected error'), onError: (_) {})
.then((_) {
Expect.equals(FILE_CONTENT2, file1.readAsStringSync());
});
});
})
.whenComplete(() {
tmp.deleteSync(recursive: true);
asyncEnd();
});
});
}).whenComplete(() {
tmp.deleteSync(recursive: true);
asyncEnd();
});
}
main() {
+3 -1
View File
@@ -31,7 +31,9 @@ testExclusiveCreate() async {
Expect.equals(file, createdFile);
Expect.isTrue(await createdFile.exists());
Expect.throws(
() => file.createSync(exclusive: true), (e) => e is FileSystemException);
() => file.createSync(exclusive: true),
(e) => e is FileSystemException,
);
bool createFailed = false;
try {
await file.create(exclusive: true);
+3 -1
View File
@@ -21,7 +21,9 @@ testReadSyncBigInt() {
var bigint = 9223372036854775807;
var openedFile = file.openSync();
Expect.throws(
() => openedFile.readSync(bigint), (e) => e is FileSystemException);
() => openedFile.readSync(bigint),
(e) => e is FileSystemException,
);
openedFile.closeSync();
done();
});
+109 -63
View File
@@ -47,7 +47,9 @@ bool checkDeleteNonExistentFileSystemException(e) {
bool checkLengthNonExistentFileSystemException(e) {
return checkNonExistentFileSystemException(
e, "Cannot retrieve length of file");
e,
"Cannot retrieve length of file",
);
}
void testOpenBlankFilename() {
@@ -72,7 +74,9 @@ void testOpenNonExistent() {
// Non-existing file should throw exception.
Expect.throws(
() => file.openSync(), (e) => checkOpenNonExistentFileSystemException(e));
() => file.openSync(),
(e) => checkOpenNonExistentFileSystemException(e),
);
var openFuture = file.open(mode: FileMode.read);
openFuture.then((raf) => Expect.fail("Unreachable code")).catchError((error) {
@@ -89,8 +93,10 @@ void testDeleteNonExistent() {
var file = new File("${temp.path}/nonExistentFile");
// Non-existing file should throw exception.
Expect.throws(() => file.deleteSync(),
(e) => checkDeleteNonExistentFileSystemException(e));
Expect.throws(
() => file.deleteSync(),
(e) => checkDeleteNonExistentFileSystemException(e),
);
var delete = file.delete();
delete.then((ignore) => Expect.fail("Unreachable code")).catchError((error) {
@@ -107,8 +113,10 @@ void testLengthNonExistent() {
var file = new File("${temp.path}/nonExistentFile");
// Non-existing file should throw exception.
Expect.throws(() => file.lengthSync(),
(e) => checkLengthNonExistentFileSystemException(e));
Expect.throws(
() => file.lengthSync(),
(e) => checkLengthNonExistentFileSystemException(e),
);
var lenFuture = file.length();
lenFuture.then((len) => Expect.fail("Unreachable code")).catchError((error) {
@@ -140,8 +148,10 @@ void testCreateInNonExistentDirectory() {
var file = new File("${temp.path}/nonExistentDirectory/newFile");
// Create in nonexistent directory should throw exception.
Expect.throws(() => file.createSync(),
(e) => checkCreateInNonExistentFileSystemException(e));
Expect.throws(
() => file.createSync(),
(e) => checkCreateInNonExistentFileSystemException(e),
);
var create = file.create();
create.then((ignore) => Expect.fail("Unreachable code")).catchError((error) {
@@ -168,18 +178,20 @@ void testResolveSymbolicLinksOnNonExistentDirectory() {
var file = new File("${temp.path}/nonExistentDirectory");
// Full path nonexistent directory should throw exception.
Expect.throws(() => file.resolveSymbolicLinksSync(),
(e) => checkResolveSymbolicLinksOnNonExistentFileSystemException(e));
Expect.throws(
() => file.resolveSymbolicLinksSync(),
(e) => checkResolveSymbolicLinksOnNonExistentFileSystemException(e),
);
var resolvedFuture = file.resolveSymbolicLinks();
resolvedFuture
.then((path) => Expect.fail("Unreachable code $path"))
.catchError((error) {
checkResolveSymbolicLinksOnNonExistentFileSystemException(error);
temp.deleteSync(recursive: true);
asyncEnd();
return file;
});
checkResolveSymbolicLinksOnNonExistentFileSystemException(error);
temp.deleteSync(recursive: true);
asyncEnd();
return file;
});
}
void testReadAsBytesNonExistent() {
@@ -188,13 +200,15 @@ void testReadAsBytesNonExistent() {
var file = new File("${temp.path}/nonExistentFile3");
// Non-existing file should throw exception.
Expect.throws(() => file.readAsBytesSync(),
(e) => checkOpenNonExistentFileSystemException(e));
Expect.throws(
() => file.readAsBytesSync(),
(e) => checkOpenNonExistentFileSystemException(e),
);
var readAsBytesFuture = file.readAsBytes();
readAsBytesFuture
.then((data) => Expect.fail("Unreachable code"))
.catchError((error) {
readAsBytesFuture.then((data) => Expect.fail("Unreachable code")).catchError((
error,
) {
checkOpenNonExistentFileSystemException(error);
temp.deleteSync(recursive: true);
asyncEnd();
@@ -208,18 +222,20 @@ void testReadAsTextNonExistent() {
var file = new File("${temp.path}/nonExistentFile4");
// Non-existing file should throw exception.
Expect.throws(() => file.readAsStringSync(),
(e) => checkOpenNonExistentFileSystemException(e));
Expect.throws(
() => file.readAsStringSync(),
(e) => checkOpenNonExistentFileSystemException(e),
);
var readAsStringFuture = file.readAsString(encoding: ascii);
readAsStringFuture
.then((data) => Expect.fail("Unreachable code"))
.catchError((error) {
checkOpenNonExistentFileSystemException(error);
temp.deleteSync(recursive: true);
asyncEnd();
return file;
});
readAsStringFuture.then((data) => Expect.fail("Unreachable code")).catchError(
(error) {
checkOpenNonExistentFileSystemException(error);
temp.deleteSync(recursive: true);
asyncEnd();
return file;
},
);
}
testReadAsLinesNonExistent() {
@@ -228,13 +244,15 @@ testReadAsLinesNonExistent() {
var file = new File("${temp.path}/nonExistentFile5");
// Non-existing file should throw exception.
Expect.throws(() => file.readAsLinesSync(),
(e) => checkOpenNonExistentFileSystemException(e));
Expect.throws(
() => file.readAsLinesSync(),
(e) => checkOpenNonExistentFileSystemException(e),
);
var readAsLinesFuture = file.readAsLines(encoding: ascii);
readAsLinesFuture
.then((data) => Expect.fail("Unreachable code"))
.catchError((error) {
readAsLinesFuture.then((data) => Expect.fail("Unreachable code")).catchError((
error,
) {
checkOpenNonExistentFileSystemException(error);
temp.deleteSync(recursive: true);
asyncEnd();
@@ -268,8 +286,10 @@ testWriteByteToReadOnlyFile() {
var openedFile = file.openSync(mode: FileMode.read);
// Writing to read only file should throw an exception.
Expect.throws(() => openedFile.writeByteSync(0),
(e) => checkWriteReadOnlyFileSystemException(e));
Expect.throws(
() => openedFile.writeByteSync(0),
(e) => checkWriteReadOnlyFileSystemException(e),
);
var writeByteFuture = openedFile.writeByte(0);
writeByteFuture.catchError((error) {
@@ -286,8 +306,10 @@ testWriteFromToReadOnlyFile() {
List<int> data = [0, 1, 2, 3];
// Writing to read only file should throw an exception.
Expect.throws(() => openedFile.writeFromSync(data, 0, data.length),
(e) => checkWriteReadOnlyFileSystemException(e));
Expect.throws(
() => openedFile.writeFromSync(data, 0, data.length),
(e) => checkWriteReadOnlyFileSystemException(e),
);
var writeFromFuture = openedFile.writeFrom(data, 0, data.length);
writeFromFuture.catchError((error) {
@@ -306,17 +328,19 @@ testTruncateReadOnlyFile() {
openedFile = file.openSync(mode: FileMode.read);
// Truncating read only file should throw an exception.
Expect.throws(() => openedFile.truncateSync(0),
(e) => checkWriteReadOnlyFileSystemException(e));
Expect.throws(
() => openedFile.truncateSync(0),
(e) => checkWriteReadOnlyFileSystemException(e),
);
var truncateFuture = openedFile.truncate(0);
truncateFuture
.then((ignore) => Expect.fail("Unreachable code"))
.catchError((error) {
checkWriteReadOnlyFileSystemException(error);
openedFile.close().then((_) => done());
return openedFile;
});
truncateFuture.then((ignore) => Expect.fail("Unreachable code")).catchError(
(error) {
checkWriteReadOnlyFileSystemException(error);
openedFile.close().then((_) => done());
return openedFile;
},
);
});
}
@@ -334,25 +358,45 @@ testOperateOnClosedFile() {
List<int> data = [0, 1, 2, 3];
Expect.throws(
() => openedFile.readByteSync(), (e) => checkFileClosedException(e));
() => openedFile.readByteSync(),
(e) => checkFileClosedException(e),
);
Expect.throws(
() => openedFile.writeByteSync(0), (e) => checkFileClosedException(e));
Expect.throws(() => openedFile.writeFromSync(data, 0, data.length),
(e) => checkFileClosedException(e));
Expect.throws(() => openedFile.readIntoSync(data, 0, data.length),
(e) => checkFileClosedException(e));
Expect.throws(() => openedFile.writeStringSync("Hello"),
(e) => checkFileClosedException(e));
() => openedFile.writeByteSync(0),
(e) => checkFileClosedException(e),
);
Expect.throws(
() => openedFile.positionSync(), (e) => checkFileClosedException(e));
Expect.throws(() => openedFile.setPositionSync(0),
(e) => checkFileClosedException(e));
() => openedFile.writeFromSync(data, 0, data.length),
(e) => checkFileClosedException(e),
);
Expect.throws(
() => openedFile.truncateSync(0), (e) => checkFileClosedException(e));
() => openedFile.readIntoSync(data, 0, data.length),
(e) => checkFileClosedException(e),
);
Expect.throws(
() => openedFile.lengthSync(), (e) => checkFileClosedException(e));
() => openedFile.writeStringSync("Hello"),
(e) => checkFileClosedException(e),
);
Expect.throws(
() => openedFile.flushSync(), (e) => checkFileClosedException(e));
() => openedFile.positionSync(),
(e) => checkFileClosedException(e),
);
Expect.throws(
() => openedFile.setPositionSync(0),
(e) => checkFileClosedException(e),
);
Expect.throws(
() => openedFile.truncateSync(0),
(e) => checkFileClosedException(e),
);
Expect.throws(
() => openedFile.lengthSync(),
(e) => checkFileClosedException(e),
);
Expect.throws(
() => openedFile.flushSync(),
(e) => checkFileClosedException(e),
);
var errorCount = 0;
@@ -445,7 +489,9 @@ testReadSyncClosedFile() {
var openedFile = file.openSync();
openedFile.closeSync();
Expect.throws(
() => openedFile.readSync(1), (e) => e is FileSystemException);
() => openedFile.readSync(1),
(e) => e is FileSystemException,
);
done();
});
}
+119 -87
View File
@@ -45,11 +45,13 @@ void testOpenStreamAsync() {
// File contains "Hello Dart\nwassup!\n"
var expected = "Hello Dart\nwassup!\n".codeUnits;
var byteCount = 0;
(new File(fileName)).openRead().listen((d) => byteCount += d.length,
onDone: () {
Expect.equals(expected.length, byteCount);
asyncEnd();
});
(new File(fileName)).openRead().listen(
(d) => byteCount += d.length,
onDone: () {
Expect.equals(expected.length, byteCount);
asyncEnd();
},
);
}
// Create a file that is big enough that a file stream will
@@ -76,24 +78,28 @@ void testInputStreamTruncate() {
// without getting all data.
var streamedBytes = 0;
var subscription;
subscription = file.openRead().listen((d) {
if (streamedBytes == 0) {
subscription.pause();
// Truncate the file by opening it for writing.
file.open(mode: FileMode.write).then((opened) {
opened.close().then((_) {
Expect.equals(0, file.lengthSync());
subscription.resume();
subscription = file.openRead().listen(
(d) {
if (streamedBytes == 0) {
subscription.pause();
// Truncate the file by opening it for writing.
file.open(mode: FileMode.write).then((opened) {
opened.close().then((_) {
Expect.equals(0, file.lengthSync());
subscription.resume();
});
});
});
}
streamedBytes += d.length;
}, onDone: () {
Expect.isTrue(streamedBytes > 0 && streamedBytes <= originalLength);
temp.delete(recursive: true).then((_) => asyncEnd());
}, onError: (e) {
Expect.fail("Unexpected error");
});
}
streamedBytes += d.length;
},
onDone: () {
Expect.isTrue(streamedBytes > 0 && streamedBytes <= originalLength);
temp.delete(recursive: true).then((_) => asyncEnd());
},
onError: (e) {
Expect.fail("Unexpected error");
},
);
}
void testInputStreamDelete() {
@@ -106,28 +112,35 @@ void testInputStreamDelete() {
// without getting all data.
var streamedBytes = 0;
var subscription;
subscription = file.openRead().listen((d) {
if (streamedBytes == 0) {
subscription.pause();
// Delete the underlying file by opening it for writing.
file.delete().then((deleted) {
Expect.isFalse(deleted.existsSync());
subscription.resume();
}).catchError((e) {
// On Windows, you cannot delete a file that is open
// somewhere else. The stream has this file open
// and therefore we get an error on deletion on Windows.
Expect.equals('windows', Platform.operatingSystem);
subscription.resume();
});
}
streamedBytes += d.length;
}, onDone: () {
Expect.equals(originalLength, streamedBytes);
temp.delete(recursive: true).then((_) => asyncEnd());
}, onError: (e) {
Expect.fail("Unexpected error");
});
subscription = file.openRead().listen(
(d) {
if (streamedBytes == 0) {
subscription.pause();
// Delete the underlying file by opening it for writing.
file
.delete()
.then((deleted) {
Expect.isFalse(deleted.existsSync());
subscription.resume();
})
.catchError((e) {
// On Windows, you cannot delete a file that is open
// somewhere else. The stream has this file open
// and therefore we get an error on deletion on Windows.
Expect.equals('windows', Platform.operatingSystem);
subscription.resume();
});
}
streamedBytes += d.length;
},
onDone: () {
Expect.equals(originalLength, streamedBytes);
temp.delete(recursive: true).then((_) => asyncEnd());
},
onError: (e) {
Expect.fail("Unexpected error");
},
);
}
void testInputStreamAppend() {
@@ -139,24 +152,28 @@ void testInputStreamAppend() {
// underlying file and check that the stream gets all the data.
var streamedBytes = 0;
var subscription;
subscription = file.openRead().listen((d) {
if (streamedBytes == 0) {
subscription.pause();
// Double the length of the underlying file.
file.readAsBytes().then((bytes) {
file.writeAsBytes(bytes, mode: FileMode.append).then((_) {
Expect.equals(2 * originalLength, file.lengthSync());
subscription.resume();
subscription = file.openRead().listen(
(d) {
if (streamedBytes == 0) {
subscription.pause();
// Double the length of the underlying file.
file.readAsBytes().then((bytes) {
file.writeAsBytes(bytes, mode: FileMode.append).then((_) {
Expect.equals(2 * originalLength, file.lengthSync());
subscription.resume();
});
});
});
}
streamedBytes += d.length;
}, onDone: () {
Expect.equals(2 * originalLength, streamedBytes);
temp.delete(recursive: true).then((_) => asyncEnd());
}, onError: (e) {
Expect.fail("Unexpected error");
});
}
streamedBytes += d.length;
},
onDone: () {
Expect.equals(2 * originalLength, streamedBytes);
temp.delete(recursive: true).then((_) => asyncEnd());
},
onError: (e) {
Expect.fail("Unexpected error");
},
);
}
void testInputStreamOffset() {
@@ -167,14 +184,20 @@ void testInputStreamOffset() {
var originalLength = writeLongFileSync(file);
var streamedBytes = 0;
if (expectedBytes < 0) expectedBytes = originalLength + expectedBytes;
file.openRead(start, end).listen((d) {
streamedBytes += d.length;
}, onDone: () {
Expect.equals(expectedBytes, streamedBytes);
temp.delete(recursive: true).then((_) => asyncEnd());
}, onError: (e) {
Expect.fail("Unexpected error");
});
file
.openRead(start, end)
.listen(
(d) {
streamedBytes += d.length;
},
onDone: () {
Expect.equals(expectedBytes, streamedBytes);
temp.delete(recursive: true).then((_) => asyncEnd());
},
onError: (e) {
Expect.fail("Unexpected error");
},
);
}
test(10, 20, 10);
@@ -195,15 +218,21 @@ void testInputStreamBadOffset() {
var originalLength = writeLongFileSync(file);
var streamedBytes = 0;
bool error = false;
file.openRead(start, end).listen((d) {
streamedBytes += d.length;
}, onDone: () {
Expect.isTrue(error);
temp.deleteSync(recursive: true);
asyncEnd();
}, onError: (e) {
error = true;
});
file
.openRead(start, end)
.listen(
(d) {
streamedBytes += d.length;
},
onDone: () {
Expect.isTrue(error);
temp.deleteSync(recursive: true);
asyncEnd();
},
onError: (e) {
error = true;
},
);
}
test(-1, null);
@@ -222,15 +251,18 @@ void testStringLineSplitterEnding(String name, int length) {
.transform(utf8.decoder)
.transform(new LineSplitter());
int lineCount = 0;
lineStream.listen((line) {
lineCount++;
Expect.isTrue(lineCount <= 10);
if (line[0] != "#") {
Expect.equals("Line $lineCount", line);
}
}, onDone: () {
Expect.equals(10, lineCount);
});
lineStream.listen(
(line) {
lineCount++;
Expect.isTrue(lineCount <= 10);
if (line[0] != "#") {
Expect.equals("Line $lineCount", line);
}
},
onDone: () {
Expect.equals(10, lineCount);
},
);
}
main() {
+15 -10
View File
@@ -94,11 +94,13 @@ class FileTest {
var expected = [206, 187, 120, 46, 32, 120, 10];
Expect.listEquals(expected, text.codeUnits);
var readAsStringFuture = f.readAsString(encoding: ascii);
readAsStringFuture.then((text) {
Expect.fail("Non-ascii char should cause error");
}).catchError((e) {
asyncTestDone("testReadAsText");
});
readAsStringFuture
.then((text) {
Expect.fail("Non-ascii char should cause error");
})
.catchError((e) {
asyncTestDone("testReadAsText");
});
});
});
});
@@ -116,12 +118,15 @@ class FileTest {
static testMain() {
asyncStart();
var outerZone = Zone.current;
var firstZone = Zone.current.fork(specification: ZoneSpecification(
var firstZone = Zone.current.fork(
specification: ZoneSpecification(
handleUncaughtError: (self, parent, zone, error, stacktrace) {
asyncEnd();
print("unittest-suite-success"); // For the test harness.
exit(0);
}));
asyncEnd();
print("unittest-suite-success"); // For the test harness.
exit(0);
},
),
);
firstZone.run(() async {
Expect.identical(firstZone, Zone.current);
createTempDirectory(() {
+39 -28
View File
@@ -23,8 +23,9 @@ check(String path, int start, int end, FileLock mode, {required bool locked}) {
..add('$start')
..add('$end');
var stacktrace = StackTrace.current;
return Process.run(Platform.executable, arguments)
.then((ProcessResult result) {
return Process.run(Platform.executable, arguments).then((
ProcessResult result,
) {
if (result.exitCode != 0 || !result.stdout.contains(expected)) {
print("Client failed, exit code ${result.exitCode}");
print(" stdout:");
@@ -40,13 +41,19 @@ check(String path, int start, int end, FileLock mode, {required bool locked}) {
});
}
checkLocked(String path,
[int start = 0, int end = -1, FileLock mode = FileLock.exclusive]) =>
check(path, start, end, mode, locked: true);
checkLocked(
String path, [
int start = 0,
int end = -1,
FileLock mode = FileLock.exclusive,
]) => check(path, start, end, mode, locked: true);
checkNotLocked(String path,
[int start = 0, int end = -1, FileLock mode = FileLock.exclusive]) =>
check(path, start, end, mode, locked: false);
checkNotLocked(
String path, [
int start = 0,
int end = -1,
FileLock mode = FileLock.exclusive,
]) => check(path, start, end, mode, locked: false);
void testLockWholeFile() {
Directory directory = Directory.systemTemp.createTempSync('dart_file_lock');
@@ -55,16 +62,18 @@ void testLockWholeFile() {
var raf = file.openSync(mode: FileMode.write);
raf.lockSync();
asyncStart();
checkLocked(file.path).then((_) {
return checkLocked(file.path, 0, 2).then((_) {
raf.unlockSync();
return checkNotLocked(file.path).then((_) {});
});
}).whenComplete(() {
raf.closeSync();
directory.deleteSync(recursive: true);
asyncEnd();
});
checkLocked(file.path)
.then((_) {
return checkLocked(file.path, 0, 2).then((_) {
raf.unlockSync();
return checkNotLocked(file.path).then((_) {});
});
})
.whenComplete(() {
raf.closeSync();
directory.deleteSync(recursive: true);
asyncEnd();
});
}
void testLockWholeFileAsync() {
@@ -116,11 +125,13 @@ void testLockRange() {
() => checkLocked(file.path, 6),
() => checkNotLocked(file.path, 7),
() => raf2.unlockSync(6, 7),
() => checkNotLocked(file.path)
() => checkNotLocked(file.path),
]);
} else {
tests
.addAll([() => raf2.unlockSync(5, 7), () => checkNotLocked(file.path)]);
tests.addAll([
() => raf2.unlockSync(5, 7),
() => checkNotLocked(file.path),
]);
}
Future.forEach<Function>(tests, (f) => f()).whenComplete(() {
raf1.closeSync();
@@ -160,7 +171,7 @@ void testLockRangeAsync() {
() => checkLocked(file.path, 6),
() => checkNotLocked(file.path, 7),
() => raf2.unlock(6, 7),
() => checkNotLocked(file.path)
() => checkNotLocked(file.path),
]);
} else {
tests.addAll([() => raf2.unlock(5, 7), () => checkNotLocked(file.path)]);
@@ -188,7 +199,7 @@ void testLockEnd() {
() => checkLocked(file.path, 10),
() => checkLocked(file.path, 19),
() => raf.unlockSync(2),
() => checkNotLocked(file.path)
() => checkNotLocked(file.path),
], (f) => f()).whenComplete(() {
raf.closeSync();
directory.deleteSync(recursive: true);
@@ -211,7 +222,7 @@ void testLockEndAsync() {
() => checkLocked(file.path, 10),
() => checkLocked(file.path, 19),
() => raf.unlock(2),
() => checkNotLocked(file.path)
() => checkNotLocked(file.path),
], (f) => f()).whenComplete(() {
raf.closeSync();
directory.deleteSync(recursive: true);
@@ -229,7 +240,7 @@ void testLockShared() {
() => raf.lock(FileLock.shared),
() => checkLocked(file.path),
() => checkLocked(file.path, 0, 2),
() => checkNotLocked(file.path, 0, 2, FileLock.shared)
() => checkNotLocked(file.path, 0, 2, FileLock.shared),
], (f) => f()).then((_) {
raf.closeSync();
directory.deleteSync(recursive: true);
@@ -247,7 +258,7 @@ void testLockSharedAsync() {
() => raf.lock(FileLock.shared),
() => checkLocked(file.path),
() => checkLocked(file.path, 0, 2),
() => checkNotLocked(file.path, 0, 2, FileLock.shared)
() => checkNotLocked(file.path, 0, 2, FileLock.shared),
], (f) => f()).whenComplete(() {
raf.closeSync();
directory.deleteSync(recursive: true);
@@ -271,7 +282,7 @@ void testLockAfterLength() {
() => checkLocked(file.path, 10),
() => checkNotLocked(file.path, 15),
() => raf.unlockSync(2, 15),
() => checkNotLocked(file.path)
() => checkNotLocked(file.path),
], (f) => f()).whenComplete(() {
raf.closeSync();
directory.deleteSync(recursive: true);
@@ -295,7 +306,7 @@ void testLockAfterLengthAsync() {
() => checkLocked(file.path, 10),
() => checkNotLocked(file.path, 15),
() => raf.unlock(2, 15),
() => checkNotLocked(file.path)
() => checkNotLocked(file.path),
], (f) => f()).whenComplete(() {
raf.closeSync();
directory.deleteSync(recursive: true);
+27 -14
View File
@@ -99,11 +99,15 @@ void testFileStat(String dir) {
file.setLastModifiedSync(dateTime);
Expect.notEquals(
stat.modified.toString(), file.lastModifiedSync().toString());
stat.modified.toString(),
file.lastModifiedSync().toString(),
);
file.setLastAccessedSync(dateTime);
Expect.notEquals(
stat.accessed.toString(), file.lastAccessedSync().toString());
stat.accessed.toString(),
file.lastAccessedSync().toString(),
);
}
String _createDirectoryHelper(String currentDir, String targetDir) {
@@ -122,10 +126,14 @@ void testCreateLinkToDir(String dir, String dir2) {
Expect.isTrue(linkPath.length > maxPath);
Expect.isTrue(renamedPath.length > maxPath);
final targetDirectory1 =
_createDirectoryHelper(dir, p.join(dir2, 'a_long_directory_target1'));
final targetDirectory2 =
_createDirectoryHelper(dir, p.join(dir2, 'a_long_directory_target2'));
final targetDirectory1 = _createDirectoryHelper(
dir,
p.join(dir2, 'a_long_directory_target1'),
);
final targetDirectory2 = _createDirectoryHelper(
dir,
p.join(dir2, 'a_long_directory_target2'),
);
final linkTarget1 = p.isRelative(dir2)
? p.relative(targetDirectory1, from: p.dirname(p.absolute(linkPath)))
@@ -140,8 +148,9 @@ void testCreateLinkToDir(String dir, String dir2) {
Expect.isTrue(link.existsSync());
final resolvedCreatePath = link.resolveSymbolicLinksSync();
Expect.isTrue(
FileSystemEntity.identicalSync(targetDirectory1, resolvedCreatePath),
'${link.path} should resolve to $targetDirectory1 but resolved to $resolvedCreatePath');
FileSystemEntity.identicalSync(targetDirectory1, resolvedCreatePath),
'${link.path} should resolve to $targetDirectory1 but resolved to $resolvedCreatePath',
);
// Rename link
var renamedLink = link.renameSync(renamedPath);
@@ -149,15 +158,17 @@ void testCreateLinkToDir(String dir, String dir2) {
Expect.isFalse(link.existsSync());
final resolvedRenamePath = renamedLink.resolveSymbolicLinksSync();
Expect.isTrue(
FileSystemEntity.identicalSync(targetDirectory1, resolvedRenamePath),
'${link.path} should resolve to $targetDirectory1 but resolved to $resolvedRenamePath');
FileSystemEntity.identicalSync(targetDirectory1, resolvedRenamePath),
'${link.path} should resolve to $targetDirectory1 but resolved to $resolvedRenamePath',
);
// Update link target
renamedLink.updateSync(linkTarget2);
final resolvedUpdatedPath = renamedLink.resolveSymbolicLinksSync();
Expect.isTrue(
FileSystemEntity.identicalSync(targetDirectory2, resolvedUpdatedPath),
'${link.path} should resolve to $targetDirectory2 but resolved to $resolvedRenamePath');
FileSystemEntity.identicalSync(targetDirectory2, resolvedUpdatedPath),
'${link.path} should resolve to $targetDirectory2 but resolved to $resolvedRenamePath',
);
Directory(targetDirectory1).deleteSync();
Directory(targetDirectory2).deleteSync();
@@ -194,8 +205,10 @@ void testCreateLinkToFile(String dir, String dir2) {
Expect.isTrue(link.existsSync());
final resolvedPath = link.resolveSymbolicLinksSync();
Expect.isTrue(FileSystemEntity.identicalSync(target, resolvedPath),
'${link.path} should resolve to $target but resolved to $resolvedPath');
Expect.isTrue(
FileSystemEntity.identicalSync(target, resolvedPath),
'${link.path} should resolve to $target but resolved to $resolvedPath',
);
// Rename link
var renamedLink = link.renameSync(p.join(dir, 'a_renamed_long_path_link'));
@@ -6,8 +6,9 @@ import "package:expect/expect.dart";
import 'dart:io';
main() {
Directory tempDir =
Directory.systemTemp.createTempSync('dart_file_non_ascii_sync');
Directory tempDir = Directory.systemTemp.createTempSync(
'dart_file_non_ascii_sync',
);
Directory nonAsciiDir = new Directory('${tempDir.path}/æøå');
nonAsciiDir.createSync();
Expect.isTrue(nonAsciiDir.existsSync());
@@ -26,7 +27,8 @@ main() {
Expect.equals(6, nonAsciiFile.lengthSync());
nonAsciiFile.lastModifiedSync();
path = nonAsciiFile.resolveSymbolicLinksSync();
Expect.isTrue(path.endsWith('${precomposed}.txt') ||
path.endsWith('${decomposed}.txt'));
Expect.isTrue(
path.endsWith('${precomposed}.txt') || path.endsWith('${decomposed}.txt'),
);
tempDir.deleteSync(recursive: true);
}
+34 -27
View File
@@ -15,30 +15,38 @@ main() {
var precomposed = 'æøå';
var decomposed = new String.fromCharCodes([47, 230, 248, 97, 778]);
Directory.systemTemp.createTemp('dart_file_non_ascii').then((tempDir) {
Directory nonAsciiDir = new Directory('${tempDir.path}/æøå');
nonAsciiDir.create().then((nonAsciiDir) {
nonAsciiDir.exists().then((result) {
Expect.isTrue(result);
File nonAsciiFile = new File('${nonAsciiDir.path}/æøå.txt');
nonAsciiFile.writeAsString('æøå').then((_) {
nonAsciiFile.exists().then((result) {
Directory.systemTemp
.createTemp('dart_file_non_ascii')
.then((tempDir) {
Directory nonAsciiDir = new Directory('${tempDir.path}/æøå');
nonAsciiDir.create().then((nonAsciiDir) {
nonAsciiDir.exists().then((result) {
Expect.isTrue(result);
nonAsciiFile.readAsString().then((contents) {
// The contents of the file is precomposed utf8.
Expect.equals(precomposed, contents);
nonAsciiFile.create().then((_) {
var d = nonAsciiFile.parent;
Expect.isTrue(d.path.endsWith(precomposed) ||
d.path.endsWith(decomposed));
nonAsciiFile.length().then((length) {
Expect.equals(6, length);
nonAsciiFile.lastModified().then((_) {
nonAsciiFile.resolveSymbolicLinks().then((path) {
Expect.isTrue(path.endsWith('${precomposed}.txt') ||
path.endsWith('${decomposed}.txt'));
tempDir.delete(recursive: true).then((_) {
asyncEnd();
File nonAsciiFile = new File('${nonAsciiDir.path}/æøå.txt');
nonAsciiFile.writeAsString('æøå').then((_) {
nonAsciiFile.exists().then((result) {
Expect.isTrue(result);
nonAsciiFile.readAsString().then((contents) {
// The contents of the file is precomposed utf8.
Expect.equals(precomposed, contents);
nonAsciiFile.create().then((_) {
var d = nonAsciiFile.parent;
Expect.isTrue(
d.path.endsWith(precomposed) ||
d.path.endsWith(decomposed),
);
nonAsciiFile.length().then((length) {
Expect.equals(6, length);
nonAsciiFile.lastModified().then((_) {
nonAsciiFile.resolveSymbolicLinks().then((path) {
Expect.isTrue(
path.endsWith('${precomposed}.txt') ||
path.endsWith('${decomposed}.txt'),
);
tempDir.delete(recursive: true).then((_) {
asyncEnd();
});
});
});
});
});
@@ -47,9 +55,8 @@ main() {
});
});
});
})
.catchError((e) {
Expect.fail("File not found");
});
});
}).catchError((e) {
Expect.fail("File not found");
});
}
@@ -9,8 +9,9 @@ import "package:expect/async_helper.dart";
import "package:expect/expect.dart";
void testOpenOutputStreamSync() {
Directory tempDirectory =
Directory.systemTemp.createTempSync('dart_file_output_stream');
Directory tempDirectory = Directory.systemTemp.createTempSync(
'dart_file_output_stream',
);
asyncStart();
String fileName = "${tempDirectory.path}/test";
+18 -12
View File
@@ -17,12 +17,15 @@ void testReadAsString() {
Expect.throws(file.readAsStringSync, (e) => e is FileSystemException);
asyncStart();
file.readAsString().then((_) {
Expect.fail("expected exception");
}).catchError((e) {
tmp.deleteSync(recursive: true);
asyncEnd();
}, test: (e) => e is FileSystemException);
file
.readAsString()
.then((_) {
Expect.fail("expected exception");
})
.catchError((e) {
tmp.deleteSync(recursive: true);
asyncEnd();
}, test: (e) => e is FileSystemException);
}
void testReadAsLines() {
@@ -36,12 +39,15 @@ void testReadAsLines() {
Expect.throws(file.readAsLinesSync, (e) => e is FileSystemException);
asyncStart();
file.readAsLines().then((_) {
Expect.fail("expected exception");
}).catchError((e) {
tmp.deleteSync(recursive: true);
asyncEnd();
}, test: (e) => e is FileSystemException);
file
.readAsLines()
.then((_) {
Expect.fail("expected exception");
})
.catchError((e) {
tmp.deleteSync(recursive: true);
asyncEnd();
}, test: (e) => e is FileSystemException);
}
void main() {
@@ -14,7 +14,7 @@ void openAndWriteScript(String script) {
var file = script; // Use script as file.
Process.start("bash", [
"-c",
"$executable ${Platform.executableArguments.join(' ')} $script < $file"
"$executable ${Platform.executableArguments.join(' ')} $script < $file",
]).then((process) {
process.exitCode.then((exitCode) {
Expect.equals(0, exitCode);
+78 -52
View File
@@ -44,9 +44,11 @@ void testStat() {
Expect.equals(FileSystemEntityType.directory, directoryStatDirect.type);
if (Platform.operatingSystem != 'windows') {
Expect.isTrue(
directoryStat.modified.compareTo(directoryStat.accessed) < 0);
directoryStat.modified.compareTo(directoryStat.accessed) < 0,
);
Expect.isTrue(
directoryStat.changed.compareTo(directoryStat.accessed) < 0);
directoryStat.changed.compareTo(directoryStat.accessed) < 0,
);
}
Expect.equals(7 << 6, directoryStat.mode & (7 << 6)); // Includes +urwx.
@@ -64,63 +66,87 @@ Future testStatAsync() {
return Directory.systemTemp.createTemp('dart_file_stat').then((directory) {
File file = new File(join(directory.path, "file"));
return FileStat.stat(file.path)
.then((fileStat) =>
Expect.equals(FileSystemEntityType.notFound, fileStat.type))
.then(
(fileStat) =>
Expect.equals(FileSystemEntityType.notFound, fileStat.type),
)
.then((_) => file.stat())
.then((fileStat) =>
Expect.equals(FileSystemEntityType.notFound, fileStat.type))
.then(
(fileStat) =>
Expect.equals(FileSystemEntityType.notFound, fileStat.type),
)
.then((_) => file.writeAsString("Dart IO library test of FileStat"))
.then((_) => new Future.delayed(const Duration(seconds: 2)))
.then((_) => file.readAsString())
.then((_) => directory.list().last)
.then((_) => FileStat.stat(file.path))
.then((FileStat fileStat) {
Expect.equals(FileSystemEntityType.file, fileStat.type);
Expect.equals(32, fileStat.size);
if (Platform.operatingSystem != 'windows') {
Expect.isTrue(fileStat.modified.compareTo(fileStat.accessed) < 0);
Expect.isTrue(fileStat.changed.compareTo(fileStat.accessed) < 0);
}
Expect.equals(6 << 6, fileStat.mode & (6 << 6)); // Mode includes +urw.
return file.stat();
}).then((FileStat fileStat) {
Expect.equals(FileSystemEntityType.file, fileStat.type);
Expect.equals(32, fileStat.size);
if (Platform.operatingSystem != 'windows') {
Expect.isTrue(fileStat.modified.compareTo(fileStat.accessed) < 0);
Expect.isTrue(fileStat.changed.compareTo(fileStat.accessed) < 0);
}
Expect.equals(6 << 6, fileStat.mode & (6 << 6)); // Mode includes +urw.
return FileStat.stat(directory.path);
}).then((FileStat directoryStat) {
Expect.equals(FileSystemEntityType.directory, directoryStat.type);
if (Platform.operatingSystem != 'windows') {
Expect.isTrue(
directoryStat.modified.compareTo(directoryStat.accessed) < 0);
Expect.isTrue(
directoryStat.changed.compareTo(directoryStat.accessed) < 0);
}
Expect.equals(7 << 6, directoryStat.mode & (7 << 6)); // Includes +urwx.
return directory.stat();
}).then((FileStat directoryStat) {
Expect.equals(FileSystemEntityType.directory, directoryStat.type);
if (Platform.operatingSystem != 'windows') {
Expect.isTrue(
directoryStat.modified.compareTo(directoryStat.accessed) < 0);
Expect.isTrue(
directoryStat.changed.compareTo(directoryStat.accessed) < 0);
}
Expect.equals(7 << 6, directoryStat.mode & (7 << 6)); // Includes +urwx.
return new Link(directory.path).stat();
}).then((FileStat linkStat) {
Expect.equals(FileSystemEntityType.directory, linkStat.type);
if (Platform.operatingSystem != 'windows') {
Expect.isTrue(linkStat.modified.compareTo(linkStat.accessed) < 0);
Expect.isTrue(linkStat.changed.compareTo(linkStat.accessed) < 0);
}
Expect.equals(7 << 6, linkStat.mode & (7 << 6)); // Includes +urwx.
return directory.delete(recursive: true);
});
Expect.equals(FileSystemEntityType.file, fileStat.type);
Expect.equals(32, fileStat.size);
if (Platform.operatingSystem != 'windows') {
Expect.isTrue(fileStat.modified.compareTo(fileStat.accessed) < 0);
Expect.isTrue(fileStat.changed.compareTo(fileStat.accessed) < 0);
}
Expect.equals(
6 << 6,
fileStat.mode & (6 << 6),
); // Mode includes +urw.
return file.stat();
})
.then((FileStat fileStat) {
Expect.equals(FileSystemEntityType.file, fileStat.type);
Expect.equals(32, fileStat.size);
if (Platform.operatingSystem != 'windows') {
Expect.isTrue(fileStat.modified.compareTo(fileStat.accessed) < 0);
Expect.isTrue(fileStat.changed.compareTo(fileStat.accessed) < 0);
}
Expect.equals(
6 << 6,
fileStat.mode & (6 << 6),
); // Mode includes +urw.
return FileStat.stat(directory.path);
})
.then((FileStat directoryStat) {
Expect.equals(FileSystemEntityType.directory, directoryStat.type);
if (Platform.operatingSystem != 'windows') {
Expect.isTrue(
directoryStat.modified.compareTo(directoryStat.accessed) < 0,
);
Expect.isTrue(
directoryStat.changed.compareTo(directoryStat.accessed) < 0,
);
}
Expect.equals(
7 << 6,
directoryStat.mode & (7 << 6),
); // Includes +urwx.
return directory.stat();
})
.then((FileStat directoryStat) {
Expect.equals(FileSystemEntityType.directory, directoryStat.type);
if (Platform.operatingSystem != 'windows') {
Expect.isTrue(
directoryStat.modified.compareTo(directoryStat.accessed) < 0,
);
Expect.isTrue(
directoryStat.changed.compareTo(directoryStat.accessed) < 0,
);
}
Expect.equals(
7 << 6,
directoryStat.mode & (7 << 6),
); // Includes +urwx.
return new Link(directory.path).stat();
})
.then((FileStat linkStat) {
Expect.equals(FileSystemEntityType.directory, linkStat.type);
if (Platform.operatingSystem != 'windows') {
Expect.isTrue(linkStat.modified.compareTo(linkStat.accessed) < 0);
Expect.isTrue(linkStat.changed.compareTo(linkStat.accessed) < 0);
}
Expect.equals(7 << 6, linkStat.mode & (7 << 6)); // Includes +urwx.
return directory.delete(recursive: true);
});
});
}
+25 -26
View File
@@ -12,29 +12,30 @@ void testPauseResumeCancelStream() {
asyncStart();
Directory.systemTemp.createTemp('dart_file_stream').then((d) {
var file = new File("${d.path}/file");
new File(Platform.executable)
.openRead()
.cast<List<int>>()
.pipe(file.openWrite())
.then((_) {
new File(
Platform.executable,
).openRead().cast<List<int>>().pipe(file.openWrite()).then((_) {
var subscription;
subscription = file.openRead().listen((data) {
subscription.pause();
subscription.resume();
void close() {
d.deleteSync(recursive: true);
asyncEnd();
}
subscription = file.openRead().listen(
(data) {
subscription.pause();
subscription.resume();
void close() {
d.deleteSync(recursive: true);
asyncEnd();
}
var future = subscription.cancel();
if (future != null) {
future.whenComplete(close);
} else {
close();
}
}, onDone: () {
Expect.fail('the stream was canceled, onDone should not happen');
});
var future = subscription.cancel();
if (future != null) {
future.whenComplete(close);
} else {
close();
}
},
onDone: () {
Expect.fail('the stream was canceled, onDone should not happen');
},
);
});
});
}
@@ -43,11 +44,9 @@ void testStreamIsEmpty() {
asyncStart();
Directory.systemTemp.createTemp('dart_file_stream').then((d) {
var file = new File("${d.path}/file");
new File(Platform.executable)
.openRead()
.cast<List<int>>()
.pipe(file.openWrite())
.then((_) {
new File(
Platform.executable,
).openRead().cast<List<int>>().pipe(file.openWrite()).then((_) {
// isEmpty will cancel the stream after first data event.
file.openRead().isEmpty.then((empty) {
Expect.isFalse(empty);
@@ -18,9 +18,10 @@ class FutureExpect {
static Future listEquals(expected, Future result) =>
result.then((value) => Expect.listEquals(expected, value));
static Future throws(Future result) => result.then((value) {
throw new ExpectException(
"FutureExpect.throws received $value instead of an exception");
}, onError: (_) => null);
throw new ExpectException(
"FutureExpect.throws received $value instead of an exception",
);
}, onError: (_) => null);
}
Future testFileExistsCreate() {
@@ -34,14 +35,30 @@ Future testFileExistsCreate() {
.then((_) => FutureExpect.isFalse(new File(x).exists()))
.then((_) => FutureExpect.isTrue(FileSystemEntity.isLink(y)))
.then((_) => FutureExpect.isFalse(FileSystemEntity.isLink(x)))
.then((_) => FutureExpect.equals(
FileSystemEntityType.notFound, FileSystemEntity.type(y)))
.then((_) => FutureExpect.equals(
FileSystemEntityType.notFound, FileSystemEntity.type(x)))
.then((_) => FutureExpect.equals(FileSystemEntityType.link,
FileSystemEntity.type(y, followLinks: false)))
.then((_) => FutureExpect.equals(FileSystemEntityType.notFound,
FileSystemEntity.type(x, followLinks: false)))
.then(
(_) => FutureExpect.equals(
FileSystemEntityType.notFound,
FileSystemEntity.type(y),
),
)
.then(
(_) => FutureExpect.equals(
FileSystemEntityType.notFound,
FileSystemEntity.type(x),
),
)
.then(
(_) => FutureExpect.equals(
FileSystemEntityType.link,
FileSystemEntity.type(y, followLinks: false),
),
)
.then(
(_) => FutureExpect.equals(
FileSystemEntityType.notFound,
FileSystemEntity.type(x, followLinks: false),
),
)
.then((_) => FutureExpect.equals(x, new Link(y).target()))
.then((_) => new File(y).create())
.then((yFile) => Expect.equals(y, yFile.path))
@@ -51,14 +68,30 @@ Future testFileExistsCreate() {
.then((_) => FutureExpect.isFalse(FileSystemEntity.isLink(x)))
.then((_) => FutureExpect.isTrue(FileSystemEntity.isFile(y)))
.then((_) => FutureExpect.isTrue(FileSystemEntity.isFile(x)))
.then((_) => FutureExpect.equals(
FileSystemEntityType.file, FileSystemEntity.type(y)))
.then((_) => FutureExpect.equals(
FileSystemEntityType.file, FileSystemEntity.type(x)))
.then((_) => FutureExpect.equals(FileSystemEntityType.link,
FileSystemEntity.type(y, followLinks: false)))
.then((_) => FutureExpect.equals(FileSystemEntityType.file,
FileSystemEntity.type(x, followLinks: false)))
.then(
(_) => FutureExpect.equals(
FileSystemEntityType.file,
FileSystemEntity.type(y),
),
)
.then(
(_) => FutureExpect.equals(
FileSystemEntityType.file,
FileSystemEntity.type(x),
),
)
.then(
(_) => FutureExpect.equals(
FileSystemEntityType.link,
FileSystemEntity.type(y, followLinks: false),
),
)
.then(
(_) => FutureExpect.equals(
FileSystemEntityType.file,
FileSystemEntity.type(x, followLinks: false),
),
)
.then((_) => FutureExpect.equals(x, new Link(y).target()))
.then((_) => new File(x).delete())
.then((xDeletedFile) => Expect.equals(x, xDeletedFile.path))
@@ -68,22 +101,46 @@ Future testFileExistsCreate() {
.then((_) => FutureExpect.isFalse(FileSystemEntity.isLink(x)))
.then((_) => FutureExpect.isTrue(FileSystemEntity.isDirectory(y)))
.then((_) => FutureExpect.isTrue(FileSystemEntity.isDirectory(x)))
.then((_) => FutureExpect.equals(
FileSystemEntityType.directory, FileSystemEntity.type(y)))
.then((_) => FutureExpect.equals(
FileSystemEntityType.directory, FileSystemEntity.type(x)))
.then((_) => FutureExpect.equals(FileSystemEntityType.link,
FileSystemEntity.type(y, followLinks: false)))
.then((_) => FutureExpect.equals(FileSystemEntityType.directory,
FileSystemEntity.type(x, followLinks: false)))
.then(
(_) => FutureExpect.equals(
FileSystemEntityType.directory,
FileSystemEntity.type(y),
),
)
.then(
(_) => FutureExpect.equals(
FileSystemEntityType.directory,
FileSystemEntity.type(x),
),
)
.then(
(_) => FutureExpect.equals(
FileSystemEntityType.link,
FileSystemEntity.type(y, followLinks: false),
),
)
.then(
(_) => FutureExpect.equals(
FileSystemEntityType.directory,
FileSystemEntity.type(x, followLinks: false),
),
)
.then((_) => FutureExpect.equals(x, new Link(y).target()))
.then((_) => new Link(y).delete())
.then((_) => FutureExpect.isFalse(FileSystemEntity.isLink(y)))
.then((_) => FutureExpect.isFalse(FileSystemEntity.isLink(x)))
.then((_) => FutureExpect.equals(
FileSystemEntityType.notFound, FileSystemEntity.type(y)))
.then(
(_) => FutureExpect.equals(FileSystemEntityType.directory, FileSystemEntity.type(x)))
(_) => FutureExpect.equals(
FileSystemEntityType.notFound,
FileSystemEntity.type(y),
),
)
.then(
(_) => FutureExpect.equals(
FileSystemEntityType.directory,
FileSystemEntity.type(x),
),
)
.then((_) => FutureExpect.throws(new Link(y).target()))
.then((_) => temp.delete(recursive: true));
});
@@ -119,8 +176,10 @@ Future testFileWriteRead() {
return new File(x)
.create()
.then((_) => new Link(y).create(x))
.then((_) =>
(new File(y).openWrite(mode: FileMode.write)..add(data)).close())
.then(
(_) =>
(new File(y).openWrite(mode: FileMode.write)..add(data)).close(),
)
.then((_) => FutureExpect.listEquals(data, new File(y).readAsBytes()))
.then((_) => FutureExpect.listEquals(data, new File(x).readAsBytes()))
.then((_) => temp.delete(recursive: true));
@@ -142,9 +201,9 @@ Future testDirectoryExistsCreate() {
Future testDirectoryDelete() {
return Directory.systemTemp.createTemp('dart_file_system_async').then((temp) {
return Directory.systemTemp
.createTemp('dart_file_system_async')
.then((temp2) {
return Directory.systemTemp.createTemp('dart_file_system_async').then((
temp2,
) {
var y = '${temp.path}${Platform.pathSeparator}y';
var x = '${temp2.path}${Platform.pathSeparator}x';
var link = new Directory(y);
@@ -170,25 +229,30 @@ Future testDirectoryDelete() {
Future testDirectoryListing() {
return Directory.systemTemp.createTemp('dart_file_system_async').then((temp) {
return Directory.systemTemp
.createTemp('dart_file_system_async_links')
.then((temp2) {
var sep = Platform.pathSeparator;
var y = '${temp.path}${sep}y';
var x = '${temp2.path}${sep}x';
return new File(x)
.create()
.then((_) => new Link(y).create(temp2.path))
.then((_) =>
temp.list(recursive: true).singleWhere((entry) => entry is File))
.then((file) => Expect.isTrue(file.path.endsWith('$y${sep}x')))
.then((_) => temp
.list(recursive: true)
.singleWhere((entry) => entry is Directory))
.then((dir) => Expect.isTrue(dir.path.endsWith('y')))
.then((_) => temp.delete(recursive: true))
.then((_) => temp2.delete(recursive: true));
});
return Directory.systemTemp.createTemp('dart_file_system_async_links').then(
(temp2) {
var sep = Platform.pathSeparator;
var y = '${temp.path}${sep}y';
var x = '${temp2.path}${sep}x';
return new File(x)
.create()
.then((_) => new Link(y).create(temp2.path))
.then(
(_) => temp
.list(recursive: true)
.singleWhere((entry) => entry is File),
)
.then((file) => Expect.isTrue(file.path.endsWith('$y${sep}x')))
.then(
(_) => temp
.list(recursive: true)
.singleWhere((entry) => entry is Directory),
)
.then((dir) => Expect.isTrue(dir.path.endsWith('y')))
.then((_) => temp.delete(recursive: true))
.then((_) => temp2.delete(recursive: true));
},
);
});
}
@@ -202,18 +266,20 @@ Future testDirectoryListingBrokenLink() {
return new File(x)
.create()
.then((_) => new Link(link).create(doesNotExist))
.then((_) => temp.list(recursive: true).forEach((entity) {
if (entity is File) {
Expect.isFalse(sawFile);
sawFile = true;
Expect.isTrue(entity.path.endsWith(x));
} else {
Expect.isTrue(entity is Link);
Expect.isFalse(sawLink);
sawLink = true;
Expect.isTrue(entity.path.endsWith(link));
}
}))
.then(
(_) => temp.list(recursive: true).forEach((entity) {
if (entity is File) {
Expect.isFalse(sawFile);
sawFile = true;
Expect.isTrue(entity.path.endsWith(x));
} else {
Expect.isTrue(entity is Link);
Expect.isFalse(sawLink);
sawLink = true;
Expect.isTrue(entity.path.endsWith(link));
}
}),
)
.then((_) => temp.delete(recursive: true));
});
}
+70 -50
View File
@@ -22,10 +22,14 @@ testFileExistsCreate() {
Expect.isFalse(FileSystemEntity.isLinkSync(x));
Expect.equals(FileSystemEntityType.notFound, FileSystemEntity.typeSync(y));
Expect.equals(FileSystemEntityType.notFound, FileSystemEntity.typeSync(x));
Expect.equals(FileSystemEntityType.link,
FileSystemEntity.typeSync(y, followLinks: false));
Expect.equals(FileSystemEntityType.notFound,
FileSystemEntity.typeSync(x, followLinks: false));
Expect.equals(
FileSystemEntityType.link,
FileSystemEntity.typeSync(y, followLinks: false),
);
Expect.equals(
FileSystemEntityType.notFound,
FileSystemEntity.typeSync(x, followLinks: false),
);
Expect.equals(x, new Link(y).targetSync());
new File(y).createSync();
@@ -37,10 +41,14 @@ testFileExistsCreate() {
Expect.isTrue(FileSystemEntity.isFileSync(x));
Expect.equals(FileSystemEntityType.file, FileSystemEntity.typeSync(y));
Expect.equals(FileSystemEntityType.file, FileSystemEntity.typeSync(x));
Expect.equals(FileSystemEntityType.link,
FileSystemEntity.typeSync(y, followLinks: false));
Expect.equals(FileSystemEntityType.file,
FileSystemEntity.typeSync(x, followLinks: false));
Expect.equals(
FileSystemEntityType.link,
FileSystemEntity.typeSync(y, followLinks: false),
);
Expect.equals(
FileSystemEntityType.file,
FileSystemEntity.typeSync(x, followLinks: false),
);
Expect.equals(x, new Link(y).targetSync());
new File(x).deleteSync();
@@ -51,10 +59,14 @@ testFileExistsCreate() {
Expect.isTrue(FileSystemEntity.isDirectorySync(x));
Expect.equals(FileSystemEntityType.directory, FileSystemEntity.typeSync(y));
Expect.equals(FileSystemEntityType.directory, FileSystemEntity.typeSync(x));
Expect.equals(FileSystemEntityType.link,
FileSystemEntity.typeSync(y, followLinks: false));
Expect.equals(FileSystemEntityType.directory,
FileSystemEntity.typeSync(x, followLinks: false));
Expect.equals(
FileSystemEntityType.link,
FileSystemEntity.typeSync(y, followLinks: false),
);
Expect.equals(
FileSystemEntityType.directory,
FileSystemEntity.typeSync(x, followLinks: false),
);
Expect.equals(x, new Link(y).targetSync());
new Link(y).deleteSync();
@@ -171,22 +183,27 @@ testDirectoryListing() {
files = [];
dirs = [];
var lister = temp.list(recursive: true).listen((entity) {
if (entity is File) {
files.add(entity.path);
} else {
Expect.isTrue(entity is Directory);
dirs.add(entity.path);
}
}, onDone: () {
Expect.equals(1, files.length);
Expect.isTrue(files[0].endsWith('$y${Platform.pathSeparator}x'));
Expect.equals(1, dirs.length);
Expect.isTrue(dirs[0].endsWith(y));
temp.deleteSync(recursive: true);
temp2.deleteSync(recursive: true);
asyncEnd();
});
var lister = temp
.list(recursive: true)
.listen(
(entity) {
if (entity is File) {
files.add(entity.path);
} else {
Expect.isTrue(entity is Directory);
dirs.add(entity.path);
}
},
onDone: () {
Expect.equals(1, files.length);
Expect.isTrue(files[0].endsWith('$y${Platform.pathSeparator}x'));
Expect.equals(1, dirs.length);
Expect.isTrue(dirs[0].endsWith(y));
temp.deleteSync(recursive: true);
temp2.deleteSync(recursive: true);
asyncEnd();
},
);
});
}
@@ -203,28 +220,31 @@ testDirectoryListingBrokenLink() {
var dirs = [];
var links = [];
var errors = [];
temp.list(recursive: true).listen(
(entity) {
if (entity is File) {
files.add(entity.path);
} else if (entity is Link) {
links.add(entity.path);
} else {
Expect.isTrue(entity is Directory);
dirs.add(entity.path);
}
},
onError: (e) => errors.add(e),
onDone: () {
Expect.equals(1, files.length);
Expect.isTrue(files[0].endsWith(x));
Expect.equals(1, links.length);
Expect.isTrue(links[0].endsWith(link));
Expect.equals(0, dirs.length);
Expect.equals(0, errors.length);
temp.deleteSync(recursive: true);
asyncEnd();
});
temp
.list(recursive: true)
.listen(
(entity) {
if (entity is File) {
files.add(entity.path);
} else if (entity is Link) {
links.add(entity.path);
} else {
Expect.isTrue(entity is Directory);
dirs.add(entity.path);
}
},
onError: (e) => errors.add(e),
onDone: () {
Expect.equals(1, files.length);
Expect.isTrue(files[0].endsWith(x));
Expect.equals(1, links.length);
Expect.isTrue(links[0].endsWith(link));
Expect.equals(0, dirs.length);
Expect.equals(0, errors.length);
temp.deleteSync(recursive: true);
asyncEnd();
},
);
});
}
+176 -129
View File
@@ -18,17 +18,20 @@ void testWatchCreateFile() {
asyncStart();
var sub;
sub = watcher.listen((event) {
if (event is FileSystemCreateEvent && event.path.endsWith('file')) {
Expect.isFalse(event.isDirectory);
asyncEnd();
sub.cancel();
sub = watcher.listen(
(event) {
if (event is FileSystemCreateEvent && event.path.endsWith('file')) {
Expect.isFalse(event.isDirectory);
asyncEnd();
sub.cancel();
dir.deleteSync(recursive: true);
}
},
onError: (e) {
dir.deleteSync(recursive: true);
}
}, onError: (e) {
dir.deleteSync(recursive: true);
throw e;
});
throw e;
},
);
file.createSync();
}
@@ -41,17 +44,20 @@ void testWatchCreateDir() {
asyncStart();
var sub;
sub = watcher.listen((event) {
if (event is FileSystemCreateEvent && event.path.endsWith('dir')) {
Expect.isTrue(event.isDirectory);
asyncEnd();
sub.cancel();
sub = watcher.listen(
(event) {
if (event is FileSystemCreateEvent && event.path.endsWith('dir')) {
Expect.isTrue(event.isDirectory);
asyncEnd();
sub.cancel();
dir.deleteSync(recursive: true);
}
},
onError: (e) {
dir.deleteSync(recursive: true);
}
}, onError: (e) {
dir.deleteSync(recursive: true);
throw e;
});
throw e;
},
);
subdir.createSync();
}
@@ -65,17 +71,20 @@ void testWatchModifyFile() {
asyncStart();
var sub;
sub = watcher.listen((event) {
if (event is FileSystemModifyEvent) {
Expect.isTrue(event.path.endsWith('file'));
sub.cancel();
asyncEnd();
sub = watcher.listen(
(event) {
if (event is FileSystemModifyEvent) {
Expect.isTrue(event.path.endsWith('file'));
sub.cancel();
asyncEnd();
dir.deleteSync(recursive: true);
}
},
onError: (e) {
dir.deleteSync(recursive: true);
}
}, onError: (e) {
dir.deleteSync(recursive: true);
throw e;
});
throw e;
},
);
file.writeAsStringSync('a');
}
@@ -90,19 +99,22 @@ void testWatchTruncateFile() {
asyncStart();
var sub;
sub = watcher.listen((event) {
if (event is FileSystemModifyEvent) {
Expect.isTrue(event.path.endsWith('file'));
Expect.isTrue(event.contentChanged);
sub.cancel();
asyncEnd();
fileHandle.closeSync();
sub = watcher.listen(
(event) {
if (event is FileSystemModifyEvent) {
Expect.isTrue(event.path.endsWith('file'));
Expect.isTrue(event.contentChanged);
sub.cancel();
asyncEnd();
fileHandle.closeSync();
dir.deleteSync(recursive: true);
}
},
onError: (e) {
dir.deleteSync(recursive: true);
}
}, onError: (e) {
dir.deleteSync(recursive: true);
throw e;
});
throw e;
},
);
fileHandle.truncateSync(1);
}
@@ -118,21 +130,24 @@ void testWatchMoveFile() {
asyncStart();
var sub;
sub = watcher.listen((event) {
if (event is FileSystemMoveEvent) {
Expect.isTrue(event.path.endsWith('file'));
final destination = event.destination;
if (destination != null) {
Expect.isTrue(destination.endsWith('file2'));
sub = watcher.listen(
(event) {
if (event is FileSystemMoveEvent) {
Expect.isTrue(event.path.endsWith('file'));
final destination = event.destination;
if (destination != null) {
Expect.isTrue(destination.endsWith('file2'));
}
sub.cancel();
asyncEnd();
dir.deleteSync(recursive: true);
}
sub.cancel();
asyncEnd();
},
onError: (e) {
dir.deleteSync(recursive: true);
}
}, onError: (e) {
dir.deleteSync(recursive: true);
throw e;
});
throw e;
},
);
file.renameSync(join(dir.path, 'file2'));
}
@@ -146,17 +161,20 @@ void testWatchDeleteFile() {
asyncStart();
var sub;
sub = watcher.listen((event) {
if (event is FileSystemDeleteEvent) {
Expect.isTrue(event.path.endsWith('file'));
sub.cancel();
asyncEnd();
sub = watcher.listen(
(event) {
if (event is FileSystemDeleteEvent) {
Expect.isTrue(event.path.endsWith('file'));
sub.cancel();
asyncEnd();
dir.deleteSync(recursive: true);
}
},
onError: (e) {
dir.deleteSync(recursive: true);
}
}, onError: (e) {
dir.deleteSync(recursive: true);
throw e;
});
throw e;
},
);
file.deleteSync();
}
@@ -169,13 +187,16 @@ void testWatchDeleteDir() {
var watcher = dir.watch(events: 0);
asyncStart();
watcher.listen((event) {
if (event is FileSystemDeleteEvent) {
Expect.isTrue(event.path == dir.path);
}
}, onDone: () {
asyncEnd();
});
watcher.listen(
(event) {
if (event is FileSystemDeleteEvent) {
Expect.isTrue(event.path == dir.path);
}
},
onDone: () {
asyncEnd();
},
);
dir.deleteSync();
}
@@ -188,16 +209,19 @@ void testWatchOnlyModifyFile() {
asyncStart();
var sub;
sub = watcher.listen((event) {
Expect.isTrue(event is FileSystemModifyEvent);
Expect.isTrue(event.path.endsWith('file'));
sub.cancel();
asyncEnd();
dir.deleteSync(recursive: true);
}, onError: (e) {
dir.deleteSync(recursive: true);
throw e;
});
sub = watcher.listen(
(event) {
Expect.isTrue(event is FileSystemModifyEvent);
Expect.isTrue(event.path.endsWith('file'));
sub.cancel();
asyncEnd();
dir.deleteSync(recursive: true);
},
onError: (e) {
dir.deleteSync(recursive: true);
throw e;
},
);
file.createSync();
file.writeAsStringSync('a');
@@ -261,16 +285,19 @@ void testWatchRecursive() {
asyncStart();
var sub;
sub = watcher.listen((event) {
if (event.path.endsWith('file')) {
sub.cancel();
asyncEnd();
sub = watcher.listen(
(event) {
if (event.path.endsWith('file')) {
sub.cancel();
asyncEnd();
dir.deleteSync(recursive: true);
}
},
onError: (e) {
dir.deleteSync(recursive: true);
}
}, onError: (e) {
dir.deleteSync(recursive: true);
throw e;
});
throw e;
},
);
file.createSync();
}
@@ -285,14 +312,17 @@ void testWatchNonRecursive() {
asyncStart();
var sub;
sub = watcher.listen((event) {
if (event.path.endsWith('file')) {
throw "File change event not expected";
}
}, onError: (e) {
dir.deleteSync(recursive: true);
throw e;
});
sub = watcher.listen(
(event) {
if (event.path.endsWith('file')) {
throw "File change event not expected";
}
},
onError: (e) {
dir.deleteSync(recursive: true);
throw e;
},
);
file.createSync();
@@ -307,12 +337,15 @@ void testWatchNonExisting() {
// MacOS allows listening on non-existing paths.
if (Platform.isMacOS) return;
asyncStart();
new Directory('__some_none_existing_dir__').watch().listen((_) {
Expect.fail('unexpected error');
}, onError: (e) {
asyncEnd();
Expect.isTrue(e is PathNotFoundException);
});
new Directory('__some_none_existing_dir__').watch().listen(
(_) {
Expect.fail('unexpected error');
},
onError: (e) {
asyncEnd();
Expect.isTrue(e is PathNotFoundException);
},
);
}
void testWatchMoveSelf() {
@@ -326,16 +359,19 @@ void testWatchMoveSelf() {
asyncStart();
bool gotDelete = false;
watcher.listen((event) {
if (event is FileSystemDeleteEvent) {
Expect.isTrue(event.path.endsWith('dir'));
gotDelete = true;
}
}, onDone: () {
Expect.isTrue(gotDelete);
dir.deleteSync(recursive: true);
asyncEnd();
});
watcher.listen(
(event) {
if (event is FileSystemDeleteEvent) {
Expect.isTrue(event.path.endsWith('dir'));
gotDelete = true;
}
},
onDone: () {
Expect.isTrue(gotDelete);
dir.deleteSync(recursive: true);
asyncEnd();
},
);
dir2.renameSync(join(dir.path, 'new_dir'));
}
@@ -386,8 +422,12 @@ testWatchConsistentModifiedFile() async {
RawReceivePort errorReceivePort = RawReceivePort((object) {
print('worker errored: $object');
});
Isolate isolate = await Isolate.spawn(modifyFiles, receivePort.sendPort,
onExit: exitReceivePort.sendPort, onError: errorReceivePort.sendPort);
Isolate isolate = await Isolate.spawn(
modifyFiles,
receivePort.sendPort,
onExit: exitReceivePort.sendPort,
onError: errorReceivePort.sendPort,
);
await modificationEventReceived.future;
workerSendPort.send('end');
@@ -443,13 +483,17 @@ testWatchOverflow() async {
ReceivePort receivePort = ReceivePort();
Completer<bool> exiting = Completer<bool>();
Directory dir =
Directory.systemTemp.createTempSync('dart_file_system_watcher');
Directory dir = Directory.systemTemp.createTempSync(
'dart_file_system_watcher',
);
var file = new File(join(dir.path, 'file'));
file.createSync();
Isolate isolate =
await Isolate.spawn(watcher, receivePort.sendPort, paused: true);
Isolate isolate = await Isolate.spawn(
watcher,
receivePort.sendPort,
paused: true,
);
var subscription;
subscription = receivePort.listen((object) async {
@@ -476,14 +520,17 @@ testWatchOverflow() async {
}
void watcher(SendPort sendPort) async {
runZonedGuarded(() {
var watcher = Directory.systemTemp.watch(recursive: true);
watcher.listen((data) async {});
sendPort.send('start');
}, (error, stack) {
print(error);
sendPort.send('end');
});
runZonedGuarded(
() {
var watcher = Directory.systemTemp.watch(recursive: true);
watcher.listen((data) async {});
sendPort.send('start');
},
(error, stack) {
print(error);
sendPort.send('end');
},
);
}
void main() {
+2 -1
View File
@@ -1684,7 +1684,8 @@ class FileTest {
}
static void testRename({required bool targetExists}) {
lift(Function f) => (futureValue) => futureValue.then((value) => f(value));
lift(Function f) =>
(futureValue) => futureValue.then((value) => f(value));
asyncTestStarted();
String source = join(tempDirectory.path, 'rename_${targetExists}_source');
+338 -212
View File
@@ -18,26 +18,34 @@ void testWriteInt8ListAndView() {
const int VIEW_LENGTH = 4;
Int8List list = new Int8List(LIST_LENGTH);
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
var view =
new Int8List.view(list.buffer, OFFSET_IN_BYTES_FOR_VIEW, VIEW_LENGTH);
var view = new Int8List.view(
list.buffer,
OFFSET_IN_BYTES_FOR_VIEW,
VIEW_LENGTH,
);
Directory.systemTemp.createTemp('dart_file_typed_data').then((temp) {
var file = new File("${temp.path}/test");
file.open(mode: FileMode.write).then((raf) {
return raf.writeFrom(list, 0, LIST_LENGTH);
}).then((raf) {
return raf.writeFrom(view, 0, VIEW_LENGTH);
}).then((raf) {
return raf.close();
}).then((_) {
var expected = [];
expected.addAll(list);
expected.addAll(view);
var content = file.readAsBytesSync();
Expect.listEquals(expected, content);
temp.deleteSync(recursive: true);
asyncEnd();
});
file
.open(mode: FileMode.write)
.then((raf) {
return raf.writeFrom(list, 0, LIST_LENGTH);
})
.then((raf) {
return raf.writeFrom(view, 0, VIEW_LENGTH);
})
.then((raf) {
return raf.close();
})
.then((_) {
var expected = [];
expected.addAll(list);
expected.addAll(view);
var content = file.readAsBytesSync();
Expect.listEquals(expected, content);
temp.deleteSync(recursive: true);
asyncEnd();
});
});
}
@@ -48,26 +56,34 @@ void testWriteUint8ListAndView() {
const int VIEW_LENGTH = 4;
Uint8List list = new Uint8List(LIST_LENGTH);
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
var view =
new Uint8List.view(list.buffer, OFFSET_IN_BYTES_FOR_VIEW, VIEW_LENGTH);
var view = new Uint8List.view(
list.buffer,
OFFSET_IN_BYTES_FOR_VIEW,
VIEW_LENGTH,
);
Directory.systemTemp.createTemp('dart_file_typed_data').then((temp) {
var file = new File("${temp.path}/test");
file.open(mode: FileMode.write).then((raf) {
return raf.writeFrom(list, 0, LIST_LENGTH);
}).then((raf) {
return raf.writeFrom(view, 0, VIEW_LENGTH);
}).then((raf) {
return raf.close();
}).then((_) {
var expected = [];
expected.addAll(list);
expected.addAll(view);
var content = file.readAsBytesSync();
Expect.listEquals(expected, content);
temp.deleteSync(recursive: true);
asyncEnd();
});
file
.open(mode: FileMode.write)
.then((raf) {
return raf.writeFrom(list, 0, LIST_LENGTH);
})
.then((raf) {
return raf.writeFrom(view, 0, VIEW_LENGTH);
})
.then((raf) {
return raf.close();
})
.then((_) {
var expected = [];
expected.addAll(list);
expected.addAll(view);
var content = file.readAsBytesSync();
Expect.listEquals(expected, content);
temp.deleteSync(recursive: true);
asyncEnd();
});
});
}
@@ -79,25 +95,33 @@ void testWriteUint8ClampedListAndView() {
Uint8ClampedList list = new Uint8ClampedList(LIST_LENGTH);
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
var view = new Uint8ClampedList.view(
list.buffer, OFFSET_IN_BYTES_FOR_VIEW, VIEW_LENGTH);
list.buffer,
OFFSET_IN_BYTES_FOR_VIEW,
VIEW_LENGTH,
);
Directory.systemTemp.createTemp('dart_file_typed_data').then((temp) {
var file = new File("${temp.path}/test");
file.open(mode: FileMode.write).then((raf) {
return raf.writeFrom(list, 0, LIST_LENGTH);
}).then((raf) {
return raf.writeFrom(view, 0, VIEW_LENGTH);
}).then((raf) {
return raf.close();
}).then((_) {
var expected = [];
expected.addAll(list);
expected.addAll(view);
var content = file.readAsBytesSync();
Expect.listEquals(expected, content);
temp.deleteSync(recursive: true);
asyncEnd();
});
file
.open(mode: FileMode.write)
.then((raf) {
return raf.writeFrom(list, 0, LIST_LENGTH);
})
.then((raf) {
return raf.writeFrom(view, 0, VIEW_LENGTH);
})
.then((raf) {
return raf.close();
})
.then((_) {
var expected = [];
expected.addAll(list);
expected.addAll(view);
var content = file.readAsBytesSync();
Expect.listEquals(expected, content);
temp.deleteSync(recursive: true);
asyncEnd();
});
});
}
@@ -110,36 +134,53 @@ void testWriteInt16ListAndView() {
const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int16List.bytesPerElement;
var list = new Int16List(LIST_LENGTH);
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
var view =
new Int16List.view(list.buffer, OFFSET_IN_BYTES_FOR_VIEW, VIEW_LENGTH);
var view = new Int16List.view(
list.buffer,
OFFSET_IN_BYTES_FOR_VIEW,
VIEW_LENGTH,
);
Directory.systemTemp.createTemp('dart_file_typed_data').then((temp) {
var file = new File("${temp.path}/test");
file.open(mode: FileMode.write).then((raf) {
return raf.writeFrom(
new Uint8List.view(list.buffer), 0, LIST_LENGTH_IN_BYTES);
}).then((raf) {
return raf.writeFrom(
new Uint8List.view(
view.buffer, view.offsetInBytes, view.lengthInBytes),
0,
VIEW_LENGTH_IN_BYTES);
}).then((raf) {
return raf.close();
}).then((_) {
var expected = [];
expected.addAll(list);
expected.addAll(view);
var content = file.readAsBytesSync();
var typed_data_content = new Uint8List(content.length);
for (int i = 0; i < content.length; i++) {
typed_data_content[i] = content[i];
}
Expect.listEquals(
expected, new Int16List.view(typed_data_content.buffer));
temp.deleteSync(recursive: true);
asyncEnd();
});
file
.open(mode: FileMode.write)
.then((raf) {
return raf.writeFrom(
new Uint8List.view(list.buffer),
0,
LIST_LENGTH_IN_BYTES,
);
})
.then((raf) {
return raf.writeFrom(
new Uint8List.view(
view.buffer,
view.offsetInBytes,
view.lengthInBytes,
),
0,
VIEW_LENGTH_IN_BYTES,
);
})
.then((raf) {
return raf.close();
})
.then((_) {
var expected = [];
expected.addAll(list);
expected.addAll(view);
var content = file.readAsBytesSync();
var typed_data_content = new Uint8List(content.length);
for (int i = 0; i < content.length; i++) {
typed_data_content[i] = content[i];
}
Expect.listEquals(
expected,
new Int16List.view(typed_data_content.buffer),
);
temp.deleteSync(recursive: true);
asyncEnd();
});
});
}
@@ -152,36 +193,53 @@ void testWriteUint16ListAndView() {
const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Uint16List.bytesPerElement;
var list = new Uint16List(LIST_LENGTH);
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
var view =
new Uint16List.view(list.buffer, OFFSET_IN_BYTES_FOR_VIEW, VIEW_LENGTH);
var view = new Uint16List.view(
list.buffer,
OFFSET_IN_BYTES_FOR_VIEW,
VIEW_LENGTH,
);
Directory.systemTemp.createTemp('dart_file_typed_data').then((temp) {
var file = new File("${temp.path}/test");
file.open(mode: FileMode.write).then((raf) {
return raf.writeFrom(
new Uint8List.view(list.buffer), 0, LIST_LENGTH_IN_BYTES);
}).then((raf) {
return raf.writeFrom(
new Uint8List.view(
view.buffer, view.offsetInBytes, view.lengthInBytes),
0,
VIEW_LENGTH_IN_BYTES);
}).then((raf) {
return raf.close();
}).then((_) {
var expected = [];
expected.addAll(list);
expected.addAll(view);
var content = file.readAsBytesSync();
var typed_data_content = new Uint8List(content.length);
for (int i = 0; i < content.length; i++) {
typed_data_content[i] = content[i];
}
Expect.listEquals(
expected, new Uint16List.view(typed_data_content.buffer));
temp.deleteSync(recursive: true);
asyncEnd();
});
file
.open(mode: FileMode.write)
.then((raf) {
return raf.writeFrom(
new Uint8List.view(list.buffer),
0,
LIST_LENGTH_IN_BYTES,
);
})
.then((raf) {
return raf.writeFrom(
new Uint8List.view(
view.buffer,
view.offsetInBytes,
view.lengthInBytes,
),
0,
VIEW_LENGTH_IN_BYTES,
);
})
.then((raf) {
return raf.close();
})
.then((_) {
var expected = [];
expected.addAll(list);
expected.addAll(view);
var content = file.readAsBytesSync();
var typed_data_content = new Uint8List(content.length);
for (int i = 0; i < content.length; i++) {
typed_data_content[i] = content[i];
}
Expect.listEquals(
expected,
new Uint16List.view(typed_data_content.buffer),
);
temp.deleteSync(recursive: true);
asyncEnd();
});
});
}
@@ -194,36 +252,53 @@ void testWriteInt32ListAndView() {
const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int32List.bytesPerElement;
var list = new Int32List(LIST_LENGTH);
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
var view =
new Int32List.view(list.buffer, OFFSET_IN_BYTES_FOR_VIEW, VIEW_LENGTH);
var view = new Int32List.view(
list.buffer,
OFFSET_IN_BYTES_FOR_VIEW,
VIEW_LENGTH,
);
Directory.systemTemp.createTemp('dart_file_typed_data').then((temp) {
var file = new File("${temp.path}/test");
file.open(mode: FileMode.write).then((raf) {
return raf.writeFrom(
new Uint8List.view(list.buffer), 0, LIST_LENGTH_IN_BYTES);
}).then((raf) {
return raf.writeFrom(
new Uint8List.view(
view.buffer, view.offsetInBytes, view.lengthInBytes),
0,
VIEW_LENGTH_IN_BYTES);
}).then((raf) {
return raf.close();
}).then((_) {
var expected = [];
expected.addAll(list);
expected.addAll(view);
var content = file.readAsBytesSync();
var typed_data_content = new Uint8List(content.length);
for (int i = 0; i < content.length; i++) {
typed_data_content[i] = content[i];
}
Expect.listEquals(
expected, new Int32List.view(typed_data_content.buffer));
temp.deleteSync(recursive: true);
asyncEnd();
});
file
.open(mode: FileMode.write)
.then((raf) {
return raf.writeFrom(
new Uint8List.view(list.buffer),
0,
LIST_LENGTH_IN_BYTES,
);
})
.then((raf) {
return raf.writeFrom(
new Uint8List.view(
view.buffer,
view.offsetInBytes,
view.lengthInBytes,
),
0,
VIEW_LENGTH_IN_BYTES,
);
})
.then((raf) {
return raf.close();
})
.then((_) {
var expected = [];
expected.addAll(list);
expected.addAll(view);
var content = file.readAsBytesSync();
var typed_data_content = new Uint8List(content.length);
for (int i = 0; i < content.length; i++) {
typed_data_content[i] = content[i];
}
Expect.listEquals(
expected,
new Int32List.view(typed_data_content.buffer),
);
temp.deleteSync(recursive: true);
asyncEnd();
});
});
}
@@ -236,36 +311,53 @@ void testWriteUint32ListAndView() {
const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int32List.bytesPerElement;
var list = new Uint32List(LIST_LENGTH);
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
var view =
new Uint32List.view(list.buffer, OFFSET_IN_BYTES_FOR_VIEW, VIEW_LENGTH);
var view = new Uint32List.view(
list.buffer,
OFFSET_IN_BYTES_FOR_VIEW,
VIEW_LENGTH,
);
Directory.systemTemp.createTemp('dart_file_typed_data').then((temp) {
var file = new File("${temp.path}/test");
file.open(mode: FileMode.write).then((raf) {
return raf.writeFrom(
new Uint8List.view(list.buffer), 0, LIST_LENGTH_IN_BYTES);
}).then((raf) {
return raf.writeFrom(
new Uint8List.view(
view.buffer, view.offsetInBytes, view.lengthInBytes),
0,
VIEW_LENGTH_IN_BYTES);
}).then((raf) {
return raf.close();
}).then((_) {
var expected = [];
expected.addAll(list);
expected.addAll(view);
var content = file.readAsBytesSync();
var typed_data_content = new Uint8List(content.length);
for (int i = 0; i < content.length; i++) {
typed_data_content[i] = content[i];
}
Expect.listEquals(
expected, new Uint32List.view(typed_data_content.buffer));
temp.deleteSync(recursive: true);
asyncEnd();
});
file
.open(mode: FileMode.write)
.then((raf) {
return raf.writeFrom(
new Uint8List.view(list.buffer),
0,
LIST_LENGTH_IN_BYTES,
);
})
.then((raf) {
return raf.writeFrom(
new Uint8List.view(
view.buffer,
view.offsetInBytes,
view.lengthInBytes,
),
0,
VIEW_LENGTH_IN_BYTES,
);
})
.then((raf) {
return raf.close();
})
.then((_) {
var expected = [];
expected.addAll(list);
expected.addAll(view);
var content = file.readAsBytesSync();
var typed_data_content = new Uint8List(content.length);
for (int i = 0; i < content.length; i++) {
typed_data_content[i] = content[i];
}
Expect.listEquals(
expected,
new Uint32List.view(typed_data_content.buffer),
);
temp.deleteSync(recursive: true);
asyncEnd();
});
});
}
@@ -278,36 +370,53 @@ void testWriteInt64ListAndView() {
const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int64List.bytesPerElement;
var list = new Int64List(LIST_LENGTH);
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
var view =
new Int64List.view(list.buffer, OFFSET_IN_BYTES_FOR_VIEW, VIEW_LENGTH);
var view = new Int64List.view(
list.buffer,
OFFSET_IN_BYTES_FOR_VIEW,
VIEW_LENGTH,
);
Directory.systemTemp.createTemp('dart_file_typed_data').then((temp) {
var file = new File("${temp.path}/test");
file.open(mode: FileMode.write).then((raf) {
return raf.writeFrom(
new Uint8List.view(list.buffer), 0, LIST_LENGTH_IN_BYTES);
}).then((raf) {
return raf.writeFrom(
new Uint8List.view(
view.buffer, view.offsetInBytes, view.lengthInBytes),
0,
VIEW_LENGTH_IN_BYTES);
}).then((raf) {
return raf.close();
}).then((_) {
var expected = [];
expected.addAll(list);
expected.addAll(view);
var content = file.readAsBytesSync();
var typed_data_content = new Uint8List(content.length);
for (int i = 0; i < content.length; i++) {
typed_data_content[i] = content[i];
}
Expect.listEquals(
expected, new Int64List.view(typed_data_content.buffer));
temp.deleteSync(recursive: true);
asyncEnd();
});
file
.open(mode: FileMode.write)
.then((raf) {
return raf.writeFrom(
new Uint8List.view(list.buffer),
0,
LIST_LENGTH_IN_BYTES,
);
})
.then((raf) {
return raf.writeFrom(
new Uint8List.view(
view.buffer,
view.offsetInBytes,
view.lengthInBytes,
),
0,
VIEW_LENGTH_IN_BYTES,
);
})
.then((raf) {
return raf.close();
})
.then((_) {
var expected = [];
expected.addAll(list);
expected.addAll(view);
var content = file.readAsBytesSync();
var typed_data_content = new Uint8List(content.length);
for (int i = 0; i < content.length; i++) {
typed_data_content[i] = content[i];
}
Expect.listEquals(
expected,
new Int64List.view(typed_data_content.buffer),
);
temp.deleteSync(recursive: true);
asyncEnd();
});
});
}
@@ -320,36 +429,53 @@ void testWriteUint64ListAndView() {
const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Uint64List.bytesPerElement;
var list = new Uint64List(LIST_LENGTH);
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
var view =
new Uint64List.view(list.buffer, OFFSET_IN_BYTES_FOR_VIEW, VIEW_LENGTH);
var view = new Uint64List.view(
list.buffer,
OFFSET_IN_BYTES_FOR_VIEW,
VIEW_LENGTH,
);
Directory.systemTemp.createTemp('dart_file_typed_data').then((temp) {
var file = new File("${temp.path}/test");
file.open(mode: FileMode.write).then((raf) {
return raf.writeFrom(
new Uint8List.view(list.buffer), 0, LIST_LENGTH_IN_BYTES);
}).then((raf) {
return raf.writeFrom(
new Uint8List.view(
view.buffer, view.offsetInBytes, view.lengthInBytes),
0,
VIEW_LENGTH_IN_BYTES);
}).then((raf) {
return raf.close();
}).then((_) {
var expected = [];
expected.addAll(list);
expected.addAll(view);
var content = file.readAsBytesSync();
var typed_data_content = new Uint8List(content.length);
for (int i = 0; i < content.length; i++) {
typed_data_content[i] = content[i];
}
Expect.listEquals(
expected, new Uint64List.view(typed_data_content.buffer));
temp.deleteSync(recursive: true);
asyncEnd();
});
file
.open(mode: FileMode.write)
.then((raf) {
return raf.writeFrom(
new Uint8List.view(list.buffer),
0,
LIST_LENGTH_IN_BYTES,
);
})
.then((raf) {
return raf.writeFrom(
new Uint8List.view(
view.buffer,
view.offsetInBytes,
view.lengthInBytes,
),
0,
VIEW_LENGTH_IN_BYTES,
);
})
.then((raf) {
return raf.close();
})
.then((_) {
var expected = [];
expected.addAll(list);
expected.addAll(view);
var content = file.readAsBytesSync();
var typed_data_content = new Uint8List(content.length);
for (int i = 0; i < content.length; i++) {
typed_data_content[i] = content[i];
}
Expect.listEquals(
expected,
new Uint64List.view(typed_data_content.buffer),
);
temp.deleteSync(recursive: true);
asyncEnd();
});
});
}
+6 -3
View File
@@ -31,11 +31,14 @@ void testFromUri() {
void testFromUriUnsupported() {
Expect.throwsUnsupportedError(
() => new File.fromUri(Uri.parse('http://localhost:8080/index.html')));
() => new File.fromUri(Uri.parse('http://localhost:8080/index.html')),
);
Expect.throwsUnsupportedError(
() => new File.fromUri(Uri.parse('ftp://localhost/tmp/xxx')));
() => new File.fromUri(Uri.parse('ftp://localhost/tmp/xxx')),
);
Expect.throwsUnsupportedError(
() => new File.fromUri(Uri.parse('name#fragment')));
() => new File.fromUri(Uri.parse('name#fragment')),
);
}
void main() {
+4 -2
View File
@@ -40,8 +40,10 @@ void testDriveLetterNoBackslash() {
}
}
noBackslash += path.substring(3);
Expect.equals("${Directory(noBackslash).statSync()}",
"${Directory(path).statSync()}");
Expect.equals(
"${Directory(noBackslash).statSync()}",
"${Directory(path).statSync()}",
);
}
}
}
+3 -2
View File
@@ -21,8 +21,9 @@ testWriteAsBytesSync(dir) {
}
void testWriteAsBytesOutsideOf0to256Sync(dir) {
final f =
new File('${dir.path}${Platform.pathSeparator}outside_bytes_sync.txt');
final f = new File(
'${dir.path}${Platform.pathSeparator}outside_bytes_sync.txt',
);
final data = [-256, -255, -1, 0, 255, 256];
f.writeAsBytesSync(data);
@@ -40,12 +40,16 @@ Future write(Directory dir) async {
await raf.writeString('Hello');
await raf.setPosition(0);
await expectThrowsAsync(
raf.readByte(), 'Read from write only file succeeded');
raf.readByte(),
'Read from write only file succeeded',
);
await raf.close();
raf = await f.open(mode: FileMode.writeOnlyAppend);
await raf.writeString('Hello');
await expectThrowsAsync(
raf.readByte(), 'Read from write only file succeeded');
raf.readByte(),
'Read from write only file succeeded',
);
await raf.setPosition(0);
await raf.writeString('Hello');
await raf.close();
+5 -4
View File
@@ -16,7 +16,7 @@ const typeMapping = const {
'FileMode': FileMode.read,
'num': 0.50,
'List<int>': const [1, 2, 3],
'Map<String, int>': const {"a": 23}
'Map<String, int>': const {"a": 23},
};
typePermutations(int argCount) {
@@ -52,7 +52,8 @@ doItSync(Function f) {
// completion.
Future doItAsync(FutureOr f()) {
// Ignore value and errors.
return new Future.delayed(Duration.zero, f)
.catchError((_) {})
.then((_) => true);
return new Future.delayed(
Duration.zero,
f,
).catchError((_) {}).then((_) => true);
}
@@ -33,12 +33,15 @@ void test(responseBytes, bodyLength) async {
server.listen(handleSocket);
var client = new HttpClient();
var request =
await client.getUrl(Uri.parse('http://127.0.0.1:${server.port}/'));
var request = await client.getUrl(
Uri.parse('http://127.0.0.1:${server.port}/'),
);
var response = await request.close();
Expect.equals(response.statusCode, 200);
Expect.equals(bodyLength,
(await response.fold<List<int>>(<int>[], (p, e) => p..addAll(e))).length);
Expect.equals(
bodyLength,
(await response.fold<List<int>>(<int>[], (p, e) => p..addAll(e))).length,
);
server.close();
}
+142 -116
View File
@@ -17,26 +17,29 @@ import "package:expect/expect.dart";
// connection as there is no keep alive.
void testHttp10NoKeepAlive() {
HttpServer.bind("127.0.0.1", 0).then((server) {
server.listen((HttpRequest request) {
Expect.isNull(request.headers.value('content-length'));
Expect.equals(-1, request.contentLength);
var response = request.response;
response.contentLength = 1;
Expect.equals("1.0", request.protocolVersion);
response.done
.then((_) => Expect.fail("Unexpected response completion"))
.catchError((error) => Expect.isTrue(error is HttpException));
response.write("Z");
response.write("Z");
response.close();
Expect.throws(() {
response.write("x");
}, (e) => e is StateError);
}, onError: (e, trace) {
String msg = "Unexpected error $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
});
server.listen(
(HttpRequest request) {
Expect.isNull(request.headers.value('content-length'));
Expect.equals(-1, request.contentLength);
var response = request.response;
response.contentLength = 1;
Expect.equals("1.0", request.protocolVersion);
response.done
.then((_) => Expect.fail("Unexpected response completion"))
.catchError((error) => Expect.isTrue(error is HttpException));
response.write("Z");
response.write("Z");
response.close();
Expect.throws(() {
response.write("x");
}, (e) => e is StateError);
},
onError: (e, trace) {
String msg = "Unexpected error $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
},
);
int count = 0;
makeRequest() {
@@ -44,17 +47,20 @@ void testHttp10NoKeepAlive() {
socket.write("GET / HTTP/1.0\r\n\r\n");
List<int> response = [];
socket.listen(response.addAll, onDone: () {
count++;
socket.destroy();
String s = new String.fromCharCodes(response).toLowerCase();
Expect.equals(-1, s.indexOf("keep-alive"));
if (count < 10) {
makeRequest();
} else {
server.close();
}
});
socket.listen(
response.addAll,
onDone: () {
count++;
socket.destroy();
String s = new String.fromCharCodes(response).toLowerCase();
Expect.equals(-1, s.indexOf("keep-alive"));
if (count < 10) {
makeRequest();
} else {
server.close();
}
},
);
});
}
@@ -67,20 +73,26 @@ void testHttp10NoKeepAlive() {
// the response.
void testHttp10ServerClose() {
HttpServer.bind("127.0.0.1", 0).then((server) {
server.listen((HttpRequest request) {
Expect.isNull(request.headers.value('content-length'));
Expect.equals(-1, request.contentLength);
request.listen((_) {}, onDone: () {
var response = request.response;
Expect.equals("1.0", request.protocolVersion);
response.write("Z");
response.close();
});
}, onError: (e, trace) {
String msg = "Unexpected error $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
});
server.listen(
(HttpRequest request) {
Expect.isNull(request.headers.value('content-length'));
Expect.equals(-1, request.contentLength);
request.listen(
(_) {},
onDone: () {
var response = request.response;
Expect.equals("1.0", request.protocolVersion);
response.write("Z");
response.close();
},
);
},
onError: (e, trace) {
String msg = "Unexpected error $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
},
);
int count = 0;
makeRequest() {
@@ -89,21 +101,23 @@ void testHttp10ServerClose() {
socket.write("Connection: Keep-Alive\r\n\r\n");
List<int> response = [];
socket.listen(response.addAll,
onDone: () {
socket.destroy();
count++;
String s = new String.fromCharCodes(response).toLowerCase();
Expect.equals("z", s[s.length - 1]);
Expect.equals(-1, s.indexOf("content-length:"));
Expect.equals(-1, s.indexOf("keep-alive"));
if (count < 10) {
makeRequest();
} else {
server.close();
}
},
onError: (e) => print(e));
socket.listen(
response.addAll,
onDone: () {
socket.destroy();
count++;
String s = new String.fromCharCodes(response).toLowerCase();
Expect.equals("z", s[s.length - 1]);
Expect.equals(-1, s.indexOf("content-length:"));
Expect.equals(-1, s.indexOf("keep-alive"));
if (count < 10) {
makeRequest();
} else {
server.close();
}
},
onError: (e) => print(e),
);
});
}
@@ -116,20 +130,23 @@ void testHttp10ServerClose() {
// used.
void testHttp10KeepAlive() {
HttpServer.bind("127.0.0.1", 0).then((server) {
server.listen((HttpRequest request) {
Expect.isNull(request.headers.value('content-length'));
Expect.equals(-1, request.contentLength);
var response = request.response;
response.contentLength = 1;
response.persistentConnection = true;
Expect.equals("1.0", request.protocolVersion);
response.write("Z");
response.close();
}, onError: (e, trace) {
String msg = "Unexpected error $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
});
server.listen(
(HttpRequest request) {
Expect.isNull(request.headers.value('content-length'));
Expect.equals(-1, request.contentLength);
var response = request.response;
response.contentLength = 1;
response.persistentConnection = true;
Expect.equals("1.0", request.protocolVersion);
response.write("Z");
response.close();
},
onError: (e, trace) {
String msg = "Unexpected error $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
},
);
Socket.connect("127.0.0.1", server.port).then((socket) {
void sendRequest() {
@@ -139,24 +156,27 @@ void testHttp10KeepAlive() {
List<int> response = [];
int count = 0;
socket.listen((d) {
response.addAll(d);
if (response[response.length - 1] == "Z".codeUnitAt(0)) {
String s = new String.fromCharCodes(response).toLowerCase();
Expect.isTrue(s.indexOf("\r\nconnection: keep-alive\r\n") > 0);
Expect.isTrue(s.indexOf("\r\ncontent-length: 1\r\n") > 0);
count++;
if (count < 10) {
response = [];
sendRequest();
} else {
socket.close();
socket.listen(
(d) {
response.addAll(d);
if (response[response.length - 1] == "Z".codeUnitAt(0)) {
String s = new String.fromCharCodes(response).toLowerCase();
Expect.isTrue(s.indexOf("\r\nconnection: keep-alive\r\n") > 0);
Expect.isTrue(s.indexOf("\r\ncontent-length: 1\r\n") > 0);
count++;
if (count < 10) {
response = [];
sendRequest();
} else {
socket.close();
}
}
}
}, onDone: () {
socket.destroy();
server.close();
});
},
onDone: () {
socket.destroy();
server.close();
},
);
sendRequest();
});
});
@@ -167,18 +187,21 @@ void testHttp10KeepAlive() {
// keep alive.
void testHttp10KeepAliveServerCloses() {
HttpServer.bind("127.0.0.1", 0).then((server) {
server.listen((HttpRequest request) {
Expect.isNull(request.headers.value('content-length'));
Expect.equals(-1, request.contentLength);
var response = request.response;
Expect.equals("1.0", request.protocolVersion);
response.write("Z");
response.close();
}, onError: (e, trace) {
String msg = "Unexpected error $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
});
server.listen(
(HttpRequest request) {
Expect.isNull(request.headers.value('content-length'));
Expect.equals(-1, request.contentLength);
var response = request.response;
Expect.equals("1.0", request.protocolVersion);
response.write("Z");
response.close();
},
onError: (e, trace) {
String msg = "Unexpected error $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
},
);
int count = 0;
makeRequest() {
@@ -187,19 +210,22 @@ void testHttp10KeepAliveServerCloses() {
socket.write("Connection: Keep-Alive\r\n\r\n");
List<int> response = [];
socket.listen(response.addAll, onDone: () {
socket.destroy();
count++;
String s = new String.fromCharCodes(response).toLowerCase();
Expect.equals("z", s[s.length - 1]);
Expect.equals(-1, s.indexOf("content-length"));
Expect.equals(-1, s.indexOf("connection"));
if (count < 10) {
makeRequest();
} else {
server.close();
}
});
socket.listen(
response.addAll,
onDone: () {
socket.destroy();
count++;
String s = new String.fromCharCodes(response).toLowerCase();
Expect.equals("z", s[s.length - 1]);
Expect.equals(-1, s.indexOf("content-length"));
Expect.equals(-1, s.indexOf("connection"));
if (count < 10) {
makeRequest();
} else {
server.close();
}
},
);
});
}
+148 -97
View File
@@ -40,8 +40,10 @@ class IsolatedHttpServer {
void shutdown() {
// Send server stop message to the server.
_serverPort
.send([new IsolatedHttpServerCommand.stop(), _statusPort.sendPort]);
_serverPort.send([
new IsolatedHttpServerCommand.stop(),
_statusPort.sendPort,
]);
_statusPort.close();
}
@@ -49,7 +51,7 @@ class IsolatedHttpServer {
// Send chunked encoding message to the server.
_serverPort.send([
new IsolatedHttpServerCommand.chunkedEncoding(),
_statusPort.sendPort
_statusPort.sendPort,
]);
}
@@ -158,8 +160,10 @@ class TestServer {
Expect.equals("html", request.headers.contentType!.subType);
Expect.equals("utf-8", request.headers.contentType!.parameters["charset"]);
response.headers
.set(HttpHeaders.contentTypeHeader, "text/html; charset = utf-8");
response.headers.set(
HttpHeaders.contentTypeHeader,
"text/html; charset = utf-8",
);
response.close();
}
@@ -247,36 +251,42 @@ Future testHost() {
IsolatedHttpServer server = new IsolatedHttpServer();
server.setServerStartedHandler((int port) {
HttpClient httpClient = new HttpClient();
httpClient.get("127.0.0.1", port, "/host").then((request) {
Expect.equals("127.0.0.1:$port", request.headers["host"]![0]);
request.headers.host = "www.dartlang.com";
Expect.equals("www.dartlang.com:$port", request.headers["host"]![0]);
Expect.equals("www.dartlang.com", request.headers.host);
Expect.equals(port, request.headers.port);
request.headers.port = 1234;
Expect.equals("www.dartlang.com:1234", request.headers["host"]![0]);
Expect.equals(1234, request.headers.port);
request.headers.port = HttpClient.defaultHttpPort;
Expect.equals(HttpClient.defaultHttpPort, request.headers.port);
Expect.equals("www.dartlang.com", request.headers["host"]![0]);
request.headers.set("Host", "www.dartlang.org");
Expect.equals("www.dartlang.org", request.headers.host);
Expect.equals(HttpClient.defaultHttpPort, request.headers.port);
request.headers.set("Host", "www.dartlang.org:");
Expect.equals("www.dartlang.org", request.headers.host);
Expect.equals(HttpClient.defaultHttpPort, request.headers.port);
request.headers.set("Host", "www.dartlang.org:1234");
Expect.equals("www.dartlang.org", request.headers.host);
Expect.equals(1234, request.headers.port);
return request.close();
}).then((response) {
Expect.equals(HttpStatus.ok, response.statusCode);
response.listen((_) {}, onDone: () {
httpClient.close();
server.shutdown();
completer.complete(true);
});
});
httpClient
.get("127.0.0.1", port, "/host")
.then((request) {
Expect.equals("127.0.0.1:$port", request.headers["host"]![0]);
request.headers.host = "www.dartlang.com";
Expect.equals("www.dartlang.com:$port", request.headers["host"]![0]);
Expect.equals("www.dartlang.com", request.headers.host);
Expect.equals(port, request.headers.port);
request.headers.port = 1234;
Expect.equals("www.dartlang.com:1234", request.headers["host"]![0]);
Expect.equals(1234, request.headers.port);
request.headers.port = HttpClient.defaultHttpPort;
Expect.equals(HttpClient.defaultHttpPort, request.headers.port);
Expect.equals("www.dartlang.com", request.headers["host"]![0]);
request.headers.set("Host", "www.dartlang.org");
Expect.equals("www.dartlang.org", request.headers.host);
Expect.equals(HttpClient.defaultHttpPort, request.headers.port);
request.headers.set("Host", "www.dartlang.org:");
Expect.equals("www.dartlang.org", request.headers.host);
Expect.equals(HttpClient.defaultHttpPort, request.headers.port);
request.headers.set("Host", "www.dartlang.org:1234");
Expect.equals("www.dartlang.org", request.headers.host);
Expect.equals(1234, request.headers.port);
return request.close();
})
.then((response) {
Expect.equals(HttpStatus.ok, response.statusCode);
response.listen(
(_) {},
onDone: () {
httpClient.close();
server.shutdown();
completer.complete(true);
},
);
});
});
server.start();
return completer.future;
@@ -292,17 +302,24 @@ Future testExpires() {
void processResponse(HttpClientResponse response) {
Expect.equals(HttpStatus.ok, response.statusCode);
Expect.equals(
"Fri, 11 Jun 1999 18:46:53 GMT", response.headers["expires"]![0]);
Expect.equals(new DateTime.utc(1999, DateTime.june, 11, 18, 46, 53, 0),
response.headers.expires);
response.listen((_) {}, onDone: () {
responses++;
if (responses == 2) {
httpClient.close();
server.shutdown();
completer.complete(true);
}
});
"Fri, 11 Jun 1999 18:46:53 GMT",
response.headers["expires"]![0],
);
Expect.equals(
new DateTime.utc(1999, DateTime.june, 11, 18, 46, 53, 0),
response.headers.expires,
);
response.listen(
(_) {},
onDone: () {
responses++;
if (responses == 2) {
httpClient.close();
server.shutdown();
completer.complete(true);
}
},
);
}
httpClient
@@ -328,33 +345,51 @@ Future testContentType() {
void processResponse(HttpClientResponse response) {
Expect.equals(HttpStatus.ok, response.statusCode);
Expect.equals(
"text/html; charset=utf-8", response.headers.contentType.toString());
"text/html; charset=utf-8",
response.headers.contentType.toString(),
);
Expect.equals("text/html", response.headers.contentType!.value);
Expect.equals("text", response.headers.contentType!.primaryType);
Expect.equals("html", response.headers.contentType!.subType);
Expect.equals(
"utf-8", response.headers.contentType!.parameters["charset"]);
response.listen((_) {}, onDone: () {
responses++;
if (responses == 2) {
httpClient.close();
server.shutdown();
completer.complete(true);
}
});
"utf-8",
response.headers.contentType!.parameters["charset"],
);
response.listen(
(_) {},
onDone: () {
responses++;
if (responses == 2) {
httpClient.close();
server.shutdown();
completer.complete(true);
}
},
);
}
httpClient.get("127.0.0.1", port, "/contenttype1").then((request) {
request.headers.contentType =
new ContentType("text", "html", charset: "utf-8");
return request.close();
}).then(processResponse);
httpClient
.get("127.0.0.1", port, "/contenttype1")
.then((request) {
request.headers.contentType = new ContentType(
"text",
"html",
charset: "utf-8",
);
return request.close();
})
.then(processResponse);
httpClient.get("127.0.0.1", port, "/contenttype2").then((request) {
request.headers
.set(HttpHeaders.contentTypeHeader, "text/html; charset = utf-8");
return request.close();
}).then(processResponse);
httpClient
.get("127.0.0.1", port, "/contenttype2")
.then((request) {
request.headers.set(
HttpHeaders.contentTypeHeader,
"text/html; charset = utf-8",
);
return request.close();
})
.then(processResponse);
});
server.start();
return completer.future;
@@ -371,39 +406,55 @@ Future testCookies() {
.get("127.0.0.1", port, "/cookie1")
.then((request) => request.close())
.then((response) {
Expect.equals(2, response.cookies.length);
response.cookies.forEach((cookie) {
if (cookie.name == "name1") {
Expect.equals("value1", cookie.value);
DateTime date =
new DateTime.utc(2014, DateTime.january, 5, 23, 59, 59, 0);
Expect.equals(date, cookie.expires);
Expect.equals("www.example.com", cookie.domain);
Expect.isTrue(cookie.httpOnly);
} else if (cookie.name == "name2") {
Expect.equals("value2", cookie.value);
Expect.equals(100, cookie.maxAge);
Expect.equals(".example.com", cookie.domain);
Expect.equals("/shop", cookie.path);
} else {
Expect.fail("Unexpected cookie");
}
});
response.listen((_) {}, onDone: () {
httpClient.get("127.0.0.1", port, "/cookie2").then((request) {
request.cookies.add(response.cookies[0]);
request.cookies.add(response.cookies[1]);
return request.close();
}).then((response) {
response.listen((_) {}, onDone: () {
httpClient.close();
server.shutdown();
completer.complete(true);
Expect.equals(2, response.cookies.length);
response.cookies.forEach((cookie) {
if (cookie.name == "name1") {
Expect.equals("value1", cookie.value);
DateTime date = new DateTime.utc(
2014,
DateTime.january,
5,
23,
59,
59,
0,
);
Expect.equals(date, cookie.expires);
Expect.equals("www.example.com", cookie.domain);
Expect.isTrue(cookie.httpOnly);
} else if (cookie.name == "name2") {
Expect.equals("value2", cookie.value);
Expect.equals(100, cookie.maxAge);
Expect.equals(".example.com", cookie.domain);
Expect.equals("/shop", cookie.path);
} else {
Expect.fail("Unexpected cookie");
}
});
response.listen(
(_) {},
onDone: () {
httpClient
.get("127.0.0.1", port, "/cookie2")
.then((request) {
request.cookies.add(response.cookies[0]);
request.cookies.add(response.cookies[1]);
return request.close();
})
.then((response) {
response.listen(
(_) {},
onDone: () {
httpClient.close();
server.shutdown();
completer.complete(true);
},
);
});
},
);
});
});
});
});
server.start();
return completer.future;
@@ -375,8 +375,8 @@ void testMalformedAuthenticateHeaderWithAuthHandler() {
);
// Request should throw an exception if the authenticate handler is set
client.authenticate =
(Uri url, String scheme, String? realm) async => false;
client.authenticate = (Uri url, String scheme, String? realm) async =>
false;
await asyncExpectThrows<HttpException>(
client.getUrl(uri).then((request) => request.close()),
);
+82 -59
View File
@@ -26,8 +26,10 @@ class TestServerMain {
if (chunkedEncoding) {
// Send chunked encoding message to the server.
port.send(
[new TestServerCommand.chunkedEncoding(), _statusPort.sendPort]);
port.send([
new TestServerCommand.chunkedEncoding(),
_statusPort.sendPort,
]);
}
// Send server start message to the server.
@@ -110,10 +112,13 @@ class TestServer {
void _zeroToTenHandler(HttpRequest request) {
var response = request.response;
Expect.equals("GET", request.method);
request.listen((_) {}, onDone: () {
response.write("01234567890");
response.close();
});
request.listen(
(_) {},
onDone: () {
response.write("01234567890");
response.close();
},
);
}
// Return a 404.
@@ -208,15 +213,17 @@ void testGET() {
.get("127.0.0.1", port, "/0123456789")
.then((request) => request.close())
.then((response) {
Expect.equals(HttpStatus.ok, response.statusCode);
StringBuffer body = new StringBuffer();
response.listen((data) => body.write(new String.fromCharCodes(data)),
onDone: () {
Expect.equals("01234567890", body.toString());
httpClient.close();
testServerMain.close();
});
});
Expect.equals(HttpStatus.ok, response.statusCode);
StringBuffer body = new StringBuffer();
response.listen(
(data) => body.write(new String.fromCharCodes(data)),
onDone: () {
Expect.equals("01234567890", body.toString());
httpClient.close();
testServerMain.close();
},
);
});
});
testServerMain.start();
}
@@ -231,30 +238,35 @@ void testPOST(bool chunkedEncoding) {
int count = 0;
HttpClient httpClient = new HttpClient();
void sendRequest() {
httpClient.post("127.0.0.1", port, "/echo").then((request) {
if (chunkedEncoding) {
request.write(data.substring(0, 10));
request.write(data.substring(10, data.length));
} else {
request.contentLength = data.length;
request.write(data);
}
return request.close();
}).then((response) {
Expect.equals(HttpStatus.ok, response.statusCode);
StringBuffer body = new StringBuffer();
response.listen((data) => body.write(new String.fromCharCodes(data)),
onDone: () {
Expect.equals(data, body.toString());
count++;
if (count < kMessageCount) {
sendRequest();
} else {
httpClient.close();
testServerMain.close();
}
});
});
httpClient
.post("127.0.0.1", port, "/echo")
.then((request) {
if (chunkedEncoding) {
request.write(data.substring(0, 10));
request.write(data.substring(10, data.length));
} else {
request.contentLength = data.length;
request.write(data);
}
return request.close();
})
.then((response) {
Expect.equals(HttpStatus.ok, response.statusCode);
StringBuffer body = new StringBuffer();
response.listen(
(data) => body.write(new String.fromCharCodes(data)),
onDone: () {
Expect.equals(data, body.toString());
count++;
if (count < kMessageCount) {
sendRequest();
} else {
httpClient.close();
testServerMain.close();
}
},
);
});
}
sendRequest();
@@ -272,15 +284,17 @@ void test404() {
.get("127.0.0.1", port, "/thisisnotfound")
.then((request) => request.close())
.then((response) {
Expect.equals(HttpStatus.notFound, response.statusCode);
var body = new StringBuffer();
response.listen((data) => body.write(new String.fromCharCodes(data)),
onDone: () {
Expect.equals("Page not found", body.toString());
httpClient.close();
testServerMain.close();
});
});
Expect.equals(HttpStatus.notFound, response.statusCode);
var body = new StringBuffer();
response.listen(
(data) => body.write(new String.fromCharCodes(data)),
onDone: () {
Expect.equals("Page not found", body.toString());
httpClient.close();
testServerMain.close();
},
);
});
});
testServerMain.start();
}
@@ -289,17 +303,26 @@ void testReasonPhrase() {
TestServerMain testServerMain = new TestServerMain();
testServerMain.setServerStartedHandler((int port) {
HttpClient httpClient = new HttpClient();
httpClient.get("127.0.0.1", port, "/reasonformoving").then((request) {
request.followRedirects = false;
return request.close();
}).then((response) {
Expect.equals(HttpStatus.movedPermanently, response.statusCode);
Expect.equals("Don't come looking here any more", response.reasonPhrase);
response.listen((data) => Expect.fail("No data expected"), onDone: () {
httpClient.close();
testServerMain.close();
});
});
httpClient
.get("127.0.0.1", port, "/reasonformoving")
.then((request) {
request.followRedirects = false;
return request.close();
})
.then((response) {
Expect.equals(HttpStatus.movedPermanently, response.statusCode);
Expect.equals(
"Don't come looking here any more",
response.reasonPhrase,
);
response.listen(
(data) => Expect.fail("No data expected"),
onDone: () {
httpClient.close();
testServerMain.close();
},
);
});
});
testServerMain.start();
}
+117 -92
View File
@@ -25,8 +25,8 @@ void testGetEmptyRequest() {
.get("127.0.0.1", server.port, "/")
.then((request) => request.close())
.then((response) {
response.listen((data) {}, onDone: server.close);
});
response.listen((data) {}, onDone: server.close);
});
});
}
@@ -43,12 +43,15 @@ void testGetDataRequest() {
.get("127.0.0.1", server.port, "/")
.then((request) => request.close())
.then((response) {
int count = 0;
response.listen((data) => count += data.length, onDone: () {
server.close();
Expect.equals(data.length, count);
});
});
int count = 0;
response.listen(
(data) => count += data.length,
onDone: () {
server.close();
Expect.equals(data.length, count);
},
);
});
});
}
@@ -56,8 +59,8 @@ void testGetInvalidHost() {
asyncStart();
var client = new HttpClient();
Future<HttpClientRequest?>.value(
client.get("__SOMETHING_INVALID__", 8888, "/"))
.catchError((error) {
client.get("__SOMETHING_INVALID__", 8888, "/"),
).catchError((error) {
client.close();
asyncEnd();
});
@@ -112,9 +115,12 @@ void testGetServerForceClose() {
.get("127.0.0.1", server.port, "/")
.then((request) => request.close())
.then((response) {
Expect.fail("Request not expected");
}).catchError((error) => asyncEnd(),
test: (error) => error is HttpException);
Expect.fail("Request not expected");
})
.catchError(
(error) => asyncEnd(),
test: (error) => error is HttpException,
);
});
}
@@ -135,17 +141,19 @@ void testGetDataServerForceClose() {
.get("127.0.0.1", server.port, "/")
.then((request) => request.close())
.then((response) {
// Close the (incomplete) response, now that we have seen
// the response object.
completer.complete(null);
int errors = 0;
response.listen((data) {},
onError: (error) => errors++,
onDone: () {
Expect.equals(1, errors);
asyncEnd();
});
});
// Close the (incomplete) response, now that we have seen
// the response object.
completer.complete(null);
int errors = 0;
response.listen(
(data) {},
onError: (error) => errors++,
onDone: () {
Expect.equals(1, errors);
asyncEnd();
},
);
});
});
}
@@ -158,7 +166,7 @@ void testOpenEmptyRequest() {
[client.put, 'PUT'],
[client.delete, 'DELETE'],
[client.patch, 'PATCH'],
[client.head, 'HEAD']
[client.head, 'HEAD'],
];
for (var method in methods) {
@@ -169,11 +177,11 @@ void testOpenEmptyRequest() {
});
Callback1 cb = method[0] as Callback1;
cb("127.0.0.1", server.port, "/")
.then((request) => request.close())
.then((response) {
response.listen((data) {}, onDone: server.close);
});
cb("127.0.0.1", server.port, "/").then((request) => request.close()).then(
(response) {
response.listen((data) {}, onDone: server.close);
},
);
});
}
}
@@ -187,7 +195,7 @@ void testOpenUrlEmptyRequest() {
[client.putUrl, 'PUT'],
[client.deleteUrl, 'DELETE'],
[client.patchUrl, 'PATCH'],
[client.headUrl, 'HEAD']
[client.headUrl, 'HEAD'],
];
for (var method in methods) {
@@ -198,9 +206,9 @@ void testOpenUrlEmptyRequest() {
});
Callback2 cb = method[0] as Callback2;
cb(Uri.parse("http://127.0.0.1:${server.port}/"))
.then((request) => request.close())
.then((response) {
cb(
Uri.parse("http://127.0.0.1:${server.port}/"),
).then((request) => request.close()).then((response) {
response.listen((data) {}, onDone: server.close);
});
});
@@ -222,36 +230,38 @@ void testNoBuffer() {
.get("127.0.0.1", server.port, "/")
.then((request) => request.close())
.then((clientResponse) {
var iterator = new StreamIterator(clientResponse
.cast<List<int>>()
.transform(utf8.decoder)
.transform(new LineSplitter()));
iterator.moveNext().then((hasValue) {
Expect.isTrue(hasValue);
Expect.equals('init', iterator.current);
int count = 0;
void run() {
if (count == 10) {
response.close();
iterator.moveNext().then((hasValue) {
Expect.isFalse(hasValue);
server.close();
asyncEnd();
});
} else {
response.writeln('output$count');
iterator.moveNext().then((hasValue) {
Expect.isTrue(hasValue);
Expect.equals('output$count', iterator.current);
count++;
run();
});
}
}
var iterator = new StreamIterator(
clientResponse
.cast<List<int>>()
.transform(utf8.decoder)
.transform(new LineSplitter()),
);
iterator.moveNext().then((hasValue) {
Expect.isTrue(hasValue);
Expect.equals('init', iterator.current);
int count = 0;
void run() {
if (count == 10) {
response.close();
iterator.moveNext().then((hasValue) {
Expect.isFalse(hasValue);
server.close();
asyncEnd();
});
} else {
response.writeln('output$count');
iterator.moveNext().then((hasValue) {
Expect.isTrue(hasValue);
Expect.equals('output$count', iterator.current);
count++;
run();
});
}
}
run();
});
});
run();
});
});
});
}
@@ -261,9 +271,10 @@ void testMaxConnectionsPerHost(int connectionCap, int connections) {
int handled = 0;
server.listen((request) {
Expect.isTrue(
server.connectionsInfo().total <= connectionCap,
'${server.connectionsInfo().total} <= $connectionCap ' +
'(connections: $connections)');
server.connectionsInfo().total <= connectionCap,
'${server.connectionsInfo().total} <= $connectionCap ' +
'(connections: $connections)',
);
request.response.close();
handled++;
if (handled == connections) {
@@ -280,10 +291,13 @@ void testMaxConnectionsPerHost(int connectionCap, int connections) {
.get("127.0.0.1", server.port, "/")
.then((request) => request.close())
.then((response) {
response.listen(null, onDone: () {
asyncEnd();
});
});
response.listen(
null,
onDone: () {
asyncEnd();
},
);
});
}
});
}
@@ -303,8 +317,10 @@ Future<void> testMaxConnectionsWithFailure() async {
}
try {
await client.getUrl(Uri.parse('http://domain.invalid'));
Expect.fail("Calls exceed client's maxConnectionsPerHost should throw "
"exceptions as well");
Expect.fail(
"Calls exceed client's maxConnectionsPerHost should throw "
"exceptions as well",
);
} catch (e) {
if (e is! SocketException) {
Expect.fail("Unexpected exception $e is thrown");
@@ -334,13 +350,16 @@ Future<void> testHttpAbort() async {
asyncEnd();
});
});
request.close().then((response) {
Expect.fail('abort() prevents a response being returned');
}, onError: (e) {
Expect.type<HttpException>(e);
Expect.isTrue(e.toString().contains('abort'));
asyncEnd();
});
request.close().then(
(response) {
Expect.fail('abort() prevents a response being returned');
},
onError: (e) {
Expect.type<HttpException>(e);
Expect.isTrue(e.toString().contains('abort'));
asyncEnd();
},
);
}
Future<void> testHttpAbortBeforeWrite() async {
@@ -368,12 +387,15 @@ Future<void> testHttpAbortBeforeWrite() async {
server.close();
asyncEnd();
});
request.close().then((response) {
Expect.fail('abort() prevents a response being returned');
}, onError: (e) {
Expect.type<HttpException>(e);
asyncEnd();
});
request.close().then(
(response) {
Expect.fail('abort() prevents a response being returned');
},
onError: (e) {
Expect.type<HttpException>(e);
asyncEnd();
},
);
}
Future<void> testHttpAbortBeforeClose() async {
@@ -401,13 +423,16 @@ Future<void> testHttpAbortBeforeClose() async {
await completer.future;
final string = 'abort message';
request.abort(string);
request.close().then((response) {
Expect.fail('abort() prevents a response being returned');
}, onError: (e) {
Expect.type<String>(e);
Expect.equals(string, e);
asyncEnd();
});
request.close().then(
(response) {
Expect.fail('abort() prevents a response being returned');
},
onError: (e) {
Expect.type<String>(e);
Expect.equals(string, e);
asyncEnd();
},
);
}
Future<void> testHttpAbortAfterClose() async {
@@ -10,31 +10,48 @@ import "package:expect/expect.dart";
void testInvalidUrl() {
HttpClient client = new HttpClient();
Expect.throws(() => client.getUrl(Uri.parse('ftp://www.google.com')),
(e) => e.toString().contains("Unsupported scheme"));
Expect.throws(() => client.getUrl(Uri.parse('httpx://www.google.com')),
(e) => e.toString().contains("Unsupported scheme"));
Expect.throws(
() => client.getUrl(Uri.parse('ftp://www.google.com')),
(e) => e.toString().contains("Unsupported scheme"),
);
Expect.throws(
() => client.getUrl(Uri.parse('httpx://www.google.com')),
(e) => e.toString().contains("Unsupported scheme"),
);
Expect.throwsFormatException(() => client.getUrl(Uri.parse('http://::1')));
Expect.throws(() => client.getUrl(Uri.parse('http://user@:1')),
(e) => e.toString().contains("No host specified"));
Expect.throws(() => client.getUrl(Uri.parse('http:///')),
(e) => e.toString().contains("No host specified"));
Expect.throws(() => client.getUrl(Uri.parse('http:///index.html')),
(e) => e.toString().contains("No host specified"));
Expect.throws(() => client.getUrl(Uri.parse('///')),
(e) => e.toString().contains("No host specified"));
Expect.throws(() => client.getUrl(Uri.parse('///index.html')),
(e) => e.toString().contains("No host specified"));
Expect.throws(
() => client.getUrl(Uri.parse('http://user@:1')),
(e) => e.toString().contains("No host specified"),
);
Expect.throws(
() => client.getUrl(Uri.parse('http:///')),
(e) => e.toString().contains("No host specified"),
);
Expect.throws(
() => client.getUrl(Uri.parse('http:///index.html')),
(e) => e.toString().contains("No host specified"),
);
Expect.throws(
() => client.getUrl(Uri.parse('///')),
(e) => e.toString().contains("No host specified"),
);
Expect.throws(
() => client.getUrl(Uri.parse('///index.html')),
(e) => e.toString().contains("No host specified"),
);
}
void testBadHostName() {
asyncStart();
HttpClient client = new HttpClient();
client.get("some.bad.host.name.7654321", 0, "/").then((request) {
Expect.fail("Should not open a request on bad hostname");
}).catchError((error) {
asyncEnd(); // We expect onError to be called, due to bad host name.
}, test: (error) => error is! String);
client
.get("some.bad.host.name.7654321", 0, "/")
.then((request) {
Expect.fail("Should not open a request on bad hostname");
})
.catchError((error) {
asyncEnd(); // We expect onError to be called, due to bad host name.
}, test: (error) => error is! String);
}
void main() {
@@ -24,24 +24,32 @@ Future testHttpClient(header) {
});
});
await runZonedGuarded(() {
var client = new HttpClient();
client.userAgent = null;
client
.get("127.0.0.1", server.port, "/")
.then((request) => request.close())
.then((response) {
response.transform(utf8.decoder).listen((contents) {
completer.complete();
}, onDone: () {
client.close(force: true);
server.close();
});
});
}, (e, st) {
server.close();
completer.completeError(e, st);
});
await runZonedGuarded(
() {
var client = new HttpClient();
client.userAgent = null;
client
.get("127.0.0.1", server.port, "/")
.then((request) => request.close())
.then((response) {
response
.transform(utf8.decoder)
.listen(
(contents) {
completer.complete();
},
onDone: () {
client.close(force: true);
server.close();
},
);
});
},
(e, st) {
server.close();
completer.completeError(e, st);
},
);
});
return completer.future;
}
@@ -19,8 +19,9 @@ Future<void> main() async {
for (var i = 0; i < max; i++) {
new Future(() async {
try {
final request = await client
.getUrl(Uri.parse("http://localhost:${servers[i].port}/"));
final request = await client.getUrl(
Uri.parse("http://localhost:${servers[i].port}/"),
);
got++;
if (got == max) {
// Test that no stack overflow happens.
+47 -31
View File
@@ -23,7 +23,9 @@ testClientAndServerCloseNoListen(int connections) {
if (closed == connections) {
Expect.equals(0, server.connectionsInfo().active);
Expect.equals(
server.connectionsInfo().total, server.connectionsInfo().idle);
server.connectionsInfo().total,
server.connectionsInfo().idle,
);
server.close();
}
});
@@ -46,16 +48,21 @@ testClientCloseServerListen(int connections) {
if (closed == connections * 2) {
Expect.equals(0, server.connectionsInfo().active);
Expect.equals(
server.connectionsInfo().total, server.connectionsInfo().idle);
server.connectionsInfo().total,
server.connectionsInfo().idle,
);
server.close();
}
}
server.listen((request) {
request.listen((_) {}, onDone: () {
request.response.close();
request.response.done.then((_) => check());
});
request.listen(
(_) {},
onDone: () {
request.response.close();
request.response.done.then((_) => check());
},
);
});
var client = HttpClient();
for (int i = 0; i < connections; i++) {
@@ -81,7 +88,9 @@ testClientCloseSendingResponse(int connections) {
if (closed == connections * 2) {
Expect.equals(0, server.connectionsInfo().active);
Expect.equals(
server.connectionsInfo().total, server.connectionsInfo().idle);
server.connectionsInfo().total,
server.connectionsInfo().idle,
);
server.close();
}
}
@@ -101,14 +110,14 @@ testClientCloseSendingResponse(int connections) {
.get("127.0.0.1", server.port, "/")
.then((request) => request.close())
.then((response) {
// Ensure we don't accept the response until we have send the entire
// request.
var subscription = response.listen((_) {});
Timer(const Duration(milliseconds: 20), () {
subscription.cancel();
check();
});
});
// Ensure we don't accept the response until we have send the entire
// request.
var subscription = response.listen((_) {});
Timer(const Duration(milliseconds: 20), () {
subscription.cancel();
check();
});
});
}
});
}
@@ -119,25 +128,32 @@ testClientCloseWhileSendingRequest(int connections) {
HttpServer.bind("127.0.0.1", 0).then((server) {
int serverErrors = 0;
int clientErrors = 0;
server.listen((request) {
request.listen((_) {}, onError: (_) {
serverErrors++;
if (serverErrors == connections) {
server.close();
}
});
}, onDone: () {
Expect.equals(connections, clientErrors);
Expect.equals(connections, serverErrors);
});
server.listen(
(request) {
request.listen(
(_) {},
onError: (_) {
serverErrors++;
if (serverErrors == connections) {
server.close();
}
},
);
},
onDone: () {
Expect.equals(connections, clientErrors);
Expect.equals(connections, serverErrors);
},
);
var client = HttpClient();
for (int i = 0; i < connections; i++) {
Future<HttpClientResponse?>.value(
client.post("127.0.0.1", server.port, "/").then((request) {
request.contentLength = 110;
request.write("0123456789");
return request.close();
})).catchError((_) {
client.post("127.0.0.1", server.port, "/").then((request) {
request.contentLength = 110;
request.write("0123456789");
return request.close();
}),
).catchError((_) {
clientErrors++;
});
}
+17 -7
View File
@@ -25,9 +25,13 @@ Future<void> testServerCompress({bool clientAutoUncompress = true}) async {
request.headers.set(HttpHeaders.acceptEncodingHeader, "gzip,deflate");
final response = await request.close();
Expect.equals(
"gzip", response.headers.value(HttpHeaders.contentEncodingHeader));
final list =
await response.fold<List<int>>(<int>[], (list, b) => list..addAll(b));
"gzip",
response.headers.value(HttpHeaders.contentEncodingHeader),
);
final list = await response.fold<List<int>>(
<int>[],
(list, b) => list..addAll(b),
);
if (clientAutoUncompress) {
Expect.listEquals(data, list);
} else {
@@ -57,8 +61,10 @@ Future<void> testAcceptEncodingHeader() async {
final request = await client.get("127.0.0.1", server.port, "/");
request.headers.set(HttpHeaders.acceptEncodingHeader, encoding);
final response = await request.close();
Expect.equals(valid,
("gzip" == response.headers.value(HttpHeaders.contentEncodingHeader)));
Expect.equals(
valid,
("gzip" == response.headers.value(HttpHeaders.contentEncodingHeader)),
);
await response.listen((_) {}).asFuture();
server.close();
client.close();
@@ -83,7 +89,9 @@ Future<void> testDisableCompressTest() async {
Expect.equals(false, server.autoCompress);
server.listen((request) {
Expect.equals(
'gzip', request.headers.value(HttpHeaders.acceptEncodingHeader));
'gzip',
request.headers.value(HttpHeaders.acceptEncodingHeader),
);
request.response.write("data");
request.response.close();
});
@@ -91,7 +99,9 @@ Future<void> testDisableCompressTest() async {
final request = await client.get("127.0.0.1", server.port, "/");
final response = await request.close();
Expect.equals(
null, response.headers.value(HttpHeaders.contentEncodingHeader));
null,
response.headers.value(HttpHeaders.contentEncodingHeader),
);
await response.listen((_) {}).asFuture();
server.close();
client.close();
@@ -15,10 +15,13 @@ void testHttp10Close(bool closeRequest) {
Socket.connect("127.0.0.1", server.port).then((socket) {
socket.write("GET / HTTP/1.0\r\n\r\n");
socket.listen((data) {}, onDone: () {
if (!closeRequest) socket.destroy();
server.close();
});
socket.listen(
(data) {},
onDone: () {
if (!closeRequest) socket.destroy();
server.close();
},
);
if (closeRequest) socket.close();
});
});
@@ -33,10 +36,13 @@ void testHttp11Close(bool closeRequest) {
Socket.connect("127.0.0.1", server.port).then((socket) {
List<int> buffer = new List<int>.filled(1024, 0);
socket.write("GET / HTTP/1.1\r\nConnection: close\r\n\r\n");
socket.listen((data) {}, onDone: () {
if (!closeRequest) socket.destroy();
server.close();
});
socket.listen(
(data) {},
onDone: () {
if (!closeRequest) socket.destroy();
server.close();
},
);
if (closeRequest) socket.close();
});
});
@@ -46,12 +52,15 @@ void testStreamResponse() {
HttpServer.bind("127.0.0.1", 0).then((server) {
server.listen((request) {
var timer = new Timer.periodic(const Duration(milliseconds: 0), (_) {
request.response
.write('data:${new DateTime.now().millisecondsSinceEpoch}\n\n');
request.response.write(
'data:${new DateTime.now().millisecondsSinceEpoch}\n\n',
);
});
request.response.done.whenComplete(() {
timer.cancel();
}).catchError((_) {});
request.response.done
.whenComplete(() {
timer.cancel();
})
.catchError((_) {});
});
var client = new HttpClient();
@@ -59,16 +68,19 @@ void testStreamResponse() {
.getUrl(Uri.parse("http://127.0.0.1:${server.port}"))
.then((request) => request.close())
.then((response) {
int bytes = 0;
response.listen((data) {
bytes += data.length;
if (bytes > 100) {
client.close(force: true);
}
}, onError: (error) {
server.close();
});
});
int bytes = 0;
response.listen(
(data) {
bytes += data.length;
if (bytes > 100) {
client.close(force: true);
}
},
onError: (error) {
server.close();
},
);
});
});
}
@@ -141,17 +141,20 @@ testDifferentAddressFamiliesAndProxySettings(String dir) async {
Expect.equals("Hello via Proxy", inet6ResponseText);
// Fetch a URL from the Unix server and verify the results.
final unixResponse = await client
.getUrl(Uri(
.getUrl(
Uri(
scheme: "unix",
// Connection pooling is based on the host/port combination
// so ensure that the host is unique for unique logical
// endpoints. Also, the `host` property is converted to
// lowercase so you cannot use it directly for file paths.
host: 'dummy',
path: "/"))
path: "/",
),
)
.then((request) {
return request.close();
});
return request.close();
});
Expect.equals(200, unixResponse.statusCode);
final unixResponseText = await unixResponse
.transform(utf8.decoder)
@@ -15,19 +15,30 @@ void setConnectionHeaders(HttpHeaders headers) {
}
void checkExpectedConnectionHeaders(
HttpHeaders headers, bool persistentConnection) {
HttpHeaders headers,
bool persistentConnection,
) {
Expect.equals("some-value1", headers.value("My-Connection-Header1"));
Expect.equals("some-value2", headers.value("My-Connection-Header2"));
Expect.isTrue(headers[HttpHeaders.connectionHeader]!
.any((value) => value.toLowerCase() == "my-connection-header1"));
Expect.isTrue(headers[HttpHeaders.connectionHeader]!
.any((value) => value.toLowerCase() == "my-connection-header2"));
Expect.isTrue(
headers[HttpHeaders.connectionHeader]!.any(
(value) => value.toLowerCase() == "my-connection-header1",
),
);
Expect.isTrue(
headers[HttpHeaders.connectionHeader]!.any(
(value) => value.toLowerCase() == "my-connection-header2",
),
);
if (persistentConnection) {
Expect.equals(2, headers[HttpHeaders.connectionHeader]!.length);
} else {
Expect.equals(3, headers[HttpHeaders.connectionHeader]!.length);
Expect.isTrue(headers[HttpHeaders.connectionHeader]!
.any((value) => value.toLowerCase() == "close"));
Expect.isTrue(
headers[HttpHeaders.connectionHeader]!.any(
(value) => value.toLowerCase() == "close",
),
);
}
}
@@ -37,9 +48,13 @@ void test(int totalConnections, bool clientPersistentConnection) {
// Check expected request.
Expect.equals(clientPersistentConnection, request.persistentConnection);
Expect.equals(
clientPersistentConnection, request.response.persistentConnection);
clientPersistentConnection,
request.response.persistentConnection,
);
checkExpectedConnectionHeaders(
request.headers, request.persistentConnection);
request.headers,
request.persistentConnection,
);
// Generate response. If the client signaled non-persistent
// connection the server should not need to set it.
@@ -56,21 +71,27 @@ void test(int totalConnections, bool clientPersistentConnection) {
client
.get("127.0.0.1", server.port, "/")
.then((HttpClientRequest request) {
setConnectionHeaders(request.headers);
request.persistentConnection = clientPersistentConnection;
return request.close();
}).then((HttpClientResponse response) {
Expect.isFalse(response.persistentConnection);
checkExpectedConnectionHeaders(
response.headers, response.persistentConnection);
response.listen((_) {}, onDone: () {
count++;
if (count == totalConnections) {
client.close();
server.close();
}
});
});
setConnectionHeaders(request.headers);
request.persistentConnection = clientPersistentConnection;
return request.close();
})
.then((HttpClientResponse response) {
Expect.isFalse(response.persistentConnection);
checkExpectedConnectionHeaders(
response.headers,
response.persistentConnection,
);
response.listen(
(_) {},
onDone: () {
count++;
if (count == totalConnections) {
client.close();
server.close();
}
},
);
});
}
});
}
@@ -18,25 +18,36 @@ void testHttpConnectionInfo() {
Expect.isNotNull(clientPort);
Expect.equals(request.connectionInfo!.remotePort, clientPort);
Expect.equals(response.connectionInfo!.remotePort, clientPort);
request.listen((_) {}, onDone: () {
request.response.close();
});
request.listen(
(_) {},
onDone: () {
request.response.close();
},
);
});
HttpClient client = new HttpClient();
client.get("127.0.0.1", server.port, "/").then((request) {
Expect.isTrue(request.connectionInfo!.remoteAddress is InternetAddress);
Expect.equals(request.connectionInfo!.remotePort, server.port);
clientPort = request.connectionInfo!.localPort;
return request.close();
}).then((response) {
Expect.equals(server.port, response.connectionInfo!.remotePort);
Expect.equals(clientPort, response.connectionInfo!.localPort);
response.listen((_) {}, onDone: () {
client.close();
server.close();
});
});
client
.get("127.0.0.1", server.port, "/")
.then((request) {
Expect.isTrue(
request.connectionInfo!.remoteAddress is InternetAddress,
);
Expect.equals(request.connectionInfo!.remotePort, server.port);
clientPort = request.connectionInfo!.localPort;
return request.close();
})
.then((response) {
Expect.equals(server.port, response.connectionInfo!.remotePort);
Expect.equals(clientPort, response.connectionInfo!.localPort);
response.listen(
(_) {},
onDone: () {
client.close();
server.close();
},
);
});
});
}
+211 -159
View File
@@ -15,51 +15,60 @@ import "package:expect/expect.dart";
void testNoBody(int totalConnections, bool explicitContentLength) {
int count = 0;
HttpServer.bind("127.0.0.1", 0, backlog: totalConnections).then((server) {
server.listen((HttpRequest request) {
Expect.equals(null, request.headers.value('content-length'));
Expect.equals(-1, request.contentLength);
var response = request.response;
response.contentLength = 0;
response.done.then((_) {
Expect.fail("Unexpected successful response completion");
}).catchError((error) {
Expect.isTrue(error is HttpException);
if (++count == totalConnections) {
server.close();
}
});
// write with content length 0 closes the connection and
// reports an error.
response.write("x");
// Subsequent write are ignored as there is already an
// error.
response.write("x");
// After an explicit close, write becomes a state error
// because we have said we will not add more.
response.close();
Expect.throws(() {
server.listen(
(HttpRequest request) {
Expect.equals(null, request.headers.value('content-length'));
Expect.equals(-1, request.contentLength);
var response = request.response;
response.contentLength = 0;
response.done
.then((_) {
Expect.fail("Unexpected successful response completion");
})
.catchError((error) {
Expect.isTrue(error is HttpException);
if (++count == totalConnections) {
server.close();
}
});
// write with content length 0 closes the connection and
// reports an error.
response.write("x");
}, (e) => e is StateError);
}, onError: (e, trace) {
String msg = "Unexpected server error $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
});
// Subsequent write are ignored as there is already an
// error.
response.write("x");
// After an explicit close, write becomes a state error
// because we have said we will not add more.
response.close();
Expect.throws(() {
response.write("x");
}, (e) => e is StateError);
},
onError: (e, trace) {
String msg = "Unexpected server error $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
},
);
HttpClient client = new HttpClient();
for (int i = 0; i < totalConnections; i++) {
client.get("127.0.0.1", server.port, "/").then((request) {
if (explicitContentLength) {
request.contentLength = 0;
}
return request.close();
}).then((response) {
Expect.equals("0", response.headers.value('content-length'));
Expect.equals(0, response.contentLength);
response.drain();
}).catchError((e, trace) {
// It's also okay to fail, as headers may not be written.
});
client
.get("127.0.0.1", server.port, "/")
.then((request) {
if (explicitContentLength) {
request.contentLength = 0;
}
return request.close();
})
.then((response) {
Expect.equals("0", response.headers.value('content-length'));
Expect.equals(0, response.contentLength);
response.drain();
})
.catchError((e, trace) {
// It's also okay to fail, as headers may not be written.
});
}
});
}
@@ -67,133 +76,173 @@ void testNoBody(int totalConnections, bool explicitContentLength) {
void testBody(int totalConnections, bool useHeader) {
HttpServer.bind("127.0.0.1", 0, backlog: totalConnections).then((server) {
int serverCount = 0;
server.listen((HttpRequest request) {
Expect.equals("2", request.headers.value('content-length'));
Expect.equals(2, request.contentLength);
var response = request.response;
if (useHeader) {
response.contentLength = 2;
} else {
response.headers.set("content-length", 2);
}
request.listen((d) {}, onDone: () {
response.write("x");
Expect.throws(
() => response.contentLength = 3, (e) => e is HttpException);
response.write("x");
response.write("x");
response.done.then((_) {
Expect.fail("Unexpected successful response completion");
}).catchError((error) {
Expect.isTrue(error is HttpException, "[$error]");
if (++serverCount == totalConnections) {
server.close();
}
});
response.close();
Expect.throws(() {
response.write("x");
}, (e) => e is StateError);
});
}, onError: (e, trace) {
String msg = "Unexpected error $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
});
server.listen(
(HttpRequest request) {
Expect.equals("2", request.headers.value('content-length'));
Expect.equals(2, request.contentLength);
var response = request.response;
if (useHeader) {
response.contentLength = 2;
} else {
response.headers.set("content-length", 2);
}
request.listen(
(d) {},
onDone: () {
response.write("x");
Expect.throws(
() => response.contentLength = 3,
(e) => e is HttpException,
);
response.write("x");
response.write("x");
response.done
.then((_) {
Expect.fail("Unexpected successful response completion");
})
.catchError((error) {
Expect.isTrue(error is HttpException, "[$error]");
if (++serverCount == totalConnections) {
server.close();
}
});
response.close();
Expect.throws(() {
response.write("x");
}, (e) => e is StateError);
},
);
},
onError: (e, trace) {
String msg = "Unexpected error $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
},
);
int clientCount = 0;
HttpClient client = new HttpClient();
for (int i = 0; i < totalConnections; i++) {
client.get("127.0.0.1", server.port, "/").then((request) {
if (useHeader) {
request.contentLength = 2;
} else {
request.headers.add(HttpHeaders.contentLengthHeader, "7");
request.headers.add(HttpHeaders.contentLengthHeader, "2");
}
request.write("x");
Expect.throws(
() => request.contentLength = 3, (e) => e is HttpException);
request.write("x");
return request.close();
}).then((response) {
Expect.equals("2", response.headers.value('content-length'));
Expect.equals(2, response.contentLength);
response.listen((d) {}, onDone: () {
if (++clientCount == totalConnections) {
client.close();
}
}, onError: (error, trace) {
// Undefined what server response sends.
});
}).catchError((error) {
// It's also okay to fail, as headers may not be written.
});
client
.get("127.0.0.1", server.port, "/")
.then((request) {
if (useHeader) {
request.contentLength = 2;
} else {
request.headers.add(HttpHeaders.contentLengthHeader, "7");
request.headers.add(HttpHeaders.contentLengthHeader, "2");
}
request.write("x");
Expect.throws(
() => request.contentLength = 3,
(e) => e is HttpException,
);
request.write("x");
return request.close();
})
.then((response) {
Expect.equals("2", response.headers.value('content-length'));
Expect.equals(2, response.contentLength);
response.listen(
(d) {},
onDone: () {
if (++clientCount == totalConnections) {
client.close();
}
},
onError: (error, trace) {
// Undefined what server response sends.
},
);
})
.catchError((error) {
// It's also okay to fail, as headers may not be written.
});
}
});
}
void testBodyChunked(int totalConnections, bool useHeader) {
HttpServer.bind("127.0.0.1", 0, backlog: totalConnections).then((server) {
server.listen((HttpRequest request) {
Expect.isNull(request.headers.value('content-length'));
Expect.equals(-1, request.contentLength);
var response = request.response;
if (useHeader) {
response.contentLength = 2;
response.headers.chunkedTransferEncoding = true;
} else {
response.headers.set("content-length", 2);
response.headers.set("transfer-encoding", "chunked");
}
request.listen((d) {}, onDone: () {
response.write("x");
Expect.throws(() => response.headers.chunkedTransferEncoding = false,
(e) => e is HttpException);
response.write("x");
response.write("x");
response.close();
Expect.throws(() {
response.write("x");
}, (e) => e is StateError);
});
}, onError: (e, trace) {
String msg = "Unexpected error $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
});
server.listen(
(HttpRequest request) {
Expect.isNull(request.headers.value('content-length'));
Expect.equals(-1, request.contentLength);
var response = request.response;
if (useHeader) {
response.contentLength = 2;
response.headers.chunkedTransferEncoding = true;
} else {
response.headers.set("content-length", 2);
response.headers.set("transfer-encoding", "chunked");
}
request.listen(
(d) {},
onDone: () {
response.write("x");
Expect.throws(
() => response.headers.chunkedTransferEncoding = false,
(e) => e is HttpException,
);
response.write("x");
response.write("x");
response.close();
Expect.throws(() {
response.write("x");
}, (e) => e is StateError);
},
);
},
onError: (e, trace) {
String msg = "Unexpected error $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
},
);
int count = 0;
HttpClient client = new HttpClient();
for (int i = 0; i < totalConnections; i++) {
client.get("127.0.0.1", server.port, "/").then((request) {
if (useHeader) {
request.contentLength = 2;
request.headers.chunkedTransferEncoding = true;
} else {
request.headers.add(HttpHeaders.contentLengthHeader, "2");
request.headers.set(HttpHeaders.transferEncodingHeader, "chunked");
}
request.write("x");
Expect.throws(() => request.headers.chunkedTransferEncoding = false,
(e) => e is HttpException);
request.write("x");
request.write("x");
return request.close();
}).then((response) {
Expect.isNull(response.headers.value('content-length'));
Expect.equals(-1, response.contentLength);
response.listen((d) {}, onDone: () {
if (++count == totalConnections) {
client.close();
server.close();
}
});
}).catchError((e, trace) {
String msg = "Unexpected error $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
});
client
.get("127.0.0.1", server.port, "/")
.then((request) {
if (useHeader) {
request.contentLength = 2;
request.headers.chunkedTransferEncoding = true;
} else {
request.headers.add(HttpHeaders.contentLengthHeader, "2");
request.headers.set(
HttpHeaders.transferEncodingHeader,
"chunked",
);
}
request.write("x");
Expect.throws(
() => request.headers.chunkedTransferEncoding = false,
(e) => e is HttpException,
);
request.write("x");
request.write("x");
return request.close();
})
.then((response) {
Expect.isNull(response.headers.value('content-length'));
Expect.equals(-1, response.contentLength);
response.listen(
(d) {},
onDone: () {
if (++count == totalConnections) {
client.close();
server.close();
}
},
);
})
.catchError((e, trace) {
String msg = "Unexpected error $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
});
}
});
}
@@ -216,11 +265,14 @@ void testSetContentLength() {
.get("127.0.0.1", server.port, "/")
.then((request) => request.close())
.then((response) {
response.listen((_) {}, onDone: () {
client.close();
server.close();
});
});
response.listen(
(_) {},
onDone: () {
client.close();
server.close();
},
);
});
});
}
+18 -4
View File
@@ -12,10 +12,24 @@ var _parseCookieDate = Testing$HttpDate.test$_parseCookieDate;
void testParseHttpCookieDate() {
Expect.throws(() => _parseCookieDate(""));
test(int year, int month, int day, int hours, int minutes, int seconds,
String formatted) {
DateTime date =
new DateTime.utc(year, month, day, hours, minutes, seconds, 0);
test(
int year,
int month,
int day,
int hours,
int minutes,
int seconds,
String formatted,
) {
DateTime date = new DateTime.utc(
year,
month,
day,
hours,
minutes,
seconds,
0,
);
Expect.equals(date, _parseCookieDate(formatted));
}
+85 -53
View File
@@ -11,7 +11,7 @@ void testCookies() {
{'abc': 'def'},
{'ABC': 'DEF'},
{'Abc': 'Def'},
{'Abc': 'Def', 'SID': 'sffFSDF4FsdfF56765'}
{'Abc': 'Def', 'SID': 'sffFSDF4FsdfF56765'},
];
HttpServer.bind("127.0.0.1", 0).then((server) {
@@ -31,29 +31,36 @@ void testCookies() {
int count = 0;
HttpClient client = new HttpClient();
for (int i = 0; i < cookies.length; i++) {
client.get("127.0.0.1", server.port, "/$i").then((request) {
// Send the cookies to the server.
cookies[i].forEach((k, v) {
request.cookies.add(new Cookie(k, v));
});
return request.close();
}).then((response) {
// Expect the same cookies back.
var cookiesMap = {};
response.cookies.forEach((c) => cookiesMap[c.name] = c.value);
Expect.mapEquals(cookies[i], cookiesMap);
response.cookies.forEach((c) => Expect.isTrue(c.httpOnly));
response.listen((d) {}, onDone: () {
if (++count == cookies.length) {
client.close();
server.close();
}
});
}).catchError((e, trace) {
String msg = "Unexpected error $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
});
client
.get("127.0.0.1", server.port, "/$i")
.then((request) {
// Send the cookies to the server.
cookies[i].forEach((k, v) {
request.cookies.add(new Cookie(k, v));
});
return request.close();
})
.then((response) {
// Expect the same cookies back.
var cookiesMap = {};
response.cookies.forEach((c) => cookiesMap[c.name] = c.value);
Expect.mapEquals(cookies[i], cookiesMap);
response.cookies.forEach((c) => Expect.isTrue(c.httpOnly));
response.listen(
(d) {},
onDone: () {
if (++count == cookies.length) {
client.close();
server.close();
}
},
);
})
.catchError((e, trace) {
String msg = "Unexpected error $e";
if (trace != null) msg += "\nStackTrace: $trace";
Expect.fail(msg);
});
}
});
}
@@ -63,24 +70,35 @@ void testValidateCookieWithDoubleQuotes() {
Expect.equals(Cookie('key', '').toString(), 'key=; HttpOnly');
Expect.equals(Cookie('key', '""').toString(), 'key=""; HttpOnly');
Expect.equals(Cookie('key', '"value"').toString(), 'key="value"; HttpOnly');
Expect.equals(Cookie.fromSetCookieValue('key=value; HttpOnly').toString(),
'key=value; HttpOnly');
Expect.equals(
Cookie.fromSetCookieValue('key=; HttpOnly').toString(), 'key=; HttpOnly');
Expect.equals(Cookie.fromSetCookieValue('key=""; HttpOnly').toString(),
'key=""; HttpOnly');
Expect.equals(Cookie.fromSetCookieValue('key="value"; HttpOnly').toString(),
'key="value"; HttpOnly');
Cookie.fromSetCookieValue('key=value; HttpOnly').toString(),
'key=value; HttpOnly',
);
Expect.equals(
Cookie.fromSetCookieValue('key=; HttpOnly').toString(),
'key=; HttpOnly',
);
Expect.equals(
Cookie.fromSetCookieValue('key=""; HttpOnly').toString(),
'key=""; HttpOnly',
);
Expect.equals(
Cookie.fromSetCookieValue('key="value"; HttpOnly').toString(),
'key="value"; HttpOnly',
);
Expect.throwsFormatException(() => Cookie('key', '"'));
Expect.throwsFormatException(() => Cookie('key', '"""'));
Expect.throwsFormatException(() => Cookie('key', '"x""'));
Expect.throwsFormatException(() => Cookie('key', '"x"y"'));
Expect.throwsFormatException(
() => Cookie.fromSetCookieValue('key="; HttpOnly'));
() => Cookie.fromSetCookieValue('key="; HttpOnly'),
);
Expect.throwsFormatException(
() => Cookie.fromSetCookieValue('key="""; HttpOnly'));
() => Cookie.fromSetCookieValue('key="""; HttpOnly'),
);
Expect.throwsFormatException(
() => Cookie.fromSetCookieValue('key="x""; HttpOnly'));
() => Cookie.fromSetCookieValue('key="x""; HttpOnly'),
);
}
void testValidatePath() {
@@ -112,37 +130,51 @@ void testValidatePath() {
void testCookieSameSite() {
Cookie cookie1 = Cookie.fromSetCookieValue(
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; Secure; "
"HttpOnly; Path=/; SameSite=None");
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; Secure; "
"HttpOnly; Path=/; SameSite=None",
);
Expect.equals(cookie1.sameSite, SameSite.none);
Cookie cookie2 = Cookie.fromSetCookieValue(
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
"Path=/; SameSite=Lax");
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
"Path=/; SameSite=Lax",
);
Expect.equals(cookie2.sameSite, SameSite.lax);
Cookie cookie3 = Cookie.fromSetCookieValue(
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
"Path=/; SameSite=LAX");
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
"Path=/; SameSite=LAX",
);
Expect.equals(cookie3.sameSite, SameSite.lax);
Cookie cookie4 = Cookie.fromSetCookieValue(
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
"Path=/; SameSite= Lax");
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
"Path=/; SameSite= Lax",
);
Expect.equals(cookie4.sameSite, SameSite.lax);
Cookie cookie5 = Cookie.fromSetCookieValue(
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
"Path=/; sAmEsItE= nOnE");
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
"Path=/; sAmEsItE= nOnE",
);
Expect.equals(cookie5.sameSite, SameSite.none);
Expect.throws<HttpException>(() => Cookie.fromSetCookieValue(
Expect.throws<HttpException>(
() => Cookie.fromSetCookieValue(
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
"Path=/; SameSite=Relax"),
(e) => e.message == "SameSite value should be one of Lax, Strict or None.");
Expect.throws<HttpException>(() => Cookie.fromSetCookieValue(
"Path=/; SameSite=Relax",
),
(e) => e.message == "SameSite value should be one of Lax, Strict or None.",
);
Expect.throws<HttpException>(
() => Cookie.fromSetCookieValue(
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
"Path=/; SameSite="),
(e) => e.message == "SameSite value should be one of Lax, Strict or None.");
Expect.throws<HttpException>(() => Cookie.fromSetCookieValue(
"Path=/; SameSite=",
),
(e) => e.message == "SameSite value should be one of Lax, Strict or None.",
);
Expect.throws<HttpException>(
() => Cookie.fromSetCookieValue(
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
"Path=/; SameSite=无"),
(e) => e.message == "SameSite value should be one of Lax, Strict or None.");
"Path=/; SameSite=无",
),
(e) => e.message == "SameSite value should be one of Lax, Strict or None.",
);
}
void main() {
@@ -35,13 +35,13 @@ Future makeServer() {
Future runClientProcess(int port) {
return Process.run(
Platform.executable,
[]
..addAll(Platform.executableArguments)
..add(Platform.script.toFilePath())
..add('--client')
..add(port.toString()))
.then((ProcessResult result) {
Platform.executable,
[]
..addAll(Platform.executableArguments)
..add(Platform.script.toFilePath())
..add('--client')
..add(port.toString()),
).then((ProcessResult result) {
if (result.exitCode != 0 || !result.stdout.contains('SUCCESS')) {
print("Client failed, exit code ${result.exitCode}");
print(" stdout:");
+9 -2
View File
@@ -26,8 +26,15 @@ void testParseHttpDate() {
}
void testFormatParseHttpDate() {
test(int year, int month, int day, int hours, int minutes, int seconds,
String expectedFormatted) {
test(
int year,
int month,
int day,
int hours,
int minutes,
int seconds,
String expectedFormatted,
) {
DateTime date;
String formatted;
date = new DateTime.utc(year, month, day, hours, minutes, seconds, 0);
+102 -72
View File
@@ -22,8 +22,10 @@ void testServerDetachSocket() {
response.detachSocket().then((socket) {
Expect.isNotNull(socket);
var body = new StringBuffer();
socket.listen((data) => body.write(new String.fromCharCodes(data)),
onDone: () => Expect.equals("Some data", body.toString()));
socket.listen(
(data) => body.write(new String.fromCharCodes(data)),
onDone: () => Expect.equals("Some data", body.toString()),
);
socket.write("Test!");
socket.close();
});
@@ -31,20 +33,25 @@ void testServerDetachSocket() {
});
Socket.connect("127.0.0.1", server.port).then((socket) {
socket.write("GET / HTTP/1.1\r\n"
"content-length: 0\r\n\r\n"
"Some data");
socket.write(
"GET / HTTP/1.1\r\n"
"content-length: 0\r\n\r\n"
"Some data",
);
var body = new StringBuffer();
socket.listen((data) => body.write(new String.fromCharCodes(data)),
onDone: () {
Expect.equals(
socket.listen(
(data) => body.write(new String.fromCharCodes(data)),
onDone: () {
Expect.equals(
"HTTP/1.1 200 OK\r\n"
"content-length: 0\r\n"
"\r\n"
"Test!",
body.toString());
socket.close();
});
body.toString(),
);
socket.close();
},
);
});
});
}
@@ -57,8 +64,10 @@ void testServerDetachSocketNoWriteHeaders() {
response.detachSocket(writeHeaders: false).then((socket) {
Expect.isNotNull(socket);
var body = new StringBuffer();
socket.listen((data) => body.write(new String.fromCharCodes(data)),
onDone: () => Expect.equals("Some data", body.toString()));
socket.listen(
(data) => body.write(new String.fromCharCodes(data)),
onDone: () => Expect.equals("Some data", body.toString()),
);
socket.write("Test!");
socket.close();
});
@@ -66,15 +75,19 @@ void testServerDetachSocketNoWriteHeaders() {
});
Socket.connect("127.0.0.1", server.port).then((socket) {
socket.write("GET / HTTP/1.1\r\n"
"content-length: 0\r\n\r\n"
"Some data");
socket.write(
"GET / HTTP/1.1\r\n"
"content-length: 0\r\n\r\n"
"Some data",
);
var body = new StringBuffer();
socket.listen((data) => body.write(new String.fromCharCodes(data)),
onDone: () {
Expect.equals("Test!", body.toString());
socket.close();
});
socket.listen(
(data) => body.write(new String.fromCharCodes(data)),
onDone: () {
Expect.equals("Test!", body.toString());
socket.close();
},
);
});
});
}
@@ -90,11 +103,16 @@ void testBadServerDetachSocket() {
});
Socket.connect("127.0.0.1", server.port).then((socket) {
socket.write("GET / HTTP/1.1\r\n"
"content-length: 0\r\n\r\n");
socket.listen((_) {}, onDone: () {
socket.close();
});
socket.write(
"GET / HTTP/1.1\r\n"
"content-length: 0\r\n\r\n",
);
socket.listen(
(_) {},
onDone: () {
socket.close();
},
);
});
});
}
@@ -103,22 +121,26 @@ void testClientDetachSocket() {
ServerSocket.bind("127.0.0.1", 0).then((server) {
server.listen((socket) {
int port = server.port;
socket.write("HTTP/1.1 200 OK\r\n"
"\r\n"
"Test!");
socket.write(
"HTTP/1.1 200 OK\r\n"
"\r\n"
"Test!",
);
var body = new StringBuffer();
socket.listen((data) => body.write(new String.fromCharCodes(data)),
onDone: () {
List<String> lines = body.toString().split("\r\n");
Expect.equals(5, lines.length);
Expect.equals("GET / HTTP/1.1", lines[0]);
Expect.equals("", lines[3]);
Expect.equals("Some data", lines[4]);
lines.sort(); // Lines 1-2 becomes 3-4 in a fixed order.
Expect.equals("accept-encoding: gzip", lines[3]);
Expect.equals("host: 127.0.0.1:${port}", lines[4]);
socket.close();
});
socket.listen(
(data) => body.write(new String.fromCharCodes(data)),
onDone: () {
List<String> lines = body.toString().split("\r\n");
Expect.equals(5, lines.length);
Expect.equals("GET / HTTP/1.1", lines[0]);
Expect.equals("", lines[3]);
Expect.equals("Some data", lines[4]);
lines.sort(); // Lines 1-2 becomes 3-4 in a fixed order.
Expect.equals("accept-encoding: gzip", lines[3]);
Expect.equals("host: 127.0.0.1:${port}", lines[4]);
socket.close();
},
);
server.close();
});
@@ -128,17 +150,19 @@ void testClientDetachSocket() {
.get("127.0.0.1", server.port, "/")
.then((request) => request.close())
.then((response) {
response.detachSocket().then((socket) {
var body = new StringBuffer();
socket.listen((data) => body.write(new String.fromCharCodes(data)),
onDone: () {
Expect.equals("Test!", body.toString());
client.close();
response.detachSocket().then((socket) {
var body = new StringBuffer();
socket.listen(
(data) => body.write(new String.fromCharCodes(data)),
onDone: () {
Expect.equals("Test!", body.toString());
client.close();
},
);
socket.write("Some data");
socket.close();
});
});
socket.write("Some data");
socket.close();
});
});
});
}
@@ -161,30 +185,36 @@ void testUpgradedConnection() {
var client = new HttpClient();
client.userAgent = null;
client.get("127.0.0.1", server.port, "/").then((request) {
request.headers.set('upgrade', 'mine');
return request.close();
}).then((response) {
client.get("127.0.0.1", server.port, "/").then((request) {
response.detachSocket().then((socket) {
// We are testing that we can detach the socket, even though
// we made a new connection (testing it was not reused).
request.close().then((response) {
asyncStart();
response.listen(null, onDone: () {
server.close();
asyncEnd();
});
socket.add([0]);
socket.close();
socket.fold<List<int>>([], (l, d) => l..addAll(d)).then((data) {
asyncEnd();
Expect.listEquals([0], data);
client
.get("127.0.0.1", server.port, "/")
.then((request) {
request.headers.set('upgrade', 'mine');
return request.close();
})
.then((response) {
client.get("127.0.0.1", server.port, "/").then((request) {
response.detachSocket().then((socket) {
// We are testing that we can detach the socket, even though
// we made a new connection (testing it was not reused).
request.close().then((response) {
asyncStart();
response.listen(
null,
onDone: () {
server.close();
asyncEnd();
},
);
socket.add([0]);
socket.close();
socket.fold<List<int>>([], (l, d) => l..addAll(d)).then((data) {
asyncEnd();
Expect.listEquals([0], data);
});
});
});
});
});
});
});
});
}
@@ -15,11 +15,14 @@ const sampleData = <int>[1, 2, 3, 4, 5];
void testBadHostName() {
asyncStart();
HttpClient client = new HttpClient();
client.get("some.bad.host.name.7654321", 0, "/").then((request) {
Expect.fail("Should not open a request on bad hostname");
}).catchError((error) {
asyncEnd(); // We expect onError to be called, due to bad host name.
}, test: (error) => error is! String);
client
.get("some.bad.host.name.7654321", 0, "/")
.then((request) {
Expect.fail("Should not open a request on bad hostname");
})
.catchError((error) {
asyncEnd(); // We expect onError to be called, due to bad host name.
}, test: (error) => error is! String);
}
void testConnect(InternetAddress loopback, {int expectedElapsedMs = 0}) async {
@@ -37,24 +40,31 @@ void testConnect(InternetAddress loopback, {int expectedElapsedMs = 0}) async {
final sw = Stopwatch()..start();
var got = 0;
for (var i = 0; i < max; i++) {
final client = await Socket.connect('localhost', servers[i].port,
sourceAddress: loopback);
client.listen((received) {
Expect.listEquals(sampleData, received);
}, onError: (e) {
Expect.fail('Unexpected failure $e');
}, onDone: () {
client.close();
got++;
if (got == max) {
// Test that no stack overflow happens.
for (final server in servers) {
server.close();
final client = await Socket.connect(
'localhost',
servers[i].port,
sourceAddress: loopback,
);
client.listen(
(received) {
Expect.listEquals(sampleData, received);
},
onError: (e) {
Expect.fail('Unexpected failure $e');
},
onDone: () {
client.close();
got++;
if (got == max) {
// Test that no stack overflow happens.
for (final server in servers) {
server.close();
}
Expect.isTrue(sw.elapsedMilliseconds > expectedElapsedMs);
asyncEnd();
}
Expect.isTrue(sw.elapsedMilliseconds > expectedElapsedMs);
asyncEnd();
}
});
},
);
}
}
@@ -68,8 +78,10 @@ void main() async {
if (localhosts.contains(InternetAddress.loopbackIPv6)) {
// matches value in socket_patch.dart
const concurrentLookupDelay = Duration(milliseconds: 10);
testConnect(InternetAddress.loopbackIPv6,
expectedElapsedMs: concurrentLookupDelay.inMilliseconds);
testConnect(
InternetAddress.loopbackIPv6,
expectedElapsedMs: concurrentLookupDelay.inMilliseconds,
);
}
asyncEnd();
}
+12 -8
View File
@@ -48,19 +48,23 @@ void testHEAD(int totalConnections) {
.open("HEAD", "127.0.0.1", server.port, "/test$len")
.then((request) => request.close())
.then((HttpClientResponse response) {
Expect.equals(len, response.contentLength);
response.listen((_) => Expect.fail("Data from HEAD request"),
onDone: requestDone);
});
Expect.equals(len, response.contentLength);
response.listen(
(_) => Expect.fail("Data from HEAD request"),
onDone: requestDone,
);
});
client
.open("HEAD", "127.0.0.1", server.port, "/testChunked$len")
.then((request) => request.close())
.then((HttpClientResponse response) {
Expect.equals(-1, response.contentLength);
response.listen((_) => Expect.fail("Data from HEAD request"),
onDone: requestDone);
});
Expect.equals(-1, response.contentLength);
response.listen(
(_) => Expect.fail("Data from HEAD request"),
onDone: requestDone,
);
});
}
});
}
@@ -12,30 +12,38 @@ void test(int totalConnections, [String? body]) {
server.listen((HttpRequest request) {
HttpResponse response = request.response;
// Cannot mutate request headers.
Expect.throws(() => request.headers.add("X-Request-Header", "value"),
(e) => e is HttpException);
Expect.throws(
() => request.headers.add("X-Request-Header", "value"),
(e) => e is HttpException,
);
Expect.equals("value", request.headers.value("X-Request-Header"));
request.listen((_) {}, onDone: () {
// Can still mutate response headers as long as no data has been sent.
response.headers.add("X-Response-Header", "value");
if (body != null) {
response.write(body);
// Cannot change state or reason when data has been sent.
request.listen(
(_) {},
onDone: () {
// Can still mutate response headers as long as no data has been sent.
response.headers.add("X-Response-Header", "value");
if (body != null) {
response.write(body);
// Cannot change state or reason when data has been sent.
Expect.throwsStateError(() => response.statusCode = 200);
Expect.throwsStateError(() => response.reasonPhrase = "OK");
// Cannot mutate response headers when data has been sent.
Expect.throws(
() => response.headers.add("X-Request-Header", "value2"),
(e) => e is HttpException,
);
}
response..close();
// Cannot change state or reason after connection is closed.
Expect.throwsStateError(() => response.statusCode = 200);
Expect.throwsStateError(() => response.reasonPhrase = "OK");
// Cannot mutate response headers when data has been sent.
// Cannot mutate response headers after connection is closed.
Expect.throws(
() => response.headers.add("X-Request-Header", "value2"),
(e) => e is HttpException);
}
response..close();
// Cannot change state or reason after connection is closed.
Expect.throwsStateError(() => response.statusCode = 200);
Expect.throwsStateError(() => response.reasonPhrase = "OK");
// Cannot mutate response headers after connection is closed.
Expect.throws(() => response.headers.add("X-Request-Header", "value3"),
(e) => e is HttpException);
});
() => response.headers.add("X-Request-Header", "value3"),
(e) => e is HttpException,
);
},
);
});
int count = 0;
@@ -44,36 +52,46 @@ void test(int totalConnections, [String? body]) {
client
.get("127.0.0.1", server.port, "/")
.then((HttpClientRequest request) {
if (body != null) {
request.contentLength = -1;
}
// Can still mutate request headers as long as no data has been sent.
request.headers.add("X-Request-Header", "value");
if (body != null) {
request.write(body);
// Cannot mutate request headers when data has been sent.
Expect.throws(() => request.headers.add("X-Request-Header", "value2"),
(e) => e is HttpException);
}
request.close();
// Cannot mutate request headers when data has been sent.
Expect.throws(() => request.headers.add("X-Request-Header", "value3"),
(e) => e is HttpException);
return request.done;
}).then((HttpClientResponse response) {
// Cannot mutate response headers.
Expect.throws(() => response.headers.add("X-Response-Header", "value"),
(e) => e is HttpException);
Expect.equals("value", response.headers.value("X-Response-Header"));
response.listen((_) {}, onDone: () {
// Do not close the connections before we have read the
// full response bodies for all connections.
if (++count == totalConnections) {
client.close();
server.close();
}
});
});
if (body != null) {
request.contentLength = -1;
}
// Can still mutate request headers as long as no data has been sent.
request.headers.add("X-Request-Header", "value");
if (body != null) {
request.write(body);
// Cannot mutate request headers when data has been sent.
Expect.throws(
() => request.headers.add("X-Request-Header", "value2"),
(e) => e is HttpException,
);
}
request.close();
// Cannot mutate request headers when data has been sent.
Expect.throws(
() => request.headers.add("X-Request-Header", "value3"),
(e) => e is HttpException,
);
return request.done;
})
.then((HttpClientResponse response) {
// Cannot mutate response headers.
Expect.throws(
() => response.headers.add("X-Response-Header", "value"),
(e) => e is HttpException,
);
Expect.equals("value", response.headers.value("X-Response-Header"));
response.listen(
(_) {},
onDone: () {
// Do not close the connections before we have read the
// full response bodies for all connections.
if (++count == totalConnections) {
client.close();
server.close();
}
},
);
});
}
});
}
+153 -93
View File
@@ -26,16 +26,25 @@ void testMultiValue() {
headers.add(HttpHeaders.pragmaHeader, "pragma2");
Expect.equals(2, headers[HttpHeaders.pragmaHeader]!.length);
Expect.throws(
() => headers.value(HttpHeaders.pragmaHeader), (e) => e is HttpException);
() => headers.value(HttpHeaders.pragmaHeader),
(e) => e is HttpException,
);
headers.add(HttpHeaders.pragmaHeader, ["pragma3", "pragma4"]);
Expect.listEquals(["pragma1", "pragma2", "pragma3", "pragma4"],
headers[HttpHeaders.pragmaHeader]!);
Expect.listEquals([
"pragma1",
"pragma2",
"pragma3",
"pragma4",
], headers[HttpHeaders.pragmaHeader]!);
headers.remove(HttpHeaders.pragmaHeader, "pragma3");
Expect.equals(3, headers[HttpHeaders.pragmaHeader]!.length);
Expect.listEquals(
["pragma1", "pragma2", "pragma4"], headers[HttpHeaders.pragmaHeader]!);
Expect.listEquals([
"pragma1",
"pragma2",
"pragma4",
], headers[HttpHeaders.pragmaHeader]!);
headers.remove(HttpHeaders.pragmaHeader, "pragma3");
Expect.equals(3, headers[HttpHeaders.pragmaHeader]!.length);
@@ -269,8 +278,11 @@ void testEnumeration() {
}
void testHeaderValue() {
void check(HeaderValue headerValue, String value,
[Map<String, String?>? parameters]) {
void check(
HeaderValue headerValue,
String value, [
Map<String, String?>? parameters,
]) {
Expect.equals(value, headerValue.value);
if (parameters != null) {
Expect.equals(parameters.length, headerValue.parameters.length);
@@ -298,28 +310,38 @@ void testHeaderValue() {
check(headerValue, "v", {"a": ""});
Expect.throws(() => HeaderValue.parse("v;a=\"\\"), (e) => e is HttpException);
Expect.throws(
() => HeaderValue.parse("v;a=\";b=\"c\""), (e) => e is HttpException);
() => HeaderValue.parse("v;a=\";b=\"c\""),
(e) => e is HttpException,
);
Expect.throws(() => HeaderValue.parse("v;a=b c"), (e) => e is HttpException);
headerValue = HeaderValue.parse("æ;ø=å");
check(headerValue, "æ", {"ø": "å"});
headerValue =
HeaderValue.parse("xxx; aaa=bbb; ccc=\"\\\";\\a\"; ddd=\" \"");
headerValue = HeaderValue.parse(
"xxx; aaa=bbb; ccc=\"\\\";\\a\"; ddd=\" \"",
);
check(headerValue, "xxx", {"aaa": "bbb", "ccc": '\";a', "ddd": " "});
headerValue =
new HeaderValue("xxx", {"aaa": "bbb", "ccc": '\";a', "ddd": " "});
headerValue = new HeaderValue("xxx", {
"aaa": "bbb",
"ccc": '\";a',
"ddd": " ",
});
check(headerValue, "xxx", {"aaa": "bbb", "ccc": '\";a', "ddd": " "});
headerValue = HeaderValue.parse("attachment; filename=genome.jpeg;"
"modification-date=\"Wed, 12 February 1997 16:29:51 -0500\"");
headerValue = HeaderValue.parse(
"attachment; filename=genome.jpeg;"
"modification-date=\"Wed, 12 February 1997 16:29:51 -0500\"",
);
var parameters = {
"filename": "genome.jpeg",
"modification-date": "Wed, 12 February 1997 16:29:51 -0500"
"modification-date": "Wed, 12 February 1997 16:29:51 -0500",
};
check(headerValue, "attachment", parameters);
headerValue = new HeaderValue("attachment", parameters);
check(headerValue, "attachment", parameters);
headerValue = HeaderValue.parse(" attachment ;filename=genome.jpeg ;"
"modification-date = \"Wed, 12 February 1997 16:29:51 -0500\"");
headerValue = HeaderValue.parse(
" attachment ;filename=genome.jpeg ;"
"modification-date = \"Wed, 12 February 1997 16:29:51 -0500\"",
);
check(headerValue, "attachment", parameters);
headerValue = HeaderValue.parse("xxx; aaa; bbb; ccc");
check(headerValue, "xxx", {"aaa": null, "bbb": null, "ccc": null});
@@ -337,14 +359,20 @@ void testHeaderValue() {
Expect.equals("v; a", HeaderValue("v", {"a": null}).toString());
Expect.equals("v; a; b", HeaderValue("v", {"a": null, "b": null}).toString());
Expect.equals(
"v; a; b=c", HeaderValue("v", {"a": null, "b": "c"}).toString());
"v; a; b=c",
HeaderValue("v", {"a": null, "b": "c"}).toString(),
);
Expect.equals(
"v; a=c; b", HeaderValue("v", {"a": "c", "b": null}).toString());
"v; a=c; b",
HeaderValue("v", {"a": "c", "b": null}).toString(),
);
Expect.equals("v; a=\"\"", HeaderValue("v", {"a": ""}).toString());
Expect.equals("v; a=\"b c\"", HeaderValue("v", {"a": "b c"}).toString());
Expect.equals("v; a=\",\"", HeaderValue("v", {"a": ","}).toString());
Expect.equals(
"v; a=\"\\\\\\\"\"", HeaderValue("v", {"a": "\\\""}).toString());
"v; a=\"\\\\\\\"\"",
HeaderValue("v", {"a": "\\\""}).toString(),
);
Expect.equals("v; a=\"ø\"", HeaderValue("v", {"a": "ø"}).toString());
}
@@ -364,7 +392,8 @@ void testContentLength() {
headers = new _HttpHeaders("1.1");
var e = Expect.throws<HttpException>(
() => headers.set("content-length", ["cat"]));
() => headers.set("content-length", ["cat"]),
);
Expect.isTrue(e.message.contains("Content-Length must contain only digits"));
headers = new _HttpHeaders("1.1");
@@ -378,7 +407,8 @@ void testContentLength() {
headers = new _HttpHeaders("1.1");
e = Expect.throws<HttpException>(() => headers.set("content-length", [[]]));
Expect.isTrue(
e.message.contains("Unexpected type for header named content-length"));
e.message.contains("Unexpected type for header named content-length"),
);
headers = new _HttpHeaders("1.1");
headers.set("content-length", ["1", "2"]);
@@ -388,8 +418,12 @@ void testContentLength() {
}
void testContentType() {
void check(ContentType contentType, String primaryType, String subType,
[Map<String, String?>? parameters]) {
void check(
ContentType contentType,
String primaryType,
String subType, [
Map<String, String?>? parameters,
]) {
Expect.equals(primaryType, contentType.primaryType);
Expect.equals(subType, contentType.subType);
Expect.equals("$primaryType/$subType", contentType.value);
@@ -418,22 +452,31 @@ void testContentType() {
Expect.equals("text/html; charset=utf-8", contentType.toString());
Expect.throwsUnsupportedError(() => contentType.parameters["xxx"] = "yyy");
contentType = new ContentType("text", "html",
parameters: {"CHARSET": "UTF-8", "xxx": "YYY"});
contentType = new ContentType(
"text",
"html",
parameters: {"CHARSET": "UTF-8", "xxx": "YYY"},
);
check(contentType, "text", "html", {"charset": "utf-8", "xxx": "YYY"});
String s = contentType.toString();
bool expectedToString = (s == "text/html; charset=utf-8; xxx=YYY" ||
bool expectedToString =
(s == "text/html; charset=utf-8; xxx=YYY" ||
s == "text/html; xxx=YYY; charset=utf-8");
Expect.isTrue(expectedToString);
contentType = ContentType.parse("text/html; CHARSET=UTF-8; xxx=YYY");
check(contentType, "text", "html", {"charset": "utf-8", "xxx": "YYY"});
Expect.throwsUnsupportedError(() => contentType.parameters["xxx"] = "yyy");
contentType = new ContentType("text", "html",
charset: "ISO-8859-1", parameters: {"CHARSET": "UTF-8", "xxx": "yyy"});
contentType = new ContentType(
"text",
"html",
charset: "ISO-8859-1",
parameters: {"CHARSET": "UTF-8", "xxx": "yyy"},
);
check(contentType, "text", "html", {"charset": "iso-8859-1", "xxx": "yyy"});
s = contentType.toString();
expectedToString = (s == "text/html; charset=iso-8859-1; xxx=yyy" ||
expectedToString =
(s == "text/html; charset=iso-8859-1; xxx=yyy" ||
s == "text/html; xxx=yyy; charset=iso-8859-1");
Expect.isTrue(expectedToString);
@@ -447,13 +490,15 @@ void testContentType() {
check(contentType, "text", "html", {"charset": "utf-8"});
contentType = ContentType.parse("text/html; charset=utf-8; xxx=yyy");
check(contentType, "text", "html", {"charset": "utf-8", "xxx": "yyy"});
contentType =
ContentType.parse(" text/html ; charset = utf-8 ; xxx=yyy ");
contentType = ContentType.parse(
" text/html ; charset = utf-8 ; xxx=yyy ",
);
check(contentType, "text", "html", {"charset": "utf-8", "xxx": "yyy"});
contentType = ContentType.parse('text/html; charset=utf-8; xxx="yyy"');
check(contentType, "text", "html", {"charset": "utf-8", "xxx": "yyy"});
contentType =
ContentType.parse(" text/html ; charset = utf-8 ; xxx=yyy ");
contentType = ContentType.parse(
" text/html ; charset = utf-8 ; xxx=yyy ",
);
check(contentType, "text", "html", {"charset": "utf-8", "xxx": "yyy"});
contentType = ContentType.parse("text/html; charset=;");
@@ -517,79 +562,89 @@ void testCookie() {
DateTime date = new DateTime.utc(2014, DateTime.january, 5, 23, 59, 59, 0);
cookie.expires = date;
checkCookie(
cookie,
"$name=$value"
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
"; HttpOnly");
cookie,
"$name=$value"
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
"; HttpOnly",
);
cookie.maxAge = 567;
checkCookie(
cookie,
"$name=$value"
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
"; Max-Age=567"
"; HttpOnly");
cookie,
"$name=$value"
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
"; Max-Age=567"
"; HttpOnly",
);
cookie.domain = "example.com";
checkCookie(
cookie,
"$name=$value"
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
"; Max-Age=567"
"; Domain=example.com"
"; HttpOnly");
cookie,
"$name=$value"
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
"; Max-Age=567"
"; Domain=example.com"
"; HttpOnly",
);
cookie.path = "/xxx";
checkCookie(
cookie,
"$name=$value"
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
"; Max-Age=567"
"; Domain=example.com"
"; Path=/xxx"
"; HttpOnly");
cookie,
"$name=$value"
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
"; Max-Age=567"
"; Domain=example.com"
"; Path=/xxx"
"; HttpOnly",
);
cookie.secure = true;
checkCookie(
cookie,
"$name=$value"
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
"; Max-Age=567"
"; Domain=example.com"
"; Path=/xxx"
"; Secure"
"; HttpOnly");
cookie,
"$name=$value"
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
"; Max-Age=567"
"; Domain=example.com"
"; Path=/xxx"
"; Secure"
"; HttpOnly",
);
cookie.httpOnly = false;
checkCookie(
cookie,
"$name=$value"
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
"; Max-Age=567"
"; Domain=example.com"
"; Path=/xxx"
"; Secure");
cookie,
"$name=$value"
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
"; Max-Age=567"
"; Domain=example.com"
"; Path=/xxx"
"; Secure",
);
cookie.expires = null;
checkCookie(
cookie,
"$name=$value"
"; Max-Age=567"
"; Domain=example.com"
"; Path=/xxx"
"; Secure");
cookie,
"$name=$value"
"; Max-Age=567"
"; Domain=example.com"
"; Path=/xxx"
"; Secure",
);
cookie.maxAge = null;
checkCookie(
cookie,
"$name=$value"
"; Domain=example.com"
"; Path=/xxx"
"; Secure");
cookie,
"$name=$value"
"; Domain=example.com"
"; Path=/xxx"
"; Secure",
);
cookie.domain = null;
checkCookie(
cookie,
"$name=$value"
"; Path=/xxx"
"; Secure");
cookie,
"$name=$value"
"; Path=/xxx"
"; Secure",
);
cookie.path = null;
checkCookie(
cookie,
"$name=$value"
"; Secure");
cookie,
"$name=$value"
"; Secure",
);
cookie.secure = false;
checkCookie(cookie, "$name=$value");
}
@@ -607,17 +662,22 @@ void testInvalidCookie() {
Expect.throws(() => new _Cookie.fromSetCookieValue("=xxx"));
Expect.throws(() => new _Cookie.fromSetCookieValue("xxx"));
Expect.throws(
() => new _Cookie.fromSetCookieValue("xxx=yyy; expires=12 jan 2013"));
() => new _Cookie.fromSetCookieValue("xxx=yyy; expires=12 jan 2013"),
);
Expect.throws(() => new _Cookie.fromSetCookieValue("x x = y y"));
Expect.throws(() => new _Cookie("[4", "y"));
Expect.throws(() => new _Cookie("4", "y\""));
_HttpHeaders headers = new _HttpHeaders("1.1");
headers.set(
'Cookie', 'DARTSESSID=d3d6fdd78d51aaaf2924c32e991f4349; undefined');
'Cookie',
'DARTSESSID=d3d6fdd78d51aaaf2924c32e991f4349; undefined',
);
Expect.equals('DARTSESSID', headers.test$_parseCookies().single.name);
Expect.equals('d3d6fdd78d51aaaf2924c32e991f4349',
headers.test$_parseCookies().single.value);
Expect.equals(
'd3d6fdd78d51aaaf2924c32e991f4349',
headers.test$_parseCookies().single.value,
);
}
void testHeaderLists() {
+7 -6
View File
@@ -32,12 +32,13 @@ void testHttpIPv6() {
.openUrl('GET', url)
.then((request) => request.close())
.then((response) {
Expect.equals(response.statusCode, HttpStatus.ok);
}).whenComplete(() {
server.close();
client.close();
asyncEnd();
});
Expect.equals(response.statusCode, HttpStatus.ok);
})
.whenComplete(() {
server.close();
client.close();
asyncEnd();
});
});
}
+15 -15
View File
@@ -16,12 +16,12 @@ Future getData(HttpClient client, int port, bool chunked, int length) {
.get("127.0.0.1", port, "/?chunked=$chunked&length=$length")
.then((request) => request.close())
.then((response) {
return response
.fold<int>(0, (bytes, data) => bytes + data.length)
.then((bytes) {
Expect.equals(length, bytes);
});
});
return response.fold<int>(0, (bytes, data) => bytes + data.length).then(
(bytes) {
Expect.equals(length, bytes);
},
);
});
}
Future<HttpServer> startServer() {
@@ -48,9 +48,9 @@ testKeepAliveNonChunked() {
.then((_) => getData(client, server.port, false, 100))
.then((_) => getData(client, server.port, false, 100))
.then((_) {
server.close();
client.close();
});
server.close();
client.close();
});
});
}
@@ -64,9 +64,9 @@ testKeepAliveChunked() {
.then((_) => getData(client, server.port, true, 100))
.then((_) => getData(client, server.port, true, 100))
.then((_) {
server.close();
client.close();
});
server.close();
client.close();
});
});
}
@@ -83,9 +83,9 @@ testKeepAliveMixed() {
.then((_) => getData(client, server.port, true, 100))
.then((_) => getData(client, server.port, false, 100))
.then((_) {
server.close();
client.close();
});
server.close();
client.close();
});
});
}
+10 -6
View File
@@ -22,8 +22,10 @@ String localFile(path) => Platform.script.resolve(path).toFilePath();
SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
..usePrivateKey(
localFile('certificates/server_key.pem'),
password: 'dartdart',
);
Future<HttpServer> startEchoServer() {
return HttpServer.bindSecure(HOST, 0, serverContext).then((server) {
@@ -45,8 +47,9 @@ testSuccess(HttpServer server) async {
client.keyLog = (String line) {
log += line;
};
final request =
await client.getUrl(Uri.parse('https://localhost:${server.port}/test'));
final request = await client.getUrl(
Uri.parse('https://localhost:${server.port}/test'),
);
final response = await request.close();
await response.drain();
@@ -63,8 +66,9 @@ testExceptionInKeyLogFunction(HttpServer server) async {
++numCalls;
throw FileSystemException("Something bad happened");
};
final request =
await client.getUrl(Uri.parse('https://localhost:${server.port}/test'));
final request = await client.getUrl(
Uri.parse('https://localhost:${server.port}/test'),
);
final response = await request.close();
await response.drain();
@@ -26,12 +26,15 @@ void main() {
HttpServer.bind(ipv6, 0).then((server) {
server.listen((request) {
var timer = new Timer.periodic(const Duration(milliseconds: 0), (_) {
request.response
.write('data:${new DateTime.now().millisecondsSinceEpoch}\n\n');
request.response.write(
'data:${new DateTime.now().millisecondsSinceEpoch}\n\n',
);
});
request.response.done.whenComplete(() {
timer.cancel();
}).catchError((_) {});
request.response.done
.whenComplete(() {
timer.cancel();
})
.catchError((_) {});
});
var client = new HttpClient();
@@ -39,18 +42,22 @@ void main() {
.getUrl(Uri.parse("http://[${ipv6}]:${server.port}"))
.then((request) => request.close())
.then((response) {
print(
'response: status code: ${response.statusCode}, reason: ${response.reasonPhrase}');
int bytes = 0;
response.listen((data) {
bytes += data.length;
if (bytes > 100) {
client.close(force: true);
}
}, onError: (error) {
server.close();
});
});
print(
'response: status code: ${response.statusCode}, reason: ${response.reasonPhrase}',
);
int bytes = 0;
response.listen(
(data) {
bytes += data.length;
if (bytes > 100) {
client.close(force: true);
}
},
onError: (error) {
server.close();
},
);
});
asyncEnd();
});
} catch (e) {
+7 -3
View File
@@ -23,7 +23,9 @@ makeListener([List<int>? remotePorts]) {
/// Verify that you can't connect to loopback via mismatching protocol, e.g.
/// if the server is listening to IPv4 then you can't connect via IPv6.
Future<void> failureTest(
InternetAddress serverAddr, InternetAddress clientAddr) async {
InternetAddress serverAddr,
InternetAddress clientAddr,
) async {
final remotePorts = <int>[];
final server = await RawServerSocket.bind(serverAddr, 0);
server.listen(makeListener(remotePorts));
@@ -48,8 +50,10 @@ Future<void> failureTest(
} catch (e) {
Expect.fail('Unexpected exception: $e');
} finally {
Expect.isTrue(success,
'Unexpected connection to $serverAddr via $clientAddr address!');
Expect.isTrue(
success,
'Unexpected connection to $serverAddr via $clientAddr address!',
);
await server.close();
}
}
@@ -29,10 +29,11 @@ void missingReasonPhrase(int statusCode, bool includeSpace) {
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/"))
.then((request) => request.close())
.then((response) {
Expect.equals(statusCode, response.statusCode);
Expect.equals("", response.reasonPhrase);
return response.drain();
}).whenComplete(() => server.close());
Expect.equals(statusCode, response.statusCode);
Expect.equals("", response.reasonPhrase);
return response.drain();
})
.whenComplete(() => server.close());
});
}
@@ -13,17 +13,23 @@ Future testHttpServer(String name) async {
var address = InternetAddress('$sockname', type: InternetAddressType.unix);
var httpServer = await HttpServer.bind(address, 0);
var sub;
sub = httpServer.listen((HttpRequest request) {
request.response.write('Hello, world!');
request.response.close();
sub.cancel();
}, onDone: () {
httpServer.close();
});
sub = httpServer.listen(
(HttpRequest request) {
request.response.write('Hello, world!');
request.response.close();
sub.cancel();
},
onDone: () {
httpServer.close();
},
);
var option = "--unix-socket $sockname";
var result =
await Process.run("curl", ["--unix-socket", "$sockname", "localhost"]);
var result = await Process.run("curl", [
"--unix-socket",
"$sockname",
"localhost",
]);
Expect.isTrue(result.stdout.toString().contains('Hello, world!'));
}
@@ -8,11 +8,14 @@ import "dart:io";
import "package:expect/expect.dart";
void testInvalidArgumentException(String method) {
Expect.throws(() => HttpClient()..open(method, "127.0.0.1", 8080, "/"),
(e) => e is ArgumentError);
Expect.throws(
() => HttpClient()..openUrl(method, Uri.parse("http://127.0.0.1/")),
(e) => e is ArgumentError);
() => HttpClient()..open(method, "127.0.0.1", 8080, "/"),
(e) => e is ArgumentError,
);
Expect.throws(
() => HttpClient()..openUrl(method, Uri.parse("http://127.0.0.1/")),
(e) => e is ArgumentError,
);
}
main() {
@@ -33,19 +33,25 @@ void testChunkedBufferSizeMsg() {
request.response.close();
});
var client = new HttpClient();
client.get('127.0.0.1', server.port, '/').then((request) {
request.headers.set(HttpHeaders.acceptEncodingHeader, "");
return request.close();
}).then((response) {
var buffer = [];
response.listen((data) => buffer.addAll(data), onDone: () {
Expect.equals(sendData.length * 8, buffer.length);
for (int i = 0; i < buffer.length; i++) {
Expect.equals(sendData[i % sendData.length], buffer[i]);
}
server.close();
});
});
client
.get('127.0.0.1', server.port, '/')
.then((request) {
request.headers.set(HttpHeaders.acceptEncodingHeader, "");
return request.close();
})
.then((response) {
var buffer = [];
response.listen(
(data) => buffer.addAll(data),
onDone: () {
Expect.equals(sendData.length * 8, buffer.length);
for (int i = 0; i < buffer.length; i++) {
Expect.equals(sendData[i % sendData.length], buffer[i]);
}
server.close();
},
);
});
});
}
+54 -20
View File
@@ -19,8 +19,11 @@ class MyHttpClient1 implements HttpClient {
bool enableTimelineLogging = false;
Future<HttpClientRequest> open(
String method, String host, int port, String path) =>
throw "";
String method,
String host,
int port,
String path,
) => throw "";
Future<HttpClientRequest> openUrl(String method, Uri url) => throw "";
Future<HttpClientRequest> get(String host, int port, String path) => throw "";
Future<HttpClientRequest> getUrl(Uri url) => throw "";
@@ -40,18 +43,31 @@ class MyHttpClient1 implements HttpClient {
Future<HttpClientRequest> headUrl(Uri url) => throw "";
set authenticate(Future<bool> f(Uri url, String scheme, String realm)?) {}
void addCredentials(
Uri url, String realm, HttpClientCredentials credentials) {}
Uri url,
String realm,
HttpClientCredentials credentials,
) {}
set connectionFactory(
Future<ConnectionTask<Socket>> Function(
Uri url, String? proxyHost, int? proxyPort)?
f) {}
Future<ConnectionTask<Socket>> Function(
Uri url,
String? proxyHost,
int? proxyPort,
)?
f,
) {}
set findProxy(String f(Uri url)?) {}
set authenticateProxy(
Future<bool> f(String host, int port, String scheme, String realm)?) {}
Future<bool> f(String host, int port, String scheme, String realm)?,
) {}
void addProxyCredentials(
String host, int port, String realm, HttpClientCredentials credentials) {}
String host,
int port,
String realm,
HttpClientCredentials credentials,
) {}
set badCertificateCallback(
bool callback(X509Certificate cert, String host, int port)?) {}
bool callback(X509Certificate cert, String host, int port)?,
) {}
void set keyLog(Function(String line)? callback) {}
void close({bool force = false}) {}
}
@@ -68,8 +84,11 @@ class MyHttpClient2 implements HttpClient {
bool enableTimelineLogging = false;
Future<HttpClientRequest> open(
String method, String host, int port, String path) =>
throw "";
String method,
String host,
int port,
String path,
) => throw "";
Future<HttpClientRequest> openUrl(String method, Uri url) => throw "";
Future<HttpClientRequest> get(String host, int port, String path) => throw "";
Future<HttpClientRequest> getUrl(Uri url) => throw "";
@@ -89,18 +108,31 @@ class MyHttpClient2 implements HttpClient {
Future<HttpClientRequest> headUrl(Uri url) => throw "";
set authenticate(Future<bool> f(Uri url, String scheme, String realm)?) {}
void addCredentials(
Uri url, String realm, HttpClientCredentials credentials) {}
Uri url,
String realm,
HttpClientCredentials credentials,
) {}
set connectionFactory(
Future<ConnectionTask<Socket>> Function(
Uri url, String? proxyHost, int? proxyPort)?
f) {}
Future<ConnectionTask<Socket>> Function(
Uri url,
String? proxyHost,
int? proxyPort,
)?
f,
) {}
set findProxy(String f(Uri url)?) {}
set authenticateProxy(
Future<bool> f(String host, int port, String scheme, String realm)?) {}
Future<bool> f(String host, int port, String scheme, String realm)?,
) {}
void addProxyCredentials(
String host, int port, String realm, HttpClientCredentials credentials) {}
String host,
int port,
String realm,
HttpClientCredentials credentials,
) {}
set badCertificateCallback(
bool callback(X509Certificate cert, String host, int port)?) {}
bool callback(X509Certificate cert, String host, int port)?,
) {}
void set keyLog(Function(String line)? callback) {}
void close({bool force = false}) {}
}
@@ -170,8 +202,10 @@ nestedDifferentOverridesTest() {
Expect.isNotNull(httpClient);
Expect.isTrue(httpClient is MyHttpClient1);
Expect.equals((new MyHttpClient1(null)).userAgent, httpClient.userAgent);
Expect.equals(myFindProxyFromEnvironment(new Uri(), null),
HttpClient.findProxyFromEnvironment(new Uri()));
Expect.equals(
myFindProxyFromEnvironment(new Uri(), null),
HttpClient.findProxyFromEnvironment(new Uri()),
);
}, findProxyFromEnvironment: myFindProxyFromEnvironment);
httpClient = new HttpClient();
Expect.isNotNull(httpClient);
@@ -23,24 +23,25 @@ Future<void> test(String header, value) async {
client
.open(connect, "127.0.0.1", server.port, "/")
.then((HttpClientRequest request) {
return request.close();
}).then((HttpClientResponse response) {
Expect.equals(200, response.statusCode);
// Headers except Content-Length and Transfer-Encoding header will be read.
if (header == HttpHeaders.contentLengthHeader ||
header == HttpHeaders.transferEncodingHeader) {
Expect.isNull(response.headers[header]);
} else {
final list = response.headers[header];
Expect.isNotNull(list);
Expect.equals(1, list!.length);
Expect.equals(value, list[0]);
}
return request.close();
})
.then((HttpClientResponse response) {
Expect.equals(200, response.statusCode);
// Headers except Content-Length and Transfer-Encoding header will be read.
if (header == HttpHeaders.contentLengthHeader ||
header == HttpHeaders.transferEncodingHeader) {
Expect.isNull(response.headers[header]);
} else {
final list = response.headers[header];
Expect.isNotNull(list);
Expect.equals(1, list!.length);
Expect.equals(value, list[0]);
}
client.close(force: true);
server.close();
completer.complete();
});
client.close(force: true);
server.close();
completer.complete();
});
await completer.future;
}
@@ -25,7 +25,8 @@ Future<void> testFormatException() async {
final client = HttpClient()..userAgent = 'Bobs browser';
try {
await asyncExpectThrows<FormatException>(
client.open("CONNECT", "127.0.0.1", server.port, "/"));
client.open("CONNECT", "127.0.0.1", server.port, "/"),
);
} finally {
client.close(force: true);
server.close();
+230 -160
View File
@@ -18,8 +18,10 @@ String localFile(path) => Platform.script.resolve(path).toFilePath();
final SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
..usePrivateKey(
localFile('certificates/server_key.pem'),
password: 'dartdart',
);
final SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(localFile('certificates/trusted_certs.pem'));
@@ -38,10 +40,10 @@ class Server {
? HttpServer.bindSecure("localhost", 0, serverContext)
: HttpServer.bind("localhost", 0))
.then((s) {
server = s;
server.listen(requestHandler);
return this;
});
server = s;
server.listen(requestHandler);
return this;
});
}
void requestHandler(HttpRequest request) {
@@ -49,12 +51,16 @@ class Server {
requestCount++;
// Check whether a proxy or direct connection is expected.
bool direct = directRequestPaths.fold(
false, (prev, path) => prev ? prev : path == request.uri.path);
false,
(prev, path) => prev ? prev : path == request.uri.path,
);
if (!secure && !direct && proxyHops > 0) {
Expect.isNotNull(request.headers[HttpHeaders.viaHeader]);
Expect.equals(1, request.headers[HttpHeaders.viaHeader]!.length);
Expect.equals(proxyHops,
request.headers[HttpHeaders.viaHeader]![0].split(",").length);
Expect.equals(
proxyHops,
request.headers[HttpHeaders.viaHeader]![0].split(",").length,
);
} else {
Expect.isNull(request.headers[HttpHeaders.viaHeader]);
}
@@ -81,8 +87,11 @@ class Server {
int get port => server.port;
}
Future<Server> setupServer(int proxyHops,
{List<String> directRequestPaths = const <String>[], secure = false}) {
Future<Server> setupServer(
int proxyHops, {
List<String> directRequestPaths = const <String>[],
secure = false,
}) {
Server server = new Server(proxyHops, directRequestPaths, secure);
return server.start();
}
@@ -125,8 +134,10 @@ class ProxyServer {
basicAuthenticationRequired(request) {
request.fold(null, (x, y) {}).then((_) {
var response = request.response;
response.headers
.set(HttpHeaders.proxyAuthenticateHeader, "Basic, realm=$realm");
response.headers.set(
HttpHeaders.proxyAuthenticateHeader,
"Basic, realm=$realm",
);
response.statusCode = HttpStatus.proxyAuthenticationRequired;
response.close();
});
@@ -167,8 +178,10 @@ class ProxyServer {
}
return;
} else {
Expect.equals(1,
request.headers[HttpHeaders.proxyAuthorizationHeader]!.length);
Expect.equals(
1,
request.headers[HttpHeaders.proxyAuthorizationHeader]!.length,
);
String authorization =
request.headers[HttpHeaders.proxyAuthorizationHeader]![0];
if (authScheme == "Basic") {
@@ -180,8 +193,10 @@ class ProxyServer {
return;
}
} else {
HeaderValue header =
HeaderValue.parse(authorization, parameterSeparator: ",");
HeaderValue header = HeaderValue.parse(
authorization,
parameterSeparator: ",",
);
Expect.equals("Digest", header.value);
var uri = header.parameters["uri"];
var qop = header.parameters["qop"];
@@ -214,13 +229,17 @@ class ProxyServer {
digest = md5.convert("$ha1:${nonce}:$ha2".codeUnits);
} else {
digest = md5.convert(
"$ha1:${nonce}:${nc}:${cnonce}:${qop}:$ha2".codeUnits);
"$ha1:${nonce}:${nc}:${cnonce}:${qop}:$ha2".codeUnits,
);
}
Expect.equals(
hex.encode(digest.bytes), header.parameters["response"]);
hex.encode(digest.bytes),
header.parameters["response"],
);
// Add a bogus Proxy-Authentication-Info for testing.
var info = 'rspauth="77180d1ab3d6c9de084766977790f482", '
var info =
'rspauth="77180d1ab3d6c9de084766977790f482", '
'cnonce="8f971178", '
'nc=000002c74, '
'qop=auth';
@@ -242,27 +261,30 @@ class ProxyServer {
client
.openUrl(request.method, request.uri)
.then((HttpClientRequest clientRequest) {
// Forward all headers.
request.headers.forEach((String name, List<String> values) {
values.forEach((String value) {
if (name != "content-length" && name != "via") {
clientRequest.headers.add(name, value);
}
// Forward all headers.
request.headers.forEach((String name, List<String> values) {
values.forEach((String value) {
if (name != "content-length" && name != "via") {
clientRequest.headers.add(name, value);
}
});
});
// Special handling of Content-Length and Via.
clientRequest.contentLength = request.contentLength;
List<String>? via = request.headers[HttpHeaders.viaHeader];
String viaPrefix = via == null ? "" : "${via[0]}, ";
clientRequest.headers.add(
HttpHeaders.viaHeader,
"${viaPrefix}1.1 localhost:$port",
);
// Copy all content.
return request.cast<List<int>>().pipe(clientRequest);
})
.then((clientResponse) {
(clientResponse as HttpClientResponse).cast<List<int>>().pipe(
request.response,
);
});
});
// Special handling of Content-Length and Via.
clientRequest.contentLength = request.contentLength;
List<String>? via = request.headers[HttpHeaders.viaHeader];
String viaPrefix = via == null ? "" : "${via[0]}, ";
clientRequest.headers
.add(HttpHeaders.viaHeader, "${viaPrefix}1.1 localhost:$port");
// Copy all content.
return request.cast<List<int>>().pipe(clientRequest);
}).then((clientResponse) {
(clientResponse as HttpClientResponse)
.cast<List<int>>()
.pipe(request.response);
});
}
});
});
@@ -286,8 +308,9 @@ int testProxyIPV6DoneCount = 0;
void testProxyIPV6() {
setupProxyServer(ipV6: true).then((proxyServer) {
setupServer(1, directRequestPaths: ["/4"]).then((server) {
setupServer(1, directRequestPaths: ["/4"], secure: true)
.then((secureServer) {
setupServer(1, directRequestPaths: ["/4"], secure: true).then((
secureServer,
) {
HttpClient client = new HttpClient(context: clientContext);
List<String> proxy = ["PROXY [::1]:${proxyServer.port}"];
@@ -306,22 +329,26 @@ void testProxyIPV6() {
client
.postUrl(Uri.parse(url))
.then((HttpClientRequest clientRequest) {
String content = "$i$i$i";
clientRequest.write(content);
return clientRequest.close();
}).then((HttpClientResponse response) {
response.listen((_) {}, onDone: () {
testProxyIPV6DoneCount++;
if (testProxyIPV6DoneCount == proxy.length * 2) {
Expect.equals(proxy.length, server.requestCount);
Expect.equals(proxy.length, secureServer.requestCount);
proxyServer.shutdown();
server.shutdown();
secureServer.shutdown();
client.close();
}
});
});
String content = "$i$i$i";
clientRequest.write(content);
return clientRequest.close();
})
.then((HttpClientResponse response) {
response.listen(
(_) {},
onDone: () {
testProxyIPV6DoneCount++;
if (testProxyIPV6DoneCount == proxy.length * 2) {
Expect.equals(proxy.length, server.requestCount);
Expect.equals(proxy.length, secureServer.requestCount);
proxyServer.shutdown();
server.shutdown();
secureServer.shutdown();
client.close();
}
},
);
});
}
test(false);
@@ -340,10 +367,13 @@ void testProxyFromEnvironment() {
HttpClient client = new HttpClient(context: clientContext);
client.findProxy = (Uri uri) {
return HttpClient.findProxyFromEnvironment(uri, environment: {
"http_proxy": "localhost:${proxyServer.port}",
"https_proxy": "localhost:${proxyServer.port}"
});
return HttpClient.findProxyFromEnvironment(
uri,
environment: {
"http_proxy": "localhost:${proxyServer.port}",
"https_proxy": "localhost:${proxyServer.port}",
},
);
};
const int loopCount = 5;
@@ -356,22 +386,26 @@ void testProxyFromEnvironment() {
client
.postUrl(Uri.parse(url))
.then((HttpClientRequest clientRequest) {
String content = "$i$i$i";
clientRequest.write(content);
return clientRequest.close();
}).then((HttpClientResponse response) {
response.listen((_) {}, onDone: () {
testProxyFromEnvironmentDoneCount++;
if (testProxyFromEnvironmentDoneCount == loopCount * 2) {
Expect.equals(loopCount, server.requestCount);
Expect.equals(loopCount, secureServer.requestCount);
proxyServer.shutdown();
server.shutdown();
secureServer.shutdown();
client.close();
}
});
});
String content = "$i$i$i";
clientRequest.write(content);
return clientRequest.close();
})
.then((HttpClientResponse response) {
response.listen(
(_) {},
onDone: () {
testProxyFromEnvironmentDoneCount++;
if (testProxyFromEnvironmentDoneCount == loopCount * 2) {
Expect.equals(loopCount, server.requestCount);
Expect.equals(loopCount, secureServer.requestCount);
proxyServer.shutdown();
server.shutdown();
secureServer.shutdown();
client.close();
}
},
);
});
}
test(false);
@@ -384,7 +418,10 @@ void testProxyFromEnvironment() {
int testProxyAuthenticateCount = 0;
Future testProxyAuthenticate(
bool useDigestAuthentication, String username, String password) {
bool useDigestAuthentication,
String username,
String password,
) {
testProxyAuthenticateCount = 0;
var completer = new Completer();
@@ -417,19 +454,21 @@ Future testProxyAuthenticate(
client
.postUrl(Uri.parse(url))
.then((HttpClientRequest clientRequest) {
String content = "$i$i$i";
clientRequest.write(content);
return clientRequest.close();
}).then((HttpClientResponse response) {
Expect.fail("No response expected");
}).catchError((e) {
testProxyAuthenticateCount++;
if (testProxyAuthenticateCount == loopCount * 2) {
Expect.equals(0, server.requestCount);
Expect.equals(0, secureServer.requestCount);
step1.complete(null);
}
});
String content = "$i$i$i";
clientRequest.write(content);
return clientRequest.close();
})
.then((HttpClientResponse response) {
Expect.fail("No response expected");
})
.catchError((e) {
testProxyAuthenticateCount++;
if (testProxyAuthenticateCount == loopCount * 2) {
Expect.equals(0, server.requestCount);
Expect.equals(0, secureServer.requestCount);
step1.complete(null);
}
});
}
test(false);
@@ -438,10 +477,14 @@ Future testProxyAuthenticate(
step1.future.then((_) {
testProxyAuthenticateCount = 0;
if (useDigestAuthentication) {
client.findProxy =
(Uri uri) => "PROXY localhost:${proxyServer.port}";
client.addProxyCredentials("localhost", proxyServer.port, "test",
new HttpClientDigestCredentials(username, password));
client.findProxy = (Uri uri) =>
"PROXY localhost:${proxyServer.port}";
client.addProxyCredentials(
"localhost",
proxyServer.port,
"test",
new HttpClientDigestCredentials(username, password),
);
} else {
client.findProxy = (Uri uri) {
return "PROXY ${username}:${password}@localhost:${proxyServer.port}";
@@ -458,20 +501,24 @@ Future testProxyAuthenticate(
client
.postUrl(Uri.parse(url))
.then((HttpClientRequest clientRequest) {
String content = "$i$i$i";
clientRequest.write(content);
return clientRequest.close();
}).then((HttpClientResponse response) {
response.listen((_) {}, onDone: () {
testProxyAuthenticateCount++;
Expect.equals(HttpStatus.ok, response.statusCode);
if (testProxyAuthenticateCount == loopCount * 2) {
Expect.equals(loopCount, server.requestCount);
Expect.equals(loopCount, secureServer.requestCount);
step2.complete(null);
}
});
});
String content = "$i$i$i";
clientRequest.write(content);
return clientRequest.close();
})
.then((HttpClientResponse response) {
response.listen(
(_) {},
onDone: () {
testProxyAuthenticateCount++;
Expect.equals(HttpStatus.ok, response.statusCode);
if (testProxyAuthenticateCount == loopCount * 2) {
Expect.equals(loopCount, server.requestCount);
Expect.equals(loopCount, secureServer.requestCount);
step2.complete(null);
}
},
);
});
}
test(false);
@@ -486,8 +533,12 @@ Future testProxyAuthenticate(
};
client.authenticateProxy = (host, port, scheme, realm) {
client.addProxyCredentials("localhost", proxyServer.port, "realm",
new HttpClientBasicCredentials(username, password));
client.addProxyCredentials(
"localhost",
proxyServer.port,
"realm",
new HttpClientBasicCredentials(username, password),
);
return new Future.value(true);
};
@@ -500,24 +551,31 @@ Future testProxyAuthenticate(
client
.postUrl(Uri.parse(url))
.then((HttpClientRequest clientRequest) {
String content = "$i$i$i";
clientRequest.write(content);
return clientRequest.close();
}).then((HttpClientResponse response) {
response.listen((_) {}, onDone: () {
testProxyAuthenticateCount++;
Expect.equals(HttpStatus.ok, response.statusCode);
if (testProxyAuthenticateCount == loopCount * 2) {
Expect.equals(loopCount * 2, server.requestCount);
Expect.equals(loopCount * 2, secureServer.requestCount);
proxyServer.shutdown();
server.shutdown();
secureServer.shutdown();
client.close();
completer.complete(null);
}
});
});
String content = "$i$i$i";
clientRequest.write(content);
return clientRequest.close();
})
.then((HttpClientResponse response) {
response.listen(
(_) {},
onDone: () {
testProxyAuthenticateCount++;
Expect.equals(HttpStatus.ok, response.statusCode);
if (testProxyAuthenticateCount == loopCount * 2) {
Expect.equals(loopCount * 2, server.requestCount);
Expect.equals(
loopCount * 2,
secureServer.requestCount,
);
proxyServer.shutdown();
server.shutdown();
secureServer.shutdown();
client.close();
completer.complete(null);
}
},
);
});
}
test(false);
@@ -535,14 +593,18 @@ int testRealProxyDoneCount = 0;
void testRealProxy() {
setupServer(1).then((server) {
HttpClient client = new HttpClient(context: clientContext);
client.addProxyCredentials("localhost", 8080, "test",
new HttpClientBasicCredentials("dart", "password"));
client.addProxyCredentials(
"localhost",
8080,
"test",
new HttpClientBasicCredentials("dart", "password"),
);
List<String> proxy = [
"PROXY localhost:8080",
"PROXY localhost:8080; PROXY hede.hule.hest:8080",
"PROXY hede.hule.hest:8080; PROXY localhost:8080",
"PROXY localhost:8080; DIRECT"
"PROXY localhost:8080; DIRECT",
];
client.findProxy = (Uri uri) {
@@ -555,19 +617,23 @@ void testRealProxy() {
client
.getUrl(Uri.parse("http://localhost:${server.port}/$i"))
.then((HttpClientRequest clientRequest) {
String content = "$i$i$i";
clientRequest.contentLength = content.length;
clientRequest.write(content);
return clientRequest.close();
}).then((HttpClientResponse response) {
response.listen((_) {}, onDone: () {
if (++testRealProxyDoneCount == proxy.length) {
Expect.equals(proxy.length, server.requestCount);
server.shutdown();
client.close();
}
});
});
String content = "$i$i$i";
clientRequest.contentLength = content.length;
clientRequest.write(content);
return clientRequest.close();
})
.then((HttpClientResponse response) {
response.listen(
(_) {},
onDone: () {
if (++testRealProxyDoneCount == proxy.length) {
Expect.equals(proxy.length, server.requestCount);
server.shutdown();
client.close();
}
},
);
});
}
});
}
@@ -581,7 +647,7 @@ void testRealProxyAuth() {
"PROXY dart:password@localhost:8080",
"PROXY dart:password@localhost:8080; PROXY hede.hule.hest:8080",
"PROXY hede.hule.hest:8080; PROXY dart:password@localhost:8080",
"PROXY dart:password@localhost:8080; DIRECT"
"PROXY dart:password@localhost:8080; DIRECT",
];
client.findProxy = (Uri uri) {
@@ -594,19 +660,23 @@ void testRealProxyAuth() {
client
.getUrl(Uri.parse("http://localhost:${server.port}/$i"))
.then((HttpClientRequest clientRequest) {
String content = "$i$i$i";
clientRequest.contentLength = content.length;
clientRequest.write(content);
return clientRequest.close();
}).then((HttpClientResponse response) {
response.listen((_) {}, onDone: () {
if (++testRealProxyAuthDoneCount == proxy.length) {
Expect.equals(proxy.length, server.requestCount);
server.shutdown();
client.close();
}
});
});
String content = "$i$i$i";
clientRequest.contentLength = content.length;
clientRequest.write(content);
return clientRequest.close();
})
.then((HttpClientResponse response) {
response.listen(
(_) {},
onDone: () {
if (++testRealProxyAuthDoneCount == proxy.length) {
Expect.equals(proxy.length, server.requestCount);
server.shutdown();
client.close();
}
},
);
});
}
});
}
@@ -7,16 +7,22 @@ import "package:expect/expect.dart";
expect(expected, String uri, environment) {
Expect.equals(
expected,
HttpClient.findProxyFromEnvironment(Uri.parse(uri),
environment: environment));
expected,
HttpClient.findProxyFromEnvironment(
Uri.parse(uri),
environment: environment,
),
);
}
expectDirect(String uri, Map<String, String> environment) {
Expect.equals(
"DIRECT",
HttpClient.findProxyFromEnvironment(Uri.parse(uri),
environment: environment));
"DIRECT",
HttpClient.findProxyFromEnvironment(
Uri.parse(uri),
environment: environment,
),
);
}
main() {
@@ -24,111 +30,143 @@ main() {
expectDirect("http://www.google.com", {"http_proxy": ""});
expectDirect("http://www.google.com", {"http_proxy": " "});
expect("PROXY www.proxy.com:1080", "http://www.google.com",
{"http_proxy": "www.proxy.com"});
expect("PROXY www.proxys.com:1080", "https://www.google.com",
{"https_proxy": "www.proxys.com"});
expect("PROXY www.proxy.com:8080", "http://www.google.com",
{"http_proxy": "www.proxy.com:8080"});
expect("PROXY www.proxys.com:8080", "https://www.google.com",
{"https_proxy": "www.proxys.com:8080"});
expect("PROXY www.proxy.com:1080", "http://www.google.com", {
"http_proxy": "www.proxy.com",
});
expect("PROXY www.proxys.com:1080", "https://www.google.com", {
"https_proxy": "www.proxys.com",
});
expect("PROXY www.proxy.com:8080", "http://www.google.com", {
"http_proxy": "www.proxy.com:8080",
"https_proxy": "www.proxys.com:8080"
});
expect("PROXY www.proxys.com:8080", "https://www.google.com", {
"https_proxy": "www.proxys.com:8080",
});
expect("PROXY www.proxy.com:8080", "http://www.google.com", {
"http_proxy": "www.proxy.com:8080",
"https_proxy": "www.proxys.com:8080",
});
expect("PROXY www.proxys.com:8080", "https://www.google.com", {
"http_proxy": "www.proxy.com:8080",
"https_proxy": "www.proxys.com:8080"
"https_proxy": "www.proxys.com:8080",
});
expect("PROXY [::ffff:1]:1080", "http://www.google.com",
{"http_proxy": "[::ffff:1]"});
expect("PROXY [::ffff:2]:1080", "https://www.google.com",
{"https_proxy": "[::ffff:2]"});
expect("PROXY [::ffff:1]:8080", "http://www.google.com",
{"http_proxy": "[::ffff:1]:8080"});
expect("PROXY [::ffff:2]:8080", "https://www.google.com",
{"https_proxy": "[::ffff:2]:8080"});
expect("PROXY [::ffff:1]:8080", "http://www.google.com",
{"http_proxy": "[::ffff:1]:8080", "https_proxy": "[::ffff:2]:8080"});
expect("PROXY [::ffff:2]:8080", "https://www.google.com",
{"http_proxy": "[::ffff:1]:8080", "https_proxy": "[::ffff:2]:8080"});
expect("PROXY www.proxy.com:1080", "http://www.google.com",
{"http_proxy": "http://www.proxy.com"});
expect("PROXY www.proxy.com:1080", "http://www.google.com",
{"http_proxy": "http://www.proxy.com/"});
expect("PROXY www.proxy.com:8080", "http://www.google.com",
{"http_proxy": "http://www.proxy.com:8080/"});
expect("PROXY www.proxy.com:8080", "http://www.google.com",
{"http_proxy": "http://www.proxy.com:8080/index.html"});
expect("PROXY www.proxy.com:8080", "http://www.google.com", {
"http_proxy": "http://www.proxy.com:8080/",
"https_proxy": "http://www.proxys.com:8080/"
expect("PROXY [::ffff:1]:1080", "http://www.google.com", {
"http_proxy": "[::ffff:1]",
});
expect("PROXY www.proxys.com:8080", "https://www.google.com", {
"http_proxy": "http://www.proxy.com:8080/",
"https_proxy": "http://www.proxys.com:8080/"
expect("PROXY [::ffff:2]:1080", "https://www.google.com", {
"https_proxy": "[::ffff:2]",
});
expect("PROXY [::ffff:1]:8080", "http://www.google.com", {
"http_proxy": "[::ffff:1]:8080",
});
expect("PROXY [::ffff:2]:8080", "https://www.google.com", {
"https_proxy": "[::ffff:2]:8080",
});
expect("PROXY [::ffff:1]:8080", "http://www.google.com", {
"http_proxy": "[::ffff:1]:8080",
"https_proxy": "[::ffff:2]:8080",
});
expect("PROXY [::ffff:2]:8080", "https://www.google.com", {
"http_proxy": "[::ffff:1]:8080",
"https_proxy": "[::ffff:2]:8080",
});
expect("PROXY www.proxy.com:1080", "http://www.google.com", {
"http_proxy": "http://www.proxy.com",
});
expect("PROXY www.proxy.com:1080", "http://www.google.com", {
"http_proxy": "http://www.proxy.com/",
});
expect("PROXY www.proxy.com:8080", "http://www.google.com", {
"http_proxy": "http://www.proxy.com:8080/",
"https_proxy": "http://www.proxys.com:8080/index.html"
});
expect("PROXY www.proxy.com:8080", "http://www.google.com", {
"http_proxy": "http://www.proxy.com:8080/index.html",
});
expect("PROXY www.proxy.com:8080", "http://www.google.com", {
"http_proxy": "http://www.proxy.com:8080/",
"https_proxy": "http://www.proxys.com:8080/",
});
expect("PROXY www.proxys.com:8080", "https://www.google.com", {
"http_proxy": "http://www.proxy.com:8080/",
"https_proxy": "http://www.proxys.com:8080/index.html"
"https_proxy": "http://www.proxys.com:8080/",
});
expect("PROXY www.proxy.com:8080", "http://www.google.com", {
"http_proxy": "http://www.proxy.com:8080/",
"https_proxy": "http://www.proxys.com:8080/index.html",
});
expect("PROXY www.proxys.com:8080", "https://www.google.com", {
"http_proxy": "http://www.proxy.com:8080/",
"https_proxy": "http://www.proxys.com:8080/index.html",
});
expect("PROXY [::ffff:1]:1080", "http://www.google.com",
{"http_proxy": "http://[::ffff:1]"});
expect("PROXY [::ffff:1]:1080", "http://www.google.com",
{"http_proxy": "http://[::ffff:1]/"});
expect("PROXY [::ffff:1]:8080", "http://www.google.com",
{"http_proxy": "http://[::ffff:1]:8080/"});
expect("PROXY [::ffff:1]:8080", "http://www.google.com",
{"http_proxy": "http://[::ffff:1]:8080/index.html"});
expect("PROXY [::ffff:1]:8080", "http://www.google.com", {
"http_proxy": "http://[::ffff:1]:8080/",
"https_proxy": "http://[::ffff:1]:8080/"
expect("PROXY [::ffff:1]:1080", "http://www.google.com", {
"http_proxy": "http://[::ffff:1]",
});
expect("PROXY [::ffff:2]:8080", "https://www.google.com", {
"http_proxy": "http://[::ffff:1]:8080/",
"https_proxy": "http://[::ffff:2]:8080/"
expect("PROXY [::ffff:1]:1080", "http://www.google.com", {
"http_proxy": "http://[::ffff:1]/",
});
expect("PROXY [::ffff:1]:8080", "http://www.google.com", {
"http_proxy": "http://[::ffff:1]:8080/",
"https_proxy": "http://[::ffff:1]:8080/index.html"
});
expect("PROXY [::ffff:1]:8080", "http://www.google.com", {
"http_proxy": "http://[::ffff:1]:8080/index.html",
});
expect("PROXY [::ffff:1]:8080", "http://www.google.com", {
"http_proxy": "http://[::ffff:1]:8080/",
"https_proxy": "http://[::ffff:1]:8080/",
});
expect("PROXY [::ffff:2]:8080", "https://www.google.com", {
"http_proxy": "http://[::ffff:1]:8080/",
"https_proxy": "http://[::ffff:2]:8080/index.html"
"https_proxy": "http://[::ffff:2]:8080/",
});
expect("PROXY [::ffff:1]:8080", "http://www.google.com", {
"http_proxy": "http://[::ffff:1]:8080/",
"https_proxy": "http://[::ffff:1]:8080/index.html",
});
expect("PROXY [::ffff:2]:8080", "https://www.google.com", {
"http_proxy": "http://[::ffff:1]:8080/",
"https_proxy": "http://[::ffff:2]:8080/index.html",
});
expectDirect("http://www.google.com",
{"http_proxy": "www.proxy.com:8080", "no_proxy": "www.google.com"});
expectDirect("http://www.google.com",
{"http_proxy": "www.proxy.com:8080", "no_proxy": "google.com"});
expectDirect("http://www.google.com",
{"http_proxy": "www.proxy.com:8080", "no_proxy": ".com"});
expectDirect("http://www.google.com", {
"http_proxy": "www.proxy.com:8080",
"no_proxy": ",, , www.google.edu,,.com "
"no_proxy": "www.google.com",
});
expectDirect("http://www.google.com", {
"http_proxy": "www.proxy.com:8080",
"no_proxy": "google.com",
});
expectDirect("http://www.google.com", {
"http_proxy": "www.proxy.com:8080",
"no_proxy": ".com",
});
expectDirect("http://www.google.com", {
"http_proxy": "www.proxy.com:8080",
"no_proxy": ",, , www.google.edu,,.com ",
});
expectDirect("http://www.google.edu", {
"http_proxy": "www.proxy.com:8080",
"no_proxy": ",, , www.google.edu,,.com "
"no_proxy": ",, , www.google.edu,,.com ",
});
expectDirect("http://www.google.com", {"https_proxy": "www.proxy.com:8080"});
expect("PROXY www.proxy.com:8080", "http://[::ffff:1]",
{"http_proxy": "www.proxy.com:8080", "no_proxy": "["});
expect("PROXY www.proxy.com:8080", "http://[::ffff:1]",
{"http_proxy": "www.proxy.com:8080", "no_proxy": "[]"});
expect("PROXY www.proxy.com:8080", "http://[::ffff:1]", {
"http_proxy": "www.proxy.com:8080",
"no_proxy": "[",
});
expect("PROXY www.proxy.com:8080", "http://[::ffff:1]", {
"http_proxy": "www.proxy.com:8080",
"no_proxy": "[]",
});
expectDirect("http://[::ffff:1]",
{"http_proxy": "www.proxy.com:8080", "no_proxy": "[::ffff:1]"});
expectDirect("http://[::ffff:1]", {
"http_proxy": "www.proxy.com:8080",
"no_proxy": ",, , www.google.edu,,[::ffff:1] "
"no_proxy": "[::ffff:1]",
});
expectDirect("http://[::ffff:1]", {
"http_proxy": "www.proxy.com:8080",
"no_proxy": ",, , www.google.edu,,[::ffff:1] ",
});
}
+138 -103
View File
@@ -18,8 +18,10 @@ String localFile(path) => Platform.script.resolve(path).toFilePath();
final SecurityContext serverContext = new SecurityContext()
..useCertificateChain(localFile('certificates/server_chain.pem'))
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
..usePrivateKey(
localFile('certificates/server_key.pem'),
password: 'dartdart',
);
final SecurityContext clientContext = new SecurityContext()
..setTrustedCertificates(localFile('certificates/trusted_certs.pem'));
@@ -38,10 +40,10 @@ class Server {
? HttpServer.bindSecure("localhost", 0, serverContext)
: HttpServer.bind("localhost", 0))
.then((s) {
server = s;
server.listen(requestHandler);
return this;
});
server = s;
server.listen(requestHandler);
return this;
});
}
void requestHandler(HttpRequest request) {
@@ -49,12 +51,16 @@ class Server {
requestCount++;
// Check whether a proxy or direct connection is expected.
bool direct = directRequestPaths.fold(
false, (prev, path) => prev ? prev : path == request.uri.path);
false,
(prev, path) => prev ? prev : path == request.uri.path,
);
if (!secure && !direct && proxyHops > 0) {
Expect.isNotNull(request.headers[HttpHeaders.viaHeader]);
Expect.equals(1, request.headers[HttpHeaders.viaHeader]!.length);
Expect.equals(proxyHops,
request.headers[HttpHeaders.viaHeader]![0].split(",").length);
Expect.equals(
proxyHops,
request.headers[HttpHeaders.viaHeader]![0].split(",").length,
);
} else {
Expect.isNull(request.headers[HttpHeaders.viaHeader]);
}
@@ -81,8 +87,11 @@ class Server {
int get port => server.port;
}
Future<Server> setupServer(int proxyHops,
{List<String> directRequestPaths = const <String>[], secure = false}) {
Future<Server> setupServer(
int proxyHops, {
List<String> directRequestPaths = const <String>[],
secure = false,
}) {
Server server = new Server(proxyHops, directRequestPaths, secure);
return server.start();
}
@@ -115,8 +124,10 @@ class ProxyServer {
basicAuthenticationRequired(request) {
request.fold(null, (x, y) {}).then((_) {
var response = request.response;
response.headers
.set(HttpHeaders.proxyAuthenticateHeader, "Basic, realm=$realm");
response.headers.set(
HttpHeaders.proxyAuthenticateHeader,
"Basic, realm=$realm",
);
response.statusCode = HttpStatus.proxyAuthenticationRequired;
response.close();
});
@@ -157,8 +168,10 @@ class ProxyServer {
}
return;
} else {
Expect.equals(1,
request.headers[HttpHeaders.proxyAuthorizationHeader]!.length);
Expect.equals(
1,
request.headers[HttpHeaders.proxyAuthorizationHeader]!.length,
);
String authorization =
request.headers[HttpHeaders.proxyAuthorizationHeader]![0];
if (authScheme == "Basic") {
@@ -170,8 +183,10 @@ class ProxyServer {
return;
}
} else {
HeaderValue header =
HeaderValue.parse(authorization, parameterSeparator: ",");
HeaderValue header = HeaderValue.parse(
authorization,
parameterSeparator: ",",
);
Expect.equals("Digest", header.value);
var uri = header.parameters["uri"];
var qop = header.parameters["qop"];
@@ -203,13 +218,17 @@ class ProxyServer {
digest = md5.convert("$ha1:${nonce}:$ha2".codeUnits);
} else {
digest = md5.convert(
"$ha1:${nonce}:${nc}:${cnonce}:${qop}:$ha2".codeUnits);
"$ha1:${nonce}:${nc}:${cnonce}:${qop}:$ha2".codeUnits,
);
}
Expect.equals(
hex.encode(digest.bytes), header.parameters["response"]);
hex.encode(digest.bytes),
header.parameters["response"],
);
// Add a bogus Proxy-Authentication-Info for testing.
var info = 'rspauth="77180d1ab3d6c9de084766977790f482", '
var info =
'rspauth="77180d1ab3d6c9de084766977790f482", '
'cnonce="8f971178", '
'nc=000002c74, '
'qop=auth';
@@ -231,27 +250,30 @@ class ProxyServer {
client
.openUrl(request.method, request.uri)
.then((HttpClientRequest clientRequest) {
// Forward all headers.
request.headers.forEach((String name, List<String> values) {
values.forEach((String value) {
if (name != "content-length" && name != "via") {
clientRequest.headers.add(name, value);
}
// Forward all headers.
request.headers.forEach((String name, List<String> values) {
values.forEach((String value) {
if (name != "content-length" && name != "via") {
clientRequest.headers.add(name, value);
}
});
});
// Special handling of Content-Length and Via.
clientRequest.contentLength = request.contentLength;
List<String>? via = request.headers[HttpHeaders.viaHeader];
String viaPrefix = via == null ? "" : "${via[0]}, ";
clientRequest.headers.add(
HttpHeaders.viaHeader,
"${viaPrefix}1.1 localhost:$port",
);
// Copy all content.
return request.cast<List<int>>().pipe(clientRequest);
})
.then((clientResponse) {
(clientResponse as HttpClientResponse).cast<List<int>>().pipe(
request.response,
);
});
});
// Special handling of Content-Length and Via.
clientRequest.contentLength = request.contentLength;
List<String>? via = request.headers[HttpHeaders.viaHeader];
String viaPrefix = via == null ? "" : "${via[0]}, ";
clientRequest.headers
.add(HttpHeaders.viaHeader, "${viaPrefix}1.1 localhost:$port");
// Copy all content.
return request.cast<List<int>>().pipe(clientRequest);
}).then((clientResponse) {
(clientResponse as HttpClientResponse)
.cast<List<int>>()
.pipe(request.response);
});
}
});
});
@@ -276,23 +298,23 @@ testInvalidProxy() {
client.findProxy = (Uri uri) => "";
Future<HttpClientRequest?>.value(
client.getUrl(Uri.parse("http://www.google.com/test")))
.catchError((error) {}, test: (e) => e is HttpException);
client.getUrl(Uri.parse("http://www.google.com/test")),
).catchError((error) {}, test: (e) => e is HttpException);
client.findProxy = (Uri uri) => "XXX";
Future<HttpClientRequest?>.value(
client.getUrl(Uri.parse("http://www.google.com/test")))
.catchError((error) {}, test: (e) => e is HttpException);
client.getUrl(Uri.parse("http://www.google.com/test")),
).catchError((error) {}, test: (e) => e is HttpException);
client.findProxy = (Uri uri) => "PROXY www.google.com";
Future<HttpClientRequest?>.value(
client.getUrl(Uri.parse("http://www.google.com/test")))
.catchError((error) {}, test: (e) => e is HttpException);
client.getUrl(Uri.parse("http://www.google.com/test")),
).catchError((error) {}, test: (e) => e is HttpException);
client.findProxy = (Uri uri) => "PROXY www.google.com:http";
Future<HttpClientRequest?>.value(
client.getUrl(Uri.parse("http://www.google.com/test")))
.catchError((error) {}, test: (e) => e is HttpException);
client.getUrl(Uri.parse("http://www.google.com/test")),
).catchError((error) {}, test: (e) => e is HttpException);
}
int testDirectDoneCount = 0;
@@ -306,7 +328,7 @@ void testDirectProxy() {
" DIRECT ; ",
";DIRECT",
" ; DIRECT ",
";;DIRECT;;"
";;DIRECT;;",
];
client.findProxy = (Uri uri) {
@@ -318,20 +340,24 @@ void testDirectProxy() {
client
.getUrl(Uri.parse("http://localhost:${server.port}/$i"))
.then((HttpClientRequest clientRequest) {
String content = "$i$i$i";
clientRequest.contentLength = content.length;
clientRequest.write(content);
return clientRequest.close();
}).then((HttpClientResponse response) {
response.listen((_) {}, onDone: () {
testDirectDoneCount++;
if (testDirectDoneCount == proxy.length) {
Expect.equals(proxy.length, server.requestCount);
server.shutdown();
client.close();
}
});
});
String content = "$i$i$i";
clientRequest.contentLength = content.length;
clientRequest.write(content);
return clientRequest.close();
})
.then((HttpClientResponse response) {
response.listen(
(_) {},
onDone: () {
testDirectDoneCount++;
if (testDirectDoneCount == proxy.length) {
Expect.equals(proxy.length, server.requestCount);
server.shutdown();
client.close();
}
},
);
});
}
});
}
@@ -340,8 +366,9 @@ int testProxyDoneCount = 0;
void testProxy() {
setupProxyServer().then((proxyServer) {
setupServer(1, directRequestPaths: ["/4"]).then((server) {
setupServer(1, directRequestPaths: ["/4"], secure: true)
.then((secureServer) {
setupServer(1, directRequestPaths: ["/4"], secure: true).then((
secureServer,
) {
HttpClient client = new HttpClient(context: clientContext);
List<String> proxy;
@@ -353,7 +380,7 @@ void testProxy() {
""
" PROXY localhost:${proxyServer.port}",
"DIRECT",
"PROXY localhost:${proxyServer.port}; DIRECT"
"PROXY localhost:${proxyServer.port}; DIRECT",
];
} else {
proxy = [
@@ -363,7 +390,7 @@ void testProxy() {
"PROXY hede.hule.hest:8080; PROXY hede.hule.hest:8181;"
" PROXY localhost:${proxyServer.port}",
"PROXY hede.hule.hest:8080; PROXY hede.hule.hest:8181; DIRECT",
"PROXY localhost:${proxyServer.port}; DIRECT"
"PROXY localhost:${proxyServer.port}; DIRECT",
];
}
client.findProxy = (Uri uri) {
@@ -381,22 +408,26 @@ void testProxy() {
client
.postUrl(Uri.parse(url))
.then((HttpClientRequest clientRequest) {
String content = "$i$i$i";
clientRequest.write(content);
return clientRequest.close();
}).then((HttpClientResponse response) {
response.listen((_) {}, onDone: () {
testProxyDoneCount++;
if (testProxyDoneCount == proxy.length * 2) {
Expect.equals(proxy.length, server.requestCount);
Expect.equals(proxy.length, secureServer.requestCount);
proxyServer.shutdown();
server.shutdown();
secureServer.shutdown();
client.close();
}
});
});
String content = "$i$i$i";
clientRequest.write(content);
return clientRequest.close();
})
.then((HttpClientResponse response) {
response.listen(
(_) {},
onDone: () {
testProxyDoneCount++;
if (testProxyDoneCount == proxy.length * 2) {
Expect.equals(proxy.length, server.requestCount);
Expect.equals(proxy.length, secureServer.requestCount);
proxyServer.shutdown();
server.shutdown();
secureServer.shutdown();
client.close();
}
},
);
});
}
test(false);
@@ -412,8 +443,8 @@ void testProxyChain() {
// Setup two proxy servers having the first using the second as its proxy.
setupProxyServer().then((proxyServer1) {
setupProxyServer().then((proxyServer2) {
proxyServer1.client.findProxy =
(_) => "PROXY localhost:${proxyServer2.port}";
proxyServer1.client.findProxy = (_) =>
"PROXY localhost:${proxyServer2.port}";
setupServer(2, directRequestPaths: ["/4"]).then((server) {
HttpClient client = new HttpClient(context: clientContext);
@@ -426,7 +457,7 @@ void testProxyChain() {
"PROXY localhost:${proxyServer1.port}",
"PROXY localhost:${proxyServer1.port}",
"DIRECT",
"PROXY localhost:${proxyServer1.port}; DIRECT"
"PROXY localhost:${proxyServer1.port}; DIRECT",
];
} else {
proxy = [
@@ -436,7 +467,7 @@ void testProxyChain() {
"PROXY hede.hule.hest:8080; PROXY hede.hule.hest:8181;"
" PROXY localhost:${proxyServer1.port}",
"PROXY hede.hule.hest:8080; PROXY hede.hule.hest:8181; DIRECT",
"PROXY localhost:${proxyServer1.port}; DIRECT"
"PROXY localhost:${proxyServer1.port}; DIRECT",
];
}
@@ -450,22 +481,26 @@ void testProxyChain() {
client
.getUrl(Uri.parse("http://localhost:${server.port}/$i"))
.then((HttpClientRequest clientRequest) {
String content = "$i$i$i";
clientRequest.contentLength = content.length;
clientRequest.write(content);
return clientRequest.close();
}).then((HttpClientResponse response) {
response.listen((_) {}, onDone: () {
testProxyChainDoneCount++;
if (testProxyChainDoneCount == proxy.length) {
Expect.equals(proxy.length, server.requestCount);
proxyServer1.shutdown();
proxyServer2.shutdown();
server.shutdown();
client.close();
}
});
});
String content = "$i$i$i";
clientRequest.contentLength = content.length;
clientRequest.write(content);
return clientRequest.close();
})
.then((HttpClientResponse response) {
response.listen(
(_) {},
onDone: () {
testProxyChainDoneCount++;
if (testProxyChainDoneCount == proxy.length) {
Expect.equals(proxy.length, server.requestCount);
proxyServer1.shutdown();
proxyServer2.shutdown();
server.shutdown();
client.close();
}
},
);
});
}
});
});
+34 -26
View File
@@ -28,7 +28,7 @@ class IsolatedHttpServer {
// Send chunked encoding message to the server.
port.send([
new IsolatedHttpServerCommand.chunkedEncoding(),
_statusPort.sendPort
_statusPort.sendPort,
]);
}
@@ -47,8 +47,10 @@ class IsolatedHttpServer {
void shutdown() {
// Send server stop message to the server.
_serverPort
.send([new IsolatedHttpServerCommand.stop(), _statusPort.sendPort]);
_serverPort.send([
new IsolatedHttpServerCommand.stop(),
_statusPort.sendPort,
]);
_statusPort.close();
}
@@ -173,29 +175,35 @@ void testRead(bool chunkedEncoding) {
int count = 0;
HttpClient httpClient = new HttpClient();
void sendRequest() {
httpClient.post("127.0.0.1", port, "/echo").then((request) {
if (chunkedEncoding) {
request.write(data.substring(0, 10));
request.write(data.substring(10, data.length));
} else {
request.contentLength = data.length;
request.add(data.codeUnits);
}
return request.close();
}).then((response) {
Expect.equals(HttpStatus.ok, response.statusCode);
List<int> body = <int>[];
response.listen(body.addAll, onDone: () {
Expect.equals(data, new String.fromCharCodes(body));
count++;
if (count < kMessageCount) {
sendRequest();
} else {
httpClient.close();
server.shutdown();
}
});
});
httpClient
.post("127.0.0.1", port, "/echo")
.then((request) {
if (chunkedEncoding) {
request.write(data.substring(0, 10));
request.write(data.substring(10, data.length));
} else {
request.contentLength = data.length;
request.add(data.codeUnits);
}
return request.close();
})
.then((response) {
Expect.equals(HttpStatus.ok, response.statusCode);
List<int> body = <int>[];
response.listen(
body.addAll,
onDone: () {
Expect.equals(data, new String.fromCharCodes(body));
count++;
if (count < kMessageCount) {
sendRequest();
} else {
httpClient.close();
server.shutdown();
}
},
);
});
}
sendRequest();
+433 -236
View File
@@ -13,7 +13,9 @@ Future<HttpServer> setupServer({Uri? targetServer}) {
HttpServer.bind("127.0.0.1", 0).then((server) {
var handlers = new Map<String, Function>();
addRequestHandler(
String path, void handler(HttpRequest request, HttpResponse response)) {
String path,
void handler(HttpRequest request, HttpResponse response),
) {
handlers[path] = handler;
}
@@ -21,34 +23,48 @@ Future<HttpServer> setupServer({Uri? targetServer}) {
if (handlers.containsKey(request.uri.path)) {
handlers[request.uri.path]!(request, request.response);
} else {
request.listen((_) {}, onDone: () {
request.response.statusCode = 404;
request.response.close();
});
request.listen(
(_) {},
onDone: () {
request.response.statusCode = 404;
request.response.close();
},
);
}
});
void addRedirectHandler(int number, int statusCode) {
addRequestHandler("/$number",
(HttpRequest request, HttpResponse response) {
addRequestHandler("/$number", (
HttpRequest request,
HttpResponse response,
) {
response.redirect(
Uri.parse("http://127.0.0.1:${server.port}/${number + 1}"));
Uri.parse("http://127.0.0.1:${server.port}/${number + 1}"),
);
});
}
// Setup simple redirect.
addRequestHandler("/redirect",
(HttpRequest request, HttpResponse response) {
response.redirect(Uri.parse("http://127.0.0.1:${server.port}/location"),
status: HttpStatus.movedPermanently);
addRequestHandler("/redirect", (
HttpRequest request,
HttpResponse response,
) {
response.redirect(
Uri.parse("http://127.0.0.1:${server.port}/location"),
status: HttpStatus.movedPermanently,
);
});
addRequestHandler("/location",
(HttpRequest request, HttpResponse response) {
addRequestHandler("/location", (
HttpRequest request,
HttpResponse response,
) {
response.close();
});
addRequestHandler("/redirect-no-location",
(HttpRequest request, HttpResponse response) {
addRequestHandler("/redirect-no-location", (
HttpRequest request,
HttpResponse response,
) {
response
..statusCode = HttpStatus.movedPermanently
..reasonPhrase = "Moved Permanently"
@@ -56,55 +72,73 @@ Future<HttpServer> setupServer({Uri? targetServer}) {
});
// Setup redirects with relative url.
addRequestHandler("/redirectUrl",
(HttpRequest request, HttpResponse response) {
addRequestHandler("/redirectUrl", (
HttpRequest request,
HttpResponse response,
) {
response.headers.set(HttpHeaders.locationHeader, "/some/relativeUrl");
response.statusCode = HttpStatus.movedPermanently;
response.close();
});
addRequestHandler("/some/redirectUrl",
(HttpRequest request, HttpResponse response) {
addRequestHandler("/some/redirectUrl", (
HttpRequest request,
HttpResponse response,
) {
response.headers.set(HttpHeaders.locationHeader, "relativeUrl");
response.statusCode = HttpStatus.movedPermanently;
response.close();
});
addRequestHandler("/some/relativeUrl",
(HttpRequest request, HttpResponse response) {
addRequestHandler("/some/relativeUrl", (
HttpRequest request,
HttpResponse response,
) {
response.close();
});
addRequestHandler("/some/relativeToAbsolute",
(HttpRequest request, HttpResponse response) {
addRequestHandler("/some/relativeToAbsolute", (
HttpRequest request,
HttpResponse response,
) {
response.redirect(Uri.parse("xxx"), status: HttpStatus.seeOther);
});
addRequestHandler("/redirectUrl2",
(HttpRequest request, HttpResponse response) {
addRequestHandler("/redirectUrl2", (
HttpRequest request,
HttpResponse response,
) {
response.headers.set(HttpHeaders.locationHeader, "location");
response.statusCode = HttpStatus.movedPermanently;
response.close();
});
addRequestHandler("/redirectUrl3",
(HttpRequest request, HttpResponse response) {
addRequestHandler("/redirectUrl3", (
HttpRequest request,
HttpResponse response,
) {
response.headers.set(HttpHeaders.locationHeader, "./location");
response.statusCode = HttpStatus.movedPermanently;
response.close();
});
addRequestHandler("/redirectUrl4",
(HttpRequest request, HttpResponse response) {
addRequestHandler("/redirectUrl4", (
HttpRequest request,
HttpResponse response,
) {
response.headers.set(HttpHeaders.locationHeader, "./a/b/../../location");
response.statusCode = HttpStatus.movedPermanently;
response.close();
});
addRequestHandler("/redirectUrl5",
(HttpRequest request, HttpResponse response) {
addRequestHandler("/redirectUrl5", (
HttpRequest request,
HttpResponse response,
) {
response.headers.set(
HttpHeaders.locationHeader, "//127.0.0.1:${server.port}/location");
HttpHeaders.locationHeader,
"//127.0.0.1:${server.port}/location",
);
response.statusCode = HttpStatus.movedPermanently;
response.close();
});
@@ -122,14 +156,18 @@ Future<HttpServer> setupServer({Uri? targetServer}) {
// Setup redirect loop.
addRequestHandler("/A", (HttpRequest request, HttpResponse response) {
response.headers
.set(HttpHeaders.locationHeader, "http://127.0.0.1:${server.port}/B");
response.headers.set(
HttpHeaders.locationHeader,
"http://127.0.0.1:${server.port}/B",
);
response.statusCode = HttpStatus.movedPermanently;
response.close();
});
addRequestHandler("/B", (HttpRequest request, HttpResponse response) {
response.headers
.set(HttpHeaders.locationHeader, "http://127.0.0.1:${server.port}/A");
response.headers.set(
HttpHeaders.locationHeader,
"http://127.0.0.1:${server.port}/A",
);
response.statusCode = HttpStatus.movedTemporarily;
response.close();
});
@@ -137,28 +175,40 @@ Future<HttpServer> setupServer({Uri? targetServer}) {
// Setup redirect checking headers.
addRequestHandler("/src", (HttpRequest request, HttpResponse response) {
Expect.equals("value", request.headers.value("X-Request-Header"));
Expect.isNotNull(request.headers.value("Authorization"),
"expected 'Authorization' header to be set");
Expect.isNotNull(
request.headers.value("Authorization"),
"expected 'Authorization' header to be set",
);
response.headers.set(
HttpHeaders.locationHeader, "http://127.0.0.1:${server.port}/target");
HttpHeaders.locationHeader,
"http://127.0.0.1:${server.port}/target",
);
response.statusCode = HttpStatus.movedPermanently;
response.close();
});
addRequestHandler("/target", (HttpRequest request, HttpResponse response) {
Expect.equals("value", request.headers.value("X-Request-Header"));
Expect.isNotNull(request.headers.value("Authorization"),
"expected 'Authorization' header to be set");
Expect.isNotNull(
request.headers.value("Authorization"),
"expected 'Authorization' header to be set",
);
response.close();
});
if (targetServer != null) {
addRequestHandler("/src-crossdomain",
(HttpRequest request, HttpResponse response) {
addRequestHandler("/src-crossdomain", (
HttpRequest request,
HttpResponse response,
) {
Expect.equals("value", request.headers.value("X-Request-Header"));
Expect.isNotNull(request.headers.value("Authorization"),
"expected 'Authorization' header to be set");
response.headers
.set(HttpHeaders.locationHeader, targetServer.toString());
Expect.isNotNull(
request.headers.value("Authorization"),
"expected 'Authorization' header to be set",
);
response.headers.set(
HttpHeaders.locationHeader,
targetServer.toString(),
);
response.statusCode = HttpStatus.movedPermanently;
response.close();
});
@@ -167,38 +217,54 @@ Future<HttpServer> setupServer({Uri? targetServer}) {
// Setup redirect for 301 where POST should not redirect.
addRequestHandler("/301src", (HttpRequest request, HttpResponse response) {
Expect.equals("POST", request.method);
request.listen((_) {}, onDone: () {
response.headers.set(HttpHeaders.locationHeader,
"http://127.0.0.1:${server.port}/301target");
response.statusCode = HttpStatus.movedPermanently;
response.close();
});
request.listen(
(_) {},
onDone: () {
response.headers.set(
HttpHeaders.locationHeader,
"http://127.0.0.1:${server.port}/301target",
);
response.statusCode = HttpStatus.movedPermanently;
response.close();
},
);
});
addRequestHandler("/301target",
(HttpRequest request, HttpResponse response) {
addRequestHandler("/301target", (
HttpRequest request,
HttpResponse response,
) {
Expect.fail("Redirect of POST should not happen");
});
// Setup redirect for 303 where POST should turn into GET.
addRequestHandler("/303src", (HttpRequest request, HttpResponse response) {
request.listen((_) {}, onDone: () {
Expect.equals("POST", request.method);
response.headers.set(HttpHeaders.locationHeader,
"http://127.0.0.1:${server.port}/303target");
response.statusCode = HttpStatus.seeOther;
response.close();
});
request.listen(
(_) {},
onDone: () {
Expect.equals("POST", request.method);
response.headers.set(
HttpHeaders.locationHeader,
"http://127.0.0.1:${server.port}/303target",
);
response.statusCode = HttpStatus.seeOther;
response.close();
},
);
});
addRequestHandler("/303target",
(HttpRequest request, HttpResponse response) {
addRequestHandler("/303target", (
HttpRequest request,
HttpResponse response,
) {
Expect.equals("GET", request.method);
response.close();
});
// Setup redirect where we close the connection.
addRequestHandler("/closing", (HttpRequest request, HttpResponse response) {
response.headers
.set(HttpHeaders.locationHeader, "http://127.0.0.1:${server.port}/");
response.headers.set(
HttpHeaders.locationHeader,
"http://127.0.0.1:${server.port}/",
);
response.statusCode = HttpStatus.found;
response.persistentConnection = false;
response.close();
@@ -216,21 +282,28 @@ Future<HttpServer> setupTargetServer() {
HttpServer.bind("127.0.0.1", 0).then((server) {
var handlers = new Map<String, Function>();
addRequestHandler(
String path, void handler(HttpRequest request, HttpResponse response)) {
String path,
void handler(HttpRequest request, HttpResponse response),
) {
handlers[path] = handler;
}
server.listen((HttpRequest request) {
if (request.uri.path == "/target") {
Expect.equals("value", request.headers.value("X-Request-Header"));
Expect.isNull(request.headers.value("Authorization"),
"expected 'Authorization' header to be removed on redirect");
Expect.isNull(
request.headers.value("Authorization"),
"expected 'Authorization' header to be removed on redirect",
);
request.response.close();
} else {
request.listen((_) {}, onDone: () {
request.response.statusCode = 404;
request.response.close();
});
request.listen(
(_) {},
onDone: () {
request.response.statusCode = 404;
request.response.close();
},
);
}
});
@@ -256,27 +329,30 @@ void testManualRedirect() {
int redirectCount = 0;
handleResponse(HttpClientResponse response) {
response.listen((_) => Expect.fail("Response data not expected"),
onDone: () {
redirectCount++;
if (redirectCount < 10) {
Expect.isTrue(response.isRedirect);
checkRedirects(redirectCount, response);
response.redirect().then(handleResponse);
} else {
Expect.equals(HttpStatus.notFound, response.statusCode);
server.close();
client.close();
}
});
response.listen(
(_) => Expect.fail("Response data not expected"),
onDone: () {
redirectCount++;
if (redirectCount < 10) {
Expect.isTrue(response.isRedirect);
checkRedirects(redirectCount, response);
response.redirect().then(handleResponse);
} else {
Expect.equals(HttpStatus.notFound, response.statusCode);
server.close();
client.close();
}
},
);
}
client
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/1"))
.then((HttpClientRequest request) {
request.followRedirects = false;
return request.close();
}).then(handleResponse);
request.followRedirects = false;
return request.close();
})
.then(handleResponse);
});
}
@@ -287,28 +363,31 @@ void testManualRedirectWithHeaders() {
int redirectCount = 0;
handleResponse(HttpClientResponse response) {
response.listen((_) => Expect.fail("Response data not expected"),
onDone: () {
redirectCount++;
if (redirectCount < 2) {
Expect.isTrue(response.isRedirect);
response.redirect().then(handleResponse);
} else {
Expect.equals(HttpStatus.ok, response.statusCode);
server.close();
client.close();
}
});
response.listen(
(_) => Expect.fail("Response data not expected"),
onDone: () {
redirectCount++;
if (redirectCount < 2) {
Expect.isTrue(response.isRedirect);
response.redirect().then(handleResponse);
} else {
Expect.equals(HttpStatus.ok, response.statusCode);
server.close();
client.close();
}
},
);
}
client
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/src"))
.then((HttpClientRequest request) {
request.followRedirects = false;
request.headers.add("X-Request-Header", "value");
request.headers.add("Authorization", "Basic ...");
return request.close();
}).then(handleResponse);
request.followRedirects = false;
request.headers.add("X-Request-Header", "value");
request.headers.add("Authorization", "Basic ...");
return request.close();
})
.then(handleResponse);
});
}
@@ -319,15 +398,18 @@ void testAutoRedirect() {
client
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/redirect"))
.then((HttpClientRequest request) {
return request.close();
}).then((HttpClientResponse response) {
response.listen((_) => Expect.fail("Response data not expected"),
onDone: () {
Expect.equals(1, response.redirects.length);
server.close();
client.close();
});
});
return request.close();
})
.then((HttpClientResponse response) {
response.listen(
(_) => Expect.fail("Response data not expected"),
onDone: () {
Expect.equals(1, response.redirects.length);
server.close();
client.close();
},
);
});
});
}
@@ -336,7 +418,8 @@ Future<void> testAutoRedirectNoLocationHeader() async {
HttpClient client = new HttpClient();
final request = await client.getUrl(
Uri.parse("http://127.0.0.1:${server.port}/redirect-no-location"));
Uri.parse("http://127.0.0.1:${server.port}/redirect-no-location"),
);
try {
final response = await request.close();
@@ -354,21 +437,25 @@ void testAutoRedirectZeroMaxRedirects() {
client
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/redirect"))
.then((HttpClientRequest request) {
request
..followRedirects = true
..maxRedirects = 0;
request
..followRedirects = true
..maxRedirects = 0;
return request.close();
}).then((HttpClientResponse response) {
response.drain();
Expect.fail("Response data not expected");
}, onError: (error) {
final httpException = error as HttpException;
Expect.equals(httpException.message, "Redirect limit exceeded");
Expect.equals(httpException.uri, null);
server.close();
client.close();
});
return request.close();
})
.then(
(HttpClientResponse response) {
response.drain();
Expect.fail("Response data not expected");
},
onError: (error) {
final httpException = error as HttpException;
Expect.equals(httpException.message, "Redirect limit exceeded");
Expect.equals(httpException.uri, null);
server.close();
client.close();
},
);
});
}
@@ -379,17 +466,20 @@ void testAutoRedirectWithHeaders() {
client
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/src"))
.then((HttpClientRequest request) {
request.headers.add("X-Request-Header", "value");
request.headers.add("Authorization", "Basic ...");
return request.close();
}).then((HttpClientResponse response) {
response.listen((_) => Expect.fail("Response data not expected"),
onDone: () {
Expect.equals(1, response.redirects.length);
server.close();
client.close();
});
});
request.headers.add("X-Request-Header", "value");
request.headers.add("Authorization", "Basic ...");
return request.close();
})
.then((HttpClientResponse response) {
response.listen(
(_) => Expect.fail("Response data not expected"),
onDone: () {
Expect.equals(1, response.redirects.length);
server.close();
client.close();
},
);
});
});
}
@@ -398,113 +488,202 @@ void testShouldCopyHeadersOnRedirect() {
final fnName = Symbol("shouldCopyHeaderOnRedirect");
shouldCopyHeaderOnRedirect(
String headerKey, Uri originalUrl, Uri redirectUri) =>
clientClass.invoke(
fnName, [headerKey, originalUrl, redirectUri]).reflectee as bool;
String headerKey,
Uri originalUrl,
Uri redirectUri,
) =>
clientClass.invoke(fnName, [
headerKey,
originalUrl,
redirectUri,
]).reflectee
as bool;
checkShouldCopyHeader(
String headerKey, String originalUrl, String redirectUri, bool expected) {
String headerKey,
String originalUrl,
String redirectUri,
bool expected,
) {
if (shouldCopyHeaderOnRedirect(
headerKey, Uri.parse(originalUrl), Uri.parse(redirectUri)) !=
headerKey,
Uri.parse(originalUrl),
Uri.parse(redirectUri),
) !=
expected) {
Expect.fail(
"shouldCopyHeaderOnRedirect($headerKey, $originalUrl, $redirectUri) => ${!expected}");
"shouldCopyHeaderOnRedirect($headerKey, $originalUrl, $redirectUri) => ${!expected}",
);
}
}
// Redirect on localhost.
checkShouldCopyHeader(
"authorization", "http://localhost", "http://localhost/foo", true);
"authorization",
"http://localhost",
"http://localhost/foo",
true,
);
checkShouldCopyHeader(
"cat", "http://localhost", "http://localhost/foo", true);
"cat",
"http://localhost",
"http://localhost/foo",
true,
);
// Redirect to same IP address.
checkShouldCopyHeader("authorization", "http://192.168.20.20",
"http://192.168.20.20/foo", true);
checkShouldCopyHeader(
"cat", "http://192.168.20.20", "http://192.168.20.20/foo", true);
"authorization",
"http://192.168.20.20",
"http://192.168.20.20/foo",
true,
);
checkShouldCopyHeader(
"cat",
"http://192.168.20.20",
"http://192.168.20.20/foo",
true,
);
// Redirect to different IP address.
checkShouldCopyHeader(
"authorization", "http://192.168.20.20", "http://192.168.20.99", false);
"authorization",
"http://192.168.20.20",
"http://192.168.20.99",
false,
);
checkShouldCopyHeader(
"cat", "http://192.168.20.20", "http://192.168.20.99", true);
"cat",
"http://192.168.20.20",
"http://192.168.20.99",
true,
);
// Redirect to same domain.
checkShouldCopyHeader(
"authorization", "http://foo.com", "http://foo.com/foo", true);
"authorization",
"http://foo.com",
"http://foo.com/foo",
true,
);
checkShouldCopyHeader("cat", "http://foo.com", "http://foo.com/foo", true);
// Redirect to same domain with explicit ports.
checkShouldCopyHeader(
"authorization", "http://foo.com", "http://foo.com:80/foo", true);
"authorization",
"http://foo.com",
"http://foo.com:80/foo",
true,
);
checkShouldCopyHeader("cat", "http://foo.com", "http://foo.com:80/foo", true);
// Redirect to subdomain.
checkShouldCopyHeader(
"authorization", "https://foo.com", "https://www.foo.com", true);
"authorization",
"https://foo.com",
"https://www.foo.com",
true,
);
checkShouldCopyHeader("cat", "https://foo.com", "https://www.foo.com", true);
// Redirect to different domain.
checkShouldCopyHeader(
"authorization", "https://foo.com", "https://wwwfoo.com", false);
"authorization",
"https://foo.com",
"https://wwwfoo.com",
false,
);
checkShouldCopyHeader("cat", "https://foo.com", "https://wwwfoo.com", true);
// Redirect to different port.
checkShouldCopyHeader(
"authorization", "http://foo.com", "http://foo.com:81", false);
"authorization",
"http://foo.com",
"http://foo.com:81",
false,
);
checkShouldCopyHeader("cat", "http://foo.com", "http://foo.com:81", true);
// Redirect from secure to insecure.
checkShouldCopyHeader(
"authorization", "https://foo.com", "http://foo.com", false);
"authorization",
"https://foo.com",
"http://foo.com",
false,
);
checkShouldCopyHeader("cat", "https://foo.com", "http://foo.com", true);
// Redirect from secure to insecure, same port.
checkShouldCopyHeader(
"authorization", "https://foo.com:8888", "http://foo.com:8888", false);
"authorization",
"https://foo.com:8888",
"http://foo.com:8888",
false,
);
checkShouldCopyHeader(
"cat", "https://foo.com:8888", "http://foo.com:8888", true);
"cat",
"https://foo.com:8888",
"http://foo.com:8888",
true,
);
// Redirect from insecure to secure.
checkShouldCopyHeader(
"authorization", "http://foo.com", "https://foo.com", false);
"authorization",
"http://foo.com",
"https://foo.com",
false,
);
checkShouldCopyHeader("cat", "http://foo.com", "https://foo.com", true);
// Redirect to subdomain, different port.
checkShouldCopyHeader(
"authorization", "https://foo.com:80", "https://www.foo.com:81", false);
"authorization",
"https://foo.com:80",
"https://www.foo.com:81",
false,
);
checkShouldCopyHeader(
"cat", "https://foo.com:80", "https://www.foo.com:81", true);
"cat",
"https://foo.com:80",
"https://www.foo.com:81",
true,
);
// Different header casting:
checkShouldCopyHeader(
"AuThOrIzAtiOn", "https://foo.com", "https://bar.com", false);
"AuThOrIzAtiOn",
"https://foo.com",
"https://bar.com",
false,
);
}
void testCrossDomainAutoRedirectWithHeaders() {
setupTargetServer().then((targetServer) {
setupServer(
targetServer:
Uri.parse("http://127.0.0.1:${targetServer.port}/target"))
.then((server) {
targetServer: Uri.parse("http://127.0.0.1:${targetServer.port}/target"),
).then((server) {
HttpClient client = new HttpClient();
client
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/src-crossdomain"))
.then((HttpClientRequest request) {
request.headers.add("X-Request-Header", "value");
request.headers.add("Authorization", "Basic ...");
return request.close();
}).then((HttpClientResponse response) {
response.listen((_) => Expect.fail("Response data not expected"),
onDone: () {
Expect.equals(1, response.redirects.length);
targetServer.close();
server.close();
client.close();
});
});
request.headers.add("X-Request-Header", "value");
request.headers.add("Authorization", "Basic ...");
return request.close();
})
.then((HttpClientResponse response) {
response.listen(
(_) => Expect.fail("Response data not expected"),
onDone: () {
Expect.equals(1, response.redirects.length);
targetServer.close();
server.close();
client.close();
},
);
});
});
});
}
@@ -516,16 +695,19 @@ void testAutoRedirect301POST() {
client
.postUrl(Uri.parse("http://127.0.0.1:${server.port}/301src"))
.then((HttpClientRequest request) {
return request.close();
}).then((HttpClientResponse response) {
Expect.equals(HttpStatus.movedPermanently, response.statusCode);
response.listen((_) => Expect.fail("Response data not expected"),
onDone: () {
Expect.equals(0, response.redirects.length);
server.close();
client.close();
});
});
return request.close();
})
.then((HttpClientResponse response) {
Expect.equals(HttpStatus.movedPermanently, response.statusCode);
response.listen(
(_) => Expect.fail("Response data not expected"),
onDone: () {
Expect.equals(0, response.redirects.length);
server.close();
client.close();
},
);
});
});
}
@@ -536,16 +718,19 @@ void testAutoRedirect303POST() {
client
.postUrl(Uri.parse("http://127.0.0.1:${server.port}/303src"))
.then((HttpClientRequest request) {
return request.close();
}).then((HttpClientResponse response) {
Expect.equals(HttpStatus.ok, response.statusCode);
response.listen((_) => Expect.fail("Response data not expected"),
onDone: () {
Expect.equals(1, response.redirects.length);
server.close();
client.close();
});
});
return request.close();
})
.then((HttpClientResponse response) {
Expect.equals(HttpStatus.ok, response.statusCode);
response.listen(
(_) => Expect.fail("Response data not expected"),
onDone: () {
Expect.equals(1, response.redirects.length);
server.close();
client.close();
},
);
});
});
}
@@ -553,10 +738,11 @@ void testAutoRedirectLimit() {
setupServer().then((server) {
HttpClient client = new HttpClient();
Future<HttpClientResponse?>.value(client
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/1"))
.then((HttpClientRequest request) => request.close()))
.catchError((error) {
Future<HttpClientResponse?>.value(
client
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/1"))
.then((HttpClientRequest request) => request.close()),
).catchError((error) {
Expect.equals(5, error.redirects.length);
server.close();
client.close();
@@ -569,10 +755,11 @@ void testRedirectLoop() {
HttpClient client = new HttpClient();
int redirectCount = 0;
Future<HttpClientResponse?>.value(client
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/A"))
.then((HttpClientRequest request) => request.close()))
.catchError((error) {
Future<HttpClientResponse?>.value(
client
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/A"))
.then((HttpClientRequest request) => request.close()),
).catchError((error) {
Expect.equals(2, error.redirects.length);
server.close();
client.close();
@@ -588,12 +775,15 @@ void testRedirectClosingConnection() {
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/closing"))
.then((request) => request.close())
.then((response) {
response.listen((_) {}, onDone: () {
Expect.equals(1, response.redirects.length);
server.close();
client.close();
});
});
response.listen(
(_) {},
onDone: () {
Expect.equals(1, response.redirects.length);
server.close();
client.close();
},
);
});
});
}
@@ -607,13 +797,16 @@ void testRedirectRelativeUrl() {
.getUrl(Uri.parse("http://127.0.0.1:${server.port}$path"))
.then((request) => request.close())
.then((response) {
response.listen((_) {}, onDone: () {
Expect.equals(HttpStatus.ok, response.statusCode);
Expect.equals(1, response.redirects.length);
server.close();
client.close();
});
});
response.listen(
(_) {},
onDone: () {
Expect.equals(HttpStatus.ok, response.statusCode);
Expect.equals(1, response.redirects.length);
server.close();
client.close();
},
);
});
});
}
@@ -631,23 +824,27 @@ void testRedirectRelativeToAbsolute() {
int redirectCount = 0;
handleResponse(HttpClientResponse response) {
response.listen((_) => Expect.fail("Response data not expected"),
onDone: () {
Expect.equals(HttpStatus.seeOther, response.statusCode);
Expect.equals("xxx", response.headers["Location"]![0]);
Expect.isTrue(response.isRedirect);
server.close();
client.close();
});
response.listen(
(_) => Expect.fail("Response data not expected"),
onDone: () {
Expect.equals(HttpStatus.seeOther, response.statusCode);
Expect.equals("xxx", response.headers["Location"]![0]);
Expect.isTrue(response.isRedirect);
server.close();
client.close();
},
);
}
client
.getUrl(Uri.parse(
"http://127.0.0.1:${server.port}/some/relativeToAbsolute"))
.getUrl(
Uri.parse("http://127.0.0.1:${server.port}/some/relativeToAbsolute"),
)
.then((HttpClientRequest request) {
request.followRedirects = false;
return request.close();
}).then(handleResponse);
request.followRedirects = false;
return request.close();
})
.then(handleResponse);
});
}
@@ -55,12 +55,14 @@ void testAbsoluteUriInRequest() {
socket.write("Host: google.com\r\n");
socket.write("Connection: close\r\n");
socket.write("\r\n");
socket.flush().then((_) => socket.drain().then((_) {
Expect.equals(Uri.http("google.com", "/"), requestedUri);
socket.close();
server.close();
asyncEnd();
}));
socket.flush().then(
(_) => socket.drain().then((_) {
Expect.equals(Uri.http("google.com", "/"), requestedUri);
socket.close();
server.close();
asyncEnd();
}),
);
});
});
}
@@ -22,10 +22,12 @@ void testSimpleDeadline(int connections) {
var futures = <Future>[];
var client = new HttpClient();
for (int i = 0; i < connections; i++) {
futures.add(client
.get('localhost', server.port, '/')
.then((request) => request.close())
.then((response) => response.drain()));
futures.add(
client
.get('localhost', server.port, '/')
.then((request) => request.close())
.then((response) => response.drain()),
);
}
Future.wait(futures).then((_) => server.close());
});
@@ -42,15 +44,20 @@ void testExceedDeadline(int connections) {
var futures = <Future>[];
var client = new HttpClient();
for (int i = 0; i < connections; i++) {
futures.add(client
.get('localhost', server.port, '/')
.then((request) => request.close())
.then((response) => response.drain())
.then((_) {
Expect.fail("Expected error");
}, onError: (e) {
// Expect error.
}));
futures.add(
client
.get('localhost', server.port, '/')
.then((request) => request.close())
.then((response) => response.drain())
.then(
(_) {
Expect.fail("Expected error");
},
onError: (e) {
// Expect error.
},
),
);
}
Future.wait(futures).then((_) => server.close());
});
@@ -74,16 +81,21 @@ void testDeadlineAndDetach(int connections) {
var futures = <Future>[];
var client = new HttpClient();
for (int i = 0; i < connections; i++) {
futures.add(client
.get('localhost', server.port, '/')
.then((request) => request.close())
.then((response) {
return response
.fold<BytesBuilder>(new BytesBuilder(), (b, d) => b..add(d))
.then((builder) {
Expect.equals('stuff', new String.fromCharCodes(builder.takeBytes()));
});
}));
futures.add(
client
.get('localhost', server.port, '/')
.then((request) => request.close())
.then((response) {
return response
.fold<BytesBuilder>(new BytesBuilder(), (b, d) => b..add(d))
.then((builder) {
Expect.equals(
'stuff',
new String.fromCharCodes(builder.takeBytes()),
);
});
}),
);
}
Future.wait(futures).then((_) => server.close());
});
@@ -26,16 +26,18 @@ Future<int> runServer(int port, int connections, bool clean) {
}
});
Future.wait(new List.generate(connections, (_) {
var client = new HttpClient();
return client
.get("127.0.0.1", server.port, "/")
.then((request) => request.close())
.then((response) => response.drain())
.catchError((e) {
if (clean) throw e;
});
})).then((_) {
Future.wait(
new List.generate(connections, (_) {
var client = new HttpClient();
return client
.get("127.0.0.1", server.port, "/")
.then((request) => request.close())
.then((response) => response.drain())
.catchError((e) {
if (clean) throw e;
});
}),
).then((_) {
if (clean) {
int port = server.port;
server.close().then((_) => completer.complete(port));
@@ -16,19 +16,23 @@ const CLIENT_SCRIPT = "http_server_close_response_after_error_client.dart";
void main() {
HttpServer.bind("127.0.0.1", 0).then((server) {
server.listen((request) {
request.listen(null, onError: (e) {}, onDone: () {
request.response.close();
});
request.listen(
null,
onError: (e) {},
onDone: () {
request.response.close();
},
);
});
Process.run(
Platform.executable,
[]
..addAll(Platform.executableArguments)
..addAll([
Platform.script.resolve(CLIENT_SCRIPT).toString(),
server.port.toString()
]))
.then((result) {
Platform.executable,
[]
..addAll(Platform.executableArguments)
..addAll([
Platform.script.resolve(CLIENT_SCRIPT).toString(),
server.port.toString(),
]),
).then((result) {
if (result.exitCode != 0) throw "Bad exit code";
server.close();
});
@@ -16,11 +16,11 @@ main() {
HttpServer.bind("127.0.0.1", 0).then((server) {
server.listen((request) {
String name = Platform.script.toFilePath();
new File(name)
.openRead()
.cast<List<int>>()
.pipe(request.response)
.catchError((e) {/* ignore */});
new File(
name,
).openRead().cast<List<int>>().pipe(request.response).catchError((e) {
/* ignore */
});
});
var count = 0;

Some files were not shown because too many files have changed in this diff Show More