test/sort.test.ts   A
last analyzed

Complexity

Total Complexity 1
Complexity/F 1

Size

Lines of Code 212
Function Count 1

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 170
dl 0
loc 212
rs 10
c 0
b 0
f 0
wmc 1
mnd 0
bc 0
fnc 1
bpm 0
cpm 1
noi 0
1
import { sort } from '../src'
2
3
describe('sort', () => {
4
  it('should sort an object in ascending order by default', () => {
5
    const input = { c: 'c', b: 'b', a: 'a' }
6
    const expected = { a: 'a', b: 'b', c: 'c' }
7
    expect(sort(input)).toEqual(expected)
8
  })
9
10
  it('should sort an object in descending order when specified', () => {
11
    const input = { a: 'a', b: 'b', c: 'c' }
12
    const expected = { c: 'c', b: 'b', a: 'a' }
13
    expect(sort(input, false)).toEqual(expected)
14
  })
15
16
  it('should not modify an array of primitives', () => {
17
    const input = ['b', 'a', 'c']
18
    expect(sort(input)).toEqual(input)
19
  })
20
21
  it('should sort an array of objects', () => {
22
    const input = [
23
      { b: 'b', a: 'a' },
24
      { d: 'd', c: 'c' },
25
    ]
26
    const expected = [
27
      { a: 'a', b: 'b' },
28
      { c: 'c', d: 'd' },
29
    ]
30
    expect(sort(input)).toEqual(expected)
31
  })
32
33
  it('should sort nested objects', () => {
34
    const input = {
35
      b: { z: 'z', y: 'y' },
36
      a: { x: 'x', w: 'w' },
37
    }
38
    const expected = {
39
      a: { w: 'w', x: 'x' },
40
      b: { y: 'y', z: 'z' },
41
    }
42
    expect(sort(input)).toEqual(expected)
43
  })
44
45
  it('should handle mixed nested structures', () => {
46
    const input = {
47
      b: ['b', 'a'],
48
      a: { d: 'd', c: 'c' },
49
    }
50
    const expected = {
51
      a: { c: 'c', d: 'd' },
52
      b: ['b', 'a'],
53
    }
54
    expect(sort(input)).toEqual(expected)
55
  })
56
57
  it('should return primitive inputs unchanged', () => {
58
    expect(sort('string')).toBe('string')
59
    expect(sort(123)).toBe(123)
60
    expect(sort(true)).toBe(true)
61
    expect(sort(null)).toBe(null)
62
    expect(sort(undefined)).toBe(undefined)
63
  })
64
65
  it('should handle deeply nested objects and arrays', () => {
66
    const input = {
67
      z: {
68
        y: [
69
          { c: 3, b: 2, a: 1 },
70
          { f: 6, e: 5, d: 4 }
71
        ],
72
        x: {
73
          w: { beta: 'β', alpha: 'α', gamma: 'γ' },
74
          v: [3, 1, 4, 1, 5, 9, 2, 6, 5]
75
        }
76
      },
77
      a: [
78
        { foo: { bar: { baz: 'qux' } } },
79
        [{ nested: { array: [3, 2, 1] } }]
80
      ]
81
    }
82
    const expected = {
83
      a: [
84
        { foo: { bar: { baz: 'qux' } } },
85
        [{ nested: { array: [3, 2, 1] } }]
86
      ],
87
      z: {
88
        x: {
89
          v: [3, 1, 4, 1, 5, 9, 2, 6, 5],
90
          w: { alpha: 'α', beta: 'β', gamma: 'γ' }
91
        },
92
        y: [
93
          { a: 1, b: 2, c: 3 },
94
          { d: 4, e: 5, f: 6 }
95
        ]
96
      }
97
    }
98
    expect(sort(input)).toEqual(expected)
99
  })
100
101
  it('should handle objects with various value types', () => {
102
    const date = new Date('2023-01-01')
103
    const regex = /regex/
104
    const func = () => 'function'
105
    const input = {
106
      e: date,
107
      d: regex,
108
      c: [1, 2, 3],
109
      b: { nested: 'object' },
110
      a: func
111
    }
112
    const expected = {
113
      a: func,
114
      b: { nested: 'object' },
115
      c: [1, 2, 3],
116
      d: regex,
117
      e: date
118
    }
119
    expect(sort(input)).toEqual(expected)
120
    expect(sort(input).e).toBe(date)
121
    expect(sort(input).d).toBe(regex)
122
    expect(sort(input).a).toBe(func)
123
  })
124
125
  it('should sort keys that are numbers or can be coerced to numbers', () => {
126
    const input = {
127
      '10': 'ten',
128
      '1': 'one',
129
      '2': 'two',
130
      foo: 'bar'
131
    }
132
    const expected = {
133
      '1': 'one',
134
      '2': 'two',
135
      '10': 'ten',
136
      foo: 'bar'
137
    }
138
    expect(sort(input)).toEqual(expected)
139
  })
140
141
  it('should not sort non-sortable objects', () => {
142
    const date = new Date('2023-01-01')
143
    const regex = /test/
144
    const func = () => {}
145
    const error = new Error('test')
146
    const map = new Map()
147
    const set = new Set()
148
    const weakMap = new WeakMap()
149
    const weakSet = new WeakSet()
150
    const promise = Promise.resolve()
151
    const iterable = {
152
      *[Symbol.iterator]() {
153
        yield 1
154
        yield 2
155
      }
156
    }
157
158
    const input = {
159
      date,
160
      regex,
161
      func,
162
      error,
163
      map,
164
      set,
165
      weakMap,
166
      weakSet,
167
      promise,
168
      iterable
169
    }
170
171
    const result = sort(input) as typeof input
172
173
    expect(result).toEqual({
174
      date,
175
      error,
176
      func,
177
      iterable,
178
      map,
179
      promise,
180
      regex,
181
      set,
182
      weakMap,
183
      weakSet
184
    })
185
186
    // Ensure the objects are the same instances
187
    Object.keys(input).forEach(key => {
188
      expect(result[key as keyof typeof input]).toBe(input[key as keyof typeof input])
189
    })
190
  })
191
192
  it('should handle empty objects and arrays', () => {
193
    expect(sort({})).toEqual({})
194
    expect(sort([])).toEqual([])
195
  })
196
197
  it('should handle objects with symbol keys', () => {
198
    const sym1 = Symbol('test1')
199
    const sym2 = Symbol('test2')
200
    const input = {
201
      [sym1]: 'value1',
202
      [sym2]: 'value2',
203
      c: 'c',
204
      a: 'a',
205
      b: 'b'
206
    }
207
    const result = sort(input)
208
    expect(Object.getOwnPropertySymbols(result)).toEqual([sym1, sym2])
209
    expect(Object.keys(result)).toEqual(['a', 'b', 'c'])
210
  })
211
})
212