Skip to content

Instantly share code, notes, and snippets.

@alangpierce
Created September 10, 2019 01:10
Show Gist options
  • Save alangpierce/c73ae70a82cd5741cf32ca58889bf455 to your computer and use it in GitHub Desktop.
Save alangpierce/c73ae70a82cd5741cf32ca58889bf455 to your computer and use it in GitHub Desktop.
function assertResultsEqual(jadeResult: string, reactResult: string, name: string): void {
const normalizedJade = jadeResult
// React needs defaultChecked instead of checked and puts it at the end, and renders it as
// `checked=""`. Jade renders it as `checked="checked"`. Reposition and rewrite Jade checked
// attributes to match React.
.replace(/<([^>]*) checked="checked"([^>]*)\/>/g, '<$1$2 checked=""/>')
// Same with defaultValue/value.
.replace(/<([^>]*) value="([^"]*)"([^>]*)\/>/g, '<$1$3 value="$2"/>')
// Similar to "checked", some other boolean attributes render differently.
.replace(/disabled="disabled"/g, 'disabled=""')
.replace(/multiple="multiple"/g, 'multiple=""')
.replace(/selected="selected"/g, 'selected=""')
.replace(/readonly="readonly"/g, 'readonly=""')
// React puts "type" as the first attribute for inputs.
.replace(/<input ([^>]*) (type="[^"]*")/g, '<input $2 $1')
// Jade can emit HTML comments, which won't be emitted by React.
.replace(/<!--[^>]*-->/g, '')
// Jade puts single-quotes around number attribute values, so switch to double-quotes.
.replace(/='(\d*)'/g, '="$1"')
// Jade allows non-self-closing br, JSX does not.
.replace(/<br>/g, '<br/>')
// Normalize to HTML entities.
.replace(/\u00d7/g, '&times;')
.replace(/\u00a0/g, '&nbsp;')
.replace(/\u00b7/g, '&middot;')
.replace(/\u22c5/g, '&sdot;')
.replace(/\u00b0/g, '&deg;')
.replace(/\u0394/g, '&Delta;')
.replace(/\u2013/g, '&ndash;')
.replace(/\u2014/g, '&mdash;')
.replace(/\u2026/g, '&hellip;')
// Normalize to remove blank class names to agree with React normalization.
.replace(/ class=""/g, '');
// JSX emits actual unicode rather than HTML entities, at least in some cases, and entities rather
// than text in other cases.
const normalizedReact = reactResult
.replace(/\u00d7/g, '&times;')
.replace(/\u00a0/g, '&nbsp;')
.replace(/\u00b7/g, '&middot;')
.replace(/\u22c5/g, '&sdot;')
.replace(/\u00b0/g, '&deg;')
.replace(/\u0394/g, '&Delta;')
.replace(/\u2013/g, '&ndash;')
.replace(/\u2014/g, '&mdash;')
.replace(/\u2026/g, '&hellip;')
.replace(/&#x27;/g, "'")
// Normalize value to the end since sometimes this isn't done by React.
.replace(/<([^>]*) value="([^"]*)"([^>]*)\/>/g, '<$1$3 value="$2"/>')
// Data attributes from React sometimes use single-quotes, switch to double quotes.
.replace(/(data-[-a-z]*=)'([^']*)'/g, '$1"$2"')
// Normal classNames code can produce class="", so ignore those.
.replace(/ class=""/g, '');
assertAndContinue(
normalizedJade === normalizedReact,
`Expected Jade and React results for ${name} to match.`,
{
jadeResult,
reactResult,
normalizedJade,
normalizedReact,
}
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment