import { INITIAL_STATE } from '../state' import type { ColumnSortDetails, GridState } from '../state/types' import type { SortDirection } from '../types' import { buildSort } from './build-sort' describe('sortReducer', () => { describe('buildSort', () => { let columns: GridState['columns']['sortEntities'] let rows: GridState['rows']['collection'] beforeEach(() => { rows = { ...INITIAL_STATE.rows.collection, ids: ['1', '2', '3'], entities: new Map( Object.entries({ 1: { id: '1', title: 'Book 2: Adventure Series', altTitle: 'Book 2: Adventure Series', }, 2: { id: '2', title: 'Book 1: Adventure Series', altTitle: 'Book 1: Adventure Series', }, 3: { id: '3', title: 'Book 10: Adventure Series', altTitle: 'Book 10: Adventure Series', }, }) ), meta: new Map(), } }) describe('without value getters', () => { beforeEach(() => { columns = { title: { sortStrategy: 'natural', }, count: { sortStrategy: 'fast', }, } }) it('should sort with ascending, natural sort', () => { const sort = buildSort( [{ columnId: 'title', direction: 'asc' }], 'en-US', columns ) const results = sort(rows.ids, rows.entities, rows.meta) expect(results).toEqual(['2', '1', '3']) }) it('should sort with descending, natural sort', () => { const sort = buildSort( [{ columnId: 'title', direction: 'desc' }], 'en-US', columns ) const results = sort(rows.ids, rows.entities, rows.meta) expect(results).toEqual(['3', '1', '2']) }) it('should sort with ascending, fast sort', () => { const sort = buildSort( [{ columnId: 'altTitle', direction: 'asc' }], 'en-US', columns ) const results = sort(rows.ids, rows.entities, rows.meta) expect(results).toEqual(['3', '2', '1']) }) it('should sort with descending, fast sort', () => { const sort = buildSort( [{ columnId: 'altTitle', direction: 'desc' }], 'en-US', columns ) const results = sort(rows.ids, rows.entities, rows.meta) expect(results).toEqual(['1', '2', '3']) }) }) describe('with value getters', () => { beforeEach(() => { columns = { title: { sortStrategy: 'natural', valueLookup({ row }) { return `${3 - Number(row.id)} ${row.title}` }, }, count: { sortStrategy: 'fast', }, } rows = { ...INITIAL_STATE.rows, ids: ['1', '2', '3'], entities: new Map( Object.entries({ 1: { id: '1', title: 'Book 2: Adventure Series', altTitle: 'Book 2: Adventure Series', }, 2: { id: '2', title: 'Book 1: Adventure Series', altTitle: 'Book 1: Adventure Series', }, 3: { id: '3', title: 'Book 10: Adventure Series', altTitle: 'Book 10: Adventure Series', }, }) ), meta: new Map(), } }) it('should sort with ascending, natural sort', () => { const sort = buildSort( [{ columnId: 'title', direction: 'asc' }], 'en-US', columns ) const results = sort(rows.ids, rows.entities, rows.meta) expect(results).toEqual(['3', '2', '1']) }) it('should sort with descending, natural sort', () => { const sort = buildSort( [{ columnId: 'title', direction: 'desc' }], 'en-US', columns ) const results = sort(rows.ids, rows.entities, rows.meta) expect(results).toEqual(['1', '2', '3']) }) it('should not error when row data has not loaded', () => { const sort = buildSort( [{ columnId: 'title', direction: 'desc' }], 'en-US', columns ) const results = sort(rows.ids, new Map(), new Map()) expect(results).toEqual(['1', '2', '3']) }) }) describe('with missing values', () => { beforeEach(() => { rows = { ...INITIAL_STATE.rows, ids: ['1', '2', '3', '4', '5', '6'], entities: new Map( Object.entries({ 1: { id: '1', title: 'Book 2: Adventure Series', altTitle: 'Book 2: Adventure Series', }, 2: { id: '2', title: 'Book 1: Adventure Series', altTitle: 'Book 1: Adventure Series', }, 3: { id: '3', title: 'Book 10: Adventure Series', altTitle: 'Book 10: Adventure Series', }, 4: { id: '4', title: undefined, altTitle: undefined, }, 5: { id: '5', title: null, altTitle: undefined, }, 6: { id: '6', title: '', altTitle: undefined, }, }) ), meta: new Map(), } }) it.each< [ ColumnSortDetails['sortStrategy'], ColumnSortDetails['sortEmptyAs'], SortDirection, string[], ] >([ /* Treat as low */ ['natural', 'low', 'asc', ['4', '5', '6', '2', '1', '3']], ['natural', 'low', 'desc', ['3', '1', '2', '4', '5', '6']], ['fast', 'low', 'asc', ['4', '5', '6', '3', '2', '1']], ['fast', 'low', 'desc', ['1', '2', '3', '4', '5', '6']], /* Treat as high */ ['natural', 'high', 'asc', ['2', '1', '3', '4', '5', '6']], ['natural', 'high', 'desc', ['4', '5', '6', '3', '1', '2']], ['fast', 'high', 'asc', ['3', '2', '1', '4', '5', '6']], ['fast', 'high', 'desc', ['4', '5', '6', '1', '2', '3']], /* Always first */ [ 'natural', 'always-first', 'asc', ['4', '5', '6', '2', '1', '3'], ], [ 'natural', 'always-first', 'desc', ['4', '5', '6', '3', '1', '2'], ], ['fast', 'always-first', 'asc', ['4', '5', '6', '3', '2', '1']], [ 'fast', 'always-first', 'desc', ['4', '5', '6', '1', '2', '3'], ], /* Always last */ [ 'natural', 'always-last', 'asc', ['2', '1', '3', '4', '5', '6'], ], [ 'natural', 'always-last', 'desc', ['3', '1', '2', '4', '5', '6'], ], ['fast', 'always-last', 'asc', ['3', '2', '1', '4', '5', '6']], ['fast', 'always-last', 'desc', ['1', '2', '3', '4', '5', '6']], ])( 'with sortStrategy %s, sortEmptyAs %s, direction %s', (sortStrategy, sortEmptyAs, direction, expectedResult) => { columns = { title: { sortStrategy, sortEmptyAs, }, } const sort = buildSort( [{ columnId: 'title', direction }], 'en-US', columns ) const results = sort(rows.ids, rows.entities, rows.meta) expect(results).toEqual(expectedResult) } ) }) }) })