Skip to content

Commit 7ab18f5

Browse files
authored
chore: add date sorting functionality to pipe (RocketChat#36438)
1 parent 1830e7f commit 7ab18f5

2 files changed

Lines changed: 57 additions & 45 deletions

File tree

apps/meteor/client/lib/cachedCollections/pipe.spec.ts

Lines changed: 53 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,31 @@ describe('pipe', () => {
55
_id: number;
66
name: string;
77
ts: number;
8+
date: Date;
89
}
910

1011
const sampleData: ITestData[] = [
11-
{ _id: 1, name: 'Alice', ts: 30 },
12-
{ _id: 2, name: 'Charlie', ts: 25 },
13-
{ _id: 3, name: 'Bob', ts: 35 },
14-
{ _id: 4, name: 'David', ts: 20 },
15-
{ _id: 5, name: 'Eve', ts: 40 },
12+
{ _id: 1, name: 'Alice', ts: 30, date: new Date('2025-07-16T01:00:00.000Z') },
13+
{ _id: 2, name: 'Charlie', ts: 25, date: new Date('2025-07-16T02:00:00.000Z') },
14+
{ _id: 3, name: 'Bob', ts: 35, date: new Date('2025-07-16T03:00:00.000Z') },
15+
{ _id: 4, name: 'David', ts: 20, date: new Date('2025-07-16T04:00:00.000Z') },
16+
{ _id: 5, name: 'Eve', ts: 40, date: new Date('2025-07-16T05:00:00.000Z') },
1617
];
1718

1819
it('should correctly slice the array with skip and limit', () => {
1920
const result = pipe<ITestData>().slice(1, 2).apply(sampleData);
2021
expect(result).toEqual([
21-
{ _id: 2, name: 'Charlie', ts: 25 },
22-
{ _id: 3, name: 'Bob', ts: 35 },
22+
{ _id: 2, name: 'Charlie', ts: 25, date: new Date('2025-07-16T02:00:00.000Z') },
23+
{ _id: 3, name: 'Bob', ts: 35, date: new Date('2025-07-16T03:00:00.000Z') },
2324
]);
2425
});
2526

2627
it('should correctly slice the array with only limit', () => {
2728
const result = pipe<ITestData>().slice(0, 3).apply(sampleData);
2829
expect(result).toEqual([
29-
{ _id: 1, name: 'Alice', ts: 30 },
30-
{ _id: 2, name: 'Charlie', ts: 25 },
31-
{ _id: 3, name: 'Bob', ts: 35 },
30+
{ _id: 1, name: 'Alice', ts: 30, date: new Date('2025-07-16T01:00:00.000Z') },
31+
{ _id: 2, name: 'Charlie', ts: 25, date: new Date('2025-07-16T02:00:00.000Z') },
32+
{ _id: 3, name: 'Bob', ts: 35, date: new Date('2025-07-16T03:00:00.000Z') },
3233
]);
3334
});
3435

@@ -40,71 +41,78 @@ describe('pipe', () => {
4041
it('should return remaining elements if limit is greater than available', () => {
4142
const result = pipe<ITestData>().slice(3, 10).apply(sampleData);
4243
expect(result).toEqual([
43-
{ _id: 4, name: 'David', ts: 20 },
44-
{ _id: 5, name: 'Eve', ts: 40 },
44+
{ _id: 4, name: 'David', ts: 20, date: new Date('2025-07-16T04:00:00.000Z') },
45+
{ _id: 5, name: 'Eve', ts: 40, date: new Date('2025-07-16T05:00:00.000Z') },
4546
]);
4647
});
4748

4849
it('should sort the array by a string field in ascending order', () => {
4950
const result = pipe<ITestData>().sortByField('name', 1).apply(sampleData);
5051
expect(result).toEqual([
51-
{ _id: 1, name: 'Alice', ts: 30 },
52-
{ _id: 3, name: 'Bob', ts: 35 },
53-
{ _id: 2, name: 'Charlie', ts: 25 },
54-
{ _id: 4, name: 'David', ts: 20 },
55-
{ _id: 5, name: 'Eve', ts: 40 },
52+
{ _id: 1, name: 'Alice', ts: 30, date: new Date('2025-07-16T01:00:00.000Z') },
53+
{ _id: 3, name: 'Bob', ts: 35, date: new Date('2025-07-16T03:00:00.000Z') },
54+
{ _id: 2, name: 'Charlie', ts: 25, date: new Date('2025-07-16T02:00:00.000Z') },
55+
{ _id: 4, name: 'David', ts: 20, date: new Date('2025-07-16T04:00:00.000Z') },
56+
{ _id: 5, name: 'Eve', ts: 40, date: new Date('2025-07-16T05:00:00.000Z') },
5657
]);
5758
});
5859

60+
it('should sort the array by a date field in ascending order', () => {
61+
const result = pipe<ITestData>()
62+
.sortByField('date', 1)
63+
.apply([...sampleData].sort(() => Math.random() - 0.5));
64+
expect(result).toEqual(sampleData);
65+
});
66+
5967
it('should sort the array by a string field in descending order', () => {
6068
const result = pipe<ITestData>().sortByField('name', -1).apply(sampleData);
6169
expect(result).toEqual([
62-
{ _id: 5, name: 'Eve', ts: 40 },
63-
{ _id: 4, name: 'David', ts: 20 },
64-
{ _id: 2, name: 'Charlie', ts: 25 },
65-
{ _id: 3, name: 'Bob', ts: 35 },
66-
{ _id: 1, name: 'Alice', ts: 30 },
70+
{ _id: 5, name: 'Eve', ts: 40, date: new Date('2025-07-16T05:00:00.000Z') },
71+
{ _id: 4, name: 'David', ts: 20, date: new Date('2025-07-16T04:00:00.000Z') },
72+
{ _id: 2, name: 'Charlie', ts: 25, date: new Date('2025-07-16T02:00:00.000Z') },
73+
{ _id: 3, name: 'Bob', ts: 35, date: new Date('2025-07-16T03:00:00.000Z') },
74+
{ _id: 1, name: 'Alice', ts: 30, date: new Date('2025-07-16T01:00:00.000Z') },
6775
]);
6876
});
6977

7078
it('should sort the array by a number field in ascending order', () => {
7179
const result = pipe<ITestData>().sortByField('ts', 1).apply(sampleData);
7280
expect(result).toEqual([
73-
{ _id: 4, name: 'David', ts: 20 },
74-
{ _id: 2, name: 'Charlie', ts: 25 },
75-
{ _id: 1, name: 'Alice', ts: 30 },
76-
{ _id: 3, name: 'Bob', ts: 35 },
77-
{ _id: 5, name: 'Eve', ts: 40 },
81+
{ _id: 4, name: 'David', ts: 20, date: new Date('2025-07-16T04:00:00.000Z') },
82+
{ _id: 2, name: 'Charlie', ts: 25, date: new Date('2025-07-16T02:00:00.000Z') },
83+
{ _id: 1, name: 'Alice', ts: 30, date: new Date('2025-07-16T01:00:00.000Z') },
84+
{ _id: 3, name: 'Bob', ts: 35, date: new Date('2025-07-16T03:00:00.000Z') },
85+
{ _id: 5, name: 'Eve', ts: 40, date: new Date('2025-07-16T05:00:00.000Z') },
7886
]);
7987
});
8088

8189
it('should sort the array by a number field in descending order', () => {
8290
const result = pipe<ITestData>().sortByField('ts', -1).apply(sampleData);
8391
expect(result).toEqual([
84-
{ _id: 5, name: 'Eve', ts: 40 },
85-
{ _id: 3, name: 'Bob', ts: 35 },
86-
{ _id: 1, name: 'Alice', ts: 30 },
87-
{ _id: 2, name: 'Charlie', ts: 25 },
88-
{ _id: 4, name: 'David', ts: 20 },
92+
{ _id: 5, name: 'Eve', ts: 40, date: new Date('2025-07-16T05:00:00.000Z') },
93+
{ _id: 3, name: 'Bob', ts: 35, date: new Date('2025-07-16T03:00:00.000Z') },
94+
{ _id: 1, name: 'Alice', ts: 30, date: new Date('2025-07-16T01:00:00.000Z') },
95+
{ _id: 2, name: 'Charlie', ts: 25, date: new Date('2025-07-16T02:00:00.000Z') },
96+
{ _id: 4, name: 'David', ts: 20, date: new Date('2025-07-16T04:00:00.000Z') },
8997
]);
9098
});
9199

92100
it('should apply chained operations correctly (sort then slice)', () => {
93101
const result = pipe<ITestData>().sortByField('ts').slice(1, 3).apply(sampleData);
94102
expect(result).toEqual([
95-
{ _id: 2, name: 'Charlie', ts: 25 },
96-
{ _id: 1, name: 'Alice', ts: 30 },
97-
{ _id: 3, name: 'Bob', ts: 35 },
103+
{ _id: 2, name: 'Charlie', ts: 25, date: new Date('2025-07-16T02:00:00.000Z') },
104+
{ _id: 1, name: 'Alice', ts: 30, date: new Date('2025-07-16T01:00:00.000Z') },
105+
{ _id: 3, name: 'Bob', ts: 35, date: new Date('2025-07-16T03:00:00.000Z') },
98106
]);
99107
});
100108

101109
it('should apply chained operations correctly (slice then sort)', () => {
102110
const result = pipe<ITestData>().slice(0, 4).sortByField('name', -1).apply(sampleData);
103111
expect(result).toEqual([
104-
{ _id: 4, name: 'David', ts: 20 },
105-
{ _id: 2, name: 'Charlie', ts: 25 },
106-
{ _id: 3, name: 'Bob', ts: 35 },
107-
{ _id: 1, name: 'Alice', ts: 30 },
112+
{ _id: 4, name: 'David', ts: 20, date: new Date('2025-07-16T04:00:00.000Z') },
113+
{ _id: 2, name: 'Charlie', ts: 25, date: new Date('2025-07-16T02:00:00.000Z') },
114+
{ _id: 3, name: 'Bob', ts: 35, date: new Date('2025-07-16T03:00:00.000Z') },
115+
{ _id: 1, name: 'Alice', ts: 30, date: new Date('2025-07-16T01:00:00.000Z') },
108116
]);
109117
});
110118

@@ -120,8 +128,8 @@ describe('pipe', () => {
120128

121129
const result = combinedPipeline.apply(sampleData);
122130
expect(result).toEqual([
123-
{ _id: 3, name: 'Bob', ts: 35 },
124-
{ _id: 2, name: 'Charlie', ts: 25 },
131+
{ _id: 3, name: 'Bob', ts: 35, date: new Date('2025-07-16T03:00:00.000Z') },
132+
{ _id: 2, name: 'Charlie', ts: 25, date: new Date('2025-07-16T02:00:00.000Z') },
125133
]);
126134
});
127135

@@ -134,8 +142,8 @@ describe('pipe', () => {
134142
// Expected order after ts sort: David, Charlie, Alice, Bob, Eve
135143
// Slice(2,2) should take: Alice, Bob
136144
expect(result).toEqual([
137-
{ _id: 1, name: 'Alice', ts: 30 },
138-
{ _id: 3, name: 'Bob', ts: 35 },
145+
{ _id: 1, name: 'Alice', ts: 30, date: new Date('2025-07-16T01:00:00.000Z') },
146+
{ _id: 3, name: 'Bob', ts: 35, date: new Date('2025-07-16T03:00:00.000Z') },
139147
]);
140148
});
141149

@@ -167,8 +175,8 @@ describe('pipe', () => {
167175
it('should slice the array with skip and limit', () => {
168176
const result = pipe(sampleData).slice(1, 2).apply();
169177
expect(result).toEqual([
170-
{ _id: 2, name: 'Charlie', ts: 25 },
171-
{ _id: 3, name: 'Bob', ts: 35 },
178+
{ _id: 2, name: 'Charlie', ts: 25, date: new Date('2025-07-16T02:00:00.000Z') },
179+
{ _id: 3, name: 'Bob', ts: 35, date: new Date('2025-07-16T03:00:00.000Z') },
172180
]);
173181
});
174182
});

apps/meteor/client/lib/cachedCollections/pipe.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ export function pipe<D>(
4444
const aValue = a[fieldName];
4545
const bValue = b[fieldName];
4646

47+
if (aValue instanceof Date && bValue instanceof Date) {
48+
return direction * (aValue.getTime() - bValue.getTime());
49+
}
50+
4751
if (typeof aValue === 'string' && typeof bValue === 'string') {
4852
return direction * aValue.localeCompare(bValue);
4953
}

0 commit comments

Comments
 (0)