2025-10-21 21:52:06 -07:00
|
|
|
import * as asserts from "@std/assert";
|
|
|
|
|
import * as fsdb from "../fsdb.ts";
|
|
|
|
|
import { FSDB_INDEXER_SYMLINKS } from "../indexers.ts";
|
|
|
|
|
import { get_data_dir, random_email_address, random_phone_number } from "./helpers.ts";
|
|
|
|
|
import lurid from "@andyburke/lurid";
|
|
|
|
|
import by_email from "../organizers/by_email.ts";
|
|
|
|
|
import by_character from "../organizers/by_character.ts";
|
|
|
|
|
import by_phone from "../organizers/by_phone.ts";
|
|
|
|
|
import { sentence } from "jsr:@ndaidong/txtgen";
|
2025-06-13 20:40:28 -07:00
|
|
|
|
|
|
|
|
Deno.test({
|
2025-10-21 21:52:06 -07:00
|
|
|
name: "index some items",
|
2025-06-13 20:40:28 -07:00
|
|
|
permissions: {
|
|
|
|
|
env: true,
|
|
|
|
|
|
|
|
|
|
// https://github.com/denoland/deno/discussions/17258
|
|
|
|
|
read: true,
|
2025-10-21 21:52:06 -07:00
|
|
|
write: true,
|
2025-06-13 20:40:28 -07:00
|
|
|
},
|
|
|
|
|
fn: async () => {
|
|
|
|
|
type ITEM = {
|
|
|
|
|
id: string;
|
|
|
|
|
email: string;
|
|
|
|
|
phone: string;
|
2025-10-21 21:52:06 -07:00
|
|
|
stable: string;
|
2025-06-13 20:40:28 -07:00
|
|
|
value: string;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const item_collection: fsdb.FSDB_COLLECTION<ITEM> = new fsdb.FSDB_COLLECTION<ITEM>({
|
2025-10-21 21:52:06 -07:00
|
|
|
name: "test-04-items",
|
|
|
|
|
root: get_data_dir() + "/test-04-items",
|
2025-06-13 20:40:28 -07:00
|
|
|
indexers: {
|
|
|
|
|
email: new FSDB_INDEXER_SYMLINKS<ITEM>({
|
2025-10-21 21:52:06 -07:00
|
|
|
name: "email",
|
|
|
|
|
field: "email",
|
|
|
|
|
organize: by_email,
|
2025-06-13 20:40:28 -07:00
|
|
|
}),
|
|
|
|
|
phone: new FSDB_INDEXER_SYMLINKS<ITEM>({
|
2025-10-21 21:52:06 -07:00
|
|
|
name: "phone",
|
|
|
|
|
field: "phone",
|
|
|
|
|
organize: by_phone,
|
|
|
|
|
}),
|
|
|
|
|
stable: new FSDB_INDEXER_SYMLINKS<ITEM>({
|
|
|
|
|
name: "stable",
|
|
|
|
|
field: "stable",
|
|
|
|
|
to_many: true,
|
|
|
|
|
organize: by_character,
|
2025-06-13 20:40:28 -07:00
|
|
|
}),
|
|
|
|
|
by_character_test: new FSDB_INDEXER_SYMLINKS<ITEM>({
|
2025-10-21 21:52:06 -07:00
|
|
|
name: "by_character_test",
|
2025-06-13 20:40:28 -07:00
|
|
|
organize: by_character,
|
2025-10-21 21:52:06 -07:00
|
|
|
get_values_to_index: (item: ITEM) =>
|
|
|
|
|
item.value.split(/\W/).filter((word) => word.length > 3),
|
|
|
|
|
to_many: true,
|
2025-09-21 17:16:50 -07:00
|
|
|
}),
|
|
|
|
|
by_possibly_undefined: new FSDB_INDEXER_SYMLINKS<ITEM>({
|
2025-10-21 21:52:06 -07:00
|
|
|
name: "by_possibly_undefined",
|
2025-09-21 17:16:50 -07:00
|
|
|
organize: by_character,
|
2025-10-21 21:52:06 -07:00
|
|
|
get_values_to_index: (item: ITEM) =>
|
|
|
|
|
item.email.indexOf(".com") > 0 ? [item.email] : [],
|
|
|
|
|
to_many: true,
|
|
|
|
|
}),
|
|
|
|
|
},
|
2025-06-13 20:40:28 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
asserts.assert(item_collection);
|
|
|
|
|
|
|
|
|
|
const items: ITEM[] = [];
|
2025-09-21 17:16:50 -07:00
|
|
|
for (let i = 0; i < 50; ++i) {
|
2025-06-13 20:40:28 -07:00
|
|
|
const item = {
|
|
|
|
|
id: lurid(),
|
|
|
|
|
email: random_email_address(),
|
|
|
|
|
phone: random_phone_number(),
|
2025-10-21 21:52:06 -07:00
|
|
|
stable: "stable",
|
|
|
|
|
value: sentence(),
|
2025-06-13 20:40:28 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
items.push(item);
|
|
|
|
|
|
|
|
|
|
const stored_item: ITEM = await item_collection.create(item);
|
|
|
|
|
|
|
|
|
|
asserts.assertObjectMatch(stored_item, item);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const item of items) {
|
2025-10-21 21:52:06 -07:00
|
|
|
const fetched_by_email: ITEM[] = (
|
|
|
|
|
await item_collection.find({ email: item.email })
|
|
|
|
|
).map((entry) => entry.load());
|
2025-06-13 20:40:28 -07:00
|
|
|
asserts.assertLess(fetched_by_email.length, items.length);
|
|
|
|
|
asserts.assertGreater(fetched_by_email.length, 0);
|
|
|
|
|
asserts.assert(fetched_by_email.find((email_item) => email_item.id === item.id));
|
|
|
|
|
|
2025-10-21 21:52:06 -07:00
|
|
|
const fetched_by_phone: ITEM[] = (
|
|
|
|
|
await item_collection.find({ phone: item.phone })
|
|
|
|
|
).map((entry) => entry.load());
|
2025-06-13 20:40:28 -07:00
|
|
|
asserts.assertLess(fetched_by_phone.length, items.length);
|
|
|
|
|
asserts.assertGreater(fetched_by_phone.length, 0);
|
|
|
|
|
asserts.assert(fetched_by_phone.find((phone_item) => phone_item.id === item.id));
|
|
|
|
|
|
2025-10-21 21:52:06 -07:00
|
|
|
const words_in_value: string[] = item.value
|
|
|
|
|
.split(/\W/)
|
|
|
|
|
.filter((word) => word.length > 3);
|
|
|
|
|
const random_word_in_value: string =
|
|
|
|
|
words_in_value[Math.floor(Math.random() * words_in_value.length)];
|
|
|
|
|
const fetched_by_word_in_value: ITEM[] = (
|
|
|
|
|
await item_collection.find({ by_character_test: random_word_in_value })
|
|
|
|
|
).map((entry) => entry.load());
|
2025-06-13 20:40:28 -07:00
|
|
|
asserts.assertLess(fetched_by_word_in_value.length, items.length);
|
|
|
|
|
asserts.assertGreater(fetched_by_word_in_value.length, 0);
|
2025-10-21 21:52:06 -07:00
|
|
|
asserts.assert(
|
|
|
|
|
fetched_by_word_in_value.find(
|
|
|
|
|
(word_in_value_item) => word_in_value_item.id === item.id,
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < 10; ++i) {
|
|
|
|
|
const random_item = items[Math.floor(Math.random() * items.length)];
|
|
|
|
|
asserts.assert(random_item);
|
|
|
|
|
|
|
|
|
|
const criteria: Record<string, string> = {
|
|
|
|
|
stable: "stable",
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (Math.random() < 0.5) {
|
|
|
|
|
criteria.email = random_item.email;
|
|
|
|
|
} else {
|
|
|
|
|
criteria.phone = random_item.phone;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const found_entries = await item_collection.find(criteria);
|
|
|
|
|
asserts.assertEquals(found_entries.length, 1);
|
|
|
|
|
|
|
|
|
|
const found: ITEM = found_entries[0].load();
|
|
|
|
|
|
|
|
|
|
asserts.assert(found);
|
|
|
|
|
asserts.assertEquals(found, random_item);
|
2025-06-13 20:40:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// leave one item behind so the whole db for this test doesn't get cleaned up so I can hand-review it
|
2025-09-21 17:16:50 -07:00
|
|
|
// for (const item of items.slice(1)) {
|
|
|
|
|
// await item_collection.delete(item);
|
2025-06-13 20:40:28 -07:00
|
|
|
|
2025-09-21 17:16:50 -07:00
|
|
|
// const fetched_by_email: ITEM[] = (await item_collection.find({ email: item.email })).map((entry) => entry.load());
|
|
|
|
|
// asserts.assertFalse(fetched_by_email.find((email_item) => email_item.id === item.id));
|
2025-06-13 20:40:28 -07:00
|
|
|
|
2025-09-21 17:16:50 -07:00
|
|
|
// const fetched_by_phone: ITEM[] = (await item_collection.find({ phone: item.phone })).map((entry) => entry.load());
|
|
|
|
|
// asserts.assertFalse(fetched_by_phone.find((phone_item) => phone_item.id === item.id));
|
2025-06-13 20:40:28 -07:00
|
|
|
|
2025-09-21 17:16:50 -07:00
|
|
|
// const words_in_value: string[] = item.value.split(/\W/).filter((word) => word.length > 3);
|
|
|
|
|
// const random_word_in_value: string = words_in_value[Math.floor(Math.random() * words_in_value.length)];
|
|
|
|
|
// const fetched_by_word_in_value: ITEM[] = (await item_collection.find({ by_character_test: random_word_in_value })).map((
|
|
|
|
|
// entry
|
|
|
|
|
// ) => entry.load());
|
|
|
|
|
// asserts.assertFalse(fetched_by_word_in_value.find((word_in_value_item) => word_in_value_item.id === item.id));
|
|
|
|
|
// }
|
2025-10-21 21:52:06 -07:00
|
|
|
},
|
2025-06-13 20:40:28 -07:00
|
|
|
});
|