Skip to content

Commit 74931e4

Browse files
Merge pull request #156 from remarkablemark/test/coverage
test: refactor and add missing tests, get coverage to 100%
2 parents d299826 + aeed1bf commit 74931e4

7 files changed

+186
-185
lines changed

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ script:
1212
- npm run build
1313
- npm run benchmark
1414
after_success:
15-
- npm run coveralls
15+
- npx nyc report --reporter=text-lcov | npx coveralls
1616
cache:
1717
directories:
1818
- node_modules

lib/attributes-to-props.js

+13-15
Original file line numberDiff line numberDiff line change
@@ -68,26 +68,24 @@ function attributesToProps(attributes) {
6868
}
6969

7070
/**
71-
* Converts CSS style string to JS style object.
71+
* Converts inline CSS style to POJO (Plain Old JavaScript Object).
7272
*
73-
* @param {String} style - The CSS style.
74-
* @return {Object} - The JS style object.
73+
* @param {String} style - The inline CSS style.
74+
* @return {Object} - The style object.
7575
*/
7676
function cssToJs(style) {
77-
if (typeof style !== 'string') {
78-
throw new TypeError('First argument must be a string.');
77+
var styleObject = {};
78+
79+
if (style) {
80+
styleToObject(style, function(property, value) {
81+
// skip CSS comment
82+
if (property && value) {
83+
styleObject[camelCase(property)] = value;
84+
}
85+
});
7986
}
8087

81-
var styleObj = {};
82-
83-
styleToObject(style, function(property, value) {
84-
// skip if it's a comment node
85-
if (property && value) {
86-
styleObj[camelCase(property)] = value;
87-
}
88-
});
89-
90-
return styleObj;
88+
return styleObject;
9189
}
9290

9391
module.exports = attributesToProps;

package.json

-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
"build:min": "cross-env NODE_ENV=production rollup --config --file dist/html-react-parser.min.js --sourcemap",
1111
"build:unmin": "cross-env NODE_ENV=development rollup --config --file dist/html-react-parser.js",
1212
"clean": "rimraf dist",
13-
"coveralls": "nyc report --reporter=text-lcov | coveralls",
1413
"lint": "eslint --ignore-path .gitignore --ignore-pattern /examples/ .",
1514
"lint:dts": "dtslint .",
1615
"lint:fix": "npm run lint -- --fix",
@@ -45,7 +44,6 @@
4544
"@commitlint/config-conventional": "^8.2.0",
4645
"@types/react": "^16.9.11",
4746
"benchmark": "^2.1.4",
48-
"coveralls": "^3.0.7",
4947
"cross-env": "^6.0.3",
5048
"dtslint": "^2.0.0",
5149
"eslint": "^6.6.0",

test/attributes-to-props.js

+12-24
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,19 @@ describe('attributes-to-props', () => {
171171
});
172172
});
173173

174+
// cssToJs
174175
describe('style', () => {
175-
it('converts inline style to object', () => {
176+
it('parses empty inline style to object', () => {
177+
assert.deepEqual(attributesToProps({ style: '' }), { style: {} });
178+
});
179+
180+
it('does not parse CSS comment', () => {
181+
assert.deepEqual(attributesToProps({ style: '/* comment */' }), {
182+
style: {}
183+
});
184+
});
185+
186+
it('parses inline style to object', () => {
176187
assert.deepEqual(
177188
attributesToProps({
178189
style:
@@ -222,29 +233,6 @@ describe('attributes-to-props', () => {
222233
style: undefined
223234
}
224235
);
225-
226-
assert.deepEqual(
227-
attributesToProps({
228-
style: ''
229-
}),
230-
{
231-
style: {}
232-
}
233-
);
234-
});
235-
236-
[Object, Array, Number, Date, Function].forEach(type => {
237-
it(`throws an error when attributes.style=${type.name}`, () => {
238-
assert.throws(
239-
() => {
240-
attributesToProps({ style: type });
241-
},
242-
{
243-
name: 'TypeError',
244-
message: 'First argument must be a string.'
245-
}
246-
);
247-
});
248236
});
249237
});
250238

test/dom-to-react.js

+52-48
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,11 @@
11
const assert = require('assert');
22
const React = require('react');
3-
const Preact = require('preact');
43
const htmlToDOM = require('html-dom-parser');
54
const domToReact = require('../lib/dom-to-react');
65
const { data, render } = require('./helpers/');
76
const utilities = require('../lib/utilities');
87

9-
describe('dom-to-react parser', () => {
10-
let actualReactVersion;
11-
beforeEach(() => {
12-
actualReactVersion = React.version;
13-
});
14-
15-
afterEach(() => {
16-
React.version = actualReactVersion;
17-
});
18-
8+
describe('dom-to-react', () => {
199
it('converts single DOM node to React', () => {
2010
const html = data.html.single;
2111
const reactElement = domToReact(htmlToDOM(html));
@@ -39,7 +29,7 @@ describe('dom-to-react parser', () => {
3929
]);
4030
});
4131

42-
// https://facebook.github.io/react/docs/forms.html#why-textarea-value
32+
// https://reactjs.org/docs/forms.html#the-textarea-tag
4333
it('converts <textarea> correctly', () => {
4434
const html = data.html.textarea;
4535
const reactElement = domToReact(htmlToDOM(html));
@@ -131,7 +121,7 @@ describe('dom-to-react parser', () => {
131121
]);
132122
});
133123

134-
it("handles svg's with a viewBox", () => {
124+
it('converts SVG element with viewBox attribute', () => {
135125
const html = data.svg.simple;
136126
const reactElement = domToReact(
137127
htmlToDOM(html, { lowerCaseAttributeNames: false })
@@ -160,47 +150,61 @@ describe('dom-to-react parser', () => {
160150
);
161151
});
162152

163-
it('handles using a custom component library', () => {
164-
const html = data.html.single;
165-
const preactElement = domToReact(htmlToDOM(html), { library: Preact });
153+
describe('library', () => {
154+
const Preact = require('preact');
155+
156+
it('converts with Preact instead of React', () => {
157+
const html = data.html.single;
158+
const preactElement = domToReact(htmlToDOM(html), { library: Preact });
166159

167-
assert.deepEqual(preactElement, Preact.createElement('p', {}, 'foo'));
160+
assert.deepEqual(preactElement, Preact.createElement('p', {}, 'foo'));
161+
});
168162
});
169163

170-
it('does not modify keys for replacement if it has one', () => {
171-
const html = [data.html.single, data.html.customElement].join('');
164+
describe('replace', () => {
165+
it("does not set key if there's 1 node", () => {
166+
const replaceElement = React.createElement('p');
167+
const reactElement = domToReact(htmlToDOM(data.html.single), {
168+
replace: () => replaceElement
169+
});
170+
assert.deepEqual(reactElement, replaceElement);
171+
});
172172

173-
const reactElements = domToReact(htmlToDOM(html), {
174-
replace: node => {
175-
if (node.name === 'p') {
176-
return React.createElement('p', {}, 'replaced foo');
177-
}
178-
if (node.name === 'custom-button') {
179-
return React.createElement(
180-
'custom-button',
181-
{
182-
key: 'myKey',
183-
class: 'myClass',
184-
'custom-attribute': 'replaced value'
185-
},
186-
null
187-
);
173+
it("does not modify keys if it's already set", () => {
174+
const html = [data.html.single, data.html.customElement].join('');
175+
176+
const reactElements = domToReact(htmlToDOM(html), {
177+
replace: node => {
178+
if (node.name === 'p') {
179+
return React.createElement('p', {}, 'replaced foo');
180+
}
181+
if (node.name === 'custom-button') {
182+
return React.createElement(
183+
'custom-button',
184+
{
185+
key: 'myKey',
186+
class: 'myClass',
187+
'custom-attribute': 'replaced value'
188+
},
189+
null
190+
);
191+
}
188192
}
189-
}
193+
});
194+
195+
assert.deepEqual(reactElements, [
196+
React.createElement('p', { key: 0 }, 'replaced foo'),
197+
React.createElement(
198+
'custom-button',
199+
{
200+
key: 'myKey',
201+
class: 'myClass',
202+
'custom-attribute': 'replaced value'
203+
},
204+
null
205+
)
206+
]);
190207
});
191-
192-
assert.deepEqual(reactElements, [
193-
React.createElement('p', { key: 0 }, 'replaced foo'),
194-
React.createElement(
195-
'custom-button',
196-
{
197-
key: 'myKey',
198-
class: 'myClass',
199-
'custom-attribute': 'replaced value'
200-
},
201-
null
202-
)
203-
]);
204208
});
205209

206210
describe('when React <16', () => {

test/html-to-react.js

+11-11
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,26 @@ describe('html-to-react', () => {
1818
});
1919

2020
it('returns string if it cannot be parsed as HTML', () => {
21-
assert.equal(parse('foo'), 'foo');
21+
assert.strictEqual(parse('foo'), 'foo');
2222
});
2323

2424
it('converts single HTML element to React', () => {
2525
const html = data.html.single;
2626
const reactElement = parse(html);
27-
assert.equal(render(reactElement), html);
27+
assert.strictEqual(render(reactElement), html);
2828
});
2929

3030
it('converts single HTML element and ignores comment', () => {
3131
const html = data.html.single;
3232
// comment should be ignored
3333
const reactElement = parse(html + data.html.comment);
34-
assert.equal(render(reactElement), html);
34+
assert.strictEqual(render(reactElement), html);
3535
});
3636

3737
it('converts multiple HTML elements to React', () => {
3838
const html = data.html.multiple;
3939
const reactElements = parse(html);
40-
assert.equal(
40+
assert.strictEqual(
4141
render(React.createElement('div', {}, reactElements)),
4242
'<div>' + html + '</div>'
4343
);
@@ -46,32 +46,32 @@ describe('html-to-react', () => {
4646
it('converts complex HTML to React', () => {
4747
const html = data.html.complex;
4848
const reactElement = parse(data.html.doctype + html);
49-
assert.equal(render(reactElement), html);
49+
assert.strictEqual(render(reactElement), html);
5050
});
5151

5252
it('converts empty <script> to React', () => {
5353
const html = '<script></script>';
5454
const reactElement = parse(html);
55-
assert.equal(render(reactElement), html);
55+
assert.strictEqual(render(reactElement), html);
5656
});
5757

5858
it('converts empty <style> to React', () => {
5959
const html = '<style></style>';
6060
const reactElement = parse(html);
61-
assert.equal(render(reactElement), html);
61+
assert.strictEqual(render(reactElement), html);
6262
});
6363

6464
it('converts SVG to React', () => {
6565
const svg = data.svg.complex;
6666
const reactElement = parse(svg);
67-
assert.equal(render(reactElement), svg);
67+
assert.strictEqual(render(reactElement), svg);
6868
});
6969

7070
it('decodes HTML entities', () => {
7171
const encodedEntities = 'asdf &amp; &yuml; &uuml; &apos;';
7272
const decodedEntities = "asdf & ÿ ü '";
7373
const reactElement = parse('<i>' + encodedEntities + '</i>');
74-
assert.equal(reactElement.props.children, decodedEntities);
74+
assert.strictEqual(reactElement.props.children, decodedEntities);
7575
});
7676
});
7777

@@ -86,7 +86,7 @@ describe('html-to-react', () => {
8686
}
8787
}
8888
});
89-
assert.equal(
89+
assert.strictEqual(
9090
render(reactElement),
9191
html.replace('<title>Title</title>', '<title>Replaced Title</title>')
9292
);
@@ -118,6 +118,6 @@ describe('html-to-react', () => {
118118

119119
describe('dom-to-react', () => {
120120
it('exports domToReact', () => {
121-
assert.equal(parse.domToReact, require('../lib/dom-to-react'));
121+
assert.strictEqual(parse.domToReact, require('../lib/dom-to-react'));
122122
});
123123
});

0 commit comments

Comments
 (0)