mirror of
https://github.com/powerline/powerline.git
synced 2025-07-29 16:55:07 +02:00
Do not use create_renderer from a separate thread
Also moves functions from tests.test_config_reload to tests.lib.config_mock Using create_renderer for vim results in vim access from a separate thread.
This commit is contained in:
parent
b990c920e9
commit
33d32498b9
@ -159,8 +159,8 @@ class Powerline(object):
|
|||||||
|
|
||||||
self.config_paths = self.get_config_paths()
|
self.config_paths = self.get_config_paths()
|
||||||
|
|
||||||
self.renderer_lock = Lock()
|
|
||||||
self.configs_lock = Lock()
|
self.configs_lock = Lock()
|
||||||
|
self.create_renderer_kwargs = {}
|
||||||
self.shutdown_event = Event()
|
self.shutdown_event = Event()
|
||||||
self.configs = defaultdict(set)
|
self.configs = defaultdict(set)
|
||||||
self.missing = defaultdict(set)
|
self.missing = defaultdict(set)
|
||||||
@ -276,15 +276,14 @@ class Powerline(object):
|
|||||||
# Renderer updates configuration file via segments’ .startup thus it
|
# Renderer updates configuration file via segments’ .startup thus it
|
||||||
# should be locked to prevent state when configuration was updated,
|
# should be locked to prevent state when configuration was updated,
|
||||||
# but .render still uses old renderer.
|
# but .render still uses old renderer.
|
||||||
with self.renderer_lock:
|
try:
|
||||||
try:
|
renderer = Renderer(**self.renderer_options)
|
||||||
renderer = Renderer(**self.renderer_options)
|
except Exception as e:
|
||||||
except Exception as e:
|
self.pl.exception('Failed to construct renderer object: {0}', str(e))
|
||||||
self.pl.exception('Failed to construct renderer object: {0}', str(e))
|
if not hasattr(self, 'renderer'):
|
||||||
if not hasattr(self, 'renderer'):
|
raise
|
||||||
raise
|
else:
|
||||||
else:
|
self.renderer = renderer
|
||||||
self.renderer = renderer
|
|
||||||
|
|
||||||
if not self.run_once and not self.is_alive() and self.interval is not None:
|
if not self.run_once and not self.is_alive() and self.interval is not None:
|
||||||
self.start()
|
self.start()
|
||||||
@ -397,8 +396,15 @@ class Powerline(object):
|
|||||||
'''Lock renderer from modifications and pass all arguments further to
|
'''Lock renderer from modifications and pass all arguments further to
|
||||||
``self.renderer.render()``.
|
``self.renderer.render()``.
|
||||||
'''
|
'''
|
||||||
with self.renderer_lock:
|
if self.create_renderer_kwargs:
|
||||||
return self.renderer.render(*args, **kwargs)
|
try:
|
||||||
|
with self.configs_lock:
|
||||||
|
cr_kwargs = self.create_renderer_kwargs.copy()
|
||||||
|
self.create_renderer_kwargs.clear()
|
||||||
|
self.create_renderer(**cr_kwargs)
|
||||||
|
except Exception as e:
|
||||||
|
self.pl.exception('Failed to create renderer: {0}', str(e))
|
||||||
|
return self.renderer.render(*args, **kwargs)
|
||||||
|
|
||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
'''Lock renderer from modifications and run its ``.shutdown()`` method.
|
'''Lock renderer from modifications and run its ``.shutdown()`` method.
|
||||||
@ -406,8 +412,7 @@ class Powerline(object):
|
|||||||
self.shutdown_event.set()
|
self.shutdown_event.set()
|
||||||
if self.use_daemon_threads and self.is_alive():
|
if self.use_daemon_threads and self.is_alive():
|
||||||
self.thread.join()
|
self.thread.join()
|
||||||
with self.renderer_lock:
|
self.renderer.shutdown()
|
||||||
self.renderer.shutdown()
|
|
||||||
self.watcher.unsubscribe()
|
self.watcher.unsubscribe()
|
||||||
|
|
||||||
def is_alive(self):
|
def is_alive(self):
|
||||||
@ -435,11 +440,8 @@ class Powerline(object):
|
|||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
kwargs['load_' + type] = True
|
kwargs['load_' + type] = True
|
||||||
if kwargs:
|
if kwargs:
|
||||||
try:
|
self.create_renderer_kwargs.update(kwargs)
|
||||||
self.create_renderer(**kwargs)
|
|
||||||
except Exception as e:
|
|
||||||
self.pl.exception('Failed to create renderer: {0}', str(e))
|
|
||||||
self.shutdown_event.wait(self.interval)
|
self.shutdown_event.wait(self.interval)
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
|
119
tests/lib/config_mock.py
Normal file
119
tests/lib/config_mock.py
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
# vim:fileencoding=utf-8:noet
|
||||||
|
from threading import Lock
|
||||||
|
from powerline.renderer import Renderer
|
||||||
|
from powerline import Powerline
|
||||||
|
from copy import deepcopy
|
||||||
|
|
||||||
|
|
||||||
|
access_log = []
|
||||||
|
access_lock = Lock()
|
||||||
|
|
||||||
|
|
||||||
|
def load_json_config(config, config_file_path, *args, **kwargs):
|
||||||
|
global access_log
|
||||||
|
with access_lock:
|
||||||
|
access_log.append(config_file_path)
|
||||||
|
try:
|
||||||
|
return deepcopy(config[config_file_path])
|
||||||
|
except KeyError:
|
||||||
|
raise IOError(config_file_path)
|
||||||
|
|
||||||
|
|
||||||
|
def find_config_file(config, search_paths, config_file):
|
||||||
|
if config_file.endswith('raise') and config_file not in config:
|
||||||
|
raise IOError('fcf:' + config_file)
|
||||||
|
return config_file
|
||||||
|
|
||||||
|
|
||||||
|
def pop_events():
|
||||||
|
global access_log
|
||||||
|
with access_lock:
|
||||||
|
r = access_log[:]
|
||||||
|
access_log = []
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
class Watcher(object):
|
||||||
|
events = set()
|
||||||
|
lock = Lock()
|
||||||
|
|
||||||
|
def watch(self, file):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __call__(self, file):
|
||||||
|
if file in self.events:
|
||||||
|
with self.lock:
|
||||||
|
self.events.remove(file)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _reset(self, files):
|
||||||
|
with self.lock:
|
||||||
|
self.events.clear()
|
||||||
|
self.events.update(files)
|
||||||
|
|
||||||
|
def unsubscribe(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Logger(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.messages = []
|
||||||
|
self.lock = Lock()
|
||||||
|
|
||||||
|
def _add_msg(self, attr, msg):
|
||||||
|
with self.lock:
|
||||||
|
self.messages.append(attr + ':' + msg)
|
||||||
|
|
||||||
|
def _pop_msgs(self):
|
||||||
|
with self.lock:
|
||||||
|
r = self.messages
|
||||||
|
self.messages = []
|
||||||
|
return r
|
||||||
|
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
return lambda *args, **kwargs: self._add_msg(attr, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class SimpleRenderer(Renderer):
|
||||||
|
def hlstyle(self, fg=None, bg=None, attr=None):
|
||||||
|
return '<{fg} {bg} {attr}>'.format(fg=fg and fg[0], bg=bg and bg[0], attr=attr)
|
||||||
|
|
||||||
|
|
||||||
|
class TestPowerline(Powerline):
|
||||||
|
_created = False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_local_themes(local_themes):
|
||||||
|
return local_themes
|
||||||
|
|
||||||
|
def _will_create_renderer(self):
|
||||||
|
return self.create_renderer_kwargs
|
||||||
|
|
||||||
|
|
||||||
|
renderer = SimpleRenderer
|
||||||
|
|
||||||
|
|
||||||
|
def get_powerline(**kwargs):
|
||||||
|
return TestPowerline(
|
||||||
|
ext='test',
|
||||||
|
renderer_module='tests.lib.config_mock',
|
||||||
|
interval=0,
|
||||||
|
logger=Logger(),
|
||||||
|
watcher=Watcher(),
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def swap_attributes(config_container, powerline_module, replaces):
|
||||||
|
if not replaces:
|
||||||
|
replaces = {
|
||||||
|
'watcher': Watcher(),
|
||||||
|
'load_json_config': lambda *args: load_json_config(config_container['config'], *args),
|
||||||
|
'find_config_file': lambda *args: find_config_file(config_container['config'], *args),
|
||||||
|
}
|
||||||
|
for attr, val in replaces.items():
|
||||||
|
old_val = getattr(powerline_module, attr)
|
||||||
|
setattr(powerline_module, attr, val)
|
||||||
|
replaces[attr] = old_val
|
||||||
|
return replaces
|
@ -2,55 +2,13 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import powerline as powerline_module
|
import powerline as powerline_module
|
||||||
import time
|
import time
|
||||||
from powerline.renderer import Renderer
|
|
||||||
from tests import TestCase
|
from tests import TestCase
|
||||||
from tests.lib import replace_item
|
from tests.lib import replace_item
|
||||||
|
from tests.lib.config_mock import swap_attributes, get_powerline, pop_events
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from threading import Lock
|
from threading import Lock
|
||||||
|
|
||||||
|
|
||||||
class Watcher(object):
|
|
||||||
events = set()
|
|
||||||
lock = Lock()
|
|
||||||
|
|
||||||
def watch(self, file):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def __call__(self, file):
|
|
||||||
if file in self.events:
|
|
||||||
with self.lock:
|
|
||||||
self.events.remove(file)
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def _reset(self, files):
|
|
||||||
with self.lock:
|
|
||||||
self.events.clear()
|
|
||||||
self.events.update(files)
|
|
||||||
|
|
||||||
def unsubscribe(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Logger(object):
|
|
||||||
def __init__(self):
|
|
||||||
self.messages = []
|
|
||||||
self.lock = Lock()
|
|
||||||
|
|
||||||
def _add_msg(self, msg):
|
|
||||||
with self.lock:
|
|
||||||
self.messages.append(msg)
|
|
||||||
|
|
||||||
def _pop_msgs(self):
|
|
||||||
with self.lock:
|
|
||||||
r = self.messages
|
|
||||||
self.messages = []
|
|
||||||
return r
|
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
|
||||||
return self._add_msg
|
|
||||||
|
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
'config': {
|
'config': {
|
||||||
'common': {
|
'common': {
|
||||||
@ -134,106 +92,37 @@ config = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
access_log = []
|
|
||||||
access_lock = Lock()
|
|
||||||
|
|
||||||
|
|
||||||
def load_json_config(config_file_path, *args, **kwargs):
|
|
||||||
global access_log
|
|
||||||
with access_lock:
|
|
||||||
access_log.append(config_file_path)
|
|
||||||
try:
|
|
||||||
return deepcopy(config[config_file_path])
|
|
||||||
except KeyError:
|
|
||||||
raise IOError(config_file_path)
|
|
||||||
|
|
||||||
|
|
||||||
def find_config_file(search_paths, config_file):
|
|
||||||
if config_file.endswith('raise') and config_file not in config:
|
|
||||||
raise IOError('fcf:' + config_file)
|
|
||||||
return config_file
|
|
||||||
|
|
||||||
|
|
||||||
class SimpleRenderer(Renderer):
|
|
||||||
def hlstyle(self, fg=None, bg=None, attr=None):
|
|
||||||
return '<{fg} {bg} {attr}>'.format(fg=fg and fg[0], bg=bg and bg[0], attr=attr)
|
|
||||||
|
|
||||||
|
|
||||||
class TestPowerline(powerline_module.Powerline):
|
|
||||||
_created = False
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_local_themes(local_themes):
|
|
||||||
return local_themes
|
|
||||||
|
|
||||||
def create_renderer(self, *args, **kwargs):
|
|
||||||
try:
|
|
||||||
r = super(TestPowerline, self).create_renderer(*args, **kwargs)
|
|
||||||
finally:
|
|
||||||
self._created = True
|
|
||||||
return r
|
|
||||||
|
|
||||||
def _created_renderer(self):
|
|
||||||
if self._created:
|
|
||||||
self._created = False
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
renderer = SimpleRenderer
|
|
||||||
|
|
||||||
|
|
||||||
def get_powerline(**kwargs):
|
|
||||||
return TestPowerline(
|
|
||||||
ext='test',
|
|
||||||
renderer_module='tests.test_config_reload',
|
|
||||||
interval=0,
|
|
||||||
logger=Logger(),
|
|
||||||
watcher=Watcher(),
|
|
||||||
**kwargs
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def sleep(interval):
|
def sleep(interval):
|
||||||
time.sleep(interval)
|
time.sleep(interval)
|
||||||
|
|
||||||
|
|
||||||
def add_watcher_events(p, *args, **kwargs):
|
def add_watcher_events(p, *args, **kwargs):
|
||||||
p._created_renderer()
|
|
||||||
p.watcher._reset(args)
|
p.watcher._reset(args)
|
||||||
while not p._created_renderer():
|
while not p._will_create_renderer():
|
||||||
sleep(kwargs.get('interval', 0.000001))
|
sleep(kwargs.get('interval', 0.000001))
|
||||||
if not kwargs.get('wait', True):
|
if not kwargs.get('wait', True):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def clear_events():
|
|
||||||
global access_log
|
|
||||||
with access_lock:
|
|
||||||
access_log = []
|
|
||||||
|
|
||||||
|
|
||||||
class TestConfigReload(TestCase):
|
class TestConfigReload(TestCase):
|
||||||
def assertAccessEvents(self, *args):
|
def assertAccessEvents(self, *args):
|
||||||
with access_lock:
|
self.assertEqual(set(pop_events()), set(args))
|
||||||
self.assertEqual(set(access_log), set(args))
|
|
||||||
clear_events()
|
|
||||||
|
|
||||||
def test_noreload(self):
|
def test_noreload(self):
|
||||||
with get_powerline(run_once=True) as p:
|
with get_powerline(run_once=True) as p:
|
||||||
with replace_item(globals(), 'config', deepcopy(config)):
|
with replace_item(globals(), 'config', deepcopy(config)):
|
||||||
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default')
|
|
||||||
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
||||||
|
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default')
|
||||||
config['config']['common']['spaces'] = 1
|
config['config']['common']['spaces'] = 1
|
||||||
add_watcher_events(p, 'config', wait=False, interval=0.05)
|
add_watcher_events(p, 'config', wait=False, interval=0.05)
|
||||||
# When running once thread should not start
|
# When running once thread should not start
|
||||||
self.assertAccessEvents()
|
|
||||||
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
||||||
|
self.assertAccessEvents()
|
||||||
self.assertEqual(p.logger._pop_msgs(), [])
|
self.assertEqual(p.logger._pop_msgs(), [])
|
||||||
# Without the following assertion test_reload_colors may fail for
|
# Without the following assertion test_reload_colors may fail for
|
||||||
# unknown reason (with AssertionError telling about “config” accessed
|
# unknown reason (with AssertionError telling about “config” accessed
|
||||||
# one more time then needed)
|
# one more time then needed)
|
||||||
clear_events()
|
pop_events()
|
||||||
|
|
||||||
def test_reload_main(self):
|
def test_reload_main(self):
|
||||||
with get_powerline(run_once=False) as p:
|
with get_powerline(run_once=False) as p:
|
||||||
@ -243,62 +132,62 @@ class TestConfigReload(TestCase):
|
|||||||
|
|
||||||
config['config']['common']['spaces'] = 1
|
config['config']['common']['spaces'] = 1
|
||||||
add_watcher_events(p, 'config')
|
add_watcher_events(p, 'config')
|
||||||
self.assertAccessEvents('config')
|
|
||||||
self.assertEqual(p.render(), '<1 2 1> s <2 4 False>>><3 4 4>g <4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 2 1> s <2 4 False>>><3 4 4>g <4 False False>>><None None None>')
|
||||||
|
self.assertAccessEvents('config')
|
||||||
self.assertEqual(p.logger._pop_msgs(), [])
|
self.assertEqual(p.logger._pop_msgs(), [])
|
||||||
|
|
||||||
config['config']['ext']['test']['theme'] = 'nonexistent'
|
config['config']['ext']['test']['theme'] = 'nonexistent'
|
||||||
add_watcher_events(p, 'config')
|
add_watcher_events(p, 'config')
|
||||||
self.assertAccessEvents('config', 'themes/test/nonexistent')
|
|
||||||
self.assertEqual(p.render(), '<1 2 1> s <2 4 False>>><3 4 4>g <4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 2 1> s <2 4 False>>><3 4 4>g <4 False False>>><None None None>')
|
||||||
|
self.assertAccessEvents('config', 'themes/test/nonexistent')
|
||||||
# It should normally handle file missing error
|
# It should normally handle file missing error
|
||||||
self.assertEqual(p.logger._pop_msgs(), ['test:Failed to create renderer: themes/test/nonexistent'])
|
self.assertEqual(p.logger._pop_msgs(), ['exception:test:Failed to create renderer: themes/test/nonexistent'])
|
||||||
|
|
||||||
config['config']['ext']['test']['theme'] = 'default'
|
config['config']['ext']['test']['theme'] = 'default'
|
||||||
add_watcher_events(p, 'config')
|
add_watcher_events(p, 'config')
|
||||||
self.assertAccessEvents('config', 'themes/test/default')
|
|
||||||
self.assertEqual(p.render(), '<1 2 1> s <2 4 False>>><3 4 4>g <4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 2 1> s <2 4 False>>><3 4 4>g <4 False False>>><None None None>')
|
||||||
|
self.assertAccessEvents('config', 'themes/test/default')
|
||||||
self.assertEqual(p.logger._pop_msgs(), [])
|
self.assertEqual(p.logger._pop_msgs(), [])
|
||||||
|
|
||||||
config['config']['ext']['test']['colorscheme'] = 'nonexistent'
|
config['config']['ext']['test']['colorscheme'] = 'nonexistent'
|
||||||
add_watcher_events(p, 'config')
|
add_watcher_events(p, 'config')
|
||||||
self.assertAccessEvents('config', 'colorschemes/test/nonexistent')
|
|
||||||
self.assertEqual(p.render(), '<1 2 1> s <2 4 False>>><3 4 4>g <4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 2 1> s <2 4 False>>><3 4 4>g <4 False False>>><None None None>')
|
||||||
|
self.assertAccessEvents('config', 'colorschemes/test/nonexistent')
|
||||||
# It should normally handle file missing error
|
# It should normally handle file missing error
|
||||||
self.assertEqual(p.logger._pop_msgs(), ['test:Failed to create renderer: colorschemes/test/nonexistent'])
|
self.assertEqual(p.logger._pop_msgs(), ['exception:test:Failed to create renderer: colorschemes/test/nonexistent'])
|
||||||
|
|
||||||
config['config']['ext']['test']['colorscheme'] = '2'
|
config['config']['ext']['test']['colorscheme'] = '2'
|
||||||
add_watcher_events(p, 'config')
|
add_watcher_events(p, 'config')
|
||||||
self.assertAccessEvents('config', 'colorschemes/test/2')
|
|
||||||
self.assertEqual(p.render(), '<2 3 1> s <3 4 False>>><1 4 4>g <4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<2 3 1> s <3 4 False>>><1 4 4>g <4 False False>>><None None None>')
|
||||||
|
self.assertAccessEvents('config', 'colorschemes/test/2')
|
||||||
self.assertEqual(p.logger._pop_msgs(), [])
|
self.assertEqual(p.logger._pop_msgs(), [])
|
||||||
|
|
||||||
config['config']['ext']['test']['theme'] = '2'
|
config['config']['ext']['test']['theme'] = '2'
|
||||||
add_watcher_events(p, 'config')
|
add_watcher_events(p, 'config')
|
||||||
self.assertAccessEvents('config', 'themes/test/2')
|
|
||||||
self.assertEqual(p.render(), '<2 3 1> t <3 4 False>>><1 4 4>b <4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<2 3 1> t <3 4 False>>><1 4 4>b <4 False False>>><None None None>')
|
||||||
|
self.assertAccessEvents('config', 'themes/test/2')
|
||||||
self.assertEqual(p.logger._pop_msgs(), [])
|
self.assertEqual(p.logger._pop_msgs(), [])
|
||||||
|
|
||||||
self.assertEqual(p.renderer.local_themes, None)
|
self.assertEqual(p.renderer.local_themes, None)
|
||||||
config['config']['ext']['test']['local_themes'] = 'something'
|
config['config']['ext']['test']['local_themes'] = 'something'
|
||||||
add_watcher_events(p, 'config')
|
add_watcher_events(p, 'config')
|
||||||
self.assertAccessEvents('config')
|
|
||||||
self.assertEqual(p.render(), '<2 3 1> t <3 4 False>>><1 4 4>b <4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<2 3 1> t <3 4 False>>><1 4 4>b <4 False False>>><None None None>')
|
||||||
|
self.assertAccessEvents('config')
|
||||||
self.assertEqual(p.logger._pop_msgs(), [])
|
self.assertEqual(p.logger._pop_msgs(), [])
|
||||||
self.assertEqual(p.renderer.local_themes, 'something')
|
self.assertEqual(p.renderer.local_themes, 'something')
|
||||||
clear_events()
|
pop_events()
|
||||||
|
|
||||||
def test_reload_unexistent(self):
|
def test_reload_unexistent(self):
|
||||||
with get_powerline(run_once=False) as p:
|
with get_powerline(run_once=False) as p:
|
||||||
with replace_item(globals(), 'config', deepcopy(config)):
|
with replace_item(globals(), 'config', deepcopy(config)):
|
||||||
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default')
|
|
||||||
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
||||||
|
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default')
|
||||||
|
|
||||||
config['config']['ext']['test']['colorscheme'] = 'nonexistentraise'
|
config['config']['ext']['test']['colorscheme'] = 'nonexistentraise'
|
||||||
add_watcher_events(p, 'config')
|
add_watcher_events(p, 'config')
|
||||||
self.assertAccessEvents('config')
|
|
||||||
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
||||||
self.assertEqual(p.logger._pop_msgs(), ['test:Failed to create renderer: fcf:colorschemes/test/nonexistentraise'])
|
self.assertAccessEvents('config')
|
||||||
|
self.assertEqual(p.logger._pop_msgs(), ['exception:test:Failed to create renderer: fcf:colorschemes/test/nonexistentraise'])
|
||||||
|
|
||||||
config['colorschemes/test/nonexistentraise'] = {
|
config['colorschemes/test/nonexistentraise'] = {
|
||||||
'groups': {
|
'groups': {
|
||||||
@ -306,69 +195,62 @@ class TestConfigReload(TestCase):
|
|||||||
"str2": {"fg": "col2", "bg": "col4", "attr": ["underline"]},
|
"str2": {"fg": "col2", "bg": "col4", "attr": ["underline"]},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
while not p._created_renderer():
|
while not p._will_create_renderer():
|
||||||
sleep(0.000001)
|
sleep(0.000001)
|
||||||
self.assertAccessEvents('colorschemes/test/nonexistentraise')
|
|
||||||
self.assertEqual(p.render(), '<1 3 1> s<3 4 False>>><2 4 4>g<4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 3 1> s<3 4 False>>><2 4 4>g<4 False False>>><None None None>')
|
||||||
|
self.assertAccessEvents('colorschemes/test/nonexistentraise')
|
||||||
self.assertEqual(p.logger._pop_msgs(), [])
|
self.assertEqual(p.logger._pop_msgs(), [])
|
||||||
clear_events()
|
pop_events()
|
||||||
|
|
||||||
def test_reload_colors(self):
|
def test_reload_colors(self):
|
||||||
with get_powerline(run_once=False) as p:
|
with get_powerline(run_once=False) as p:
|
||||||
with replace_item(globals(), 'config', deepcopy(config)):
|
with replace_item(globals(), 'config', deepcopy(config)):
|
||||||
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default')
|
|
||||||
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
||||||
|
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default')
|
||||||
|
|
||||||
config['colors']['colors']['col1'] = 5
|
config['colors']['colors']['col1'] = 5
|
||||||
add_watcher_events(p, 'colors')
|
add_watcher_events(p, 'colors')
|
||||||
self.assertAccessEvents('colors')
|
|
||||||
self.assertEqual(p.render(), '<5 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<5 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
||||||
|
self.assertAccessEvents('colors')
|
||||||
self.assertEqual(p.logger._pop_msgs(), [])
|
self.assertEqual(p.logger._pop_msgs(), [])
|
||||||
clear_events()
|
pop_events()
|
||||||
|
|
||||||
def test_reload_colorscheme(self):
|
def test_reload_colorscheme(self):
|
||||||
with get_powerline(run_once=False) as p:
|
with get_powerline(run_once=False) as p:
|
||||||
with replace_item(globals(), 'config', deepcopy(config)):
|
with replace_item(globals(), 'config', deepcopy(config)):
|
||||||
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default')
|
|
||||||
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
||||||
|
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default')
|
||||||
|
|
||||||
config['colorschemes/test/default']['groups']['str1']['bg'] = 'col3'
|
config['colorschemes/test/default']['groups']['str1']['bg'] = 'col3'
|
||||||
add_watcher_events(p, 'colorschemes/test/default')
|
add_watcher_events(p, 'colorschemes/test/default')
|
||||||
self.assertAccessEvents('colorschemes/test/default')
|
|
||||||
self.assertEqual(p.render(), '<1 3 1> s<3 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 3 1> s<3 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
||||||
|
self.assertAccessEvents('colorschemes/test/default')
|
||||||
self.assertEqual(p.logger._pop_msgs(), [])
|
self.assertEqual(p.logger._pop_msgs(), [])
|
||||||
clear_events()
|
pop_events()
|
||||||
|
|
||||||
def test_reload_theme(self):
|
def test_reload_theme(self):
|
||||||
with get_powerline(run_once=False) as p:
|
with get_powerline(run_once=False) as p:
|
||||||
with replace_item(globals(), 'config', deepcopy(config)):
|
with replace_item(globals(), 'config', deepcopy(config)):
|
||||||
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default')
|
|
||||||
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
||||||
|
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default')
|
||||||
|
|
||||||
config['themes/test/default']['segments']['left'][0]['contents'] = 'col3'
|
config['themes/test/default']['segments']['left'][0]['contents'] = 'col3'
|
||||||
add_watcher_events(p, 'themes/test/default')
|
add_watcher_events(p, 'themes/test/default')
|
||||||
self.assertAccessEvents('themes/test/default')
|
|
||||||
self.assertEqual(p.render(), '<1 2 1> col3<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 2 1> col3<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
||||||
|
self.assertAccessEvents('themes/test/default')
|
||||||
self.assertEqual(p.logger._pop_msgs(), [])
|
self.assertEqual(p.logger._pop_msgs(), [])
|
||||||
clear_events()
|
pop_events()
|
||||||
|
|
||||||
|
|
||||||
replaces = {
|
replaces = {}
|
||||||
'watcher': Watcher(),
|
|
||||||
'load_json_config': load_json_config,
|
|
||||||
'find_config_file': find_config_file,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def swap_attributes():
|
def setUpModule():
|
||||||
global replaces
|
global replaces
|
||||||
for attr, val in replaces.items():
|
replaces = swap_attributes(globals(), powerline_module, replaces)
|
||||||
old_val = getattr(powerline_module, attr)
|
|
||||||
setattr(powerline_module, attr, val)
|
|
||||||
replaces[attr] = old_val
|
|
||||||
|
|
||||||
|
|
||||||
tearDownModule = setUpModule = swap_attributes
|
tearDownModule = setUpModule
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
Loading…
x
Reference in New Issue
Block a user