Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

From 618816f, implement interpolation of %([BLOCK.]KEY) #2

Closed
wants to merge 1 commit into from

2 participants

@pivaldi

On my branch "optimized"…
I've reverted to commit 618816f because the commit bcb7c67 disallows an optimized implementation of interpolation of %(block.key), see comment on the commit bcb7c67.
I've implemented the extension of %(block.key) like the Python ConfigParser does but %(REF) can refer to an other block and can be recursive.

@Ajnasz
Owner

Check out my interpolation branch 9c7e9b6

How differs the getParam from yours:
First I'm working with the params like when the inheritDefault is false. Then if it's true and the values has the DEFAULT section, I update the values. The updating is moved out into a separate method, so it's easier to read to me.

@pivaldi

It looks perfect !

@pivaldi

In fact, in your branch interpolation, parser.interpolate() does not extend the %(*)

@Ajnasz
Owner

I copied your interpolate method or maybe I missed something?

@pivaldi

Hi,
I think that all is right with the commit 808b247 in my branch "interpolation".

@Ajnasz
Owner

That looks good.
I thought of something. It would look better if we would use the Object.keys to walk through on the object keys instead of for .. in. Then we wouldn't need to use hasOwnProperty all the time, it would look better.

@pivaldi

I'm not sure that was useful because the objects treated haven't prototype but it's done :)

@Ajnasz
Owner

Yeash, but I'm using jslint and it always mark it as a warning. :)
Thanks

@Ajnasz
Owner

merged

@Ajnasz Ajnasz closed this
@Ajnasz
Owner

I also published to npm.

Can I ask one more thing? Could you describe this method in the readme file please?

@pivaldi

Done in the branch "master"

@Ajnasz
Owner

Thank you very much

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 24, 2011
  1. From 618816f, implement interpolation of %([BLOCK.]KEY)

    Philippe Ivaldi authored
This page is out of date. Refresh to see the latest.
View
58 index.js
@@ -83,6 +83,22 @@ var inheritDefault = function(block, _default, key) {
return out;
};
+/**
+ * return a deep copy of the object o
+ */
+var deepCopy = function(o, c) {
+ var out = c || {};
+ for (var key in o) {
+ if (typeof o[key] === 'object') {
+ out[key] = (o[key].constructor === Array ? [] : {});
+ deepCopy(o[key], out[key]);
+ } else {
+ out[key] = o[key];
+ }
+ };
+ return out;
+};
+
/**
* Parses a .ini file and convert's it's content to a JS object
@@ -328,6 +344,48 @@ IniReader.prototype.param = function (prop, value) {
}
};
+IniReader.prototype.interpolate = function(param) {
+ var output = this.getParam(param),
+ block, key, refParams, refParam, references;
+ var self = this;
+
+ if (typeof output === 'object') {
+ output = deepCopy(output);
+ }
+
+ if (param) {
+ param = param.split('.');
+ block = param[0];
+ key = param[1];
+ }
+
+ if (typeof key == 'undefined' || !param) {
+ for (block in output) {
+ for (key in output[block]) {
+ output[block][key] = this.interpolate(block + '.' + key);
+ }
+ }
+ } else {
+ if (typeof output === 'string') {
+ references = output.match(/%\(.*?\)/g);
+ references && references.forEach(
+ function(reference) {
+ var refKey = reference.replace(/%\((.*?)\)/, '$1');
+ refParams = refKey.split('.');
+ if (refParams.length < 2) { // interpolation in current block
+ refParam = block + '.' + refParams[0];
+ } else {
+ refParam = refKey;
+ }
+ output = output.replace(reference, self.interpolate(refParam));
+ }
+ );
+ }
+ }
+
+ return output;
+};
+
IniReader.prototype.getLe = function (le) {
return typeof le === 'string' && (le === '\n' || le === '\r\n' || le === '\r') ? le : '\n';
};
View
6 tests/ize-dos.ini
@@ -8,6 +8,9 @@ lorem = ipsum
ipus = foo bar baz
dolor=sit
amet=
+interpolate=%(dolor)tercity
+interpolate_default="%(test_default) / interpolation"
+interpolate_block="%(bar.test_default) / block interpolation"
[bar]
asdfas=fooobar
@@ -15,4 +18,5 @@ asdfas=fooobar
2=" lorem ipsum"
3='lorem ipsum'
4='lorem ipsum '
-test_default='I come from bar'
+test_default='I come from bar'
+interpolate_block_recursive='%(foo.interpolate_block) / recursive'
View
2  tests/ize-mac.ini
@@ -1 +1 @@
-
+
View
6 tests/ize-unix.ini
@@ -8,6 +8,9 @@ lorem = ipsum
ipus = foo bar baz
dolor=sit
amet=
+interpolate=%(dolor)tercity
+interpolate_default='%(test_default) / interpolation'
+interpolate_block="%(bar.test_default) / block interpolation"
[bar]
asdfas=fooobar
@@ -15,4 +18,5 @@ asdfas=fooobar
2=" lorem ipsum"
3='lorem ipsum'
4='lorem ipsum '
-test_default='I come from bar'
+test_default='I come from bar'
+interpolate_block_recursive='%(foo.interpolate_block) / recursive'
View
3  tests/makefile
@@ -1,2 +1,3 @@
all:
- node ./test.js
+ node ./test.js
+ node ./test-old.js
View
114 tests/test.js
@@ -27,58 +27,76 @@
};
test = function (obj) {
- assert.equal(typeof(obj.param()), 'object',
- 'empty key doesn\'t returned object');
- assert.equal(typeof(obj.param('doesntexists')), 'undefined',
- 'nonexisting key doesn\'t returned undefined');
- assert.equal(typeof(obj.param('foo')), 'object', 'existing key doesn\'t returned an object');
- assert.equal(typeof(obj.param('bar')), 'object', 'existing key doesn\'t returned an object');
-
- assert.deepEqual(obj.param('foo.lorem'),
- 'ipsum', 'lorem\'s key value in foo conf is not ipsum');
- assert.deepEqual(obj.param().foo.lorem,
- 'ipsum', 'lorem\'s key value in foo conf is not ipsum');
- assert.deepEqual(obj.param('foo.amet'), '', 'amet\'s value should be an empty string');
- assert.equal(typeof(obj.param('foo.doesntexists')),
- 'undefined', 'value which should not exist returned something else then undefined');
-
-
- // Test of section "DEFAULT" {--
- assert.deepEqual(obj.param('DEFAULT.test_default'), 'I come from the default section',
- 'test_default\'s key value in DEFAULT is wrong'
+ ['param', 'interpolate'].forEach(function(fnGet) {
+ assert.equal(typeof(obj[fnGet]()), 'object',
+ 'empty key doesn\'t returned object');
+ assert.equal(typeof(obj[fnGet]('doesntexists')), 'undefined',
+ 'nonexisting key doesn\'t returned undefined');
+ assert.equal(typeof(obj[fnGet]('foo')), 'object', 'existing key doesn\'t returned an object');
+ assert.equal(typeof(obj[fnGet]('bar')), 'object', 'existing key doesn\'t returned an object');
+
+ assert.deepEqual(obj[fnGet]('foo.lorem'),
+ 'ipsum', 'lorem\'s key value in foo conf is not ipsum');
+ assert.deepEqual(obj[fnGet]().foo.lorem,
+ 'ipsum', 'lorem\'s key value in foo conf is not ipsum');
+ assert.deepEqual(obj[fnGet]('foo.amet'), '', 'amet\'s value should be an empty string');
+ assert.equal(typeof(obj[fnGet]('foo.doesntexists')),
+ 'undefined', 'value which should not exist returned something else then undefined');
+
+
+ // Test of section "DEFAULT" {--
+ assert.deepEqual(obj[fnGet]('DEFAULT.test_default'), 'I come from the default section',
+ 'test_default\'s key value in DEFAULT is wrong'
+ );
+
+ if (obj.inheritDefault) {
+ assert.deepEqual(obj[fnGet]('foo.test_default'), 'I come from the default section',
+ 'test_default\'s key value in foo is not inherited from DEFAULT section'
+ );
+ assert.deepEqual(obj[fnGet]().foo.test_default, 'I come from the default section',
+ 'test_default\'s key value in foo is not inherited from DEFAULT section'
+ );
+ [obj[fnGet]().foo.test_default, obj[fnGet]('foo.test_default')].forEach(
+ function(_) {
+ assert.deepEqual(_, 'I come from the default section', ''
+ + 'test_default\'s key value in foo is'
+ + ' not inherited from DEFAULT section'
+ );}
+ );
+ [obj[fnGet]().bar.test_default, obj[fnGet]('bar.test_default')].forEach(
+ function(_) {assert.deepEqual(_, 'I come from bar',
+ 'test_default\'s key value in bar is not overwrited');}
+ );
+ } else {
+ assert.equal(typeof(obj[fnGet]('foo.test_default')), 'undefined',
+ 'value which should not exist returned something else then undefined'
);
+ }
+ // --}
- if (obj.inheritDefault) {
- assert.deepEqual(obj.param('foo.test_default'), 'I come from the default section',
- 'test_default\'s key value in foo is not inherited from DEFAULT section'
- );
- assert.deepEqual(obj.param().foo.test_default, 'I come from the default section',
- 'test_default\'s key value in foo is not inherited from DEFAULT section'
- );
- [obj.param().foo.test_default, obj.param('foo.test_default')].forEach(
- function(_) {
- assert.deepEqual(_, 'I come from the default section', ''
- + 'test_default\'s key value in foo is'
- + ' not inherited from DEFAULT section'
- );}
- );
- [obj.param().bar.test_default, obj.param('bar.test_default')].forEach(
- function(_) {assert.deepEqual(_, 'I come from bar',
- 'test_default\'s key value in bar is not overwrited');}
- );
- } else {
- assert.equal(typeof(obj.param('foo.test_default')), 'undefined',
- 'value which should not exist returned something else then undefined'
- );
- }
- // --}
+ assert.deepEqual(obj[fnGet]('bar.asdfas'), 'fooobar', 'bad value');
+ assert.deepEqual(obj[fnGet]('bar.1'), 'lorem ipsum');
+ assert.deepEqual(obj[fnGet]('bar.2'), ' lorem ipsum');
+ assert.deepEqual(obj[fnGet]('bar.3'), 'lorem ipsum');
+ assert.deepEqual(obj[fnGet]('bar.4'), 'lorem ipsum ');
+ });
- assert.deepEqual(obj.param('bar.asdfas'), 'fooobar', 'bad value');
- assert.deepEqual(obj.param('bar.1'), 'lorem ipsum');
- assert.deepEqual(obj.param('bar.2'), ' lorem ipsum');
- assert.deepEqual(obj.param('bar.3'), 'lorem ipsum');
- assert.deepEqual(obj.param('bar.4'), 'lorem ipsum ');
+ // Test the interpolations {--
+ assert.deepEqual(obj.interpolate('foo.interpolate'), 'sittercity', 'Interpolation is wrong');
+ if (obj.inheritDefault) {
+ assert.deepEqual(obj.interpolate('foo.interpolate_default'),
+ 'I come from the default section / interpolation',
+ 'Interpolation with inheritance from block "DEFAULT" is wrong');
+ assert.deepEqual(obj.interpolate('bar.interpolate_block_recursive'),
+ 'I come from bar / block interpolation / recursive',
+ 'Interpolation wiht inheritance from block "DEFAULT" and recursion is wrong');
+ }
+ assert.deepEqual(obj.interpolate('foo.interpolate_block'),
+ 'I come from bar / block interpolation',
+ 'Interpolation from other block is wrong');
+
+ // --}
};
Something went wrong with that request. Please try again.