mirror of
https://github.com/nvms/prsm.git
synced 2025-12-16 00:00:52 +00:00
222 lines
7.2 KiB
TypeScript
222 lines
7.2 KiB
TypeScript
import { testSuite, expect } from "manten";
|
|
import { CREATED_AT_KEY, ID_KEY, UPDATED_AT_KEY } from "../../../src/collection";
|
|
import { nrml, testCollection } from "../../common";
|
|
|
|
export default testSuite(async ({ describe }) => {
|
|
describe("project", ({ test }) => {
|
|
test("implicit exclusion", () => {
|
|
const collection = testCollection({ timestamps: false });
|
|
collection.insert({ a: 1, b: 1, c: 1 });
|
|
collection.insert({ a: 2, b: 2, c: 2 });
|
|
collection.insert({ a: 3, b: 3, c: 3 });
|
|
const found = collection.find({ a: 1 }, { project: { b: 1 } });
|
|
expect(found).toEqual([{ b: 1 }]);
|
|
});
|
|
|
|
test("implicit inclusion", () => {
|
|
const collection = testCollection({ timestamps: false });
|
|
collection.insert({ a: 1, b: 1, c: 1 });
|
|
collection.insert({ a: 2, b: 2, c: 2 });
|
|
collection.insert({ a: 3, b: 3, c: 3 });
|
|
const found = collection.find({ a: 1 }, { project: { b: 0 } });
|
|
const id = found[0][ID_KEY];
|
|
expect(id).toBeDefined();
|
|
expect(found).toEqual([{ _id: id, a: 1, c: 1 }]);
|
|
});
|
|
|
|
test("implicit inclusion - _id implicitly included", () => {
|
|
const collection = testCollection({ timestamps: false });
|
|
collection.insert({ a: 1, b: 1, c: 1 });
|
|
collection.insert({ a: 2, b: 2, c: 2 });
|
|
collection.insert({ a: 3, b: 3, c: 3 });
|
|
const foundWithId = collection.find({ a: 1 }, { project: { b: 0 } });
|
|
const id = foundWithId[0][ID_KEY];
|
|
expect(id).toBeDefined();
|
|
expect(foundWithId).toEqual([{ _id: id, a: 1, c: 1 }]);
|
|
});
|
|
|
|
test("explicit", () => {
|
|
const collection = testCollection({ timestamps: false });
|
|
collection.insert({ a: 1, b: 1, c: 1 });
|
|
collection.insert({ a: 2, b: 2, c: 2 });
|
|
collection.insert({ a: 3, b: 3, c: 3 });
|
|
const found = nrml(collection.find({ a: 1 }, { project: { b: 1, c: 0 } }));
|
|
expect(found).toEqual([{ a: 1, b: 1 }]);
|
|
});
|
|
|
|
test("explicit - ID_KEY implicitly included", () => {
|
|
const collection = testCollection({ timestamps: false });
|
|
collection.insert({ a: 1, b: 1, c: 1 });
|
|
collection.insert({ a: 2, b: 2, c: 2 });
|
|
collection.insert({ a: 3, b: 3, c: 3 });
|
|
const foundWithId = collection.find(
|
|
{ a: 1 },
|
|
{
|
|
project: {
|
|
b: 1,
|
|
c: 0,
|
|
_created_at: 0,
|
|
_updated_at: 0,
|
|
},
|
|
}
|
|
);
|
|
const id = foundWithId[0][ID_KEY];
|
|
expect(id).toBeDefined();
|
|
expect(foundWithId).toEqual([{ _id: id, a: 1, b: 1 }]);
|
|
});
|
|
|
|
test("empty query respects projection", () => {
|
|
const collection = testCollection({ timestamps: false });
|
|
collection.insert({ a: 1, b: 1, c: 1 });
|
|
collection.insert({ a: 2, b: 2, c: 2 });
|
|
|
|
const found = collection.find({}, { project: { b: 1 } });
|
|
|
|
for (const doc of found) {
|
|
expect(doc[ID_KEY]).toBeUndefined();
|
|
expect(doc[CREATED_AT_KEY]).toBeUndefined();
|
|
expect(doc[UPDATED_AT_KEY]).toBeUndefined();
|
|
}
|
|
});
|
|
|
|
describe("aggregation", ({ test }) => {
|
|
test("$floor, $ceil, $sub, $add, $mult, $div", () => {
|
|
const collection = testCollection({ timestamps: false });
|
|
collection.insert({ a: 1, b: 1, c: 5.6 });
|
|
collection.insert({ a: 2, b: 2, c: 2 });
|
|
collection.insert({ a: 3, b: 3, c: 3 });
|
|
|
|
const found = collection.find(
|
|
{ a: 1 },
|
|
{
|
|
aggregate: {
|
|
flooredC: { $floor: "c" },
|
|
ceiledC: { $ceil: "c" },
|
|
subbed1: { $sub: ["c", "a"] },
|
|
subbed2: { $sub: [15, "flooredC", 0, 1] },
|
|
mult1: { $mult: ["c", 2, "subbed2"] },
|
|
div1: { $div: ["subbed2", 2, "a", 2] },
|
|
add1: { $add: ["c", 2, "subbed2"] },
|
|
},
|
|
project: {
|
|
b: 0,
|
|
_created_at: 0,
|
|
_updated_at: 0,
|
|
_id: 0,
|
|
},
|
|
}
|
|
);
|
|
|
|
expect(found).toEqual([{
|
|
a: 1,
|
|
c: 5.6,
|
|
flooredC: 5,
|
|
ceiledC: 6,
|
|
subbed1: 4.6,
|
|
subbed2: 9,
|
|
mult1: 100.8,
|
|
div1: 2.25,
|
|
add1: 16.6,
|
|
}]);
|
|
});
|
|
|
|
test("more realistic use-case", () => {
|
|
const collection = testCollection({ timestamps: false });
|
|
collection.insert({ math: 72, english: 82, science: 92 });
|
|
collection.insert({ math: 60, english: 70, science: 80 });
|
|
collection.insert({ math: 90, english: 72, science: 84 });
|
|
|
|
const found = nrml(collection.find(
|
|
{ $has: ["math", "english", "science"] },
|
|
{
|
|
aggregate: {
|
|
total: { $add: ["math", "english", "science"] },
|
|
average: { $div: ["total", 3] },
|
|
},
|
|
}
|
|
));
|
|
|
|
expect(found).toEqual([
|
|
{ math: 72, english: 82, science: 92, total: 246, average: 82 },
|
|
{ math: 60, english: 70, science: 80, total: 210, average: 70 },
|
|
{ math: 90, english: 72, science: 84, total: 246, average: 82 },
|
|
]);
|
|
});
|
|
|
|
test("remove intermediate aggregation properties with projection", () => {
|
|
const collection = testCollection();
|
|
collection.insert({ math: 72, english: 82, science: 92 });
|
|
collection.insert({ math: 60, english: 70, science: 80 });
|
|
collection.insert({ math: 90, english: 72, science: 84 });
|
|
|
|
const found = nrml(collection.find(
|
|
{ $has: ["math", "english", "science"] },
|
|
{
|
|
aggregate: {
|
|
total: { $add: ["math", "english", "science"] }, // <-- projected out
|
|
average: { $div: ["total", 3] },
|
|
},
|
|
project: {
|
|
math: 1,
|
|
english: 1,
|
|
science: 1,
|
|
average: 1,
|
|
},
|
|
}
|
|
));
|
|
|
|
expect(found).toEqual([
|
|
{ math: 72, english: 82, science: 92, average: 82 },
|
|
{ math: 60, english: 70, science: 80, average: 70 },
|
|
{ math: 90, english: 72, science: 84, average: 82 },
|
|
]);
|
|
});
|
|
|
|
test("accessing properties with dot notation", () => {
|
|
const collection = testCollection();
|
|
collection.insert({ a: { b: { c: 1 } } });
|
|
collection.insert({ a: { b: { c: 2 } } });
|
|
collection.insert({ a: { b: { c: 3 } } });
|
|
|
|
const found = collection.find(
|
|
{ a: { b: { c: 1 } } },
|
|
{
|
|
aggregate: {
|
|
d: { $add: ["a.b.c", 1] },
|
|
},
|
|
project: {
|
|
a: 0,
|
|
_created_at: 0,
|
|
_updated_at: 0,
|
|
_id: 0,
|
|
},
|
|
}
|
|
);
|
|
|
|
expect(found).toEqual([{ d: 2 }]);
|
|
});
|
|
|
|
test("$fn", () => {
|
|
const collection = testCollection();
|
|
collection.insert({ first: "John", last: "Doe" });
|
|
collection.insert({ first: "Jane", last: "Doe" });
|
|
|
|
const found = nrml(collection.find(
|
|
{ $has: ["first", "last"] },
|
|
{
|
|
aggregate: {
|
|
fullName: { $fn: (doc) => `${doc.first} ${doc.last}` },
|
|
},
|
|
}
|
|
));
|
|
|
|
expect(found).toEqual([
|
|
{ first: "John", last: "Doe", fullName: "John Doe" },
|
|
{ first: "Jane", last: "Doe", fullName: "Jane Doe" },
|
|
]);
|
|
});
|
|
});
|
|
|
|
});
|
|
});
|