mapping.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. from itertools import chain, islice
  2. import attr
  3. import re
  4. from allure_commons.types import Severity, LabelType, LinkType
  5. from allure_commons.types import ALLURE_UNIQUE_LABELS
  6. from allure_commons.model2 import Label, Link
  7. TAG_PREFIX = "allure"
  8. semi_sep = re.compile(r"allure[\.\w]+[^:=]*:")
  9. eq_sep = re.compile(r"allure[\.\w]+[^:=]*=")
  10. def allure_tag_sep(tag):
  11. if semi_sep.search(tag):
  12. return ":"
  13. if eq_sep.search(tag):
  14. return "="
  15. def __is(kind, t):
  16. return kind in [v for k, v in t.__dict__.items() if not k.startswith('__')]
  17. def parse_tag(tag, issue_pattern=None, link_pattern=None):
  18. """
  19. >>> parse_tag("blocker")
  20. Label(name='severity', value='blocker')
  21. >>> parse_tag("allure.issue:http://example.com/BUG-42")
  22. Link(type='issue', url='http://example.com/BUG-42', name='http://example.com/BUG-42')
  23. >>> parse_tag("allure.link.home:http://qameta.io")
  24. Link(type='link', url='http://qameta.io', name='home')
  25. >>> parse_tag("allure.suite:mapping")
  26. Label(name='suite', value='mapping')
  27. >>> parse_tag("allure.suite:mapping")
  28. Label(name='suite', value='mapping')
  29. >>> parse_tag("allure.label.owner:me")
  30. Label(name='owner', value='me')
  31. >>> parse_tag("foo.label:1")
  32. Label(name='tag', value='foo.label:1')
  33. >>> parse_tag("allure.foo:1")
  34. Label(name='tag', value='allure.foo:1')
  35. """
  36. sep = allure_tag_sep(tag)
  37. schema, value = islice(chain(tag.split(sep, 1), [None]), 2)
  38. prefix, kind, name = islice(chain(schema.split('.'), [None], [None]), 3)
  39. if tag in [severity for severity in Severity]:
  40. return Label(name=LabelType.SEVERITY, value=tag)
  41. if prefix == TAG_PREFIX and value is not None:
  42. if __is(kind, LinkType):
  43. if issue_pattern and kind == "issue" and not value.startswith("http"):
  44. value = issue_pattern.format(value)
  45. if link_pattern and kind == "link" and not value.startswith("http"):
  46. value = link_pattern.format(value)
  47. return Link(type=kind, name=name or value, url=value)
  48. if __is(kind, LabelType):
  49. return Label(name=kind, value=value)
  50. if kind == "id":
  51. return Label(name=LabelType.ID, value=value)
  52. if kind == "label" and name is not None:
  53. return Label(name=name, value=value)
  54. return Label(name=LabelType.TAG, value=tag)
  55. def labels_set(labels):
  56. """
  57. >>> labels_set([Label(name=LabelType.SEVERITY, value=Severity.NORMAL),
  58. ... Label(name=LabelType.SEVERITY, value=Severity.BLOCKER)
  59. ... ])
  60. [Label(name='severity', value=<Severity.BLOCKER: 'blocker'>)]
  61. >>> labels_set([Label(name=LabelType.SEVERITY, value=Severity.NORMAL),
  62. ... Label(name='severity', value='minor')
  63. ... ])
  64. [Label(name='severity', value='minor')]
  65. >>> labels_set([Label(name=LabelType.EPIC, value="Epic"),
  66. ... Label(name=LabelType.EPIC, value="Epic")
  67. ... ])
  68. [Label(name='epic', value='Epic')]
  69. >>> labels_set([Label(name=LabelType.EPIC, value="Epic1"),
  70. ... Label(name=LabelType.EPIC, value="Epic2")
  71. ... ])
  72. [Label(name='epic', value='Epic1'), Label(name='epic', value='Epic2')]
  73. """
  74. class Wl:
  75. def __init__(self, label):
  76. self.label = label
  77. def __repr__(self):
  78. return "{name}{value}".format(**attr.asdict(self.label))
  79. def __eq__(self, other):
  80. if self.label.name in ALLURE_UNIQUE_LABELS:
  81. return self.label.name == other.label.name
  82. return repr(self) == repr(other)
  83. def __hash__(self):
  84. if self.label.name in ALLURE_UNIQUE_LABELS:
  85. return hash(self.label.name)
  86. return hash(repr(self))
  87. return sorted([wl.label for wl in set([Wl(label) for label in reversed(labels)])])