[Pkg-javascript-commits] [node-json-localizer] 01/03: Imported Upstream version 0.0.3
Ross Gammon
ross-guest at moszumanska.debian.org
Wed Mar 2 20:28:44 UTC 2016
This is an automated email from the git hooks/post-receive script.
ross-guest pushed a commit to branch master
in repository node-json-localizer.
commit daf97e7b714488ff31f4adf7a8496d6f79ca770c
Author: Ross Gammon <rossgammon at mail.dk>
Date: Wed Mar 2 20:40:36 2016 +0100
Imported Upstream version 0.0.3
---
.eslintrc | 23 +++++
README.md | 44 ++++++++++
index.js | 131 +++++++++++++++++++++++++++++
package.json | 22 +++++
tests/index.js | 261 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 481 insertions(+)
diff --git a/.eslintrc b/.eslintrc
new file mode 100644
index 0000000..780352d
--- /dev/null
+++ b/.eslintrc
@@ -0,0 +1,23 @@
+{
+ "env": {
+ "browser": true,
+ "node": true
+ },
+ "rules": {
+ "quotes": [2, "single"],
+ "no-underscore-dangle": 0,
+ "curly": 0,
+ "consistent-return": 0,
+ "new-cap": 0,
+ "strict": [2, "never"],
+ "indent": [2, 4],
+ "no-shadow": 0,
+ "semi-spacing": 0,
+ "camelcase": 0,
+ "no-labels": 0
+ },
+ "globals": {
+ "L": true,
+ "kosmtik": true
+ }
+}
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..b26849f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,44 @@
+# localize-json
+When you need humans to localize a json object from a
+config file. Typical use case is for a local config file to extend
+an application config on the fly.
+
+## Example
+
+```
+var Localizer = require('localize-json').Localizer;
+var localizer = new Localizer(myobj);
+localizer.where('path.to.prop').if({'prop': 'hasvalue'}.then({'addthis': 'propandvalue'}));
+// `if` is optional
+localizer.where('simpleprop').then('setthisvalue');
+```
+
+## API
+
+### .where(rules)
+
+`rules`: path to an object; eg.: `prop`, `nested.prop`.
+
+Define which object(s) to target.
+
+### .if(rules)
+
+`rules`: object of rules to filter the targeted objects.
+Eg.: `{'thisprop': 'hasthisvalue'}
+
+Can be a single flat value instead of an object, and then the targeted
+key will be checked against this value.
+
+### .then(rules)
+
+`rules`: object of rules to apply on the filtered objects.
+Eg.: `{sethis: 'propandvalue', {anotherprop: 'tobeset'}}`
+
+Can be a single flat value instead of an object, and then the targeted key
+will be replaced by this value.
+
+Can be a function, which then should return either a flat value or an object.
+The function will take the current targeted object as parameter.
+
+
+See [tests](https://github.com/yohanboniface/json-localizer/blob/master/tests/index.js) for more examples.
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..b3c7e92
--- /dev/null
+++ b/index.js
@@ -0,0 +1,131 @@
+// API
+// var localizer = Localizer(source);
+// localizer.where('path.to.prop').then('newvalue');
+// localizer.where('path.to.prop').if({key: value}).then({anotherkey: value, andalso: anothervalue});
+
+
+var L = function (source) {
+ this.source = source;
+ this.target = [];
+ this.leaf = null;
+};
+
+L.prototype.where = function (path) {
+ var paths = path.split('.'),
+ source = this.source,
+ step, leaf = paths.length - 1;
+ for (var i = 0; i <= leaf; i++) {
+ step = source[paths[i]];
+ this.leaf = paths[i];
+ if (typeof step !== 'undefined') {
+ if (i === leaf) {
+ if (L.isObject(step) || L.isObjectsArray(step)) source = step;
+ else continue; // Keep parent as reference.
+ } else if (step instanceof Object) {
+ source = step; // Continue.
+ } else {
+ // We have hit somethings that is not an object,
+ // and we are not at the leaf of the path, that's
+ // and invalid path.
+ source = null;
+ break;
+ }
+ } else return this;
+ }
+ if (source) this.target = Array.isArray(source) ? source : [source];
+ return this;
+};
+
+L.prototype.if = function (rules) {
+ if (!(rules instanceof Object) || Array.isArray(rules)) {
+ var tmp = rules;
+ rules = {};
+ rules[this.leaf] = tmp;
+ }
+ var target = [];
+ main: for (var i = 0; i < this.target.length; i++) {
+ for (var path in rules) {
+ if (!L.hasValue(this.target[i], path, rules[path])) continue main;
+ }
+ target.push(this.target[i]);
+ }
+ this.target = target;
+ return this;
+};
+
+L.prototype.then = function (rules) {
+ var toapply = rules;
+ for (var i = 0; i < this.target.length; i++) {
+ if (typeof rules === 'function') toapply = rules(this.target[i]);
+ if (!(toapply instanceof Object) || Array.isArray(toapply)) {
+ var tmp = toapply;
+ toapply = {};
+ toapply[this.leaf] = tmp;
+ }
+ for (var path in toapply) {
+ L.setValue(this.target[i], path, toapply[path]);
+ }
+ }
+ return this;
+};
+
+L.prototype.fromString = function (rules) {
+ rules = typeof rules === 'string' ? JSON.parse(rules) : rules;
+ if (!Array.isArray(rules)) rules = [rules];
+ for (var i = 0, rule; i < rules.length; i++) {
+ rule = rules[i];
+ if (rule.where) this.where(rule.where);
+ else continue;
+ if (rule.if) this.if(rule.if);
+ if (rule.then) this.then(rule.then);
+ }
+ return this;
+};
+
+/*
+* Turns {"Datasource": {"id": "xxx"}} into {"Datasource.id": "xxx"}
+*/
+L.flaten = function (obj) {
+ var output = {};
+ var flaten = function (els, prefix) {
+ prefix = prefix && prefix + '.' || '';
+ var key, value;
+ for (var el in els) {
+ key = prefix + el;
+ value = els[el];
+ if (value instanceof Object) {
+ flaten(value, key);
+ } else {
+ output[key] = value;
+ }
+ }
+ };
+ flaten(obj);
+ return output;
+};
+
+L.hasValue = function (obj, path, expected) {
+ var flat = L.flaten(obj),
+ current = flat[path];
+ return expected instanceof Array && expected.indexOf(current) !== -1 || current === expected;
+};
+
+L.setValue = function(obj, path, value) {
+ var path_elements = path.split('.'),
+ field = obj;
+ for (var el in path_elements) {
+ if (typeof field === 'undefined') break;
+ if (L.isObject(field[path_elements[el]])) field = field[path_elements[el]];
+ else field[path_elements[el]] = value;
+ }
+};
+
+L.isObject = function (what) {
+ return what && what.constructor === Object;
+};
+
+L.isObjectsArray = function (what) {
+ return Array.isArray(what) && what.every(L.isObject);
+};
+
+exports.Localizer = L;
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..8e26181
--- /dev/null
+++ b/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "json-localizer",
+ "version": "0.0.3",
+ "description": "Utility to localize a json object from another json object or a simple API",
+ "main": "index.js",
+ "directories": {
+ "test": "tests"
+ },
+ "scripts": {
+ "test": "node tests/index.js"
+ },
+ "keywords": [
+ "utils"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/yohanboniface/json-localizer.git"
+ },
+ "homepage": "https://github.com/yohanboniface/json-localizer/",
+ "author": "Yohan Boniface",
+ "license": "WTFPL"
+}
diff --git a/tests/index.js b/tests/index.js
new file mode 100644
index 0000000..544c1e9
--- /dev/null
+++ b/tests/index.js
@@ -0,0 +1,261 @@
+var assert = require('assert'),
+ Localizer = require('../index.js').Localizer;
+
+var Suite = {
+
+ test_simple_replace: function () {
+ var obj = {key: 'value'},
+ l = new Localizer(obj);
+ l.where('key').then('othervalue');
+ assert.equal(obj.key, 'othervalue');
+ },
+
+ test_simple_replace_with_function: function () {
+ var obj = {key: 'value'},
+ l = new Localizer(obj);
+ l.where('key').then(function () {return 'othervalue';});
+ assert.equal(obj.key, 'othervalue');
+ },
+
+ test_replace_undefined_key_does_not_fail: function () {
+ var obj = {key: 'value'},
+ l = new Localizer(obj);
+ l.where('undefined').then('othervalue');
+ assert.equal(obj.key, 'value');
+ },
+
+ test_replace_by_array: function () {
+ var obj = {key: 'value'},
+ l = new Localizer(obj);
+ l.where('key').then([1, 2, 3]);
+ assert.deepEqual(obj.key, [1, 2, 3]);
+ },
+
+ test_replace_by_array_with_function: function () {
+ var obj = {key: 'value'},
+ l = new Localizer(obj);
+ l.where('key').then(function () {return [1, 2, 3];});
+ assert.deepEqual(obj.key, [1, 2, 3]);
+ },
+
+ test_replace_array_by_array: function () {
+ var obj = {key: [3, 2, 1]},
+ l = new Localizer(obj);
+ l.where('key').then([1, 2, 3]);
+ assert.deepEqual(obj.key, [1, 2, 3]);
+ },
+
+ test_replace_nested: function () {
+ var obj = {nested: {key: 'value'}},
+ l = new Localizer(obj);
+ l.where('nested.key').then('othervalue');
+ assert.deepEqual(obj.nested.key, 'othervalue');
+ },
+
+ test_replace_nested_with_function: function () {
+ var obj = {nested: {key: 'value'}},
+ l = new Localizer(obj);
+ l.where('nested.key').then(function (obj) {return 'other' + obj.key;});
+ assert.deepEqual(obj.nested.key, 'othervalue');
+ },
+
+ test_replace_nested_with_object: function () {
+ var obj = {nested: {key: 'value'}},
+ l = new Localizer(obj);
+ l.where('nested.key').then({key: 'value'});
+ assert.deepEqual(obj.nested.key, 'value');
+ },
+
+ test_replace_nested_with_function_returning_object: function () {
+ var obj = {nested: {key: 'value'}},
+ l = new Localizer(obj);
+ l.where('nested.key').then(function (obj) { return {key: 'other' + obj.key};});
+ assert.deepEqual(obj.nested.key, 'othervalue');
+ },
+
+ test_replace_nested_with_multiple_keys: function () {
+ var obj = {nested: {key: 'value', otherkey: 'othervalue'}},
+ l = new Localizer(obj);
+ l.where('nested.key').then({key: 'value2', newkey: 'newvalue'});
+ assert.deepEqual(obj.nested.key, 'value2');
+ assert.deepEqual(obj.nested.newkey, 'newvalue');
+ assert.deepEqual(obj.nested.otherkey, 'othervalue');
+ },
+
+ test_replace_nested_with_function_and_multiple_keys: function () {
+ var obj = {nested: {key: 'value', otherkey: 'othervalue'}},
+ l = new Localizer(obj);
+ l.where('nested.key').then(function (obj) {return {key: obj.key + '2', newkey: 'new' + obj.key};});
+ assert.deepEqual(obj.nested.key, 'value2');
+ assert.deepEqual(obj.nested.newkey, 'newvalue');
+ assert.deepEqual(obj.nested.otherkey, 'othervalue');
+ },
+
+ test_replace_with_nested_path: function () {
+ var obj = {nested: {key: 'value'}},
+ l = new Localizer(obj);
+ l.where('nested').then({'nested.key': 'value2'});
+ assert.equal(obj.nested.key, 'value2');
+ },
+
+ test_replace_with_nested_path_and_function: function () {
+ var obj = {nested: {key: 'value'}},
+ l = new Localizer(obj);
+ l.where('nested').then(function (obj) {return {'nested.key': obj.key + '2'};});
+ assert.equal(obj.nested.key, 'value2');
+ },
+
+ test_if_with_array_and_function: function () {
+ var obj = {root: {nested: [{key: 'value'}, {key: 'othervalue'}]}},
+ l = new Localizer(obj);
+ l.where('root.nested').then(function (obj) {return {key: obj.key + '2'}; });
+ assert.equal(obj.root.nested[0].key, 'value2');
+ assert.equal(obj.root.nested[1].key, 'othervalue2');
+ },
+
+ test_simple_if: function () {
+ var obj = {key: 'value'},
+ l = new Localizer(obj);
+ l.where('key').if('value').then('othervalue');
+ assert.equal(obj.key, 'othervalue');
+ },
+
+ test_wrong_if: function () {
+ var obj = {key: 'value'},
+ l = new Localizer(obj);
+ l.where('key').if('wrongvalue').then('othervalue');
+ assert.equal(obj.key, 'value');
+ },
+
+ test_wrong_if_with_object: function () {
+ var obj = {key: 'value'},
+ l = new Localizer(obj);
+ l.where('key').if({key: 'value', otherkey: 'wrongvalue'}).then('othervalue');
+ assert.equal(obj.key, 'value');
+ },
+
+ test_if_nested: function () {
+ var obj = {root: {nested: {key: 'value'}}},
+ l = new Localizer(obj);
+ l.where('root.nested').if({key: 'value'}).then({key: 'othervalue'});
+ assert.equal(obj.root.nested.key, 'othervalue');
+ },
+
+ test_if_with_array: function () {
+ var obj = {root: {nested: [{key: 'value'}, {key: 'donotmatch'}]}},
+ l = new Localizer(obj);
+ l.where('root.nested').if({key: 'value'}).then({key: 'othervalue'});
+ assert.equal(obj.root.nested[0].key, 'othervalue');
+ assert.equal(obj.root.nested[1].key, 'donotmatch');
+ },
+
+ xtest_if_with_array_of_values: function () {
+ var obj = {root: {nested: [{key: ['value', 'value2']}, {key: 'donotmatch'}]}},
+ l = new Localizer(obj);
+ l.where('root.nested').if({key: 'value'}).then({key: 'othervalue'});
+ assert.equal(obj.root.nested[0].key, 'othervalue');
+ assert.equal(obj.root.nested[1].key, 'donotmatch');
+ },
+
+ test_real_life: function () {
+ var actual = {
+ 'bounds': [1.2219, 43.0923, 1.3057, 43.1517],
+ 'center': [1.256, 43.1249, 16],
+ 'minzoom': 6,
+ 'maxzoom': 20,
+ 'Stylesheet': [
+ 'style.mss'
+ ],
+ 'Layer': [
+ {
+ 'id': 'countries',
+ 'Datasource': {
+ 'file': 'afile.zip',
+ 'type': 'shape'
+ }
+ },
+ {
+ 'geometry': 'polygon',
+ 'id': 'polys',
+ 'Datasource': {
+ 'dbname': 'othertable',
+ 'geometry_field': 'way',
+ 'host': 'localhost',
+ 'password': 'otherpassword',
+ 'port': '5432',
+ 'srs': '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over',
+ 'table': 'ansqlrequest',
+ 'type': 'postgis',
+ 'extent': '-20037508,-19929239,20037508,19929239',
+ 'user': 'otheruser'
+ }
+ }
+ ]
+ };
+ var expected = {
+ 'bounds': [1, 2, 3, 4],
+ 'center': [1, 2, 3],
+ 'minzoom': 6,
+ 'maxzoom': 20,
+ 'Stylesheet': [
+ 'style.mss'
+ ],
+ 'Layer': [
+ {
+ 'id': 'countries',
+ 'Datasource': {
+ 'file': 'localized.shp',
+ 'type': 'shape'
+ }
+ },
+ {
+ 'geometry': 'polygon',
+ 'id': 'polys',
+ 'Datasource': {
+ 'dbname': 'localizedtable',
+ 'geometry_field': 'way',
+ 'host': '',
+ 'password': '',
+ 'port': '5432',
+ 'srs': '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over',
+ 'table': 'ansqlrequest',
+ 'type': 'postgis',
+ 'extent': '-20037508,-19929239,20037508,19929239',
+ 'user': 'localizeduser'
+ }
+ }
+ ]
+ };
+ var l = new Localizer(actual);
+ l.where('bounds').then([1, 2, 3, 4]);
+ l.where('center').then([1, 2, 3]);
+ l.where('Layer').if({id: 'countries'}).then({'Datasource.file': 'localized.shp'});
+ l.where('Layer').if({'Datasource.type': 'postgis'}).then({
+ 'Datasource.dbname': 'localizedtable',
+ 'Datasource.host': '',
+ 'Datasource.password': '',
+ 'Datasource.user': 'localizeduser'
+ });
+ assert.deepEqual(actual, expected);
+ },
+
+ test_from_string: function () {
+ var obj = {root: {nested: {key: 'value'}}},
+ rules = '[{"where": "root.nested", "if": {"key": "value"}, "then": {"key": "othervalue"}}]';
+ new Localizer(obj).fromString(rules);
+ assert.equal(obj.root.nested.key, 'othervalue');
+ }
+};
+
+Object.keys(Suite).forEach(function (key) {
+ if (process.argv.length === 3 && key !== process.argv[2]) return console.log('.', key, 'SKIP');
+ if (key.indexOf('test_') !== 0) return console.log('.', key, 'SKIP');
+ try {
+ Suite[key]();
+ console.log('✓', key, 'PASSED');
+ }
+ catch (err) {
+ console.log('✗', key, 'FAIL');
+ console.log(err);
+ }
+});
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-json-localizer.git
More information about the Pkg-javascript-commits
mailing list