@datarailsshared/dr_renderer 1.5.159 → 1.5.168

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.
Files changed (32) hide show
  1. package/.idea/jsLibraryMappings.xml +6 -0
  2. package/.idea/misc.xml +9 -0
  3. package/.nvmrc +1 -0
  4. package/jest.config.js +1 -1
  5. package/package.json +9 -11
  6. package/scripts/check-versions.js +16 -0
  7. package/src/highcharts_renderer.d.ts +2 -2
  8. package/tsconfig.json +1 -1
  9. package/.circleci/config.yml +0 -85
  10. package/.github/workflows/ai-coder-jira.yml +0 -915
  11. package/.github/workflows/ai-coder-n8n-caller.yml +0 -82
  12. package/.github/workflows/release.yml +0 -49
  13. package/tests/__snapshots__/suboptions.test.js.snap +0 -5028
  14. package/tests/dr-renderer-helpers.test.js +0 -228
  15. package/tests/dr_chart_tooltip.test.js +0 -789
  16. package/tests/dr_gauge_chart.test.js +0 -2041
  17. package/tests/errors.test.js +0 -157
  18. package/tests/highcharts_renderer.test.js +0 -9407
  19. package/tests/mock/add-in-dynamic-ranges.json +0 -127
  20. package/tests/mock/add-in-functions.json +0 -410
  21. package/tests/mock/add-in-tables.json +0 -347
  22. package/tests/mock/tables.json +0 -2258
  23. package/tests/mock/widgets.json +0 -401
  24. package/tests/options-builder.test.js +0 -1698
  25. package/tests/pivot-table/freeze-panes/constants.test.js +0 -92
  26. package/tests/pivot-table/freeze-panes/index.test.js +0 -193
  27. package/tests/pivot-table/freeze-panes/sticky-strategy.test.js +0 -542
  28. package/tests/pivot-table/freeze-panes/transform-strategy.test.js +0 -304
  29. package/tests/ptCreateDrillDownSeriesToDrilldownChart.test.js +0 -509
  30. package/tests/seriesPointStyles-helper.test.js +0 -114
  31. package/tests/suboptions.test.js +0 -322
  32. package/tests/value.formatter.test.js +0 -143
@@ -1,322 +0,0 @@
1
- /**
2
- * @fileoverview Snapshot tests for highchartsRenderer.suboptions
3
- *
4
- * These tests ensure that the suboptions structure remains consistent
5
- * during the migration to the new builder pattern.
6
- */
7
-
8
- import * as JQuery from "jquery";
9
- import * as lodash from 'lodash';
10
- import moment from 'moment/min/moment.min';
11
-
12
- const getHighchartsRenderer = require('../src/highcharts_renderer');
13
- const DataFormatter = require('../src/dataformatter');
14
-
15
- const DEFAULT_USER_COLORS = {
16
- colors: ['#008aff', '#91e7e7', '#f37789', '#ffdc65', '#0e569d', '#bbe0ff', '#57b2ff', '#5ecfb9', '#c7ffda', '#179ab9'],
17
- variance_color: null
18
- };
19
-
20
- const $ = JQuery.default;
21
- let highchartsRenderer = {};
22
- let Highcharts;
23
-
24
- // Helper to strip function properties for snapshot comparison
25
- const stripFunctions = (obj) => {
26
- return JSON.parse(JSON.stringify(obj, (key, value) => {
27
- if (typeof value === 'function') {
28
- return '[Function]';
29
- }
30
- return value;
31
- }));
32
- };
33
-
34
- describe('highchartsRenderer.suboptions', () => {
35
- beforeAll(() => {
36
- Highcharts = {
37
- charts: [],
38
- opt: {},
39
- setOptions: function(value) { Highcharts.opt = value; },
40
- numberFormat: function(value) { return value; },
41
- getOptions: function() { return Highcharts.opt; },
42
- Tooltip: {},
43
- wrap: () => {},
44
- chart: () => {},
45
- };
46
-
47
- highchartsRenderer = getHighchartsRenderer(
48
- $,
49
- document,
50
- Highcharts,
51
- lodash.cloneDeep(DEFAULT_USER_COLORS),
52
- highchartsRenderer,
53
- DataFormatter,
54
- lodash,
55
- moment,
56
- true
57
- );
58
- });
59
-
60
- describe('structure snapshots', () => {
61
- // Dynamically generate tests for each suboption key
62
- const expectedKeys = [
63
- 'widget_library',
64
- 'table_options',
65
- 'table_design_options',
66
- 'table_options_transpose',
67
- 'table_options_gauge',
68
- 'value',
69
- 'range',
70
- 'name',
71
- 'subtitle',
72
- 'chart',
73
- 'chart_grid',
74
- 'chart_forecast',
75
- 'total_value_label_donut',
76
- 'chart_position',
77
- 'label',
78
- 'label_pie',
79
- 'label_gauge',
80
- 'label_with_percentage',
81
- 'label_with_percentage_percent_stacked',
82
- 'axisY',
83
- 'axisY_percent_stacked',
84
- 'axisX',
85
- 'ticks',
86
- 'tooltips',
87
- 'tooltips_pie',
88
- 'tooltips_gauge',
89
- 'negative_number_format',
90
- 'delta_column',
91
- 'delta_column_for_drill_down',
92
- 'advanced',
93
- 'legends',
94
- 'gauge_goal',
95
- 'gauge_segments',
96
- 'gauge_is_absolute',
97
- ];
98
-
99
- test('all expected suboption keys exist', () => {
100
- const actualKeys = Object.keys(highchartsRenderer.suboptions);
101
- expectedKeys.forEach(key => {
102
- expect(actualKeys).toContain(key);
103
- });
104
- });
105
-
106
- expectedKeys.forEach(key => {
107
- test(`${key} structure matches snapshot`, () => {
108
- const suboption = highchartsRenderer.suboptions[key];
109
- expect(suboption).toBeDefined();
110
- expect(stripFunctions(suboption)).toMatchSnapshot();
111
- });
112
- });
113
- });
114
-
115
- describe('suboption structure validation', () => {
116
- test('all suboptions have required properties', () => {
117
- Object.entries(highchartsRenderer.suboptions).forEach(([key, suboption]) => {
118
- // category_class is required
119
- expect(suboption.category_class).toBeDefined();
120
-
121
- // category_type is required
122
- expect(suboption.category_type).toBeDefined();
123
-
124
- // category_label is required
125
- expect(suboption.category_label).toBeDefined();
126
-
127
- // Should have either elements array or default_value
128
- const hasElements = Array.isArray(suboption.elements);
129
- const hasDefaultValue = suboption.default_value !== undefined;
130
- expect(hasElements || hasDefaultValue).toBe(true);
131
- });
132
- });
133
-
134
- test('all elements have required properties', () => {
135
- Object.entries(highchartsRenderer.suboptions).forEach(([key, suboption]) => {
136
- if (!Array.isArray(suboption.elements)) return;
137
-
138
- suboption.elements.forEach((element, index) => {
139
- // element_type is always required
140
- expect(element.element_type).toBeDefined();
141
-
142
- // For non-divider elements, value_name should be defined
143
- if (element.element_type !== 'devider' && element.element_type !== 'text') {
144
- expect(element.value_name).toBeDefined();
145
- }
146
- });
147
- });
148
- });
149
-
150
- test('element types are valid', () => {
151
- const validTypes = [
152
- 'toggle', 'checkbox', 'input', 'select', 'radio',
153
- 'color_picker', 'devider', 'textarea', 'tag', 'text'
154
- ];
155
-
156
- Object.entries(highchartsRenderer.suboptions).forEach(([key, suboption]) => {
157
- if (!Array.isArray(suboption.elements)) return;
158
-
159
- suboption.elements.forEach((element) => {
160
- expect(validTypes).toContain(element.element_type);
161
- });
162
- });
163
- });
164
- });
165
-
166
- describe('getDefaultValueForChart', () => {
167
- const chartTypesToTest = [
168
- 'line-chart',
169
- 'line-chart-smooth',
170
- 'line-chart-forecast',
171
- 'column-chart',
172
- 'column-chart-stacked',
173
- 'column-chart-stacked-percent',
174
- 'bar-chart',
175
- 'bar-chart-stacked',
176
- 'bar-chart-stacked-percent',
177
- 'scatter-chart',
178
- 'area-chart',
179
- 'area-chart-smooth',
180
- 'polygon-chart',
181
- 'pie-chart',
182
- 'pie-chart-drilldown',
183
- 'donut-chart',
184
- 'gauge-chart-enhanced',
185
- 'kpi-widget',
186
- 'text-widget',
187
- 'table_only',
188
- 'waterfall-chart-breakdown',
189
- 'waterfall-chart-walkthrough',
190
- ];
191
-
192
- chartTypesToTest.forEach(chartType => {
193
- test(`${chartType} defaults match snapshot`, () => {
194
- const defaults = highchartsRenderer.getDefaultValueForChart(chartType);
195
- expect(stripFunctions(defaults)).toMatchSnapshot();
196
- });
197
- });
198
- });
199
-
200
- describe('getDefaultValueForSubOptions', () => {
201
- test('extracts default values correctly for label suboption', () => {
202
- const labelSuboption = highchartsRenderer.suboptions['label'];
203
- const defaults = highchartsRenderer.getDefaultValueForSubOptions(labelSuboption, {}, 'column-chart');
204
-
205
- expect(defaults).toBeDefined();
206
- expect(defaults.show).toBe(true);
207
- expect(defaults.overlap).toBe(false);
208
- expect(defaults.show_value).toBe(true);
209
- });
210
-
211
- test('extracts default values correctly for tooltips suboption', () => {
212
- const tooltipsSuboption = highchartsRenderer.suboptions['tooltips'];
213
- const defaults = highchartsRenderer.getDefaultValueForSubOptions(tooltipsSuboption, {}, 'column-chart');
214
-
215
- expect(defaults).toBeDefined();
216
- expect(defaults.show).toBe(true);
217
- expect(defaults.show_value).toBe(true);
218
- expect(defaults.show_x_axis).toBe(true);
219
- });
220
-
221
- test('respects existing options when extracting defaults', () => {
222
- const labelSuboption = highchartsRenderer.suboptions['label'];
223
- const existingOptions = {
224
- label: {
225
- show: false,
226
- font_size: '14'
227
- }
228
- };
229
- const defaults = highchartsRenderer.getDefaultValueForSubOptions(labelSuboption, existingOptions, 'column-chart');
230
-
231
- expect(defaults.show).toBe(false);
232
- expect(defaults.font_size).toBe('14');
233
- });
234
- });
235
-
236
- describe('label suboptions consistency', () => {
237
- test('label families share common structure', () => {
238
- const labelKeys = ['label', 'label_pie', 'label_gauge', 'label_with_percentage'];
239
-
240
- labelKeys.forEach(key => {
241
- const suboption = highchartsRenderer.suboptions[key];
242
- expect(suboption).toBeDefined();
243
- expect(suboption.category_label).toBe('Label');
244
- expect(Array.isArray(suboption.elements)).toBe(true);
245
-
246
- // All should have show toggle
247
- const showElement = suboption.elements.find(e => e.value_name === 'show');
248
- expect(showElement).toBeDefined();
249
- expect(showElement.element_type).toBe('toggle');
250
- });
251
- });
252
-
253
- test('label families have font styling elements', () => {
254
- const labelKeys = ['label', 'label_pie', 'label_gauge', 'label_with_percentage'];
255
-
256
- labelKeys.forEach(key => {
257
- const suboption = highchartsRenderer.suboptions[key];
258
-
259
- const fontStyleElement = suboption.elements.find(e => e.value_name === 'font_style');
260
- const fontSizeElement = suboption.elements.find(e => e.value_name === 'font_size');
261
- const fontColorElement = suboption.elements.find(e => e.value_name === 'font_color');
262
-
263
- expect(fontStyleElement).toBeDefined();
264
- expect(fontSizeElement).toBeDefined();
265
- expect(fontColorElement).toBeDefined();
266
- });
267
- });
268
- });
269
-
270
- describe('tooltip suboptions consistency', () => {
271
- test('tooltip families share common structure', () => {
272
- const tooltipKeys = ['tooltips', 'tooltips_pie', 'tooltips_gauge'];
273
-
274
- tooltipKeys.forEach(key => {
275
- const suboption = highchartsRenderer.suboptions[key];
276
- expect(suboption).toBeDefined();
277
- expect(suboption.category_label).toBe('Tooltip');
278
- expect(suboption.category_type).toBe('tooltips');
279
- expect(Array.isArray(suboption.elements)).toBe(true);
280
-
281
- // All should have show toggle
282
- const showElement = suboption.elements.find(e => e.value_name === 'show');
283
- expect(showElement).toBeDefined();
284
- expect(showElement.element_type).toBe('toggle');
285
- });
286
- });
287
- });
288
-
289
- describe('axis suboptions consistency', () => {
290
- test('axisY and axisY_percent_stacked share base structure', () => {
291
- const axisY = highchartsRenderer.suboptions['axisY'];
292
- const axisYPercent = highchartsRenderer.suboptions['axisY_percent_stacked'];
293
-
294
- expect(axisY.category_type).toBe('axisY');
295
- expect(axisYPercent.category_type).toBe('axisY');
296
- expect(axisY.category_label).toBe('Y Axis');
297
- expect(axisYPercent.category_label).toBe('Y Axis');
298
-
299
- // Both should have autoylabel and name
300
- const axisYAutoLabel = axisY.elements.find(e => e.value_name === 'autoylabel');
301
- const axisYPercentAutoLabel = axisYPercent.elements.find(e => e.value_name === 'autoylabel');
302
-
303
- expect(axisYAutoLabel).toBeDefined();
304
- expect(axisYPercentAutoLabel).toBeDefined();
305
- });
306
-
307
- test('axisY has min/max but axisY_percent_stacked does not', () => {
308
- const axisY = highchartsRenderer.suboptions['axisY'];
309
- const axisYPercent = highchartsRenderer.suboptions['axisY_percent_stacked'];
310
-
311
- const axisYMin = axisY.elements.find(e => e.value_name === 'min');
312
- const axisYMax = axisY.elements.find(e => e.value_name === 'max');
313
- const axisYPercentMin = axisYPercent.elements.find(e => e.value_name === 'min');
314
- const axisYPercentMax = axisYPercent.elements.find(e => e.value_name === 'max');
315
-
316
- expect(axisYMin).toBeDefined();
317
- expect(axisYMax).toBeDefined();
318
- expect(axisYPercentMin).toBeUndefined();
319
- expect(axisYPercentMax).toBeUndefined();
320
- });
321
- });
322
- });
@@ -1,143 +0,0 @@
1
- const { getAggregatorPercentageValueIfRequired, getRelatedValue, isAbsoluteValue } = require('../src/value.formatter');
2
-
3
- describe('Function getAggregatorPercentageValueIfRequired', () => {
4
- let render_options, rowKey, colKey;
5
-
6
- beforeEach(() => {
7
- render_options = {
8
- comboOptions: { secondaryAxisSettings: { is_percentage: true } },
9
- chartOptions: {
10
- delta_column: {
11
- name: 'Variance',
12
- formula: 'x2-x1',
13
- is_percentage: false
14
- }
15
- }
16
- };
17
- rowKey = ['Variance'];
18
- colKey = ['SomeCol'];
19
- });
20
-
21
- it('should return percentage string when secondaryAxisSettings.is_percentage is true but delta_column.is_percentage is false', () => {
22
- const data = {
23
- rowKeys: ['Variance'],
24
- getAggregator: jest.fn(() => ({
25
- value: () => 200
26
- }))
27
- };
28
- const result = getAggregatorPercentageValueIfRequired(50, render_options, data, rowKey, colKey);
29
- expect(result).toBe('25%');
30
- });
31
-
32
- it('should return percentage string when secondaryAxisSettings.is_percentage is false but delta_column.is_percentage is true', () => {
33
- const data = {
34
- rowKeys: ['Variance'],
35
- getAggregator: jest.fn(() => ({
36
- value: () => 200
37
- }))
38
- };
39
- render_options.comboOptions.secondaryAxisSettings.is_percentage = false;
40
- render_options.chartOptions.delta_column.is_percentage = true;
41
- const result = getAggregatorPercentageValueIfRequired(50, render_options, data, rowKey, colKey);
42
- expect(result).toBe('25%');
43
- });
44
-
45
- it('should return null if is_percentage is false', () => {
46
- const data = {
47
- rowKeys: ['Variance'],
48
- getAggregator: jest.fn()
49
- };
50
- render_options.comboOptions.secondaryAxisSettings.is_percentage = false;
51
- const result = getAggregatorPercentageValueIfRequired(50, render_options, data, rowKey, colKey);
52
- expect(result).toBeNull();
53
- });
54
-
55
- it('should return null if isVariance is false', () => {
56
- const data = {
57
- rowKeys: ['NotVariance'],
58
- getAggregator: jest.fn()
59
- };
60
- rowKey = ['NotVariance'];
61
- const result = getAggregatorPercentageValueIfRequired(50, render_options, data, rowKey, colKey);
62
- expect(result).toBeNull();
63
- });
64
-
65
- it('should return null if baseRowKey is missing', () => {
66
- const data = {
67
- rowKeys: [],
68
- getAggregator: jest.fn()
69
- };
70
- const result = getAggregatorPercentageValueIfRequired(50, render_options, data, rowKey, colKey);
71
- expect(result).toBeNull();
72
- });
73
-
74
- it('should return null if agg is missing', () => {
75
- const data = {
76
- rowKeys: ['Variance'],
77
- getAggregator: jest.fn(() => null)
78
- };
79
- const result = getAggregatorPercentageValueIfRequired(50, render_options, data, rowKey, colKey);
80
- expect(result).toBeNull();
81
- });
82
-
83
- it('should return null if data is null', () => {
84
- const result = getAggregatorPercentageValueIfRequired(50, render_options, null, rowKey, colKey);
85
- expect(result).toBeNull();
86
- });
87
-
88
- it('should return null if data is undefined', () => {
89
- const result = getAggregatorPercentageValueIfRequired(50, render_options, undefined, rowKey, colKey);
90
- expect(result).toBeNull();
91
- });
92
-
93
- it('should return null if baseRowKey is null even when data exists', () => {
94
- const data = {
95
- rowKeys: [null],
96
- getAggregator: jest.fn()
97
- };
98
- const result = getAggregatorPercentageValueIfRequired(50, render_options, data, rowKey, colKey);
99
- expect(result).toBeNull();
100
- expect(data.getAggregator).not.toHaveBeenCalled();
101
- });
102
- });
103
-
104
- describe('Function getRelatedValue', () => {
105
- it('should return -1 when baseValue is falsy and value < 0', () => {
106
- expect(getRelatedValue(-50, 0)).toBe(-1);
107
- });
108
-
109
- it('should return 1 when baseValue is falsy and value >= 0', () => {
110
- expect(getRelatedValue(50, null)).toBe(1);
111
- });
112
-
113
- it('should return related value when baseValue is truthy', () => {
114
- expect(getRelatedValue(50, 200)).toBe(0.25);
115
- expect(getRelatedValue(200, 200)).toBe(1);
116
- });
117
- });
118
-
119
- describe('Function isAbsoluteValue', () => {
120
- it('should return false if formula is undefined', () => {
121
- expect(isAbsoluteValue(undefined)).toBe(false);
122
- });
123
-
124
- it('should return false if formula is null', () => {
125
- expect(isAbsoluteValue(null)).toBe(false);
126
- });
127
-
128
- it('should return false if formula contains "/"', () => {
129
- expect(isAbsoluteValue('/')).toBe(false);
130
- expect(isAbsoluteValue(' / ')).toBe(false);
131
- });
132
-
133
- it('should return true if formula does not contain "/"', () => {
134
- expect(isAbsoluteValue('x2-x1')).toBe(true);
135
- expect(isAbsoluteValue(' x1 - x2 ')).toBe(true);
136
- expect(isAbsoluteValue('some text x2-x1 more text')).toBe(true);
137
- });
138
-
139
- it('should ignore spaces in formula', () => {
140
- expect(isAbsoluteValue('x2 - x1')).toBe(true);
141
- expect(isAbsoluteValue(' x1 - x2 ')).toBe(true);
142
- });
143
- });