- Added Vue plugin to vitest.config.ts for better component testing. - Introduced vitest.setup.ts to expose Vue reactivity and lifecycle methods globally, ensuring compatibility with .vue components. - Updated mock implementations in nuxt-imports.ts to include readonly for improved reactivity handling. - Refactored useMapBookmarks and useToast composables to utilize readonly from Vue for better state management.
144 lines
4.3 KiB
TypeScript
144 lines
4.3 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
|
|
import L from 'leaflet'
|
|
import type { Map, LayerGroup } from 'leaflet'
|
|
import { createMarker, type MarkerData, type MapViewRef } from '../Marker'
|
|
|
|
vi.mock('leaflet', () => {
|
|
const markerMock = {
|
|
on: vi.fn().mockReturnThis(),
|
|
addTo: vi.fn().mockReturnThis(),
|
|
setLatLng: vi.fn().mockReturnThis(),
|
|
remove: vi.fn().mockReturnThis(),
|
|
bindTooltip: vi.fn().mockReturnThis(),
|
|
setTooltipContent: vi.fn().mockReturnThis(),
|
|
openPopup: vi.fn().mockReturnThis(),
|
|
closePopup: vi.fn().mockReturnThis(),
|
|
}
|
|
const point = (x: number, y: number) => ({ x, y })
|
|
const L = {
|
|
marker: vi.fn(() => markerMock),
|
|
Icon: vi.fn(),
|
|
point,
|
|
}
|
|
return { __esModule: true, default: L, ...L }
|
|
})
|
|
|
|
vi.mock('~/lib/LeafletCustomTypes', () => ({
|
|
HnHMaxZoom: 6,
|
|
TileSize: 100,
|
|
ImageIcon: vi.fn(),
|
|
}))
|
|
|
|
function makeMarkerData(overrides: Partial<MarkerData> = {}): MarkerData {
|
|
return {
|
|
id: 1,
|
|
position: { x: 100, y: 200 },
|
|
name: 'Tower',
|
|
image: 'gfx/terobjs/mm/tower',
|
|
hidden: false,
|
|
map: 1,
|
|
...overrides,
|
|
}
|
|
}
|
|
|
|
function makeMapViewRef(): MapViewRef {
|
|
return {
|
|
map: {
|
|
unproject: vi.fn(() => ({ lat: 0, lng: 0 })),
|
|
} as unknown as Map,
|
|
mapid: 1,
|
|
markerLayer: {
|
|
removeLayer: vi.fn(),
|
|
addLayer: vi.fn(),
|
|
} as unknown as LayerGroup,
|
|
}
|
|
}
|
|
|
|
describe('createMarker', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
it('creates a marker with correct properties', () => {
|
|
const marker = createMarker(makeMarkerData(), undefined, L)
|
|
expect(marker.id).toBe(1)
|
|
expect(marker.name).toBe('Tower')
|
|
expect(marker.position).toEqual({ x: 100, y: 200 })
|
|
expect(marker.image).toBe('gfx/terobjs/mm/tower')
|
|
expect(marker.hidden).toBe(false)
|
|
expect(marker.map).toBe(1)
|
|
expect(marker.value).toBe(1)
|
|
expect(marker.text).toBe('Tower')
|
|
})
|
|
|
|
it('detects quest type', () => {
|
|
const marker = createMarker(makeMarkerData({ image: 'gfx/invobjs/small/bush' }), undefined, L)
|
|
expect(marker.type).toBe('quest')
|
|
})
|
|
|
|
it('detects quest type for bumling', () => {
|
|
const marker = createMarker(makeMarkerData({ image: 'gfx/invobjs/small/bumling' }), undefined, L)
|
|
expect(marker.type).toBe('quest')
|
|
})
|
|
|
|
it('detects custom type', () => {
|
|
const marker = createMarker(makeMarkerData({ image: 'custom' }), undefined, L)
|
|
expect(marker.type).toBe('custom')
|
|
})
|
|
|
|
it('extracts type from gfx path', () => {
|
|
const marker = createMarker(makeMarkerData({ image: 'gfx/terobjs/mm/village' }), undefined, L)
|
|
expect(marker.type).toBe('village')
|
|
})
|
|
|
|
it('starts with null leaflet marker', () => {
|
|
const marker = createMarker(makeMarkerData(), undefined, L)
|
|
expect(marker.leafletMarker).toBeNull()
|
|
})
|
|
|
|
it('add creates a leaflet marker for non-hidden markers', () => {
|
|
const marker = createMarker(makeMarkerData(), undefined, L)
|
|
const mapview = makeMapViewRef()
|
|
marker.add(mapview)
|
|
expect(mapview.map.unproject).toHaveBeenCalled()
|
|
})
|
|
|
|
it('add does nothing for hidden markers', () => {
|
|
const marker = createMarker(makeMarkerData({ hidden: true }), undefined, L)
|
|
const mapview = makeMapViewRef()
|
|
marker.add(mapview)
|
|
expect(mapview.map.unproject).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('update changes position and name', () => {
|
|
const marker = createMarker(makeMarkerData(), undefined, L)
|
|
const mapview = makeMapViewRef()
|
|
|
|
marker.update(mapview, {
|
|
...makeMarkerData(),
|
|
position: { x: 300, y: 400 },
|
|
name: 'Castle',
|
|
})
|
|
|
|
expect(marker.position).toEqual({ x: 300, y: 400 })
|
|
expect(marker.name).toBe('Castle')
|
|
})
|
|
|
|
it('setClickCallback and setContextMenu work', () => {
|
|
const marker = createMarker(makeMarkerData(), undefined, L)
|
|
const clickCb = vi.fn()
|
|
const contextCb = vi.fn()
|
|
|
|
marker.setClickCallback(clickCb)
|
|
marker.setContextMenu(contextCb)
|
|
})
|
|
|
|
it('remove on a marker without leaflet marker does nothing', () => {
|
|
const marker = createMarker(makeMarkerData(), undefined, L)
|
|
const mapview = makeMapViewRef()
|
|
marker.remove(mapview) // should not throw
|
|
expect(marker.leafletMarker).toBeNull()
|
|
})
|
|
})
|