diff --git a/src/components/report.jsx b/src/components/report.jsx index 85a03750..88e52b59 100644 --- a/src/components/report.jsx +++ b/src/components/report.jsx @@ -2,7 +2,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import DevTools from 'mobx-react-devtools'; -import { observer } from 'mobx-react'; +import { Provider, observer } from 'mobx-react'; import { Footer, Navbar } from 'components'; import { NavMenu } from 'components/nav-menu'; import { Suite } from 'components/suite'; @@ -50,26 +50,28 @@ class MochawesomeReport extends Component { }; return ( -
- (this.qsNode = node) } /> -
- { suites.map(suite => ( - ) - ) } + +
+ (this.qsNode = node) } /> +
+ { suites.map(suite => ( + ) + ) } +
+
+ + { devMode && }
-
- - { devMode && } -
+ ); } } diff --git a/src/components/test/code-snippet.jsx b/src/components/test/code-snippet.jsx index d49adf4a..7cda7d8e 100644 --- a/src/components/test/code-snippet.jsx +++ b/src/components/test/code-snippet.jsx @@ -1,5 +1,6 @@ /* eslint-disable import/no-dynamic-require, react/no-danger */ import React, { Component } from 'react'; +import { inject } from 'mobx-react'; import PropTypes from 'prop-types'; import isEqual from 'lodash/isEqual'; import hljs from 'highlight.js/lib/highlight'; @@ -8,16 +9,18 @@ import styles from './test.css'; const cx = classNames.bind(styles); +@inject(stores => ({ useInlineDiffs: stores.reportStore && stores.reportStore.useInlineDiffs })) class CodeSnippet extends Component { static displayName = 'CodeSnippet'; static propTypes = { className: PropTypes.string, - code: PropTypes.string, + code: PropTypes.oneOfType([ PropTypes.string, PropTypes.array ]), lang: PropTypes.string, highlight: PropTypes.bool, label: PropTypes.string, - showLabel: PropTypes.bool + showLabel: PropTypes.bool, + useInlineDiffs: PropTypes.bool }; static defaultProps = { @@ -34,24 +37,59 @@ class CodeSnippet extends Component { return !isEqual(this.props, nextProps); } + shouldHighlight() { + const { code, highlight, lang, useInlineDiffs } = this.props; + if (lang === 'diff' && useInlineDiffs) { + return false; + } + return code && highlight; + } + highlightCode() { - const { code, highlight } = this.props; - if (highlight && code) { + if (this.shouldHighlight()) { hljs.highlightBlock(this.node); } } render() { - const { className, code, lang, highlight, label, showLabel } = this.props; - const cxName = cx(className, lang, { hljs: !highlight }); + const { className, code, lang, label, showLabel, useInlineDiffs } = this.props; const isDiff = lang === 'diff'; + const cxName = cx(className, lang, { + hljs: !this.shouldHighlight(), + 'code-diff': isDiff, + 'inline-diff': isDiff && useInlineDiffs + }); + + const renderLegendLeft = () => isDiff && ( + useInlineDiffs + ? actual + : + expected + ); + + const renderLegendRight = () => isDiff && ( + useInlineDiffs + ? {'expected\n\n'} + : {'- actual\n\n'} + ); + + const mapInlineDiffCode = ({ added, removed, value }, i) => { + if (added) { + return { value }; + } + + if (removed) { + return { value }; + } + + return value; + }; return !!code && (
 (this.node = node) }>
         
-          { isDiff && + expected   }
-          { isDiff && {'- actual\n\n'} }
-          { code }
+          { renderLegendLeft() }
+          { renderLegendRight() }
+          { (isDiff && useInlineDiffs) ? code.map(mapInlineDiffCode) : code }
         
         { !!label && showLabel && { label } }
       
diff --git a/src/components/test/test.css b/src/components/test/test.css index fb242165..abc8788a 100644 --- a/src/components/test/test.css +++ b/src/components/test/test.css @@ -178,12 +178,30 @@ } } -.code-diff-expected span { - color: #859900; +.code-diff code > span:first-child { + margin-right: 11px; } -.code-diff-actual span { - color: #dc322f; +.code-diff-expected { + & span { + color: #859900; + } + + @nest .inline-diff & { + background-color: #859900; + color: #fff; + } +} + +.code-diff-actual { + & span { + color: #dc322f; + } + + @nest .inline-diff & { + background-color: #dc322f; + color: #fff; + } } .code-label { diff --git a/test/spec/components/test/code-snippet.test.jsx b/test/spec/components/test/code-snippet.test.jsx index e705b224..a94523c9 100644 --- a/test/spec/components/test/code-snippet.test.jsx +++ b/test/spec/components/test/code-snippet.test.jsx @@ -3,6 +3,7 @@ import { mount } from 'enzyme'; import chai, { expect } from 'chai'; import chaiEnzyme from 'chai-enzyme'; import sinon from 'sinon'; +import { Provider } from 'mobx-react'; import CodeSnippet from 'components/test/code-snippet'; import hljs from 'highlight.js/lib/highlight'; @@ -11,10 +12,14 @@ chai.use(chaiEnzyme()); describe('', () => { let node; - const getInstance = instanceProps => { - const wrapper = mount(, { - attachTo: node - }); + const getInstance = (instanceProps, store = {}) => { + const wrapper = mount( + + + , { + attachTo: node + } + ); return wrapper; }; @@ -23,6 +28,7 @@ describe('', () => { node.setAttribute('id', 'app'); document.body.appendChild(node); hljs.registerLanguage('javascript', require('highlight.js/lib/languages/javascript')); + hljs.registerLanguage('diff', require('highlight.js/lib/languages/diff')); }); afterEach(() => { @@ -39,12 +45,31 @@ describe('', () => { it('renders and highlights diff snippet', () => { const props = { - code: 'function(){console.log(\'sample code\');}', + code: ' {\n- "a": 2\n+ "a": 1\n }\n', lang: 'diff' }; - getInstance(props); + const wrapper = getInstance(props); + expect(wrapper.hasClass('inline-diff')).to.equal(false); expect(document.querySelectorAll('.test-code-diff-expected').length).to.equal(1); expect(document.querySelectorAll('.test-code-diff-actual').length).to.equal(1); + expect(document.querySelectorAll('.hljs-addition').length).to.equal(3); + expect(document.querySelectorAll('.hljs-deletion').length).to.equal(1); + }); + + it('renders and does not highlight inline diff snippet', () => { + const props = { + code: [ + { count: 6, value: '{\n "a": ' }, + { count: 1, added: undefined, removed: true, value: '2' }, + { count: 1, added: true, removed: undefined, value: '1' }, + { count: 2, value: '\n}' } + ], + lang: 'diff' + }; + const wrapper = getInstance(props, { useInlineDiffs: true }); + expect(wrapper.hasClass('inline-diff')).to.equal(true); + expect(document.querySelectorAll('.test-code-diff-expected').length).to.equal(2); + expect(document.querySelectorAll('.test-code-diff-actual').length).to.equal(2); }); it('does not highlight when prop is false', () => { @@ -83,7 +108,7 @@ describe('', () => { const props = { code: 'function(){console.log(\'sample code\');}' }; - const wrapper = getInstance(props); + const wrapper = mount(); sinon.spy(CodeSnippet.prototype, 'shouldComponentUpdate'); wrapper.setProps({ highlight: false