Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / tools / metrics / actions / extract_actions_test.py
blob8a6b94273ad50b25388c000696ce9df7a1150c8b
1 #!/usr/bin/env python
2 # Copyright 2014 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 import unittest
8 import extract_actions
10 # Empty value to be inserted to |ACTIONS_MOCK|.
11 NO_VALUE = ''
13 ONE_OWNER = '<owner>name1@google.com</owner>\n'
14 TWO_OWNERS = """
15 <owner>name1@google.com</owner>\n
16 <owner>name2@google.com</owner>\n
17 """
19 DESCRIPTION = '<description>Description.</description>\n'
20 TWO_DESCRIPTIONS = """
21 <description>Description.</description>\n
22 <description>Description2.</description>\n
23 """
25 OBSOLETE = '<obsolete>Not used anymore. Replaced by action2.</obsolete>\n'
26 TWO_OBSOLETE = '<obsolete>Obsolete1.</obsolete><obsolete>Obsolete2.</obsolete>'
28 COMMENT = '<!--comment-->'
30 NOT_USER_TRIGGERED = 'not_user_triggered="true"'
32 # A format string to mock the input action.xml file.
33 ACTIONS_XML = """
34 {comment}
35 <actions>
37 <action name="action1" {not_user_triggered}>
38 {owners}{obsolete}{description}
39 </action>
41 </actions>"""
43 NO_OWNER_EXPECTED_XML = (
44 '<actions>\n\n'
45 '<action name="action1">\n'
46 ' <owner>Please list the metric\'s owners. '
47 'Add more owner tags as needed.</owner>\n'
48 ' <description>Description.</description>\n'
49 '</action>\n\n'
50 '</actions>\n'
53 ONE_OWNER_EXPECTED_XML = (
54 '<actions>\n\n'
55 '<action name="action1">\n'
56 ' <owner>name1@google.com</owner>\n'
57 ' <description>Description.</description>\n'
58 '</action>\n\n'
59 '</actions>\n'
62 TWO_OWNERS_EXPECTED_XML = (
63 '<actions>\n\n'
64 '<action name="action1">\n'
65 ' <owner>name1@google.com</owner>\n'
66 ' <owner>name2@google.com</owner>\n'
67 ' <description>Description.</description>\n'
68 '</action>\n\n'
69 '</actions>\n'
72 NO_DESCRIPTION_EXPECTED_XML = (
73 '<actions>\n\n'
74 '<action name="action1">\n'
75 ' <owner>name1@google.com</owner>\n'
76 ' <owner>name2@google.com</owner>\n'
77 ' <description>Please enter the description of the metric.</description>\n'
78 '</action>\n\n'
79 '</actions>\n'
82 OBSOLETE_EXPECTED_XML = (
83 '<actions>\n\n'
84 '<action name="action1">\n'
85 ' <owner>name1@google.com</owner>\n'
86 ' <owner>name2@google.com</owner>\n'
87 ' <description>Description.</description>\n'
88 ' <obsolete>Not used anymore. Replaced by action2.</obsolete>\n'
89 '</action>\n\n'
90 '</actions>\n'
93 ADD_ACTION_EXPECTED_XML = (
94 '<actions>\n\n'
95 '<action name="action1">\n'
96 ' <owner>name1@google.com</owner>\n'
97 ' <owner>name2@google.com</owner>\n'
98 ' <description>Description.</description>\n'
99 '</action>\n\n'
100 '<action name="action2">\n'
101 ' <owner>Please list the metric\'s owners.'
102 ' Add more owner tags as needed.</owner>\n'
103 ' <description>Please enter the description of the metric.</description>\n'
104 '</action>\n\n'
105 '</actions>\n'
108 COMMENT_EXPECTED_XML = (
109 '<!--comment-->\n\n'
110 '<actions>\n\n'
111 '<action name="action1">\n'
112 ' <owner>name1@google.com</owner>\n'
113 ' <owner>name2@google.com</owner>\n'
114 ' <description>Description.</description>\n'
115 '</action>\n\n'
116 '</actions>\n'
119 NOT_USER_TRIGGERED_EXPECTED_XML = (
120 '<actions>\n\n'
121 '<action name="action1" not_user_triggered="true">\n'
122 ' <owner>Please list the metric\'s owners. '
123 'Add more owner tags as needed.</owner>\n'
124 ' <description>Description.</description>\n'
125 '</action>\n\n'
126 '</actions>\n'
129 class ActionXmlTest(unittest.TestCase):
131 def _GetProcessedAction(self, owner, description, obsolete,
132 not_user_triggered=NO_VALUE, new_actions=[],
133 comment=NO_VALUE):
134 """Forms an actions XML string and returns it after processing.
136 It parses the original XML string, adds new user actions (if there is any),
137 and pretty prints it.
139 Args:
140 owner: the owner tag to be inserted in the original XML string.
141 description: the description tag to be inserted in the original XML
142 string.
143 obsolete: the obsolete tag to be inserted in the original XML string.
144 new_actions: optional. List of new user actions' names to be inserted.
145 comment: the comment tag to be inserted in the original XML string.
147 Returns:
148 An updated and pretty-printed action XML string.
150 # Form the actions.xml mock content based on the input parameters.
151 current_xml = ACTIONS_XML.format(owners=owner, description=description,
152 obsolete=obsolete, comment=comment,
153 not_user_triggered=not_user_triggered)
154 actions, actions_dict, comments = extract_actions.ParseActionFile(
155 current_xml)
156 for new_action in new_actions:
157 actions.add(new_action)
158 return extract_actions.PrettyPrint(actions, actions_dict, comments)
160 def testNoOwner(self):
161 xml_result = self._GetProcessedAction(NO_VALUE, DESCRIPTION, NO_VALUE)
162 self.assertEqual(NO_OWNER_EXPECTED_XML, xml_result)
164 def testOneOwnerOneDescription(self):
165 xml_result = self._GetProcessedAction(ONE_OWNER, DESCRIPTION, NO_VALUE)
166 self.assertEqual(ONE_OWNER_EXPECTED_XML, xml_result)
168 def testTwoOwners(self):
169 xml_result = self._GetProcessedAction(TWO_OWNERS, DESCRIPTION, NO_VALUE)
170 self.assertEqual(TWO_OWNERS_EXPECTED_XML, xml_result)
172 def testNoDescription(self):
173 xml_result = self._GetProcessedAction(TWO_OWNERS, NO_VALUE, NO_VALUE)
174 self.assertEqual(NO_DESCRIPTION_EXPECTED_XML, xml_result)
176 def testTwoDescriptions(self):
177 current_xml = ACTIONS_XML.format(owners=TWO_OWNERS, obsolete=NO_VALUE,
178 description=TWO_DESCRIPTIONS,
179 comment=NO_VALUE,
180 not_user_triggered=NO_VALUE)
181 # Since there are two description tags, the function ParseActionFile will
182 # raise SystemExit with exit code 1.
183 with self.assertRaises(SystemExit) as cm:
184 _, _ = extract_actions.ParseActionFile(current_xml)
185 self.assertEqual(cm.exception.code, 1)
187 def testObsolete(self):
188 xml_result = self._GetProcessedAction(TWO_OWNERS, DESCRIPTION, OBSOLETE)
189 self.assertEqual(OBSOLETE_EXPECTED_XML, xml_result)
192 def testTwoObsoletes(self):
193 current_xml = ACTIONS_XML.format(owners=TWO_OWNERS, obsolete=TWO_OBSOLETE,
194 description=DESCRIPTION, comment=NO_VALUE,
195 not_user_triggered=NO_VALUE)
197 # Since there are two obsolete tags, the function ParseActionFile will
198 # raise SystemExit with exit code 1.
199 with self.assertRaises(SystemExit) as cm:
200 _, _ = extract_actions.ParseActionFile(current_xml)
201 self.assertEqual(cm.exception.code, 1)
203 def testAddNewActions(self):
204 xml_result = self._GetProcessedAction(TWO_OWNERS, DESCRIPTION, NO_VALUE,
205 new_actions=['action2'])
206 self.assertEqual(ADD_ACTION_EXPECTED_XML, xml_result)
208 def testComment(self):
209 xml_result = self._GetProcessedAction(TWO_OWNERS, DESCRIPTION, NO_VALUE,
210 comment=COMMENT)
211 self.assertEqual(COMMENT_EXPECTED_XML, xml_result)
213 def testNotUserTriggered(self):
214 xml_result = self._GetProcessedAction(NO_VALUE, DESCRIPTION, NO_VALUE,
215 NOT_USER_TRIGGERED)
216 self.assertEqual(NOT_USER_TRIGGERED_EXPECTED_XML, xml_result)
218 def testUserMetricsActionSpanningTwoLines(self):
219 code = 'base::UserMetricsAction(\n"Foo.Bar"));'
220 finder = extract_actions.ActionNameFinder('dummy', code)
221 self.assertEqual('Foo.Bar', finder.FindNextAction())
222 self.assertFalse(finder.FindNextAction())
224 def testUserMetricsActionAsAParam(self):
225 code = 'base::UserMetricsAction("Test.Foo"), "Test.Bar");'
226 finder = extract_actions.ActionNameFinder('dummy', code)
227 self.assertEqual('Test.Foo', finder.FindNextAction())
228 self.assertFalse(finder.FindNextAction())
230 def testNonLiteralUserMetricsAction(self):
231 code = 'base::UserMetricsAction(FOO)'
232 finder = extract_actions.ActionNameFinder('dummy', code)
233 with self.assertRaises(Exception):
234 finder.FindNextAction()
236 def testTernaryUserMetricsAction(self):
237 code = 'base::UserMetricsAction(foo ? "Foo.Bar" : "Bar.Foo"));'
238 finder = extract_actions.ActionNameFinder('dummy', code)
239 with self.assertRaises(Exception):
240 finder.FindNextAction()
242 def testTernaryUserMetricsActionWithNewLines(self):
243 code = """base::UserMetricsAction(
244 foo_bar ? "Bar.Foo" :
245 "Foo.Car")"""
246 finder = extract_actions.ActionNameFinder('dummy', code)
247 with self.assertRaises(extract_actions.InvalidStatementException):
248 finder.FindNextAction()
251 if __name__ == '__main__':
252 unittest.main()