-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(ui): [Theme] Migrate to MUI. (#278)
- Loading branch information
1 parent
d977761
commit 168530b
Showing
27 changed files
with
1,626 additions
and
202 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
'use strict'; | ||
|
||
const identity = require('lodash/identity'); | ||
const fs = require('fs/promises'); | ||
const path = require('path'); | ||
const traverse = require('@babel/traverse').default; | ||
const { diff } = require('jest-diff'); | ||
const { parseAsync } = require('@babel/core'); | ||
|
||
function diffString(a, b) { | ||
return diff(a, b, { | ||
expand: false, | ||
contextLines: -1, // Forces to use default from Jest | ||
aAnnotation: 'v4', | ||
bAnnotation: 'v5', | ||
|
||
aColor: identity, | ||
bColor: identity, | ||
changeColor: identity, | ||
commonColor: identity, | ||
patchColor: identity, | ||
}); | ||
} | ||
|
||
async function parseAST(filename) { | ||
const plugins = []; | ||
const presets = [require.resolve('babel-preset-current-node-syntax')]; | ||
|
||
if (/\.tsx?$/.test(filename)) { | ||
plugins.push([ | ||
require.resolve('@babel/plugin-syntax-typescript'), | ||
{ isTSX: filename.endsWith('x') }, | ||
]); | ||
} | ||
|
||
const content = await fs.readFile(filename); | ||
return parseAsync(content.toString(), { | ||
filename, | ||
plugins, | ||
presets, | ||
root: path.dirname(filename), | ||
}); | ||
} | ||
|
||
function traverseAST(ast, results) { | ||
traverse(ast, { | ||
CallExpression({ node }) { | ||
const { arguments: args, callee } = node; | ||
if ( | ||
callee.type !== 'MemberExpression' || | ||
callee.property.type !== 'Identifier' || | ||
callee.property.loc == null | ||
) { | ||
return; | ||
} | ||
|
||
const templateLiteral = args.find( | ||
({ type }) => type === 'TemplateLiteral', | ||
); | ||
|
||
if (templateLiteral) { | ||
const [{ value }] = templateLiteral.quasis; | ||
results.push(value.cooked); | ||
} | ||
}, | ||
}); | ||
} | ||
|
||
class DiffReporter { | ||
constructor(globalConfig, options) { | ||
this._globalConfig = globalConfig; | ||
this._options = options; | ||
} | ||
|
||
async onTestFileResult(test) { | ||
// todo check for snapshot from testResult | ||
if (test.path.includes('/v5')) { | ||
await processFileSnapshots(test); | ||
await processInlineSnapshots(test); | ||
} | ||
} | ||
} | ||
|
||
async function processInlineSnapshots(test) { | ||
const pathV4 = getPathV4(test.path); | ||
const snapshots = await getInlineSnapshotValues(test.path); | ||
const snapshotsV4 = await getInlineSnapshotValues(pathV4); | ||
|
||
if (!snapshotsV4) { | ||
console.warn('DiffReporter: v4 snapshots not found for ' + test.path); | ||
return; | ||
} | ||
|
||
if (snapshots.length !== snapshotsV4.length) { | ||
console.warn( | ||
'DiffReporter: v4 and v5 snapshots are not the same length for ' + | ||
test.path, | ||
); | ||
return; | ||
} | ||
|
||
const diffs = []; | ||
|
||
for (let i = 0; i < snapshots.length; i++) { | ||
const snapshot = snapshots[i]; | ||
const snapshotV4 = snapshotsV4[i]; | ||
const diffContent = diffString(snapshot, snapshotV4); | ||
|
||
if (diffContent.length) { | ||
diffs.push(diffString(snapshotV4, snapshot)); | ||
} | ||
} | ||
|
||
if (diffs.length) { | ||
const diffPath = getDiffPath(test.path); | ||
await fs.writeFile(diffPath, diffs.join('\n')); | ||
} | ||
} | ||
|
||
async function getInlineSnapshotValues(filename) { | ||
const results = []; | ||
const content = await fs.readFile(filename); | ||
|
||
if (content.includes('toMatchInlineSnapshot')) { | ||
const ast = await parseAST(filename); | ||
|
||
traverseAST(ast, results); | ||
} | ||
|
||
return results; | ||
} | ||
|
||
async function processFileSnapshots(test) { | ||
const pathV4 = getPathV4(test.path); | ||
const snapshotPath = getSnapshotPath(test.path); | ||
const snapshotPathV4 = getSnapshotPath(pathV4); | ||
|
||
try { | ||
await fs.access(snapshotPath); | ||
await fs.access(snapshotPathV4); | ||
} catch (err) { | ||
return; | ||
} | ||
|
||
const snapshot = await fs.readFile(snapshotPath); | ||
const snapshotV4 = await fs.readFile(snapshotPathV4); | ||
if (snapshot.toString() !== snapshotV4.toString()) { | ||
const diffPath = getDiffPath(snapshotPath); | ||
await fs.writeFile( | ||
diffPath, | ||
diffString(snapshotV4.toString(), snapshot.toString()), | ||
); | ||
} | ||
} | ||
|
||
function getDiffPath(filename) { | ||
return filename + '.diff'; | ||
} | ||
|
||
function getSnapshotPath(filename) { | ||
const dir = path.dirname(filename); | ||
const basename = path.basename(filename); | ||
return dir + '/__snapshots__/' + basename + '.snap'; | ||
} | ||
|
||
function getPathV4(filename) { | ||
return filename.replace('/v5', ''); | ||
} | ||
|
||
module.exports = DiffReporter; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { ForwardRef } from 'react-is'; | ||
|
||
export function getForwardRefSerializer() { | ||
return { | ||
test: (value: any) => value?.$$typeof === ForwardRef, | ||
serialize: (value: any) => | ||
`React.forwardRef(${value.displayName || 'unknown'})`, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from './renderComponent'; | ||
export * from './renderCSS'; | ||
export * from './renderTheme'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { v5 } from '@superdispatch/ui'; | ||
import { render } from '@testing-library/react'; | ||
import { parse as parseCSS, stringify as stringifyCSS, Stylesheet } from 'css'; | ||
import { format } from 'prettier'; | ||
|
||
const colors = new Map<string, string>( | ||
Object.entries(v5.Color).map(([k, v]) => [v, `Color.${k}`]), | ||
); | ||
|
||
const colorRegExp = new RegExp( | ||
Array.from(colors.keys(), (x) => | ||
x.replace('(', '\\(').replace(')', '\\)'), | ||
).join('|'), | ||
'g', | ||
); | ||
|
||
const renderedCSS = new Set<string>(); | ||
|
||
function getAllSheets(): Element[] { | ||
return Array.from(document.querySelectorAll('[data-styled]')); | ||
} | ||
|
||
function getSheets(): Element[] { | ||
const sheets = getAllSheets(); | ||
|
||
if (sheets.length === 0) { | ||
throw new Error('There are no mounted JSS components.'); | ||
} | ||
|
||
return sheets; | ||
} | ||
|
||
function parseStyleSheet(): Stylesheet { | ||
return parseCSS( | ||
getSheets() | ||
.map((node) => node.textContent) | ||
.join('\n'), | ||
); | ||
} | ||
|
||
function formatAST(sheet: Stylesheet): string { | ||
return format( | ||
stringifyCSS(sheet).replace( | ||
colorRegExp, | ||
(color) => colors.get(color) as string, | ||
), | ||
{ parser: 'css', singleQuote: true }, | ||
).trim(); | ||
} | ||
|
||
expect.addSnapshotSerializer({ | ||
test: (value) => typeof value === 'string' && renderedCSS.has(value), | ||
print: (value) => String(value), | ||
}); | ||
|
||
export function extractGlobalCSS(): string { | ||
const targetSheet = parseStyleSheet(); | ||
const formatted = formatAST(targetSheet); | ||
|
||
renderedCSS.add(formatted); | ||
|
||
return formatted; | ||
} | ||
|
||
export function renderGlobalCSS() { | ||
render(<v5.ThemeProvider />); | ||
|
||
return extractGlobalCSS(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { v5 } from '@superdispatch/ui'; | ||
import { render, RenderOptions, RenderResult } from '@testing-library/react'; | ||
import { ReactElement, Suspense } from 'react'; | ||
|
||
function Wrapper({ children }: v5.ThemeProviderProps): ReactElement { | ||
return ( | ||
<Suspense fallback="Suspended…"> | ||
<v5.ThemeProvider>{children}</v5.ThemeProvider> | ||
</Suspense> | ||
); | ||
} | ||
|
||
export function renderComponent( | ||
ui: ReactElement, | ||
options?: Omit<RenderOptions, 'queries' | 'wrapper'>, | ||
): RenderResult { | ||
return render(ui, { ...options, wrapper: Wrapper }); | ||
} |
Oops, something went wrong.