No flags found
Use flags to group coverage reports by test type, project and/or folders.
Then setup custom commit statuses and notifications for each flag.
e.g., #unittest #integration
#production #enterprise
#frontend #backend
d43f3ef
... +43 ...
5b70c18
Use flags to group coverage reports by test type, project and/or folders.
Then setup custom commit statuses and notifications for each flag.
e.g., #unittest #integration
#production #enterprise
#frontend #backend
1 | + | /** |
|
2 | + | * @typedef {import('vfile').VFile} VFile |
|
3 | + | * @typedef {import('property-information').Schema} Schema |
|
4 | + | * @typedef {import('unist').Position} Position |
|
5 | + | * @typedef {import('unist').Point} Point |
|
6 | + | * @typedef {import('hast').Element} Element |
|
7 | + | * @typedef {import('hast').Root} Root |
|
8 | + | * @typedef {import('hast').Content} Content |
|
9 | + | * @typedef {import('parse5').DefaultTreeAdapterMap} DefaultTreeAdapterMap |
|
10 | + | * @typedef {import('parse5').Token.ElementLocation} P5ElementLocation |
|
11 | + | * @typedef {import('parse5').Token.Location} P5Location |
|
12 | + | */ |
|
13 | + | ||
14 | + | /** |
|
15 | + | * @typedef {Content | Root} Node |
|
16 | + | * @typedef {DefaultTreeAdapterMap['document']} P5Document |
|
17 | + | * @typedef {DefaultTreeAdapterMap['documentFragment']} P5DocumentFragment |
|
18 | + | * @typedef {DefaultTreeAdapterMap['documentType']} P5DocumentType |
|
19 | + | * @typedef {DefaultTreeAdapterMap['commentNode']} P5Comment |
|
20 | + | * @typedef {DefaultTreeAdapterMap['textNode']} P5Text |
|
21 | + | * @typedef {DefaultTreeAdapterMap['element']} P5Element |
|
22 | + | * @typedef {DefaultTreeAdapterMap['node']} P5Node |
|
23 | + | * @typedef {DefaultTreeAdapterMap['template']} P5Template |
|
24 | + | * |
|
25 | + | * @typedef {'html' | 'svg'} Space |
|
26 | + | * Namespace. |
|
27 | + | * |
|
28 | + | * @typedef Options |
|
29 | + | * Configuration. |
|
30 | + | * @property {Space | null | undefined} [space='html'] |
|
31 | + | * Which space the document is in. |
|
32 | + | * |
|
33 | + | * When an `<svg>` element is found in the HTML space, this package already |
|
34 | + | * automatically switches to and from the SVG space when entering and exiting |
|
35 | + | * it. |
|
36 | + | * @property {VFile | null | undefined} [file] |
|
37 | + | * File used to add positional info to nodes. |
|
38 | + | * |
|
39 | + | * If given, the file should represent the original HTML source. |
|
40 | + | * @property {boolean} [verbose=false] |
|
41 | + | * Whether to add extra positional info about starting tags, closing tags, |
|
42 | + | * and attributes to elements. |
|
43 | + | * |
|
44 | + | * > 👉 **Note**: only used when `file` is given. |
|
45 | + | * |
|
46 | + | * @typedef State |
|
47 | + | * Info passed around about the current state. |
|
48 | + | * @property {Schema} schema |
|
49 | + | * Current schema. |
|
50 | + | * @property {VFile | undefined} file |
|
51 | + | * Corresponding file. |
|
52 | + | * @property {boolean | undefined} verbose |
|
53 | + | * Add extra positional info. |
|
54 | + | * @property {boolean} location |
|
55 | + | * Whether location info was found. |
|
56 | + | */ |
|
57 | + | ||
58 | + | import {h, s} from 'hastscript' |
|
59 | + | import {html, svg, find} from 'property-information' |
|
60 | + | import {location} from 'vfile-location' |
|
61 | + | import {webNamespaces} from 'web-namespaces' |
|
62 | + | ||
63 | + | const own = {}.hasOwnProperty |
|
64 | + | ||
65 | + | /** |
|
66 | + | * Transform a `parse5` AST to hast. |
|
67 | + | * |
|
68 | + | * @param {P5Node} tree |
|
69 | + | * `parse5` tree to transform. |
|
70 | + | * @param {Options | VFile | null | undefined} [options] |
|
71 | + | * Configuration. |
|
72 | + | * @returns {Node} |
|
73 | + | * hast tree. |
|
74 | + | */ |
|
75 | + | export function fromParse5(tree, options) { |
|
76 | + | const options_ = options || {} |
|
77 | + | /** @type {Options} */ |
|
78 | + | let settings |
|
79 | + | /** @type {VFile | undefined} */ |
|
80 | + | let file |
|
81 | + | ||
82 | + | if (isFile(options_)) { |
|
83 | + | file = options_ |
|
84 | + | settings = {} |
|
85 | + | } else { |
|
86 | + | file = options_.file || undefined |
|
87 | + | settings = options_ |
|
88 | + | } |
|
89 | + | ||
90 | + | return one( |
|
91 | + | { |
|
92 | + | schema: settings.space === 'svg' ? svg : html, |
|
93 | + | file, |
|
94 | + | verbose: settings.verbose, |
|
95 | + | location: false |
|
96 | + | }, |
|
97 | + | tree |
|
98 | + | ) |
|
99 | + | } |
|
100 | + | ||
101 | + | /** |
|
102 | + | * Transform a node. |
|
103 | + | * |
|
104 | + | * @param {State} state |
|
105 | + | * Info passed around about the current state. |
|
106 | + | * @param {P5Node} node |
|
107 | + | * p5 node. |
|
108 | + | * @returns {Node} |
|
109 | + | * hast node. |
|
110 | + | */ |
|
111 | + | function one(state, node) { |
|
112 | + | /** @type {Node} */ |
|
113 | + | let result |
|
114 | + | ||
115 | + | switch (node.nodeName) { |
|
116 | + | case '#comment': { |
|
117 | + | const reference = /** @type {P5Comment} */ (node) |
|
118 | + | result = {type: 'comment', value: reference.data} |
|
119 | + | patch(state, reference, result) |
|
120 | + | return result |
|
121 | + | } |
|
122 | + | ||
123 | + | case '#document': |
|
124 | + | case '#document-fragment': { |
|
125 | + | const reference = /** @type {P5Document | P5DocumentFragment} */ (node) |
|
126 | + | const quirksMode = |
|
127 | + | 'mode' in reference |
|
128 | + | ? reference.mode === 'quirks' || reference.mode === 'limited-quirks' |
|
129 | + | : false |
|
130 | + | ||
131 | + | result = { |
|
132 | + | type: 'root', |
|
133 | + | children: all(state, node.childNodes), |
|
134 | + | data: {quirksMode} |
|
135 | + | } |
|
136 | + | ||
137 | + | if (state.file && state.location) { |
|
138 | + | const doc = String(state.file) |
|
139 | + | const loc = location(doc) |
|
140 | + | result.position = {start: loc.toPoint(0), end: loc.toPoint(doc.length)} |
|
141 | + | } |
|
142 | + | ||
143 | + | return result |
|
144 | + | } |
|
145 | + | ||
146 | + | case '#documentType': { |
|
147 | + | const reference = /** @type {P5DocumentType} */ (node) |
|
148 | + | // @ts-expect-error Types are out of date. |
|
149 | + | result = {type: 'doctype'} |
|
150 | + | patch(state, reference, result) |
|
151 | + | return result |
|
152 | + | } |
|
153 | + | ||
154 | + | case '#text': { |
|
155 | + | const reference = /** @type {P5Text} */ (node) |
|
156 | + | result = {type: 'text', value: reference.value} |
|
157 | + | patch(state, reference, result) |
|
158 | + | return result |
|
159 | + | } |
|
160 | + | ||
161 | + | // Element. |
|
162 | + | default: { |
|
163 | + | const reference = /** @type {P5Element} */ (node) |
|
164 | + | result = element(state, reference) |
|
165 | + | return result |
|
166 | + | } |
|
167 | + | } |
|
168 | + | } |
|
169 | + | ||
170 | + | /** |
|
171 | + | * Transform children. |
|
172 | + | * |
|
173 | + | * @param {State} state |
|
174 | + | * Info passed around about the current state. |
|
175 | + | * @param {Array<P5Node>} nodes |
|
176 | + | * Nodes. |
|
177 | + | * @returns {Array<Content>} |
|
178 | + | * hast nodes. |
|
179 | + | */ |
|
180 | + | function all(state, nodes) { |
|
181 | + | let index = -1 |
|
182 | + | /** @type {Array<Content>} */ |
|
183 | + | const result = [] |
|
184 | + | ||
185 | + | while (++index < nodes.length) { |
|
186 | + | // @ts-expect-error Assume no roots in `nodes`. |
|
187 | + | result[index] = one(state, nodes[index]) |
|
188 | + | } |
|
189 | + | ||
190 | + | return result |
|
191 | + | } |
|
192 | + | ||
193 | + | /** |
|
194 | + | * Transform an element. |
|
195 | + | * |
|
196 | + | * @param {State} state |
|
197 | + | * Info passed around about the current state. |
|
198 | + | * @param {P5Element} node |
|
199 | + | * `parse5` node to transform. |
|
200 | + | * @returns {Element} |
|
201 | + | * hast node. |
|
202 | + | */ |
|
203 | + | function element(state, node) { |
|
204 | + | const schema = state.schema |
|
205 | + | ||
206 | + | state.schema = node.namespaceURI === webNamespaces.svg ? svg : html |
|
207 | + | ||
208 | + | // Props. |
|
209 | + | let index = -1 |
|
210 | + | /** @type {Record<string, string>} */ |
|
211 | + | const props = {} |
|
212 | + | ||
213 | + | while (++index < node.attrs.length) { |
|
214 | + | const attribute = node.attrs[index] |
|
215 | + | props[(attribute.prefix ? attribute.prefix + ':' : '') + attribute.name] = |
|
216 | + | attribute.value |
|
217 | + | } |
|
218 | + | ||
219 | + | // Build. |
|
220 | + | const fn = state.schema.space === 'svg' ? s : h |
|
221 | + | const result = fn(node.tagName, props, all(state, node.childNodes)) |
|
222 | + | patch(state, node, result) |
|
223 | + | ||
224 | + | // Switch content. |
|
225 | + | if (result.tagName === 'template') { |
|
226 | + | const reference = /** @type {P5Template} */ (node) |
|
227 | + | const pos = reference.sourceCodeLocation |
|
228 | + | const startTag = pos && pos.startTag && position(pos.startTag) |
|
229 | + | const endTag = pos && pos.endTag && position(pos.endTag) |
|
230 | + | ||
231 | + | /** @type {Root} */ |
|
232 | + | // @ts-expect-error Types are wrong. |
|
233 | + | const content = one(state, reference.content) |
|
234 | + | ||
235 | + | if (startTag && endTag && state.file) { |
|
236 | + | content.position = {start: startTag.end, end: endTag.start} |
|
237 | + | } |
|
238 | + | ||
239 | + | result.content = content |
|
240 | + | } |
|
241 | + | ||
242 | + | state.schema = schema |
|
243 | + | ||
244 | + | return result |
|
245 | + | } |
|
246 | + | ||
247 | + | /** |
|
248 | + | * Patch positional info from `from` onto `to`. |
|
249 | + | * |
|
250 | + | * @param {State} state |
|
251 | + | * Info passed around about the current state. |
|
252 | + | * @param {P5Node} from |
|
253 | + | * p5 node. |
|
254 | + | * @param {Node} to |
|
255 | + | * hast node. |
|
256 | + | * @returns {void} |
|
257 | + | * Nothing. |
|
258 | + | */ |
|
259 | + | function patch(state, from, to) { |
|
260 | + | if ('sourceCodeLocation' in from && from.sourceCodeLocation && state.file) { |
|
261 | + | const position = createLocation(state, to, from.sourceCodeLocation) |
|
262 | + | ||
263 | + | if (position) { |
|
264 | + | state.location = true |
|
265 | + | to.position = position |
|
266 | + | } |
|
267 | + | } |
|
268 | + | } |
|
269 | + | ||
270 | + | /** |
|
271 | + | * Create clean positional information. |
|
272 | + | * |
|
273 | + | * @param {State} state |
|
274 | + | * Info passed around about the current state. |
|
275 | + | * @param {Node} node |
|
276 | + | * hast node. |
|
277 | + | * @param {P5ElementLocation} location |
|
278 | + | * p5 location info. |
|
279 | + | * @returns {Position | undefined} |
|
280 | + | * Position, or nothing. |
|
281 | + | */ |
|
282 | + | function createLocation(state, node, location) { |
|
283 | + | const result = position(location) |
|
284 | + | ||
285 | + | if (node.type === 'element') { |
|
286 | + | const tail = node.children[node.children.length - 1] |
|
287 | + | ||
288 | + | // Bug for unclosed with children. |
|
289 | + | // See: <https://github.com/inikulin/parse5/issues/109>. |
|
290 | + | if ( |
|
291 | + | result && |
|
292 | + | !location.endTag && |
|
293 | + | tail && |
|
294 | + | tail.position && |
|
295 | + | tail.position.end |
|
296 | + | ) { |
|
297 | + | result.end = Object.assign({}, tail.position.end) |
|
298 | + | } |
|
299 | + | ||
300 | + | if (state.verbose) { |
|
301 | + | /** @type {Record<string, Position | undefined>} */ |
|
302 | + | const props = {} |
|
303 | + | /** @type {string} */ |
|
304 | + | let key |
|
305 | + | ||
306 | + | if (location.attrs) { |
|
307 | + | for (key in location.attrs) { |
|
308 | + | if (own.call(location.attrs, key)) { |
|
309 | + | props[find(state.schema, key).property] = position( |
|
310 | + | location.attrs[key] |
|
311 | + | ) |
|
312 | + | } |
|
313 | + | } |
|
314 | + | } |
|
315 | + | ||
316 | + | node.data = { |
|
317 | + | position: { |
|
318 | + | // @ts-expect-error: assume not `undefined`. |
|
319 | + | opening: position(location.startTag), |
|
320 | + | closing: location.endTag ? position(location.endTag) : null, |
|
321 | + | properties: props |
|
322 | + | } |
|
323 | + | } |
|
324 | + | } |
|
325 | + | } |
|
326 | + | ||
327 | + | return result |
|
328 | + | } |
|
329 | + | ||
330 | + | /** |
|
331 | + | * Turn a p5 location into a position. |
|
332 | + | * |
|
333 | + | * @param {P5Location} loc |
|
334 | + | * Location. |
|
335 | + | * @returns {Position | undefined} |
|
336 | + | * Position or nothing. |
|
337 | + | */ |
|
338 | + | function position(loc) { |
|
339 | + | const start = point({ |
|
340 | + | line: loc.startLine, |
|
341 | + | column: loc.startCol, |
|
342 | + | offset: loc.startOffset |
|
343 | + | }) |
|
344 | + | const end = point({ |
|
345 | + | line: loc.endLine, |
|
346 | + | column: loc.endCol, |
|
347 | + | offset: loc.endOffset |
|
348 | + | }) |
|
349 | + | // @ts-expect-error `undefined` is fine. |
|
350 | + | return start || end ? {start, end} : undefined |
|
351 | + | } |
|
352 | + | ||
353 | + | /** |
|
354 | + | * Filter out invalid points. |
|
355 | + | * |
|
356 | + | * @param {Point} point |
|
357 | + | * Point with potentially `undefined` values. |
|
358 | + | * @returns {Point | undefined} |
|
359 | + | * Point or nothing. |
|
360 | + | */ |
|
361 | + | function point(point) { |
|
362 | + | return point.line && point.column ? point : undefined |
|
363 | + | } |
|
364 | + | ||
365 | + | /** |
|
366 | + | * Check if something is a file. |
|
367 | + | * |
|
368 | + | * @param {VFile | Options} value |
|
369 | + | * File or options. |
|
370 | + | * @returns {value is VFile} |
|
371 | + | * Whether `value` is a file. |
|
372 | + | */ |
|
373 | + | function isFile(value) { |
|
374 | + | return 'messages' in value |
|
375 | + | } |
1 | - | 'use strict' |
|
1 | + | /** |
|
2 | + | * @typedef {import('./lib/index.js').Options} Options |
|
3 | + | * @typedef {import('./lib/index.js').Space} Space |
|
4 | + | */ |
|
2 | 5 | ||
3 | - | var html = require('property-information/html') |
|
4 | - | var svg = require('property-information/svg') |
|
5 | - | var find = require('property-information/find') |
|
6 | - | var ns = require('web-namespaces') |
|
7 | - | var s = require('hastscript/svg') |
|
8 | - | var h = require('hastscript') |
|
9 | - | var count = require('ccount') |
|
10 | - | ||
11 | - | module.exports = wrapper |
|
12 | - | ||
13 | - | var own = {}.hasOwnProperty |
|
14 | - | ||
15 | - | // Handlers. |
|
16 | - | var map = { |
|
17 | - | '#document': root, |
|
18 | - | '#document-fragment': root, |
|
19 | - | '#text': text, |
|
20 | - | '#comment': comment, |
|
21 | - | '#documentType': doctype |
|
22 | - | } |
|
23 | - | ||
24 | - | // Wrapper to normalise options. |
|
25 | - | function wrapper(ast, options) { |
|
26 | - | var settings = options || {} |
|
27 | - | var file |
|
28 | - | ||
29 | - | if (settings.messages) { |
|
30 | - | file = settings |
|
31 | - | settings = {} |
|
32 | - | } else { |
|
33 | - | file = settings.file |
|
34 | - | } |
|
35 | - | ||
36 | - | return transform(ast, { |
|
37 | - | schema: settings.space === 'svg' ? svg : html, |
|
38 | - | file: file, |
|
39 | - | verbose: settings.verbose, |
|
40 | - | location: false |
|
41 | - | }) |
|
42 | - | } |
|
43 | - | ||
44 | - | // Transform a node. |
|
45 | - | function transform(ast, config) { |
|
46 | - | var schema = config.schema |
|
47 | - | var fn = own.call(map, ast.nodeName) ? map[ast.nodeName] : element |
|
48 | - | var children |
|
49 | - | var node |
|
50 | - | var pos |
|
51 | - | ||
52 | - | if (fn === element) { |
|
53 | - | config.schema = ast.namespaceURI === ns.svg ? svg : html |
|
54 | - | } |
|
55 | - | ||
56 | - | if (ast.childNodes) { |
|
57 | - | children = nodes(ast.childNodes, config) |
|
58 | - | } |
|
59 | - | ||
60 | - | node = fn(ast, children, config) |
|
61 | - | ||
62 | - | if (ast.sourceCodeLocation && config.file) { |
|
63 | - | pos = location(node, ast.sourceCodeLocation, config) |
|
64 | - | ||
65 | - | if (pos) { |
|
66 | - | config.location = true |
|
67 | - | node.position = pos |
|
68 | - | } |
|
69 | - | } |
|
70 | - | ||
71 | - | config.schema = schema |
|
72 | - | ||
73 | - | return node |
|
74 | - | } |
|
75 | - | ||
76 | - | // Transform children. |
|
77 | - | function nodes(children, config) { |
|
78 | - | var length = children.length |
|
79 | - | var index = -1 |
|
80 | - | var result = [] |
|
81 | - | ||
82 | - | while (++index < length) { |
|
83 | - | result[index] = transform(children[index], config) |
|
84 | - | } |
|
85 | - | ||
86 | - | return result |
|
87 | - | } |
|
88 | - | ||
89 | - | // Transform a document. |
|
90 | - | // Stores `ast.quirksMode` in `node.data.quirksMode`. |
|
91 | - | function root(ast, children, config) { |
|
92 | - | var node = {type: 'root', children: children, data: {}} |
|
93 | - | var doc |
|
94 | - | ||
95 | - | node.data.quirksMode = ast.mode === 'quirks' || ast.mode === 'limited-quirks' |
|
96 | - | ||
97 | - | if (config.file && config.location) { |
|
98 | - | doc = String(config.file) |
|
99 | - | ||
100 | - | node.position = { |
|
101 | - | start: {line: 1, column: 1, offset: 0}, |
|
102 | - | end: { |
|
103 | - | line: count(doc, '\n') + 1, |
|
104 | - | column: doc.length - doc.lastIndexOf('\n'), |
|
105 | - | offset: doc.length |
|
106 | - | } |
|
107 | - | } |
|
108 | - | } |
|
109 | - | ||
110 | - | return node |
|
111 | - | } |
|
112 | - | ||
113 | - | // Transform a doctype. |
|
114 | - | function doctype(ast) { |
|
115 | - | return { |
|
116 | - | type: 'doctype', |
|
117 | - | name: ast.name || '', |
|
118 | - | public: ast.publicId || null, |
|
119 | - | system: ast.systemId || null |
|
120 | - | } |
|
121 | - | } |
|
122 | - | ||
123 | - | // Transform a text. |
|
124 | - | function text(ast) { |
|
125 | - | return {type: 'text', value: ast.value} |
|
126 | - | } |
|
127 | - | ||
128 | - | // Transform a comment. |
|
129 | - | function comment(ast) { |
|
130 | - | return {type: 'comment', value: ast.data} |
|
131 | - | } |
|
132 | - | ||
133 | - | // Transform an element. |
|
134 | - | function element(ast, children, config) { |
|
135 | - | var fn = config.schema.space === 'svg' ? s : h |
|
136 | - | var name = ast.tagName |
|
137 | - | var attributes = ast.attrs |
|
138 | - | var length = attributes.length |
|
139 | - | var props = {} |
|
140 | - | var index = -1 |
|
141 | - | var attribute |
|
142 | - | var prop |
|
143 | - | var node |
|
144 | - | var pos |
|
145 | - | var start |
|
146 | - | var end |
|
147 | - | ||
148 | - | while (++index < length) { |
|
149 | - | attribute = attributes[index] |
|
150 | - | prop = (attribute.prefix ? attribute.prefix + ':' : '') + attribute.name |
|
151 | - | props[prop] = attribute.value |
|
152 | - | } |
|
153 | - | ||
154 | - | node = fn(name, props, children) |
|
155 | - | ||
156 | - | if (name === 'template' && 'content' in ast) { |
|
157 | - | pos = ast.sourceCodeLocation |
|
158 | - | start = pos && pos.startTag && position(pos.startTag).end |
|
159 | - | end = pos && pos.endTag && position(pos.endTag).start |
|
160 | - | ||
161 | - | node.content = transform(ast.content, config) |
|
162 | - | ||
163 | - | if ((start || end) && config.file) { |
|
164 | - | node.content.position = {start: start, end: end} |
|
165 | - | } |
|
166 | - | } |
|
167 | - | ||
168 | - | return node |
|
169 | - | } |
|
170 | - | ||
171 | - | // Create clean positional information. |
|
172 | - | function location(node, location, config) { |
|
173 | - | var schema = config.schema |
|
174 | - | var verbose = config.verbose |
|
175 | - | var pos = position(location) |
|
176 | - | var reference |
|
177 | - | var attributes |
|
178 | - | var attribute |
|
179 | - | var props |
|
180 | - | var prop |
|
181 | - | ||
182 | - | if (node.type === 'element') { |
|
183 | - | reference = node.children[node.children.length - 1] |
|
184 | - | ||
185 | - | // Bug for unclosed with children. |
|
186 | - | // See: <https://github.com/inikulin/parse5/issues/109>. |
|
187 | - | if ( |
|
188 | - | !location.endTag && |
|
189 | - | reference && |
|
190 | - | reference.position && |
|
191 | - | reference.position.end |
|
192 | - | ) { |
|
193 | - | pos.end = Object.assign({}, reference.position.end) |
|
194 | - | } |
|
195 | - | ||
196 | - | if (verbose) { |
|
197 | - | attributes = location.attrs |
|
198 | - | props = {} |
|
199 | - | ||
200 | - | for (attribute in attributes) { |
|
201 | - | prop = find(schema, attribute).property |
|
202 | - | props[prop] = position(attributes[attribute]) |
|
203 | - | } |
|
204 | - | ||
205 | - | node.data = { |
|
206 | - | position: { |
|
207 | - | opening: position(location.startTag), |
|
208 | - | closing: location.endTag ? position(location.endTag) : null, |
|
209 | - | properties: props |
|
210 | - | } |
|
211 | - | } |
|
212 | - | } |
|
213 | - | } |
|
214 | - | ||
215 | - | return pos |
|
216 | - | } |
|
217 | - | ||
218 | - | function position(loc) { |
|
219 | - | var start = point({ |
|
220 | - | line: loc.startLine, |
|
221 | - | column: loc.startCol, |
|
222 | - | offset: loc.startOffset |
|
223 | - | }) |
|
224 | - | var end = point({ |
|
225 | - | line: loc.endLine, |
|
226 | - | column: loc.endCol, |
|
227 | - | offset: loc.endOffset |
|
228 | - | }) |
|
229 | - | return start || end ? {start: start, end: end} : null |
|
230 | - | } |
|
231 | - | ||
232 | - | function point(point) { |
|
233 | - | return point.line && point.column ? point : null |
|
234 | - | } |
|
6 | + | export {fromParse5} from './lib/index.js' |
Learn more Showing 1 files with coverage changes found.
lib/index.js
Files | Coverage |
---|---|
index.js | 100.00% |
lib/index.js | 100.00% |
Project Totals (2 files) | 100.00% |
5b70c18
b3d202a
00413a1
ed996fe
ab3559e
bdf41fc
155923c
6a6bdad
10328ea
cb567c5
b344419
2a9bd42
fa0be0e
3bd13d7
3397a66
5e813f0
f45d2ac
9f63db3
302f6f8
c5c6819
3a0adc3
762ba62
8df84b7
a57a0bb
0977456
3a594c0
1584594
7fd0848
21e9223
20e9416
8e6ee62
c8170b1
2736de8
05b63c2
2085ef4
cea54a6
7a3a3c9
e75a23b
4f3e76b
cb5d14e
d3bbec1
2103471
c9b1e27
4c1e5c5
d43f3ef