@hrforte/react-pivottable 1.1.0 → 2.1.0

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.
@@ -0,0 +1,114 @@
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 _PivotTableUI = require('../PivotTableUI');
10
+
11
+ var _PivotTableUI2 = _interopRequireDefault(_PivotTableUI);
12
+
13
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
+
15
+ /* eslint-disable no-magic-numbers */
16
+
17
+ // React 19 needs to be told that this environment supports `act`.
18
+ global.IS_REACT_ACT_ENVIRONMENT = true;
19
+
20
+ // `isShowProcessing` is a debugging/testing hook that forces the loading
21
+ // overlay on top of the rendered table without running a real worker
22
+ // computation, so the overlay can be inspected while consuming the package.
23
+ 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 }];
24
+
25
+ var baseProps = {
26
+ data: records,
27
+ rows: ['name'],
28
+ cols: [],
29
+ aggregatorName: 'Count',
30
+ vals: [],
31
+ rendererName: 'Table'
32
+ };
33
+
34
+ function rerenderPivot(root, props) {
35
+ (0, _react.act)(function () {
36
+ root.render(_react2.default.createElement(_PivotTableUI2.default, props));
37
+ });
38
+ }
39
+
40
+ describe(' PivotTableUI isShowProcessing', function () {
41
+ var containers = void 0;
42
+
43
+ beforeEach(function () {
44
+ containers = [];
45
+ });
46
+
47
+ afterEach(function () {
48
+ containers.forEach(function (container) {
49
+ (0, _react.act)(function () {
50
+ container.root.unmount();
51
+ });
52
+ container.node.remove();
53
+ });
54
+ });
55
+
56
+ var mount = function mount(props) {
57
+ var node = document.createElement('div');
58
+ document.body.appendChild(node);
59
+ var root = (0, _client.createRoot)(node);
60
+ (0, _react.act)(function () {
61
+ root.render(_react2.default.createElement(_PivotTableUI2.default, props));
62
+ });
63
+ var entry = { node: node, root: root };
64
+ containers.push(entry);
65
+ return entry;
66
+ };
67
+
68
+ it('does not render the overlay by default', function () {
69
+ var _mount = mount(baseProps),
70
+ node = _mount.node;
71
+
72
+ expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();
73
+ expect(node.querySelector('.pvtTable')).not.toBeNull();
74
+ });
75
+
76
+ it('renders the overlay on top of the table when isShowProcessing is true', function () {
77
+ var _mount2 = mount(baseProps),
78
+ node = _mount2.node,
79
+ root = _mount2.root;
80
+ // Table is rendered from the real data first (no overlay).
81
+
82
+
83
+ expect(node.querySelector('.pvtTable')).not.toBeNull();
84
+ expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();
85
+
86
+ rerenderPivot(root, Object.assign({}, baseProps, { isShowProcessing: true }));
87
+
88
+ var overlay = node.querySelector('.pvtLoadingOverlay');
89
+ expect(overlay).not.toBeNull();
90
+ // The overlay is layered on top of the table: the table must survive.
91
+ expect(node.querySelector('.pvtTable')).not.toBeNull();
92
+ // Nothing was actually being computed, so a sample progress is supplied
93
+ // to exercise the progress bar/percentage branch of the overlay.
94
+ expect(overlay.querySelector('.pvtLoadingSpinner')).not.toBeNull();
95
+ expect(overlay.querySelector('.pvtLoadingBar').style.width).toBe('60%');
96
+ expect(overlay.querySelector('.pvtLoadingPercent').textContent).toBe('60%');
97
+
98
+ // Turning the flag back off removes the overlay.
99
+ rerenderPivot(root, baseProps);
100
+ expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();
101
+ });
102
+
103
+ it('renders an indeterminate overlay when progress.total is unavailable', function () {
104
+ var node = document.createElement('div');
105
+ (0, _react.act)(function () {
106
+ (0, _client.createRoot)(node).render(_react2.default.createElement(_PivotTableUI.PivotLoadingOverlay, {
107
+ progress: { phase: 'aggregate' }
108
+ }));
109
+ });
110
+ expect(node.querySelector('.pvtLoadingBarWrap')).toBeNull();
111
+ expect(node.querySelector('.pvtLoadingText').textContent).toBe('Aggregating data…');
112
+ });
113
+ });
114
+ //# sourceMappingURL=PivotTableUI-processing-test.js.map
@@ -0,0 +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":";;AAAA;;;;AACA;;AACA;;;;;;AACA;;AAEA;AACAA,OAAOC,wBAAP,GAAkC,IAAlC;;AAEA;AACA;AACA;AACA,IAAMC,UAAU,CACd,EAACC,MAAM,MAAP,EAAeC,QAAQ,MAAvB,EAA+BC,QAAQ,MAAvC,EAA+CC,QAAQ,GAAvD,EADc,EAEd,EAACH,MAAM,MAAP,EAAeC,QAAQ,QAAvB,EAAiCC,QAAQ,KAAzC,EAAgDC,QAAQ,EAAxD,EAFc,EAGd,EAACH,MAAM,MAAP,EAAeC,QAAQ,MAAvB,EAA+BC,QAAQ,MAAvC,EAA+CC,QAAQ,GAAvD,EAHc,EAId,EAACH,MAAM,OAAP,EAAgBC,QAAQ,QAAxB,EAAkCC,QAAQ,QAA1C,EAAoDC,QAAQ,GAA5D,EAJc,CAAhB;;AAOA,IAAMC,YAAY;AAChBC,QAAMN,OADU;AAEhBO,QAAM,CAAC,MAAD,CAFU;AAGhBC,QAAM,EAHU;AAIhBC,kBAAgB,OAJA;AAKhBC,QAAM,EALU;AAMhBC,gBAAc;AANE,CAAlB;;AASA,SAASC,aAAT,CAAuBC,IAAvB,EAA6BC,KAA7B,EAAoC;AAClC,kBAAI,YAAM;AACRD,SAAKE,MAAL,CAAYC,gBAAMC,aAAN,CAAoBC,sBAApB,EAAkCJ,KAAlC,CAAZ;AACD,GAFD;AAGD;;AAEDK,SAAS,iCAAT,EAA4C,YAAW;AACrD,MAAIC,mBAAJ;;AAEAC,aAAW,YAAW;AACpBD,iBAAa,EAAb;AACD,GAFD;;AAIAE,YAAU,YAAW;AACnBF,eAAWG,OAAX,CAAmB,qBAAa;AAC9B,sBAAI,YAAM;AACRC,kBAAUX,IAAV,CAAeY,OAAf;AACD,OAFD;AAGAD,gBAAUE,IAAV,CAAeC,MAAf;AACD,KALD;AAMD,GAPD;;AASA,MAAMC,QAAQ,SAARA,KAAQ,QAAS;AACrB,QAAMF,OAAOG,SAASZ,aAAT,CAAuB,KAAvB,CAAb;AACAY,aAASC,IAAT,CAAcC,WAAd,CAA0BL,IAA1B;AACA,QAAMb,OAAO,wBAAWa,IAAX,CAAb;AACA,oBAAI,YAAM;AACRb,WAAKE,MAAL,CAAYC,gBAAMC,aAAN,CAAoBC,sBAApB,EAAkCJ,KAAlC,CAAZ;AACD,KAFD;AAGA,QAAMkB,QAAQ,EAACN,UAAD,EAAOb,UAAP,EAAd;AACAO,eAAWa,IAAX,CAAgBD,KAAhB;AACA,WAAOA,KAAP;AACD,GAVD;;AAYAE,KAAG,wCAAH,EAA6C,YAAW;AAAA,iBACvCN,MAAMvB,SAAN,CADuC;AAAA,QAC/CqB,IAD+C,UAC/CA,IAD+C;;AAEtDS,WAAOT,KAAKU,aAAL,CAAmB,oBAAnB,CAAP,EAAiDC,QAAjD;AACAF,WAAOT,KAAKU,aAAL,CAAmB,WAAnB,CAAP,EAAwCE,GAAxC,CAA4CD,QAA5C;AACD,GAJD;;AAMAH,KAAG,uEAAH,EAA4E,YAAW;AAAA,kBAChEN,MAAMvB,SAAN,CADgE;AAAA,QAC9EqB,IAD8E,WAC9EA,IAD8E;AAAA,QACxEb,IADwE,WACxEA,IADwE;AAErF;;;AACAsB,WAAOT,KAAKU,aAAL,CAAmB,WAAnB,CAAP,EAAwCE,GAAxC,CAA4CD,QAA5C;AACAF,WAAOT,KAAKU,aAAL,CAAmB,oBAAnB,CAAP,EAAiDC,QAAjD;;AAEAzB,kBAAcC,IAAd,EAAoB0B,OAAOC,MAAP,CAAc,EAAd,EAAkBnC,SAAlB,EAA6B,EAACoC,kBAAkB,IAAnB,EAA7B,CAApB;;AAEA,QAAMC,UAAUhB,KAAKU,aAAL,CAAmB,oBAAnB,CAAhB;AACAD,WAAOO,OAAP,EAAgBJ,GAAhB,CAAoBD,QAApB;AACA;AACAF,WAAOT,KAAKU,aAAL,CAAmB,WAAnB,CAAP,EAAwCE,GAAxC,CAA4CD,QAA5C;AACA;AACA;AACAF,WAAOO,QAAQN,aAAR,CAAsB,oBAAtB,CAAP,EAAoDE,GAApD,CAAwDD,QAAxD;AACAF,WAAOO,QAAQN,aAAR,CAAsB,gBAAtB,EAAwCO,KAAxC,CAA8CC,KAArD,EAA4DC,IAA5D,CAAiE,KAAjE;AACAV,WAAOO,QAAQN,aAAR,CAAsB,oBAAtB,EAA4CU,WAAnD,EAAgED,IAAhE,CAAqE,KAArE;;AAEA;AACAjC,kBAAcC,IAAd,EAAoBR,SAApB;AACA8B,WAAOT,KAAKU,aAAL,CAAmB,oBAAnB,CAAP,EAAiDC,QAAjD;AACD,GArBD;;AAuBAH,KAAG,qEAAH,EAA0E,YAAW;AACnF,QAAMR,OAAOG,SAASZ,aAAT,CAAuB,KAAvB,CAAb;AACA,oBAAI,YAAM;AACR,8BAAWS,IAAX,EAAiBX,MAAjB,CACEC,gBAAMC,aAAN,CAAoB8B,iCAApB,EAAyC;AACvCC,kBAAU,EAACC,OAAO,WAAR;AAD6B,OAAzC,CADF;AAKD,KAND;AAOAd,WAAOT,KAAKU,aAAL,CAAmB,oBAAnB,CAAP,EAAiDC,QAAjD;AACAF,WAAOT,KAAKU,aAAL,CAAmB,iBAAnB,EAAsCU,WAA7C,EAA0DD,IAA1D,CACE,mBADF;AAGD,GAbD;AAcD,CAvED","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"]}
@@ -0,0 +1,215 @@
1
+ 'use strict';
2
+
3
+ var _pivotCompute = require('../pivotCompute');
4
+
5
+ var pivotCompute = _interopRequireWildcard(_pivotCompute);
6
+
7
+ var _Utilities = require('../Utilities');
8
+
9
+ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
10
+
11
+ /* eslint-disable no-magic-numbers */
12
+
13
+ var records = [{ name: 'Nick', gender: 'male', colour: 'blue', trials: 103, successes: 12 }, { name: 'Jane', gender: 'female', colour: 'red', trials: 95, successes: 25 }, { name: 'John', gender: 'male', colour: 'blue', trials: 112, successes: 30 }, {
14
+ name: 'Carol',
15
+ gender: 'female',
16
+ colour: 'yellow',
17
+ trials: 102,
18
+ successes: 14
19
+ }];
20
+
21
+ var multiAggregationConfig = [{ key: 'sum-trials', aggregatorName: 'Sum', vals: ['trials'] }, { key: 'count', aggregatorName: 'Count', vals: [] }];
22
+
23
+ describe(' pivotCompute', function () {
24
+ describe('.materializeData()', function () {
25
+ it('collects attribute values and materialized records', function () {
26
+ var materialized = pivotCompute.materializeData(records, {});
27
+ expect(materialized.totalRecords).toBe(4);
28
+ expect(materialized.materializedInput).toEqual(records);
29
+ expect(materialized.attrValues.gender).toEqual({ male: 2, female: 2 });
30
+ });
31
+
32
+ it('reports progress only in batches', function () {
33
+ var progressCalls = [];
34
+ pivotCompute.materializeData(records, {}, function (processed, total, phase) {
35
+ progressCalls.push([processed, total, phase]);
36
+ });
37
+ // No batch boundary is crossed with only 4 records.
38
+ expect(progressCalls).toEqual([]);
39
+ });
40
+ });
41
+
42
+ describe('.computePivotState() with PivotData hydration', function () {
43
+ var config = {
44
+ rows: ['gender'],
45
+ cols: ['colour'],
46
+ aggregations: multiAggregationConfig
47
+ };
48
+
49
+ it('hydrates to the same results as a direct PivotData build', function () {
50
+ var materialized = pivotCompute.materializeData(records, {});
51
+ var serialized = pivotCompute.computePivotState(materialized, config);
52
+ var direct = new _Utilities.PivotData(Object.assign({}, config, { data: records }));
53
+ var hydrated = new _Utilities.PivotData({
54
+ data: materialized.materializedInput,
55
+ precomputedData: serialized,
56
+ aggregations: multiAggregationConfig,
57
+ rows: ['gender'],
58
+ cols: ['colour']
59
+ });
60
+
61
+ expect(hydrated.getRowKeys()).toEqual(direct.getRowKeys());
62
+ expect(hydrated.getColKeys()).toEqual(direct.getColKeys());
63
+
64
+ var compareCells = function compareCells(rowKey, colKey) {
65
+ multiAggregationConfig.forEach(function (agg) {
66
+ expect(hydrated.getAggregator(rowKey, colKey, agg.key).value()).toBe(direct.getAggregator(rowKey, colKey, agg.key).value());
67
+ });
68
+ };
69
+
70
+ compareCells([], []);
71
+ direct.getRowKeys().forEach(function (rowKey) {
72
+ compareCells(rowKey, []);
73
+ direct.getColKeys().forEach(function (colKey) {
74
+ compareCells(rowKey, colKey);
75
+ });
76
+ });
77
+ direct.getColKeys().forEach(function (colKey) {
78
+ compareCells([], colKey);
79
+ });
80
+ });
81
+
82
+ it('provides working format() on hydrated aggregators', function () {
83
+ var materialized = pivotCompute.materializeData(records, {});
84
+ var serialized = pivotCompute.computePivotState(materialized, config);
85
+ var direct = new _Utilities.PivotData(Object.assign({}, config, { data: records }));
86
+ var hydrated = new _Utilities.PivotData({
87
+ data: materialized.materializedInput,
88
+ precomputedData: serialized,
89
+ aggregations: multiAggregationConfig,
90
+ rows: ['gender'],
91
+ cols: ['colour']
92
+ });
93
+
94
+ var directFormat = direct.getAggregator([], [], 'sum-trials').format(1234.5);
95
+ var hydratedFormat = hydrated.getAggregator([], [], 'sum-trials').format(1234.5);
96
+ expect(hydratedFormat).toBe(directFormat);
97
+ });
98
+
99
+ it('respects valueFilter like the classic path', function () {
100
+ var filteredConfig = Object.assign({}, config, {
101
+ valueFilter: { gender: { male: true } }
102
+ });
103
+ var materialized = pivotCompute.materializeData(records, {});
104
+ var serialized = pivotCompute.computePivotState(materialized, filteredConfig);
105
+ var direct = new _Utilities.PivotData(Object.assign({}, filteredConfig, { data: records }));
106
+ var hydrated = new _Utilities.PivotData({
107
+ data: materialized.materializedInput,
108
+ precomputedData: serialized,
109
+ aggregations: multiAggregationConfig,
110
+ rows: ['gender'],
111
+ cols: ['colour'],
112
+ valueFilter: { gender: { male: true } }
113
+ });
114
+ expect(hydrated.getRowKeys()).toEqual(direct.getRowKeys());
115
+ expect(hydrated.getAggregator([], [], 'count').value()).toBe(direct.getAggregator([], [], 'count').value());
116
+ });
117
+
118
+ it('re-sorts keys on the main thread for function sorters', function () {
119
+ var materialized = pivotCompute.materializeData(records, {});
120
+ var serialized = pivotCompute.computePivotState(materialized, config);
121
+ var reverseSorter = function reverseSorter(a, b) {
122
+ return a < b ? 1 : a > b ? -1 : 0;
123
+ };
124
+ var hydrated = new _Utilities.PivotData({
125
+ data: materialized.materializedInput,
126
+ precomputedData: serialized,
127
+ aggregations: multiAggregationConfig,
128
+ rows: ['gender'],
129
+ cols: ['colour'],
130
+ sorters: { gender: reverseSorter }
131
+ });
132
+ var keys = hydrated.getRowKeys().map(function (key) {
133
+ return key[0];
134
+ });
135
+ expect(keys.indexOf('male')).toBeLessThan(keys.indexOf('female'));
136
+ });
137
+ });
138
+
139
+ describe('.createComputeSignature()', function () {
140
+ it('is stable for identical configs and differs otherwise', function () {
141
+ var props = {
142
+ rows: ['gender'],
143
+ cols: [],
144
+ aggregations: multiAggregationConfig,
145
+ valueFilter: {},
146
+ sorters: {}
147
+ };
148
+ var first = pivotCompute.createComputeSignature(props);
149
+ var second = pivotCompute.createComputeSignature(Object.assign({}, props));
150
+ expect(first).toBe(second);
151
+ var different = pivotCompute.createComputeSignature(Object.assign({}, props, { rows: ['colour'] }));
152
+ expect(different).not.toBe(first);
153
+ });
154
+
155
+ it('strips function-based sorters from the signature', function () {
156
+ var props = {
157
+ rows: ['gender'],
158
+ sorters: { gender: function gender(a, b) {
159
+ return a.localeCompare(b);
160
+ } }
161
+ };
162
+ var signature = pivotCompute.createComputeSignature(props);
163
+ expect(signature).not.toContain('localeCompare');
164
+ });
165
+ });
166
+
167
+ describe('.canComputeInWorker()', function () {
168
+ var eligibleProps = {
169
+ data: records,
170
+ aggregators: _Utilities.PivotData.defaultProps.aggregators,
171
+ derivedAttributes: {}
172
+ };
173
+
174
+ beforeAll(function () {
175
+ // jsdom has no Worker implementation; simulate availability.
176
+ global.Worker = function FakeWorker() {};
177
+ });
178
+
179
+ it('accepts plain-array datasets above the threshold', function () {
180
+ expect(pivotCompute.canComputeInWorker(eligibleProps, { threshold: 2 })).toBe(true);
181
+ });
182
+
183
+ it('rejects datasets below the threshold', function () {
184
+ expect(pivotCompute.canComputeInWorker(eligibleProps, { threshold: 1000 })).toBe(false);
185
+ });
186
+
187
+ it('rejects custom aggregator maps', function () {
188
+ var props = Object.assign({}, eligibleProps, {
189
+ aggregators: { Count: function Count() {
190
+ return function () {
191
+ return {};
192
+ };
193
+ } }
194
+ });
195
+ expect(pivotCompute.canComputeInWorker(props, { threshold: 2 })).toBe(false);
196
+ });
197
+
198
+ it('rejects custom derived attributes', function () {
199
+ var props = Object.assign({}, eligibleProps, {
200
+ derivedAttributes: { extra: function extra(record) {
201
+ return record.name;
202
+ } }
203
+ });
204
+ expect(pivotCompute.canComputeInWorker(props, { threshold: 2 })).toBe(false);
205
+ });
206
+
207
+ it('rejects disabled mode', function () {
208
+ expect(pivotCompute.canComputeInWorker(eligibleProps, {
209
+ enabled: false,
210
+ threshold: 2
211
+ })).toBe(false);
212
+ });
213
+ });
214
+ });
215
+ //# sourceMappingURL=pivotCompute-test.js.map
@@ -0,0 +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"]}