def test_terminal_check_theme(terminal): monochrome = Theme(use_color=False) default = Theme() color256 = Theme.from_name('molokai') curses.has_colors.return_value = False assert terminal.check_theme(monochrome) assert not terminal.check_theme(default) assert not terminal.check_theme(color256) curses.has_colors.return_value = True curses.COLORS = 0 assert terminal.check_theme(monochrome) assert not terminal.check_theme(default) assert not terminal.check_theme(color256) curses.COLORS = 8 assert terminal.check_theme(monochrome) assert terminal.check_theme(default) assert not terminal.check_theme(color256) curses.COLORS = 256 assert terminal.check_theme(monochrome) assert terminal.check_theme(default) assert terminal.check_theme(color256) curses.COLOR_PAIRS = 8 assert terminal.check_theme(monochrome) assert terminal.check_theme(default) assert not terminal.check_theme(color256)
def test_terminal_set_theme(terminal, stdscr): # Default with color enabled stdscr.reset_mock() terminal.set_theme() assert terminal.theme.use_color assert terminal.theme.display_string == 'default (built-in)' stdscr.bkgd.assert_called_once_with(' ', 0) # When the user passes in the --monochrome flag terminal.theme = None terminal.set_theme(Theme(use_color=False)) assert not terminal.theme.use_color assert terminal.theme.display_string == 'monochrome (built-in)' # When the terminal doesn't support colors curses.COLORS = 0 terminal.theme = None terminal.set_theme() assert terminal.theme.display_string == 'monochrome (built-in)' # When the terminal doesn't support 256 colors so it falls back to the # built-in default theme curses.COLORS = 8 terminal.theme = None terminal.set_theme(Theme.from_name('molokai')) assert terminal.theme.display_string == 'default (built-in)' # When the terminal does support the 256 color theme curses.COLORS = 256 terminal.theme = None terminal.set_theme(Theme.from_name('molokai')) assert terminal.theme.display_string == 'molokai (preset)'
def test_theme_from_name(): with _ephemeral_directory() as dirname: with NamedTemporaryFile(mode='w+', suffix='.cfg', dir=dirname) as fp: path, filename = os.path.split(fp.name) theme_name = filename[:-4] fp.write('[theme]\n') fp.write('Upvote = default default\n') fp.flush() # Full file path theme = Theme.from_name(fp.name, path=path) assert theme.name == theme_name assert theme.source == 'custom' assert theme.elements['Upvote'] == (-1, -1, curses.A_NORMAL) # Relative to the directory theme = Theme.from_name(theme_name, path=path) assert theme.name == theme_name assert theme.source == 'installed' assert theme.elements['Upvote'] == (-1, -1, curses.A_NORMAL) # Invalid theme name with pytest.raises(ConfigError): theme.from_name('invalid_theme_name', path=path)
def test_theme_from_file_invalid(line): with _ephemeral_directory() as dirname: with NamedTemporaryFile(mode='w+', dir=dirname) as fp: fp.write('[theme]\n') fp.write(line) fp.flush() with pytest.raises(ConfigError): Theme.from_file(fp.name, 'installed')
def test_theme_list_themes_invalid(): with _ephemeral_directory() as dirname: with NamedTemporaryFile(mode='w+', suffix='.cfg', dir=dirname) as fp: path, filename = os.path.split(fp.name) theme_name = filename[:-4] fp.write('[theme]\n') fp.write('Upvote = invalid value\n') fp.flush() Theme.print_themes(path) themes, errors = Theme.list_themes(path) assert ('installed', theme_name) in errors
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) # I can't remember why the above rule was implemented, so I reverted it assert theme.elements['@Link'] == (5, 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_monochrome_construct(): theme = Theme(use_color=False) assert theme.name == 'monochrome' assert theme.source == 'built-in' assert theme.required_colors == 0 assert theme.required_color_pairs == 0
def test_theme_default_cfg_matches_builtin(): filename = os.path.join(Config.DEFAULT_THEMES, 'default.cfg.example') default_theme = Theme.from_file(filename, 'built-in') # The default theme file should match the hardcoded values 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): def __init__(self, name=None, source=None, elements=None): assert name == 'default.cfg' assert source == 'preset' assert elements == Theme.DEFAULT_ELEMENTS MockTheme.from_file(filename, 'preset')
def test_theme_list_themes(): with _ephemeral_directory() as dirname: with NamedTemporaryFile(mode='w+', suffix='.cfg', dir=dirname) as fp: path, filename = os.path.split(fp.name) theme_name = filename[:-4] fp.write('[theme]\n') fp.flush() Theme.print_themes(path) themes, errors = Theme.list_themes(path) assert not errors theme_strings = [t.display_string for t in themes] 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_default_construct(): theme = Theme() assert theme.name == 'default' assert theme.source == 'built-in' assert theme.required_colors == 8 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)
def test_terminal_set_theme_no_colors(terminal, stdscr): # Monochrome should be forced if the terminal doesn't support color with mock.patch('curses.has_colors') as has_colors: has_colors.return_value = False terminal.set_theme() assert not terminal.theme.use_color terminal.set_theme(Theme(use_color=True)) assert not terminal.theme.use_color
def test_theme_from_file(): with _ephemeral_directory() as dirname: with NamedTemporaryFile(mode='w+', dir=dirname) as fp: with pytest.raises(ConfigError): Theme.from_file(fp.name, 'installed') fp.write('[theme]\n') fp.write('Unknown = - -\n') fp.write('Upvote = - red\n') fp.write('Downvote = ansi_255 default bold\n') fp.write('NeutralVote = #000000 #ffffff bold+reverse\n') fp.flush() theme = Theme.from_file(fp.name, 'installed') assert theme.source == 'installed' assert 'Unknown' not in theme.elements assert theme.elements['Upvote'] == (-1, curses.COLOR_RED, curses.A_NORMAL) assert theme.elements['Downvote'] == (255, -1, curses.A_BOLD) assert theme.elements['NeutralVote'] == (16, 231, curses.A_BOLD | curses.A_REVERSE)
def test_theme_initialize_attributes_monochrome(stdscr): theme = Theme(use_color=False) theme.bind_curses() theme.get('Upvote') # Avoid making these curses calls if colors aren't initialized assert not curses.init_pair.called assert not curses.color_pair.called
def test_theme_256_construct(): elements = {'CursorBar1': (None, 101, curses.A_UNDERLINE)} theme = Theme(elements=elements) assert theme.elements['CursorBar1'] == (-1, 101, curses.A_UNDERLINE) assert theme.required_colors == 256
def test_theme_initialize_attributes(stdscr): theme = Theme() with pytest.raises(RuntimeError): theme.get('Upvote') theme.bind_curses() assert len(theme._color_pair_map) == theme.required_color_pairs for element in Theme.DEFAULT_ELEMENTS: assert isinstance(theme.get(element), int) theme = Theme(use_color=False) theme.bind_curses()
def main(): locale.setlocale(locale.LC_ALL, '') if len(sys.argv) > 1: theme = Theme.from_name(sys.argv[1]) else: theme = Theme() vcr = initialize_vcr() with vcr.use_cassette('demo_theme.yaml') as cassette, \ curses_session() as stdscr: config = Config() if vcr.record_mode == 'once': config.load_refresh_token() else: config.refresh_token = 'mock_refresh_token' reddit = praw.Reddit(user_agent='RTV Theme Demo', decode_html_entities=False, disable_update_check=True) reddit.config.api_request_delay = 0 config.history.add('https://api.reddit.com/comments/6llvsl/_/djutc3s') config.history.add('http://i.imgur.com/Z9iGKWv.gifv') config.history.add( 'https://www.reddit.com/r/Python/comments/6302cj/rpython_official_job_board/' ) term = Terminal(stdscr, config) term.set_theme() oauth = OAuthHelper(reddit, term, config) oauth.authorize() theme_list = ThemeList() while True: term = Terminal(stdscr, config) term.set_theme(theme) threads = draw_screen(stdscr, reddit, config, theme, oauth) try: ch = term.show_notification(theme.display_string) except KeyboardInterrupt: ch = Terminal.ESCAPE for thread, term in threads: term.pause_getch = False thread.join() if vcr.record_mode == 'once': break else: cassette.play_counts = Counter() theme_list.reload() if ch == curses.KEY_RIGHT: theme = theme_list.next(theme) elif ch == curses.KEY_LEFT: theme = theme_list.previous(theme) elif ch == Terminal.ESCAPE: break else: # Force the theme to reload theme = theme_list.next(theme) theme = theme_list.previous(theme)
def test_theme_invalid_source(): with pytest.raises(ValueError): Theme(name='default', source=None) with pytest.raises(ValueError): Theme(name=None, source='installed')