@thoughtspot/ts-chart-sdk 0.0.2-alpha.6 → 0.0.2-alpha.8
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/dist/ts-chart-sdk.d.ts +20 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/main/custom-chart-context.spec.js +53 -2
- package/lib/main/custom-chart-context.spec.js.map +1 -1
- package/lib/react/use-custom-chart-context.spec.js +54 -2
- package/lib/react/use-custom-chart-context.spec.js.map +1 -1
- package/lib/types/answer-column.types.d.ts +1 -0
- package/lib/types/answer-column.types.d.ts.map +1 -1
- package/lib/types/common.types.d.ts +1 -1
- package/lib/types/common.types.d.ts.map +1 -1
- package/lib/utils/conditional-formatting/conditional-formatting.spec.js +20 -1
- package/lib/utils/conditional-formatting/conditional-formatting.spec.js.map +1 -1
- package/lib/utils/date-formatting.d.ts +19 -0
- package/lib/utils/date-formatting.d.ts.map +1 -0
- package/lib/utils/date-formatting.js +56 -0
- package/lib/utils/date-formatting.js.map +1 -0
- package/lib/utils/date-formatting.spec.d.ts +2 -0
- package/lib/utils/date-formatting.spec.d.ts.map +1 -0
- package/lib/utils/date-formatting.spec.js +123 -0
- package/lib/utils/date-formatting.spec.js.map +1 -0
- package/package.json +3 -1
- package/src/index.ts +1 -0
- package/src/main/custom-chart-context.spec.ts +64 -4
- package/src/react/use-custom-chart-context.spec.tsx +65 -2
- package/src/types/answer-column.types.ts +7 -0
- package/src/types/common.types.ts +9 -3
- package/src/utils/conditional-formatting/conditional-formatting.spec.ts +52 -0
- package/src/utils/date-formatting.spec.ts +166 -0
- package/src/utils/date-formatting.ts +109 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date-formatting.spec.d.ts","sourceRoot":"","sources":["../../src/utils/date-formatting.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { ColumnTimeBucket, ColumnType, DataType, } from '../types/answer-column.types';
|
|
2
|
+
import { dateFormatter, getCustomCalendarGuidFromColumn, getDisplayString, getStartEpoch, hasCustomCalendar, isAttribute, isDateColumn, isDateFamilyColumn, isDateNumColumn, isTimeColumn, } from './date-formatting';
|
|
3
|
+
describe('date-formatting', () => {
|
|
4
|
+
let col;
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
col = {
|
|
7
|
+
id: 'testId',
|
|
8
|
+
name: 'test',
|
|
9
|
+
type: ColumnType.MEASURE,
|
|
10
|
+
timeBucket: ColumnTimeBucket.AUTO,
|
|
11
|
+
dataType: DataType.UNKNOWN,
|
|
12
|
+
calenderGuid: '12345',
|
|
13
|
+
};
|
|
14
|
+
});
|
|
15
|
+
test('isDateColumn should return true for DATE data type', () => {
|
|
16
|
+
col.dataType = DataType.DATE;
|
|
17
|
+
expect(isDateColumn(col)).toBe(true);
|
|
18
|
+
});
|
|
19
|
+
test('isDateColumn should return true for DATE_TIME data type', () => {
|
|
20
|
+
col.dataType = DataType.DATE_TIME;
|
|
21
|
+
expect(isDateColumn(col)).toBe(true);
|
|
22
|
+
});
|
|
23
|
+
test('isAttribute should return true for ATTRIBUTE column type', () => {
|
|
24
|
+
col.type = ColumnType.ATTRIBUTE;
|
|
25
|
+
expect(isAttribute(col)).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
test('isAttribute should return false for non-ATTRIBUTE column type', () => {
|
|
28
|
+
col.type = ColumnType.MEASURE;
|
|
29
|
+
expect(isAttribute(col)).toBe(false);
|
|
30
|
+
});
|
|
31
|
+
test('getCustomCalendarGuidFromColumn should return the calendarGuid', () => {
|
|
32
|
+
col.calenderGuid = '12345';
|
|
33
|
+
expect(getCustomCalendarGuidFromColumn(col)).toBe('12345');
|
|
34
|
+
});
|
|
35
|
+
test('isDateNumColumn should return true for ATTRIBUTE type with specific time buckets', () => {
|
|
36
|
+
col.type = ColumnType.ATTRIBUTE;
|
|
37
|
+
col.timeBucket = ColumnTimeBucket.HOUR_OF_DAY;
|
|
38
|
+
expect(isDateNumColumn(col)).toBe(true);
|
|
39
|
+
});
|
|
40
|
+
test('isDateNumColumn should return false for non-ATTRIBUTE type', () => {
|
|
41
|
+
col.type = ColumnType.MEASURE;
|
|
42
|
+
col.timeBucket = ColumnTimeBucket.DAY_OF_WEEK;
|
|
43
|
+
expect(isDateNumColumn(col)).toBe(false);
|
|
44
|
+
});
|
|
45
|
+
test('isDateFamilyColumn should return true for DATE data type', () => {
|
|
46
|
+
col.dataType = DataType.DATE;
|
|
47
|
+
expect(isDateFamilyColumn(col)).toBe(true);
|
|
48
|
+
});
|
|
49
|
+
test('isDateFamilyColumn should return true for DATE_NUM column', () => {
|
|
50
|
+
col.type = ColumnType.ATTRIBUTE;
|
|
51
|
+
col.timeBucket = ColumnTimeBucket.DAY_OF_WEEK;
|
|
52
|
+
expect(isDateFamilyColumn(col)).toBe(true);
|
|
53
|
+
});
|
|
54
|
+
test('isTimeColumn should return true for TIME data type', () => {
|
|
55
|
+
col.dataType = DataType.TIME;
|
|
56
|
+
expect(isTimeColumn(col)).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
test('hasCustomCalendar should return true for date family columns with custom calendar', () => {
|
|
59
|
+
col.dataType = DataType.DATE;
|
|
60
|
+
col.calenderGuid = '12345';
|
|
61
|
+
expect(hasCustomCalendar(col)).toBe(true);
|
|
62
|
+
});
|
|
63
|
+
test('getStartEpoch should return the start epoch from CustomCalendarDate', () => {
|
|
64
|
+
const date = {
|
|
65
|
+
v: { s: 12345, e: 12346 },
|
|
66
|
+
d: 'Custom_Date',
|
|
67
|
+
};
|
|
68
|
+
expect(getStartEpoch(date)).toBe(date.v.s);
|
|
69
|
+
});
|
|
70
|
+
test('getStartEpoch should return null if start epoch is not present', () => {
|
|
71
|
+
const date = { v: {}, d: '01-07-2021' };
|
|
72
|
+
expect(getStartEpoch(date)).toBe(null);
|
|
73
|
+
});
|
|
74
|
+
test('getDisplayString should return display string if present', () => {
|
|
75
|
+
const date = { v: { s: 1625097600, e: 1625184000 }, d: '01-07-2021' };
|
|
76
|
+
expect(getDisplayString(date)).toBe('01-07-2021');
|
|
77
|
+
});
|
|
78
|
+
test('getDisplayString should return null if display string is not present', () => {
|
|
79
|
+
const date = {
|
|
80
|
+
v: { s: 1625097600, e: 1625184000 },
|
|
81
|
+
};
|
|
82
|
+
expect(getDisplayString(date)).toBe(null);
|
|
83
|
+
});
|
|
84
|
+
test('dateFormatter should return custom calendar display string if present', () => {
|
|
85
|
+
const dataValue = {
|
|
86
|
+
v: { s: 1625097600, e: 1625184000 },
|
|
87
|
+
d: '01-07-2021',
|
|
88
|
+
};
|
|
89
|
+
col.dataType = DataType.DATE;
|
|
90
|
+
col.calenderGuid = '12345';
|
|
91
|
+
expect(dateFormatter(dataValue, col)).toBe('01-07-2021');
|
|
92
|
+
});
|
|
93
|
+
test('dateFormatter should return formatted date from start epoch if custom calendar display string is not present', () => {
|
|
94
|
+
const dataValue = {
|
|
95
|
+
v: { s: 1625097600, e: 1625184000 },
|
|
96
|
+
};
|
|
97
|
+
col.dataType = DataType.DATE;
|
|
98
|
+
col.calenderGuid = '12345';
|
|
99
|
+
expect(dateFormatter(dataValue, col)).toBe('01-07-2021');
|
|
100
|
+
});
|
|
101
|
+
test('dateFormatter should return null if start epoch is not present', () => {
|
|
102
|
+
const dataValue = { v: { e: 1625184000 } };
|
|
103
|
+
col.dataType = DataType.DATE;
|
|
104
|
+
col.calenderGuid = '12345';
|
|
105
|
+
expect(dateFormatter(dataValue, col)).toBe(null);
|
|
106
|
+
});
|
|
107
|
+
test('dateFormatter should return formatted date for non-custom calendar column', () => {
|
|
108
|
+
const dataValue = 1625097600;
|
|
109
|
+
col.dataType = DataType.DATE;
|
|
110
|
+
col.calenderGuid = undefined;
|
|
111
|
+
expect(dateFormatter(dataValue, col)).toBe('01-07-2021');
|
|
112
|
+
});
|
|
113
|
+
test('dateFormatter should format the date based on custom calendar', () => {
|
|
114
|
+
col.dataType = DataType.DATE;
|
|
115
|
+
col.calenderGuid = '12345';
|
|
116
|
+
const date = {
|
|
117
|
+
v: { s: 12345, e: 12346 },
|
|
118
|
+
d: 'Custom_Date',
|
|
119
|
+
};
|
|
120
|
+
expect(dateFormatter(date, col)).toBe(date.d);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
//# sourceMappingURL=date-formatting.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date-formatting.spec.js","sourceRoot":"","sources":["../../src/utils/date-formatting.spec.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thoughtspot/ts-chart-sdk",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.0.2-alpha.
|
|
4
|
+
"version": "0.0.2-alpha.8",
|
|
5
5
|
"module": "lib/index",
|
|
6
6
|
"main": "lib/index",
|
|
7
7
|
"types": "lib/index",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"@testing-library/react-hooks": "^7.0.2",
|
|
37
37
|
"@types/jest": "^27.0.3",
|
|
38
38
|
"@types/lodash": "4.14.175",
|
|
39
|
+
"@types/luxon": "^3.4.2",
|
|
39
40
|
"@types/node": "18.16.3",
|
|
40
41
|
"@types/react": "^17.0.2",
|
|
41
42
|
"@types/react-dom": "^17.0.11",
|
|
@@ -74,6 +75,7 @@
|
|
|
74
75
|
},
|
|
75
76
|
"dependencies": {
|
|
76
77
|
"lodash": "^4.17.21",
|
|
78
|
+
"luxon": "^3.4.4",
|
|
77
79
|
"promise-postmessage": "^3.5.0",
|
|
78
80
|
"react": "^17.0.2",
|
|
79
81
|
"react-dom": "^17.0.2"
|
package/src/index.ts
CHANGED
|
@@ -7,4 +7,5 @@ export * from './types/ts-to-chart-event.types';
|
|
|
7
7
|
export * from './main/custom-chart-context';
|
|
8
8
|
export * from './react/use-custom-chart-context';
|
|
9
9
|
export * from './types/conditional-formatting.types';
|
|
10
|
+
export * from './utils/date-formatting';
|
|
10
11
|
export * from './utils/conditional-formatting/conditional-formatting';
|
|
@@ -112,23 +112,83 @@ describe('CustomChartContext', () => {
|
|
|
112
112
|
expect(mockPostMessageToHost).not.toHaveBeenCalled();
|
|
113
113
|
});
|
|
114
114
|
|
|
115
|
-
test('
|
|
115
|
+
test('type check string for visualProps on initialize payload should not throw an error.', async () => {
|
|
116
|
+
expect(mockInitMessage).toHaveBeenCalled();
|
|
117
|
+
|
|
116
118
|
// Call the initialize function and wait for it to resolve
|
|
117
119
|
const promise = customChartContext.initialize();
|
|
118
120
|
|
|
119
121
|
// Check that the hasInitializedPromise has resolved
|
|
120
|
-
|
|
121
|
-
|
|
122
|
+
|
|
123
|
+
const mockInitializeContextPayloadWithVisualProps = {
|
|
124
|
+
...mockInitializeContextPayload,
|
|
125
|
+
chartModel: {
|
|
126
|
+
...mockInitializeContextPayload.chartModel,
|
|
127
|
+
visualProps: 'visualPropStringPayload',
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
await eventProcessor({
|
|
132
|
+
payload: mockInitializeContextPayloadWithVisualProps,
|
|
122
133
|
eventType: TSToChartEvent.Initialize,
|
|
123
134
|
});
|
|
124
|
-
|
|
125
135
|
eventProcessor({
|
|
126
136
|
payload: {},
|
|
127
137
|
eventType: TSToChartEvent.InitializeComplete,
|
|
128
138
|
});
|
|
139
|
+
await expect(promise).resolves.toBeUndefined();
|
|
140
|
+
const chartModel = customChartContext.getChartModel();
|
|
141
|
+
expect(typeof chartModel.visualProps).toEqual('string');
|
|
142
|
+
expect(chartModel.visualProps).toEqual('visualPropStringPayload');
|
|
143
|
+
expect(mockPostMessageToHost).not.toHaveBeenCalled();
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
test('type check object for visualProps on initialize payload should not throw an error.', async () => {
|
|
147
|
+
expect(mockInitMessage).toHaveBeenCalled();
|
|
129
148
|
|
|
149
|
+
// Call the initialize function and wait for it to resolve
|
|
150
|
+
const promise = customChartContext.initialize();
|
|
151
|
+
|
|
152
|
+
// Check that the hasInitializedPromise has resolved
|
|
153
|
+
|
|
154
|
+
const mockInitializeContextPayloadWithVisualProps = {
|
|
155
|
+
...mockInitializeContextPayload,
|
|
156
|
+
chartModel: {
|
|
157
|
+
...mockInitializeContextPayload.chartModel,
|
|
158
|
+
visualProps: {
|
|
159
|
+
data: 'sample data',
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
await eventProcessor({
|
|
165
|
+
payload: mockInitializeContextPayloadWithVisualProps,
|
|
166
|
+
eventType: TSToChartEvent.Initialize,
|
|
167
|
+
});
|
|
168
|
+
eventProcessor({
|
|
169
|
+
payload: {},
|
|
170
|
+
eventType: TSToChartEvent.InitializeComplete,
|
|
171
|
+
});
|
|
130
172
|
await expect(promise).resolves.toBeUndefined();
|
|
173
|
+
const chartModel = customChartContext.getChartModel();
|
|
174
|
+
expect(typeof chartModel.visualProps).toEqual('object');
|
|
175
|
+
expect(chartModel.visualProps).toEqual({
|
|
176
|
+
data: 'sample data',
|
|
177
|
+
});
|
|
178
|
+
expect(mockPostMessageToHost).not.toHaveBeenCalled();
|
|
179
|
+
});
|
|
131
180
|
|
|
181
|
+
test('multiple intializations should throw an error', async () => {
|
|
182
|
+
// Call the initialize function and wait for it to resolve
|
|
183
|
+
getChartContext({
|
|
184
|
+
getDefaultChartConfig,
|
|
185
|
+
getQueriesFromChartConfig,
|
|
186
|
+
renderChart,
|
|
187
|
+
});
|
|
188
|
+
eventProcessor({
|
|
189
|
+
payload: {},
|
|
190
|
+
eventType: TSToChartEvent.InitializeComplete,
|
|
191
|
+
});
|
|
132
192
|
let error;
|
|
133
193
|
try {
|
|
134
194
|
customChartContext = new CustomChartContext({
|
|
@@ -3,6 +3,7 @@ import { renderHook } from '@testing-library/react-hooks';
|
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import * as PostMessageEventBridge from '../main/post-message-event-bridge';
|
|
5
5
|
import { mockInitializeContextPayload } from '../test/test-utils';
|
|
6
|
+
import { ColumnType } from '../types/answer-column.types';
|
|
6
7
|
import { ChartToTSEvent } from '../types/chart-to-ts-event.types';
|
|
7
8
|
import { TSToChartEvent } from '../types/ts-to-chart-event.types';
|
|
8
9
|
import { contextChartProps } from './mocks/custom-chart-context-mock';
|
|
@@ -12,7 +13,10 @@ describe('useChartContext initialization', () => {
|
|
|
12
13
|
let eventProcessor: any;
|
|
13
14
|
let mockInitMessage;
|
|
14
15
|
let mockPostMessageToHost;
|
|
15
|
-
const mockedChartModel = {
|
|
16
|
+
const mockedChartModel = {
|
|
17
|
+
columns: [{ type: ColumnType.MEASURE }, { type: ColumnType.ATTRIBUTE }],
|
|
18
|
+
config: {},
|
|
19
|
+
};
|
|
16
20
|
beforeEach(() => {
|
|
17
21
|
mockInitMessage = jest.spyOn(
|
|
18
22
|
PostMessageEventBridge,
|
|
@@ -67,6 +71,66 @@ describe('useChartContext initialization', () => {
|
|
|
67
71
|
});
|
|
68
72
|
});
|
|
69
73
|
|
|
74
|
+
test('should trigger getDataQuery and fetch correct query response', async () => {
|
|
75
|
+
// Render the hook with the custom chart context props
|
|
76
|
+
const { result, waitFor } = renderHook(() =>
|
|
77
|
+
useChartContext(contextChartProps),
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
// Assert that the context is not initialized initially
|
|
81
|
+
expect(result.current.hasInitialized).toBe(false);
|
|
82
|
+
expect(result.current.chartModel).toBeUndefined();
|
|
83
|
+
await eventProcessor({
|
|
84
|
+
payload: {
|
|
85
|
+
componentId: 'COMPONENT_ID',
|
|
86
|
+
hostUrl: 'https://some.chart.app',
|
|
87
|
+
chartModel: mockedChartModel,
|
|
88
|
+
},
|
|
89
|
+
eventType: TSToChartEvent.Initialize,
|
|
90
|
+
});
|
|
91
|
+
const response = await eventProcessor({
|
|
92
|
+
payload: {
|
|
93
|
+
config: [
|
|
94
|
+
{
|
|
95
|
+
key: 'column',
|
|
96
|
+
dimensions: [
|
|
97
|
+
{
|
|
98
|
+
key: 'x',
|
|
99
|
+
columns: [mockedChartModel.columns[0]],
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
key: 'y',
|
|
103
|
+
columns: [mockedChartModel.columns[1]],
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
eventType: TSToChartEvent.GetDataQuery,
|
|
110
|
+
source: 'ts-host-app',
|
|
111
|
+
});
|
|
112
|
+
await eventProcessor({
|
|
113
|
+
payload: {},
|
|
114
|
+
eventType: TSToChartEvent.TriggerRenderChart,
|
|
115
|
+
source: 'ts-host-app',
|
|
116
|
+
});
|
|
117
|
+
await eventProcessor({
|
|
118
|
+
payload: {},
|
|
119
|
+
eventType: TSToChartEvent.InitializeComplete,
|
|
120
|
+
source: 'ts-host-app',
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
await waitFor(() => {
|
|
124
|
+
expect(response.queries[0].queryColumns[0]).toBe(
|
|
125
|
+
mockedChartModel.columns[0],
|
|
126
|
+
);
|
|
127
|
+
expect(response.queries[0].queryColumns[1]).toBe(
|
|
128
|
+
mockedChartModel.columns[1],
|
|
129
|
+
);
|
|
130
|
+
expect(result.current.hasInitialized).toBeTruthy();
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
70
134
|
test('should make sure hasInitialized to remain false when context initialization failed', async () => {
|
|
71
135
|
jest.mock('../main/custom-chart-context', () => ({
|
|
72
136
|
CustomChartContext: jest.fn().mockImplementation(() => ({
|
|
@@ -76,7 +140,6 @@ describe('useChartContext initialization', () => {
|
|
|
76
140
|
emitEvent: jest.fn(),
|
|
77
141
|
on: jest.fn(),
|
|
78
142
|
getChartModel: jest.fn(),
|
|
79
|
-
renderChart: jest.fn(),
|
|
80
143
|
destroy: jest.fn(),
|
|
81
144
|
})),
|
|
82
145
|
}));
|
|
@@ -242,4 +242,11 @@ export interface ChartColumn {
|
|
|
242
242
|
* @version SDK: 0.1 | ThoughtSpot:
|
|
243
243
|
*/
|
|
244
244
|
customOrder?: Array<string>;
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Guid of Custom calender for the column if defined in worksheet else null
|
|
248
|
+
*
|
|
249
|
+
* @version SDK: 0.1 | ThoughtSpot: sdcwdc
|
|
250
|
+
*/
|
|
251
|
+
calenderGuid?: string;
|
|
245
252
|
}
|
|
@@ -179,15 +179,21 @@ export type ValidationResponse = {
|
|
|
179
179
|
/**
|
|
180
180
|
* Custom Visual props is the stored metadata for the visual props definition
|
|
181
181
|
* configured by the user in the visual prop editor
|
|
182
|
-
* The
|
|
183
|
-
*
|
|
182
|
+
* The object is defined by the visual prop types. See VisualPropEditorDefinition.
|
|
183
|
+
* If there is any local state specific to charts needs to be maintained on save answer, store it
|
|
184
|
+
* in VisualProps, with visualProps.clientState variable. The clientState variable should be a
|
|
185
|
+
* string, preferrably a result of JSON.stringify(<yourlocalClientState>).
|
|
186
|
+
* @remark
|
|
187
|
+
* only values stored in clientSate variable will be preserved on changing the
|
|
188
|
+
* visualPropeditorDefinition, any other variable store would not be preserved
|
|
184
189
|
* @group Chart Model
|
|
185
190
|
* @version SDK: 0.1 | ThoughtSpot:
|
|
186
191
|
*/
|
|
187
|
-
export type VisualProps =
|
|
192
|
+
export type VisualProps = unknown;
|
|
188
193
|
|
|
189
194
|
/**
|
|
190
195
|
* Custom Font Faces type from TS.
|
|
196
|
+
*
|
|
191
197
|
*/
|
|
192
198
|
|
|
193
199
|
export type CustomFontFaces = {
|
|
@@ -21,7 +21,9 @@ import { DataPointsArray } from '../../types/common.types';
|
|
|
21
21
|
import {
|
|
22
22
|
ConditionalFormatting,
|
|
23
23
|
ConditionalFormattingComparisonTypes,
|
|
24
|
+
FalconDataType,
|
|
24
25
|
Operators,
|
|
26
|
+
ParameterValueType,
|
|
25
27
|
} from '../../types/conditional-formatting.types';
|
|
26
28
|
import {
|
|
27
29
|
applicableConditionalFormatting,
|
|
@@ -64,12 +66,26 @@ const doesNotContainOperator = createAttributeOperator(
|
|
|
64
66
|
const startsWithOperator = createAttributeOperator(Operators.StartsWith);
|
|
65
67
|
const endsWithOperator = createAttributeOperator(Operators.EndsWith);
|
|
66
68
|
|
|
69
|
+
const invalidOperator = createMetricOperator('invalid-operator' as any);
|
|
70
|
+
|
|
67
71
|
const parameter = undefined;
|
|
68
72
|
|
|
69
73
|
const mockConditionalFormatting: ConditionalFormatting = {
|
|
70
74
|
rows: [lessThanOperator, greaterThanOperator, isBetweenOperator],
|
|
71
75
|
};
|
|
72
76
|
|
|
77
|
+
const parameters = [
|
|
78
|
+
{
|
|
79
|
+
id: 'parameter1',
|
|
80
|
+
defaultValue: 'abc',
|
|
81
|
+
dataType: FalconDataType.Char,
|
|
82
|
+
description: '',
|
|
83
|
+
owner: null as any,
|
|
84
|
+
valueType: ParameterValueType.Any,
|
|
85
|
+
name: 'parameter1',
|
|
86
|
+
},
|
|
87
|
+
];
|
|
88
|
+
|
|
73
89
|
describe('validateCfCondition', () => {
|
|
74
90
|
test('verify validateCfCondition util', () => {
|
|
75
91
|
expect(
|
|
@@ -115,6 +131,19 @@ describe('validateCfCondition', () => {
|
|
|
115
131
|
expect(
|
|
116
132
|
validateCfCondition(isBetweenOperator, 4, 'col1', mockDataAttr),
|
|
117
133
|
).toBe(false);
|
|
134
|
+
expect(
|
|
135
|
+
validateCfCondition(invalidOperator, 4, 'col1', mockDataAttr),
|
|
136
|
+
).toBe(false);
|
|
137
|
+
|
|
138
|
+
const operatorWithColId = createMetricOperator(
|
|
139
|
+
Operators.LessThan,
|
|
140
|
+
'col1',
|
|
141
|
+
'col2',
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
expect(
|
|
145
|
+
validateCfCondition(operatorWithColId, 4, '', mockDataAttr),
|
|
146
|
+
).toBe(false);
|
|
118
147
|
});
|
|
119
148
|
});
|
|
120
149
|
|
|
@@ -220,6 +249,9 @@ describe('isConditionSatisfied', () => {
|
|
|
220
249
|
expect(isConditionSatisfied(notEqualToOperator, parameter, 200)).toBe(
|
|
221
250
|
false,
|
|
222
251
|
);
|
|
252
|
+
expect(isConditionSatisfied(notEqualToOperator, parameter, null)).toBe(
|
|
253
|
+
true,
|
|
254
|
+
);
|
|
223
255
|
expect(isConditionSatisfied(isBetweenOperator, parameter, 200)).toBe(
|
|
224
256
|
true,
|
|
225
257
|
);
|
|
@@ -232,6 +264,9 @@ describe('isConditionSatisfied', () => {
|
|
|
232
264
|
expect(isConditionSatisfied(isBetweenOperator, parameter, 50)).toBe(
|
|
233
265
|
false,
|
|
234
266
|
);
|
|
267
|
+
expect(isConditionSatisfied(isBetweenOperator, parameter, 50)).toBe(
|
|
268
|
+
false,
|
|
269
|
+
);
|
|
235
270
|
|
|
236
271
|
expect(
|
|
237
272
|
isConditionSatisfied(
|
|
@@ -411,5 +446,22 @@ describe('isConditionSatisfied', () => {
|
|
|
411
446
|
expect(
|
|
412
447
|
isConditionSatisfied(columnBasedOperator, undefined, 'abc', 'def'),
|
|
413
448
|
).toBe(false);
|
|
449
|
+
|
|
450
|
+
// Parameter Based
|
|
451
|
+
const parameterBasedOperator = createMetricOperator(
|
|
452
|
+
Operators.EqualTo,
|
|
453
|
+
'col1',
|
|
454
|
+
'col2',
|
|
455
|
+
'parameter1',
|
|
456
|
+
ConditionalFormattingComparisonTypes.ParameterBased,
|
|
457
|
+
);
|
|
458
|
+
expect(
|
|
459
|
+
isConditionSatisfied(
|
|
460
|
+
parameterBasedOperator,
|
|
461
|
+
parameters,
|
|
462
|
+
'abc',
|
|
463
|
+
'abc',
|
|
464
|
+
),
|
|
465
|
+
).toBe(true);
|
|
414
466
|
});
|
|
415
467
|
});
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file: Date Formatting Spec
|
|
3
|
+
*
|
|
4
|
+
* @author Yashvardhan Nehra <yashvardhan.nehra@thoughtspot.com>
|
|
5
|
+
*
|
|
6
|
+
* Copyright: ThoughtSpot Inc. 2023
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
ChartColumn,
|
|
11
|
+
ColumnTimeBucket,
|
|
12
|
+
ColumnType,
|
|
13
|
+
DataType,
|
|
14
|
+
} from '../types/answer-column.types';
|
|
15
|
+
import {
|
|
16
|
+
CustomCalendarDate,
|
|
17
|
+
dateFormatter,
|
|
18
|
+
getCustomCalendarGuidFromColumn,
|
|
19
|
+
getDisplayString,
|
|
20
|
+
getStartEpoch,
|
|
21
|
+
hasCustomCalendar,
|
|
22
|
+
isAttribute,
|
|
23
|
+
isDateColumn,
|
|
24
|
+
isDateFamilyColumn,
|
|
25
|
+
isDateNumColumn,
|
|
26
|
+
isTimeColumn,
|
|
27
|
+
} from './date-formatting';
|
|
28
|
+
|
|
29
|
+
describe('date-formatting', () => {
|
|
30
|
+
let col: ChartColumn;
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
col = {
|
|
33
|
+
id: 'testId',
|
|
34
|
+
name: 'test',
|
|
35
|
+
type: ColumnType.MEASURE,
|
|
36
|
+
timeBucket: ColumnTimeBucket.AUTO,
|
|
37
|
+
dataType: DataType.UNKNOWN,
|
|
38
|
+
calenderGuid: '12345',
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
test('isDateColumn should return true for DATE data type', () => {
|
|
42
|
+
col.dataType = DataType.DATE;
|
|
43
|
+
expect(isDateColumn(col)).toBe(true);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('isDateColumn should return true for DATE_TIME data type', () => {
|
|
47
|
+
col.dataType = DataType.DATE_TIME;
|
|
48
|
+
expect(isDateColumn(col)).toBe(true);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test('isAttribute should return true for ATTRIBUTE column type', () => {
|
|
52
|
+
col.type = ColumnType.ATTRIBUTE;
|
|
53
|
+
expect(isAttribute(col)).toBe(true);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test('isAttribute should return false for non-ATTRIBUTE column type', () => {
|
|
57
|
+
col.type = ColumnType.MEASURE;
|
|
58
|
+
expect(isAttribute(col)).toBe(false);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('getCustomCalendarGuidFromColumn should return the calendarGuid', () => {
|
|
62
|
+
col.calenderGuid = '12345';
|
|
63
|
+
expect(getCustomCalendarGuidFromColumn(col)).toBe('12345');
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('isDateNumColumn should return true for ATTRIBUTE type with specific time buckets', () => {
|
|
67
|
+
col.type = ColumnType.ATTRIBUTE;
|
|
68
|
+
col.timeBucket = ColumnTimeBucket.HOUR_OF_DAY;
|
|
69
|
+
expect(isDateNumColumn(col)).toBe(true);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test('isDateNumColumn should return false for non-ATTRIBUTE type', () => {
|
|
73
|
+
col.type = ColumnType.MEASURE;
|
|
74
|
+
col.timeBucket = ColumnTimeBucket.DAY_OF_WEEK;
|
|
75
|
+
expect(isDateNumColumn(col)).toBe(false);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test('isDateFamilyColumn should return true for DATE data type', () => {
|
|
79
|
+
col.dataType = DataType.DATE;
|
|
80
|
+
expect(isDateFamilyColumn(col)).toBe(true);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test('isDateFamilyColumn should return true for DATE_NUM column', () => {
|
|
84
|
+
col.type = ColumnType.ATTRIBUTE;
|
|
85
|
+
col.timeBucket = ColumnTimeBucket.DAY_OF_WEEK;
|
|
86
|
+
expect(isDateFamilyColumn(col)).toBe(true);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test('isTimeColumn should return true for TIME data type', () => {
|
|
90
|
+
col.dataType = DataType.TIME;
|
|
91
|
+
expect(isTimeColumn(col)).toBe(true);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
test('hasCustomCalendar should return true for date family columns with custom calendar', () => {
|
|
95
|
+
col.dataType = DataType.DATE;
|
|
96
|
+
col.calenderGuid = '12345';
|
|
97
|
+
expect(hasCustomCalendar(col)).toBe(true);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('getStartEpoch should return the start epoch from CustomCalendarDate', () => {
|
|
101
|
+
const date = {
|
|
102
|
+
v: { s: 12345, e: 12346 },
|
|
103
|
+
d: 'Custom_Date',
|
|
104
|
+
} as CustomCalendarDate;
|
|
105
|
+
expect(getStartEpoch(date)).toBe(date.v.s);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test('getStartEpoch should return null if start epoch is not present', () => {
|
|
109
|
+
const date = { v: {}, d: '01-07-2021' } as CustomCalendarDate;
|
|
110
|
+
expect(getStartEpoch(date)).toBe(null);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
test('getDisplayString should return display string if present', () => {
|
|
114
|
+
const date = { v: { s: 1625097600, e: 1625184000 }, d: '01-07-2021' };
|
|
115
|
+
expect(getDisplayString(date)).toBe('01-07-2021');
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test('getDisplayString should return null if display string is not present', () => {
|
|
119
|
+
const date = {
|
|
120
|
+
v: { s: 1625097600, e: 1625184000 },
|
|
121
|
+
} as CustomCalendarDate;
|
|
122
|
+
expect(getDisplayString(date)).toBe(null);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test('dateFormatter should return custom calendar display string if present', () => {
|
|
126
|
+
const dataValue = {
|
|
127
|
+
v: { s: 1625097600, e: 1625184000 },
|
|
128
|
+
d: '01-07-2021',
|
|
129
|
+
} as CustomCalendarDate;
|
|
130
|
+
col.dataType = DataType.DATE;
|
|
131
|
+
col.calenderGuid = '12345';
|
|
132
|
+
expect(dateFormatter(dataValue, col)).toBe('01-07-2021');
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
test('dateFormatter should return formatted date from start epoch if custom calendar display string is not present', () => {
|
|
136
|
+
const dataValue = {
|
|
137
|
+
v: { s: 1625097600, e: 1625184000 },
|
|
138
|
+
} as CustomCalendarDate;
|
|
139
|
+
col.dataType = DataType.DATE;
|
|
140
|
+
col.calenderGuid = '12345';
|
|
141
|
+
expect(dateFormatter(dataValue, col)).toBe('01-07-2021');
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test('dateFormatter should return null if start epoch is not present', () => {
|
|
145
|
+
const dataValue = { v: { e: 1625184000 } } as CustomCalendarDate;
|
|
146
|
+
col.dataType = DataType.DATE;
|
|
147
|
+
col.calenderGuid = '12345';
|
|
148
|
+
expect(dateFormatter(dataValue, col)).toBe(null);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test('dateFormatter should return formatted date for non-custom calendar column', () => {
|
|
152
|
+
const dataValue = 1625097600;
|
|
153
|
+
col.dataType = DataType.DATE;
|
|
154
|
+
col.calenderGuid = undefined;
|
|
155
|
+
expect(dateFormatter(dataValue, col)).toBe('01-07-2021');
|
|
156
|
+
});
|
|
157
|
+
test('dateFormatter should format the date based on custom calendar', () => {
|
|
158
|
+
col.dataType = DataType.DATE;
|
|
159
|
+
col.calenderGuid = '12345';
|
|
160
|
+
const date = {
|
|
161
|
+
v: { s: 12345, e: 12346 },
|
|
162
|
+
d: 'Custom_Date',
|
|
163
|
+
} as CustomCalendarDate;
|
|
164
|
+
expect(dateFormatter(date, col)).toBe(date.d);
|
|
165
|
+
});
|
|
166
|
+
});
|