From 9ecb2291ff6f53f1fa1546d8a8b271a8a0216854 Mon Sep 17 00:00:00 2001 From: Pavlo Zhukov Date: Thu, 30 Aug 2018 01:15:51 +0300 Subject: [PATCH 1/8] Add .idea folder to .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index ad46b30..b55295f 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,6 @@ typings/ # next.js build output .next + +# JetBrains IDE's project config folder +.idea From 81f1a15b004f46b04aa27a8eea789a92545d7366 Mon Sep 17 00:00:00 2001 From: Pavlo Zhukov Date: Thu, 30 Aug 2018 01:17:18 +0300 Subject: [PATCH 2/8] Init npm package --- package-lock.json | 5 +++++ package.json | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 package-lock.json create mode 100644 package.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..09e16c8 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,5 @@ +{ + "name": "database-js-common", + "version": "1.0.0", + "lockfileVersion": 1 +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..10df14e --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "database-js-common", + "version": "1.0.0", + "description": "database-js common code", + "main": "index.js", + "repository": { + "type": "git", + "url": "git+https://github.com/mlaanderson/database-js-common.git" + }, + "keywords": [ + "database-js" + ], + "author": "Michael Anderson ", + "license": "MIT", + "bugs": { + "url": "https://github.com/mlaanderson/database-js-common/issues" + }, + "homepage": "https://github.com/mlaanderson/database-js-common#readme", + "devDependencies": {} +} From 0c9cc6bb42c5604f333fed3fa63453c37da407d3 Mon Sep 17 00:00:00 2001 From: Pavlo Zhukov Date: Thu, 30 Aug 2018 01:18:05 +0300 Subject: [PATCH 3/8] Implement parsing algorithm --- index.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 index.js diff --git a/index.js b/index.js new file mode 100644 index 0000000..264c5ab --- /dev/null +++ b/index.js @@ -0,0 +1,24 @@ +function parseConnectionParams(paramstring, parseValues = false) { + if (parseValues) { + const params = {}; + const numberRegex = /^[-+]?(\d+\.)?\d+(E[-+]?\d+)?$/i; + + paramstring.split('&').map(s => { + let [key, val] = s.split('='); + const lowerCasedValue = val.toLowerCase(); + if (lowerCasedValue === 'true') val = true; + else if (lowerCasedValue === 'false') val = false; + else if (numberRegex.test(val)) val = parseFloat(val); + + params[key] = val; + }); + + return params; + } else { + return paramstring; + } +} + +module.exports = { + parseConnectionParams +}; From 9f88895e4fcfc9320cb4c3b47fc1b8138547a717 Mon Sep 17 00:00:00 2001 From: Pavlo Zhukov Date: Thu, 30 Aug 2018 01:18:41 +0300 Subject: [PATCH 4/8] Add mocha tests to parseConnectionParams --- package-lock.json | 193 ++++++++++++++++++++++++++++++++++++++++++++- package.json | 7 +- spec/index.spec.js | 39 +++++++++ 3 files changed, 237 insertions(+), 2 deletions(-) create mode 100644 spec/index.spec.js diff --git a/package-lock.json b/package-lock.json index 09e16c8..27573a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,196 @@ { "name": "database-js-common", "version": "1.0.0", - "lockfileVersion": 1 + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.11" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } } diff --git a/package.json b/package.json index 10df14e..840d450 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,9 @@ "version": "1.0.0", "description": "database-js common code", "main": "index.js", + "scripts": { + "test": "./node_modules/.bin/mocha --reporter spec" + }, "repository": { "type": "git", "url": "git+https://github.com/mlaanderson/database-js-common.git" @@ -16,5 +19,7 @@ "url": "https://github.com/mlaanderson/database-js-common/issues" }, "homepage": "https://github.com/mlaanderson/database-js-common#readme", - "devDependencies": {} + "devDependencies": { + "mocha": "^5.2.0" + } } diff --git a/spec/index.spec.js b/spec/index.spec.js new file mode 100644 index 0000000..b26bd31 --- /dev/null +++ b/spec/index.spec.js @@ -0,0 +1,39 @@ +const assert = require('assert'); + +describe('Test parseConnectionParams method', function () { + const parseConnectionParams = require('../.').parseConnectionParams; + const testedParamString = 'booleanTrue=true&booleanFalse=false&string=foo&integer=35&float=35.8'; + + it('should be not processed by default', function () { + const result = parseConnectionParams(testedParamString); + assert.equal(result, testedParamString) + }); + + describe('Test parsed values', function () { + const result = parseConnectionParams(testedParamString, true); + + it('should be parsed', function () { + assert.ok(typeof result === 'object', 'result not parsed'); + }); + + it('should be boolean true', function () { + assert.ok(result.booleanTrue === true, 'boolean true not parsed') + }); + + it('should be boolean false', function () { + assert.ok(result.booleanFalse === false, 'boolean false not parsed') + }); + + it('should be string', function () { + assert.ok(typeof result.string === 'string', 'string not parsed') + }); + + it('should be integer', function () { + assert.ok(result.integer % 1 === 0, 'integer not parsed') + }); + + it('should be float', function () { + assert.ok(result.float % 1 !== 0, 'float not parsed') + }); + }) +}); From b9fc7df4541578bcd6d9145f2cc0a11b8116e270 Mon Sep 17 00:00:00 2001 From: Pavlo Zhukov Date: Thu, 30 Aug 2018 01:45:14 +0300 Subject: [PATCH 5/8] Fix not run test by npm command --- spec/index.spec.js => test/index.test.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename spec/index.spec.js => test/index.test.js (100%) diff --git a/spec/index.spec.js b/test/index.test.js similarity index 100% rename from spec/index.spec.js rename to test/index.test.js From c45898c911e7f8d70499db1b289a507b342a3803 Mon Sep 17 00:00:00 2001 From: Pavlo Zhukov Date: Thu, 30 Aug 2018 01:45:57 +0300 Subject: [PATCH 6/8] Fix error on trying to parse empty string. Return empty object instead --- index.js | 18 ++++++++++-------- test/index.test.js | 5 +++++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index 264c5ab..7da1931 100644 --- a/index.js +++ b/index.js @@ -3,15 +3,17 @@ function parseConnectionParams(paramstring, parseValues = false) { const params = {}; const numberRegex = /^[-+]?(\d+\.)?\d+(E[-+]?\d+)?$/i; - paramstring.split('&').map(s => { - let [key, val] = s.split('='); - const lowerCasedValue = val.toLowerCase(); - if (lowerCasedValue === 'true') val = true; - else if (lowerCasedValue === 'false') val = false; - else if (numberRegex.test(val)) val = parseFloat(val); + if (paramstring) { + paramstring.split('&').map(s => { + let [key, val] = s.split('='); + const lowerCasedValue = val.toLowerCase(); + if (lowerCasedValue === 'true') val = true; + else if (lowerCasedValue === 'false') val = false; + else if (numberRegex.test(val)) val = parseFloat(val); - params[key] = val; - }); + params[key] = val; + }); + } return params; } else { diff --git a/test/index.test.js b/test/index.test.js index b26bd31..47c94c8 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -9,6 +9,11 @@ describe('Test parseConnectionParams method', function () { assert.equal(result, testedParamString) }); + it('should return empty object', function () { + const result = parseConnectionParams('', true); + assert.deepEqual(result, {}) + }); + describe('Test parsed values', function () { const result = parseConnectionParams(testedParamString, true); From db3f163dcb1ba62f53a569914d0b2ba1da589710 Mon Sep 17 00:00:00 2001 From: Pavlo Zhukov Date: Sun, 2 Sep 2018 23:25:25 +0300 Subject: [PATCH 7/8] Return object with not parsed config values on parseValues = false #2. Improve tests --- index.js | 35 ++++++++++++++++++----------------- test/index.test.js | 35 ++++++++++++++++++++++++++++------- 2 files changed, 46 insertions(+), 24 deletions(-) diff --git a/index.js b/index.js index 7da1931..c59b855 100644 --- a/index.js +++ b/index.js @@ -1,24 +1,25 @@ function parseConnectionParams(paramstring, parseValues = false) { - if (parseValues) { - const params = {}; - const numberRegex = /^[-+]?(\d+\.)?\d+(E[-+]?\d+)?$/i; + const params = {}; + const numberRegex = /^[-+]?(\d+\.)?\d+(E[-+]?\d+)?$/i; - if (paramstring) { - paramstring.split('&').map(s => { - let [key, val] = s.split('='); - const lowerCasedValue = val.toLowerCase(); - if (lowerCasedValue === 'true') val = true; - else if (lowerCasedValue === 'false') val = false; - else if (numberRegex.test(val)) val = parseFloat(val); + if (paramstring) { + const valuesPreprocessor = parseValues ? + (value) => { + const lowerCasedValue = value.toLowerCase(); + if (lowerCasedValue === 'true') value = true; + else if (lowerCasedValue === 'false') value = false; + else if (numberRegex.test(value)) value = parseFloat(value); + return value; + } : + (value) => value; - params[key] = val; - }); - } - - return params; - } else { - return paramstring; + paramstring.split('&').map(s => { + let [key, val] = s.split('='); + params[key] = valuesPreprocessor(val); + }); } + + return params; } module.exports = { diff --git a/test/index.test.js b/test/index.test.js index 47c94c8..1d3c898 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -4,9 +4,30 @@ describe('Test parseConnectionParams method', function () { const parseConnectionParams = require('../.').parseConnectionParams; const testedParamString = 'booleanTrue=true&booleanFalse=false&string=foo&integer=35&float=35.8'; - it('should be not processed by default', function () { + describe('Test default not parsed values', function () { const result = parseConnectionParams(testedParamString); - assert.equal(result, testedParamString) + + it('should be string true', function () { + assert.equal(result.booleanTrue, 'true') + }); + + it('should be string false', function () { + assert.equal(result.booleanFalse, 'false') + }); + + + it('should be string', function () { + assert.equal(result.string, 'foo') + }); + + + it('should be string number', function () { + assert.equal(result.integer, '35') + }); + + it('should be string float', function () { + assert.equal(result.float, '35.8') + }); }); it('should return empty object', function () { @@ -22,23 +43,23 @@ describe('Test parseConnectionParams method', function () { }); it('should be boolean true', function () { - assert.ok(result.booleanTrue === true, 'boolean true not parsed') + assert.equal(result.booleanTrue, true) }); it('should be boolean false', function () { - assert.ok(result.booleanFalse === false, 'boolean false not parsed') + assert.equal(result.booleanFalse, false) }); it('should be string', function () { - assert.ok(typeof result.string === 'string', 'string not parsed') + assert.equal(result.string, 'foo') }); it('should be integer', function () { - assert.ok(result.integer % 1 === 0, 'integer not parsed') + assert.equal(result.integer, 35) }); it('should be float', function () { - assert.ok(result.float % 1 !== 0, 'float not parsed') + assert.equal(result.float, 35.8) }); }) }); From 782b720b7ca0d21bef64061eb86f719c533e4f82 Mon Sep 17 00:00:00 2001 From: Andrew Barnett Date: Tue, 23 Oct 2018 13:46:05 -0400 Subject: [PATCH 8/8] feat(multilevel-config): support multilevel config Adds support for multilevel objects and arrays to the query string parsing. For example, the string `ssl[ca]=ca.pem&ssl[key]=key.pem&ssl[cert]=cert.pem` would parse to: ``` { ssl: { ca: 'ca.pem', key: 'key.pem', cert: 'cert.pem' } } ``` --- README.md | 7 +++ index.js | 21 ++++++++- package.json | 2 +- test/index.test.js | 109 ++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 136 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 185ab8a..b4e0b84 100644 --- a/README.md +++ b/README.md @@ -32,3 +32,10 @@ Parses a parameter string of the format key1=value1&key2=value2, optionally conv If the value types are to be converted, true and false are converted to booleans irrespective of case. Values are converted to numbers if they match the following regex ```/^[-+]?(\d+\.)?\d+(E[-+]?\d+)?$/i```. If you need finer control of value conversions, leave parseValues at false and handle the conversions in your driver code. + +If the driver supports multiple levels to the config object (like the MySQL driver), you can modify the `key` as follows: +- `key1=value1&key2[subkey1]=value2` yields `{ key1: "value1", key2: { subkey1: "value2" } }` +- `key1=value1&key2[subkey1][subsubkey1]=value2` yields `{ key1: "value1", key2: { subkey1: { subkey2: "value2" } } }` +- `key1=value1&key2[]=value2` yields `{ key1: "value1", key2: [ "value2" ] }` +- `key1=value1&key2[]=value2&key2[]=value3` yields `{ key1: "value1", key2: [ "value2", "value3" ] }` +- `key1=value1&key2[0]=value2` yields `{ key1: "value1", key2: [ "value2" ] }` diff --git a/index.js b/index.js index c59b855..67577b2 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,6 @@ +var keyBreaker = /([^\[\]]+)|(\[\])/g, + digitTest = /^\d+$/; + function parseConnectionParams(paramstring, parseValues = false) { const params = {}; const numberRegex = /^[-+]?(\d+\.)?\d+(E[-+]?\d+)?$/i; @@ -13,9 +16,25 @@ function parseConnectionParams(paramstring, parseValues = false) { } : (value) => value; + // based on $.String.deparam: https://github.com/jupiterjs/jquerymx/blob/master/lang/string/deparam/deparam.js paramstring.split('&').map(s => { let [key, val] = s.split('='); - params[key] = valuesPreprocessor(val); + let current = params; + let parts = key.match(keyBreaker); + for(var i = 0; i < parts.length - 1; i++) { + let part = parts[i]; + if(!current[part]) { + // if what we are pointing to looks like an array + current[part] = digitTest.test(parts[i+1]) || parts[i+1] == "[]" ? [] : {} + } + current = current[part]; + } + let lastPart = parts[parts.length - 1]; + if(lastPart == "[]"){ + current.push(valuesPreprocessor(val)); + } else { + current[lastPart] = valuesPreprocessor(val); + } }); } diff --git a/package.json b/package.json index 840d450..6246c7c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "database-js-common", - "version": "1.0.0", + "version": "1.0.1", "description": "database-js common code", "main": "index.js", "scripts": { diff --git a/test/index.test.js b/test/index.test.js index 1d3c898..b50e706 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -3,6 +3,8 @@ const assert = require('assert'); describe('Test parseConnectionParams method', function () { const parseConnectionParams = require('../.').parseConnectionParams; const testedParamString = 'booleanTrue=true&booleanFalse=false&string=foo&integer=35&float=35.8'; + const testedSingleNestedObjectString = 'subkey[string]=foo&subkey[booleanTrue]=true&subkey[booleanFalse]=false&subkey[integer]=42&subkey[float]=98.6&array[0]=0&array[1]=98.6&array2[]=0&array2[]=98.6'; + const testedMultiNestedObjectString = 'subkey[subkey][string]=foo&subkey[subkey][booleanTrue]=true&subkey[subkey][booleanFalse]=false&subkey[subkey][integer]=42&subkey[subkey][float]=98.6&subkey[subkey][array][]=0&subkey[subkey][array][]=98.6&array[0][0]=0&array[0][1]=98.6&array[1][]=0&array[1][]=98.6'; describe('Test default not parsed values', function () { const result = parseConnectionParams(testedParamString); @@ -61,5 +63,110 @@ describe('Test parseConnectionParams method', function () { it('should be float', function () { assert.equal(result.float, 35.8) }); - }) + }); + + describe('Test parsing single-level nested objects', function () { + const result = parseConnectionParams(testedSingleNestedObjectString, true); + + it('should be parsed', function () { + assert.ok(typeof result === 'object', 'result not parsed'); + }); + + it('should have object subkey', function () { + assert.ok(typeof result.subkey === 'object', 'result subkey is not an object'); + }); + + it('subkey should be boolean true', function () { + assert.equal(result.subkey.booleanTrue, true); + }); + + it('subkey should be boolean false', function () { + assert.equal(result.subkey.booleanFalse, false); + }); + + it('subkey should be string', function () { + assert.equal(result.subkey.string, 'foo'); + }); + + it('subkey should be integer', function () { + assert.equal(result.subkey.integer, 42); + }); + + it('subkey should be float', function () { + assert.equal(result.subkey.float, 98.6); + }); + + it('should have array subkey', function () { + assert.ok(result.array.constructor === Array, 'result array is not an array'); + }); + + it('array length should be 2', function () { + assert.equal(result.array.length, 2); + }); + + it('array item should be integer', function () { + assert.equal(result.array[0], 0); + }); + + it('array item should be float', function () { + assert.equal(result.array[1], 98.6); + }); + + it('should have array2 subkey', function () { + assert.ok(result.array2.constructor === Array, 'result array2 is not an array'); + }); + + it('array2 length should be 2', function () { + assert.equal(result.array2.length, 2); + }); + + it('array2 item should be integer', function () { + assert.equal(result.array2[0], 0); + }); + + it('array2 item should be float', function () { + assert.equal(result.array2[1], 98.6); + }); + }); + + describe('Test parsing multi-level nested objects', function () { + const result = parseConnectionParams(testedMultiNestedObjectString, true); + + it('should be parsed', function () { + assert.ok(typeof result === 'object', 'result not parsed'); + }); + + it('should have object subkey', function () { + assert.ok(typeof result.subkey === 'object', 'result subkey is not an object'); + }); + + it('should have object subkey object subkey', function () { + assert.ok(typeof result.subkey.subkey === 'object', 'result subkey subkey is not an object'); + }); + + it('subkey should be boolean true', function () { + assert.equal(result.subkey.subkey.booleanTrue, true); + }); + + it('subkey should be boolean false', function () { + assert.equal(result.subkey.subkey.booleanFalse, false); + }); + + it('subkey should be string', function () { + assert.equal(result.subkey.subkey.string, 'foo'); + }); + + it('subkey should be integer', function () { + assert.equal(result.subkey.subkey.integer, 42); + }); + + it('subkey should be float', function () { + assert.equal(result.subkey.subkey.float, 98.6); + }); + + it('subkey should be array', function () { + assert.ok(result.subkey.subkey.array.constructor === Array, 'result subkey array is not an array'); + }); + }); + });