mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-07-08 06:28:37 +00:00
fix(shadcn): flaky create-project tests (#7590)
* fix(shadcn): flaky create-project tests * fix * fix
This commit is contained in:
5
.changeset/tricky-terms-smell.md
Normal file
5
.changeset/tricky-terms-smell.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"shadcn": patch
|
||||
---
|
||||
|
||||
fix flacky tests
|
||||
@@ -1,8 +1,17 @@
|
||||
import { fetchRegistry } from "@/src/registry/api"
|
||||
import { spinner } from "@/src/utils/spinner"
|
||||
import { execa } from "execa"
|
||||
import fs from "fs-extra"
|
||||
import prompts from "prompts"
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"
|
||||
import {
|
||||
afterEach,
|
||||
beforeEach,
|
||||
describe,
|
||||
expect,
|
||||
it,
|
||||
vi,
|
||||
type MockInstance,
|
||||
} from "vitest"
|
||||
|
||||
import { TEMPLATES, createProject } from "./create-project"
|
||||
|
||||
@@ -14,16 +23,85 @@ vi.mock("@/src/registry/api")
|
||||
vi.mock("@/src/utils/get-package-manager", () => ({
|
||||
getPackageManager: vi.fn().mockResolvedValue("npm"),
|
||||
}))
|
||||
vi.mock("@/src/utils/spinner")
|
||||
vi.mock("@/src/utils/logger", () => ({
|
||||
logger: {
|
||||
break: vi.fn(),
|
||||
error: vi.fn(),
|
||||
info: vi.fn(),
|
||||
},
|
||||
}))
|
||||
|
||||
describe("createProject", () => {
|
||||
let mockExit: MockInstance
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
|
||||
// Reset all fs mocks
|
||||
vi.mocked(fs.access).mockResolvedValue(undefined)
|
||||
vi.mocked(fs.existsSync).mockReturnValue(false)
|
||||
vi.mocked(fs.ensureDir).mockResolvedValue(undefined)
|
||||
vi.mocked(fs.writeFile).mockResolvedValue(undefined)
|
||||
vi.mocked(fs.move).mockResolvedValue(undefined)
|
||||
vi.mocked(fs.remove).mockResolvedValue(undefined)
|
||||
|
||||
// Mock execa to resolve immediately without actual execution
|
||||
vi.mocked(execa).mockResolvedValue({
|
||||
stdout: "",
|
||||
stderr: "",
|
||||
exitCode: 0,
|
||||
signal: undefined,
|
||||
signalDescription: undefined,
|
||||
command: "",
|
||||
escapedCommand: "",
|
||||
failed: false,
|
||||
timedOut: false,
|
||||
isCanceled: false,
|
||||
killed: false,
|
||||
} as any)
|
||||
|
||||
// Mock fetch for monorepo template
|
||||
global.fetch = vi.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
arrayBuffer: () => Promise.resolve(new ArrayBuffer(0)),
|
||||
} as any)
|
||||
|
||||
// Reset prompts mock
|
||||
vi.mocked(prompts).mockResolvedValue({ type: "next", name: "my-app" })
|
||||
|
||||
// Reset registry mock
|
||||
vi.mocked(fetchRegistry).mockResolvedValue([])
|
||||
|
||||
// Mock spinner function
|
||||
const mockSpinner = {
|
||||
start: vi.fn().mockReturnThis(),
|
||||
succeed: vi.fn().mockReturnThis(),
|
||||
fail: vi.fn().mockReturnThis(),
|
||||
stop: vi.fn().mockReturnThis(),
|
||||
text: "",
|
||||
prefixText: "",
|
||||
suffixText: "",
|
||||
color: "cyan" as const,
|
||||
indent: 0,
|
||||
spinner: "dots" as const,
|
||||
isSpinning: false,
|
||||
interval: 100,
|
||||
stream: process.stderr,
|
||||
clear: vi.fn(),
|
||||
render: vi.fn(),
|
||||
frame: vi.fn(),
|
||||
stopAndPersist: vi.fn(),
|
||||
warn: vi.fn(),
|
||||
info: vi.fn(),
|
||||
}
|
||||
vi.mocked(spinner).mockReturnValue(mockSpinner as any)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
vi.resetAllMocks()
|
||||
mockExit?.mockRestore()
|
||||
delete (global as any).fetch
|
||||
})
|
||||
|
||||
it("should create a Next.js project with default options", async () => {
|
||||
@@ -84,10 +162,13 @@ describe("createProject", () => {
|
||||
})
|
||||
|
||||
it("should throw error if project path already exists", async () => {
|
||||
vi.mocked(fs.existsSync).mockReturnValue(true)
|
||||
// Mock fs.existsSync to return true only for the specific package.json path
|
||||
vi.mocked(fs.existsSync).mockImplementation((path: any) => {
|
||||
return path.toString().includes("existing-app/package.json")
|
||||
})
|
||||
vi.mocked(prompts).mockResolvedValue({ type: "next", name: "existing-app" })
|
||||
|
||||
const mockExit = vi
|
||||
mockExit = vi
|
||||
.spyOn(process, "exit")
|
||||
.mockImplementation(() => undefined as never)
|
||||
|
||||
@@ -103,7 +184,7 @@ describe("createProject", () => {
|
||||
vi.mocked(fs.access).mockRejectedValue(new Error("Permission denied"))
|
||||
vi.mocked(prompts).mockResolvedValue({ type: "next", name: "my-app" })
|
||||
|
||||
const mockExit = vi
|
||||
mockExit = vi
|
||||
.spyOn(process, "exit")
|
||||
.mockImplementation(() => undefined as never)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user