Skip to content

Commit

Permalink
test: Add tests. (#442)
Browse files Browse the repository at this point in the history
  • Loading branch information
vxern authored Sep 30, 2024
2 parents a7dddff + 8c96b84 commit a014eb6
Show file tree
Hide file tree
Showing 12 changed files with 239 additions and 101 deletions.
35 changes: 17 additions & 18 deletions source/library/adapters/databases/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,7 @@ abstract class DocumentConventions<Metadata = any> {
}: { document: Model; data: IdentifierDataOrMetadata<Model, Metadata>; collection: Collection }) {
this.document = document as Model & Metadata;

this.assignAccessorsToModel();

this.#assignAccessorsToModel();
this.#populateModelData(data, { collection });

const partialId = this.#getPartialIdFromData(data);
Expand All @@ -229,15 +228,13 @@ abstract class DocumentConventions<Metadata = any> {
this.idParts = partialId.split(constants.special.database.separator);
}

#getPartialIdFromData(data: IdentifierDataOrMetadata<Model, Metadata>): string {
let partialId: string;
if (this.hasMetadata(data)) {
partialId = Model.decomposeId(this.id)[1];
} else {
partialId = Model.buildPartialId(data as IdentifierData<Model>);
}

return partialId;
#assignAccessorsToModel(): void {
const conventions = this;
Object.defineProperty(this.document, "id", {
get(): string {
return conventions.id;
},
});
}

#populateModelData(
Expand All @@ -252,13 +249,15 @@ abstract class DocumentConventions<Metadata = any> {
}
}

assignAccessorsToModel(): void {
const conventions = this;
Object.defineProperty(this.document, "id", {
get(): string {
return conventions.id;
},
});
#getPartialIdFromData(data: IdentifierDataOrMetadata<Model, Metadata>): string {
let partialId: string;
if (this.hasMetadata(data)) {
partialId = Model.decomposeId(this.id)[1];
} else {
partialId = Model.buildPartialId(data as IdentifierData<Model>);
}

return partialId;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion source/library/client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Environment } from "logos:core/loaders/environment";
import { Collector, type InteractionCollector } from "logos/collectors.ts";
import { Collector, type InteractionCollector } from "logos/collectors";
import commands from "logos/commands/commands";
import { DiscordConnection } from "logos/connection";
import { Diagnostics } from "logos/diagnostics";
Expand Down
23 changes: 17 additions & 6 deletions source/library/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ class DiscordConnection {
readonly bot: Discord.Bot;

constructor({
log,
log = constants.loggers.silent,
environment,
eventHandlers,
cacheHandlers,
eventHandlers = {},
cacheHandlers = {},
}: {
log: pino.Logger;
log?: pino.Logger;
environment: Environment;
eventHandlers: Partial<Discord.EventHandlers>;
cacheHandlers: Partial<Discord.Transformers["customizers"]>;
eventHandlers?: Partial<Discord.EventHandlers>;
cacheHandlers?: Partial<Discord.Transformers["customizers"]>;
}) {
this.log = log.child({ name: "DiscordConnection" });
this.bot = Discord.createBot({
Expand Down Expand Up @@ -46,6 +46,17 @@ class DiscordConnection {
loggerFactory: (name) => constants.loggers.discordeno.child({ name: name.toLowerCase() }),
});
this.bot.rest.createBaseHeaders = () => ({ "User-Agent": "Logos (https://github.com/vxern/logos)" });
// REMINDER(vxern): The Discordeno shutdown() method has a weird delay, so we override its definition to
// remove the delay.
this.bot.gateway.shutdown = async (code, reason, clearReshardingInterval = true) => {
for (const shard of this.bot.gateway.shards.values()) {
shard.close(code, reason);
}

if (clearReshardingInterval) {
clearInterval(this.bot.gateway.resharding.checkIntervalId);
}
};
}

async open(): Promise<void> {
Expand Down
2 changes: 1 addition & 1 deletion source/library/services/music.ts
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ class ListingManager extends EventEmitter {
return listing;
}

dispose() {
dispose(): void {
this.removeAllListeners();
}
}
Expand Down
2 changes: 1 addition & 1 deletion source/library/stores/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class DatabaseStore {
return DatabaseStore.#classes[collection];
}

async setup({ prefetchDocuments }: { prefetchDocuments: boolean }): Promise<void> {
async setup({ prefetchDocuments = false }: { prefetchDocuments?: boolean } = {}): Promise<void> {
this.log.info("Setting up database store...");

await this.#adapter.setup();
Expand Down
4 changes: 2 additions & 2 deletions source/library/stores/interactions.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { timestamp, trim } from "logos:constants/formatting";
import { getSnowflakeFromIdentifier } from "logos:constants/patterns";
import type { Client } from "logos/client";
import { InteractionCollector } from "logos/collectors.ts";
import type { CommandStore } from "logos/stores/commands.ts";
import { InteractionCollector } from "logos/collectors";
import type { CommandStore } from "logos/stores/commands";
import type pino from "pino";

type InteractionCallbackData = Omit<Discord.InteractionCallbackData, "flags">;
Expand Down
7 changes: 5 additions & 2 deletions source/library/stores/localisations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ class LocalisationStore {

readonly #localisations: Localisations;

constructor({ log, localisations }: { log: pino.Logger; localisations: RawLocalisations }) {
constructor({
log = constants.loggers.silent,
localisations,
}: { log?: pino.Logger; localisations: RawLocalisations }) {
this.log = log.child({ name: "LocalisationStore" });

this.#localisations = LocalisationStore.#buildLocalisations(localisations);
Expand Down Expand Up @@ -230,7 +233,7 @@ class LocalisationStore {
const pluralised = pluralise(`${quantity}`, { one, two, many });
if (pluralised === undefined) {
this.log.warn(`Could not pluralise string with key '${key}' in ${language}.`);
return key;
return constants.special.missingString;
}

return pluralised;
Expand Down
77 changes: 62 additions & 15 deletions test/dependencies.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,74 @@
import { afterEach, beforeEach } from "bun:test";
import { mockEnvironment } from "logos:test/mocks";
import { type Environment, loadEnvironment } from "logos:core/loaders/environment";
import { CacheStore } from "logos/stores/cache";
import { DatabaseStore } from "logos/stores/database";
import { DiscordConnection } from "logos/connection";

type DependencyProvider<T> = () => T;

function useDatabaseStore(): DependencyProvider<DatabaseStore> {
let database: DatabaseStore;
function createProvider<T>({
create,
destroy,
}: {
create: () => Promise<T> | T;
destroy?: (object: T) => Promise<void> | void;
}): () => DependencyProvider<T> {
let object: T;

beforeEach(async () => {
database = DatabaseStore.create({
log: constants.loggers.silent,
environment: mockEnvironment,
cache: new CacheStore({ log: constants.loggers.silent }),
});
await database.setup({ prefetchDocuments: false });
});
beforeEach(async () => (object = await create()));

if (destroy !== undefined) {
afterEach(() => destroy(object));
}

return () => () => object;
}

function createEnvironment(): Environment {
return loadEnvironment({ log: constants.loggers.silent });
}

afterEach(async () => {
await database.teardown();
function createDatabaseStore(): DatabaseStore {
return DatabaseStore.create({
log: constants.loggers.silent,
environment: createEnvironment(),
cache: new CacheStore({ log: constants.loggers.silent }),
});
}

let connection: DiscordConnection;
/**
* This is the only dependency we do not re-create on every call. It takes at least 5 seconds to establish a connection
* to Discord, which is definitely not the kind of overhead we want when running tests.
*/
function createDiscordConnection(): DiscordConnection {
if (connection !== undefined) {
return connection;
}

connection = new DiscordConnection({ environment: loadEnvironment({ log: constants.loggers.silent }) });

return () => database;
return connection;
}

export { useDatabaseStore };
const useEnvironment = createProvider({ create: () => createEnvironment() });
const useDatabaseStore = createProvider({
create: async () => {
const database = createDatabaseStore();
await database.setup();

return database;
},
destroy: (database) => database.teardown(),
});
const useDiscordConnection = createProvider({
create: async () => {
const connection = createDiscordConnection();
await connection.open();

return connection;
},
destroy: (connection) => connection.close(),
});

export { useEnvironment, useDatabaseStore, useDiscordConnection };
38 changes: 35 additions & 3 deletions test/source/library/connection.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,43 @@
import { describe } from "bun:test";
import { describe, it } from "bun:test";
import { useEnvironment } from "logos:test/dependencies";
import { expect } from "chai";
import { DiscordConnection } from "logos/connection";

const TEST_TIMEOUT = constants.time.second * 10;

describe("DiscordConnection", () => {
const environment = useEnvironment();

describe("open()", () => {
// TODO(vxern): Add tests.
it(
"opens a gateway connection to Discord.",
async () => {
const connection = new DiscordConnection({ environment: environment() });

expect(() => connection.bot.gateway.editBotStatus({ status: "offline" })).to.throw;

await connection.open();

expect(() => connection.bot.gateway.editBotStatus({ status: "offline" })).to.not.throw;
},
{ timeout: TEST_TIMEOUT },
);
});

describe("close()", () => {
// TODO(vxern): Add tests.
it(
"closes the gateway connection to Discord.",
async () => {
const connection = new DiscordConnection({ environment: environment() });
await connection.open();

expect(() => connection.bot.gateway.editBotStatus({ status: "offline" })).to.not.throw;

await connection.close();

expect(() => connection.bot.gateway.editBotStatus({ status: "offline" })).to.throw;
},
{ timeout: TEST_TIMEOUT },
);
});
});
3 changes: 3 additions & 0 deletions test/source/library/stores/cache.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { describe } from "bun:test";

describe("CacheStore", () => {});
20 changes: 1 addition & 19 deletions test/source/library/stores/database.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe } from "bun:test";

describe("Database", () => {
describe("DatabaseStore", () => {
describe("start()", () => {
// TODO(vxern): Add tests.
});
Expand Down Expand Up @@ -29,21 +29,3 @@ describe("Database", () => {
// TODO(vxern): Add tests.
});
});

describe("DocumentSession", () => {
describe("instantiateModel()", () => {
// TODO(vxern): Add tests.
});

describe("get()", () => {
// TODO(vxern): Add tests.
});

describe("set()", () => {
// TODO(vxern): Add tests.
});

describe("remove()", () => {
// TODO(vxern): Add tests.
});
});
Loading

0 comments on commit a014eb6

Please sign in to comment.