Commit 4cba063d authored by Marco Mariani's avatar Marco Mariani

added some checks over key and key_schema objects

parent 7f4bdc7f
......@@ -2,6 +2,36 @@
/*global Query: true, inherits: true, query_class_dict: true, _export: true,
convertStringToRegExp: true */
var checkKeySchema = function (key_schema) {
var prop;
if (key_schema !== undefined) {
if (typeof key_schema !== 'object') {
throw new TypeError("SimpleQuery().create(): " +
"key_schema is not of type 'object'");
}
// keys is mandatory
if (key_schema.keys === undefined) {
throw new TypeError("SimpleQuery().create(): " +
"key_schema has no 'keys' property");
}
for (prop in key_schema) {
if (key_schema.hasOwnProperty(prop)) {
switch (prop) {
case 'keys':
case 'types':
case 'comparators':
break;
default:
throw new TypeError("SimpleQuery().create(): " +
"key_schema has unknown property '" + prop + "'");
}
}
}
}
};
/**
* The SimpleQuery inherits from Query, and compares one metadata value
*
......@@ -15,13 +45,8 @@
function SimpleQuery(spec, key_schema) {
Query.call(this);
// XXX check for correctness of key_schema:
// XXX 'keys' must exist
// XXX 'types' is optional
// XXX 'comparators' is optional
// XXX anything else is invalid
// XXX each key can have readFrom, castTo, defaultMatch
// (can be checked in the match function)
checkKeySchema(key_schema);
this._key_schema = key_schema || {};
/**
......@@ -55,6 +80,29 @@ function SimpleQuery(spec, key_schema) {
inherits(SimpleQuery, Query);
var checkKey = function (key) {
var prop;
if (key.readFrom === undefined) {
throw new TypeError("Custom key is missing the readFrom property");
}
for (prop in key) {
if (key.hasOwnProperty(prop)) {
switch (prop) {
case 'readFrom':
case 'castTo':
case 'defaultMatch':
break;
default:
throw new TypeError("Custom key has unknown property '" +
prop + "'");
}
}
}
};
/**
* #crossLink "Query/match:method"
*/
......@@ -73,6 +121,7 @@ SimpleQuery.prototype.match = function (item, wildcard_character) {
}
if (typeof key === 'object') {
checkKey(key);
object_value = item[key.readFrom];
// defaultMatch overrides the default '=' operator
......
/*jslint indent: 2, maxlen: 90, nomen: true */
/*global define, exports, require, module, complex_queries, window, test,
raises, ok, equal, deepEqual, sinon */
// define([module_name], [dependencies], module);
(function (dependencies, module) {
"use strict";
if (typeof define === 'function' && define.amd) {
return define(dependencies, module);
}
if (typeof exports === 'object') {
return module(require('complex_queries'));
}
module(complex_queries);
}(['complex_queries', 'qunit'], function (complex_queries) {
"use strict";
module('Checks upon validity of key and key_schema objects');
test('Check the parameters passed to exec() and create()', function () {
try {
complex_queries.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 {
complex_queries.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 {
complex_queries.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 {
complex_queries.QueryFactory.create({type: 'simple'}, '');
ok(false, 'key_schema type is not checked');
} catch (e) {
equal(e.name, 'TypeError', 'wrong exception type');
equal(e.message,
"SimpleQuery().create(): key_schema is not of type 'object'",
'wrong exception message');
}
try {
complex_queries.QueryFactory.create({type: 'simple'}, {});
ok(false, 'key_schema.keys is not checked');
} catch (e) {
equal(e.name, 'TypeError', 'wrong exception type');
equal(e.message,
"SimpleQuery().create(): key_schema has no 'keys' property",
'wrong exception message');
}
try {
complex_queries.QueryFactory.create({type: 'simple'}, {keys: {}, foobar: {}});
ok(false, 'unknown key_schema properties are not checked');
} catch (e) {
equal(e.name, 'TypeError', 'wrong exception type');
equal(e.message,
"SimpleQuery().create(): key_schema has unknown property 'foobar'",
'wrong exception message');
}
});
test('Check the key options', function () {
var doc_list = [
{'identifier': 'a'}
];
try {
complex_queries.QueryFactory.create({
type: 'simple',
key: {},
value: 'a'
}).exec(doc_list);
ok(false, 'key.readFrom is not checked');
} catch (e) {
equal(e.name, 'TypeError', 'wrong exception type');
equal(e.message,
"Custom key is missing the readFrom property",
'wrong exception message');
}
try {
complex_queries.QueryFactory.create({
type: 'simple',
key: {
readFrom: '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');
}
});
}));
......@@ -302,7 +302,7 @@
};
test('Test overriding operators', function () {
test('Test overriding operators and compound query', function () {
var doc_list, docList = function () {
return [
{'identifier': '10', 'number': '10'},
......@@ -323,7 +323,7 @@
}).exec(doc_list);
deepEqual(doc_list, [
{'identifier': '100', 'number': '100'}
], 'Key Schema: Numbers are correctly compared (>) after casting');
], 'Numbers are correctly compared (>) after casting');
doc_list = docList();
complex_queries.QueryFactory.create({
......@@ -337,7 +337,34 @@
}).exec(doc_list);
deepEqual(doc_list, [
{'identifier': '10', 'number': '10'}
], 'Key Schema: Numbers are correctly compared (<) after casting');
], 'Numbers are correctly compared (<) after casting');
doc_list = docList();
complex_queries.QueryFactory.create({
type: 'complex',
operator: 'OR',
query_list: [{
type: 'simple',
key: {
readFrom: 'number',
castTo: intType
},
operator: '<',
value: '19'
}, {
type: 'simple',
key: {
readFrom: 'number',
castTo: intType
},
operator: '>',
value: '19'
}]
}).exec(doc_list);
deepEqual(doc_list, [
{'identifier': '10', 'number': '10'},
{'identifier': '100', 'number': '100'}
], 'Custom keys should also work within compound queries');
});
......
......@@ -22,6 +22,7 @@
<script src="queries/keys.tests.js"></script>
<script src="queries/key-schema.tests.js"></script>
<script src="queries/tests.js"></script>
<script src="queries/key-typechecks.tests.js"></script>
<script src="../src/jio.storage/localstorage.js"></script>
<script src="queries/localstorage-keys.tests.js"></script>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment