test: add test not fully functioning yet

This commit is contained in:
zernonia 2023-09-06 10:59:42 +08:00
parent 9399f6606a
commit bc545c95e4
49 changed files with 1574 additions and 71 deletions

View File

@ -18,7 +18,8 @@
"build:cli": "pnpm --filter shadcn-vue build",
"build:registry": "pnpm --filter=www build:registry",
"pub:beta": "cd packages/cli && pnpm pub:beta",
"pub:release": "cd packages/cli && pnpm pub:release"
"pub:release": "cd packages/cli && pnpm pub:release",
"test": "pnpm --filter shadcn-vue test"
},
"devDependencies": {
"@antfu/eslint-config": "^0.39.7",

View File

@ -75,6 +75,7 @@
"rimraf": "^5.0.1",
"tsup": "^7.2.0",
"type-fest": "^4.3.0",
"typescript": "^5.2.2"
"typescript": "^5.2.2",
"vite-tsconfig-paths": "^4.2.0"
}
}

View File

@ -8,15 +8,15 @@ import template from 'lodash.template'
import ora from 'ora'
import prompts from 'prompts'
import * as z from 'zod'
import * as templates from '@/src/utils/templates'
import * as templates from '../utils/templates'
import {
getRegistryBaseColor,
getRegistryBaseColors,
getRegistryStyles,
} from '@/src/utils/registry'
import { logger } from '@/src/utils/logger'
import { handleError } from '@/src/utils/handle-error'
import { getPackageManager } from '@/src/utils/get-package-manager'
} from '../utils/registry'
import { logger } from '../utils/logger'
import { handleError } from '../utils/handle-error'
import { getPackageManager } from '../utils/get-package-manager'
import {
type Config,
DEFAULT_COMPONENTS,
@ -27,7 +27,7 @@ import {
getConfig,
rawConfigSchema,
resolveConfigPaths,
} from '@/src/utils/get-config'
} from '../utils/get-config'
const PROJECT_DEPENDENCIES = {
base: [

View File

@ -0,0 +1,160 @@
import fs from 'node:fs'
import path from 'node:path'
import { execa } from 'execa'
import { afterEach, expect, test, vi } from 'vitest'
import { runInit } from '../../src/commands/init'
import { getConfig } from '../../src/utils/get-config'
import * as getPackageManger from '../../src/utils/get-package-manager'
import * as registry from '../../src/utils/registry'
vi.mock('execa')
vi.mock('fs/promises', () => ({
writeFile: vi.fn(),
mkdir: vi.fn(),
}))
vi.mock('ora')
test('init config-full', async () => {
vi.spyOn(getPackageManger, 'getPackageManager').mockResolvedValue('pnpm')
vi.spyOn(registry, 'getRegistryBaseColor').mockResolvedValue({
inlineColors: {},
cssVars: {},
inlineColorsTemplate:
'@tailwind base;\n@tailwind components;\n@tailwind utilities;\n',
cssVarsTemplate:
'@tailwind base;\n@tailwind components;\n@tailwind utilities;\n',
})
const mockMkdir = vi.spyOn(fs.promises, 'mkdir').mockResolvedValue(undefined)
const mockWriteFile = vi.spyOn(fs.promises, 'writeFile').mockResolvedValue()
const targetDir = path.resolve(__dirname, '../fixtures/config-full')
const config = await getConfig(targetDir)
await runInit(targetDir, config!)
expect(mockMkdir).toHaveBeenNthCalledWith(
1,
expect.stringMatching(/src\/app$/),
expect.anything(),
)
expect(mockMkdir).toHaveBeenNthCalledWith(
2,
expect.stringMatching(/src\/lib$/),
expect.anything(),
)
expect(mockMkdir).toHaveBeenNthCalledWith(
3,
expect.stringMatching(/src\/components$/),
expect.anything(),
)
expect(mockWriteFile).toHaveBeenNthCalledWith(
1,
expect.stringMatching(/tailwind.config.ts$/),
expect.stringContaining('/** @type {import(\'tailwindcss\').Config} */'),
'utf8',
)
expect(mockWriteFile).toHaveBeenNthCalledWith(
2,
expect.stringMatching(/src\/app\/globals.css$/),
expect.stringContaining('@tailwind base'),
'utf8',
)
expect(mockWriteFile).toHaveBeenNthCalledWith(
3,
expect.stringMatching(/src\/lib\/utils.ts$/),
expect.stringContaining('import { type ClassValue, clsx } from "clsx"'),
'utf8',
)
expect(execa).toHaveBeenCalledWith(
'pnpm',
[
'add',
'tailwindcss-animate',
'class-variance-authority',
'clsx',
'tailwind-merge',
'@radix-ui/react-icons',
],
{
cwd: targetDir,
},
)
mockMkdir.mockRestore()
mockWriteFile.mockRestore()
})
test('init config-partial', async () => {
vi.spyOn(getPackageManger, 'getPackageManager').mockResolvedValue('npm')
vi.spyOn(registry, 'getRegistryBaseColor').mockResolvedValue({
inlineColors: {},
cssVars: {},
inlineColorsTemplate:
'@tailwind base;\n@tailwind components;\n@tailwind utilities;\n',
cssVarsTemplate:
'@tailwind base;\n@tailwind components;\n@tailwind utilities;\n',
})
const mockMkdir = vi.spyOn(fs.promises, 'mkdir').mockResolvedValue(undefined)
const mockWriteFile = vi.spyOn(fs.promises, 'writeFile').mockResolvedValue()
const targetDir = path.resolve(__dirname, '../fixtures/config-partial')
const config = await getConfig(targetDir)
await runInit(targetDir, config!)
expect(mockMkdir).toHaveBeenNthCalledWith(
1,
expect.stringMatching(/src\/assets\/css$/),
expect.anything(),
)
expect(mockMkdir).toHaveBeenNthCalledWith(
2,
expect.stringMatching(/lib$/),
expect.anything(),
)
expect(mockMkdir).toHaveBeenNthCalledWith(
3,
expect.stringMatching(/components$/),
expect.anything(),
)
expect(mockWriteFile).toHaveBeenNthCalledWith(
1,
expect.stringMatching(/tailwind.config.ts$/),
expect.stringContaining('/** @type {import(\'tailwindcss\').Config} */'),
'utf8',
)
expect(mockWriteFile).toHaveBeenNthCalledWith(
2,
expect.stringMatching(/src\/assets\/css\/tailwind.css$/),
expect.stringContaining('@tailwind base'),
'utf8',
)
expect(mockWriteFile).toHaveBeenNthCalledWith(
3,
expect.stringMatching(/utils.ts$/),
expect.stringContaining('import { type ClassValue, clsx } from "clsx"'),
'utf8',
)
expect(execa).toHaveBeenCalledWith(
'npm',
[
'install',
'tailwindcss-animate',
'class-variance-authority',
'clsx',
'tailwind-merge',
'lucide-react',
],
{
cwd: targetDir,
},
)
mockMkdir.mockRestore()
mockWriteFile.mockRestore()
})
afterEach(() => {
vi.resetAllMocks()
})

View File

@ -0,0 +1,92 @@
{
"inlineColors": {
"light": {
"background": "white",
"foreground": "neutral-950",
"muted": "neutral-100",
"muted-foreground": "neutral-500",
"popover": "white",
"popover-foreground": "neutral-950",
"border": "neutral-200",
"input": "neutral-200",
"card": "white",
"card-foreground": "neutral-950",
"primary": "neutral-900",
"primary-foreground": "neutral-50",
"secondary": "neutral-100",
"secondary-foreground": "neutral-900",
"accent": "neutral-100",
"accent-foreground": "neutral-900",
"destructive": "red-500",
"destructive-foreground": "neutral-50",
"ring": "neutral-400"
},
"dark": {
"background": "neutral-950",
"foreground": "neutral-50",
"muted": "neutral-800",
"muted-foreground": "neutral-400",
"popover": "neutral-950",
"popover-foreground": "neutral-50",
"border": "neutral-800",
"input": "neutral-800",
"card": "neutral-950",
"card-foreground": "neutral-50",
"primary": "neutral-50",
"primary-foreground": "neutral-900",
"secondary": "neutral-800",
"secondary-foreground": "neutral-50",
"accent": "neutral-800",
"accent-foreground": "neutral-50",
"destructive": "red-900",
"destructive-foreground": "red-50",
"ring": "neutral-800"
}
},
"cssVars": {
"light": {
"background": "0 0% 100%",
"foreground": "0 0% 3.9%",
"muted": "0 0% 96.1%",
"muted-foreground": "0 0% 45.1%",
"popover": "0 0% 100%",
"popover-foreground": "0 0% 3.9%",
"border": "0 0% 89.8%",
"input": "0 0% 89.8%",
"card": "0 0% 100%",
"card-foreground": "0 0% 3.9%",
"primary": "0 0% 9%",
"primary-foreground": "0 0% 98%",
"secondary": "0 0% 96.1%",
"secondary-foreground": "0 0% 9%",
"accent": "0 0% 96.1%",
"accent-foreground": "0 0% 9%",
"destructive": "0 84.2% 60.2%",
"destructive-foreground": "0 0% 98%",
"ring": "0 0% 63.9%"
},
"dark": {
"background": "0 0% 3.9%",
"foreground": "0 0% 98%",
"muted": "0 0% 14.9%",
"muted-foreground": "0 0% 63.9%",
"popover": "0 0% 3.9%",
"popover-foreground": "0 0% 98%",
"border": "0 0% 14.9%",
"input": "0 0% 14.9%",
"card": "0 0% 3.9%",
"card-foreground": "0 0% 98%",
"primary": "0 0% 98%",
"primary-foreground": "0 0% 9%",
"secondary": "0 0% 14.9%",
"secondary-foreground": "0 0% 98%",
"accent": "0 0% 14.9%",
"accent-foreground": "0 0% 98%",
"destructive": "0 62.8% 30.6%",
"destructive-foreground": "0 85.7% 97.3%",
"ring": "0 0% 14.9%"
}
},
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 0 0% 3.9%;\n \n --muted: 0 0% 96.1%;\n --muted-foreground: 0 0% 45.1%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 0 0% 3.9%;\n \n --card: 0 0% 100%;\n --card-foreground: 0 0% 3.9%;\n \n --border: 0 0% 89.8%;\n --input: 0 0% 89.8%;\n \n --primary: 0 0% 9%;\n --primary-foreground: 0 0% 98%;\n \n --secondary: 0 0% 96.1%;\n --secondary-foreground: 0 0% 9%;\n \n --accent: 0 0% 96.1%;\n --accent-foreground: 0 0% 9%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 0 0% 98%;\n \n --ring: 0 0% 63.9%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 0 0% 3.9%;\n --foreground: 0 0% 98%;\n \n --muted: 0 0% 14.9%;\n --muted-foreground: 0 0% 63.9%;\n \n --popover: 0 0% 3.9%;\n --popover-foreground: 0 0% 98%;\n \n --card: 0 0% 3.9%;\n --card-foreground: 0 0% 98%;\n \n --border: 0 0% 14.9%;\n --input: 0 0% 14.9%;\n \n --primary: 0 0% 98%;\n --primary-foreground: 0 0% 9%;\n \n --secondary: 0 0% 14.9%;\n --secondary-foreground: 0 0% 98%;\n \n --accent: 0 0% 14.9%;\n --accent-foreground: 0 0% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 85.7% 97.3%;\n \n --ring: 0 0% 14.9%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
}

View File

@ -0,0 +1,92 @@
{
"inlineColors": {
"light": {
"background": "white",
"foreground": "slate-950",
"muted": "slate-100",
"muted-foreground": "slate-500",
"popover": "white",
"popover-foreground": "slate-950",
"border": "slate-200",
"input": "slate-200",
"card": "white",
"card-foreground": "slate-950",
"primary": "slate-900",
"primary-foreground": "slate-50",
"secondary": "slate-100",
"secondary-foreground": "slate-900",
"accent": "slate-100",
"accent-foreground": "slate-900",
"destructive": "red-500",
"destructive-foreground": "slate-50",
"ring": "slate-400"
},
"dark": {
"background": "slate-950",
"foreground": "slate-50",
"muted": "slate-800",
"muted-foreground": "slate-400",
"popover": "slate-950",
"popover-foreground": "slate-50",
"border": "slate-800",
"input": "slate-800",
"card": "slate-950",
"card-foreground": "slate-50",
"primary": "slate-50",
"primary-foreground": "slate-900",
"secondary": "slate-800",
"secondary-foreground": "slate-50",
"accent": "slate-800",
"accent-foreground": "slate-50",
"destructive": "red-900",
"destructive-foreground": "red-50",
"ring": "slate-800"
}
},
"cssVars": {
"light": {
"background": "0 0% 100%",
"foreground": "222.2 84% 4.9%",
"muted": "210 40% 96.1%",
"muted-foreground": "215.4 16.3% 46.9%",
"popover": "0 0% 100%",
"popover-foreground": "222.2 84% 4.9%",
"border": "214.3 31.8% 91.4%",
"input": "214.3 31.8% 91.4%",
"card": "0 0% 100%",
"card-foreground": "222.2 84% 4.9%",
"primary": "222.2 47.4% 11.2%",
"primary-foreground": "210 40% 98%",
"secondary": "210 40% 96.1%",
"secondary-foreground": "222.2 47.4% 11.2%",
"accent": "210 40% 96.1%",
"accent-foreground": "222.2 47.4% 11.2%",
"destructive": "0 84.2% 60.2%",
"destructive-foreground": "210 40% 98%",
"ring": "215 20.2% 65.1%"
},
"dark": {
"background": "222.2 84% 4.9%",
"foreground": "210 40% 98%",
"muted": "217.2 32.6% 17.5%",
"muted-foreground": "215 20.2% 65.1%",
"popover": "222.2 84% 4.9%",
"popover-foreground": "210 40% 98%",
"border": "217.2 32.6% 17.5%",
"input": "217.2 32.6% 17.5%",
"card": "222.2 84% 4.9%",
"card-foreground": "210 40% 98%",
"primary": "210 40% 98%",
"primary-foreground": "222.2 47.4% 11.2%",
"secondary": "217.2 32.6% 17.5%",
"secondary-foreground": "210 40% 98%",
"accent": "217.2 32.6% 17.5%",
"accent-foreground": "210 40% 98%",
"destructive": "0 62.8% 30.6%",
"destructive-foreground": "0 85.7% 97.3%",
"ring": "217.2 32.6% 17.5%"
}
},
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 222.2 84% 4.9%;\n \n --muted: 210 40% 96.1%;\n --muted-foreground: 215.4 16.3% 46.9%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 222.2 84% 4.9%;\n \n --card: 0 0% 100%;\n --card-foreground: 222.2 84% 4.9%;\n \n --border: 214.3 31.8% 91.4%;\n --input: 214.3 31.8% 91.4%;\n \n --primary: 222.2 47.4% 11.2%;\n --primary-foreground: 210 40% 98%;\n \n --secondary: 210 40% 96.1%;\n --secondary-foreground: 222.2 47.4% 11.2%;\n \n --accent: 210 40% 96.1%;\n --accent-foreground: 222.2 47.4% 11.2%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 40% 98%;\n \n --ring: 215 20.2% 65.1%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 222.2 84% 4.9%;\n --foreground: 210 40% 98%;\n \n --muted: 217.2 32.6% 17.5%;\n --muted-foreground: 215 20.2% 65.1%;\n \n --popover: 222.2 84% 4.9%;\n --popover-foreground: 210 40% 98%;\n \n --card: 222.2 84% 4.9%;\n --card-foreground: 210 40% 98%;\n \n --border: 217.2 32.6% 17.5%;\n --input: 217.2 32.6% 17.5%;\n \n --primary: 210 40% 98%;\n --primary-foreground: 222.2 47.4% 11.2%;\n \n --secondary: 217.2 32.6% 17.5%;\n --secondary-foreground: 210 40% 98%;\n \n --accent: 217.2 32.6% 17.5%;\n --accent-foreground: 210 40% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 85.7% 97.3%;\n \n --ring: 217.2 32.6% 17.5%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
}

View File

@ -0,0 +1,92 @@
{
"inlineColors": {
"light": {
"background": "white",
"foreground": "stone-950",
"muted": "stone-100",
"muted-foreground": "stone-500",
"popover": "white",
"popover-foreground": "stone-950",
"border": "stone-200",
"input": "stone-200",
"card": "white",
"card-foreground": "stone-950",
"primary": "stone-900",
"primary-foreground": "stone-50",
"secondary": "stone-100",
"secondary-foreground": "stone-900",
"accent": "stone-100",
"accent-foreground": "stone-900",
"destructive": "red-500",
"destructive-foreground": "stone-50",
"ring": "stone-400"
},
"dark": {
"background": "stone-950",
"foreground": "stone-50",
"muted": "stone-800",
"muted-foreground": "stone-400",
"popover": "stone-950",
"popover-foreground": "stone-50",
"border": "stone-800",
"input": "stone-800",
"card": "stone-950",
"card-foreground": "stone-50",
"primary": "stone-50",
"primary-foreground": "stone-900",
"secondary": "stone-800",
"secondary-foreground": "stone-50",
"accent": "stone-800",
"accent-foreground": "stone-50",
"destructive": "red-900",
"destructive-foreground": "red-50",
"ring": "stone-800"
}
},
"cssVars": {
"light": {
"background": "0 0% 100%",
"foreground": "20 14.3% 4.1%",
"muted": "60 4.8% 95.9%",
"muted-foreground": "25 5.3% 44.7%",
"popover": "0 0% 100%",
"popover-foreground": "20 14.3% 4.1%",
"border": "20 5.9% 90%",
"input": "20 5.9% 90%",
"card": "0 0% 100%",
"card-foreground": "20 14.3% 4.1%",
"primary": "24 9.8% 10%",
"primary-foreground": "60 9.1% 97.8%",
"secondary": "60 4.8% 95.9%",
"secondary-foreground": "24 9.8% 10%",
"accent": "60 4.8% 95.9%",
"accent-foreground": "24 9.8% 10%",
"destructive": "0 84.2% 60.2%",
"destructive-foreground": "60 9.1% 97.8%",
"ring": "24 5.4% 63.9%"
},
"dark": {
"background": "20 14.3% 4.1%",
"foreground": "60 9.1% 97.8%",
"muted": "12 6.5% 15.1%",
"muted-foreground": "24 5.4% 63.9%",
"popover": "20 14.3% 4.1%",
"popover-foreground": "60 9.1% 97.8%",
"border": "12 6.5% 15.1%",
"input": "12 6.5% 15.1%",
"card": "20 14.3% 4.1%",
"card-foreground": "60 9.1% 97.8%",
"primary": "60 9.1% 97.8%",
"primary-foreground": "24 9.8% 10%",
"secondary": "12 6.5% 15.1%",
"secondary-foreground": "60 9.1% 97.8%",
"accent": "12 6.5% 15.1%",
"accent-foreground": "60 9.1% 97.8%",
"destructive": "0 62.8% 30.6%",
"destructive-foreground": "0 85.7% 97.3%",
"ring": "12 6.5% 15.1%"
}
},
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 20 14.3% 4.1%;\n \n --muted: 60 4.8% 95.9%;\n --muted-foreground: 25 5.3% 44.7%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 20 14.3% 4.1%;\n \n --card: 0 0% 100%;\n --card-foreground: 20 14.3% 4.1%;\n \n --border: 20 5.9% 90%;\n --input: 20 5.9% 90%;\n \n --primary: 24 9.8% 10%;\n --primary-foreground: 60 9.1% 97.8%;\n \n --secondary: 60 4.8% 95.9%;\n --secondary-foreground: 24 9.8% 10%;\n \n --accent: 60 4.8% 95.9%;\n --accent-foreground: 24 9.8% 10%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 60 9.1% 97.8%;\n \n --ring: 24 5.4% 63.9%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 20 14.3% 4.1%;\n --foreground: 60 9.1% 97.8%;\n \n --muted: 12 6.5% 15.1%;\n --muted-foreground: 24 5.4% 63.9%;\n \n --popover: 20 14.3% 4.1%;\n --popover-foreground: 60 9.1% 97.8%;\n \n --card: 20 14.3% 4.1%;\n --card-foreground: 60 9.1% 97.8%;\n \n --border: 12 6.5% 15.1%;\n --input: 12 6.5% 15.1%;\n \n --primary: 60 9.1% 97.8%;\n --primary-foreground: 24 9.8% 10%;\n \n --secondary: 12 6.5% 15.1%;\n --secondary-foreground: 60 9.1% 97.8%;\n \n --accent: 12 6.5% 15.1%;\n --accent-foreground: 60 9.1% 97.8%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 85.7% 97.3%;\n \n --ring: 12 6.5% 15.1%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
}

View File

@ -0,0 +1,92 @@
{
"inlineColors": {
"light": {
"background": "white",
"foreground": "zinc-950",
"muted": "zinc-100",
"muted-foreground": "zinc-500",
"popover": "white",
"popover-foreground": "zinc-950",
"border": "zinc-200",
"input": "zinc-200",
"card": "white",
"card-foreground": "zinc-950",
"primary": "zinc-900",
"primary-foreground": "zinc-50",
"secondary": "zinc-100",
"secondary-foreground": "zinc-900",
"accent": "zinc-100",
"accent-foreground": "zinc-900",
"destructive": "red-500",
"destructive-foreground": "zinc-50",
"ring": "zinc-400"
},
"dark": {
"background": "zinc-950",
"foreground": "zinc-50",
"muted": "zinc-800",
"muted-foreground": "zinc-400",
"popover": "zinc-950",
"popover-foreground": "zinc-50",
"border": "zinc-800",
"input": "zinc-800",
"card": "zinc-950",
"card-foreground": "zinc-50",
"primary": "zinc-50",
"primary-foreground": "zinc-900",
"secondary": "zinc-800",
"secondary-foreground": "zinc-50",
"accent": "zinc-800",
"accent-foreground": "zinc-50",
"destructive": "red-900",
"destructive-foreground": "red-50",
"ring": "zinc-800"
}
},
"cssVars": {
"light": {
"background": "0 0% 100%",
"foreground": "240 10% 3.9%",
"muted": "240 4.8% 95.9%",
"muted-foreground": "240 3.8% 46.1%",
"popover": "0 0% 100%",
"popover-foreground": "240 10% 3.9%",
"border": "240 5.9% 90%",
"input": "240 5.9% 90%",
"card": "0 0% 100%",
"card-foreground": "240 10% 3.9%",
"primary": "240 5.9% 10%",
"primary-foreground": "0 0% 98%",
"secondary": "240 4.8% 95.9%",
"secondary-foreground": "240 5.9% 10%",
"accent": "240 4.8% 95.9%",
"accent-foreground": "240 5.9% 10%",
"destructive": "0 84.2% 60.2%",
"destructive-foreground": "0 0% 98%",
"ring": "240 5% 64.9%"
},
"dark": {
"background": "240 10% 3.9%",
"foreground": "0 0% 98%",
"muted": "240 3.7% 15.9%",
"muted-foreground": "240 5% 64.9%",
"popover": "240 10% 3.9%",
"popover-foreground": "0 0% 98%",
"border": "240 3.7% 15.9%",
"input": "240 3.7% 15.9%",
"card": "240 10% 3.9%",
"card-foreground": "0 0% 98%",
"primary": "0 0% 98%",
"primary-foreground": "240 5.9% 10%",
"secondary": "240 3.7% 15.9%",
"secondary-foreground": "0 0% 98%",
"accent": "240 3.7% 15.9%",
"accent-foreground": "0 0% 98%",
"destructive": "0 62.8% 30.6%",
"destructive-foreground": "0 85.7% 97.3%",
"ring": "240 3.7% 15.9%"
}
},
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n",
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 240 10% 3.9%;\n \n --muted: 240 4.8% 95.9%;\n --muted-foreground: 240 3.8% 46.1%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 240 10% 3.9%;\n \n --card: 0 0% 100%;\n --card-foreground: 240 10% 3.9%;\n \n --border: 240 5.9% 90%;\n --input: 240 5.9% 90%;\n \n --primary: 240 5.9% 10%;\n --primary-foreground: 0 0% 98%;\n \n --secondary: 240 4.8% 95.9%;\n --secondary-foreground: 240 5.9% 10%;\n \n --accent: 240 4.8% 95.9%;\n --accent-foreground: 240 5.9% 10%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 0 0% 98%;\n \n --ring: 240 5% 64.9%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 240 10% 3.9%;\n --foreground: 0 0% 98%;\n \n --muted: 240 3.7% 15.9%;\n --muted-foreground: 240 5% 64.9%;\n \n --popover: 240 10% 3.9%;\n --popover-foreground: 0 0% 98%;\n \n --card: 240 10% 3.9%;\n --card-foreground: 0 0% 98%;\n \n --border: 240 3.7% 15.9%;\n --input: 240 3.7% 15.9%;\n \n --primary: 0 0% 98%;\n --primary-foreground: 240 5.9% 10%;\n \n --secondary: 240 3.7% 15.9%;\n --secondary-foreground: 0 0% 98%;\n \n --accent: 240 3.7% 15.9%;\n --accent-foreground: 0 0% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 85.7% 97.3%;\n \n --ring: 240 3.7% 15.9%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
}

View File

@ -0,0 +1,14 @@
{
"style": "default",
"tailwind": {
"config": "tailwind.config.ts",
"css": "src/app/globals.css",
"baseColor": "zinc",
"cssVariables": true
},
"rsc": false,
"aliases": {
"utils": "~/lib/utils",
"components": "~/components"
}
}

View File

@ -0,0 +1,7 @@
{
"name": "test-cli-config-full",
"version": "1.0.0",
"main": "index.js",
"author": "shadcn",
"license": "MIT"
}

View File

@ -0,0 +1,33 @@
{
"compilerOptions": {
"target": "es2017",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"checkJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"noUncheckedIndexedAccess": true,
"baseUrl": ".",
"paths": {
"~/*": ["./src/*"]
}
},
"include": [
".eslintrc.cjs",
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
"**/*.cjs",
"**/*.mjs"
],
"exclude": ["node_modules"]
}

View File

@ -0,0 +1,5 @@
{
"cn": "./components",
"ui": "./ui",
"does-not-exist": "./does-not-exist"
}

View File

@ -0,0 +1,7 @@
{
"name": "test-cli-config-invalid",
"version": "1.0.0",
"main": "index.js",
"author": "shadcn",
"license": "MIT"
}

View File

@ -0,0 +1,14 @@
{
"style": "default",
"tsx": false,
"tailwind": {
"config": "./tailwind.config.js",
"css": "./src/assets/css/tailwind.css",
"baseColor": "neutral",
"cssVariables": false
},
"aliases": {
"utils": "@/lib/utils",
"components": "@/components"
}
}

View File

@ -0,0 +1,7 @@
{
"compilerOptions": {
"paths": {
"@/*": ["./*"]
}
}
}

View File

@ -0,0 +1,7 @@
{
"name": "test-cli-config-partial",
"version": "1.0.0",
"main": "index.js",
"author": "shadcn",
"license": "MIT"
}

View File

@ -0,0 +1,7 @@
{
"name": "test-cli-config-none",
"version": "1.0.0",
"main": "index.js",
"author": "shadcn",
"license": "MIT"
}

View File

@ -0,0 +1,13 @@
{
"style": "default",
"tailwind": {
"config": "./tailwind.config.ts",
"css": "./src/assets/css/tailwind.css",
"baseColor": "neutral",
"cssVariables": false
},
"aliases": {
"utils": "@/lib/utils",
"components": "@/components"
}
}

View File

@ -0,0 +1,7 @@
{
"name": "test-cli-config-partial",
"version": "1.0.0",
"main": "index.js",
"author": "shadcn",
"license": "MIT"
}

View File

@ -0,0 +1,9 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./*"]
}
}
}

Binary file not shown.

View File

@ -0,0 +1,7 @@
{
"name": "test-cli-project-bun",
"version": "1.0.0",
"main": "index.js",
"author": "shadcn",
"license": "MIT"
}

View File

@ -0,0 +1,13 @@
{
"name": "test-cli-npm-project",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "npm-project",
"version": "1.0.0",
"license": "MIT"
}
}
}

View File

@ -0,0 +1,7 @@
{
"name": "test-cli-project-npm",
"version": "1.0.0",
"main": "index.js",
"author": "shadcn",
"license": "MIT"
}

View File

@ -0,0 +1,7 @@
{
"name": "test-cli-project-pnpm",
"version": "1.0.0",
"main": "index.js",
"author": "shadcn",
"license": "MIT"
}

View File

@ -0,0 +1 @@
lockfileVersion: '6.0'

View File

@ -0,0 +1,7 @@
{
"components": "src/components",
"ui": "src/ui",
"styles": "src/styles/main.css",
"utils": "src/lib/cn.ts",
"tailwindConfig": "tailwind.config.ts"
}

View File

@ -0,0 +1,13 @@
{
"name": "test-cli-project-src",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "npm-project",
"version": "1.0.0",
"license": "MIT"
}
}
}

View File

@ -0,0 +1,5 @@
{
"name": "project-src",
"version": "0.1.0",
"private": true
}

View File

@ -0,0 +1,7 @@
{
"name": "test-cli-project-yarn",
"version": "1.0.0",
"main": "index.js",
"author": "shadcn",
"license": "MIT"
}

View File

@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

View File

@ -0,0 +1,8 @@
{
"tailwindConfig": "./tailwind.config.ts",
"importPaths": {
"styles": "~/styles/globals.css",
"utils:cn": "~/lib/cn.ts",
"components:ui": "~/components/ui"
}
}

View File

@ -0,0 +1,5 @@
{
"name": "test-cli-project",
"version": "0.1.0",
"private": true
}

View File

@ -0,0 +1 @@
lockfileVersion: "6.0"

View File

@ -0,0 +1,9 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./*"]
}
}
}

View File

@ -0,0 +1,9 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"paths": {
"~/components/*": ["./components/*"],
"~/lib/*": ["./lib/*"]
}
}
}

View File

@ -0,0 +1,25 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`transform css vars 1`] = `
"import * as React from \\"react\\"
export function Foo() {
return <div className=\\"bg-background hover:bg-muted text-primary-foreground sm:focus:text-accent-foreground\\">foo</div>
}\\"
"
`;
exports[`transform css vars 2`] = `
"import * as React from \\"react\\"
export function Foo() {
return <div className=\\"bg-white hover:bg-stone-100 text-stone-50 sm:focus:text-stone-900 dark:bg-stone-950 dark:hover:bg-stone-800 dark:text-stone-900 dark:sm:focus:text-stone-50\\">foo</div>
}\\"\\"
"
`;
exports[`transform css vars 3`] = `
"import * as React from \\"react\\"
export function Foo() {
return <div className={cn(\\"bg-white hover:bg-stone-100 dark:bg-stone-950 dark:hover:bg-stone-800\\", true && \\"text-stone-50 sm:focus:text-stone-900 dark:text-stone-900 dark:sm:focus:text-stone-50\\")}>foo</div>
}\\"\\"
"
`;

View File

@ -0,0 +1,36 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`transform import 1`] = `
"import * as React from \\"react\\"
import { Foo } from \\"bar\\"
import { Button } from \\"@/components/ui/button\\"
import { Label} from \\"ui/label\\"
import { Box } from \\"@/components/box\\"
import { cn } from \\"@/lib/utils\\"
"
`;
exports[`transform import 2`] = `
"import * as React from \\"react\\"
import { Foo } from \\"bar\\"
import { Button } from \\"~/src/components/ui/button\\"
import { Label} from \\"ui/label\\"
import { Box } from \\"~/src/components/box\\"
import { cn, foo, bar } from \\"~/lib\\"
import { bar } from \\"@/lib/utils/bar\\"
"
`;
exports[`transform import 3`] = `
"import * as React from \\"react\\"
import { Foo } from \\"bar\\"
import { Button } from \\"~/src/components/ui/button\\"
import { Label} from \\"ui/label\\"
import { Box } from \\"~/src/components/box\\"
import { cn } from \\"~/src/utils\\"
import { bar } from \\"@/lib/utils/bar\\"
"
`;

View File

@ -0,0 +1,31 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`transform rsc 1`] = `
"import * as React from \\"react\\"
import { Foo } from \\"bar\\"
"
`;
exports[`transform rsc 2`] = `
"\\"use client\\"
import * as React from \\"react\\"
import { Foo } from \\"bar\\"
"
`;
exports[`transform rsc 3`] = `
" import * as React from \\"react\\"
import { Foo } from \\"bar\\"
"
`;
exports[`transform rsc 4`] = `
"\\"use foo\\"
import * as React from \\"react\\"
import { Foo } from \\"bar\\"
\\"use client\\"
"
`;

View File

@ -0,0 +1,84 @@
import { describe, expect, test } from 'vitest'
import {
applyColorMapping,
splitClassName,
} from '../../src/utils/transformers/transform-css-vars'
import baseColor from '../fixtures/colors/slate.json'
describe('split className', () => {
test.each([
{
input: 'bg-popover',
output: [null, 'bg-popover', null],
},
{
input: 'bg-popover/50',
output: [null, 'bg-popover', '50'],
},
{
input: 'hover:bg-popover/50',
output: ['hover', 'bg-popover', '50'],
},
{
input: 'hover:bg-popover',
output: ['hover', 'bg-popover', null],
},
{
input: '[&_[cmdk-group-heading]]:px-2',
output: ['[&_[cmdk-group-heading]]', 'px-2', null],
},
{
input: '[&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0',
output: ['[&_[cmdk-group]:not([hidden])_~[cmdk-group]]', 'pt-0', null],
},
{
input: '[&_[cmdk-group]:not([hidden])_~[cmdk-group]]:bg-red-200',
output: [
'[&_[cmdk-group]:not([hidden])_~[cmdk-group]]',
'bg-red-200',
null,
],
},
{
input: 'sm:focus:text-accent-foreground/30',
output: ['sm:focus', 'text-accent-foreground', '30'],
},
])('splitClassName($input) -> $output', ({ input, output }) => {
expect(splitClassName(input)).toStrictEqual(output)
})
})
describe('apply color mapping', async () => {
test.each([
{
input: 'bg-background text-foreground',
output: 'bg-white text-slate-950 dark:bg-slate-950 dark:text-slate-50',
},
{
input: 'rounded-lg border bg-card text-card-foreground shadow-sm',
output:
'rounded-lg border border-slate-200 bg-white text-slate-950 shadow-sm dark:border-slate-800 dark:bg-slate-950 dark:text-slate-50',
},
{
input:
'text-destructive border-destructive/50 dark:border-destructive [&>svg]:text-destructive text-destructive',
output:
'text-red-500 border-red-500/50 dark:border-red-500 [&>svg]:text-red-500 text-red-500 dark:text-red-900 dark:border-red-900/50 dark:dark:border-red-900 dark:[&>svg]:text-red-900 dark:text-red-900',
},
{
input:
'flex h-full w-full items-center justify-center rounded-full bg-muted',
output:
'flex h-full w-full items-center justify-center rounded-full bg-slate-100 dark:bg-slate-800',
},
{
input:
'absolute right-4 top-4 bg-primary rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary',
output:
'absolute right-4 top-4 bg-slate-900 rounded-sm opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-slate-100 dark:bg-slate-50 dark:ring-offset-slate-950 dark:focus:ring-slate-800 dark:data-[state=open]:bg-slate-800',
},
])('applyColorMapping($input) -> $output', ({ input, output }) => {
expect(applyColorMapping(input, baseColor.inlineColors)).toBe(output)
})
})

View File

@ -0,0 +1,158 @@
import path from 'node:path'
import { expect, test } from 'vitest'
import { getConfig, getRawConfig } from '../../src/utils/get-config'
test('get raw config', async () => {
expect(
await getRawConfig(path.resolve(__dirname, '../fixtures/config-none')),
).toEqual(null)
expect(
await getRawConfig(path.resolve(__dirname, '../fixtures/config-partial')),
).toEqual({
style: 'default',
tailwind: {
config: './tailwind.config.ts',
css: './src/assets/css/tailwind.css',
baseColor: 'neutral',
cssVariables: false,
},
rsc: false,
tsx: true,
aliases: {
components: '@/components',
utils: '@/lib/utils',
},
})
expect(
getRawConfig(path.resolve(__dirname, '../fixtures/config-invalid')),
).rejects.toThrowError()
})
test('get config', async () => {
expect(
await getConfig(path.resolve(__dirname, '../fixtures/config-none')),
).toEqual(null)
expect(
getConfig(path.resolve(__dirname, '../fixtures/config-invalid')),
).rejects.toThrowError()
expect(
await getConfig(path.resolve(__dirname, '../fixtures/config-partial')),
).toEqual({
style: 'default',
tailwind: {
config: './tailwind.config.ts',
css: './src/assets/css/tailwind.css',
baseColor: 'neutral',
cssVariables: false,
},
rsc: false,
tsx: true,
aliases: {
components: '@/components',
utils: '@/lib/utils',
},
resolvedPaths: {
tailwindConfig: path.resolve(
__dirname,
'../fixtures/config-partial',
'tailwind.config.ts',
),
tailwindCss: path.resolve(
__dirname,
'../fixtures/config-partial',
'./src/assets/css/tailwind.css',
),
components: path.resolve(
__dirname,
'../fixtures/config-partial',
'./components',
),
utils: path.resolve(
__dirname,
'../fixtures/config-partial',
'./lib/utils',
),
},
})
expect(
await getConfig(path.resolve(__dirname, '../fixtures/config-full')),
).toEqual({
style: 'new-york',
rsc: false,
tsx: true,
tailwind: {
config: 'tailwind.config.ts',
baseColor: 'zinc',
css: 'src/app/globals.css',
cssVariables: true,
},
aliases: {
components: '~/components',
utils: '~/lib/utils',
},
resolvedPaths: {
tailwindConfig: path.resolve(
__dirname,
'../fixtures/config-full',
'tailwind.config.ts',
),
tailwindCss: path.resolve(
__dirname,
'../fixtures/config-full',
'./src/app/globals.css',
),
components: path.resolve(
__dirname,
'../fixtures/config-full',
'./src/components',
),
utils: path.resolve(
__dirname,
'../fixtures/config-full',
'./src/lib/utils',
),
},
})
expect(
await getConfig(path.resolve(__dirname, '../fixtures/config-jsx')),
).toEqual({
style: 'default',
tailwind: {
config: './tailwind.config.js',
css: './src/assets/css/tailwind.css',
baseColor: 'neutral',
cssVariables: false,
},
rsc: false,
tsx: false,
aliases: {
components: '@/components',
utils: '@/lib/utils',
},
resolvedPaths: {
tailwindConfig: path.resolve(
__dirname,
'../fixtures/config-jsx',
'tailwind.config.js',
),
tailwindCss: path.resolve(
__dirname,
'../fixtures/config-jsx',
'./src/assets/css/tailwind.css',
),
components: path.resolve(
__dirname,
'../fixtures/config-jsx',
'./components',
),
utils: path.resolve(__dirname, '../fixtures/config-jsx', './lib/utils'),
},
})
})

View File

@ -0,0 +1,26 @@
import path from 'node:path'
import { expect, test } from 'vitest'
import { getPackageManager } from '../../src/utils/get-package-manager'
test('get package manager', async () => {
expect(
await getPackageManager(path.resolve(__dirname, '../fixtures/project-yarn')),
).toBe('yarn')
expect(
await getPackageManager(path.resolve(__dirname, '../fixtures/project-npm')),
).toBe('npm')
expect(
await getPackageManager(path.resolve(__dirname, '../fixtures/project-pnpm')),
).toBe('pnpm')
expect(
await getPackageManager(path.resolve(__dirname, '../fixtures/project-bun')),
).toBe('bun')
expect(
await getPackageManager(path.resolve(__dirname, '../fixtures/next')),
).toBe('pnpm')
})

View File

@ -0,0 +1,70 @@
import { expect, test } from 'vitest'
import { resolveTree } from '../../src/utils/registry'
test('resolve tree', async () => {
const index = [
{
name: 'button',
dependencies: ['@radix-ui/react-slot'],
type: 'components:ui',
files: ['button.tsx'],
},
{
name: 'dialog',
dependencies: ['@radix-ui/react-dialog'],
registryDependencies: ['button'],
type: 'components:ui',
files: ['dialog.tsx'],
},
{
name: 'input',
registryDependencies: ['button'],
type: 'components:ui',
files: ['input.tsx'],
},
{
name: 'alert-dialog',
dependencies: ['@radix-ui/react-alert-dialog'],
registryDependencies: ['button', 'dialog'],
type: 'components:ui',
files: ['alert-dialog.tsx'],
},
{
name: 'example-card',
type: 'components:component',
files: ['example-card.tsx'],
registryDependencies: ['button', 'dialog', 'input'],
},
]
expect(
(await resolveTree(index, ['button'])).map(entry => entry.name).sort(),
).toEqual(['button'])
expect(
(await resolveTree(index, ['dialog'])).map(entry => entry.name).sort(),
).toEqual(['button', 'dialog'])
expect(
(await resolveTree(index, ['alert-dialog', 'dialog']))
.map(entry => entry.name)
.sort(),
).toEqual(['alert-dialog', 'button', 'dialog'])
expect(
(await resolveTree(index, ['example-card']))
.map(entry => entry.name)
.sort(),
).toEqual(['button', 'dialog', 'example-card', 'input'])
expect(
(await resolveTree(index, ['foo'])).map(entry => entry.name).sort(),
).toEqual([])
expect(
(await resolveTree(index, ['button', 'foo']))
.map(entry => entry.name)
.sort(),
).toEqual(['button'])
})

View File

@ -0,0 +1,81 @@
import path from 'node:path'
import { type ConfigLoaderSuccessResult, loadConfig } from 'tsconfig-paths'
import { expect, test } from 'vitest'
import { resolveImport } from '../../src/utils/resolve-import'
test('resolve import', async () => {
expect(
await resolveImport('@/foo/bar', {
absoluteBaseUrl: '/Users/shadcn/Projects/foobar',
paths: {
'@/*': ['./src/*'],
'~/components/*': ['./src/components/*'],
'~/lib': ['./src/lib'],
},
}),
).toEqual('/Users/shadcn/Projects/foobar/src/foo/bar')
expect(
await resolveImport('~/components/foo/bar/baz', {
absoluteBaseUrl: '/Users/shadcn/Projects/foobar',
paths: {
'@/*': ['./src/*'],
'~/components/*': ['./src/components/*'],
'~/lib': ['./src/lib'],
},
}),
).toEqual('/Users/shadcn/Projects/foobar/src/components/foo/bar/baz')
expect(
await resolveImport('components/foo/bar', {
absoluteBaseUrl: '/Users/shadcn/Projects/foobar',
paths: {
'components/*': ['./src/app/components/*'],
'ui/*': ['./src/ui/primities/*'],
'lib': ['./lib'],
},
}),
).toEqual('/Users/shadcn/Projects/foobar/src/app/components/foo/bar')
expect(
await resolveImport('lib/utils', {
absoluteBaseUrl: '/Users/shadcn/Projects/foobar',
paths: {
'components/*': ['./src/app/components/*'],
'ui/*': ['./src/ui/primities/*'],
'lib': ['./lib'],
},
}),
).toEqual('/Users/shadcn/Projects/foobar/lib/utils')
})
test('resolve import with base url', async () => {
const cwd = path.resolve(__dirname, '../fixtures/with-base-url')
const config = (await loadConfig(cwd)) as ConfigLoaderSuccessResult
expect(await resolveImport('@/components/ui', config)).toEqual(
path.resolve(cwd, 'components/ui'),
)
expect(await resolveImport('@/lib/utils', config)).toEqual(
path.resolve(cwd, 'lib/utils'),
)
expect(await resolveImport('foo/bar', config)).toEqual(
path.resolve(cwd, 'foo/bar'),
)
})
test('resolve import without base url', async () => {
const cwd = path.resolve(__dirname, '../fixtures/without-base-url')
const config = (await loadConfig(cwd)) as ConfigLoaderSuccessResult
expect(await resolveImport('~/components/ui', config)).toEqual(
path.resolve(cwd, 'components/ui'),
)
expect(await resolveImport('~/lib/utils', config)).toEqual(
path.resolve(cwd, 'lib/utils'),
)
expect(await resolveImport('foo/bar', config)).toEqual(
path.resolve(cwd, 'foo/bar'),
)
})

View File

@ -0,0 +1,75 @@
// import { expect, test } from 'vitest'
// import { transform } from '../../src/utils/transformers'
// import stone from '../fixtures/colors/stone.json'
// test('transform css vars', async () => {
// expect(
// await transform({
// filename: 'test.ts',
// raw: `import * as React from "react"
// export function Foo() {
// return <div className="bg-background hover:bg-muted text-primary-foreground sm:focus:text-accent-foreground">foo</div>
// }"
// `,
// config: {
// tsx: true,
// tailwind: {
// baseColor: 'stone',
// cssVariables: true,
// },
// aliases: {
// components: '@/components',
// utils: '@/lib/utils',
// },
// },
// baseColor: stone,
// }),
// ).toMatchSnapshot()
// expect(
// await transform({
// filename: 'test.ts',
// raw: `import * as React from "react"
// export function Foo() {
// return <div className="bg-background hover:bg-muted text-primary-foreground sm:focus:text-accent-foreground">foo</div>
// }"
// `,
// config: {
// tsx: true,
// tailwind: {
// baseColor: 'stone',
// cssVariables: false,
// },
// aliases: {
// components: '@/components',
// utils: '@/lib/utils',
// },
// },
// baseColor: stone,
// }),
// ).toMatchSnapshot()
// expect(
// await transform({
// filename: 'test.ts',
// raw: `import * as React from "react"
// export function Foo() {
// return <div className={cn("bg-background hover:bg-muted", true && "text-primary-foreground sm:focus:text-accent-foreground")}>foo</div>
// }"
// `,
// config: {
// tsx: true,
// tailwind: {
// baseColor: 'stone',
// cssVariables: false,
// },
// aliases: {
// components: '@/components',
// utils: '@/lib/utils',
// },
// },
// baseColor: stone,
// }),
// ).toMatchSnapshot()
// })

View File

@ -0,0 +1,74 @@
// import { expect, test } from 'vitest'
// import { transform } from '../../src/utils/transformers'
// test('transform import', async () => {
// expect(
// await transform({
// filename: 'test.ts',
// raw: `import * as React from "react"
// import { Foo } from "bar"
// import { Button } from "@/registry/new-york/ui/button"
// import { Label} from "ui/label"
// import { Box } from "@/registry/new-york/box"
// import { cn } from "@/lib/utils"
// `,
// config: {
// tsx: true,
// tailwind: {
// baseColor: 'neutral',
// cssVariables: true,
// },
// aliases: {
// components: '@/components',
// utils: '@/lib/utils',
// },
// },
// }),
// ).toMatchSnapshot()
// expect(
// await transform({
// filename: 'test.ts',
// raw: `import * as React from "react"
// import { Foo } from "bar"
// import { Button } from "@/registry/new-york/ui/button"
// import { Label} from "ui/label"
// import { Box } from "@/registry/new-york/box"
// import { cn, foo, bar } from "@/lib/utils"
// import { bar } from "@/lib/utils/bar"
// `,
// config: {
// tsx: true,
// aliases: {
// components: '~/src/components',
// utils: '~/lib',
// },
// },
// }),
// ).toMatchSnapshot()
// expect(
// await transform({
// filename: 'test.ts',
// raw: `import * as React from "react"
// import { Foo } from "bar"
// import { Button } from "@/registry/new-york/ui/button"
// import { Label} from "ui/label"
// import { Box } from "@/registry/new-york/box"
// import { cn } from "@/lib/utils"
// import { bar } from "@/lib/utils/bar"
// `,
// config: {
// tsx: true,
// aliases: {
// components: '~/src/components',
// utils: '~/src/utils',
// },
// },
// }),
// ).toMatchSnapshot()
// })

View File

@ -0,0 +1,65 @@
// import { expect, test } from 'vitest'
// import { transform } from '../../src/utils/transformers'
// test('transform rsc', async () => {
// expect(
// await transform({
// filename: 'test.ts',
// raw: `import * as React from "react"
// import { Foo } from "bar"
// `,
// config: {
// tsx: true,
// rsc: true,
// },
// }),
// ).toMatchSnapshot()
// expect(
// await transform({
// filename: 'test.ts',
// raw: `"use client"
// import * as React from "react"
// import { Foo } from "bar"
// `,
// config: {
// tsx: true,
// rsc: true,
// },
// }),
// ).toMatchSnapshot()
// expect(
// await transform({
// filename: 'test.ts',
// raw: `"use client"
// import * as React from "react"
// import { Foo } from "bar"
// `,
// config: {
// tsx: true,
// rsc: false,
// },
// }),
// ).toMatchSnapshot()
// expect(
// await transform({
// filename: 'test.ts',
// raw: `"use foo"
// import * as React from "react"
// import { Foo } from "bar"
// "use client"
// `,
// config: {
// tsx: true,
// rsc: false,
// },
// }),
// ).toMatchSnapshot()
// })

View File

@ -0,0 +1,9 @@
import tsconfigPaths from 'vite-tsconfig-paths'
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
// ...
},
plugins: [tsconfigPaths()],
})

View File

@ -29,9 +29,6 @@ importers:
simple-git-hooks:
specifier: ^2.9.0
version: 2.9.0
turbo:
specifier: ^1.10.13
version: 1.10.13
typescript:
specifier: ^5.2.2
version: 5.2.2
@ -147,6 +144,9 @@ importers:
vite:
specifier: ^4.3.9
version: 4.3.9(@types/node@20.5.7)
vite-tsconfig-paths:
specifier: ^4.2.0
version: 4.2.0(typescript@5.0.2)(vite@4.3.9)
vue-tsc:
specifier: ^1.4.2
version: 1.4.2(typescript@5.0.2)
@ -241,6 +241,9 @@ importers:
typescript:
specifier: ^5.2.2
version: 5.2.2
vite-tsconfig-paths:
specifier: ^4.2.0
version: 4.2.0(typescript@5.2.2)
packages:
@ -4951,6 +4954,10 @@ packages:
slash: 4.0.0
dev: false
/globrex@0.1.2:
resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==}
dev: true
/gopd@1.0.1:
resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
dependencies:
@ -7217,6 +7224,32 @@ packages:
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
/tsconfck@2.1.2(typescript@5.0.2):
resolution: {integrity: sha512-ghqN1b0puy3MhhviwO2kGF8SeMDNhEbnKxjK7h6+fvY9JAxqvXi8y5NAHSQv687OVboS2uZIByzGd45/YxrRHg==}
engines: {node: ^14.13.1 || ^16 || >=18}
hasBin: true
peerDependencies:
typescript: ^4.3.5 || ^5.0.0
peerDependenciesMeta:
typescript:
optional: true
dependencies:
typescript: 5.0.2
dev: true
/tsconfck@2.1.2(typescript@5.2.2):
resolution: {integrity: sha512-ghqN1b0puy3MhhviwO2kGF8SeMDNhEbnKxjK7h6+fvY9JAxqvXi8y5NAHSQv687OVboS2uZIByzGd45/YxrRHg==}
engines: {node: ^14.13.1 || ^16 || >=18}
hasBin: true
peerDependencies:
typescript: ^4.3.5 || ^5.0.0
peerDependenciesMeta:
typescript:
optional: true
dependencies:
typescript: 5.2.2
dev: true
/tsconfig-paths@4.2.0:
resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==}
engines: {node: '>=6'}
@ -7280,66 +7313,6 @@ packages:
typescript: 5.2.2
dev: true
/turbo-darwin-64@1.10.13:
resolution: {integrity: sha512-vmngGfa2dlYvX7UFVncsNDMuT4X2KPyPJ2Jj+xvf5nvQnZR/3IeDEGleGVuMi/hRzdinoxwXqgk9flEmAYp0Xw==}
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/turbo-darwin-arm64@1.10.13:
resolution: {integrity: sha512-eMoJC+k7gIS4i2qL6rKmrIQGP6Wr9nN4odzzgHFngLTMimok2cGLK3qbJs5O5F/XAtEeRAmuxeRnzQwTl/iuAw==}
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/turbo-linux-64@1.10.13:
resolution: {integrity: sha512-0CyYmnKTs6kcx7+JRH3nPEqCnzWduM0hj8GP/aodhaIkLNSAGAa+RiYZz6C7IXN+xUVh5rrWTnU2f1SkIy7Gdg==}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/turbo-linux-arm64@1.10.13:
resolution: {integrity: sha512-0iBKviSGQQlh2OjZgBsGjkPXoxvRIxrrLLbLObwJo3sOjIH0loGmVIimGS5E323soMfi/o+sidjk2wU1kFfD7Q==}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/turbo-windows-64@1.10.13:
resolution: {integrity: sha512-S5XySRfW2AmnTeY1IT+Jdr6Goq7mxWganVFfrmqU+qqq3Om/nr0GkcUX+KTIo9mPrN0D3p5QViBRzulwB5iuUQ==}
cpu: [x64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/turbo-windows-arm64@1.10.13:
resolution: {integrity: sha512-nKol6+CyiExJIuoIc3exUQPIBjP9nIq5SkMJgJuxsot2hkgGrafAg/izVDRDrRduQcXj2s8LdtxJHvvnbI8hEQ==}
cpu: [arm64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/turbo@1.10.13:
resolution: {integrity: sha512-vOF5IPytgQPIsgGtT0n2uGZizR2N3kKuPIn4b5p5DdeLoI0BV7uNiydT7eSzdkPRpdXNnO8UwS658VaI4+YSzQ==}
hasBin: true
optionalDependencies:
turbo-darwin-64: 1.10.13
turbo-darwin-arm64: 1.10.13
turbo-linux-64: 1.10.13
turbo-linux-arm64: 1.10.13
turbo-windows-64: 1.10.13
turbo-windows-arm64: 1.10.13
dev: true
/type-check@0.4.0:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'}
@ -7613,6 +7586,39 @@ packages:
- terser
dev: true
/vite-tsconfig-paths@4.2.0(typescript@5.0.2)(vite@4.3.9):
resolution: {integrity: sha512-jGpus0eUy5qbbMVGiTxCL1iB9ZGN6Bd37VGLJU39kTDD6ZfULTTb1bcc5IeTWqWJKiWV5YihCaibeASPiGi8kw==}
peerDependencies:
vite: '*'
peerDependenciesMeta:
vite:
optional: true
dependencies:
debug: 4.3.4
globrex: 0.1.2
tsconfck: 2.1.2(typescript@5.0.2)
vite: 4.3.9(@types/node@20.5.7)
transitivePeerDependencies:
- supports-color
- typescript
dev: true
/vite-tsconfig-paths@4.2.0(typescript@5.2.2):
resolution: {integrity: sha512-jGpus0eUy5qbbMVGiTxCL1iB9ZGN6Bd37VGLJU39kTDD6ZfULTTb1bcc5IeTWqWJKiWV5YihCaibeASPiGi8kw==}
peerDependencies:
vite: '*'
peerDependenciesMeta:
vite:
optional: true
dependencies:
debug: 4.3.4
globrex: 0.1.2
tsconfck: 2.1.2(typescript@5.2.2)
transitivePeerDependencies:
- supports-color
- typescript
dev: true
/vite@4.3.9(@types/node@20.4.7):
resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==}
engines: {node: ^14.18.0 || >=16.0.0}