@hrforte/react-pivottable 2.1.2 → 2.2.1
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.
- package/README.md +18 -4
- package/dist/PivotDataWorker.js +11 -16
- package/dist/PivotDataWorker.js.map +1 -1
- package/dist/PivotTableUI.js +63 -74
- package/dist/PivotTableUI.js.map +1 -1
- package/dist/PlotlyRenderers.js +9 -5
- package/dist/PlotlyRenderers.js.map +1 -1
- package/dist/TableRenderers.js +35 -2
- package/dist/TableRenderers.js.map +1 -1
- package/dist/Utilities.js +2 -20
- package/dist/Utilities.js.map +1 -1
- package/dist/__tests__/PivotDataWorker-test.js +7 -8
- package/dist/__tests__/PivotDataWorker-test.js.map +1 -1
- package/dist/__tests__/PivotTableUI-processing-test.js +108 -13
- package/dist/__tests__/PivotTableUI-processing-test.js.map +1 -1
- package/dist/__tests__/TableRenderers-showNumericalOrder-test.js +178 -0
- package/dist/__tests__/TableRenderers-showNumericalOrder-test.js.map +1 -0
- package/dist/__tests__/pivotCompute-test.js +7 -7
- package/dist/__tests__/pivotCompute-test.js.map +1 -1
- package/dist/pivot-worker.js +8 -60
- package/dist/pivotCompute.js +5 -22
- package/dist/pivotCompute.js.map +1 -1
- package/dist/pivotWorker.js +2 -18
- package/dist/pivotWorker.js.map +1 -1
- package/dist/pivottable.css +3 -20
- package/package.json +1 -1
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
4
|
+
|
|
3
5
|
var _react = require('react');
|
|
4
6
|
|
|
5
7
|
var _react2 = _interopRequireDefault(_react);
|
|
@@ -10,14 +12,18 @@ var _PivotTableUI = require('../PivotTableUI');
|
|
|
10
12
|
|
|
11
13
|
var _PivotTableUI2 = _interopRequireDefault(_PivotTableUI);
|
|
12
14
|
|
|
15
|
+
var _pivotCompute = require('../pivotCompute');
|
|
16
|
+
|
|
13
17
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
14
18
|
|
|
19
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
20
|
+
|
|
15
21
|
/* eslint-disable no-magic-numbers */
|
|
16
22
|
|
|
17
23
|
// React 19 needs to be told that this environment supports `act`.
|
|
18
24
|
global.IS_REACT_ACT_ENVIRONMENT = true;
|
|
19
25
|
|
|
20
|
-
// `
|
|
26
|
+
// `showProcessing` is a debugging/testing hook that forces the loading
|
|
21
27
|
// overlay on top of the rendered table without running a real worker
|
|
22
28
|
// computation, so the overlay can be inspected while consuming the package.
|
|
23
29
|
var records = [{ name: 'Nick', gender: 'male', colour: 'blue', trials: 103 }, { name: 'Jane', gender: 'female', colour: 'red', trials: 95 }, { name: 'John', gender: 'male', colour: 'blue', trials: 112 }, { name: 'Carol', gender: 'female', colour: 'yellow', trials: 102 }];
|
|
@@ -37,7 +43,7 @@ function rerenderPivot(root, props) {
|
|
|
37
43
|
});
|
|
38
44
|
}
|
|
39
45
|
|
|
40
|
-
describe(' PivotTableUI
|
|
46
|
+
describe(' PivotTableUI showProcessing', function () {
|
|
41
47
|
var containers = void 0;
|
|
42
48
|
|
|
43
49
|
beforeEach(function () {
|
|
@@ -73,7 +79,7 @@ describe(' PivotTableUI isShowProcessing', function () {
|
|
|
73
79
|
expect(node.querySelector('.pvtTable')).not.toBeNull();
|
|
74
80
|
});
|
|
75
81
|
|
|
76
|
-
it('renders the overlay on top of the table when
|
|
82
|
+
it('renders the overlay on top of the table when showProcessing is true', function () {
|
|
77
83
|
var _mount2 = mount(baseProps),
|
|
78
84
|
node = _mount2.node,
|
|
79
85
|
root = _mount2.root;
|
|
@@ -83,32 +89,121 @@ describe(' PivotTableUI isShowProcessing', function () {
|
|
|
83
89
|
expect(node.querySelector('.pvtTable')).not.toBeNull();
|
|
84
90
|
expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();
|
|
85
91
|
|
|
86
|
-
rerenderPivot(root, Object.assign({}, baseProps, {
|
|
92
|
+
rerenderPivot(root, Object.assign({}, baseProps, { showProcessing: true }));
|
|
87
93
|
|
|
88
94
|
var overlay = node.querySelector('.pvtLoadingOverlay');
|
|
89
95
|
expect(overlay).not.toBeNull();
|
|
90
96
|
// The overlay is layered on top of the table: the table must survive.
|
|
91
97
|
expect(node.querySelector('.pvtTable')).not.toBeNull();
|
|
92
|
-
//
|
|
93
|
-
//
|
|
98
|
+
// Only a spinner and a label: progress percentages were removed, the
|
|
99
|
+
// overlay simply stays until the worker posts its result event.
|
|
94
100
|
expect(overlay.querySelector('.pvtLoadingSpinner')).not.toBeNull();
|
|
95
|
-
expect(overlay.querySelector('.
|
|
96
|
-
expect(overlay.querySelector('.
|
|
101
|
+
expect(overlay.querySelector('.pvtLoadingText').textContent).toBe('Processing…');
|
|
102
|
+
expect(overlay.querySelector('.pvtLoadingBar')).toBeNull();
|
|
103
|
+
expect(overlay.querySelector('.pvtLoadingPercent')).toBeNull();
|
|
97
104
|
|
|
98
105
|
// Turning the flag back off removes the overlay.
|
|
99
106
|
rerenderPivot(root, baseProps);
|
|
100
107
|
expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();
|
|
101
108
|
});
|
|
102
109
|
|
|
103
|
-
it('renders
|
|
110
|
+
it('renders a spinner without any percentage markup', function () {
|
|
104
111
|
var node = document.createElement('div');
|
|
105
112
|
(0, _react.act)(function () {
|
|
106
|
-
(0, _client.createRoot)(node).render(_react2.default.createElement(_PivotTableUI.PivotLoadingOverlay,
|
|
107
|
-
progress: { phase: 'aggregate' }
|
|
108
|
-
}));
|
|
113
|
+
(0, _client.createRoot)(node).render(_react2.default.createElement(_PivotTableUI.PivotLoadingOverlay, null));
|
|
109
114
|
});
|
|
115
|
+
expect(node.querySelector('.pvtLoadingOverlay')).not.toBeNull();
|
|
116
|
+
expect(node.querySelector('.pvtLoadingSpinner')).not.toBeNull();
|
|
110
117
|
expect(node.querySelector('.pvtLoadingBarWrap')).toBeNull();
|
|
111
|
-
expect(node.querySelector('.
|
|
118
|
+
expect(node.querySelector('.pvtLoadingPercent')).toBeNull();
|
|
119
|
+
expect(node.querySelector('.pvtLoadingText').textContent).toBe('Processing…');
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('hides the overlay only after the worker responds and the table renders', function () {
|
|
123
|
+
var wait = function wait(ms) {
|
|
124
|
+
return new Promise(function (resolve) {
|
|
125
|
+
return setTimeout(resolve, ms);
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
// React's act() returns a non-standard thenable whose .then() does not
|
|
129
|
+
// return a promise, so it cannot be chained directly - wrap it first.
|
|
130
|
+
var actAsync = function actAsync(callback) {
|
|
131
|
+
return new Promise(function (resolve, reject) {
|
|
132
|
+
return (0, _react.act)(callback).then(resolve, reject);
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
var workerInstances = [];
|
|
136
|
+
|
|
137
|
+
var FakeWorker = function () {
|
|
138
|
+
function FakeWorker(url) {
|
|
139
|
+
_classCallCheck(this, FakeWorker);
|
|
140
|
+
|
|
141
|
+
this.url = url;
|
|
142
|
+
this.posted = [];
|
|
143
|
+
this.onmessage = null;
|
|
144
|
+
workerInstances.push(this);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
_createClass(FakeWorker, [{
|
|
148
|
+
key: 'postMessage',
|
|
149
|
+
value: function postMessage(message) {
|
|
150
|
+
this.posted.push(message);
|
|
151
|
+
}
|
|
152
|
+
}, {
|
|
153
|
+
key: 'terminate',
|
|
154
|
+
value: function terminate() {}
|
|
155
|
+
}]);
|
|
156
|
+
|
|
157
|
+
return FakeWorker;
|
|
158
|
+
}();
|
|
159
|
+
|
|
160
|
+
var previousWorker = global.Worker;
|
|
161
|
+
global.Worker = FakeWorker;
|
|
162
|
+
|
|
163
|
+
// workerThreshold: 2 makes this small dataset worker-eligible.
|
|
164
|
+
var props = Object.assign({}, baseProps, { workerThreshold: 2 });
|
|
165
|
+
|
|
166
|
+
var _mount3 = mount(props),
|
|
167
|
+
node = _mount3.node;
|
|
168
|
+
|
|
169
|
+
var restore = function restore() {
|
|
170
|
+
global.Worker = previousWorker;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
// The overlay is up while the computation is pending.
|
|
174
|
+
expect(node.querySelector('.pvtLoadingOverlay')).not.toBeNull();
|
|
175
|
+
|
|
176
|
+
// Wait out the dispatch debounce so the request reaches the worker.
|
|
177
|
+
return actAsync(function () {
|
|
178
|
+
return wait(80);
|
|
179
|
+
}).then(function () {
|
|
180
|
+
var worker = workerInstances[0];
|
|
181
|
+
expect(worker).toBeDefined();
|
|
182
|
+
var computeMsg = worker.posted.find(function (m) {
|
|
183
|
+
return m.type === 'pivot:compute';
|
|
184
|
+
});
|
|
185
|
+
expect(computeMsg).toBeDefined();
|
|
186
|
+
// The worker has not answered yet: the overlay must stay up.
|
|
187
|
+
expect(node.querySelector('.pvtLoadingOverlay')).not.toBeNull();
|
|
188
|
+
|
|
189
|
+
// Worker finishes and posts its result event.
|
|
190
|
+
var result = (0, _pivotCompute.computePivotState)((0, _pivotCompute.materializeData)(records, {}), (0, _pivotCompute.createWorkerConfig)(props));
|
|
191
|
+
return actAsync(function () {
|
|
192
|
+
worker.onmessage({
|
|
193
|
+
data: { type: 'pivot:result', id: computeMsg.id, result: result }
|
|
194
|
+
});
|
|
195
|
+
return wait(0);
|
|
196
|
+
});
|
|
197
|
+
}).then(function () {
|
|
198
|
+
// The overlay is gone only now - and the freshly computed table is
|
|
199
|
+
// already on screen in the same state where the overlay disappeared.
|
|
200
|
+
expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();
|
|
201
|
+
expect(node.querySelector('.pvtTable')).not.toBeNull();
|
|
202
|
+
restore();
|
|
203
|
+
}).catch(function (error) {
|
|
204
|
+
restore();
|
|
205
|
+
throw error;
|
|
206
|
+
});
|
|
112
207
|
});
|
|
113
208
|
});
|
|
114
209
|
//# sourceMappingURL=PivotTableUI-processing-test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/__tests__/PivotTableUI-processing-test.js"],"names":["global","IS_REACT_ACT_ENVIRONMENT","records","name","gender","colour","trials","baseProps","data","rows","cols","aggregatorName","vals","rendererName","rerenderPivot","root","props","render","React","createElement","PivotTableUI","describe","containers","beforeEach","afterEach","forEach","container","unmount","node","remove","mount","document","body","appendChild","entry","push","it","expect","querySelector","toBeNull","not","Object","assign","isShowProcessing","overlay","style","width","toBe","textContent","PivotLoadingOverlay","progress","phase"],"mappings":"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","file":"PivotTableUI-processing-test.js","sourcesContent":["import React, {act} from 'react';\nimport {createRoot} from 'react-dom/client';\nimport PivotTableUI, {PivotLoadingOverlay} from '../PivotTableUI';\n/* eslint-disable no-magic-numbers */\n\n// React 19 needs to be told that this environment supports `act`.\nglobal.IS_REACT_ACT_ENVIRONMENT = true;\n\n// `isShowProcessing` is a debugging/testing hook that forces the loading\n// overlay on top of the rendered table without running a real worker\n// computation, so the overlay can be inspected while consuming the package.\nconst records = [\n {name: 'Nick', gender: 'male', colour: 'blue', trials: 103},\n {name: 'Jane', gender: 'female', colour: 'red', trials: 95},\n {name: 'John', gender: 'male', colour: 'blue', trials: 112},\n {name: 'Carol', gender: 'female', colour: 'yellow', trials: 102},\n];\n\nconst baseProps = {\n data: records,\n rows: ['name'],\n cols: [],\n aggregatorName: 'Count',\n vals: [],\n rendererName: 'Table',\n};\n\nfunction rerenderPivot(root, props) {\n act(() => {\n root.render(React.createElement(PivotTableUI, props));\n });\n}\n\ndescribe(' PivotTableUI isShowProcessing', function() {\n let containers;\n\n beforeEach(function() {\n containers = [];\n });\n\n afterEach(function() {\n containers.forEach(container => {\n act(() => {\n container.root.unmount();\n });\n container.node.remove();\n });\n });\n\n const mount = props => {\n const node = document.createElement('div');\n document.body.appendChild(node);\n const root = createRoot(node);\n act(() => {\n root.render(React.createElement(PivotTableUI, props));\n });\n const entry = {node, root};\n containers.push(entry);\n return entry;\n };\n\n it('does not render the overlay by default', function() {\n const {node} = mount(baseProps);\n expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();\n expect(node.querySelector('.pvtTable')).not.toBeNull();\n });\n\n it('renders the overlay on top of the table when isShowProcessing is true', function() {\n const {node, root} = mount(baseProps);\n // Table is rendered from the real data first (no overlay).\n expect(node.querySelector('.pvtTable')).not.toBeNull();\n expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();\n\n rerenderPivot(root, Object.assign({}, baseProps, {isShowProcessing: true}));\n\n const overlay = node.querySelector('.pvtLoadingOverlay');\n expect(overlay).not.toBeNull();\n // The overlay is layered on top of the table: the table must survive.\n expect(node.querySelector('.pvtTable')).not.toBeNull();\n // Nothing was actually being computed, so a sample progress is supplied\n // to exercise the progress bar/percentage branch of the overlay.\n expect(overlay.querySelector('.pvtLoadingSpinner')).not.toBeNull();\n expect(overlay.querySelector('.pvtLoadingBar').style.width).toBe('60%');\n expect(overlay.querySelector('.pvtLoadingPercent').textContent).toBe('60%');\n\n // Turning the flag back off removes the overlay.\n rerenderPivot(root, baseProps);\n expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();\n });\n\n it('renders an indeterminate overlay when progress.total is unavailable', function() {\n const node = document.createElement('div');\n act(() => {\n createRoot(node).render(\n React.createElement(PivotLoadingOverlay, {\n progress: {phase: 'aggregate'},\n })\n );\n });\n expect(node.querySelector('.pvtLoadingBarWrap')).toBeNull();\n expect(node.querySelector('.pvtLoadingText').textContent).toBe(\n 'Aggregating data…'\n );\n });\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/__tests__/PivotTableUI-processing-test.js"],"names":["global","IS_REACT_ACT_ENVIRONMENT","records","name","gender","colour","trials","baseProps","data","rows","cols","aggregatorName","vals","rendererName","rerenderPivot","root","props","render","React","createElement","PivotTableUI","describe","containers","beforeEach","afterEach","forEach","container","unmount","node","remove","mount","document","body","appendChild","entry","push","it","expect","querySelector","toBeNull","not","Object","assign","showProcessing","overlay","textContent","toBe","PivotLoadingOverlay","wait","Promise","setTimeout","resolve","ms","actAsync","reject","callback","then","workerInstances","FakeWorker","url","posted","onmessage","message","previousWorker","Worker","workerThreshold","restore","worker","toBeDefined","computeMsg","find","m","type","result","id","catch","error"],"mappings":"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","file":"PivotTableUI-processing-test.js","sourcesContent":["import React, {act} from 'react';\nimport {createRoot} from 'react-dom/client';\nimport PivotTableUI, {PivotLoadingOverlay} from '../PivotTableUI';\nimport {\n computePivotState,\n createWorkerConfig,\n materializeData,\n} from '../pivotCompute';\n/* eslint-disable no-magic-numbers */\n\n// React 19 needs to be told that this environment supports `act`.\nglobal.IS_REACT_ACT_ENVIRONMENT = true;\n\n// `showProcessing` is a debugging/testing hook that forces the loading\n// overlay on top of the rendered table without running a real worker\n// computation, so the overlay can be inspected while consuming the package.\nconst records = [\n {name: 'Nick', gender: 'male', colour: 'blue', trials: 103},\n {name: 'Jane', gender: 'female', colour: 'red', trials: 95},\n {name: 'John', gender: 'male', colour: 'blue', trials: 112},\n {name: 'Carol', gender: 'female', colour: 'yellow', trials: 102},\n];\n\nconst baseProps = {\n data: records,\n rows: ['name'],\n cols: [],\n aggregatorName: 'Count',\n vals: [],\n rendererName: 'Table',\n};\n\nfunction rerenderPivot(root, props) {\n act(() => {\n root.render(React.createElement(PivotTableUI, props));\n });\n}\n\ndescribe(' PivotTableUI showProcessing', function() {\n let containers;\n\n beforeEach(function() {\n containers = [];\n });\n\n afterEach(function() {\n containers.forEach(container => {\n act(() => {\n container.root.unmount();\n });\n container.node.remove();\n });\n });\n\n const mount = props => {\n const node = document.createElement('div');\n document.body.appendChild(node);\n const root = createRoot(node);\n act(() => {\n root.render(React.createElement(PivotTableUI, props));\n });\n const entry = {node, root};\n containers.push(entry);\n return entry;\n };\n\n it('does not render the overlay by default', function() {\n const {node} = mount(baseProps);\n expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();\n expect(node.querySelector('.pvtTable')).not.toBeNull();\n });\n\n it('renders the overlay on top of the table when showProcessing is true', function() {\n const {node, root} = mount(baseProps);\n // Table is rendered from the real data first (no overlay).\n expect(node.querySelector('.pvtTable')).not.toBeNull();\n expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();\n\n rerenderPivot(root, Object.assign({}, baseProps, {showProcessing: true}));\n\n const overlay = node.querySelector('.pvtLoadingOverlay');\n expect(overlay).not.toBeNull();\n // The overlay is layered on top of the table: the table must survive.\n expect(node.querySelector('.pvtTable')).not.toBeNull();\n // Only a spinner and a label: progress percentages were removed, the\n // overlay simply stays until the worker posts its result event.\n expect(overlay.querySelector('.pvtLoadingSpinner')).not.toBeNull();\n expect(overlay.querySelector('.pvtLoadingText').textContent).toBe(\n 'Processing…'\n );\n expect(overlay.querySelector('.pvtLoadingBar')).toBeNull();\n expect(overlay.querySelector('.pvtLoadingPercent')).toBeNull();\n\n // Turning the flag back off removes the overlay.\n rerenderPivot(root, baseProps);\n expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();\n });\n\n it('renders a spinner without any percentage markup', function() {\n const node = document.createElement('div');\n act(() => {\n createRoot(node).render(\n React.createElement(PivotLoadingOverlay, null)\n );\n });\n expect(node.querySelector('.pvtLoadingOverlay')).not.toBeNull();\n expect(node.querySelector('.pvtLoadingSpinner')).not.toBeNull();\n expect(node.querySelector('.pvtLoadingBarWrap')).toBeNull();\n expect(node.querySelector('.pvtLoadingPercent')).toBeNull();\n expect(node.querySelector('.pvtLoadingText').textContent).toBe(\n 'Processing…'\n );\n });\n\n it('hides the overlay only after the worker responds and the table renders', function() {\n const wait = ms => new Promise(resolve => setTimeout(resolve, ms));\n // React's act() returns a non-standard thenable whose .then() does not\n // return a promise, so it cannot be chained directly - wrap it first.\n const actAsync = callback =>\n new Promise((resolve, reject) => act(callback).then(resolve, reject));\n const workerInstances = [];\n class FakeWorker {\n constructor(url) {\n this.url = url;\n this.posted = [];\n this.onmessage = null;\n workerInstances.push(this);\n }\n\n postMessage(message) {\n this.posted.push(message);\n }\n\n terminate() {}\n }\n\n const previousWorker = global.Worker;\n global.Worker = FakeWorker;\n\n // workerThreshold: 2 makes this small dataset worker-eligible.\n const props = Object.assign({}, baseProps, {workerThreshold: 2});\n const {node} = mount(props);\n\n const restore = () => {\n global.Worker = previousWorker;\n };\n\n // The overlay is up while the computation is pending.\n expect(node.querySelector('.pvtLoadingOverlay')).not.toBeNull();\n\n // Wait out the dispatch debounce so the request reaches the worker.\n return actAsync(() => wait(80))\n .then(() => {\n const worker = workerInstances[0];\n expect(worker).toBeDefined();\n const computeMsg = worker.posted.find(m => m.type === 'pivot:compute');\n expect(computeMsg).toBeDefined();\n // The worker has not answered yet: the overlay must stay up.\n expect(node.querySelector('.pvtLoadingOverlay')).not.toBeNull();\n\n // Worker finishes and posts its result event.\n const result = computePivotState(\n materializeData(records, {}),\n createWorkerConfig(props)\n );\n return actAsync(() => {\n worker.onmessage({\n data: {type: 'pivot:result', id: computeMsg.id, result},\n });\n return wait(0);\n });\n })\n .then(() => {\n // The overlay is gone only now - and the freshly computed table is\n // already on screen in the same state where the overlay disappeared.\n expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();\n expect(node.querySelector('.pvtTable')).not.toBeNull();\n restore();\n })\n .catch(error => {\n restore();\n throw error;\n });\n });\n});\n"]}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var _react = require('react');
|
|
4
|
+
|
|
5
|
+
var _react2 = _interopRequireDefault(_react);
|
|
6
|
+
|
|
7
|
+
var _client = require('react-dom/client');
|
|
8
|
+
|
|
9
|
+
var _PivotTable = require('../PivotTable');
|
|
10
|
+
|
|
11
|
+
var _PivotTable2 = _interopRequireDefault(_PivotTable);
|
|
12
|
+
|
|
13
|
+
var _PivotTableUI = require('../PivotTableUI');
|
|
14
|
+
|
|
15
|
+
var _PivotTableUI2 = _interopRequireDefault(_PivotTableUI);
|
|
16
|
+
|
|
17
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
18
|
+
|
|
19
|
+
/* eslint-disable no-magic-numbers */
|
|
20
|
+
|
|
21
|
+
// React 19 needs to be told that this environment supports `act`.
|
|
22
|
+
global.IS_REACT_ACT_ENVIRONMENT = true;
|
|
23
|
+
|
|
24
|
+
// `showNumericalOrder` adds a "No." column in front of the row attributes so
|
|
25
|
+
// every data row is prefixed with its 1-based index.
|
|
26
|
+
var records = [{ name: 'Nick', gender: 'male', colour: 'blue', trials: 103 }, { name: 'Jane', gender: 'female', colour: 'red', trials: 95 }, { name: 'John', gender: 'male', colour: 'blue', trials: 112 }, { name: 'Carol', gender: 'female', colour: 'yellow', trials: 102 }];
|
|
27
|
+
|
|
28
|
+
var baseProps = {
|
|
29
|
+
data: records,
|
|
30
|
+
rows: ['name'],
|
|
31
|
+
cols: [],
|
|
32
|
+
aggregatorName: 'Count',
|
|
33
|
+
vals: [],
|
|
34
|
+
rendererName: 'Table'
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
var mount = function mount(element) {
|
|
38
|
+
var node = document.createElement('div');
|
|
39
|
+
document.body.appendChild(node);
|
|
40
|
+
var root = (0, _client.createRoot)(node);
|
|
41
|
+
(0, _react.act)(function () {
|
|
42
|
+
root.render(element);
|
|
43
|
+
});
|
|
44
|
+
return { node: node, root: root };
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
var unmount = function unmount(_ref) {
|
|
48
|
+
var node = _ref.node,
|
|
49
|
+
root = _ref.root;
|
|
50
|
+
|
|
51
|
+
(0, _react.act)(function () {
|
|
52
|
+
root.unmount();
|
|
53
|
+
});
|
|
54
|
+
node.remove();
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// Both helpers are scoped to `.pvtTable`: PivotTableUI wraps the pivot table
|
|
58
|
+
// in its own `.pvtUi` layout table, so an unscoped `tbody ...` selector would
|
|
59
|
+
// also match header cells through that outer table.
|
|
60
|
+
var numberTexts = function numberTexts(node, selector) {
|
|
61
|
+
return Array.from(node.querySelectorAll('.pvtTable ' + selector)).map(function (cell) {
|
|
62
|
+
return cell.textContent.trim();
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
var numberHeaders = function numberHeaders(node) {
|
|
67
|
+
return numberTexts(node, 'thead .pvtRowNumber');
|
|
68
|
+
};
|
|
69
|
+
var numberCells = function numberCells(node) {
|
|
70
|
+
return numberTexts(node, 'tbody .pvtRowNumber');
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
describe('Table renderer showNumericalOrder', function () {
|
|
74
|
+
var mounted = void 0;
|
|
75
|
+
|
|
76
|
+
afterEach(function () {
|
|
77
|
+
if (mounted) {
|
|
78
|
+
unmount(mounted);
|
|
79
|
+
mounted = null;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('renders no "No." column by default', function () {
|
|
84
|
+
mounted = mount(_react2.default.createElement(_PivotTable2.default, baseProps));
|
|
85
|
+
expect(mounted.node.querySelector('.pvtRowNumber')).toBeNull();
|
|
86
|
+
expect(mounted.node.querySelector('.pvtTable').textContent).not.toContain('No.');
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('renders no "No." column when showNumericalOrder is false', function () {
|
|
90
|
+
mounted = mount(_react2.default.createElement(_PivotTable2.default, Object.assign({}, baseProps, { showNumericalOrder: false })));
|
|
91
|
+
expect(mounted.node.querySelector('.pvtRowNumber')).toBeNull();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('numbers every data row from 1 with a "No." header', function () {
|
|
95
|
+
mounted = mount(_react2.default.createElement(_PivotTable2.default, Object.assign({}, baseProps, { showNumericalOrder: true })));
|
|
96
|
+
|
|
97
|
+
var headers = numberHeaders(mounted.node);
|
|
98
|
+
expect(headers).toEqual(['No.']);
|
|
99
|
+
|
|
100
|
+
var cells = numberCells(mounted.node);
|
|
101
|
+
expect(cells).toEqual(['1', '2', '3', '4']);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('keeps the "No." column in front of the row attribute column', function () {
|
|
105
|
+
mounted = mount(_react2.default.createElement(_PivotTable2.default, Object.assign({}, baseProps, { showNumericalOrder: true })));
|
|
106
|
+
|
|
107
|
+
var headerCells = Array.from(mounted.node.querySelectorAll('.pvtTable thead tr:last-child th'));
|
|
108
|
+
expect(headerCells[0].classList.contains('pvtRowNumber')).toBe(true);
|
|
109
|
+
expect(headerCells[1].textContent).toContain('name');
|
|
110
|
+
|
|
111
|
+
var firstBodyRow = mounted.node.querySelector('.pvtTable tbody tr');
|
|
112
|
+
var bodyCells = Array.from(firstBodyRow.querySelectorAll('th,td'));
|
|
113
|
+
expect(bodyCells[0].classList.contains('pvtRowNumber')).toBe(true);
|
|
114
|
+
expect(bodyCells[1].classList.contains('pvtRowLabel')).toBe(true);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('extends the totals label over the "No." column', function () {
|
|
118
|
+
mounted = mount(_react2.default.createElement(_PivotTable2.default, Object.assign({}, baseProps, { showNumericalOrder: true })));
|
|
119
|
+
|
|
120
|
+
var totalLabel = mounted.node.querySelector('.pvtTable tbody .pvtTotalLabel');
|
|
121
|
+
expect(totalLabel.getAttribute('colspan')).toBe('2');
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('spans the "No." header across the column-attribute header rows', function () {
|
|
125
|
+
mounted = mount(_react2.default.createElement(_PivotTable2.default, Object.assign({}, baseProps, {
|
|
126
|
+
cols: ['gender'],
|
|
127
|
+
showNumericalOrder: true
|
|
128
|
+
})));
|
|
129
|
+
|
|
130
|
+
var header = mounted.node.querySelector('.pvtTable thead .pvtRowNumber');
|
|
131
|
+
expect(header.textContent.trim()).toBe('No.');
|
|
132
|
+
expect(header.getAttribute('rowspan')).toBe('2');
|
|
133
|
+
|
|
134
|
+
expect(numberCells(mounted.node)).toEqual(['1', '2', '3', '4']);
|
|
135
|
+
|
|
136
|
+
// Totals now covers "No." + the row attribute + the column axis column.
|
|
137
|
+
var totalLabel = mounted.node.querySelector('.pvtTable tbody .pvtTotalLabel');
|
|
138
|
+
expect(totalLabel.getAttribute('colspan')).toBe('3');
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('spans the "No." header across row group header rows', function () {
|
|
142
|
+
mounted = mount(_react2.default.createElement(_PivotTable2.default, Object.assign({}, baseProps, {
|
|
143
|
+
rows: ['name', 'gender'],
|
|
144
|
+
rowGroupConfig: [{ label: 'GRP', match: ['name'] }],
|
|
145
|
+
showNumericalOrder: true
|
|
146
|
+
})));
|
|
147
|
+
|
|
148
|
+
var header = mounted.node.querySelector('.pvtTable thead .pvtRowNumber');
|
|
149
|
+
expect(header.getAttribute('rowspan')).toBe('2');
|
|
150
|
+
expect(numberCells(mounted.node)).toEqual(['1', '2', '3', '4']);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('passes showNumericalOrder through PivotTableUI', function () {
|
|
154
|
+
// PivotTableUI computes asynchronously (worker / deferred main thread
|
|
155
|
+
// computation, WORKER_DEBOUNCE_MS = 100ms), so the numbered rows only show
|
|
156
|
+
// up after those timers ran.
|
|
157
|
+
var wait = function wait(ms) {
|
|
158
|
+
return new Promise(function (resolve) {
|
|
159
|
+
return setTimeout(resolve, ms);
|
|
160
|
+
});
|
|
161
|
+
};
|
|
162
|
+
var actAsync = function actAsync(callback) {
|
|
163
|
+
return new Promise(function (resolve, reject) {
|
|
164
|
+
return (0, _react.act)(callback).then(resolve, reject);
|
|
165
|
+
});
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
mounted = mount(_react2.default.createElement(_PivotTableUI2.default, Object.assign({}, baseProps, { showNumericalOrder: true })));
|
|
169
|
+
|
|
170
|
+
return actAsync(function () {
|
|
171
|
+
return wait(300);
|
|
172
|
+
}).then(function () {
|
|
173
|
+
expect(mounted.node.querySelector('.pvtTable thead .pvtRowNumber').textContent).toBe('No.');
|
|
174
|
+
expect(numberCells(mounted.node)).toEqual(['1', '2', '3', '4']);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
//# sourceMappingURL=TableRenderers-showNumericalOrder-test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/__tests__/TableRenderers-showNumericalOrder-test.js"],"names":["global","IS_REACT_ACT_ENVIRONMENT","records","name","gender","colour","trials","baseProps","data","rows","cols","aggregatorName","vals","rendererName","mount","node","document","createElement","body","appendChild","root","render","element","unmount","remove","numberTexts","selector","Array","from","querySelectorAll","map","cell","textContent","trim","numberHeaders","numberCells","describe","mounted","afterEach","it","React","PivotTable","expect","querySelector","toBeNull","not","toContain","Object","assign","showNumericalOrder","headers","toEqual","cells","headerCells","classList","contains","toBe","firstBodyRow","bodyCells","totalLabel","getAttribute","header","rowGroupConfig","label","match","wait","Promise","setTimeout","resolve","ms","actAsync","reject","callback","then","PivotTableUI"],"mappings":"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","file":"TableRenderers-showNumericalOrder-test.js","sourcesContent":["import React, {act} from 'react';\nimport {createRoot} from 'react-dom/client';\nimport PivotTable from '../PivotTable';\nimport PivotTableUI from '../PivotTableUI';\n\n/* eslint-disable no-magic-numbers */\n\n// React 19 needs to be told that this environment supports `act`.\nglobal.IS_REACT_ACT_ENVIRONMENT = true;\n\n// `showNumericalOrder` adds a \"No.\" column in front of the row attributes so\n// every data row is prefixed with its 1-based index.\nconst records = [\n {name: 'Nick', gender: 'male', colour: 'blue', trials: 103},\n {name: 'Jane', gender: 'female', colour: 'red', trials: 95},\n {name: 'John', gender: 'male', colour: 'blue', trials: 112},\n {name: 'Carol', gender: 'female', colour: 'yellow', trials: 102},\n];\n\nconst baseProps = {\n data: records,\n rows: ['name'],\n cols: [],\n aggregatorName: 'Count',\n vals: [],\n rendererName: 'Table',\n};\n\nconst mount = element => {\n const node = document.createElement('div');\n document.body.appendChild(node);\n const root = createRoot(node);\n act(() => {\n root.render(element);\n });\n return {node, root};\n};\n\nconst unmount = ({node, root}) => {\n act(() => {\n root.unmount();\n });\n node.remove();\n};\n\n// Both helpers are scoped to `.pvtTable`: PivotTableUI wraps the pivot table\n// in its own `.pvtUi` layout table, so an unscoped `tbody ...` selector would\n// also match header cells through that outer table.\nconst numberTexts = (node, selector) =>\n Array.from(node.querySelectorAll(`.pvtTable ${selector}`)).map(cell =>\n cell.textContent.trim()\n );\n\nconst numberHeaders = node => numberTexts(node, 'thead .pvtRowNumber');\nconst numberCells = node => numberTexts(node, 'tbody .pvtRowNumber');\n\ndescribe('Table renderer showNumericalOrder', function() {\n let mounted;\n\n afterEach(function() {\n if (mounted) {\n unmount(mounted);\n mounted = null;\n }\n });\n\n it('renders no \"No.\" column by default', function() {\n mounted = mount(React.createElement(PivotTable, baseProps));\n expect(mounted.node.querySelector('.pvtRowNumber')).toBeNull();\n expect(mounted.node.querySelector('.pvtTable').textContent).not.toContain(\n 'No.'\n );\n });\n\n it('renders no \"No.\" column when showNumericalOrder is false', function() {\n mounted = mount(\n React.createElement(\n PivotTable,\n Object.assign({}, baseProps, {showNumericalOrder: false})\n )\n );\n expect(mounted.node.querySelector('.pvtRowNumber')).toBeNull();\n });\n\n it('numbers every data row from 1 with a \"No.\" header', function() {\n mounted = mount(\n React.createElement(\n PivotTable,\n Object.assign({}, baseProps, {showNumericalOrder: true})\n )\n );\n\n const headers = numberHeaders(mounted.node);\n expect(headers).toEqual(['No.']);\n\n const cells = numberCells(mounted.node);\n expect(cells).toEqual(['1', '2', '3', '4']);\n });\n\n it('keeps the \"No.\" column in front of the row attribute column', function() {\n mounted = mount(\n React.createElement(\n PivotTable,\n Object.assign({}, baseProps, {showNumericalOrder: true})\n )\n );\n\n const headerCells = Array.from(\n mounted.node.querySelectorAll('.pvtTable thead tr:last-child th')\n );\n expect(headerCells[0].classList.contains('pvtRowNumber')).toBe(true);\n expect(headerCells[1].textContent).toContain('name');\n\n const firstBodyRow = mounted.node.querySelector('.pvtTable tbody tr');\n const bodyCells = Array.from(firstBodyRow.querySelectorAll('th,td'));\n expect(bodyCells[0].classList.contains('pvtRowNumber')).toBe(true);\n expect(bodyCells[1].classList.contains('pvtRowLabel')).toBe(true);\n });\n\n it('extends the totals label over the \"No.\" column', function() {\n mounted = mount(\n React.createElement(\n PivotTable,\n Object.assign({}, baseProps, {showNumericalOrder: true})\n )\n );\n\n const totalLabel = mounted.node.querySelector(\n '.pvtTable tbody .pvtTotalLabel'\n );\n expect(totalLabel.getAttribute('colspan')).toBe('2');\n });\n\n it('spans the \"No.\" header across the column-attribute header rows', function() {\n mounted = mount(\n React.createElement(\n PivotTable,\n Object.assign({}, baseProps, {\n cols: ['gender'],\n showNumericalOrder: true,\n })\n )\n );\n\n const header = mounted.node.querySelector('.pvtTable thead .pvtRowNumber');\n expect(header.textContent.trim()).toBe('No.');\n expect(header.getAttribute('rowspan')).toBe('2');\n\n expect(numberCells(mounted.node)).toEqual(['1', '2', '3', '4']);\n\n // Totals now covers \"No.\" + the row attribute + the column axis column.\n const totalLabel = mounted.node.querySelector(\n '.pvtTable tbody .pvtTotalLabel'\n );\n expect(totalLabel.getAttribute('colspan')).toBe('3');\n });\n\n it('spans the \"No.\" header across row group header rows', function() {\n mounted = mount(\n React.createElement(\n PivotTable,\n Object.assign({}, baseProps, {\n rows: ['name', 'gender'],\n rowGroupConfig: [{label: 'GRP', match: ['name']}],\n showNumericalOrder: true,\n })\n )\n );\n\n const header = mounted.node.querySelector('.pvtTable thead .pvtRowNumber');\n expect(header.getAttribute('rowspan')).toBe('2');\n expect(numberCells(mounted.node)).toEqual(['1', '2', '3', '4']);\n });\n\n it('passes showNumericalOrder through PivotTableUI', function() {\n // PivotTableUI computes asynchronously (worker / deferred main thread\n // computation, WORKER_DEBOUNCE_MS = 100ms), so the numbered rows only show\n // up after those timers ran.\n const wait = ms => new Promise(resolve => setTimeout(resolve, ms));\n const actAsync = callback =>\n new Promise((resolve, reject) => act(callback).then(resolve, reject));\n\n mounted = mount(\n React.createElement(\n PivotTableUI,\n Object.assign({}, baseProps, {showNumericalOrder: true})\n )\n );\n\n return actAsync(() => wait(300)).then(() => {\n expect(\n mounted.node.querySelector('.pvtTable thead .pvtRowNumber').textContent\n ).toBe('No.');\n expect(numberCells(mounted.node)).toEqual(['1', '2', '3', '4']);\n });\n });\n});\n"]}
|
|
@@ -29,13 +29,13 @@ describe(' pivotCompute', function () {
|
|
|
29
29
|
expect(materialized.attrValues.gender).toEqual({ male: 2, female: 2 });
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
-
it('reports progress
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
expect(
|
|
32
|
+
it('reports no progress (percentages were removed)', function () {
|
|
33
|
+
// materializeData no longer accepts an onProgress callback: passing
|
|
34
|
+
// one is ignored and nothing is reported during the scan.
|
|
35
|
+
var maybeCallback = jest.fn();
|
|
36
|
+
var materialized = pivotCompute.materializeData(records, {}, maybeCallback);
|
|
37
|
+
expect(materialized.totalRecords).toBe(4);
|
|
38
|
+
expect(maybeCallback).not.toHaveBeenCalled();
|
|
39
39
|
});
|
|
40
40
|
});
|
|
41
41
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/__tests__/pivotCompute-test.js"],"names":["pivotCompute","records","name","gender","colour","trials","successes","multiAggregationConfig","key","aggregatorName","vals","describe","it","materialized","materializeData","expect","totalRecords","toBe","materializedInput","toEqual","attrValues","male","female","progressCalls","processed","total","phase","push","config","rows","cols","aggregations","serialized","computePivotState","direct","PivotData","Object","assign","data","hydrated","precomputedData","getRowKeys","getColKeys","compareCells","rowKey","colKey","forEach","getAggregator","agg","value","directFormat","format","hydratedFormat","filteredConfig","valueFilter","reverseSorter","a","b","sorters","keys","map","indexOf","toBeLessThan","props","first","createComputeSignature","second","different","not","localeCompare","signature","toContain","eligibleProps","aggregators","defaultProps","derivedAttributes","beforeAll","global","Worker","FakeWorker","canComputeInWorker","threshold","Count","extra","record","enabled"],"mappings":"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","file":"pivotCompute-test.js","sourcesContent":["import * as pivotCompute from '../pivotCompute';\nimport {PivotData} from '../Utilities';\n/* eslint-disable no-magic-numbers */\n\nconst records = [\n {name: 'Nick', gender: 'male', colour: 'blue', trials: 103, successes: 12},\n {name: 'Jane', gender: 'female', colour: 'red', trials: 95, successes: 25},\n {name: 'John', gender: 'male', colour: 'blue', trials: 112, successes: 30},\n {\n name: 'Carol',\n gender: 'female',\n colour: 'yellow',\n trials: 102,\n successes: 14,\n },\n];\n\nconst multiAggregationConfig = [\n {key: 'sum-trials', aggregatorName: 'Sum', vals: ['trials']},\n {key: 'count', aggregatorName: 'Count', vals: []},\n];\n\ndescribe(' pivotCompute', function() {\n describe('.materializeData()', function() {\n it('collects attribute values and materialized records', function() {\n const materialized = pivotCompute.materializeData(records, {});\n expect(materialized.totalRecords).toBe(4);\n expect(materialized.materializedInput).toEqual(records);\n expect(materialized.attrValues.gender).toEqual({male: 2, female: 2});\n });\n\n it('reports progress only in batches', function() {\n const progressCalls = [];\n pivotCompute.materializeData(records, {}, (processed, total, phase) => {\n progressCalls.push([processed, total, phase]);\n });\n // No batch boundary is crossed with only 4 records.\n expect(progressCalls).toEqual([]);\n });\n });\n\n describe('.computePivotState() with PivotData hydration', function() {\n const config = {\n rows: ['gender'],\n cols: ['colour'],\n aggregations: multiAggregationConfig,\n };\n\n it('hydrates to the same results as a direct PivotData build', function() {\n const materialized = pivotCompute.materializeData(records, {});\n const serialized = pivotCompute.computePivotState(materialized, config);\n const direct = new PivotData(Object.assign({}, config, {data: records}));\n const hydrated = new PivotData({\n data: materialized.materializedInput,\n precomputedData: serialized,\n aggregations: multiAggregationConfig,\n rows: ['gender'],\n cols: ['colour'],\n });\n\n expect(hydrated.getRowKeys()).toEqual(direct.getRowKeys());\n expect(hydrated.getColKeys()).toEqual(direct.getColKeys());\n\n const compareCells = (rowKey, colKey) => {\n multiAggregationConfig.forEach(agg => {\n expect(hydrated.getAggregator(rowKey, colKey, agg.key).value()).toBe(\n direct.getAggregator(rowKey, colKey, agg.key).value()\n );\n });\n };\n\n compareCells([], []);\n direct.getRowKeys().forEach(rowKey => {\n compareCells(rowKey, []);\n direct.getColKeys().forEach(colKey => {\n compareCells(rowKey, colKey);\n });\n });\n direct.getColKeys().forEach(colKey => {\n compareCells([], colKey);\n });\n });\n\n it('provides working format() on hydrated aggregators', function() {\n const materialized = pivotCompute.materializeData(records, {});\n const serialized = pivotCompute.computePivotState(materialized, config);\n const direct = new PivotData(Object.assign({}, config, {data: records}));\n const hydrated = new PivotData({\n data: materialized.materializedInput,\n precomputedData: serialized,\n aggregations: multiAggregationConfig,\n rows: ['gender'],\n cols: ['colour'],\n });\n\n const directFormat = direct\n .getAggregator([], [], 'sum-trials')\n .format(1234.5);\n const hydratedFormat = hydrated\n .getAggregator([], [], 'sum-trials')\n .format(1234.5);\n expect(hydratedFormat).toBe(directFormat);\n });\n\n it('respects valueFilter like the classic path', function() {\n const filteredConfig = Object.assign({}, config, {\n valueFilter: {gender: {male: true}},\n });\n const materialized = pivotCompute.materializeData(records, {});\n const serialized = pivotCompute.computePivotState(\n materialized,\n filteredConfig\n );\n const direct = new PivotData(\n Object.assign({}, filteredConfig, {data: records})\n );\n const hydrated = new PivotData({\n data: materialized.materializedInput,\n precomputedData: serialized,\n aggregations: multiAggregationConfig,\n rows: ['gender'],\n cols: ['colour'],\n valueFilter: {gender: {male: true}},\n });\n expect(hydrated.getRowKeys()).toEqual(direct.getRowKeys());\n expect(hydrated.getAggregator([], [], 'count').value()).toBe(\n direct.getAggregator([], [], 'count').value()\n );\n });\n\n it('re-sorts keys on the main thread for function sorters', function() {\n const materialized = pivotCompute.materializeData(records, {});\n const serialized = pivotCompute.computePivotState(materialized, config);\n const reverseSorter = (a, b) => (a < b ? 1 : a > b ? -1 : 0);\n const hydrated = new PivotData({\n data: materialized.materializedInput,\n precomputedData: serialized,\n aggregations: multiAggregationConfig,\n rows: ['gender'],\n cols: ['colour'],\n sorters: {gender: reverseSorter},\n });\n const keys = hydrated.getRowKeys().map(key => key[0]);\n expect(keys.indexOf('male')).toBeLessThan(keys.indexOf('female'));\n });\n });\n\n describe('.createComputeSignature()', function() {\n it('is stable for identical configs and differs otherwise', function() {\n const props = {\n rows: ['gender'],\n cols: [],\n aggregations: multiAggregationConfig,\n valueFilter: {},\n sorters: {},\n };\n const first = pivotCompute.createComputeSignature(props);\n const second = pivotCompute.createComputeSignature(\n Object.assign({}, props)\n );\n expect(first).toBe(second);\n const different = pivotCompute.createComputeSignature(\n Object.assign({}, props, {rows: ['colour']})\n );\n expect(different).not.toBe(first);\n });\n\n it('strips function-based sorters from the signature', function() {\n const props = {\n rows: ['gender'],\n sorters: {gender: (a, b) => a.localeCompare(b)},\n };\n const signature = pivotCompute.createComputeSignature(props);\n expect(signature).not.toContain('localeCompare');\n });\n });\n\n describe('.canComputeInWorker()', function() {\n const eligibleProps = {\n data: records,\n aggregators: PivotData.defaultProps.aggregators,\n derivedAttributes: {},\n };\n\n beforeAll(function() {\n // jsdom has no Worker implementation; simulate availability.\n global.Worker = function FakeWorker() {};\n });\n\n it('accepts plain-array datasets above the threshold', function() {\n expect(\n pivotCompute.canComputeInWorker(eligibleProps, {threshold: 2})\n ).toBe(true);\n });\n\n it('rejects datasets below the threshold', function() {\n expect(\n pivotCompute.canComputeInWorker(eligibleProps, {threshold: 1000})\n ).toBe(false);\n });\n\n it('rejects custom aggregator maps', function() {\n const props = Object.assign({}, eligibleProps, {\n aggregators: {Count: () => () => ({})},\n });\n expect(pivotCompute.canComputeInWorker(props, {threshold: 2})).toBe(\n false\n );\n });\n\n it('rejects custom derived attributes', function() {\n const props = Object.assign({}, eligibleProps, {\n derivedAttributes: {extra: record => record.name},\n });\n expect(pivotCompute.canComputeInWorker(props, {threshold: 2})).toBe(\n false\n );\n });\n\n it('rejects disabled mode', function() {\n expect(\n pivotCompute.canComputeInWorker(eligibleProps, {\n enabled: false,\n threshold: 2,\n })\n ).toBe(false);\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/__tests__/pivotCompute-test.js"],"names":["pivotCompute","records","name","gender","colour","trials","successes","multiAggregationConfig","key","aggregatorName","vals","describe","it","materialized","materializeData","expect","totalRecords","toBe","materializedInput","toEqual","attrValues","male","female","maybeCallback","jest","fn","not","toHaveBeenCalled","config","rows","cols","aggregations","serialized","computePivotState","direct","PivotData","Object","assign","data","hydrated","precomputedData","getRowKeys","getColKeys","compareCells","rowKey","colKey","forEach","getAggregator","agg","value","directFormat","format","hydratedFormat","filteredConfig","valueFilter","reverseSorter","a","b","sorters","keys","map","indexOf","toBeLessThan","props","first","createComputeSignature","second","different","localeCompare","signature","toContain","eligibleProps","aggregators","defaultProps","derivedAttributes","beforeAll","global","Worker","FakeWorker","canComputeInWorker","threshold","Count","extra","record","enabled"],"mappings":"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","file":"pivotCompute-test.js","sourcesContent":["import * as pivotCompute from '../pivotCompute';\nimport {PivotData} from '../Utilities';\n/* eslint-disable no-magic-numbers */\n\nconst records = [\n {name: 'Nick', gender: 'male', colour: 'blue', trials: 103, successes: 12},\n {name: 'Jane', gender: 'female', colour: 'red', trials: 95, successes: 25},\n {name: 'John', gender: 'male', colour: 'blue', trials: 112, successes: 30},\n {\n name: 'Carol',\n gender: 'female',\n colour: 'yellow',\n trials: 102,\n successes: 14,\n },\n];\n\nconst multiAggregationConfig = [\n {key: 'sum-trials', aggregatorName: 'Sum', vals: ['trials']},\n {key: 'count', aggregatorName: 'Count', vals: []},\n];\n\ndescribe(' pivotCompute', function() {\n describe('.materializeData()', function() {\n it('collects attribute values and materialized records', function() {\n const materialized = pivotCompute.materializeData(records, {});\n expect(materialized.totalRecords).toBe(4);\n expect(materialized.materializedInput).toEqual(records);\n expect(materialized.attrValues.gender).toEqual({male: 2, female: 2});\n });\n\n it('reports no progress (percentages were removed)', function() {\n // materializeData no longer accepts an onProgress callback: passing\n // one is ignored and nothing is reported during the scan.\n const maybeCallback = jest.fn();\n const materialized = pivotCompute.materializeData(\n records,\n {},\n maybeCallback\n );\n expect(materialized.totalRecords).toBe(4);\n expect(maybeCallback).not.toHaveBeenCalled();\n });\n });\n\n describe('.computePivotState() with PivotData hydration', function() {\n const config = {\n rows: ['gender'],\n cols: ['colour'],\n aggregations: multiAggregationConfig,\n };\n\n it('hydrates to the same results as a direct PivotData build', function() {\n const materialized = pivotCompute.materializeData(records, {});\n const serialized = pivotCompute.computePivotState(materialized, config);\n const direct = new PivotData(Object.assign({}, config, {data: records}));\n const hydrated = new PivotData({\n data: materialized.materializedInput,\n precomputedData: serialized,\n aggregations: multiAggregationConfig,\n rows: ['gender'],\n cols: ['colour'],\n });\n\n expect(hydrated.getRowKeys()).toEqual(direct.getRowKeys());\n expect(hydrated.getColKeys()).toEqual(direct.getColKeys());\n\n const compareCells = (rowKey, colKey) => {\n multiAggregationConfig.forEach(agg => {\n expect(hydrated.getAggregator(rowKey, colKey, agg.key).value()).toBe(\n direct.getAggregator(rowKey, colKey, agg.key).value()\n );\n });\n };\n\n compareCells([], []);\n direct.getRowKeys().forEach(rowKey => {\n compareCells(rowKey, []);\n direct.getColKeys().forEach(colKey => {\n compareCells(rowKey, colKey);\n });\n });\n direct.getColKeys().forEach(colKey => {\n compareCells([], colKey);\n });\n });\n\n it('provides working format() on hydrated aggregators', function() {\n const materialized = pivotCompute.materializeData(records, {});\n const serialized = pivotCompute.computePivotState(materialized, config);\n const direct = new PivotData(Object.assign({}, config, {data: records}));\n const hydrated = new PivotData({\n data: materialized.materializedInput,\n precomputedData: serialized,\n aggregations: multiAggregationConfig,\n rows: ['gender'],\n cols: ['colour'],\n });\n\n const directFormat = direct\n .getAggregator([], [], 'sum-trials')\n .format(1234.5);\n const hydratedFormat = hydrated\n .getAggregator([], [], 'sum-trials')\n .format(1234.5);\n expect(hydratedFormat).toBe(directFormat);\n });\n\n it('respects valueFilter like the classic path', function() {\n const filteredConfig = Object.assign({}, config, {\n valueFilter: {gender: {male: true}},\n });\n const materialized = pivotCompute.materializeData(records, {});\n const serialized = pivotCompute.computePivotState(\n materialized,\n filteredConfig\n );\n const direct = new PivotData(\n Object.assign({}, filteredConfig, {data: records})\n );\n const hydrated = new PivotData({\n data: materialized.materializedInput,\n precomputedData: serialized,\n aggregations: multiAggregationConfig,\n rows: ['gender'],\n cols: ['colour'],\n valueFilter: {gender: {male: true}},\n });\n expect(hydrated.getRowKeys()).toEqual(direct.getRowKeys());\n expect(hydrated.getAggregator([], [], 'count').value()).toBe(\n direct.getAggregator([], [], 'count').value()\n );\n });\n\n it('re-sorts keys on the main thread for function sorters', function() {\n const materialized = pivotCompute.materializeData(records, {});\n const serialized = pivotCompute.computePivotState(materialized, config);\n const reverseSorter = (a, b) => (a < b ? 1 : a > b ? -1 : 0);\n const hydrated = new PivotData({\n data: materialized.materializedInput,\n precomputedData: serialized,\n aggregations: multiAggregationConfig,\n rows: ['gender'],\n cols: ['colour'],\n sorters: {gender: reverseSorter},\n });\n const keys = hydrated.getRowKeys().map(key => key[0]);\n expect(keys.indexOf('male')).toBeLessThan(keys.indexOf('female'));\n });\n });\n\n describe('.createComputeSignature()', function() {\n it('is stable for identical configs and differs otherwise', function() {\n const props = {\n rows: ['gender'],\n cols: [],\n aggregations: multiAggregationConfig,\n valueFilter: {},\n sorters: {},\n };\n const first = pivotCompute.createComputeSignature(props);\n const second = pivotCompute.createComputeSignature(\n Object.assign({}, props)\n );\n expect(first).toBe(second);\n const different = pivotCompute.createComputeSignature(\n Object.assign({}, props, {rows: ['colour']})\n );\n expect(different).not.toBe(first);\n });\n\n it('strips function-based sorters from the signature', function() {\n const props = {\n rows: ['gender'],\n sorters: {gender: (a, b) => a.localeCompare(b)},\n };\n const signature = pivotCompute.createComputeSignature(props);\n expect(signature).not.toContain('localeCompare');\n });\n });\n\n describe('.canComputeInWorker()', function() {\n const eligibleProps = {\n data: records,\n aggregators: PivotData.defaultProps.aggregators,\n derivedAttributes: {},\n };\n\n beforeAll(function() {\n // jsdom has no Worker implementation; simulate availability.\n global.Worker = function FakeWorker() {};\n });\n\n it('accepts plain-array datasets above the threshold', function() {\n expect(\n pivotCompute.canComputeInWorker(eligibleProps, {threshold: 2})\n ).toBe(true);\n });\n\n it('rejects datasets below the threshold', function() {\n expect(\n pivotCompute.canComputeInWorker(eligibleProps, {threshold: 1000})\n ).toBe(false);\n });\n\n it('rejects custom aggregator maps', function() {\n const props = Object.assign({}, eligibleProps, {\n aggregators: {Count: () => () => ({})},\n });\n expect(pivotCompute.canComputeInWorker(props, {threshold: 2})).toBe(\n false\n );\n });\n\n it('rejects custom derived attributes', function() {\n const props = Object.assign({}, eligibleProps, {\n derivedAttributes: {extra: record => record.name},\n });\n expect(pivotCompute.canComputeInWorker(props, {threshold: 2})).toBe(\n false\n );\n });\n\n it('rejects disabled mode', function() {\n expect(\n pivotCompute.canComputeInWorker(eligibleProps, {\n enabled: false,\n threshold: 2,\n })\n ).toBe(false);\n });\n });\n});\n"]}
|