blob: 0eff2821b010e3e41ec4fffe9b7b9e3b2b2d959a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
/**
* Serialize an object
* @param {Object} obj
* @return {string}
*/
function serialize(obj) {
if (obj instanceof Text) return '#text';
if (obj instanceof Element) return `<${obj.localName}>${obj.textContent}`;
if (obj === document) return 'document';
if (typeof obj == 'string') return obj;
return Object.prototype.toString.call(obj).replace(/(^\[object |\]$)/g, '');
}
/** @type {string[]} */
let log = [];
/**
* Modify obj's original method to log calls and arguments on logger object
* @template T
* @param {T} obj
* @param {keyof T} method
*/
export function logCall(obj, method) {
let old = obj[method];
obj[method] = function(...args) {
let c = '';
for (let i = 0; i < args.length; i++) {
if (c) c += ', ';
c += serialize(args[i]);
}
// Normalize removeChild -> remove to keep output clean and readable
const operation =
method != 'removeChild'
? `${serialize(this)}.${method}(${c})`
: `${serialize(c)}.remove()`;
log.push(operation);
return old.apply(this, args);
};
return () => (obj[method] = old);
}
/**
* Return log object
* @return {string[]} log
*/
export function getLog() {
return log;
}
/** Clear log object */
export function clearLog() {
log = [];
}
export function getLogSummary() {
/** @type {{ [key: string]: number }} */
const summary = {};
for (let entry of log) {
summary[entry] = (summary[entry] || 0) + 1;
}
return summary;
}
|