Beispiel #1
0
    def test_getitem(self):
        """ __getitem__ should navigate escape codes, and raise on errors.
        """
        cb = ChainedBase('\x1b[31mtesting\x1b[0m')
        cases = (
            (0, '\x1b[31mt'),
            (3, '\x1b[31mt'),
            ((2, ), '\x1b[31mte'),
            ((1, 3), '\x1b[31mes'),
            ((0, 6, 2), '\x1b[31mtsig'),
            # A [::n] slice.
            ((6, 6, 1), '\x1b[31mtesting'),
            # A slice that ends past the string.
            ((45, 99), ''),
            # A negative slice that ends before the string.
            ((-1, -3), ''),
            # Reversed slices.
            # A [::-n] slice.
            ((6, 6, -1), '\x1b[31mgnitset'),
            # A [6:0:-1] slice.
            ((6, 0, -1), '\x1b[31mgnitse'),
            # A slice that starts way outside the bounds.
            ((65, 0, -1), '\x1b[31mgnitse'),
            # A stepping slice less than -1.
            ((6, 0, -2), '\x1b[31mgist'),
        )
        for index, expected in cases:
            if isinstance(index, tuple):
                index = slice(*index)
            self.assertCallEqual(
                ChainedBase(expected),
                func=cb.__getitem__,
                args=(index, ),
                msg='Failed to ignore escape codes in __getitem__',
            )

        err_cases = (7, -8)
        for index in err_cases:
            raiser = self.assertRaises(
                IndexError,
                msg='Failed to raise for bad index: {!r}'.format(index))
            with raiser:
                cb[index]
        index = 'wat'
        raiser = self.assertRaises(
            TypeError,
            msg='Failed to raise for bad index: {!r}'.format(index),
        )
        with raiser:
            # Index must be integer/slice.
            cb[index]

        index = slice(0, 2, 0)
        raiser = self.assertRaises(
            ValueError,
            msg='Failed to raise for 0 step.',
        )
        with raiser:
            # Step cannot be 0.
            cb[index]
Beispiel #2
0
 def test_strip(self):
     """ strip() should act like str.strip(). """
     cases = {
         '  test  ': 'test',
         '\n\ttest\n\t': 'test',
         '\n\n\t\t  \n\n \t\ttest\n\n\t\t  \n\n \t\t': 'test',
     }
     for s, expected in cases.items():
         self.assertCallEqual(
             ChainedBase(expected),
             func=ChainedBase(s).strip,
             msg='Failed to strip ChainedBase.',
         )
     charcases = (
         ('\x1b[31mtest\x1b[0m', '\x1b[31m', 'test\x1b[0m'),
         ('\x1b[31mtest\x1b[0m', '\x1b[0m', '\x1b[31mtest'),
         ('test', '\x1b[0m', 'test'),
     )
     for s, chars, expected in charcases:
         self.assertCallEqual(
             ChainedBase(expected),
             func=ChainedBase(s).strip,
             args=(chars, ),
             msg='Failed to strip escape codes properly.',
         )
Beispiel #3
0
 def test_call(self):
     """ Calling a ChainedBase appends data to it. """
     cb = ChainedBase('')
     self.assertCallEqual(
         ChainedBase('test'),
         func=cb.__call__,
         args=('test', ),
         msg='Call did not add data.',
     )
Beispiel #4
0
 def test_center(self):
     """ Center justify should behave like str.just, without escape codes.
     """
     s = '\x1b[31mtesting\x1b[0m'
     cb = ChainedBase(s)
     self.assertCallEqual(
         ChainedBase('  {} '.format(s)),
         func=cb.center,
         args=(10, ),
         msg='Failed to properly center a ChainedBase.',
     )
Beispiel #5
0
 def test_lt(self):
     """ __lt__ should operate on ChainedBases and strings. """
     a = ChainedBase('a')
     b = ChainedBase('b')
     self.assertLess(a,
                     b,
                     msg='__lt__ failed to recognize the proper order.')
     self.assertLess(
         a, 'c', msg='__lt__ failed to recognize the proper order for str.')
     with self.assertRaises(TypeError):
         a < 5
Beispiel #6
0
 def test_rstrip(self):
     """ rstrip() should act like str.rstrip(). """
     cases = {
         'test  ': 'test',
         'test\n\t': 'test',
         'test\n\n\t\t  \n\n \t\t': 'test',
     }
     for s, expected in cases.items():
         self.assertCallEqual(
             ChainedBase(expected),
             func=ChainedBase(s).rstrip,
             msg='Failed to rstrip ChainedBase.',
         )
Beispiel #7
0
 def test_format(self):
     """ __format__ should work, and raise errors where needed. """
     cb = ChainedBase('test')
     cases = {
         '{}': 'test',
         '{:}': 'test',
         '{:8}': 'test    ',
         '{:>8}': '    test',
         '{:<8}': 'test    ',
         '{:^8}': '  test  ',
     }
     for fmt, expected in cases.items():
         self.assertCallEqual(
             expected,
             func=fmt.format,
             args=(cb, ),
             msg='Failed to format ChainedBase.',
         )
     for badfmt in ('{:>BAD}', '{:BAD}'):
         raiser = self.assertCallRaises(
             ValueError,
             func=str.format,
             args=(badfmt, ),
             msg='Failed to raise on bad width specifier.',
         )
         with raiser:
             badfmt.format(cb)
Beispiel #8
0
    def test_mul(self):
        """ __mul__ should act like str.__mul__. """
        a = ChainedBase('a')
        self.assertEqual(a * 3,
                         ChainedBase('aaa'),
                         msg='Failed to multiply ChainedBase data.')
        # rmul
        self.assertEqual(3 * a,
                         ChainedBase('aaa'),
                         msg='Failed to multiply ChainedBase data.')

        with self.assertRaises(TypeError):
            # Non-int multiplier.
            a * 'wat'
        with self.assertRaises(TypeError):
            # Non-int rmultiplier.
            'wat' * a
Beispiel #9
0
 def test_len(self):
     """ __len__ should return len(self.data). """
     # This is mostly here for test coverage.
     cb = ChainedBase('test')
     self.assertCallEqual(
         4,
         func=cb.__len__,
         msg='__len__ failed.',
     )
Beispiel #10
0
 def test_join(self):
     """ join() should join self.data for ChainedBases and strings. """
     cases = {
         ('a', ): 'a',
         ('a', 'b'): 'ab',
         (('a', 'b', 'c'), ): 'abc',
         (ChainedBase('ac'), ): 'ac',
         (ChainedBase('ac'), ChainedBase('bc')): 'acbc',
         ((ChainedBase('a'), ChainedBase('b'), ChainedBase('c')), ): 'abc',
         ((ChainedBase('ac'), 'b', ChainedBase('cc')), ): 'acbcc',
     }
     for joinargs, expected in cases.items():
         self.assertCallEqual(
             ChainedBase(expected),
             func=ChainedBase('').join,
             args=joinargs,
             msg='Failed to join strings correctly.',
         )
Beispiel #11
0
 def test_str(self):
     """ str() should return str(self.data). """
     # Mostly here for test coverage.
     cases = {
         'test': 'test',
         0: '0',
         1: '1',
         1.5: '1.5',
         tuple(): '()',
         tuple((1, 2)): '(1, 2)',
     }
     # str() called on a ChainedBase.
     for initarg, expected in cases.items():
         cb = ChainedBase(initarg)
         self.assertCallEqual(
             expected,
             func=str,
             args=(cb, ),
             msg='str() failed to return the proper string for {!r}.'.
             format(initarg, ),
         )
     # ChainedBase.str method.
     for initarg, expected in cases.items():
         cb = ChainedBase(initarg)
         self.assertCallEqual(
             expected,
             func=cb.str,
             msg='str() failed to return the proper string for {!r}.'.
             format(initarg, ),
         )
     # Initialized with False/True
     for val in (False, True):
         cb = ChainedBase(val)
         self.assertCallEqual(
             str(val),
             func=str,
             args=(cb, ),
             msg='str() failed to return the proper string for False.',
         )
Beispiel #12
0
    def test_add(self):
        """ __add__ should add ChainedBases, and raise TypeError for others.
        """
        cb = ChainedBase('')
        self.assertCallEqual(
            ChainedBase('test'),
            func=cb.__add__,
            args=('test', ),
            msg='Failed to add data to a ChainedBase.',
        )
        # radd
        self.assertCallEqual(
            ChainedBase('test'),
            func=cb.__radd__,
            args=('test', ),
            msg='Failed to radd data to a ChainedBase.',
        )

        with self.assertRaises(TypeError):
            cb + 25
        with self.assertRaises(TypeError):
            25 + cb
Beispiel #13
0
 def test_index(self):
     """ index() should behave like self.data.index(). """
     cb = ChainedBase('\x1b[31mtesting\x1b[0m')
     cases = {
         '\x1b': 0,
         't': 5,
         'ing': 9,
     }
     for substr, expected in cases.items():
         self.assertCallEqual(
             expected,
             func=cb.index,
             args=(substr, ),
             msg='Failed to find index for known substr: {!r}'.format(
                 substr))
Beispiel #14
0
    def test_write(self):
        """ write() should write self.data and then clear it. """
        cb = ChainedBase('test')
        file = TestFileBytes()
        cb.write(file=file)
        self.assertCallEqual(
            bytes(file),
            b'test',
            func=cb.write,
            kwargs={'file': file},
            msg='Failed to write to file object.',
        )
        self.assertEqual(
            cb,
            ChainedBase(''),
            msg='Failed to clear self.data after write() call.',
        )

        cb = ChainedBase('again')
        cb.write(file=file, end='\n')
        self.assertCallEqual(
            bytes(file),
            b'again\n',
            func=cb.write,
            kwargs={
                'file': file,
                'end': '\n'
            },
            msg='Failed to write to file object with `end`.',
        )
        self.assertEqual(
            cb,
            ChainedBase(''),
            msg='Failed to clear self.data after write() call.',
        )

        cb = ChainedBase('with delay')
        cb.write(file=file, end='\n', delay=0.005)
        self.assertCallEqual(
            bytes(file),
            b'with delay\n',
            func=cb.write,
            kwargs={
                'file': file,
                'end': '\n',
                'delay': 0.005
            },
            msg='Failed to write to file object with delay.',
        )
        self.assertEqual(
            cb,
            ChainedBase(''),
            msg='Failed to clear self.data after write() call.',
        )
Beispiel #15
0
    def test_parts(self):
        """ parts() should recognize code parts and text parts. """
        s = '\x1b[31mtesting\x1b[0m'
        cb = ChainedBase(s)
        parts = cb.parts()
        self.assertTrue(
            parts[0].is_code(),
            msg='First part should be a code part.',
        )
        self.assertFalse(
            parts[0].is_text(),
            msg='First part should be a code part.',
        )
        self.assertTrue(
            parts[1].is_text(),
            msg='Second part should be a text part.',
        )
        self.assertFalse(
            parts[1].is_code(),
            msg='Second part should be a text part.',
        )
        self.assertTrue(
            parts[2].is_code(),
            msg='Third part should be a code part.',
        )
        self.assertFalse(
            parts[2].is_text(),
            msg='Third part should be a code part.',
        )
        # __eq__
        codepart = CodePart(s, start=0, stop=5)
        self.assertEqual(parts[0], codepart, msg='CodePart doesn\'t match.')
        textpart = TextPart(s, start=5, stop=12)
        self.assertEqual(parts[1], textpart, msg='TextPart doesn\'t match.')
        # __eq__ should raise TypeError.
        raiser = self.assertRaises(
            TypeError,
            msg='Failed to raise for bad type.',
        )
        for badtype in (1, 'a', 0.3, [], {}):
            with raiser:
                codepart == badtype
            with raiser:
                textpart == badtype

        # __hash__
        self.assertEqual(
            hash(parts[0]),
            hash(codepart),
            msg='hash() failed on same code part.',
        )
        self.assertEqual(
            hash(parts[1]),
            hash(textpart),
            msg='hash() failed on same text part.',
        )

        # __repr__
        self.assertEqual(
            repr(codepart),
            'CodePart({!r})'.format(s[codepart.start:codepart.stop]),
            msg='repr() failed on CodePart.',
        )
        self.assertEqual(
            repr(textpart),
            'TextPart({!r})'.format(s[textpart.start:textpart.stop]),
            msg='repr() failed on TextPart.',
        )

        # ChainedPart cannot be used directly.
        raiser = self.assertRaises(
            NotImplementedError,
            msg='Failed to raise when using a ChainedPart directly.',
        )
        with raiser:
            ChainedPart('a', 0, 0).is_code()
        with raiser:
            ChainedPart('a', 0, 0).is_text()
Beispiel #16
0
    def test_just(self):
        """ ljust()/rjust() should work around escape codes. """
        s = '\x1b[31mtest\x1b[0m'
        rjustcases = {
            0: '\x1b[31mtest\x1b[0m',
            8: '    \x1b[31mtest\x1b[0m',
        }
        for width, expected in rjustcases.items():
            self.assertCallEqual(
                ChainedBase(expected),
                func=ChainedBase(s).rjust,
                args=(width, ),
                msg='Failed to rjust ChainedBase correctly.',
            )
        ljustcases = {
            0: '\x1b[31mtest\x1b[0m',
            8: '\x1b[31mtest\x1b[0m    ',
        }
        for width, expected in ljustcases.items():
            self.assertCallEqual(
                ChainedBase(expected),
                func=ChainedBase(s).ljust,
                args=(width, ),
                msg='Failed to ljust ChainedBase correctly.',
            )
            # New text.
            self.assertCallEqual(
                ChainedBase(expected),
                func=ChainedBase().ljust,
                kwargs={
                    'text': s,
                    'width': width
                },
                msg='Failed to ljust(text={!r}) ChainedBase correctly.'.format(
                    s, ),
            )

        # Bad width should raise ValueError.
        cb = ChainedBase(s)
        for func in (cb.ljust, cb.rjust):
            raiser = self.assertCallRaises(
                ValueError,
                func=func,
                kwargs={'width': 'BAD'},
                msg='Failed to raise in {} for bad `width` arg.'.format(
                    func.__name__, ),
            )
            with raiser:
                func(width='BAD')

        # Text squeezer should honor existing data.
        cb = ChainedBase('test')
        self.assertCallEqual(
            ChainedBase('testthis    '),
            func=cb.ljust,
            args=(12, ),
            kwargs={
                'text': 'this',
                'squeeze': True
            },
            msg='Failed to "squeeze" old text and new text for ljust.',
        )
        self.assertCallEqual(
            ChainedBase('test    this'),
            func=cb.rjust,
            args=(12, ),
            kwargs={
                'text': 'this',
                'squeeze': True
            },
            msg='Failed to "squeeze" old text and new text for rjust.',
        )