coh-content-db 2.0.0-rc.4 → 2.0.0-rc.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -4
- package/dist/coh-content-db.d.ts +189 -68
- package/dist/coh-content-db.js +323 -229
- package/dist/coh-content-db.js.map +1 -1
- package/dist/coh-content-db.mjs +317 -228
- package/dist/coh-content-db.mjs.map +1 -1
- package/package.json +1 -4
- package/src/main/api/alternate-data.ts +2 -2
- package/src/main/api/badge-data.ts +5 -10
- package/src/main/api/badge-partial-data.ts +6 -5
- package/src/main/api/change.ts +5 -2
- package/src/main/api/content-bundle.ts +2 -3
- package/src/main/api/markdown-string.ts +4 -0
- package/src/main/api/vidiot-map-point-of-interest-data.ts +3 -3
- package/src/main/changelog.ts +3 -2
- package/src/main/db/alignments.ts +17 -0
- package/src/main/db/alternates.ts +8 -14
- package/src/main/db/badge-index.ts +87 -0
- package/src/main/db/badge-partial.ts +54 -6
- package/src/main/db/badge-search-options.ts +51 -0
- package/src/main/db/badge.ts +8 -13
- package/src/main/db/bundle-metadata.ts +2 -3
- package/src/main/db/coh-content-database.ts +17 -25
- package/src/main/db/paged.ts +7 -0
- package/src/main/db/vidiot-map-point-of-interest.ts +2 -3
- package/src/main/index.ts +7 -1
- package/src/main/util.ts +36 -6
- package/src/test/api/alignments.test.ts +40 -0
- package/src/test/api/badge-partial-data.fixture.ts +1 -1
- package/src/test/db/alternates.test.ts +16 -74
- package/src/test/db/badge-index.test.ts +488 -0
- package/src/test/db/coh-content-database.test.ts +15 -0
- package/src/test/index.test.ts +4 -2
- package/src/test/util.test.ts +49 -13
- package/src/main/db/badge-search-document.ts +0 -16
- package/src/test/db/badge-search-document.test.ts +0 -35
- package/src/test/db/coh-content-database-search.test.ts +0 -119
|
@@ -0,0 +1,488 @@
|
|
|
1
|
+
import { badgeDataFixture } from '../api/badge-data.fixture'
|
|
2
|
+
import { Badge, BadgeIndex, GameMap } from '../../main'
|
|
3
|
+
import { gameMapDataFixture } from '../api/game-map-data.fixture'
|
|
4
|
+
|
|
5
|
+
const TEST_MAPS = [
|
|
6
|
+
new GameMap(gameMapDataFixture.create({ key: 'atlas-park', name: 'Atlas Park' })),
|
|
7
|
+
new GameMap(gameMapDataFixture.create({ key: 'perez-park', name: 'Perez Park' })),
|
|
8
|
+
new GameMap(gameMapDataFixture.create({ key: 'abandoned-sewer-network', name: 'Abandoned Sewer Network' })),
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
describe(BadgeIndex.name, () => {
|
|
12
|
+
describe('Constructor', () => {
|
|
13
|
+
test(`should throw an error on duplicate key`, () => {
|
|
14
|
+
const data = [
|
|
15
|
+
new Badge(badgeDataFixture.create({ key: 'foo' })),
|
|
16
|
+
new Badge(badgeDataFixture.create({ key: 'foo' })),
|
|
17
|
+
]
|
|
18
|
+
expect(() => new BadgeIndex(data)).toThrow('Duplicate badge key [foo]')
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
describe('getBadge', () => {
|
|
23
|
+
test(`should retrieve badge from the index`, () => {
|
|
24
|
+
const data = [new Badge(badgeDataFixture.create({ key: 'foo' }))]
|
|
25
|
+
|
|
26
|
+
expect(new BadgeIndex(data).getBadge('foo')).not.toBeUndefined()
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
test(`should throw error for unknown badge`, () => {
|
|
30
|
+
expect(() => new BadgeIndex([]).getBadge('foo')).toThrow('Unknown badge key [foo]')
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
describe('searchBadges', () => {
|
|
35
|
+
test(`should return everything for an empty query`, () => {
|
|
36
|
+
const data = [
|
|
37
|
+
new Badge(badgeDataFixture.create({ key: 'foo-1', acquisition: 'Foo 1' })),
|
|
38
|
+
new Badge(badgeDataFixture.create({ key: 'foo-2', acquisition: 'Foo 2' })),
|
|
39
|
+
new Badge(badgeDataFixture.create({ key: 'bar-1', acquisition: 'Bar 1' })),
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
const result = new BadgeIndex(data).searchBadges()
|
|
43
|
+
const keys = result.items.map(x => x.key)
|
|
44
|
+
expect(keys).toStrictEqual(['foo-1', 'foo-2', 'bar-1'])
|
|
45
|
+
expect(keys).toContain('foo-1')
|
|
46
|
+
expect(keys).toContain('foo-2')
|
|
47
|
+
expect(keys).toContain('bar-1')
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
describe('query', () => {
|
|
51
|
+
test(`should match on badge name`, () => {
|
|
52
|
+
const data = [
|
|
53
|
+
new Badge(badgeDataFixture.create({ key: 'match-1', name: [{ value: 'Foo 1' }] })),
|
|
54
|
+
new Badge(badgeDataFixture.create({ key: 'match-2', name: [{ value: 'Foo 2' }, { value: 'Bar 2' }] })),
|
|
55
|
+
new Badge(badgeDataFixture.create({ key: 'match-3', name: [{ value: 'Bar 3' }, { value: 'Foo 3' }] })),
|
|
56
|
+
new Badge(badgeDataFixture.create({ key: 'miss-1', name: [{ value: 'Bar 4' }] })),
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
const result = new BadgeIndex(data).searchBadges({ query: { str: 'Foo', on: { name: true } } })
|
|
60
|
+
const keys = result.items.map(x => x.key)
|
|
61
|
+
expect(keys).toStrictEqual(['match-1', 'match-2', 'match-3'])
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
test(`should match on badge text`, () => {
|
|
65
|
+
const data = [
|
|
66
|
+
new Badge(badgeDataFixture.create({ key: 'match-1', badgeText: [{ value: 'Foo 1' }] })),
|
|
67
|
+
new Badge(badgeDataFixture.create({ key: 'match-2', badgeText: [{ value: 'Foo 2' }, { value: 'Bar 2' }] })),
|
|
68
|
+
new Badge(badgeDataFixture.create({ key: 'match-3', badgeText: [{ value: 'Bar 3' }, { value: 'Foo 3' }] })),
|
|
69
|
+
new Badge(badgeDataFixture.create({ key: 'miss-1', badgeText: [{ value: 'Bar 4' }] })),
|
|
70
|
+
new Badge(badgeDataFixture.create({ key: 'miss-2', badgeText: undefined })),
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
const result = new BadgeIndex(data).searchBadges({ query: { str: 'Foo', on: { badgeText: true } } })
|
|
74
|
+
const keys = result.items.map(x => x.key)
|
|
75
|
+
expect(keys).toStrictEqual(['match-1', 'match-2', 'match-3'])
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
test(`should match on acquisition`, () => {
|
|
79
|
+
const data = [
|
|
80
|
+
new Badge(badgeDataFixture.create({ key: 'match-1', acquisition: 'Foo 1' })),
|
|
81
|
+
new Badge(badgeDataFixture.create({ key: 'match-2', acquisition: 'Foo 2' })),
|
|
82
|
+
new Badge(badgeDataFixture.create({ key: 'miss-1', acquisition: 'Bar 1' })),
|
|
83
|
+
new Badge(badgeDataFixture.create({ key: 'miss-2', acquisition: undefined })),
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
const result = new BadgeIndex(data).searchBadges({ query: { str: 'Foo', on: { acquisition: true } } })
|
|
87
|
+
const keys = result.items.map(x => x.key)
|
|
88
|
+
expect(keys).toStrictEqual(['match-1', 'match-2'])
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
test(`should match on effect`, () => {
|
|
92
|
+
const data = [
|
|
93
|
+
new Badge(badgeDataFixture.create({ key: 'match-1', effect: 'Foo 1' })),
|
|
94
|
+
new Badge(badgeDataFixture.create({ key: 'match-2', effect: 'Foo 2' })),
|
|
95
|
+
new Badge(badgeDataFixture.create({ key: 'miss-1', effect: 'Bar 1' })),
|
|
96
|
+
new Badge(badgeDataFixture.create({ key: 'miss-2', effect: undefined })),
|
|
97
|
+
]
|
|
98
|
+
|
|
99
|
+
const result = new BadgeIndex(data).searchBadges({ query: { str: 'Foo', on: { effect: true } } })
|
|
100
|
+
const keys = result.items.map(x => x.key)
|
|
101
|
+
expect(keys).toStrictEqual(['match-1', 'match-2'])
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
test(`should match on notes`, () => {
|
|
105
|
+
const data = [
|
|
106
|
+
new Badge(badgeDataFixture.create({ key: 'match-1', notes: 'Foo 1' })),
|
|
107
|
+
new Badge(badgeDataFixture.create({ key: 'match-2', notes: 'Foo 2' })),
|
|
108
|
+
new Badge(badgeDataFixture.create({ key: 'miss-1', notes: 'Bar 1' })),
|
|
109
|
+
new Badge(badgeDataFixture.create({ key: 'miss-2', notes: undefined })),
|
|
110
|
+
]
|
|
111
|
+
|
|
112
|
+
const result = new BadgeIndex(data).searchBadges({ query: { str: 'Foo', on: { notes: true } } })
|
|
113
|
+
const keys = result.items.map(x => x.key)
|
|
114
|
+
expect(keys).toStrictEqual(['match-1', 'match-2'])
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
test(`should match on setTitle`, () => {
|
|
118
|
+
const data = [
|
|
119
|
+
new Badge(badgeDataFixture.create({ key: 'match-1', setTitle: { id: 123 } })),
|
|
120
|
+
new Badge(badgeDataFixture.create({ key: 'match-2', setTitle: { id: 456, praetorianId: 123 } })),
|
|
121
|
+
new Badge(badgeDataFixture.create({ key: 'miss-1', setTitle: { id: 456 } })),
|
|
122
|
+
new Badge(badgeDataFixture.create({ key: 'miss-2', setTitle: undefined })),
|
|
123
|
+
]
|
|
124
|
+
|
|
125
|
+
const result = new BadgeIndex(data).searchBadges({ query: { str: '123', on: { setTitle: true } } })
|
|
126
|
+
|
|
127
|
+
expect(result.items).toHaveLength(2)
|
|
128
|
+
const keys = result.items.map(x => x.key)
|
|
129
|
+
expect(keys).toStrictEqual(['match-1', 'match-2'])
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
test(`should match the start of a string`, () => {
|
|
133
|
+
const data = [
|
|
134
|
+
new Badge(badgeDataFixture.create({ key: 'match-1', acquisition: 'Foo 1' })),
|
|
135
|
+
new Badge(badgeDataFixture.create({ key: 'match-2', acquisition: 'Foo 2' })),
|
|
136
|
+
new Badge(badgeDataFixture.create({ key: 'miss-1', acquisition: 'Bar 1' })),
|
|
137
|
+
]
|
|
138
|
+
|
|
139
|
+
const result = new BadgeIndex(data).searchBadges({ query: { str: 'Fo', on: { acquisition: true } } })
|
|
140
|
+
const keys = result.items.map(x => x.key)
|
|
141
|
+
expect(keys).toStrictEqual(['match-1', 'match-2'])
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
test(`should be case insensitive`, () => {
|
|
145
|
+
const data = [
|
|
146
|
+
new Badge(badgeDataFixture.create({ key: 'match-1', acquisition: 'Foo 1' })),
|
|
147
|
+
new Badge(badgeDataFixture.create({ key: 'match-2', acquisition: 'Foo 2' })),
|
|
148
|
+
new Badge(badgeDataFixture.create({ key: 'miss-1', acquisition: 'Bar 1' })),
|
|
149
|
+
]
|
|
150
|
+
|
|
151
|
+
const result = new BadgeIndex(data).searchBadges({ query: { str: 'foo', on: { acquisition: true } } })
|
|
152
|
+
const keys = result.items.map(x => x.key)
|
|
153
|
+
expect(keys).toStrictEqual(['match-1', 'match-2'])
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
test(`should default to querying on name only`, () => {
|
|
157
|
+
const data = [
|
|
158
|
+
new Badge(badgeDataFixture.create({ key: 'match-1', name: [{ value: 'Foo 1' }] })),
|
|
159
|
+
new Badge(badgeDataFixture.create({ key: 'miss-1', acquisition: 'Foo 2' })),
|
|
160
|
+
new Badge(badgeDataFixture.create({ key: 'miss-2', name: [{ value: 'Bar 1' }] })),
|
|
161
|
+
]
|
|
162
|
+
|
|
163
|
+
const result = new BadgeIndex(data).searchBadges({ query: { str: 'foo' } })
|
|
164
|
+
|
|
165
|
+
const keys = result.items.map(x => x.key)
|
|
166
|
+
expect(keys).toStrictEqual(['match-1'])
|
|
167
|
+
})
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
describe('filter', () => {
|
|
171
|
+
test(`should filter nothing if not specified`, () => {
|
|
172
|
+
const data = [
|
|
173
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1' })),
|
|
174
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2' })),
|
|
175
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3' })),
|
|
176
|
+
new Badge(badgeDataFixture.create({ key: 'badge-4' })),
|
|
177
|
+
new Badge(badgeDataFixture.create({ key: 'badge-5' })),
|
|
178
|
+
new Badge(badgeDataFixture.create({ key: 'badge-6' })),
|
|
179
|
+
]
|
|
180
|
+
|
|
181
|
+
const result = new BadgeIndex(data).searchBadges()
|
|
182
|
+
const keys = result.items.map(x => x.key)
|
|
183
|
+
expect(keys).toStrictEqual(['badge-1', 'badge-2', 'badge-3', 'badge-4', 'badge-5', 'badge-6'])
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
test(`should filter on badge type`, () => {
|
|
187
|
+
const data = [
|
|
188
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1', type: 'EXPLORATION' })),
|
|
189
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2', type: 'EXPLORATION' })),
|
|
190
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3', type: 'HISTORY' })),
|
|
191
|
+
new Badge(badgeDataFixture.create({ key: 'badge-4', type: 'HISTORY' })),
|
|
192
|
+
new Badge(badgeDataFixture.create({ key: 'badge-5', type: 'ACCOLADE' })),
|
|
193
|
+
new Badge(badgeDataFixture.create({ key: 'badge-6', type: 'ACCOLADE' })),
|
|
194
|
+
]
|
|
195
|
+
|
|
196
|
+
const result = new BadgeIndex(data).searchBadges({ filter: { type: 'HISTORY' } })
|
|
197
|
+
const keys = result.items.map(x => x.key)
|
|
198
|
+
expect(keys).toStrictEqual(['badge-3', 'badge-4'])
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
test(`should filter on badge type`, () => {
|
|
202
|
+
const data = [
|
|
203
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1', mapKey: 'atlas-park' })),
|
|
204
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2', mapKey: 'perez-park' })),
|
|
205
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3', mapKey: 'abandoned-sewer-network' })),
|
|
206
|
+
new Badge(badgeDataFixture.create({ key: 'badge-4', mapKey: 'atlas-park' })),
|
|
207
|
+
new Badge(badgeDataFixture.create({ key: 'badge-5', mapKey: 'perez-park' })),
|
|
208
|
+
new Badge(badgeDataFixture.create({ key: 'badge-6', mapKey: undefined })),
|
|
209
|
+
]
|
|
210
|
+
|
|
211
|
+
const result = new BadgeIndex(data).searchBadges({ filter: { mapKey: 'perez-park' } })
|
|
212
|
+
const keys = result.items.map(x => x.key)
|
|
213
|
+
expect(keys).toStrictEqual(['badge-2', 'badge-5'])
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
test(`should filter on badge type`, () => {
|
|
217
|
+
const data = [
|
|
218
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1', alignment: ['H'] })),
|
|
219
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2', alignment: ['V'] })),
|
|
220
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3', alignment: ['P'] })),
|
|
221
|
+
new Badge(badgeDataFixture.create({ key: 'badge-4', alignment: ['H', 'V'] })),
|
|
222
|
+
new Badge(badgeDataFixture.create({ key: 'badge-5', alignment: ['V', 'P'] })),
|
|
223
|
+
new Badge(badgeDataFixture.create({ key: 'badge-6', alignment: ['H', 'V', 'P'] })),
|
|
224
|
+
]
|
|
225
|
+
|
|
226
|
+
const result = new BadgeIndex(data).searchBadges({ filter: { alignment: 'H' } })
|
|
227
|
+
const keys = result.items.map(x => x.key)
|
|
228
|
+
expect(keys).toStrictEqual(['badge-1', 'badge-4', 'badge-6'])
|
|
229
|
+
})
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
describe('pagination', () => {
|
|
233
|
+
test(`should return all results with no pagination data`, () => {
|
|
234
|
+
const data = [
|
|
235
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1' })),
|
|
236
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2' })),
|
|
237
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3' })),
|
|
238
|
+
new Badge(badgeDataFixture.create({ key: 'badge-4' })),
|
|
239
|
+
new Badge(badgeDataFixture.create({ key: 'badge-5' })),
|
|
240
|
+
new Badge(badgeDataFixture.create({ key: 'badge-6' })),
|
|
241
|
+
]
|
|
242
|
+
|
|
243
|
+
const result = new BadgeIndex(data).searchBadges()
|
|
244
|
+
const keys = result.items.map(x => x.key)
|
|
245
|
+
expect(keys).toStrictEqual(['badge-1', 'badge-2', 'badge-3', 'badge-4', 'badge-5', 'badge-6'])
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
test(`should be 1-based for page number`, () => {
|
|
249
|
+
const result = new BadgeIndex([]).searchBadges()
|
|
250
|
+
expect(result.page).toBe(1)
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
test(`should return the requested page size`, () => {
|
|
254
|
+
const data = [
|
|
255
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1' })),
|
|
256
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2' })),
|
|
257
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3' })),
|
|
258
|
+
new Badge(badgeDataFixture.create({ key: 'badge-4' })),
|
|
259
|
+
new Badge(badgeDataFixture.create({ key: 'badge-5' })),
|
|
260
|
+
new Badge(badgeDataFixture.create({ key: 'badge-6' })),
|
|
261
|
+
]
|
|
262
|
+
|
|
263
|
+
const result = new BadgeIndex(data).searchBadges({ pageSize: 2 })
|
|
264
|
+
expect(result.items).toHaveLength(2)
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
test(`should return the start of the array with no page specified`, () => {
|
|
268
|
+
const data = [
|
|
269
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1' })),
|
|
270
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2' })),
|
|
271
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3' })),
|
|
272
|
+
new Badge(badgeDataFixture.create({ key: 'badge-4' })),
|
|
273
|
+
new Badge(badgeDataFixture.create({ key: 'badge-5' })),
|
|
274
|
+
new Badge(badgeDataFixture.create({ key: 'badge-6' })),
|
|
275
|
+
]
|
|
276
|
+
|
|
277
|
+
const result = new BadgeIndex(data).searchBadges({ pageSize: 2 })
|
|
278
|
+
const keys = result.items.map(x => x.key)
|
|
279
|
+
expect(keys).toStrictEqual(['badge-1', 'badge-2'])
|
|
280
|
+
})
|
|
281
|
+
|
|
282
|
+
test(`should return results from the middle of the array with a page specified`, () => {
|
|
283
|
+
const data = [
|
|
284
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1' })),
|
|
285
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2' })),
|
|
286
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3' })),
|
|
287
|
+
new Badge(badgeDataFixture.create({ key: 'badge-4' })),
|
|
288
|
+
new Badge(badgeDataFixture.create({ key: 'badge-5' })),
|
|
289
|
+
new Badge(badgeDataFixture.create({ key: 'badge-6' })),
|
|
290
|
+
]
|
|
291
|
+
|
|
292
|
+
const result = new BadgeIndex(data).searchBadges({ page: 2, pageSize: 2 })
|
|
293
|
+
const keys = result.items.map(x => x.key)
|
|
294
|
+
expect(keys).toStrictEqual(['badge-3', 'badge-4'])
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
test(`should return a partial page if at the end of the array`, () => {
|
|
298
|
+
const data = [
|
|
299
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1' })),
|
|
300
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2' })),
|
|
301
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3' })),
|
|
302
|
+
new Badge(badgeDataFixture.create({ key: 'badge-4' })),
|
|
303
|
+
new Badge(badgeDataFixture.create({ key: 'badge-5' })),
|
|
304
|
+
]
|
|
305
|
+
|
|
306
|
+
const result = new BadgeIndex(data).searchBadges({ page: 3, pageSize: 2 })
|
|
307
|
+
const keys = result.items.map(x => x.key)
|
|
308
|
+
expect(keys).toStrictEqual(['badge-5'])
|
|
309
|
+
})
|
|
310
|
+
|
|
311
|
+
test(`should return the correct total entry count`, () => {
|
|
312
|
+
const data = [
|
|
313
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1' })),
|
|
314
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2' })),
|
|
315
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3' })),
|
|
316
|
+
new Badge(badgeDataFixture.create({ key: 'badge-4' })),
|
|
317
|
+
new Badge(badgeDataFixture.create({ key: 'badge-5' })),
|
|
318
|
+
]
|
|
319
|
+
|
|
320
|
+
const result = new BadgeIndex(data).searchBadges({ page: 1, pageSize: 2 })
|
|
321
|
+
expect(result.totalItems).toBe(5)
|
|
322
|
+
})
|
|
323
|
+
|
|
324
|
+
test(`should return the page size`, () => {
|
|
325
|
+
const data = [
|
|
326
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1' })),
|
|
327
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2' })),
|
|
328
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3' })),
|
|
329
|
+
new Badge(badgeDataFixture.create({ key: 'badge-4' })),
|
|
330
|
+
new Badge(badgeDataFixture.create({ key: 'badge-5' })),
|
|
331
|
+
]
|
|
332
|
+
|
|
333
|
+
const result = new BadgeIndex(data).searchBadges({ pageSize: 2 })
|
|
334
|
+
expect(result.pageSize).toBe(2)
|
|
335
|
+
})
|
|
336
|
+
|
|
337
|
+
test(`should return the correct total page count`, () => {
|
|
338
|
+
const data = [
|
|
339
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1' })),
|
|
340
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2' })),
|
|
341
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3' })),
|
|
342
|
+
new Badge(badgeDataFixture.create({ key: 'badge-4' })),
|
|
343
|
+
new Badge(badgeDataFixture.create({ key: 'badge-5' })),
|
|
344
|
+
]
|
|
345
|
+
|
|
346
|
+
const result = new BadgeIndex(data).searchBadges({ pageSize: 2 })
|
|
347
|
+
expect(result.totalPages).toBe(3)
|
|
348
|
+
})
|
|
349
|
+
|
|
350
|
+
test(`should return a total page count of 1 when no page size is provided`, () => {
|
|
351
|
+
const data = [
|
|
352
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1' })),
|
|
353
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2' })),
|
|
354
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3' })),
|
|
355
|
+
new Badge(badgeDataFixture.create({ key: 'badge-4' })),
|
|
356
|
+
new Badge(badgeDataFixture.create({ key: 'badge-5' })),
|
|
357
|
+
]
|
|
358
|
+
|
|
359
|
+
const result = new BadgeIndex(data).searchBadges()
|
|
360
|
+
expect(result.totalPages).toBe(1)
|
|
361
|
+
})
|
|
362
|
+
})
|
|
363
|
+
|
|
364
|
+
describe('sort', () => {
|
|
365
|
+
test(`should not modify sort if not specified`, () => {
|
|
366
|
+
const data = [
|
|
367
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1' })),
|
|
368
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2' })),
|
|
369
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3' })),
|
|
370
|
+
new Badge(badgeDataFixture.create({ key: 'badge-4' })),
|
|
371
|
+
]
|
|
372
|
+
|
|
373
|
+
const result = new BadgeIndex(data, TEST_MAPS).searchBadges()
|
|
374
|
+
|
|
375
|
+
const keys = result.items.map(x => x.key)
|
|
376
|
+
expect(keys).toStrictEqual(['badge-1', 'badge-2', 'badge-3', 'badge-4'])
|
|
377
|
+
})
|
|
378
|
+
|
|
379
|
+
test(`should reverse default sort with desc`, () => {
|
|
380
|
+
const data = [
|
|
381
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1' })),
|
|
382
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2' })),
|
|
383
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3' })),
|
|
384
|
+
new Badge(badgeDataFixture.create({ key: 'badge-4' })),
|
|
385
|
+
]
|
|
386
|
+
|
|
387
|
+
const result = new BadgeIndex(data, TEST_MAPS).searchBadges({ sort: { dir: 'DESC' } })
|
|
388
|
+
|
|
389
|
+
const keys = result.items.map(x => x.key)
|
|
390
|
+
expect(keys).toStrictEqual(['badge-4', 'badge-3', 'badge-2', 'badge-1'])
|
|
391
|
+
})
|
|
392
|
+
|
|
393
|
+
test(`should sort by badge name`, () => {
|
|
394
|
+
const data = [
|
|
395
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1', name: [{ value: 'Abc' }] })),
|
|
396
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2', name: [{ value: 'XYZ' }] })),
|
|
397
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3', name: [{ value: 'AAB' }] })),
|
|
398
|
+
]
|
|
399
|
+
|
|
400
|
+
const result = new BadgeIndex(data, TEST_MAPS).searchBadges({ sort: { by: 'BADGE_NAME' } })
|
|
401
|
+
|
|
402
|
+
const keys = result.items.map(x => x.key)
|
|
403
|
+
expect(keys).toStrictEqual(['badge-3', 'badge-1', 'badge-2'])
|
|
404
|
+
})
|
|
405
|
+
|
|
406
|
+
test(`should sort by badge name descending`, () => {
|
|
407
|
+
const data = [
|
|
408
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1', name: [{ value: 'Abc' }] })),
|
|
409
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2', name: [{ value: 'XYZ' }] })),
|
|
410
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3', name: [{ value: 'AAB' }] })),
|
|
411
|
+
]
|
|
412
|
+
|
|
413
|
+
const result = new BadgeIndex(data, TEST_MAPS).searchBadges({ sort: { by: 'BADGE_NAME', dir: 'DESC' } })
|
|
414
|
+
|
|
415
|
+
const keys = result.items.map(x => x.key)
|
|
416
|
+
expect(keys).toStrictEqual(['badge-2', 'badge-1', 'badge-3'])
|
|
417
|
+
})
|
|
418
|
+
|
|
419
|
+
test(`should use the default badge name when sorting by name`, () => {
|
|
420
|
+
const data = [
|
|
421
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1', name: [{ value: 'Abc' }] })),
|
|
422
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2', name: [{ value: 'XYZ' }, { sex: 'F', value: 'AAA' }] })),
|
|
423
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3', name: [{ value: 'AAB' }] })),
|
|
424
|
+
]
|
|
425
|
+
|
|
426
|
+
const result = new BadgeIndex(data, TEST_MAPS).searchBadges({ sort: { by: 'BADGE_NAME' } })
|
|
427
|
+
|
|
428
|
+
const keys = result.items.map(x => x.key)
|
|
429
|
+
expect(keys).toStrictEqual(['badge-3', 'badge-1', 'badge-2'])
|
|
430
|
+
})
|
|
431
|
+
|
|
432
|
+
test(`should sort by map name`, () => {
|
|
433
|
+
const data = [
|
|
434
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1', mapKey: 'atlas-park' })),
|
|
435
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2', mapKey: 'perez-park' })),
|
|
436
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3', mapKey: 'abandoned-sewer-network' })),
|
|
437
|
+
]
|
|
438
|
+
|
|
439
|
+
const result = new BadgeIndex(data, TEST_MAPS).searchBadges({ sort: { by: 'MAP_NAME' } })
|
|
440
|
+
|
|
441
|
+
const keys = result.items.map(x => x.key)
|
|
442
|
+
expect(keys).toStrictEqual(['badge-3', 'badge-1', 'badge-2'])
|
|
443
|
+
})
|
|
444
|
+
|
|
445
|
+
test(`should sort by map name descending`, () => {
|
|
446
|
+
const data = [
|
|
447
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1', mapKey: 'atlas-park' })),
|
|
448
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2', mapKey: 'perez-park' })),
|
|
449
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3', mapKey: 'abandoned-sewer-network' })),
|
|
450
|
+
]
|
|
451
|
+
|
|
452
|
+
const result = new BadgeIndex(data, TEST_MAPS).searchBadges({ sort: { by: 'MAP_NAME', dir: 'DESC' } })
|
|
453
|
+
|
|
454
|
+
const keys = result.items.map(x => x.key)
|
|
455
|
+
expect(keys).toStrictEqual(['badge-2', 'badge-1', 'badge-3'])
|
|
456
|
+
})
|
|
457
|
+
|
|
458
|
+
test(`should maintain canonical as secondary sort when sorting by map name`, () => {
|
|
459
|
+
const data = [
|
|
460
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1', mapKey: 'atlas-park' })),
|
|
461
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2', mapKey: 'perez-park' })),
|
|
462
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3', mapKey: 'atlas-park' })),
|
|
463
|
+
new Badge(badgeDataFixture.create({ key: 'badge-4', mapKey: 'abandoned-sewer-network' })),
|
|
464
|
+
]
|
|
465
|
+
|
|
466
|
+
const result = new BadgeIndex(data, TEST_MAPS).searchBadges({ sort: { by: 'MAP_NAME' } })
|
|
467
|
+
|
|
468
|
+
const keys = result.items.map(x => x.key)
|
|
469
|
+
expect(keys).toStrictEqual(['badge-4', 'badge-1', 'badge-3', 'badge-2'])
|
|
470
|
+
})
|
|
471
|
+
|
|
472
|
+
test(`should sort unknown map names to the end`, () => {
|
|
473
|
+
const data = [
|
|
474
|
+
new Badge(badgeDataFixture.create({ key: 'badge-1', mapKey: 'atlas-park' })),
|
|
475
|
+
new Badge(badgeDataFixture.create({ key: 'badge-2', mapKey: 'unknown' })),
|
|
476
|
+
new Badge(badgeDataFixture.create({ key: 'badge-3', mapKey: 'perez-park' })),
|
|
477
|
+
new Badge(badgeDataFixture.create({ key: 'badge-4', mapKey: 'unexpected' })),
|
|
478
|
+
new Badge(badgeDataFixture.create({ key: 'badge-5', mapKey: 'abandoned-sewer-network' })),
|
|
479
|
+
]
|
|
480
|
+
|
|
481
|
+
const result = new BadgeIndex(data, TEST_MAPS).searchBadges({ sort: { by: 'MAP_NAME' } })
|
|
482
|
+
|
|
483
|
+
const keys = result.items.map(x => x.key)
|
|
484
|
+
expect(keys).toStrictEqual(['badge-5', 'badge-1', 'badge-3', 'badge-2', 'badge-4'])
|
|
485
|
+
})
|
|
486
|
+
})
|
|
487
|
+
})
|
|
488
|
+
})
|
|
@@ -140,4 +140,19 @@ describe(CohContentDatabase.name, () => {
|
|
|
140
140
|
expect(() => new CohContentDatabase(data).getBadge('foo')).toThrow('Unknown badge key [foo]')
|
|
141
141
|
})
|
|
142
142
|
})
|
|
143
|
+
|
|
144
|
+
describe('searchBadges', () => {
|
|
145
|
+
test(`should search the badge list`, () => {
|
|
146
|
+
const data = contentBundleFixture.create({
|
|
147
|
+
badges: [
|
|
148
|
+
badgeDataFixture.create({ key: 'foo', name: [{ value: 'Foo' }] }),
|
|
149
|
+
badgeDataFixture.create({ key: 'bar', name: [{ value: 'Bar' }] }),
|
|
150
|
+
],
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
const result = new CohContentDatabase(data).searchBadges({ query: { str: 'oo' } })
|
|
154
|
+
expect(result.totalItems).toBe(1)
|
|
155
|
+
expect(result.items.map(x => x.key)).toStrictEqual(['foo'])
|
|
156
|
+
})
|
|
157
|
+
})
|
|
143
158
|
})
|
package/src/test/index.test.ts
CHANGED
|
@@ -5,6 +5,8 @@ test('should export the changelog', () => {
|
|
|
5
5
|
})
|
|
6
6
|
|
|
7
7
|
test('should export badge reference utils', () => {
|
|
8
|
-
expect(index).toHaveProperty('
|
|
9
|
-
expect(index).toHaveProperty('
|
|
8
|
+
expect(index).toHaveProperty('badgeUri')
|
|
9
|
+
expect(index).toHaveProperty('badgeLink')
|
|
10
|
+
expect(index).toHaveProperty('mapUri')
|
|
11
|
+
expect(index).toHaveProperty('mapLink')
|
|
10
12
|
})
|
package/src/test/util.test.ts
CHANGED
|
@@ -1,39 +1,75 @@
|
|
|
1
|
-
import { Badge,
|
|
1
|
+
import { Badge, badgeLink, badgeUri, GameMap, mapLink, mapUri } from '../main'
|
|
2
2
|
import { badgeDataFixture } from './api/badge-data.fixture'
|
|
3
3
|
import { gameMapDataFixture } from './api/game-map-data.fixture'
|
|
4
4
|
|
|
5
|
-
describe(
|
|
5
|
+
describe(badgeUri.name, () => {
|
|
6
6
|
test('should return the expected pattern', () => {
|
|
7
|
-
expect(
|
|
8
|
-
expect(
|
|
9
|
-
expect(
|
|
7
|
+
expect(badgeUri('foo')).toBe('badge://foo')
|
|
8
|
+
expect(badgeUri('bar')).toBe('badge://bar')
|
|
9
|
+
expect(badgeUri('foo-bar')).toBe('badge://foo-bar')
|
|
10
10
|
})
|
|
11
11
|
|
|
12
12
|
test('should accept a Badge object', () => {
|
|
13
13
|
const badge = new Badge(badgeDataFixture.create({ key: 'foo' }))
|
|
14
|
-
expect(
|
|
14
|
+
expect(badgeUri(badge)).toBe('badge://foo')
|
|
15
15
|
})
|
|
16
16
|
|
|
17
17
|
test('should accept a BadgeData object', () => {
|
|
18
18
|
const badge = badgeDataFixture.create({ key: 'foo' })
|
|
19
|
-
expect(
|
|
19
|
+
expect(badgeUri(badge)).toBe('badge://foo')
|
|
20
20
|
})
|
|
21
21
|
})
|
|
22
22
|
|
|
23
|
-
describe(
|
|
23
|
+
describe(badgeLink.name, () => {
|
|
24
24
|
test('should return the expected pattern', () => {
|
|
25
|
-
expect(
|
|
26
|
-
expect(
|
|
27
|
-
expect(
|
|
25
|
+
expect(badgeLink('foo')).toBe('[foo](badge://foo)')
|
|
26
|
+
expect(badgeLink('bar')).toBe('[bar](badge://bar)')
|
|
27
|
+
expect(badgeLink('foo-bar')).toBe('[foo-bar](badge://foo-bar)')
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
test('should accept a Badge object', () => {
|
|
31
|
+
const badge = new Badge(badgeDataFixture.create({ key: 'foo' }))
|
|
32
|
+
expect(badgeLink(badge)).toBe('[foo](badge://foo)')
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
test('should accept a BadgeData object', () => {
|
|
36
|
+
const badge = badgeDataFixture.create({ key: 'foo' })
|
|
37
|
+
expect(badgeLink(badge)).toBe('[foo](badge://foo)')
|
|
38
|
+
})
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
describe(mapUri.name, () => {
|
|
42
|
+
test('should return the expected pattern', () => {
|
|
43
|
+
expect(mapUri('foo')).toBe('map://foo')
|
|
44
|
+
expect(mapUri('bar')).toBe('map://bar')
|
|
45
|
+
expect(mapUri('foo-bar')).toBe('map://foo-bar')
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
test('should accept a GameMap object', () => {
|
|
49
|
+
const map = new GameMap(gameMapDataFixture.create({ key: 'foo' }))
|
|
50
|
+
expect(mapUri(map)).toBe('map://foo')
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
test('should accept a GameMapData object', () => {
|
|
54
|
+
const map = gameMapDataFixture.create({ key: 'foo' })
|
|
55
|
+
expect(mapUri(map)).toBe('map://foo')
|
|
56
|
+
})
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
describe(mapLink.name, () => {
|
|
60
|
+
test('should return the expected pattern', () => {
|
|
61
|
+
expect(mapLink('foo')).toBe('[foo](map://foo)')
|
|
62
|
+
expect(mapLink('bar')).toBe('[bar](map://bar)')
|
|
63
|
+
expect(mapLink('foo-bar')).toBe('[foo-bar](map://foo-bar)')
|
|
28
64
|
})
|
|
29
65
|
|
|
30
66
|
test('should accept a GameMap object', () => {
|
|
31
67
|
const map = new GameMap(gameMapDataFixture.create({ key: 'foo' }))
|
|
32
|
-
expect(
|
|
68
|
+
expect(mapLink(map)).toBe('[foo](map://foo)')
|
|
33
69
|
})
|
|
34
70
|
|
|
35
71
|
test('should accept a GameMapData object', () => {
|
|
36
72
|
const map = gameMapDataFixture.create({ key: 'foo' })
|
|
37
|
-
expect(
|
|
73
|
+
expect(mapLink(map)).toBe('[foo](map://foo)')
|
|
38
74
|
})
|
|
39
75
|
})
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { Badge } from './badge'
|
|
2
|
-
|
|
3
|
-
export class BadgeSearchDocument {
|
|
4
|
-
id: string
|
|
5
|
-
key: string
|
|
6
|
-
name: string
|
|
7
|
-
badgeText: string
|
|
8
|
-
acquisition: string
|
|
9
|
-
|
|
10
|
-
constructor(badge: Badge) {
|
|
11
|
-
this.id = this.key = badge.key
|
|
12
|
-
this.name = badge.name.toString(', ')
|
|
13
|
-
this.badgeText = badge.badgeText.toString(', ')
|
|
14
|
-
this.acquisition = badge.acquisition ?? ''
|
|
15
|
-
}
|
|
16
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { Badge } from '../../main'
|
|
2
|
-
import { badgeDataFixture } from '../api/badge-data.fixture'
|
|
3
|
-
import { BadgeSearchDocument } from '../../main/db/badge-search-document'
|
|
4
|
-
|
|
5
|
-
describe(Badge.name, () => {
|
|
6
|
-
test(`should set the id from the badge key`, () => {
|
|
7
|
-
expect(new BadgeSearchDocument(new Badge(badgeDataFixture.create({ key: 'foo' }))).id).toBe('foo')
|
|
8
|
-
})
|
|
9
|
-
|
|
10
|
-
test(`should set the key from the badge`, () => {
|
|
11
|
-
expect(new BadgeSearchDocument(new Badge(badgeDataFixture.create({ key: 'foo' }))).key).toBe('foo')
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
test(`should set the name from the badge names`, () => {
|
|
15
|
-
expect(new BadgeSearchDocument(new Badge(badgeDataFixture.create({
|
|
16
|
-
name: [
|
|
17
|
-
{ value: 'foo' },
|
|
18
|
-
{ alignment: 'H', value: 'bar' },
|
|
19
|
-
],
|
|
20
|
-
}))).name).toBe('foo, bar')
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
test(`should set the badge text`, () => {
|
|
24
|
-
expect(new BadgeSearchDocument(new Badge(badgeDataFixture.create({
|
|
25
|
-
badgeText: [
|
|
26
|
-
{ value: 'foo' },
|
|
27
|
-
{ alignment: 'H', value: 'bar' },
|
|
28
|
-
],
|
|
29
|
-
}))).badgeText).toBe('foo, bar')
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
test(`should set the acquisition`, () => {
|
|
33
|
-
expect(new BadgeSearchDocument(new Badge(badgeDataFixture.create({ acquisition: 'foo' }))).acquisition).toBe('foo')
|
|
34
|
-
})
|
|
35
|
-
})
|