All files / test SunorhcTimeline._test.ts

0% Statements 0/113
0% Branches 0/1
0% Functions 0/1
0% Lines 0/113

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114                                                                                                                                                                                                                                   
import { describe, it, expect, vi, beforeEach } from 'vitest'
import { SunorhcTimeline } from '../src/SunorhcTimeline'
import * as Util from '../src/utils'
import * as packageJson from '../package.json'

// Mock the necessary utilities
vi.mock('./utils', () => ({
  deepMergeObjects: vi.fn(),
  isObject: vi.fn(),
  isEmptyObject: vi.fn(),
  deserialize: vi.fn(),
  validateTimelineOptions: vi.fn(),
  fetchData: vi.fn(),
  setStyles: vi.fn(),
  deepCloneObject: vi.fn(),
}))

describe('SunorhcTimeline', () => {
  const elementId = 'timeline-element'
  let targetElement: HTMLDivElement

  beforeEach(() => {
    document.body.innerHTML = `<div id="${elementId}" data-options='{"start":"2022-01-01","end":"2022-12-31"}'></div>`
    targetElement = document.querySelector<HTMLDivElement>(`#${elementId}`)!
  })

  it('should have a static VERSION property', () => {
    expect(SunorhcTimeline.VERSION).toBe(packageJson.version)
  })

  describe('create method', () => {
    it('should create an instance of SunorhcTimeline', async () => {
      const instance = await SunorhcTimeline.create(elementId, { start: '2023-01-01' })
      expect(instance).toBeInstanceOf(SunorhcTimeline)
      expect(instance.elementId).toBe(elementId)
    })

    it('should handle errors during options initialization', async () => {
      Util.deepMergeObjects.mockImplementationOnce(() => { throw new Error('Test Error') })
      const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => { })

      const instance = await SunorhcTimeline.create(elementId)
      expect(consoleErrorSpy).toHaveBeenCalledWith('Failed to create timeline:', expect.any(Error))
      expect(Util.setStyles).toHaveBeenCalledWith(instance.targetElement, { display: 'none' })

      consoleErrorSpy.mockRestore()
    })

    it('should add instance to global window object', async () => {
      await SunorhcTimeline.create(elementId)
      expect(window.SunorhcTimelineInstances[elementId]).toBeInstanceOf(SunorhcTimeline)
    })
  })

  describe('initOptions method', () => {
    let instance: SunorhcTimeline

    beforeEach(async () => {
      instance = await SunorhcTimeline.create(elementId)
    })

    it('should merge options from dataset', async () => {
      Util.deserialize.mockReturnValue({ timezone: 'UTC', scale: 'week' })
      Util.validateTimelineOptions.mockReturnValue({ timezone: 'UTC', scale: 'week' })
      Util.isObject.mockReturnValue(true)
      Util.deepMergeObjects.mockReturnValueOnce(instance.options)

      await instance['initOptions']()
      expect(Util.deepMergeObjects).toHaveBeenCalled()
    })

    it('should merge options from inputOptions', async () => {
      const inputOptions = { start: new Date('2023-01-01'), end: new Date('2023-12-31') }
      instance = await SunorhcTimeline.create(elementId, inputOptions)
      Util.isObject.mockReturnValue(true)
      Util.deepMergeObjects.mockReturnValueOnce(instance.options)
      await instance['initOptions']()
      expect(Util.deepMergeObjects).toHaveBeenCalled()
    })

    it('should fetch and merge options from external file', async () => {
      instance = await SunorhcTimeline.create(elementId, { file: 'config.json' })
      Util.fetchData.mockResolvedValue({ timezone: 'PST', scale: 'month' })
      Util.validateTimelineOptions.mockReturnValue({ timezone: 'PST', scale: 'month' })
      Util.deepMergeObjects.mockReturnValueOnce(instance.options)
      await instance['initOptions']()
      expect(Util.fetchData).toHaveBeenCalled()
      expect(Util.deepMergeObjects).toHaveBeenCalled()
    })
  })

  describe('getOptions method', () => {
    let instance: SunorhcTimeline

    beforeEach(async () => {
      instance = await SunorhcTimeline.create(elementId)
    })

    it('should return cloned options if toClone is true', () => {
      const clonedOptions = { ...instance.options }
      Util.deepCloneObject.mockReturnValue(clonedOptions)
      const options = instance.getOptions(true)
      expect(options).toEqual(clonedOptions)
      expect(Util.deepCloneObject).toHaveBeenCalledWith(instance.options)
    })

    it('should return options directly if toClone is false', () => {
      const options = instance.getOptions(false)
      expect(options).toEqual(instance.options)
      expect(Util.deepCloneObject).not.toHaveBeenCalled()
    })
  })
})