-
Notifications
You must be signed in to change notification settings - Fork 4
/
datatree.py
executable file
·140 lines (114 loc) · 3.91 KB
/
datatree.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from Peach.mutator import *
from Peach.Engine.common import *
class DataTreeRemoveMutator(Mutator):
"""
Remove nodes from data tree.
"""
def __init__(self, peach, node):
Mutator.__init__(self)
self.isFinite = True
self.name = "DataTreeRemoveMutator"
self._peach = peach
def next(self):
raise MutatorCompleted()
def getCount(self):
return 1
@staticmethod
def supportedDataElement(e):
if isinstance(e, DataElement) and e.isMutable:
return True
return False
def sequentialMutation(self, node):
self.changedName = node.getFullnameInDataModel()
node.setValue("")
def randomMutation(self, node, rand):
self.changedName = node.getFullnameInDataModel()
node.setValue("")
class DataTreeDuplicateMutator(Mutator):
"""
Duplicate a node's value starting at 2x through 50x.
"""
def __init__(self, peach, node):
Mutator.__init__(self)
self.isFinite = True
self.name = "DataTreeDuplicateMutator"
self._peach = peach
self._cnt = 2
self._maxCount = 50
def next(self):
self._cnt += 1
if self._cnt > self._maxCount:
raise MutatorCompleted()
def getCount(self):
return self._maxCount
@staticmethod
def supportedDataElement(e):
if isinstance(e, DataElement) and e.isMutable:
return True
return False
def sequentialMutation(self, node):
self.changedName = node.getFullnameInDataModel()
node.setValue(node.getValue() * self._cnt)
def randomMutation(self, node, rand):
self.changedName = node.getFullnameInDataModel()
count = rand.randint(0, self._cnt)
node.setValue(node.getValue() * count)
class DataTreeSwapNearNodesMutator(Mutator):
"""
Swap two nodes in the data model that are near each other.
TODO: Actually move the nodes instead of just the data.
"""
def __init__(self, peach, node):
Mutator.__init__(self)
self.isFinite = True
self.name = "DataTreeSwapNearNodesMutator"
self._peach = peach
def next(self):
raise MutatorCompleted()
def getCount(self):
return 1
def _moveNext(self, currentNode):
# Check if we are top dogM
if currentNode.parent is None or \
not isinstance(currentNode.parent, DataElement):
return None
# Get sibling
foundCurrent = False
for node in currentNode.parent:
if node == currentNode:
foundCurrent = True
continue
if foundCurrent and isinstance(node, DataElement):
return node
# Get sibling of parentM
return self._moveNext(currentNode.parent)
def _nextNode(self, node):
nextNode = None
# Walk down node tree
for child in node._children:
if isinstance(child, DataElement):
nextNode = child
break
# Walk over or up if we can
if nextNode is None:
nextNode = self._moveNext(node)
return nextNode
@staticmethod
def supportedDataElement(e):
if isinstance(e, DataElement) and e.isMutable:
return True
return False
def sequentialMutation(self, node):
self.changedName = node.getFullnameInDataModel()
nextNode = self._nextNode(node)
if nextNode is not None:
v1 = node.getValue()
v2 = nextNode.getValue()
node.setValue(v2)
nextNode.setValue(v1)
def randomMutation(self, node, rand):
self.changedName = node.getFullnameInDataModel()
self.sequentialMutation(node)