mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-07-01 00:24:20 +00:00
Compare commits
1 Commits
@shadcn/re
...
shadcn/01-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51e1940525 |
78
packages/shadcn/src/utils/highlighter.test.ts
Normal file
78
packages/shadcn/src/utils/highlighter.test.ts
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import { describe, expect, test } from "vitest"
|
||||||
|
|
||||||
|
import { highlighter } from "../../src/utils/highlighter"
|
||||||
|
import { generateRandomString } from "../../test/fuzz-utils"
|
||||||
|
|
||||||
|
describe("fuzzing", () => {
|
||||||
|
test("should handle various input strings", () => {
|
||||||
|
const testCases = Array.from({ length: 100 }, () => ({
|
||||||
|
text: generateRandomString(Math.floor(Math.random() * 100) + 1),
|
||||||
|
}))
|
||||||
|
|
||||||
|
for (const { text } of testCases) {
|
||||||
|
try {
|
||||||
|
// Test each highlighter function
|
||||||
|
const errorResult = highlighter.error(text)
|
||||||
|
const warnResult = highlighter.warn(text)
|
||||||
|
const infoResult = highlighter.info(text)
|
||||||
|
const successResult = highlighter.success(text)
|
||||||
|
|
||||||
|
// All results should be strings
|
||||||
|
expect(typeof errorResult).toBe("string")
|
||||||
|
expect(typeof warnResult).toBe("string")
|
||||||
|
expect(typeof infoResult).toBe("string")
|
||||||
|
expect(typeof successResult).toBe("string")
|
||||||
|
|
||||||
|
// All results should have the same length as input
|
||||||
|
expect(errorResult.length).toBe(text.length)
|
||||||
|
expect(warnResult.length).toBe(text.length)
|
||||||
|
expect(infoResult.length).toBe(text.length)
|
||||||
|
expect(successResult.length).toBe(text.length)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed with text: ${text}`, error)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
test("should handle edge cases", () => {
|
||||||
|
const edgeCases = [
|
||||||
|
"", // Empty string
|
||||||
|
" ", // Single space
|
||||||
|
" ", // Multiple spaces
|
||||||
|
"0", // Zero as string
|
||||||
|
"null", // "null" as string
|
||||||
|
"undefined", // "undefined" as string
|
||||||
|
"NaN", // "NaN" as string
|
||||||
|
"true", // "true" as string
|
||||||
|
"false", // "false" as string
|
||||||
|
"[]", // Empty array as string
|
||||||
|
"{}", // Empty object as string
|
||||||
|
]
|
||||||
|
|
||||||
|
for (const text of edgeCases) {
|
||||||
|
try {
|
||||||
|
// Test each highlighter function
|
||||||
|
const errorResult = highlighter.error(text)
|
||||||
|
const warnResult = highlighter.warn(text)
|
||||||
|
const infoResult = highlighter.info(text)
|
||||||
|
const successResult = highlighter.success(text)
|
||||||
|
|
||||||
|
// All results should be strings
|
||||||
|
expect(typeof errorResult).toBe("string")
|
||||||
|
expect(typeof warnResult).toBe("string")
|
||||||
|
expect(typeof infoResult).toBe("string")
|
||||||
|
expect(typeof successResult).toBe("string")
|
||||||
|
|
||||||
|
// All results should have the same length as input
|
||||||
|
expect(errorResult.length).toBe(text.length)
|
||||||
|
expect(warnResult.length).toBe(text.length)
|
||||||
|
expect(infoResult.length).toBe(text.length)
|
||||||
|
expect(successResult.length).toBe(text.length)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed with edge case: ${text}`, error)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
16
packages/shadcn/test/fuzz-utils.ts
Normal file
16
packages/shadcn/test/fuzz-utils.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
export const generateRandomString = (length: number): string => {
|
||||||
|
const chars =
|
||||||
|
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+-=[]{}|;:,.<>?"
|
||||||
|
return Array.from(
|
||||||
|
{ length },
|
||||||
|
() => chars[Math.floor(Math.random() * chars.length)]
|
||||||
|
).join("")
|
||||||
|
}
|
||||||
|
|
||||||
|
export const generateRandomPath = (): string => {
|
||||||
|
const segments = Array.from(
|
||||||
|
{ length: Math.floor(Math.random() * 5) + 1 },
|
||||||
|
() => generateRandomString(Math.floor(Math.random() * 10) + 1)
|
||||||
|
)
|
||||||
|
return segments.join("/")
|
||||||
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
import path from "path"
|
import path from "path"
|
||||||
import { loadConfig, type ConfigLoaderSuccessResult } from "tsconfig-paths"
|
import { loadConfig, type ConfigLoaderSuccessResult } from "tsconfig-paths"
|
||||||
import { expect, test } from "vitest"
|
import { describe, expect, test } from "vitest"
|
||||||
|
|
||||||
import { resolveImport } from "../../src/utils/resolve-import"
|
import { resolveImport } from "../../src/utils/resolve-import"
|
||||||
|
import { generateRandomPath } from "../fuzz-utils"
|
||||||
|
|
||||||
test("resolve import", async () => {
|
test("resolve import", async () => {
|
||||||
expect(
|
expect(
|
||||||
@@ -79,3 +80,88 @@ test("resolve import without base url", async () => {
|
|||||||
path.resolve(cwd, "foo/bar")
|
path.resolve(cwd, "foo/bar")
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("fuzzing", () => {
|
||||||
|
test("should handle various import paths", async () => {
|
||||||
|
const generateRandomConfig = (): Pick<
|
||||||
|
ConfigLoaderSuccessResult,
|
||||||
|
"absoluteBaseUrl" | "paths"
|
||||||
|
> => ({
|
||||||
|
absoluteBaseUrl: generateRandomPath(),
|
||||||
|
paths: {
|
||||||
|
"@/*": [generateRandomPath()],
|
||||||
|
"@/components/*": [generateRandomPath()],
|
||||||
|
"@/lib/*": [generateRandomPath()],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const testCases = Array.from({ length: 100 }, () => ({
|
||||||
|
importPath: generateRandomPath(),
|
||||||
|
config: generateRandomConfig(),
|
||||||
|
}))
|
||||||
|
|
||||||
|
for (const { importPath, config } of testCases) {
|
||||||
|
try {
|
||||||
|
const result = await resolveImport(importPath, config)
|
||||||
|
// Should either return undefined or a valid path
|
||||||
|
if (result) {
|
||||||
|
expect(typeof result).toBe("string")
|
||||||
|
expect(result.length).toBeGreaterThan(0)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Expected for invalid paths
|
||||||
|
expect(error).toBeDefined()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
test("should handle edge cases", async () => {
|
||||||
|
const edgeCases: Array<{
|
||||||
|
importPath: string
|
||||||
|
config: Pick<ConfigLoaderSuccessResult, "absoluteBaseUrl" | "paths">
|
||||||
|
}> = [
|
||||||
|
{
|
||||||
|
importPath: "",
|
||||||
|
config: {
|
||||||
|
absoluteBaseUrl: "",
|
||||||
|
paths: {
|
||||||
|
"@/*": [""],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
importPath: "/",
|
||||||
|
config: {
|
||||||
|
absoluteBaseUrl: "/",
|
||||||
|
paths: {
|
||||||
|
"@/*": ["/"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
importPath: "@/components/button",
|
||||||
|
config: {
|
||||||
|
absoluteBaseUrl: "/",
|
||||||
|
paths: {
|
||||||
|
"@/*": ["/"],
|
||||||
|
"@/components/*": ["/components"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
for (const { importPath, config } of edgeCases) {
|
||||||
|
try {
|
||||||
|
const result = await resolveImport(importPath, config)
|
||||||
|
// Should either return undefined or a valid path
|
||||||
|
if (result) {
|
||||||
|
expect(typeof result).toBe("string")
|
||||||
|
expect(result.length).toBeGreaterThan(0)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed with edge case:`, { importPath, config }, error)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user