pathos
Version:
Decompose a javascript object into a set of path/value slices.
778 lines (705 loc) • 17.5 kB
JavaScript
var expect = require('expect.js'),
pathos = require('..');
describe('pathos', function() {
it('should be able to slice an object', function(done) {
var o = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota',
model: 'Camry'
},
{
make: 'Toyota',
model: 'Corolla'
}
]
};
var paths = pathos.slice(o);
expect(paths).to.eql(
[ { key: [ 'name' ], value: 'Eugene' },
{ key: [ 'number' ], value: 42 },
{ key: [ 'tags' ], value: [] },
{ key: [ 'tags', 0 ], value: 'tag1' },
{ key: [ 'tags', 1 ], value: 'tag2' },
{ key: [ 'tags', 2 ], value: 'tag3' },
{ key: [ 'cars' ], value: [] },
{ key: [ 'cars', 0, 'make' ], value: 'Toyota' },
{ key: [ 'cars', 0, 'model' ], value: 'Camry' },
{ key: [ 'cars', 1, 'make' ], value: 'Toyota' },
{ key: [ 'cars', 1, 'model' ], value: 'Corolla' } ]);
expect(typeof paths[3].key[1]).to.equal('number');
expect(typeof paths[7].key[1]).to.equal('number');
done();
});
it('should be able to slice an object with an empty array', function(done) {
var o = {
tags: [],
};
var paths = pathos.slice(o);
expect(paths).to.eql(
[ { key: [ 'tags' ], value: [] } ]);
done();
});
it('should be able to slice a top level array', function(done) {
var o = ['tag1', 'tag2', 'tag3'];
var paths = pathos.slice(o);
expect(paths).to.eql([
{ key: [], value: [] },
{ key: [ 0 ], value: 'tag1' },
{ key: [ 1 ], value: 'tag2' },
{ key: [ 2 ], value: 'tag3' }
]);
done();
});
it('should be able to build an object from a top level array slice', function(done) {
var o = ['tag1', 'tag2', 'tag3'];
var paths = [
{ key: [], value: [] },
{ key: [ 0 ], value: 'tag1' },
{ key: [ 1 ], value: 'tag2' },
{ key: [ 2 ], value: 'tag3' }
];
var result = pathos.build(paths);
expect(Array.isArray(result)).to.equal(true);
expect(result).to.eql(o);
done();
});
it('should be able to build an object from empty array paths', function(done) {
var o = {
tags: [],
moreTags: ['do', 're', 'mi']
};
var paths = [
{ key: [ 'tags' ], value: [] },
{ key: [ 'moreTags' ], value: [] },
{ key: [ 'moreTags', 0 ], value: 'do' },
{ key: [ 'moreTags', 1 ], value: 're' },
{ key: [ 'moreTags', 2 ], value: 'mi' }
];
var result = pathos.build(paths);
expect(result).to.eql(o);
done();
});
it('should default to the slice method', function(done) {
var o = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota',
model: 'Camry'
},
{
make: 'Toyota',
model: 'Corolla'
}
]
};
// default method is slice
var paths = pathos(o);
expect(paths).to.eql(
[ { key: [ 'name' ], value: 'Eugene' },
{ key: [ 'number' ], value: 42 },
{ key: [ 'tags' ], value: [] },
{ key: [ 'tags', 0 ], value: 'tag1' },
{ key: [ 'tags', 1 ], value: 'tag2' },
{ key: [ 'tags', 2 ], value: 'tag3' },
{ key: [ 'cars' ], value: [] },
{ key: [ 'cars', 0, 'make' ], value: 'Toyota' },
{ key: [ 'cars', 0, 'model' ], value: 'Camry' },
{ key: [ 'cars', 1, 'make' ], value: 'Toyota' },
{ key: [ 'cars', 1, 'model' ], value: 'Corolla' } ]);
done();
});
it('should be able to walk a path', function(done) {
var o = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota',
model: 'Camry'
},
{
make: 'Toyota',
model: 'Corolla'
}
]
};
var ret = pathos.walk(o, [ 'cars', '1', 'make' ]);
expect(ret).to.equal('Toyota');
done();
});
it('should be able to retrieve the root of an object', function(done) {
var o = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota',
model: 'Camry'
},
{
make: 'Toyota',
model: 'Corolla'
}
]
};
var ret = pathos.walk(o, []);
var expected = JSON.parse(JSON.stringify(o));
expect(ret).to.eql(expected);
done();
});
it('should be able to build an object from paths', function(done) {
var o = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota',
model: 'Camry'
},
{
make: 'Toyota',
model: 'Corolla'
}
]
};
var paths =
[ { key: [ 'name' ], value: 'Eugene' },
{ key: [ 'number' ], value: 42 },
{ key: [ 'tags', '0' ], value: 'tag1' },
{ key: [ 'tags', '1' ], value: 'tag2' },
{ key: [ 'tags', '2' ], value: 'tag3' },
{ key: [ 'cars', '0', 'make' ], value: 'Toyota' },
{ key: [ 'cars', '0', 'model' ], value: 'Camry' },
{ key: [ 'cars', '1', 'make' ], value: 'Toyota' },
{ key: [ 'cars', '1', 'model' ], value: 'Corolla' } ];
var result = pathos.build(paths);
expect(result).to.eql(o);
expect(Array.isArray(result.tags)).to.equal(false);
expect(Array.isArray(result.cars)).to.equal(false);
done();
});
it('should be able to build an object from paths (arrays)', function(done) {
var o = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota',
model: 'Camry'
},
{
make: 'Toyota',
model: 'Corolla'
}
]
};
var paths =
[ { key: [ 'name' ], value: 'Eugene' },
{ key: [ 'number' ], value: 42 },
{ key: [ 'tags', 0 ], value: 'tag1' },
{ key: [ 'tags', 1 ], value: 'tag2' },
{ key: [ 'tags', 2 ], value: 'tag3' },
{ key: [ 'cars', 0, 'make' ], value: 'Toyota' },
{ key: [ 'cars', 0, 'model' ], value: 'Camry' },
{ key: [ 'cars', 1, 'make' ], value: 'Toyota' },
{ key: [ 'cars', 1, 'model' ], value: 'Corolla' } ];
var result = pathos.build(paths);
expect(result).to.eql(o);
expect(Array.isArray(result.tags)).to.equal(true);
expect(Array.isArray(result.cars)).to.equal(true);
done();
});
it('should be able to set an object field with a path and value',
function(done) {
var o = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota',
model: 'Camry'
},
{
make: 'Toyota',
model: 'Corolla'
}
]
};
pathos.set(o, [ 'cars', '1', 'make' ], 'Toyoda');
var expected1 = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota',
model: 'Camry'
},
{
make: 'Toyoda',
model: 'Corolla'
}
]
};
expect(o).to.eql(expected1);
pathos.set(o, [ 'cars', '1', 'make' ], { old_name: 'Toyota', new_name: 'Toyota' });
var expected2 = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota',
model: 'Camry'
},
{
make: { old_name: 'Toyota', new_name: 'Toyota' },
model: 'Corolla'
}
]
};
expect(o).to.eql(expected2);
done();
});
it('should handle setting of new properties', function(done) {
var o = {
nothing: 'here'
}
pathos.set(o, [ 'cars', '1', 'make' ], 'Toyoda');
var expected = {
nothing: 'here',
cars: {
'1': {
make: 'Toyoda'
}
}
};
expect(o).to.eql(expected);
done();
});
it('should be able to visit every key-value pair', function(done) {
var o = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota',
model: 'Camry'
},
{
make: 'Toyota',
model: 'Corolla'
}
]
};
var paths = [];
function visit(key, value) {
paths.push({ key: key, value: value });
}
pathos.visit(o, visit);
expect(paths).to.eql(
[ { key: [ 'name' ], value: 'Eugene' },
{ key: [ 'number' ], value: 42 },
{ key: [ 'tags' ], value: [] },
{ key: [ 'tags', '0' ], value: 'tag1' },
{ key: [ 'tags', '1' ], value: 'tag2' },
{ key: [ 'tags', '2' ], value: 'tag3' },
{ key: [ 'cars' ], value: [] },
{ key: [ 'cars', '0', 'make' ], value: 'Toyota' },
{ key: [ 'cars', '0', 'model' ], value: 'Camry' },
{ key: [ 'cars', '1', 'make' ], value: 'Toyota' },
{ key: [ 'cars', '1', 'model' ], value: 'Corolla' } ]);
done();
});
it('should be able to rename a field', function(done) {
var o = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota',
model: 'Camry'
},
{
make: 'Toyota',
model: 'Corolla'
}
]
};
function rename(key, value) {
if (key[key.length - 1] === 'make') {
key[key.length - 1] = 'manufacturer';
return {
key: key,
value: value
};
} else {
return true;
}
}
pathos.rewrite(o, rename);
var expected = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
manufacturer: 'Toyota',
model: 'Camry'
},
{
manufacturer: 'Toyota',
model: 'Corolla'
}
]
};
expect(o).to.eql(expected);
done();
});
it('should be able to change a fields\'s value', function(done) {
var o = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota',
model: 'Camry'
},
{
make: 'Toyota',
model: 'Corolla'
}
]
};
function change(key, value) {
if (key[key.length - 1] === 'make') {
return {
key: key,
value: 'Toyoda'
};
} else {
return true;
}
}
pathos.rewrite(o, change);
var expected = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyoda',
model: 'Camry'
},
{
make: 'Toyoda',
model: 'Corolla'
}
]
};
expect(o).to.eql(expected);
done();
});
it('should be able to remove a field', function(done) {
var o = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota',
model: 'Camry'
},
{
make: 'Toyota',
model: 'Corolla'
}
]
};
var expected = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota'
},
{
make: 'Toyota'
}
]
};
function remove1(key, value) {
return key[key.length - 1] !== 'model';
}
pathos.rewrite(o, remove1);
expect(o).to.eql(expected);
function remove2(key, value) {
if (key[key.length - 1] === 'model') {
return {
key: key
};
}
return true;
}
pathos.rewrite(o, remove2);
expect(o).to.eql(expected);
done();
});
it('should be able to set an object field with a path and value',
function(done) {
var o = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota',
model: 'Camry'
},
{
make: 'Toyota',
model: 'Corolla'
}
]
};
pathos.set(o, [ 'cars', '1', 'make' ], 'Toyoda');
var expected1 = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota',
model: 'Camry'
},
{
make: 'Toyoda',
model: 'Corolla'
}
]
};
expect(o).to.eql(expected1);
pathos.set(o, [ 'cars', '1', 'make' ], { old_name: 'Toyota', new_name: 'Toyota' });
var expected2 = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota',
model: 'Camry'
},
{
make: { old_name: 'Toyota', new_name: 'Toyota' },
model: 'Corolla'
}
]
};
expect(o).to.eql(expected2);
done();
});
it('should handle setting of new properties', function(done) {
var o = {
nothing: 'here'
}
pathos.set(o, [ 'cars', '1', 'make' ], 'Toyoda');
var expected = {
nothing: 'here',
cars: {
'1': {
make: 'Toyoda'
}
}
};
expect(o).to.eql(expected);
done();
});
it('should be able to visit every key-value pair', function(done) {
var o = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota',
model: 'Camry'
},
{
make: 'Toyota',
model: 'Corolla'
}
]
};
var paths = [];
function visit(key, value) {
paths.push({ key: key, value: value });
}
pathos.visit(o, visit);
expect(paths).to.eql(
[ { key: [ 'name' ], value: 'Eugene' },
{ key: [ 'number' ], value: 42 },
{ key: [ 'tags' ], value: [] },
{ key: [ 'tags', '0' ], value: 'tag1' },
{ key: [ 'tags', '1' ], value: 'tag2' },
{ key: [ 'tags', '2' ], value: 'tag3' },
{ key: [ 'cars' ], value: [] },
{ key: [ 'cars', '0', 'make' ], value: 'Toyota' },
{ key: [ 'cars', '0', 'model' ], value: 'Camry' },
{ key: [ 'cars', '1', 'make' ], value: 'Toyota' },
{ key: [ 'cars', '1', 'model' ], value: 'Corolla' } ]);
done();
});
it('should be able to rename a field', function(done) {
var o = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota',
model: 'Camry'
},
{
make: 'Toyota',
model: 'Corolla'
}
]
};
function rename(key, value) {
if (key[key.length - 1] === 'make') {
key[key.length - 1] = 'manufacturer';
return {
key: key,
value: value
};
} else {
return true;
}
}
pathos.rewrite(o, rename);
var expected = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
manufacturer: 'Toyota',
model: 'Camry'
},
{
manufacturer: 'Toyota',
model: 'Corolla'
}
]
};
expect(o).to.eql(expected);
done();
});
it('should be able to change a fields\'s value', function(done) {
var o = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota',
model: 'Camry'
},
{
make: 'Toyota',
model: 'Corolla'
}
]
};
function change(key, value) {
if (key[key.length - 1] === 'make') {
return {
key: key,
value: 'Toyoda'
};
} else {
return true;
}
}
pathos.rewrite(o, change);
var expected = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyoda',
model: 'Camry'
},
{
make: 'Toyoda',
model: 'Corolla'
}
]
};
expect(o).to.eql(expected);
done();
});
it('should be able to remove a field', function(done) {
var o = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota',
model: 'Camry'
},
{
make: 'Toyota',
model: 'Corolla'
}
]
};
var expected = {
name: 'Eugene',
number: 42,
tags: ['tag1', 'tag2', 'tag3'],
cars: [
{
make: 'Toyota'
},
{
make: 'Toyota'
}
]
};
function remove1(key, value) {
return key[key.length - 1] !== 'model';
}
pathos.rewrite(o, remove1);
expect(o).to.eql(expected);
function remove2(key, value) {
if (key[key.length - 1] === 'model') {
return {
key: key
};
}
return true;
}
pathos.rewrite(o, remove2);
expect(o).to.eql(expected);
done();
});
});