text: # -*- coding: utf-8 -*-
  
  # Copyright 2018 Google Inc.
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  
  import curses
  import unittest
  import unicodedata
  
  import app.curses_util
  
  
  class CursesUtilTestCases(unittest.TestCase):
      def test_curses_key_name(self):
          # These actually test the fake curses.
          def test1():
              curses.keyname(-3)
  
          self.assertRaises(ValueError, test1)
  
          def test2():
              curses.keyname([])
  
          self.assertRaises(TypeError, test2)
  
          def test3():
              curses.keyname(9 ** 999)
  
          self.assertRaises(OverflowError, test3)
  
      def test_rendered_find_iter(self):
          def test(line, startCol, endCol, matches):
              matches.reverse()
              for s, column, length, index in app.curses_util.rendered_find_iter(
                  line, startCol, endCol, (u"[]{}()",), True, True
              ):
                  self.assertEqual(matches.pop(), (s, column, length, index))
  
          # Float and leading zero.
          line = u"""5.32e+30 a 000808"""
          test(
              line,
              0,
              len(line),
              [
                  (u"5.32e+30", 0, 8, 1),
                  (u"000808", 11, 6, 1),
              ],
          )
  
          # Parenthesis and number.
          line = u"""(23432ull a"""
          test(
              line,
              0,
              len(line),
              [
                  (u"(", 0, 1, 0),
                  (u"23432ull", 1, 8, 1),
              ],
          )
  
          # Multiple numbers and string of brackets.
          line = u"""23 five )}]](23432ull a"""
          test(
              line,
              0,
              len(line),
              [
                  (u"23", 0, 2, 1),
                  (u")}]](", 8, 5, 0),
                  (u"23432ull", 13, 8, 1),
              ],
          )
  
          # Constrained columns.
          line = u"""23 five )}]](23432ull a"""
          test(
              line,
              1,
              len(line) - 4,
              [
                  (u"3", 1, 1, 1),
                  (u")}]](", 8, 5, 0),
                  (u"23432u", 13, 6, 1),
              ],
          )
  
      def test_unicode_data(self):
          self.assertEqual(unicodedata.east_asian_width(u"a"), "Na")
          self.assertEqual(unicodedata.east_asian_width(u" "), "Na")
          self.assertEqual(unicodedata.east_asian_width(u"\b"), "N")
          self.assertEqual(unicodedata.east_asian_width(u"こ"), "W")
          # This is "W" in python3 and "F" in python2.
          self.assertIn(unicodedata.east_asian_width(u"⏰"), ("F", "W"))
  
      def test_column_to_index(self):
          self.assertEqual(0, app.curses_util.column_to_index(0, u"test"))
          self.assertEqual(1, app.curses_util.column_to_index(1, u"test"))
          self.assertEqual(2, app.curses_util.column_to_index(2, u"test"))
          self.assertEqual(3, app.curses_util.column_to_index(3, u"test"))
          # Test past the length of the string.
          self.assertIs(None, app.curses_util.column_to_index(4, u"test"))
          self.assertIs(None, app.curses_util.column_to_index(8, u"test"))
  
          self.assertEqual(0, app.curses_util.column_to_index(0, u"\ttest\ttabs"))
          self.assertEqual(0, app.curses_util.column_to_index(1, u"\ttest\ttabs"))
          self.assertEqual(0, app.curses_util.column_to_index(2, u"\ttest\ttabs"))
          self.assertEqual(0, app.curses_util.column_to_index(3, u"\ttest\ttabs"))
          self.assertEqual(0, app.curses_util.column_to_index(4, u"\ttest\ttabs"))
          self.assertEqual(0, app.curses_util.column_to_index(5, u"\ttest\ttabs"))
          self.assertEqual(0, app.curses_util.column_to_index(6, u"\ttest\ttabs"))
          self.assertEqual(0, app.curses_util.column_to_index(7, u"\ttest\ttabs"))
          self.assertEqual(1, app.curses_util.column_to_index(8, u"\ttest\ttabs"))
          self.assertEqual(2, app.curses_util.column_to_index(9, u"\ttest\ttabs"))
          self.assertEqual(3, app.curses_util.column_to_index(10, u"\ttest\ttabs"))
          self.assertEqual(4, app.curses_util.column_to_index(11, u"\ttest\ttabs"))
          self.assertEqual(5, app.curses_util.column_to_index(12, u"\ttest\ttabs"))
          self.assertEqual(5, app.curses_util.column_to_index(13, u"\ttest\ttabs"))
          self.assertEqual(5, app.curses_util.column_to_index(14, u"\ttest\ttabs"))
          self.assertEqual(5, app.curses_util.column_to_index(15, u"\ttest\ttabs"))
          self.assertEqual(6, app.curses_util.column_to_index(16, u"\ttest\ttabs"))
          self.assertEqual(7, app.curses_util.column_to_index(17, u"\ttest\ttabs"))
          self.assertEqual(8, app.curses_util.column_to_index(18, u"\ttest\ttabs"))
          # Test past the length of the string.
          self.assertIs(None, app.curses_util.column_to_index(21, u"\ttest\ttabs"))
          self.assertIs(None, app.curses_util.column_to_index(22, u"\ttest\ttabs"))
          self.assertIs(None, app.curses_util.column_to_index(999, u"\ttest\ttabs"))
  
          self.assertEqual(0, app.curses_util.column_to_index(0, u"こんにちは"))
          self.assertEqual(0, app.curses_util.column_to_index(1, u"こんにちは"))
          self.assertEqual(1, app.curses_util.column_to_index(2, u"こんにちは"))
          self.assertEqual(1, app.curses_util.column_to_index(3, u"こんにちは"))
          self.assertEqual(2, app.curses_util.column_to_index(4, u"こんにちは"))
          self.assertEqual(4, app.curses_util.column_to_index(8, u"こんにちは"))
          self.assertEqual(4, app.curses_util.column_to_index(9, u"こんにちは"))
          # Test past the length of the string.
          self.assertIs(None, app.curses_util.column_to_index(10, u"こんにちは"))
          self.assertIs(None, app.curses_util.column_to_index(11, u"こんにちは"))
          self.assertIs(None, app.curses_util.column_to_index(12, u"こんにちは"))
  
      def test_char_at_column(self):
          cu = app.curses_util
          self.assertEqual(u"t", cu.char_at_column(0, u"test"))
          self.assertEqual(u"e", cu.char_at_column(1, u"test"))
          self.assertEqual(u"s", cu.char_at_column(2, u"test"))
          self.assertEqual(u"t", cu.char_at_column(3, u"test"))
          # Test past the length of the string.
          self.assertIs(None, cu.char_at_column(4, u"test"))
          self.assertIs(None, cu.char_at_column(8, u"test"))
  
          self.assertEqual(u"\t", cu.char_at_column(0, u"\ttest\ttabs"))
          self.assertEqual(u"\t", cu.char_at_column(1, u"\ttest\ttabs"))
          self.assertEqual(u"\t", cu.char_at_column(2, u"\ttest\ttabs"))
          self.assertEqual(u"\t", cu.char_at_column(3, u"\ttest\ttabs"))
          self.assertEqual(u"\t", cu.char_at_column(4, u"\ttest\ttabs"))
          self.assertEqual(u"\t", cu.char_at_column(5, u"\ttest\ttabs"))
          self.assertEqual(u"\t", cu.char_at_column(6, u"\ttest\ttabs"))
          self.assertEqual(u"\t", cu.char_at_column(7, u"\ttest\ttabs"))
          self.assertEqual(u"t", cu.char_at_column(8, u"\ttest\ttabs"))
          self.assertEqual(u"e", cu.char_at_column(9, u"\ttest\ttabs"))
          self.assertEqual(u"s", cu.char_at_column(10, u"\ttest\ttabs"))
          self.assertEqual(u"t", cu.char_at_column(11, u"\ttest\ttabs"))
          self.assertEqual(u"\t", cu.char_at_column(12, u"\ttest\ttabs"))
          self.assertEqual(u"\t", cu.char_at_column(13, u"\ttest\ttabs"))
          self.assertEqual(u"\t", cu.char_at_column(14, u"\ttest\ttabs"))
          self.assertEqual(u"\t", cu.char_at_column(15, u"\ttest\ttabs"))
          self.assertEqual(u"t", cu.char_at_column(16, u"\ttest\ttabs"))
          self.assertEqual(u"a", cu.char_at_column(17, u"\ttest\ttabs"))
          self.assertEqual(u"b", cu.char_at_column(18, u"\ttest\ttabs"))
          self.assertEqual(u"s", cu.char_at_column(19, u"\ttest\ttabs"))
          # Test past the length of the string.
          self.assertIs(None, cu.char_at_column(20, u"\ttest\ttabs"))
          self.assertIs(None, cu.char_at_column(21, u"\ttest\ttabs"))
          self.assertIs(None, cu.char_at_column(999, u"\ttest\ttabs"))
  
          self.assertEqual(u"こ", cu.char_at_column(0, u"こんにちは"))
          self.assertEqual(u"こ", cu.char_at_column(1, u"こんにちは"))
          self.assertEqual(u"ん", cu.char_at_column(2, u"こんにちは"))
          self.assertEqual(u"ん", cu.char_at_column(3, u"こんにちは"))
          self.assertEqual(u"に", cu.char_at_column(4, u"こんにちは"))
          self.assertEqual(u"は", cu.char_at_column(8, u"こんにちは"))
          self.assertEqual(u"は", cu.char_at_column(9, u"こんにちは"))
          # Test past the length of the string.
          self.assertIs(None, cu.char_at_column(10, u"こんにちは"))
          self.assertIs(None, cu.char_at_column(11, u"こんにちは"))
          self.assertIs(None, cu.char_at_column(12, u"こんにちは"))
  
      def test_fit_to_rendered_width(self):
          fit_to_rendered_width = app.curses_util.fit_to_rendered_width
  
          self.assertEqual(0, fit_to_rendered_width(0, 0, u"test"))
          self.assertEqual(1, fit_to_rendered_width(0, 1, u"test"))
          self.assertEqual(2, fit_to_rendered_width(0, 2, u"test"))
          self.assertEqual(3, fit_to_rendered_width(0, 3, u"test"))
          self.assertEqual(4, fit_to_rendered_width(0, 4, u"test"))
          # Test past the length of the string.
          self.assertEqual(4, fit_to_rendered_width(0, 8, u"test"))
  
          # Test double wide characters (theses characters render as two cells in
          # a fixed width font).
          self.assertEqual(0, fit_to_rendered_width(0, 0, u"こんにちは"))
          self.assertEqual(0, fit_to_rendered_width(0, 1, u"こんにちは"))
          self.assertEqual(1, fit_to_rendered_width(0, 2, u"こんにちは"))
          self.assertEqual(1, fit_to_rendered_width(0, 3, u"こんにちは"))
          self.assertEqual(2, fit_to_rendered_width(0, 4, u"こんにちは"))
          self.assertEqual(4, fit_to_rendered_width(0, 8, u"こんにちは"))
          self.assertEqual(4, fit_to_rendered_width(0, 9, u"こんにちは"))
          self.assertEqual(5, fit_to_rendered_width(0, 10, u"こんにちは"))
  
          # Test past the length of the string.
          self.assertEqual(5, fit_to_rendered_width(0, 11, u"こんにちは"))
          self.assertEqual(5, fit_to_rendered_width(0, 12, u"こんにちは"))
  
          # Test tabs.
          self.assertEqual(1, fit_to_rendered_width(0, 8, u"\t"))
          self.assertEqual(0, fit_to_rendered_width(0, 7, u"\t"))
  
      def test_rendered_sub_str(self):
          self.assertEqual(u"test", app.curses_util.rendered_sub_str(u"test", 0))
          self.assertEqual(u"test", app.curses_util.rendered_sub_str(u"test", 0, 4))
          self.assertEqual(u"est", app.curses_util.rendered_sub_str(u"test", 1, 4))
          self.assertEqual(u"st", app.curses_util.rendered_sub_str(u"test", 2, 4))
          self.assertEqual(u"t", app.curses_util.rendered_sub_str(u"test", 3, 4))
          self.assertEqual(u"", app.curses_util.rendered_sub_str(u"test", 4, 4))
          self.assertEqual(u"tes", app.curses_util.rendered_sub_str(u"test", 0, 3))
          self.assertEqual(u"te", app.curses_util.rendered_sub_str(u"test", 0, 2))
          self.assertEqual(u"t", app.curses_util.rendered_sub_str(u"test", 0, 1))
          self.assertEqual(u"", app.curses_util.rendered_sub_str(u"test", 0, 0))
          self.assertEqual(u"es", app.curses_util.rendered_sub_str(u"test", 1, 3))
          self.assertEqual(u"", app.curses_util.rendered_sub_str(u"test", 2, 2))
          self.assertEqual(u"eight", app.curses_util.rendered_sub_str(u"eight", 0, 5))
          self.assertEqual(u"igh", app.curses_util.rendered_sub_str(u"eight", 1, 4))
          self.assertEqual(u"g", app.curses_util.rendered_sub_str(u"eight", 2, 3))
          self.assertEqual(u"", app.curses_util.rendered_sub_str(u"eight", 3, 3))
          self.assertEqual(u"こんにちは", app.curses_util.rendered_sub_str(u"こんにちは", 0, 10))
          self.assertEqual(u" んにちは", app.curses_util.rendered_sub_str(u"こんにちは", 1, 10))
          self.assertEqual(u"んにちは", app.curses_util.rendered_sub_str(u"こんにちは", 2, 10))
          self.assertEqual(u" にちは", app.curses_util.rendered_sub_str(u"こんにちは", 3, 10))
          self.assertEqual(u"にちは", app.curses_util.rendered_sub_str(u"こんにちは", 4, 10))
          self.assertEqual(u"は", app.curses_util.rendered_sub_str(u"こんにちは", 8))
          self.assertEqual(u"は", app.curses_util.rendered_sub_str(u"こんにちは", 8, 10))
          self.assertEqual(u" ", app.curses_util.rendered_sub_str(u"こんにちは", 9, 10))
          self.assertEqual(u"", app.curses_util.rendered_sub_str(u"こんにちは", 10, 10))
          self.assertEqual(u"こんにち ", app.curses_util.rendered_sub_str(u"こんにちは", 0, 9))
          self.assertEqual(u"こんにち", app.curses_util.rendered_sub_str(u"こんにちは", 0, 8))
          self.assertEqual(u"こんに ", app.curses_util.rendered_sub_str(u"こんにちは", 0, 7))
          self.assertEqual(u"こんに", app.curses_util.rendered_sub_str(u"こんにちは", 0, 6))
          self.assertEqual(u"こん ", app.curses_util.rendered_sub_str(u"こんにちは", 0, 5))
          self.assertEqual(u"こん", app.curses_util.rendered_sub_str(u"こんにちは", 0, 4))
          self.assertEqual(u"こ ", app.curses_util.rendered_sub_str(u"こんにちは", 0, 3))
          self.assertEqual(u"こ", app.curses_util.rendered_sub_str(u"こんにちは", 0, 2))
          self.assertEqual(u" ", app.curses_util.rendered_sub_str(u"こんにちは", 0, 1))
          self.assertEqual(u"", app.curses_util.rendered_sub_str(u"こんにちは", 0, 0))
  
          # Test past the length of the string.
          self.assertEqual(u"", app.curses_util.rendered_sub_str(u"", 1, 1))
          self.assertEqual(u"test", app.curses_util.rendered_sub_str(u"test", 0, 8))
  
          # Test with tabs.
          self.assertEqual(u"   ", app.curses_util.rendered_sub_str(u"\tこんにちは", 0, 3))
          self.assertEqual(u"     こ", app.curses_util.rendered_sub_str(u"\tこんにちは", 3, 10))
          self.assertEqual(
              u"        こん", app.curses_util.rendered_sub_str(u"\tこんにちは", 0, 12)
          )
          self.assertEqual(
              u"        <tab", app.curses_util.rendered_sub_str(u"\t<tab", 0, None)
          )
          self.assertEqual(
              u"         <tab+space",
              app.curses_util.rendered_sub_str(u"\t <tab+space", 0, None),
          )
          self.assertEqual(
              u"        <space+tab",
              app.curses_util.rendered_sub_str(u" \t<space+tab", 0, None),
          )
          self.assertEqual(
              u"a       <", app.curses_util.rendered_sub_str(u"a\t<", 0, None)
          )
          self.assertEqual(
              u"some text.>     <",
              app.curses_util.rendered_sub_str(u"some text.>\t<", 0, None),
          )
          self.assertEqual(
              u"                <2tabs",
              app.curses_util.rendered_sub_str(u"\t\t<2tabs", 0, None),
          )
          self.assertEqual(
              u"line    with    tabs",
              app.curses_util.rendered_sub_str(u"line\twith\ttabs", 0, None),
          )
          self.assertEqual(
              u"ends with tab>  ",
              app.curses_util.rendered_sub_str(u"ends with tab>\t", 0, None),
          )
  
      def test_rendered_width(self):
          self.assertEqual(0, app.curses_util.column_width(u""))
          self.assertEqual(4, app.curses_util.column_width(u"test"))
          self.assertEqual(8, app.curses_util.column_width(u"\t"))
          self.assertEqual(9, app.curses_util.column_width(u"\ta"))
          self.assertEqual(16, app.curses_util.column_width(u"\ta\t"))
          self.assertEqual(8, app.curses_util.column_width(u"i\t"))
  
          self.assertEqual(2, app.curses_util.column_width(u"こ"))
          self.assertEqual(4, app.curses_util.column_width(u"こん"))
          self.assertEqual(6, app.curses_util.column_width(u"こんに"))
          self.assertEqual(10, app.curses_util.column_width(u"こんにちは"))
  
          self.assertEqual(3, app.curses_util.column_width(u"aこ"))
          self.assertEqual(5, app.curses_util.column_width(u"aこん"))
          self.assertEqual(3, app.curses_util.column_width(u"こc"))
          self.assertEqual(4, app.curses_util.column_width(u"aこc"))
          self.assertEqual(7, app.curses_util.column_width(u"aこbんc"))
  
      def test_char_width(self):
          self.assertEqual(0, app.curses_util.char_width(u"", 0))
          self.assertEqual(8, app.curses_util.char_width(u"\t", 0))
          self.assertEqual(1, app.curses_util.char_width(u" ", 0))
          self.assertEqual(7, app.curses_util.char_width(u"\t", 1))
          self.assertEqual(6, app.curses_util.char_width(u"\t", 2))
          self.assertEqual(2, app.curses_util.char_width(u"\t", 6))
          self.assertEqual(1, app.curses_util.char_width(u"\t", 7))
          self.assertEqual(0, app.curses_util.char_width(u"", 8))
          self.assertEqual(8, app.curses_util.char_width(u"\t", 8))
          self.assertEqual(7, app.curses_util.char_width(u"\t", 9))
          self.assertEqual(2, app.curses_util.char_width(u"こ", 0))
          self.assertEqual(0, app.curses_util.char_width(u"\b", 0))
          self.assertEqual(0, app.curses_util.char_width(u"\n", 0))
          self.assertEqual(2, app.curses_util.char_width(u"⏰", 0))
  
      def test_floor_col(self):
          test = u"""\tfive\t"""
          floor_col = app.curses_util.floor_col
          self.assertEqual(0, floor_col(0, test))
          self.assertEqual(0, floor_col(1, test))
          self.assertEqual(0, floor_col(2, test))
          self.assertEqual(0, floor_col(3, test))
          self.assertEqual(0, floor_col(4, test))
          self.assertEqual(0, floor_col(5, test))
          self.assertEqual(0, floor_col(6, test))
          self.assertEqual(0, floor_col(7, test))
          self.assertEqual(8, floor_col(8, test))
          self.assertEqual(9, floor_col(9, test))
          self.assertEqual(10, floor_col(10, test))
          self.assertEqual(11, floor_col(11, test))
          self.assertEqual(12, floor_col(12, test))
          self.assertEqual(12, floor_col(13, test))
          self.assertEqual(12, floor_col(14, test))
          self.assertEqual(12, floor_col(15, test))
          self.assertEqual(16, floor_col(16, test))
          self.assertEqual(16, floor_col(17, test))
          self.assertEqual(16, floor_col(99, test))
  
          test2 = u"""more testing"""
          self.assertEqual(0, floor_col(0, test2))
          self.assertEqual(2, floor_col(2, test2))
          self.assertEqual(12, floor_col(99, test2))
  
      def test_prior_char_col(self):
          test = u"""\tfive\t"""
          prior_char_col = app.curses_util.prior_char_col
          self.assertEqual(None, prior_char_col(0, test))
          self.assertEqual(0, prior_char_col(1, test))
          self.assertEqual(0, prior_char_col(2, test))
          self.assertEqual(0, prior_char_col(3, test))
          self.assertEqual(0, prior_char_col(4, test))
          self.assertEqual(0, prior_char_col(5, test))
          self.assertEqual(0, prior_char_col(6, test))
          self.assertEqual(0, prior_char_col(7, test))
          self.assertEqual(0, prior_char_col(8, test))
          self.assertEqual(8, prior_char_col(9, test))
          self.assertEqual(9, prior_char_col(10, test))
          self.assertEqual(10, prior_char_col(11, test))
          self.assertEqual(11, prior_char_col(12, test))
          self.assertEqual(12, prior_char_col(13, test))
          self.assertEqual(12, prior_char_col(14, test))
          self.assertEqual(12, prior_char_col(15, test))
          self.assertEqual(12, prior_char_col(16, test))
          self.assertEqual(None, prior_char_col(17, test))
  
          test2 = u"""more testing"""
          self.assertEqual(None, prior_char_col(0, test2))
          self.assertEqual(1, prior_char_col(2, test2))
          self.assertEqual(11, prior_char_col(12, test2))
          self.assertEqual(None, prior_char_col(13, test2))
  