blacksmith-cli 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blacksmith-cli",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Fullstack Django + React framework — one command, one codebase, one mental model",
5
5
  "type": "module",
6
6
  "bin": {
@@ -8,6 +8,9 @@
8
8
  "build": "tsc -b && vite build",
9
9
  "lint": "eslint .",
10
10
  "preview": "vite preview",
11
+ "test": "vitest run",
12
+ "test:watch": "vitest",
13
+ "test:coverage": "vitest run --coverage",
11
14
  "openapi-ts": "openapi-ts"
12
15
  },
13
16
  "dependencies": {
@@ -32,13 +35,18 @@
32
35
  },
33
36
  "devDependencies": {
34
37
  "@hey-api/openapi-ts": "^0.93.0",
38
+ "@testing-library/jest-dom": "^6.6.0",
39
+ "@testing-library/react": "^16.1.0",
40
+ "@testing-library/user-event": "^14.5.0",
35
41
  "@types/react": "^19.1.0",
36
42
  "@types/react-dom": "^19.1.0",
37
43
  "@vitejs/plugin-react": "^5.0.0",
38
44
  "autoprefixer": "^10.4.0",
45
+ "jsdom": "^25.0.0",
39
46
  "postcss": "^8.4.0",
40
47
  "tailwindcss-animate": "^1.0.7",
41
48
  "typescript": "~5.8.0",
42
- "vite": "^6.3.0"
49
+ "vite": "^6.3.0",
50
+ "vitest": "^3.0.0"
43
51
  }
44
52
  }
@@ -0,0 +1,21 @@
1
+ import '@testing-library/jest-dom/vitest'
2
+
3
+ // Mock window.matchMedia (not implemented in jsdom)
4
+ Object.defineProperty(window, 'matchMedia', {
5
+ writable: true,
6
+ value: vi.fn().mockImplementation((query: string) => ({
7
+ matches: false,
8
+ media: query,
9
+ onchange: null,
10
+ addListener: vi.fn(),
11
+ removeListener: vi.fn(),
12
+ addEventListener: vi.fn(),
13
+ removeEventListener: vi.fn(),
14
+ dispatchEvent: vi.fn(),
15
+ })),
16
+ })
17
+
18
+ // Clean up after each test
19
+ afterEach(() => {
20
+ document.body.innerHTML = ''
21
+ })
@@ -0,0 +1,80 @@
1
+ import { type ReactElement, type ReactNode } from 'react'
2
+ import { render, type RenderOptions } from '@testing-library/react'
3
+ import userEvent from '@testing-library/user-event'
4
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
5
+ import { ThemeProvider } from '@blacksmith-ui/react'
6
+ import { MemoryRouter } from 'react-router-dom'
7
+
8
+ /**
9
+ * Creates a fresh QueryClient configured for tests.
10
+ * Disables retries and garbage collection to keep tests fast and deterministic.
11
+ */
12
+ function createTestQueryClient() {
13
+ return new QueryClient({
14
+ defaultOptions: {
15
+ queries: {
16
+ retry: false,
17
+ gcTime: 0,
18
+ },
19
+ mutations: {
20
+ retry: false,
21
+ },
22
+ },
23
+ })
24
+ }
25
+
26
+ interface WrapperProps {
27
+ children: ReactNode
28
+ }
29
+
30
+ interface CustomRenderOptions extends Omit<RenderOptions, 'wrapper'> {
31
+ /** Initial route entries for MemoryRouter (defaults to ["/"]) */
32
+ routerEntries?: string[]
33
+ /** Provide your own QueryClient (a fresh one is created by default) */
34
+ queryClient?: QueryClient
35
+ }
36
+
37
+ /**
38
+ * Custom render that wraps components with all app providers:
39
+ * - ThemeProvider (light mode for consistent snapshots)
40
+ * - QueryClientProvider (with test-friendly defaults)
41
+ * - MemoryRouter (for components that use routing hooks)
42
+ *
43
+ * Also returns a `user` instance from @testing-library/user-event.
44
+ *
45
+ * @example
46
+ * const { user } = renderWithProviders(<MyComponent />)
47
+ * await user.click(screen.getByRole('button'))
48
+ */
49
+ export function renderWithProviders(
50
+ ui: ReactElement,
51
+ {
52
+ routerEntries = ['/'],
53
+ queryClient = createTestQueryClient(),
54
+ ...renderOptions
55
+ }: CustomRenderOptions = {},
56
+ ) {
57
+ function Wrapper({ children }: WrapperProps) {
58
+ return (
59
+ <ThemeProvider defaultMode="light" storageKey="test-theme">
60
+ <QueryClientProvider client={queryClient}>
61
+ <MemoryRouter initialEntries={routerEntries}>
62
+ {children}
63
+ </MemoryRouter>
64
+ </QueryClientProvider>
65
+ </ThemeProvider>
66
+ )
67
+ }
68
+
69
+ return {
70
+ user: userEvent.setup(),
71
+ ...render(ui, { wrapper: Wrapper, ...renderOptions }),
72
+ }
73
+ }
74
+
75
+ export { createTestQueryClient }
76
+
77
+ // Re-export everything from @testing-library/react for convenience
78
+ export * from '@testing-library/react'
79
+ // Override render with our custom version
80
+ export { renderWithProviders as render }
@@ -11,6 +11,7 @@
11
11
  "moduleDetection": "force",
12
12
  "noEmit": true,
13
13
  "jsx": "react-jsx",
14
+ "types": ["vitest/globals"],
14
15
  "strict": true,
15
16
  "noUnusedLocals": true,
16
17
  "noUnusedParameters": true,
@@ -1,3 +1,4 @@
1
+ /// <reference types="vitest/config" />
1
2
  import { defineConfig } from 'vite'
2
3
  import react from '@vitejs/plugin-react'
3
4
  import { resolve } from 'path'
@@ -18,4 +19,11 @@ export default defineConfig({
18
19
  },
19
20
  },
20
21
  },
22
+ test: {
23
+ globals: true,
24
+ environment: 'jsdom',
25
+ setupFiles: ['./src/__tests__/setup.ts'],
26
+ include: ['src/**/*.spec.{ts,tsx}'],
27
+ css: true,
28
+ },
21
29
  })