simpler ReacordTester with more parallelizing

This commit is contained in:
itsMapleLeaf
2022-08-07 12:57:14 -05:00
parent 74bada9351
commit fd8f85ea89
7 changed files with 79 additions and 105 deletions

View File

@@ -1,16 +1,11 @@
import { ComponentType } from "discord.js" import { ComponentType } from "discord.js"
import React from "react" import React from "react"
import { beforeAll, expect, test } from "vitest" import { expect, test } from "vitest"
import { ActionRow, Button, Option, Select } from "../src/main" import { ActionRow, Button, Option, Select } from "../src/main"
import { ReacordTester } from "./tester" import { ReacordTester } from "./tester"
let tester: ReacordTester
beforeAll(async () => {
tester = await ReacordTester.create()
})
test("action row", async () => { test("action row", async () => {
const { message } = await tester.render( const { message } = await ReacordTester.render(
"action row", "action row",
<> <>
<Button label="outside button" onClick={() => {}} /> <Button label="outside button" onClick={() => {}} />

View File

@@ -1,5 +1,5 @@
import React from "react" import React from "react"
import { beforeAll, expect, test } from "vitest" import { expect, test } from "vitest"
import { import {
Embed, Embed,
EmbedAuthor, EmbedAuthor,
@@ -11,15 +11,10 @@ import {
} from "../src/main" } from "../src/main"
import { ReacordTester } from "./tester" import { ReacordTester } from "./tester"
let tester: ReacordTester
beforeAll(async () => {
tester = await ReacordTester.create()
})
test("kitchen sink", async () => { test("kitchen sink", async () => {
const now = new Date() const now = new Date()
const { message } = await tester.render( const { message } = await ReacordTester.render(
"kitchen sink", "kitchen sink",
<> <>
<Embed color={0xfe_ee_ef}> <Embed color={0xfe_ee_ef}>
@@ -78,7 +73,7 @@ test("kitchen sink", async () => {
}) })
test("author variants", async () => { test("author variants", async () => {
const { message } = await tester.render( const { message } = await ReacordTester.render(
"author variants", "author variants",
<> <>
<Embed> <Embed>
@@ -112,7 +107,7 @@ test("author variants", async () => {
}, 20_000) }, 20_000)
test("field variants", async () => { test("field variants", async () => {
const { message } = await tester.render( const { message } = await ReacordTester.render(
"field variants", "field variants",
<> <>
<Embed> <Embed>
@@ -157,7 +152,7 @@ test("field variants", async () => {
test("footer variants", async () => { test("footer variants", async () => {
const now = new Date() const now = new Date()
const { message } = await tester.render( const { message } = await ReacordTester.render(
"footer variants", "footer variants",
<> <>
<Embed> <Embed>
@@ -205,7 +200,7 @@ test("footer variants", async () => {
test("embed props", async () => { test("embed props", async () => {
const now = new Date() const now = new Date()
const { message } = await tester.render( const { message } = await ReacordTester.render(
"embed props", "embed props",
<Embed <Embed
title="title text" title="title text"

View File

@@ -1,5 +1,6 @@
import { ReacordTester } from "./tester" import { ReacordTester } from "./tester"
export async function setup() { export async function setup() {
console.info("Running test setup...")
await ReacordTester.removeChannels() await ReacordTester.removeChannels()
} }

View File

@@ -1,16 +1,11 @@
import { ButtonStyle, ComponentType } from "discord.js" import { ButtonStyle, ComponentType } from "discord.js"
import React from "react" import React from "react"
import { beforeEach, expect, test } from "vitest" import { expect, test } from "vitest"
import { Link } from "../src/main" import { Link } from "../src/main"
import { ReacordTester } from "./tester" import { ReacordTester } from "./tester"
let tester: ReacordTester
beforeEach(async () => {
tester = await ReacordTester.create()
})
test("link", async () => { test("link", async () => {
const { message } = await tester.render( const { message } = await ReacordTester.render(
"link", "link",
<> <>
<Link url="https://example.com/">link text</Link> <Link url="https://example.com/">link text</Link>

View File

@@ -1,14 +1,9 @@
import { waitFor } from "@reacord/helpers/wait-for.js" import { waitFor } from "@reacord/helpers/wait-for.js"
import * as React from "react" import * as React from "react"
import { beforeAll, expect, test } from "vitest" import { expect, test } from "vitest"
import { Button, Embed, EmbedField, EmbedTitle } from "../src/main" import { Button, Embed, EmbedField, EmbedTitle } from "../src/main"
import { ReacordTester } from "./tester" import { ReacordTester } from "./tester"
let tester: ReacordTester
beforeAll(async () => {
tester = await ReacordTester.create()
})
test.skip("rendering behavior", async () => { test.skip("rendering behavior", async () => {
// const tester = new ReacordTester() // const tester = new ReacordTester()
// const reply = tester.reply() // const reply = tester.reply()
@@ -239,7 +234,7 @@ test.skip("rendering behavior", async () => {
}) })
test("destroy()", async () => { test("destroy()", async () => {
const { message, channel, instance } = await tester.render( const { message, channel, instance } = await ReacordTester.render(
"destroy()", "destroy()",
<> <>
some text some text

View File

@@ -1,5 +1,4 @@
import { raise } from "@reacord/helpers/raise" import { raise } from "@reacord/helpers/raise"
import type { Client } from "discord.js"
import { CategoryChannel, ChannelType, GatewayIntentBits } from "discord.js" import { CategoryChannel, ChannelType, GatewayIntentBits } from "discord.js"
import { kebabCase } from "lodash-es" import { kebabCase } from "lodash-es"
import { randomBytes } from "node:crypto" import { randomBytes } from "node:crypto"
@@ -8,30 +7,26 @@ import { createDiscordClient } from "../src/create-discord-client"
import { ReacordClient } from "../src/main" import { ReacordClient } from "../src/main"
import { testEnv } from "./test-env" import { testEnv } from "./test-env"
export class ReacordTester { const reacord = new ReacordClient({
private static client?: Client token: testEnv.TEST_BOT_TOKEN,
})
static async removeChannels() { const clientPromise = createDiscordClient(testEnv.TEST_BOT_TOKEN, {
const client = await ReacordTester.getClient() intents: GatewayIntentBits.Guilds | GatewayIntentBits.GuildMessages,
const category = await ReacordTester.getCategory(client) })
const categoryPromise = getCategory()
async function removeChannels() {
const category = await categoryPromise
for (const [, channel] of category.children.cache) { for (const [, channel] of category.children.cache) {
await channel.delete() await channel.delete()
} }
} }
static async create() { async function getCategory() {
const client = await ReacordTester.getClient() const client = await clientPromise
const category = await ReacordTester.getCategory(client)
return new ReacordTester(client, category)
}
private static async getClient() {
return (this.client ??= await createDiscordClient(testEnv.TEST_BOT_TOKEN, {
intents: GatewayIntentBits.Guilds | GatewayIntentBits.GuildMessages,
}))
}
private static async getCategory(client: Client<true>) {
const category = const category =
client.channels.cache.get(testEnv.TEST_CATEGORY_ID) ?? client.channels.cache.get(testEnv.TEST_CATEGORY_ID) ??
(await client.channels.fetch(testEnv.TEST_CATEGORY_ID)) (await client.channels.fetch(testEnv.TEST_CATEGORY_ID))
@@ -40,21 +35,17 @@ export class ReacordTester {
throw new TypeError("Category channel not found") throw new TypeError("Category channel not found")
} }
return category return category
} }
private reacord?: ReacordClient async function getTestChannel(testName: string) {
constructor(readonly client: Client, readonly category: CategoryChannel) {}
private async getTestChannel(testName: string) {
const hash = randomBytes(16).toString("hex").slice(0, 6) const hash = randomBytes(16).toString("hex").slice(0, 6)
const channelName = `${kebabCase(testName)}-${hash}` const channelName = `${kebabCase(testName)}-${hash}`
let channel = this.category.children.cache.find( const category = await categoryPromise
(the) => the.name === channelName,
) let channel = category.children.cache.find((the) => the.name === channelName)
if (!channel || !channel.isTextBased()) { if (!channel || !channel.isTextBased()) {
channel = await this.category.children.create({ channel = await category.children.create({
type: ChannelType.GuildText, type: ChannelType.GuildText,
name: channelName, name: channelName,
}) })
@@ -65,21 +56,21 @@ export class ReacordTester {
} }
return channel return channel
} }
async render(testName: string, content?: ReactNode) { async function render(testName: string, content?: ReactNode) {
this.reacord ??= new ReacordClient({ const channel = await getTestChannel(testName)
token: testEnv.TEST_BOT_TOKEN,
})
const channel = await this.getTestChannel(testName)
await channel.sendTyping() await channel.sendTyping()
const instance = this.reacord.send(channel.id, content) const instance = reacord.send(channel.id, content)
const result = await channel.awaitMessages({ max: 1 }) const result = await channel.awaitMessages({ max: 1 })
const message = result.first() ?? raise("failed to send message") const message = result.first() ?? raise("failed to send message")
return { channel, message, instance } return { channel, message, instance }
} }
export const ReacordTester = {
render,
removeChannels,
} }

View File

@@ -9,8 +9,10 @@ export default defineConfig({
globalSetup: ["packages/reacord/test/global-setup.ts"], globalSetup: ["packages/reacord/test/global-setup.ts"],
threads: false, threads: false,
isolate: false, isolate: false,
hookTimeout: 20_000,
testTimeout: 20_000,
reporters: ["verbose"], reporters: ["verbose"],
// rate limiting means these timeouts need to be long af
hookTimeout: 60_000,
testTimeout: 60_000,
}, },
}) })