Skip to content

Commit

Permalink
Add groupByDate tests (#346)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergio Clebal authored Feb 21, 2022
1 parent 4a622c2 commit 72ee22a
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 31 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Not released

- Add groupByDate tests [#346](https://github.com/CartoDB/carto-react/pull/346)

## 1.2

### 1.2.1-beta.7 (2022-02-18)
Expand Down
155 changes: 155 additions & 0 deletions packages/react-core/__tests__/operations/groupByDate.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import { AggregationTypes } from '../../src/operations/aggregation/AggregationTypes';
import { GroupDateTypes } from '../../src/operations/GroupDateTypes';
import { groupValuesByDateColumn } from '../../src/operations/groupByDate';

const REVENUE = 50;

const DATES_VALUES = [
Date.UTC(1970, 0, 1, 0, 0),
Date.UTC(1970, 0, 1, 0, 30),
Date.UTC(1970, 1, 1, 0, 0),
Date.UTC(1970, 1, 1, 0, 30),
Date.UTC(1971, 0, 1, 1, 0)
];

const DATE_COLUMN = 'test_date';
const OPERATION_COLUMN = 'test_revenue';

const FEATURES = DATES_VALUES.map((value) => ({
[DATE_COLUMN]: value,
[OPERATION_COLUMN]: REVENUE
}));

describe('groupValuesByDateColumn', () => {
test('should return null due to empty data array', () => {
expect(groupValuesByDateColumn([])).toEqual(null);
});

describe('valid features', () => {
test('should return null due to invalid grouping operation', () => {
expect(
groupValuesByDateColumn(
FEATURES,
OPERATION_COLUMN,
DATE_COLUMN,
'__fake_group_type__',
AggregationTypes.COUNT
)
).toEqual(null);
});

test('should return an empty array due to invalid operation', () => {
expect(
groupValuesByDateColumn(
FEATURES,
OPERATION_COLUMN,
DATE_COLUMN,
GroupDateTypes.DAYS,
'__fake_operation__'
)
).toEqual([]);
});

describe('grouping operation tests', () => {
const params = {
features: FEATURES,
valuesColumn: OPERATION_COLUMN,
keysColumn: DATE_COLUMN
};

test(GroupDateTypes.YEARS, () => {
params.operation = GroupDateTypes.YEARS;

const RESULT = [
{ name: Date.UTC(1970, 0, 1), value: 4 },
{ name: Date.UTC(1971, 0, 1), value: 1 }
];

executeGroupByDateFnTests(params, RESULT);
});

test(GroupDateTypes.MONTHS, () => {
params.operation = GroupDateTypes.MONTHS;

const RESULT = [
{ name: Date.UTC(1970, 0, 1), value: 2 },
{ name: Date.UTC(1970, 1, 1), value: 2 },
{ name: Date.UTC(1971, 0, 1), value: 1 }
];

executeGroupByDateFnTests(params, RESULT);
});

test(GroupDateTypes.WEEKS, () => {
params.operation = GroupDateTypes.WEEKS;

const RESULT = [
{ name: Date.UTC(1969, 11, 29), value: 2 },
{ name: Date.UTC(1970, 0, 26), value: 2 },
{ name: Date.UTC(1970, 11, 28), value: 1 }
];

executeGroupByDateFnTests(params, RESULT);
});

test(GroupDateTypes.DAYS, () => {
params.operation = GroupDateTypes.DAYS;

const RESULT = [
{ name: Date.UTC(1970, 0, 1), value: 2 },
{ name: Date.UTC(1970, 1, 1), value: 2 },
{ name: Date.UTC(1971, 0, 1), value: 1 }
];

executeGroupByDateFnTests(params, RESULT);
});

test(GroupDateTypes.HOURS, () => {
params.operation = GroupDateTypes.HOURS;

const RESULT = [
{ name: Date.UTC(1970, 0, 1, 0, 0), value: 2 },
{ name: Date.UTC(1970, 1, 1, 0, 0), value: 2 },
{ name: Date.UTC(1971, 0, 1, 1, 0), value: 1 }
];

executeGroupByDateFnTests(params, RESULT);
});

test(GroupDateTypes.MINUTES, () => {
params.operation = GroupDateTypes.MINUTES;

const RESULT = DATES_VALUES.map((dateValue) => ({ name: dateValue, value: 1 }));

executeGroupByDateFnTests(params, RESULT);
});
});
});

describe('invalid features', () => {
test('invalid date columns are not taken into consideration', () => {
const h = groupValuesByDateColumn(
[{ [DATE_COLUMN]: '__non_number__', [OPERATION_COLUMN]: 100 }],
OPERATION_COLUMN,
DATE_COLUMN,
GroupDateTypes.DAYS,
AggregationTypes.COUNT
);
expect(h).toEqual([]);
});
});
});

// Aux
function executeGroupByDateFnTests(args, result) {
const sumResult = result.map((item) => ({
...item,
value: item.value * REVENUE
}));

[AggregationTypes.COUNT, AggregationTypes.SUM].forEach((aggregation, idx) =>
expect(groupValuesByDateColumn(...Object.values(args), aggregation)).toEqual(
idx ? sumResult : result
)
);
}
50 changes: 26 additions & 24 deletions packages/react-core/src/operations/groupByDate.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,25 @@ import { GroupDateTypes } from './GroupDateTypes';

const GROUP_KEY_FN_MAPPING = {
// @ts-ignore
[GroupDateTypes.YEARS]: (date) => new Date(Date.UTC(date.getFullYear())),
[GroupDateTypes.MONTHS]: (date) =>
new Date(Date.UTC(date.getFullYear(), date.getMonth())),
[GroupDateTypes.YEARS]: (date) => Date.UTC(date.getUTCFullYear()),
[GroupDateTypes.MONTHS]: (date) => Date.UTC(date.getUTCFullYear(), date.getUTCMonth()),
[GroupDateTypes.WEEKS]: (date) => getMonday(date),
[GroupDateTypes.DAYS]: (date) =>
new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())),
Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()),
[GroupDateTypes.HOURS]: (date) =>
new Date(
Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours())
Date.UTC(
date.getUTCFullYear(),
date.getUTCMonth(),
date.getUTCDate(),
date.getUTCHours()
),
[GroupDateTypes.MINUTES]: (date) =>
new Date(
Date.UTC(
date.getFullYear(),
date.getMonth(),
date.getDate(),
date.getHours(),
date.getMinutes()
)
Date.UTC(
date.getUTCFullYear(),
date.getUTCMonth(),
date.getUTCDate(),
date.getUTCHours(),
date.getUTCMinutes()
)
};

Expand All @@ -46,19 +46,21 @@ export function groupValuesByDateColumn(
const groups = data.reduce((acc, item) => {
const value = item[keysColumn];
const formattedValue = new Date(value);
const group = groupKeyFn(formattedValue).getTime();
const groupKey = groupKeyFn(formattedValue);

let groupedValues = acc.get(group);
if (!groupedValues) {
groupedValues = [];
acc.set(group, groupedValues);
}
if (!isNaN(groupKey)) {
let groupedValues = acc.get(groupKey);
if (!groupedValues) {
groupedValues = [];
acc.set(groupKey, groupedValues);
}

const isValid = item[valuesColumn] !== null && item[valuesColumn] !== undefined;
const isValid = item[valuesColumn] !== null && item[valuesColumn] !== undefined;

if (isValid) {
groupedValues.push(item[valuesColumn]);
acc.set(group, groupedValues);
if (isValid) {
groupedValues.push(item[valuesColumn]);
acc.set(groupKey, groupedValues);
}
}

return acc;
Expand Down
11 changes: 5 additions & 6 deletions packages/react-core/src/utils/dateUtils.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
export function getMonday(date) {
const day = date.getDay();
const diff = date.getDate() - day + (day ? 1 : -6); // adjust when day is sunday
date.setDate(diff);
// Ignore hours
date.setHours(0, 0, 0, 0);
return date;
const dateCp = new Date(date);
const day = dateCp.getDay();
const diff = dateCp.getDate() - day + (day ? 1 : -6); // adjust when day is sunday
dateCp.setDate(diff);
return Date.UTC(dateCp.getUTCFullYear(), dateCp.getUTCMonth(), dateCp.getUTCDate());
}
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ function daysCurrentDateRange(date) {
}

function weeksCurrentDateRange(date) {
return `Week of ${getMonday(date).toLocaleDateString()}`;
return `Week of ${new Date(getMonday(date)).toLocaleDateString()}`;
}

function yearCurrentDateRange(date) {
Expand Down

0 comments on commit 72ee22a

Please sign in to comment.