const test = {
run(name, fn) {
try {
fn();
console.log(`✅ ${name}`);
} catch (error) {
console.error(`❌ ${name}`);
console.error(error);
}
},
assertEquals(actual, expected, message = '') {
const actualStr = JSON.stringify(actual);
const expectedStr = JSON.stringify(expected);
if (actualStr !== expectedStr) {
throw new Error(`${message}\nExpected: ${expectedStr}\nReceived: ${actualStr}`);
}
}
};
const testData = [
{
name: 'John',
age: 30,
hobbies: ['reading', 'music'],
address: {
city: 'New York',
country: 'USA'
},
preferences: {
theme: 'dark',
notifications: { email: true, sms: false }
}
},
{
name: 'Jane',
age: 25,
hobbies: ['sports'],
address: {
city: 'London',
country: 'UK'
},
preferences: {
theme: 'light',
notifications: { email: false, sms: true }
}
},
{
name: 'Bob',
age: 30,
hobbies: ['reading', 'music'],
address: {
city: 'New York',
country: 'USA'
},
preferences: {
theme: 'dark',
notifications: { email: true, sms: true }
}
}
];
test.run('should handle empty inputs', () => {
test.assertEquals(where([], {}), [], 'Empty array and empty object');
test.assertEquals(where(null, {}), [], 'Null collection');
test.assertEquals(where(undefined, {}), [], 'Undefined collection');
test.assertEquals(where(testData, null), [], 'Null properties');
});
test.run('should match simple properties', () => {
const result = where(testData, { age: 30 });
test.assertEquals(result.length, 2, 'Should find two 30-year-olds');
test.assertEquals(
result.map(p => p.name),
['John', 'Bob'],
'Should find John and Bob'
);
});
test.run('should match nested objects', () => {
const result = where(testData, {
address: { city: 'New York', country: 'USA' }
});
test.assertEquals(result.length, 2, 'Should find two New Yorkers');
});
test.run('should match arrays exactly', () => {
const result = where(testData, {
hobbies: ['reading', 'music']
});
test.assertEquals(result.length, 2, 'Should find two people with exact hobbies match');
});
test.run('should match deeply nested properties', () => {
const result = where(testData, {
preferences: { notifications: { email: true } }
});
test.assertEquals(result.length, 2, 'Should find two people with email notifications');
});
test.run('should handle multiple criteria', () => {
const result = where(testData, {
age: 30,
'preferences.theme': 'dark',
'address.city': 'New York'
});
test.assertEquals(result.length, 2, 'Should find people matching all criteria');
});
test.run('should return empty array for non-matching criteria', () => {
const result = where(testData, {
age: 99
});
test.assertEquals(result, [], 'Should return empty array for non-matching criteria');
});
test.run('should handle null values correctly', () => {
const dataWithNull = [...testData, { name: 'Alice', age: null }];
const result = where(dataWithNull, { age: null });
test.assertEquals(result.length, 1, 'Should find one person with null age');
test.assertEquals(result[0].name, 'Alice', 'Should find Alice');
});
if (typeof module !== 'undefined' && module.exports) {
module.exports = { test };
}
process.stdout.setEncoding('utf8');