@projectwallace/css-code-coverage 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,98 +1,98 @@
1
- import * as v from "valibot";
2
- import { format as q } from "@projectwallace/format-css";
3
- import { tokenTypes as b, tokenize as N } from "css-tree/tokenizer";
4
- let z = v.array(
5
- v.object({
6
- text: v.optional(v.string()),
7
- url: v.string(),
8
- ranges: v.array(
9
- v.object({
10
- start: v.number(),
11
- end: v.number()
1
+ import * as h from "valibot";
2
+ import { format as F } from "@projectwallace/format-css";
3
+ import { tokenTypes as x, tokenize as $ } from "css-tree/tokenizer";
4
+ let J = h.array(
5
+ h.object({
6
+ text: h.optional(h.string()),
7
+ url: h.string(),
8
+ ranges: h.array(
9
+ h.object({
10
+ start: h.number(),
11
+ end: h.number()
12
12
  })
13
13
  )
14
14
  })
15
15
  );
16
- function T(t) {
17
- return v.safeParse(z, t).success;
16
+ function q(t) {
17
+ return h.safeParse(J, t).success;
18
18
  }
19
- function Q(t) {
19
+ function X(t) {
20
20
  try {
21
21
  let e = JSON.parse(t);
22
- return T(e) ? e : [];
22
+ return q(e) ? e : [];
23
23
  } catch {
24
24
  return [];
25
25
  }
26
26
  }
27
- function F(t) {
28
- return t.map(({ url: e, text: l, ranges: n }) => {
29
- if (!l)
30
- return { url: e, text: l, ranges: n };
31
- let d = q(l), u = /* @__PURE__ */ new Set([
32
- b.EOF,
33
- b.BadString,
34
- b.BadUrl,
35
- b.WhiteSpace,
36
- b.Semicolon,
37
- b.Comment,
38
- b.Colon
39
- ]), o = n.map(({ start: i, end: s }) => ({ start: i, end: s, tokens: [] }));
40
- function p(i, s) {
27
+ function P(t) {
28
+ return t.map(({ url: e, text: s, ranges: n }) => {
29
+ if (!s)
30
+ return { url: e, text: s, ranges: n };
31
+ let c = F(s), f = /* @__PURE__ */ new Set([
32
+ x.EOF,
33
+ x.BadString,
34
+ x.BadUrl,
35
+ x.WhiteSpace,
36
+ x.Semicolon,
37
+ x.Comment,
38
+ x.Colon
39
+ ]), o = n.map(({ start: a, end: i }) => ({ start: a, end: i, tokens: [] }));
40
+ function v(a, i) {
41
41
  let r = 0;
42
- for (let _ of o) {
43
- if (_.start > s) return -1;
44
- if (_.start <= i && _.end >= s)
42
+ for (let u of o) {
43
+ if (u.start > i) return -1;
44
+ if (u.start <= a && u.end >= i)
45
45
  return r;
46
46
  r++;
47
47
  }
48
48
  return -1;
49
49
  }
50
- let a = 0;
51
- N(l, (i, s, r) => {
52
- if (u.has(i)) return;
53
- a++, i === b.Url && (a += 2);
54
- let _ = p(s, r);
55
- _ !== -1 && o[_].tokens.push(a);
50
+ let _ = 0;
51
+ $(s, (a, i, r) => {
52
+ if (f.has(a)) return;
53
+ _++, a === x.Url && (_ += 2);
54
+ let u = v(i, r);
55
+ u !== -1 && o[u].tokens.push(_);
56
56
  });
57
- let c = /* @__PURE__ */ new Map();
58
- a = 0, N(d, (i, s, r) => {
59
- u.has(i) || (a++, i === b.Url && (a += 2), c.set(a, { start: s, end: r }));
57
+ let g = /* @__PURE__ */ new Map();
58
+ _ = 0, $(c, (a, i, r) => {
59
+ f.has(a) || (_++, a === x.Url && (_ += 2), g.set(_, { start: i, end: r }));
60
60
  });
61
- let g = [];
62
- for (let i of o) {
63
- let s = c.get(i.tokens.at(0)), r = c.get(i.tokens.at(-1));
64
- s !== void 0 && r !== void 0 && g.push({
65
- start: s.start,
61
+ let y = [];
62
+ for (let a of o) {
63
+ let i = g.get(a.tokens.at(0)), r = g.get(a.tokens.at(-1));
64
+ i !== void 0 && r !== void 0 && y.push({
65
+ start: i.start,
66
66
  end: r.end
67
67
  });
68
68
  }
69
- return { url: e, text: d, ranges: g };
69
+ return { url: e, text: c, ranges: y };
70
70
  });
71
71
  }
72
- function J(t) {
72
+ function R(t) {
73
73
  let e = /* @__PURE__ */ new Map();
74
- for (let l of t) {
75
- let n = l.text || "";
74
+ for (let s of t) {
75
+ let n = s.text || "";
76
76
  if (e.has(n)) {
77
- let u = e.get(n).ranges;
78
- for (let o of l.ranges) {
79
- let p = !1;
80
- for (let a of u)
81
- if (a.start === o.start && a.end === o.end) {
82
- p = !0;
77
+ let f = e.get(n).ranges;
78
+ for (let o of s.ranges) {
79
+ let v = !1;
80
+ for (let _ of f)
81
+ if (_.start === o.start && _.end === o.end) {
82
+ v = !0;
83
83
  break;
84
84
  }
85
- p || u.push(o);
85
+ v || f.push(o);
86
86
  }
87
87
  } else
88
88
  e.set(n, {
89
- url: l.url,
90
- ranges: l.ranges
89
+ url: s.url,
90
+ ranges: s.ranges
91
91
  });
92
92
  }
93
93
  return e;
94
94
  }
95
- function P(t) {
95
+ function D(t) {
96
96
  try {
97
97
  let e = new URL(t);
98
98
  return e.pathname.slice(e.pathname.lastIndexOf(".") + 1);
@@ -101,102 +101,123 @@ function P(t) {
101
101
  return t.slice(e, t.indexOf("/", e) + 1);
102
102
  }
103
103
  }
104
- function R(t, e, l) {
105
- let n = t(e), d = "", u = [], o = 0, p = n.querySelectorAll("style");
106
- for (let a of Array.from(p)) {
107
- let c = a.textContent;
108
- if (!c.trim()) continue;
109
- d += c;
110
- let g = e.indexOf(c), i = g + c.length;
111
- for (let s of l)
112
- s.start >= g && s.end <= i && u.push({
113
- start: o + (s.start - g),
114
- end: o + (s.end - g)
104
+ function G(t, e, s) {
105
+ let n = t(e), c = "", f = [], o = 0, v = n.querySelectorAll("style");
106
+ for (let _ of Array.from(v)) {
107
+ let g = _.textContent;
108
+ if (!g.trim()) continue;
109
+ c += g;
110
+ let y = e.indexOf(g), a = y + g.length;
111
+ for (let i of s)
112
+ i.start >= y && i.end <= a && f.push({
113
+ start: o + (i.start - y),
114
+ end: o + (i.end - y)
115
115
  });
116
- o += c.length;
116
+ o += g.length;
117
117
  }
118
118
  return {
119
- css: d,
120
- ranges: u
119
+ css: c,
120
+ ranges: f
121
121
  };
122
122
  }
123
- function D(t) {
123
+ function H(t) {
124
124
  return /<\/?(html|body|head|div|span|script|style)/i.test(t);
125
125
  }
126
- function G(t, e) {
127
- let l = [];
126
+ function K(t, e) {
127
+ let s = [];
128
128
  for (let n of t) {
129
129
  if (!n.text) continue;
130
- let d = P(n.url).toLowerCase();
131
- if (d !== "js") {
132
- if (d === "css") {
133
- l.push(n);
130
+ let c = D(n.url).toLowerCase();
131
+ if (c !== "js") {
132
+ if (c === "css") {
133
+ s.push(n);
134
134
  continue;
135
135
  }
136
- if (D(n.text)) {
136
+ if (H(n.text)) {
137
137
  if (!e)
138
138
  continue;
139
- let { css: u, ranges: o } = R(e, n.text, n.ranges);
140
- l.push({
139
+ let { css: f, ranges: o } = G(e, n.text, n.ranges);
140
+ s.push({
141
141
  url: n.url,
142
- text: u,
142
+ text: f,
143
143
  ranges: o
144
144
  });
145
145
  continue;
146
146
  }
147
- l.push({
147
+ s.push({
148
148
  url: n.url,
149
149
  text: n.text,
150
150
  ranges: n.ranges
151
151
  });
152
152
  }
153
153
  }
154
- return l;
154
+ return s;
155
155
  }
156
- function A(t, e) {
156
+ function j(t, e) {
157
157
  return e === 0 ? 0 : t / e;
158
158
  }
159
- function V(t, e) {
160
- let l = t.length;
161
- if (!T(t))
159
+ function Y(t, e) {
160
+ let s = t.length;
161
+ if (!q(t))
162
162
  throw new TypeError("No valid coverage data found");
163
- let n = G(t, e), d = F(n), u = J(d), o = Array.from(u).map(([r, { url: _, ranges: E }]) => {
164
- function I(f, y) {
165
- let m = y + f.length, L = m + 1, U = /^\s*$/.test(f), x = f.endsWith("}");
166
- if (!U && !x) {
167
- for (let h of E)
168
- if (!(h.start > m || h.end < y)) {
169
- if (h.start <= y && h.end >= m)
163
+ let n = K(t, e), c = P(n), f = R(c), o = Array.from(f).map(([r, { url: u, ranges: L }]) => {
164
+ function M(l, d) {
165
+ let b = d + l.length, N = b + 1, W = /^\s*$/.test(l), k = l.endsWith("}");
166
+ if (!W && !k) {
167
+ for (let m of L)
168
+ if (!(m.start > b || m.end < d)) {
169
+ if (m.start <= d && m.end >= b)
170
170
  return !0;
171
- if (f.startsWith("@") && h.start > y && h.start < L)
171
+ if (l.startsWith("@") && m.start > d && m.start < N)
172
172
  return !0;
173
173
  }
174
174
  }
175
175
  return !1;
176
176
  }
177
- let w = r.split(`
178
- `), S = w.length, W = new Uint8Array(S), O = 0, j = r.length, C = 0, B = 0;
179
- for (let f = 0; f < w.length; f++) {
180
- let y = w[f], m = B, U = B + y.length + 1, x = /^\s*$/.test(y), h = y.endsWith("}"), $ = I(y, m), k = !1, M = f > 0 && W[f - 1] === 1;
181
- ($ && !h && !x || (x || h) && M || x && !M && I(w[f + 1], U)) && (k = !0), W[f] = k ? 1 : 0, k && (O++, C += y.length + 1), B = U;
177
+ let S = r.split(`
178
+ `), O = S.length, p = new Uint8Array(O), C = 0, B = r.length, U = 0, E = 0;
179
+ for (let l = 0; l < S.length; l++) {
180
+ let d = S[l], b = E, W = E + d.length + 1, k = /^\s*$/.test(d), m = d.endsWith("}"), z = M(d, b), w = !1, T = l > 0 && p[l - 1] === 1;
181
+ (z && !m && !k || (k || m) && T || k && !T && M(S[l + 1], W)) && (w = !0), p[l] = w ? 1 : 0, w && (C++, U += d.length + 1), E = W;
182
+ }
183
+ let A = [
184
+ {
185
+ start_line: 1,
186
+ is_covered: p[0] === 1,
187
+ end_line: 1,
188
+ total_lines: 1
189
+ }
190
+ ];
191
+ for (let l = 1; l < p.length; l++) {
192
+ let d = p[l];
193
+ if (d !== p[l - 1]) {
194
+ let b = A.at(-1);
195
+ b.end_line = l, b.total_lines = l - b.start_line + 1, A.push({
196
+ start_line: l + 1,
197
+ is_covered: d === 1,
198
+ end_line: l,
199
+ total_lines: 0
200
+ });
201
+ }
182
202
  }
183
- return {
184
- url: _,
203
+ let I = A.at(-1);
204
+ return I.total_lines = p.length + 1 - I.start_line, I.end_line = p.length, {
205
+ url: u,
185
206
  text: r,
186
- ranges: E,
187
- unused_bytes: j - C,
188
- used_bytes: C,
189
- total_bytes: j,
190
- line_coverage_ratio: A(O, S),
191
- byte_coverage_ratio: A(C, j),
192
- line_coverage: W,
193
- total_lines: S,
194
- covered_lines: O,
195
- uncovered_lines: S - O
196
- // TODO: { is_covered: boolean, start_offset: number, start_line: number, end_offset: number, end_line: number }[]
207
+ ranges: L,
208
+ unused_bytes: B - U,
209
+ used_bytes: U,
210
+ total_bytes: B,
211
+ line_coverage_ratio: j(C, O),
212
+ byte_coverage_ratio: j(U, B),
213
+ line_coverage: p,
214
+ total_lines: O,
215
+ covered_lines: C,
216
+ uncovered_lines: O - C,
217
+ chunks: A
197
218
  };
198
- }), { total_lines: p, total_covered_lines: a, total_uncovered_lines: c, total_bytes: g, total_used_bytes: i, total_unused_bytes: s } = o.reduce(
199
- (r, _) => (r.total_lines += _.total_lines, r.total_covered_lines += _.covered_lines, r.total_uncovered_lines += _.uncovered_lines, r.total_bytes += _.total_bytes, r.total_used_bytes += _.used_bytes, r.total_unused_bytes += _.unused_bytes, r),
219
+ }), { total_lines: v, total_covered_lines: _, total_uncovered_lines: g, total_bytes: y, total_used_bytes: a, total_unused_bytes: i } = o.reduce(
220
+ (r, u) => (r.total_lines += u.total_lines, r.total_covered_lines += u.covered_lines, r.total_uncovered_lines += u.uncovered_lines, r.total_bytes += u.total_bytes, r.total_used_bytes += u.used_bytes, r.total_unused_bytes += u.unused_bytes, r),
200
221
  {
201
222
  total_lines: 0,
202
223
  total_covered_lines: 0,
@@ -207,20 +228,20 @@ function V(t, e) {
207
228
  }
208
229
  );
209
230
  return {
210
- total_files_found: l,
211
- total_bytes: g,
212
- total_lines: p,
213
- used_bytes: i,
214
- covered_lines: a,
215
- unused_bytes: s,
216
- uncovered_lines: c,
217
- byte_coverage_ratio: A(i, g),
218
- line_coverage_ratio: A(a, p),
231
+ total_files_found: s,
232
+ total_bytes: y,
233
+ total_lines: v,
234
+ used_bytes: a,
235
+ covered_lines: _,
236
+ unused_bytes: i,
237
+ uncovered_lines: g,
238
+ byte_coverage_ratio: j(a, y),
239
+ line_coverage_ratio: j(_, v),
219
240
  coverage_per_stylesheet: o,
220
241
  total_stylesheets: o.length
221
242
  };
222
243
  }
223
244
  export {
224
- V as calculate_coverage,
225
- Q as parse_coverage
245
+ Y as calculate_coverage,
246
+ X as parse_coverage
226
247
  };
@@ -15,6 +15,12 @@ export type StylesheetCoverage = CoverageData & {
15
15
  text: string;
16
16
  ranges: Range[];
17
17
  line_coverage: Uint8Array;
18
+ chunks: {
19
+ is_covered: boolean;
20
+ start_line: number;
21
+ end_line: number;
22
+ total_lines: number;
23
+ }[];
18
24
  };
19
25
  export type CoverageResult = CoverageData & {
20
26
  total_files_found: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@projectwallace/css-code-coverage",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "",
5
5
  "author": "Bart Veneman <bart@projectwallace.com>",
6
6
  "repository": {