diff --git a/packages/mdxui/core/tests/__mocks__/testing-library-react.ts b/packages/mdxui/core/tests/__mocks__/testing-library-react.ts
new file mode 100644
index 000000000..05b282501
--- /dev/null
+++ b/packages/mdxui/core/tests/__mocks__/testing-library-react.ts
@@ -0,0 +1,45 @@
+import React from 'react'
+
+function createDomNode(element: React.ReactElement): HTMLElement {
+ if (typeof element.type === 'function') {
+ return createDomNode(element.type(element.props))
+ }
+ const node = document.createElement(element.type as string)
+ const { children, className, ...rest } = element.props || {}
+ if (className) node.setAttribute('class', className)
+ Object.entries(rest).forEach(([k, v]) => {
+ if (v != null) node.setAttribute(k, String(v))
+ })
+ React.Children.toArray(children).forEach((child) => {
+ if (typeof child === 'string') {
+ node.appendChild(document.createTextNode(child))
+ } else {
+ node.appendChild(createDomNode(child as React.ReactElement))
+ }
+ })
+ return node
+}
+
+export function render(ui: React.ReactElement) {
+ const container = document.createElement('div')
+ container.appendChild(createDomNode(ui))
+ document.body.appendChild(container)
+ return { container }
+}
+
+export const screen = {
+ getByRole(role: string) {
+ return document.querySelector(`[role="${role}"]`) as HTMLElement
+ },
+ getByText(text: string) {
+ const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT)
+ while (walker.nextNode()) {
+ const el = walker.currentNode as HTMLElement
+ if (el.textContent && el.textContent.includes(text)) return el
+ }
+ throw new Error('Element not found')
+ },
+ getByTestId(id: string) {
+ return document.querySelector(`[data-testid="${id}"]`) as HTMLElement
+ }
+}
diff --git a/packages/mdxui/core/tests/index.test.ts b/packages/mdxui/core/tests/index.test.ts
deleted file mode 100644
index 9d8fa7c94..000000000
--- a/packages/mdxui/core/tests/index.test.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { describe, it, expect } from 'vitest'
-
-describe('mdxui package', () => {
- it('should be importable', () => {
- expect(true).toBe(true)
- })
-})
diff --git a/packages/mdxui/core/tests/index.test.tsx b/packages/mdxui/core/tests/index.test.tsx
new file mode 100644
index 000000000..e526b428a
--- /dev/null
+++ b/packages/mdxui/core/tests/index.test.tsx
@@ -0,0 +1,30 @@
+import { describe, it, expect } from 'vitest'
+import { render, screen } from '@testing-library/react'
+import React from 'react'
+import { Button } from '../components/button'
+import { Card } from '../components/card'
+import { Gradient } from '../components/gradient'
+
+describe('exported components', () => {
+ it('renders Button', () => {
+ render()
+ const button = document.querySelector('button')
+ expect(button).not.toBeNull()
+ })
+
+ it('renders Card', () => {
+ render(
+
+ Card body
+
+ )
+ const link = document.querySelector('a')
+ expect(link?.getAttribute('href')).to.contain('https://example.com')
+ expect(screen.getByText('Card body')).not.toBeNull()
+ })
+
+ it('renders Gradient', () => {
+ const { container } = render(
)
+ expect(container.querySelector('span')).not.toBeNull()
+ })
+})
diff --git a/packages/mdxui/core/tests/workflow.test.ts b/packages/mdxui/core/tests/workflow.test.ts
index eed43911f..a758bd3c1 100644
--- a/packages/mdxui/core/tests/workflow.test.ts
+++ b/packages/mdxui/core/tests/workflow.test.ts
@@ -1,33 +1,56 @@
import { describe, it, expect } from 'vitest'
import { z } from 'zod'
-import type { Step, Workflow } from '../workflow'
-
-describe('Workflow interfaces', () => {
- it('should define Step interface correctly', () => {
- const step: Step = {
- id: 'test-step',
- name: 'Test Step',
- description: 'A test step',
+import type { Step, Workflow, WorkflowExecution } from '../workflow'
+
+async function executeStep(step: Step, input: TInput): Promise {
+ if (step.inputSchema) step.inputSchema.parse(input)
+ const result = await step.execute?.(input)
+ return step.outputSchema.parse(result)
+}
+
+describe('workflow utilities', () => {
+ it('executes a step with schema validation', async () => {
+ const step: Step<{ input: string }, { output: string }> = {
+ id: 'step',
+ name: 'Example',
inputSchema: z.object({ input: z.string() }),
outputSchema: z.object({ output: z.string() }),
+ execute: async (value) => ({ output: value.input.toUpperCase() }),
}
- expect(step.id).toBe('test-step')
- expect(step.name).toBe('Test Step')
- expect(step.inputSchema).toBeDefined()
- expect(step.outputSchema).toBeDefined()
+ const result = await executeStep(step, { input: 'test' })
+ expect(result.output).toBe('TEST')
})
- it('should define Workflow interface correctly', () => {
- const workflow: Workflow = {
- id: 'test-workflow',
- name: 'Test Workflow',
- inputSchema: z.object({ start: z.string() }),
- outputSchema: z.object({ end: z.string() }),
- steps: [],
+ it('tracks workflow execution state', async () => {
+ const step: Step = {
+ id: 's1',
+ name: 'first',
+ outputSchema: z.string(),
+ execute: async () => 'done',
+ }
+
+ const workflow: Workflow = {
+ id: 'wf',
+ name: 'wf',
+ inputSchema: z.undefined(),
+ outputSchema: z.string(),
+ steps: [step],
}
- expect(workflow.id).toBe('test-workflow')
- expect(workflow.steps).toEqual([])
+ const execution: WorkflowExecution = {
+ workflow,
+ currentStepIndex: 0,
+ stepResults: {},
+ status: 'pending',
+ }
+
+ const output = await executeStep(workflow.steps[0], undefined)
+ execution.stepResults[step.id] = output
+ execution.currentStepIndex = 1
+ execution.status = 'completed'
+
+ expect(execution.stepResults[step.id]).toBe('done')
+ expect(execution.status).toBe('completed')
})
})
diff --git a/packages/mdxui/core/vitest.config.ts b/packages/mdxui/core/vitest.config.ts
index 9fd90ef52..0c25681d7 100644
--- a/packages/mdxui/core/vitest.config.ts
+++ b/packages/mdxui/core/vitest.config.ts
@@ -1,10 +1,15 @@
import { defineConfig } from 'vitest/config'
export default defineConfig({
+ resolve: {
+ alias: {
+ '@testing-library/react': new URL('./tests/__mocks__/testing-library-react.ts', import.meta.url).pathname,
+ },
+ },
test: {
globals: true,
environment: 'jsdom',
- include: ['src/**/*.test.{ts,tsx}'],
+ include: ['src/**/*.test.{ts,tsx}', 'tests/**/*.test.{ts,tsx}'],
exclude: ['**/node_modules/**', '**/dist/**'],
testTimeout: 300000,
coverage: {