Skip to content

Commit 63feba2

Browse files
babu-chclaude
andcommitted
Add VitePress docs site with 8-language i18n
Multi-locale documentation site deployable to GitHub Pages. - 40 pages: index + 4 guides (getting-started / eslint / rubocop / phpcs) translated to en / ja / zh / ko / es / fr / de / pt - Shared VitePress config with per-locale nav, sidebar, footer labels - Local search enabled, base path /aaa-lint/ for Pages hosting - GitHub Actions workflow triggers on docs/ changes, builds and deploys via actions/deploy-pages - Root scripts: docs:dev / docs:build / docs:preview - Build verified locally (all 8 locales render) NOTE: repo Settings -> Pages -> Source must be set to "GitHub Actions" before the first deploy will work. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 6af018e commit 63feba2

47 files changed

Lines changed: 6083 additions & 141 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/deploy-docs.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Deploy Docs
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- 'docs/**'
8+
- 'package.json'
9+
- 'package-lock.json'
10+
- '.github/workflows/deploy-docs.yml'
11+
workflow_dispatch:
12+
13+
permissions:
14+
contents: read
15+
pages: write
16+
id-token: write
17+
18+
concurrency:
19+
group: pages
20+
cancel-in-progress: false
21+
22+
jobs:
23+
build:
24+
runs-on: ubuntu-latest
25+
steps:
26+
- uses: actions/checkout@v4
27+
- uses: actions/setup-node@v4
28+
with:
29+
node-version: '20'
30+
cache: 'npm'
31+
- run: npm ci
32+
- run: npm run docs:build
33+
- uses: actions/configure-pages@v5
34+
- uses: actions/upload-pages-artifact@v3
35+
with:
36+
path: docs/.vitepress/dist
37+
38+
deploy:
39+
needs: build
40+
runs-on: ubuntu-latest
41+
environment:
42+
name: github-pages
43+
url: ${{ steps.deployment.outputs.page_url }}
44+
steps:
45+
- id: deployment
46+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
node_modules/
22
dist/
3+
docs/.vitepress/dist/
4+
docs/.vitepress/cache/
35
composer.lock
46
.phpunit.result.cache
57
.DS_Store

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ There is no built-in preset besides the English default. Use the `labels` option
4040
}
4141
```
4242

43+
## Documentation
44+
45+
Full docs (English / 日本語 / 中文 / 한국어 / Español / Français / Deutsch / Português): <https://babu-ch.github.io/aaa-lint/>
46+
4347
## Development
4448

4549
All tests run inside Docker — no local Node/Ruby/PHP installs required. See [DEVELOPMENT.md](./DEVELOPMENT.md).

docs/.vitepress/config.mts

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
import { defineConfig, type DefaultTheme } from 'vitepress'
2+
3+
const guideSidebar = (prefix: string, labels: {
4+
gettingStarted: string
5+
eslint: string
6+
rubocop: string
7+
phpcs: string
8+
guide: string
9+
}): DefaultTheme.SidebarItem[] => [
10+
{
11+
text: labels.guide,
12+
items: [
13+
{ text: labels.gettingStarted, link: `${prefix}/guide/getting-started` },
14+
{ text: labels.eslint, link: `${prefix}/guide/eslint` },
15+
{ text: labels.rubocop, link: `${prefix}/guide/rubocop` },
16+
{ text: labels.phpcs, link: `${prefix}/guide/phpcs` }
17+
]
18+
}
19+
]
20+
21+
export default defineConfig({
22+
title: 'aaa-lint',
23+
description: 'Enforce the Arrange-Act-Assert pattern in your tests.',
24+
base: '/aaa-lint/',
25+
cleanUrls: true,
26+
lastUpdated: true,
27+
28+
head: [
29+
['link', { rel: 'icon', href: '/aaa-lint/favicon.svg', type: 'image/svg+xml' }]
30+
],
31+
32+
themeConfig: {
33+
socialLinks: [
34+
{ icon: 'github', link: 'https://github.com/babu-ch/aaa-lint' }
35+
],
36+
search: { provider: 'local' }
37+
},
38+
39+
locales: {
40+
root: {
41+
label: 'English',
42+
lang: 'en',
43+
link: '/',
44+
themeConfig: {
45+
nav: [
46+
{ text: 'Guide', link: '/guide/getting-started' },
47+
{ text: 'GitHub', link: 'https://github.com/babu-ch/aaa-lint' }
48+
],
49+
sidebar: guideSidebar('', {
50+
guide: 'Guide',
51+
gettingStarted: 'Getting Started',
52+
eslint: 'ESLint (JS / TS)',
53+
rubocop: 'RuboCop (Ruby)',
54+
phpcs: 'PHP_CodeSniffer (PHP)'
55+
}),
56+
docFooter: { prev: 'Previous', next: 'Next' }
57+
}
58+
},
59+
ja: {
60+
label: '日本語',
61+
lang: 'ja',
62+
link: '/ja/',
63+
themeConfig: {
64+
nav: [
65+
{ text: 'ガイド', link: '/ja/guide/getting-started' },
66+
{ text: 'GitHub', link: 'https://github.com/babu-ch/aaa-lint' }
67+
],
68+
sidebar: guideSidebar('/ja', {
69+
guide: 'ガイド',
70+
gettingStarted: 'はじめに',
71+
eslint: 'ESLint (JS / TS)',
72+
rubocop: 'RuboCop (Ruby)',
73+
phpcs: 'PHP_CodeSniffer (PHP)'
74+
}),
75+
docFooter: { prev: '前のページ', next: '次のページ' }
76+
}
77+
},
78+
zh: {
79+
label: '中文',
80+
lang: 'zh',
81+
link: '/zh/',
82+
themeConfig: {
83+
nav: [
84+
{ text: '指南', link: '/zh/guide/getting-started' },
85+
{ text: 'GitHub', link: 'https://github.com/babu-ch/aaa-lint' }
86+
],
87+
sidebar: guideSidebar('/zh', {
88+
guide: '指南',
89+
gettingStarted: '快速开始',
90+
eslint: 'ESLint (JS / TS)',
91+
rubocop: 'RuboCop (Ruby)',
92+
phpcs: 'PHP_CodeSniffer (PHP)'
93+
}),
94+
docFooter: { prev: '上一页', next: '下一页' }
95+
}
96+
},
97+
ko: {
98+
label: '한국어',
99+
lang: 'ko',
100+
link: '/ko/',
101+
themeConfig: {
102+
nav: [
103+
{ text: '가이드', link: '/ko/guide/getting-started' },
104+
{ text: 'GitHub', link: 'https://github.com/babu-ch/aaa-lint' }
105+
],
106+
sidebar: guideSidebar('/ko', {
107+
guide: '가이드',
108+
gettingStarted: '시작하기',
109+
eslint: 'ESLint (JS / TS)',
110+
rubocop: 'RuboCop (Ruby)',
111+
phpcs: 'PHP_CodeSniffer (PHP)'
112+
}),
113+
docFooter: { prev: '이전', next: '다음' }
114+
}
115+
},
116+
es: {
117+
label: 'Español',
118+
lang: 'es',
119+
link: '/es/',
120+
themeConfig: {
121+
nav: [
122+
{ text: 'Guía', link: '/es/guide/getting-started' },
123+
{ text: 'GitHub', link: 'https://github.com/babu-ch/aaa-lint' }
124+
],
125+
sidebar: guideSidebar('/es', {
126+
guide: 'Guía',
127+
gettingStarted: 'Primeros pasos',
128+
eslint: 'ESLint (JS / TS)',
129+
rubocop: 'RuboCop (Ruby)',
130+
phpcs: 'PHP_CodeSniffer (PHP)'
131+
}),
132+
docFooter: { prev: 'Anterior', next: 'Siguiente' }
133+
}
134+
},
135+
fr: {
136+
label: 'Français',
137+
lang: 'fr',
138+
link: '/fr/',
139+
themeConfig: {
140+
nav: [
141+
{ text: 'Guide', link: '/fr/guide/getting-started' },
142+
{ text: 'GitHub', link: 'https://github.com/babu-ch/aaa-lint' }
143+
],
144+
sidebar: guideSidebar('/fr', {
145+
guide: 'Guide',
146+
gettingStarted: 'Démarrage',
147+
eslint: 'ESLint (JS / TS)',
148+
rubocop: 'RuboCop (Ruby)',
149+
phpcs: 'PHP_CodeSniffer (PHP)'
150+
}),
151+
docFooter: { prev: 'Précédent', next: 'Suivant' }
152+
}
153+
},
154+
de: {
155+
label: 'Deutsch',
156+
lang: 'de',
157+
link: '/de/',
158+
themeConfig: {
159+
nav: [
160+
{ text: 'Leitfaden', link: '/de/guide/getting-started' },
161+
{ text: 'GitHub', link: 'https://github.com/babu-ch/aaa-lint' }
162+
],
163+
sidebar: guideSidebar('/de', {
164+
guide: 'Leitfaden',
165+
gettingStarted: 'Erste Schritte',
166+
eslint: 'ESLint (JS / TS)',
167+
rubocop: 'RuboCop (Ruby)',
168+
phpcs: 'PHP_CodeSniffer (PHP)'
169+
}),
170+
docFooter: { prev: 'Vorherige', next: 'Nächste' }
171+
}
172+
},
173+
pt: {
174+
label: 'Português',
175+
lang: 'pt',
176+
link: '/pt/',
177+
themeConfig: {
178+
nav: [
179+
{ text: 'Guia', link: '/pt/guide/getting-started' },
180+
{ text: 'GitHub', link: 'https://github.com/babu-ch/aaa-lint' }
181+
],
182+
sidebar: guideSidebar('/pt', {
183+
guide: 'Guia',
184+
gettingStarted: 'Primeiros passos',
185+
eslint: 'ESLint (JS / TS)',
186+
rubocop: 'RuboCop (Ruby)',
187+
phpcs: 'PHP_CodeSniffer (PHP)'
188+
}),
189+
docFooter: { prev: 'Anterior', next: 'Próximo' }
190+
}
191+
}
192+
}
193+
})

docs/de/guide/eslint.md

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# ESLint (JS / TS)
2+
3+
`eslint-plugin-aaa` erzwingt das Arrange-Act-Assert-Muster in JavaScript- / TypeScript-Testdateien.
4+
5+
## Installation
6+
7+
```bash
8+
npm install --save-dev eslint-plugin-aaa
9+
```
10+
11+
## Flat config (ESLint v9+)
12+
13+
```js
14+
// eslint.config.js
15+
import aaa from 'eslint-plugin-aaa'
16+
17+
export default [
18+
{
19+
files: ['**/*.test.{js,ts}'],
20+
plugins: { aaa },
21+
rules: {
22+
'aaa/pattern': 'error'
23+
}
24+
}
25+
]
26+
```
27+
28+
Oder die mitgelieferte Empfehlung nutzen:
29+
30+
```js
31+
import aaa from 'eslint-plugin-aaa'
32+
33+
export default [aaa.configs.recommended]
34+
```
35+
36+
## Legacy config (ESLint v8)
37+
38+
```jsonc
39+
// .eslintrc.json
40+
{
41+
"plugins": ["aaa"],
42+
"overrides": [
43+
{
44+
"files": ["**/*.test.js"],
45+
"rules": { "aaa/pattern": "error" }
46+
}
47+
]
48+
}
49+
```
50+
51+
## Regel: `aaa/pattern`
52+
53+
### Optionen
54+
55+
```jsonc
56+
{
57+
"aaa/pattern": ["error", {
58+
"labels": {
59+
"arrange": ["arrange"],
60+
"act": ["act"],
61+
"assert": ["assert"]
62+
},
63+
"testFunctions": ["it", "test"],
64+
"caseSensitive": false,
65+
"allowEmptySection": true
66+
}]
67+
}
68+
```
69+
70+
| Option | Standard | Beschreibung |
71+
|---|---|---|
72+
| `labels` | Englische Standards | Akzeptierte Kommentartexte je Sektion. Array, Synonyme möglich. |
73+
| `testFunctions` | `["it", "test"]` | Test-definierende Aufrufe, die inspiziert werden. Ergänze `"specify"`, `"example"` etc. |
74+
| `caseSensitive` | `false` | Bei `false` entspricht `// ARRANGE` dem Wort `arrange`. |
75+
| `allowEmptySection` | `true` | Bei `false` wird gemeldet, wenn eine Sektion keine Anweisungen enthält. |
76+
77+
### Beispiele
78+
79+
#### Given / When / Then
80+
81+
```jsonc
82+
{
83+
"labels": {
84+
"arrange": ["given"],
85+
"act": ["when"],
86+
"assert": ["then"]
87+
}
88+
}
89+
```
90+
91+
#### Deutsch
92+
93+
```jsonc
94+
{
95+
"labels": {
96+
"arrange": ["vorbereiten", "gegeben"],
97+
"act": ["ausführen"],
98+
"assert": ["prüfen", "erwarten"]
99+
}
100+
}
101+
```
102+
103+
### Was erkannt wird
104+
105+
```js
106+
// Fehler: "arrange"-Kommentar fehlt
107+
it('bad', () => {
108+
// act
109+
const x = doThing()
110+
// assert
111+
expect(x).toBe(1)
112+
})
113+
114+
// Fehler: falsche Reihenfolge
115+
it('also bad', () => {
116+
// act
117+
const x = doThing()
118+
// arrange
119+
const y = 1
120+
// assert
121+
expect(x).toBe(y)
122+
})
123+
```

0 commit comments

Comments
 (0)