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:unittest/unittest.dart'; | |
12 | |
13 import 'test_util.dart'; | |
14 | |
15 class _TestMessage extends Message { | |
16 _TestMessage(Map<String, String> headers, Map<String, Object> context, | |
17 Stream<List<int>> body) | |
18 : super(body, headers: headers, context: context); | |
19 | |
20 Message change({Map<String, String> headers, Map<String, Object> context}) { | |
21 throw new UnimplementedError(); | |
22 } | |
23 } | |
24 | |
25 Message _createMessage({Map<String, String> headers, | |
26 Map<String, Object> context, Stream<List<int>> body}) { | |
27 if (body == null) body = new Stream.fromIterable([]); | |
28 return new _TestMessage(headers, context, body); | |
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(), completion(equals([ | |
123 HELLO_BYTES, | |
124 WORLD_BYTES | |
125 ]))); | |
126 | |
127 controller.add(HELLO_BYTES); | |
128 return new Future(() { | |
129 controller | |
130 ..add(WORLD_BYTES) | |
131 ..close(); | |
132 }); | |
133 }); | |
134 | |
135 test("throws when calling read()/readAsString() multiple times", () { | |
136 var request; | |
137 | |
138 request = _createMessage(); | |
139 expect(request.read().toList(), completion(isEmpty)); | |
140 expect(() => request.read(), throwsStateError); | |
141 | |
142 request = _createMessage(); | |
143 expect(request.readAsString(), completion(isEmpty)); | |
144 expect(() => request.readAsString(), throwsStateError); | |
145 | |
146 request = _createMessage(); | |
147 expect(request.readAsString(), completion(isEmpty)); | |
148 expect(() => request.read(), throwsStateError); | |
149 | |
150 request = _createMessage(); | |
151 expect(request.read().toList(), completion(isEmpty)); | |
152 expect(() => request.readAsString(), throwsStateError); | |
153 }); | |
154 }); | |
155 | |
156 group("contentLength", () { | |
157 test("is null without a content-length header", () { | |
158 var request = _createMessage(); | |
159 expect(request.contentLength, isNull); | |
160 }); | |
161 | |
162 test("comes from the content-length header", () { | |
163 var request = _createMessage(headers: { | |
164 'content-length': '42' | |
165 }); | |
166 expect(request.contentLength, 42); | |
167 }); | |
168 }); | |
169 | |
170 group("mimeType", () { | |
171 test("is null without a content-type header", () { | |
172 expect(_createMessage().mimeType, isNull); | |
173 }); | |
174 | |
175 test("comes from the content-type header", () { | |
176 expect(_createMessage(headers: { | |
177 'content-type': 'text/plain' | |
178 }).mimeType, equals('text/plain')); | |
179 }); | |
180 | |
181 test("doesn't include parameters", () { | |
182 expect(_createMessage(headers: { | |
183 'content-type': 'text/plain; foo=bar; bar=baz' | |
184 }).mimeType, equals('text/plain')); | |
185 }); | |
186 }); | |
187 | |
188 group("encoding", () { | |
189 test("is null without a content-type header", () { | |
190 expect(_createMessage().encoding, isNull); | |
191 }); | |
192 | |
193 test("is null without a charset parameter", () { | |
194 expect(_createMessage(headers: { | |
195 'content-type': 'text/plain' | |
196 }).encoding, isNull); | |
197 }); | |
198 | |
199 test("is null with an unrecognized charset parameter", () { | |
200 expect(_createMessage(headers: { | |
201 'content-type': 'text/plain; charset=fblthp' | |
202 }).encoding, isNull); | |
203 }); | |
204 | |
205 test("comes from the content-type charset parameter", () { | |
206 expect(_createMessage(headers: { | |
207 'content-type': 'text/plain; charset=iso-8859-1' | |
208 }).encoding, equals(LATIN1)); | |
209 }); | |
210 }); | |
211 } | |
OLD | NEW |