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"; Deno.test({ name: "index some items", permissions: { env: true, // https://github.com/denoland/deno/discussions/17258 read: true, write: true, }, fn: async () => { type ITEM = { id: string; email: string; phone: string; stable: string; value: string; }; const item_collection: fsdb.FSDB_COLLECTION = new fsdb.FSDB_COLLECTION({ name: "test-04-items", root: get_data_dir() + "/test-04-items", indexers: { email: new FSDB_INDEXER_SYMLINKS({ name: "email", field: "email", organize: by_email, }), phone: new FSDB_INDEXER_SYMLINKS({ name: "phone", field: "phone", organize: by_phone, }), stable: new FSDB_INDEXER_SYMLINKS({ name: "stable", field: "stable", to_many: true, organize: by_character, }), by_character_test: new FSDB_INDEXER_SYMLINKS({ name: "by_character_test", organize: by_character, get_values_to_index: (item: ITEM) => item.value.split(/\W/).filter((word) => word.length > 3), to_many: true, }), by_possibly_undefined: new FSDB_INDEXER_SYMLINKS({ name: "by_possibly_undefined", organize: by_character, get_values_to_index: (item: ITEM) => item.email.indexOf(".com") > 0 ? [item.email] : [], to_many: true, }), }, }); asserts.assert(item_collection); const items: ITEM[] = []; for (let i = 0; i < 50; ++i) { const item = { id: lurid(), email: random_email_address(), phone: random_phone_number(), stable: "stable", value: sentence(), }; items.push(item); const stored_item: ITEM = await item_collection.create(item); asserts.assertObjectMatch(stored_item, item); } for (const item of items) { const fetched_by_email: ITEM[] = ( await item_collection.find({ email: item.email }) ).map((entry) => entry.load()); 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)); const fetched_by_phone: ITEM[] = ( await item_collection.find({ phone: item.phone }) ).map((entry) => entry.load()); 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)); 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.assertLess(fetched_by_word_in_value.length, items.length); asserts.assertGreater(fetched_by_word_in_value.length, 0); 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 = { 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); } // leave one item behind so the whole db for this test doesn't get cleaned up so I can hand-review it // for (const item of items.slice(1)) { // await item_collection.delete(item); // 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)); // 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)); // 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)); // } }, });