def get_row_data( self, row_comparison, columns, include_columns=None, exclude_columns=None, display_index=False, ): """Return single row data to be printed""" result = [] for idx, column in enumerate(columns): actual = row_comparison.data[idx] other, matched = row_comparison.get_comparison_value(column, idx) value_limit = int((constants.CELL_STRING_LENGTH - 4) / 2) other, actual = format_cell_data(data=[other, actual], limit=value_limit) include_columns = include_columns or columns exclude_columns = exclude_columns or [] if (column not in include_columns) or (column in exclude_columns): result.append("{} .. {}".format(actual, other)) elif matched: result.append(Color.green("{} == {}".format(actual, other))) else: result.append(Color.red("{} != {}".format(actual, other))) if display_index: result = [row_comparison.idx] + result return result
def get_assertion_details(self, entry): raised_exc = entry.raised_exception expected_exceptions = ", ".join( [exc.__name__ for exc in entry.expected_exceptions]) label = ("not instance of" if isinstance( entry, assertions.ExceptionNotRaised) else "instance of") msg = "{} {} {}".format(type(raised_exc), label, expected_exceptions) if entry.func: msg += "{} Function: {}".format( os.linesep, str(entry.func) if entry.passed else Color.red(str(entry.func)), ) if entry.pattern: msg += "{} Pattern: {}".format( os.linesep, entry.pattern if entry.passed else Color.red(entry.pattern), ) msg += "{} Exception message: {}".format(os.linesep, entry.raised_exception) return msg
def add_printable_dict_comparison(result, row): """Stdout representation of fix/dict match rows.""" indent, key, status, left, right = row if left or right: if not left: left = "None" if not right: right = "None" else: left = "" right = "" if status == "Passed": coloured = Color.colored(status, "green") operator = " == " elif status == "Failed": coloured = Color.colored(status, "red") operator = " != " else: coloured = "Ignore" operator = " " result.append("{} {}{} {}{}{}".format( "({})".format(coloured) if coloured else " " * len("(Passed)"), " " * 4 * indent, "Key({}),".format(key) if key else "", "{} <{}>".format(left[1], left[0]) if isinstance(left, tuple) else left, operator if left and right else " ", "{} <{}>".format(right[1], right[0]) if isinstance(right, tuple) else right, ))
def get_assertion_details(self, entry): """ Render the message if there is any, then render XMLTagComparison items. """ result = [] result.append("xpath: {}".format(entry.xpath)) if entry.namespaces: result.append("Namespaces: {}".format(entry.namespaces)) if entry.message: result.append( entry.message if entry.passed else Color.red(entry.message)) if entry.data: result.append("Tags:") for tag_comp in entry.data: template = " {actual} {operator} {expected}" common = dict(actual=tag_comp.tag, expected=tag_comp.comparison_value) if tag_comp.passed: result.append(template.format(operator="==", **common)) else: result.append( Color.red(template.format(operator="!=", **common))) return os.linesep.join(result)
def add_printable_dict_comparison(result, row): """Stdout representation of fix/dict match rows.""" indent, key, status, left, right = row if left or right: if not left: left = 'None' if not right: right = 'None' else: left = '' right = '' if status == 'Passed': coloured = Color.colored(status, 'green') operator = ' == ' elif status == 'Failed': coloured = Color.colored(status, 'red') operator = ' != ' else: coloured = 'Ignore' operator = ' ' result.append('{} {}{} {}{}{}'.format( '({})'.format(coloured) if coloured else ' ' * len('(Passed)'), ' ' * 4 * indent, 'Key({}),'.format(key) if key else '', '{} <{}>'.format( left[1], left[0]) if isinstance(left, tuple) else left, operator if left and right else ' ', '{} <{}>'.format( right[1], right[0]) if isinstance(right, tuple) else right))
def log_test_status(self, name, passed, indent=0, level=TEST_INFO): """Shortcut to log a pass/fail status for a test.""" pass_label = Color.green('Pass') if passed else Color.red('Fail') indent_str = indent * ' ' msg = self._TEST_STATUS_FORMAT self._custom_log( level, msg, {'name': name, 'pass_label': pass_label, 'indent': indent_str})
def _print_test_result(self, task_result): if not isinstance(task_result.result, RunnableResult) or\ not hasattr(task_result.result, 'report'): return # Currently prints report top level result and not details. name = task_result.result.report.name if task_result.result.report.passed is True: self.logger.test_info('{} -> {}'.format(name, Color.green('Pass'))) else: self.logger.test_info('{} -> {}'.format(name, Color.red('Fail')))
def _print_test_result(self, task_result): if (not isinstance(task_result.result, entity.RunnableResult)) or ( not hasattr(task_result.result, "report")): return # Currently prints report top level result and not details. name = task_result.result.report.name if task_result.result.report.passed is True: self.logger.test_info("{} -> {}".format(name, Color.green("Pass"))) else: self.logger.test_info("{} -> {}".format(name, Color.red("Fail")))
def get_assertion_details(self, entry): """ Return highlighted patterns within the string, if there is a match. """ string = entry.string pattern = "Pattern: `{}`{}".format(entry.pattern, os.linesep) if entry.match_indexes: curr_idx = 0 parts = [] for begin, end in entry.match_indexes: if begin > curr_idx: parts.append(string[curr_idx:begin]) parts.append( Color.colored(string[begin:end], self.highlight_color)) curr_idx = end if curr_idx < len(string): parts.append(string[curr_idx:]) return "{}{}".format(pattern, "".join(parts)) else: return "{}{}".format(pattern, string)
def get_assertion_details(self, entry): """ `RegexMatchLine` returns line indexes along with begin/end character indexes per matched line. """ pattern = "Pattern: `{}`{}".format(entry.pattern, os.linesep) if entry.match_indexes: parts = [] match_map = { line_no: (begin, end) for line_no, begin, end in entry.match_indexes } for idx, line in enumerate(entry.string.splitlines()): if idx in match_map: begin, end = match_map[idx] parts.append( line[:begin] + Color.green(line[begin:end]) + line[end:] ) else: parts.append(line) return "{}{}".format(pattern, os.linesep.join(parts)) return "{}{}".format(pattern, entry.string)
def get_assertion_details(self, entry): """Return row by row match results in tabular format""" if entry.message: result = ( Color.red(entry.message) if not entry.passed else entry.message ) else: result = "" row_data = [ self.get_row_data( row_comparison, entry.display_columns, display_index=entry.report_fails_only, ) for row_comparison in entry.data ] columns = ( ["row"] + list(entry.display_columns) if entry.report_fails_only else entry.display_columns ) ascii_table = ( AsciiTable([columns] + row_data).table if row_data else "" ) return "{}{}{}".format( result, os.linesep if result and ascii_table else "", ascii_table )
def get_assertion_details(self, entry): """ Use a format like `1 == 2`, highlighting failing comparisons in red. """ msg = "{} {} {}".format(entry.first, entry.label, entry.second) return msg if entry else Color.red(msg)
def get_assertion_details(self, entry): """Return `has_keys` & `absent_keys` context""" msg = "" if entry.has_keys: msg += "Existence check: {}".format(entry.has_keys) if entry.has_keys_diff: msg += "{}\tMissing keys: {}".format( os.linesep, Color.red(list(entry.has_keys_diff))) if entry.absent_keys: if msg: msg += os.linesep msg += "Absence check: {}".format(entry.absent_keys) if entry.absent_keys_diff: msg += "{}\tKey should be absent: {}".format( os.linesep, Color.red(list(entry.absent_keys_diff))) return msg
def get_assertion_details(self, entry): """ Use a format like `99 ~= 100 (with rel_tol=0.1, abs_tol=0.0)`, highlighting failing comparisons in red. """ msg = '{} {} {} (rel_tol: {}, abs_tol: {})'.format( entry.first, entry.label, entry.second, entry.rel_tol, entry.abs_tol) return msg if entry else Color.red(msg)
def get_assertion_details(self, entry): """Return fix and dict match_all result representations""" result = [] for match in entry.matches: comparison = match["comparison"] description = match["description"] passed = match["passed"] if passed is True: coloured = Color.colored("Passed", "green") else: coloured = Color.colored("Failed", "red") result.append("({}) {}".format(coloured, description)) for row in comparison: add_printable_dict_comparison(result, row) if result: result.append("") return str(os.linesep.join(result))
def get_assertion_details(self, entry): """Return fix and dict match_all result representations""" result = [] for match in entry.matches: comparison = match['comparison'] description = match['description'] passed = match['passed'] if passed is True: coloured = Color.colored('Passed', 'green') else: coloured = Color.colored('Failed', 'red') result.append('({}) {}'.format(coloured, description)) for row in comparison: add_printable_dict_comparison(result, row) if result: result.append('') return str(os.linesep.join(result))
def get_assertion_details(self, entry): """Render `condition` attribute as well, if it exists""" msg = super(RegexFindIterRenderer, self).get_assertion_details(entry) if entry.condition_match is not None: msg += '{}Condition: {}'.format( os.linesep, Color.colored( entry.condition, color='green' if entry.condition_match else 'red')) return msg
def get_assertion_details(self, entry): result = [] if not entry.passed: result.append(Color.red("*** a.text ***" + os.linesep)) for line in self._get_truncated_lines( entry.first, n=constants.NUM_DISPLAYED_ROWS ): result.append(" {}".format(line)) if not (result[-1].endswith(os.linesep) or result[-1][-1] == "\n"): result[-1] += os.linesep result.append(Color.red("*** b.text ***" + os.linesep)) for line in self._get_truncated_lines( entry.second, n=constants.NUM_DISPLAYED_ROWS ): result.append(" {}".format(line)) if not (result[-1].endswith(os.linesep) or result[-1][-1] == "\n"): result[-1] += os.linesep options = "" options += "-b " if entry.ignore_space_change else "" options += "-w " if entry.ignore_whitespaces else "" options += "-B " if entry.ignore_blank_lines else "" options += "-u " if entry.unified else "" options += "-c " if entry.context and not entry.unified else "" options = " ( " + options + ")" if options else "" if entry.passed: result.append("No difference found{}".format(options)) else: result.append( Color.red("Differences{}:{}".format(options, os.linesep)) ) for line in self._get_truncated_lines( entry.delta, n=constants.NUM_DISPLAYED_ROWS * 5 ): result.append(" {}".format(line)) result[-1] = re.sub(r"[\r\n]+$", "", result[-1]) return "".join(result)
def log_test_status(self, name, status, indent=0, level=TEST_INFO): """Shortcut to log a pass/fail status for a test.""" if Status.STATUS_CATEGORY[status] == Status.PASSED: pass_label = Color.green(status.title()) elif Status.STATUS_CATEGORY[status] in [Status.FAILED, Status.ERROR]: pass_label = Color.red(status.title()) elif Status.STATUS_CATEGORY[status] == Status.UNSTABLE: pass_label = Color.yellow(status.title()) else: # unknown pass_label = status indent_str = indent * " " msg = self._TEST_STATUS_FORMAT self._custom_log( level, msg, { "name": name, "pass_label": pass_label, "indent": indent_str }, )
def get_assertion_details(self, entry): result = [] if not entry.passed: result.append(Color.red('*** a.text ***' + os.linesep)) for line in self._get_truncated_lines( entry.first, n=constants.NUM_DISPLAYED_ROWS): result.append(' {}'.format(line)) if not (result[-1].endswith(os.linesep) or result[-1][-1] == '\n'): result[-1] += os.linesep result.append(Color.red('*** b.text ***' + os.linesep)) for line in self._get_truncated_lines( entry.second, n=constants.NUM_DISPLAYED_ROWS): result.append(' {}'.format(line)) if not (result[-1].endswith(os.linesep) or result[-1][-1] == '\n'): result[-1] += os.linesep options = '' options += '-b ' if entry.ignore_space_change else '' options += '-w ' if entry.ignore_whitespaces else '' options += '-B ' if entry.ignore_blank_lines else '' options += '-u ' if entry.unified else '' options += '-c ' if entry.context and not entry.unified else '' options = ' ( ' + options + ')' if options else '' if entry.passed: result.append('No difference found{}'.format(options)) else: result.append( Color.red('Differences{}:{}'.format(options, os.linesep)) ) for line in self._get_truncated_lines( entry.delta, n=constants.NUM_DISPLAYED_ROWS*5): result.append(' {}'.format(line)) result[-1] = re.sub(r'[\r\n]+$', '', result[-1]) return ''.join(result)
def get_assertion_details(self, entry): ascii_columns = [entry.column, 'Passed'] if entry.report_fails_only: ascii_columns = ['row'] + ascii_columns table = [] for comp_obj in entry.data: ascii_row = [comp_obj.value, Color.passed(check=comp_obj.passed)] if entry.report_fails_only: ascii_row = [comp_obj.idx] + ascii_row table.append(ascii_row) return '{}{}{}'.format('Values: {}'.format(entry.values), os.linesep, AsciiTable([ascii_columns] + table).table)
def get_assertion_details(self, entry): result = [ '{} - excluded'.format(slice_comp.slice) for slice_comp in entry.data ] actual = [entry.actual[i] for i in entry.included_indices] expected = [entry.expected[i] for i in entry.included_indices] result.extend([ '{}: {}'.format(title, data if entry.passed else Color.red(data)) for title, data in (('Compared indices', list(entry.included_indices)), ('Actual', actual), ('Expected', expected)) ]) return os.linesep.join(result)
def get_assertion_details(self, entry): result = [] for slice_comp in entry.data: result.append("{}".format(slice_comp.slice if slice_comp. passed else Color.red(slice_comp.slice))) # Display mismatched indexes if slice has # a step, for easier debugging if slice_comp.mismatch_indices: result.append(" Mismatched indices: {}".format( slice_comp.mismatch_indices)) result.append(" Actual:\t{}".format(slice_comp.actual)) result.append(" Expected:\t{}".format(slice_comp.expected)) return os.linesep.join(result)
def get_assertion_details(self, entry): """Return row by row match results in tabular format""" if entry.message: message = Color.red(entry.message) \ if not entry.passed else entry.message result = '{}{}'.format(message, os.linesep) else: result = '' display_index = entry.fail_limit > 0 row_data = [ self.get_row_data(row_comparison, entry.display_columns, display_index=display_index) for row_comparison in entry.data ] columns = ['row'] + list(entry.display_columns) \ if display_index else entry.display_columns return '{}{}'.format(result, AsciiTable([columns] + row_data).table)
def get_assertion_details(self, entry): """Return row by row match results in tabular format""" if entry.message: result = Color.red(entry.message) \ if not entry.passed else entry.message else: result = '' row_data = [ self.get_row_data(row_comparison, entry.display_columns, display_index=entry.report_fails_only) for row_comparison in entry.data ] columns = ['row'] + list(entry.display_columns) \ if entry.report_fails_only else entry.display_columns ascii_table = AsciiTable([columns] + row_data).table \ if row_data else '' return '{}{}{}'.format(result, os.linesep if result and ascii_table else '', ascii_table)
def get_header_text(self, entry): """Always return text in red as it is an explicit failure.""" return Color.red(entry.description)
def get_test_status_message(name, passed): pass_label = Color.green('Pass') if passed else Color.red('Fail') return TEST_STATUS_FORMAT.format(name=name, pass_label=pass_label)
def pass_label(self, entry): return Color.green("Pass") if entry else Color.red("Fail")
def pass_label(self, entry): return Color.green('Pass') if entry else Color.red('Fail')