snapshot of https://github.com/RocketChat/Rocket.Chat.git (develop, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 1s
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 1s
This commit is contained in:
210
packages/mongo-adapter/src/sort.spec.ts
Normal file
210
packages/mongo-adapter/src/sort.spec.ts
Normal file
@@ -0,0 +1,210 @@
|
||||
import { createComparatorFromSort } from './sort';
|
||||
|
||||
describe('createComparatorFromSort', () => {
|
||||
describe('object specification format', () => {
|
||||
it('should sort by a single field ascending', () => {
|
||||
const sorter = createComparatorFromSort({ name: 1 });
|
||||
|
||||
const a = { name: 'Alice' };
|
||||
const b = { name: 'Bob' };
|
||||
|
||||
expect(sorter(a, b)).toBeLessThan(0);
|
||||
expect(sorter(b, a)).toBeGreaterThan(0);
|
||||
expect(sorter(a, a)).toBe(0);
|
||||
});
|
||||
|
||||
it('should sort by a single field descending', () => {
|
||||
const sorter = createComparatorFromSort({ name: -1 });
|
||||
|
||||
const a = { name: 'Alice' };
|
||||
const b = { name: 'Bob' };
|
||||
|
||||
expect(sorter(a, b)).toBeGreaterThan(0);
|
||||
expect(sorter(b, a)).toBeLessThan(0);
|
||||
expect(sorter(a, a)).toBe(0);
|
||||
});
|
||||
|
||||
it('should handle multiple fields with different directions', () => {
|
||||
const sorter = createComparatorFromSort({ age: 1, name: -1 });
|
||||
|
||||
const a = { age: 30, name: 'Alice' };
|
||||
const b = { age: 30, name: 'Bob' };
|
||||
const c = { age: 25, name: 'Charlie' };
|
||||
|
||||
expect(sorter(a, b)).toBeGreaterThan(0); // Same age, name is used (desc)
|
||||
expect(sorter(a, c)).toBeGreaterThan(0); // Different age
|
||||
expect(sorter(c, b)).toBeLessThan(0); // Different age
|
||||
});
|
||||
|
||||
it('should handle when the first field has equal values', () => {
|
||||
const sorter = createComparatorFromSort({ age: 1, name: 1 });
|
||||
|
||||
const a = { age: 30, name: 'Alice' };
|
||||
const b = { age: 30, name: 'Bob' };
|
||||
|
||||
expect(sorter(a, b)).toBeLessThan(0); // Same age, name is used (asc)
|
||||
});
|
||||
|
||||
it('should handle missing fields', () => {
|
||||
const sorter = createComparatorFromSort({ age: 1 });
|
||||
|
||||
const a = { age: 30 };
|
||||
const b = {}; // Missing age
|
||||
|
||||
expect(sorter(a, b)).toBeGreaterThan(0); // undefined is considered smaller
|
||||
expect(sorter(b, a)).toBeLessThan(0);
|
||||
});
|
||||
|
||||
it('should sort numbers correctly', () => {
|
||||
const sorter = createComparatorFromSort({ score: 1 });
|
||||
|
||||
const a = { score: 100 };
|
||||
const b = { score: 50 };
|
||||
|
||||
expect(sorter(a, b)).toBeGreaterThan(0);
|
||||
expect(sorter(b, a)).toBeLessThan(0);
|
||||
});
|
||||
|
||||
it('should handle nested fields', () => {
|
||||
const sorter = createComparatorFromSort({ 'user.age': 1 });
|
||||
|
||||
const a = { user: { age: 30 } };
|
||||
const b = { user: { age: 25 } };
|
||||
|
||||
expect(sorter(a, b)).toBeGreaterThan(0);
|
||||
expect(sorter(b, a)).toBeLessThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('array specification format', () => {
|
||||
it('should sort using string array format', () => {
|
||||
const sorter = createComparatorFromSort(['name']);
|
||||
|
||||
const a = { name: 'Alice' };
|
||||
const b = { name: 'Bob' };
|
||||
|
||||
expect(sorter(a, b)).toBeLessThan(0);
|
||||
expect(sorter(b, a)).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should sort using field and direction array format', () => {
|
||||
const sorter = createComparatorFromSort([['name', 'desc']]);
|
||||
|
||||
const a = { name: 'Alice' };
|
||||
const b = { name: 'Bob' };
|
||||
|
||||
expect(sorter(a, b)).toBeGreaterThan(0);
|
||||
expect(sorter(b, a)).toBeLessThan(0);
|
||||
});
|
||||
|
||||
it('should handle mix of string and array formats', () => {
|
||||
// @ts-expect-error - mixing string and array formats is allowed
|
||||
const sorter = createComparatorFromSort(['age', ['name', 'desc']]);
|
||||
|
||||
const a = { age: 30, name: 'Alice' };
|
||||
const b = { age: 30, name: 'Bob' };
|
||||
|
||||
expect(sorter(a, b)).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should handle ascending in array format', () => {
|
||||
const sorter = createComparatorFromSort([['name', 'asc']]);
|
||||
|
||||
const a = { name: 'Alice' };
|
||||
const b = { name: 'Bob' };
|
||||
|
||||
expect(sorter(a, b)).toBeLessThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('array values handling', () => {
|
||||
it('should handle array values by selecting min value for ascending', () => {
|
||||
const sorter = createComparatorFromSort({ scores: 1 });
|
||||
|
||||
const a = { scores: [10, 20, 30] };
|
||||
const b = { scores: [5, 15, 25] };
|
||||
|
||||
expect(sorter(a, b)).toBe(5);
|
||||
});
|
||||
|
||||
it('should handle array values by selecting max value for descending', () => {
|
||||
const sorter = createComparatorFromSort({ scores: -1 });
|
||||
|
||||
const a = { scores: [10, 20, 30] };
|
||||
const b = { scores: [5, 15, 25] };
|
||||
|
||||
expect(sorter(a, b)).toBe(-5);
|
||||
});
|
||||
|
||||
it('should handle empty arrays', () => {
|
||||
const sorter = createComparatorFromSort({ scores: 1 });
|
||||
|
||||
const a = { scores: [] };
|
||||
const b = { scores: [5] };
|
||||
|
||||
expect(sorter(a, b)).toBeLessThan(0); // undefined vs 5
|
||||
});
|
||||
|
||||
it('should handle nested arrays', () => {
|
||||
const sorter = createComparatorFromSort({ 'users.scores': 1 });
|
||||
|
||||
const a = { users: [{ scores: [10, 5] }, { scores: [20, 15] }] };
|
||||
const b = { users: [{ scores: [8, 3] }, { scores: [18, 13] }] };
|
||||
|
||||
expect(sorter(a, b)).toBeGreaterThan(0); // Should compare minimums
|
||||
});
|
||||
});
|
||||
|
||||
describe('edge cases', () => {
|
||||
it('should handle empty sort specification', () => {
|
||||
const sorter = createComparatorFromSort({});
|
||||
|
||||
const a = { name: 'Alice' };
|
||||
const b = { name: 'Bob' };
|
||||
|
||||
expect(sorter(a, b)).toBe(0); // No sort criteria so all docs equal
|
||||
});
|
||||
|
||||
it('should handle empty array sort specification', () => {
|
||||
const sorter = createComparatorFromSort([]);
|
||||
|
||||
const a = { name: 'Alice' };
|
||||
const b = { name: 'Bob' };
|
||||
|
||||
expect(sorter(a, b)).toBe(0); // No sort criteria so all docs equal
|
||||
});
|
||||
|
||||
it('should sort by multiple fields when first fields are equal', () => {
|
||||
const sorter = createComparatorFromSort({ lastName: 1, firstName: 1 });
|
||||
|
||||
const a = { lastName: 'Smith', firstName: 'Alice' };
|
||||
const b = { lastName: 'Smith', firstName: 'Bob' };
|
||||
const c = { lastName: 'Jones', firstName: 'Charlie' };
|
||||
|
||||
expect(sorter(a, b)).toBeLessThan(0); // Same last name, different first name
|
||||
expect(sorter(a, c)).toBeGreaterThan(0); // Different last names
|
||||
});
|
||||
|
||||
it('should handle objects and scalars in the same comparison', () => {
|
||||
const sorter = createComparatorFromSort({ data: 1 });
|
||||
|
||||
const a = { data: { value: 10 } };
|
||||
const b = { data: 5 };
|
||||
|
||||
// This tests that the BSON comparison works correctly for different types
|
||||
expect(typeof sorter(a, b)).toBe('number'); // Should return a number without error
|
||||
});
|
||||
|
||||
it('should handle null and undefined values', () => {
|
||||
const sorter = createComparatorFromSort({ value: 1 });
|
||||
|
||||
const a = { value: null };
|
||||
const b = {};
|
||||
const c = { value: 0 };
|
||||
|
||||
expect(sorter(a, c)).toBeLessThan(0); // null is less than 0
|
||||
expect(sorter(b, c)).toBeLessThan(0); // undefined is less than 0
|
||||
expect(sorter(a, b)).toBeGreaterThan(0); // undefined is less than null
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user