summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2009-11-09 09:28:31 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2009-11-09 09:28:31 (GMT)
commit89fa7ae6d922ff5b62fca65eab95f35845c069eb (patch)
treeeddd885fe5a5e606afe60b2f4b2794d601c9a756
parentd3b1232df8fc8b238d1be8301e58c14e7102cce3 (diff)
downloadQt-89fa7ae6d922ff5b62fca65eab95f35845c069eb.zip
Qt-89fa7ae6d922ff5b62fca65eab95f35845c069eb.tar.gz
Qt-89fa7ae6d922ff5b62fca65eab95f35845c069eb.tar.bz2
XMLHttpRequest tests
-rw-r--r--src/declarative/qml/qmlxmlhttprequest.cpp136
-rw-r--r--tests/auto/declarative/declarative.pro4
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/constructor.qml14
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/defaultState.qml30
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/domExceptionCodes.qml60
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/instanceStateValues.qml33
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/open.qml53
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/open_arg_count.1.qml18
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/open_arg_count.2.qml18
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/open_invalid_method.qml16
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/open_network.expect7
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/open_network.reply2
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/open_network.wait0
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/open_sync.qml17
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/open_username.qml54
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/seconddocument.html1
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/setRequestHeader.expect9
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/setRequestHeader.qml28
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/setRequestHeader.reply2
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/setRequestHeader_illegalName.qml55
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/setRequestHeader_sent.qml31
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/setRequestHeader_unsent.qml17
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/staticStateValues.qml24
-rw-r--r--tests/auto/declarative/xmlhttprequest/data/testdocument.html1
-rw-r--r--tests/auto/declarative/xmlhttprequest/testhttpserver.cpp148
-rw-r--r--tests/auto/declarative/xmlhttprequest/testhttpserver.h75
-rw-r--r--tests/auto/declarative/xmlhttprequest/tst_xmlhttprequest.cpp426
-rw-r--r--tests/auto/declarative/xmlhttprequest/xmlhttprequest.pro12
28 files changed, 1256 insertions, 35 deletions
diff --git a/src/declarative/qml/qmlxmlhttprequest.cpp b/src/declarative/qml/qmlxmlhttprequest.cpp
index 0c0cd9c..f51b59f 100644
--- a/src/declarative/qml/qmlxmlhttprequest.cpp
+++ b/src/declarative/qml/qmlxmlhttprequest.cpp
@@ -54,8 +54,37 @@
#include <QtCore/qdebug.h>
-// ### Find real values
-#define INVALID_STATE_ERR ((QScriptContext::Error)15)
+// From DOM-Level-3-Core spec
+// http://www.w3.org/TR/DOM-Level-3-Core/core.html
+#define INDEX_SIZE_ERR 1
+#define DOMSTRING_SIZE_ERR 2
+#define HIERARCHY_REQUEST_ERR 3
+#define WRONG_DOCUMENT_ERR 4
+#define INVALID_CHARACTER_ERR 5
+#define NO_DATA_ALLOWED_ERR 6
+#define NO_MODIFICATION_ALLOWED_ERR 7
+#define NOT_FOUND_ERR 8
+#define NOT_SUPPORTED_ERR 9
+#define INUSE_ATTRIBUTE_ERR 10
+#define INVALID_STATE_ERR 11
+#define SYNTAX_ERR 12
+#define INVALID_MODIFICATION_ERR 13
+#define NAMESPACE_ERR 14
+#define INVALID_ACCESS_ERR 15
+#define VALIDATION_ERR 16
+#define TYPE_MISMATCH_ERR 17
+
+#define THROW_DOM(error, desc) \
+{ \
+ QScriptValue errorValue = context->throwError(QLatin1String(desc)); \
+ errorValue.setProperty(QLatin1String("code"), error); \
+ return errorValue; \
+}
+
+#define THROW_SYNTAX(desc) \
+ return context->throwError(QScriptContext::SyntaxError, QLatin1String(desc));
+#define THROW_REFERENCE(desc) \
+ return context->throwError(QScriptContext::ReferenceError, QLatin1String(desc));
#define D(arg) (arg)->release()
#define A(arg) (arg)->addref()
@@ -1189,10 +1218,11 @@ void QmlXMLHttpRequest::destroyNetwork()
static QScriptValue qmlxmlhttprequest_open(QScriptContext *context, QScriptEngine *engine)
{
QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
- if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object"));
+ if (!request)
+ THROW_REFERENCE("Not an XMLHttpRequest object");
if (context->argumentCount() < 2 || context->argumentCount() > 5)
- return context->throwError(QScriptContext::SyntaxError, QLatin1String("Incorrect argument count"));
+ THROW_DOM(SYNTAX_ERR, "Incorrect argument count");
// Argument 0 - Method
QString method = context->argument(0).toString().toUpper();
@@ -1200,23 +1230,21 @@ static QScriptValue qmlxmlhttprequest_open(QScriptContext *context, QScriptEngin
method != QLatin1String("PUT") &&
method != QLatin1String("HEAD") &&
method != QLatin1String("POST"))
- return context->throwError(QScriptContext::SyntaxError, QLatin1String("Unsupported method"));
+ THROW_DOM(SYNTAX_ERR, "Unsupported HTTP method type");
// Argument 1 - URL
- QUrl url(context->argument(1).toString()); // ### Need to resolve correctly
+ QUrl url(context->argument(1).toString());
if (url.isRelative()) {
- QmlContext *ctxt = QmlEnginePrivate::get(engine)->currentExpression?QmlEnginePrivate::get(engine)->currentExpression->context():0;
- if (ctxt)
- url = ctxt->resolvedUrl(url);
- else
- return context->throwError(QScriptContext::SyntaxError, QLatin1String("Relative URLs not supported"));
+ QmlContext *ctxt = QmlEnginePrivate::get(engine)->getContext(context);
+ Q_ASSERT(ctxt);
+ url = ctxt->resolvedUrl(url);
}
// Argument 2 - async (optional)
if (context->argumentCount() > 2 && !context->argument(2).toBoolean())
- return context->throwError(QScriptContext::SyntaxError, QLatin1String("Synchronous call not supported"));
+ THROW_DOM(NOT_SUPPORTED_ERR, "Synchronous XMLHttpRequest calls are not supported");
// Argument 3/4 - user/pass (optional)
@@ -1241,15 +1269,16 @@ static QScriptValue qmlxmlhttprequest_open(QScriptContext *context, QScriptEngin
static QScriptValue qmlxmlhttprequest_setRequestHeader(QScriptContext *context, QScriptEngine *engine)
{
QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
- if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object"));
+ if (!request)
+ THROW_REFERENCE("Not an XMLHttpRequest object");
if (context->argumentCount() != 2)
- return context->throwError(QScriptContext::SyntaxError, QLatin1String("Incorrect argument count"));
+ THROW_SYNTAX("Incorrect argument count");
if (request->readyState() != QmlXMLHttpRequest::Opened ||
request->sendFlag())
- return context->throwError(INVALID_STATE_ERR, QLatin1String("Invalid state"));
+ THROW_DOM(INVALID_STATE_ERR, "Invalid state");
QString name = context->argument(0).toString();
@@ -1288,13 +1317,14 @@ static QScriptValue qmlxmlhttprequest_setRequestHeader(QScriptContext *context,
static QScriptValue qmlxmlhttprequest_send(QScriptContext *context, QScriptEngine *engine)
{
QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
- if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object"));
+ if (!request)
+ THROW_REFERENCE("Not an XMLHttpRequest object");
if (request->readyState() != QmlXMLHttpRequest::Opened)
- return context->throwError(INVALID_STATE_ERR, QLatin1String("Invalid state"));
+ THROW_DOM(INVALID_STATE_ERR, "Invalid state");
if (request->sendFlag())
- return context->throwError(INVALID_STATE_ERR, QLatin1String("Invalid state"));
+ THROW_DOM(INVALID_STATE_ERR, "Invalid state");
QByteArray data;
if (context->argumentCount() > 0)
@@ -1308,7 +1338,8 @@ static QScriptValue qmlxmlhttprequest_send(QScriptContext *context, QScriptEngin
static QScriptValue qmlxmlhttprequest_abort(QScriptContext *context, QScriptEngine *engine)
{
QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
- if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object"));
+ if (!request)
+ THROW_REFERENCE("Not an XMLHttpRequest object");
request->abort();
@@ -1319,15 +1350,16 @@ static QScriptValue qmlxmlhttprequest_getResponseHeader(QScriptContext *context,
{
Q_UNUSED(engine)
QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
- if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object"));
+ if (!request)
+ THROW_REFERENCE("Not an XMLHttpRequest object");
if (context->argumentCount() != 1)
- return context->throwError(QScriptContext::SyntaxError, QLatin1String("Incorrect argument count"));
+ THROW_SYNTAX("Incorrect argument count");
if (request->readyState() != QmlXMLHttpRequest::Loading &&
request->readyState() != QmlXMLHttpRequest::Done &&
request->readyState() != QmlXMLHttpRequest::HeadersReceived)
- return context->throwError(INVALID_STATE_ERR, QLatin1String("Invalid state"));
+ THROW_DOM(INVALID_STATE_ERR, "Invalid state");
QString headerName = context->argument(0).toString();
@@ -1338,15 +1370,16 @@ static QScriptValue qmlxmlhttprequest_getAllResponseHeaders(QScriptContext *cont
{
Q_UNUSED(engine)
QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
- if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object"));
+ if (!request)
+ THROW_REFERENCE("Not an XMLHttpRequest object");
if (context->argumentCount() != 0)
- return context->throwError(QScriptContext::SyntaxError, QLatin1String("Incorrect argument count"));
+ THROW_SYNTAX("Incorrect argument count");
if (request->readyState() != QmlXMLHttpRequest::Loading &&
request->readyState() != QmlXMLHttpRequest::Done &&
request->readyState() != QmlXMLHttpRequest::HeadersReceived)
- return context->throwError(INVALID_STATE_ERR, QLatin1String("Invalid state"));
+ THROW_DOM(INVALID_STATE_ERR, "Invalid state");
return QScriptValue(request->headers());
}
@@ -1356,7 +1389,8 @@ static QScriptValue qmlxmlhttprequest_readyState(QScriptContext *context, QScrip
{
Q_UNUSED(engine)
QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
- if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object"));
+ if (!request)
+ THROW_REFERENCE("Not an XMLHttpRequest object");
return QScriptValue(request->readyState());
}
@@ -1365,11 +1399,12 @@ static QScriptValue qmlxmlhttprequest_status(QScriptContext *context, QScriptEng
{
Q_UNUSED(engine)
QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
- if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object"));
+ if (!request)
+ THROW_REFERENCE("Not an XMLHttpRequest object");
if (request->readyState() == QmlXMLHttpRequest::Unsent ||
request->readyState() == QmlXMLHttpRequest::Opened)
- return context->throwError(INVALID_STATE_ERR, QLatin1String("Invalid state"));
+ THROW_DOM(INVALID_STATE_ERR, "Invalid state");
if (request->errorFlag())
return QScriptValue(0);
@@ -1381,11 +1416,12 @@ static QScriptValue qmlxmlhttprequest_statusText(QScriptContext *context, QScrip
{
Q_UNUSED(engine)
QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
- if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object"));
+ if (!request)
+ THROW_REFERENCE("Not an XMLHttpRequest object");
if (request->readyState() == QmlXMLHttpRequest::Unsent ||
request->readyState() == QmlXMLHttpRequest::Opened)
- return context->throwError(INVALID_STATE_ERR, QLatin1String("Invalid state"));
+ THROW_DOM(INVALID_STATE_ERR, "Invalid state");
if (request->errorFlag())
return QScriptValue(0);
@@ -1397,19 +1433,21 @@ static QScriptValue qmlxmlhttprequest_responseText(QScriptContext *context, QScr
{
Q_UNUSED(engine)
QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
- if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object"));
+ if (!request)
+ THROW_REFERENCE("Not an XMLHttpRequest object");
if (request->readyState() != QmlXMLHttpRequest::Loading &&
request->readyState() != QmlXMLHttpRequest::Done)
return QScriptValue(QString());
- else
+ else
return QScriptValue(request->responseBody());
}
static QScriptValue qmlxmlhttprequest_responseXML(QScriptContext *context, QScriptEngine *engine)
{
QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
- if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object"));
+ if (!request)
+ THROW_REFERENCE("Not an XMLHttpRequest object");
if (request->readyState() != QmlXMLHttpRequest::Loading &&
request->readyState() != QmlXMLHttpRequest::Done)
@@ -1422,7 +1460,8 @@ static QScriptValue qmlxmlhttprequest_onreadystatechange(QScriptContext *context
{
Q_UNUSED(engine)
QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
- if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object"));
+ if (!request)
+ THROW_REFERENCE("Not an XMLHttpRequest object");
if (context->argumentCount())
request->setCallback(context->argument(0));
@@ -1459,6 +1498,13 @@ void qt_add_qmlxmlhttprequest(QScriptEngine *engine)
prototype.setProperty(QLatin1String("responseXML"), engine->newFunction(qmlxmlhttprequest_responseXML), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);
prototype.setProperty(QLatin1String("onreadystatechange"), engine->newFunction(qmlxmlhttprequest_onreadystatechange), QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
+ // State values
+ prototype.setProperty(QLatin1String("UNSENT"), 0, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ prototype.setProperty(QLatin1String("OPENED"), 1, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ prototype.setProperty(QLatin1String("HEADERS_RECEIVED"), 2, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ prototype.setProperty(QLatin1String("LOADING"), 3, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ prototype.setProperty(QLatin1String("DONE"), 4, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+
// Constructor
QScriptValue constructor = engine->newFunction(qmlxmlhttprequest_new, prototype);
constructor.setProperty(QLatin1String("UNSENT"), 0, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
@@ -1467,6 +1513,28 @@ void qt_add_qmlxmlhttprequest(QScriptEngine *engine)
constructor.setProperty(QLatin1String("LOADING"), 3, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
constructor.setProperty(QLatin1String("DONE"), 4, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
engine->globalObject().setProperty(QLatin1String("XMLHttpRequest"), constructor);
+
+ // DOM Exception
+ QScriptValue domExceptionPrototype = engine->newObject();
+ domExceptionPrototype.setProperty("INDEX_SIZE_ERR", INDEX_SIZE_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ domExceptionPrototype.setProperty("DOMSTRING_SIZE_ERR", DOMSTRING_SIZE_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ domExceptionPrototype.setProperty("HIERARCHY_REQUEST_ERR", HIERARCHY_REQUEST_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ domExceptionPrototype.setProperty("WRONG_DOCUMENT_ERR", WRONG_DOCUMENT_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ domExceptionPrototype.setProperty("INVALID_CHARACTER_ERR", INVALID_CHARACTER_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ domExceptionPrototype.setProperty("NO_DATA_ALLOWED_ERR", NO_DATA_ALLOWED_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ domExceptionPrototype.setProperty("NO_MODIFICATION_ALLOWED_ERR", NO_MODIFICATION_ALLOWED_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ domExceptionPrototype.setProperty("NOT_FOUND_ERR", NOT_FOUND_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ domExceptionPrototype.setProperty("NOT_SUPPORTED_ERR", NOT_SUPPORTED_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ domExceptionPrototype.setProperty("INUSE_ATTRIBUTE_ERR", INUSE_ATTRIBUTE_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ domExceptionPrototype.setProperty("INVALID_STATE_ERR", INVALID_STATE_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ domExceptionPrototype.setProperty("SYNTAX_ERR", SYNTAX_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ domExceptionPrototype.setProperty("INVALID_MODIFICATION_ERR", INVALID_MODIFICATION_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ domExceptionPrototype.setProperty("NAMESPACE_ERR", NAMESPACE_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ domExceptionPrototype.setProperty("INVALID_ACCESS_ERR", INVALID_ACCESS_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ domExceptionPrototype.setProperty("VALIDATION_ERR", VALIDATION_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ domExceptionPrototype.setProperty("TYPE_MISMATCH_ERR", TYPE_MISMATCH_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+
+ engine->globalObject().setProperty(QLatin1String("DOMException"), domExceptionPrototype);
}
#include "qmlxmlhttprequest.moc"
diff --git a/tests/auto/declarative/declarative.pro b/tests/auto/declarative/declarative.pro
index 134ae1b..4c31998 100644
--- a/tests/auto/declarative/declarative.pro
+++ b/tests/auto/declarative/declarative.pro
@@ -46,7 +46,9 @@ SUBDIRS += \
sql \ # Cover
states \ # Cover
valuetypes \ # Cover
- visual # Cover
+ visual \ # Cover
+ xmlhttprequest # Cover
+
# Tests which should run in Pulse
PULSE_TESTS = $$SUBDIRS
diff --git a/tests/auto/declarative/xmlhttprequest/data/constructor.qml b/tests/auto/declarative/xmlhttprequest/data/constructor.qml
new file mode 100644
index 0000000..4b9e9ce
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/constructor.qml
@@ -0,0 +1,14 @@
+import Qt 4.6
+
+Object {
+ property bool calledAsConstructor
+ property bool calledAsFunction
+
+ Component.onCompleted: {
+ var x1 = new XMLHttpRequest;
+ var x2 = XMLHttpRequest();
+
+ calledAsConstructor = (x1 != null && x1 instanceof XMLHttpRequest);
+ calledAsFunction = (x2 == undefined);
+ }
+}
diff --git a/tests/auto/declarative/xmlhttprequest/data/defaultState.qml b/tests/auto/declarative/xmlhttprequest/data/defaultState.qml
new file mode 100644
index 0000000..5cc2971
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/defaultState.qml
@@ -0,0 +1,30 @@
+import Qt 4.6
+
+Object {
+ property int readyState
+ property bool statusIsException: false
+ property bool statusTextIsException: false
+ property string responseText
+ property bool responseXMLIsNull
+
+ Component.onCompleted: {
+ var xhr = new XMLHttpRequest();
+
+ readyState = xhr.readyState;
+ try {
+ status = xhr.status;
+ } catch (error) {
+ if (error.code == DOMException.INVALID_STATE_ERR)
+ statusIsException = true;
+ }
+ try {
+ statusText = xhr.statusText;
+ } catch (error) {
+ if (error.code == DOMException.INVALID_STATE_ERR)
+ statusTextIsException = true;
+ }
+ responseText = xhr.responseText;
+ responseXMLIsNull = (xhr.responseXML == null);
+ }
+}
+
diff --git a/tests/auto/declarative/xmlhttprequest/data/domExceptionCodes.qml b/tests/auto/declarative/xmlhttprequest/data/domExceptionCodes.qml
new file mode 100644
index 0000000..a4ab66c
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/domExceptionCodes.qml
@@ -0,0 +1,60 @@
+import Qt 4.6
+
+Object {
+ property int index_size_err: DOMException.INDEX_SIZE_ERR
+ property int domstring_size_err: DOMException.DOMSTRING_SIZE_ERR
+ property int hierarchy_request_err: DOMException.HIERARCHY_REQUEST_ERR
+ property int wrong_document_err: DOMException.WRONG_DOCUMENT_ERR
+ property int invalid_character_err: DOMException.INVALID_CHARACTER_ERR
+ property int no_data_allowed_err: DOMException.NO_DATA_ALLOWED_ERR
+ property int no_modification_allowed_err: DOMException.NO_MODIFICATION_ALLOWED_ERR
+ property int not_found_err: DOMException.NOT_FOUND_ERR
+ property int not_supported_err: DOMException.NOT_SUPPORTED_ERR
+ property int inuse_attribute_err: DOMException.INUSE_ATTRIBUTE_ERR
+ property int invalid_state_err: DOMException.INVALID_STATE_ERR
+ property int syntax_err: DOMException.SYNTAX_ERR
+ property int invalid_modification_err: DOMException.INVALID_MODIFICATION_ERR
+ property int namespace_err: DOMException.NAMESPACE_ERR
+ property int invalid_access_err: DOMException.INVALID_ACCESS_ERR
+ property int validation_err: DOMException.VALIDATION_ERR
+ property int type_mismatch_err: DOMException.TYPE_MISMATCH_ERR
+
+ Component.onCompleted: {
+ // Attempt to overwrite and delete values
+ DOMException.INDEX_SIZE_ERR = 44;
+ DOMException.DOMSTRING_SIZE_ERR = 44;
+ DOMException.HIERARCHY_REQUEST_ERR = 44;
+ DOMException.WRONG_DOCUMENT_ERR = 44;
+ DOMException.INVALID_CHARACTER_ERR = 44;
+ DOMException.NO_DATA_ALLOWED_ERR = 44;
+ DOMException.NO_MODIFICATION_ALLOWED_ERR = 44;
+ DOMException.NOT_FOUND_ERR = 44;
+ DOMException.NOT_SUPPORTED_ERR = 44;
+ DOMException.INUSE_ATTRIBUTE_ERR = 44;
+ DOMException.INVALID_STATE_ERR = 44;
+ DOMException.SYNTAX_ERR = 44;
+ DOMException.INVALID_MODIFICATION_ERR = 44;
+ DOMException.NAMESPACE_ERR = 44;
+ DOMException.INVALID_ACCESS_ERR = 44;
+ DOMException.VALIDATION_ERR = 44;
+ DOMException.TYPE_MISMATCH_ERR = 44;
+
+ delete DOMException.INDEX_SIZE_ERR;
+ delete DOMException.DOMSTRING_SIZE_ERR;
+ delete DOMException.HIERARCHY_REQUEST_ERR;
+ delete DOMException.WRONG_DOCUMENT_ERR;
+ delete DOMException.INVALID_CHARACTER_ERR;
+ delete DOMException.NO_DATA_ALLOWED_ERR;
+ delete DOMException.NO_MODIFICATION_ALLOWED_ERR;
+ delete DOMException.NOT_FOUND_ERR;
+ delete DOMException.NOT_SUPPORTED_ERR;
+ delete DOMException.INUSE_ATTRIBUTE_ERR;
+ delete DOMException.INVALID_STATE_ERR;
+ delete DOMException.SYNTAX_ERR;
+ delete DOMException.INVALID_MODIFICATION_ERR;
+ delete DOMException.NAMESPACE_ERR;
+ delete DOMException.INVALID_ACCESS_ERR;
+ delete DOMException.VALIDATION_ERR;
+ delete DOMException.TYPE_MISMATCH_ERR;
+ }
+}
diff --git a/tests/auto/declarative/xmlhttprequest/data/instanceStateValues.qml b/tests/auto/declarative/xmlhttprequest/data/instanceStateValues.qml
new file mode 100644
index 0000000..ab3064f
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/instanceStateValues.qml
@@ -0,0 +1,33 @@
+import Qt 4.6
+
+Object {
+ property int unsent
+ property int opened
+ property int headers_received
+ property int loading
+ property int done
+
+ Component.onCompleted: {
+ // Attempt to overwrite and delete values
+ var x = new XMLHttpRequest();
+
+ x.UNSENT = 9;
+ x.OPENED = 9;
+ x.HEADERS_RECEIVED = 9;
+ x.LOADING = 9;
+ x.DONE = 9;
+
+ delete x.UNSENT;
+ delete x.OPENED;
+ delete x.HEADERS_RECEIVED;
+ delete x.LOADING;
+ delete x.DONE;
+
+ unsent = x.UNSENT
+ opened = x.OPENED
+ headers_received = x.HEADERS_RECEIVED
+ loading = x.LOADING
+ done = x.DONE
+ }
+}
+
diff --git a/tests/auto/declarative/xmlhttprequest/data/open.qml b/tests/auto/declarative/xmlhttprequest/data/open.qml
new file mode 100644
index 0000000..7729bab
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/open.qml
@@ -0,0 +1,53 @@
+import Qt 4.6
+
+Object {
+ property string url
+
+ property bool readyState: false
+ property bool openedState: false
+
+ property bool status: false
+ property bool statusText: false
+ property bool responseText: false
+ property bool responseXML: false
+
+ property bool dataOK: false
+
+ Component.onCompleted: {
+ var x = new XMLHttpRequest;
+
+ if (x.readyState == XMLHttpRequest.UNSENT)
+ readyState = true;
+
+ x.open("GET", url);
+
+ if (x.readyState == XMLHttpRequest.OPENED)
+ openedState = true;
+
+ try {
+ var a = x.status;
+ } catch (error) {
+ if (error.code == DOMException.INVALID_STATE_ERR)
+ status = true;
+ }
+ try {
+ var a = x.statusText;
+ } catch (error) {
+ if (error.code == DOMException.INVALID_STATE_ERR)
+ statusText = true;
+ }
+ responseText = (x.responseText == "");
+ responseXML = (x.responseXML == null);
+
+ // Test to the end
+ x.onreadystatechange = function() {
+ if (x.readyState == XMLHttpRequest.DONE) {
+ dataOK = (x.responseText == "QML Rocks!\n");
+ }
+ }
+
+
+ x.send()
+ }
+}
+
diff --git a/tests/auto/declarative/xmlhttprequest/data/open_arg_count.1.qml b/tests/auto/declarative/xmlhttprequest/data/open_arg_count.1.qml
new file mode 100644
index 0000000..74f13ba
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/open_arg_count.1.qml
@@ -0,0 +1,18 @@
+import Qt 4.6
+
+Object {
+ property bool exceptionThrown: false
+
+ Component.onCompleted: {
+ var x = new XMLHttpRequest;
+
+ try {
+ x.open("GET");
+ } catch (e) {
+ if (e.code == DOMException.SYNTAX_ERR)
+ exceptionThrown = true;
+ }
+ }
+}
+
+
diff --git a/tests/auto/declarative/xmlhttprequest/data/open_arg_count.2.qml b/tests/auto/declarative/xmlhttprequest/data/open_arg_count.2.qml
new file mode 100644
index 0000000..35dce9f
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/open_arg_count.2.qml
@@ -0,0 +1,18 @@
+import Qt 4.6
+
+Object {
+ property bool exceptionThrown: false
+
+ Component.onCompleted: {
+ var x = new XMLHttpRequest;
+
+ try {
+ x.open("GET", "http://www.nokia.com", true, "user", "password", "extra");
+ } catch (e) {
+ if (e.code == DOMException.SYNTAX_ERR)
+ exceptionThrown = true;
+ }
+ }
+}
+
+
diff --git a/tests/auto/declarative/xmlhttprequest/data/open_invalid_method.qml b/tests/auto/declarative/xmlhttprequest/data/open_invalid_method.qml
new file mode 100644
index 0000000..7fb1a4c
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/open_invalid_method.qml
@@ -0,0 +1,16 @@
+import Qt 4.6
+
+Object {
+ property bool exceptionThrown: false
+
+ Component.onCompleted: {
+ var x = new XMLHttpRequest;
+
+ try {
+ x.open("BLAH", "http://www.nokia.com");
+ } catch (e) {
+ if (e.code == DOMException.SYNTAX_ERR)
+ exceptionThrown = true;
+ }
+ }
+}
diff --git a/tests/auto/declarative/xmlhttprequest/data/open_network.expect b/tests/auto/declarative/xmlhttprequest/data/open_network.expect
new file mode 100644
index 0000000..40e648e
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/open_network.expect
@@ -0,0 +1,7 @@
+GET /testdocument.html HTTP/1.1
+Connection: Keep-Alive
+Accept-Encoding: gzip
+accept-language: en,*
+User-Agent: Mozilla/5.0
+Host: localhost:14445
+
diff --git a/tests/auto/declarative/xmlhttprequest/data/open_network.reply b/tests/auto/declarative/xmlhttprequest/data/open_network.reply
new file mode 100644
index 0000000..35b11f4
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/open_network.reply
@@ -0,0 +1,2 @@
+HTTP/1.0 200 OK
+Content-type: text/html; charset=UTF-8
diff --git a/tests/auto/declarative/xmlhttprequest/data/open_network.wait b/tests/auto/declarative/xmlhttprequest/data/open_network.wait
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/open_network.wait
diff --git a/tests/auto/declarative/xmlhttprequest/data/open_sync.qml b/tests/auto/declarative/xmlhttprequest/data/open_sync.qml
new file mode 100644
index 0000000..7133e81
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/open_sync.qml
@@ -0,0 +1,17 @@
+import Qt 4.6
+
+Object {
+ property bool exceptionThrown: false
+
+ Component.onCompleted: {
+ var x = new XMLHttpRequest;
+
+ try {
+ x.open("GET", "http://www.nokia.com", false);
+ } catch (e) {
+ if (e.code == DOMException.NOT_SUPPORTED_ERR)
+ exceptionThrown = true;
+ }
+ }
+}
+
diff --git a/tests/auto/declarative/xmlhttprequest/data/open_username.qml b/tests/auto/declarative/xmlhttprequest/data/open_username.qml
new file mode 100644
index 0000000..c38110c
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/open_username.qml
@@ -0,0 +1,54 @@
+import Qt 4.6
+
+Object {
+ property string url
+
+ property bool readyState: false
+ property bool openedState: false
+
+ property bool status: false
+ property bool statusText: false
+ property bool responseText: false
+ property bool responseXML: false
+
+ property bool dataOK: false
+
+ Component.onCompleted: {
+ var x = new XMLHttpRequest;
+
+ if (x.readyState == XMLHttpRequest.UNSENT)
+ readyState = true;
+
+ x.open("GET", url, true, "sampleusername", "password");
+
+ if (x.readyState == XMLHttpRequest.OPENED)
+ openedState = true;
+
+ try {
+ var a = x.status;
+ } catch (error) {
+ if (error.code == DOMException.INVALID_STATE_ERR)
+ status = true;
+ }
+ try {
+ var a = x.statusText;
+ } catch (error) {
+ if (error.code == DOMException.INVALID_STATE_ERR)
+ statusText = true;
+ }
+ responseText = (x.responseText == "");
+ responseXML = (x.responseXML == null);
+
+ // Test to the end
+ x.onreadystatechange = function() {
+ if (x.readyState == XMLHttpRequest.DONE) {
+ dataOK = (x.responseText == "QML Rocks!\n");
+ }
+ }
+
+
+ x.send()
+ }
+}
+
+
diff --git a/tests/auto/declarative/xmlhttprequest/data/seconddocument.html b/tests/auto/declarative/xmlhttprequest/data/seconddocument.html
new file mode 100644
index 0000000..a33f44b
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/seconddocument.html
@@ -0,0 +1 @@
+This should not be read!
diff --git a/tests/auto/declarative/xmlhttprequest/data/setRequestHeader.expect b/tests/auto/declarative/xmlhttprequest/data/setRequestHeader.expect
new file mode 100644
index 0000000..031ddff
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/setRequestHeader.expect
@@ -0,0 +1,9 @@
+GET /testdocument.html HTTP/1.1
+TEST-HEADER: value
+TEST-HEADER2: value,value2
+Connection: Keep-Alive
+Accept-Encoding: gzip
+accept-language: en,*
+User-Agent: Mozilla/5.0
+Host: localhost:14445
+
diff --git a/tests/auto/declarative/xmlhttprequest/data/setRequestHeader.qml b/tests/auto/declarative/xmlhttprequest/data/setRequestHeader.qml
new file mode 100644
index 0000000..8ea587a
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/setRequestHeader.qml
@@ -0,0 +1,28 @@
+import Qt 4.6
+
+Object {
+ property string url
+
+ property bool dataOK: false
+
+ Component.onCompleted: {
+ var x = new XMLHttpRequest;
+
+ x.open("GET", url);
+
+ x.setRequestHeader("Test-header", "value");
+ x.setRequestHeader("Test-header2", "value");
+ x.setRequestHeader("Test-header2", "value2");
+
+ // Test to the end
+ x.onreadystatechange = function() {
+ if (x.readyState == XMLHttpRequest.DONE) {
+ dataOK = (x.responseText == "QML Rocks!\n");
+ }
+ }
+
+ x.send();
+ }
+}
+
+
diff --git a/tests/auto/declarative/xmlhttprequest/data/setRequestHeader.reply b/tests/auto/declarative/xmlhttprequest/data/setRequestHeader.reply
new file mode 100644
index 0000000..35b11f4
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/setRequestHeader.reply
@@ -0,0 +1,2 @@
+HTTP/1.0 200 OK
+Content-type: text/html; charset=UTF-8
diff --git a/tests/auto/declarative/xmlhttprequest/data/setRequestHeader_illegalName.qml b/tests/auto/declarative/xmlhttprequest/data/setRequestHeader_illegalName.qml
new file mode 100644
index 0000000..cf5ebcc
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/setRequestHeader_illegalName.qml
@@ -0,0 +1,55 @@
+import Qt 4.6
+
+Object {
+ property string url
+ property string header
+
+ property bool readyState: false
+ property bool openedState: false
+
+ property bool status: false
+ property bool statusText: false
+ property bool responseText: false
+ property bool responseXML: false
+
+ property bool dataOK: false
+
+ Component.onCompleted: {
+ var x = new XMLHttpRequest;
+
+ if (x.readyState == XMLHttpRequest.UNSENT)
+ readyState = true;
+
+ x.open("GET", url);
+
+ if (x.readyState == XMLHttpRequest.OPENED)
+ openedState = true;
+
+ try {
+ var a = x.status;
+ } catch (error) {
+ if (error.code == DOMException.INVALID_STATE_ERR)
+ status = true;
+ }
+ try {
+ var a = x.statusText;
+ } catch (error) {
+ if (error.code == DOMException.INVALID_STATE_ERR)
+ statusText = true;
+ }
+ responseText = (x.responseText == "");
+ responseXML = (x.responseXML == null);
+
+ // Test to the end
+ x.onreadystatechange = function() {
+ if (x.readyState == XMLHttpRequest.DONE) {
+ dataOK = (x.responseText == "QML Rocks!\n");
+ }
+ }
+
+
+ x.send()
+ }
+}
+
+
diff --git a/tests/auto/declarative/xmlhttprequest/data/setRequestHeader_sent.qml b/tests/auto/declarative/xmlhttprequest/data/setRequestHeader_sent.qml
new file mode 100644
index 0000000..b637f17
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/setRequestHeader_sent.qml
@@ -0,0 +1,31 @@
+import Qt 4.6
+
+Object {
+ property string url
+ property bool test: false
+
+ property bool dataOK: false
+
+ Component.onCompleted: {
+ var x = new XMLHttpRequest;
+
+ x.open("GET", url);
+
+ // Test to the end
+ x.onreadystatechange = function() {
+ if (x.readyState == XMLHttpRequest.DONE) {
+ dataOK = (x.responseText == "QML Rocks!\n");
+ }
+ }
+
+ x.send();
+
+ try {
+ x.setRequestHeader("Test-header", "value");
+ } catch (e) {
+ if (e.code == DOMException.INVALID_STATE_ERR)
+ test = true;
+ }
+ }
+}
+
diff --git a/tests/auto/declarative/xmlhttprequest/data/setRequestHeader_unsent.qml b/tests/auto/declarative/xmlhttprequest/data/setRequestHeader_unsent.qml
new file mode 100644
index 0000000..4e89abf
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/setRequestHeader_unsent.qml
@@ -0,0 +1,17 @@
+import Qt 4.6
+
+Object {
+ property bool test: false
+
+ Component.onCompleted: {
+ var x = new XMLHttpRequest;
+
+ try {
+ x.setRequestHeader("Test-header", "value");
+ } catch (e) {
+ if (e.code == DOMException.INVALID_STATE_ERR)
+ test = true;
+ }
+ }
+}
+
diff --git a/tests/auto/declarative/xmlhttprequest/data/staticStateValues.qml b/tests/auto/declarative/xmlhttprequest/data/staticStateValues.qml
new file mode 100644
index 0000000..aaaadad
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/staticStateValues.qml
@@ -0,0 +1,24 @@
+import Qt 4.6
+
+Object {
+ property int unsent: XMLHttpRequest.UNSENT
+ property int opened: XMLHttpRequest.OPENED
+ property int headers_received: XMLHttpRequest.HEADERS_RECEIVED
+ property int loading: XMLHttpRequest.LOADING
+ property int done: XMLHttpRequest.DONE
+
+ Component.onCompleted: {
+ // Attempt to overwrite and delete values
+ XMLHttpRequest.UNSENT = 9;
+ XMLHttpRequest.OPENED = 9;
+ XMLHttpRequest.HEADERS_RECEIVED = 9;
+ XMLHttpRequest.LOADING = 9;
+ XMLHttpRequest.DONE = 9;
+
+ delete XMLHttpRequest.UNSENT;
+ delete XMLHttpRequest.OPENED;
+ delete XMLHttpRequest.HEADERS_RECEIVED;
+ delete XMLHttpRequest.LOADING;
+ delete XMLHttpRequest.DONE;
+ }
+}
diff --git a/tests/auto/declarative/xmlhttprequest/data/testdocument.html b/tests/auto/declarative/xmlhttprequest/data/testdocument.html
new file mode 100644
index 0000000..8fe0f4b
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/data/testdocument.html
@@ -0,0 +1 @@
+QML Rocks!
diff --git a/tests/auto/declarative/xmlhttprequest/testhttpserver.cpp b/tests/auto/declarative/xmlhttprequest/testhttpserver.cpp
new file mode 100644
index 0000000..021da05
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/testhttpserver.cpp
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "testhttpserver.h"
+#include <QTcpSocket>
+#include <QDebug>
+#include <QFile>
+
+TestHTTPServer::TestHTTPServer(quint16 port)
+: m_hasFailed(false)
+{
+ QObject::connect(&server, SIGNAL(newConnection()), this, SLOT(newConnection()));
+
+ server.listen(QHostAddress::Any, port);
+}
+
+bool TestHTTPServer::isValid() const
+{
+ return server.isListening();
+}
+
+bool TestHTTPServer::wait(const QUrl &expect, const QUrl &reply, const QUrl &body)
+{
+ m_hasFailed = false;
+
+ QFile expectFile(expect.toLocalFile());
+ if (!expectFile.open(QIODevice::ReadOnly)) return false;
+
+ QFile replyFile(reply.toLocalFile());
+ if (!replyFile.open(QIODevice::ReadOnly)) return false;
+
+ bodyData = QByteArray();
+ QFile bodyFile(body.toLocalFile());
+ if (bodyFile.open(QIODevice::ReadOnly)) {
+ bodyData = bodyFile.readAll();
+ }
+
+ waitData = expectFile.readAll();
+ replyData = replyFile.readAll();
+
+ if (!replyData.endsWith('\n'))
+ replyData.append("\n");
+ replyData.append("Content-length: " + QByteArray::number(bodyData.length()));
+ replyData .append("\n\n");
+
+ for (int ii = 0; ii < replyData.count(); ++ii) {
+ if (replyData.at(ii) == '\n' && (!ii || replyData.at(ii - 1) != '\r')) {
+ replyData.insert(ii, '\r');
+ ++ii;
+ }
+ }
+ replyData.append(bodyData);
+
+ return true;
+}
+
+bool TestHTTPServer::hasFailed() const
+{
+ return m_hasFailed;
+}
+
+void TestHTTPServer::newConnection()
+{
+ QTcpSocket *socket = server.nextPendingConnection();
+ if (!socket) return;
+
+ QObject::connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
+ QObject::connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
+}
+
+void TestHTTPServer::disconnected()
+{
+ sender()->deleteLater();
+}
+
+void TestHTTPServer::readyRead()
+{
+ QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
+ if (!socket) return;
+
+ QByteArray ba = socket->readAll();
+
+ if (m_hasFailed || waitData.isEmpty()) {
+ qWarning() << "TestHTTPServer: Unexpected data" << ba;
+ return;
+ }
+
+ for (int ii = 0; ii < ba.count(); ++ii) {
+ const char c = ba.at(ii);
+ if (c == '\r' && waitData.isEmpty())
+ continue;
+ else if (c == waitData.at(0))
+ waitData = waitData.mid(1);
+ else if (c == '\r')
+ continue;
+ else {
+ QByteArray data = ba.mid(ii);
+ qWarning() << "TestHTTPServer: Unexpected data" << data;
+ m_hasFailed = true;
+ socket->disconnect();
+ return;
+ }
+ }
+
+ if (waitData.isEmpty()) {
+ socket->write(replyData);
+ socket->disconnect();
+ }
+}
+
diff --git a/tests/auto/declarative/xmlhttprequest/testhttpserver.h b/tests/auto/declarative/xmlhttprequest/testhttpserver.h
new file mode 100644
index 0000000..709532e
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/testhttpserver.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TESTHTTPSERVER_H
+#define TESTHTTPSERVER_H
+
+#include <QObject>
+#include <QTcpServer>
+#include <QUrl>
+
+class TestHTTPServer : public QObject
+{
+ Q_OBJECT
+public:
+ TestHTTPServer(quint16 port);
+
+ bool isValid() const;
+
+ bool wait(const QUrl &expect, const QUrl &reply, const QUrl &body);
+ bool hasFailed() const;
+
+private slots:
+ void newConnection();
+ void disconnected();
+ void readyRead();
+
+private:
+ QByteArray waitData;
+ QByteArray replyData;
+ QByteArray bodyData;
+ bool m_hasFailed;
+
+ QTcpServer server;
+};
+
+#endif // TESTHTTPSERVER_H
+
diff --git a/tests/auto/declarative/xmlhttprequest/tst_xmlhttprequest.cpp b/tests/auto/declarative/xmlhttprequest/tst_xmlhttprequest.cpp
new file mode 100644
index 0000000..9acd6e6
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/tst_xmlhttprequest.cpp
@@ -0,0 +1,426 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qtest.h>
+#include <QmlEngine>
+#include <QmlComponent>
+#include <QDebug>
+#include <QWebPage>
+#include <QWebFrame>
+#include "testhttpserver.h"
+
+#define SERVER_PORT 14445
+
+class tst_xmlhttprequest : public QObject
+{
+ Q_OBJECT
+public:
+ tst_xmlhttprequest() {}
+
+private slots:
+ void domExceptionCodes();
+ void staticStateValues();
+ void instanceStateValues();
+ void constructor();
+ void defaultState();
+ void open();
+ void open_invalid_method();
+ void open_sync();
+ void open_arg_count();
+ void setRequestHeader();
+ void setRequestHeader_unsent();
+ void setRequestHeader_illegalName_data();
+ void setRequestHeader_illegalName();
+ void setRequestHeader_sent();
+
+ // Crashes
+ // void outstanding_request_at_shutdown();
+
+private:
+ QmlEngine engine;
+};
+
+class QWebPageWithJavaScriptConsoleMessages : public QWebPage {
+public:
+ void javaScriptConsoleMessage(const QString& message, int lineNumber, const QString& sourceID)
+ {
+ qWarning() << sourceID << ":" << lineNumber << ":" << message;
+ }
+};
+
+inline QUrl TEST_FILE(const QString &filename)
+{
+ return QUrl::fromLocalFile(QLatin1String(SRCDIR) + QLatin1String("/data/") + filename);
+}
+
+// Test that the dom exception codes are correct
+void tst_xmlhttprequest::domExceptionCodes()
+{
+ QmlComponent component(&engine, TEST_FILE("domExceptionCodes.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("index_size_err").toInt(), 1);
+ QCOMPARE(object->property("domstring_size_err").toInt(), 2);
+ QCOMPARE(object->property("hierarchy_request_err").toInt(), 3);
+ QCOMPARE(object->property("wrong_document_err").toInt(), 4);
+ QCOMPARE(object->property("invalid_character_err").toInt(), 5);
+ QCOMPARE(object->property("no_data_allowed_err").toInt(), 6);
+ QCOMPARE(object->property("no_modification_allowed_err").toInt(), 7);
+ QCOMPARE(object->property("not_found_err").toInt(), 8);
+ QCOMPARE(object->property("not_supported_err").toInt(), 9);
+ QCOMPARE(object->property("inuse_attribute_err").toInt(), 10);
+ QCOMPARE(object->property("invalid_state_err").toInt(), 11);
+ QCOMPARE(object->property("syntax_err").toInt(), 12);
+ QCOMPARE(object->property("invalid_modification_err").toInt(), 13);
+ QCOMPARE(object->property("namespace_err").toInt(), 14);
+ QCOMPARE(object->property("invalid_access_err").toInt(), 15);
+ QCOMPARE(object->property("validation_err").toInt(), 16);
+ QCOMPARE(object->property("type_mismatch_err").toInt(), 17);
+
+ delete object;
+}
+
+// Test that the state value properties on the XMLHttpRequest constructor have the correct values.
+// ### WebKit does not do this, but it seems to fit the standard and QML better
+void tst_xmlhttprequest::staticStateValues()
+{
+ QmlComponent component(&engine, TEST_FILE("staticStateValues.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("unsent").toInt(), 0);
+ QCOMPARE(object->property("opened").toInt(), 1);
+ QCOMPARE(object->property("headers_received").toInt(), 2);
+ QCOMPARE(object->property("loading").toInt(), 3);
+ QCOMPARE(object->property("done").toInt(), 4);
+
+ delete object;
+}
+
+// Test that the state value properties on instances have the correct values.
+void tst_xmlhttprequest::instanceStateValues()
+{
+ QmlComponent component(&engine, TEST_FILE("instanceStateValues.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("unsent").toInt(), 0);
+ QCOMPARE(object->property("opened").toInt(), 1);
+ QCOMPARE(object->property("headers_received").toInt(), 2);
+ QCOMPARE(object->property("loading").toInt(), 3);
+ QCOMPARE(object->property("done").toInt(), 4);
+
+ delete object;
+}
+
+// Test calling constructor
+void tst_xmlhttprequest::constructor()
+{
+ QmlComponent component(&engine, TEST_FILE("constructor.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("calledAsConstructor").toBool(), true);
+ QCOMPARE(object->property("calledAsFunction").toBool(), true);
+
+ delete object;
+}
+
+// Test that all the properties are set correctly before any request is sent
+void tst_xmlhttprequest::defaultState()
+{
+ QmlComponent component(&engine, TEST_FILE("defaultState.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("readState").toInt(), 0);
+ QCOMPARE(object->property("statusIsException").toBool(), true);
+ QCOMPARE(object->property("statusTextIsException").toBool(), true);
+ QCOMPARE(object->property("responseText").toString(), QString());
+ QCOMPARE(object->property("responseXMLIsNull").toBool(), true);
+
+ delete object;
+}
+
+#define TRY_WAIT(expr) \
+ do { \
+ for (int ii = 0; ii < 6; ++ii) { \
+ if ((expr)) break; \
+ QTest::qWait(50); \
+ } \
+ QVERIFY((expr)); \
+ } while (false)
+
+// Test valid XMLHttpRequest.open() calls
+void tst_xmlhttprequest::open()
+{
+ // Relative url
+ {
+ QmlComponent component(&engine, TEST_FILE("open.qml"));
+ QObject *object = component.beginCreate(engine.rootContext());
+ QVERIFY(object != 0);
+ object->setProperty("url", "testdocument.html");
+ component.completeCreate();
+
+ QCOMPARE(object->property("readyState").toBool(), true);
+ QCOMPARE(object->property("openedState").toBool(), true);
+ QCOMPARE(object->property("status").toBool(), true);
+ QCOMPARE(object->property("statusText").toBool(), true);
+ QCOMPARE(object->property("responseText").toBool(), true);
+ QCOMPARE(object->property("responseXML").toBool(), true);
+
+ TRY_WAIT(object->property("dataOK").toBool() == true);
+
+ delete object;
+ }
+
+ // Absolute url
+ {
+ QmlComponent component(&engine, TEST_FILE("open.qml"));
+ QObject *object = component.beginCreate(engine.rootContext());
+ QVERIFY(object != 0);
+ object->setProperty("url", TEST_FILE("testdocument.html").toString());
+ component.completeCreate();
+
+ QCOMPARE(object->property("readyState").toBool(), true);
+ QCOMPARE(object->property("openedState").toBool(), true);
+ QCOMPARE(object->property("status").toBool(), true);
+ QCOMPARE(object->property("statusText").toBool(), true);
+ QCOMPARE(object->property("responseText").toBool(), true);
+ QCOMPARE(object->property("responseXML").toBool(), true);
+
+ TRY_WAIT(object->property("dataOK").toBool() == true);
+
+ delete object;
+ }
+
+ // Absolute network url
+ {
+ TestHTTPServer server(SERVER_PORT);
+ QVERIFY(server.isValid());
+ QVERIFY(server.wait(TEST_FILE("open_network.expect"),
+ TEST_FILE("open_network.reply"),
+ TEST_FILE("testdocument.html")));
+
+ QmlComponent component(&engine, TEST_FILE("open.qml"));
+ QObject *object = component.beginCreate(engine.rootContext());
+ QVERIFY(object != 0);
+ object->setProperty("url", "http://localhost:14445/testdocument.html");
+ component.completeCreate();
+
+ QCOMPARE(object->property("readyState").toBool(), true);
+ QCOMPARE(object->property("openedState").toBool(), true);
+ QCOMPARE(object->property("status").toBool(), true);
+ QCOMPARE(object->property("statusText").toBool(), true);
+ QCOMPARE(object->property("responseText").toBool(), true);
+ QCOMPARE(object->property("responseXML").toBool(), true);
+
+ TRY_WAIT(object->property("dataOK").toBool() == true);
+
+ delete object;
+ }
+}
+
+// Test that calling XMLHttpRequest.open() with an invalid method raises an exception
+void tst_xmlhttprequest::open_invalid_method()
+{
+ QmlComponent component(&engine, TEST_FILE("open_invalid_method.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("exceptionThrown").toBool(), true);
+
+ delete object;
+}
+
+// Test that calling XMLHttpRequest.open() with sync raises an exception
+void tst_xmlhttprequest::open_sync()
+{
+ QmlComponent component(&engine, TEST_FILE("open_sync.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("exceptionThrown").toBool(), true);
+
+ delete object;
+}
+
+// Calling with incorrect arg count raises an exception
+void tst_xmlhttprequest::open_arg_count()
+{
+ {
+ QmlComponent component(&engine, TEST_FILE("open_arg_count.1.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("exceptionThrown").toBool(), true);
+
+ delete object;
+ }
+
+ {
+ QmlComponent component(&engine, TEST_FILE("open_arg_count.2.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("exceptionThrown").toBool(), true);
+
+ delete object;
+ }
+}
+
+// Test valid setRequestHeader() calls
+void tst_xmlhttprequest::setRequestHeader()
+{
+ TestHTTPServer server(SERVER_PORT);
+ QVERIFY(server.isValid());
+ QVERIFY(server.wait(TEST_FILE("setRequestHeader.expect"),
+ TEST_FILE("setRequestHeader.reply"),
+ TEST_FILE("testdocument.html")));
+
+ QmlComponent component(&engine, TEST_FILE("setRequestHeader.qml"));
+ QObject *object = component.beginCreate(engine.rootContext());
+ QVERIFY(object != 0);
+ object->setProperty("url", "http://localhost:14445/testdocument.html");
+ component.completeCreate();
+
+ TRY_WAIT(object->property("dataOK").toBool() == true);
+
+ delete object;
+}
+
+// Test setting headers before open() throws exception
+void tst_xmlhttprequest::setRequestHeader_unsent()
+{
+ QmlComponent component(&engine, TEST_FILE("setRequestHeader_unsent.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("test").toBool(), true);
+
+ delete object;
+}
+
+void tst_xmlhttprequest::setRequestHeader_illegalName_data()
+{
+ QTest::addColumn<QString>("name");
+
+ QTest::newRow("Accept-Charset") << "AccePT-CHArset";
+ QTest::newRow("Accept-Encoding") << "AccEpt-EnCOding";
+ QTest::newRow("Connection") << "ConnECtion";
+ QTest::newRow("Content-Length") << "ContEnt-LenGth";
+ QTest::newRow("Cookie") << "CookIe";
+ QTest::newRow("Cookie2") << "CoOkie2";
+ QTest::newRow("Content-Transfer-Encoding") << "ConteNT-tRANSFER-eNCOding";
+ QTest::newRow("Date") << "DaTE";
+ QTest::newRow("Expect") << "ExPect";
+ QTest::newRow("Host") << "HoST";
+ QTest::newRow("Keep-Alive") << "KEEP-aLive";
+ QTest::newRow("Referer") << "ReferEr";
+ QTest::newRow("TE") << "Te";
+ QTest::newRow("Trailer") << "TraILEr";
+ QTest::newRow("Transfer-Encoding") << "tRANsfer-Encoding";
+ QTest::newRow("Upgrade") << "UpgrADe";
+ QTest::newRow("User-Agent") << "uSEr-Agent";
+ QTest::newRow("Via") << "vIa";
+ QTest::newRow("Proxy-") << "ProXy-";
+ QTest::newRow("Sec-") << "SeC-";
+ QTest::newRow("Proxy-*") << "Proxy-BLAH";
+ QTest::newRow("Sec-*") << "Sec-F";
+}
+
+// Tests that using illegal header names has no effect
+void tst_xmlhttprequest::setRequestHeader_illegalName()
+{
+ QFETCH(QString, name);
+
+ TestHTTPServer server(SERVER_PORT);
+ QVERIFY(server.isValid());
+ QVERIFY(server.wait(TEST_FILE("open_network.expect"),
+ TEST_FILE("open_network.reply"),
+ TEST_FILE("testdocument.html")));
+
+ QmlComponent component(&engine, TEST_FILE("setRequestHeader_illegalName.qml"));
+ QObject *object = component.beginCreate(engine.rootContext());
+ QVERIFY(object != 0);
+ object->setProperty("url", "http://localhost:14445/testdocument.html");
+ object->setProperty("header", name);
+ component.completeCreate();
+
+ QCOMPARE(object->property("readyState").toBool(), true);
+ QCOMPARE(object->property("openedState").toBool(), true);
+ QCOMPARE(object->property("status").toBool(), true);
+ QCOMPARE(object->property("statusText").toBool(), true);
+ QCOMPARE(object->property("responseText").toBool(), true);
+ QCOMPARE(object->property("responseXML").toBool(), true);
+
+ TRY_WAIT(object->property("dataOK").toBool() == true);
+
+ delete object;
+}
+
+// Test that attempting to set a header after a request is sent throws an exception
+void tst_xmlhttprequest::setRequestHeader_sent()
+{
+ TestHTTPServer server(SERVER_PORT);
+ QVERIFY(server.isValid());
+ QVERIFY(server.wait(TEST_FILE("open_network.expect"),
+ TEST_FILE("open_network.reply"),
+ TEST_FILE("testdocument.html")));
+
+ QmlComponent component(&engine, TEST_FILE("setRequestHeader_sent.qml"));
+ QObject *object = component.beginCreate(engine.rootContext());
+ QVERIFY(object != 0);
+ object->setProperty("url", "http://localhost:14445/testdocument.html");
+ component.completeCreate();
+
+ QCOMPARE(object->property("test").toBool(), true);
+
+ TRY_WAIT(object->property("dataOK").toBool() == true);
+
+ delete object;
+}
+
+
+QTEST_MAIN(tst_xmlhttprequest)
+
+#include "tst_xmlhttprequest.moc"
diff --git a/tests/auto/declarative/xmlhttprequest/xmlhttprequest.pro b/tests/auto/declarative/xmlhttprequest/xmlhttprequest.pro
new file mode 100644
index 0000000..5d35a89
--- /dev/null
+++ b/tests/auto/declarative/xmlhttprequest/xmlhttprequest.pro
@@ -0,0 +1,12 @@
+load(qttest_p4)
+contains(QT_CONFIG,declarative): QT += declarative webkit network
+macx:CONFIG -= app_bundle
+
+HEADERS += testhttpserver.h
+
+SOURCES += tst_xmlhttprequest.cpp \
+ testhttpserver.cpp
+
+
+# Define SRCDIR equal to test's source directory
+DEFINES += SRCDIR=\\\"$$PWD\\\"