restore old tests + more parallel things

This commit is contained in:
itsMapleLeaf
2022-07-28 22:15:49 -05:00
parent 831bf9ea44
commit f2a322e4cd
2 changed files with 161 additions and 252 deletions

View File

@@ -1,134 +0,0 @@
import type { TextChannel } from "discord.js"
import { ChannelType, Client, IntentsBitField } from "discord.js"
import "dotenv/config"
import { kebabCase } from "lodash-es"
import * as React from "react"
import { useState } from "react"
import {
Button,
Option,
ReacordDiscordJs,
Select,
useInstance,
} from "../library/main"
const client = new Client({ intents: IntentsBitField.Flags.Guilds })
const reacord = new ReacordDiscordJs(client)
await client.login(process.env.TEST_BOT_TOKEN)
const guild = await client.guilds.fetch(process.env.TEST_GUILD_ID!)
const category = await guild.channels.fetch(process.env.TEST_CATEGORY_ID!)
if (category?.type !== ChannelType.GuildCategory) {
throw new Error(
`channel ${process.env.TEST_CATEGORY_ID} is not a guild category. received ${category?.type}`,
)
}
for (const [, channel] of category.children.cache) {
await channel.delete()
}
let prefix = 0
const createTest = async (
name: string,
block: (channel: TextChannel) => void | Promise<unknown>,
) => {
prefix += 1
const channel = await category.children.create({
type: ChannelType.GuildText,
name: `${String(prefix).padStart(3, "0")}-${kebabCase(name)}`,
})
await block(channel)
}
await createTest("basic", (channel) => {
reacord.send(channel.id, "Hello, world!")
})
await createTest("counter", (channel) => {
const Counter = () => {
const [count, setCount] = React.useState(0)
return (
<>
count: {count}
<Button
style="primary"
emoji=""
onClick={() => setCount(count + 1)}
/>
<Button
style="primary"
emoji=""
onClick={() => setCount(count - 1)}
/>
<Button label="reset" onClick={() => setCount(0)} />
</>
)
}
reacord.send(channel.id, <Counter />)
})
await createTest("select", (channel) => {
function FruitSelect({ onConfirm }: { onConfirm: (choice: string) => void }) {
const [value, setValue] = useState<string>()
return (
<>
<Select
placeholder="choose a fruit"
value={value}
onChangeValue={setValue}
>
<Option value="🍎" emoji="🍎" label="apple" description="it red" />
<Option value="🍌" emoji="🍌" label="banana" description="bnanbna" />
<Option value="🍒" emoji="🍒" label="cherry" description="heh" />
</Select>
<Button
label="confirm"
disabled={value == undefined}
onClick={() => {
if (value) onConfirm(value)
}}
/>
</>
)
}
const instance = reacord.send(
channel.id,
<FruitSelect
onConfirm={(value) => {
instance.render(`you chose ${value}`)
instance.deactivate()
}}
/>,
)
})
await createTest("ephemeral button", (channel) => {
reacord.send(
channel.id,
<>
<Button
label="public clic"
onClick={(event) =>
event.reply(`${event.guild?.member.displayName} clic`)
}
/>
<Button
label="clic"
onClick={(event) => event.ephemeralReply("you clic")}
/>
</>,
)
})
await createTest("delete this", (channel) => {
function DeleteThis() {
const instance = useInstance()
return <Button label="delete this" onClick={() => instance.destroy()} />
}
reacord.send(channel.id, <DeleteThis />)
})

View File

@@ -1,142 +1,185 @@
import { raise } from "@reacord/helpers/raise.js"
import { waitFor } from "@reacord/helpers/wait-for.js"
import { ChannelType, Client, IntentsBitField, TextChannel } from "discord.js"
import "dotenv/config"
import { kebabCase } from "lodash-es"
import prettyMilliseconds from "pretty-ms"
import React, { useEffect, useState } from "react"
import { Button, ReacordDiscordJs } from "../library.new/main"
import * as React from "react"
import { useState } from "react"
import {
Button,
Option,
ReacordDiscordJs,
Select,
useInstance,
} from "../library/main"
const client = new Client({ intents: IntentsBitField.Flags.Guilds })
const reacord = new ReacordDiscordJs(client)
type TestCase = {
name: string
run: (channel: TextChannel) => void | Promise<unknown>
}
const tests: TestCase[] = [
{
name: "basic",
run: async (channel) => {
await channel.send("hello world")
},
},
{
name: "counter",
run: (channel) => {
const Counter = () => {
const [count, setCount] = React.useState(0)
return (
<>
count: {count}
<Button
style="primary"
emoji=""
onClick={() => setCount(count + 1)}
/>
<Button
style="primary"
emoji=""
onClick={() => setCount(count - 1)}
/>
<Button label="reset" onClick={() => setCount(0)} />
</>
)
}
reacord.send(channel.id, <Counter />)
},
},
{
name: "ephemeral button",
run: (channel) => {
reacord.send(
channel.id,
<>
<Button
label="public clic"
onClick={(event) =>
event.reply(`${event.guild?.member.displayName} clic`)
}
/>
<Button
label="clic"
onClick={(event) => event.ephemeralReply("you clic")}
/>
</>,
)
},
},
{
name: "select",
run: (channel) => {
function FruitSelect({
onConfirm,
}: {
onConfirm: (choice: string) => void
}) {
const [value, setValue] = useState<string>()
return (
<>
<Select
placeholder="choose a fruit"
value={value}
onChangeValue={setValue}
>
<Option
value="🍎"
emoji="🍎"
label="apple"
description="it red"
/>
<Option
value="🍌"
emoji="🍌"
label="banana"
description="bnanbna"
/>
<Option value="🍒" emoji="🍒" label="cherry" description="heh" />
</Select>
<Button
label="confirm"
disabled={value == undefined}
onClick={() => {
if (value) onConfirm(value)
}}
/>
</>
)
}
const instance = reacord.send(
channel.id,
<FruitSelect
onConfirm={(value) => {
instance.render(`you chose ${value}`)
instance.deactivate()
}}
/>,
)
},
},
{
name: "delete this",
run: (channel) => {
function DeleteThis() {
const instance = useInstance()
return <Button label="delete this" onClick={() => instance.destroy()} />
}
reacord.send(channel.id, <DeleteThis />)
},
},
]
await client.login(process.env.TEST_BOT_TOKEN)
const guild = await client.guilds.fetch(process.env.TEST_GUILD_ID!)
const category = await guild.channels.fetch(process.env.TEST_CATEGORY_ID!)
const category = await client.channels.fetch(process.env.TEST_CATEGORY_ID!)
if (category?.type !== ChannelType.GuildCategory) {
throw new Error(
`channel ${process.env.TEST_CATEGORY_ID} is not a guild category. received ${category?.type}`,
)
}
let index = 0
const createTest = async (
name: string,
description: string,
block: (channel: TextChannel) => void | Promise<unknown>,
) => {
const channelName = `${String(index).padStart(3, "0")}-${kebabCase(name)}`
const getTestCaseChannelName = (test: TestCase, index: number) =>
`${String(index).padStart(3, "0")}-${kebabCase(test.name)}`
let channel = category.children.cache.find((ch) => ch.name === channelName)
const testCaseNames = new Set(
tests.map((test, index) => getTestCaseChannelName(test, index)),
)
const channelsWithoutTestCase = category.children.cache.filter(
(channel) => !testCaseNames.has(channel.name),
)
const getTestCaseChannel = async (channelName: string, index: number) => {
const channel = category.children.cache.find((ch) => ch.name === channelName)
if (channel instanceof TextChannel) {
for (const [, msg] of await channel.messages.fetch()) {
await msg.delete()
}
} else {
await channel?.delete()
channel = await category.children.create({
type: ChannelType.GuildText,
name: channelName,
topic: description,
position: index,
})
return channel
}
await block(channel)
index += 1
await channel?.delete()
return await category.children.create({
type: ChannelType.GuildText,
name: channelName,
position: index,
})
}
await createTest(
"buttons",
"should show button text, emojis, and make automatic action rows",
async (channel) => {
reacord.send(
channel.id,
<>
<Button label="strawberry" onClick={() => {}} />
<Button emoji="🍓" onClick={() => {}} />
<Button label="strawberry" emoji="🍓" onClick={() => {}} />
</>,
)
reacord.send(
channel.id,
<>
<Button label="primary" style="primary" onClick={() => {}} />
<Button label="secondary" style="secondary" onClick={() => {}} />
<Button label="success" style="success" onClick={() => {}} />
<Button label="danger" style="danger" onClick={() => {}} />
</>,
)
reacord.send(
channel.id,
<>
<Button label="disabled" disabled onClick={() => {}} />
</>,
)
},
)
await createTest("basic", "should update over time", (channel) => {
function Timer() {
const [startDate] = useState(() => new Date())
const [currentDate, setCurrentDate] = useState(startDate)
useEffect(() => {
const id = setInterval(() => {
setCurrentDate(new Date())
}, 3000)
return () => clearInterval(id)
}, [])
return (
<>
this component has been running for{" "}
{prettyMilliseconds(currentDate.valueOf() - startDate.valueOf(), {
verbose: true,
})}
</>
)
}
reacord.send(channel.id, <Timer />)
})
await createTest(
"immediate renders",
`should process renders in sequence; this should show "hi moon"`,
async (channel) => {
const instance = reacord.send(channel.id)
instance.render("hi world")
instance.render("hi moon")
},
)
await createTest(
"destroy",
"should remove the message; this channel should be empty",
async (channel) => {
const instance = reacord.send(channel.id)
instance.render("hi world")
instance.render("hi moon")
await waitFor(async () => {
const messages = await channel.messages.fetch({ limit: 1 })
if (messages.first()?.content !== "hi moon") {
raise("not ready")
}
})
instance.destroy()
},
)
await createTest(
"immediate destroy",
"should never show if called immediately; this channel should be empty",
async (channel) => {
const instance = reacord.send(channel.id)
instance.render("hi world")
instance.render("hi moon")
instance.destroy()
},
)
await Promise.all([
Promise.all(channelsWithoutTestCase.map((channel) => channel.delete())),
Promise.all(
tests.map(async (test, index) => {
const channelName = getTestCaseChannelName(test, index)
const channel = await getTestCaseChannel(channelName, index)
await test.run(channel)
}),
),
])