mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
Merge pull request #953 from NativeScript/xhr-events
XHR events and an Android bugfix
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
/* tslint:disable */
|
||||
import TKUnit = require("./TKUnit");
|
||||
import trace = require("trace");
|
||||
import frameModule = require("ui/frame");
|
||||
import platform = require("platform");
|
||||
import uiTestModule = require("./ui-test");
|
||||
import * as TKUnit from"./TKUnit";
|
||||
import {messageType} from "trace";
|
||||
import {topmost, Frame} from "ui/frame";
|
||||
import {TextView} from "ui/text-view";
|
||||
import * as platform from "platform";
|
||||
import "./ui-test";
|
||||
|
||||
frameModule.Frame.defaultAnimatedNavigation = false;
|
||||
Frame.defaultAnimatedNavigation = false;
|
||||
|
||||
export function isRunningOnEmulator(): boolean {
|
||||
// This checks are not good enough to be added to modules but keeps unittests green.
|
||||
@@ -123,22 +124,29 @@ function printRunTestStats() {
|
||||
}
|
||||
}
|
||||
}
|
||||
TKUnit.write("=== ALL TESTS COMPLETE === " + (testsCount - failedTestCount) + " OK, " + failedTestCount + " failed", trace.messageType.info);
|
||||
let finalMessage = "=== ALL TESTS COMPLETE === \n" + (testsCount - failedTestCount) + " OK, " + failedTestCount + " failed" + "\n";
|
||||
TKUnit.write(finalMessage, messageType.info);
|
||||
for (j = 0; j < failedTestInfo.length; j++) {
|
||||
TKUnit.write(failedTestInfo[j], trace.messageType.error);
|
||||
let failureMessage = failedTestInfo[j];
|
||||
TKUnit.write(failureMessage, messageType.error);
|
||||
finalMessage += "\n" + failureMessage;
|
||||
}
|
||||
|
||||
let messageContainer = new TextView();
|
||||
messageContainer.text = finalMessage;
|
||||
topmost().currentPage.content = messageContainer;
|
||||
}
|
||||
|
||||
function startLog(): void {
|
||||
let testsName: string = this.name;
|
||||
TKUnit.write("START " + testsName + " TESTS.", trace.messageType.info);
|
||||
TKUnit.write("START " + testsName + " TESTS.", messageType.info);
|
||||
this.start = TKUnit.time();
|
||||
}
|
||||
|
||||
function log(): void {
|
||||
let testsName: string = this.name;
|
||||
let duration = TKUnit.time() - this.start;
|
||||
TKUnit.write(testsName + " COMPLETED for " + duration, trace.messageType.info);
|
||||
TKUnit.write(testsName + " COMPLETED for " + duration, messageType.info);
|
||||
}
|
||||
|
||||
export var runAll = function (moduleName?: string) {
|
||||
|
||||
@@ -212,6 +212,13 @@ export var test_XMLHttpRequest_requestShouldBePossibleAfterAbort = function (don
|
||||
xhr.send(JSON.stringify({ MyVariableOne: "ValueOne", MyVariableTwo: "ValueTwo" }));
|
||||
};
|
||||
|
||||
export function test_ignore_zero_length_request_body() {
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "https://httpbin.org/get");
|
||||
|
||||
xhr.send('');
|
||||
}
|
||||
|
||||
export function test_raises_onload_Event(done) {
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.onload = () => {
|
||||
@@ -221,6 +228,33 @@ export function test_raises_onload_Event(done) {
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
export function test_xhr_events() {
|
||||
let xhr = <any>new XMLHttpRequest();
|
||||
|
||||
let loadCallbackFired = false, loadEventFired = false;
|
||||
xhr.onload = () => loadCallbackFired = true;
|
||||
let badEvent = () => { throw new Error("Shouldn't call me") }
|
||||
xhr.addEventListener('load', () => loadEventFired = true);
|
||||
xhr.addEventListener('load', badEvent);
|
||||
xhr.removeEventListener('load', badEvent);
|
||||
|
||||
xhr._errorFlag = false;
|
||||
xhr._setReadyState(xhr.DONE);
|
||||
TKUnit.assertTrue(loadCallbackFired);
|
||||
TKUnit.assertTrue(loadEventFired);
|
||||
|
||||
let errorCallbackData = null, errorEventData = null;
|
||||
xhr.onerror = (e) => errorCallbackData = e;
|
||||
xhr.addEventListener('error', (e) => errorEventData = e);
|
||||
xhr.addEventListener('error', badEvent);
|
||||
xhr.removeEventListener('error', badEvent);
|
||||
|
||||
xhr._errorFlag = true;
|
||||
xhr._setReadyState(xhr.DONE, 'error data');
|
||||
TKUnit.assertEqual(errorCallbackData, 'error data');
|
||||
TKUnit.assertEqual(errorEventData, 'error data');
|
||||
}
|
||||
|
||||
export function test_sets_status_and_statusText(done) {
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = () => {
|
||||
|
||||
53
xhr/xhr.ts
53
xhr/xhr.ts
@@ -15,7 +15,7 @@ export class XMLHttpRequest {
|
||||
public DONE = 4;
|
||||
|
||||
public onload: () => void;
|
||||
public onerror: () => void;
|
||||
public onerror: (any) => void;
|
||||
|
||||
private _options: http.HttpRequestOptions;
|
||||
private _readyState: number;
|
||||
@@ -72,7 +72,10 @@ export class XMLHttpRequest {
|
||||
this._status = null;
|
||||
|
||||
if (types.isDefined(this._options)) {
|
||||
if (types.isString(data)) {
|
||||
if (types.isString(data) && this._options.method !== 'GET') {
|
||||
//The Android Java HTTP lib throws an exception if we provide a
|
||||
//a request body for GET requests, so we avoid doing that.
|
||||
//Browser implementations silently ignore it as well.
|
||||
this._options.content = data;
|
||||
} else if (data instanceof FormData) {
|
||||
this._options.content = (<FormData>data).toString();
|
||||
@@ -99,11 +102,36 @@ export class XMLHttpRequest {
|
||||
|
||||
}).catch(e => {
|
||||
this._errorFlag = true;
|
||||
this._setReadyState(this.DONE);
|
||||
this._setReadyState(this.DONE, e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private _listeners: Map<string, Array<Function>> = new Map<string, Array<Function>>();
|
||||
|
||||
public addEventListener(eventName: string, handler: Function) {
|
||||
if (eventName !== 'load' && eventName !== 'error') {
|
||||
throw new Error('Event not supported: ' + eventName);
|
||||
}
|
||||
|
||||
let handlers = this._listeners.get(eventName) || [];
|
||||
handlers.push(handler);
|
||||
this._listeners.set(eventName, handlers);
|
||||
}
|
||||
|
||||
public removeEventListener(eventName: string, toDetach: Function) {
|
||||
let handlers = this._listeners.get(eventName) || [];
|
||||
handlers = handlers.filter((handler) => handler !== toDetach);
|
||||
this._listeners.set(eventName, handlers);
|
||||
}
|
||||
|
||||
private emitEvent(eventName: string, ...args: Array<any>) {
|
||||
let handlers = this._listeners.get(eventName) || [];
|
||||
handlers.forEach((handler) => {
|
||||
handler(...args);
|
||||
});
|
||||
}
|
||||
|
||||
public setRequestHeader(header: string, value: string) {
|
||||
if (types.isDefined(this._options) && types.isString(header) && types.isString(value)) {
|
||||
this._options.headers[header] = value;
|
||||
@@ -158,7 +186,7 @@ export class XMLHttpRequest {
|
||||
}
|
||||
}
|
||||
|
||||
private _setReadyState(value: number) {
|
||||
private _setReadyState(value: number, error?: any) {
|
||||
if (this._readyState !== value) {
|
||||
this._readyState = value;
|
||||
|
||||
@@ -168,11 +196,16 @@ export class XMLHttpRequest {
|
||||
}
|
||||
|
||||
if (this._readyState === this.DONE) {
|
||||
if (this._errorFlag && types.isFunction(this.onerror)) {
|
||||
this.onerror();
|
||||
}
|
||||
if (!this._errorFlag && types.isFunction(this.onload)) {
|
||||
this.onload();
|
||||
if (this._errorFlag) {
|
||||
if (types.isFunction(this.onerror)) {
|
||||
this.onerror(error);
|
||||
}
|
||||
this.emitEvent('error', error);
|
||||
} else {
|
||||
if (types.isFunction(this.onload)) {
|
||||
this.onload();
|
||||
}
|
||||
this.emitEvent('load');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -264,4 +297,4 @@ export class FormData {
|
||||
|
||||
return arr.join("&");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user