Skip to content

Commit

Permalink
Merge 4231d09 into 3c0a429
Browse files Browse the repository at this point in the history
  • Loading branch information
hibes committed Aug 14, 2020
2 parents 3c0a429 + 4231d09 commit 085b7f9
Show file tree
Hide file tree
Showing 49 changed files with 778 additions and 84 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @0ti.me/librarians
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@0ti.me/tiny-pfp",
"version": "0.1.11",
"version": "0.1.12",
"description": "A tiny, minimalist lodash alternative library",
"license": "GPL-3.0",
"main": "src/index.js",
Expand All @@ -19,7 +19,7 @@
},
"devDependencies": {
"@0ti.me/index-generator": "^0.1.6",
"@0ti.me/test-deps": "^0.1.13",
"@0ti.me/test-deps": "^0.1.15",
"bluebird": "^3.7.1",
"coveralls": "^3.0.7",
"eslint": "^6.5.1",
Expand Down
21 changes: 0 additions & 21 deletions src/index.js

This file was deleted.

2 changes: 2 additions & 0 deletions src/lib/for-each.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module.exports = (obj, fn) =>
Object.keys(obj).forEach(key => fn(obj[key], key, obj));
7 changes: 5 additions & 2 deletions src/lib/get.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ module.exports = (obj, bigKey, defaultValue = undefined) => {
throw TypeError('The obj parameter was not a valid type');
}

let curr = obj;

if (!(bigKey instanceof String || typeof bigKey === 'string')) {
return obj[bigKey];
curr = obj[bigKey];

return curr === undefined ? defaultValue : curr;
}

const keys = bigKey.split('.');

let curr = obj;
let key = null;

for (let i = 0; i < keys.length; ++i) {
Expand Down
9 changes: 9 additions & 0 deletions src/lib/has.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const get = require('./get');

const ABSENT_SYMBOL = Symbol();

module.exports = (obj, key) => {
console.error(obj, get(obj, key, ABSENT_SYMBOL), ABSENT_SYMBOL);

return get(obj, key, ABSENT_SYMBOL) !== ABSENT_SYMBOL;
};
2 changes: 2 additions & 0 deletions src/lib/includes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module.exports = (ray, val) =>
console.error('includes', ray, val) || ray.includes(val);
6 changes: 2 additions & 4 deletions src/lib/map-values.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
const zip = require('./zip');

const mapValues = (obj, fn) => {
module.exports = (obj, fn) => {
const keys = Object.keys(obj);

return keys.map(key => fn(obj[key], key)).reduce(zip(keys), {});
return keys.map(key => fn(obj[key], key, obj)).reduce(zip(keys), {});
};

module.exports = mapValues;
1 change: 1 addition & 0 deletions src/lib/negate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = fn => (...args) => !fn(...args);
61 changes: 61 additions & 0 deletions src/lib/omit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
const flow = require('../src/fp/flow');
const get = require('./get');
const fpIncludes = require('../src/fp/includes');
const negate = require('./negate');
const reduce = require('../src/fp/reduce');
const set = require('./set');
const unset = require('./unset');

const fpExcludes = ray => negate(fpIncludes(ray));

// TODO: Make this work for deep keys in an omitSet

module.exports = (obj, omitSet) => {
let allKeys = [];
let curr = obj;
let keys = [];
let key = null;
let newKeys = [];
let objKeys = [];

// eslint-disable-next-line no-constant-condition
while (true) {
objKeys = Object.keys(curr);

newKeys = objKeys
.map(ea => (key === null ? ea : `${key}.${ea}`))
.filter(fpExcludes(omitSet));

keys = keys.concat(newKeys);

allKeys = allKeys.concat(newKeys);

console.error({
allKeys,
curr,
key,
newKeys,
objKeys,
});

if (keys.length === 0) {
break;
}

key = keys.pop();
curr = get(obj, key);
}

allKeys = allKeys.sort((a, b) => (a < b ? 1 : -1));
console.error({ allKeys });

return flow([
reduce((acc, ea) => console.error(acc) || set(acc, ea, get(obj, ea)), {}),
initialAcc => omitSet.reduce((acc, ea) => unset(acc, ea), initialAcc),
])(allKeys);
};
/*
Object.keys(obj)
.filter(each => !omitSet.includes(each))
.reduce((acc, key) => set(acc, key, get(obj, key)), {});
*/
9 changes: 9 additions & 0 deletions src/lib/pick.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const get = require('./get');
const has = require('./has');
const set = require('./set');

module.exports = (obj, pickSet) =>
pickSet.reduce(
(acc, key) => (has(obj, key) ? set(acc, key, get(obj, key)) : acc),
{},
);
27 changes: 27 additions & 0 deletions src/lib/unset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module.exports = (obj, bigKey) => {
if (!(bigKey instanceof String || typeof bigKey === 'string')) {
delete obj[bigKey];

return obj;
}

const keys = bigKey.split('.');
let key = null;

let curr = obj;
for (let i = 0; i < keys.length; ++i) {
key = keys[i];

if (i === keys.length - 1) {
delete curr[key];
} else {
if (!Object.prototype.hasOwnProperty.call(curr, key)) {
i = keys.length;
}
}

curr = curr[key];
}

return obj;
};
3 changes: 3 additions & 0 deletions src/src/for-each.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const forEach = require('../lib/for-each');

module.exports = forEach;
4 changes: 4 additions & 0 deletions src/src/fp/for-each.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const fixedArity2Fn = require('../../lib/fixed-arity-2-fn-b-a-args');
const forEach = require('../../lib/for-each');

module.exports = fixedArity2Fn(forEach);
4 changes: 4 additions & 0 deletions src/src/fp/has.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const fixedArity2Fn = require('../../lib/fixed-arity-2-fn-b-a-args');
const has = require('../../lib/has');

module.exports = fixedArity2Fn(has);
4 changes: 4 additions & 0 deletions src/src/fp/includes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const fixedArity2Fn = require('../../lib/fixed-arity-2-fn-b-a-args');
const includes = require('../../lib/includes');

module.exports = fixedArity2Fn(includes);
4 changes: 4 additions & 0 deletions src/src/fp/omit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const fixedArity2Fn = require('../../lib/fixed-arity-2-fn-b-a-args');
const omit = require('../../lib/omit');

module.exports = fixedArity2Fn(omit);
4 changes: 4 additions & 0 deletions src/src/fp/pick.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const fixedArity2Fn = require('../../lib/fixed-arity-2-fn-b-a-args');
const pick = require('../../lib/pick');

module.exports = fixedArity2Fn(pick);
4 changes: 4 additions & 0 deletions src/src/fp/unset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const fixedArity2Fn = require('../../lib/fixed-arity-2-fn-b-a-args');
const unset = require('../../lib/unset');

module.exports = fixedArity2Fn(unset);
3 changes: 3 additions & 0 deletions src/src/has.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const has = require('../lib/has');

module.exports = has;
3 changes: 3 additions & 0 deletions src/src/omit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const omit = require('../lib/omit');

module.exports = omit;
3 changes: 3 additions & 0 deletions src/src/pick.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const pick = require('../lib/pick');

module.exports = pick;
2 changes: 2 additions & 0 deletions src/src/unset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const unset = require('../lib/unset');
module.exports = unset;
27 changes: 27 additions & 0 deletions test/unit/lib/for-each.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const {
d,
expect,
sinon: { spy },
tquire,
} = deps;

const me = __filename;

d(me, () => {
describe('given a normal require', () => {
const forEach = tquire(me);
const obj = { a: 1, b: 2, c: 3 };

const mockForEachFn = spy();

it('should call the forEachFn once per key', () => {
forEach(obj, mockForEachFn);

expect(mockForEachFn.args).to.deep.equal([
[1, 'a', obj],
[2, 'b', obj],
[3, 'c', obj],
]);
});
});
});
6 changes: 5 additions & 1 deletion test/unit/lib/get.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const { d, expect, tquire, uuid } = deps;
const get = tquire(__filename);

d(__filename, () => {
const ABSENT_SYMBOL = Symbol();
const defaultValue = Symbol();
const val = Symbol();

Expand All @@ -11,7 +12,7 @@ d(__filename, () => {
describe('given a non-string key', () => {
const key = Symbol();

describe('given an empty obj reference', () => {
describe('given an null obj reference', () => {
beforeEach(() => {
obj = null;
});
Expand All @@ -27,6 +28,9 @@ d(__filename, () => {

it('should get the value from the obj', () =>
expect(get(obj, key)).to.have.equal(val));

it('should return the default value if the value is absent from the reference', () =>
expect(get(obj, Symbol(), ABSENT_SYMBOL)).to.equal(ABSENT_SYMBOL));
});
});

Expand Down
55 changes: 55 additions & 0 deletions test/unit/lib/has.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
const { d, expect, tquire, uuid } = deps;

const has = tquire(__filename);
const set = require('../../../src/lib/set');

d(__filename, () => {
const val = Symbol();

describe('given a shallow key', () => {
let key = null;
let obj = null;

beforeEach(() => {
key = uuid();
obj = { [key]: val };
});

it('should return true if the key exists', () =>
expect(has(obj, key)).to.equal(true));

it('should return false if the key does not exist', () =>
expect(has(obj, Symbol())).to.equal(false));

it('should return false if the key does not exist', () =>
expect(has({}, Symbol())).to.equal(false));

it('should return false if the key does not exist', () =>
expect(has(obj, `gibberish-key-${uuid()}`)).to.equal(false));

it('should return false if the key does not exist', () =>
expect(has({}, key)).to.equal(false));
});

describe('given a nested key', () => {
let key = null;
let key1 = null;
let key2 = null;

beforeEach(() => {
key1 = uuid();
key2 = uuid();

key = `${key1}.${key2}`;
});

it('should return true if the key exists', () =>
expect(has(set({}, key, val), key)).to.equal(true));

it('should return false if a partial key exists but the full key does not', () =>
expect(has(set({}, key1, val), key)).to.equal(false));

it('should return false if the key does not exist', () =>
expect(has({}, key)).to.equal(false));
});
});
25 changes: 22 additions & 3 deletions test/unit/lib/map-values.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,37 @@
const { d, expect, tquire } = deps;
const {
d,
expect,
sinon: { spy },
tquire,
} = deps;

const me = __filename;

d(me, () => {
describe('given a normal require', () => {
const mapValues = tquire(me);
let incrementer = null;
let mapValues = null;
let obj = null;

beforeEach(() => {
incrementer = spy(x => x + 1);
mapValues = tquire(me);
obj = { a: 1, b: 2, c: 6 };
});

describe('and a function which increments each value by one', () => {
it('should increment each value by one, maintaining the keys', () => {
expect(mapValues({ a: 1, b: 2, c: 6 }, x => x + 1)).to.deep.equal({
expect(mapValues(obj, incrementer)).to.deep.equal({
a: 2,
b: 3,
c: 7,
});

expect(incrementer.args).to.deep.equal([
[1, 'a', obj],
[2, 'b', obj],
[6, 'c', obj],
]);
});
});
});
Expand Down

0 comments on commit 085b7f9

Please sign in to comment.