-- spec/encode_string_spec.lua
-- Specifies tests for qrprinter.encode_string functionality

--------------------------------------------------------------------------------
-- Disable LuaJIT compiler

-- LuaJIT's optimizations can frob luacov's coverage reports
require( 'jit' ).off()

--------------------------------------------------------------------------------
-- Module imports

qrprinter = require( 'qrprinter' )

--------------------------------------------------------------------------------
-- Helper functions

local function read_file_into_string( path )

   -- Open file at `path`
   local file = io.open( path, 'r' )
   if not file then
      error( 'Error opening file at ' .. path .. ' during test.' )
   end

   -- Read file contents
   local content = file:read( '*a' )

   -- Remove terminating newline
   local last_char = string.sub( content, -1 )
   if last_char == '\n' then
      content = string.sub( content, 1, -2 )
   end

   file:close()
   return content

end

--------------------------------------------------------------------------------
-- Test context

describe( 'qrprinter.print_qr functionality', function ()

             ----------------------------------------
             -- Test-wide values

             local test_qr = qrprinter.encode_string( 'abc123' )


             ----------------------------------------
             -- Replace print with mock function that returns the provided string

             setup( function()

                   _G.print = function( msg )
                      return msg
                   end

             end )


             ----------------------------------------
             -- Test definitions

             it( 'aliases print_qr to print_qr_ansi', function()

                    assert.are.same( qrprinter.print_qr( test_qr ), qrprinter.print_qr_ansi( test_qr ) )

             end )

             it( 'prints QR codes using ASCII characters', function()

                    local expected_output = read_file_into_string( 'spec/expected_output/print_qr_ascii.txt' )

                    assert.are.same( expected_output, qrprinter.print_qr_ascii( test_qr ) )

             end )

             it( 'prints QR codes using ANSI escape sequences', function()

                    local expected_output = read_file_into_string( 'spec/expected_output/print_qr_ansi.txt' )

                    assert.are.same( expected_output, qrprinter.print_qr_ansi( test_qr ) )

             end )

             it( 'prints QR codes using UTF8 block sequences', function()

                    local expected_output = read_file_into_string( 'spec/expected_output/print_qr_utf8.txt' )

                    assert.are.same( expected_output, qrprinter.print_qr_utf8( test_qr ) )

             end )

             it( 'adjusts padding of the output when the "padding" option is provided', function()

                    local padding_0_expected_output = read_file_into_string( 'spec/expected_output/print_qr_padding_0.txt' )

                    local padding_3_expected_output = read_file_into_string( 'spec/expected_output/print_qr_padding_3.txt' )

                    assert.are.same( padding_0_expected_output, qrprinter.print_qr( test_qr, { padding = 0 } ) )

                    assert.are.same( padding_3_expected_output, qrprinter.print_qr( test_qr, { padding = 3 } ) )

             end )

             it( 'inverts the colors of the output when the "invert" option is set', function()

                    local expected_output = read_file_into_string( 'spec/expected_output/print_qr_invert_true.txt' )

                    assert.are.same( expected_output, qrprinter.print_qr( test_qr, { invert = true } ) )

             end )

end )