import { parseFormulaRule, FormulaVariableContext } from './parseFormulaRule'

const context = (overrides: Partial<FormulaVariableContext> = {}) => ({
  columnNames: ['ITEM', 'PRICE', 'VOLUME', 'REVENUE'],
  rowIndex: 0,
  userName: 'sasdemo',
  origValue: 'sasinstaller',
  ...overrides
})

describe('parseFormulaRule', () => {
  it("substitutes column-name variables with this row's cell references (issue's own PRICE/VOLUME example)", () => {
    expect(parseFormulaRule('PRICE * VOLUME', context())).toEqual('=B1 * C1')
  })

  it('uses the row-relative reference for a later row', () => {
    expect(
      parseFormulaRule('PRICE * VOLUME', context({ rowIndex: 1 }))
    ).toEqual('=B2 * C2')
  })

  it('requires a leading/trailing blank (or string edge) around a variable - no match without it', () => {
    // No spaces around '*' - PRICE/VOLUME here should NOT be recognized as
    // variables (the issue's own rule: a named variable must have a
    // leading and trailing blank to avoid clashing with function names).
    expect(parseFormulaRule('PRICE*VOLUME', context())).toEqual('=PRICE*VOLUME')
  })

  it("does not substitute a variable name matched inside a function call with no surrounding blanks (the issue's MATCH() clash example)", () => {
    // MATCH is not one of our column names here, but this proves adjacency
    // to parens alone doesn't trigger substitution - only literal
    // surrounding whitespace (or string start/end) does.
    expect(parseFormulaRule('MATCH(PRICE)', context())).toEqual('=MATCH(PRICE)')
  })

  it("leaves variable occurrences inside quoted strings untouched (the issue's own ITEM example)", () => {
    expect(parseFormulaRule('ITEM & " string ITEM "', context())).toEqual(
      '=A1 & " string ITEM "'
    )
  })

  it('substitutes DC.USER_NAME with the quoted, literal current username', () => {
    expect(
      parseFormulaRule('DC.USER_NAME', context({ userName: 'sasdemo' }))
    ).toEqual('=\"sasdemo\"')
  })

  it('substitutes DC.ORIG_VALUE with the quoted, literal original cell value', () => {
    expect(
      parseFormulaRule('DC.ORIG_VALUE', context({ origValue: 'sasinstaller' }))
    ).toEqual('=\"sasinstaller\"')
  })

  it('does not substitute DC.USER_NAME/DC.ORIG_VALUE inside quoted strings either', () => {
    expect(parseFormulaRule('"DC.USER_NAME"', context())).toEqual(
      '=\"DC.USER_NAME\"'
    )
  })
})
