package com.alibaba.fastjson.parser;

import com.alibaba.fastjson.JSONException;
import org.junit.Assert;
import org.junit.Test;


public class JSONScannerTest {
  @Test
  public void inputTokenTest_Comma() throws Throwable {
    JSONScanner scanner = new JSONScanner(",");
    scanner.nextToken();
    Assert.assertEquals(JSONToken.COMMA, scanner.token());
  }

  @Test
  public void inputTokenTest_String() throws Throwable {
    JSONScanner scanner = new JSONScanner("\"text\"");
    scanner.nextToken();
    Assert.assertEquals(JSONToken.LITERAL_STRING, scanner.token());
    Assert.assertEquals("text", scanner.stringVal());
  }

  @Test
  public void inputTokenTest_Integer() throws Throwable {
    JSONScanner scanner = new JSONScanner("-352");
    scanner.nextToken();
    Assert.assertEquals(JSONToken.LITERAL_INT, scanner.token());
    Assert.assertEquals(-352, scanner.intValue());
  }

  @Test
  public void inputTokenTest_True() throws Throwable {
    JSONScanner scanner = new JSONScanner("true");
    scanner.nextToken();
    Assert.assertEquals(JSONToken.TRUE, scanner.token());
  }

  @Test
  public void inputTokenTest_False() throws Throwable {
    JSONScanner scanner = new JSONScanner("false");
    scanner.nextToken();
    Assert.assertEquals(JSONToken.FALSE, scanner.token());
  }

  @Test
  public void inputTokenTest_Float() throws Throwable {
    JSONScanner scanner = new JSONScanner("2.5e2");
    scanner.nextToken();
    Assert.assertEquals(JSONToken.LITERAL_FLOAT, scanner.token());
  }

  @Test
  public void inputTokenTest_Null() throws Throwable {
    JSONScanner scanner = new JSONScanner("null");
    scanner.nextToken();
    Assert.assertEquals(JSONToken.NULL, scanner.token());
  }

  @Test
  public void scannerSequenceTest() throws Throwable {
    JSONScanner scanner = new JSONScanner("5,:");
    scanner.nextToken();
    Assert.assertEquals(JSONToken.LITERAL_INT, scanner.token());
    Assert.assertEquals(5, scanner.intValue());

    scanner.nextToken();
    Assert.assertEquals(JSONToken.COMMA, scanner.token());

    scanner.nextToken();
    Assert.assertEquals(JSONToken.COLON, scanner.token());
  }

  @Test
  public void scannerPositionTest() throws Throwable {
    JSONScanner scanner = new JSONScanner("5,:");
    scanner.nextToken();
    Assert.assertEquals(0, scanner.pos());

    scanner.nextToken();
    Assert.assertEquals(1, scanner.pos());

    scanner.nextToken();
    Assert.assertEquals(2, scanner.pos());
  }

  @Test
  public void scannerEofTest() throws Throwable {
    JSONScanner scanner = new JSONScanner("5,:");
    scanner.nextToken();
    scanner.nextToken();
    scanner.nextToken(); // colon
    // scanner should now enter EOF
    scanner.nextToken();

    Assert.assertTrue(scanner.isEOF());
    Assert.assertEquals(JSONToken.EOF, scanner.token());
  }

  @Test(expected=JSONException.class)
  public void scannerInputFormatTest_Invalid() throws Throwable {
    JSONScanner scanner = new JSONScanner("53fds"); // invalid literal value
    scanner.nextToken(); // consumes numeric token
    scanner.nextToken(); // should raise invalid literal
  }

  @Test()
  public void complexExampleTest() throws Throwable {
    JSONScanner scanner = new JSONScanner("{\"Name\":\"Michael\",\"Last\":\"Chen\"}");
    scanner.nextToken();
    Assert.assertEquals(JSONToken.LBRACE, scanner.token());
    scanner.nextToken();
    Assert.assertEquals(JSONToken.LITERAL_STRING, scanner.token());
    scanner.nextToken();
    Assert.assertEquals(JSONToken.COLON, scanner.token());
    scanner.nextToken();
    Assert.assertEquals(JSONToken.LITERAL_STRING, scanner.token());
    scanner.nextToken();
    Assert.assertEquals(JSONToken.COMMA, scanner.token());
    scanner.nextToken();
    Assert.assertEquals(JSONToken.LITERAL_STRING, scanner.token());
    scanner.nextToken();
    Assert.assertEquals(JSONToken.COLON, scanner.token());
    scanner.nextToken();
    Assert.assertEquals(JSONToken.LITERAL_STRING, scanner.token());
    scanner.nextToken();
    Assert.assertEquals(JSONToken.RBRACE, scanner.token());
    scanner.nextToken();
    Assert.assertEquals(JSONToken.EOF, scanner.token());
  }
}
