Skip to content

Commit

Permalink
Export utility functions
Browse files Browse the repository at this point in the history
  • Loading branch information
pavolatzonky committed Mar 2, 2020
1 parent 1996387 commit f02c24d
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 32 deletions.
34 changes: 2 additions & 32 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { getPath, getPaths, setPath } from './utils';

/**
* ```typescript
* import { MacroGetter } from 'macro-decorators';
Expand Down Expand Up @@ -148,38 +150,6 @@ export default function macro(definition: MacroGetter | MacroDescriptor): Proper
};
}

function getPath(obj: any, path: string) {
let segments = path.split('.');
let current = obj;

for (let segment of segments) {
if (current === undefined || current === null) {
break;
}

current = typeof current.get === 'function' ? current.get(segment) : current[segment];
}

return current;
}

function getPaths(obj: any, paths: string[]) {
return paths.map(p => getPath(obj, p));
}

function setPath(obj: any, path: string, value: any) {
let objPath = path.substr(0, path.lastIndexOf('.'));
let key = path.substr(path.lastIndexOf('.') + 1);

let resolvedObj = objPath ? getPath(obj, objPath) : obj;

if (typeof resolvedObj.set === 'function') {
resolvedObj.set(key, value);
} else {
resolvedObj[key] = value;
}
}

// **** Aliasing ****

/**
Expand Down
90 changes: 90 additions & 0 deletions src/tests/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import 'mocha';
import { expect } from 'chai';

import { getPath, getPaths, setPath } from '../../utils';

describe('getPath', () => {
it('works with an absent class member', () => {
class Foo {}

let foo = new Foo();

expect(getPath(foo, 'bar')).to.equal(undefined);
});

it('works with a plain class member', () => {
class Foo {
foo = 123;
}

let foo = new Foo();

expect(getPath(foo, 'foo')).to.equal(123);
});

it('works with an object as a class member', () => {
class Foo {
bar = {
bao: 'bab',
};
}

let foo = new Foo();

expect(getPath(foo, 'bar')).to.equal(foo.bar);
expect(getPath(foo, 'bar.bao')).to.equal(foo.bar.bao);
});
});

describe('getPaths', () => {
it('works', () => {
class Foo {
bar = 1;
bab = '2';
}

let foo = new Foo();

expect(getPaths(foo, ['bar', 'bab', 'baz'])).to.deep.equal([1, '2', undefined]);
});
});

describe('setPath', () => {
it('works with a plain object', () => {
class Foo {
bar: any;
}

let foo = new Foo();

setPath(foo, 'bar', 'baz');

expect(foo.bar).to.equal('baz');
});

it('works with an object with setter', () => {
class Foo {
set = function() {
expect(true);
};
}

let foo = new Foo();

setPath(foo, 'bar', 'baz');
});

it('works with nested paths', () => {
class Foo {
bar = {
baz: '',
};
}

let foo = new Foo();

setPath(foo, 'bar.baz', 'bao');

expect(foo.bar.baz).to.equal('bao');
});
});
31 changes: 31 additions & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
export function getPath(obj: any, path: string) {
let segments = path.split('.');
let current = obj;

for (let segment of segments) {
if (current === undefined || current === null) {
break;
}

current = typeof current.get === 'function' ? current.get(segment) : current[segment];
}

return current;
}

export function getPaths(obj: any, paths: string[]) {
return paths.map(p => getPath(obj, p));
}

export function setPath(obj: any, path: string, value: any) {
let objPath = path.substr(0, path.lastIndexOf('.'));
let key = path.substr(path.lastIndexOf('.') + 1);

let resolvedObj = objPath ? getPath(obj, objPath) : obj;

if (typeof resolvedObj.set === 'function') {
resolvedObj.set(key, value);
} else {
resolvedObj[key] = value;
}
}

0 comments on commit f02c24d

Please sign in to comment.