| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 library scheduled_server_test; | |
| 6 | |
| 7 import 'dart:async'; | |
| 8 import 'dart:io'; | |
| 9 | |
| 10 import 'package:http/http.dart' as http; | |
| 11 import 'package:scheduled_test/scheduled_server.dart'; | |
| 12 import 'package:scheduled_test/scheduled_test.dart'; | |
| 13 import 'package:scheduled_test/src/mock_clock.dart' as mock_clock; | |
| 14 import 'package:shelf/shelf.dart' as shelf; | |
| 15 | |
| 16 import 'package:metatest/metatest.dart'; | |
| 17 import 'utils.dart'; | |
| 18 | |
| 19 void main() => initTests(_test); | |
| 20 | |
| 21 void _test(message) { | |
| 22 initMetatest(message); | |
| 23 | |
| 24 setUpTimeout(); | |
| 25 | |
| 26 expectTestPasses("a server with no handlers does nothing", | |
| 27 () => new ScheduledServer()); | |
| 28 | |
| 29 expectServerError("a server with no handlers that receives a request throws " | |
| 30 "an error", () { | |
| 31 var server = new ScheduledServer(); | |
| 32 expect(server.url.then((url) => http.read(url.resolve('/hello'))), | |
| 33 completion(equals('Hello, test!'))); | |
| 34 }, "'scheduled server 0' received GET /hello when no more requests were " | |
| 35 "expected."); | |
| 36 | |
| 37 expectTestPasses("a handler runs when it's hit", () { | |
| 38 var server = new ScheduledServer(); | |
| 39 expect(server.url.then((url) => http.read(url.resolve('/hello'))), | |
| 40 completion(equals('Hello, test!'))); | |
| 41 | |
| 42 server.handle('GET', '/hello', | |
| 43 (request) => new shelf.Response.ok('Hello, test!')); | |
| 44 }); | |
| 45 | |
| 46 expectTestPasses("a handler blocks the schedule on the returned future", () { | |
| 47 var blockedOnFuture = false; | |
| 48 var server = new ScheduledServer(); | |
| 49 expect(server.url.then((url) => http.read(url.resolve('/hello'))), | |
| 50 completion(equals('Hello, test!'))); | |
| 51 | |
| 52 server.handle('GET', '/hello', (request) { | |
| 53 return pumpEventQueue().then((_) { | |
| 54 blockedOnFuture = true; | |
| 55 return new shelf.Response.ok('Hello, test!'); | |
| 56 }); | |
| 57 }); | |
| 58 | |
| 59 schedule(() => expect(blockedOnFuture, isTrue)); | |
| 60 }); | |
| 61 | |
| 62 expectServerError("a handler fails if it's hit too early", () { | |
| 63 var server = new ScheduledServer(); | |
| 64 var response = server.url.then((url) => http.read(url.resolve('/hello'))); | |
| 65 expect(response, completion(equals('Hello, test!'))); | |
| 66 | |
| 67 // Block the schedule until we're sure the request has hit the server. | |
| 68 schedule(() => response); | |
| 69 | |
| 70 // Add an additional task here so that when the previous task hits the | |
| 71 // server, it will be considered too early. Otherwise we'd hit the heuristic | |
| 72 // of allowing the server to be hit in the immediately prior task. | |
| 73 schedule(() => null); | |
| 74 | |
| 75 server.handle('GET', '/hello', | |
| 76 (request) => new shelf.Response.ok('Hello, test!')); | |
| 77 }, "'scheduled server 0' received GET /hello earlier than expected."); | |
| 78 | |
| 79 expectTestPasses("a handler waits for the immediately prior task to complete " | |
| 80 "before checking if it's too early", () { | |
| 81 var server = new ScheduledServer(); | |
| 82 expect(server.url.then((url) => http.read(url.resolve('/hello'))), | |
| 83 completion(equals('Hello, test!'))); | |
| 84 | |
| 85 // Sleeping here is unfortunate, but we want to be sure that the HTTP | |
| 86 // request hits the server during this test without actually blocking the | |
| 87 // task on the request completing. | |
| 88 // | |
| 89 // This is also a potential race condition, but hopefully a local HTTP | |
| 90 // request won't take 500ms. | |
| 91 schedule(() => new Future.delayed(new Duration(milliseconds: 500))); | |
| 92 | |
| 93 server.handle('GET', '/hello', | |
| 94 (request) => new shelf.Response.ok('Hello, test!')); | |
| 95 }); | |
| 96 | |
| 97 expectServerError("a handler fails if the url is wrong", () { | |
| 98 var server = new ScheduledServer(); | |
| 99 expect(server.url.then((url) => http.read(url.resolve('/hello'))), | |
| 100 completion(equals('Hello, test!'))); | |
| 101 | |
| 102 server.handle('GET', '/goodbye', | |
| 103 (request) => new shelf.Response.ok('Goodbye, test!')); | |
| 104 }, "'scheduled server 0' expected GET /goodbye, but got GET /hello."); | |
| 105 | |
| 106 expectServerError("a handler fails if the method is wrong", () { | |
| 107 var server = new ScheduledServer(); | |
| 108 expect(server.url.then((url) => http.head(url.resolve('/hello'))), | |
| 109 completes); | |
| 110 | |
| 111 server.handle('GET', '/hello', | |
| 112 (request) => new shelf.Response.ok('Hello, test!')); | |
| 113 }, "'scheduled server 0' expected GET /hello, but got HEAD /hello."); | |
| 114 | |
| 115 expectTestsPass("a handler times out waiting to be hit", () { | |
| 116 var clock = mock_clock.mock()..run(); | |
| 117 var timeOfException; | |
| 118 var errors; | |
| 119 test('test 1', () { | |
| 120 currentSchedule.timeout = new Duration(milliseconds: 2); | |
| 121 currentSchedule.onException.schedule(() { | |
| 122 timeOfException = clock.time; | |
| 123 errors = currentSchedule.errors; | |
| 124 }); | |
| 125 | |
| 126 var server = new ScheduledServer(); | |
| 127 | |
| 128 server.handle('GET', '/hello', | |
| 129 (request) => new shelf.Response.ok('Hello, test!')); | |
| 130 }); | |
| 131 | |
| 132 test('test 2', () { | |
| 133 expect(clock.time, equals(2)); | |
| 134 | |
| 135 expect(errors.single, new isInstanceOf<ScheduleError>()); | |
| 136 expect(errors.single.error.toString(), equals( | |
| 137 "The schedule timed out after 0:00:00.002000 of inactivity.")); | |
| 138 }); | |
| 139 }, passing: ['test 2']); | |
| 140 | |
| 141 expectTestPasses("multiple handlers in series respond to requests in series", | |
| 142 () { | |
| 143 var server = new ScheduledServer(); | |
| 144 expect(server.url.then((url) { | |
| 145 return http.read(url.resolve('/hello/1')).then((response) { | |
| 146 expect(response, equals('Hello, request 1!')); | |
| 147 return http.read(url.resolve('/hello/2')); | |
| 148 }).then((response) { | |
| 149 expect(response, equals('Hello, request 2!')); | |
| 150 return http.read(url.resolve('/hello/3')); | |
| 151 }).then((response) => expect(response, equals('Hello, request 3!'))); | |
| 152 }), completes); | |
| 153 | |
| 154 server.handle('GET', '/hello/1', | |
| 155 (request) => new shelf.Response.ok('Hello, request 1!')); | |
| 156 | |
| 157 server.handle('GET', '/hello/2', | |
| 158 (request) => new shelf.Response.ok('Hello, request 2!')); | |
| 159 | |
| 160 server.handle('GET', '/hello/3', | |
| 161 (request) => new shelf.Response.ok('Hello, request 3!')); | |
| 162 }); | |
| 163 | |
| 164 expectServerError("a server that receives a request after all its handlers " | |
| 165 "have run throws an error", () { | |
| 166 var server = new ScheduledServer(); | |
| 167 expect(server.url.then((url) { | |
| 168 return http.read(url.resolve('/hello/1')).then((response) { | |
| 169 expect(response, equals('Hello, request 1!')); | |
| 170 return http.read(url.resolve('/hello/2')); | |
| 171 }).then((response) { | |
| 172 expect(response, equals('Hello, request 2!')); | |
| 173 return http.read(url.resolve('/hello/3')); | |
| 174 }).then((response) => expect(response, equals('Hello, request 3!'))); | |
| 175 }), completes); | |
| 176 | |
| 177 server.handle('GET', '/hello/1', | |
| 178 (request) => new shelf.Response.ok('Hello, request 1!')); | |
| 179 | |
| 180 server.handle('GET', '/hello/2', | |
| 181 (request) => new shelf.Response.ok('Hello, request 2!')); | |
| 182 }, "'scheduled server 0' received GET /hello/3 when no more requests were " | |
| 183 "expected."); | |
| 184 | |
| 185 expectServerError("an error in a handler doesn't cause a timeout", () { | |
| 186 var server = new ScheduledServer(); | |
| 187 expect(server.url.then((url) => http.read(url.resolve('/hello'))), | |
| 188 completion(equals('Hello, test!'))); | |
| 189 | |
| 190 server.handle('GET', '/hello', (request) => fail('oh no')); | |
| 191 }, 'oh no'); | |
| 192 } | |
| 193 | |
| 194 /// Creates a metatest that runs [testBody], captures its schedule errors, and | |
| 195 /// asserts that it throws an error with the given [errorMessage]. | |
| 196 void expectServerError(String description, testBody(), | |
| 197 String errorMessage) { | |
| 198 expectTestFails(description, testBody, (errors) { | |
| 199 // There can be between one and three errors here. The first is the | |
| 200 // expected server error. The second is an HttpException that may occur if | |
| 201 // the server is closed fast enough after the error. The third is due to | |
| 202 // issue 9151: the HttpException is reported without a stack trace, and so | |
| 203 // when it's wrapped twice it registers as a different exception each time | |
| 204 // (because it's given an ad-hoc stack trace). | |
| 205 expect(errors.length, inInclusiveRange(1, 3)); | |
| 206 expect(errors[0].error.toString(), equals(errorMessage)); | |
| 207 | |
| 208 for (var i = 1; i < errors.length; i++) { | |
| 209 expect(errors[i].error, new isInstanceOf<HttpException>()); | |
| 210 } | |
| 211 }); | |
| 212 } | |
| OLD | NEW |