plugin.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import sys
  2. from pytest_clarity.diff import build_split_diff, build_unified_diff
  3. from pytest_clarity.hints import hints_for
  4. from pytest_clarity.output import Colour, deleted_text, diff_intro_text, inserted_text
  5. from pytest_clarity.util import display_op_for, pformat_no_color, utf8_replace
  6. def pytest_load_initial_conftests(args):
  7. # Force verbose logging to prevent pytest truncating output
  8. if "pytest_clarity" in sys.modules:
  9. args[:] = ["-vv"] + args
  10. def pytest_addoption(parser):
  11. parser.addoption(
  12. "--no-hints",
  13. action="store_true",
  14. default=False,
  15. help="pytest-clarity: disable hints (boolean)",
  16. )
  17. parser.addoption(
  18. "--diff-width",
  19. action="store",
  20. default="80",
  21. help="pytest-clarity: configure output width",
  22. )
  23. parser.addoption(
  24. "--diff-type",
  25. action="store",
  26. default="auto",
  27. help="pytest-clarity: default auto. one of [auto, unified, split]",
  28. )
  29. def pytest_assertrepr_compare(config, op, left, right):
  30. op = display_op_for(op)
  31. width = int(config.getoption("--diff-width"))
  32. diff_type = config.getoption("--diff-type")
  33. lhs_repr = pformat_no_color(utf8_replace(left), width)
  34. rhs_repr = pformat_no_color(utf8_replace(right), width)
  35. if diff_type == "split":
  36. output = build_full_splitdiff_output(lhs_repr, rhs_repr, op)
  37. elif diff_type == "unified":
  38. output = build_full_unidiff_output(lhs_repr, rhs_repr, op)
  39. else: # assume diff_type == "auto" so decide based on newlines
  40. if "\n" in lhs_repr and "\n" in rhs_repr:
  41. output = build_full_unidiff_output(lhs_repr, rhs_repr, op)
  42. else:
  43. output = build_full_splitdiff_output(lhs_repr, rhs_repr, op)
  44. if not config.getoption("--no-hints"):
  45. output += hints_for(op, left, right)
  46. return [utf8_replace(line) for line in output]
  47. def build_full_unidiff_output(lhs_repr, rhs_repr, op):
  48. left_key = inserted_text("L=left")
  49. right_key = deleted_text("R=right")
  50. return [
  51. "left {} right failed. ".format(op),
  52. "{}Showing unified diff ({}, {}):".format(Colour.stop, left_key, right_key),
  53. "",
  54. ] + build_unified_diff(lhs_repr, rhs_repr)
  55. def build_full_splitdiff_output(lhs_repr, rhs_repr, op):
  56. lhs_diff, rhs_diff = build_split_diff(lhs_repr, rhs_repr)
  57. output = [
  58. "left {} right failed.".format(op),
  59. "{}Showing split diff:".format(Colour.stop),
  60. "",
  61. ]
  62. if lhs_diff and rhs_diff:
  63. lhs_diff[0] = Colour.stop + diff_intro_text("left: ") + lhs_diff[0]
  64. rhs_diff[0] = Colour.stop + diff_intro_text("right: ") + rhs_diff[0]
  65. output += lhs_diff + rhs_diff
  66. return output