@ -30,9 +30,13 @@ export class BrowserJsonp {
|
||||
return node;
|
||||
}
|
||||
|
||||
nextRequestID(): string { return `__req${_nextRequestId++}`; }
|
||||
nextRequestID(): string {
|
||||
return `__req${_nextRequestId++}`;
|
||||
}
|
||||
|
||||
requestCallback(id: string): string { return `${JSONP_HOME}.${id}.finished`; }
|
||||
requestCallback(id: string): string {
|
||||
return `${JSONP_HOME}.${id}.finished`;
|
||||
}
|
||||
|
||||
exposeConnection(id: string, connection: any) {
|
||||
const connections = _getJsonpConnections();
|
||||
@ -45,7 +49,9 @@ export class BrowserJsonp {
|
||||
}
|
||||
|
||||
// Attach the <script> element to the DOM
|
||||
send(node: any) { document.body.appendChild(<Node>(node)); }
|
||||
send(node: any) {
|
||||
document.body.appendChild(<Node>(node));
|
||||
}
|
||||
|
||||
// Remove <script> element from the DOM
|
||||
cleanup(node: any) {
|
||||
|
@ -19,5 +19,7 @@ import {Injectable} from '@angular/core';
|
||||
@Injectable()
|
||||
export class BrowserXhr {
|
||||
constructor() {}
|
||||
build(): any { return <any>(new XMLHttpRequest()); }
|
||||
build(): any {
|
||||
return <any>(new XMLHttpRequest());
|
||||
}
|
||||
}
|
||||
|
@ -28,9 +28,9 @@ const JSONP_ERR_WRONG_METHOD = 'JSONP requests must use GET request method.';
|
||||
*/
|
||||
export class JSONPConnection implements Connection {
|
||||
// TODO(issue/24571): remove '!'.
|
||||
private _id !: string;
|
||||
private _id!: string;
|
||||
// TODO(issue/24571): remove '!'.
|
||||
private _script !: Element;
|
||||
private _script!: Element;
|
||||
private _responseData: any;
|
||||
private _finished: boolean = false;
|
||||
|
||||
@ -38,7 +38,7 @@ export class JSONPConnection implements Connection {
|
||||
* The {@link ReadyState} of this request.
|
||||
*/
|
||||
// TODO(issue/24571): remove '!'.
|
||||
readyState !: ReadyState;
|
||||
readyState!: ReadyState;
|
||||
|
||||
/**
|
||||
* The outgoing HTTP request.
|
||||
@ -58,7 +58,6 @@ export class JSONPConnection implements Connection {
|
||||
}
|
||||
this.request = req;
|
||||
this.response = new Observable<Response>((responseObserver: Observer<Response>) => {
|
||||
|
||||
this.readyState = ReadyState.Loading;
|
||||
const id = this._id = _dom.nextRequestID();
|
||||
|
||||
|
@ -39,7 +39,7 @@ export class XHRConnection implements Connection {
|
||||
*/
|
||||
response: Observable<Response>;
|
||||
// TODO(issue/24571): remove '!'.
|
||||
readyState !: ReadyState;
|
||||
readyState!: ReadyState;
|
||||
constructor(req: Request, browserXHR: BrowserXhr, baseResponseOptions?: ResponseOptions) {
|
||||
this.request = req;
|
||||
this.response = new Observable<Response>((responseObserver: Observer<Response>) => {
|
||||
@ -116,7 +116,7 @@ export class XHRConnection implements Connection {
|
||||
if (!req.headers.has('Accept')) {
|
||||
req.headers.append('Accept', 'application/json, text/plain, */*');
|
||||
}
|
||||
req.headers.forEach((values, name) => _xhr.setRequestHeader(name !, values.join(',')));
|
||||
req.headers.forEach((values, name) => _xhr.setRequestHeader(name!, values.join(',')));
|
||||
|
||||
// Select the correct buffer type to store the response
|
||||
if (req.responseType != null && _xhr.responseType != null) {
|
||||
|
@ -65,11 +65,15 @@ export class RequestOptions {
|
||||
/**
|
||||
* @deprecated from 4.0.0. Use params instead.
|
||||
*/
|
||||
get search(): URLSearchParams { return this.params; }
|
||||
get search(): URLSearchParams {
|
||||
return this.params;
|
||||
}
|
||||
/**
|
||||
* @deprecated from 4.0.0. Use params instead.
|
||||
*/
|
||||
set search(params: URLSearchParams) { this.params = params; }
|
||||
set search(params: URLSearchParams) {
|
||||
this.params = params;
|
||||
}
|
||||
/**
|
||||
* Enable use credentials for a {@link Request}.
|
||||
*/
|
||||
@ -143,7 +147,7 @@ export class RequestOptions {
|
||||
return this._parseParams(params);
|
||||
}
|
||||
|
||||
private _parseParams(objParams: {[key: string]: any | any[]} = {}): URLSearchParams {
|
||||
private _parseParams(objParams: {[key: string]: any|any[]} = {}): URLSearchParams {
|
||||
const params = new URLSearchParams();
|
||||
Object.keys(objParams).forEach((key: string) => {
|
||||
const value: any|any[] = objParams[key];
|
||||
@ -206,5 +210,7 @@ export class RequestOptions {
|
||||
*/
|
||||
@Injectable()
|
||||
export class BaseRequestOptions extends RequestOptions {
|
||||
constructor() { super({method: RequestMethod.Get, headers: new Headers()}); }
|
||||
constructor() {
|
||||
super({method: RequestMethod.Get, headers: new Headers()});
|
||||
}
|
||||
}
|
||||
|
@ -92,8 +92,8 @@ export abstract class Body {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request's body as a Blob, assuming that body exists.
|
||||
*/
|
||||
* Returns the request's body as a Blob, assuming that body exists.
|
||||
*/
|
||||
blob(): Blob {
|
||||
if (this._body instanceof Blob) {
|
||||
return this._body;
|
||||
|
@ -96,7 +96,7 @@ export class Headers {
|
||||
/**
|
||||
* Deletes all header values for the given name.
|
||||
*/
|
||||
delete (name: string): void {
|
||||
delete(name: string): void {
|
||||
const lcName = name.toLowerCase();
|
||||
this._normalizedNames.delete(lcName);
|
||||
this._headers.delete(lcName);
|
||||
@ -124,12 +124,16 @@ export class Headers {
|
||||
/**
|
||||
* Checks for existence of header by given name.
|
||||
*/
|
||||
has(name: string): boolean { return this._headers.has(name.toLowerCase()); }
|
||||
has(name: string): boolean {
|
||||
return this._headers.has(name.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the names of the headers
|
||||
*/
|
||||
keys(): string[] { return Array.from(this._normalizedNames.values()); }
|
||||
keys(): string[] {
|
||||
return Array.from(this._normalizedNames.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets or overrides header value for given name.
|
||||
@ -148,7 +152,9 @@ export class Headers {
|
||||
/**
|
||||
* Returns values of all headers.
|
||||
*/
|
||||
values(): string[][] { return Array.from(this._headers.values()); }
|
||||
values(): string[][] {
|
||||
return Array.from(this._headers.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string of all headers.
|
||||
@ -160,7 +166,7 @@ export class Headers {
|
||||
this._headers.forEach((values: string[], name: string) => {
|
||||
const split: string[] = [];
|
||||
values.forEach(v => split.push(...v.split(',')));
|
||||
serialized[this._normalizedNames.get(name) !] = split;
|
||||
serialized[this._normalizedNames.get(name)!] = split;
|
||||
});
|
||||
|
||||
return serialized;
|
||||
@ -176,7 +182,9 @@ export class Headers {
|
||||
/**
|
||||
* This method is not implemented.
|
||||
*/
|
||||
entries() { throw new Error('"entries" method is not implemented on Headers class'); }
|
||||
entries() {
|
||||
throw new Error('"entries" method is not implemented on Headers class');
|
||||
}
|
||||
|
||||
private mayBeSetNormalizedName(name: string): void {
|
||||
const lcName = name.toLowerCase();
|
||||
|
@ -20,7 +20,7 @@ function httpRequest(backend: ConnectionBackend, request: Request): Observable<R
|
||||
}
|
||||
|
||||
function mergeOptions(
|
||||
defaultOpts: BaseRequestOptions, providedOpts: RequestOptionsArgs | undefined,
|
||||
defaultOpts: BaseRequestOptions, providedOpts: RequestOptionsArgs|undefined,
|
||||
method: RequestMethod, url: string): RequestArgs {
|
||||
const newOptions = defaultOpts;
|
||||
if (providedOpts) {
|
||||
@ -156,7 +156,7 @@ export class Http {
|
||||
/**
|
||||
* Performs a request with `delete` http method.
|
||||
*/
|
||||
delete (url: string, options?: RequestOptionsArgs): Observable<Response> {
|
||||
delete(url: string, options?: RequestOptionsArgs): Observable<Response> {
|
||||
return this.request(
|
||||
new Request(mergeOptions(this._defaultOptions, options, RequestMethod.Delete, url)));
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import {RequestMethod} from './enums';
|
||||
|
||||
export function normalizeMethodName(method: string | RequestMethod): RequestMethod {
|
||||
export function normalizeMethodName(method: string|RequestMethod): RequestMethod {
|
||||
if (typeof method !== 'string') return method;
|
||||
|
||||
switch (method.toUpperCase()) {
|
||||
|
@ -20,7 +20,9 @@ import {URLSearchParams} from './url_search_params';
|
||||
* @deprecated see https://angular.io/guide/http
|
||||
* @publicApi
|
||||
*/
|
||||
export abstract class ConnectionBackend { abstract createConnection(request: any): Connection; }
|
||||
export abstract class ConnectionBackend {
|
||||
abstract createConnection(request: any): Connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract class from which real connections are derived.
|
||||
@ -30,9 +32,9 @@ export abstract class ConnectionBackend { abstract createConnection(request: any
|
||||
*/
|
||||
export abstract class Connection {
|
||||
// TODO(issue/24571): remove '!'.
|
||||
readyState !: ReadyState;
|
||||
readyState!: ReadyState;
|
||||
// TODO(issue/24571): remove '!'.
|
||||
request !: Request;
|
||||
request!: Request;
|
||||
response: any; // TODO: generic of <Response>;
|
||||
}
|
||||
|
||||
@ -42,7 +44,9 @@ export abstract class Connection {
|
||||
* @deprecated see https://angular.io/guide/http
|
||||
* @publicApi
|
||||
*/
|
||||
export abstract class XSRFStrategy { abstract configureRequest(req: Request): void; }
|
||||
export abstract class XSRFStrategy {
|
||||
abstract configureRequest(req: Request): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for options to construct a RequestOptions, based on
|
||||
@ -66,7 +70,9 @@ export interface RequestOptionsArgs {
|
||||
/**
|
||||
* Required structure when constructing new Request();
|
||||
*/
|
||||
export interface RequestArgs extends RequestOptionsArgs { url: string|null; }
|
||||
export interface RequestArgs extends RequestOptionsArgs {
|
||||
url: string|null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for options to construct a Response, based on
|
||||
|
@ -76,7 +76,7 @@ export class Request extends Body {
|
||||
super();
|
||||
// TODO: assert that url is present
|
||||
const url = requestOptions.url;
|
||||
this.url = requestOptions.url !;
|
||||
this.url = requestOptions.url!;
|
||||
const paramsArg = requestOptions.params || requestOptions.search;
|
||||
if (paramsArg) {
|
||||
let params: string;
|
||||
@ -95,13 +95,13 @@ export class Request extends Body {
|
||||
}
|
||||
}
|
||||
this._body = requestOptions.body;
|
||||
this.method = normalizeMethodName(requestOptions.method !);
|
||||
this.method = normalizeMethodName(requestOptions.method!);
|
||||
// TODO(jeffbcross): implement behavior
|
||||
// Defaults to 'omit', consistent with browser
|
||||
this.headers = new Headers(requestOptions.headers);
|
||||
this.contentType = this.detectContentType();
|
||||
this.withCredentials = requestOptions.withCredentials !;
|
||||
this.responseType = requestOptions.responseType !;
|
||||
this.withCredentials = requestOptions.withCredentials!;
|
||||
this.responseType = requestOptions.responseType!;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,14 +73,14 @@ export class Response extends Body {
|
||||
* the result of a progress event.
|
||||
*/
|
||||
// TODO(issue/24571): remove '!'.
|
||||
bytesLoaded !: number;
|
||||
bytesLoaded!: number;
|
||||
/**
|
||||
* Non-standard property
|
||||
*
|
||||
* Denotes how many bytes are expected in the final response body.
|
||||
*/
|
||||
// TODO(issue/24571): remove '!'.
|
||||
totalBytes !: number;
|
||||
totalBytes!: number;
|
||||
/**
|
||||
* Headers object based on the `Headers` class in the [Fetch
|
||||
* Spec](https://fetch.spec.whatwg.org/#headers-class).
|
||||
@ -90,12 +90,12 @@ export class Response extends Body {
|
||||
constructor(responseOptions: ResponseOptions) {
|
||||
super();
|
||||
this._body = responseOptions.body;
|
||||
this.status = responseOptions.status !;
|
||||
this.status = responseOptions.status!;
|
||||
this.ok = (this.status >= 200 && this.status <= 299);
|
||||
this.statusText = responseOptions.statusText;
|
||||
this.headers = responseOptions.headers;
|
||||
this.type = responseOptions.type !;
|
||||
this.url = responseOptions.url !;
|
||||
this.type = responseOptions.type!;
|
||||
this.url = responseOptions.url!;
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
|
@ -26,9 +26,13 @@ function paramParser(rawParams: string = ''): Map<string, string[]> {
|
||||
* @publicApi
|
||||
**/
|
||||
export class QueryEncoder {
|
||||
encodeKey(key: string): string { return standardEncoding(key); }
|
||||
encodeKey(key: string): string {
|
||||
return standardEncoding(key);
|
||||
}
|
||||
|
||||
encodeValue(value: string): string { return standardEncoding(value); }
|
||||
encodeValue(value: string): string {
|
||||
return standardEncoding(value);
|
||||
}
|
||||
}
|
||||
|
||||
function standardEncoding(v: string): string {
|
||||
@ -93,7 +97,9 @@ export class URLSearchParams {
|
||||
return clone;
|
||||
}
|
||||
|
||||
has(param: string): boolean { return this.paramsMap.has(param); }
|
||||
has(param: string): boolean {
|
||||
return this.paramsMap.has(param);
|
||||
}
|
||||
|
||||
get(param: string): string|null {
|
||||
const storedParam = this.paramsMap.get(param);
|
||||
@ -101,7 +107,9 @@ export class URLSearchParams {
|
||||
return Array.isArray(storedParam) ? storedParam[0] : null;
|
||||
}
|
||||
|
||||
getAll(param: string): string[] { return this.paramsMap.get(param) || []; }
|
||||
getAll(param: string): string[] {
|
||||
return this.paramsMap.get(param) || [];
|
||||
}
|
||||
|
||||
set(param: string, val: string) {
|
||||
if (val === void 0 || val === null) {
|
||||
@ -182,5 +190,7 @@ export class URLSearchParams {
|
||||
return paramsList.join('&');
|
||||
}
|
||||
|
||||
delete (param: string): void { this.paramsMap.delete(param); }
|
||||
delete(param: string): void {
|
||||
this.paramsMap.delete(param);
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import {Injector} from '@angular/core';
|
||||
import {AsyncTestCompleter, SpyObject, afterEach, beforeEach, describe, inject, it} from '@angular/core/testing/src/testing_internal';
|
||||
import {afterEach, AsyncTestCompleter, beforeEach, describe, inject, it, SpyObject} from '@angular/core/testing/src/testing_internal';
|
||||
import {BrowserJsonp} from '@angular/http/src/backends/browser_jsonp';
|
||||
import {JSONPBackend, JSONPConnection} from '@angular/http/src/backends/jsonp_backend';
|
||||
import {BaseRequestOptions, RequestOptions} from '@angular/http/src/base_request_options';
|
||||
@ -21,12 +21,16 @@ let existingScripts: MockBrowserJsonp[] = [];
|
||||
|
||||
class MockBrowserJsonp extends BrowserJsonp {
|
||||
// TODO(issue/24571): remove '!'.
|
||||
src !: string;
|
||||
src!: string;
|
||||
callbacks = new Map<string, (data: any) => any>();
|
||||
|
||||
addEventListener(type: string, cb: (data: any) => any) { this.callbacks.set(type, cb); }
|
||||
addEventListener(type: string, cb: (data: any) => any) {
|
||||
this.callbacks.set(type, cb);
|
||||
}
|
||||
|
||||
removeEventListener(type: string, cb: Function) { this.callbacks.delete(type); }
|
||||
removeEventListener(type: string, cb: Function) {
|
||||
this.callbacks.delete(type);
|
||||
}
|
||||
|
||||
dispatchEvent(type: string, argument: any = {}) {
|
||||
const cb = this.callbacks.get(type);
|
||||
@ -65,10 +69,12 @@ class MockBrowserJsonp extends BrowserJsonp {
|
||||
new Request(base.merge(new RequestOptions({url: 'https://google.com'})) as any);
|
||||
});
|
||||
|
||||
afterEach(() => { existingScripts = []; });
|
||||
afterEach(() => {
|
||||
existingScripts = [];
|
||||
});
|
||||
|
||||
it('should create a connection', () => {
|
||||
let instance: JSONPConnection = undefined !;
|
||||
let instance: JSONPConnection = undefined!;
|
||||
expect(() => instance = backend.createConnection(sampleRequest)).not.toThrow();
|
||||
expect(instance).toBeAnInstanceOf(JSONPConnection);
|
||||
});
|
||||
@ -141,8 +147,9 @@ class MockBrowserJsonp extends BrowserJsonp {
|
||||
RequestMethod.Head, RequestMethod.Patch]
|
||||
.forEach(method => {
|
||||
const base = new BaseRequestOptions();
|
||||
const req = new Request(base.merge(
|
||||
new RequestOptions({url: 'https://google.com', method: method})) as any);
|
||||
const req = new Request(
|
||||
base.merge(new RequestOptions({url: 'https://google.com', method: method})) as
|
||||
any);
|
||||
expect(
|
||||
() => new (JSONPConnection as any)(req, new MockBrowserJsonp())
|
||||
.response.subscribe())
|
||||
|
@ -18,7 +18,6 @@ import {ReplaySubject} from 'rxjs';
|
||||
|
||||
{
|
||||
describe('MockBackend', () => {
|
||||
|
||||
let backend: MockBackend;
|
||||
let sampleRequest1: Request;
|
||||
let sampleResponse1: Response;
|
||||
@ -40,7 +39,9 @@ import {ReplaySubject} from 'rxjs';
|
||||
sampleResponse2 = new Response(new ResponseOptions({body: 'response2'}));
|
||||
});
|
||||
|
||||
it('should create a new MockBackend', () => { expect(backend).toBeAnInstanceOf(MockBackend); });
|
||||
it('should create a new MockBackend', () => {
|
||||
expect(backend).toBeAnInstanceOf(MockBackend);
|
||||
});
|
||||
|
||||
it('should create a new MockConnection', () => {
|
||||
expect(backend.createConnection(sampleRequest1)).toBeAnInstanceOf(MockConnection);
|
||||
@ -54,7 +55,9 @@ import {ReplaySubject} from 'rxjs';
|
||||
it('should allow responding after subscription',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
const connection: MockConnection = backend.createConnection(sampleRequest1);
|
||||
connection.response.subscribe(() => { async.done(); });
|
||||
connection.response.subscribe(() => {
|
||||
async.done();
|
||||
});
|
||||
connection.mockRespond(sampleResponse1);
|
||||
}));
|
||||
|
||||
@ -62,20 +65,26 @@ import {ReplaySubject} from 'rxjs';
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
const connection: MockConnection = backend.createConnection(sampleRequest1);
|
||||
connection.mockRespond(sampleResponse1);
|
||||
connection.response.subscribe(() => { async.done(); });
|
||||
connection.response.subscribe(() => {
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should allow responding after subscription with an error',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
const connection: MockConnection = backend.createConnection(sampleRequest1);
|
||||
connection.response.subscribe(null !, () => { async.done(); });
|
||||
connection.response.subscribe(null!, () => {
|
||||
async.done();
|
||||
});
|
||||
connection.mockError(new Error('nope'));
|
||||
}));
|
||||
|
||||
it('should not throw when there are no unresolved requests',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
const connection: MockConnection = backend.createConnection(sampleRequest1);
|
||||
connection.response.subscribe(() => { async.done(); });
|
||||
connection.response.subscribe(() => {
|
||||
async.done();
|
||||
});
|
||||
connection.mockRespond(sampleResponse1);
|
||||
backend.verifyNoPendingRequests();
|
||||
}));
|
||||
@ -83,7 +92,9 @@ import {ReplaySubject} from 'rxjs';
|
||||
xit('should throw when there are unresolved requests',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
const connection: MockConnection = backend.createConnection(sampleRequest1);
|
||||
connection.response.subscribe(() => { async.done(); });
|
||||
connection.response.subscribe(() => {
|
||||
async.done();
|
||||
});
|
||||
backend.verifyNoPendingRequests();
|
||||
}));
|
||||
|
||||
@ -91,7 +102,9 @@ import {ReplaySubject} from 'rxjs';
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
const connection1: MockConnection = backend.createConnection(sampleRequest1);
|
||||
const connection2: MockConnection = backend.createConnection(sampleRequest1);
|
||||
connection1.response.subscribe(() => { async.done(); });
|
||||
connection1.response.subscribe(() => {
|
||||
async.done();
|
||||
});
|
||||
connection2.response.subscribe(() => {});
|
||||
connection2.mockRespond(sampleResponse1);
|
||||
connection1.mockRespond(sampleResponse1);
|
||||
@ -101,12 +114,12 @@ import {ReplaySubject} from 'rxjs';
|
||||
xit('should allow double subscribing',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
const responses: Response[] = [sampleResponse1, sampleResponse2];
|
||||
backend.connections.subscribe((c: MockConnection) => c.mockRespond(responses.shift() !));
|
||||
backend.connections.subscribe((c: MockConnection) => c.mockRespond(responses.shift()!));
|
||||
const responseObservable: ReplaySubject<Response> =
|
||||
backend.createConnection(sampleRequest1).response;
|
||||
responseObservable.subscribe(res => expect(res.text()).toBe('response1'));
|
||||
responseObservable.subscribe(
|
||||
res => expect(res.text()).toBe('response2'), null !, async.done);
|
||||
res => expect(res.text()).toBe('response2'), null!, async.done);
|
||||
}));
|
||||
|
||||
// TODO(robwormald): readyStates are leaving?
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import {ɵgetDOM as getDOM} from '@angular/common';
|
||||
import {Injectable} from '@angular/core';
|
||||
import {AsyncTestCompleter, SpyObject, afterEach, beforeEach, beforeEachProviders, describe, expect, inject, it} from '@angular/core/testing/src/testing_internal';
|
||||
import {afterEach, AsyncTestCompleter, beforeEach, beforeEachProviders, describe, expect, inject, it, SpyObject} from '@angular/core/testing/src/testing_internal';
|
||||
import {BrowserXhr} from '@angular/http/src/backends/browser_xhr';
|
||||
import {CookieXSRFStrategy, XHRBackend, XHRConnection} from '@angular/http/src/backends/xhr_backend';
|
||||
import {BaseRequestOptions, RequestOptions} from '@angular/http/src/base_request_options';
|
||||
@ -34,19 +34,19 @@ class MockBrowserXHR extends BrowserXhr {
|
||||
response: any;
|
||||
responseType: string;
|
||||
// TODO(issue/24571): remove '!'.
|
||||
responseText !: string;
|
||||
responseText!: string;
|
||||
setRequestHeader: any;
|
||||
callbacks = new Map<string, Function>();
|
||||
// TODO(issue/24571): remove '!'.
|
||||
status !: number;
|
||||
status!: number;
|
||||
// TODO(issue/24571): remove '!'.
|
||||
responseHeaders !: string;
|
||||
responseHeaders!: string;
|
||||
// TODO(issue/24571): remove '!'.
|
||||
responseURL !: string;
|
||||
responseURL!: string;
|
||||
// TODO(issue/24571): remove '!'.
|
||||
statusText !: string;
|
||||
statusText!: string;
|
||||
// TODO(issue/24571): remove '!'.
|
||||
withCredentials !: boolean;
|
||||
withCredentials!: boolean;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@ -60,29 +60,49 @@ class MockBrowserXHR extends BrowserXhr {
|
||||
this.responseType = '';
|
||||
}
|
||||
|
||||
setStatusCode(status: number) { this.status = status; }
|
||||
setStatusCode(status: number) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
setStatusText(statusText: string) { this.statusText = statusText; }
|
||||
setStatusText(statusText: string) {
|
||||
this.statusText = statusText;
|
||||
}
|
||||
|
||||
setResponse(value: string) { this.response = value; }
|
||||
setResponse(value: string) {
|
||||
this.response = value;
|
||||
}
|
||||
|
||||
setResponseText(value: string) { this.responseText = value; }
|
||||
setResponseText(value: string) {
|
||||
this.responseText = value;
|
||||
}
|
||||
|
||||
setResponseURL(value: string) { this.responseURL = value; }
|
||||
setResponseURL(value: string) {
|
||||
this.responseURL = value;
|
||||
}
|
||||
|
||||
setResponseHeaders(value: string) { this.responseHeaders = value; }
|
||||
setResponseHeaders(value: string) {
|
||||
this.responseHeaders = value;
|
||||
}
|
||||
|
||||
getAllResponseHeaders() { return this.responseHeaders || ''; }
|
||||
getAllResponseHeaders() {
|
||||
return this.responseHeaders || '';
|
||||
}
|
||||
|
||||
getResponseHeader(key: string) {
|
||||
return Headers.fromResponseHeaderString(this.responseHeaders).get(key);
|
||||
}
|
||||
|
||||
addEventListener(type: string, cb: Function) { this.callbacks.set(type, cb); }
|
||||
addEventListener(type: string, cb: Function) {
|
||||
this.callbacks.set(type, cb);
|
||||
}
|
||||
|
||||
removeEventListener(type: string, cb: Function) { this.callbacks.delete(type); }
|
||||
removeEventListener(type: string, cb: Function) {
|
||||
this.callbacks.delete(type);
|
||||
}
|
||||
|
||||
dispatchEvent(type: string) { this.callbacks.get(type) !({}); }
|
||||
dispatchEvent(type: string) {
|
||||
this.callbacks.get(type)!({});
|
||||
}
|
||||
|
||||
build() {
|
||||
const xhr = new MockBrowserXHR();
|
||||
@ -99,7 +119,8 @@ class MockBrowserXHR extends BrowserXhr {
|
||||
beforeEachProviders(
|
||||
() =>
|
||||
[{provide: ResponseOptions, useClass: BaseResponseOptions},
|
||||
{provide: BrowserXhr, useClass: MockBrowserXHR}, XHRBackend,
|
||||
{provide: BrowserXhr, useClass: MockBrowserXHR},
|
||||
XHRBackend,
|
||||
{provide: XSRFStrategy, useValue: new CookieXSRFStrategy()},
|
||||
]);
|
||||
|
||||
@ -110,7 +131,9 @@ class MockBrowserXHR extends BrowserXhr {
|
||||
new Request(base.merge(new RequestOptions({url: 'https://google.com'})) as any);
|
||||
}));
|
||||
|
||||
afterEach(() => { existingXHRs = []; });
|
||||
afterEach(() => {
|
||||
existingXHRs = [];
|
||||
});
|
||||
|
||||
describe('creating a connection', () => {
|
||||
@Injectable()
|
||||
@ -119,8 +142,9 @@ class MockBrowserXHR extends BrowserXhr {
|
||||
}
|
||||
beforeEachProviders(() => [{provide: XSRFStrategy, useClass: NoopXsrfStrategy}]);
|
||||
|
||||
it('succeeds',
|
||||
() => { expect(() => backend.createConnection(sampleRequest)).not.toThrow(); });
|
||||
it('succeeds', () => {
|
||||
expect(() => backend.createConnection(sampleRequest)).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
if (getDOM().supportsCookies()) {
|
||||
@ -171,8 +195,13 @@ class MockBrowserXHR extends BrowserXhr {
|
||||
sampleRequest, new MockBrowserXHR(),
|
||||
new ResponseOptions({type: ResponseType.Error}));
|
||||
connection.response.subscribe(
|
||||
(res: Response) => { expect(res.type).toBe(ResponseType.Error); }, null !,
|
||||
() => { async.done(); });
|
||||
(res: Response) => {
|
||||
expect(res.type).toBe(ResponseType.Error);
|
||||
},
|
||||
null!,
|
||||
() => {
|
||||
async.done();
|
||||
});
|
||||
existingXHRs[0].setStatusCode(200);
|
||||
existingXHRs[0].dispatchEvent('load');
|
||||
}));
|
||||
@ -189,7 +218,7 @@ class MockBrowserXHR extends BrowserXhr {
|
||||
const connection = new XHRConnection(
|
||||
sampleRequest, new MockBrowserXHR(),
|
||||
new ResponseOptions({type: ResponseType.Error}));
|
||||
connection.response.subscribe(null !, (res: Response) => {
|
||||
connection.response.subscribe(null!, (res: Response) => {
|
||||
expect(res.type).toBe(ResponseType.Error);
|
||||
async.done();
|
||||
});
|
||||
@ -201,7 +230,7 @@ class MockBrowserXHR extends BrowserXhr {
|
||||
const connection = new XHRConnection(
|
||||
sampleRequest, new MockBrowserXHR(),
|
||||
new ResponseOptions({type: ResponseType.Error}));
|
||||
connection.response.subscribe(null !, (res: Response) => {
|
||||
connection.response.subscribe(null!, (res: Response) => {
|
||||
expect(res.type).toBe(ResponseType.Error);
|
||||
expect(res.status).toEqual(0);
|
||||
expect(res.statusText).toEqual('');
|
||||
@ -365,7 +394,7 @@ class MockBrowserXHR extends BrowserXhr {
|
||||
});
|
||||
|
||||
it('should use blob body without type to the request', () => {
|
||||
const body = createBlob(['body { color: red; }'], null !);
|
||||
const body = createBlob(['body { color: red; }'], null!);
|
||||
const base = new BaseRequestOptions();
|
||||
const connection = new XHRConnection(
|
||||
new Request(base.merge(new RequestOptions({body: body}))), new MockBrowserXHR());
|
||||
@ -377,7 +406,7 @@ class MockBrowserXHR extends BrowserXhr {
|
||||
it('should use blob body without type with custom content type header to the request',
|
||||
() => {
|
||||
const headers = new Headers({'Content-Type': 'text/css'});
|
||||
const body = createBlob(['body { color: red; }'], null !);
|
||||
const body = createBlob(['body { color: red; }'], null!);
|
||||
const base = new BaseRequestOptions();
|
||||
const connection = new XHRConnection(
|
||||
new Request(base.merge(new RequestOptions({body: body, headers: headers}))),
|
||||
@ -451,7 +480,9 @@ class MockBrowserXHR extends BrowserXhr {
|
||||
nextCalled = true;
|
||||
expect(res.status).toBe(statusCode);
|
||||
},
|
||||
(errRes: Response) => { errorCalled = true; },
|
||||
(errRes: Response) => {
|
||||
errorCalled = true;
|
||||
},
|
||||
() => {
|
||||
expect(nextCalled).toBe(true);
|
||||
expect(errorCalled).toBe(false);
|
||||
@ -484,7 +515,9 @@ class MockBrowserXHR extends BrowserXhr {
|
||||
sampleRequest, new MockBrowserXHR(), new ResponseOptions({status: statusCode}));
|
||||
|
||||
connection.response.subscribe(
|
||||
(res: Response) => { throw 'should not be called'; },
|
||||
(res: Response) => {
|
||||
throw 'should not be called';
|
||||
},
|
||||
(errRes: Response) => {
|
||||
expect(errRes.ok).toBe(false);
|
||||
async.done();
|
||||
@ -503,13 +536,17 @@ class MockBrowserXHR extends BrowserXhr {
|
||||
sampleRequest, new MockBrowserXHR(), new ResponseOptions({status: statusCode}));
|
||||
|
||||
connection.response.subscribe(
|
||||
(res: Response) => { nextCalled = true; },
|
||||
(res: Response) => {
|
||||
nextCalled = true;
|
||||
},
|
||||
(errRes: Response) => {
|
||||
expect(errRes.status).toBe(statusCode);
|
||||
expect(nextCalled).toBe(false);
|
||||
async.done();
|
||||
},
|
||||
() => { throw 'should not be called'; });
|
||||
() => {
|
||||
throw 'should not be called';
|
||||
});
|
||||
|
||||
existingXHRs[0].setStatusCode(statusCode);
|
||||
existingXHRs[0].dispatchEvent('load');
|
||||
@ -601,7 +638,7 @@ class MockBrowserXHR extends BrowserXhr {
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
const conn =
|
||||
new XHRConnection(sampleRequest, new MockBrowserXHR(), new ResponseOptions());
|
||||
conn.response.subscribe(null !, (res: Response) => {
|
||||
conn.response.subscribe(null!, (res: Response) => {
|
||||
expect(res.text()).toBe('{json: "object"}');
|
||||
async.done();
|
||||
});
|
||||
@ -622,10 +659,10 @@ Transfer-Encoding: chunked
|
||||
Connection: keep-alive`;
|
||||
|
||||
connection.response.subscribe((res: Response) => {
|
||||
expect(res.headers !.get('Date')).toEqual('Fri, 20 Nov 2015 01:45:26 GMT');
|
||||
expect(res.headers !.get('Content-Type')).toEqual('application/json; charset=utf-8');
|
||||
expect(res.headers !.get('Transfer-Encoding')).toEqual('chunked');
|
||||
expect(res.headers !.get('Connection')).toEqual('keep-alive');
|
||||
expect(res.headers!.get('Date')).toEqual('Fri, 20 Nov 2015 01:45:26 GMT');
|
||||
expect(res.headers!.get('Content-Type')).toEqual('application/json; charset=utf-8');
|
||||
expect(res.headers!.get('Transfer-Encoding')).toEqual('chunked');
|
||||
expect(res.headers!.get('Connection')).toEqual('keep-alive');
|
||||
async.done();
|
||||
});
|
||||
|
||||
|
@ -10,7 +10,6 @@ import {Headers} from '@angular/http/src/headers';
|
||||
|
||||
{
|
||||
describe('Headers', () => {
|
||||
|
||||
describe('initialization', () => {
|
||||
it('should conform to spec', () => {
|
||||
const httpHeaders = {
|
||||
@ -165,8 +164,9 @@ import {Headers} from '@angular/http/src/headers';
|
||||
ref = {'Accept': values};
|
||||
});
|
||||
|
||||
it('should be serializable with toJSON',
|
||||
() => { expect(JSON.stringify(headers)).toEqual(JSON.stringify(ref)); });
|
||||
it('should be serializable with toJSON', () => {
|
||||
expect(JSON.stringify(headers)).toEqual(JSON.stringify(ref));
|
||||
});
|
||||
|
||||
it('should be able to recreate serializedHeaders', () => {
|
||||
const parsedHeaders = JSON.parse(JSON.stringify(headers));
|
||||
|
@ -7,14 +7,14 @@
|
||||
*/
|
||||
|
||||
import {Injector} from '@angular/core';
|
||||
import {TestBed, getTestBed} from '@angular/core/testing';
|
||||
import {AsyncTestCompleter, afterEach, beforeEach, describe, inject, it} from '@angular/core/testing/src/testing_internal';
|
||||
import {getTestBed, TestBed} from '@angular/core/testing';
|
||||
import {afterEach, AsyncTestCompleter, beforeEach, describe, inject, it} from '@angular/core/testing/src/testing_internal';
|
||||
import {stringToArrayBuffer} from '@angular/http/src/http_utils';
|
||||
import {MockBackend, MockConnection} from '@angular/http/testing/src/mock_backend';
|
||||
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
||||
import {Observable, zip} from 'rxjs';
|
||||
|
||||
import {BaseRequestOptions, ConnectionBackend, Http, HttpModule, JSONPBackend, Jsonp, JsonpModule, Request, RequestMethod, RequestOptions, Response, ResponseContentType, ResponseOptions, URLSearchParams, XHRBackend} from '../index';
|
||||
import {BaseRequestOptions, ConnectionBackend, Http, HttpModule, Jsonp, JSONPBackend, JsonpModule, Request, RequestMethod, RequestOptions, Response, ResponseContentType, ResponseOptions, URLSearchParams, XHRBackend} from '../index';
|
||||
|
||||
{
|
||||
describe('injectables', () => {
|
||||
@ -38,7 +38,6 @@ import {BaseRequestOptions, ConnectionBackend, Http, HttpModule, JSONPBackend, J
|
||||
|
||||
it('should allow using jsonpInjectables and httpInjectables in same injector',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
|
||||
http = injector.get(Http);
|
||||
jsonp = injector.get(Jsonp);
|
||||
jsonpBackend = injector.get(JSONPBackend) as any as MockBackend;
|
||||
@ -105,8 +104,9 @@ import {BaseRequestOptions, ConnectionBackend, Http, HttpModule, JSONPBackend, J
|
||||
|
||||
describe('Http', () => {
|
||||
describe('.request()', () => {
|
||||
it('should return an Observable',
|
||||
() => { expect(http.request(url)).toBeAnInstanceOf(Observable); });
|
||||
it('should return an Observable', () => {
|
||||
expect(http.request(url)).toBeAnInstanceOf(Observable);
|
||||
});
|
||||
|
||||
|
||||
it('should accept a fully-qualified request as its only parameter',
|
||||
@ -174,8 +174,13 @@ import {BaseRequestOptions, ConnectionBackend, Http, HttpModule, JSONPBackend, J
|
||||
backend.connections.subscribe((c: MockConnection) => c.mockRespond(baseResponse));
|
||||
http.request('http://basic.connection')
|
||||
.subscribe(
|
||||
(res: Response) => { expect(res.text()).toBe('base response'); }, null !,
|
||||
() => { async.done(); });
|
||||
(res: Response) => {
|
||||
expect(res.text()).toBe('base response');
|
||||
},
|
||||
null!,
|
||||
() => {
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should perform multiple get requests and complete the responses',
|
||||
@ -187,8 +192,13 @@ import {BaseRequestOptions, ConnectionBackend, Http, HttpModule, JSONPBackend, J
|
||||
});
|
||||
http.request('http://basic.connection')
|
||||
.subscribe(
|
||||
(res: Response) => { expect(res.text()).toBe('base response'); }, null !,
|
||||
() => { async.done(); });
|
||||
(res: Response) => {
|
||||
expect(res.text()).toBe('base response');
|
||||
},
|
||||
null!,
|
||||
() => {
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should throw if url is not a string or Request', () => {
|
||||
@ -422,7 +432,6 @@ import {BaseRequestOptions, ConnectionBackend, Http, HttpModule, JSONPBackend, J
|
||||
});
|
||||
|
||||
describe('response buffer', () => {
|
||||
|
||||
it('should attach the provided buffer to the response',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
backend.connections.subscribe((c: MockConnection) => {
|
||||
|
@ -27,66 +27,67 @@ import {supportsWebAnimation} from '@angular/platform-browser/testing/src/browse
|
||||
|
||||
it('should return ContentType.JSON', () => {
|
||||
const req = new Request(new RequestOptions({
|
||||
url: 'test',
|
||||
method: 'GET',
|
||||
body: null,
|
||||
headers: new Headers({'content-type': 'application/json'})
|
||||
}) as any);
|
||||
url: 'test',
|
||||
method: 'GET',
|
||||
body: null,
|
||||
headers: new Headers({'content-type': 'application/json'})
|
||||
}) as any);
|
||||
|
||||
expect(req.detectContentType()).toEqual(ContentType.JSON);
|
||||
});
|
||||
|
||||
it('should return ContentType.FORM', () => {
|
||||
const req = new Request(new RequestOptions({
|
||||
url: 'test',
|
||||
method: 'GET',
|
||||
body: null,
|
||||
headers: new Headers({'content-type': 'application/x-www-form-urlencoded'})
|
||||
}) as any);
|
||||
const req = new Request(
|
||||
new RequestOptions({
|
||||
url: 'test',
|
||||
method: 'GET',
|
||||
body: null,
|
||||
headers: new Headers({'content-type': 'application/x-www-form-urlencoded'})
|
||||
}) as any);
|
||||
|
||||
expect(req.detectContentType()).toEqual(ContentType.FORM);
|
||||
});
|
||||
|
||||
it('should return ContentType.FORM_DATA', () => {
|
||||
const req = new Request(new RequestOptions({
|
||||
url: 'test',
|
||||
method: 'GET',
|
||||
body: null,
|
||||
headers: new Headers({'content-type': 'multipart/form-data'})
|
||||
}) as any);
|
||||
url: 'test',
|
||||
method: 'GET',
|
||||
body: null,
|
||||
headers: new Headers({'content-type': 'multipart/form-data'})
|
||||
}) as any);
|
||||
|
||||
expect(req.detectContentType()).toEqual(ContentType.FORM_DATA);
|
||||
});
|
||||
|
||||
it('should return ContentType.TEXT', () => {
|
||||
const req = new Request(new RequestOptions({
|
||||
url: 'test',
|
||||
method: 'GET',
|
||||
body: null,
|
||||
headers: new Headers({'content-type': 'text/plain'})
|
||||
}) as any);
|
||||
url: 'test',
|
||||
method: 'GET',
|
||||
body: null,
|
||||
headers: new Headers({'content-type': 'text/plain'})
|
||||
}) as any);
|
||||
|
||||
expect(req.detectContentType()).toEqual(ContentType.TEXT);
|
||||
});
|
||||
|
||||
it('should return ContentType.BLOB', () => {
|
||||
const req = new Request(new RequestOptions({
|
||||
url: 'test',
|
||||
method: 'GET',
|
||||
body: null,
|
||||
headers: new Headers({'content-type': 'application/octet-stream'})
|
||||
}) as any);
|
||||
url: 'test',
|
||||
method: 'GET',
|
||||
body: null,
|
||||
headers: new Headers({'content-type': 'application/octet-stream'})
|
||||
}) as any);
|
||||
|
||||
expect(req.detectContentType()).toEqual(ContentType.BLOB);
|
||||
});
|
||||
|
||||
it('should not create a blob out of ArrayBuffer', () => {
|
||||
const req = new Request(new RequestOptions({
|
||||
url: 'test',
|
||||
method: 'GET',
|
||||
body: new ArrayBuffer(1),
|
||||
headers: new Headers({'content-type': 'application/octet-stream'})
|
||||
}) as any);
|
||||
url: 'test',
|
||||
method: 'GET',
|
||||
body: new ArrayBuffer(1),
|
||||
headers: new Headers({'content-type': 'application/octet-stream'})
|
||||
}) as any);
|
||||
|
||||
expect(req.detectContentType()).toEqual(ContentType.ARRAY_BUFFER);
|
||||
});
|
||||
@ -94,11 +95,11 @@ import {supportsWebAnimation} from '@angular/platform-browser/testing/src/browse
|
||||
|
||||
it('should return empty string if no body is present', () => {
|
||||
const req = new Request(new RequestOptions({
|
||||
url: 'test',
|
||||
method: 'GET',
|
||||
body: null,
|
||||
headers: new Headers({'content-type': 'application/json'})
|
||||
}) as any);
|
||||
url: 'test',
|
||||
method: 'GET',
|
||||
body: null,
|
||||
headers: new Headers({'content-type': 'application/json'})
|
||||
}) as any);
|
||||
|
||||
expect(req.text()).toEqual('');
|
||||
});
|
||||
|
@ -36,8 +36,12 @@ import {URLSearchParams} from '@angular/http/src/url_search_params';
|
||||
|
||||
it('should optionally accept a custom parser', () => {
|
||||
const fooEveryThingParser = {
|
||||
encodeKey() { return 'I AM KEY'; },
|
||||
encodeValue() { return 'I AM VALUE'; }
|
||||
encodeKey() {
|
||||
return 'I AM KEY';
|
||||
},
|
||||
encodeValue() {
|
||||
return 'I AM VALUE';
|
||||
}
|
||||
};
|
||||
const params = new URLSearchParams('', fooEveryThingParser);
|
||||
params.set('myKey', 'myValue');
|
||||
@ -68,8 +72,9 @@ import {URLSearchParams} from '@angular/http/src/url_search_params';
|
||||
**/
|
||||
|
||||
let params = new URLSearchParams();
|
||||
'! $ \' ( ) * + , ; A 9 - . _ ~ ? / ='.split(' ').forEach(
|
||||
(char, idx) => { params.set(`a${idx}`, char); });
|
||||
'! $ \' ( ) * + , ; A 9 - . _ ~ ? / ='.split(' ').forEach((char, idx) => {
|
||||
params.set(`a${idx}`, char);
|
||||
});
|
||||
expect(params.toString())
|
||||
.toBe(
|
||||
`a0=!&a1=$&a2=\'&a3=(&a4=)&a5=*&a6=+&a7=,&a8=;&a9=A&a10=9&a11=-&a12=.&a13=_&a14=~&a15=?&a16=/&a17==`
|
||||
@ -130,8 +135,12 @@ import {URLSearchParams} from '@angular/http/src/url_search_params';
|
||||
|
||||
it('should support a clone operation via clone()', () => {
|
||||
const fooQueryEncoder = {
|
||||
encodeKey(k: string) { return encodeURIComponent(k); },
|
||||
encodeValue(v: string) { return encodeURIComponent(v); }
|
||||
encodeKey(k: string) {
|
||||
return encodeURIComponent(k);
|
||||
},
|
||||
encodeValue(v: string) {
|
||||
return encodeURIComponent(v);
|
||||
}
|
||||
};
|
||||
const paramsA = new URLSearchParams('', fooQueryEncoder);
|
||||
paramsA.set('a', '2');
|
||||
@ -151,21 +160,20 @@ import {URLSearchParams} from '@angular/http/src/url_search_params';
|
||||
|
||||
it('should remove the parameter when set to undefined or null', () => {
|
||||
const params = new URLSearchParams('q=Q');
|
||||
params.set('q', undefined !);
|
||||
params.set('q', undefined!);
|
||||
expect(params.has('q')).toBe(false);
|
||||
expect(params.toString()).toEqual('');
|
||||
params.set('q', null !);
|
||||
params.set('q', null!);
|
||||
expect(params.has('q')).toBe(false);
|
||||
expect(params.toString()).toEqual('');
|
||||
});
|
||||
|
||||
it('should ignore the value when append undefined or null', () => {
|
||||
const params = new URLSearchParams('q=Q');
|
||||
params.append('q', undefined !);
|
||||
params.append('q', undefined!);
|
||||
expect(params.toString()).toEqual('q=Q');
|
||||
params.append('q', null !);
|
||||
params.append('q', null!);
|
||||
expect(params.toString()).toEqual('q=Q');
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
@ -245,7 +245,9 @@ export class MockBackend implements ConnectionBackend {
|
||||
*
|
||||
* This method only exists in the mock implementation, not in real Backends.
|
||||
*/
|
||||
resolveAllConnections() { this.connections.subscribe((c: MockConnection) => c.readyState = 4); }
|
||||
resolveAllConnections() {
|
||||
this.connections.subscribe((c: MockConnection) => c.readyState = 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link MockConnection}. This is equivalent to calling `new
|
||||
|
Reference in New Issue
Block a user