package com.craftinkinterpreters.klox

import com.craftinginterpreters.klox.Scanner
import com.craftinginterpreters.klox.TokenType.*
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test


@DisplayName("Scanner tests")
class ScannerTests {

    @Test
    fun basicTest() {
        Scanner("1 2 3 4").scanTokens().apply {
            assertEquals(5, size)
        }

        Scanner("//comment").scanTokens().apply {
            assertEquals(1, size)
        }

        Scanner(" \t \n \n \n").scanTokens().apply {
            assertEquals(1, size)
        }

        Scanner("123.45").scanTokens().apply {
            assertEquals(2, size)
            assertEquals("123.45", this[0].lexeme)
        }

        Scanner("""if (condition) {print "yes";} else {print "no";}""").scanTokens().apply {
            assertEquals(16, size)
            assertEquals(IF, this[0].type)
            assertEquals(LEFT_PAREN, this[1].type)
            assertEquals(IDENTIFIER, this[2].type)
            assertEquals(RIGHT_PAREN, this[3].type)
            assertEquals(LEFT_BRACE, this[4].type)
            assertEquals(PRINT, this[5].type)
            assertEquals(STRING, this[6].type)
            assertEquals(SEMICOLON, this[7].type)
            assertEquals(RIGHT_BRACE, this[8].type)
            assertEquals(ELSE, this[9].type)
            assertEquals(LEFT_BRACE, this[10].type)
            assertEquals(PRINT, this[11].type)
            assertEquals(STRING, this[12].type)
            assertEquals(SEMICOLON, this[13].type)
            assertEquals(RIGHT_BRACE, this[14].type)
            assertEquals(EOF, this[15].type)
        }
    }
}
