This commit introduces a comprehensive Astro integration that automatically generates discovery files for websites: Features: - robots.txt with LLM bot support (Anthropic-AI, GPTBot, etc.) - llms.txt for AI assistant context and instructions - humans.txt for team credits and site information - Automatic sitemap integration via @astrojs/sitemap Technical Details: - TypeScript implementation with full type safety - Configurable HTTP caching headers - Custom template support for all generated files - Sensible defaults with extensive customization options - Date-based versioning (2025.11.03) Testing: - 34 unit tests covering all generators - Test coverage for robots.txt, llms.txt, and humans.txt - Integration with Vitest Documentation: - Comprehensive README with examples - API reference documentation - Contributing guidelines - Example configurations (minimal and full)
156 lines
4.2 KiB
TypeScript
156 lines
4.2 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { generateHumansTxt } from '../src/generators/humans.js';
|
|
|
|
describe('generateHumansTxt', () => {
|
|
it('generates basic humans.txt structure', () => {
|
|
const result = generateHumansTxt({});
|
|
expect(result).toBeTruthy();
|
|
});
|
|
|
|
it('includes team section', () => {
|
|
const result = generateHumansTxt({
|
|
team: [
|
|
{
|
|
name: 'Jane Doe',
|
|
role: 'Developer',
|
|
contact: 'jane@example.com',
|
|
location: 'SF',
|
|
twitter: '@jane',
|
|
github: 'jane',
|
|
},
|
|
],
|
|
});
|
|
|
|
expect(result).toContain('/* TEAM */');
|
|
expect(result).toContain('Name: Jane Doe');
|
|
expect(result).toContain('Role: Developer');
|
|
expect(result).toContain('Contact: jane@example.com');
|
|
expect(result).toContain('From: SF');
|
|
expect(result).toContain('Twitter: @jane');
|
|
expect(result).toContain('GitHub: jane');
|
|
});
|
|
|
|
it('includes multiple team members', () => {
|
|
const result = generateHumansTxt({
|
|
team: [
|
|
{ name: 'Jane Doe' },
|
|
{ name: 'John Smith' },
|
|
],
|
|
});
|
|
|
|
expect(result).toContain('Jane Doe');
|
|
expect(result).toContain('John Smith');
|
|
});
|
|
|
|
it('includes thanks section', () => {
|
|
const result = generateHumansTxt({
|
|
thanks: ['Coffee', 'Stack Overflow'],
|
|
});
|
|
|
|
expect(result).toContain('/* THANKS */');
|
|
expect(result).toContain('Coffee');
|
|
expect(result).toContain('Stack Overflow');
|
|
});
|
|
|
|
it('includes site section with auto date', () => {
|
|
const result = generateHumansTxt({
|
|
site: {
|
|
lastUpdate: 'auto',
|
|
language: 'English',
|
|
doctype: 'HTML5',
|
|
ide: 'VS Code',
|
|
},
|
|
});
|
|
|
|
const today = new Date().toISOString().split('T')[0];
|
|
|
|
expect(result).toContain('/* SITE */');
|
|
expect(result).toContain(`Last update: ${today}`);
|
|
expect(result).toContain('Language: English');
|
|
expect(result).toContain('Doctype: HTML5');
|
|
expect(result).toContain('IDE: VS Code');
|
|
});
|
|
|
|
it('includes site section with custom date', () => {
|
|
const result = generateHumansTxt({
|
|
site: {
|
|
lastUpdate: '2025-11-03',
|
|
},
|
|
});
|
|
|
|
expect(result).toContain('Last update: 2025-11-03');
|
|
});
|
|
|
|
it('includes tech stack', () => {
|
|
const result = generateHumansTxt({
|
|
site: {
|
|
techStack: ['Astro', 'TypeScript', 'React'],
|
|
standards: ['HTML5', 'CSS3'],
|
|
components: ['Astro Components'],
|
|
software: ['VS Code', 'Git'],
|
|
},
|
|
});
|
|
|
|
expect(result).toContain('Tech Stack: Astro, TypeScript, React');
|
|
expect(result).toContain('Standards: HTML5, CSS3');
|
|
expect(result).toContain('Components: Astro Components');
|
|
expect(result).toContain('Software: VS Code, Git');
|
|
});
|
|
|
|
it('includes story section', () => {
|
|
const result = generateHumansTxt({
|
|
story: 'This is our story.\nIt spans multiple lines.',
|
|
});
|
|
|
|
expect(result).toContain('/* THE STORY */');
|
|
expect(result).toContain('This is our story.');
|
|
});
|
|
|
|
it('includes fun facts', () => {
|
|
const result = generateHumansTxt({
|
|
funFacts: ['Built with love', 'Coffee powered'],
|
|
});
|
|
|
|
expect(result).toContain('/* FUN FACTS */');
|
|
expect(result).toContain('Built with love');
|
|
expect(result).toContain('Coffee powered');
|
|
});
|
|
|
|
it('includes philosophy section', () => {
|
|
const result = generateHumansTxt({
|
|
philosophy: ['Make it simple', 'Make it work'],
|
|
});
|
|
|
|
expect(result).toContain('/* PHILOSOPHY */');
|
|
expect(result).toContain('"Make it simple"');
|
|
expect(result).toContain('"Make it work"');
|
|
});
|
|
|
|
it('includes custom sections', () => {
|
|
const result = generateHumansTxt({
|
|
customSections: {
|
|
'CONTACT': 'Email: info@example.com',
|
|
'LICENSE': 'MIT License',
|
|
},
|
|
});
|
|
|
|
expect(result).toContain('/* CONTACT */');
|
|
expect(result).toContain('Email: info@example.com');
|
|
expect(result).toContain('/* LICENSE */');
|
|
expect(result).toContain('MIT License');
|
|
});
|
|
|
|
it('properly indents content', () => {
|
|
const result = generateHumansTxt({
|
|
team: [{ name: 'Jane' }],
|
|
});
|
|
|
|
expect(result).toContain(' Name: Jane');
|
|
});
|
|
|
|
it('ends with newline', () => {
|
|
const result = generateHumansTxt({});
|
|
expect(result.endsWith('\n')).toBe(true);
|
|
});
|
|
});
|