12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- from collections import Sequence
- from pytest_clarity.output import deleted_text, hint_body_text, hint_text, inserted_text
- from pytest_clarity.util import (
- direct_type_mismatch,
- has_differing_len,
- pformat_no_color,
- possibly_missing_eq,
- )
- def hints_for(op, lhs, rhs):
- hints = [""] # immediate newline
- if op == "==":
- if direct_type_mismatch(lhs, rhs):
- lhs_type, rhs_type = inserted_text(type(lhs)), deleted_text(type(rhs))
- hints += [
- hint_text("left and right are different types:"),
- hint_body_text(
- " type(left) is {}, type(right) is {}".format(lhs_type, rhs_type)
- ),
- ]
- if has_differing_len(lhs, rhs):
- lhs_len, rhs_len = inserted_text(len(lhs)), deleted_text(len(rhs))
- hints += [
- hint_text("left and right have different lengths:"),
- hint_body_text(
- " len(left) == {}, len(right) == {}".format(lhs_len, rhs_len)
- ),
- ]
- if possibly_missing_eq(lhs, rhs):
- hints += [
- hint_text("left and right are equal in data and in type: "),
- hint_body_text(" perhaps you forgot to implement __eq__ and __ne__?"),
- ]
- both_sequences = isinstance(lhs, Sequence) and isinstance(rhs, Sequence)
- both_dicts = isinstance(lhs, dict) and isinstance(rhs, dict)
- if both_dicts:
- lhs, rhs = lhs.items(), rhs.items()
- if both_sequences or both_dicts:
- num_extras, lines = find_extras(lhs, rhs, inserted_text, "+")
- hints += [
- hint_text("{} items in left, but not right:".format(num_extras))
- ] + lines
- num_extras, lines = find_extras(rhs, lhs, deleted_text, "-")
- hints += [
- hint_text("{} items in right, but not left:".format(num_extras))
- ] + lines
- return hints
- def find_extras(lhs, rhs, text_fn, item_marker):
- lhs_extras_lines = []
- num_extras = 0
- for item in lhs:
- if item not in rhs:
- num_extras += 1
- for i, line in enumerate(pformat_no_color(item, 80).splitlines()):
- gutter_content = item_marker if i == 0 else " "
- coloured_line = "{gutter_content}{spacing}{line}".format(
- gutter_content=text_fn(gutter_content),
- spacing=" ",
- line=text_fn(line),
- )
- lhs_extras_lines.append(coloured_line)
- return num_extras, lhs_extras_lines
|