diff --git a/validations_libs/cli/colors.py b/validations_libs/cli/colors.py new file mode 100644 index 00000000..8247f797 --- /dev/null +++ b/validations_libs/cli/colors.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python + +# Copyright 2021 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +# PrettyTable Colors: +RED = "\033[1;31m" +GREEN = "\033[0;32m" +CYAN = "\033[36m" +RESET = "\033[0;0m" +YELLOW = "\033[0;33m" + +colors = { + 'starting': CYAN, + 'running': CYAN, + 'PASSED': GREEN, + 'UNKNOWN': YELLOW, + 'UNREACHABLE': YELLOW, + 'ERROR': RED, + 'FAILED': RED +} + + +def color_output(output, status=None): + """Apply color to output based on colors dict entries. + Unknown status or no status at all results in aplication + of YELLOW color. + + .. note:: + + Coloring itself is performed using format method of the + string class. This function is merely a wrapper around it, + and around ANSI escape sequences as defined by ECMA-48. + + """ + if status: + color = colors.get(status, YELLOW) + else: + color = colors['UNKNOWN'] + + output = '{}{}{}'.format( + color, + output, + RESET) + + return output diff --git a/validations_libs/cli/common.py b/validations_libs/cli/common.py index 703d034a..1d0aa4bd 100644 --- a/validations_libs/cli/common.py +++ b/validations_libs/cli/common.py @@ -19,16 +19,10 @@ from prettytable import PrettyTable from validations_libs import constants from validations_libs import utils as v_utils +from validations_libs.cli import colors GROUP_FILE = constants.VALIDATION_GROUPS_INFO -# PrettyTable Colors: -RED = "\033[1;31m" -GREEN = "\033[0;32m" -CYAN = "\033[36m" -RESET = "\033[0;0m" -YELLOW = "\033[0;33m" - def print_dict(data): """Print table from python dict with PrettyTable""" @@ -49,16 +43,12 @@ def print_dict(data): # if ValueError, then host is in unknown state: _name = host _status = 'UNKNOWN' - color = (GREEN if _status == 'PASSED' else - (YELLOW if _status == 'UNREACHABLE' else RED)) - _name = '{}{}{}'.format(color, _name, RESET) + _name = colors.color_output(_name, status=_status) hosts.append(_name) row['Status_by_Host'] = ', '.join(hosts) if row.get('Status'): status = row.get('Status') - color = (CYAN if status in ['starting', 'running'] - else GREEN if status == 'PASSED' else RED) - row['Status'] = '{}{}{}'.format(color, status, RESET) + row['Status'] = colors.color_output(status, status=status) table.add_row(row.values()) print(table) diff --git a/validations_libs/tests/cli/test_colors.py b/validations_libs/tests/cli/test_colors.py new file mode 100644 index 00000000..91496a24 --- /dev/null +++ b/validations_libs/tests/cli/test_colors.py @@ -0,0 +1,68 @@ +# Copyright 2021 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +try: + from unittest import mock +except ImportError: + import mock +from unittest import TestCase + +from validations_libs.cli import colors + + +class TestColors(TestCase): + def setUp(self): + RED = "\033[1;31m" + GREEN = "\033[0;32m" + CYAN = "\033[36m" + RESET = "\033[0;0m" + YELLOW = "\033[0;33m" + + self.status_color = { + 'starting': CYAN, + 'running': CYAN, + 'PASSED': GREEN, + 'UNKNOWN': YELLOW, + 'UNREACHABLE': YELLOW, + 'ERROR': RED, + 'FAILED': RED + } + + super(TestColors, self).setUp() + + def test_format_known_status(self): + """Tests formatting, meaning coloring, for every + status recognized by VF. + """ + + for status in self.status_color: + color = self.status_color[status] + colored_output = colors.color_output("fizz", status=status) + #Checking reset color + self.assertEquals(colored_output[-6:], '\033[0;0m') + #Checking output color + self.assertEquals(colored_output[:len(color)], color) + #Checking output string + self.assertEquals(colored_output[len(color):][:4], "fizz") + + def test_format_unknown_status(self): + + color = self.status_color['UNKNOWN'] + colored_output = colors.color_output("buzz") + #Checking reset color + self.assertEquals(colored_output[-6:], '\033[0;0m') + #Checking output color + self.assertEquals(colored_output[:len(color)], color) + #Checking output string + self.assertEquals(colored_output[len(color):][:4], "buzz")