# Copyright (C) 2006  Michael Graz. <mgraz@plan10.com>
from __future__ import print_function, unicode_literals, absolute_import

import sys, unittest
sys.path.append ('../..')
#from pyreadline.modes.vi import *
#from pyreadline import keysyms
from pyreadline.lineeditor import lineobj

#----------------------------------------------------------------------


#----------------------------------------------------------------------

class Test_copy (unittest.TestCase):
    def test_copy1 (self):
        l=lineobj.ReadLineTextBuffer("first second")
        q=l.copy()
        self.assertEqual(q.get_line_text(),l.get_line_text())
        self.assertEqual(q.point,l.point)
        self.assertEqual(q.mark,l.mark)
        
    def test_copy2 (self):
        l=lineobj.ReadLineTextBuffer("first second",point=5)
        q=l.copy()
        self.assertEqual(q.get_line_text(),l.get_line_text())
        self.assertEqual(q.point,l.point)
        self.assertEqual(q.mark,l.mark)
        

class Test_linepos (unittest.TestCase):
    t="test text"
    def test_NextChar (self):
        t=self.t
        l=lineobj.ReadLineTextBuffer(t)
        for i in range(len(t)):
            self.assertEqual(i,l.point)
            l.point=lineobj.NextChar
        #advance past end of buffer            
        l.point=lineobj.NextChar
        self.assertEqual(len(t),l.point)

    def test_PrevChar (self):
        t=self.t
        l=lineobj.ReadLineTextBuffer(t,point=len(t))
        for i in range(len(t)):
            self.assertEqual(len(t)-i,l.point)
            l.point=lineobj.PrevChar
        #advance past beginning of buffer            
        l.point=lineobj.PrevChar
        self.assertEqual(0,l.point)

    def test_EndOfLine (self):
        t=self.t
        l=lineobj.ReadLineTextBuffer(t,point=len(t))
        for i in range(len(t)):
            l.point=i
            l.point=lineobj.EndOfLine
            self.assertEqual(len(t),l.point)
                        
    def test_StartOfLine (self):
        t=self.t
        l=lineobj.ReadLineTextBuffer(t,point=len(t))
        for i in range(len(t)):
            l.point=i
            l.point=lineobj.StartOfLine
            self.assertEqual(0,l.point)
                        

class Tests_linepos2(Test_linepos):
    t="kajkj"
            
class Tests_linepos3(Test_linepos):
    t=""


class Test_movement (unittest.TestCase):
    def test_NextChar (self):
        cmd=lineobj.NextChar
        tests=[
        # "First"
         (cmd,
          "First",
          "#     ",
          " #    "),
         (cmd,
          "First",
          "    # ",
          "     #"),
         (cmd,
          "First",
          "     #",
          "     #"),
          ]
        for cmd,text,init_point,expected_point in tests:
            l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
            l.point=cmd
            self.assertEqual(get_point_pos(expected_point),l.point)
        
    def test_PrevChar (self):
        cmd=lineobj.PrevChar
        tests=[
        # "First"
         (cmd,
          "First",
          "     #",
          "    # "),
         (cmd,
          "First",
          " #   ",
          "#    "),
         (cmd,
          "First",
          "#     ",
          "#     "),
          ]
        for cmd,text,init_point,expected_point in tests:
            l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
            l.point=cmd
            self.assertEqual(get_point_pos(expected_point),l.point)
        
        
        
    def test_PrevWordStart (self):
        cmd=lineobj.PrevWordStart
        tests=[
        # "First Second Third"
         (cmd,
          "First Second Third",
          "                  #",
          "             #     "),
         (cmd,
          "First Second Third",
          "             #     ",
          "      #            "),
         (cmd,
          "First Second Third",
          "     #             ",
          "#                  "),
         (cmd,
          "First Second Third",
          "#                  ",
          "#                  "),
          ]
        for cmd,text,init_point,expected_point in tests:
            l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
            l.point=cmd
            self.assertEqual(get_point_pos(expected_point),l.point)
        
    def test_NextWordStart (self):
        cmd=lineobj.NextWordStart
        tests=[
        # "First Second Third"
         (cmd,
          "First Second Third",
          "#                 ",
          "      #           "),
         (cmd,
          "First Second Third",
          "    #             ",
          "      #           "),
         (cmd,
          "First Second Third",
          "      #            ",
          "             #     "),
         (cmd,
          "First Second Third",
          "              #    ",
          "                  #"),
          ]
        for cmd,text,init_point,expected_point in tests:
            l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
            l.point=cmd
            self.assertEqual(get_point_pos(expected_point),l.point)
        
    def test_NextWordEnd (self):
        cmd=lineobj.NextWordEnd
        tests=[
        # "First Second Third"
         (cmd,
          "First Second Third",
          "#                 ",
          "     #            "),
         (cmd,
          "First Second Third",
          "    #             ",
          "     #            "),
         (cmd,
          "First Second Third",
          "      #            ",
          "            #      "),
         (cmd,
          "First Second Third",
          "              #    ",
          "                  #"),
          ]
        for cmd,text,init_point,expected_point in tests:
            l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
            l.point=cmd
            self.assertEqual(get_point_pos(expected_point),l.point)
        
    def test_PrevWordEnd (self):
        cmd=lineobj.PrevWordEnd
        tests=[
        # "First Second Third"
         (cmd,
          "First Second Third",
          "                  #",
          "            #      "),
         (cmd,
          "First Second Third",
          "            #      ",
          "     #             "),
         (cmd,
          "First Second Third",
          "     #             ",
          "#                  "),
         (cmd,
          "First Second Third",
          "#                  ",
          "#                  "),          
          ]
        for cmd,text,init_point,expected_point in tests:
            l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
            l.point=cmd
            self.assertEqual(get_point_pos(expected_point),l.point)
        
    def test_WordEnd_1 (self):
        cmd=lineobj.WordEnd
        tests=[
        # "First Second Third"
         (cmd,
          "First Second Third",
          "#                  ",
          "     #             "),
         (cmd,
          "First Second Third",
          " #                 ",
          "     #             "),
         (cmd,
          "First Second Third",
          "             #     ",
          "                  #"),
          ]
        for cmd,text,init_point,expected_point in tests:
            l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
            l.point=cmd
            self.assertEqual(get_point_pos(expected_point),l.point)

    def test_WordEnd_2 (self):
        cmd=lineobj.WordEnd
        tests=[
        # "First Second Third"
         (cmd,
          "First Second Third",
          "     #             "),
         (cmd,
          "First Second Third",
          "            #      "),
         (cmd,
          "First Second Third",
          "                  #"),
          ]

        for cmd,text,init_point in tests:
            l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
            self.assertRaises(lineobj.NotAWordError,cmd,l)
        
        
    def test_WordStart_1 (self):
        cmd=lineobj.WordStart
        tests=[
        # "First Second Third"
         (cmd,
          "First Second Third",
          "#                  ",
          "#                  "),
         (cmd,
          "First Second Third",
          " #                 ",
          "#                  "),
         (cmd,
          "First Second Third",
          "               #   ",
          "             #     "),
          ]
        for cmd,text,init_point,expected_point in tests:
            l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
            l.point=cmd
            self.assertEqual(get_point_pos(expected_point),l.point)
        
    def test_WordStart_2 (self):
        cmd=lineobj.WordStart
        tests=[
        # "First Second Third"
         (cmd,
          "First Second Third",
          "     #             "),
         (cmd,
          "First Second Third",
          "            #      "),
         (cmd,
          "First Second Third",
          "                  #"),
          ]

        for cmd,text,init_point in tests:
            l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
            self.assertRaises(lineobj.NotAWordError,cmd,l)
        

    def test_StartOfLine (self):
        cmd=lineobj.StartOfLine
        tests=[
        # "First Second Third"
         (cmd,
          "First Second Third",
          "#                 ",
          "#                 "),
         (cmd,
          "First Second Third",
          "         #         ",
          "#                  "),
         (cmd,
          "First Second Third",
          "                  #",
          "#                  "),
          ]
        for cmd,text,init_point,expected_point in tests:
            l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
            l.point=cmd
            self.assertEqual(get_point_pos(expected_point),l.point)
        
    def test_EndOfLine (self):
        cmd=lineobj.EndOfLine
        tests=[
        # "First Second Third"
         (cmd,
          "First Second Third",
          "#                 ",
          "                  #"),
         (cmd,
          "First Second Third",
          "         #         ",
          "                  #"),
         (cmd,
          "First Second Third",
          "                  #",
          "                  #"),
          ]
        for cmd,text,init_point,expected_point in tests:
            l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point))
            l.point=cmd
            self.assertEqual(get_point_pos(expected_point),l.point)

    def test_Point(self):
        cmd=lineobj.Point
        tests=[
        # "First Second Third"
         (cmd,
          "First Second Third",
          0),
         (cmd,
          "First Second Third",
          12),
         (cmd,
          "First Second Third",
          18),
          ]
        for cmd,text,p in tests:
            l=lineobj.ReadLineTextBuffer(text,p)
            self.assertEqual(p,cmd(l))


#----------------------------------------------------------------------
# utility functions

def get_point_pos(pstr):
    return pstr.index("#")

def get_mark_pos(mstr):
    try:
        return mstr.index("#")
    except ValueError:
        return -1
#----------------------------------------------------------------------

if __name__ == '__main__':
    unittest.main()

    l=lineobj.ReadLineTextBuffer("First Second Third")
