Skip to content

Commit

Permalink
Add CI linting + tests (#2)
Browse files Browse the repository at this point in the history
* feat: ini vitest

* feat: ini typescript+eslint+prettier

* feat: ini read-file

* feat: add MDX content validation tests

* Create lint.yml

* Create .nvmrc

* Update lint.yml

* Update lint.yml

* Update lint.yml

* tests: run content tests on all MDX files inside `./puzzles`

* Create tests.yml

* Update tests.yml

* Update tests.yml
  • Loading branch information
fiveoutofnine authored Dec 3, 2023
1 parent 3eb3ecf commit 31e021c
Show file tree
Hide file tree
Showing 18 changed files with 4,238 additions and 0 deletions.
23 changes: 23 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module.exports = {
env: {
browser: true,
es2021: true,
node: true,
},
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
overrides: [],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
plugins: ['@typescript-eslint', 'prettier'],
rules: {
'linebreak-style': ['error', 'unix'],
quotes: ['error', 'single'],
semi: ['error', 'always'],
'comma-dangle': [2, 'always-multiline'],
'prettier/prettier': 'error',
indent: 'off',
},
};
20 changes: 20 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Lint

on: [push, pull_request]

jobs:
lint:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Setup Node.js
uses: actions/setup-node@v4

- name: Install dependencies
run: npm install

- name: Run linter
run: npm run lint
20 changes: 20 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Tests

on: [push, pull_request]

jobs:
tests:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Setup Node.js
uses: actions/setup-node@v4

- name: Install dependencies
run: npm install

- name: Run tests
run: npm run test
29 changes: 29 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# local env files
.env*.local
.env

# typescript
*.tsbuildinfo
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
18.17.1
6 changes: 6 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"recommendations": [
"ms-vscode.vscode-typescript-tslint-plugin",
"esbenp.prettier-vscode"
]
}
12 changes: 12 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"javascript.updateImportsOnFileMove.enabled": "always",
"editor.rulers": [80, 100],
"editor.tabSize": 2,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"editor.formatOnSave": true,
"eslint.validate": ["javascript", "javascriptreact"],
"typescript.updateImportsOnFileMove.enabled": "always",
"editor.inlineSuggest.enabled": true,
}
239 changes: 239 additions & 0 deletions lib/constants/elements.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
export const CUSTOM_ELEMENTS = new Set([
'Callout',
'ComponentsDisplay',
'CredentialFeature',
'Description',
'Image',
'LinkFeature',
'LogoIcon',
]);

export const HTML_ELEMENTS = new Set([
/* 'html',
'base',
'head',
'link',
'meta',
'style',
'title',
'body', */
'address',
'article',
'aside',
'footer',
'header',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'hgroup',
'main',
'nav',
'section',
'search',
'blockquote',
'dd',
'div',
'dl',
'dt',
'figcaption',
'figure',
'hr',
'li',
'menu',
'ol',
'p',
'pre',
'ul',
'a',
'abbr',
'b',
'bdi',
'bo',
'br',
'cite',
'code',
'data',
'dfn',
'em',
'i',
'kbd',
'mark',
'q',
'rp',
'rt',
'ruby',
's',
'samp',
'small',
'span',
'strong',
'sub',
'sup',
'time',
'u',
'var',
'wbr',
'area',
'audio',
'img',
'map',
'track',
'video',
/* 'embed',
'iframe',
'object',
'picture',
'portal',
'source', */
'svg',
'math',
/* 'canvas',
'noscript',
'script', */
'del',
'ins',
'caption',
'col',
'colgroup',
'table',
'tbody',
'td',
'tfoot',
'th',
'thead',
'tr',
'button',
'datalist',
'fieldset',
'form',
'input',
'label',
'Legend',
'meter',
'optgroup',
'option',
'output',
'progress',
'select',
'textarea',
'details',
'dialog',
'summary',
'slot',
'template',
]);

export const JSX_ELEMENTS = new Set(['_Fragment']);

export const MATH_ELEMENTS = new Set([
'maction',
'math',
'menclose',
'merror',
'mfenced',
'mfrac',
'mi',
'mmultiscripts',
'mn',
'mo',
'mover',
'mpadded',
'mphantom',
'mroot',
'mrow',
'ms',
'mspace',
'msqrt',
'mstyle',
'msub',
'msubsup',
'msup',
'mtable',
'mtd',
'mtext',
'tr',
'under',
'munderover',
'semantics',
'annotation',
]);

export const MDX_ELEMENTS = new Set(['_createMdxContent', 'MDXLayout']);

export const SVG_ELEMENTS = new Set([
'a',
'animate',
'animateMotion',
'animateTransform',
'circle',
'clipPath',
'defs',
'desc',
'ellipse',
'feBlend',
'feColorMatrix',
'feComponentTransfer',
'feComposite',
'feConvolveMatrix',
'feDiffuseLighting',
'feDisplacementMap',
'feDistantLight',
'feDropShadow',
'feFlood',
'feFuncA',
'feFuncB',
'feFuncG',
'feFuncR',
'feGaussianBlur',
'feImage',
'feMerge',
'feMergeNode',
'feMorphology',
'feOffset',
'fePointLight',
'feSpecularLighting',
'feSpotLight',
'feTile',
'feTurbulence',
'filter',
/* 'foreignObject', */
'g',
'image',
'line',
'linearGradient',
'marker',
'mask',
'metadata',
'mpath',
'path',
'Pattern',
'polygon',
'polyline',
'radialGradient',
'rect',
/* 'script', */
'set',
'stop',
'style',
'svg',
'switch',
'symbol',
'text',
'textPath',
'title',
'tspan',
'use',
'view',
]);

export const ELEMENTS = new Set([
...CUSTOM_ELEMENTS,
...HTML_ELEMENTS,
...JSX_ELEMENTS,
...MATH_ELEMENTS,
...MDX_ELEMENTS,
...SVG_ELEMENTS,
]);
36 changes: 36 additions & 0 deletions lib/utils/get-unique-elements-from-mdx-source.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// -----------------------------------------------------------------------------
// Constants
// -----------------------------------------------------------------------------

const P1 = /(_jsxs|_jsx)\(_components.[a-zA-Z-_0-9]+/g;
const P2 = /(_jsxs|_jsx)\("[a-zA-Z-_0-9]+"/g;
const P3 = /(_jsxs|_jsx)\([a-zA-Z-_0-9]+/g;
export const JSX_ELEMENTS_PATTERN = new RegExp(`${P1.source}|${P2.source}|${P3.source}`, 'g');

// -----------------------------------------------------------------------------
// Function
// -----------------------------------------------------------------------------

const getUniqueElementsFromMDXSource = (mdxSource: string): string[] => {
const elements = mdxSource.match(JSX_ELEMENTS_PATTERN) ?? [];

return [
...new Set(
[...new Set(elements)].map((e) => {
let e_ = e;
// Remove `_jsxs(` and `_jsx(` from the beginning of the string.
if (e.startsWith('_jsxs(')) e_ = e.substring(6);
else if (e.startsWith('_jsx(')) e_ = e.substring(5);

// Remove `"` from the beginning and end of the string or remove
// `_components.` from the beginning of the string.
if (e_.startsWith('"') && e_.endsWith('"')) e_ = e_.substring(1, e_.length - 1);
else if (e_.startsWith('_components.')) e_ = e_.substring(12);

return e_;
}),
),
];
};

export default getUniqueElementsFromMDXSource;
Loading

0 comments on commit 31e021c

Please sign in to comment.