Skip to content

Commit

Permalink
Switch to ava and use PureComponent
Browse files Browse the repository at this point in the history
  • Loading branch information
danez committed Aug 3, 2016
1 parent 8cc8b27 commit 9b01c33
Show file tree
Hide file tree
Showing 14 changed files with 112 additions and 111 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"extends": "airbnb",
"parser": "babel-eslint",
"rules": {
"no-underscore-dangle": 0
"no-underscore-dangle": 0,
"react/jsx-filename-extension": 0
},
"globals": {
"HighlightResult": false
Expand Down
1 change: 0 additions & 1 deletion .flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,4 @@ flow/
munge_underscores=true
esproposal.class_static_fields=enable
esproposal.class_instance_fields=enable
unsafe.enable_getters_and_setters=true
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ node_js:
- "4"
- "5"
- "6"
script: npm run check
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@

[![Build Status](https://travis-ci.org/chili-labs/react-fast-highlight.svg?branch=master)](https://travis-ci.org/chili-labs/react-fast-highlight)

## Requirements

Version 1.x works with React 0.14 and <=15.2

Version 2.x works with React >=15.3

## Usage

`npm install --save react-fast-highlight`
Expand Down
37 changes: 19 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@
"scripts": {
"check": "npm run lint && npm run flow && npm test",
"clean": "rimraf lib",
"build": "cross-env NODE_ENV=production babel src --out-dir lib --ignore __tests__",
"build": "babel src --out-dir lib",
"flow": "flow",
"lint": "eslint src",
"precommit": "npm run check",
"prepublish": "npm run clean && npm run build",
"preversion": "npm run check",
"test": "cross-env NODE_ENV=test mocha tests/setup.js $(find src -path '*__tests__/*.spec.js') --compilers js:babel-register"
"test": "ava"
},
"repository": {
"type": "git",
"url": "git+https://github.com/chili-labs/react-fast-highlight.git"
"url": "https://github.com/chili-labs/react-fast-highlight.git"
},
"files": [
"lib"
Expand All @@ -35,19 +35,17 @@
},
"homepage": "https://github.com/chili-labs/react-fast-highlight#readme",
"peerDependencies": {
"react": "^0.14.0 || ^15.0.0"
"react": "^15.3.0"
},
"devDependencies": {
"ava": "^0.15.2",
"babel-cli": "^6.4.5",
"babel-eslint": "^6.0.0-beta",
"babel-eslint": "^6.0.0",
"babel-preset-es2015": "^6.3.13",
"babel-preset-es2015-loose": "^7.0.0",
"babel-preset-react": "^6.3.13",
"babel-preset-stage-1": "^6.3.13",
"babel-register": "^6.4.3",
"chai": "^3.4.1",
"cross-env": "^2.0.0",
"dirty-chai": "^1.2.2",
"babel-register": "^6.11.6",
"enzyme": "^2.2.0",
"eslint": "^3.0.0",
"eslint-config-airbnb": "^10.0.0",
Expand All @@ -57,18 +55,21 @@
"flow-bin": "^0.30.0",
"husky": "^0.11.1",
"jsdom": "^9.1.0",
"mocha": "^3.0.0",
"mocha-jsdom": "^1.1.0",
"react": "^15.0.0",
"react-addons-test-utils": "^15.0.0",
"react-dom": "^15.0.0",
"react": "^15.3.0",
"react-addons-test-utils": "^15.3.0",
"react-dom": "^15.3.0",
"rimraf": "^2.5.0",
"sinon": "^1.17.2",
"sinon-chai": "^2.8.0"
"testdouble": "^1.6.0"
},
"dependencies": {
"classnames": "^2.2.3",
"highlight.js": "^9.0.0",
"react-addons-shallow-compare": "^15.0.0"
"highlight.js": "^9.0.0"
},
"ava": {
"require": [
"babel-register",
"./test/helpers/setup-browser-env.js"
],
"babel": "inherit"
}
}
11 changes: 0 additions & 11 deletions src/__tests__/index.spec.js

This file was deleted.

33 changes: 14 additions & 19 deletions src/components/Highlight.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* @flow */
import React, { Component, Element, PropTypes } from 'react';
import shallowCompare from 'react-addons-shallow-compare';
import React, { PureComponent, PropTypes } from 'react';
import hljs from 'highlight.js';
import cx from 'classnames';

Expand All @@ -16,7 +15,7 @@ type State = {
language: ?string,
};

export default class Highlight extends Component {
export default class Highlight extends PureComponent {

state: State = {
highlightedCode: null,
Expand All @@ -27,17 +26,13 @@ export default class Highlight extends Component {
this._highlightCode();
}

shouldComponentUpdate(nextProps: Props, nextState: State): boolean {
return shallowCompare(this, nextProps, nextState);
}

componentDidUpdate() {
this._highlightCode();
}

props: Props;

get initialCode(): string {
getInitialCode() {
const type = typeof this.props.children;
if (type !== 'string') {
throw new Error(`Children of <Highlight> must be a string. '${type}' supplied`);
Expand All @@ -46,40 +41,40 @@ export default class Highlight extends Component {
return this.props.children;
}

get highlightCallback(): (resolve: Function) => HighlightResult {
getHighlightCallback() {
let callback;

if (this.props.languages && this.props.languages.length === 1) {
const language:string = this.props.languages[0];
callback = (resolve) =>
resolve(hljs.highlight(language, this.initialCode));
callback = (resolve: (x: *) => void) =>
resolve(hljs.highlight(language, this.getInitialCode()));
} else {
callback = (resolve) =>
resolve(hljs.highlightAuto(this.initialCode, this.props.languages));
callback = (resolve: (x: *) => void) =>
resolve(hljs.highlightAuto(this.getInitialCode(), this.props.languages));
}

return callback;
}

_highlightCode(): void {
_highlightCode() {
const worker = this.props.worker;
if (worker) {
worker.onmessage = event => this.setState({
highlightedCode: event.data.value,
language: event.data.language,
});
worker.postMessage({ code: this.initialCode, languages: this.props.languages });
worker.postMessage({ code: this.getInitialCode(), languages: this.props.languages });
} else {
const promise = new Promise(this.highlightCallback);
const promise = new Promise(this.getHighlightCallback());

promise.then(
result => this.setState({ highlightedCode: result.value, language: result.language })
);
}
}

render(): ?Element {
const code: ?string = this.state.highlightedCode;
render() {
const code = this.state.highlightedCode;
const classes = cx(this.props.className, 'hljs', this.state.language);

if (code) {
Expand All @@ -90,7 +85,7 @@ export default class Highlight extends Component {
);
}

return <pre><code className={classes}>{this.initialCode}</code></pre>;
return <pre><code className={classes}>{this.getInitialCode()}</code></pre>;
}
}

Expand Down
54 changes: 0 additions & 54 deletions src/components/__tests__/Highlight.spec.js

This file was deleted.

3 changes: 2 additions & 1 deletion src/worker.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/* global postMessage, onmessage:true */
/* @flow */

import hjs from 'highlight.js';

declare function postMessage(result: Object): void;

onmessage = event => {
const { code, languages } = event.data;
let result;
Expand Down
5 changes: 5 additions & 0 deletions test/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"rules": {
"import/no-extraneous-dependencies": [2, {"devDependencies": true}]
}
}
52 changes: 52 additions & 0 deletions test/components/Highlight.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React from 'react';
import td from 'testdouble';
import test from 'ava';
import { mount, shallow } from 'enzyme';

const hjs = td.replace('highlight.js');
const Highlight = require('../../src/components/Highlight').default;

test.cb('no language - calls correct highlightCall', t => {
td
.when(hjs.highlightAuto('test', undefined))
.thenReturn({ value: 'othertest', language: 'xml' });
const wrapper = mount(<Highlight>test</Highlight>);

setTimeout(() => {
t.is(wrapper.state('language'), 'xml');
t.is(wrapper.state('highlightedCode'), 'othertest');
t.end();
}, 1);
});

test.cb('one language - calls correct highlightCall', t => {
td
.when(hjs.highlight('js', 'test'))
.thenReturn({ value: 'othertest', language: 'js' });
const wrapper = mount(<Highlight languages={['js']}>test</Highlight>);

setTimeout(() => {
t.is(wrapper.state('language'), 'js');
t.is(wrapper.state('highlightedCode'), 'othertest');
t.end();
}, 1);
});

test.cb('multiple languages - calls correct highlightCall', t => {
td
.when(hjs.highlightAuto('test', ['js', 'html']))
.thenReturn({ value: 'othertest', language: 'js' });
const wrapper = mount(<Highlight languages={['js', 'html']}>test</Highlight>);

setTimeout(() => {
t.is(wrapper.state('language'), 'js');
t.is(wrapper.state('highlightedCode'), 'othertest');
t.end();
}, 1);
});

test('className is passed through', t => {
const wrapper = shallow(<Highlight className="foobar">test</Highlight>);

t.true(wrapper.childAt(0).hasClass('foobar'));
});
3 changes: 3 additions & 0 deletions test/helpers/setup-browser-env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
global.document = require('jsdom').jsdom('<body></body>');
global.window = document.defaultView;
global.navigator = window.navigator;
8 changes: 8 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react';
import { shallow } from 'enzyme';
import test from 'ava';
import Highlight from '../src/index';

test('exports default component', t => {
t.notThrows(() => shallow(<Highlight>test</Highlight>));
});
6 changes: 0 additions & 6 deletions tests/setup.js

This file was deleted.

0 comments on commit 9b01c33

Please sign in to comment.