if ENV['COVERAGE'] then
  $stderr.puts "Loading coverage library"
  require 'rubygems'
  require 'coverage'
end

require 'test/unit'
$LOAD_PATH.unshift File.join(File.dirname(__FILE__),'..','lib')
require 'latex/scanner'

class Array
  def firsts
    map { |a,b| a }
  end
end

class Wildcard
  def inspect
    "*"
  end
  def ==(other)
    true
  end
end
WILDCARD = Wildcard.new

class TestLaTeXScanner < Test::Unit::TestCase

  def setup
    @scanner = LaTeX::Scanner.new
  end
  
  def body_scanner
    scanner = LaTeX::Scanner.new
    scanner.start = :document
    scanner
  end
  
  def body_scan(str)
    s = body_scanner
    result = s.scan(str)
    s.check_stack
    result
  end
  
  def test_let
    assert_equal [:LET], body_scan('\let\someseq=\otherseq').firsts
    assert_equal [:LET], body_scan('\let\someseq\otherseq').firsts
  end
  
  def test_skip
    assert_equal [:SKIP], body_scan('\hskip-1pt').firsts
    assert_equal [:SKIP], body_scan('\hskip1pt').firsts
    assert_equal [:SKIP], body_scan('\hskip -1pt').firsts
    assert_equal [:SKIP], body_scan('\hskip 1pt').firsts
    assert_equal [:SKIP], body_scan('\hskip  1pt').firsts
    assert_equal [:SKIP], body_scan('\hskip  1 pt').firsts
    assert_equal [:SKIP], body_scan('\vskip 1pt').firsts
    assert_equal [:SKIP], body_scan('\vskip 1pt').firsts
    assert_equal [:SKIP], body_scan('\vskip 1.0pt').firsts
    assert_equal [:SKIP], body_scan('\vskip 1.0cm').firsts
  end
  
  def test_begin_verb
    tokens = body_scanner.scan("\\begin{verbatim}\n")
    assert_equal :BEGIN_VERBATIM, tokens.first.first
    
    tokens = body_scanner.scan("\\begin{Verbatim}\n")
    assert_equal :BEGIN_VERBATIM, tokens.first.first
  end
  
  def test_verb_env
    tokens = body_scan("\\begin{verbatim}\n{\n\\end{verbatim}\n")
    assert_equal [:BEGIN_VERBATIM, :VERB_LINE, :END_ENV], tokens.firsts
  end
  
  def test_verb_cs_pipe
    assert_equal [:VERB], body_scan("\\verb|Foo|").firsts
    assert_equal [:VERB], body_scan("\\verb*|Foo|").firsts
  end

  def test_verb_cs_curly
    assert_equal [:VERB], body_scan("\\verb{Foo}").firsts
    assert_equal [:VERB], body_scan("\\verb*{Foo}").firsts
  end

  def test_verb_cs_square
    assert_equal [:VERB], body_scan("\\verb[Foo]").firsts
    assert_equal [:VERB], body_scan("\\verb*[Foo]").firsts
  end

  def test_verb_cs_round
    assert_equal [:VERB], body_scan("\\verb(Foo)").firsts
    assert_equal [:VERB], body_scan("\\verb*(Foo)").firsts
  end

  def test_verb_cs_other
    assert_equal [:VERB], body_scan("\\verb!Foo!").firsts
    assert_equal [:VERB], body_scan("\\verb*!Foo!").firsts
  end

  def test_comment_env
    tokens = body_scan("\\begin{comment}\n{\n\\end{comment}")
    assert_equal [:BEGIN_COMMENT, :COMMENT_LINE, :COMMENT_LINE, :END_ENV], tokens.firsts
  end
  
  def test_cs
    tokens = body_scan("\\somecs")
    assert_equal [:CS, "\\somecs"], tokens.first
  end
  
  def test_cs_space
    tokens = body_scan("\\ ")
    # Not parsed as a control sequence => punctuation instead
    assert_equal [:PUNCT, "\\ "], tokens.first
  end

  def test_amp
    tokens = body_scan("& \\&")
    assert_equal [:AMP, :SPACE, :PUNCT], tokens.firsts
  end
  
  def test_caret_underbar
    tokens = body_scan("^_")
    assert_equal [:STANDALONE_PUNCT, :STANDALONE_PUNCT], tokens.firsts
  end
  
  def test_par_normal
    assert_equal [:PAR], body_scan("\n\n").firsts
  end
  
  def test_par_par
    assert_equal [[:CS, "\\par"]], body_scan("\\par")
  end
  
  def test_par_white
    tokens = body_scan(" \n\t\n\tX")
    assert_equal [:SPACE, :PAR, :SPACE, :WORD], tokens.firsts
  end
  
end
