refactor(http): remove default settings from RequestOptions constructor

The BaseRequestOptions class is responsible for declaring default values,
while the RequestOptions class is merely responsible for setting values
based on values provided in the constructor.
This commit is contained in:
Jeff Cross
2015-06-24 00:27:07 -07:00
parent 146dbf1270
commit b3d98cba77
20 changed files with 333 additions and 194 deletions

View File

@ -4,7 +4,7 @@ import 'dart:html' show HttpRequest;
import 'package:angular2/di.dart';
@Injectable()
class BrowserXHR {
class BrowserXhr {
HttpRequest build() {
return new HttpRequest();
}

View File

@ -1,10 +1,8 @@
declare var window;
import {Injectable} from 'angular2/di';
// Make sure not to evaluate this in a non-browser environment!
@Injectable()
export class BrowserXHR {
export class BrowserXhr {
constructor() {}
build(): any { return <any>(new window.XMLHttpRequest()); }
build(): any { return <any>(new XMLHttpRequest()); }
}

View File

@ -9,11 +9,7 @@ import {IMPLEMENTS, BaseException} from 'angular2/src/facade/lang';
/**
*
* Connection class used by MockBackend
*
* This class is typically not instantiated directly, but instances can be retrieved by subscribing
*to the `connections` Observable of
* {@link MockBackend} in order to mock responses to requests.
* Mock Connection to represent a {@link Connection} for tests.
*
**/
@IMPLEMENTS(Connection)
@ -32,9 +28,8 @@ export class MockConnection {
request: Request;
/**
* [RxJS
* Observable](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md)
* of {@link Response}. Can be subscribed to in order to be notified when a response is available.
* {@link EventEmitter} of {@link Response}. Can be subscribed to in order to be notified when a
* response is available.
*/
response: EventEmitter;
@ -55,7 +50,7 @@ export class MockConnection {
/**
* Sends a mock response to the connection. This response is the value that is emitted to the
* `Observable` returned by {@link Http}.
* {@link EventEmitter} returned by {@link Http}.
*
* #Example
*
@ -91,7 +86,8 @@ export class MockConnection {
// TODO(jeffbcross): consider using Response type
/**
* Emits the provided error object as an error to the {@link Response} observable returned
* Emits the provided error object as an error to the {@link Response} {@link EventEmitter}
* returned
* from {@link Http}.
*/
mockError(err?) {
@ -137,8 +133,7 @@ export class MockConnection {
@IMPLEMENTS(ConnectionBackend)
export class MockBackend {
/**
* [RxJS
* Subject](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/subject.md)
* {@link EventEmitter}
* of {@link MockConnection} instances that have been created by this backend. Can be subscribed
* to in order to respond to connections.
*
@ -162,7 +157,7 @@ export class MockBackend {
* http.request('something.json').subscribe(res => {
* text = res.text();
* });
* connection.mockRespond(new Response('Something'));
* connection.mockRespond(new Response({body: 'Something'}));
* expect(text).toBe('Something');
* });
* ```
@ -179,8 +174,8 @@ export class MockBackend {
*/
connectionsArray: Array<MockConnection>;
/**
* [Observable](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md)
* of {@link MockConnection} instances that haven't yet been resolved (i.e. with a `readyState`
* {@link EventEmitter} of {@link MockConnection} instances that haven't yet been resolved (i.e.
* with a `readyState`
* less than 4). Used internally to verify that no connections are pending via the
* `verifyNoPendingRequests` method.
*
@ -193,7 +188,6 @@ export class MockBackend {
ObservableWrapper.subscribe(this.connections,
connection => this.connectionsArray.push(connection));
this.pendingConnections = new EventEmitter();
// Observable.fromArray(this.connectionsArray).filter((c) => c.readyState < ReadyStates.DONE);
}
/**
@ -218,10 +212,10 @@ export class MockBackend {
/**
* Creates a new {@link MockConnection}. This is equivalent to calling `new
* MockConnection()`, except that it also will emit the new `Connection` to the `connections`
* observable of this `MockBackend` instance. This method will usually only be used by tests
* emitter of this `MockBackend` instance. This method will usually only be used by tests
* against the framework itself, not by end-users.
*/
createConnection(req: Request) {
createConnection(req: Request): Connection {
if (!isPresent(req) || !(req instanceof Request)) {
throw new BaseException(`createConnection requires an instance of Request, got ${req}`);
}

View File

@ -2,8 +2,9 @@ import {ConnectionBackend, Connection} from '../interfaces';
import {ReadyStates, RequestMethods, RequestMethodsMap} from '../enums';
import {Request} from '../static_request';
import {Response} from '../static_response';
import {ResponseOptions, BaseResponseOptions} from '../base_response_options';
import {Injectable} from 'angular2/di';
import {BrowserXHR} from './browser_xhr';
import {BrowserXhr} from './browser_xhr';
import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
import {isPresent, ENUM_INDEX} from 'angular2/src/facade/lang';
@ -18,14 +19,14 @@ import {isPresent, ENUM_INDEX} from 'angular2/src/facade/lang';
export class XHRConnection implements Connection {
request: Request;
/**
* Response
* [Subject](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/subject.md)
* which emits a single {@link Response} value on load event of `XMLHttpRequest`.
* Response {@link EventEmitter} which emits a single {@link Response} value on load event of
* `XMLHttpRequest`.
*/
response: EventEmitter; //<Response>;
response: EventEmitter; // TODO: Make generic of <Response>;
readyState: ReadyStates;
private _xhr;
constructor(req: Request, browserXHR: BrowserXHR) {
private _xhr; // TODO: make type XMLHttpRequest, pending resolution of
// https://github.com/angular/ts2dart/issues/230
constructor(req: Request, browserXHR: BrowserXhr, baseResponseOptions?: ResponseOptions) {
// TODO: get rid of this when enum lookups are available in ts2dart
// https://github.com/angular/ts2dart/issues/221
var requestMethodsMap = new RequestMethodsMap();
@ -34,12 +35,15 @@ export class XHRConnection implements Connection {
this._xhr = browserXHR.build();
// TODO(jeffbcross): implement error listening/propagation
this._xhr.open(requestMethodsMap.getMethod(ENUM_INDEX(req.method)), req.url);
this._xhr.addEventListener(
'load',
(_) => {ObservableWrapper.callNext(
this.response, new Response({
body: isPresent(this._xhr.response) ? this._xhr.response : this._xhr.responseText
}))});
this._xhr.addEventListener('load', (_) => {
var responseOptions = new ResponseOptions(
{body: isPresent(this._xhr.response) ? this._xhr.response : this._xhr.responseText});
if (isPresent(baseResponseOptions)) {
responseOptions = baseResponseOptions.merge(responseOptions);
}
ObservableWrapper.callNext(this.response, new Response(responseOptions))
});
// TODO(jeffbcross): make this more dynamic based on body type
this._xhr.send(this.request.text());
}
@ -78,8 +82,8 @@ export class XHRConnection implements Connection {
**/
@Injectable()
export class XHRBackend implements ConnectionBackend {
constructor(private _browserXHR: BrowserXHR) {}
constructor(private _browserXHR: BrowserXhr, private _baseResponseOptions: ResponseOptions) {}
createConnection(request: Request): XHRConnection {
return new XHRConnection(request, this._browserXHR);
return new XHRConnection(request, this._browserXHR, this._baseResponseOptions);
}
}