1# -*- coding: utf-8 -*- 2# Copyright 2017 - 2020 Avram Lubkin, All Rights Reserved 3 4# This Source Code Form is subject to the terms of the Mozilla Public 5# License, v. 2.0. If a copy of the MPL was not distributed with this 6# file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 8""" 9Test module for enlighten._statusbar 10""" 11 12from enlighten import EnlightenWarning, Justify 13 14import tests 15from tests import TestCase, MockManager, MockTTY, MockStatusBar, PY2, unittest 16 17 18class TestStatusBar(TestCase): 19 """ 20 Test the StatusBar class 21 """ 22 23 def setUp(self): 24 self.tty = MockTTY() 25 self.manager = MockManager(stream=self.tty.stdout) 26 27 def tearDown(self): 28 self.tty.close() 29 30 def test_static(self): 31 """ 32 Basic static status bar 33 """ 34 35 sbar = self.manager.status_bar('Hello', 'World!') 36 self.assertEqual(sbar.format(), 'Hello World!' + ' ' * 68) 37 38 sbar.update('Goodbye, World!') 39 self.assertEqual(sbar.format(), 'Goodbye, World!' + ' ' * 65) 40 41 def test_static_justify(self): 42 """ 43 Justified static status bar 44 """ 45 46 sbar = self.manager.status_bar('Hello', 'World!', justify=Justify.LEFT) 47 self.assertEqual(sbar.format(), 'Hello World!' + ' ' * 68) 48 49 sbar = self.manager.status_bar('Hello', 'World!', justify=Justify.RIGHT) 50 self.assertEqual(sbar.format(), ' ' * 68 + 'Hello World!') 51 52 sbar = self.manager.status_bar('Hello', 'World!', justify=Justify.CENTER) 53 self.assertEqual(sbar.format(), ' ' * 34 + 'Hello World!' + ' ' * 34) 54 55 def test_formatted(self): 56 """ 57 Basic formatted status bar 58 """ 59 60 sbar = self.manager.status_bar(status_format=u'Stage: {stage}, Status: {status}', stage=1, 61 fields={'status': 'All good!'}) 62 self.assertEqual(sbar.format(), 'Stage: 1, Status: All good!' + ' ' * 53) 63 sbar.update(stage=2) 64 self.assertEqual(sbar.format(), 'Stage: 2, Status: All good!' + ' ' * 53) 65 sbar.update(stage=3, status='Meh') 66 self.assertEqual(sbar.format(), 'Stage: 3, Status: Meh' + ' ' * 59) 67 68 def test_formatted_justify(self): 69 """ 70 Justified formatted status bar 71 """ 72 73 sbar = self.manager.status_bar(status_format=u'Stage: {stage}, Status: {status}', stage=1, 74 fields={'status': 'All good!'}, justify=Justify.LEFT) 75 self.assertEqual(sbar.format(), 'Stage: 1, Status: All good!' + ' ' * 53) 76 77 sbar = self.manager.status_bar(status_format=u'Stage: {stage}, Status: {status}', stage=1, 78 fields={'status': 'All good!'}, justify=Justify.RIGHT) 79 self.assertEqual(sbar.format(), ' ' * 53 + 'Stage: 1, Status: All good!') 80 81 sbar = self.manager.status_bar(status_format=u'Stage: {stage}, Status: {status}', stage=1, 82 fields={'status': 'All good'}, justify=Justify.CENTER) 83 self.assertEqual(sbar.format(), ' ' * 27 + 'Stage: 1, Status: All good' + ' ' * 27) 84 85 def test_formatted_missing_field(self): 86 """ 87 ValueError raised when a field is missing when updating status bar 88 """ 89 90 fields = {'status': 'All good!'} 91 sbar = self.manager.status_bar(status_format=u'Stage: {stage}, Status: {status}', stage=1, 92 fields=fields) 93 del fields['status'] 94 95 sbar.last_update = sbar.start - 5.0 96 with self.assertRaisesRegex(ValueError, "'status' specified in format, but not provided"): 97 sbar.update() 98 99 def test_bad_justify(self): 100 """ 101 ValueError raised when justify is given an invalid value 102 """ 103 104 with self.assertRaisesRegex(ValueError, 'justify must be one of Justify.LEFT, '): 105 self.manager.status_bar('Hello', 'World!', justify='justice') 106 107 def test_update(self): 108 """ 109 update() does not refresh is bar is disabled or min_delta hasn't passed 110 """ 111 112 self.manager.status_bar_class = MockStatusBar 113 sbar = self.manager.status_bar('Hello', 'World!') 114 115 self.assertEqual(sbar.called, 1) 116 sbar.last_update = sbar.start - 1.0 117 sbar.update() 118 self.assertEqual(sbar.called, 2) 119 120 sbar.last_update = sbar.start + 5.0 121 sbar.update() 122 self.assertEqual(sbar.called, 2) 123 124 sbar.last_update = sbar.last_update - 10.0 125 sbar.enabled = False 126 sbar.update() 127 self.assertEqual(sbar.called, 2) 128 129 sbar.enabled = True 130 sbar.update() 131 self.assertEqual(sbar.called, 3) 132 133 def test_fill(self): 134 """ 135 Fill uses remaining space 136 """ 137 138 sbar = self.manager.status_bar(status_format=u'{fill}HI', fill='-') 139 self.assertEqual(sbar.format(), u'-' * 78 + 'HI') 140 141 sbar = self.manager.status_bar(status_format=u'{fill}HI{fill}', fill='-') 142 self.assertEqual(sbar.format(), u'-' * 39 + 'HI' + u'-' * 39) 143 144 def test_fill_uneven(self): 145 """ 146 Extra fill should be equal 147 """ 148 149 sbar = self.manager.status_bar( 150 status_format=u'{fill}Helloooo!{fill}Woooorld!{fill}', fill='-' 151 ) 152 self.assertEqual(sbar.format(), 153 u'-' * 20 + 'Helloooo!' + u'-' * 21 + 'Woooorld!' + u'-' * 21) 154 155 @unittest.skipIf(PY2, 'Skip warnings tests in Python 2') 156 def test_reserve_fields(self): 157 """ 158 When reserved fields are used, a warning is raised 159 """ 160 161 with self.assertWarnsRegex(EnlightenWarning, 'Ignoring reserved fields') as warn: 162 self.manager.status_bar(status_format=u'Stage: {stage}, Fill: {fill}', stage=1, 163 fields={'fill': 'Reserved field'}) 164 self.assertRegex(tests.__file__, warn.filename) 165 166 with self.assertWarnsRegex(EnlightenWarning, 'Ignoring reserved fields') as warn: 167 self.manager.status_bar(status_format=u'Stage: {stage}, elapsed: {elapsed}', stage=1, 168 elapsed='Reserved field') 169 self.assertRegex(tests.__file__, warn.filename) 170