Coverage for Applications/PyCharm.app/Contents/plugins/python-ce/helpers/pycharm/_jb_serial_tree_manager.py: 86%

1# coding=utf-8

2

3

4 class SerialTreeManager(object):

5 """

6 Manages output tree by building it from flat test names.

7 """

8

9 def __init__(self, offset):

10 super(SerialTreeManager, self).__init__()

11 # Currently active branch as list. New nodes go to this branch

12 self.current_branch = []

13 # node unique name to its nodeId

14 self._node_ids_dict = {}

15 # Node id mast be incremented for each new branch

16 self._max_node_id = offset

17 self.offset = offset

18

19 def _calculate_relation(self, branch_as_list):

20 """

21 Get relation of branch_as_list to current branch.

22 :return: tuple. First argument could be: "same", "child", "parent" or "sibling"(need to start new tree)

23 Second argument is relative path from current branch to child if argument is child

24 """

25 if branch_as_list == self.current_branch:

26 return "same", None

27

28 hierarchy_name_len = len(branch_as_list)

29 current_branch_len = len(self.current_branch)

30

31 if hierarchy_name_len > current_branch_len and branch_as_list[0: current_branch_len] == self.current_branch:

32 return "child", branch_as_list[current_branch_len:]

33

34 if hierarchy_name_len < current_branch_len and self.current_branch[0: hierarchy_name_len] == branch_as_list:

35 return "parent", None

36

37 return "sibling", None

38

39 def _add_new_node(self, new_node_name):

40 """

41 Adds new node to branch

42 """

43 self.current_branch.append(new_node_name)

44 self._max_node_id += 1

45 self._node_ids_dict[".".join(self.current_branch)] = self._max_node_id

46

47 def level_opened(self, test_as_list, func_to_open):

48 """

49 To be called on test start.

50

51 :param test_as_list: test name splitted as list

52 :param func_to_open: func to be called if test can open new level

53 :return: None if new level opened, or tuple of command client should execute and try opening level again

54 Command is "open" (open provided level) or "close" (close it). Second item is test name as list

55 """

56 relation, relative_path = self._calculate_relation(test_as_list)

57 if relation == 'same':

58 return # Opening same level?

59 if relation == 'child':

60 # If one level -- open new level gracefully

61 if len(relative_path) == 1:

62 self._add_new_node(relative_path[0])

63 func_to_open()

64 return None

65 else:

66 # Open previous level

67 return [("open", self.current_branch + relative_path[0:1])]

68 if relation == "sibling":

69 if self.current_branch:

70 # Different tree, close whole branch

71 return [("close", self.current_branch)]

72 else:

73 return None

74 if relation == 'parent':

75 # Opening parent? Insane

76 pass

77

78 def level_closed(self, test_as_list, func_to_close):

79 """

80 To be called on test end or failure.

81

82 See level_opened doc.

83 """

84 relation, relative_path = self._calculate_relation(test_as_list)

85 if relation == 'same':

86 # Closing current level

87 func_to_close()

88 self.current_branch.pop()

89 if relation == 'child':

90 return None

91

92 if relation == 'sibling':

93 pass

94 if relation == 'parent':

95 return [("close", self.current_branch)]

96

97 @property

98 def parent_branch(self):

99 return self.current_branch[:-1] if self.current_branch else None

100

101 def _get_node_id(self, branch):

102 return self._node_ids_dict[".".join(branch)]

103

104 # Part of contract

105 # noinspection PyUnusedLocal

106 def get_node_ids(self, test_name):

107 """

108

109 :return: (current_node_id, parent_node_id)

110 """

111 current = self._get_node_id(self.current_branch)

112 parent = self._get_node_id(self.parent_branch) if self.parent_branch else str(self.offset)

113 return str(current), str(parent)