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'; import { by_lurid } from '@andyburke/fsdb/organizers'; 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 }), custom_organizing_test: new FSDB_INDEXER_SYMLINKS({ name: 'custom_organizing_test', organize: (word) => [word], organize_id: (id: string) => { return [id.substring(0, 4), ...by_lurid(id)]; }, get_values_to_index: (item: ITEM) => item.value.split(/\W/).filter((word) => word.length > 3), to_many: true }), 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 ) ); const fetched_by_custom_organization_index: ITEM[] = ( await item_collection.find({ custom_organizing_test: random_word_in_value }) ).map((entry) => entry.load()); asserts.assertLess(fetched_by_custom_organization_index.length, items.length); asserts.assertGreater(fetched_by_custom_organization_index.length, 0); asserts.assert( fetched_by_custom_organization_index.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)); // } } });