Lots of tests
This commit is contained in:
@@ -177,15 +177,15 @@ def main():
|
|||||||
|
|
||||||
term = Terminal(stdscr, config)
|
term = Terminal(stdscr, config)
|
||||||
|
|
||||||
if config['monochrome']:
|
if config['monochrome'] or config['theme'] == 'monochrome':
|
||||||
_logger.info('Using monochrome theme')
|
_logger.info('Using monochrome theme')
|
||||||
theme = Theme(use_color=False)
|
theme = Theme(use_color=False)
|
||||||
elif config['theme']:
|
elif config['theme'] and config['theme'] != 'default':
|
||||||
_logger.info('Loading theme: %s', config['theme'])
|
_logger.info('Loading theme: %s', config['theme'])
|
||||||
theme = Theme.from_name(config['theme'])
|
theme = Theme.from_name(config['theme'])
|
||||||
else:
|
else:
|
||||||
# Set to None to let the terminal figure out which default
|
# Set to None to let the terminal figure out which theme
|
||||||
# theme to use depending on if colors are supported or not
|
# to use depending on if colors are supported or not
|
||||||
theme = None
|
theme = None
|
||||||
term.set_theme(theme)
|
term.set_theme(theme)
|
||||||
|
|
||||||
|
|||||||
16
rtv/theme.py
16
rtv/theme.py
@@ -54,7 +54,7 @@ class Theme(object):
|
|||||||
# can only use the 8 basic colors with the default color as the background
|
# can only use the 8 basic colors with the default color as the background
|
||||||
DEFAULT_THEME = {
|
DEFAULT_THEME = {
|
||||||
'modifiers': {
|
'modifiers': {
|
||||||
'Normal': (None, None, None),
|
'Normal': (-1, -1, None),
|
||||||
'Selected': (None, None, None),
|
'Selected': (None, None, None),
|
||||||
'SelectedCursor': (None, None, curses.A_REVERSE),
|
'SelectedCursor': (None, None, curses.A_REVERSE),
|
||||||
},
|
},
|
||||||
@@ -91,14 +91,14 @@ class Theme(object):
|
|||||||
'MultiredditName': (curses.COLOR_YELLOW, None, curses.A_BOLD),
|
'MultiredditName': (curses.COLOR_YELLOW, None, curses.A_BOLD),
|
||||||
'MultiredditText': (None, None, None),
|
'MultiredditText': (None, None, None),
|
||||||
'NeutralVote': (None, None, curses.A_BOLD),
|
'NeutralVote': (None, None, curses.A_BOLD),
|
||||||
'NSFW': (curses.COLOR_RED, None, curses.A_BOLD),
|
'NSFW': (curses.COLOR_RED, None, curses.A_BOLD | curses.A_REVERSE),
|
||||||
'Saved': (curses.COLOR_GREEN, None, None),
|
'Saved': (curses.COLOR_GREEN, None, None),
|
||||||
'Score': (None, None, None),
|
'Score': (None, None, None),
|
||||||
'Separator': (None, None, curses.A_BOLD),
|
'Separator': (None, None, curses.A_BOLD),
|
||||||
'Stickied': (curses.COLOR_GREEN, None, None),
|
'Stickied': (curses.COLOR_GREEN, None, None),
|
||||||
'SubscriptionName': (curses.COLOR_YELLOW, None, curses.A_BOLD),
|
'SubscriptionName': (curses.COLOR_YELLOW, None, curses.A_BOLD),
|
||||||
'SubscriptionText': (None, None, None),
|
'SubscriptionText': (None, None, None),
|
||||||
'SubmissionAuthor': (curses.COLOR_GREEN, None, None),
|
'SubmissionAuthor': (curses.COLOR_GREEN, None, curses.A_BOLD),
|
||||||
'SubmissionFlair': (curses.COLOR_RED, None, None),
|
'SubmissionFlair': (curses.COLOR_RED, None, None),
|
||||||
'SubmissionSubreddit': (curses.COLOR_YELLOW, None, None),
|
'SubmissionSubreddit': (curses.COLOR_YELLOW, None, None),
|
||||||
'SubmissionText': (None, None, None),
|
'SubmissionText': (None, None, None),
|
||||||
@@ -130,6 +130,9 @@ class Theme(object):
|
|||||||
format as Theme.DEFAULT_THEME.
|
format as Theme.DEFAULT_THEME.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if source not in (None, 'built-in', 'preset', 'installed', 'custom'):
|
||||||
|
raise ValueError('Invalid source')
|
||||||
|
|
||||||
if name is None and source is None:
|
if name is None and source is None:
|
||||||
name = 'default' if use_color else 'monochrome'
|
name = 'default' if use_color else 'monochrome'
|
||||||
source = 'built-in'
|
source = 'built-in'
|
||||||
@@ -332,6 +335,12 @@ class Theme(object):
|
|||||||
line = ' {0:<20}[requires {1} colors]'
|
line = ' {0:<20}[requires {1} colors]'
|
||||||
print(line.format(theme.name, theme.required_colors))
|
print(line.format(theme.name, theme.required_colors))
|
||||||
|
|
||||||
|
print('\nBuilt-in:')
|
||||||
|
built_in = [t for t in themes if t.source == 'built-in']
|
||||||
|
for theme in built_in:
|
||||||
|
line = ' {0:<20}[requires {1} colors]'
|
||||||
|
print(line.format(theme.name, theme.required_colors))
|
||||||
|
|
||||||
if errors:
|
if errors:
|
||||||
print('\nWARNING: Some files encountered errors:')
|
print('\nWARNING: Some files encountered errors:')
|
||||||
for (source, name), error in errors.items():
|
for (source, name), error in errors.items():
|
||||||
@@ -496,7 +505,6 @@ class Theme(object):
|
|||||||
b = round(int(color[5:7], 16) / 51.0)
|
b = round(int(color[5:7], 16) / 51.0)
|
||||||
n = 36 * r + 6 * g + b + 16
|
n = 36 * r + 6 * g + b + 16
|
||||||
return 'ansi_{0}'.format(n)
|
return 'ansi_{0}'.format(n)
|
||||||
|
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,8 @@
|
|||||||
[theme]
|
[theme]
|
||||||
;<element> = <foreground> <background> <attributes>
|
;<element> = <foreground> <background> <attributes>
|
||||||
Normal = ansi_244 ansi_234 -
|
Normal = ansi_244 ansi_234 -
|
||||||
Selected = ansi_244 ansi_235 -
|
Selected = - ansi_235 -
|
||||||
SelectedCursor = ansi_244 ansi_235 bold+reverse
|
SelectedCursor = - ansi_235 bold+reverse
|
||||||
|
|
||||||
TitleBar = ansi_37 - bold+reverse
|
TitleBar = ansi_37 - bold+reverse
|
||||||
OrderBar = ansi_245 - bold
|
OrderBar = ansi_245 - bold
|
||||||
|
|||||||
@@ -20,8 +20,8 @@
|
|||||||
[theme]
|
[theme]
|
||||||
;<element> = <foreground> <background> <attributes>
|
;<element> = <foreground> <background> <attributes>
|
||||||
Normal = ansi_241 ansi_230 -
|
Normal = ansi_241 ansi_230 -
|
||||||
Selected = ansi_241 ansi_254 -
|
Selected = - ansi_254 -
|
||||||
SelectedCursor = ansi_241 ansi_254 bold+reverse
|
SelectedCursor = - ansi_254 bold+reverse
|
||||||
|
|
||||||
TitleBar = ansi_37 - bold+reverse
|
TitleBar = ansi_37 - bold+reverse
|
||||||
OrderBar = ansi_245 - bold
|
OrderBar = ansi_245 - bold
|
||||||
|
|||||||
@@ -89,7 +89,9 @@ def test_config_get_args():
|
|||||||
'--non-persistent',
|
'--non-persistent',
|
||||||
'--clear-auth',
|
'--clear-auth',
|
||||||
'--copy-config',
|
'--copy-config',
|
||||||
'--enable-media']
|
'--enable-media',
|
||||||
|
'--theme', 'molokai',
|
||||||
|
'--list-themes']
|
||||||
|
|
||||||
with mock.patch('sys.argv', ['rtv']):
|
with mock.patch('sys.argv', ['rtv']):
|
||||||
config_dict = Config.get_args()
|
config_dict = Config.get_args()
|
||||||
@@ -111,6 +113,8 @@ def test_config_get_args():
|
|||||||
assert config['config'] == 'configfile.cfg'
|
assert config['config'] == 'configfile.cfg'
|
||||||
assert config['copy_config'] is True
|
assert config['copy_config'] is True
|
||||||
assert config['enable_media'] is True
|
assert config['enable_media'] is True
|
||||||
|
assert config['theme'] == 'molokai'
|
||||||
|
assert config['list_themes'] is True
|
||||||
|
|
||||||
|
|
||||||
def test_config_link_deprecated():
|
def test_config_link_deprecated():
|
||||||
@@ -143,7 +147,8 @@ def test_config_from_file():
|
|||||||
'subreddit': 'cfb',
|
'subreddit': 'cfb',
|
||||||
'enable_media': True,
|
'enable_media': True,
|
||||||
'max_comment_cols': 150,
|
'max_comment_cols': 150,
|
||||||
'hide_username': True}
|
'hide_username': True,
|
||||||
|
'theme': 'molokai'}
|
||||||
|
|
||||||
bindings = {
|
bindings = {
|
||||||
'REFRESH': 'r, <KEY_F5>',
|
'REFRESH': 'r, <KEY_F5>',
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import curses
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from rtv.page import Page, PageController, logged_in
|
from rtv.page import Page, PageController, logged_in
|
||||||
@@ -112,3 +114,40 @@ def test_page_authenticated(reddit, terminal, config, oauth, refresh_token):
|
|||||||
terminal.stdscr.getch.return_value = ord('y')
|
terminal.stdscr.getch.return_value = ord('y')
|
||||||
page.controller.trigger('u')
|
page.controller.trigger('u')
|
||||||
assert not reddit.is_oauth_session()
|
assert not reddit.is_oauth_session()
|
||||||
|
|
||||||
|
|
||||||
|
def test_page_cycle_theme(reddit, terminal, config, oauth):
|
||||||
|
|
||||||
|
page = Page(reddit, terminal, config, oauth)
|
||||||
|
page.controller = PageController(page, keymap=config.keymap)
|
||||||
|
|
||||||
|
page.term.set_theme()
|
||||||
|
assert page.term.theme.name == 'default'
|
||||||
|
|
||||||
|
with mock.patch.object(terminal, 'show_notification'), \
|
||||||
|
mock.patch.object(page, 'draw'):
|
||||||
|
|
||||||
|
# Next theme
|
||||||
|
page.controller.trigger(curses.KEY_F3)
|
||||||
|
assert page.term.theme.name == 'monochrome'
|
||||||
|
terminal.show_notification.assert_called_with(
|
||||||
|
'monochrome (built-in)', timeout=1)
|
||||||
|
|
||||||
|
# Previous theme
|
||||||
|
page.controller.trigger(curses.KEY_F2)
|
||||||
|
assert page.term.theme.name == 'default'
|
||||||
|
terminal.show_notification.assert_called_with(
|
||||||
|
'default (built-in)', timeout=1)
|
||||||
|
|
||||||
|
# Previous - will loop to one of the 256 color themes
|
||||||
|
page.controller.trigger(curses.KEY_F2)
|
||||||
|
assert page.term.theme.source == 'installed'
|
||||||
|
|
||||||
|
# Reset
|
||||||
|
page.term.set_theme()
|
||||||
|
|
||||||
|
# Will skip over any installed themes that aren't supported
|
||||||
|
curses.has_colors.return_value = False
|
||||||
|
page.controller.trigger(curses.KEY_F2)
|
||||||
|
assert page.term.theme.required_colors == 0
|
||||||
|
|
||||||
|
|||||||
@@ -17,53 +17,98 @@ except ImportError:
|
|||||||
|
|
||||||
|
|
||||||
INVALID_ELEMENTS = OrderedDict([
|
INVALID_ELEMENTS = OrderedDict([
|
||||||
('too_few_items', 'upvote = blue\n'),
|
('too_few_items', 'Upvote = blue\n'),
|
||||||
('too_many_items', 'upvote = blue blue bold underline\n'),
|
('too_many_items', 'Upvote = blue blue bold underline\n'),
|
||||||
('invalid_fg', 'upvote = invalid blue\n'),
|
('invalid_fg', 'Upvote = invalid blue\n'),
|
||||||
('invalid_bg', 'upvote = blue invalid\n'),
|
('invalid_bg', 'Upvote = blue invalid\n'),
|
||||||
('invalid_attr', 'upvote = blue blue bold+invalid\n'),
|
('invalid_attr', 'Upvote = blue blue bold+invalid\n'),
|
||||||
('invalid_hex', 'upvote = #fffff blue\n'),
|
('invalid_hex', 'Upvote = #fffff blue\n'),
|
||||||
('invalid_hex2', 'upvote = #gggggg blue\n'),
|
('invalid_hex2', 'Upvote = #gggggg blue\n'),
|
||||||
('out_of_range', 'upvote = ansi_256 blue\n')
|
('out_of_range', 'Upvote = ansi_256 blue\n')
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
def test_theme_construct():
|
def test_theme_invalid_source():
|
||||||
|
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
Theme(name='default', source=None)
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
Theme(name=None, source='installed')
|
||||||
|
|
||||||
|
|
||||||
|
def test_theme_default_construct():
|
||||||
|
|
||||||
theme = Theme()
|
theme = Theme()
|
||||||
assert theme.name == 'default'
|
assert theme.name == 'default'
|
||||||
assert theme.elements == Theme.DEFAULT_THEME
|
assert theme.source == 'built-in'
|
||||||
assert theme.required_colors == 8
|
assert theme.required_colors == 8
|
||||||
assert theme.required_color_pairs == 6
|
assert theme.required_color_pairs == 6
|
||||||
|
for fg, bg, attr in theme.elements.values():
|
||||||
|
assert isinstance(fg, int)
|
||||||
|
assert isinstance(bg, int)
|
||||||
|
assert isinstance(attr, int)
|
||||||
|
|
||||||
theme = Theme(name='monochrome', monochrome=True)
|
|
||||||
|
def test_theme_monochrome_construct():
|
||||||
|
|
||||||
|
theme = Theme(use_color=False)
|
||||||
assert theme.name == 'monochrome'
|
assert theme.name == 'monochrome'
|
||||||
assert theme.monochrome is True
|
assert theme.source == 'built-in'
|
||||||
assert theme.required_colors == 0
|
assert theme.required_colors == 0
|
||||||
assert theme.required_color_pairs == 0
|
assert theme.required_color_pairs == 0
|
||||||
|
|
||||||
elements = {'bar_level_1': (100, 101, curses.A_UNDERLINE)}
|
|
||||||
|
def test_theme_256_construct():
|
||||||
|
|
||||||
|
elements = {'CursorBar1': (None, 101, curses.A_UNDERLINE)}
|
||||||
theme = Theme(elements=elements)
|
theme = Theme(elements=elements)
|
||||||
assert theme.elements['bar_level_1'] == elements['bar_level_1']
|
assert theme.elements['CursorBar1'] == (-1, 101, curses.A_UNDERLINE)
|
||||||
assert theme.required_colors == 256
|
assert theme.required_colors == 256
|
||||||
|
|
||||||
|
|
||||||
|
def test_theme_element_selected_attributes():
|
||||||
|
|
||||||
|
elements = {
|
||||||
|
'Normal': (1, 2, curses.A_REVERSE),
|
||||||
|
'Selected': (2, 3, None),
|
||||||
|
'TitleBar': (4, None, curses.A_BOLD),
|
||||||
|
'Link': (5, None, None)}
|
||||||
|
|
||||||
|
theme = Theme(elements=elements)
|
||||||
|
assert theme.elements['Normal'] == (1, 2, curses.A_REVERSE)
|
||||||
|
|
||||||
|
# All of the normal elements fallback to the attributes of "Normal"
|
||||||
|
assert theme.elements['Selected'] == (2, 3, curses.A_REVERSE)
|
||||||
|
assert theme.elements['TitleBar'] == (4, 2, curses.A_BOLD)
|
||||||
|
assert theme.elements['Link'] == (5, 2, curses.A_REVERSE)
|
||||||
|
|
||||||
|
# The @Selected mode will overwrite any other attributes with
|
||||||
|
# the ones defined in "Selected". Because "Selected" defines
|
||||||
|
# a foreground and a background color, they will override the
|
||||||
|
# ones that "Link" had defined.
|
||||||
|
assert theme.elements['@Link'] == (2, 3, curses.A_REVERSE)
|
||||||
|
assert '@Normal' not in theme.elements
|
||||||
|
assert '@Selected' not in theme.elements
|
||||||
|
assert '@TitleBar' not in theme.elements
|
||||||
|
|
||||||
|
|
||||||
def test_theme_default_cfg_matches_builtin():
|
def test_theme_default_cfg_matches_builtin():
|
||||||
|
|
||||||
filename = os.path.join(DEFAULT_THEMES, 'default.cfg')
|
filename = os.path.join(DEFAULT_THEMES, 'default.cfg.example')
|
||||||
default_theme = Theme.from_file(filename)
|
default_theme = Theme.from_file(filename, 'built-in')
|
||||||
|
|
||||||
# The default theme file should match the hardcoded values
|
# The default theme file should match the hardcoded values
|
||||||
assert default_theme.elements == Theme().elements
|
assert default_theme.elements == Theme().elements
|
||||||
|
|
||||||
|
# Make sure that the elements passed into the constructor exactly match
|
||||||
|
# up with the hardcoded elements
|
||||||
class MockTheme(Theme):
|
class MockTheme(Theme):
|
||||||
def __init__(self, name=None, elements=None, monochrome=False):
|
def __init__(self, name=None, source=None, elements=None):
|
||||||
assert name == 'default'
|
assert name == 'default.cfg'
|
||||||
assert elements == Theme.DEFAULT_THEME
|
assert source == 'preset'
|
||||||
assert monochrome is False
|
assert elements == Theme.DEFAULT_ELEMENTS
|
||||||
|
|
||||||
# Make sure that the config file elements exactly match the defaults
|
MockTheme.from_file(filename, 'preset')
|
||||||
MockTheme.from_file(filename)
|
|
||||||
|
|
||||||
|
|
||||||
args, ids = INVALID_ELEMENTS.values(), list(INVALID_ELEMENTS)
|
args, ids = INVALID_ELEMENTS.values(), list(INVALID_ELEMENTS)
|
||||||
@@ -75,31 +120,31 @@ def test_theme_from_file_invalid(line):
|
|||||||
fp.write(line)
|
fp.write(line)
|
||||||
fp.flush()
|
fp.flush()
|
||||||
with pytest.raises(ConfigError):
|
with pytest.raises(ConfigError):
|
||||||
Theme.from_file(fp.name)
|
Theme.from_file(fp.name, 'installed')
|
||||||
|
|
||||||
|
|
||||||
def test_theme_from_file():
|
def test_theme_from_file():
|
||||||
|
|
||||||
with NamedTemporaryFile(mode='w+') as fp:
|
with NamedTemporaryFile(mode='w+') as fp:
|
||||||
|
|
||||||
# Needs a [theme] section
|
|
||||||
with pytest.raises(ConfigError):
|
with pytest.raises(ConfigError):
|
||||||
Theme.from_file(fp.name)
|
Theme.from_file(fp.name, 'installed')
|
||||||
|
|
||||||
fp.write('[theme]\n')
|
fp.write('[theme]\n')
|
||||||
fp.write('unknown = neutral neutral\n')
|
fp.write('Unknown = - -\n')
|
||||||
fp.write('upvote = default red\n')
|
fp.write('Upvote = - red\n')
|
||||||
fp.write('downvote = ansi_0 ansi_255 bold\n')
|
fp.write('Downvote = ansi_255 default bold\n')
|
||||||
fp.write('neutral_vote = #000000 #ffffff bold+reverse\n')
|
fp.write('NeutralVote = #000000 #ffffff bold+reverse\n')
|
||||||
fp.flush()
|
fp.flush()
|
||||||
|
|
||||||
theme = Theme.from_file(fp.name)
|
theme = Theme.from_file(fp.name, 'installed')
|
||||||
assert 'unknown' not in theme.elements
|
assert theme.source == 'installed'
|
||||||
assert theme.elements['upvote'] == (
|
assert 'Unknown' not in theme.elements
|
||||||
|
assert theme.elements['Upvote'] == (
|
||||||
-1, curses.COLOR_RED, curses.A_NORMAL)
|
-1, curses.COLOR_RED, curses.A_NORMAL)
|
||||||
assert theme.elements['downvote'] == (
|
assert theme.elements['Downvote'] == (
|
||||||
0, 255, curses.A_BOLD)
|
255, -1, curses.A_BOLD)
|
||||||
assert theme.elements['neutral_vote'] == (
|
assert theme.elements['NeutralVote'] == (
|
||||||
16, 231, curses.A_BOLD | curses.A_REVERSE)
|
16, 231, curses.A_BOLD | curses.A_REVERSE)
|
||||||
|
|
||||||
|
|
||||||
@@ -110,18 +155,20 @@ def test_theme_from_name():
|
|||||||
theme_name = filename[:-4]
|
theme_name = filename[:-4]
|
||||||
|
|
||||||
fp.write('[theme]\n')
|
fp.write('[theme]\n')
|
||||||
fp.write('upvote = default default\n')
|
fp.write('Upvote = default default\n')
|
||||||
fp.flush()
|
fp.flush()
|
||||||
|
|
||||||
# Full file path
|
# Full file path
|
||||||
theme = Theme.from_name(fp.name, path=path)
|
theme = Theme.from_name(fp.name, path=path)
|
||||||
assert theme.name == theme_name
|
assert theme.name == theme_name
|
||||||
assert theme.elements['upvote'] == (-1, -1, curses.A_NORMAL)
|
assert theme.source == 'custom'
|
||||||
|
assert theme.elements['Upvote'] == (-1, -1, curses.A_NORMAL)
|
||||||
|
|
||||||
# Relative to the directory
|
# Relative to the directory
|
||||||
theme = Theme.from_name(theme_name, path=path)
|
theme = Theme.from_name(theme_name, path=path)
|
||||||
assert theme.name == theme_name
|
assert theme.name == theme_name
|
||||||
assert theme.elements['upvote'] == (-1, -1, curses.A_NORMAL)
|
assert theme.source == 'installed'
|
||||||
|
assert theme.elements['Upvote'] == (-1, -1, curses.A_NORMAL)
|
||||||
|
|
||||||
# Invalid theme name
|
# Invalid theme name
|
||||||
with pytest.raises(ConfigError, path=path):
|
with pytest.raises(ConfigError, path=path):
|
||||||
@@ -131,28 +178,27 @@ def test_theme_from_name():
|
|||||||
def test_theme_initialize_attributes(stdscr):
|
def test_theme_initialize_attributes(stdscr):
|
||||||
|
|
||||||
theme = Theme()
|
theme = Theme()
|
||||||
|
|
||||||
# Can't access elements before initializing curses
|
|
||||||
with pytest.raises(RuntimeError):
|
with pytest.raises(RuntimeError):
|
||||||
theme.get('upvote')
|
theme.get('Upvote')
|
||||||
|
|
||||||
theme.bind_curses()
|
theme.bind_curses()
|
||||||
|
|
||||||
# Our pre-computed required color pairs should have been correct
|
|
||||||
assert len(theme._color_pair_map) == theme.required_color_pairs
|
assert len(theme._color_pair_map) == theme.required_color_pairs
|
||||||
|
for element in Theme.DEFAULT_ELEMENTS:
|
||||||
for element in Theme.DEFAULT_THEME:
|
|
||||||
assert isinstance(theme.get(element), int)
|
assert isinstance(theme.get(element), int)
|
||||||
|
|
||||||
|
theme = Theme(use_color=False)
|
||||||
|
theme.bind_curses()
|
||||||
|
|
||||||
|
|
||||||
def test_theme_initialize_attributes_monochrome(stdscr):
|
def test_theme_initialize_attributes_monochrome(stdscr):
|
||||||
|
|
||||||
theme = Theme(monochrome=True)
|
theme = Theme(use_color=False)
|
||||||
theme.bind_curses()
|
theme.bind_curses()
|
||||||
|
theme.get('Upvote')
|
||||||
|
|
||||||
# Avoid making these curses calls if colors aren't initialized
|
# Avoid making these curses calls if colors aren't initialized
|
||||||
curses.init_pair.assert_not_called()
|
assert not curses.init_pair.called
|
||||||
curses.color_pair.assert_not_called()
|
assert not curses.color_pair.called
|
||||||
|
|
||||||
|
|
||||||
def test_theme_list_themes():
|
def test_theme_list_themes():
|
||||||
@@ -165,12 +211,14 @@ def test_theme_list_themes():
|
|||||||
fp.flush()
|
fp.flush()
|
||||||
|
|
||||||
Theme.print_themes(path)
|
Theme.print_themes(path)
|
||||||
themes = Theme.list_themes(path)
|
themes, errors = Theme.list_themes(path)
|
||||||
assert themes['custom'][theme_name].name == theme_name
|
assert not errors
|
||||||
assert themes['default']['monochrome'].name == 'monochrome'
|
|
||||||
|
|
||||||
# This also checks that all of the default themes are valid
|
theme_strings = [t.display_string for t in themes]
|
||||||
assert not themes['invalid']
|
assert theme_name + ' (installed)' in theme_strings
|
||||||
|
assert 'default (built-in)' in theme_strings
|
||||||
|
assert 'monochrome (built-in)' in theme_strings
|
||||||
|
assert 'molokai (preset)' in theme_strings
|
||||||
|
|
||||||
|
|
||||||
def test_theme_list_themes_invalid():
|
def test_theme_list_themes_invalid():
|
||||||
@@ -180,10 +228,24 @@ def test_theme_list_themes_invalid():
|
|||||||
theme_name = filename[:-4]
|
theme_name = filename[:-4]
|
||||||
|
|
||||||
fp.write('[theme]\n')
|
fp.write('[theme]\n')
|
||||||
fp.write('upvote = invalid value\n')
|
fp.write('Upvote = invalid value\n')
|
||||||
fp.flush()
|
fp.flush()
|
||||||
|
|
||||||
Theme.print_themes(path)
|
Theme.print_themes(path)
|
||||||
themes = Theme.list_themes(path)
|
themes, errors = Theme.list_themes(path)
|
||||||
assert theme_name in themes['invalid']
|
assert ('installed', theme_name) in errors
|
||||||
assert not themes['custom']
|
|
||||||
|
|
||||||
|
def test_theme_presets_define_all_elements():
|
||||||
|
|
||||||
|
# The themes in the preset themes/ folder should have all of the valid
|
||||||
|
# elements defined in their configuration.
|
||||||
|
class MockTheme(Theme):
|
||||||
|
|
||||||
|
def __init__(self, name=None, source=None, elements=None, use_color=True):
|
||||||
|
if source == 'preset':
|
||||||
|
assert elements.keys() == Theme.DEFAULT_ELEMENTS.keys()
|
||||||
|
super(MockTheme, self).__init__(name, source, elements, use_color)
|
||||||
|
|
||||||
|
themes, errors = MockTheme.list_themes()
|
||||||
|
assert sum(theme.source == 'preset' for theme in themes) >= 4
|
||||||
|
|||||||
Reference in New Issue
Block a user