-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8fd19b8
commit a694362
Showing
6 changed files
with
409 additions
and
125 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
161 changes: 105 additions & 56 deletions
161
packages/material-ui-styles/src/createGenerateClassName/createGenerateClassName.test.js
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 |
---|---|---|
@@ -1,66 +1,115 @@ | ||
import warning from 'warning'; | ||
import hash from '@emotion/hash'; | ||
import { assert } from 'chai'; | ||
import consoleErrorMock from 'test/utils/consoleErrorMock'; | ||
import createGenerateClassName from './createGenerateClassName'; | ||
|
||
function safePrefix(classNamePrefix) { | ||
const prefix = String(classNamePrefix); | ||
warning(prefix.length < 256, `Material-UI: the class name prefix is too long: ${prefix}.`); | ||
return prefix; | ||
} | ||
describe('createGenerateClassName', () => { | ||
const generateClassName = createGenerateClassName(); | ||
|
||
const themeHashCache = {}; | ||
it('should generate a class name', () => { | ||
assert.strictEqual( | ||
generateClassName( | ||
{ | ||
key: 'key', | ||
}, | ||
{ | ||
options: { | ||
theme: {}, | ||
classNamePrefix: 'classNamePrefix', | ||
}, | ||
}, | ||
), | ||
'classNamePrefix-key-1', | ||
); | ||
}); | ||
|
||
// Returns a function which generates unique class names based on counters. | ||
// When new generator function is created, rule counter is reset. | ||
// We need to reset the rule counter for SSR for each request. | ||
// | ||
// It's inspired by | ||
// https://github.com/cssinjs/jss/blob/4e6a05dd3f7b6572fdd3ab216861d9e446c20331/src/utils/createGenerateClassName.js | ||
export default function createGenerateClassName(options = {}) { | ||
const { dangerouslyUseGlobalCSS = false, productionPrefix = 'jss', seed = '' } = options; | ||
let ruleCounter = 0; | ||
it('should increase the counter only when needed', () => { | ||
assert.strictEqual( | ||
generateClassName( | ||
{ | ||
key: 'key', | ||
}, | ||
{ | ||
options: { | ||
theme: {}, | ||
classNamePrefix: 'classNamePrefix', | ||
}, | ||
}, | ||
), | ||
'classNamePrefix-key-2', | ||
); | ||
assert.strictEqual( | ||
generateClassName( | ||
{ | ||
key: 'key', | ||
}, | ||
{ | ||
options: { | ||
link: true, | ||
classNamePrefix: 'classNamePrefix', | ||
}, | ||
}, | ||
), | ||
'classNamePrefix-key-3', | ||
); | ||
assert.strictEqual( | ||
generateClassName( | ||
{ | ||
key: 'key', | ||
}, | ||
{ | ||
options: { | ||
link: true, | ||
classNamePrefix: 'classNamePrefix', | ||
}, | ||
}, | ||
), | ||
'classNamePrefix-key-4', | ||
); | ||
}); | ||
|
||
return (rule, styleSheet) => { | ||
const isStatic = !styleSheet.options.link; | ||
|
||
if (dangerouslyUseGlobalCSS && styleSheet && styleSheet.options.name && isStatic) { | ||
return `${safePrefix(styleSheet.options.name)}-${rule.key}`; | ||
} | ||
|
||
let suffix; | ||
|
||
// It's a static rule. | ||
if (isStatic) { | ||
let themeHash = themeHashCache[styleSheet.options.theme]; | ||
if (!themeHash) { | ||
themeHash = hash(JSON.stringify(styleSheet.options.theme)); | ||
themeHashCache[styleSheet.theme] = themeHash; | ||
} | ||
const raw = styleSheet.rules.raw[rule.key]; | ||
suffix = hash(`${themeHash}${rule.key}${JSON.stringify(raw)}`); | ||
} | ||
|
||
if (!suffix) { | ||
ruleCounter += 1; | ||
warning( | ||
ruleCounter < 1e10, | ||
[ | ||
'Material-UI: you might have a memory leak.', | ||
'The ruleCounter is not supposed to grow that much.', | ||
].join(''), | ||
describe('classNamePrefix', () => { | ||
it('should work without a classNamePrefix', () => { | ||
const generateClassName2 = createGenerateClassName(); | ||
assert.strictEqual( | ||
generateClassName2( | ||
{ key: 'root' }, | ||
{ | ||
options: {}, | ||
}, | ||
), | ||
'root-1', | ||
); | ||
}); | ||
}); | ||
|
||
suffix = ruleCounter; | ||
describe('production', () => { | ||
// Only run the test on node. | ||
if (!/jsdom/.test(window.navigator.userAgent)) { | ||
return; | ||
} | ||
|
||
if (process.env.NODE_ENV === 'production') { | ||
return `${productionPrefix}${seed}${suffix}`; | ||
} | ||
let nodeEnv; | ||
const env = process.env; | ||
|
||
// Help with debuggability. | ||
if (styleSheet.options.classNamePrefix) { | ||
return `${safePrefix(styleSheet.options.classNamePrefix)}-${rule.key}-${seed}${suffix}`; | ||
} | ||
before(() => { | ||
nodeEnv = env.NODE_ENV; | ||
env.NODE_ENV = 'production'; | ||
consoleErrorMock.spy(); | ||
}); | ||
|
||
after(() => { | ||
env.NODE_ENV = nodeEnv; | ||
consoleErrorMock.reset(); | ||
}); | ||
|
||
return `${rule.key}-${seed}${suffix}`; | ||
}; | ||
} | ||
it('should output a short representation', () => { | ||
const rule = { key: 'root' }; | ||
const styleSheet = { | ||
rules: { raw: {} }, | ||
options: {}, | ||
}; | ||
const generateClassName2 = createGenerateClassName(); | ||
assert.strictEqual(generateClassName2(rule, styleSheet), 'jss1'); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.