Skip to content

Commit

Permalink
Upgrade unist-util-visit to 4.1.0 (#19)
Browse files Browse the repository at this point in the history
* Set up spys instead of using mock

jest.mock doesn't work work against ES6 modules, but this approach of
using spys instead does.

See: jestjs/jest#10025

* Export as an ES6 module instead of CommonJS

* Upgrade unist-util-visit to 3.0.0

* Upgrade unist-util-visit to 4.1.0

Closes: #18

* Use `import` instead of `require`

* Use ES2020 instead of ESNext

It's best to use a specific version to ensure a consistent, reproducible
product.

Co-authored-by: Sam Wall <oss@samuelwall.co.uk>
  • Loading branch information
candrews and sjwall committed Jan 8, 2022
1 parent 848c054 commit ec6fc3c
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 45 deletions.
2 changes: 1 addition & 1 deletion doc/docusaurus.config.js
Expand Up @@ -23,7 +23,7 @@ const config = {
/** @type {import('@docusaurus/preset-classic').Options} */
({
docs: {
remarkPlugins: [require('mdx-mermaid')],
remarkPlugins: [import('mdx-mermaid')],
sidebarPath: require.resolve('./sidebars.js'),
// Please change this to your repo.
editUrl:
Expand Down
10 changes: 8 additions & 2 deletions jest.config.js
@@ -1,6 +1,12 @@
/** @type {import('@ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: 'ts-jest',
export default {
preset: 'ts-jest/presets/default-esm',
transform: {},
globals: {
'ts-jest': {
useESM: true
}
},
testEnvironment: 'jsdom',
coverageThreshold: {
global: {
Expand Down
7 changes: 4 additions & 3 deletions package.json
Expand Up @@ -11,9 +11,10 @@
},
"author": "Sam Wall (oss@samuelwall.co.uk)",
"license": "MIT",
"type": "module",
"scripts": {
"build": "rimraf lib && tsc",
"test": "jest --coverage"
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage"
},
"repository": {
"type": "git",
Expand All @@ -33,7 +34,7 @@
"peerDependencies": {
"mermaid": ">= 8.11.0 < 8.12.0",
"react": "^16.8.4 || ^17.0.0",
"unist-util-visit": "^2.0.0"
"unist-util-visit": "^4.1.0"
},
"devDependencies": {
"@mdx-js/mdx": "^1.6.22",
Expand All @@ -57,6 +58,6 @@
"rimraf": "^3.0.2",
"ts-jest": "^27.1.2",
"typescript": "^4.5.4",
"unist-util-visit": "^2.0.0"
"unist-util-visit": "^4.1.0"
}
}
2 changes: 1 addition & 1 deletion readme.md
Expand Up @@ -31,7 +31,7 @@ Update `docusaurus.config.js`
'@docusaurus/preset-classic',
{
docs: {
remarkPlugins: [require('mdx-mermaid')],
remarkPlugins: [import('mdx-mermaid')],
```
Use code blocks in `.md` or `.mdx` files:
Expand Down
63 changes: 38 additions & 25 deletions src/Mermaid.spec.tsx
Expand Up @@ -10,6 +10,16 @@
import mermaid from 'mermaid'
import React from 'react'
import renderer from 'react-test-renderer'

import mermaid from 'mermaid'

import { jest } from '@jest/globals'

const spy = {
initialize: jest.spyOn(mermaid, 'initialize').mockImplementation(() => {}),
render: jest.spyOn(mermaid, 'render').mockImplementation(() => {})
}

import { Mermaid } from './Mermaid'
import {
DARK_THEME_KEY,
Expand All @@ -25,22 +35,22 @@ async function waitFor (ms: number) {
})
}

jest.mock('mermaid')

afterEach(() => {
jest.clearAllMocks()
})

it('renders without diagram', () => {
const component = renderer.create(<Mermaid chart={''} />)
expect(mermaid.initialize).toBeCalledTimes(0)
expect(mermaid.render).toBeCalledTimes(0)
expect(component.toJSON()).toMatchSnapshot()
expect(spy.initialize).toBeCalledTimes(0)
expect(spy.render).toBeCalledTimes(0)
component.update()
expect(mermaid.render).toHaveBeenCalled()
expect(mermaid.initialize).toBeCalledTimes(1)
expect(spy.render).toHaveBeenCalled()
expect(spy.initialize).toBeCalledTimes(1)
component.update()
expect(mermaid.render).toBeCalledTimes(1)
expect(mermaid.initialize).toBeCalledTimes(1)
expect(spy.render).toBeCalledTimes(1)
expect(spy.initialize).toBeCalledTimes(1)
})

it('renders with diagram', () => {
Expand All @@ -49,14 +59,15 @@ it('renders with diagram', () => {
A-->C;
B-->D;
C-->D;`} />)
expect(mermaid.initialize).toBeCalledTimes(0)
expect(mermaid.render).toBeCalledTimes(0)
expect(component.toJSON()).toMatchSnapshot()
expect(spy.initialize).toBeCalledTimes(0)
expect(spy.render).toBeCalledTimes(0)
component.update()
expect(mermaid.render).toBeCalledTimes(1)
expect(mermaid.initialize).toBeCalledTimes(1)
expect(spy.render).toBeCalledTimes(1)
expect(spy.initialize).toBeCalledTimes(1)
component.update()
expect(mermaid.render).toBeCalledTimes(1)
expect(mermaid.initialize).toBeCalledTimes(1)
expect(spy.render).toBeCalledTimes(1)
expect(spy.initialize).toBeCalledTimes(1)
})

it('renders with config', () => {
Expand All @@ -65,14 +76,15 @@ it('renders with config', () => {
A-->C;
B-->D;
C-->D;`} config={{}} />)
expect(mermaid.initialize).toBeCalledTimes(0)
expect(mermaid.render).toBeCalledTimes(0)
expect(component.toJSON()).toMatchSnapshot()
expect(spy.initialize).toBeCalledTimes(0)
expect(spy.render).toBeCalledTimes(0)
component.update()
expect(mermaid.render).toHaveBeenCalled()
expect(mermaid.initialize).toBeCalledTimes(1)
expect(spy.render).toHaveBeenCalled()
expect(spy.initialize).toBeCalledTimes(1)
component.update()
expect(mermaid.render).toBeCalledTimes(1)
expect(mermaid.initialize).toBeCalledTimes(1)
expect(spy.render).toBeCalledTimes(1)
expect(spy.initialize).toBeCalledTimes(1)
})

it('renders with mermaid config', () => {
Expand All @@ -81,14 +93,15 @@ it('renders with mermaid config', () => {
A-->C;
B-->D;
C-->D;`} config={{ mermaid: { theme: 'dark' } } } />)
expect(mermaid.initialize).toBeCalledTimes(0)
expect(mermaid.render).toBeCalledTimes(0)
expect(component.toJSON()).toMatchSnapshot()
expect(spy.initialize).toBeCalledTimes(0)
expect(spy.render).toBeCalledTimes(0)
component.update()
expect(mermaid.render).toHaveBeenCalled()
expect(mermaid.initialize).toHaveBeenNthCalledWith(1, { startOnLoad: true, theme: 'dark' })
expect(spy.render).toHaveBeenCalled()
expect(spy.initialize).toHaveBeenNthCalledWith(1, { startOnLoad: true, theme: 'dark' })
component.update()
expect(mermaid.render).toBeCalledTimes(1)
expect(mermaid.initialize).toBeCalledTimes(1)
expect(spy.render).toBeCalledTimes(1)
expect(spy.initialize).toBeCalledTimes(1)
})

it('re-renders mermaid theme on html data-theme attribute change', async () => {
Expand Down
20 changes: 9 additions & 11 deletions src/mdxast-mermaid.ts
Expand Up @@ -5,7 +5,7 @@
* license file in the root directory of this source tree.
*/

import visit from 'unist-util-visit'
import { visit, EXIT } from 'unist-util-visit'
import { Literal, Parent, Node, Data } from 'unist'

import { Config } from './config.model'
Expand All @@ -21,18 +21,18 @@ type CodeMermaid = Literal<string> & {
* @param config Config passed in from parser.
* @returns Function to transform mdxast.
*/
function plugin (config?: Config) {
export default function plugin (config?: Config) {
/**
* Insert the component import into the document.
* @param ast The document to insert into.
*/
function insertImport (ast: Parent<Node<Data> | Literal, Data>) {
function insertImport (ast: any) {
// See if there is already an import for the Mermaid component
let importFound = false
visit(ast, { type: 'import' }, (node: Literal<string>) => {
if (/\s*import\s*{\s*Mermaid\s*}\s*from\s*'mdx-mermaid(\/lib)?\/Mermaid'\s*;?\s*/.test(node.value)) {
importFound = true
return visit.EXIT
return EXIT
}
})

Expand All @@ -45,16 +45,16 @@ function plugin (config?: Config) {
}
}

return async function transformer (ast: Parent<Node<Data> | Literal, Data>): Promise<Parent> {
return async function transformer (ast: any): Promise<Parent> {
// Find all the mermaid diagram code blocks. i.e. ```mermaid
const instances: [Literal, number, Parent<Node<Data> | Literal, Data>][] = []
visit<CodeMermaid>(ast, { type: 'code', lang: 'mermaid' }, (node, index, parent) => {
instances.push([node, index, parent as Parent<Node<Data>, Data>])
visit(ast, { type: 'code', lang: 'mermaid' }, (node: CodeMermaid, index, parent) => {
instances.push([node, index!, parent as Parent<Node<Data>, Data>])
})
// If there are no code blocks return
if (!instances.length) {
// Look for any components
visit<Literal<string> & { type: 'jsx' }>(ast, { type: 'jsx' }, (node, index, parent) => {
visit(ast, { type: 'jsx' }, (node: Literal<string> & { type: 'jsx' }, index, parent) => {
if (/.*<Mermaid.*/.test(node.value)) {
// If the component doesn't have config
if (typeof config !== 'undefined' && !/.*config={.*/.test(node.value)) {
Expand All @@ -64,7 +64,7 @@ function plugin (config?: Config) {
node.value.substring(index)
}
insertImport(ast)
return visit.EXIT
return EXIT
}
})
return ast
Expand Down Expand Up @@ -92,5 +92,3 @@ function plugin (config?: Config) {
return ast
}
}

export = plugin
5 changes: 3 additions & 2 deletions tsconfig.json
@@ -1,17 +1,18 @@
{
"compilerOptions": {
"declaration": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"jsx": "react",
"lib": ["ESNext", "DOM"],
"module": "CommonJS",
"module": "ES2020",
"moduleResolution": "node",
"noImplicitAny": false,
"outDir": "lib",
"rootDir": "src",
"sourceMap": true,
"strict": true,
"target": "ES2015"
"target": "ES2020"
},
"include": [
"src/**/*.ts",
Expand Down
22 changes: 22 additions & 0 deletions yarn.lock
Expand Up @@ -6177,6 +6177,11 @@ unist-util-is@^4.0.0:
resolved "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz"
integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==

unist-util-is@^5.0.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-5.1.1.tgz#e8aece0b102fa9bc097b0fef8f870c496d4a6236"
integrity sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==

unist-util-position@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.1.0.tgz#1c42ee6301f8d52f47d14f62bbdb796571fa2d47"
Expand Down Expand Up @@ -6211,6 +6216,14 @@ unist-util-visit-parents@^3.0.0:
"@types/unist" "^2.0.0"
unist-util-is "^4.0.0"

unist-util-visit-parents@^5.0.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-5.1.0.tgz#44bbc5d25f2411e7dfc5cecff12de43296aa8521"
integrity sha512-y+QVLcY5eR/YVpqDsLf/xh9R3Q2Y4HxkZTp7ViLDU6WtJCEcPmRzW1gpdWDCDIqIlhuPDXOgttqPlykrHYDekg==
dependencies:
"@types/unist" "^2.0.0"
unist-util-is "^5.0.0"

unist-util-visit@2.0.3, unist-util-visit@^2.0.0:
version "2.0.3"
resolved "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz"
Expand All @@ -6220,6 +6233,15 @@ unist-util-visit@2.0.3, unist-util-visit@^2.0.0:
unist-util-is "^4.0.0"
unist-util-visit-parents "^3.0.0"

unist-util-visit@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-4.1.0.tgz#f41e407a9e94da31594e6b1c9811c51ab0b3d8f5"
integrity sha512-n7lyhFKJfVZ9MnKtqbsqkQEk5P1KShj0+//V7mAcoI6bpbUjh3C/OG8HVD+pBihfh6Ovl01m8dkcv9HNqYajmQ==
dependencies:
"@types/unist" "^2.0.0"
unist-util-is "^5.0.0"
unist-util-visit-parents "^5.0.0"

universalify@^0.1.0, universalify@^0.1.2:
version "0.1.2"
resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz"
Expand Down

0 comments on commit ec6fc3c

Please sign in to comment.