Skip to content

Commit 55b590d

Browse files
add tests to verify content file structure
1 parent 00f82d3 commit 55b590d

File tree

10 files changed

+4480
-0
lines changed

10 files changed

+4480
-0
lines changed

.circleci/config.yml

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
version: 2.1
2+
3+
orbs:
4+
cypress: cypress-io/[email protected]
5+
6+
references:
7+
default_env: &default_env
8+
docker:
9+
- image: cypress/base:12.14.0
10+
working_directory: ~/repo
11+
12+
repo_cache_key_1: &repo_cache_key_1 v1-cypress-repo-{{ arch}}-{{ .Branch }}-{{ .Revision }}
13+
repo_cache_key_2: &repo_cache_key_2 v1-cypress-repo-{{ arch}}-{{ .Branch }}
14+
repo_cache_key_3: &repo_cache_key_3 v1-cypress-repo-{{ arch}}
15+
16+
restore_repo: &restore_repo
17+
restore_cache:
18+
keys:
19+
- *repo_cache_key_1
20+
- *repo_cache_key_2
21+
- *repo_cache_key_3
22+
23+
jobs:
24+
checkout_code:
25+
<<: *default_env
26+
steps:
27+
- *restore_repo
28+
- checkout
29+
- run: npx [email protected] --production=false --frozen-lockfile
30+
- save_cache:
31+
key: *repo_cache_key_1
32+
paths:
33+
- .
34+
35+
verify_formatting:
36+
<<: *default_env
37+
steps:
38+
- *restore_repo
39+
- run:
40+
name: Verify Prettier
41+
command: yarn prettier:verify
42+
43+
verify_compile:
44+
<<: *default_env
45+
steps:
46+
- *restore_repo
47+
- run:
48+
name: Verify Typescript
49+
command: yarn compile
50+
51+
verify_lint:
52+
<<: *default_env
53+
steps:
54+
- *restore_repo
55+
- run:
56+
name: Verify ESLint
57+
command: yarn lint --format junit --output-file /tmp/test-results/eslint.xml
58+
- store_test_results:
59+
path: /tmp/test-results
60+
61+
tests:
62+
<<: *default_env
63+
parallelism: 4
64+
resource_class: large
65+
steps:
66+
- *restore_repo
67+
- run:
68+
name: Run test suite
69+
command: yarn test
70+
71+
workflows:
72+
version: 2
73+
test:
74+
jobs:
75+
- checkout_code
76+
- verify_compile:
77+
requires:
78+
- checkout_code
79+
- verify_lint:
80+
requires:
81+
- checkout_code
82+
- verify_formatting:
83+
requires:
84+
- checkout_code
85+
- tests:
86+
requires:
87+
- checkout_code

.eslintrc.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": ["@codecademy/eslint-config"]
3+
}

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,9 @@
11
.DS_Store
2+
node_modules
3+
package-lock.json
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
*.swp
8+
*.swo
9+
tmp

.prettierignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
yarn.lock

.prettierrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('@codecademy/prettier-config');

content.test.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import fs from 'fs';
2+
import path from 'path';
3+
4+
describe('Codecademy Docs Content', () => {
5+
it('adheres to content file structure', () => {
6+
// file names can only contain alphanumerics and hyphens
7+
const validateName = (pathName: string, name: string) => {
8+
const filteredName = name.replace(/[^A-Za-z0-9.-]/g, '');
9+
10+
// format so that test failures are more helpful
11+
if (filteredName !== name) {
12+
expect(`${pathName} - file name must only include alphanumerics or -`).toBe('');
13+
}
14+
};
15+
16+
// nodes can have n directories of children and at most one .md file with the same name as its parent directory
17+
const checkNode = (nodePath: string) => {
18+
const children = fs.readdirSync(nodePath);
19+
20+
children.forEach((child) => {
21+
const childPath = path.join(nodePath, child);
22+
validateName(childPath, child);
23+
24+
if (fs.statSync(childPath).isDirectory()) {
25+
checkChild(childPath);
26+
} else {
27+
const nodeName = nodePath.split('/').slice(-1)[0];
28+
expect(childPath).toBe(path.join(nodePath, `${nodeName}.md`));
29+
}
30+
});
31+
};
32+
33+
// children can only be directories of nodes
34+
const checkChild = (childPath: string) => {
35+
const nodes = fs.readdirSync(childPath);
36+
37+
nodes.forEach((node) => {
38+
const nodePath = path.join(childPath, node);
39+
validateName(nodePath, node);
40+
41+
// format so that test failures are more helpful
42+
if(!fs.statSync(nodePath).isDirectory()) {
43+
expect(`${nodePath} - expected a directory but got a file`).toBe('');
44+
}
45+
checkNode(nodePath);
46+
});
47+
};
48+
49+
checkChild(path.join(__dirname, 'content'));
50+
});
51+
});

jest.config.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module.exports = {
2+
preset: 'ts-jest',
3+
testEnvironment: 'node',
4+
clearMocks: true,
5+
testMatch: ['**/*test.ts'],
6+
testPathIgnorePatterns: ['<rootDir>/[/\\\\]node_modules[/\\\\]'],
7+
};

package.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "CodecademyDocs",
3+
"devDependencies": {
4+
"@codecademy/eslint-config": "5.0.0",
5+
"@codecademy/prettier-config": "^0.1.10",
6+
"@codecademy/tsconfig": "^0.2.0",
7+
"@types/jest": "^26.0.24",
8+
"@types/node": "^16.4.3",
9+
"eslint": "^7.25.0",
10+
"jest": "^27.0.6",
11+
"prettier": "^2.2.1",
12+
"ts-jest": "^27.0.4",
13+
"typescript": "^4.2.4"
14+
},
15+
"scripts": {
16+
"compile": "tsc --noEmit",
17+
"format": "prettier --ignore-path .prettierignore --write",
18+
"format:verify": "prettier \"./**.ts\" --list-different",
19+
"lint": "eslint \"./**.ts\" --max-warnings 0",
20+
"test": "jest"
21+
},
22+
"version": "1.0.0"
23+
}

tsconfig.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"extends": "@codecademy/tsconfig",
3+
"compilerOptions": {
4+
"allowJs": true,
5+
"baseUrl": ".",
6+
"isolatedModules": true,
7+
"lib": ["dom", "dom.iterable", "esnext"],
8+
"noEmit": true,
9+
"noImplicitReturns": true,
10+
"module": "commonjs",
11+
"moduleResolution": "node",
12+
"resolveJsonModule": true
13+
},
14+
"exclude": ["node_modules"],
15+
"include": ["**/*.ts"]
16+
}

0 commit comments

Comments
 (0)