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 @@ ...@@ -2,6 +2,36 @@
/*global Query: true, inherits: true, query_class_dict: true, _export: true, /*global Query: true, inherits: true, query_class_dict: true, _export: true,
convertStringToRegExp: 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 * The SimpleQuery inherits from Query, and compares one metadata value
* *
...@@ -15,13 +45,8 @@ ...@@ -15,13 +45,8 @@
function SimpleQuery(spec, key_schema) { function SimpleQuery(spec, key_schema) {
Query.call(this); Query.call(this);
// XXX check for correctness of key_schema: checkKeySchema(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)
this._key_schema = key_schema || {}; this._key_schema = key_schema || {};
/** /**
...@@ -55,6 +80,29 @@ function SimpleQuery(spec, key_schema) { ...@@ -55,6 +80,29 @@ function SimpleQuery(spec, key_schema) {
inherits(SimpleQuery, Query); 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" * #crossLink "Query/match:method"
*/ */
...@@ -73,6 +121,7 @@ SimpleQuery.prototype.match = function (item, wildcard_character) { ...@@ -73,6 +121,7 @@ SimpleQuery.prototype.match = function (item, wildcard_character) {
} }
if (typeof key === 'object') { if (typeof key === 'object') {
checkKey(key);
object_value = item[key.readFrom]; object_value = item[key.readFrom];
// defaultMatch overrides the default '=' operator // 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 @@ ...@@ -302,7 +302,7 @@
}; };
test('Test overriding operators', function () { test('Test overriding operators and compound query', function () {
var doc_list, docList = function () { var doc_list, docList = function () {
return [ return [
{'identifier': '10', 'number': '10'}, {'identifier': '10', 'number': '10'},
...@@ -323,7 +323,7 @@ ...@@ -323,7 +323,7 @@
}).exec(doc_list); }).exec(doc_list);
deepEqual(doc_list, [ deepEqual(doc_list, [
{'identifier': '100', 'number': '100'} {'identifier': '100', 'number': '100'}
], 'Key Schema: Numbers are correctly compared (>) after casting'); ], 'Numbers are correctly compared (>) after casting');
doc_list = docList(); doc_list = docList();
complex_queries.QueryFactory.create({ complex_queries.QueryFactory.create({
...@@ -337,7 +337,34 @@ ...@@ -337,7 +337,34 @@
}).exec(doc_list); }).exec(doc_list);
deepEqual(doc_list, [ deepEqual(doc_list, [
{'identifier': '10', 'number': '10'} {'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 @@ ...@@ -22,6 +22,7 @@
<script src="queries/keys.tests.js"></script> <script src="queries/keys.tests.js"></script>
<script src="queries/key-schema.tests.js"></script> <script src="queries/key-schema.tests.js"></script>
<script src="queries/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="../src/jio.storage/localstorage.js"></script>
<script src="queries/localstorage-keys.tests.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