fix(jsdoc-salty): support left and right matchers (#2103)

This commit is contained in:
Jeff Williams 2024-04-15 14:24:17 -07:00
parent e9c06dbf64
commit cfda2b565d
No known key found for this signature in database
3 changed files with 74 additions and 47 deletions

View File

@ -107,6 +107,10 @@ const arrayMatcher = db({ a: [1, 3] }).get();
const multiMatcher = db({ a: 1 }, { b: 'hello' }).get();
// Get array of items where `b` is undefined
const undefinedMatcher = db({ b: { isUndefined: true } }).get();
// Get array of items where `b` starts with `he`
const leftMatcher = db({ b: { left: 'he' } }).get();
// Get array of items where `b` ends with `lo`
const rightMatcher = db({ b: { right: 'lo' } }).get();
```
### Get items with a custom query function

View File

@ -21,14 +21,6 @@ if (!Object.hasOwn) {
Object.hasOwn = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
}
const IS_UNDEFINED = {
isUndefined: true,
};
const IS_NOT_UNDEFINED = {
isUndefined: false,
};
function addToSelection(salty, item, i) {
salty._selectedItems.push(item);
salty._selectedIndexes.push(i);
@ -61,6 +53,24 @@ function finderWithFunction(salty, func) {
return salty;
}
function applyMatcherObject(value, matcherObject) {
if (matcherObject.isUndefined === true) {
return _.isUndefined(value);
}
if (matcherObject.isUndefined === false) {
return !_.isUndefined(value);
}
if (matcherObject.left) {
return value && value.startsWith && value.startsWith(matcherObject.left);
}
if (matcherObject.right) {
return value && value.endsWith && value.endsWith(matcherObject.right);
}
}
function finderWithMatcher(salty, ...args) {
let item;
let matches;
@ -81,14 +91,12 @@ function finderWithMatcher(salty, ...args) {
item = salty._items[i];
for (const key of matcherKeys) {
matcherValue = matcher[key];
if (_.isMatch(matcherValue, IS_UNDEFINED)) {
matches = _.isUndefined(item[key]);
} else if (_.isMatch(matcherValue, IS_NOT_UNDEFINED)) {
matches = !_.isUndefined(item[key]);
} else if (Array.isArray(matcherValue)) {
if (Array.isArray(matcherValue)) {
if (!matcherValue.includes(item[key])) {
matches = false;
}
} else if (_.isObject(matcherValue)) {
matches = applyMatcherObject(item[key], matcherValue);
} else if (matcherValue !== item[key]) {
matches = false;
}

View File

@ -17,20 +17,21 @@ describe('@jsdoc/salty/lib/salty', () => {
const _ = require('lodash');
const Salty = require('../../../lib/salty');
const data = [
{ a: 2, b: undefined, c: true },
{ a: 47, b: null, c: true },
{ a: 100, b: 'hello', c: true },
{ a: 7, b: 'goodbye', c: false },
{ a: 42, b: 8, c: null },
{ a: 35, b: undefined, c: true },
{ a: 22, b: null, c: true },
{ a: 17, b: 0, c: false },
{ a: 66, c: true },
];
let data;
let db;
beforeEach(() => {
data = [
{ a: 2, b: undefined, c: true },
{ a: 47, b: null, c: true },
{ a: 100, b: 'hello', c: true },
{ a: 7, b: 'goodbye', c: false },
{ a: 42, b: 8, c: null },
{ a: 35, b: undefined, c: true },
{ a: 22, b: null, c: true },
{ a: 17, b: 0, c: false },
{ a: 66, c: true },
];
db = new Salty(_.cloneDeep(data));
});
@ -162,29 +163,6 @@ describe('@jsdoc/salty/lib/salty', () => {
]);
});
it('returns the correct items with the special matcher for undefined values', () => {
const result = db({ b: { isUndefined: true } }).get();
expect(result).toMatchArrayOfObjects([
{ a: 2, b: undefined, c: true },
{ a: 35, b: undefined, c: true },
{ a: 66, c: true },
]);
});
it('returns the correct items with the special matcher for defined values', () => {
const result = db({ b: { isUndefined: false } }).get();
expect(result).toMatchArrayOfObjects([
{ a: 47, b: null, c: true },
{ a: 100, b: 'hello', c: true },
{ a: 7, b: 'goodbye', c: false },
{ a: 42, b: 8, c: null },
{ a: 22, b: null, c: true },
{ a: 17, b: 0, c: false },
]);
});
it('returns no items if the selection is empty', () => {
expect(db({ a: 1000000000 }).get()).toBeEmptyArray();
});
@ -203,6 +181,43 @@ describe('@jsdoc/salty/lib/salty', () => {
{ a: 66, c: true },
]);
});
describe('matcher objects', () => {
it('returns the correct items for `isUndefined: true`', () => {
const result = db({ b: { isUndefined: true } }).get();
expect(result).toMatchArrayOfObjects([
{ a: 2, b: undefined, c: true },
{ a: 35, b: undefined, c: true },
{ a: 66, c: true },
]);
});
it('returns the correct items for `isUndefined: false`', () => {
const result = db({ b: { isUndefined: false } }).get();
expect(result).toMatchArrayOfObjects([
{ a: 47, b: null, c: true },
{ a: 100, b: 'hello', c: true },
{ a: 7, b: 'goodbye', c: false },
{ a: 42, b: 8, c: null },
{ a: 22, b: null, c: true },
{ a: 17, b: 0, c: false },
]);
});
it('returns the correct items for `left`', () => {
const result = db({ b: { left: 'good' } }).get();
expect(result).toMatchArrayOfObjects([{ a: 7, b: 'goodbye', c: false }]);
});
it('returns the correct items for `right`', () => {
const result = db({ b: { right: 'bye' } }).get();
expect(result).toMatchArrayOfObjects([{ a: 7, b: 'goodbye', c: false }]);
});
});
});
describe('remove', () => {