import { test, expect } from "bun:test"import { Question } from "../../src/question"import { Instance } from "../../src/project/instance"import { tmpdir } from "../fixture/fixture" test("ask - returns pending promise", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { const promise = Question.ask({ sessionID: "ses_test", questions: [ { question: "What would you like to do?", header: "Action", options: [ { label: "Option 1", description: "First option" }, { label: "Option 2", description: "Second option" }, ], }, ], }) expect(promise).toBeInstanceOf(Promise) }, })}) test("ask - adds to pending list", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { const questions = [ { question: "What would you like to do?", header: "Action", options: [ { label: "Option 1", description: "First option" }, { label: "Option 2", description: "Second option" }, ], }, ] Question.ask({ sessionID: "ses_test", questions, }) const pending = await Question.list() expect(pending.length).toBe(1) expect(pending[0].questions).toEqual(questions) }, })}) // reply tests test("reply - resolves the pending ask with answers", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { const questions = [ { question: "What would you like to do?", header: "Action", options: [ { label: "Option 1", description: "First option" }, { label: "Option 2", description: "Second option" }, ], }, ] const askPromise = Question.ask({ sessionID: "ses_test", questions, }) const pending = await Question.list() const requestID = pending[0].id await Question.reply({ requestID, answers: [["Option 1"]], }) const answers = await askPromise expect(answers).toEqual([["Option 1"]]) }, })}) test("reply - removes from pending list", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { Question.ask({ sessionID: "ses_test", questions: [ { question: "What would you like to do?", header: "Action", options: [ { label: "Option 1", description: "First option" }, { label: "Option 2", description: "Second option" }, ], }, ], }) const pending = await Question.list() expect(pending.length).toBe(1) await Question.reply({ requestID: pending[0].id, answers: [["Option 1"]], }) const pendingAfter = await Question.list() expect(pendingAfter.length).toBe(0) }, })}) test("reply - does nothing for unknown requestID", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { await Question.reply({ requestID: "que_unknown", answers: [["Option 1"]], }) // Should not throw }, })}) // reject tests test("reject - throws RejectedError", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { const askPromise = Question.ask({ sessionID: "ses_test", questions: [ { question: "What would you like to do?", header: "Action", options: [ { label: "Option 1", description: "First option" }, { label: "Option 2", description: "Second option" }, ], }, ], }) const pending = await Question.list() await Question.reject(pending[0].id) await expect(askPromise).rejects.toBeInstanceOf(Question.RejectedError) }, })}) test("reject - removes from pending list", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { const askPromise = Question.ask({ sessionID: "ses_test", questions: [ { question: "What would you like to do?", header: "Action", options: [ { label: "Option 1", description: "First option" }, { label: "Option 2", description: "Second option" }, ], }, ], }) const pending = await Question.list() expect(pending.length).toBe(1) await Question.reject(pending[0].id) askPromise.catch(() => {}) // Ignore rejection const pendingAfter = await Question.list() expect(pendingAfter.length).toBe(0) }, })}) test("reject - does nothing for unknown requestID", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { await Question.reject("que_unknown") // Should not throw }, })}) // multiple questions tests test("ask - handles multiple questions", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { const questions = [ { question: "What would you like to do?", header: "Action", options: [ { label: "Build", description: "Build the project" }, { label: "Test", description: "Run tests" }, ], }, { question: "Which environment?", header: "Env", options: [ { label: "Dev", description: "Development" }, { label: "Prod", description: "Production" }, ], }, ] const askPromise = Question.ask({ sessionID: "ses_test", questions, }) const pending = await Question.list() await Question.reply({ requestID: pending[0].id, answers: [["Build"], ["Dev"]], }) const answers = await askPromise expect(answers).toEqual([["Build"], ["Dev"]]) }, })}) // list tests test("list - returns all pending requests", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { Question.ask({ sessionID: "ses_test1", questions: [ { question: "Question 1?", header: "Q1", options: [{ label: "A", description: "A" }], }, ], }) Question.ask({ sessionID: "ses_test2", questions: [ { question: "Question 2?", header: "Q2", options: [{ label: "B", description: "B" }], }, ], }) const pending = await Question.list() expect(pending.length).toBe(2) }, })}) test("list - returns empty when no pending", async () => { await using tmp = await tmpdir({ git: true }) await Instance.provide({ directory: tmp.path, fn: async () => { const pending = await Question.list() expect(pending.length).toBe(0) }, })})
import { test, expect } from "bun:test"
import { Question } from "../../src/question"
import { Instance } from "../../src/project/instance"
import { tmpdir } from "../fixture/fixture"
test("ask - returns pending promise", async () => {
await using tmp = await tmpdir({ git: true })
await Instance.provide({
directory: tmp.path,
fn: async () => {
const promise = Question.ask({
sessionID: "ses_test",
questions: [
{
question: "What would you like to do?",
header: "Action",
options: [
{ label: "Option 1", description: "First option" },
{ label: "Option 2", description: "Second option" },
],
},
],
})
expect(promise).toBeInstanceOf(Promise)
},
})
})
test("ask - adds to pending list", async () => {
await using tmp = await tmpdir({ git: true })
await Instance.provide({
directory: tmp.path,
fn: async () => {
const questions = [
{
question: "What would you like to do?",
header: "Action",
options: [
{ label: "Option 1", description: "First option" },
{ label: "Option 2", description: "Second option" },
],
},
]
Question.ask({
sessionID: "ses_test",
questions,
})
const pending = await Question.list()
expect(pending.length).toBe(1)
expect(pending[0].questions).toEqual(questions)
},
})
})
// reply tests
test("reply - resolves the pending ask with answers", async () => {
await using tmp = await tmpdir({ git: true })
await Instance.provide({
directory: tmp.path,
fn: async () => {
const questions = [
{
question: "What would you like to do?",
header: "Action",
options: [
{ label: "Option 1", description: "First option" },
{ label: "Option 2", description: "Second option" },
],
},
]
const askPromise = Question.ask({
sessionID: "ses_test",
questions,
})
const pending = await Question.list()
const requestID = pending[0].id
await Question.reply({
requestID,
answers: [["Option 1"]],
})
const answers = await askPromise
expect(answers).toEqual([["Option 1"]])
},
})
})
test("reply - removes from pending list", async () => {
await using tmp = await tmpdir({ git: true })
await Instance.provide({
directory: tmp.path,
fn: async () => {
Question.ask({
sessionID: "ses_test",
questions: [
{
question: "What would you like to do?",
header: "Action",
options: [
{ label: "Option 1", description: "First option" },
{ label: "Option 2", description: "Second option" },
],
},
],
})
const pending = await Question.list()
expect(pending.length).toBe(1)
await Question.reply({
requestID: pending[0].id,
answers: [["Option 1"]],
})
const pendingAfter = await Question.list()
expect(pendingAfter.length).toBe(0)
},
})
})
test("reply - does nothing for unknown requestID", async () => {
await using tmp = await tmpdir({ git: true })
await Instance.provide({
directory: tmp.path,
fn: async () => {
await Question.reply({
requestID: "que_unknown",
answers: [["Option 1"]],
})
// Should not throw
},
})
})
// reject tests
test("reject - throws RejectedError", async () => {
await using tmp = await tmpdir({ git: true })
await Instance.provide({
directory: tmp.path,
fn: async () => {
const askPromise = Question.ask({
sessionID: "ses_test",
questions: [
{
question: "What would you like to do?",
header: "Action",
options: [
{ label: "Option 1", description: "First option" },
{ label: "Option 2", description: "Second option" },
],
},
],
})
const pending = await Question.list()
await Question.reject(pending[0].id)
await expect(askPromise).rejects.toBeInstanceOf(Question.RejectedError)
},
})
})
test("reject - removes from pending list", async () => {
await using tmp = await tmpdir({ git: true })
await Instance.provide({
directory: tmp.path,
fn: async () => {
const askPromise = Question.ask({
sessionID: "ses_test",
questions: [
{
question: "What would you like to do?",
header: "Action",
options: [
{ label: "Option 1", description: "First option" },
{ label: "Option 2", description: "Second option" },
],
},
],
})
const pending = await Question.list()
expect(pending.length).toBe(1)
await Question.reject(pending[0].id)
askPromise.catch(() => {}) // Ignore rejection
const pendingAfter = await Question.list()
expect(pendingAfter.length).toBe(0)
},
})
})
test("reject - does nothing for unknown requestID", async () => {
await using tmp = await tmpdir({ git: true })
await Instance.provide({
directory: tmp.path,
fn: async () => {
await Question.reject("que_unknown")
// Should not throw
},
})
})
// multiple questions tests
test("ask - handles multiple questions", async () => {
await using tmp = await tmpdir({ git: true })
await Instance.provide({
directory: tmp.path,
fn: async () => {
const questions = [
{
question: "What would you like to do?",
header: "Action",
options: [
{ label: "Build", description: "Build the project" },
{ label: "Test", description: "Run tests" },
],
},
{
question: "Which environment?",
header: "Env",
options: [
{ label: "Dev", description: "Development" },
{ label: "Prod", description: "Production" },
],
},
]
const askPromise = Question.ask({
sessionID: "ses_test",
questions,
})
const pending = await Question.list()
await Question.reply({
requestID: pending[0].id,
answers: [["Build"], ["Dev"]],
})
const answers = await askPromise
expect(answers).toEqual([["Build"], ["Dev"]])
},
})
})
// list tests
test("list - returns all pending requests", async () => {
await using tmp = await tmpdir({ git: true })
await Instance.provide({
directory: tmp.path,
fn: async () => {
Question.ask({
sessionID: "ses_test1",
questions: [
{
question: "Question 1?",
header: "Q1",
options: [{ label: "A", description: "A" }],
},
],
})
Question.ask({
sessionID: "ses_test2",
questions: [
{
question: "Question 2?",
header: "Q2",
options: [{ label: "B", description: "B" }],
},
],
})
const pending = await Question.list()
expect(pending.length).toBe(2)
},
})
})
test("list - returns empty when no pending", async () => {
await using tmp = await tmpdir({ git: true })
await Instance.provide({
directory: tmp.path,
fn: async () => {
const pending = await Question.list()
expect(pending.length).toBe(0)
},
})
})