local SUITE = require 'TestSuite' 'number'
SUITE:setEnvironment{
    format  = require('pretty')
}

local function format_test (t)
    SUITE:addTest(t.expect, function ()
        assert_equal(t.expect, format(t.input, t.options))
    end, { line = debug.getinfo(2).currentline })
end

local function number_test (t)
    if t.single then
        SUITE:addTest((t.name or t.expect)..' single', function ()
            assert_equal(t.single, format(t.input, {}))
        end, { line = debug.getinfo(2).currentline })
    end
    SUITE:addTest((t.name or t.expect) .. ' small', function ()
        assert_equal('{ '..t.expect..' }', format({t.input}, {}))
    end, { line = debug.getinfo(2).currentline })
end

--------------------------------------------------------------------------------
-- Integers

number_test {
    input  =  0,
    expect = '0',
}

number_test {
    input  = -0,
    expect = '0',
}

number_test {
    input  = 2000,
    expect = '2000',
    single = '2000',
}

number_test {
    input  = -2000,
    expect = '-2000',
}

--------------------------------------------------------------------------------
-- Exponents

number_test {
    input     =  10^5,
    expect    = '10^5',
}

number_test {
    input     =  10^-6,
    expect    = '10^-6',
}

number_test {
    input     =  2^17,
    expect    = '2^17',
}

number_test {
    input     =  2^-7,
    expect    = '2^-7',
}

--------------------------------------------------------------------------------
-- Decimal numbers

number_test {
    input  = 0.1,
    expect = '0.1',
}

number_test {
    input  = 0.65,
    expect = '0.65',
}

number_test {
    input  = 2.05,
    expect = '2.05',
}

number_test {
    input  = 2.0512523,
    expect = '2.0512523',
}

number_test {
    name   = 'Large decimal number',
    input  = 60982348080952348324.42342,
    expect = '6.0982348080952*10^19',
    single = '6.0982348080952*10^19  --  Approx: 60982348080952344576',
}

--------------------------------------------------------------------------------
-- Fractions

number_test {
    input  = 1/3,
    expect = '1/3',
}

number_test {
    input  = 9/17,
    expect = '9/17',
}

--------------------------------------------------------------------------------
-- Squareroots, logarithms, and other fine functions

number_test {
    input     =  math.sqrt(8),
    expect    = 'math.sqrt(8)',
}

number_test {
    input     = 1/math.sqrt(8),
    expect    = '1/math.sqrt(8)',
}

number_test {
    input     =  math.log(8),
    expect    = 'math.log(8)',
}

--[[  Factorials are fun, but they are not inheritly supported in the language.
number_test {
    input      = 6227020800,
    expect     = 'fac(13)',
    single     = '6227020800',
}
]]

--------------------------------------------------------------------------------
-- Constants, and multiples of constants

number_test {
    input     =  math.pi,
    expect    = 'math.pi',
}

number_test {
    input     =  7*math.pi,
    expect    = '7*math.pi',
}

number_test {
    input     =  math.exp(1),
    expect    = 'math.exp(1)',
}

number_test {
    input     =  math.exp(10),
    expect    = 'math.exp(10)',
}

number_test {
    input     =  1/0,
    expect    = '1/0',
}

number_test {
    input     =  -1/0,
    expect    = '-1/0',
}

number_test {
    input     =  0/0,
    expect    = '0/0',
}

--------------------------------------------------------------------------------
-- Use the expression closest to the real value

do
    local sum = 0
    for i = 1, 100 do  sum = sum + math.pi/100  end
    number_test {
        name      = 'Approx π',
        input     =  sum,
        expect    = 'math.pi',
    }
end

number_test {
    input  = 4*4,
    expect = '16',
}


--------------------------------------------------------------------------------

number_test {
    -- A half should always be represented using 1/2, never with 2⁻¹.
    input   = 1/2,
    expect  = '1/2',
    single  = '1/2  --  Approx: 0.5'
}

format_test {
    input  = { 1/2, 1/3, 1/4, 1/5 },
    expect = '{ 1/2, 1/3, 1/4, 1/5 }',
}

format_test {
    name   = 'Format sequences and tables with common format',
    input  =  { 0.01, 0.02, 0.03, 0.04 },
    expect = '{ 0.01, 0.02, 0.03, 0.04 }',
}

--------------------------------------------------------------------------------

return SUITE