Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AI Metadata Display Component with Tests and Documentation #49

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
0852c5c
Add AI Metadata Display component with error handling
amiable-dev Nov 30, 2024
a016b10
Add test configuration and complete wrapper tests
amiable-dev Nov 30, 2024
78650af
Add comprehensive documentation
amiable-dev Nov 30, 2024
d0b78d6
Add example blog post
amiable-dev Nov 30, 2024
509de4e
Add test scripts and dependencies
amiable-dev Nov 30, 2024
1ceea25
Create test.yml
amiable-dev Nov 30, 2024
fdf5f4f
Update package.json with tests
amiable-dev Nov 30, 2024
e7a62f7
Updated package-lock and fixed audit items.
amiable-dev Dec 3, 2024
c4871f5
Fix Jest configuration for Docusaurus babel transform
amiable-dev Dec 3, 2024
6eab777
Fix babel preset path and jest configuration
amiable-dev Dec 3, 2024
ee5a15e
Update test configuration to use SWC and fix Jest setup
amiable-dev Dec 3, 2024
2bf30e0
Align test configuration with Docusaurus's official setup
amiable-dev Dec 3, 2024
464a713
Update Jest configuration to match Docusaurus standards
amiable-dev Dec 3, 2024
7ce5e66
Add Jest setup file with proper mocks
amiable-dev Dec 3, 2024
8d6fb13
Add AIMetadata component tests
amiable-dev Dec 3, 2024
aa8a205
Add BlogPostHeaderWrapper tests
amiable-dev Dec 3, 2024
6c687a4
Add testing documentation
amiable-dev Dec 3, 2024
584f7b0
Update Jest configuration to use jest-serializer-html
amiable-dev Dec 3, 2024
be01118
Reduced to just updated package-lock ...
amiable-dev Dec 3, 2024
6cd36a9
Update package.json to explicitly use jest.config.mjs
amiable-dev Dec 3, 2024
b1e5d1d
Fix Jest configuration and test settings
amiable-dev Dec 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Test

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run tests
run: npm run test:ci

- name: Upload coverage
uses: actions/upload-artifact@v3
with:
name: coverage
path: coverage/
if-no-files-found: error

- name: Check test coverage
run: |
if [ "$(jq -r '.total.lines.pct' coverage/coverage-summary.json)" -lt 80 ]; then
echo "Test coverage is below 80%"
exit 1
fi
114 changes: 114 additions & 0 deletions TESTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Testing Guidelines for Docusaurus Components

## Setup

1. Configuration Files:
- `jest.config.mjs` - Main Jest configuration
- `jest.setup.ts` - Test environment setup

2. Required Dependencies:
```json
{
"devDependencies": {
"@swc/core": "^1.3.0",
"@swc/jest": "^0.2.29",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^14.0.0",
"jest": "^29.5.0",
"snapshot-serializer-beautifier": "^1.0.0"
}
}
```

## Test File Organization

1. Test files should be placed in `__tests__` directories next to the components they test
2. Use `.test.tsx` extension for TypeScript React tests
3. Follow the pattern: `component-name.test.tsx`

## Best Practices

1. Use React Testing Library:
```typescript
import {render, screen} from '@testing-library/react';
```

2. Mock External Dependencies:
```typescript
jest.mock('@theme-original/component', () => ({
default: () => <div>Mocked Component</div>,
}));
```

3. Use Snapshots When Appropriate:
```typescript
expect(container).toMatchSnapshot();
```

4. Test Component Variants:
- Default behavior
- Edge cases
- Error states
- Loading states

5. Mock Console Errors:
```typescript
const consoleError = jest.spyOn(console, 'error').mockImplementation(() => {});
// ... test ...
consoleError.mockRestore();
```

## Common Patterns

1. Testing Optional Props:
```typescript
test('handles missing optional props', () => {
render(<Component required={value} />);
// ... assertions ...
});
```

2. Testing Error States:
```typescript
test('handles error state', () => {
render(<Component error={new Error('Test error')} />);
expect(screen.getByText('Error message')).toBeInTheDocument();
});
```

3. Testing Loading States:
```typescript
test('shows loading state', () => {
render(<Component loading={true} />);
expect(screen.getByRole('progressbar')).toBeInTheDocument();
});
```

## Coverage Requirements

- Minimum 80% coverage required
- Run coverage report: `npm run test:ci`
- Check specific areas: `npm run test:ci -- --coverage --verbose`

## Debugging Tests

1. Use Debug Mode:
```bash
npm run test:debug
```

2. Console Output:
```typescript
screen.debug();
```

3. Test Specific File:
```bash
npm test -- path/to/test.tsx
```

## Resources

- [Docusaurus Testing Examples](https://github.com/facebook/docusaurus/tree/main/packages/docusaurus-theme-classic/src/__tests__)
- [React Testing Library Docs](https://testing-library.com/docs/react-testing-library/intro/)
- [Jest Documentation](https://jestjs.io/docs/getting-started)
4 changes: 2 additions & 2 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module.exports = {
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
};
presets: ['@docusaurus/core/lib/babel/preset'],
};
99 changes: 99 additions & 0 deletions blog/2024-11-30-ai-metadata-example/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
---
title: AI Metadata Display Example
authors: [claude]
tags: [docusaurus, ai, example]
description: An example post demonstrating the AI metadata display component
slug: ai-metadata-example
ai_generated: true
ai_models:
- name: "Claude 3.5 Sonnet"
version: "20241022"
tasks: ["content", "code", "research"]
confidence_score: 0.95
- name: "GPT-4"
version: "0613"
tasks: ["research"]
confidence_score: 0.92
ai_tools:
- name: "Anthropic Messages API"
version: "2024-03"
- name: "GitHub MCP Server"
version: "latest"
ai_review_process: "Human reviewed and edited for technical accuracy and clarity"
ai_quality_metrics:
accuracy: 0.95
coherence: 0.98
technical_depth: 0.92
---

This post demonstrates the AI metadata display component in action. You should see a metadata card at the top of this post showing details about the AI involvement in its creation.

<!--truncate-->

## Component Features

The metadata display shows several key pieces of information:

1. AI Models Used
- Model names and versions
- Tasks performed by each model
- Confidence scores

2. Tools Used
- Names and versions of AI tools
- Integration APIs

3. Review Process
- How content was verified
- Human involvement

4. Quality Metrics
- Accuracy scores
- Coherence ratings
- Technical depth assessment

## Example Use Cases

### 1. Technical Content
```python
# Example code block to test syntax highlighting
def analyze_data(data):
results = {
'accuracy': 0.95,
'confidence': 0.92
}
return results
```

### 2. Documentation
> This is a blockquote showing how various markdown elements render with the component.

### 3. Mixed Content
| Feature | Status |
|---------|--------|
| Metadata Display | ✅ |
| Dark Mode | ✅ |
| Accessibility | ✅ |

## Error Cases

The component handles various error cases gracefully:

1. Missing Metadata
2. Invalid Format
3. Partial Information

## Styling Examples

The component adapts to both light and dark modes:

- Light mode: Clean, professional appearance
- Dark mode: Proper contrast and readability

## Conclusion

This example demonstrates how the AI metadata component:
- Provides transparency about AI involvement
- Maintains good design principles
- Handles various content types
- Adapts to theme settings
26 changes: 26 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/** @type {import('@jest/types').Config.InitialOptions} */
module.exports = {
testEnvironment: 'node',
testEnvironmentOptions: {
url: 'http://localhost',
},
testMatch: ['**/__tests__/**/*.ts', '**/__tests__/**/*.tsx'],
transform: {
'^.+\\.[jt]sx?$': '@docusaurus/core/lib/jest/babelTransform.js',
},
moduleNameMapper: {
'^@site/(.*)$': '<rootDir>/$1',
'^@docusaurus/(.*)': ['@docusaurus/$1', '<rootDir>/node_modules/@docusaurus/$1'],
'^@theme/(.*)$': ['@theme/$1', '@docusaurus/theme-classic/lib/theme/$1'],
},
snapshotSerializers: [
require.resolve('snapshot-serializer-beautifier'),
],
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
testPathIgnorePatterns: ['/node_modules/', '/.docusaurus/', '/build/'],
transformIgnorePatterns: [
'/node_modules/(?!(@docusaurus/|@site/|remark-|rehype-|parse5|unified|bail|trough|vfile|unist|hast|property-information|html-void-elements|ccount|nlcst|linguist))'
],
coveragePathIgnorePatterns: ['/node_modules/', '__tests__'],
collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}'],
};
50 changes: 50 additions & 0 deletions jest.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {fileURLToPath} from 'url';

const config = {
rootDir: fileURLToPath(new URL('.', import.meta.url)),
verbose: true,
testEnvironment: 'jsdom',
testEnvironmentOptions: {
url: 'http://localhost/',
},
setupFilesAfterEnv: ['./jest.setup.ts'],
testMatch: [
'**/__tests__/**/*.[jt]s?(x)',
'**/?(*.)+(spec|test).[tj]s?(x)'
],
testPathIgnorePatterns: [
'/node_modules/',
'/.docusaurus/',
'/build/',
],
transform: {
'^.+\\.[jt]sx?$': [
'@swc/jest',
{
jsc: {
target: 'es2020',
},
},
],
},
moduleNameMapper: {
'^@theme/(.*)$': '@docusaurus/theme-classic/lib/theme/$1',
'^@docusaurus/(.*)$': '@docusaurus/$1',
'^@site/(.*)$': '<rootDir>/$1',
},
transformIgnorePatterns: ['/node_modules/(?!(eta|@docusaurus)/)'],
fakeTimers: {
enableGlobally: true,
},
snapshotSerializers: ['jest-serializer-html'],
collectCoverageFrom: [
'src/**/*.{js,jsx,ts,tsx}',
'!src/**/*.d.ts',
],
coveragePathIgnorePatterns: [
'/node_modules/',
'__tests__',
],
};

export default config;
31 changes: 31 additions & 0 deletions jest.setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const util = require('util');

// Debugging utilities
global.DD = (...args) => {
console.log(util.inspect(args, false, null, true));
};

require('@testing-library/jest-dom');

Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation(query => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(),
removeListener: jest.fn(),
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});

// Mock object required by theme
Object.defineProperty(window, 'docusaurus', {
value: {
prefetch: jest.fn(),
preload: jest.fn(),
},
configurable: true,
});
Loading
Loading