@angular/common 21.0.0-next.9 → 21.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v21.0.0-next.9
2
+ * @license Angular v21.0.0-rc.0
3
3
  * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
@@ -11,351 +11,300 @@ import { HttpHeaders, HttpResponse, HttpErrorResponse, HttpStatusCode, HttpEvent
11
11
  import 'rxjs/operators';
12
12
  import './_xhr-chunk.mjs';
13
13
 
14
- /**
15
- * Controller to be injected into tests, that allows for mocking and flushing
16
- * of requests.
17
- *
18
- * @publicApi
19
- */
20
- class HttpTestingController {
21
- }
14
+ class HttpTestingController {}
22
15
 
23
- /**
24
- * A mock requests that was received and is ready to be answered.
25
- *
26
- * This interface allows access to the underlying `HttpRequest`, and allows
27
- * responding with `HttpEvent`s or `HttpErrorResponse`s.
28
- *
29
- * @publicApi
30
- */
31
16
  class TestRequest {
32
- request;
33
- observer;
34
- /**
35
- * Whether the request was cancelled after it was sent.
36
- */
37
- get cancelled() {
38
- return this._cancelled;
17
+ request;
18
+ observer;
19
+ get cancelled() {
20
+ return this._cancelled;
21
+ }
22
+ _cancelled = false;
23
+ constructor(request, observer) {
24
+ this.request = request;
25
+ this.observer = observer;
26
+ }
27
+ flush(body, opts = {}) {
28
+ if (this.cancelled) {
29
+ throw new Error(`Cannot flush a cancelled request.`);
39
30
  }
40
- /**
41
- * @internal set by `HttpClientTestingBackend`
42
- */
43
- _cancelled = false;
44
- constructor(request, observer) {
45
- this.request = request;
46
- this.observer = observer;
31
+ const url = this.request.urlWithParams;
32
+ const headers = opts.headers instanceof HttpHeaders ? opts.headers : new HttpHeaders(opts.headers);
33
+ body = _maybeConvertBody(this.request.responseType, body);
34
+ let statusText = opts.statusText;
35
+ let status = opts.status !== undefined ? opts.status : HttpStatusCode.Ok;
36
+ if (opts.status === undefined) {
37
+ if (body === null) {
38
+ status = HttpStatusCode.NoContent;
39
+ statusText ||= 'No Content';
40
+ } else {
41
+ statusText ||= 'OK';
42
+ }
47
43
  }
48
- /**
49
- * Resolve the request by returning a body plus additional HTTP information (such as response
50
- * headers) if provided.
51
- * If the request specifies an expected body type, the body is converted into the requested type.
52
- * Otherwise, the body is converted to `JSON` by default.
53
- *
54
- * Both successful and unsuccessful responses can be delivered via `flush()`.
55
- */
56
- flush(body, opts = {}) {
57
- if (this.cancelled) {
58
- throw new Error(`Cannot flush a cancelled request.`);
59
- }
60
- const url = this.request.urlWithParams;
61
- const headers = opts.headers instanceof HttpHeaders ? opts.headers : new HttpHeaders(opts.headers);
62
- body = _maybeConvertBody(this.request.responseType, body);
63
- let statusText = opts.statusText;
64
- let status = opts.status !== undefined ? opts.status : HttpStatusCode.Ok;
65
- if (opts.status === undefined) {
66
- if (body === null) {
67
- status = HttpStatusCode.NoContent;
68
- statusText ||= 'No Content';
69
- }
70
- else {
71
- statusText ||= 'OK';
72
- }
73
- }
74
- if (statusText === undefined) {
75
- throw new Error('statusText is required when setting a custom status.');
76
- }
77
- if (status >= 200 && status < 300) {
78
- this.observer.next(new HttpResponse({ body, headers, status, statusText, url }));
79
- this.observer.complete();
80
- }
81
- else {
82
- this.observer.error(new HttpErrorResponse({ error: body, headers, status, statusText, url }));
83
- }
44
+ if (statusText === undefined) {
45
+ throw new Error('statusText is required when setting a custom status.');
84
46
  }
85
- error(error, opts = {}) {
86
- if (this.cancelled) {
87
- throw new Error(`Cannot return an error for a cancelled request.`);
88
- }
89
- const headers = opts.headers instanceof HttpHeaders ? opts.headers : new HttpHeaders(opts.headers);
90
- this.observer.error(new HttpErrorResponse({
91
- error,
92
- headers,
93
- status: opts.status || 0,
94
- statusText: opts.statusText || '',
95
- url: this.request.urlWithParams,
96
- }));
47
+ if (status >= 200 && status < 300) {
48
+ this.observer.next(new HttpResponse({
49
+ body,
50
+ headers,
51
+ status,
52
+ statusText,
53
+ url
54
+ }));
55
+ this.observer.complete();
56
+ } else {
57
+ this.observer.error(new HttpErrorResponse({
58
+ error: body,
59
+ headers,
60
+ status,
61
+ statusText,
62
+ url
63
+ }));
97
64
  }
98
- /**
99
- * Deliver an arbitrary `HttpEvent` (such as a progress event) on the response stream for this
100
- * request.
101
- */
102
- event(event) {
103
- if (this.cancelled) {
104
- throw new Error(`Cannot send events to a cancelled request.`);
105
- }
106
- this.observer.next(event);
65
+ }
66
+ error(error, opts = {}) {
67
+ if (this.cancelled) {
68
+ throw new Error(`Cannot return an error for a cancelled request.`);
107
69
  }
70
+ const headers = opts.headers instanceof HttpHeaders ? opts.headers : new HttpHeaders(opts.headers);
71
+ this.observer.error(new HttpErrorResponse({
72
+ error,
73
+ headers,
74
+ status: opts.status || 0,
75
+ statusText: opts.statusText || '',
76
+ url: this.request.urlWithParams
77
+ }));
78
+ }
79
+ event(event) {
80
+ if (this.cancelled) {
81
+ throw new Error(`Cannot send events to a cancelled request.`);
82
+ }
83
+ this.observer.next(event);
84
+ }
108
85
  }
109
- /**
110
- * Helper function to convert a response body to an ArrayBuffer.
111
- */
112
86
  function _toArrayBufferBody(body) {
113
- if (typeof ArrayBuffer === 'undefined') {
114
- throw new Error('ArrayBuffer responses are not supported on this platform.');
115
- }
116
- if (body instanceof ArrayBuffer) {
117
- return body;
118
- }
119
- throw new Error('Automatic conversion to ArrayBuffer is not supported for response type.');
87
+ if (typeof ArrayBuffer === 'undefined') {
88
+ throw new Error('ArrayBuffer responses are not supported on this platform.');
89
+ }
90
+ if (body instanceof ArrayBuffer) {
91
+ return body;
92
+ }
93
+ throw new Error('Automatic conversion to ArrayBuffer is not supported for response type.');
120
94
  }
121
- /**
122
- * Helper function to convert a response body to a Blob.
123
- */
124
95
  function _toBlob(body) {
125
- if (typeof Blob === 'undefined') {
126
- throw new Error('Blob responses are not supported on this platform.');
127
- }
128
- if (body instanceof Blob) {
129
- return body;
130
- }
131
- if (ArrayBuffer && body instanceof ArrayBuffer) {
132
- return new Blob([body]);
133
- }
134
- throw new Error('Automatic conversion to Blob is not supported for response type.');
96
+ if (typeof Blob === 'undefined') {
97
+ throw new Error('Blob responses are not supported on this platform.');
98
+ }
99
+ if (body instanceof Blob) {
100
+ return body;
101
+ }
102
+ if (ArrayBuffer && body instanceof ArrayBuffer) {
103
+ return new Blob([body]);
104
+ }
105
+ throw new Error('Automatic conversion to Blob is not supported for response type.');
135
106
  }
136
- /**
137
- * Helper function to convert a response body to JSON data.
138
- */
139
107
  function _toJsonBody(body, format = 'JSON') {
140
- if (typeof ArrayBuffer !== 'undefined' && body instanceof ArrayBuffer) {
141
- throw new Error(`Automatic conversion to ${format} is not supported for ArrayBuffers.`);
142
- }
143
- if (typeof Blob !== 'undefined' && body instanceof Blob) {
144
- throw new Error(`Automatic conversion to ${format} is not supported for Blobs.`);
145
- }
146
- if (typeof body === 'string' ||
147
- typeof body === 'number' ||
148
- typeof body === 'object' ||
149
- typeof body === 'boolean' ||
150
- Array.isArray(body)) {
151
- return body;
152
- }
153
- throw new Error(`Automatic conversion to ${format} is not supported for response type.`);
108
+ if (typeof ArrayBuffer !== 'undefined' && body instanceof ArrayBuffer) {
109
+ throw new Error(`Automatic conversion to ${format} is not supported for ArrayBuffers.`);
110
+ }
111
+ if (typeof Blob !== 'undefined' && body instanceof Blob) {
112
+ throw new Error(`Automatic conversion to ${format} is not supported for Blobs.`);
113
+ }
114
+ if (typeof body === 'string' || typeof body === 'number' || typeof body === 'object' || typeof body === 'boolean' || Array.isArray(body)) {
115
+ return body;
116
+ }
117
+ throw new Error(`Automatic conversion to ${format} is not supported for response type.`);
154
118
  }
155
- /**
156
- * Helper function to convert a response body to a string.
157
- */
158
119
  function _toTextBody(body) {
159
- if (typeof body === 'string') {
160
- return body;
161
- }
162
- if (typeof ArrayBuffer !== 'undefined' && body instanceof ArrayBuffer) {
163
- throw new Error('Automatic conversion to text is not supported for ArrayBuffers.');
164
- }
165
- if (typeof Blob !== 'undefined' && body instanceof Blob) {
166
- throw new Error('Automatic conversion to text is not supported for Blobs.');
167
- }
168
- return JSON.stringify(_toJsonBody(body, 'text'));
120
+ if (typeof body === 'string') {
121
+ return body;
122
+ }
123
+ if (typeof ArrayBuffer !== 'undefined' && body instanceof ArrayBuffer) {
124
+ throw new Error('Automatic conversion to text is not supported for ArrayBuffers.');
125
+ }
126
+ if (typeof Blob !== 'undefined' && body instanceof Blob) {
127
+ throw new Error('Automatic conversion to text is not supported for Blobs.');
128
+ }
129
+ return JSON.stringify(_toJsonBody(body, 'text'));
169
130
  }
170
- /**
171
- * Convert a response body to the requested type.
172
- */
173
131
  function _maybeConvertBody(responseType, body) {
174
- if (body === null) {
175
- return null;
176
- }
177
- switch (responseType) {
178
- case 'arraybuffer':
179
- return _toArrayBufferBody(body);
180
- case 'blob':
181
- return _toBlob(body);
182
- case 'json':
183
- return _toJsonBody(body);
184
- case 'text':
185
- return _toTextBody(body);
186
- default:
187
- throw new Error(`Unsupported responseType: ${responseType}`);
188
- }
132
+ if (body === null) {
133
+ return null;
134
+ }
135
+ switch (responseType) {
136
+ case 'arraybuffer':
137
+ return _toArrayBufferBody(body);
138
+ case 'blob':
139
+ return _toBlob(body);
140
+ case 'json':
141
+ return _toJsonBody(body);
142
+ case 'text':
143
+ return _toTextBody(body);
144
+ default:
145
+ throw new Error(`Unsupported responseType: ${responseType}`);
146
+ }
189
147
  }
190
148
 
191
- /**
192
- * A testing backend for `HttpClient` which both acts as an `HttpBackend`
193
- * and as the `HttpTestingController`.
194
- *
195
- * `HttpClientTestingBackend` works by keeping a list of all open requests.
196
- * As requests come in, they're added to the list. Users can assert that specific
197
- * requests were made and then flush them. In the end, a verify() method asserts
198
- * that no unexpected requests were made.
199
- *
200
- *
201
- */
202
149
  class HttpClientTestingBackend {
203
- /**
204
- * List of pending requests which have not yet been expected.
205
- */
206
- open = [];
207
- /**
208
- * Used when checking if we need to throw the NOT_USING_FETCH_BACKEND_IN_SSR error
209
- */
210
- isTestingBackend = true;
211
- /**
212
- * Handle an incoming request by queueing it in the list of open requests.
213
- */
214
- handle(req) {
215
- return new Observable((observer) => {
216
- const testReq = new TestRequest(req, observer);
217
- this.open.push(testReq);
218
- observer.next({ type: HttpEventType.Sent });
219
- return () => {
220
- testReq._cancelled = true;
221
- };
222
- });
150
+ open = [];
151
+ isTestingBackend = true;
152
+ handle(req) {
153
+ return new Observable(observer => {
154
+ const testReq = new TestRequest(req, observer);
155
+ this.open.push(testReq);
156
+ observer.next({
157
+ type: HttpEventType.Sent
158
+ });
159
+ return () => {
160
+ testReq._cancelled = true;
161
+ };
162
+ });
163
+ }
164
+ _match(match) {
165
+ if (typeof match === 'string') {
166
+ return this.open.filter(testReq => testReq.request.urlWithParams === match);
167
+ } else if (typeof match === 'function') {
168
+ return this.open.filter(testReq => match(testReq.request));
169
+ } else {
170
+ return this.open.filter(testReq => (!match.method || testReq.request.method === match.method.toUpperCase()) && (!match.url || testReq.request.urlWithParams === match.url));
223
171
  }
224
- /**
225
- * Helper function to search for requests in the list of open requests.
226
- */
227
- _match(match) {
228
- if (typeof match === 'string') {
229
- return this.open.filter((testReq) => testReq.request.urlWithParams === match);
230
- }
231
- else if (typeof match === 'function') {
232
- return this.open.filter((testReq) => match(testReq.request));
233
- }
234
- else {
235
- return this.open.filter((testReq) => (!match.method || testReq.request.method === match.method.toUpperCase()) &&
236
- (!match.url || testReq.request.urlWithParams === match.url));
237
- }
172
+ }
173
+ match(match) {
174
+ const results = this._match(match);
175
+ results.forEach(result => {
176
+ const index = this.open.indexOf(result);
177
+ if (index !== -1) {
178
+ this.open.splice(index, 1);
179
+ }
180
+ });
181
+ return results;
182
+ }
183
+ expectOne(match, description) {
184
+ description ||= this.descriptionFromMatcher(match);
185
+ const matches = this.match(match);
186
+ if (matches.length > 1) {
187
+ throw new Error(`Expected one matching request for criteria "${description}", found ${matches.length} requests.`);
238
188
  }
239
- /**
240
- * Search for requests in the list of open requests, and return all that match
241
- * without asserting anything about the number of matches.
242
- */
243
- match(match) {
244
- const results = this._match(match);
245
- results.forEach((result) => {
246
- const index = this.open.indexOf(result);
247
- if (index !== -1) {
248
- this.open.splice(index, 1);
249
- }
250
- });
251
- return results;
189
+ if (matches.length === 0) {
190
+ let message = `Expected one matching request for criteria "${description}", found none.`;
191
+ if (this.open.length > 0) {
192
+ const requests = this.open.map(describeRequest).join(', ');
193
+ message += ` Requests received are: ${requests}.`;
194
+ }
195
+ throw new Error(message);
252
196
  }
253
- /**
254
- * Expect that a single outstanding request matches the given matcher, and return
255
- * it.
256
- *
257
- * Requests returned through this API will no longer be in the list of open requests,
258
- * and thus will not match twice.
259
- */
260
- expectOne(match, description) {
261
- description ||= this.descriptionFromMatcher(match);
262
- const matches = this.match(match);
263
- if (matches.length > 1) {
264
- throw new Error(`Expected one matching request for criteria "${description}", found ${matches.length} requests.`);
265
- }
266
- if (matches.length === 0) {
267
- let message = `Expected one matching request for criteria "${description}", found none.`;
268
- if (this.open.length > 0) {
269
- // Show the methods and URLs of open requests in the error, for convenience.
270
- const requests = this.open.map(describeRequest).join(', ');
271
- message += ` Requests received are: ${requests}.`;
272
- }
273
- throw new Error(message);
274
- }
275
- return matches[0];
197
+ return matches[0];
198
+ }
199
+ expectNone(match, description) {
200
+ description ||= this.descriptionFromMatcher(match);
201
+ const matches = this.match(match);
202
+ if (matches.length > 0) {
203
+ throw new Error(`Expected zero matching requests for criteria "${description}", found ${matches.length}.`);
276
204
  }
277
- /**
278
- * Expect that no outstanding requests match the given matcher, and throw an error
279
- * if any do.
280
- */
281
- expectNone(match, description) {
282
- description ||= this.descriptionFromMatcher(match);
283
- const matches = this.match(match);
284
- if (matches.length > 0) {
285
- throw new Error(`Expected zero matching requests for criteria "${description}", found ${matches.length}.`);
286
- }
205
+ }
206
+ verify(opts = {}) {
207
+ let open = this.open;
208
+ if (opts.ignoreCancelled) {
209
+ open = open.filter(testReq => !testReq.cancelled);
287
210
  }
288
- /**
289
- * Validate that there are no outstanding requests.
290
- */
291
- verify(opts = {}) {
292
- let open = this.open;
293
- // It's possible that some requests may be cancelled, and this is expected.
294
- // The user can ask to ignore open requests which have been cancelled.
295
- if (opts.ignoreCancelled) {
296
- open = open.filter((testReq) => !testReq.cancelled);
297
- }
298
- if (open.length > 0) {
299
- // Show the methods and URLs of open requests in the error, for convenience.
300
- const requests = open.map(describeRequest).join(', ');
301
- throw new Error(`Expected no open requests, found ${open.length}: ${requests}`);
302
- }
211
+ if (open.length > 0) {
212
+ const requests = open.map(describeRequest).join(', ');
213
+ throw new Error(`Expected no open requests, found ${open.length}: ${requests}`);
303
214
  }
304
- descriptionFromMatcher(matcher) {
305
- if (typeof matcher === 'string') {
306
- return `Match URL: ${matcher}`;
307
- }
308
- else if (typeof matcher === 'object') {
309
- const method = matcher.method || '(any)';
310
- const url = matcher.url || '(any)';
311
- return `Match method: ${method}, URL: ${url}`;
312
- }
313
- else {
314
- return `Match by function: ${matcher.name}`;
315
- }
215
+ }
216
+ descriptionFromMatcher(matcher) {
217
+ if (typeof matcher === 'string') {
218
+ return `Match URL: ${matcher}`;
219
+ } else if (typeof matcher === 'object') {
220
+ const method = matcher.method || '(any)';
221
+ const url = matcher.url || '(any)';
222
+ return `Match method: ${method}, URL: ${url}`;
223
+ } else {
224
+ return `Match by function: ${matcher.name}`;
316
225
  }
317
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: HttpClientTestingBackend, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
318
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: HttpClientTestingBackend });
226
+ }
227
+ static ɵfac = i0.ɵɵngDeclareFactory({
228
+ minVersion: "12.0.0",
229
+ version: "21.0.0-rc.0",
230
+ ngImport: i0,
231
+ type: HttpClientTestingBackend,
232
+ deps: [],
233
+ target: i0.ɵɵFactoryTarget.Injectable
234
+ });
235
+ static ɵprov = i0.ɵɵngDeclareInjectable({
236
+ minVersion: "12.0.0",
237
+ version: "21.0.0-rc.0",
238
+ ngImport: i0,
239
+ type: HttpClientTestingBackend
240
+ });
319
241
  }
320
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: HttpClientTestingBackend, decorators: [{
321
- type: Injectable
322
- }] });
242
+ i0.ɵɵngDeclareClassMetadata({
243
+ minVersion: "12.0.0",
244
+ version: "21.0.0-rc.0",
245
+ ngImport: i0,
246
+ type: HttpClientTestingBackend,
247
+ decorators: [{
248
+ type: Injectable
249
+ }]
250
+ });
323
251
  function describeRequest(testRequest) {
324
- const url = testRequest.request.urlWithParams;
325
- const method = testRequest.request.method;
326
- return `${method} ${url}`;
252
+ const url = testRequest.request.urlWithParams;
253
+ const method = testRequest.request.method;
254
+ return `${method} ${url}`;
327
255
  }
328
256
 
329
257
  function provideHttpClientTesting() {
330
- return [
331
- HttpClientTestingBackend,
332
- { provide: HttpBackend, useExisting: HttpClientTestingBackend },
333
- { provide: HttpTestingController, useExisting: HttpClientTestingBackend },
334
- { provide: REQUESTS_CONTRIBUTE_TO_STABILITY, useValue: false },
335
- ];
258
+ return [HttpClientTestingBackend, {
259
+ provide: HttpBackend,
260
+ useExisting: HttpClientTestingBackend
261
+ }, {
262
+ provide: HttpTestingController,
263
+ useExisting: HttpClientTestingBackend
264
+ }, {
265
+ provide: REQUESTS_CONTRIBUTE_TO_STABILITY,
266
+ useValue: false
267
+ }];
336
268
  }
337
269
 
338
- /**
339
- * Configures `HttpClientTestingBackend` as the `HttpBackend` used by `HttpClient`.
340
- *
341
- * Inject `HttpTestingController` to expect and flush requests in your tests.
342
- *
343
- * @publicApi
344
- *
345
- * @deprecated Add `provideHttpClientTesting()` to your providers instead.
346
- */
347
270
  class HttpClientTestingModule {
348
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: HttpClientTestingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
349
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.0.0-next.9", ngImport: i0, type: HttpClientTestingModule, imports: [HttpClientModule] });
350
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: HttpClientTestingModule, providers: [provideHttpClientTesting()], imports: [HttpClientModule] });
271
+ static ɵfac = i0.ɵɵngDeclareFactory({
272
+ minVersion: "12.0.0",
273
+ version: "21.0.0-rc.0",
274
+ ngImport: i0,
275
+ type: HttpClientTestingModule,
276
+ deps: [],
277
+ target: i0.ɵɵFactoryTarget.NgModule
278
+ });
279
+ static ɵmod = i0.ɵɵngDeclareNgModule({
280
+ minVersion: "14.0.0",
281
+ version: "21.0.0-rc.0",
282
+ ngImport: i0,
283
+ type: HttpClientTestingModule,
284
+ imports: [HttpClientModule]
285
+ });
286
+ static ɵinj = i0.ɵɵngDeclareInjector({
287
+ minVersion: "12.0.0",
288
+ version: "21.0.0-rc.0",
289
+ ngImport: i0,
290
+ type: HttpClientTestingModule,
291
+ providers: [provideHttpClientTesting()],
292
+ imports: [HttpClientModule]
293
+ });
351
294
  }
352
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0-next.9", ngImport: i0, type: HttpClientTestingModule, decorators: [{
353
- type: NgModule,
354
- args: [{
355
- imports: [HttpClientModule],
356
- providers: [provideHttpClientTesting()],
357
- }]
358
- }] });
295
+ i0.ɵɵngDeclareClassMetadata({
296
+ minVersion: "12.0.0",
297
+ version: "21.0.0-rc.0",
298
+ ngImport: i0,
299
+ type: HttpClientTestingModule,
300
+ decorators: [{
301
+ type: NgModule,
302
+ args: [{
303
+ imports: [HttpClientModule],
304
+ providers: [provideHttpClientTesting()]
305
+ }]
306
+ }]
307
+ });
359
308
 
360
309
  export { HttpClientTestingModule, HttpTestingController, TestRequest, provideHttpClientTesting };
361
310
  //# sourceMappingURL=http-testing.mjs.map