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
|
@@ -3,20 +3,68 @@ import { PlaqueType } from '../api/plaque-type'
|
|
|
3
3
|
import { BadgePartialType } from '../api/badge-partial-type'
|
|
4
4
|
import { EnhancementCategory } from '../api/enhancement-category'
|
|
5
5
|
import { Key } from './key'
|
|
6
|
+
import { MarkdownString } from '../api/markdown-string'
|
|
6
7
|
|
|
7
8
|
export class BadgePartial {
|
|
9
|
+
/**
|
|
10
|
+
* Key.
|
|
11
|
+
*/
|
|
8
12
|
readonly key: string
|
|
9
|
-
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Type of partial.
|
|
16
|
+
*/
|
|
17
|
+
readonly type: BadgePartialType
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Map the partial is located on.
|
|
21
|
+
*/
|
|
10
22
|
readonly mapKey?: string
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* /loc coordinates.
|
|
26
|
+
*/
|
|
11
27
|
readonly loc?: number[]
|
|
12
|
-
|
|
13
|
-
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Is it a wall plaque or a physical monument?
|
|
31
|
+
*/
|
|
32
|
+
readonly plaqueType?: PlaqueType
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Plaque inscription.
|
|
36
|
+
*/
|
|
37
|
+
readonly plaqueInscription?: string
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The number or letter the partial appears as on Vidiot Maps.
|
|
41
|
+
*/
|
|
14
42
|
readonly vidiotMapKey?: string
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The badge required for this partial.
|
|
46
|
+
*/
|
|
15
47
|
readonly badgeKey?: string
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Level of the invention required.
|
|
51
|
+
*/
|
|
16
52
|
readonly inventionLevel?: number
|
|
17
|
-
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The types of enhancements required to be crafted.
|
|
56
|
+
*/
|
|
57
|
+
readonly inventionTypes?: EnhancementCategory[]
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Number of invention crafts required.
|
|
61
|
+
*/
|
|
18
62
|
readonly inventionCount?: number
|
|
19
|
-
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Any additional notes.
|
|
66
|
+
*/
|
|
67
|
+
readonly notes?: MarkdownString
|
|
20
68
|
|
|
21
69
|
constructor(data: BadgePartialData) {
|
|
22
70
|
this.key = new Key(data.key).value
|
|
@@ -24,7 +72,7 @@ export class BadgePartial {
|
|
|
24
72
|
this.mapKey = data.mapKey
|
|
25
73
|
this.loc = data.loc
|
|
26
74
|
this.plaqueType = data.plaqueType
|
|
27
|
-
this.
|
|
75
|
+
this.plaqueInscription = data.plaqueInscription
|
|
28
76
|
this.vidiotMapKey = data.vidiotMapKey
|
|
29
77
|
this.badgeKey = data.badgeKey
|
|
30
78
|
this.inventionLevel = data.inventionLevel
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { BadgeType } from '../api/badge-type'
|
|
2
|
+
import { Alignment } from '../api/alignment'
|
|
3
|
+
|
|
4
|
+
export interface BadgeSearchOptions {
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Text-based search.
|
|
8
|
+
*
|
|
9
|
+
* Case-insensitive. Defaults to searching on name only.
|
|
10
|
+
*/
|
|
11
|
+
query?: {
|
|
12
|
+
str?: string
|
|
13
|
+
on?: {
|
|
14
|
+
name?: boolean
|
|
15
|
+
badgeText?: boolean
|
|
16
|
+
acquisition?: boolean
|
|
17
|
+
notes?: boolean
|
|
18
|
+
effect?: boolean
|
|
19
|
+
setTitle?: boolean
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Filter results matching the given values.
|
|
25
|
+
*/
|
|
26
|
+
filter?: {
|
|
27
|
+
type?: BadgeType
|
|
28
|
+
mapKey?: string
|
|
29
|
+
alignment?: Alignment
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Sort results.
|
|
34
|
+
*
|
|
35
|
+
* Badges are assumed to be in canonical order in the content bundle, and should match the in-game display order.
|
|
36
|
+
*/
|
|
37
|
+
sort?: {
|
|
38
|
+
by?: 'CANONICAL' | 'BADGE_NAME' | 'MAP_NAME'
|
|
39
|
+
dir?: 'ASC' | 'DESC'
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The page (1-based)
|
|
44
|
+
*/
|
|
45
|
+
page?: number
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* How many results per page
|
|
49
|
+
*/
|
|
50
|
+
pageSize?: number
|
|
51
|
+
}
|
package/src/main/db/badge.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { BadgeType } from '../api/badge-type'
|
|
2
|
-
import { Alignment } from '../api/alignment'
|
|
3
2
|
import { Link } from '../api/link'
|
|
4
3
|
import { BadgeData } from '../api/badge-data'
|
|
5
4
|
import { BadgePartial } from './badge-partial'
|
|
6
5
|
import { Key } from './key'
|
|
7
6
|
import { Alternates } from './alternates'
|
|
7
|
+
import { Alignments } from './alignments'
|
|
8
|
+
import { MarkdownString } from '../api/markdown-string'
|
|
8
9
|
|
|
9
10
|
export class Badge {
|
|
10
11
|
readonly #partialsIndex: Record<string, BadgePartial> = {}
|
|
@@ -17,7 +18,7 @@ export class Badge {
|
|
|
17
18
|
/**
|
|
18
19
|
* The type of badge.
|
|
19
20
|
*/
|
|
20
|
-
readonly type: BadgeType
|
|
21
|
+
readonly type: BadgeType
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* The name of this badge.
|
|
@@ -29,7 +30,7 @@ export class Badge {
|
|
|
29
30
|
/**
|
|
30
31
|
* The character alignments that this badge is available to.
|
|
31
32
|
*/
|
|
32
|
-
readonly alignment:
|
|
33
|
+
readonly alignment: Alignments
|
|
33
34
|
|
|
34
35
|
/**
|
|
35
36
|
* The badge text as it appears in-game. May vary by character sex or alignment.
|
|
@@ -38,10 +39,8 @@ export class Badge {
|
|
|
38
39
|
|
|
39
40
|
/**
|
|
40
41
|
* Description of how to acquire the badge.
|
|
41
|
-
*
|
|
42
|
-
* Supports {@link https://www.markdownguide.org/|Markdown} format.
|
|
43
42
|
*/
|
|
44
|
-
readonly acquisition?:
|
|
43
|
+
readonly acquisition?: MarkdownString
|
|
45
44
|
|
|
46
45
|
/**
|
|
47
46
|
* Absolute URL to this badge's icon.
|
|
@@ -52,10 +51,8 @@ export class Badge {
|
|
|
52
51
|
|
|
53
52
|
/**
|
|
54
53
|
* Freeform notes or tips about the badge.
|
|
55
|
-
*
|
|
56
|
-
* Supports {@link https://www.markdownguide.org/|Markdown} format.
|
|
57
54
|
*/
|
|
58
|
-
readonly notes?:
|
|
55
|
+
readonly notes?: MarkdownString
|
|
59
56
|
|
|
60
57
|
/**
|
|
61
58
|
* List of external links for this Badge. Wiki, forums, etc.
|
|
@@ -93,10 +90,8 @@ export class Badge {
|
|
|
93
90
|
|
|
94
91
|
/**
|
|
95
92
|
* A description of the effect the badge will have, such as a buff or granting a temporary power.
|
|
96
|
-
*
|
|
97
|
-
* Supports {@link https://www.markdownguide.org/|Markdown} format.
|
|
98
93
|
*/
|
|
99
|
-
readonly effect?:
|
|
94
|
+
readonly effect?: MarkdownString
|
|
100
95
|
|
|
101
96
|
/**
|
|
102
97
|
* A list of requirements for badges that have partial fulfilment steps, such as visiting plaques for history badges, or collecting other badges for meta-badges like accolades.
|
|
@@ -112,7 +107,7 @@ export class Badge {
|
|
|
112
107
|
this.key = new Key(data.key).value
|
|
113
108
|
this.type = data.type
|
|
114
109
|
this.name = new Alternates(data.name)
|
|
115
|
-
this.alignment = data.alignment
|
|
110
|
+
this.alignment = new Alignments(data.alignment)
|
|
116
111
|
this.badgeText = new Alternates(data.badgeText ?? [])
|
|
117
112
|
this.acquisition = data.acquisition
|
|
118
113
|
this.icon = new Alternates(data.icon ?? [])
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ContentBundle } from '../api/content-bundle'
|
|
2
2
|
import { Change } from '../api/change'
|
|
3
3
|
import { Link } from '../api/link'
|
|
4
|
+
import { MarkdownString } from '../api/markdown-string'
|
|
4
5
|
|
|
5
6
|
export class BundleMetadata {
|
|
6
7
|
/**
|
|
@@ -10,10 +11,8 @@ export class BundleMetadata {
|
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Description of the server group.
|
|
13
|
-
*
|
|
14
|
-
* Supports {@link https://www.markdownguide.org/|Markdown} format.
|
|
15
14
|
*/
|
|
16
|
-
readonly description?:
|
|
15
|
+
readonly description?: MarkdownString
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
18
|
* Repository where the db content package is maintained.
|
|
@@ -3,14 +3,14 @@ import { Archetype } from './archetype'
|
|
|
3
3
|
import { GameMap } from './game-map'
|
|
4
4
|
import { Badge } from './badge'
|
|
5
5
|
import { BundleMetadata } from './bundle-metadata'
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
6
|
+
import { BadgeIndex } from './badge-index'
|
|
7
|
+
import { BadgeSearchOptions } from './badge-search-options'
|
|
8
|
+
import { Paged } from './paged'
|
|
8
9
|
|
|
9
10
|
export class CohContentDatabase {
|
|
10
11
|
readonly #archetypeIndex: Record<string, Archetype> = {}
|
|
11
12
|
readonly #mapIndex: Record<string, GameMap> = {}
|
|
12
|
-
readonly #badgeIndex:
|
|
13
|
-
readonly #badgeSearch: MiniSearch
|
|
13
|
+
readonly #badgeIndex: BadgeIndex
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Metadata about the content bundle.
|
|
@@ -45,32 +45,23 @@ export class CohContentDatabase {
|
|
|
45
45
|
constructor(bundle: ContentBundle) {
|
|
46
46
|
this.metadata = new BundleMetadata(bundle)
|
|
47
47
|
this.servers = bundle.servers ?? []
|
|
48
|
+
|
|
48
49
|
this.archetypes = bundle.archetypes?.map((data) => {
|
|
49
50
|
if (this.#archetypeIndex[data.key] !== undefined) throw new Error(`Duplicate archetype key [${data.key}]`)
|
|
50
51
|
const archetype = new Archetype(data)
|
|
51
52
|
this.#archetypeIndex[archetype.key] = archetype
|
|
52
53
|
return archetype
|
|
53
54
|
}) ?? []
|
|
55
|
+
|
|
54
56
|
this.maps = bundle.maps?.map((data) => {
|
|
55
57
|
if (this.#mapIndex[data.key] !== undefined) throw new Error(`Duplicate map key [${data.key}]`)
|
|
56
58
|
const map = new GameMap(data)
|
|
57
59
|
this.#mapIndex[map.key] = map
|
|
58
60
|
return map
|
|
59
61
|
}) ?? []
|
|
60
|
-
this.badges = bundle.badges?.map((data) => {
|
|
61
|
-
if (this.#badgeIndex[data.key] !== undefined) throw new Error(`Duplicate badge key [${data.key}]`)
|
|
62
|
-
const badge = new Badge(data)
|
|
63
|
-
this.#badgeIndex[badge.key] = badge
|
|
64
|
-
return badge
|
|
65
|
-
}) ?? []
|
|
66
62
|
|
|
67
|
-
this
|
|
68
|
-
|
|
69
|
-
storeFields: ['key'],
|
|
70
|
-
})
|
|
71
|
-
for (const badge of this.badges) {
|
|
72
|
-
this.#badgeSearch.add(new BadgeSearchDocument(badge))
|
|
73
|
-
}
|
|
63
|
+
this.badges = bundle.badges?.map(data => new Badge(data)) ?? []
|
|
64
|
+
this.#badgeIndex = new BadgeIndex(this.badges, this.maps)
|
|
74
65
|
}
|
|
75
66
|
|
|
76
67
|
getArchetype(key: string): Archetype {
|
|
@@ -86,15 +77,16 @@ export class CohContentDatabase {
|
|
|
86
77
|
}
|
|
87
78
|
|
|
88
79
|
getBadge(key: string): Badge {
|
|
89
|
-
|
|
90
|
-
if (result === undefined) throw new Error(`Unknown badge key [${key}]`)
|
|
91
|
-
return result
|
|
80
|
+
return this.#badgeIndex.getBadge(key)
|
|
92
81
|
}
|
|
93
82
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Search, sort and filter the badge list.
|
|
85
|
+
* This is a fairly brute-forced approach and will not be as performant as loading the badge data into a traditional
|
|
86
|
+
* database engine, but is sufficient for most operations.
|
|
87
|
+
* @param options {@link BadgeSearchOptions}
|
|
88
|
+
*/
|
|
89
|
+
searchBadges(options?: BadgeSearchOptions): Paged<Badge> {
|
|
90
|
+
return this.#badgeIndex.searchBadges(options)
|
|
99
91
|
}
|
|
100
92
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { VidiotMapPointOfInterestData } from '../api/vidiot-map-point-of-interest-data'
|
|
2
|
+
import { MarkdownString } from '../api/markdown-string'
|
|
2
3
|
|
|
3
4
|
export class VidiotMapPointOfInterest {
|
|
4
5
|
/**
|
|
@@ -10,10 +11,8 @@ export class VidiotMapPointOfInterest {
|
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Freeform notes about the PoI.
|
|
13
|
-
*
|
|
14
|
-
* Supports {@link https://www.markdownguide.org/|Markdown} format.
|
|
15
14
|
*/
|
|
16
|
-
readonly notes?:
|
|
15
|
+
readonly notes?: MarkdownString
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
18
|
* If the POI is a zone transfer, the map it transfers to.
|
package/src/main/index.ts
CHANGED
|
@@ -10,6 +10,7 @@ export * from './api/change'
|
|
|
10
10
|
export * from './api/enhancement-category'
|
|
11
11
|
export * from './api/game-map-data'
|
|
12
12
|
export * from './api/link'
|
|
13
|
+
export * from './api/markdown-string'
|
|
13
14
|
export * from './api/plaque-type'
|
|
14
15
|
export * from './api/content-bundle'
|
|
15
16
|
export * from './api/sex'
|
|
@@ -17,13 +18,18 @@ export * from './api/vidiot-map-data'
|
|
|
17
18
|
export * from './api/vidiot-map-point-of-interest-data'
|
|
18
19
|
|
|
19
20
|
// DB
|
|
21
|
+
export * from './db/alignments'
|
|
22
|
+
export * from './db/alternates'
|
|
20
23
|
export * from './db/archetype'
|
|
21
24
|
export * from './db/badge'
|
|
25
|
+
export * from './db/badge-index'
|
|
22
26
|
export * from './db/badge-partial'
|
|
27
|
+
export * from './db/badge-search-options'
|
|
28
|
+
export * from './db/bundle-metadata'
|
|
23
29
|
export * from './db/coh-content-database'
|
|
24
30
|
export * from './db/game-map'
|
|
25
31
|
export * from './db/key'
|
|
26
|
-
export * from './db/
|
|
32
|
+
export * from './db/paged'
|
|
27
33
|
export * from './db/vidiot-map'
|
|
28
34
|
export * from './db/vidiot-map-point-of-interest'
|
|
29
35
|
|
package/src/main/util.ts
CHANGED
|
@@ -1,17 +1,47 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Returns the URI of the given badge that can be used in {@link MarkdownString} links.
|
|
3
|
+
*
|
|
4
|
+
* URI format: `badge://<key>`
|
|
5
|
+
*
|
|
3
6
|
* @param target The badge or badge key to target.
|
|
4
7
|
*/
|
|
5
|
-
export function
|
|
8
|
+
export function badgeUri(target: string | { key: string }): string {
|
|
6
9
|
const key = typeof target === 'string' ? target : target.key
|
|
7
|
-
return `
|
|
10
|
+
return `badge://${key}`
|
|
8
11
|
}
|
|
9
12
|
|
|
10
13
|
/**
|
|
11
|
-
*
|
|
14
|
+
* Returns a {@link MarkdownString} link to the given badge.
|
|
15
|
+
*
|
|
16
|
+
* Link format: `[<key>](badge://<key>)`
|
|
17
|
+
*
|
|
18
|
+
* @param target The badge or badge key to target.
|
|
19
|
+
*/
|
|
20
|
+
export function badgeLink(target: string | { key: string }): string {
|
|
21
|
+
const key = typeof target === 'string' ? target : target.key
|
|
22
|
+
return `[${key}](${badgeUri(target)})`
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Returns the URI of the given map that can be used in {@link MarkdownString} links.
|
|
27
|
+
*
|
|
28
|
+
* URI format: `map://<key>`
|
|
29
|
+
*
|
|
12
30
|
* @param target The {@link GameMap} or map key to target.
|
|
13
31
|
*/
|
|
14
|
-
export function
|
|
32
|
+
export function mapUri(target: string | { key: string }): string {
|
|
33
|
+
const key = typeof target === 'string' ? target : target.key
|
|
34
|
+
return `map://${key}`
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Returns a {@link MarkdownString} link to the given map.
|
|
39
|
+
*
|
|
40
|
+
* Link format: `[<key>](map://<key>)`
|
|
41
|
+
*
|
|
42
|
+
* @param target The map or map key to target.
|
|
43
|
+
*/
|
|
44
|
+
export function mapLink(target: string | { key: string }): string {
|
|
15
45
|
const key = typeof target === 'string' ? target : target.key
|
|
16
|
-
return `[
|
|
46
|
+
return `[${key}](${mapUri(target)})`
|
|
17
47
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Alignments } from '../../main'
|
|
2
|
+
|
|
3
|
+
describe(Alignments.name, () => {
|
|
4
|
+
test('should return the raw array', () => {
|
|
5
|
+
expect(new Alignments(['H', 'V']).items).toStrictEqual(['H', 'V'])
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
test('should detect a hero', () => {
|
|
9
|
+
expect(new Alignments(['H', 'V']).hero).toBeTruthy()
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
test('should detect a villain', () => {
|
|
13
|
+
expect(new Alignments(['H', 'V']).villain).toBeTruthy()
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
test('should detect a praetorian', () => {
|
|
17
|
+
expect(new Alignments(['H', 'V', 'P']).praetorian).toBeTruthy()
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
test('should detect a primal', () => {
|
|
21
|
+
expect(new Alignments(['H', 'V']).primal).toBeTruthy()
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test('should not falsely detect a hero', () => {
|
|
25
|
+
expect(new Alignments(['V']).hero).toBeFalsy()
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test('should not falsely detect a villain', () => {
|
|
29
|
+
expect(new Alignments(['H']).villain).toBeFalsy()
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
test('should not falsely detect a praetorian', () => {
|
|
33
|
+
expect(new Alignments(['V']).praetorian).toBeFalsy()
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
test('should falsely detect a primal', () => {
|
|
37
|
+
expect(new Alignments(['H', 'V', 'P']).primal).toBeFalsy()
|
|
38
|
+
expect(new Alignments(['P']).primal).toBeFalsy()
|
|
39
|
+
})
|
|
40
|
+
})
|
|
@@ -7,7 +7,7 @@ export const badgePartialDataFixture = defineFixture<BadgePartialData>((t) => {
|
|
|
7
7
|
t.mapKey?.asString()
|
|
8
8
|
t.loc?.asArray()
|
|
9
9
|
t.plaqueType?.pickFrom([...PLAQUE_TYPE])
|
|
10
|
-
t.
|
|
10
|
+
t.plaqueInscription?.asLoremIpsum()
|
|
11
11
|
t.vidiotMapKey?.asString()
|
|
12
12
|
t.badgeKey?.as(index => `badge-${index}`)
|
|
13
13
|
t.inventionLevel?.asNumber()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Alternates } from '../../main
|
|
1
|
+
import { Alternates } from '../../main'
|
|
2
2
|
|
|
3
3
|
describe(Alternates.name, () => {
|
|
4
4
|
describe('Constructor', () => {
|
|
@@ -89,7 +89,7 @@ describe(Alternates.name, () => {
|
|
|
89
89
|
{ alignment: 'H', value: 'Hero' },
|
|
90
90
|
{ alignment: 'V', sex: 'M', value: 'Male Villain' },
|
|
91
91
|
{ alignment: 'P', sex: 'F', value: 'Praetorian Female' },
|
|
92
|
-
]).default).toBe('Default')
|
|
92
|
+
]).default?.value).toBe('Default')
|
|
93
93
|
|
|
94
94
|
expect(new Alternates([
|
|
95
95
|
{ alignment: 'V', sex: 'M', value: 'Male Villain' },
|
|
@@ -97,14 +97,14 @@ describe(Alternates.name, () => {
|
|
|
97
97
|
{ sex: 'M', value: 'Male' },
|
|
98
98
|
{ value: 'Default' },
|
|
99
99
|
{ alignment: 'H', value: 'Hero' },
|
|
100
|
-
]).default).toBe('Default')
|
|
100
|
+
]).default?.value).toBe('Default')
|
|
101
101
|
|
|
102
102
|
expect(new Alternates([
|
|
103
103
|
{ alignment: 'V', sex: 'M', value: 'Male Villain' },
|
|
104
104
|
{ alignment: 'P', sex: 'F', value: 'Praetorian Female' },
|
|
105
105
|
{ sex: 'M', value: 'Male' },
|
|
106
106
|
{ alignment: 'H', value: 'Hero' },
|
|
107
|
-
]).default).toBe('Male')
|
|
107
|
+
]).default?.value).toBe('Male')
|
|
108
108
|
})
|
|
109
109
|
})
|
|
110
110
|
|
|
@@ -118,64 +118,30 @@ describe(Alternates.name, () => {
|
|
|
118
118
|
{ alignment: 'H', sex: 'F', value: 'Female Hero' },
|
|
119
119
|
{ alignment: 'P', value: 'Praetorian' },
|
|
120
120
|
{ sex: 'F', value: 'Female' },
|
|
121
|
-
{ alignment: 'H', sex: 'A', value: 'A Hero' },
|
|
122
|
-
{ alignment: 'Y', sex: 'A', value: 'A Y' },
|
|
123
121
|
{ alignment: 'V', sex: 'M', value: 'Male Villain' },
|
|
124
|
-
{ alignment: 'V', sex: 'B', value: 'B Villain' },
|
|
125
122
|
{ alignment: 'P', sex: 'M', value: 'Male Praetorian' },
|
|
126
123
|
{ alignment: 'H', value: 'Hero' },
|
|
127
|
-
{ alignment: 'V', sex: 'A', value: 'A Villain' },
|
|
128
|
-
{ sex: 'A', value: 'A Sex' },
|
|
129
|
-
{ alignment: 'X', sex: 'F', value: 'Female X' },
|
|
130
124
|
{ alignment: 'H', sex: 'M', value: 'Male Hero' },
|
|
131
|
-
{ alignment: 'X', value: 'X' },
|
|
132
|
-
{ alignment: 'P', sex: 'B', value: 'B Praetorian' },
|
|
133
|
-
{ alignment: 'P', sex: 'A', value: 'A Praetorian' },
|
|
134
|
-
{ alignment: 'X', sex: 'M', value: 'Male X' },
|
|
135
125
|
{ sex: 'M', value: 'Male' },
|
|
136
|
-
{ alignment: 'X', sex: 'B', value: 'B X' },
|
|
137
|
-
{ alignment: 'H', sex: 'B', value: 'B Hero' },
|
|
138
126
|
{ alignment: 'V', value: 'Villain' },
|
|
139
|
-
{ alignment: 'Y', sex: 'M', value: 'Male Y' },
|
|
140
127
|
{ alignment: 'V', sex: 'F', value: 'Female Villain' },
|
|
141
|
-
{ sex: 'B', value: 'B Sex' },
|
|
142
|
-
{ alignment: 'Y', sex: 'B', value: 'B Y' },
|
|
143
128
|
{ alignment: 'P', sex: 'F', value: 'Female Praetorian' },
|
|
144
|
-
{ alignment: 'X', sex: 'A', value: 'A X' },
|
|
145
129
|
{ value: 'Default' },
|
|
146
|
-
{ alignment: 'Y', sex: 'F', value: 'Female Y' },
|
|
147
130
|
]).canonical
|
|
148
131
|
|
|
149
132
|
expect(result).toStrictEqual([
|
|
150
133
|
{ value: 'Default' },
|
|
151
134
|
{ sex: 'M', value: 'Male' },
|
|
152
135
|
{ sex: 'F', value: 'Female' },
|
|
153
|
-
{ sex: 'A', value: 'A Sex' },
|
|
154
|
-
{ sex: 'B', value: 'B Sex' },
|
|
155
136
|
{ alignment: 'H', value: 'Hero' },
|
|
156
137
|
{ alignment: 'V', value: 'Villain' },
|
|
157
138
|
{ alignment: 'P', value: 'Praetorian' },
|
|
158
|
-
{ alignment: 'X', value: 'X' },
|
|
159
139
|
{ alignment: 'H', sex: 'M', value: 'Male Hero' },
|
|
160
140
|
{ alignment: 'H', sex: 'F', value: 'Female Hero' },
|
|
161
|
-
{ alignment: 'H', sex: 'A', value: 'A Hero' },
|
|
162
|
-
{ alignment: 'H', sex: 'B', value: 'B Hero' },
|
|
163
141
|
{ alignment: 'V', sex: 'M', value: 'Male Villain' },
|
|
164
142
|
{ alignment: 'V', sex: 'F', value: 'Female Villain' },
|
|
165
|
-
{ alignment: 'V', sex: 'A', value: 'A Villain' },
|
|
166
|
-
{ alignment: 'V', sex: 'B', value: 'B Villain' },
|
|
167
143
|
{ alignment: 'P', sex: 'M', value: 'Male Praetorian' },
|
|
168
144
|
{ alignment: 'P', sex: 'F', value: 'Female Praetorian' },
|
|
169
|
-
{ alignment: 'P', sex: 'A', value: 'A Praetorian' },
|
|
170
|
-
{ alignment: 'P', sex: 'B', value: 'B Praetorian' },
|
|
171
|
-
{ alignment: 'X', sex: 'M', value: 'Male X' },
|
|
172
|
-
{ alignment: 'X', sex: 'F', value: 'Female X' },
|
|
173
|
-
{ alignment: 'X', sex: 'A', value: 'A X' },
|
|
174
|
-
{ alignment: 'X', sex: 'B', value: 'B X' },
|
|
175
|
-
{ alignment: 'Y', sex: 'M', value: 'Male Y' },
|
|
176
|
-
{ alignment: 'Y', sex: 'F', value: 'Female Y' },
|
|
177
|
-
{ alignment: 'Y', sex: 'A', value: 'A Y' },
|
|
178
|
-
{ alignment: 'Y', sex: 'B', value: 'B Y' },
|
|
179
145
|
])
|
|
180
146
|
})
|
|
181
147
|
|
|
@@ -191,41 +157,17 @@ describe(Alternates.name, () => {
|
|
|
191
157
|
])
|
|
192
158
|
})
|
|
193
159
|
|
|
194
|
-
test('should sort identical values
|
|
160
|
+
test('should sort identical values by value alpha', () => {
|
|
195
161
|
expect(new Alternates([
|
|
196
|
-
{ value: '
|
|
197
|
-
{ value: '
|
|
198
|
-
{ value: '
|
|
199
|
-
{ value: '
|
|
200
|
-
]).canonical).toStrictEqual([
|
|
201
|
-
{ value: 'A' },
|
|
202
|
-
{ value: 'B' },
|
|
203
|
-
{ value: 'B' },
|
|
204
|
-
{ value: 'C' },
|
|
205
|
-
])
|
|
206
|
-
})
|
|
207
|
-
|
|
208
|
-
test('should sort unknown alignments by alpha', () => {
|
|
209
|
-
expect(new Alternates([
|
|
210
|
-
{ alignment: 'A', value: 'A' },
|
|
211
|
-
{ alignment: 'C', value: 'C' },
|
|
212
|
-
{ alignment: 'B', value: 'B' },
|
|
213
|
-
]).canonical).toStrictEqual([
|
|
214
|
-
{ alignment: 'A', value: 'A' },
|
|
215
|
-
{ alignment: 'B', value: 'B' },
|
|
216
|
-
{ alignment: 'C', value: 'C' },
|
|
217
|
-
])
|
|
218
|
-
})
|
|
219
|
-
|
|
220
|
-
test('should sort unknown sex by alpha', () => {
|
|
221
|
-
expect(new Alternates([
|
|
222
|
-
{ sex: 'A', value: 'A' },
|
|
223
|
-
{ sex: 'C', value: 'C' },
|
|
224
|
-
{ sex: 'B', value: 'B' },
|
|
162
|
+
{ alignment: 'V', value: 'B' },
|
|
163
|
+
{ sex: 'M', value: 'D' },
|
|
164
|
+
{ alignment: 'V', value: 'A' },
|
|
165
|
+
{ sex: 'M', value: 'C' },
|
|
225
166
|
]).canonical).toStrictEqual([
|
|
226
|
-
{ sex: '
|
|
227
|
-
{ sex: '
|
|
228
|
-
{
|
|
167
|
+
{ sex: 'M', value: 'C' },
|
|
168
|
+
{ sex: 'M', value: 'D' },
|
|
169
|
+
{ alignment: 'V', value: 'A' },
|
|
170
|
+
{ alignment: 'V', value: 'B' },
|
|
229
171
|
])
|
|
230
172
|
})
|
|
231
173
|
})
|
|
@@ -233,9 +175,9 @@ describe(Alternates.name, () => {
|
|
|
233
175
|
describe('toString', () => {
|
|
234
176
|
test('should create a string separated by the separator', () => {
|
|
235
177
|
expect(new Alternates([
|
|
236
|
-
{ sex: '
|
|
237
|
-
{ sex: '
|
|
238
|
-
{
|
|
178
|
+
{ sex: 'M', value: 'A' },
|
|
179
|
+
{ sex: 'F', value: 'B' },
|
|
180
|
+
{ alignment: 'H', value: 'C' },
|
|
239
181
|
]).toString(', ')).toBe('A, B, C')
|
|
240
182
|
})
|
|
241
183
|
})
|