",
"method": "post",
"result": "success",
"status": 201,
"statusText": "Created"
}, "Post document without id");
// check uploaded documents
return jio_local_list.get({"_id": shared.uuid});
}).then(function (answers) {
var i;
for (i = 0; i < answers.length; i += 1) {
deepEqual(answers[i].data, {
"_id": shared.uuid,
"_underscored_meta": "uvalue",
"data": i === 0 ? "{\"meta\"" : ":\"data\"}"
}, "Check uploaded document in sub storage " + (i + 1));
}
// post with id
return jio.post({
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data",
"hello": "world"
});
}).then(function (answer) {
deepEqual(answer, {
"id": "one",
"method": "post",
"result": "success",
"status": 201,
"statusText": "Created"
}, "Post document with id");
// check uploaded documents
return jio_local_list.get({"_id": "one"});
}).then(function (answers) {
deepEqual(answers[0].data, {
"_id": "one",
"_underscored_meta": "uvalue",
"data": "{\"meta\":\"data\","
}, "Check uploaded document in sub storage 1");
deepEqual(answers[1].data, {
"_id": "one",
"_underscored_meta": "uvalue",
"data": "\"hello\":\"world\"}"
}, "Check uploaded document in sub storage 2");
// post with id
return reverse(jio.post({
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data",
"hello": "world"
}));
}).then(function (answer) {
deepEqual(answer, {
"error": "conflict",
"id": "one",
"message": "Unable to post document",
"method": "post",
"reason": "document exists",
"result": "error",
"status": 409,
"statusText": "Conflict"
}, "Post document with same id -> 409 Conflict");
}).fail(unexpectedError).always(start);
});
test("PutAttachment", function () {
var shared = {}, jio, jio_local_list = [];
shared.workspace = {};
shared.local_storage_description1 = {
"type": "local",
"username": "splitstorage",
"application_name": "putAttachment1",
"mode": "memory"
};
shared.local_storage_description2 = {
"type": "local",
"username": "splitstorage",
"application_name": "putAttachment2",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.local_storage_description1,
shared.local_storage_description2
]
}, {"workspace": shared.workspace});
jio_local_list[0] = jIO.createJIO(shared.local_storage_description1, {
"workspace": shared.workspace
});
jio_local_list[1] = jIO.createJIO(shared.local_storage_description2, {
"workspace": shared.workspace
});
jio_local_list.run = function (method, argument) {
var i, promises = [];
for (i = 0; i < this.length; i += 1) {
promises[i] = this[i][method].apply(this[i], argument);
}
return RSVP.all(promises);
};
jio_local_list.get = function () {
return this.run("get", arguments);
};
jio_local_list.getAttachmentAsBinaryString = function () {
return this.run("getAttachment", arguments).then(function (answers) {
var i, promises = [];
for (i = 0; i < answers.length; i += 1) {
promises[i] = tool.readBlobAsBinaryString(answers[i].data);
}
return RSVP.all(promises);
});
};
stop();
return reverse(jio.putAttachment({
"_id": "one",
"_attachment": "my_attachment",
"_data": "My Data",
"_content_type": "text/plain"
})).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "one",
"message": "Unable to put attachment",
"method": "putAttachment",
"reason": "missing",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Put attachment on a inexistent document -> 404 Not Found");
return jio.post({
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data"
});
}).then(function () {
return jio.putAttachment({
"_id": "one",
"_attachment": "my_attachment",
"_data": "My Data",
"_mimetype": "text/plain"
});
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"id": "one",
"method": "putAttachment",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Put attachment on a document");
// check uploaded documents
return jio_local_list.get({"_id": "one"});
}).then(function (answers) {
deepEqual(answers[0].data, {
"_attachments": {
"my_attachment": {
"content_type": "text/plain",
"digest": "sha256-ebf2d770a6a2dfa135f6c81431f22fc3cbcde9ae" +
"e52759ca9e520d4d964c1322", // sha256("My ")
"length": 3
}
},
"_id": "one",
"_underscored_meta": "uvalue",
"data": "{\"meta\""
}, "Check uploaded document in sub storage 1");
deepEqual(answers[1].data, {
"_attachments": {
"my_attachment": {
"content_type": "text/plain",
"digest": "sha256-cec3a9b89b2e391393d0f68e4bc12a9fa6cf358b" +
"3cdf79496dc442d52b8dd528", // sha256("Data")
"length": 4
}
},
"_id": "one",
"_underscored_meta": "uvalue",
"data": ":\"data\"}"
}, "Check uploaded document in sub storage 2");
return jio_local_list.getAttachmentAsBinaryString({
"_id": "one",
"_attachment": "my_attachment"
});
}).then(function (events) {
deepEqual(events[0].target.result, "My ",
"Check uploaded document in sub storage 1");
deepEqual(events[1].target.result, "Data",
"Check uploaded document in sub storage 1");
}).fail(unexpectedError).always(start);
});
test("Get", function () {
var shared = {}, jio;
shared.workspace = {};
shared.local_storage_description1 = {
"type": "local",
"username": "splitstorage",
"application_name": "get1",
"mode": "memory"
};
shared.local_storage_description2 = {
"type": "local",
"username": "splitstorage",
"application_name": "get2",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.local_storage_description1,
shared.local_storage_description2
]
}, {"workspace": shared.workspace});
stop();
reverse(jio.get({"_id": "one"})).then(function (answer) {
deepEqual(answer, {
"error": "not_found",
"id": "one",
"message": "Unable to get document",
"method": "get",
"reason": "missing",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Get missing document");
return jio.post({
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data"
});
}).then(function () {
return jio.get({"_id": "one"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data"
}, "Get posted document");
return jio.putAttachment({
"_id": "one",
"_attachment": "my_attachment",
"_data": "My Data",
"_content_type": "text/plain"
});
}).then(function () {
return jio.get({"_id": "one"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data",
"_attachments": {
"my_attachment": {
"length": 7,
"content_type": "text/plain"
}
}
}, "Get document with attachment informations");
}).fail(unexpectedError).always(start);
});
test("GetAttachment", function () {
var shared = {}, jio;
shared.workspace = {};
shared.local_storage_description1 = {
"type": "local",
"username": "splitstorage",
"application_name": "getAttachment1",
"mode": "memory"
};
shared.local_storage_description2 = {
"type": "local",
"username": "splitstorage",
"application_name": "getAttachment2",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.local_storage_description1,
shared.local_storage_description2
]
}, {"workspace": shared.workspace});
stop();
reverse(jio.getAttachment({
"_id": "one",
"_attachment": "my_attachment"
})).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "one",
"message": "Unable to get attachment",
"method": "getAttachment",
"reason": "missing document",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Get attachment from missing document -> 404 Not Found");
return jio.post({
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data"
});
}).then(function () {
return reverse(jio.getAttachment({
"_id": "one",
"_attachment": "my_attachment"
}));
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "one",
"message": "Unable to get attachment",
"method": "getAttachment",
"reason": "missing attachment",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Get missing attachment from document");
return jio.putAttachment({
"_id": "one",
"_attachment": "my_attachment",
"_data": "My Data",
"_mimetype": "text/plain"
});
}).then(function () {
return jio.getAttachment({"_id": "one", "_attachment": "my_attachment"});
}).then(function (answer) {
return tool.readBlobAsBinaryString(answer.data);
}).then(function (event) {
deepEqual(event.target.result, "My Data", "Get attachment");
}).fail(unexpectedError).always(start);
});
test("RemoveAttachment", function () {
var shared = {}, jio;
shared.workspace = {};
shared.local_storage_description1 = {
"type": "local",
"username": "splitstorage",
"application_name": "removeAttachment1",
"mode": "memory"
};
shared.local_storage_description2 = {
"type": "local",
"username": "splitstorage",
"application_name": "removeAttachment2",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.local_storage_description1,
shared.local_storage_description2
]
}, {"workspace": shared.workspace});
stop();
reverse(jio.removeAttachment({
"_id": "one",
"_attachment": "my_attachment"
})).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "one",
"message": "Unable to remove attachment",
"method": "removeAttachment",
"reason": "missing document",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Remove attachment from inexistent document -> 404 Not Found");
return jio.post({
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data"
});
}).then(function () {
return reverse(jio.removeAttachment({
"_id": "one",
"_attachment": "my_attachment"
}));
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "one",
"message": "Unable to remove attachment",
"method": "removeAttachment",
"reason": "missing attachment",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Remove inexistent attachment -> 404 Not Found");
return jio.putAttachment({
"_id": "one",
"_attachment": "my_attachment",
"_data": "My Data",
"_mimetype": "text/plain"
});
}).then(function () {
return jio.removeAttachment({
"_id": "one",
"_attachment": "my_attachment"
});
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"id": "one",
"method": "removeAttachment",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Remove attachment");
return jio.get({"_id": "one"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data"
}, "Check document");
return reverse(jio.getAttachment({
"_id": "one",
"_attachment": "my_attachment"
}));
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "one",
"message": "Unable to get attachment",
"method": "getAttachment",
"reason": "missing attachment",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Check attachment -> 404 Not Found");
}).fail(unexpectedError).always(start);
});
test("Remove", function () {
var shared = {}, jio;
shared.workspace = {};
shared.local_storage_description1 = {
"type": "local",
"username": "splitstorage",
"application_name": "remove1",
"mode": "memory"
};
shared.local_storage_description2 = {
"type": "local",
"username": "splitstorage",
"application_name": "remove2",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.local_storage_description1,
shared.local_storage_description2
]
}, {"workspace": shared.workspace});
stop();
reverse(jio.remove({"_id": "one"})).then(function (answer) {
deepEqual(answer, {
"error": "not_found",
"id": "one",
"message": "Unable to remove document",
"method": "remove",
"reason": "missing",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Remove missing document -> 404 Not Found");
return jio.post({
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data"
});
}).then(function () {
return jio.putAttachment({
"_id": "one",
"_attachment": "my_attachment",
"_data": "My Data",
"_mimetype": "text/plain"
});
}).then(function () {
return jio.remove({"_id": "one"});
}).then(function (answer) {
deepEqual(answer, {
"id": "one",
"method": "remove",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Remove document");
return reverse(jio.getAttachment({
"_id": "one",
"_attachment": "my_attachment"
}));
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "one",
"message": "Unable to get attachment",
"method": "getAttachment",
"reason": "missing document",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Check attachment -> 404 Not Found");
return reverse(jio.get({"_id": "one"}));
}).then(function (answer) {
deepEqual(answer, {
"error": "not_found",
"id": "one",
"message": "Unable to get document",
"method": "get",
"reason": "missing",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Check document -> 404 Not Found");
}).fail(unexpectedError).always(start);
});
test("Put", function () {
var shared = {}, jio;
shared.workspace = {};
shared.local_storage_description1 = {
"type": "local",
"username": "splitstorage",
"application_name": "put1",
"mode": "memory"
};
shared.local_storage_description2 = {
"type": "local",
"username": "splitstorage",
"application_name": "put2",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.local_storage_description1,
shared.local_storage_description2
]
}, {"workspace": shared.workspace});
stop();
jio.put({
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data"
}).then(function (answer) {
deepEqual(answer, {
"id": "one",
"method": "put",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Put new document");
return jio.get({"_id": "one"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data"
}, "Check document");
return jio.put({
"_id": "one",
"_underscored_meta": "uvalue",
"meow": "dog"
});
}).then(function (answer) {
deepEqual(answer, {
"id": "one",
"method": "put",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Put same document again");
return jio.get({"_id": "one"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "one",
"_underscored_meta": "uvalue",
"meow": "dog"
}, "Get document for check");
}).fail(unexpectedError).always(start);
});
test("AllDocs", function () {
var shared = {}, jio;
shared.workspace = {};
shared.local_storage_description1 = {
"type": "local",
"username": "splitstorage",
"application_name": "alldocs1",
"mode": "memory"
};
shared.local_storage_description2 = {
"type": "local",
"username": "splitstorage",
"application_name": "alldocs2",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.local_storage_description1,
shared.local_storage_description2
]
}, {"workspace": shared.workspace});
stop();
function prepareDatabase() {
var i, do_list = [];
function post(i) {
return function () {
return jio.post({
"_id": "doc" + i,
"_underscored_meta": "uvalue" + i,
"meta": "data" + i
});
};
}
function putAttachment(i) {
return function () {
return jio.putAttachment({
"_id": "doc" + i,
"_attachment": "my_attachment" + i,
"_data": "My Data" + i,
"_content_type": "text/plain"
});
};
}
for (i = 0; i < 5; i += 1) {
do_list.push(post(i));
}
for (i = 0; i < 2; i += 1) {
do_list.push(putAttachment(i));
}
return sequence(do_list);
}
prepareDatabase().then(function () {
return jio.get({"_id": "doc1"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "doc1",
"_underscored_meta": "uvalue1",
"meta": "data1",
"_attachments": {
"my_attachment1": {
"length": 8,
"content_type": "text/plain"
}
}
}, "Check document");
return jio.allDocs();
}).then(function (answer) {
answer.data.rows.sort(function (a, b) {
return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
});
deepEqual(answer.data, {
"total_rows": 5,
"rows": [{
"id": "doc0",
"key": "doc0",
"value": {}
}, {
"id": "doc1",
"key": "doc1",
"value": {}
}, {
"id": "doc2",
"key": "doc2",
"value": {}
}, {
"id": "doc3",
"key": "doc3",
"value": {}
}, {
"id": "doc4",
"key": "doc4",
"value": {}
}]
}, "AllDocs with document ids only");
}).fail(unexpectedError).always(start);
});
}));
jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/jio.storage/unionstorage.tests.js 0000664 0000000 0000000 00000075634 14230544473 0030366 0 ustar 00root root 0000000 0000000 /*
* Copyright 2014, Nexedi SA
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Free Software licenses or any of the Open Source
* Initiative approved licenses and Convey the resulting work. Corresponding
* source of such a combination shall include the source code for all other
* software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
* See https://www.nexedi.com/licensing for rationale and options.
*/
/*global Blob*/
/*jslint nomen: true */
(function (jIO, QUnit, Blob) {
"use strict";
var test = QUnit.test,
stop = QUnit.stop,
start = QUnit.start,
ok = QUnit.ok,
expect = QUnit.expect,
deepEqual = QUnit.deepEqual,
equal = QUnit.equal,
module = QUnit.module,
throws = QUnit.throws,
frozen_blob = new Blob(["foobar"]);
/////////////////////////////////////////////////////////////////
// Custom test substorage definition
/////////////////////////////////////////////////////////////////
function Storage404() {
return this;
}
function generate404Error(id) {
equal(id, "bar", "get 404 called");
throw new jIO.util.jIOError("Cannot find document", 404);
}
Storage404.prototype.get = generate404Error;
jIO.addStorage('unionstorage404', Storage404);
function Storage200() {
return this;
}
Storage200.prototype.get = function (id) {
equal(id, "bar", "get 200 called");
return {title: "foo"};
};
Storage200.prototype.allAttachments = function (id) {
equal(id, "bar", "allAttachments 200 called");
return {attachmentname: {}};
};
Storage200.prototype.getAttachment = function (id, name) {
equal(id, "bar", "getAttachment 200 called");
equal(name, "foo", "getAttachment 200 called");
return frozen_blob;
};
Storage200.prototype.removeAttachment = function (id, name) {
equal(id, "bar", "removeAttachment 200 called");
equal(name, "foo", "removeAttachment 200 called");
return "deleted";
};
Storage200.prototype.putAttachment = function (id, name, blob) {
equal(id, "bar", "putAttachment 200 called");
equal(name, "foo", "putAttachment 200 called");
deepEqual(blob, frozen_blob, "putAttachment 200 called");
return "stored";
};
Storage200.prototype.put = function (id, param) {
equal(id, "bar", "put 200 called");
deepEqual(param, {"title": "foo"}, "put 200 called");
return id;
};
Storage200.prototype.remove = function (id) {
equal(id, "bar", "remove 200 called");
return id;
};
Storage200.prototype.post = function (param) {
deepEqual(param, {"title": "foo"}, "post 200 called");
return "bar";
};
Storage200.prototype.hasCapacity = function () {
return true;
};
Storage200.prototype.buildQuery = function (options) {
deepEqual(options, {query: 'title: "two"'},
"buildQuery 200 called");
return [{
id: 200,
value: {
foo: "bar"
}
}];
};
Storage200.prototype.repair = function (options) {
deepEqual(options, {foo: "bar"}, "repair 200 called");
return "OK";
};
jIO.addStorage('unionstorage200', Storage200);
function Storage200v2() {
return this;
}
Storage200v2.prototype.hasCapacity = function () {
return true;
};
Storage200v2.prototype.buildQuery = function (options) {
deepEqual(options, {query: 'title: "two"'},
"buildQuery 200v2 called");
return [{
id: "200v2",
value: {
bar: "foo"
}
}];
};
jIO.addStorage('unionstorage200v2', Storage200v2);
function Storage500() {
return this;
}
function generateError() {
ok(true, "Error generation called");
throw new Error("manually triggered error");
}
Storage500.prototype.get = generateError;
Storage500.prototype.post = generateError;
Storage500.prototype.repair = generateError;
jIO.addStorage('unionstorage500', Storage500);
/////////////////////////////////////////////////////////////////
// unionStorage.constructor
/////////////////////////////////////////////////////////////////
module("unionStorage.constructor");
test("no storage list", function () {
var jio = jIO.createJIO({
type: "union",
storage_list: []
});
deepEqual(jio.__storage._storage_list, []);
});
test("initialize storage list", function () {
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage404"
}, {
type: "unionstorage200"
}]
});
equal(jio.__storage._storage_list.length, 2);
ok(jio.__storage._storage_list[0] instanceof jio.constructor);
equal(jio.__storage._storage_list[0].__type, "unionstorage404");
ok(jio.__storage._storage_list[1] instanceof jio.constructor);
equal(jio.__storage._storage_list[1].__type, "unionstorage200");
});
/////////////////////////////////////////////////////////////////
// unionStorage.get
/////////////////////////////////////////////////////////////////
module("unionStorage.get");
test("get inexistent document", function () {
stop();
expect(5);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage404"
}, {
type: "unionstorage404"
}]
});
jio.get("bar")
.fail(function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.message, "Cannot find document");
equal(error.status_code, 404);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("get document on first storage", function () {
stop();
expect(2);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage200"
}, {
type: "unionstorage404"
}]
});
jio.get("bar")
.then(function (result) {
deepEqual(result, {
"title": "foo"
}, "Check document");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("get document on second storage", function () {
stop();
expect(3);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage404"
}, {
type: "unionstorage200"
}]
});
jio.get("bar")
.then(function (result) {
deepEqual(result, {
"title": "foo"
}, "Check document");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("get error on first storage", function () {
stop();
expect(4);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage500"
}, {
type: "unionstorage200"
}]
});
jio.get("bar")
.fail(function (error) {
ok(error instanceof Error);
equal(error.message, "manually triggered error");
equal(error.status_code, undefined);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("get error on second storage", function () {
stop();
expect(5);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage404"
}, {
type: "unionstorage500"
}]
});
jio.get("bar")
.fail(function (error) {
ok(error instanceof Error);
equal(error.message, "manually triggered error");
equal(error.status_code, undefined);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// unionStorage.allAttachments
/////////////////////////////////////////////////////////////////
module("unionStorage.allAttachments");
test("allAttachments inexistent document", function () {
stop();
expect(5);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage404"
}, {
type: "unionstorage404"
}]
});
jio.allAttachments("bar")
.fail(function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.message, "Cannot find document");
equal(error.status_code, 404);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("allAttachments document on first storage", function () {
stop();
expect(3);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage200"
}, {
type: "unionstorage404"
}]
});
jio.allAttachments("bar")
.then(function (result) {
deepEqual(result, {
"attachmentname": {}
}, "Check document");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("allAttachments document on second storage", function () {
stop();
expect(4);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage404"
}, {
type: "unionstorage200"
}]
});
jio.allAttachments("bar")
.then(function (result) {
deepEqual(result, {
"attachmentname": {}
}, "Check document");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("allAttachments error on first storage", function () {
stop();
expect(4);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage500"
}, {
type: "unionstorage200"
}]
});
jio.allAttachments("bar")
.fail(function (error) {
ok(error instanceof Error);
equal(error.message, "manually triggered error");
equal(error.status_code, undefined);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("allAttachments error on second storage", function () {
stop();
expect(5);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage404"
}, {
type: "unionstorage500"
}]
});
jio.allAttachments("bar")
.fail(function (error) {
ok(error instanceof Error);
equal(error.message, "manually triggered error");
equal(error.status_code, undefined);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// unionStorage.post
/////////////////////////////////////////////////////////////////
module("unionStorage.post");
test("post generate an error", function () {
stop();
expect(4);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage500"
}, {
type: "unionstorage200"
}]
});
jio.post({"title": "foo"})
.fail(function (error) {
ok(error instanceof Error);
equal(error.message, "manually triggered error");
equal(error.status_code, undefined);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("post store on first storage", function () {
stop();
expect(2);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage200"
}, {
type: "unionstorage500"
}]
});
jio.post({"title": "foo"})
.then(function (result) {
equal(result, "bar");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// unionStorage.put
/////////////////////////////////////////////////////////////////
module("unionStorage.put");
test("put generate an error", function () {
stop();
expect(4);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage500"
}, {
type: "unionstorage200"
}]
});
jio.put("bar", {"title": "foo"})
.fail(function (error) {
ok(error instanceof Error);
equal(error.message, "manually triggered error");
equal(error.status_code, undefined);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("put on first storage", function () {
stop();
expect(4);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage200"
}, {
type: "unionstorage500"
}]
});
jio.put("bar", {"title": "foo"})
.then(function (result) {
equal(result, "bar");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("put on second storage", function () {
stop();
expect(5);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage404"
}, {
type: "unionstorage200"
}]
});
jio.put("bar", {"title": "foo"})
.then(function (result) {
equal(result, "bar");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("put create on first storage", function () {
stop();
expect(5);
function StoragePut404() {
return this;
}
function generatePut404Error(id) {
equal(id, "bar", "get Put404 called");
throw new jIO.util.jIOError("Cannot find document", 404);
}
StoragePut404.prototype.get = generatePut404Error;
StoragePut404.prototype.put = function (id, param) {
equal(id, "bar", "put 404 called");
deepEqual(param, {"title": "foo"}, "put 404 called");
return id;
};
jIO.addStorage('unionstorageput404', StoragePut404);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorageput404"
}, {
type: "unionstorage404"
}]
});
jio.put("bar", {"title": "foo"})
.then(function (result) {
equal(result, "bar");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// unionStorage.remove
/////////////////////////////////////////////////////////////////
module("unionStorage.remove");
test("remove generate an error", function () {
stop();
expect(4);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage500"
}, {
type: "unionstorage200"
}]
});
jio.remove("bar")
.fail(function (error) {
ok(error instanceof Error);
equal(error.message, "manually triggered error");
equal(error.status_code, undefined);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("remove on first storage", function () {
stop();
expect(3);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage200"
}, {
type: "unionstorage500"
}]
});
jio.remove("bar")
.then(function (result) {
equal(result, "bar");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("remove on second storage", function () {
stop();
expect(4);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage404"
}, {
type: "unionstorage200"
}]
});
jio.remove("bar")
.then(function (result) {
equal(result, "bar");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// unionStorage.hasCapacity
/////////////////////////////////////////////////////////////////
module("unionStorage.hasCapacity");
test("Supported capacity without storage", function () {
var jio = jIO.createJIO({
type: "union",
storage_list: []
});
ok(jio.hasCapacity("list"));
ok(jio.hasCapacity("query"));
ok(jio.hasCapacity("select"));
});
test("hasCapacity list not implemented in substorage", function () {
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage200"
}, {
type: "unionstorage404"
}]
});
throws(
function () {
jio.hasCapacity("list");
},
function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.status_code, 501);
equal(error.message,
"Capacity 'list' is not implemented on 'unionstorage404'");
return true;
}
);
});
test("hasCapacity list implemented in substorage", function () {
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage200"
}, {
type: "unionstorage200"
}]
});
ok(jio.hasCapacity("list"));
});
test("hasCapacity sort not manually done in union", function () {
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage200"
}, {
type: "unionstorage200"
}]
});
throws(
function () {
jio.hasCapacity("sort");
},
function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.status_code, 501);
equal(error.message, "Capacity 'sort' is not implemented on 'union'");
return true;
}
);
});
/////////////////////////////////////////////////////////////////
// unionStorage.allDocs
/////////////////////////////////////////////////////////////////
module("unionStorage.allDocs");
test("allDocs remove duplicated keys", function () {
stop();
expect(3);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage200"
}, {
type: "unionstorage200"
}]
});
jio.allDocs({
query: 'title: "two"'
})
.then(function (result) {
deepEqual(result, {
data: {
rows: [{
id: 200,
value: {
foo: "bar"
}
}],
total_rows: 1
}
});
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("allDocs concatenates results", function () {
stop();
expect(3);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage200v2"
}, {
type: "unionstorage200"
}]
});
jio.allDocs({
query: 'title: "two"'
})
.then(function (result) {
deepEqual(result, {
data: {
rows: [{
id: "200v2",
value: {
bar: "foo"
}
}, {
id: 200,
value: {
foo: "bar"
}
}],
total_rows: 2
}
});
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("allDocs fails in one substorage fails", function () {
stop();
expect(3);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage200"
}, {
type: "unionstorage500"
}]
});
jio.allDocs({
query: 'title: "two"'
})
.fail(function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.message,
"Capacity 'list' is not implemented on 'unionstorage500'");
equal(error.status_code, 501);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// unionStorage.repair
/////////////////////////////////////////////////////////////////
module("unionStorage.repair");
test("repair called substorage repair", function () {
stop();
expect(3);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage200"
}, {
type: "unionstorage200"
}]
});
jio.repair({foo: "bar"})
.then(function (result) {
deepEqual(result, ["OK", "OK"]);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("repair fails in one substorage fails", function () {
stop();
expect(5);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage200"
}, {
type: "unionstorage500"
}]
});
jio.repair({foo: "bar"})
.fail(function (error) {
ok(error instanceof Error);
equal(error.message, "manually triggered error");
equal(error.status_code, undefined);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// unionStorage.getAttachment
/////////////////////////////////////////////////////////////////
module("unionStorage.getAttachment");
test("getAttachment inexistent document", function () {
stop();
expect(5);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage404"
}, {
type: "unionstorage404"
}]
});
jio.getAttachment("bar", "foo")
.fail(function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.message, "Cannot find document");
equal(error.status_code, 404);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("getAttachment document on first storage", function () {
stop();
expect(4);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage200"
}, {
type: "unionstorage404"
}]
});
jio.getAttachment("bar", "foo")
.then(function (result) {
deepEqual(result, frozen_blob, "Check Blob");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("getAttachment document on second storage", function () {
stop();
expect(5);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage404"
}, {
type: "unionstorage200"
}]
});
jio.getAttachment("bar", "foo")
.then(function (result) {
deepEqual(result, frozen_blob, "Check Blob");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("getAttachment error on first storage", function () {
stop();
expect(4);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage500"
}, {
type: "unionstorage200"
}]
});
jio.getAttachment("bar", "foo")
.fail(function (error) {
ok(error instanceof Error);
equal(error.message, "manually triggered error");
equal(error.status_code, undefined);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("getAttachment error on second storage", function () {
stop();
expect(5);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage404"
}, {
type: "unionstorage500"
}]
});
jio.getAttachment("bar", "foo")
.fail(function (error) {
ok(error instanceof Error);
equal(error.message, "manually triggered error");
equal(error.status_code, undefined);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// unionStorage.removeAttachment
/////////////////////////////////////////////////////////////////
module("unionStorage.removeAttachment");
test("removeAttachment inexistent document", function () {
stop();
expect(5);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage404"
}, {
type: "unionstorage404"
}]
});
jio.removeAttachment("bar", "foo")
.fail(function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.message, "Cannot find document");
equal(error.status_code, 404);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("removeAttachment document on first storage", function () {
stop();
expect(4);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage200"
}, {
type: "unionstorage404"
}]
});
jio.removeAttachment("bar", "foo")
.then(function (result) {
equal(result, "deleted", "Check result");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("removeAttachment document on second storage", function () {
stop();
expect(5);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage404"
}, {
type: "unionstorage200"
}]
});
jio.removeAttachment("bar", "foo")
.then(function (result) {
equal(result, "deleted", "Check result");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("removeAttachment error on first storage", function () {
stop();
expect(4);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage500"
}, {
type: "unionstorage200"
}]
});
jio.removeAttachment("bar", "foo")
.fail(function (error) {
ok(error instanceof Error);
equal(error.message, "manually triggered error");
equal(error.status_code, undefined);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("removeAttachment error on second storage", function () {
stop();
expect(5);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage404"
}, {
type: "unionstorage500"
}]
});
jio.removeAttachment("bar", "foo")
.fail(function (error) {
ok(error instanceof Error);
equal(error.message, "manually triggered error");
equal(error.status_code, undefined);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// unionStorage.putAttachment
/////////////////////////////////////////////////////////////////
module("unionStorage.putAttachment");
test("putAttachment inexistent document", function () {
stop();
expect(5);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage404"
}, {
type: "unionstorage404"
}]
});
jio.putAttachment("bar", "foo", frozen_blob)
.fail(function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.message, "Cannot find document");
equal(error.status_code, 404);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("putAttachment document on first storage", function () {
stop();
expect(5);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage200"
}, {
type: "unionstorage404"
}]
});
jio.putAttachment("bar", "foo", frozen_blob)
.then(function (result) {
equal(result, "stored", "Check result");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("putAttachment document on second storage", function () {
stop();
expect(6);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage404"
}, {
type: "unionstorage200"
}]
});
jio.putAttachment("bar", "foo", frozen_blob)
.then(function (result) {
equal(result, "stored", "Check result");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("putAttachment error on first storage", function () {
stop();
expect(4);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage500"
}, {
type: "unionstorage200"
}]
});
jio.putAttachment("bar", "foo", frozen_blob)
.fail(function (error) {
ok(error instanceof Error);
equal(error.message, "manually triggered error");
equal(error.status_code, undefined);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("putAttachment error on second storage", function () {
stop();
expect(5);
var jio = jIO.createJIO({
type: "union",
storage_list: [{
type: "unionstorage404"
}, {
type: "unionstorage500"
}]
});
jio.putAttachment("bar", "foo", frozen_blob)
.fail(function (error) {
ok(error instanceof Error);
equal(error.message, "manually triggered error");
equal(error.status_code, undefined);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
}(jIO, QUnit, Blob));
jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/jio.storage/uuidstorage.tests.js 0000664 0000000 0000000 00000027067 14230544473 0030201 0 ustar 00root root 0000000 0000000 /*
* Copyright 2015, Nexedi SA
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Free Software licenses or any of the Open Source
* Initiative approved licenses and Convey the resulting work. Corresponding
* source of such a combination shall include the source code for all other
* software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
* See https://www.nexedi.com/licensing for rationale and options.
*/
/*jslint nomen: true*/
/*global Blob*/
(function (jIO, QUnit, Blob) {
"use strict";
var test = QUnit.test,
stop = QUnit.stop,
start = QUnit.start,
ok = QUnit.ok,
expect = QUnit.expect,
deepEqual = QUnit.deepEqual,
equal = QUnit.equal,
module = QUnit.module,
throws = QUnit.throws;
/////////////////////////////////////////////////////////////////
// Custom test substorage definition
/////////////////////////////////////////////////////////////////
function Storage200() {
return this;
}
jIO.addStorage('uuidstorage200', Storage200);
/////////////////////////////////////////////////////////////////
// uuidStorage.constructor
/////////////////////////////////////////////////////////////////
module("uuidStorage.constructor");
test("create substorage", function () {
var jio = jIO.createJIO({
type: "uuid",
sub_storage: {
type: "uuidstorage200"
}
});
ok(jio.__storage._sub_storage instanceof jio.constructor);
equal(jio.__storage._sub_storage.__type, "uuidstorage200");
});
/////////////////////////////////////////////////////////////////
// uuidStorage.get
/////////////////////////////////////////////////////////////////
module("uuidStorage.get");
test("get called substorage get", function () {
stop();
expect(2);
var jio = jIO.createJIO({
type: "uuid",
sub_storage: {
type: "uuidstorage200"
}
});
Storage200.prototype.get = function (param) {
equal(param, "bar", "get 200 called");
return {title: "foo"};
};
jio.get("bar")
.then(function (result) {
deepEqual(result, {
"title": "foo"
}, "Check document");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// uuidStorage.allAttachments
/////////////////////////////////////////////////////////////////
module("uuidStorage.allAttachments");
test("get called substorage allAttachments", function () {
stop();
expect(2);
var jio = jIO.createJIO({
type: "uuid",
sub_storage: {
type: "uuidstorage200"
}
});
Storage200.prototype.allAttachments = function (param) {
equal(param, "bar", "allAttachments 200 called");
return {attachmentname: {}};
};
jio.allAttachments("bar")
.then(function (result) {
deepEqual(result, {
attachmentname: {}
}, "Check document");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// uuidStorage.post
/////////////////////////////////////////////////////////////////
module("uuidStorage.post");
test("post called substorage put with a new id", function () {
stop();
expect(3);
var jio = jIO.createJIO({
type: "uuid",
sub_storage: {
type: "uuidstorage200"
}
}),
uuid;
function isUuid(uuid) {
var x = "[0-9a-fA-F]";
if (typeof uuid !== "string") {
return false;
}
return (uuid.match(
"^" + x + "{8}-" + x + "{4}-" +
x + "{4}-" + x + "{4}-" + x + "{12}$"
) === null ? false : true);
}
Storage200.prototype.put = function (id, param) {
uuid = id;
deepEqual(param, {"title": "foo"}, "post 200 called");
return "bar";
};
jio.post({"title": "foo"})
.then(function (result) {
equal(result, uuid);
ok(isUuid(uuid), uuid);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// uuidStorage.put
/////////////////////////////////////////////////////////////////
module("uuidStorage.put");
test("put called substorage put", function () {
stop();
expect(3);
var jio = jIO.createJIO({
type: "uuid",
sub_storage: {
type: "uuidstorage200"
}
});
Storage200.prototype.put = function (id, param) {
equal(id, "bar", "put 200 called");
deepEqual(param, {"title": "foo"}, "put 200 called");
return id;
};
jio.put("bar", {"title": "foo"})
.then(function (result) {
equal(result, "bar");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// uuidStorage.remove
/////////////////////////////////////////////////////////////////
module("uuidStorage.remove");
test("remove called substorage remove", function () {
stop();
expect(2);
var jio = jIO.createJIO({
type: "uuid",
sub_storage: {
type: "uuidstorage200"
}
});
Storage200.prototype.remove = function (param) {
equal(param, "bar", "remove 200 called");
return param._id;
};
jio.remove("bar")
.then(function (result) {
equal(result, "bar");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// uuidStorage.getAttachment
/////////////////////////////////////////////////////////////////
module("uuidStorage.getAttachment");
test("getAttachment called substorage getAttachment", function () {
stop();
expect(3);
var jio = jIO.createJIO({
type: "uuid",
sub_storage: {
type: "uuidstorage200"
}
}),
blob = new Blob([""]);
Storage200.prototype.getAttachment = function (id, name) {
equal(id, "bar", "getAttachment 200 called");
equal(name, "foo", "getAttachment 200 called");
return blob;
};
jio.getAttachment("bar", "foo")
.then(function (result) {
equal(result, blob);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// uuidStorage.putAttachment
/////////////////////////////////////////////////////////////////
module("uuidStorage.putAttachment");
test("putAttachment called substorage putAttachment", function () {
stop();
expect(4);
var jio = jIO.createJIO({
type: "uuid",
sub_storage: {
type: "uuidstorage200"
}
}),
blob = new Blob([""]);
Storage200.prototype.putAttachment = function (id, name, blob2) {
equal(id, "bar", "putAttachment 200 called");
equal(name, "foo", "putAttachment 200 called");
deepEqual(blob2, blob, "putAttachment 200 called");
return "OK";
};
jio.putAttachment("bar", "foo", blob)
.then(function (result) {
equal(result, "OK");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// uuidStorage.removeAttachment
/////////////////////////////////////////////////////////////////
module("uuidStorage.removeAttachment");
test("removeAttachment called substorage removeAttachment", function () {
stop();
expect(3);
var jio = jIO.createJIO({
type: "uuid",
sub_storage: {
type: "uuidstorage200"
}
});
Storage200.prototype.removeAttachment = function (id, name) {
equal(id, "bar", "removeAttachment 200 called");
equal(name, "foo", "removeAttachment 200 called");
return "Removed";
};
jio.removeAttachment("bar", "foo")
.then(function (result) {
equal(result, "Removed");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// uuidStorage.hasCapacity
/////////////////////////////////////////////////////////////////
module("uuidStorage.hasCapacity");
test("hasCapacity return substorage value", function () {
var jio = jIO.createJIO({
type: "uuid",
sub_storage: {
type: "uuidstorage200"
}
});
delete Storage200.prototype.hasCapacity;
throws(
function () {
jio.hasCapacity("foo");
},
function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.status_code, 501);
equal(error.message,
"Capacity 'foo' is not implemented on 'uuidstorage200'");
return true;
}
);
});
/////////////////////////////////////////////////////////////////
// uuidStorage.buildQuery
/////////////////////////////////////////////////////////////////
module("uuidStorage.buildQuery");
test("buildQuery return substorage buildQuery", function () {
stop();
expect(2);
var jio = jIO.createJIO({
type: "uuid",
sub_storage: {
type: "uuidstorage200"
}
});
Storage200.prototype.hasCapacity = function () {
return true;
};
Storage200.prototype.buildQuery = function (options) {
deepEqual(options, {
include_docs: false,
sort_on: [["title", "ascending"]],
limit: [5],
select_list: ["title", "id"],
uuid: 'title: "two"'
}, "allDocs parameter");
return "bar";
};
jio.allDocs({
include_docs: false,
sort_on: [["title", "ascending"]],
limit: [5],
select_list: ["title", "id"],
uuid: 'title: "two"'
})
.then(function (result) {
deepEqual(result, {
data: {
rows: "bar",
total_rows: 3
}
});
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// uuidStorage.repair
/////////////////////////////////////////////////////////////////
module("uuidStorage.repair");
test("repair called substorage repair", function () {
stop();
expect(2);
var jio = jIO.createJIO({
type: "uuid",
sub_storage: {
type: "uuidstorage200"
}
}),
expected_options = {foo: "bar"};
Storage200.prototype.repair = function (options) {
deepEqual(options, expected_options, "repair 200 called");
return "OK";
};
jio.repair(expected_options)
.then(function (result) {
equal(result, "OK");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
}(jIO, QUnit, Blob));
jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/jio.storage/websqlstorage.tests.js 0000664 0000000 0000000 00000106152 14230544473 0030521 0 ustar 00root root 0000000 0000000 /*
* Copyright 2015, Nexedi SA
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Free Software licenses or any of the Open Source
* Initiative approved licenses and Convey the resulting work. Corresponding
* source of such a combination shall include the source code for all other
* software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
* See https://www.nexedi.com/licensing for rationale and options.
*/
/*jslint nomen: true */
/*global openDatabase, Blob, sinon*/
(function (jIO, QUnit, openDatabase, Blob, sinon) {
"use strict";
var test = QUnit.test,
stop = QUnit.stop,
start = QUnit.start,
ok = QUnit.ok,
expect = QUnit.expect,
deepEqual = QUnit.deepEqual,
equal = QUnit.equal,
module = QUnit.module,
big_string = "",
db,
j;
try {
db = openDatabase('jio:qunit', '1.0', '', 2 * 1024 * 1024);
} catch (ignore) {
}
if (db === undefined) {
return;
}
function getSpy() {
return new RSVP.Promise(function (resolve, reject) {
var spy;
db.transaction(function (tx) {
spy = sinon.spy(tx.constructor.prototype, "executeSql");
resolve(spy);
}, reject);
});
}
function exec(transac, args) {
return new RSVP.Promise(function (resolve, reject) {
db.transaction(function (tx) {
/*jslint unparam: true*/
tx.executeSql(transac, args,
function (tx, result) {
resolve(result);
},
function (tx, error) {
reject(error);
});
});
/*jslint unparam: false*/
});
}
function spyStorageCreation(context) {
ok(context.spy.callCount >= 5);
equal(context.spy.args[0][0],
'CREATE TABLE IF NOT EXISTS document(id VARCHAR PRIMARY ' +
'KEY NOT NULL, data TEXT)');
equal(context.spy.args[1][0],
'CREATE TABLE IF NOT EXISTS attachment(id VARCHAR, attachment' +
' VARCHAR, part INT, blob TEXT)');
equal(context.spy.args[2][0],
"CREATE TRIGGER IF NOT EXISTS removeAttachment " +
"BEFORE DELETE ON document FOR EACH ROW " +
"BEGIN DELETE from attachment WHERE id = OLD.id;END;");
equal(context.spy.args[3][0],
"CREATE INDEX IF NOT EXISTS index_document ON document (id);");
equal(context.spy.args[4][0], "CREATE INDEX IF NOT EXISTS " +
"index_attachment ON attachment (id, attachment);");
}
function deleteRow(it, queue, result) {
queue.push(function () {
return exec("DELETE FROM " + result.rows[it].name);
});
}
function deleteWebsql() {
return new RSVP.Queue()
.push(function () {
return exec('SELECT name FROM sqlite_master WHERE' +
' type ="table" AND name != "__WebKitDatabaseInfoTable__"');
})
.push(function (result) {
var i,
len = result.rows.length,
queue = new RSVP.Queue();
for (i = 0; i < len; i += 1) {
deleteRow(i, queue, result);
}
return queue;
});
}
for (j = 0; j < 40; j += 1) {
big_string += "a";
}
/////////////////////////////////////////////////////////////////
// websqlStorage.constructor
/////////////////////////////////////////////////////////////////
module("websqlStorage.constructor", {
setup: function () {
this.jio = jIO.createJIO({
type: "websql",
database: "qunit"
});
this.spy = getSpy();
},
teardown: function () {
this.spy.restore();
delete this.spy;
}
});
test("creation of the storage", function () {
var context = this;
stop();
expect(1);
context.spy.then(function (value) {
context.spy = value;
return;
})
.then(function () {
equal(context.jio.__type, "websql");
return deleteWebsql();
})
.fail(function (error) {
ok(false, error);
return deleteWebsql();
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// websqlStorage.hasCapacity
/////////////////////////////////////////////////////////////////
module("websqlStorage.hasCapacity", {
setup: function () {
this.jio = jIO.createJIO({
type: "websql",
database: "qunit"
});
this.spy = getSpy();
},
teardown: function () {
this.spy.restore();
delete this.spy;
}
});
test("can list document", function () {
var context = this;
stop();
expect(1);
context.spy.then(function (value) {
context.spy = value;
return;
})
.then(function () {
ok(context.jio.hasCapacity("list"));
return deleteWebsql();
})
.fail(function (error) {
ok(false, error);
return deleteWebsql();
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// websqlStorage.buildQuery
/////////////////////////////////////////////////////////////////
module("websqlStorage.buildQuery", {
setup: function () {
this.jio = jIO.createJIO({
type: "websql",
database: "qunit"
});
this.spy = getSpy();
},
teardown: function () {
this.spy.restore();
delete this.spy;
}
});
test("spy webSQL usage", function () {
var context = this;
stop();
expect(8);
context.spy.then(function (value) {
context.spy = value;
return;
})
.then(function () {
return context.jio.allDocs();
})
.then(function () {
equal(context.spy.args[5][0], 'SELECT id FROM document');
deepEqual(context.spy.args[5][1], []);
spyStorageCreation(context);
return;
})
.then(function () {
return deleteWebsql();
})
.fail(function (error) {
ok(false, error);
return deleteWebsql();
})
.always(function () {
start();
});
});
test("spy webSQL usage with include_docs", function () {
var context = this;
stop();
expect(8);
context.spy.then(function (value) {
context.spy = value;
return;
})
.then(function () {
return context.jio.allDocs({include_docs: true});
})
.then(function () {
equal(context.spy.args[5][0],
'SELECT id, data AS doc FROM document');
deepEqual(context.spy.args[5][1], []);
spyStorageCreation(context);
return;
})
.then(function () {
return deleteWebsql();
})
.fail(function (error) {
ok(false, error);
return deleteWebsql();
})
.always(function () {
start();
});
});
test("empty result", function () {
var context = this;
stop();
expect(1);
context.spy.then(function (value) {
context.spy = value;
})
.then(function () {
return context.jio.allDocs();
})
.then(function (result) {
deepEqual(result, {
"data": {
"rows": [
],
"total_rows": 0
}
});
return deleteWebsql();
})
.fail(function (error) {
ok(false, error);
return deleteWebsql();
})
.always(function () {
start();
});
});
test("list all document", function () {
var context = this;
stop();
expect(1);
context.spy.then(function (value) {
context.spy = value;
})
.then(function () {
return RSVP.all([
context.jio.put("2", {"title": "title2"}),
context.jio.put("1", {"title": "title1"})
]);
})
.then(function () {
return context.jio.allDocs();
})
.then(function (result) {
deepEqual(result, {
"data": {
"rows": [{
"id": "1",
"value": {}
}, {
"id": "2",
"value": {}
}],
"total_rows": 2
}
});
return deleteWebsql();
})
.fail(function (error) {
ok(false, error);
return deleteWebsql();
})
.always(function () {
start();
});
});
test("handle include_docs", function () {
var context = this;
stop();
expect(1);
context.spy.then(function (value) {
context.spy = value;
})
.then(function () {
return RSVP.all([
context.jio.put("2", {"title": "title2"}),
context.jio.put("1", {"title": "title1"})
]);
})
.then(function () {
return context.jio.allDocs({include_docs: true});
})
.then(function (result) {
deepEqual(result, {
"data": {
"rows": [{
"id": "2",
"doc": {"title": "title2"},
"value": {}
}, {
"id": "1",
"doc": {"title": "title1"},
"value": {}
}],
"total_rows": 2
}
});
return deleteWebsql();
})
.fail(function (error) {
ok(false, error);
return deleteWebsql();
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// websqlStorage.get
/////////////////////////////////////////////////////////////////
module("websqlStorage.get", {
setup: function () {
this.jio = jIO.createJIO({
type: "websql",
database: "qunit"
});
this.spy = getSpy();
},
teardown: function () {
this.spy.restore();
delete this.spy;
}
});
test("spy webSQL usage", function () {
var context = this;
stop();
expect(10);
context.spy.then(function (value) {
context.spy = value;
return;
})
.then(function () {
return context.jio.put("foo", {"title": "bar"});
})
.then(function () {
return context.jio.get("foo");
})
.then(function () {
equal(context.spy.args[5][0],
'INSERT OR REPLACE INTO document(id, data) VALUES(?,?)');
deepEqual(context.spy.args[5][1], ['foo', '{"title":"bar"}']);
equal(context.spy.args[6][0],
'SELECT data FROM document WHERE id = ?');
deepEqual(context.spy.args[6][1], ['foo']);
spyStorageCreation(context);
})
.then(function () {
return deleteWebsql();
})
.fail(function (error) {
ok(false, error);
return deleteWebsql();
})
.always(function () {
start();
});
});
test("get inexistent document", function () {
var context = this;
stop();
expect(3);
context.spy.then(function (value) {
context.spy = value;
return deleteWebsql();
})
.then(function () {
return context.jio.get("inexistent");
})
.fail(function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.message, "Cannot find document");
equal(error.status_code, 404);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("get document without attachment", function () {
var id = "/",
context = this;
stop();
expect(1);
context.spy.then(function (value) {
context.spy = value;
return deleteWebsql();
})
.then(function () {
return context.jio.put(id, {"title": "bar"});
})
.then(function () {
return context.jio.get(id);
})
.then(function (result) {
deepEqual(result, {
"title": "bar"
}, "Check document");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("get document with attachment", function () {
var id = "/",
attachment = "foo",
context = this;
stop();
expect(1);
context.spy.then(function (value) {
context.spy = value;
return deleteWebsql();
})
.then(function () {
return context.jio.put(id, {"title": "bar"});
})
.then(function () {
return context.jio.putAttachment(id, attachment, "bar");
})
.then(function () {
return context.jio.get(id);
})
.then(function (result) {
deepEqual(result, {
"title": "bar"
}, "Check document");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// websqlStorage.allAttachments
/////////////////////////////////////////////////////////////////
module("websqlStorage.allAttachments", {
setup: function () {
this.jio = jIO.createJIO({
type: "websql",
database: "qunit"
});
this.spy = getSpy();
},
teardown: function () {
this.spy.restore();
delete this.spy;
}
});
test("spy webSQL usage", function () {
var context = this;
stop();
expect(12);
context.spy.then(function (value) {
context.spy = value;
return;
})
.then(function () {
return context.jio.put("foo", {"title": "bar"});
})
.then(function () {
return context.jio.allAttachments("foo");
})
.then(function () {
spyStorageCreation(context);
equal(context.spy.args[5][0],
'INSERT OR REPLACE INTO document(id, data) VALUES(?,?)');
deepEqual(context.spy.args[5][1], ['foo', '{"title":"bar"}']);
equal(context.spy.args[6][0],
'SELECT id FROM document WHERE id = ?');
deepEqual(context.spy.args[6][1], ['foo']);
equal(context.spy.args[7][0],
'SELECT DISTINCT attachment FROM attachment WHERE id = ?');
deepEqual(context.spy.args[7][1], ['foo']);
})
.then(function () {
return deleteWebsql();
})
.fail(function (error) {
ok(false, error);
return deleteWebsql();
})
.always(function () {
start();
});
});
test("get inexistent document", function () {
var context = this;
stop();
expect(3);
context.spy.then(function (value) {
context.spy = value;
return deleteWebsql();
})
.then(function () {
return context.jio.allAttachments("inexistent");
})
.fail(function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.message, "Cannot find document");
equal(error.status_code, 404);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("get document without attachment", function () {
var id = "/",
context = this;
stop();
expect(1);
context.spy.then(function (value) {
context.spy = value;
return deleteWebsql();
})
.then(function () {
return context.jio.put(id, {"title": "bar"});
})
.then(function () {
return context.jio.allAttachments(id);
})
.then(function (result) {
deepEqual(result, {}, "Check document");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("get document with attachment", function () {
var id = "/",
attachment = "foo",
context = this;
stop();
expect(1);
context.spy.then(function (value) {
context.spy = value;
return deleteWebsql();
})
.then(function () {
return context.jio.put(id, {"title": "bar"});
})
.then(function () {
return context.jio.putAttachment(id, attachment, "bar");
})
.then(function () {
return context.jio.allAttachments(id);
})
.then(function (result) {
deepEqual(result, {
"foo": {}
}, "Check document");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// websqlStorage.put
/////////////////////////////////////////////////////////////////
module("websqlStorage.put", {
setup: function () {
this.jio = jIO.createJIO({
type: "websql",
database: "qunit"
});
this.spy = getSpy();
},
teardown: function () {
this.spy.restore();
delete this.spy;
}
});
test("spy webSQL usage", function () {
var context = this;
stop();
expect(8);
context.spy.then(function (value) {
context.spy = value;
return;
})
.then(function () {
return context.jio.put("foo", {"title": "bar"});
})
.then(function () {
return context.jio.allAttachments("foo");
})
.then(function () {
spyStorageCreation(context);
equal(context.spy.args[5][0],
'INSERT OR REPLACE INTO document(id, data) VALUES(?,?)');
deepEqual(context.spy.args[5][1], ['foo', '{"title":"bar"}']);
})
.then(function () {
return deleteWebsql();
})
.fail(function (error) {
ok(false, error);
return deleteWebsql();
})
.always(function () {
start();
});
});
test("put document", function () {
var context = this;
stop();
expect(1);
context.spy.then(function (value) {
context.spy = value;
return deleteWebsql();
})
.then(function () {
return context.jio.put("inexistent", {});
})
.then(function (result) {
equal(result, "inexistent");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// websqlStorage.remove
/////////////////////////////////////////////////////////////////
module("websqlStorage.remove", {
setup: function () {
this.jio = jIO.createJIO({
type: "websql",
database: "qunit"
});
this.spy = getSpy();
},
teardown: function () {
this.spy.restore();
delete this.spy;
}
});
test("spy webSQL usage with one document", function () {
var context = this;
stop();
expect(10);
context.spy.then(function (value) {
context.spy = value;
return;
})
.then(function () {
return context.jio.put("foo", {"title": "bar"});
})
.then(function () {
return context.jio.remove("foo");
})
.then(function () {
spyStorageCreation(context);
equal(context.spy.args[5][0],
'INSERT OR REPLACE INTO document(id, data) VALUES(?,?)');
deepEqual(context.spy.args[5][1], ['foo', '{"title":"bar"}']);
equal(context.spy.args[6][0], 'DELETE FROM document WHERE id = ?');
deepEqual(context.spy.args[6][1], ['foo']);
})
.then(function () {
return deleteWebsql();
})
.fail(function (error) {
ok(false, error);
return deleteWebsql();
})
.always(function () {
start();
});
});
test("spy webSQL usage with two attachments", function () {
var context = this;
stop();
expect(26);
context.spy.then(function (value) {
context.spy = value;
return;
})
.then(function () {
return context.jio.put("foo", {"title": "bar"});
})
.then(function () {
return context.jio.putAttachment("foo", "attachment1", "bar");
})
.then(function () {
return context.jio.putAttachment("foo", "attachment2", "bar2");
})
.then(function () {
return context.jio.remove("foo");
})
.then(function () {
spyStorageCreation(context);
equal(context.spy.args[5][0],
'INSERT OR REPLACE INTO document(id, data) VALUES(?,?)');
deepEqual(context.spy.args[5][1], ['foo', '{"title":"bar"}']);
equal(context.spy.args[6][0],
'SELECT id FROM document WHERE id = ?');
deepEqual(context.spy.args[6][1], ['foo']);
equal(context.spy.args[7][0],
'DELETE FROM attachment WHERE id = ? AND attachment = ?');
deepEqual(context.spy.args[7][1], ['foo', 'attachment1']);
equal(context.spy.args[8][0],
'INSERT INTO attachment(id, attachment, ' +
'part, blob)VALUES(?, ?, ?, ?)');
deepEqual(context.spy.args[8][1],
['foo', 'attachment1', -1, 'text/plain;charset=utf-8']);
equal(context.spy.args[9][0],
'INSERT INTO attachment(id, attachment, ' +
'part, blob)VALUES(?, ?, ?, ?)');
deepEqual(context.spy.args[9][1],
['foo', 'attachment1', 0, 'data:;base64,YmFy']);
equal(context.spy.args[10][0],
'SELECT id FROM document WHERE id = ?');
deepEqual(context.spy.args[10][1], ['foo']);
equal(context.spy.args[11][0],
'DELETE FROM attachment WHERE id = ? AND attachment = ?');
deepEqual(context.spy.args[11][1], ['foo', 'attachment2']);
equal(context.spy.args[12][0],
'INSERT INTO attachment(id, attachment, ' +
'part, blob)VALUES(?, ?, ?, ?)');
deepEqual(context.spy.args[12][1],
['foo', 'attachment2', -1, 'text/plain;charset=utf-8']);
equal(context.spy.args[13][0],
'INSERT INTO attachment(id, attachment, ' +
'part, blob)VALUES(?, ?, ?, ?)');
deepEqual(context.spy.args[13][1],
['foo', 'attachment2', 0, 'data:;base64,YmFyMg==']);
equal(context.spy.args[14][0], 'DELETE FROM document WHERE id = ?');
deepEqual(context.spy.args[14][1], ['foo']);
})
.then(function () {
return deleteWebsql();
})
.fail(function (error) {
ok(false, error);
return deleteWebsql();
})
.always(function () {
start();
});
});
test("remove document", function () {
var context = this;
stop();
expect(3);
context.spy.then(function (value) {
context.spy = value;
return deleteWebsql();
})
.then(function () {
return context.jio.put("foo", {});
})
.then(function () {
return exec("SELECT id FROM document", []);
})
.then(function (selectResult) {
equal(selectResult.rows.length, 1, "putAttachment done");
})
.then(function () {
return context.jio.remove("foo");
})
.then(function (result) {
equal(result, "foo");
return exec("SELECT id FROM document", []);
})
.then(function (selectResult) {
equal(selectResult.rows.length, 0, "remove done");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// websqlStorage.getAttachment
/////////////////////////////////////////////////////////////////
module("websqlStorage.getAttachment", {
setup: function () {
this.jio = jIO.createJIO({
type: "websql",
database: "qunit",
blob_length: 20
});
this.spy = getSpy();
},
teardown: function () {
this.spy.restore();
delete this.spy;
}
});
test("spy webSQL usage", function () {
var context = this;
stop();
expect(20);
context.spy.then(function (value) {
context.spy = value;
return;
})
.then(function () {
return context.jio.put("foo", {"title": "bar"});
})
.then(function () {
return context.jio.putAttachment("foo", "attachment", big_string);
})
.then(function () {
return context.jio.getAttachment("foo", "attachment");
})
.then(function () {
spyStorageCreation(context);
equal(context.spy.args[5][0],
'INSERT OR REPLACE INTO document(id, data) VALUES(?,?)');
deepEqual(context.spy.args[5][1],
['foo', '{"title":"bar"}']);
equal(context.spy.args[6][0],
'SELECT id FROM document WHERE id = ?');
deepEqual(context.spy.args[6][1], ['foo']);
equal(context.spy.args[7][0],
'DELETE FROM attachment WHERE id = ? AND attachment = ?');
deepEqual(context.spy.args[7][1], ['foo', 'attachment']);
equal(context.spy.args[8][0],
'INSERT INTO attachment(id, attachment, part, blob)' +
'VALUES(?, ?, ?, ?)');
deepEqual(context.spy.args[8][1],
['foo', 'attachment', -1, 'text/plain;charset=utf-8']);
equal(context.spy.args[9][0],
'INSERT INTO attachment(id, attachment, ' +
'part, blob)VALUES(?, ?, ?, ?)');
deepEqual(context.spy.args[9][1],
['foo', 'attachment', 0,
'data:;base64,YWFhYWFhYWFhYWFhYWFhYWFhYWE=']);
equal(context.spy.args[10][0],
'INSERT INTO attachment(id, attachment, ' +
'part, blob)VALUES(?, ?, ?, ?)');
deepEqual(context.spy.args[10][1],
['foo', 'attachment', 1,
'data:;base64,YWFhYWFhYWFhYWFhYWFhYWFhYWE=']);
equal(context.spy.args[11][0],
'SELECT part, blob FROM attachment WHERE id = ? ' +
'AND attachment = ? AND part >= ?');
deepEqual(context.spy.args[11][1], ['foo', 'attachment', -1]);
})
.then(function () {
return deleteWebsql();
})
.fail(function (error) {
ok(false, error);
return deleteWebsql();
})
.always(function () {
start();
});
});
test("check result", function () {
var context = this,
attachment = "attachment";
stop();
expect(3);
context.spy.then(function (value) {
context.spy = value;
return deleteWebsql();
})
.then(function () {
return context.jio.put("foo", {"title": "bar"});
})
.then(function () {
return context.jio.putAttachment("foo", attachment, big_string);
})
.then(function () {
return context.jio.getAttachment("foo", attachment);
})
.then(function (result) {
ok(result instanceof Blob, "Data is Blob");
equal(result.type, "text/plain;charset=utf-8");
return jIO.util.readBlobAsText(result);
})
.then(function (result) {
equal(result.target.result, big_string,
"Attachment correctly fetched");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("streaming", function () {
var context = this,
attachment = "attachment";
stop();
expect(3);
context.spy.then(function (value) {
context.spy = value;
return deleteWebsql();
})
.then(function () {
return context.jio.put("foo", {"title": "bar"});
})
.then(function () {
return context.jio.putAttachment("foo", attachment, big_string);
})
.then(function () {
return context.jio.getAttachment("foo", attachment,
{"start": 15, "end": 25});
})
.then(function (result) {
ok(result instanceof Blob, "Data is Blob");
equal(result.type, "application/octet-stream");
return jIO.util.readBlobAsText(result);
})
.then(function (result) {
var expected = "aaaaaaaaaa";
equal(result.target.result, expected, "Attachment correctly fetched");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// websqlStorage.removeAttachment
/////////////////////////////////////////////////////////////////
module("websqlStorage.removeAttachment", {
setup: function () {
this.jio = jIO.createJIO({
type: "websql",
database: "qunit"
});
this.spy = getSpy();
},
teardown: function () {
this.spy.restore();
delete this.spy;
}
});
test("spy webSQL usage", function () {
var context = this;
stop();
expect(18);
context.spy.then(function (value) {
context.spy = value;
return;
})
.then(function () {
return context.jio.put("foo", {"title": "bar"});
})
.then(function () {
return context.jio.putAttachment("foo", "attachment", big_string);
})
.then(function () {
return context.jio.removeAttachment("foo", "attachment");
})
.then(function () {
spyStorageCreation(context);
equal(context.spy.args[5][0],
'INSERT OR REPLACE INTO document(id, data) VALUES(?,?)');
deepEqual(context.spy.args[5][1],
['foo', '{"title":"bar"}']);
equal(context.spy.args[6][0],
'SELECT id FROM document WHERE id = ?');
deepEqual(context.spy.args[6][1], ['foo']);
equal(context.spy.args[7][0],
'DELETE FROM attachment WHERE id = ? AND attachment = ?');
deepEqual(context.spy.args[7][1], ['foo', 'attachment']);
equal(context.spy.args[8][0],
'INSERT INTO attachment(id, attachment, part, blob)' +
'VALUES(?, ?, ?, ?)');
deepEqual(context.spy.args[8][1],
['foo', 'attachment', -1, 'text/plain;charset=utf-8']);
equal(context.spy.args[9][0],
'INSERT INTO attachment(id, attachment, ' +
'part, blob)VALUES(?, ?, ?, ?)');
deepEqual(context.spy.args[9][1],
['foo', 'attachment', 0,
"data:;base64,YWFhYWFhYWFhYWFhYWFhYWF" +
"hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYQ=="]);
equal(context.spy.args[10][0],
'DELETE FROM attachment WHERE id = ? AND attachment = ?');
deepEqual(context.spy.args[10][1], ['foo', 'attachment']);
})
.then(function () {
return deleteWebsql();
})
.fail(function (error) {
ok(false, error);
return deleteWebsql();
})
.always(function () {
start();
});
});
test("remove attachment", function () {
var context = this,
attachment = "attachment";
stop();
expect(3);
context.spy.then(function (value) {
context.spy = value;
return deleteWebsql();
})
.then(function () {
return context.jio.put("foo", {"title": "bar"});
})
.then(function () {
return context.jio.putAttachment("foo", attachment, big_string);
})
.then(function () {
return exec("SELECT id, attachment FROM attachment", []);
})
.then(function (selectResult) {
equal(selectResult.rows.length, 2, "putAttachment done");
})
.then(function () {
return context.jio.removeAttachment("foo", attachment);
})
.then(function (result) {
equal(result, attachment);
return exec("SELECT id, attachment FROM attachment", []);
})
.then(function (selectResult) {
equal(selectResult.rows.length, 0, "removeAttachment done");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// websqlStorage.putAttachment
/////////////////////////////////////////////////////////////////
module("websqlStorage.putAttachment", {
setup: function () {
this.jio = jIO.createJIO({
type: "websql",
database: "qunit",
blob_length: 20
});
this.spy = getSpy();
},
teardown: function () {
this.spy.restore();
delete this.spy;
}
});
test("spy webSQL usage", function () {
var context = this;
stop();
expect(18);
context.spy.then(function (value) {
context.spy = value;
return;
})
.then(function () {
return context.jio.put("foo", {"title": "bar"});
})
.then(function () {
return context.jio.putAttachment("foo", "attachment", big_string);
})
.then(function () {
spyStorageCreation(context);
equal(context.spy.args[5][0],
'INSERT OR REPLACE INTO document(id, data) VALUES(?,?)');
deepEqual(context.spy.args[5][1],
['foo', '{"title":"bar"}']);
equal(context.spy.args[6][0],
'SELECT id FROM document WHERE id = ?');
deepEqual(context.spy.args[6][1], ['foo']);
equal(context.spy.args[7][0],
'DELETE FROM attachment WHERE id = ? AND attachment = ?');
deepEqual(context.spy.args[7][1], ['foo', 'attachment']);
equal(context.spy.args[8][0],
'INSERT INTO attachment(id, attachment, part, blob)' +
'VALUES(?, ?, ?, ?)');
deepEqual(context.spy.args[8][1],
['foo', 'attachment', -1, 'text/plain;charset=utf-8']);
equal(context.spy.args[9][0],
'INSERT INTO attachment(id, attachment, ' +
'part, blob)VALUES(?, ?, ?, ?)');
deepEqual(context.spy.args[9][1],
['foo', 'attachment', 0,
'data:;base64,YWFhYWFhYWFhYWFhYWFhYWFhYWE=']);
equal(context.spy.args[10][0],
'INSERT INTO attachment(id, attachment, ' +
'part, blob)VALUES(?, ?, ?, ?)');
deepEqual(context.spy.args[10][1],
['foo', 'attachment', 1,
'data:;base64,YWFhYWFhYWFhYWFhYWFhYWFhYWE=']);
})
.then(function () {
return deleteWebsql();
})
.fail(function (error) {
ok(false, error);
return deleteWebsql();
})
.always(function () {
start();
});
});
test("put attachment", function () {
var context = this,
attachment = "attachment";
stop();
expect(2);
context.spy.then(function (value) {
context.spy = value;
return deleteWebsql();
})
.then(function () {
return context.jio.put("foo", {"title": "bar"});
})
.then(function () {
return context.jio.putAttachment("foo", attachment, big_string);
})
.then(function () {
return exec("SELECT id, attachment FROM attachment", []);
})
.then(function (selectResult) {
equal(selectResult.rows.length, 3, "putAttachment done");
})
.then(function () {
return context.jio.getAttachment("foo", attachment);
})
.then(function (result) {
return jIO.util.readBlobAsText(result);
})
.then(function (result) {
equal(result.target.result, big_string, "attachment correctly fetched");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
}(jIO, QUnit, openDatabase, Blob, sinon));
jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/jio.storage/xwikistorage.tests.js 0000664 0000000 0000000 00000047062 14230544473 0030363 0 ustar 00root root 0000000 0000000 /*jslint
indent: 2,
maxlen: 80,
plusplus: true,
nomen: true,
regexp: true
*/
/*global
define,
jIO,
test,
ok,
sinon,
module,
clearTimeout,
setTimeout,
start,
stop,
deepEqual
*/
// define([module_name], [dependencies], module);
(function (dependencies, module) {
"use strict";
if (typeof define === 'function' && define.amd) {
return define(dependencies, module);
}
module(jIO);
}(['jio', 'xwikistorage'], function (jIO) {
"use strict";
function nThen(next) {
var funcs = [],
timeouts = [],
calls = 0,
abort,
ret,
waitFor;
waitFor = function (func) {
calls++;
return function () {
if (func) {
func.apply(null, arguments);
}
calls = (calls || 1) - 1;
while (!calls && funcs.length && !abort) {
funcs.shift()(waitFor);
}
};
};
waitFor.abort = function () {
timeouts.forEach(clearTimeout);
abort = 1;
};
ret = {
nThen: function (next) {
if (!abort) {
if (!calls) {
next(waitFor);
} else {
funcs.push(next);
}
}
return ret;
},
orTimeout: function (func, milliseconds) {
var cto, timeout;
if (abort) { return ret; }
if (!milliseconds) {
throw new Error("Must specify milliseconds to orTimeout()");
}
timeout = setTimeout(function () {
var f;
while (f !== cto) { f = funcs.shift(); }
func(waitFor);
calls = (calls || 1) - 1;
while (!calls && funcs.length) { funcs.shift()(waitFor); }
}, milliseconds);
cto = function () {
var i;
for (i = 0; i < timeouts.length; i++) {
if (timeouts[i] === timeout) {
timeouts.splice(i, 1);
clearTimeout(timeout);
return;
}
}
throw new Error('timeout not listed in array');
};
funcs.push(cto);
timeouts.push(timeout);
return ret;
}
};
return ret.nThen(next);
}
module('XWikiStorage');
function setUp() {
var o = {
sinon: sinon.sandbox.create()
};
o.addFakeServerResponse =
function (type, method, path, status, response, t) {
t = t || 'application/xml';
/*jslint unparam: true */
o.sinon.server.respondWith(method, new RegExp(path), [
status,
{"Content-Type": t},
response
]);
};
o.sinon.useFakeTimers();
o.sinon.useFakeServer();
o.respond = function () {
o.sinon.clock.tick(5000);
o.sinon.server.respond();
};
o.jio = jIO.createJIO(
{type: 'xwiki', formTokenPath: 'form_token', xwikiurl: ''}
);
o.addFakeServerResponse("xwiki", "GET", "form_token", 200,
'');
o._addFakeServerResponse = o.addFakeServerResponse;
o.expectedRequests = [];
o.addFakeServerResponse = function (a, b, c, d, e) {
o._addFakeServerResponse(a, b, c, d, e);
o.expectedRequests.push([b, c]);
};
o.assertReqs = function (count, message) {
var i, j, req, expected, ex;
o.requests = (o.requests || 0) + count;
ok(o.sinon.server.requests.length === o.requests,
message + "[expected [" + count + "] got [" +
(o.sinon.server.requests.length - (o.requests - count)) + "]]");
for (i = 1; i <= count; i += 1) {
req = o.sinon.server.requests[o.sinon.server.requests.length - i];
if (!req) {
break;
}
for (j = o.expectedRequests.length - 1; j >= 0; j -= 1) {
expected = o.expectedRequests[j];
if (req.method === expected[0] &&
req.url.indexOf(expected[1]) !== 0) {
o.expectedRequests.splice(j, 1);
}
}
}
ex = o.expectedRequests.pop();
if (ex) {
ok(0, "expected [" + ex[0] + "] request for [" + ex[1] + "]");
}
};
return o;
}
function nThenTest(o, nt) {
stop();
nt.nThen(function () {
o.sinon.restore();
start();
}).orTimeout(function () {
o.sinon.restore();
ok(0);
start();
}, 1000);
}
test("Post", function () {
var o = setUp(this);
nThenTest(o, nThen(function (waitFor) {
// post non empty document
o.addFakeServerResponse("xwiki", "POST", "myFile1", 201, "HTML RESPONSE");
o.jio.post({"_id": "myFile1", "title": "hello there"}).
then(waitFor(function (ret) {
deepEqual({
id: "myFile1",
method: "post",
result: "success",
status: 201,
statusText: "Created"
}, ret);
}));
o.respond();
}).nThen(function () {
o.assertReqs(
3,
"post -> 1 request to get csrf token, 1 to get doc and 1 to post data"
);
}));
});
test("Post2", function () {
var o = setUp(this);
nThenTest(o, nThen(function (waitFor) {
// post but document already exists (post = error!, put = ok)
o.answer = '' +
'hello there';
o.addFakeServerResponse("xwiki", "GET", "pages/myFile2", 200, o.answer);
o.jio.post({"_id": "myFile2", "title": "hello again"}).
then(function () {
ok(0);
}, waitFor(function (err) {
deepEqual({
error: "conflict",
id: "myFile2",
message: "Cannot create a new document",
method: "post",
reason: "document exists",
result: "error",
status: 409,
statusText: "Conflict"
}, err);
}));
o.respond();
}).nThen(function () {
o.assertReqs(2, "post w/ existing doc -> 2 request to get doc then fail");
}));
});
test("PutNoId", function () {
var o = setUp(this);
nThenTest(o, nThen(function (waitFor) {
// put without id => id required
o.jio.put({}).then(function () {
ok(0);
}, waitFor(function (err) {
deepEqual({
"error": "bad_request",
"message": "Document id must be a non empty string.",
"method": "put",
"reason": "wrong document id",
"result": "error",
"status": 400,
"statusText": "Bad Request"
}, err);
}));
}).nThen(function () {
o.assertReqs(0, "put w/o id -> 0 requests");
}));
});
test("Put", function () {
var o = setUp(this);
nThenTest(o, nThen(function (waitFor) {
// put non empty document
o.addFakeServerResponse("xwiki", "POST", "put1", 201, "HTML RESPONSE");
o.jio.put({"_id": "put1", "title": "myPut1"}).
then(waitFor(function (res) {
deepEqual({
"id": "put1",
"method": "put",
"result": "success",
"status": 201,
"statusText": "Created"
}, res);
}));
o.respond();
}).nThen(function () {
o.assertReqs(
3,
"put normal doc -> 1 req to get doc (404), 1 for csrf token, 1 to post"
);
}));
});
test("PutUpdateDoc", function () {
var o = setUp(this);
nThenTest(o, nThen(function (waitFor) {
// put but document already exists = update
o.answer = '' +
'mtPut1';
o.addFakeServerResponse("xwiki", "GET", "put2", 200, o.answer);
o.addFakeServerResponse("xwiki", "POST", "put2", 201, "HTML RESPONSE");
o.jio.put({"_id": "put2", "title": "myPut2abcdedg"}).
then(waitFor(function (ret) {
deepEqual({
"id": "put2",
"method": "put",
"result": "success",
"status": 204,
"statusText": "No Content"
}, ret);
}));
o.respond();
}).nThen(function () {
o.assertReqs(
4,
"put update doc -> 2 req to get doc, 1 for csrf token, 1 to post"
);
}));
});
test("PutAttachmentNoDocId", function () {
var o = setUp(this);
nThenTest(o, nThen(function (waitFor) {
// putAttachment without doc id => id required
o.jio.putAttachment({}, function () {
ok(0);
}, waitFor(function (err) {
deepEqual({
"attachment": undefined,
"error": "bad_request",
"message": "Document id must be a non empty string.",
"method": "putAttachment",
"reason": "wrong document id",
"result": "error",
"status": 400,
"statusText": "Bad Request"
}, err);
}));
o.respond();
}).nThen(function () {
o.assertReqs(0, "put attach w/o doc id -> 0 requests");
}));
});
test("PutAttachmentNoAttachId", function () {
var o = setUp(this);
nThenTest(o, nThen(function (waitFor) {
// putAttachment without attachment id => attachment id required
o.jio.putAttachment({"_id": "putattmt1"}, function () {
ok(0);
}, waitFor(function (err) {
deepEqual({
"attachment": undefined,
"error": "bad_request",
"id": "putattmt1",
"message": "Attachment id must be a non empty string.",
"method": "putAttachment",
"reason": "wrong attachment id",
"result": "error",
"status": 400,
"statusText": "Bad Request"
}, err);
}));
o.respond();
}).nThen(function () {
o.assertReqs(0, "put attach w/o attach id -> 0 requests");
}));
});
test("PutAttachmentUnderlyingDocumentNonexistant", function () {
var o = setUp(this);
nThenTest(o, nThen(function (waitFor) {
// putAttachment without underlying document => not found
o.jio.putAttachment(
{"_id": "putattmtx", "_attachment": "putattmt2", "_data": ""},
function () {
ok(0);
},
waitFor(function (err) {
deepEqual({
"attachment": "putattmt2",
"error": "not_found",
"id": "putattmtx",
"message": "Impossible to add attachment",
"method": "putAttachment",
"reason": "missing",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, err);
})
);
o.respond();
}).nThen(function () {
o.assertReqs(
1,
"put attach w/o existing document -> 1 request to get doc"
);
}));
});
test("GetNonexistantDoc", function () {
var o = setUp(this);
nThenTest(o, nThen(function (waitFor) {
// get inexistent document
o.jio.get({_id: "get_nonexistant_doc"}, function () {
ok(0);
}, waitFor(function (err) {
deepEqual({
"error": "not_found",
"id": "get_nonexistant_doc",
"message": "Cannot find document",
"method": "get",
"reason": "missing",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, err);
}));
o.respond();
}).nThen(function () {
o.assertReqs(1, "try to get nonexistent doc -> 1 request");
}));
});
test("GetAttachInNonexistantDoc", function () {
var o = setUp(this);
nThenTest(o, nThen(function (waitFor) {
o.jio.getAttachment(
{"_id": "noSuchDoc", "_attachment": "its_attachment"},
function () {
ok(0);
},
waitFor(function (err) {
deepEqual({
"attachment": "its_attachment",
"error": "not_found",
"id": "noSuchDoc",
"message": "Cannot find document",
"method": "getAttachment",
"reason": "missing document",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, err);
})
);
o.respond();
}).nThen(function () {
o.assertReqs(1, "try to get nonexistent attach -> 1 request");
}));
});
test("GetDoc", function () {
var o = setUp(this);
nThenTest(o, nThen(function (waitFor) {
o.answer = '' +
'some title';
o.addFakeServerResponse("xwiki", "GET", "get_doc", 200, o.answer);
o.jio.get({_id: "get_doc"}).then(waitFor(function (ret) {
deepEqual({
"data": {
"_attachments": {},
"_id": "get_doc",
"title": "some title"
},
"id": "get_doc",
"method": "get",
"result": "success",
"status": 200,
"statusText": "Ok"
}, ret);
}));
o.respond();
}).nThen(function () {
o.assertReqs(2, "get document -> 2 request");
}));
});
test("GetNonexistantAttach", function () {
var o = setUp(this);
nThenTest(o, nThen(function (waitFor) {
// get inexistent attachment (document exists)
o.answer = '' +
'some title';
o.addFakeServerResponse(
"xwiki",
"GET",
"get_nonexistant_attach",
200,
o.answer
);
o.jio.getAttachment(
{"_id": "get_nonexistant_attach", "_attachment": "nxattach"},
function () {
ok(0);
},
waitFor(function (err) {
deepEqual({
"attachment": "nxattach",
"error": "not_found",
"id": "get_nonexistant_attach",
"message": "Cannot find attachment",
"method": "getAttachment",
"reason": "missing attachment",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, err);
})
);
o.respond();
}).nThen(function () {
o.assertReqs(2, "get nonexistant attachment -> 2 request to get doc");
}));
});
test("GetAttachHappyPath", function () {
var o = setUp(this);
nThenTest(o, nThen(function (waitFor) {
// get attachment
o.addFakeServerResponse(
"xwiki",
"GET",
"spaces/Main/pages/get_attachment$",
200,
'' +
'some title'
);
o.addFakeServerResponse(
"xwiki",
"GET",
"spaces/Main/pages/get_attachment/attachments",
200,
'' +
'' +
'attach_name' +
''
);
// We can't fully test this
// because sinon doesn't support HTML5 blob responses.
//o.addFakeServerResponse(
// "xwiki", "GET", "download/Main/get_attachment/attach_name", 200,
// "content", "application/octet-stream");
o.jio.getAttachment(
{"_id": "get_attachment", "_attachment": "attach_name"},
waitFor(function (ret) {
deepEqual({
"attachment": "attach_name",
"error": "err_network_error",
"id": "get_attachment",
"message": "Failed to get attachment [get_attachment/attach_name]",
"method": "getAttachment",
"reason": "Error getting data from network",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, ret);
})
);
o.respond();
}).nThen(function () {
o.assertReqs(3, "get attachment -> 2 requests to get doc, 1 for attach");
}));
});
test("RemoveNonexistantDocument", function () {
var o = setUp(this);
nThenTest(o, nThen(function (waitFor) {
// remove inexistent document
o.addFakeServerResponse("xwiki", "GET", "remove1", 404, "HTML RESPONSE");
o.jio.remove({"_id": "remove1"}, waitFor(function (ret) {
deepEqual({
"error": "error",
"id": "remove1",
"message": "Failed to delete document [remove1]",
"method": "remove",
"reason": "Not Found",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, ret);
}));
o.respond();
}).nThen(function () {
o.assertReqs(
2,
"remove nonexistent doc -> 1 request for csrf and 1 for doc"
);
}));
});
test("RemoveNonexistantAttachment", function () {
var o = setUp(this);
nThenTest(o, nThen(function (waitFor) {
// remove inexistent document/attachment
o.addFakeServerResponse("xwiki", "GET", "remove1/remove2", 404, "HTML" +
"RESPONSE");
o.jio.removeAttachment(
{"_id": "remove1", "_attachment": "remove2"},
function () {
ok(0);
},
waitFor(function (err) {
deepEqual({
"attachment": "remove2",
"error": "not_found",
"id": "remove1",
"message": "Document not found",
"method": "removeAttachment",
"reason": "missing document",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, err);
})
);
o.respond();
}).nThen(function () {
o.assertReqs(1, "remove nonexistant attach -> 1 request for doc");
}));
});
test("RemoveDocument", function () {
var o = setUp(this);
nThenTest(o, nThen(function (waitFor) {
o.addFakeServerResponse("xwiki", "POST", "delete/Main/remove3",
200, "HTML RESPONSE");
o.jio.remove({"_id": "remove3"}).then(waitFor(function (ret) {
deepEqual({
"id": "remove3",
"method": "remove",
"result": "success",
"status": 204,
"statusText": "No Content"
}, ret);
}));
o.respond();
}).nThen(function () {
o.assertReqs(
2,
"remove document -> 1 request for csrf and 1 for deleting doc"
);
}));
});
test("RemoveAttachment", function () {
var o = setUp(this);
nThenTest(o, nThen(function (waitFor) {
// remove attachment
o.addFakeServerResponse(
"xwiki",
"GET",
"spaces/Main/pages/remove4$",
200,
'' +
'some title'
);
o.addFakeServerResponse(
"xwiki",
"GET",
"spaces/Main/pages/remove4/attachments",
200,
'' +
'' +
'remove5' +
''
);
o.addFakeServerResponse(
"xwiki",
"POST",
"delattachment/Main/remove4/remove5",
200,
"HTML RESPONSE"
);
o.jio.removeAttachment(
{"_id": "remove4", "_attachment": "remove5"}
).always(waitFor(function (ret) {
deepEqual({
"attachment": "remove5",
"id": "remove4",
"method": "removeAttachment",
"result": "success",
"status": 204,
"statusText": "No Content"
}, ret);
}));
o.respond();
}).nThen(function () {
o.assertReqs(
4,
"remove attach -> get doc, get attachments, get csrf, remove attach"
);
}));
});
}));
jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/jio.storage/zipstorage.tests.js 0000664 0000000 0000000 00000037667 14230544473 0030044 0 ustar 00root root 0000000 0000000 /*
* Copyright 2015, Nexedi SA
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Free Software licenses or any of the Open Source
* Initiative approved licenses and Convey the resulting work. Corresponding
* source of such a combination shall include the source code for all other
* software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
* See https://www.nexedi.com/licensing for rationale and options.
*/
/*jslint nomen: true*/
/*global Blob, LZString*/
(function (jIO, QUnit, Blob, LZString) {
"use strict";
var test = QUnit.test,
stop = QUnit.stop,
start = QUnit.start,
ok = QUnit.ok,
expect = QUnit.expect,
deepEqual = QUnit.deepEqual,
equal = QUnit.equal,
throws = QUnit.throws,
module = QUnit.module;
/////////////////////////////////////////////////////////////////
// Custom test substorage definition
/////////////////////////////////////////////////////////////////
function Storage200() {
return this;
}
jIO.addStorage('zipstorage200', Storage200);
/////////////////////////////////////////////////////////////////
// ZipStorage.constructor
/////////////////////////////////////////////////////////////////
module("ZipStorage.constructor");
test("create substorage", function () {
var jio = jIO.createJIO({
type: "zip",
sub_storage: {type : "zipstorage200"}
});
equal(jio.__type, "zip");
equal(jio.__storage._sub_storage.__type, "zipstorage200");
});
/////////////////////////////////////////////////////////////////
// ZipStorage.get
/////////////////////////////////////////////////////////////////
module("ZipStorage.get");
test("get called substorage get", function () {
stop();
expect(2);
var jio = jIO.createJIO({
type: "zip",
sub_storage: {type : "zipstorage200"}
});
Storage200.prototype.get = function (id) {
equal(id, "bar", "get 200 called");
return {title: "foo"};
};
jio.get("bar")
.then(function (result) {
deepEqual(result, {
"title": "foo"
}, "Check document");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// ZipStorage.post
/////////////////////////////////////////////////////////////////
module("ZipStorage.post");
test("post called substorage post", function () {
stop();
expect(2);
var jio = jIO.createJIO({
type: "zip",
sub_storage: {type : "zipstorage200"}
});
Storage200.prototype.post = function (id) {
equal(id, "bar", "post 200 called");
return {title: "foo"};
};
jio.post("bar")
.then(function (result) {
deepEqual(result, {
"title": "foo"
}, "Check document");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// ZipStorage.put
/////////////////////////////////////////////////////////////////
module("ZipStorage.put");
test("put called substorage put", function () {
stop();
expect(2);
var jio = jIO.createJIO({
type: "zip",
sub_storage: {type : "zipstorage200"}
});
Storage200.prototype.put = function (id) {
equal(id, "bar", "put 200 called");
return {title: "foo"};
};
jio.put("bar")
.then(function (result) {
equal(result, "bar");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// ZipStorage.remove
/////////////////////////////////////////////////////////////////
module("ZipStorage.remove");
test("remove called substorage remove", function () {
stop();
expect(2);
var jio = jIO.createJIO({
type: "zip",
sub_storage: {type : "zipstorage200"}
});
Storage200.prototype.remove = function (id) {
equal(id, "bar", "remove 200 called");
return {title: "foo"};
};
jio.remove("bar")
.then(function (result) {
equal(result, "bar");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// ZipStorage.hasCapacity
/////////////////////////////////////////////////////////////////
module("ZipStorage.hasCapacity");
test("hasCapacity return substorage value", function () {
var jio = jIO.createJIO({
type: "zip",
sub_storage: {type : "zipstorage200"}
});
delete Storage200.prototype.hasCapacity;
throws(
function () {
jio.hasCapacity("foo");
},
function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.status_code, 501);
equal(error.message,
"Capacity 'foo' is not implemented on 'zipstorage200'");
return true;
}
);
});
/////////////////////////////////////////////////////////////////
// ZipStorage.buildQuery
/////////////////////////////////////////////////////////////////
module("ZipStorage.buildQuery");
test("buildQuery called substorage buildQuery", function () {
stop();
expect(2);
var jio = jIO.createJIO({
type: "zip",
sub_storage: {type : "zipstorage200"}
});
Storage200.prototype.buildQuery = function (id) {
equal(id, "bar", "buildQuery 200 called");
return {title: "foo"};
};
jio.buildQuery("bar")
.then(function (result) {
deepEqual(result, {
"title": "foo"
}, "Check document");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// ZipStorage.removeAttachment
/////////////////////////////////////////////////////////////////
module("ZipStorage.removeAttachment");
test("removeAttachment called substorage removeAttachment", function () {
stop();
expect(3);
var jio = jIO.createJIO({
type: "zip",
sub_storage: {type : "zipstorage200"}
});
Storage200.prototype.removeAttachment = function (id, name) {
equal(id, "bar", "removeAttachment 200 called");
equal(name, "foo", "removeAttachment 200 called");
return {title: "foo"};
};
jio.removeAttachment("bar", "foo")
.then(function (result) {
deepEqual(result, {
"title": "foo"
}, "Check document");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// ZipStorage.allAttachments
/////////////////////////////////////////////////////////////////
module("ZipStorage.allAttachments");
test("allAttachments called substorage allAttachments", function () {
stop();
expect(2);
var jio = jIO.createJIO({
type: "zip",
sub_storage: {type : "zipstorage200"}
});
Storage200.prototype.allAttachments = function (id) {
equal(id, "bar", "allAttachments 200 called");
return {title: "foo"};
};
jio.allAttachments("bar")
.then(function (result) {
deepEqual(result, {
"title": "foo"
}, "Check document");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// ZipStorage.getAttachment
/////////////////////////////////////////////////////////////////
module("ZipStorage.getAttachment", {
setup: function () {
this.jio = jIO.createJIO({
type: "zip",
sub_storage: {type : "zipstorage200"}
});
}
});
test("return substorage getattachment", function () {
var id = "/",
attachment = "stringattachment",
blob = new Blob(['foo']);
Storage200.prototype.getAttachment = function (arg1, arg2) {
equal(arg1, id, "getAttachment 200 called");
equal(arg2, attachment, "getAttachment 200 called");
return blob;
};
stop();
expect(3);
this.jio.getAttachment(id, attachment)
.then(function (result) {
equal(result, blob, "Return substorage result");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("return substorage getattachment if uncompress fails", function () {
var id = "/",
attachment = "stringattachment",
blob = new Blob(['foo'], {type: 'application/x-utf16_lz_string'});
Storage200.prototype.getAttachment = function (arg1, arg2) {
equal(arg1, id, "getAttachment 200 called");
equal(arg2, attachment, "getAttachment 200 called");
return blob;
};
stop();
expect(3);
this.jio.getAttachment(id, attachment)
.then(function (result) {
equal(result, blob, "Return substorage result");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("return substorage getattachment if not data url", function () {
var id = "/",
attachment = "stringattachment",
blob = new Blob([LZString.compressToUTF16('foo')],
{type: 'application/x-utf16_lz_string'});
Storage200.prototype.getAttachment = function (arg1, arg2) {
equal(arg1, id, "getAttachment 200 called");
equal(arg2, attachment, "getAttachment 200 called");
return blob;
};
stop();
expect(3);
this.jio.getAttachment(id, attachment)
.then(function (result) {
equal(result, blob, "Return substorage result");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("uncompress blob lz-string mime type", function () {
var id = "/",
attachment = "stringattachment",
value = "azertyuio\npàç_è-('é&",
tocheck = "data:text/plain;charset=utf-8;base64," +
"YXplcnR5dWlvCnDDoMOnX8OoLSgnw6km",
blob = new Blob([LZString.compressToUTF16(tocheck)],
{type: 'application/x-jio-utf16_lz_string'});
Storage200.prototype.getAttachment = function (arg1, arg2) {
equal(arg1, id, "getAttachment 200 called");
equal(arg2, attachment, "getAttachment 200 called");
return blob;
};
stop();
expect(6);
this.jio.getAttachment(id, attachment)
.then(function (result) {
ok(result !== blob, "Does not return substorage result");
ok(result instanceof Blob, "Data is Blob");
deepEqual(result.type, "text/plain;charset=utf-8",
"Check mimetype");
return jIO.util.readBlobAsText(result);
})
.then(function (result) {
equal(result.target.result, value, "Attachment correctly fetched");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// ZipStorage.putAttachment
/////////////////////////////////////////////////////////////////
module("ZipStorage.putAttachment", {
setup: function () {
this.jio = jIO.createJIO({
type: "zip",
sub_storage: {type : "zipstorage200"}
});
}
});
test("store directly unhandled mime types", function () {
var id = "/",
attachment = "stringattachment",
blob = new Blob(['foo']);
Storage200.prototype.putAttachment = function (arg1, arg2, arg3) {
equal(arg1, id, "putAttachment 200 called");
equal(arg2, attachment, "putAttachment 200 called");
equal(arg3, blob, "putAttachment 200 called");
return "ok";
};
stop();
expect(4);
this.jio.putAttachment(id, attachment, blob)
.then(function (result) {
equal(result, "ok", "Return substorage result");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("compress text mime type", function () {
var id = "/",
attachment = "stringattachment",
value = "azertyuio\npàç_è-('é&",
blob = new Blob([value],
{type: 'text/foo'});
Storage200.prototype.putAttachment = function (arg1, arg2, arg3) {
equal(arg1, id, "putAttachment 200 called");
equal(arg2, attachment, "putAttachment 200 called");
ok(true, arg3 !== blob, "putAttachment 200 called");
ok(arg3 instanceof Blob, "Data is Blob");
equal(arg3.type, "application/x-jio-utf16_lz_string",
"Check mimetype");
return jIO.util.readBlobAsText(arg3, 'utf16')
.then(function (result) {
var dataurl = LZString.decompressFromUTF16(result.target.result);
equal(
dataurl,
"data:text/foo;base64,YXplcnR5dWlvCnDDoMOnX8OoLSgnw6km"
);
return jIO.util.readBlobAsDataURL(arg3);
})
.then(function (result) {
equal(
result.target.result,
"data:application/x-jio-utf16_lz_string;base64,06LgsKvkkKvkmK" +
"rjgK/hoK/igLnkhJblkLvkgYPgoKznhqDjmKDisKDmoKTmoKHlgKHmgK3kgo" +
"PClsK0y5M94o2g45yh5IisxLfnlaDgrYDgvYDmhaDOtOOUoOCyoOOKoOOmo8" +
"KXxKDmrKDlrYAgIA=="
);
return "ok";
});
};
stop();
expect(8);
this.jio.putAttachment(id, attachment, blob)
.then(function (result) {
equal(result, "ok", "Return substorage result");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("compress json mime type", function () {
var id = "/",
attachment = "stringattachment",
value = "azertyuio\npàç_è-('é&",
blob = new Blob([value],
{type: 'application/foo+json'});
Storage200.prototype.putAttachment = function (arg1, arg2, arg3) {
equal(arg1, id, "putAttachment 200 called");
equal(arg2, attachment, "putAttachment 200 called");
ok(true, arg3 !== blob, "putAttachment 200 called");
ok(arg3 instanceof Blob, "Data is Blob");
equal(arg3.type, "application/x-jio-utf16_lz_string",
"Check mimetype");
return jIO.util.readBlobAsText(arg3, 'utf16')
.then(function (result) {
var dataurl = LZString.decompressFromUTF16(result.target.result);
equal(
dataurl,
"data:application/foo+json;base64,YXplcnR5dWlvCnDDoMOnX8OoLSgnw6km"
);
return jIO.util.readBlobAsDataURL(arg3);
})
.then(function (result) {
equal(
result.target.result,
"data:application/x-jio-utf16_lz_string;base64,06LgsKvkkKvkiKD" +
"nhqHloLLmgoPjpLDjtqDnmKflgKzmvJTNsMuQ4LSF5IKOZuGFqOCqgOC2oOCs" +
"oOGooeGooOOQtuKmoOKUoeKzoMe154Ch5bCj1ZDCqeKfgNaw3rTmhIDHoOW6o" +
"Nmg4aWg4bOzW+SGoOOWoOK2sCAg"
);
return "ok";
});
};
stop();
expect(8);
this.jio.putAttachment(id, attachment, blob)
.then(function (result) {
equal(result, "ok", "Return substorage result");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
}(jIO, QUnit, Blob, LZString));
jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/jio/ 0000775 0000000 0000000 00000000000 14230544473 0022470 5 ustar 00root root 0000000 0000000 jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/jio/fakestorage.js 0000664 0000000 0000000 00000007404 14230544473 0025326 0 ustar 00root root 0000000 0000000 /*
* Copyright 2013, Nexedi SA
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Free Software licenses or any of the Open Source
* Initiative approved licenses and Convey the resulting work. Corresponding
* source of such a combination shall include the source code for all other
* software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
* See https://www.nexedi.com/licensing for rationale and options.
*/
/*jslint indent: 2, maxlen: 80, nomen: true */
/*global define, exports, window, require, jIO */
(function (dependencies, module) {
"use strict";
if (typeof define === 'function' && define.amd) {
return define(dependencies, module);
}
if (typeof exports === 'object') {
module(exports, require('jio'));
}
if (typeof window === 'object') {
window.fake_storage = {};
module(window.fake_storage, jIO);
}
}(['exports', 'jio'], function (exports, jIO) {
"use strict";
var fakestorage = {};
function FakeStorage(spec) {
this._id = spec.id;
if (typeof this._id !== 'string' || this._id.length <= 0) {
throw new TypeError(
"Initialization error: wrong id"
);
}
}
FakeStorage.createNamespace = function (
that,
method,
command,
param,
options
) {
fakestorage[that._id + '/' + method] = {
param: param,
options: options,
success: function () {
var res = command.success.apply(command, arguments);
delete fakestorage[that._id + '/' + method];
return res;
},
error: function () {
var res = command.error.apply(command, arguments);
delete fakestorage[that._id + '/' + method];
return res;
},
retry: function () {
var res = command.retry.apply(command, arguments);
delete fakestorage[that._id + '/' + method];
return res;
},
notify: function () {
return command.notify.apply(command, arguments);
},
storage: function () {
return command.storage.apply(command, arguments);
},
end: function () {
return command.end.apply(command, arguments);
},
commit: function () {
return command.commit.apply(command, arguments);
},
free: function () {
delete fakestorage[that._id + '/' + method];
},
setCanceller: function () {
return command.setCanceller.apply(command, arguments);
}
};
};
FakeStorage.makeMethod = function (method) {
return function (command, param, options) {
FakeStorage.createNamespace(this, method, command, param, options);
};
};
FakeStorage.prototype.post = FakeStorage.makeMethod('post');
FakeStorage.prototype.put = FakeStorage.makeMethod('put');
FakeStorage.prototype.get = FakeStorage.makeMethod('get');
FakeStorage.prototype.remove = FakeStorage.makeMethod('remove');
FakeStorage.prototype.putAttachment = FakeStorage.makeMethod('putAttachment');
FakeStorage.prototype.getAttachment = FakeStorage.makeMethod('getAttachment');
FakeStorage.prototype.removeAttachment =
FakeStorage.makeMethod('removeAttachment');
FakeStorage.prototype.check = FakeStorage.makeMethod('check');
FakeStorage.prototype.repair = FakeStorage.makeMethod('repair');
FakeStorage.prototype.allDocs = FakeStorage.makeMethod('allDocs');
jIO.addStorage('fake', FakeStorage);
exports.commands = fakestorage;
}));
jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/jio/tests.js 0000664 0000000 0000000 00000067316 14230544473 0024205 0 ustar 00root root 0000000 0000000 /*
* Copyright 2013, Nexedi SA
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Free Software licenses or any of the Open Source
* Initiative approved licenses and Convey the resulting work. Corresponding
* source of such a combination shall include the source code for all other
* software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
* See https://www.nexedi.com/licensing for rationale and options.
*/
/*jslint indent: 2, maxlen: 80, nomen: true */
/*global define, window, exports, require, jIO, fake_storage, ok, module, test,
stop, start, deepEqual, FileReader, Blob, setTimeout, clearTimeout,
localStorage, test_util */
(function (dependencies, factory) {
"use strict";
if (typeof define === "function" && define.amd) {
return define(dependencies, factory);
}
if (typeof module === "object" && module !== null &&
typeof module.exports === "object" && module.exports !== null &&
typeof require === "function") {
return factory(dependencies.map(require));
}
factory(fake_storage, jIO, test_util);
}([
'fakestorage',
'jio',
'test_util',
'sinon_qunit'
], function (fake_storage, jIO, util) {
"use strict";
var test_name, JIO = jIO.JIO, commands = fake_storage.commands;
//////////////////////////////////////////////////////////////////////////////
// Tests
module('JIO and storages descriptions');
test('should initialize itself without error', 1, function () {
var jio = new JIO(undefined, {
"workspace": {}
});
// tests if jio is an object
ok(typeof jio === 'object', 'instance is an object');
});
test_name = 'should return an error when a wrong storage type is given';
test(test_name, 1, function () {
var jio = new JIO({
"type": "blue"
}, {
"workspace": {}
});
stop();
jio.post({}).always(function (answer) {
start();
deepEqual(answer, {
"error": "internal_storage_error",
"message": "Check if the storage description respects the " +
"constraints provided by the storage designer. (TypeError: " +
"Unknown storage 'blue')",
"method": "post",
"reason": "invalid description",
"result": "error",
"status": 551,
"statusText": "Internal Storage Error"
}, "Unknown storage error");
});
});
test('should return an error when a description is given', 1, function () {
var jio = new JIO({
"type": "fake",
"id": ""
}, {
"workspace": {}
});
stop();
jio.post({}).always(function (answer) {
start();
deepEqual(answer, {
"error": "internal_storage_error",
"message": "Check if the storage description respects the " +
"constraints provided by the storage designer. (TypeError: " +
"Initialization error: wrong id)",
"method": "post",
"reason": "invalid description",
"result": "error",
"status": 551,
"statusText": "Internal Storage Error"
}, "Initialization error");
});
});
module('JIO timeout');
test('should fail after storage inactivity timeout', 2, function () {
var i, called = false, jio = new JIO({
"type": "fake",
"id": "2 No Respons"
}, {
"workspace": {},
"default_timeout": 10000
});
stop();
jio.post({}).always(function (answer) {
var message = (answer && answer.message) || "Timeout";
called = true;
if (i !== undefined) {
start();
clearTimeout(i);
}
delete answer.message;
deepEqual(answer, {
"error": "request_timeout",
"method": "post",
"result": "error",
"reason": "timeout",
"status": 408,
"statusText": "Request Timeout"
}, message);
});
setTimeout(function () {
commands['2 No Respons/post'].notify();
}, 5000);
setTimeout(function () {
commands['2 No Respons/post'].free();
}, 6000);
setTimeout(function () {
ok(!called, "callback " + (called ? "" : "not") + " called");
}, 14999);
i = setTimeout(function () {
i = undefined;
start();
ok(false, "No response");
}, 16000);
});
test('should fail after jio option default timeout', 2, function () {
var i, called = false, jio = new JIO({
"type": "fake",
"id": "3 No Respons"
}, {
"workspace": {},
"default_timeout": 2000
});
stop();
setTimeout(function () {
ok(!called, "callback " + (called ? "" : "not") + " called");
}, 1999);
jio.post({}).always(function (answer) {
var message = (answer && answer.message) || "Timeout";
called = true;
if (i !== undefined) {
start();
clearTimeout(i);
}
delete answer.message;
deepEqual(answer, {
"error": "request_timeout",
"method": "post",
"result": "error",
"reason": "timeout",
"status": 408,
"statusText": "Request Timeout"
}, message);
});
setTimeout(function () {
commands['3 No Respons/post'].free();
}, 100);
i = setTimeout(function () {
i = undefined;
start();
ok(false, "No response");
}, 3000);
});
test('should fail after command option timeout', 2, function () {
var i, called = false, jio = new JIO({
"type": "fake",
"id": "4 No Respons"
}, {
"workspace": {},
"default_timeout": 2000
});
stop();
setTimeout(function () {
ok(!called, "callback " + (called ? "" : "not") + " called");
}, 2999);
jio.post({}, {"timeout": 3000}).always(function (answer) {
var message = (answer && answer.message) || "Timeout";
called = true;
if (i !== undefined) {
start();
clearTimeout(i);
}
delete answer.message;
deepEqual(answer, {
"error": "request_timeout",
"method": "post",
"result": "error",
"reason": "timeout",
"status": 408,
"statusText": "Request Timeout"
}, message);
});
setTimeout(function () {
commands['4 No Respons/post'].free();
}, 1000);
i = setTimeout(function () {
i = undefined;
start();
ok(false, "No response");
}, 4000);
});
module('JIO responses');
test('should fail when command succeed with a bad response', 1, function () {
var jio = new JIO({
"type": "fake",
"id": "1 Invalid Re"
}, {
"workspace": {}
});
stop();
jio.post({}).always(function (answer) {
start();
deepEqual(answer, {
"error": "internal_storage_error",
"message": "New document id have to be specified",
"method": "post",
"result": "error",
"reason": "invalid response",
"status": 551,
"statusText": "Internal Storage Error"
}, "response");
});
setTimeout(function () {
commands['1 Invalid Re/post'].success();
}, 50);
});
test('should fail when command end with a bad error', 1, function () {
var jio = new JIO({
"type": "fake",
"id": "2 Invalid Re"
}, {
"workspace": {}
});
stop();
jio.post({}).always(function (answer) {
start();
deepEqual(answer, {
"error": "internal_storage_error",
"message": "Unknown status \"undefined\"",
"method": "post",
"reason": "invalid response",
"result": "error",
"status": 551,
"statusText": "Internal Storage Error"
}, "response");
});
setTimeout(function () {
commands['2 Invalid Re/post'].error();
}, 50);
});
test('should succeed when giving a good `post` response', 1, function () {
var jio = new JIO({
"type": "fake",
"id": "Valid post"
}, {
"workspace": {}
});
stop();
jio.post({}).always(function (answer) {
start();
deepEqual(answer, {
"id": "document id a",
"method": "post",
"result": "success",
"status": 201,
"statusText": "Created"
}, "response");
});
setTimeout(function () {
commands['Valid post/post'].success({"id": "document id a"});
}, 50);
});
test('`getAttachment` should respond blob', 2, function () {
var jio = new JIO({
"type": "fake",
"id": "Valid getA"
}, {
"workspace": {}
});
stop();
jio.getAttachment({"_id": "a", "_attachment": "b"}).
always(function (answer) {
start();
ok(answer.data instanceof Blob,
"Get Attachment Command: Blob should be returned");
delete answer.data;
deepEqual(JSON.parse(JSON.stringify(answer)), {
"attachment": "b",
"id": "a",
"method": "getAttachment",
"result": "success",
"status": 200,
"statusText": "Ok"
});
});
setTimeout(function () {
commands['Valid getA/getAttachment'].success("ok", {
"data": "document id a"
});
}, 50);
});
test('should be notified by the command', 4, function () {
var i = 0, jio = new JIO({
"type": "fake",
"id": "Valid noti"
}, {
"workspace": {}
});
stop();
jio.put({"_id": "a"}).then(function () {
start();
}, function (answer) {
start();
deepEqual(answer, "No error", "should not fail");
}, function (answer) {
deepEqual(answer, i, "notified");
ok(i < 3, (i < 3 ? "" : "not ") + "called before success");
i += 1;
});
setTimeout(function () {
var notify = commands['Valid noti/put'].notify;
notify(0);
notify(1);
commands['Valid noti/put'].success();
notify(2);
}, 50);
});
test('should be cancelled', 1, function () {
var time_array = [], put_promise,
start = util.starter(1000),
jio = new JIO({
"type": "fake",
"id": "Cancel Err"
}, {
"workspace": {}
});
stop();
put_promise = jio.put({"_id": "a"});
put_promise.then(start, function (answer) {
time_array.push(answer);
deepEqual(time_array, ["cancelled", {
"error": "cancelled",
"id": "a",
"message": "Command failed",
"method": "put",
"reason": "unknown",
"result": "error",
"status": 555,
"statusText": "Cancelled"
}]);
start();
});
setTimeout(function () {
commands['Cancel Err/put'].setCanceller(function () {
time_array.push("cancelled");
});
put_promise.cancel();
}, 50);
});
module('JIO parameters');
test('should throw error when giving no parameter to `post`', 1, function () {
var result, jio = new JIO({
"type": "fake",
"id": "Wrong para"
}, {
"workspace": {}
});
try {
jio.post(); // post(kwargs, [options], [callbacks]);
result = "No error thrown";
} catch (e1) {
result = e1.name + ": " + e1.message;
}
deepEqual(
result,
"TypeError: JIO().post(): Argument 1 is not of type 'object'",
"Wrong parameter"
);
});
test_name = 'should not throw error when giving no param to `allDocs`';
test(test_name, 1, function () {
var result, jio = new JIO({
"type": "fake",
"id": "Good para"
}, {
"workspace": {}
});
try {
jio.allDocs(); // allDocs([options], [callbacks]);
result = "No error thrown";
} catch (e2) {
result = e2.name + ": " + e2.message;
}
deepEqual(result, "No error thrown", "Good parameter");
});
test('metadata values should be formatted on `post`', 1, function () {
var request, response, jio = new JIO({
"type": "fake",
"id": "Metadata v"
}, {
"workspace": {}
});
request = {
"_id": undefined,
"number": -13,
"date": new Date(0),
"boolean": true,
"array": ['a'],
"long_array": ['a', 'b'],
"object": {'content': 'c'},
"long_object": {'content': 'd', "scheme": "e"},
"toJSON": {toJSON: function () {
return 'hey!';
}},
"null": null,
"undefined": undefined,
"invalid_date": new Date('aoeuh'),
"not_finite": Infinity,
"empty_array": [],
"empty_object": {},
"no_content_object": {"e": "f"},
"wrong_array": [{}, null, {"blue": "green"}]
};
response = {
"number": -13,
"date": new Date(0).toJSON(),
"boolean": true,
"array": "a",
"long_array": ["a", "b"],
"object": "c",
"long_object": {"content": "d", "scheme": "e"},
"toJSON": "hey!"
};
stop();
jio.post(request);
setTimeout(function () {
start();
deepEqual(
commands["Metadata v/post"].param,
response,
"Post"
);
commands["Metadata v/post"].success();
}, 50);
// o.request._id = 'a';
// o.response._id = 'a';
// jio.put(o.request);
// clock.tick(1);
// deepEqual(commands["Metadata v/put"].param, o.response, "Put");
// commands["Metadata v/put"].success();
// clock.tick(1);
// jio.get({
// "_id": "a"
// });
// clock.tick(1);
// deepEqual(commands["Metadata v/get"].param, {
// "_id": "a"
// }, "Get");
// commands["Metadata v/get"].success();
// clock.tick(1);
// jio.remove({
// "_id": "a"
// });
// clock.tick(1);
// deepEqual(commands["Metadata v/remove"].param, {
// "_id": "a"
// }, "Remove");
// commands["Metadata v/remove"].success();
// clock.tick(1);
});
test('data should be converted to blob on `putAttachment`', 3, function () {
var request, jio = new JIO({
"type": "fake",
"id": "Metadata v"
}, {
"workspace": {}
});
request = {
"_id": "a",
"_attachment": "body",
"_data": "b",
"_mimetype": "c"
};
stop();
jio.putAttachment(request);
setTimeout(function () {
start();
ok(commands["Metadata v/putAttachment"].param._blob instanceof Blob,
"param._blob should be a blob");
deepEqual(
commands["Metadata v/putAttachment"].param._blob.type,
"c",
"param._blob type should be equal to request._mimetype"
);
deepEqual([
commands["Metadata v/putAttachment"].param._id,
commands["Metadata v/putAttachment"].param._attachment
], ["a", "body"], "param._id and param._attachment exist");
commands["Metadata v/putAttachment"].success();
}, 50);
});
test('blob should be given to param on `putAttachment`', 3, function () {
var request = {}, jio = new JIO({
"type": "fake",
"id": "Metadata 2"
}, {
"workspace": {}
});
request._id = "a";
request._attachment = "body";
request._blob = new Blob(['d'], {"type": "e"});
stop();
jio.putAttachment(request);
setTimeout(function () {
start();
ok(commands["Metadata 2/putAttachment"].param._blob === request._blob,
"param._blob should be the given blob");
deepEqual(
commands["Metadata 2/putAttachment"].param._blob.type,
"e",
"param._blob type should be equal to request._mimetype"
);
deepEqual([
commands["Metadata 2/putAttachment"].param._id,
commands["Metadata 2/putAttachment"].param._attachment
], ["a", "body"], "param._id and param._attachment exist");
commands["Metadata 2/putAttachment"].success();
}, 50);
});
test('no param should be given to `allDocs`', 1, function () {
var jio = new JIO({
"type": "fake",
"id": "Metadata v"
}, {
"workspace": {}
});
stop();
jio.allDocs();
setTimeout(function () {
start();
deepEqual(commands["Metadata v/allDocs"].param, {}, "No param given");
commands["Metadata v/allDocs"].success();
}, 50);
});
module('JIO job management');
test("job should respond 3 retries to return an error", 4, function () {
var jio, state;
jio = new JIO({
"type": "fake",
"id": "1 Job Retry"
}, {
"workspace": {}
});
stop();
state = "Not called yet";
jio.get({"_id": "a"}).always(function (answer) {
state = "Called";
deepEqual(answer, {
"error": "internal_server_error",
"id": "a",
"message": "Command failed",
"method": "get",
"reason": "unknown",
"result": "error",
"status": 500,
"statusText": "Internal Server Error"
}, "Error response");
});
setTimeout(function () {
commands['1 Job Retry/get'].retry('internal_server_error');
}, 50); // wait 50 ms
setTimeout(function () {
deepEqual(state, "Not called yet", "Check callback state.");
}, 100); // wait 50 ms
setTimeout(function () {
commands['1 Job Retry/get'].retry('internal_server_error');
}, 2150); // wait 2050 ms
setTimeout(function () {
deepEqual(state, "Not called yet", "Check callback state.");
}, 2200); // wait 50 ms
setTimeout(function () {
commands['1 Job Retry/get'].retry('internal_server_error');
}, 6250); // wait 4050 ms
setTimeout(function () {
start();
deepEqual(state, "Called", "Check callback state.");
}, 6300); // wait 50 ms
});
test("Job Management", 8, function () {
var tmp, workspace = {}, jio, o = {};
jio = new JIO({
"type": "fake",
"id": "1 Job Manage"
}, {
"workspace": workspace
});
stop();
// Launch a get command, check the workspace and then respond
jio.get({"_id": "a"}, {"max_retry": 2, "timeout": 1200}).
always(function (answer) {
deepEqual(answer, {
"id": "a",
"method": "get",
"result": "success",
"status": 200,
"statusText": "Ok",
"data": {"b": "c"}
}, "Job respond");
});
o.job1 = {
"kwargs": {"_id": "a"},
"options": {"max_retry": 2, "timeout": 1200},
"storage_spec": {"type": "fake", "id": "1 Job Manage"},
"method": "get",
//"created": new Date(),
"tried": 0, // deferred writing 1
"state": "ready", // deferred writing "running"
//"modified": new Date(),
"max_retry": 2,
"timeout": 1200,
"id": 1
};
tmp = workspace["jio/jobs/{\"id\":\"1 Job Manage\",\"type\":\"fake\"}"];
tmp = JSON.parse(tmp);
delete tmp[0].created;
delete tmp[0].modified;
deepEqual(tmp, [o.job1], 'workspace have one job');
setTimeout(function () {
commands["1 Job Manage/get"].success({"data": {"b": "c"}});
}, 100); // wait 100 ms
setTimeout(function () {
deepEqual(workspace, {}, 'Job ended, empty workspace');
// Launch a get command which launches another get command
// check workspace after every command and respond
jio.get({"_id": "b"}, {"max_retry": 2, "timeout": 1200}).
always(function (answer) {
deepEqual(answer, {
"id": "b",
"method": "get",
"result": "success",
"status": 200,
"statusText": "Ok",
"data": {"c": "d"}
}, "First job respond");
});
o.job1.kwargs._id = 'b';
// o.job1.created = new Date();
// o.job1.modified = new Date();
}, 200); // wait 100 ms
setTimeout(function () {
commands["1 Job Manage/get"].storage({
"type": "fake",
"id": "2 Job Manage"
}).get({"_id": "c"}).always(function (answer) {
start();
deepEqual(answer, {
"id": "c",
"method": "get",
"result": "success",
"status": 200,
"statusText": "Ok",
"data": {"d": "e"}
}, "Second job respond");
});
o.job1.tried = 1;
o.job1.state = 'running';
o.job2 = {
"kwargs": {"_id": "c"},
"options": {},
"storage_spec": {"type": "fake", "id": "2 Job Manage"},
"method": "get",
//"created": new Date(),
"tried": 0, // deferred writing 1
"state": "ready", // deferred writing "running"
//"modified": new Date(),
"max_retry": 2,
"timeout": 0,
"id": 2
};
tmp = workspace["jio/jobs/{\"id\":\"1 Job Manage\",\"type\":\"fake\"}"];
tmp = JSON.parse(tmp);
delete tmp[0].created;
delete tmp[0].modified;
delete tmp[1].created;
delete tmp[1].modified;
deepEqual(tmp, [
o.job1,
o.job2
], 'Job calls another job, workspace have two jobs');
}, 300); // wait 100 ms
setTimeout(function () {
commands['1 Job Manage/get'].end();
tmp = workspace["jio/jobs/{\"id\":\"1 Job Manage\",\"type\":\"fake\"}"];
tmp = JSON.parse(tmp);
delete tmp[0].created;
delete tmp[0].modified;
o.job2.tried = 1;
o.job2.state = 'running';
deepEqual(tmp, [o.job2], 'First Job ended, second still there');
commands['1 Job Manage/get'].success({"data": {"c": "d"}});
commands['2 Job Manage/get'].success({"data": {"d": "e"}});
deepEqual(workspace, {}, 'No more job in the queue');
}, 400); // wait 100 ms
});
test('job state running, job recovery', 2, function () {
var workspace, jio;
//////////////////////////////
// Running job recovery
workspace = {};
// create instance
jio = new JIO({
"type": "fake",
"id": "Job Recove"
}, {
"workspace": workspace,
"default_timeout": 10000
});
stop();
// create a job
jio.post({});
// copy workspace when job is running
workspace = jIO.util.deepClone(workspace);
setTimeout(function () {
commands['Job Recove/post'].success({"id": "a"});
}, 50);
// create instance with copied workspace
jio = new JIO({
"type": "fake",
"id": "Job Recove"
}, {
"workspace": workspace,
"recovery_delay": 10000
});
setTimeout(function () {
if (commands['Job Recove/post']) {
ok(false, "Command called, job recovered to earlier");
}
}, 19999);
setTimeout(function () {
if (!commands['Job Recove/post']) {
ok(false, "Command not called, job recovery failed");
} else {
ok(true, "Command called, job recovery ok");
}
commands['Job Recove/post'].success({"id": "a"});
}, 20050);
setTimeout(function () {
start();
deepEqual(workspace, {}, 'No more job in the queue');
}, 20100);
});
test('job state waiting for time, job recovery', 2, function () {
var workspace, jio;
//////////////////////////////
// Waiting for time job recovery
workspace = {};
// create instance
jio = new JIO({
"type": "fake",
"id": "Job Recovw"
}, {
"workspace": workspace,
"default_timeout": 10000
});
stop();
// create a job
jio.post({});
setTimeout(function () {
// copy workspace when job is waiting
commands['Job Recovw/post'].retry();
}, 50);
setTimeout(function () {
workspace = jIO.util.deepClone(workspace);
}, 100);
setTimeout(function () {
commands['Job Recovw/post'].success({"id": "a"});
}, 2100);
// create instance with copied workspace
setTimeout(function () {
jio = new JIO({
"type": "fake",
"id": "Job Recovw"
}, {
"workspace": workspace,
"recovery_delay": 10000
});
setTimeout(function () {
if (commands['Job Recovw/post']) {
ok(false, "Command called, job recovered to earlier");
}
}, 19889); // need to wait around 19900 ms
setTimeout(function () {
if (!commands['Job Recovw/post']) {
ok(false, "Command not called, job recovery failed");
} else {
ok(true, "Command called, job recovery ok");
}
commands['Job Recovw/post'].success({"id": "a"});
}, 20050);
setTimeout(function () {
start();
deepEqual(workspace, {}, 'No more job in the queue');
}, 20100);
}, 150);
//////////////////////////////
// XXX Waiting for jobs job recovery
});
test('Job Update', 5, function () {
var jio, o = {};
o.workspace = {};
jio = new JIO({
"type": "fake",
"id": "Job Update"
}, {
"workspace": o.workspace
});
stop();
jio.put({"_id": "a"}).always(function (answer) {
deepEqual(answer, {
"id": "a",
"method": "put",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "First put respond");
});
setTimeout(function () {
o.first_put_command = commands["Job Update/put"];
ok(o.first_put_command, "First command called");
o.first_put_command.free();
}, 50);
setTimeout(function () {
jio.put({"_id": "a"}).always(function (answer) {
deepEqual(answer, {
"id": "a",
"method": "put",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Second put respond");
});
}, 51);
setTimeout(function () {
ok(commands['Job Update/put'] === undefined,
'Second command not called');
o.first_put_command.success();
}, 100);
setTimeout(function () {
start();
deepEqual(o.workspace, {}, 'No job in the queue');
}, 150);
});
test('Job Wait', 6, function () {
var jio, o = {};
o.workspace = {};
jio = new JIO({
"type": "fake",
"id": "Job Wait"
}, {
"workspace": o.workspace
});
stop();
jio.put({"_id": "a"}).always(function (answer) {
deepEqual(answer, {
"id": "a",
"method": "put",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "First put respond");
});
setTimeout(function () {
o.first_put_command = commands["Job Wait/put"];
ok(o.first_put_command, "First command called");
o.first_put_command.free();
}, 50);
setTimeout(function () {
jio.put({"_id": "a", "a": "b"}).always(function (answer) {
deepEqual(answer, {
"id": "a",
"method": "put",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Second put respond");
});
}, 51);
setTimeout(function () {
ok(commands['Job Wait/put'] === undefined,
'Second command not called yet');
o.first_put_command.success();
}, 100);
setTimeout(function () {
ok(commands['Job Wait/put'], 'Second command called');
commands['Job Wait/put'].success();
}, 150);
setTimeout(function () {
start();
deepEqual(o.workspace, {}, 'No job in the queue');
}, 200);
});
test('Job Deny + Job condition addition', 2, function () {
var jio, workspace = {};
jIO.addJobRuleCondition('isGetMethod', function (job) {
return job.method === 'get';
});
jio = new JIO({
"type": "fake",
"id": "Job Wait"
}, {
"workspace": workspace,
"job_rules": [{
"code_name": "get rejecter",
"single": true,
"action": "deny",
"conditions": ["isGetMethod"]
}]
});
stop();
jio.get({"_id": "a"}).always(function (answer) {
deepEqual(answer, {
"error": "precondition_failed",
"id": "a",
"message": "Command rejected by the job checker.",
"method": "get",
"reason": "command denied",
"result": "error",
"status": 412,
"statusText": "Precondition Failed"
}, "Get respond");
});
setTimeout(function () {
start();
deepEqual(workspace, {}, 'No job in the queue');
}, 50);
});
}));
jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/jio/util.js 0000664 0000000 0000000 00000005425 14230544473 0024011 0 ustar 00root root 0000000 0000000 /*
* Copyright 2013, Nexedi SA
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Free Software licenses or any of the Open Source
* Initiative approved licenses and Convey the resulting work. Corresponding
* source of such a combination shall include the source code for all other
* software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
* See https://www.nexedi.com/licensing for rationale and options.
*/
(function (jIO, QUnit) {
"use strict";
var test = QUnit.test,
equal = QUnit.equal,
stop = QUnit.stop,
start = QUnit.start,
expect = QUnit.expect,
module = QUnit.module,
ok = QUnit.ok;
/////////////////////////////////////////////////////////////////
// util.stringify
/////////////////////////////////////////////////////////////////
module("util.stringify");
test("is stable", function () {
var str = jIO.util.stringify;
// https://developer.mozilla.org/search?q=stringify
equal(str({}), '{}');
equal(str(true), 'true');
equal(str('foo'), '"foo"');
equal(str([1, 'false', false]), '[1,"false",false]');
equal(str({ x: 5 }), '{"x":5}');
equal(str(new Date(Date.UTC(2006, 0, 2, 15, 4, 5))),
'"2006-01-02T15:04:05.000Z"');
equal(str({ x: 5, y: 6, z: 7 }), '{"x":5,"y":6,"z":7}');
equal(str({ z: 7, y: 6, x: 5 }), '{"x":5,"y":6,"z":7}');
equal(str({ z: "", y: undefined, x: 5 }), '{"x":5,"z":""}');
equal(str(Object.create(null, { x: { value: 'x', enumerable: false },
y: { value: 'y', enumerable: true } })),
'{"y":"y"}');
equal(str({y: "y", testnull: null}),
'{"testnull":null,"y":"y"}');
});
/////////////////////////////////////////////////////////////////
// util.ajax
/////////////////////////////////////////////////////////////////
module("util.ajax");
test("ajax timeout", function () {
var timeout = 1;
stop();
expect(3);
return new RSVP.Queue()
.then(function () {
return jIO.util.ajax({
type: 'GET',
url: "https://www.example.org/com/bar",
timeout: timeout
});
})
.fail(function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.message, "Gateway Timeout");
equal(error.status_code, 504);
})
.always(function () {
start();
});
});
}(jIO, QUnit)); jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/node.js 0000664 0000000 0000000 00000005551 14230544473 0023200 0 ustar 00root root 0000000 0000000 /*
* Copyright 2018, Nexedi SA
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Free Software licenses or any of the Open Source
* Initiative approved licenses and Convey the resulting work. Corresponding
* source of such a combination shall include the source code for all other
* software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
* See https://www.nexedi.com/licensing for rationale and options.
*/
/*global require, process, console, JSON */
(function (require, process, console, JSON) {
"use strict";
var testrunner = require('qunit'),
report_data = process.env.CI ? {} : null,
runner_options = process.env.CI ? {
log: {}
} : {
log: {
errors: true,
summary: true,
tests: true
}
};
testrunner.setup(runner_options);
if (report_data) {
testrunner.log.add = function (type, obj) {
if (!report_data.hasOwnProperty(type)) {
report_data[type] = [];
}
report_data[type].push(obj);
return report_data[type];
};
}
testrunner.run({
code: 'test/node/node-require.js',
tests: [
'test/node/ajax.tests.js',
'test/jio/util.js',
'test/queries/key.tests.js',
'test/queries/key-schema.tests.js',
/*
'test/queries/tests.js',
*/
'test/queries/key-typechecks.tests.js',
'test/queries/jiodate.tests.js',
'test/queries/key-jiodate.tests.js',
'test/jio.storage/documentstorage.tests.js',
'test/jio.storage/drivetojiomapping.tests.js',
'test/jio.storage/dropboxstorage.tests.js',
'test/jio.storage/erp5storage.tests.js',
'test/jio.storage/fbstorage.tests.js',
'test/jio.storage/gdrivestorage.tests.js',
'test/jio.storage/memorystorage.tests.js',
'test/jio.storage/querystorage.tests.js',
'test/jio.storage/replicatestorage.tests.js',
'test/jio.storage/replicatestorage_fastrepair.tests.js',
'test/jio.storage/replicatestorage_fastrepairattachment.tests.js',
'test/jio.storage/replicatestorage_repair.tests.js',
'test/jio.storage/replicatestorage_repairattachment.tests.js',
'test/jio.storage/shastorage.tests.js',
'test/jio.storage/unionstorage.tests.js',
'test/jio.storage/uuidstorage.tests.js'
]
}, function (err) {
if (err) {
console.error('error', err);
}
if (report_data) {
console.log(JSON.stringify(report_data));
}
});
}(require, process, console, JSON));
jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/node/ 0000775 0000000 0000000 00000000000 14230544473 0022634 5 ustar 00root root 0000000 0000000 jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/node/ajax.tests.js 0000664 0000000 0000000 00000015656 14230544473 0025273 0 ustar 00root root 0000000 0000000 /*
* Copyright 2019, Nexedi SA
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Free Software licenses or any of the Open Source
* Initiative approved licenses and Convey the resulting work. Corresponding
* source of such a combination shall include the source code for all other
* software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
* See https://www.nexedi.com/licensing for rationale and options.
*/
/*global FormData, sinon, RSVP, jIO, QUnit, XMLHttpRequest, Blob, ArrayBuffer*/
(function (jIO, QUnit, FormData, Blob, ArrayBuffer) {
"use strict";
var test = QUnit.test,
equal = QUnit.equal,
stop = QUnit.stop,
start = QUnit.start,
expect = QUnit.expect,
ok = QUnit.ok,
module = QUnit.module;
/////////////////////////////////////////////////////////////////
// util.ajax
/////////////////////////////////////////////////////////////////
module("node.ajax", {
setup: function () {
this.server = sinon.fakeServer.create();
this.server.autoRespond = true;
this.server.autoRespondAfter = 5;
this.spySetRequestHeader = sinon.spy(XMLHttpRequest.prototype,
"setRequestHeader");
},
teardown: function () {
this.spySetRequestHeader.restore();
delete this.spySetRequestHeader;
this.server.restore();
delete this.server;
}
});
test("Blob data handling", function () {
stop();
expect(5);
var url = "https://www.example.org/com/bar",
server = this.server,
blob = new Blob(['abc']);
this.server.respondWith("POST", url, [200, {}, 'OK']);
return new RSVP.Queue()
.then(function () {
return jIO.util.ajax({
type: 'POST',
url: url,
data: blob
});
})
.then(function () {
equal(server.requests.length, 1);
equal(server.requests[0].method, "POST");
equal(server.requests[0].url, url);
ok(server.requests[0].requestBody instanceof ArrayBuffer);
return jIO.util.readBlobAsText(
new Blob([server.requests[0].requestBody])
);
})
.then(function (evt) {
equal(evt.target.result, 'abc');
})
.always(function () {
start();
});
});
test("FormData handling without headers", function () {
stop();
expect(7);
var url = "https://www.example.org/com/bar",
server = this.server,
context = this;
this.server.respondWith("POST", url, [200, {}, 'OK']);
return new RSVP.Queue()
.then(function () {
var form_data = new FormData();
form_data.append("foo", "bar");
form_data.append("foo2", "bar2", "barfilename2");
return jIO.util.ajax({
type: 'POST',
url: url,
data: form_data
});
})
.then(function () {
var content_type =
"multipart/form-data; boundary=----------------------------",
boundary;
equal(context.spySetRequestHeader.callCount, 1);
equal(context.spySetRequestHeader.firstCall.args[0], "Content-Type");
equal(context.spySetRequestHeader.firstCall.args[1].length,
content_type.length + 10);
boundary = context.spySetRequestHeader.firstCall.args[1].slice(
"multipart/form-data; boundary=".length
);
equal(server.requests.length, 1);
equal(server.requests[0].method, "POST");
equal(server.requests[0].url, url);
equal(server.requests[0].requestBody,
'--' + boundary +
'\r\nContent-Disposition: form-data; name="foo"\r\n\r\nbar\r\n' +
'--' + boundary +
'\r\nContent-Disposition: form-data; name="foo2"; ' +
'filename="barfilename2"\r\n\r\nbar2\r\n' +
'--' + boundary + '--\r\n'
);
})
.always(function () {
start();
});
});
test("FormData handling with headers", function () {
stop();
expect(9);
var url = "https://www.example.org/com/bar",
server = this.server,
context = this;
this.server.respondWith("POST", url, [200, {}, 'OK']);
return new RSVP.Queue()
.then(function () {
var form_data = new FormData();
form_data.append("foo", "bar");
form_data.append("foo2", "bar2", "barfilename2");
return jIO.util.ajax({
type: 'POST',
url: url,
data: form_data,
headers: {"bar": "foo"}
});
})
.then(function () {
var content_type =
"multipart/form-data; boundary=----------------------------",
boundary;
equal(context.spySetRequestHeader.callCount, 2);
equal(context.spySetRequestHeader.firstCall.args[0], "bar");
equal(context.spySetRequestHeader.firstCall.args[1], "foo");
equal(context.spySetRequestHeader.secondCall.args[0], "Content-Type");
equal(context.spySetRequestHeader.secondCall.args[1].length,
content_type.length + 10);
boundary = context.spySetRequestHeader.secondCall.args[1].slice(
"multipart/form-data; boundary=".length
);
equal(server.requests.length, 1);
equal(server.requests[0].method, "POST");
equal(server.requests[0].url, url);
equal(server.requests[0].requestBody,
'--' + boundary +
'\r\nContent-Disposition: form-data; name="foo"\r\n\r\nbar\r\n' +
'--' + boundary +
'\r\nContent-Disposition: form-data; name="foo2"; ' +
'filename="barfilename2"\r\n\r\nbar2\r\n' +
'--' + boundary + '--\r\n'
);
})
.always(function () {
start();
});
});
test("Blob responseType handling", function () {
stop();
expect(6);
var url = "https://www.example.org/com/bar",
server = this.server;
this.server.respondWith("POST", url, [200, {}, 'OK']);
return new RSVP.Queue()
.then(function () {
return jIO.util.ajax({
type: 'POST',
url: url,
dataType: 'blob'
});
})
.then(function (evt) {
equal(server.requests.length, 1);
equal(server.requests[0].method, "POST");
equal(server.requests[0].url, url);
equal(server.requests[0].responseType, 'arraybuffer');
equal(server.requests[0].responseText, 'OK');
ok(evt.target.response instanceof Blob, evt.target.response);
})
.always(function () {
start();
});
});
}(jIO, QUnit, FormData, Blob, ArrayBuffer)); jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/node/node-require.js 0000664 0000000 0000000 00000002312 14230544473 0025567 0 ustar 00root root 0000000 0000000 /*
* Copyright 2018, Nexedi SA
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Free Software licenses or any of the Open Source
* Initiative approved licenses and Convey the resulting work. Corresponding
* source of such a combination shall include the source code for all other
* software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
* See https://www.nexedi.com/licensing for rationale and options.
*/
/*global require, global, Object */
(function (require, global, Object) {
"use strict";
var sinon,
jIO = require('../../dist/jio-latest-node');
global.jIO = jIO;
Object.keys(jIO.node_env).forEach(function (key) {
global[key] = jIO.node_env[key];
});
sinon = require('./sinon-require');
global.sinon = sinon;
}(require, global, Object));
jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/node/sinon-require.js 0000664 0000000 0000000 00000047652 14230544473 0026010 0 ustar 00root root 0000000 0000000 var sinon = require('sinon');
global.sinon = sinon;
// sinon/lib/sinon/util/event.js
(function () {
var push = [].push;
sinon.Event = function Event(type, bubbles, cancelable, target) {
this.initEvent(type, bubbles, cancelable, target);
};
sinon.Event.prototype = {
initEvent: function (type, bubbles, cancelable, target) {
this.type = type;
this.bubbles = bubbles;
this.cancelable = cancelable;
this.target = target;
},
stopPropagation: function () { },
preventDefault: function () {
this.defaultPrevented = true;
}
};
sinon.EventTarget = {
addEventListener: function addEventListener(event, listener, useCapture) {
this.eventListeners = this.eventListeners || {};
this.eventListeners[event] = this.eventListeners[event] || [];
push.call(this.eventListeners[event], listener);
},
removeEventListener: function removeEventListener(event, listener, useCapture) {
var listeners = this.eventListeners && this.eventListeners[event] || [];
for (var i = 0, l = listeners.length; i < l; ++i) {
if (listeners[i] == listener) {
return listeners.splice(i, 1);
}
}
},
dispatchEvent: function dispatchEvent(event) {
var type = event.type;
var listeners = this.eventListeners && this.eventListeners[type] || [];
for (var i = 0; i < listeners.length; i++) {
if (typeof listeners[i] == "function") {
listeners[i].call(this, event);
} else {
listeners[i].handleEvent(event);
}
}
return !!event.defaultPrevented;
}
};
}());
// sinon/lib/sinon/util/fake_server.js
sinon.fakeServer = (function () {
var push = [].push;
function F() { }
function create(proto) {
F.prototype = proto;
return new F();
}
function responseArray(handler) {
var response = handler;
if (Object.prototype.toString.call(handler) != "[object Array]") {
response = [200, {}, handler];
}
if (typeof response[2] != "string") {
throw new TypeError("Fake server response body should be string, but was " +
typeof response[2]);
}
return response;
}
var wloc = typeof window !== "undefined" ? window.location : {};
var rCurrLoc = new RegExp("^" + wloc.protocol + "//" + wloc.host);
function matchOne(response, reqMethod, reqUrl) {
var rmeth = response.method;
var matchMethod = !rmeth || rmeth.toLowerCase() == reqMethod.toLowerCase();
var url = response.url;
var matchUrl = !url || url == reqUrl || (typeof url.test == "function" && url.test(reqUrl));
return matchMethod && matchUrl;
}
function match(response, request) {
var requestMethod = this.getHTTPMethod(request);
var requestUrl = request.url;
if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) {
requestUrl = requestUrl.replace(rCurrLoc, "");
}
if (matchOne(response, this.getHTTPMethod(request), requestUrl)) {
if (typeof response.response == "function") {
var ru = response.url;
var args = [request].concat(!ru ? [] : requestUrl.match(ru).slice(1));
return response.response.apply(response, args);
}
return true;
}
return false;
}
function log(response, request) {
var str;
str = "Request:\n" + sinon.format(request) + "\n\n";
str += "Response:\n" + sinon.format(response) + "\n\n";
sinon.log(str);
}
return {
create: function () {
var server = create(this);
this.xhr = sinon.useFakeXMLHttpRequest();
server.requests = [];
this.xhr.onCreate = function (xhrObj) {
server.addRequest(xhrObj);
};
return server;
},
addRequest: function addRequest(xhrObj) {
var server = this;
push.call(this.requests, xhrObj);
xhrObj.onSend = function () {
server.handleRequest(this);
};
if (this.autoRespond && !this.responding) {
setTimeout(function () {
server.responding = false;
server.respond();
}, this.autoRespondAfter || 10);
this.responding = true;
}
},
getHTTPMethod: function getHTTPMethod(request) {
if (this.fakeHTTPMethods && /post/i.test(request.method)) {
var matches = (request.requestBody || "").match(/_method=([^\b;]+)/);
return !!matches ? matches[1] : request.method;
}
return request.method;
},
handleRequest: function handleRequest(xhr) {
if (xhr.async) {
if (!this.queue) {
this.queue = [];
}
push.call(this.queue, xhr);
} else {
this.processRequest(xhr);
}
},
respondWith: function respondWith(method, url, body) {
if (arguments.length == 1 && typeof method != "function") {
this.response = responseArray(method);
return;
}
if (!this.responses) { this.responses = []; }
if (arguments.length == 1) {
body = method;
url = method = null;
}
if (arguments.length == 2) {
body = url;
url = method;
method = null;
}
push.call(this.responses, {
method: method,
url: url,
response: typeof body == "function" ? body : responseArray(body)
});
},
respond: function respond() {
if (arguments.length > 0) this.respondWith.apply(this, arguments);
var queue = this.queue || [];
var request;
while (request = queue.shift()) {
this.processRequest(request);
}
},
processRequest: function processRequest(request) {
try {
if (request.aborted) {
return;
}
var response = this.response || [404, {}, ""];
if (this.responses) {
for (var i = 0, l = this.responses.length; i < l; i++) {
if (match.call(this, this.responses[i], request)) {
response = this.responses[i].response;
break;
}
}
}
if (request.readyState != 4) {
log(response, request);
request.respond(response[0], response[1], response[2]);
}
} catch (e) {
sinon.logError("Fake server request processing", e);
}
},
restore: function restore() {
return this.xhr.restore && this.xhr.restore.apply(this.xhr, arguments);
}
};
}());
// sinon/lib/sinon/util/fake_xml_http_request.js
sinon.xhr = { XMLHttpRequest: global.XMLHttpRequest };
// wrapper for global
(function () {
var xhr = sinon.xhr;
xhr.GlobalXMLHttpRequest = global.XMLHttpRequest;
xhr.GlobalActiveXObject = global.ActiveXObject;
xhr.supportsActiveX = typeof xhr.GlobalActiveXObject != "undefined";
xhr.supportsXHR = typeof xhr.GlobalXMLHttpRequest != "undefined";
xhr.workingXHR = xhr.supportsXHR ? xhr.GlobalXMLHttpRequest : xhr.supportsActiveX
? function () { return new xhr.GlobalActiveXObject("MSXML2.XMLHTTP.3.0") } : false;
/*jsl:ignore*/
var unsafeHeaders = {
"Accept-Charset": true,
"Accept-Encoding": true,
"Connection": true,
"Content-Length": true,
"Cookie": true,
"Cookie2": true,
"Content-Transfer-Encoding": true,
"Date": true,
"Expect": true,
"Host": true,
"Keep-Alive": true,
"Referer": true,
"TE": true,
"Trailer": true,
"Transfer-Encoding": true,
"Upgrade": true,
"User-Agent": true,
"Via": true
};
/*jsl:end*/
function FakeXMLHttpRequest() {
this.readyState = FakeXMLHttpRequest.UNSENT;
this.requestHeaders = {};
this.requestBody = null;
this.status = 0;
this.statusText = "";
var xhr = this;
var events = ["loadstart", "load", "abort", "loadend"];
function addEventListener(eventName) {
xhr.addEventListener(eventName, function (event) {
var listener = xhr["on" + eventName];
if (listener && typeof listener == "function") {
listener(event);
}
});
}
for (var i = events.length - 1; i >= 0; i--) {
addEventListener(events[i]);
}
if (typeof FakeXMLHttpRequest.onCreate == "function") {
FakeXMLHttpRequest.onCreate(this);
}
}
function verifyState(xhr) {
if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
throw new Error("INVALID_STATE_ERR");
}
if (xhr.sendFlag) {
throw new Error("INVALID_STATE_ERR");
}
}
// filtering to enable a white-list version of Sinon FakeXhr,
// where whitelisted requests are passed through to real XHR
function each(collection, callback) {
if (!collection) return;
for (var i = 0, l = collection.length; i < l; i += 1) {
callback(collection[i]);
}
}
function some(collection, callback) {
for (var index = 0; index < collection.length; index++) {
if (callback(collection[index]) === true) return true;
};
return false;
}
// largest arity in XHR is 5 - XHR#open
var apply = function (obj, method, args) {
switch (args.length) {
case 0: return obj[method]();
case 1: return obj[method](args[0]);
case 2: return obj[method](args[0], args[1]);
case 3: return obj[method](args[0], args[1], args[2]);
case 4: return obj[method](args[0], args[1], args[2], args[3]);
case 5: return obj[method](args[0], args[1], args[2], args[3], args[4]);
};
};
FakeXMLHttpRequest.filters = [];
FakeXMLHttpRequest.addFilter = function (fn) {
this.filters.push(fn)
};
var IE6Re = /MSIE 6/;
FakeXMLHttpRequest.defake = function (fakeXhr, xhrArgs) {
var xhr = new sinon.xhr.workingXHR();
each(["open", "setRequestHeader", "send", "abort", "getResponseHeader",
"getAllResponseHeaders", "addEventListener", "overrideMimeType", "removeEventListener"],
function (method) {
fakeXhr[method] = function () {
return apply(xhr, method, arguments);
};
});
var copyAttrs = function (args) {
each(args, function (attr) {
try {
fakeXhr[attr] = xhr[attr]
} catch (e) {
if (!IE6Re.test(navigator.userAgent)) throw e;
}
});
};
var stateChange = function () {
fakeXhr.readyState = xhr.readyState;
if (xhr.readyState >= FakeXMLHttpRequest.HEADERS_RECEIVED) {
copyAttrs(["status", "statusText"]);
}
if (xhr.readyState >= FakeXMLHttpRequest.LOADING) {
copyAttrs(["responseText"]);
}
if (xhr.readyState === FakeXMLHttpRequest.DONE) {
copyAttrs(["responseXML"]);
}
if (fakeXhr.onreadystatechange) fakeXhr.onreadystatechange.call(fakeXhr);
};
if (xhr.addEventListener) {
for (var event in fakeXhr.eventListeners) {
if (fakeXhr.eventListeners.hasOwnProperty(event)) {
each(fakeXhr.eventListeners[event], function (handler) {
xhr.addEventListener(event, handler);
});
}
}
xhr.addEventListener("readystatechange", stateChange);
} else {
xhr.onreadystatechange = stateChange;
}
apply(xhr, "open", xhrArgs);
};
FakeXMLHttpRequest.useFilters = false;
function verifyRequestSent(xhr) {
if (xhr.readyState == FakeXMLHttpRequest.DONE) {
throw new Error("Request done");
}
}
function verifyHeadersReceived(xhr) {
if (xhr.async && xhr.readyState != FakeXMLHttpRequest.HEADERS_RECEIVED) {
throw new Error("No headers received");
}
}
function verifyResponseBodyType(body) {
if (typeof body != "string") {
var error = new Error("Attempted to respond to fake XMLHttpRequest with " +
body + ", which is not a string.");
error.name = "InvalidBodyException";
throw error;
}
}
sinon.extend(FakeXMLHttpRequest.prototype, sinon.EventTarget, {
async: true,
open: function open(method, url, async, username, password) {
this.method = method;
this.url = url;
this.async = typeof async == "boolean" ? async : true;
this.username = username;
this.password = password;
this.responseText = null;
this.responseXML = null;
this.requestHeaders = {};
this.sendFlag = false;
if (sinon.FakeXMLHttpRequest.useFilters === true) {
var xhrArgs = arguments;
var defake = some(FakeXMLHttpRequest.filters, function (filter) {
return filter.apply(this, xhrArgs)
});
if (defake) {
return sinon.FakeXMLHttpRequest.defake(this, arguments);
}
}
this.readyStateChange(FakeXMLHttpRequest.OPENED);
},
readyStateChange: function readyStateChange(state) {
this.readyState = state;
if (typeof this.onreadystatechange == "function") {
try {
this.onreadystatechange();
} catch (e) {
sinon.logError("Fake XHR onreadystatechange handler", e);
}
}
this.dispatchEvent(new sinon.Event("readystatechange"));
switch (this.readyState) {
case FakeXMLHttpRequest.DONE:
this.dispatchEvent(new sinon.Event("load", false, false, this));
this.dispatchEvent(new sinon.Event("loadend", false, false, this));
break;
}
},
setRequestHeader: function setRequestHeader(header, value) {
verifyState(this);
if (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header)) {
throw new Error("Refused to set unsafe header \"" + header + "\"");
}
if (this.requestHeaders[header]) {
this.requestHeaders[header] += "," + value;
} else {
this.requestHeaders[header] = value;
}
},
// Helps testing
setResponseHeaders: function setResponseHeaders(headers) {
this.responseHeaders = {};
for (var header in headers) {
if (headers.hasOwnProperty(header)) {
this.responseHeaders[header] = headers[header];
}
}
if (this.async) {
this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED);
} else {
this.readyState = FakeXMLHttpRequest.HEADERS_RECEIVED;
}
},
// Currently treats ALL data as a DOMString (i.e. no Document)
send: function send(data) {
verifyState(this);
if (!/^(get|head)$/i.test(this.method)) {
if (this.requestHeaders["Content-Type"]) {
var value = this.requestHeaders["Content-Type"].split(";");
this.requestHeaders["Content-Type"] = value[0] + ";charset=utf-8";
} else {
this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8";
}
this.requestBody = data;
}
this.errorFlag = false;
this.sendFlag = this.async;
this.readyStateChange(FakeXMLHttpRequest.OPENED);
if (typeof this.onSend == "function") {
this.onSend(this);
}
this.dispatchEvent(new sinon.Event("loadstart", false, false, this));
},
abort: function abort() {
this.aborted = true;
this.responseText = null;
this.errorFlag = true;
this.requestHeaders = {};
if (this.readyState > sinon.FakeXMLHttpRequest.UNSENT && this.sendFlag) {
this.readyStateChange(sinon.FakeXMLHttpRequest.DONE);
this.sendFlag = false;
}
this.readyState = sinon.FakeXMLHttpRequest.UNSENT;
this.dispatchEvent(new sinon.Event("abort", false, false, this));
if (typeof this.onerror === "function") {
this.onerror();
}
},
getResponseHeader: function getResponseHeader(header) {
if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
return null;
}
if (/^Set-Cookie2?$/i.test(header)) {
return null;
}
header = header.toLowerCase();
for (var h in this.responseHeaders) {
if (h.toLowerCase() == header) {
return this.responseHeaders[h];
}
}
return null;
},
getAllResponseHeaders: function getAllResponseHeaders() {
if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
return "";
}
var headers = "";
for (var header in this.responseHeaders) {
if (this.responseHeaders.hasOwnProperty(header) &&
!/^Set-Cookie2?$/i.test(header)) {
headers += header + ": " + this.responseHeaders[header] + "\r\n";
}
}
return headers;
},
setResponseBody: function setResponseBody(body) {
verifyRequestSent(this);
verifyHeadersReceived(this);
verifyResponseBodyType(body);
var chunkSize = this.chunkSize || 10;
var index = 0;
this.responseText = "";
do {
if (this.async) {
this.readyStateChange(FakeXMLHttpRequest.LOADING);
}
this.responseText += body.substring(index, index + chunkSize);
index += chunkSize;
} while (index < body.length);
var type = this.getResponseHeader("Content-Type");
if (this.responseText &&
(!type || /(text\/xml)|(application\/xml)|(\+xml)/.test(type))) {
try {
this.responseXML = FakeXMLHttpRequest.parseXML(this.responseText);
} catch (e) {
// Unable to parse XML - no biggie
}
}
if (this.async) {
this.readyStateChange(FakeXMLHttpRequest.DONE);
} else {
this.readyState = FakeXMLHttpRequest.DONE;
}
},
respond: function respond(status, headers, body) {
this.setResponseHeaders(headers || {});
this.status = typeof status == "number" ? status : 200;
this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
this.setResponseBody(body || "");
if (typeof this.onload === "function") {
this.onload();
}
}
});
sinon.extend(FakeXMLHttpRequest, {
UNSENT: 0,
OPENED: 1,
HEADERS_RECEIVED: 2,
LOADING: 3,
DONE: 4
});
// Borrowed from JSpec
FakeXMLHttpRequest.parseXML = function parseXML(text) {
var xmlDoc;
if (typeof DOMParser != "undefined") {
var parser = new DOMParser();
xmlDoc = parser.parseFromString(text, "text/xml");
} else {
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = "false";
xmlDoc.loadXML(text);
}
return xmlDoc;
};
FakeXMLHttpRequest.statusCodes = {
100: "Continue",
101: "Switching Protocols",
200: "OK",
201: "Created",
202: "Accepted",
203: "Non-Authoritative Information",
204: "No Content",
205: "Reset Content",
206: "Partial Content",
300: "Multiple Choice",
301: "Moved Permanently",
302: "Found",
303: "See Other",
304: "Not Modified",
305: "Use Proxy",
307: "Temporary Redirect",
400: "Bad Request",
401: "Unauthorized",
402: "Payment Required",
403: "Forbidden",
404: "Not Found",
405: "Method Not Allowed",
406: "Not Acceptable",
407: "Proxy Authentication Required",
408: "Request Timeout",
409: "Conflict",
410: "Gone",
411: "Length Required",
412: "Precondition Failed",
413: "Request Entity Too Large",
414: "Request-URI Too Long",
415: "Unsupported Media Type",
416: "Requested Range Not Satisfiable",
417: "Expectation Failed",
422: "Unprocessable Entity",
500: "Internal Server Error",
501: "Not Implemented",
502: "Bad Gateway",
503: "Service Unavailable",
504: "Gateway Timeout",
505: "HTTP Version Not Supported"
};
sinon.useFakeXMLHttpRequest = function () {
sinon.FakeXMLHttpRequest.restore = function restore(keepOnCreate) {
if (xhr.supportsXHR) {
global.XMLHttpRequest = xhr.GlobalXMLHttpRequest;
}
if (xhr.supportsActiveX) {
global.ActiveXObject = xhr.GlobalActiveXObject;
}
delete sinon.FakeXMLHttpRequest.restore;
if (keepOnCreate !== true) {
delete sinon.FakeXMLHttpRequest.onCreate;
}
};
if (xhr.supportsXHR) {
global.XMLHttpRequest = sinon.FakeXMLHttpRequest;
}
if (xhr.supportsActiveX) {
global.ActiveXObject = function ActiveXObject(objId) {
if (objId == "Microsoft.XMLHTTP" || /^Msxml2\.XMLHTTP/i.test(objId)) {
return new sinon.FakeXMLHttpRequest();
}
return new xhr.GlobalActiveXObject(objId);
};
}
return sinon.FakeXMLHttpRequest;
};
sinon.FakeXMLHttpRequest = FakeXMLHttpRequest;
})();
module.exports = sinon;
jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/queries/ 0000775 0000000 0000000 00000000000 14230544473 0023364 5 ustar 00root root 0000000 0000000 jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/queries/jiodate.tests.js 0000664 0000000 0000000 00000024736 14230544473 0026516 0 ustar 00root root 0000000 0000000 /*
* Copyright 2014, Nexedi SA
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Free Software licenses or any of the Open Source
* Initiative approved licenses and Convey the resulting work. Corresponding
* source of such a combination shall include the source code for all other
* software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
* See https://www.nexedi.com/licensing for rationale and options.
*/
/*jslint nomen: true, newcap: true */
/*global jiodate, moment, console*/
(function (QUnit, jiodate, moment) {
"use strict";
var test = QUnit.test,
ok = QUnit.ok,
strictEqual = QUnit.strictEqual,
equal = QUnit.equal,
module = QUnit.module,
JIODate = jiodate.JIODate,
throws = QUnit.throws;
module('JIODate');
test("A JIODate can be instantiated without parameters (=now)", function () {
ok((new JIODate()) instanceof JIODate);
ok(JIODate() instanceof JIODate);
});
test("Parsing from ISO string and exposing Moment/Date objects", function () {
var d = JIODate('2012-03-04T08:52:13.746Z');
// Because the above JIODate is created in ISO string, which uses UTC time,
// it's necessary to set the moment to use the UTC mode. Otherwise different
// timezones may have different results for the getters below, as they will
// try to convert it to local time.
//
d.mom.utc();
ok(moment.isMoment(d.mom));
strictEqual(d.mom.toISOString(), '2012-03-04T08:52:13.746Z');
strictEqual(d.mom.year(), 2012);
strictEqual(d.mom.month(), 2);
strictEqual(d.mom.date(), 4);
// and so on..
strictEqual(d.mom.isoWeekday(), 7);
strictEqual(d.mom.dayOfYear(), 64);
strictEqual(d.mom.week(), 10);
strictEqual(d.mom.isoWeek(), 9);
strictEqual(d.mom.day(), 0);
strictEqual(d.mom.hours(), 8);
strictEqual(d.mom.minutes(), 52);
strictEqual(d.mom.seconds(), 13);
strictEqual(d.mom.milliseconds(), 746);
// careful: changing the Date object changes the moment as well
ok(d.mom.toDate() instanceof Date);
});
test("By default, maximum precision is kept, " +
"but it can be changed later", function () {
var d = new JIODate();
equal(d.getPrecision(), jiodate.MSEC);
d.setPrecision(jiodate.SEC);
equal(d.getPrecision(), jiodate.SEC);
d.setPrecision(jiodate.DAY);
equal(d.getPrecision(), jiodate.DAY);
d.setPrecision(jiodate.MONTH);
equal(d.getPrecision(), jiodate.MONTH);
});
test("Passing a JIODate object to the constructor clones it", function () {
var d = JIODate('2012-05-06');
strictEqual(d.cmp(JIODate(d)), 0);
});
test("Comparison with .cmp() - any precision", function () {
var data = [
[
jiodate.MSEC,
'2012-03-04T08:52:13.746Z',
'2012-03-04T08:52:13.746Z',
'2012-03-04T08:52:13.747Z'
], [
jiodate.SEC,
'2012-03-04T08:52:13.746Z',
'2012-03-04T08:52:13.999Z',
'2012-03-04T08:52:14.746Z'
], [
jiodate.MIN,
'2012-03-04T08:52:13.746Z',
'2012-03-04T08:52:59.999Z',
'2012-03-04T08:53:13.746Z'
], [
jiodate.HOUR,
'2012-03-04T08:52:13.746Z',
'2012-03-04T08:59:59.999Z',
'2012-03-04T09:52:13.746Z'
], [
jiodate.DAY,
'2012-03-04T08:52:13.746Z',
'2012-03-04T20:59:59.999Z',
'2012-03-05T08:52:13.746Z'
], [
jiodate.MONTH,
'2012-03-04T08:52:13.746Z',
'2012-03-31T20:59:59.999Z',
'2012-04-04T08:53:13.746Z'
], [
jiodate.YEAR,
'2012-03-04T08:52:13.746Z',
'2012-12-31T20:59:59.999Z',
'2013-03-04T08:53:13.746Z'
]
], i = 0, precision, d1, d2, d3, s1, s2, s3, mp;
for (i = 0; i < data.length; i += 1) {
precision = data[i][0];
d1 = JIODate(data[i][1]);
d2 = JIODate(data[i][2]);
d3 = JIODate(data[i][3]);
d1.setPrecision(precision);
d2.setPrecision(precision);
d3.setPrecision(precision);
s1 = d1.mom.format();
s2 = d2.mom.format();
s3 = d3.mom.format();
mp = ' - ' + precision;
strictEqual(d1.cmp(d2), 0, s1 + ' cmp ' + s2 + mp);
strictEqual(d1.cmp(d3), -1, s1 + ' cmp ' + s3 + mp);
strictEqual(d2.cmp(d1), 0, s2 + ' cmp ' + s1 + mp);
strictEqual(d2.cmp(d3), -1, s2 + ' cmp ' + s3 + mp);
strictEqual(d3.cmp(d1), 1, s3 + ' cmp ' + s1 + mp);
strictEqual(d3.cmp(d2), 1, s1 + ' cmp ' + s2 + mp);
}
});
test("Display timestamp value trucated to precision", function () {
var d = JIODate('2012-03-04T08:52:13.746');
strictEqual(d.toPrecisionString(jiodate.MSEC), '2012-03-04 08:52:13.746');
strictEqual(d.toPrecisionString(jiodate.SEC), '2012-03-04 08:52:13');
strictEqual(d.toPrecisionString(jiodate.MIN), '2012-03-04 08:52');
strictEqual(d.toPrecisionString(jiodate.HOUR), '2012-03-04 08');
strictEqual(d.toPrecisionString(jiodate.DAY), '2012-03-04');
strictEqual(d.toPrecisionString(jiodate.MONTH), '2012-03');
strictEqual(d.toPrecisionString(jiodate.YEAR), '2012');
throws(
function () {
d.toPrecisionString('something');
},
/Unsupported precision value 'something'/,
"Precision parameter must be a valid value"
);
d.setPrecision(jiodate.HOUR);
strictEqual(d.toPrecisionString(), '2012-03-04 08');
});
test("Parsing of invalid input", function () {
throws(
function () {
JIODate('foobar');
},
/Cannot parse: foobar/,
"Invalid strings raise exceptions"
);
});
test("The toString() method should retain the precision", function () {
var d;
d = JIODate('2012-05-08');
strictEqual(d.toString(), '2012-05-08');
d = JIODate('2012-05');
strictEqual(d.toString(), '2012-05');
d = JIODate('2012');
strictEqual(d.toString(), '2012');
});
test("Parsing of partial timestamp values with any precision", function () {
var d;
d = JIODate('2012-05-02 06:07:08.989');
strictEqual(d.getPrecision(), 'millisecond');
strictEqual(d.toPrecisionString(), '2012-05-02 06:07:08.989');
strictEqual(
d.mom.toDate().valueOf(),
// This Date constructor needs to be used because of older Firefox
// versions that do not parse some date strings formats correctly. It
// uses months from 0 to 11. So if we want to create a date in May, we
// need to use 4 instead of 5.
//
new Date(2012, 4, 2, 6, 7, 8, 989).valueOf()
);
d = JIODate('2012-05-02 06:07:08');
strictEqual(d.getPrecision(), 'second');
strictEqual(d.toPrecisionString(), '2012-05-02 06:07:08');
strictEqual(
d.mom.toDate().valueOf(),
new Date(2012, 4, 2, 6, 7, 8, 0).valueOf()
);
d = JIODate('2012-05-02 06:07');
strictEqual(d.getPrecision(), 'minute');
strictEqual(d.toPrecisionString(), '2012-05-02 06:07');
strictEqual(
d.mom.toDate().valueOf(),
new Date(2012, 4, 2, 6, 7, 0, 0).valueOf()
);
d = JIODate('2012-05-02 06');
strictEqual(d.getPrecision(), 'hour');
strictEqual(d.toPrecisionString(), '2012-05-02 06');
strictEqual(
d.mom.toDate().valueOf(),
new Date(2012, 4, 2, 6, 0, 0, 0).valueOf()
);
d = JIODate('2012-05-02');
strictEqual(d.getPrecision(), 'day');
strictEqual(d.toPrecisionString(), '2012-05-02');
strictEqual(
d.mom.toDate().valueOf(),
new Date(2012, 4, 2, 0, 0, 0, 0).valueOf()
);
d = JIODate('2012-05');
strictEqual(d.getPrecision(), 'month');
strictEqual(d.toPrecisionString(), '2012-05');
strictEqual(
d.mom.toDate().valueOf(),
new Date(2012, 4, 1, 0, 0, 0, 0).valueOf()
);
d = JIODate('2012');
strictEqual(d.getPrecision(), 'year');
strictEqual(d.toPrecisionString(), '2012');
strictEqual(
d.mom.toDate().valueOf(),
new Date(2012, 0, 1, 0, 0, 0, 0).valueOf()
);
});
test("Comparison between heterogeneous values is done with " +
"the lesser precision", function () {
var dmsec = JIODate('2012-05-02 06:07:08.989'),
dsec = JIODate('2012-05-02 06:07:08'),
dmin = JIODate('2012-05-02 06:07'),
dhour = JIODate('2012-05-02 06'),
dday = JIODate('2012-05-02'),
dmonth = JIODate('2012-05'),
dyear = JIODate('2012');
strictEqual(dmsec.cmp(dsec), 0);
strictEqual(dmsec.cmp(dmin), 0);
strictEqual(dmsec.cmp(dhour), 0);
strictEqual(dmsec.cmp(dday), 0);
strictEqual(dmsec.cmp(dmonth), 0);
strictEqual(dmsec.cmp(dyear), 0);
strictEqual(dsec.cmp(dmsec), 0);
strictEqual(dsec.cmp(dmin), 0);
strictEqual(dsec.cmp(dhour), 0);
strictEqual(dsec.cmp(dday), 0);
strictEqual(dsec.cmp(dmonth), 0);
strictEqual(dsec.cmp(dyear), 0);
strictEqual(dmin.cmp(dmsec), 0);
strictEqual(dmin.cmp(dsec), 0);
strictEqual(dmin.cmp(dhour), 0);
strictEqual(dmin.cmp(dday), 0);
strictEqual(dmin.cmp(dmonth), 0);
strictEqual(dmin.cmp(dyear), 0);
strictEqual(dhour.cmp(dmsec), 0);
strictEqual(dhour.cmp(dsec), 0);
strictEqual(dhour.cmp(dmin), 0);
strictEqual(dhour.cmp(dday), 0);
strictEqual(dhour.cmp(dmonth), 0);
strictEqual(dhour.cmp(dyear), 0);
strictEqual(dday.cmp(dmsec), 0);
strictEqual(dday.cmp(dsec), 0);
strictEqual(dday.cmp(dmin), 0);
strictEqual(dday.cmp(dhour), 0);
strictEqual(dday.cmp(dmonth), 0);
strictEqual(dday.cmp(dyear), 0);
strictEqual(dmonth.cmp(dmsec), 0);
strictEqual(dmonth.cmp(dsec), 0);
strictEqual(dmonth.cmp(dmin), 0);
strictEqual(dmonth.cmp(dhour), 0);
strictEqual(dmonth.cmp(dday), 0);
strictEqual(dmonth.cmp(dyear), 0);
strictEqual(dyear.cmp(dmsec), 0);
strictEqual(dyear.cmp(dsec), 0);
strictEqual(dyear.cmp(dmin), 0);
strictEqual(dyear.cmp(dhour), 0);
strictEqual(dyear.cmp(dday), 0);
strictEqual(dyear.cmp(dmonth), 0);
strictEqual(dmsec.cmp(JIODate('2012-05-02 06:07:07')), +1);
strictEqual(dmsec.cmp(JIODate('2012-05-02 06:07:08')), 0);
strictEqual(dmsec.cmp(JIODate('2012-05-02 06:07:09')), -1);
});
}(QUnit, jiodate, moment));
jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/queries/key-jiodate.tests.js 0000664 0000000 0000000 00000013047 14230544473 0027275 0 ustar 00root root 0000000 0000000 /*
* Copyright 2014, Nexedi SA
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Free Software licenses or any of the Open Source
* Initiative approved licenses and Convey the resulting work. Corresponding
* source of such a combination shall include the source code for all other
* software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
* See https://www.nexedi.com/licensing for rationale and options.
*/
/*global jiodate*/
(function (jIO, jiodate) {
"use strict";
var test = QUnit.test,
stop = QUnit.stop,
start = QUnit.start,
deepEqual = QUnit.deepEqual,
module = QUnit.module,
noop = function () {
return; // use with RSVP.all
};
module('Custom Key Queries with JIODate');
test('Stock comparison operators with year precision', function () {
var docList = function () {
return [
{'identifier': 'twenty ten', 'date': '2010-03-04 08:52:13.746'},
{'identifier': 'twenty eleven', 'date': '2011-03-04 08:52:13.746'},
{'identifier': 'twenty twelve', 'date': '2012-03-04 08:52:13.746'}
];
}, key_schema = {
key_set: {
date: {
read_from: 'date',
cast_to: jiodate.JIODate
}
}
}, query_list = [], promise = [];
stop();
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: 'date',
value: '2011'
}, key_schema).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'date': '2011-03-04 08:52:13.746', 'identifier': 'twenty eleven'}
], 'Match with "date = 2011" (query tree form)');
})
);
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: 'date',
operator: '!=',
value: '2011'
}, key_schema).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'date': '2010-03-04 08:52:13.746', 'identifier': 'twenty ten'},
{'date': '2012-03-04 08:52:13.746', 'identifier': 'twenty twelve'}
], 'Match with "date != 2011" (query tree form)');
})
);
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: 'date',
operator: '<',
value: '2011'
}, key_schema).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'date': '2010-03-04 08:52:13.746', 'identifier': 'twenty ten'}
], 'Match with "date < 2011" (query tree form)');
})
);
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: 'date',
operator: '<=',
value: '2011'
}, key_schema).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'date': '2010-03-04 08:52:13.746', 'identifier': 'twenty ten'},
{'date': '2011-03-04 08:52:13.746', 'identifier': 'twenty eleven'}
], 'Match with "date <= 2011" (query tree form)');
})
);
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: 'date',
operator: '>',
value: '2011'
}, key_schema).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'date': '2012-03-04 08:52:13.746', 'identifier': 'twenty twelve'}
], 'Match with "date > 2011" (query tree form)');
})
);
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: 'date',
operator: '>=',
value: '2011'
}, key_schema).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'date': '2011-03-04 08:52:13.746', 'identifier': 'twenty eleven'},
{'date': '2012-03-04 08:52:13.746', 'identifier': 'twenty twelve'}
], 'Match with "date >= 2011" (query tree form)');
})
);
query_list = [
[
'date: < "2011" OR date: "2012-03"',
[
{'date': '2010-03-04 08:52:13.746', 'identifier': 'twenty ten'},
{'date': '2012-03-04 08:52:13.746', 'identifier': 'twenty twelve'}
]
],
[
'date: >= "2011-01" AND date: != "2012-03-04 08:52:13.746"',
[
{'date': '2011-03-04 08:52:13.746', 'identifier': 'twenty eleven'}
]
]
];
query_list.forEach(function (o) {
var qs = o[0], expected = o[1];
promise.push(
jIO.QueryFactory.create(qs, key_schema).
exec(docList()).
then(function (dl) {
deepEqual(dl, expected, "Match with '" + qs +
"' (parsed query string)");
})
);
});
query_list = [
'date < "2011"',
'date <= "2011"',
'date > "2011"',
'date >= "2011"'
];
query_list.forEach(function (qs) {
promise.push(
jIO.QueryFactory.create(qs, key_schema).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
], "Match with an invalid parsed string " + qs +
" should return empty list but not raise errors");
})
);
});
RSVP.all(promise).then(noop).always(start);
});
}(jIO, jiodate));
jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/queries/key-localstorage.tests.js 0000664 0000000 0000000 00000015232 14230544473 0030333 0 ustar 00root root 0000000 0000000 /*
* Copyright 2014, Nexedi SA
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Free Software licenses or any of the Open Source
* Initiative approved licenses and Convey the resulting work. Corresponding
* source of such a combination shall include the source code for all other
* software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
* See https://www.nexedi.com/licensing for rationale and options.
*/
/*jslint maxlen: 120, nomen: true */
/*global localStorage, test_util, console*/
(function (jIO, localStorage, QUnit) {
"use strict";
var test = QUnit.test,
stop = QUnit.stop,
start = QUnit.start,
ok = QUnit.ok,
expect = QUnit.expect,
// deepEqual = QUnit.deepEqual,
module = QUnit.module,
key_schema;
key_schema = {
cast_lookup: {
dateType: function (obj) {
if (Object.prototype.toString.call(obj) === '[object Date]') {
// no need to clone
return obj;
}
return new Date(obj);
}
},
key_set: {
mydate: {
read_from: 'date',
cast_to: 'dateType'
}
}
};
module("localStorage", {
setup: function () {
localStorage.clear();
this.jio = jIO.createJIO({
"type": "local"
}, {
"workspace": {}
});
}
});
test("AllDocs", function () {
expect(3);
var o = {}, jio = jIO.createJIO({
"type": "local",
"username": "ualldocs",
"application_name": "aalldocs",
"key_schema": key_schema
}, {
"workspace": {}
});
stop();
o.date_a = new Date(0);
o.date_b = new Date();
// put some document before listing them
RSVP.all([
jio.put({
"_id": "a",
"title": "one",
"date": o.date_a
}).then(function () {
return jio.putAttachment({
"_id": "a",
"_attachment": "aa",
"_data": "aaa"
});
}),
jio.put({"_id": "b", "title": "two", "date": o.date_a}),
jio.put({"_id": "c", "title": "one", "date": o.date_b}),
jio.put({"_id": "d", "title": "two", "date": o.date_b})
])
// .then(function () {
//
// // get a list of documents
// return jio.allDocs();
//
// })
// .then(function (answer) {
//
// // sort answer rows for comparison
// if (answer.data && answer.data.rows) {
// answer.data.rows.sort(function (a, b) {
// return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
// });
// }
//
// deepEqual(answer, {
// "data": {
// "rows": [{
// "id": "a",
// "key": "a",
// "value": {}
// }, {
// "id": "b",
// "key": "b",
// "value": {}
// }, {
// "id": "c",
// "key": "c",
// "value": {}
// }, {
// "id": "d",
// "key": "d",
// "value": {}
// }],
// "total_rows": 4
// },
// "method": "allDocs",
// "result": "success",
// "status": 200,
// "statusText": "Ok"
// }, "AllDocs");
//
// })
// .then(function () {
//
// // get a list of documents
// return jio.allDocs({
// "include_docs": true,
// "sort_on": [['title', 'ascending'], ['date', 'descending']],
// "select_list": ['title', 'date'],
// "limit": [1] // ==> equal [1, 3] in this case
// });
//
// })
// .then(function (answer) {
//
// deepEqual(answer, {
// "data": {
// "rows": [{
// "doc": {
// "_attachments": {
// "aa": {
// "content_type": "",
// "digest": "sha256-9834876dcfb05cb167a5c24953eba58c4" +
// "ac89b1adf57f28f2f9d09af107ee8f0",
// "length": 3
// }
// },
// "_id": "a",
// "date": o.date_a.toJSON(),
// "title": "one"
// },
// "id": "a",
// "key": "a",
// "value": {
// "date": o.date_a.toJSON(),
// "title": "one"
// }
// }, {
// "doc": {
// "_id": "d",
// "date": o.date_b.toJSON(),
// "title": "two"
// },
// "id": "d",
// "key": "d",
// "value": {
// "date": o.date_b.toJSON(),
// "title": "two"
// }
// }, {
// "doc": {
// "_id": "b",
// "date": o.date_a.toJSON(),
// "title": "two"
// },
// "id": "b",
// "key": "b",
// "value": {
// "date": o.date_a.toJSON(),
// "title": "two"
// }
// }],
// "total_rows": 3
// },
// "method": "allDocs",
// "result": "success",
// "status": 200,
// "statusText": "Ok"
// }, "AllDocs include docs + sort on + limit + select_list");
//
// })
// .then(function () {
//
// // use a query
// return jio.allDocs({'query': {
// type: 'simple',
// key: 'mydate',
// operator: '=',
// value: o.date_a.toString()
// }});
//
// })
// .then(function (answer) {
//
// deepEqual(answer, {
// "data": {
// "rows": [{
// "id": "a",
// "key": "a",
// "value": {}
// }, {
// "id": "b",
// "key": "b",
// "value": {}
// }],
// "total_rows": 2
// },
// "method": "allDocs",
// "result": "success",
// "status": 200,
// "statusText": "Ok"
// }, "AllDocs sort on + query");
//
// })
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
}(jIO, localStorage, QUnit));
jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/queries/key-schema.tests.js 0000664 0000000 0000000 00000022454 14230544473 0027120 0 ustar 00root root 0000000 0000000 /*
* Copyright 2014, Nexedi SA
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Free Software licenses or any of the Open Source
* Initiative approved licenses and Convey the resulting work. Corresponding
* source of such a combination shall include the source code for all other
* software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
* See https://www.nexedi.com/licensing for rationale and options.
*/
/*global jiodate*/
(function (jIO, jiodate) {
"use strict";
var test = QUnit.test,
stop = QUnit.stop,
start = QUnit.start,
deepEqual = QUnit.deepEqual,
module = QUnit.module,
noop = function () {
return; // use with RSVP.all
},
translationEqualityMatcher = function (data) {
return function (object_value, value) {
value = data[value];
return (object_value === value);
};
},
key_schema;
module('Custom Key Queries with Schema');
/*jslint unparam: true*/
key_schema = {
cast_lookup: {
dateType: function (obj) {
return new jiodate.JIODate(obj);
}
},
match_lookup: {
sameDay: function (a, b) {
return (
(a.mom.year() === b.mom.year()) &&
(a.mom.month() === b.mom.month()) &&
(a.mom.date() === b.mom.date())
);
},
sameMonth: function (a, b) {
return (
(a.mom.year() === b.mom.year()) &&
(a.mom.month() === b.mom.month())
);
},
sameYear: function (a, b) {
return (a.mom.year() === b.mom.year());
},
equalState: translationEqualityMatcher({'ouvert': 'open'})
},
key_set: {
case_insensitive_identifier: {
read_from: 'identifier',
equal_match: function (object_value, value, wildcard_character) {
// XXX do this with a regexp and wildcard support
return (object_value.toLowerCase() === value.toLowerCase());
}
},
date_day: {
read_from: 'date',
cast_to: 'dateType',
equal_match: 'sameDay'
},
date_month: {
read_from: 'date',
cast_to: 'dateType',
equal_match: 'sameMonth'
},
date_year: {
read_from: 'date',
cast_to: 'dateType',
equal_match: 'sameYear'
},
translated_state: {
read_from: 'state',
equal_match: 'equalState'
}
}
};
/*jslint unparam: false*/
test('Keys defined in a Schema can be used like metadata', function () {
var docList = function () {
return [
{'identifier': 'a'},
{'identifier': 'A'},
{'identifier': 'b'}
];
}, promise = [];
stop();
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: 'case_insensitive_identifier',
value: 'A'
}, key_schema).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': 'a'},
{'identifier': 'A'}
], 'Key Schema: case_insensitive_identifier');
})
);
RSVP.all(promise).then(noop).always(start);
});
test('Standard date keys', function () {
var docList = function () {
return [
{'identifier': 'a', 'date': '2013-01-01'},
{'identifier': 'b', 'date': '2013-02-01'},
{'identifier': 'bb', 'date': '2013-02-02'},
{'identifier': 'bbb', 'date': '2013-02-03'},
{'identifier': 'c', 'date': '2013-03-03'},
{'identifier': 'd', 'date': '2013-04-04'}
];
}, promise = [];
stop();
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: 'date_day',
value: '2013-02-02'
}, key_schema).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': 'bb', 'date': '2013-02-02'}
], 'Key Schema: same_day');
})
);
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: 'date_month',
value: '2013-02-10'
}, key_schema).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'date': '2013-02-01', 'identifier': 'b'},
{'date': '2013-02-02', 'identifier': 'bb'},
{'date': '2013-02-03', 'identifier': 'bbb'}
], 'Key Schema: date_month');
})
);
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: 'date_year',
value: '2013-02-10'
}, key_schema).
exec(docList()).
then(function (dl) {
deepEqual(dl.length, 6, 'Key Schema: date_year');
})
);
RSVP.all(promise).then(noop).always(start);
});
test('Test key schema + jio query', function () {
var docList = function () {
return [
{'identifier': '10', 'number': '10'},
{'identifier': '19', 'number': '19'},
{'identifier': '100', 'number': '100'}
];
}, test_key_schema = {
cast_lookup: {
intType: function (value) {
if (typeof value === 'string') {
return parseInt(value, 10);
}
return value;
}
},
key_set: {
number: {
read_from: 'number',
cast_to: 'intType'
}
}
}, promise = [];
stop();
promise.push(
jIO.QueryFactory.create({
type: 'complex',
operator: 'OR',
query_list: [{
type: 'simple',
key: 'number',
operator: '<',
value: '19'
}, {
type: 'simple',
key: 'number',
operator: '=',
value: '19'
}]
}, test_key_schema).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': '10', 'number': '10'},
{'identifier': '19', 'number': '19'}
], 'Key schema should be propagated from complex to simple queries');
})
);
RSVP.all(promise).then(noop).always(start);
});
test('Test key schema + jio query with sort on', function () {
var docList = function () {
return [
{'identifier': '10', 'number': '10'},
{'identifier': '2', 'number': '2'},
{'identifier': '19', 'number': '19'},
{'identifier': '100', 'number': '100'}
];
}, test_key_schema = {
cast_lookup: {
intType: function (value) {
if (typeof value === 'string') {
return parseInt(value, 10);
}
return value;
}
},
key_set: {
number: {
read_from: 'number',
cast_to: 'intType'
}
}
}, promise = [];
stop();
promise.push(
jIO.QueryFactory.create({
type: 'complex',
operator: 'OR',
query_list: [{
type: 'simple',
key: 'number',
operator: '<',
value: '19'
}, {
type: 'simple',
key: 'number',
operator: '=',
value: '19'
}]
}, test_key_schema).
exec(
docList(),
{sort_on: [['number', 'ascending']]}
).
then(function (dl) {
deepEqual(dl, [
{'identifier': '2', 'number': '2'},
{'identifier': '10', 'number': '10'},
{'identifier': '19', 'number': '19'}
], 'Key schema should be propagated from complex to simple queries');
})
);
RSVP.all(promise).then(noop).always(start);
});
test('Key Schema with translation lookup', function () {
var docList = function () {
return [
{'identifier': '1', 'state': 'open'},
{'identifier': '2', 'state': 'closed'}
];
}, promise = [];
stop();
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: 'translated_state',
value: 'ouvert'
}, key_schema).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': '1', 'state': 'open'}
], 'Key Schema: It should be possible to look for a translated ' +
'string');
})
);
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: 'translated_state',
operator: '=',
value: 'ouvert'
}, key_schema).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': '1', 'state': 'open'}
], 'Key Schema: It should be possible to look for a translated ' +
'string with operator =');
})
);
// XXX not implemented yet
// doc_list = docList();
// jIO.QueryFactory.create({
// type: 'simple',
// key: 'translated_state',
// operator: '!=',
// value: 'ouvert'
// }).exec(doc_list);
// deepEqual(doc_list, [
// {'identifier': '2', 'state': 'closed'}
// ], 'Key Schema: It should be possible to look for a translated ' +
// 'string with operator !=');
RSVP.all(promise).then(noop).always(start);
});
}(jIO, jiodate));
jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/queries/key-typechecks.tests.js 0000664 0000000 0000000 00000007730 14230544473 0030022 0 ustar 00root root 0000000 0000000 /*
* Copyright 2014, Nexedi SA
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Free Software licenses or any of the Open Source
* Initiative approved licenses and Convey the resulting work. Corresponding
* source of such a combination shall include the source code for all other
* software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
* See https://www.nexedi.com/licensing for rationale and options.
*/
(function (jIO) {
"use strict";
var test = QUnit.test,
equal = QUnit.equal,
ok = QUnit.ok,
module = QUnit.module;
module('Key and key_schema objects validation');
test('Check the parameters passed to exec() and create()', function () {
try {
jIO.QueryFactory.create('').exec('gnegne');
ok(false, 'argument 1 not checked');
} catch (e) {
equal(e.name, 'TypeError', 'wrong exception type');
equal(e.message,
"Query().exec(): Argument 1 is not of type 'array'",
'wrong exception message');
}
try {
jIO.QueryFactory.create({});
ok(false, 'argument 1 not checked');
} catch (e) {
equal(e.name, 'TypeError', 'wrong exception type');
equal(e.message,
"QueryFactory.create(): Argument 1 is not a search text or a " +
"parsable object",
'wrong exception message');
}
try {
jIO.QueryFactory.create('').exec([], 1);
ok(false, 'argument 2 not checked');
} catch (e) {
equal(e.name, 'TypeError', 'wrong exception type');
equal(e.message,
"Query().exec(): Optional argument 2 is not of type 'object'",
'wrong exception message');
}
try {
jIO.QueryFactory.create({type: 'simple'}, '');
ok(false, 'key_schema type is not checked');
} catch (e) {
equal(e.name, 'TypeError', 'wrong exception type');
equal(e.message,
"Query().create(): key_schema is not of type 'object'",
'wrong exception message');
}
try {
jIO.QueryFactory.create({type: 'simple'}, {});
ok(false, 'key_schema.key_set is not checked');
} catch (e) {
equal(e.name, 'TypeError', 'wrong exception type');
equal(e.message,
"Query().create(): key_schema has no 'key_set' property",
'wrong exception message');
}
try {
jIO.QueryFactory.create({
type: 'simple'
}, {key_set: {}, foobar: {}});
ok(false, 'unknown key_schema properties are not checked');
} catch (e) {
equal(e.name, 'TypeError', 'wrong exception type');
equal(e.message,
"Query().create(): key_schema has unknown property 'foobar'",
'wrong exception message');
}
});
test('Check the key options', function () {
var doc_list = [
{'identifier': 'a'}
];
try {
jIO.QueryFactory.create({
type: 'simple',
key: {},
value: 'a'
}).exec(doc_list);
ok(false, 'key.read_from is not checked');
} catch (e) {
equal(e.name, 'TypeError', 'wrong exception type');
equal(e.message,
"Custom key is missing the read_from property",
'wrong exception message');
}
try {
jIO.QueryFactory.create({
type: 'simple',
key: {
read_from: 'identifier',
foobar: ''
},
value: 'a'
}).exec(doc_list);
ok(false, 'unknown key properties are not checked');
} catch (e) {
equal(e.name, 'TypeError', 'wrong exception type');
equal(e.message,
"Custom key has unknown property 'foobar'",
'wrong exception message');
}
});
}(jIO));
jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/queries/key.tests.js 0000664 0000000 0000000 00000040073 14230544473 0025657 0 ustar 00root root 0000000 0000000 /*
* Copyright 2014, Nexedi SA
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Free Software licenses or any of the Open Source
* Initiative approved licenses and Convey the resulting work. Corresponding
* source of such a combination shall include the source code for all other
* software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
* See https://www.nexedi.com/licensing for rationale and options.
*/
/*global jiodate*/
(function (jIO, jiodate) {
"use strict";
var test = QUnit.test,
stop = QUnit.stop,
start = QUnit.start,
equal = QUnit.equal,
deepEqual = QUnit.deepEqual,
module = QUnit.module,
noop = function () {
return; // use with RSVP.all
},
dateCast = function (obj) {
return new jiodate.JIODate(obj);
},
translationEqualityMatcher = function (data) {
return function (object_value, value) {
value = data[value];
return (object_value === value);
};
},
// This method is provided as an example.
// A more robust solution to manage diacritics is recommended for production
// environments, with unicode normalization, like (untested):
// https://github.com/walling/unorm/
accentFold = function (s) {
var map = [
[new RegExp('[àáâãäå]', 'gi'), 'a'],
[new RegExp('æ', 'gi'), 'ae'],
[new RegExp('ç', 'gi'), 'c'],
[new RegExp('[èéêë]', 'gi'), 'e'],
[new RegExp('[ìíîï]', 'gi'), 'i'],
[new RegExp('ñ', 'gi'), 'n'],
[new RegExp('[òóôõö]', 'gi'), 'o'],
[new RegExp('œ', 'gi'), 'oe'],
[new RegExp('[ùúûü]', 'gi'), 'u'],
[new RegExp('[ýÿ]', 'gi'), 'y']
];
map.forEach(function (o) {
var rep = function (match) {
if (match.toUpperCase() === match) {
return o[1].toUpperCase();
}
return o[1];
};
s = s.replace(o[0], rep);
});
return s;
};
module('Custom Key Queries');
test('Simple Key with read_from', function () {
var docList = function () {
return [
{'identifier': 'a'},
{'identifier': 'A'},
{'identifier': 'b'}
];
}, keys = {
title: {
read_from: 'identifier'
},
case_insensitive_identifier: {
read_from: 'identifier',
equal_match: function (object_value, value) {
return (object_value.toLowerCase() === value.toLowerCase());
}
}
}, promise = [];
stop();
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: keys.title,
value: 'a'
}).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': 'a'}
], 'It should be possible to query with an alias key');
})
);
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: keys.case_insensitive_identifier,
value: 'A'
}).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': 'a'},
{'identifier': 'A'}
], 'It should be possible to query with a case-insensitive alias ' +
'key');
})
);
RSVP.all(promise).then(noop).always(start);
});
test('Simple Key with date casting', function () {
var docList = function () {
return [
{'identifier': 'a', 'date': '2013-01-01'},
{'identifier': 'b', 'date': '2013-02-01'},
{'identifier': 'bb', 'date': '2013-02-02'},
{'identifier': 'bbb', 'date': '2013-02-03'},
{'identifier': 'c', 'date': '2013-03-03'},
{'identifier': 'd', 'date': '2013-04-04'}
];
},
promise = [],
sameDay = function (a, b) {
return (
(a.mom.year() === b.mom.year()) &&
(a.mom.month() === b.mom.month()) &&
(a.mom.date() === b.mom.date())
);
},
sameMonth = function (a, b) {
return (
(a.mom.year() === b.mom.year()) &&
(a.mom.month() === b.mom.month())
);
},
sameYear = function (a, b) {
return (a.mom.year() === b.mom.year());
},
keys = {
day: {
read_from: 'date',
cast_to: dateCast,
equal_match: sameDay
},
month: {
read_from: 'date',
cast_to: dateCast,
equal_match: sameMonth
},
year: {
read_from: 'date',
cast_to: dateCast,
equal_match: sameYear
},
broken: {
read_from: 'date',
cast_to: function () { throw new Error('Broken!'); }
}
};
stop();
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: keys.day,
value: '2013-02-02'
}).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': 'bb', 'date': '2013-02-02'}
], 'It should be possible to compare dates with sameDay');
})
);
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: keys.month,
value: '2013-02-10'
}).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'date': '2013-02-01', 'identifier': 'b'},
{'date': '2013-02-02', 'identifier': 'bb'},
{'date': '2013-02-03', 'identifier': 'bbb'}
], 'It should be possible to compare dates with sameMonth');
})
);
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: keys.year,
value: '2013-02-10'
}).
exec(docList()).
then(function (dl) {
deepEqual(dl.length, 6,
'It should be possible to compare dates with sameYear');
})
);
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: keys.broken,
value: '2013-02-10'
}).
exec(docList()).
then(function (dl) {
deepEqual(dl.length, 0,
'Constructors that throw exceptions should not break a ' +
'query, but silently fail comparisons');
})
);
RSVP.all(promise).then(noop).always(start);
});
test('Simple Key with date casting and <=> operators', function () {
var docList = function () {
return [
{'identifier': '1', 'date': '2013-01-01'},
{'identifier': '2', 'date': '2013-02-02'},
{'identifier': '3', 'date': '2013-03-03'}
];
}, keys = {
mydate: {
read_from: 'date',
cast_to: dateCast
}
}, promise = [];
stop();
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: keys.mydate,
operator: '=',
value: '2013-02-02'
}).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': '2', 'date': '2013-02-02'}
], 'It should be possible to search for dates with operator =');
})
);
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: keys.mydate,
operator: '!=',
value: '2013-02-02'
}).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': '1', 'date': '2013-01-01'},
{'identifier': '3', 'date': '2013-03-03'}
], 'It should be possible to search for dates with operator !=');
})
);
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: keys.mydate,
operator: '<=',
value: '2013-02-02'
}).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': '1', 'date': '2013-01-01'},
{'identifier': '2', 'date': '2013-02-02'}
], 'It should be possible to search for dates with operator <=');
})
);
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: keys.mydate,
operator: '<',
value: '2013-02-02'
}).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': '1', 'date': '2013-01-01'}
], 'It should be possible to search for dates with operator <');
})
);
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: keys.mydate,
operator: '>',
value: '2013-02-02'
}).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': '3', 'date': '2013-03-03'}
], 'It should be possible to search for dates with operator >');
})
);
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: keys.mydate,
operator: '>=',
value: '2013-02-02'
}).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': '2', 'date': '2013-02-02'},
{'identifier': '3', 'date': '2013-03-03'}
], 'It should be possible to search for dates with operator >=');
})
);
RSVP.all(promise).then(noop).always(start);
});
test('Simple Key with both equal_match and operator attributes', function () {
var docList = function () {
return [
{'identifier': '1', 'date': '2013-01-01'},
{'identifier': '2', 'date': '2013-02-02'},
{'identifier': '3', 'date': '2013-03-03'}
];
}, keys = {
mydate: {
read_from: 'date',
cast_to: dateCast,
equal_match: function alwaysTrue(o1) { /*, o2*/
return o1.mom.date() === 2;
}
}
}, promise = [];
stop();
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: keys.mydate,
value: '2013-02-02'
}).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': '2', 'date': '2013-02-02'}
], "'equal_match' with no 'operator'");
})
);
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: keys.mydate,
operator: '=',
value: '2013-01-01'
}).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': '2', 'date': '2013-02-02'}
], "'equal_match' overrides '=' operator");
})
);
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: keys.mydate,
operator: '>=',
value: '2013-02-02'
}).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': '2', 'date': '2013-02-02'},
{'identifier': '3', 'date': '2013-03-03'}
], "'equal_match' does not override '>' operator");
})
);
RSVP.all(promise).then(noop).always(start);
});
test('Test overriding operators and compound query', function () {
var docList = function () {
return [
{'identifier': '10', 'number': '10'},
{'identifier': '19', 'number': '19'},
{'identifier': '100', 'number': '100'}
];
}, intType = function (value) {
if (typeof value === 'string') {
return parseInt(value, 10);
}
return value;
}, promise = [];
stop();
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: {
read_from: 'number',
cast_to: intType
},
operator: '>',
value: '19'
}).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': '100', 'number': '100'}
], 'Numbers are correctly compared (>) after casting');
})
);
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: {
read_from: 'number',
cast_to: intType
},
operator: '<',
value: '19'
}).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': '10', 'number': '10'}
], 'Numbers are correctly compared (<) after casting');
})
);
promise.push(
jIO.QueryFactory.create({
type: 'complex',
operator: 'OR',
query_list: [{
type: 'simple',
key: {
read_from: 'number',
cast_to: intType
},
operator: '<',
value: '19'
}, {
type: 'simple',
key: {
read_from: 'number',
cast_to: intType
},
operator: '=',
value: '19'
}]
}).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': '10', 'number': '10'},
{'identifier': '19', 'number': '19'}
], 'Custom keys should also work within compound queries');
})
);
RSVP.all(promise).then(noop).always(start);
});
test('Simple Key with translation lookup', function () {
var docList = function () {
return [
{'identifier': '1', 'state': 'open'},
{'identifier': '2', 'state': 'closed'}
];
},
equalState = translationEqualityMatcher({'ouvert': 'open'}),
keys = {
translated_state: {
read_from: 'state',
equal_match: equalState
}
}, promise = [];
stop();
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: keys.translated_state,
value: 'ouvert'
}).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': '1', 'state': 'open'}
], 'It should be possible to look for a translated string with a ' +
'custom match function');
})
);
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: keys.translated_state,
operator: '=',
value: 'ouvert'
}).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': '1', 'state': 'open'}
], 'It should be possible to look for a translated string with ' +
'operator =');
})
);
// XXX not implemented yet
// doc_list = docList();
// jIO.QueryFactory.create({
// type: 'simple',
// key: keys.translated_state,
// operator: '!=',
// value: 'ouvert'
// }).exec(doc_list);
// deepEqual(doc_list, [
// {'identifier': '2', 'state': 'closed'}
// ], 'It should be possible to look for a translated string with ' +
// 'operator !=');
RSVP.all(promise).then(noop).always(start);
});
test('Accent folding', function () {
equal(accentFold('àéîöùç'), 'aeiouc');
equal(accentFold('ÀÉÎÖÙÇ'), 'AEIOUC');
equal(accentFold('àéî öùç'), 'aei ouc');
});
test('Query with accent folding and wildcard', function () {
/*jslint unparam: true*/
var docList = function () {
return [
{'identifier': 'àéîöùç'},
{'identifier': 'âèî ôùc'},
{'identifier': 'ÀÉÎÖÙÇ'},
{'identifier': 'b'}
];
}, keys = {
identifier: {
read_from: 'identifier',
cast_to: accentFold
}
}, promise = [];
/*jslint unparam: false*/
stop();
promise.push(
jIO.QueryFactory.create({
type: 'simple',
key: keys.identifier,
value: 'aei%'
}).
exec(docList()).
then(function (dl) {
deepEqual(dl, [
{'identifier': 'àéîöùç'},
{'identifier': 'âèî ôùc'},
{'identifier': 'ÀÉÎÖÙÇ'}
], 'It should be possible to query regardless of accents');
})
);
RSVP.all(promise).then(noop).always(start);
});
}(jIO, jiodate));
jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/queries/tests.js 0000664 0000000 0000000 00000052442 14230544473 0025073 0 ustar 00root root 0000000 0000000 /*
* Copyright 2013, Nexedi SA
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Free Software licenses or any of the Open Source
* Initiative approved licenses and Convey the resulting work. Corresponding
* source of such a combination shall include the source code for all other
* software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
* See https://www.nexedi.com/licensing for rationale and options.
*/
/*global jiodate*/
(function (jIO, jiodate) {
"use strict";
var test = QUnit.test,
stop = QUnit.stop,
start = QUnit.start,
deepEqual = QUnit.deepEqual,
expect = QUnit.expect,
ok = QUnit.ok,
module = QUnit.module;
module('Query');
// XXX test documentation
test('Empty Query', function () {
var doc_list = [
{"identifier": "a"},
{"identifier": ["b", "c"]}
];
stop();
expect(1);
jIO.QueryFactory.create('').exec(doc_list).
then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "a"},
{"identifier": ["b", "c"]}
], 'Nothing done on the list');
}).always(start);
});
test('Simple Query', function () {
var doc_list = [
{"identifier": "a"},
{"identifier": ["b", "c"]}
];
stop();
expect(2);
jIO.QueryFactory.create('identifier: "a"').exec(doc_list).
then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "a"}
], 'Document with several identifier should be removed');
doc_list = [
{"identifier": "a"},
{"identifier": ["a", "b"]}
];
return jIO.QueryFactory.create('identifier: "a"').
exec(doc_list);
}).then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "a"},
{"identifier": ["a", "b"]}
], 'Document with several identifier should be kept');
}).always(start);
});
test('Complex Query', function () {
var doc_list = [
{"identifier": "a"},
{"identifier": ["b", "c"]}
];
stop();
expect(3);
jIO.QueryFactory.create(
'identifier: "b" AND identifier: "c"'
).exec(doc_list).then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": ["b", "c"]}
], 'Document with only one identifier should be removed');
doc_list = [
{"identifier": "a"},
{"identifier": ["b", "c"]}
];
return jIO.QueryFactory.create(
'identifier: "a" OR identifier: "c"'
).exec(doc_list);
}).then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "a"},
{"identifier": ["b", "c"]}
], 'All document matches');
doc_list = [
{"identifier": "a", "title": "o"},
{"identifier": ["b", "c"]}
];
return jIO.QueryFactory.create(
'(identifier: "a" OR identifier: "b") AND title: "o"'
).exec(doc_list);
}).then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "a", "title": "o"}
], 'Only first document should be kept');
}).always(start);
});
test('Chinese Character', function () {
var doc_list = [
{"identifier": ["测试一", "测试四"]},
{"identifier": ["测试一", "测试五"]},
{"identifier": ["a", "b"]}
];
stop();
expect(4);
jIO.QueryFactory.create(
'(identifier: "%测试一%" OR identifier: "%测试二%") AND identifier: "%测试四%"'
)
.exec(
doc_list
).then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": ["测试一", "测试四"]}
], 'Only first document should be kept');
doc_list = [
{"identifier": ["测试一", "测试四"]},
{"identifier": ["测试一", "测试五"]},
{"identifier": ["测试四", "b"]}
];
return jIO.QueryFactory.create('identifier: "%测试%"')
.exec(doc_list);
})
.then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": ["测试一", "测试四"]},
{"identifier": ["测试一", "测试五"]},
{"identifier": ["测试四", "b"]}
], 'All document should be kept');
doc_list = [
{"identifier": "测试一"},
{"identifier": "测试一", "title": "标题"},
{"identifier": "测试一", "title": "b"}
];
return jIO.QueryFactory.create('identifier: "%测试%" AND title: "标题"')
.exec(doc_list);
})
.then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "测试一", "title": "标题"}
], 'Only second document should be kept');
return jIO.QueryFactory.create('测试')
.exec(doc_list);
})
.then(function (doc_list) {
deepEqual(doc_list, [{"identifier": "测试一", "title": "标题"}
], 'Full text query matched document should be returned');
})
.fail(function (error) {
ok(false, error);
}).always(start);
});
test('Wildcard Character', function () {
var doc_list = [
{"identifier": "a"},
{"identifier": "a%"},
{"identifier": "a\\%"},
{"identifier": ["ab", "b"]}
];
stop();
expect(4);
jIO.QueryFactory.create('identifier: "a%"').exec(
doc_list
).then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "a"},
{"identifier": "a%"},
{"identifier": "a\\%"},
{"identifier": ["ab", "b"]}
], 'All documents should be kept');
doc_list = [
{"identifier": "a"},
{"identifier": "a%"},
{"identifier": "a\\%"},
{"identifier": ["ab", "b"]}
];
return jIO.QueryFactory.create('identifier: "a\\%"').
exec(doc_list);
}).then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "a\\%"}
], 'Only third document should be kept');
// yes.. it's weird but ERP5 acts like that.
// `\` (or "\\") is taken literaly (= /\\/)
doc_list = [
{"identifier": "a"},
{"identifier": "a%"},
{"identifier": "a\\%"},
{"identifier": ["ab", "b"]}
];
return jIO.QueryFactory.create('identifier: "__"').
exec(doc_list);
}).then(function (doc_list) {
deepEqual(doc_list, [
], 'Should keep nothing');
doc_list = [
{"identifier": "a"},
{"identifier": "a%"},
{"identifier": "a\\%"},
{"identifier": ["ab", "b"]}
];
return jIO.QueryFactory.create('identifier: "__%"').
exec(doc_list);
}).then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "a%"},
{"identifier": "a\\%"},
{"identifier": ["ab", "b"]}
], 'First should not be kept');
// yes.. it's weird but ERP5 acts like that.
// `_` is not considered as wildcard (= /./)
}).always(start);
});
test("Additional Filters", function () {
var doc_list = [
{"identifier": "b", "title": "e"},
{"identifier": "a", "title": "f"},
{"identifier": "b", "title": "d"}
];
stop();
expect(1);
jIO.QueryFactory.create('').exec(doc_list, {
"select_list": ["title"],
"limit": [2, 1],
"sort_on": [["identifier", "ascending"], ["title", "descending"]]
}).then(function (doc_list) {
deepEqual(doc_list, [
{"title": "d"}
], 'The first document should be kept');
}).always(start);
});
test("JSON query", function () {
var jsoned = jIO.QueryFactory.create(
"NOT(a:=b OR c:% AND d:<2)"
).toJSON();
deepEqual(
jsoned,
{
"type": "complex",
"operator": "NOT",
"query_list": [{
"type": "complex",
"operator": "OR",
"query_list": [{
"key": "a",
"operator": "=",
"type": "simple",
"value": "b"
}, {
"type": "complex",
"operator": "AND",
"query_list": [{
"key": "c",
"type": "simple",
"value": "%"
}, {
"key": "d",
"operator": "<",
"type": "simple",
"value": "2"
}]
}]
}]
},
"\"NOT(a:=b OR c:% AND d:<2)\".toJSON()"
);
deepEqual(
jIO.Query.parseStringToObject("NOT(a:=b OR c:% AND d:<2)"),
jsoned,
"parseStringToObject(\"NOT(a:=b OR c:% AND d:<2)\");"
);
deepEqual(
jIO.QueryFactory.create(
"NOT(a:=b OR c:% AND d:<2)"
),
jIO.QueryFactory.create(
jIO.QueryFactory.create(
"NOT(a:=b OR c:% AND d:<2)"
)
),
"create(create(\"NOT(a:=b OR c:% AND d:<2)\"));"
);
deepEqual(
jIO.QueryFactory.create(
jIO.QueryFactory.create(
"NOT(a:=b OR c:% AND d:<2)"
)
).toString(),
"NOT ( ( a: = \"b\" OR ( c: \"%\" AND d: < \"2\" ) ) )",
"create(create(\"NOT(a:=b OR c:% AND d:<2)\")).toString();"
);
deepEqual(
jIO.QueryFactory.create(jIO.Query.objectToSearchText(jsoned)).toJSON(),
jsoned,
"create( objectToSearchText(create(\"NOT(a:=b OR c:% AND d:<2)\")" +
".toJSON()) ).toJSON()"
);
deepEqual(
jIO.QueryFactory.create("a:(b OR c)").toString(),
"a: ( \"b\" OR \"c\" )",
"create( \"a:(b OR c)\" ).toString()"
);
deepEqual(
jIO.QueryFactory.create("(a:b OR a:c)").toString(),
"a: ( \"b\" OR \"c\" )",
"create( \"(a:b OR a:c)\" ).toString()"
);
deepEqual(
jIO.QueryFactory.create({
"type": "complex",
"query_list": [{
"type": "simple",
"value": "a"
}, {
"type": "simple",
"value": "b"
}]
}).toString(),
"( \"a\" \"b\" )",
"{complex query without operator}.toString()"
);
deepEqual(
jIO.QueryFactory.create({
"type": "simple",
"value": '"a b"'
}).toString(),
' "\\"a b\\""',
"{simple query with value: '\"a b\"'}.toString()"
);
deepEqual(
jIO.Query.parseStringToObject('"\\"a b\\""'),
{
"key": "",
"type": "simple",
"value": '"a b"',
},
"parseStringToObject('\"\\\"a b\\\"\"')"
);
});
test('Docs with space, tab, and newline', function () {
var doc_list = [
{"identifier": "a"},
{"identifier": "a "}
];
stop();
expect(3);
jIO.QueryFactory.create('identifier: "%a%"').exec(
doc_list
).then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "a"},
{"identifier": "a "}
], 'Document with space is matched');
doc_list = [
{"identifier": "a"},
{"identifier": "a \t"}
];
return jIO.QueryFactory.create('identifier: "%a%"').
exec(doc_list);
}).then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "a"},
{"identifier": "a \t"}
], 'Document with tab is matched');
doc_list = [
{"identifier": "a"},
{"identifier": "a\n"},
{"identifier": "\na\nb\nc\n"}
];
return jIO.QueryFactory.create('identifier: "%a%"').
exec(doc_list);
}).then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "a"},
{"identifier": "a\n"},
{"identifier": "\na\nb\nc\n"}
], 'Documents with newlines are matched');
}).always(start);
});
test('Default operator for complex query', function () {
var doc_list = [
{"identifier": "a", "value": "test1", "time": "2016"},
{"identifier": "a", "value": "test", "time": "2016"},
{"identifier": "c", "value": "test1", "time": "2017"}
];
stop();
expect(1);
jIO.QueryFactory.create('identifier:%a% value:"%test1%" time:%2016%')
.exec(doc_list)
.then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "a", "value": "test1", "time": "2016"}],
'Document which matches all the fields is matched');
}).always(start);
});
test('Full text query with single word', function () {
var doc_list = [
{"identifier": "a", "value": "test", "time": "2016"},
{"identifier": "b", "value": "test 1", "time": "2017"},
{"identifier": "c", "value": "test 2016", "time": "2017"}
];
stop();
expect(2);
jIO.QueryFactory.create('test').exec(doc_list).
then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "a", "value": "test", "time": "2016"},
{"identifier": "b", "value": "test 1", "time": "2017"},
{"identifier": "c", "value": "test 2016", "time": "2017"}
], 'Documents which have test in any column are matched');
doc_list = [
{"identifier": "a", "value": "test", "time": "2016"},
{"identifier": "b", "value": "test 1", "time": "2017"},
{"identifier": "c", "value": "test 2016", "time": "2017"}
];
return jIO.QueryFactory.create('2016').exec(doc_list).
then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "a", "value": "test", "time": "2016"},
{"identifier": "c", "value": "test 2016", "time": "2017"}
], 'Documents which have 2016 in any column are matched');
}).always(start);
});
});
test('Full text query with multiple words', function () {
var doc_list = [
{"identifier": "a", "value": "test post", "time": "2016"},
{"identifier": "b", "value": "test post 1", "time": "2017"},
{"identifier": "c", "value": "test post 2016", "time": "2017"}
];
stop();
expect(2);
jIO.QueryFactory.create('test post').exec(doc_list).
then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "a", "value": "test post", "time": "2016"},
{"identifier": "b", "value": "test post 1", "time": "2017"},
{"identifier": "c", "value": "test post 2016", "time": "2017"}
], 'Documents which have test post in any column are matched');
doc_list = [
{"identifier": "a", "value": "test post", "time": "2016"},
{"identifier": "b", "value": "test post 1", "time": "2017"},
{"identifier": "c", "value": "test post 2016", "time": "2017"}
];
return jIO.QueryFactory.create('test post 2016').exec(doc_list).
then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "a", "value": "test post", "time": "2016"},
{"identifier": "c", "value": "test post 2016", "time": "2017"}
], 'Documents which have test post 2016 in any column are matched');
}).always(start);
});
});
// Test queries which have components with key and without it.
// Default operator used if not present is AND.
test('Mixed query', function () {
var doc_list = [
{"identifier": "a", "value": "test1", "time": "2016"},
{"identifier": "b", "value": "test2", "time": "2017"},
{"identifier": "c", "value": "test3", "time": "2017"}
];
stop();
expect(2);
jIO.QueryFactory.create('test2 time:%2017%').exec(doc_list).
then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "b", "value": "test2", "time": "2017"}
], 'Document with test2 in any column and 2017 in time is matched');
doc_list = [
{"identifier": "a", "value": "test post 1", "time": "2016"},
{"identifier": "b", "value": "test post 2", "time": "2017"},
{"identifier": "c", "value": "test post 3", "time": "2018"}
];
return jIO.QueryFactory.create('value:"%test post 2%" OR c OR ' +
'2016').exec(doc_list).
then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "a", "value": "test post 1", "time": "2016"},
{"identifier": "b", "value": "test post 2", "time": "2017"},
{"identifier": "c", "value": "test post 3", "time": "2018"}
], 'Documents with "test post 2" in value or "c" or "2016" ' +
'anywhere are matched');
}).always(start);
});
});
test('Case insensitive queries', function () {
var doc_list = [
{"identifier": "a", "value": "Test Post", "time": "2016"},
{"identifier": "b", "value": "test post", "time": "2017"},
{"identifier": "c", "value": "test3", "time": "2018"}
];
stop();
expect(2);
jIO.QueryFactory.create('test post').exec(doc_list).
then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "a", "value": "Test Post", "time": "2016"},
{"identifier": "b", "value": "test post", "time": "2017"}
], 'Documunts with the value irrespective of case are matched');
doc_list = [
{"identifier": "a", "value": "Test Post", "time": "2016"},
{"identifier": "b", "value": "test post", "time": "2017"},
{"identifier": "c", "value": "test3", "time": "2018"}
];
return jIO.QueryFactory.create('value:"test post"').exec(doc_list).
then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "b", "value": "test post", "time": "2017"}
], 'If value is in quotes, only match if exactly same');
}).always(start);
});
});
test('Query & sort_on option', function () {
var doc_list = [
{
idendifier: 'a',
date: "Fri, 08 Sep 2017 07:46:27 +0000"
},
{
identifier: 'c',
date: "Wed, 06 Sep 2017 00:27:13 +0000"
},
{
identifier: 'b',
date: "Thu, 07 Sep 2017 18:59:23 +0000"
}
];
stop();
expect(2);
jIO.QueryFactory.create("").exec(
doc_list,
{sort_on: [['date', 'descending']]}
).
then(function (list) {
var key_schema =
{
key_set: {
date: {
read_from: 'date',
cast_to: 'dateType'
}
},
cast_lookup: {
dateType: function (str) {
return jiodate.JIODate(new Date(str).toISOString());
}
}
};
deepEqual(list, [
{
identifier: 'c',
date: "Wed, 06 Sep 2017 00:27:13 +0000"
},
{
identifier: 'b',
date: "Thu, 07 Sep 2017 18:59:23 +0000"
},
{
idendifier: 'a',
date: "Fri, 08 Sep 2017 07:46:27 +0000"
}
], 'Document list is sorted');
return jIO.QueryFactory.create("", key_schema).exec(
doc_list,
{sort_on: [['date', 'ascending']]}
);
})
.then(function (list) {
deepEqual(list, [
{
identifier: 'c',
date: "Wed, 06 Sep 2017 00:27:13 +0000"
},
{
identifier: 'b',
date: "Thu, 07 Sep 2017 18:59:23 +0000"
},
{
idendifier: 'a',
date: "Fri, 08 Sep 2017 07:46:27 +0000"
}
], 'Document list is sorted with key_schema');
}).always(start);
});
// Asterisk wildcard is not supported yet.
/* test('Full text query with asterisk', function () {
var doc_list = [
{"identifier": "abc"},
{"identifier": "ab"}
];
stop();
expect(1);
jIO.QueryFactory.create('a*').exec(doc_list).
then(function (doc_list) {
deepEqual(doc_list, [
{"identifier": "abc"},
{"identifier": "ab"}
], 'Documents which satisfy the asterisk wildcard should be returned')
.always(start);
});
});*/
test('Empty sort_on options do not raise', function () {
var doc_list = [
{'a': 1},
{'c': 3},
{'b': 2}
];
stop();
expect(1);
jIO.QueryFactory.create("").exec(
doc_list,
{
sort_on: [],
}
)
.then(function (list) {
deepEqual(list, [
{'a': 1},
{'c': 3},
{'b': 2}
], 'Sorting didn\'t raise');
}).always(start);
});
test('Multiple sort_on options', function () {
var i,
len = 1000,
doc_list = [];
for (i = 0; i < len; i += 1) {
doc_list.push({s: 'b', i: i});
}
stop();
expect(1);
jIO.QueryFactory.create("").exec(
doc_list,
{
sort_on: [['s', 'ascending'], ['i', 'ascending']],
limit: [0, 2]
}
)
.then(function (list) {
deepEqual(list, [
{s: 'b', i: 0},
{s: 'b', i: 1}
], 'Document list is sorted');
}).always(start);
});
test('sort_on options do not raise in case of null value', function () {
var doc_list = [
{'a': null},
{'c': 3},
{'b': 2}
];
stop();
expect(1);
jIO.QueryFactory.create("").exec(
doc_list,
{
sort_on: [['a', 'ascending']],
}
)
.then(function (list) {
deepEqual(list, [
{'c': 3},
{'b': 2},
{'a': null}
], 'Sorting didn\'t raise');
}).always(start);
});
}(jIO, jiodate));
jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/tests-webworker.html 0000664 0000000 0000000 00000000640 14230544473 0025744 0 ustar 00root root 0000000 0000000
jIO in WebWorker Tests
jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/tests.html 0000664 0000000 0000000 00000011132 14230544473 0023735 0 ustar 00root root 0000000 0000000
JIO Qunit/Sinon Unit Tests
test markup, will be hidden
jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/webworker.js 0000664 0000000 0000000 00000001562 14230544473 0024260 0 ustar 00root root 0000000 0000000 /*global QUnit, Worker, console*/
(function (QUnit) {
"use strict";
var worker = new Worker("webworker.tests.js");
//queue = new RSVP.Queue();
worker.onerror = function (event) {
console.log(event);
};
worker.onmessage = function (event) {
var parsed_data = JSON.parse(event.data),
//callbacks = QUnit.config[parsed_data.method],
callbacks = QUnit.config.callbacks[parsed_data.method],
i,
start;
if (parsed_data.method) {
if (parsed_data.method === 'tap') {
start = parsed_data.data.slice(0, 6);
if (start === "not ok") {
console.log(parsed_data.data);
}
} else {
for (i = 0; i < callbacks.length; i += 1) {
callbacks[i](parsed_data.data);
}
if (parsed_data.method === 'done') {
worker.terminate();
}
}
}
};
}(QUnit));
jio-d5ae73d6fd57e02f4f95abc5a3556d2dbea5edc9-test/test/webworker.tests.js 0000664 0000000 0000000 00000003753 14230544473 0025425 0 ustar 00root root 0000000 0000000 /*global self, QUnit, qunitTap, importScripts*/
var global = self,
window = self;
(function (self) {
"use strict";
self.DOMParser = {};
self.DOMError = {};
self.sessionStorage = {};
self.localStorage = {};
self.openDatabase = {};
importScripts(
"../external/rsvp-2.0.4.js",
"../dist/jio-latest.js"
);
self.exports = self;
importScripts("../external/qunit.js");
self.exports = undefined;
//QUnit.config.autorun = false;
//QUnit.config.testTimeout = 5000;
importScripts("../external/sinon.js");
importScripts("../node_modules/qunit-tap/lib/qunit-tap.js");
qunitTap(QUnit, function (data) {
self.postMessage(JSON.stringify({
method: 'tap',
data: data
}));
});
function createCallback(logType) {
QUnit[logType](function (data) {
self.postMessage(JSON.stringify({
method: logType,
data: data
}));
});
}
var i,
logs = [
"begin",
"testStart",
"testDone",
"log",
"moduleStart",
"moduleDone",
"done"
];
for (i = 0; i < logs.length; i += 1) {
createCallback(logs[i]);
}
// queries/key.tests.js needs it
//self.module = QUnit.module;
//self.test = QUnit.test;
//self.stop = QUnit.stop;
//self.start = QUnit.start;
//self.ok = QUnit.ok;
//self.expect = QUnit.expect;
//self.deepEqual = QUnit.deepEqual;
//self.equal = QUnit.equal;
importScripts(
//"jio/util.js",
//"queries/key.tests.js",
//"queries/key-schema.tests.js",
//"queries/tests.js",
//"queries/key-typechecks.tests.js",
//"queries/jiodate.tests.js",
//"queries/key-jiodate.tests.js",
//"jio.storage/querystorage.tests.js",
//"jio.storage/uuidstorage.tests.js",
//"jio.storage/replicatestorage.tests.js",
//"jio.storage/unionstorage.tests.js",
//"jio.storage/shastorage.tests.js",
//"jio.storage/cryptstorage.tests.js",
//"jio.storage/zipstorage.tests.js",
"jio.storage/indexeddbstorage.tests.js"
);
QUnit.load();
}(self));