1#!/usr/bin/env python3
2import unittest
3
4from saneterm.color import Color, ColorType
5from saneterm.pty import PositionedIterator
6
7from gi.repository import Gdk
8
9TEST_STRING = 'foo;bar'
10
11class TestPositionedIterator(unittest.TestCase):
12 """Tests for saneterm.pty.PositionedIterator"""
13
14 def test_lossless(self):
15 """Test that the iterator doesn't loose any content"""
16
17 it = PositionedIterator(TEST_STRING)
18
19 self.assertEqual([x for x in it], list(TEST_STRING))
20 self.assertEqual(it.wrapped, TEST_STRING)
21
22 def test_indices(self):
23 """Test that the iterator's pos matches the string indices"""
24 it = PositionedIterator(TEST_STRING)
25
26 self.assertEqual(it.pos, -1)
27
28 for x in it:
29 assert x == TEST_STRING[it.pos]
30
31 if x == ';':
32 break
33
34 self.assertEqual(it.pos, 3)
35
36 for x in it:
37 self.assertEqual(x, it.wrapped[it.pos])
38
39 self.assertTrue(it.empty())
40
41 def test_backtracking(self):
42 """Test waypoint() and backtrack() methods"""
43 it = PositionedIterator(TEST_STRING)
44
45 semicolon_index = None
46
47 for x in it:
48 if x == ';':
49 it.waypoint()
50 semicolon_index = it.pos
51
52 self.assertEqual(semicolon_index, TEST_STRING.index(';'))
53
54 self.assertTrue(it.empty())
55
56 with self.assertRaises(StopIteration):
57 _ = it.next()
58
59 it.backtrack()
60
61 self.assertEqual(it.next(), ';')
62 self.assertEqual(it.pos, semicolon_index)
63
64 def test_takewhile_greedy(self):
65 """Test takewhile_greedy() method"""
66 it = PositionedIterator(TEST_STRING)
67
68 s = it.takewhile_greedy(lambda x: x != ';')
69
70 self.assertEqual(s, TEST_STRING.split(';')[0])
71 self.assertEqual(it.pos, len(s) - 1)
72 self.assertEqual(it.next(), ';')
73
74 def test_empty(self):
75 """Test empty() predicate"""
76 it = PositionedIterator(TEST_STRING)
77
78 for x in it:
79 if it.pos + 1 == len(TEST_STRING):
80 self.assertTrue(it.empty())
81
82 self.assertTrue(it.empty())
83
84 with self.assertRaises(StopIteration):
85 _ = it.next()
86
87 def test_take(self):
88 """Test take() method"""
89 length = 3
90 it1 = PositionedIterator(TEST_STRING)
91 it2 = PositionedIterator(TEST_STRING)
92
93 s1 = it1.take(length)
94 s2 = ''
95 for x in it2:
96 if it2.pos >= length:
97 break
98 else:
99 s2 += x
100
101 self.assertEqual(s1, s2)
102 self.assertEqual(s1, TEST_STRING[0:length])
103
104 # using take does not consume the next element!
105 self.assertEqual(it1.pos, length - 1)
106
107class TestColor(unittest.TestCase):
108 """Tests for saneterm.color"""
109
110 def test_256_colors(self):
111 """
112 Check divmod based RGB value calculation
113 against 256 color table generation as implemented
114 in XTerm's 256colres.pl.
115 """
116 def channel_val(c):
117 return (c * 40 + 55 if c > 0 else 0) / 255
118
119 for r in range(6):
120 for g in range(6):
121 for b in range(6):
122 n = 16 + (r * 36) + (g * 6) + b
123
124 expected = Gdk.RGBA(*map(channel_val, (r, g, b)))
125 col = Color(ColorType.NUMBERED_256, n).to_gdk()
126
127 self.assertTrue(
128 expected.equal(col),
129 'Color {}: expected: {}; got: {}'.format(
130 n, expected.to_string(), col.to_string()
131 )
132 )
133
134if __name__ == '__main__':
135 unittest.main()