Skip to content

Instantly share code, notes, and snippets.

@rmerkushin
Last active April 3, 2017 11:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rmerkushin/d416da3d2e032ca0d949d4cf8266b50c to your computer and use it in GitHub Desktop.
Save rmerkushin/d416da3d2e032ca0d949d4cf8266b50c to your computer and use it in GitHub Desktop.
Function for checking equality of two tables
import math
from dateutil import parser
from colorclass import Color
from colorclass.toggles import disable_all_colors
from terminaltables import AsciiTable
from terminaltables import SingleTable
from behave.configuration import Configuration
def _highlight_row(row: list, color: str) -> list:
"""Wraps every cell in row in specific Color"""
return [Color('{{{0}}}{1}{{/{0}}}'.format(color, cell)) for cell in row]
def _mark_rows_as(mark: str, rows: list, idx_start: int) -> list:
"""Wraps every cell in rows in Color(red) with row mark"""
return [[Color('{{red}}{0} ({1}){{/red}}'.format(idx_start + idx, mark))]
+ _highlight_row(row, 'red') for idx, row in enumerate(rows)]
def _mark_cell_as_passed(expected: str) -> Color:
"""Wrap cell in Color(green)"""
return Color('{{green}}{}{{/green}}'.format(expected))
def _mark_cell_as_failed(expected: str, actual: str) -> Color:
"""Wraps cell in Color(red) with info about comparison"""
return Color('{{red}}expected: {0}{{/red}}\n{{red}}actual: {1}{{/red}}'.format(expected, actual))
def assert_tables_are_equal(expected: list, actual: list, header: list = None,
title: str = None, datetime: bool = False, dt_delta: int = 60) -> None:
"""
Checks equality of two tables (for Behave test framework)
:param expected: expected table
:param actual: actual table
:param header: header for table with comparison results
:param title: title for table with comparison results
:param datetime: if true, compares time strings by delta.
Time strings should be present in format with `$dt=<timestamp>`.
More information about possible time format can be found here: https://dateutil.readthedocs.io/en/stable/parser.html
Example: $dt=2016-12-28 12:18:43.675448
:param dt_delta: delta for time comparison (seconds)
"""
failed = False
table_data = []
missing_rows = None
surplus_rows = None
len_expected = len(expected)
len_actual = len(actual)
if len_expected > len_actual:
missing_rows = expected[len_actual:]
expected = expected[:len_actual]
elif len_actual > len_expected:
surplus_rows = actual[len_expected:]
actual = actual[:len_expected]
for row_exp, row_act in zip(expected, actual):
if row_exp == row_act:
table_data.append(_highlight_row(row_exp, 'green'))
else:
row = []
for cell_exp, cell_act in zip(row_exp, row_act):
if cell_exp == cell_act:
cell = _mark_cell_as_passed(cell_exp)
row.append(cell)
elif datetime and cell_exp.startswith('$dt='):
exp = parser.parse(cell_exp.split('=')[1])
act = parser.parse(cell_act)
delta = exp - act
if math.fabs(delta.total_seconds()) > dt_delta:
failed = True
cell = _mark_cell_as_failed(cell_exp.split('=')[1], cell_act)
row.append(cell)
else:
cell = _mark_cell_as_passed(cell_act)
row.append(cell)
else:
failed = True
cell = _mark_cell_as_failed(cell_exp, cell_act)
row.append(cell)
table_data.append(row)
table_data = [[str(idx + 1)] + row for idx, row in enumerate(table_data)]
if missing_rows:
failed = True
message = 'Actual table has missing rows:\n'
table_data += _mark_rows_as('missing', missing_rows, len(table_data) + 1)
elif surplus_rows:
failed = True
message = 'Actual table has surplus rows:\n'
table_data += _mark_rows_as('surplus', surplus_rows, len(table_data) + 1)
else:
message = 'Tables are not equals:\n'
if header:
table_data.insert(0, ['№'] + header)
if ('ttest_out', 'console') in Configuration().userdata.items():
table = SingleTable(table_data)
else:
disable_all_colors()
table = AsciiTable(table_data)
table.inner_row_border = True
table.title = title
if failed:
raise AssertionError(message + table.table)
else:
print('Tables are equals:\n{}\n'.format(table.table))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment