OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 library shelf.message_test; |
| 6 |
| 7 import 'dart:async'; |
| 8 import 'dart:convert'; |
| 9 |
| 10 import 'package:shelf/src/message.dart'; |
| 11 import 'package:test/test.dart'; |
| 12 |
| 13 import 'test_util.dart'; |
| 14 |
| 15 class _TestMessage extends Message { |
| 16 _TestMessage(Map<String, String> headers, Map<String, Object> context, body, |
| 17 Encoding encoding) |
| 18 : super(body, headers: headers, context: context, encoding: encoding); |
| 19 |
| 20 Message change({Map<String, String> headers, Map<String, Object> context, |
| 21 body}) { |
| 22 throw new UnimplementedError(); |
| 23 } |
| 24 } |
| 25 |
| 26 Message _createMessage({Map<String, String> headers, |
| 27 Map<String, Object> context, body, Encoding encoding}) { |
| 28 return new _TestMessage(headers, context, body, encoding); |
| 29 } |
| 30 |
| 31 void main() { |
| 32 group('headers', () { |
| 33 test('message headers are case insensitive', () { |
| 34 var message = _createMessage(headers: {'foo': 'bar'}); |
| 35 |
| 36 expect(message.headers, containsPair('foo', 'bar')); |
| 37 expect(message.headers, containsPair('Foo', 'bar')); |
| 38 expect(message.headers, containsPair('FOO', 'bar')); |
| 39 }); |
| 40 |
| 41 test('null header value becomes empty, immutable', () { |
| 42 var message = _createMessage(); |
| 43 expect(message.headers, isEmpty); |
| 44 expect(() => message.headers['h1'] = 'value1', throwsUnsupportedError); |
| 45 }); |
| 46 |
| 47 test('headers are immutable', () { |
| 48 var message = _createMessage(headers: {'h1': 'value1'}); |
| 49 expect(() => message.headers['h1'] = 'value1', throwsUnsupportedError); |
| 50 expect(() => message.headers['h1'] = 'value2', throwsUnsupportedError); |
| 51 expect(() => message.headers['h2'] = 'value2', throwsUnsupportedError); |
| 52 }); |
| 53 }); |
| 54 |
| 55 group('context', () { |
| 56 test('is accessible', () { |
| 57 var message = _createMessage(context: {'foo': 'bar'}); |
| 58 expect(message.context, containsPair('foo', 'bar')); |
| 59 }); |
| 60 |
| 61 test('null context value becomes empty and immutable', () { |
| 62 var message = _createMessage(); |
| 63 expect(message.context, isEmpty); |
| 64 expect(() => message.context['key'] = 'value', throwsUnsupportedError); |
| 65 }); |
| 66 |
| 67 test('is immutable', () { |
| 68 var message = _createMessage(context: {'key': 'value'}); |
| 69 expect(() => message.context['key'] = 'value', throwsUnsupportedError); |
| 70 expect(() => message.context['key2'] = 'value', throwsUnsupportedError); |
| 71 }); |
| 72 }); |
| 73 |
| 74 group("readAsString", () { |
| 75 test("supports a null body", () { |
| 76 var request = _createMessage(); |
| 77 expect(request.readAsString(), completion(equals(""))); |
| 78 }); |
| 79 |
| 80 test("supports a Stream<List<int>> body", () { |
| 81 var controller = new StreamController(); |
| 82 var request = _createMessage(body: controller.stream); |
| 83 expect(request.readAsString(), completion(equals("hello, world"))); |
| 84 |
| 85 controller.add(HELLO_BYTES); |
| 86 return new Future(() { |
| 87 controller |
| 88 ..add(WORLD_BYTES) |
| 89 ..close(); |
| 90 }); |
| 91 }); |
| 92 |
| 93 test("defaults to UTF-8", () { |
| 94 var request = _createMessage(body: new Stream.fromIterable([[195, 168]])); |
| 95 expect(request.readAsString(), completion(equals("è"))); |
| 96 }); |
| 97 |
| 98 test("the content-type header overrides the default", () { |
| 99 var request = _createMessage( |
| 100 headers: {'content-type': 'text/plain; charset=iso-8859-1'}, |
| 101 body: new Stream.fromIterable([[195, 168]])); |
| 102 expect(request.readAsString(), completion(equals("è"))); |
| 103 }); |
| 104 |
| 105 test("an explicit encoding overrides the content-type header", () { |
| 106 var request = _createMessage( |
| 107 headers: {'content-type': 'text/plain; charset=iso-8859-1'}, |
| 108 body: new Stream.fromIterable([[195, 168]])); |
| 109 expect(request.readAsString(LATIN1), completion(equals("è"))); |
| 110 }); |
| 111 }); |
| 112 |
| 113 group("read", () { |
| 114 test("supports a null body", () { |
| 115 var request = _createMessage(); |
| 116 expect(request.read().toList(), completion(isEmpty)); |
| 117 }); |
| 118 |
| 119 test("supports a Stream<List<int>> body", () { |
| 120 var controller = new StreamController(); |
| 121 var request = _createMessage(body: controller.stream); |
| 122 expect(request.read().toList(), |
| 123 completion(equals([HELLO_BYTES, WORLD_BYTES]))); |
| 124 |
| 125 controller.add(HELLO_BYTES); |
| 126 return new Future(() { |
| 127 controller |
| 128 ..add(WORLD_BYTES) |
| 129 ..close(); |
| 130 }); |
| 131 }); |
| 132 |
| 133 test("throws when calling read()/readAsString() multiple times", () { |
| 134 var request; |
| 135 |
| 136 request = _createMessage(); |
| 137 expect(request.read().toList(), completion(isEmpty)); |
| 138 expect(() => request.read(), throwsStateError); |
| 139 |
| 140 request = _createMessage(); |
| 141 expect(request.readAsString(), completion(isEmpty)); |
| 142 expect(() => request.readAsString(), throwsStateError); |
| 143 |
| 144 request = _createMessage(); |
| 145 expect(request.readAsString(), completion(isEmpty)); |
| 146 expect(() => request.read(), throwsStateError); |
| 147 |
| 148 request = _createMessage(); |
| 149 expect(request.read().toList(), completion(isEmpty)); |
| 150 expect(() => request.readAsString(), throwsStateError); |
| 151 }); |
| 152 }); |
| 153 |
| 154 group("contentLength", () { |
| 155 test("is null without a content-length header", () { |
| 156 var request = _createMessage(); |
| 157 expect(request.contentLength, isNull); |
| 158 }); |
| 159 |
| 160 test("comes from the content-length header", () { |
| 161 var request = _createMessage(headers: {'content-length': '42'}); |
| 162 expect(request.contentLength, 42); |
| 163 }); |
| 164 }); |
| 165 |
| 166 group("mimeType", () { |
| 167 test("is null without a content-type header", () { |
| 168 expect(_createMessage().mimeType, isNull); |
| 169 }); |
| 170 |
| 171 test("comes from the content-type header", () { |
| 172 expect(_createMessage(headers: {'content-type': 'text/plain'}).mimeType, |
| 173 equals('text/plain')); |
| 174 }); |
| 175 |
| 176 test("doesn't include parameters", () { |
| 177 expect(_createMessage( |
| 178 headers: { |
| 179 'content-type': 'text/plain; foo=bar; bar=baz' |
| 180 }).mimeType, equals('text/plain')); |
| 181 }); |
| 182 }); |
| 183 |
| 184 group("encoding", () { |
| 185 test("is null without a content-type header", () { |
| 186 expect(_createMessage().encoding, isNull); |
| 187 }); |
| 188 |
| 189 test("is null without a charset parameter", () { |
| 190 expect(_createMessage(headers: {'content-type': 'text/plain'}).encoding, |
| 191 isNull); |
| 192 }); |
| 193 |
| 194 test("is null with an unrecognized charset parameter", () { |
| 195 expect(_createMessage( |
| 196 headers: {'content-type': 'text/plain; charset=fblthp'}).encoding, |
| 197 isNull); |
| 198 }); |
| 199 |
| 200 test("comes from the content-type charset parameter", () { |
| 201 expect(_createMessage( |
| 202 headers: { |
| 203 'content-type': 'text/plain; charset=iso-8859-1' |
| 204 }).encoding, equals(LATIN1)); |
| 205 }); |
| 206 |
| 207 test("defaults to encoding a String as UTF-8", () { |
| 208 expect(_createMessage(body: "è").read().toList(), |
| 209 completion(equals([[195, 168]]))); |
| 210 }); |
| 211 |
| 212 test("uses the explicit encoding if available", () { |
| 213 expect(_createMessage(body: "è", encoding: LATIN1).read().toList(), |
| 214 completion(equals([[232]]))); |
| 215 }); |
| 216 |
| 217 test("adds an explicit encoding to the content-type", () { |
| 218 var request = _createMessage( |
| 219 body: "è", encoding: LATIN1, headers: {'content-type': 'text/plain'}); |
| 220 expect(request.headers, |
| 221 containsPair('content-type', 'text/plain; charset=iso-8859-1')); |
| 222 }); |
| 223 |
| 224 test("sets an absent content-type to application/octet-stream in order to " |
| 225 "set the charset", () { |
| 226 var request = _createMessage(body: "è", encoding: LATIN1); |
| 227 expect(request.headers, containsPair( |
| 228 'content-type', 'application/octet-stream; charset=iso-8859-1')); |
| 229 }); |
| 230 |
| 231 test("overwrites an existing charset if given an explicit encoding", () { |
| 232 var request = _createMessage( |
| 233 body: "è", |
| 234 encoding: LATIN1, |
| 235 headers: {'content-type': 'text/plain; charset=whatever'}); |
| 236 expect(request.headers, |
| 237 containsPair('content-type', 'text/plain; charset=iso-8859-1')); |
| 238 }); |
| 239 }); |
| 240 } |
OLD | NEW |