refactor(xhr): move render's xhr implementation to render/
The existence of this module in the services/ folder led some to believe xhr is meant to be a general-purpose http library. Fixes #2305
This commit is contained in:
@ -4,7 +4,7 @@ import {Map, MapWrapper, StringMapWrapper, StringMap} from 'angular2/src/facade/
|
||||
import {PromiseWrapper, Promise} from 'angular2/src/facade/async';
|
||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||
|
||||
import {XHR} from 'angular2/src/services/xhr';
|
||||
import {XHR} from 'angular2/src/render/xhr';
|
||||
|
||||
import {ViewDefinition} from '../../api';
|
||||
import {UrlResolver} from 'angular2/src/services/url_resolver';
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {Injectable} from 'angular2/di';
|
||||
import {XHR} from 'angular2/src/services/xhr';
|
||||
import {XHR} from 'angular2/src/render/xhr';
|
||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
|
||||
import {UrlResolver} from 'angular2/src/services/url_resolver';
|
||||
|
5
modules/angular2/src/render/xhr.ts
Normal file
5
modules/angular2/src/render/xhr.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import {Promise} from 'angular2/src/facade/async';
|
||||
|
||||
export class XHR {
|
||||
get(url: string): Promise<string> { return null; }
|
||||
}
|
14
modules/angular2/src/render/xhr_impl.dart
Normal file
14
modules/angular2/src/render/xhr_impl.dart
Normal file
@ -0,0 +1,14 @@
|
||||
library angular2.src.services.xhr_impl;
|
||||
|
||||
import 'dart:async' show Future;
|
||||
import 'dart:html' show HttpRequest;
|
||||
import 'package:angular2/di.dart';
|
||||
import './xhr.dart' show XHR;
|
||||
|
||||
@Injectable()
|
||||
class XHRImpl extends XHR {
|
||||
Future<String> get(String url) {
|
||||
return HttpRequest.request(url).then((HttpRequest req) => req.responseText,
|
||||
onError: (_) => new Future.error('Failed to load $url'));
|
||||
}
|
||||
}
|
27
modules/angular2/src/render/xhr_impl.ts
Normal file
27
modules/angular2/src/render/xhr_impl.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import {Injectable} from 'angular2/di';
|
||||
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
|
||||
import {XHR} from './xhr';
|
||||
|
||||
@Injectable()
|
||||
export class XHRImpl extends XHR {
|
||||
get(url: string): Promise<string> {
|
||||
var completer = PromiseWrapper.completer();
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', url, true);
|
||||
xhr.responseType = 'text';
|
||||
|
||||
xhr.onload = function() {
|
||||
var status = xhr.status;
|
||||
if (200 <= status && status <= 300) {
|
||||
completer.resolve(xhr.responseText);
|
||||
} else {
|
||||
completer.reject(`Failed to load ${url}`, null);
|
||||
}
|
||||
};
|
||||
|
||||
xhr.onerror = function() { completer.reject(`Failed to load ${url}`, null); };
|
||||
|
||||
xhr.send();
|
||||
return completer.promise;
|
||||
}
|
||||
}
|
105
modules/angular2/src/render/xhr_mock.ts
Normal file
105
modules/angular2/src/render/xhr_mock.ts
Normal file
@ -0,0 +1,105 @@
|
||||
import {XHR} from 'angular2/src/render/xhr';
|
||||
import {List, ListWrapper, Map, MapWrapper} from 'angular2/src/facade/collection';
|
||||
import {isBlank, isPresent, normalizeBlank, BaseException} from 'angular2/src/facade/lang';
|
||||
import {PromiseWrapper, Promise} from 'angular2/src/facade/async';
|
||||
|
||||
export class MockXHR extends XHR {
|
||||
private _expectations: List<_Expectation>;
|
||||
private _definitions: Map<string, string>;
|
||||
private _requests: List<Promise<string>>;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._expectations = [];
|
||||
this._definitions = MapWrapper.create();
|
||||
this._requests = [];
|
||||
}
|
||||
|
||||
get(url: string): Promise<string> {
|
||||
var request = new _PendingRequest(url);
|
||||
ListWrapper.push(this._requests, request);
|
||||
return request.getPromise();
|
||||
}
|
||||
|
||||
expect(url: string, response: string) {
|
||||
var expectation = new _Expectation(url, response);
|
||||
ListWrapper.push(this._expectations, expectation);
|
||||
}
|
||||
|
||||
when(url: string, response: string) { MapWrapper.set(this._definitions, url, response); }
|
||||
|
||||
flush() {
|
||||
if (this._requests.length === 0) {
|
||||
throw new BaseException('No pending requests to flush');
|
||||
}
|
||||
|
||||
do {
|
||||
var request = ListWrapper.removeAt(this._requests, 0);
|
||||
this._processRequest(request);
|
||||
} while (this._requests.length > 0);
|
||||
|
||||
this.verifyNoOustandingExpectations();
|
||||
}
|
||||
|
||||
verifyNoOustandingExpectations() {
|
||||
if (this._expectations.length === 0) return;
|
||||
|
||||
var urls = [];
|
||||
for (var i = 0; i < this._expectations.length; i++) {
|
||||
var expectation = this._expectations[i];
|
||||
ListWrapper.push(urls, expectation.url);
|
||||
}
|
||||
|
||||
throw new BaseException(`Unsatisfied requests: ${ListWrapper.join(urls, ', ')}`);
|
||||
}
|
||||
|
||||
private _processRequest(request: _PendingRequest) {
|
||||
var url = request.url;
|
||||
|
||||
if (this._expectations.length > 0) {
|
||||
var expectation = this._expectations[0];
|
||||
if (expectation.url == url) {
|
||||
ListWrapper.remove(this._expectations, expectation);
|
||||
request.complete(expectation.response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (MapWrapper.contains(this._definitions, url)) {
|
||||
var response = MapWrapper.get(this._definitions, url);
|
||||
request.complete(normalizeBlank(response));
|
||||
return;
|
||||
}
|
||||
|
||||
throw new BaseException(`Unexpected request ${url}`);
|
||||
}
|
||||
}
|
||||
|
||||
class _PendingRequest {
|
||||
url: string;
|
||||
completer;
|
||||
|
||||
constructor(url) {
|
||||
this.url = url;
|
||||
this.completer = PromiseWrapper.completer();
|
||||
}
|
||||
|
||||
complete(response: string) {
|
||||
if (isBlank(response)) {
|
||||
this.completer.reject(`Failed to load ${this.url}`, null);
|
||||
} else {
|
||||
this.completer.resolve(response);
|
||||
}
|
||||
}
|
||||
|
||||
getPromise(): Promise<string> { return this.completer.promise; }
|
||||
}
|
||||
|
||||
class _Expectation {
|
||||
url: string;
|
||||
response: string;
|
||||
constructor(url: string, response: string) {
|
||||
this.url = url;
|
||||
this.response = response;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user