- de.ts: traits-Array -> traitCategories (4 Kategorien: Sozialverhalten / Eignung & Umgang / Hobbys & Eigenarten / Wesen & Temperament); alle 15 bestehenden Keys erhalten (stored auf Live-Tieren); 10 neue Keys additiv; warn:true auf schwer-vergesellschaftbar + territorial. - format/traits.ts: TraitEntry/TraitCategory-Interface, TRAIT_CATEGORIES-Export, ALL_TRAITS via flatMap, neuer isWarnTrait()-Helper. - Charakterbogen.tsx: grouped-Rendering nach Kategorie (section + h4); warn-Chips mit trait-chip--warn-Klasse + trait-warn-badge. - charakterbogen.css: .trait-category__heading + .trait-chip--warn (amber) + .trait-warn-badge. - format/__tests__/traits.test.ts: 14 neue Vitest-Tests (Kategorien, Keys, warn, traitLabel/traitLabels). - Gate: vitest 122/122, tsc clean, build clean, eslint clean.
92 lines
3.1 KiB
TypeScript
92 lines
3.1 KiB
TypeScript
import { describe, it, expect } from 'vitest'
|
|
import { ALL_TRAITS, TRAIT_CATEGORIES, traitLabel, traitLabels, isWarnTrait } from '../traits'
|
|
|
|
describe('trait catalog', () => {
|
|
it('has 4 categories', () => {
|
|
expect(TRAIT_CATEGORIES).toHaveLength(4)
|
|
})
|
|
|
|
it('category names match spec', () => {
|
|
const names = TRAIT_CATEGORIES.map((c) => c.category)
|
|
expect(names).toEqual([
|
|
'Sozialverhalten',
|
|
'Eignung & Umgang',
|
|
'Hobbys & Eigenarten',
|
|
'Wesen & Temperament',
|
|
])
|
|
})
|
|
|
|
it('ALL_TRAITS flattens all categories', () => {
|
|
const total = TRAIT_CATEGORIES.reduce((sum, c) => sum + c.traits.length, 0)
|
|
expect(ALL_TRAITS).toHaveLength(total)
|
|
})
|
|
|
|
it('all keys are unique', () => {
|
|
const keys = ALL_TRAITS.map((t) => t.key)
|
|
expect(new Set(keys).size).toBe(keys.length)
|
|
})
|
|
|
|
it('existing 15 keys are still present (stored on live animals)', () => {
|
|
const legacy = [
|
|
'zutraulich', 'handzahm', 'neugierig', 'aufgeschlossen', 'ruhig', 'lebhaft',
|
|
'verschmust', 'eigenstaendig', 'anfaengergeeignet', 'futterfreudig',
|
|
'buddelt', 'klettert', 'laufrad', 'vertraeglich', 'schreckhaft',
|
|
]
|
|
const allKeys = new Set(ALL_TRAITS.map((t) => t.key))
|
|
for (const key of legacy) {
|
|
expect(allKeys.has(key), `missing legacy key: ${key}`).toBe(true)
|
|
}
|
|
})
|
|
|
|
it('new keys are present', () => {
|
|
const newKeys = [
|
|
'dominant', 'rangniedrig', 'sozialkompetent', 'schwer-vergesellschaftbar',
|
|
'erfahrene-halter', 'beobachtungstier', 'familiengeeignet',
|
|
'schredder', 'nestbauer', 'territorial',
|
|
]
|
|
const allKeys = new Set(ALL_TRAITS.map((t) => t.key))
|
|
for (const key of newKeys) {
|
|
expect(allKeys.has(key), `missing new key: ${key}`).toBe(true)
|
|
}
|
|
})
|
|
|
|
it('warn traits are schwer-vergesellschaftbar and territorial', () => {
|
|
expect(isWarnTrait('schwer-vergesellschaftbar')).toBe(true)
|
|
expect(isWarnTrait('territorial')).toBe(true)
|
|
})
|
|
|
|
it('non-warn traits return false from isWarnTrait', () => {
|
|
expect(isWarnTrait('zutraulich')).toBe(false)
|
|
expect(isWarnTrait('dominant')).toBe(false)
|
|
expect(isWarnTrait('beobachtungstier')).toBe(false)
|
|
expect(isWarnTrait('schreckhaft')).toBe(false)
|
|
})
|
|
|
|
it('unknown key returns false from isWarnTrait', () => {
|
|
expect(isWarnTrait('not-a-real-key')).toBe(false)
|
|
})
|
|
|
|
it('traitLabel returns German label for known key', () => {
|
|
expect(traitLabel('zutraulich')).toBe('zutraulich')
|
|
expect(traitLabel('dominant')).toBe('dominant (Leittier)')
|
|
expect(traitLabel('schwer-vergesellschaftbar')).toBe('schwer vergesellschaftbar')
|
|
expect(traitLabel('territorial')).toBe('territorial')
|
|
})
|
|
|
|
it('traitLabel returns the key itself for unknown key', () => {
|
|
expect(traitLabel('not-a-real-key')).toBe('not-a-real-key')
|
|
})
|
|
|
|
it('traitLabels maps a list of keys to labels', () => {
|
|
expect(traitLabels(['zutraulich', 'dominant'])).toEqual([
|
|
'zutraulich',
|
|
'dominant (Leittier)',
|
|
])
|
|
})
|
|
|
|
it('traitLabels handles null and undefined gracefully', () => {
|
|
expect(traitLabels(null)).toEqual([])
|
|
expect(traitLabels(undefined)).toEqual([])
|
|
})
|
|
})
|