import { describe, it, expect } from 'vitest'
import { Workbook, CellUtils } from './excelEngine'

function createWorkbookWithSheet(name = 'Sheet1') {
  const wb = new Workbook()
  const sheet = wb.addSheet(name)
  return { wb, sheet }
}

describe('Workbook — формулы', () => {
  // ==================== Базовые значения ====================

  describe('Базовые значения', () => {
    it('устанавливает и получает число', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 42)
      expect(wb.getValue('Sheet1!A1')).toBe(42)
    })

    it('устанавливает и получает строку', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 'hello')
      expect(wb.getValue('Sheet1!A1')).toBe('hello')
    })

    it('пустая ячейка возвращает null', () => {
      const { wb } = createWorkbookWithSheet()
      expect(wb.getValue('Sheet1!A1')).toBe(null)
    })
  })

  // ==================== Простые формулы ====================

  describe('Простые формулы', () => {
    it('формула с числом', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', '=1+2')
      expect(wb.getValue('Sheet1!A1')).toBe(3)
    })

    it('формула со ссылкой на ячейку', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 10)
      sheet.setCell('A2', '=A1+5')
      expect(wb.getValue('Sheet1!A2')).toBe(15)
    })

    it('формула с несколькими ссылками', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 10)
      sheet.setCell('A2', 20)
      sheet.setCell('A3', '=A1+A2')
      expect(wb.getValue('Sheet1!A3')).toBe(30)
    })
  })

  // ==================== Функции в формулах ====================

  describe('СУММ в формуле', () => {
    it('суммирует диапазон', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 1)
      sheet.setCell('A2', 2)
      sheet.setCell('A3', 3)
      sheet.setCell('B1', '=СУММ(A1:A3)')
      expect(wb.getValue('Sheet1!B1')).toBe(6)
    })
  })

  describe('СРЗНАЧ в формуле', () => {
    it('считает среднее диапазона', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 2)
      sheet.setCell('A2', 4)
      sheet.setCell('A3', 6)
      sheet.setCell('B1', '=СРЗНАЧ(A1:A3)')
      expect(wb.getValue('Sheet1!B1')).toBe(4)
    })
  })

  describe('МАКС в формуле', () => {
    it('возвращает максимум двух ячеек', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 3)
      sheet.setCell('A2', 7)
      sheet.setCell('B1', '=МАКС(A1, A2)')
      expect(wb.getValue('Sheet1!B1')).toBe(7)
    })
  })

  describe('СТЕПЕНЬ в формуле', () => {
    it('возводит значение ячейки в степень', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 2)
      sheet.setCell('B1', '=СТЕПЕНЬ(A1, 10)')
      expect(wb.getValue('Sheet1!B1')).toBe(1024)
    })
  })

  describe('КОРЕНЬ в формуле', () => {
    it('извлекает корень из ячейки', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 25)
      sheet.setCell('B1', '=КОРЕНЬ(A1)')
      expect(wb.getValue('Sheet1!B1')).toBe(5)
    })
  })

  describe('ABS в формуле', () => {
    it('возвращает модуль ячейки', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', -15)
      sheet.setCell('B1', '=ABS(A1)')
      expect(wb.getValue('Sheet1!B1')).toBe(15)
    })
  })

  // ==================== БОЛЬШЕ / МЕНЬШЕ ====================

  describe('БОЛЬШЕ в формуле', () => {
    it('сравнивает два числа', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 10)
      sheet.setCell('A2', 5)
      sheet.setCell('B1', '=БОЛЬШЕ(A1, A2)')
      expect(wb.getValue('Sheet1!B1')).toBe(true)
    })

    it('возвращает false при меньшем значении', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 3)
      sheet.setCell('A2', 5)
      sheet.setCell('B1', '=БОЛЬШЕ(A1, A2)')
      expect(wb.getValue('Sheet1!B1')).toBe(false)
    })
  })

  describe('МЕНЬШЕ в формуле', () => {
    it('сравнивает два числа', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 3)
      sheet.setCell('A2', 10)
      sheet.setCell('B1', '=МЕНЬШЕ(A1, A2)')
      expect(wb.getValue('Sheet1!B1')).toBe(true)
    })
  })

  // ==================== ЕСЛИ + БОЛЬШЕ/МЕНЬШЕ ====================

  describe('ЕСЛИ + БОЛЬШЕ/МЕНЬШЕ', () => {
    it('ЕСЛИ(БОЛЬШЕ(...)) возвращает правильную ветку', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 100)
      sheet.setCell('B1', '=ЕСЛИ(БОЛЬШЕ(A1, 50), "Много", "Мало")')
      expect(wb.getValue('Sheet1!B1')).toBe('Много')
    })

    it('ЕСЛИ(МЕНЬШЕ(...)) возвращает ветку лжи', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 100)
      sheet.setCell('B1', '=ЕСЛИ(МЕНЬШЕ(A1, 50), "Мало", "Много")')
      expect(wb.getValue('Sheet1!B1')).toBe('Много')
    })

    it('ЕСЛИ с И и БОЛЬШЕ', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 50)
      sheet.setCell('B1', '=ЕСЛИ(И(БОЛЬШЕ(A1, 10), МЕНЬШЕ(A1, 100)), "В диапазоне", "Вне")')
      expect(wb.getValue('Sheet1!B1')).toBe('В диапазоне')
    })

    it('ЕСЛИ с ИЛИ', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 5)
      sheet.setCell('B1', '=ЕСЛИ(ИЛИ(БОЛЬШЕ(A1, 100), МЕНЬШЕ(A1, 10)), "Крайнее", "Норм")')
      expect(wb.getValue('Sheet1!B1')).toBe('Крайнее')
    })

    it('вложенный ЕСЛИ', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 50)
      sheet.setCell('B1', '=ЕСЛИ(БОЛЬШЕ(A1, 100), "Много", ЕСЛИ(МЕНЬШЕ(A1, 10), "Мало", "Норм"))')
      expect(wb.getValue('Sheet1!B1')).toBe('Норм')
    })
  })

  // ==================== ЕПУСТО ====================

  describe('ЕПУСТО в формуле', () => {
    it('true для пустой ячейки', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('B1', '=ЕПУСТО(A1)')
      expect(wb.getValue('Sheet1!B1')).toBe(true)
    })

    it('false для заполненной ячейки', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 42)
      sheet.setCell('B1', '=ЕПУСТО(A1)')
      expect(wb.getValue('Sheet1!B1')).toBe(false)
    })

    it('false для ячейки с нулём', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 0)
      sheet.setCell('B1', '=ЕПУСТО(A1)')
      expect(wb.getValue('Sheet1!B1')).toBe(false)
    })

    it('ЕСЛИ(ЕПУСТО(...)) работает', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('B1', '=ЕСЛИ(ЕПУСТО(A1), "Пусто", "Заполнено")')
      expect(wb.getValue('Sheet1!B1')).toBe('Пусто')
    })
  })

  // ==================== Строковые функции в формулах ====================

  describe('Строковые функции в формулах', () => {
    it('СЦЕПИТЬ', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 'Привет')
      sheet.setCell('A2', ' мир')
      sheet.setCell('B1', '=СЦЕПИТЬ(A1, A2)')
      expect(wb.getValue('Sheet1!B1')).toBe('Привет мир')
    })

    it('ПРОПИСН', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 'hello')
      sheet.setCell('B1', '=ПРОПИСН(A1)')
      expect(wb.getValue('Sheet1!B1')).toBe('HELLO')
    })

    it('СТРОЧН', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 'HELLO')
      sheet.setCell('B1', '=СТРОЧН(A1)')
      expect(wb.getValue('Sheet1!B1')).toBe('hello')
    })
  })

  // ==================== Округление в формулах ====================

  describe('Округление в формулах', () => {
    it('ОКРУГЛ', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 3.456)
      sheet.setCell('B1', '=ОКРУГЛ(A1, 2)')
      expect(wb.getValue('Sheet1!B1')).toBe(3.46)
    })

    it('ЦЕЛОЕ', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 3.9)
      sheet.setCell('B1', '=ЦЕЛОЕ(A1)')
      expect(wb.getValue('Sheet1!B1')).toBe(3)
    })
  })

  // ==================== Межлистовые ссылки ====================

  describe('Межлистовые ссылки', () => {
    it('ссылка на другой лист', () => {
      const wb = new Workbook()
      const sheetL = wb.addSheet('L')
      const sheetR = wb.addSheet('R')
      sheetL.setCell('A1', 100)
      sheetR.setCell('A1', '=L!A1+50')
      expect(wb.getValue('R!A1')).toBe(150)
    })
  })

  // ==================== Зависимости и пересчёт ====================

  describe('Зависимости и пересчёт', () => {
    it('пересчёт при изменении зависимой ячейки', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 10)
      sheet.setCell('B1', '=A1*2')
      expect(wb.getValue('Sheet1!B1')).toBe(20)

      sheet.setCell('A1', 20)
      expect(wb.getValue('Sheet1!B1')).toBe(40)
    })

    it('цепочка зависимостей', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 5)
      sheet.setCell('A2', '=A1+1')
      sheet.setCell('A3', '=A2+1')
      expect(wb.getValue('Sheet1!A3')).toBe(7)

      sheet.setCell('A1', 10)
      expect(wb.getValue('Sheet1!A3')).toBe(12)
    })
  })

  // ==================== Замена функций (регрессия) ====================

  describe('Регрессия: замена функций не ломает кириллические имена', () => {
    it('ЕСЛИ не должен быть разбит заменой И', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 50)
      sheet.setCell('B1', '=ЕСЛИ(БОЛЬШЕ(A1, 100), "Много", "Мало")')
      expect(wb.getValue('Sheet1!B1')).toBe('Мало')
    })

    it('И внутри ЕСЛИ(И(...)) работает корректно', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 50)
      sheet.setCell('B1', '=ЕСЛИ(И(БОЛЬШЕ(A1, 10), МЕНЬШЕ(A1, 100)), "Да", "Нет")')
      expect(wb.getValue('Sheet1!B1')).toBe('Да')
    })

    it('НЕ не ломает другие функции', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 50)
      sheet.setCell('B1', '=ЕСЛИ(НЕ(БОЛЬШЕ(A1, 100)), "Не больше", "Больше")')
      expect(wb.getValue('Sheet1!B1')).toBe('Не больше')
    })
  })

  // ==================== Case-insensitive функции ====================

  describe('Функции в нижнем регистре', () => {
    it('случдр в нижнем регистре', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', '=случдр(1, 10, 2)')
      const val = wb.getValue('Sheet1!A1') as number
      expect(val).toBeGreaterThanOrEqual(1)
      expect(val).toBeLessThanOrEqual(10)
    })

    it('округл в нижнем регистре', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', '=округл(3.456, 2)')
      expect(wb.getValue('Sheet1!A1')).toBe(3.46)
    })

    it('сумм в нижнем регистре', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 1)
      sheet.setCell('A2', 2)
      sheet.setCell('A3', 3)
      sheet.setCell('B1', '=сумм(A1:A3)')
      expect(wb.getValue('Sheet1!B1')).toBe(6)
    })

    it('если в нижнем регистре с больше', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 100)
      sheet.setCell('B1', '=если(больше(A1, 50), "Много", "Мало")')
      expect(wb.getValue('Sheet1!B1')).toBe('Много')
    })

    it('смешанный регистр', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 5)
      sheet.setCell('B1', '=Если(Больше(A1, 3), "да", "нет")')
      expect(wb.getValue('Sheet1!B1')).toBe('да')
    })

    it('епусто в нижнем регистре — пустая ячейка', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('B1', '=епусто(A1)')
      expect(wb.getValue('Sheet1!B1')).toBe(true)
    })

    it('епусто в нижнем регистре — заполненная ячейка', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('A1', 42)
      sheet.setCell('B1', '=епусто(A1)')
      expect(wb.getValue('Sheet1!B1')).toBe(false)
    })

    it('если(епусто(...)) в нижнем регистре', () => {
      const { wb, sheet } = createWorkbookWithSheet()
      sheet.setCell('B1', '=если(епусто(A1), "Пусто", "Есть")')
      expect(wb.getValue('Sheet1!B1')).toBe('Пусто')
    })
  })
})

// ==================== Сценарий протокола ====================

describe('Сценарий протокола: шаблон → ввод данных → пересчёт → выгрузка', () => {
  /**
   * Имитирует реальный flow:
   * 1. Загружается шаблон с формулами (fromJSON)
   * 2. Пользователь заполняет форму → значения пишутся в ячейки (setCell)
   * 3. Движок пересчитывает формулы (recalc)
   * 4. getAllModifiedCells / toJSON отдают данные для бэкенда
   */

  function createProtocolWorkbook() {
    const wb = new Workbook()
    wb.addSheet('L') // лист протокола
    wb.addSheet('R') // лист настроек/расчётов
    return wb
  }

  it('загрузка шаблона и пересчёт формул', () => {
    const wb = createProtocolWorkbook()

    // Шаблон: R!A1 — имя файла, R!A2 — область печати
    // L!A1 — заголовок, L!B1 — формула суммы
    wb.fromJSON({
      L: {
        A1: 'Протокол испытаний',
        A2: 10,
        A3: 20,
        A4: '=СУММ(A2:A3)',
      },
      R: {
        A1: 'protocol_output.xlsx',
        A2: 'A1:D20',
      },
    })

    expect(wb.getValue('L!A1')).toBe('Протокол испытаний')
    expect(wb.getValue('L!A4')).toBe(30)
    expect(wb.getValue('R!A1')).toBe('protocol_output.xlsx')
    expect(wb.getValue('R!A2')).toBe('A1:D20')
  })

  it('ввод данных из формы и пересчёт зависимых ячеек', () => {
    const wb = createProtocolWorkbook()

    wb.fromJSON({
      L: {
        A1: '',  // ячейка для ввода (пустая в шаблоне)
        B1: '=ОКРУГЛ(A1 * 1.2, 2)',  // формула зависит от A1
        C1: '=ЕСЛИ(БОЛЬШЕ(B1, 100), "Не соответствует", "Соответствует")',
      },
    })

    // Первый recalc после загрузки (как в useMultiSheetEngine.safeRecalc)
    wb.recalc()

    // Пользователь вводит значение через форму → setCellValue
    wb.setCell('L!A1', 50)
    expect(wb.getValue('L!B1')).toBe(60)
    expect(wb.getValue('L!C1')).toBe('Соответствует')

    // Пользователь меняет значение
    wb.setCell('L!A1', 100)
    expect(wb.getValue('L!B1')).toBe(120)
    expect(wb.getValue('L!C1')).toBe('Не соответствует')
  })

  it('формулы со ссылками между листами L и R', () => {
    const wb = createProtocolWorkbook()

    wb.fromJSON({
      R: {
        A5: 0.15,      // коэффициент из настроек
        C1: '=случдр(10, 20, 2)', // случайное значение
      },
      L: {
        A1: 100,
        B1: '=ОКРУГЛ(A1 * R!A5, 2)', // 100 * 0.15 = 15
      },
    })

    expect(wb.getValue('L!B1')).toBe(15)

    // recalc чтобы зарегистрировать зависимости
    wb.recalc()

    // Меняем входное значение
    wb.setCell('L!A1', 200)
    expect(wb.getValue('L!B1')).toBe(30)
  })

  it('ЕСЛИ + БОЛЬШЕ + МЕНЬШЕ в контексте протокола', () => {
    const wb = createProtocolWorkbook()

    // Типичный сценарий: проверка допусков
    wb.fromJSON({
      L: {
        A1: 'Параметр',
        A2: 50,           // измеренное значение
        B2: 10,           // нижний допуск
        C2: 100,          // верхний допуск
        D2: '=ЕСЛИ(И(БОЛЬШЕ(A2, B2), МЕНЬШЕ(A2, C2)), "Годен", "Брак")',
      },
    })

    expect(wb.getValue('L!D2')).toBe('Годен')

    // Значение вне допуска
    wb.setCell('L!A2', 5)
    expect(wb.getValue('L!D2')).toBe('Брак')

    // Значение на верхней границе — БОЛЬШЕ возвращает false при равенстве
    wb.setCell('L!A2', 100)
    expect(wb.getValue('L!D2')).toBe('Брак')
  })

  it('ЕПУСТО в контексте протокола — пропуск пустых строк', () => {
    const wb = createProtocolWorkbook()

    wb.fromJSON({
      L: {
        A1: 42,
        B1: '=ЕСЛИ(ЕПУСТО(A1), "", ОКРУГЛ(A1 * 1.1, 1))',
        A2: '',  // пустая
        B2: '=ЕСЛИ(ЕПУСТО(A2), "", ОКРУГЛ(A2 * 1.1, 1))',
      },
    })

    expect(wb.getValue('L!B1')).toBe(46.2)
    expect(wb.getValue('L!B2')).toBe('')
  })

  it('СТЕПЕНЬ в формулах протокола', () => {
    const wb = createProtocolWorkbook()

    wb.fromJSON({
      L: {
        A1: 3,
        B1: '=СТЕПЕНЬ(A1, 2)',     // 9
        C1: '=КОРЕНЬ(B1)',          // 3
      },
    })

    expect(wb.getValue('L!B1')).toBe(9)
    expect(wb.getValue('L!C1')).toBe(3)
  })

  it('цепочка пересчёта: A → B → C → D', () => {
    const wb = createProtocolWorkbook()

    wb.fromJSON({
      L: {
        A1: 10,
        B1: '=A1 * 2',       // 20
        C1: '=B1 + 5',       // 25
        D1: '=ОКРУГЛ(C1 / 3, 2)', // 8.33
      },
    })

    expect(wb.getValue('L!D1')).toBe(8.33)

    wb.setCell('L!A1', 100)
    // 100 → 200 → 205 → 68.33
    expect(wb.getValue('L!B1')).toBe(200)
    expect(wb.getValue('L!C1')).toBe(205)
    expect(wb.getValue('L!D1')).toBe(68.33)
  })

  it('toJSON возвращает raw-значения (формулы) для бэкенда', () => {
    const wb = createProtocolWorkbook()

    wb.fromJSON({
      L: {
        A1: 10,
        B1: '=A1 * 2',
      },
    })

    // getValue возвращает вычисленное
    expect(wb.getValue('L!B1')).toBe(20)

    // toJSON возвращает raw (формулу) — это идёт в cells_to_update
    const json = wb.toJSON()
    expect(json['L']['A1']).toBe(10)
    expect(json['L']['B1']).toBe('=A1 * 2')
  })

  it('getAllModifiedCells: baseline vs текущее состояние', () => {
    const wb = createProtocolWorkbook()

    // Загружаем шаблон
    const templateData = {
      L: {
        A1: '',
        B1: '=A1 * 2',
      },
    }

    wb.fromJSON(templateData)

    // Сохраняем baseline (как делает setTemplateData в хуке)
    const baseline = JSON.parse(JSON.stringify(templateData))

    // Пользователь вводит данные
    wb.setCell('L!A1', 42)

    // Сравниваем текущее с baseline
    const currentData = wb.toJSON()
    const modified: Record<string, any> = {}

    for (const cellAddr of Object.keys(currentData['L'] || {})) {
      const current = String(currentData['L'][cellAddr] ?? '')
      const original = String(baseline['L']?.[cellAddr] ?? '')
      if (current !== original) {
        modified[cellAddr] = currentData['L'][cellAddr]
      }
    }

    // A1 изменилась (была '', стала 42)
    expect(modified['A1']).toBe(42)
    // B1 не изменилась (формула та же)
    expect(modified['B1']).toBeUndefined()
  })

  it('множественные элементы формы → разные ячейки', () => {
    const wb = createProtocolWorkbook()

    wb.fromJSON({
      L: {
        A1: '', // ячейка для ввода
        B1: '', // ячейка для ввода
        A2: '', // ячейка для ввода
        B2: '', // ячейка для ввода
        // Формулы зависят от ячеек, куда пишутся значения формы
        C1: '=СЦЕПИТЬ(A1, " ", B1)',
        C2: '=A2 + B2',
      },
    })

    // Первый recalc после загрузки (как в useMultiSheetEngine)
    wb.recalc()

    // Элемент формы 1 → A1 (текст)
    wb.setCell('L!A1', 'Иванов')
    // Элемент формы 2 → B1 (текст)
    wb.setCell('L!B1', 'И.И.')

    // Элемент формы 3 → A2 (число)
    wb.setCell('L!A2', 10)
    // Элемент формы 4 → B2 (число)
    wb.setCell('L!B2', 20)

    expect(wb.getValue('L!C1')).toBe('Иванов И.И.')
    expect(wb.getValue('L!C2')).toBe(30)
  })

  it('формулы в нижнем регистре в шаблоне (как в реальных данных)', () => {
    const wb = createProtocolWorkbook()

    wb.fromJSON({
      R: {
        C7: '=случдр(16, 17.6, 3)',
        D7: '=если(больше(A1, 100), "Много", "Мало")',
      },
      L: {
        A1: 50,
      },
    })

    // случдр должна вернуть число в диапазоне
    const c7 = wb.getValue('R!C7') as number
    expect(c7).toBeGreaterThanOrEqual(16)
    expect(c7).toBeLessThanOrEqual(17.6)

    // если + больше в нижнем регистре
    expect(wb.getValue('R!D7')).toBe('Мало')
  })
})

// ==================== CellUtils ====================

describe('CellUtils', () => {
  it('indexToColumn', () => {
    expect(CellUtils.indexToColumn(0)).toBe('A')
    expect(CellUtils.indexToColumn(25)).toBe('Z')
    expect(CellUtils.indexToColumn(26)).toBe('AA')
  })

  it('createCellName с номером колонки', () => {
    expect(CellUtils.createCellName(0, 1)).toBe('A1')
    expect(CellUtils.createCellName(2, 5)).toBe('C5')
  })

  it('createCellName со строкой колонки', () => {
    expect(CellUtils.createCellName('B', 3)).toBe('B3')
  })
})
