Skip to content

Commit

Permalink
feat: add onError hook for JSON.parse
Browse files Browse the repository at this point in the history
  • Loading branch information
chenckang committed Mar 14, 2019
1 parent 57170df commit 5b883c8
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 25 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ The preview is as below:

## Others

### Error

Use `onError` function property to get `JSON.parse` errors.

```jsx
<JSONPretty data={invalid} onError={e => console.error(e)}></JSONPretty>
```

### Formation

Actually, react-json-pretty is based on `JSON.stringify(value[, replacer[, space]])`. However, `JSON.stringify(value[, replacer[, space]])` has some optional parameters additionally such as `replacer` and `space`. This is also available in `react-json-pretty`.
Expand Down
2 changes: 1 addition & 1 deletion example/app/Example.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ ReactDOM.render(
</div>
<div>
<h4>XSS pretection</h4>
<JSONPretty id="json-pretty" style={{fontSize: "1.1em"}} data={{data: "<img onerror='alert(document.cookie)' src='invalid-image' />"}}></JSONPretty>
<JSONPretty id="json-pretty" data={`{data: \"<img onerror='alert(document.cookie)' src='invalid-image' />}`} onError={alert}></JSONPretty>
</div>
</div>,
document.getElementById('example')
Expand Down
10 changes: 4 additions & 6 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@ module.exports = {
"^.+\\.tsx?$": "ts-jest",
},
"testRegex": "test\\.tsx?$",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx"
"coveragePathIgnorePatterns": [
"/node_modules/",
"<rootDir>/tests/"
],
"snapshotSerializers": ["enzyme-to-json/serializer"],
"setupTestFrameworkScriptFile": "<rootDir>/tests/setupEnzyme.ts",
"setupFilesAfterEnv": ["<rootDir>/tests/setupEnzyme.ts"],
}
6 changes: 2 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,17 @@
"react-dom": ">=15.0"
},
"devDependencies": {
"@types/chai": "^4.1.7",
"@types/enzyme": "^3.1.15",
"@types/enzyme-adapter-react-16": "^1.0.3",
"@types/jest": "^23.3.11",
"@types/prop-types": "^15.5.8",
"@types/react": "^16.7.18",
"@types/react-dom": "^16.0.11",
"chai": "^4.2.0",
"enzyme": "^3.8.0",
"enzyme-adapter-react-16": "^1.7.1",
"enzyme-adapter-react-16": "^1.9.1",
"enzyme-to-json": "^3.3.5",
"husky": "^1.3.1",
"jest": "^23.6.0",
"jest": "^24.5.0",
"react": "^16.7.0",
"react-dom": "^16.7.0",
"react-test-renderer": "^16.7.0",
Expand Down
8 changes: 7 additions & 1 deletion src/JSONPretty.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ interface IProps {
themeClassName?: string;
theme?: ITheme;
silent?: boolean;
onError?: (e: Error) => void;
}

function getStyleValue(name: string, theme: ITheme): string {
Expand Down Expand Up @@ -48,6 +49,7 @@ class JSONPretty extends React.Component<IProps, {}> {
space: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
theme: PropTypes.object,
themeClassName: PropTypes.string,
onError: PropTypes.func
};

public static defaultProps = {
Expand All @@ -59,7 +61,7 @@ class JSONPretty extends React.Component<IProps, {}> {
};

public render() {
const { json, data, replacer, space, themeClassName, theme, silent, ...rest } = this.props;
const { json, data, replacer, space, themeClassName, theme, onError, silent, ...rest } = this.props;

let obj = data || json;

Expand All @@ -72,6 +74,10 @@ class JSONPretty extends React.Component<IProps, {}> {
console.warn(`[react-json-pretty]: ${e.message}`);
}

if (onError) {
onError(e);
}

return(
<div {...rest} dangerouslySetInnerHTML={
{__html:
Expand Down
28 changes: 15 additions & 13 deletions tests/JSONPretty.test.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { shallow } from 'enzyme';
import * as React from 'react';

import { expect } from 'chai';

import JSONPretty from '../src/JSONPretty';

test('simple', () => {
const box = shallow(<JSONPretty json={'123'}></JSONPretty>);
expect(box.html()).to.equal('<div><pre class=__json-pretty__><span class=__json-value__>123</span></pre></div>');
expect(box.html()).toEqual('<div><pre class=__json-pretty__><span class=__json-value__>123</span></pre></div>');
});

test('complex object', () => {
Expand Down Expand Up @@ -47,7 +45,7 @@ test('complex object', () => {
.split('\n')
.map((line) => line.trim())
.forEach((line) => {
expect(box.html()).to.include(line);
expect(box.html()).toMatch(line);
});
});

Expand Down Expand Up @@ -88,7 +86,7 @@ test('complex string', () => {
.split('\n')
.map((line) => line.trim())
.forEach((line) => {
expect(box.html()).to.include(line);
expect(box.html()).toMatch(line);
});
});

Expand Down Expand Up @@ -144,7 +142,7 @@ test('complex string with theme', () => {
.split('\n')
.map((line) => line.trim())
.forEach((line) => {
expect(box.html()).to.include(line);
expect(box.html()).toMatch(line);
});
});

Expand Down Expand Up @@ -199,13 +197,13 @@ test('complex string with theme missing boolean theme', () => {
.split('\n')
.map((line) => line.trim())
.forEach((line) => {
expect(box.html()).to.include(line);
expect(box.html()).toMatch(line);
});
});

test('invalid', () => {
const box = shallow(<JSONPretty json={undefined} silent={false}></JSONPretty>);
expect(box.html()).to.equal('<div><pre class=__json-pretty__></pre></div>');
expect(box.html()).toEqual('<div><pre class=__json-pretty__></pre></div>');
});

test('invalid json', () => {
Expand All @@ -215,7 +213,7 @@ test('invalid json', () => {
.split('\n')
.map((line) => line.trim())
.forEach((line) => {
expect(box.html()).to.include(line);
expect(box.html()).toMatch(line);
});
});

Expand All @@ -226,7 +224,7 @@ test('invalid space', () => {
.split('\n')
.map((line) => line.trim())
.forEach((line) => {
expect(box.html()).to.include(line);
expect(box.html()).toMatch(line);
});
});

Expand Down Expand Up @@ -283,12 +281,16 @@ test('complex object with format', () => {
.split('\n')
.map((line) => line.trim())
.forEach((line) => {
expect(box.html()).to.include(line);
expect(box.html()).toMatch(line);
});
});

test('xss pretection', () => {
expect.assertions(2);
function onError(e: Error) {
expect(e).toBeInstanceOf(SyntaxError);
}
const data = `{data: \"<img onerror='alert(document.cookie)' src='invalid-image' />}`;
const box = shallow(<JSONPretty json={data}></JSONPretty>);
expect(box.html()).to.eql('<div><pre class=__json-pretty__>{data: &quot;&ltimg onerror=&apos;alert(document.cookie)&apos; src=&apos;invalid-image&apos; /&gt;}</pre></div>');
const box = shallow(<JSONPretty json={data} onError={onError}></JSONPretty>);
expect(box.html()).toEqual('<div><pre class=__json-pretty__>{data: &quot;&ltimg onerror=&apos;alert(document.cookie)&apos; src=&apos;invalid-image&apos; /&gt;}</pre></div>');
});

0 comments on commit 5b883c8

Please sign in to comment.