Files
reacord/packages/reacord/scripts/discordjs-manual-test.tsx
2022-07-28 22:15:49 -05:00

186 lines
4.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { ChannelType, Client, IntentsBitField, TextChannel } 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)
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 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}`,
)
}
const getTestCaseChannelName = (test: TestCase, index: number) =>
`${String(index).padStart(3, "0")}-${kebabCase(test.name)}`
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()
}
return channel
}
await channel?.delete()
return await category.children.create({
type: ChannelType.GuildText,
name: channelName,
position: index,
})
}
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)
}),
),
])