/**
 * @license Angular v8.0.0-beta.10+1.sha-a28b3e3
 * (c) 2010-2019 Google LLC. https://angular.io/
 * License: MIT
 */
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@angular/core"),require("@angular/http"),require("rxjs"),require("rxjs/operators")):"function"==typeof define&&define.amd?define("@angular/http/testing",["exports","@angular/core","@angular/http","rxjs","rxjs/operators"],t):t(((e=e||self).ng=e.ng||{},e.ng.http=e.ng.http||{},e.ng.http.testing={}),e.ng.core,e.ng.http,e.rxjs,e.rxjs.operators)}(this,function(e,t,n,o,r){"use strict";function i(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}
/**
     * @license
     * Copyright Google Inc. All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */var c=function(){function e(e){this.response=new o.ReplaySubject(1).pipe(r.take(1)),this.readyState=n.ReadyState.Open,this.request=e}return e.prototype.mockRespond=function(e){if(this.readyState===n.ReadyState.Done||this.readyState===n.ReadyState.Cancelled)throw new Error("Connection has already been resolved");this.readyState=n.ReadyState.Done,this.response.next(e),this.response.complete()},e.prototype.mockDownload=function(e){},e.prototype.mockError=function(e){this.readyState=n.ReadyState.Done,this.response.error(e)},e}(),s=function(){function e(){var e=this;this.connectionsArray=[],this.connections=new o.Subject,this.connections.subscribe(function(t){return e.connectionsArray.push(t)}),this.pendingConnections=new o.Subject}return e.prototype.verifyNoPendingRequests=function(){var e=0;if(this.pendingConnections.subscribe(function(t){return e++}),e>0)throw new Error(e+" pending connections to be resolved")},e.prototype.resolveAllConnections=function(){this.connections.subscribe(function(e){return e.readyState=4})},e.prototype.createConnection=function(e){if(!(e&&e instanceof n.Request))throw new Error("createConnection requires an instance of Request, got "+e);var t=new c(e);return this.connections.next(t),t},function r(e,t,n,o){var r,i=arguments.length,c=i<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,n):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)c=Reflect.decorate(e,t,n,o);else for(var s=e.length-1;s>=0;s--)(r=e[s])&&(c=(i<3?r(c):i>3?r(t,n,c):r(t,n))||c);return i>3&&c&&Object.defineProperty(t,n,c),c}([t.Injectable(),i("design:paramtypes",[])],e)}();
/**
     * @license
     * Copyright Google Inc. All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */
/**
     * @license
     * Copyright Google Inc. All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */
/**
     * @license
     * Copyright Google Inc. All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */
e.MockConnection=c,e.MockBackend=s,Object.defineProperty(e,"__esModule",{value:!0})});