@hrforte/react-pivottable 1.1.0 → 2.0.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,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"]}