xref: /aosp_15_r20/external/protobuf/objectivec/DevTools/pddm_tests.py (revision 1b3f573f81763fcece89efc2b6a5209149e44ab8)
1*1b3f573fSAndroid Build Coastguard Worker#! /usr/bin/env python3
2*1b3f573fSAndroid Build Coastguard Worker#
3*1b3f573fSAndroid Build Coastguard Worker# Protocol Buffers - Google's data interchange format
4*1b3f573fSAndroid Build Coastguard Worker# Copyright 2015 Google Inc.  All rights reserved.
5*1b3f573fSAndroid Build Coastguard Worker# https://developers.google.com/protocol-buffers/
6*1b3f573fSAndroid Build Coastguard Worker#
7*1b3f573fSAndroid Build Coastguard Worker# Redistribution and use in source and binary forms, with or without
8*1b3f573fSAndroid Build Coastguard Worker# modification, are permitted provided that the following conditions are
9*1b3f573fSAndroid Build Coastguard Worker# met:
10*1b3f573fSAndroid Build Coastguard Worker#
11*1b3f573fSAndroid Build Coastguard Worker#     * Redistributions of source code must retain the above copyright
12*1b3f573fSAndroid Build Coastguard Worker# notice, this list of conditions and the following disclaimer.
13*1b3f573fSAndroid Build Coastguard Worker#     * Redistributions in binary form must reproduce the above
14*1b3f573fSAndroid Build Coastguard Worker# copyright notice, this list of conditions and the following disclaimer
15*1b3f573fSAndroid Build Coastguard Worker# in the documentation and/or other materials provided with the
16*1b3f573fSAndroid Build Coastguard Worker# distribution.
17*1b3f573fSAndroid Build Coastguard Worker#     * Neither the name of Google Inc. nor the names of its
18*1b3f573fSAndroid Build Coastguard Worker# contributors may be used to endorse or promote products derived from
19*1b3f573fSAndroid Build Coastguard Worker# this software without specific prior written permission.
20*1b3f573fSAndroid Build Coastguard Worker#
21*1b3f573fSAndroid Build Coastguard Worker# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22*1b3f573fSAndroid Build Coastguard Worker# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23*1b3f573fSAndroid Build Coastguard Worker# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24*1b3f573fSAndroid Build Coastguard Worker# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25*1b3f573fSAndroid Build Coastguard Worker# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26*1b3f573fSAndroid Build Coastguard Worker# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27*1b3f573fSAndroid Build Coastguard Worker# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28*1b3f573fSAndroid Build Coastguard Worker# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29*1b3f573fSAndroid Build Coastguard Worker# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30*1b3f573fSAndroid Build Coastguard Worker# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31*1b3f573fSAndroid Build Coastguard Worker# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32*1b3f573fSAndroid Build Coastguard Worker
33*1b3f573fSAndroid Build Coastguard Worker"""Tests for pddm.py."""
34*1b3f573fSAndroid Build Coastguard Worker
35*1b3f573fSAndroid Build Coastguard Workerimport io
36*1b3f573fSAndroid Build Coastguard Workerimport unittest
37*1b3f573fSAndroid Build Coastguard Worker
38*1b3f573fSAndroid Build Coastguard Workerimport pddm
39*1b3f573fSAndroid Build Coastguard Worker
40*1b3f573fSAndroid Build Coastguard Worker
41*1b3f573fSAndroid Build Coastguard Workerclass TestParsingMacros(unittest.TestCase):
42*1b3f573fSAndroid Build Coastguard Worker
43*1b3f573fSAndroid Build Coastguard Worker  def testParseEmpty(self):
44*1b3f573fSAndroid Build Coastguard Worker    f = io.StringIO('')
45*1b3f573fSAndroid Build Coastguard Worker    result = pddm.MacroCollection(f)
46*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(len(result._macros), 0)
47*1b3f573fSAndroid Build Coastguard Worker
48*1b3f573fSAndroid Build Coastguard Worker  def testParseOne(self):
49*1b3f573fSAndroid Build Coastguard Worker    f = io.StringIO("""PDDM-DEFINE foo( )
50*1b3f573fSAndroid Build Coastguard Workerbody""")
51*1b3f573fSAndroid Build Coastguard Worker    result = pddm.MacroCollection(f)
52*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(len(result._macros), 1)
53*1b3f573fSAndroid Build Coastguard Worker    macro = result._macros.get('foo')
54*1b3f573fSAndroid Build Coastguard Worker    self.assertIsNotNone(macro)
55*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(macro.name, 'foo')
56*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(macro.args, tuple())
57*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(macro.body, 'body')
58*1b3f573fSAndroid Build Coastguard Worker
59*1b3f573fSAndroid Build Coastguard Worker  def testParseGeneral(self):
60*1b3f573fSAndroid Build Coastguard Worker    # Tests multiple defines, spaces in all places, etc.
61*1b3f573fSAndroid Build Coastguard Worker    f = io.StringIO("""
62*1b3f573fSAndroid Build Coastguard WorkerPDDM-DEFINE noArgs( )
63*1b3f573fSAndroid Build Coastguard Workerbody1
64*1b3f573fSAndroid Build Coastguard Workerbody2
65*1b3f573fSAndroid Build Coastguard Worker
66*1b3f573fSAndroid Build Coastguard WorkerPDDM-DEFINE-END
67*1b3f573fSAndroid Build Coastguard Worker
68*1b3f573fSAndroid Build Coastguard WorkerPDDM-DEFINE oneArg(foo)
69*1b3f573fSAndroid Build Coastguard Workerbody3
70*1b3f573fSAndroid Build Coastguard WorkerPDDM-DEFINE  twoArgs( bar_ , baz )
71*1b3f573fSAndroid Build Coastguard Workerbody4
72*1b3f573fSAndroid Build Coastguard Workerbody5""")
73*1b3f573fSAndroid Build Coastguard Worker    result = pddm.MacroCollection(f)
74*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(len(result._macros), 3)
75*1b3f573fSAndroid Build Coastguard Worker    macro = result._macros.get('noArgs')
76*1b3f573fSAndroid Build Coastguard Worker    self.assertIsNotNone(macro)
77*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(macro.name, 'noArgs')
78*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(macro.args, tuple())
79*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(macro.body, 'body1\nbody2\n')
80*1b3f573fSAndroid Build Coastguard Worker    macro = result._macros.get('oneArg')
81*1b3f573fSAndroid Build Coastguard Worker    self.assertIsNotNone(macro)
82*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(macro.name, 'oneArg')
83*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(macro.args, ('foo',))
84*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(macro.body, 'body3')
85*1b3f573fSAndroid Build Coastguard Worker    macro = result._macros.get('twoArgs')
86*1b3f573fSAndroid Build Coastguard Worker    self.assertIsNotNone(macro)
87*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(macro.name, 'twoArgs')
88*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(macro.args, ('bar_', 'baz'))
89*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(macro.body, 'body4\nbody5')
90*1b3f573fSAndroid Build Coastguard Worker    # Add into existing collection
91*1b3f573fSAndroid Build Coastguard Worker    f = io.StringIO("""
92*1b3f573fSAndroid Build Coastguard WorkerPDDM-DEFINE another(a,b,c)
93*1b3f573fSAndroid Build Coastguard Workerbody1
94*1b3f573fSAndroid Build Coastguard Workerbody2""")
95*1b3f573fSAndroid Build Coastguard Worker    result.ParseInput(f)
96*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(len(result._macros), 4)
97*1b3f573fSAndroid Build Coastguard Worker    macro = result._macros.get('another')
98*1b3f573fSAndroid Build Coastguard Worker    self.assertIsNotNone(macro)
99*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(macro.name, 'another')
100*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(macro.args, ('a', 'b', 'c'))
101*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(macro.body, 'body1\nbody2')
102*1b3f573fSAndroid Build Coastguard Worker
103*1b3f573fSAndroid Build Coastguard Worker  def testParseDirectiveIssues(self):
104*1b3f573fSAndroid Build Coastguard Worker    test_list = [
105*1b3f573fSAndroid Build Coastguard Worker      # Unknown directive
106*1b3f573fSAndroid Build Coastguard Worker      ('PDDM-DEFINE foo()\nbody\nPDDM-DEFINED foo\nbaz',
107*1b3f573fSAndroid Build Coastguard Worker       'Hit a line with an unknown directive: '),
108*1b3f573fSAndroid Build Coastguard Worker      # End without begin
109*1b3f573fSAndroid Build Coastguard Worker      ('PDDM-DEFINE foo()\nbody\nPDDM-DEFINE-END\nPDDM-DEFINE-END\n',
110*1b3f573fSAndroid Build Coastguard Worker       'Got DEFINE-END directive without an active macro: '),
111*1b3f573fSAndroid Build Coastguard Worker      # Line not in macro block
112*1b3f573fSAndroid Build Coastguard Worker      ('PDDM-DEFINE foo()\nbody\nPDDM-DEFINE-END\nmumble\n',
113*1b3f573fSAndroid Build Coastguard Worker       'Hit a line that wasn\'t a directive and no open macro definition: '),
114*1b3f573fSAndroid Build Coastguard Worker      # Redefine macro
115*1b3f573fSAndroid Build Coastguard Worker      ('PDDM-DEFINE foo()\nbody\nPDDM-DEFINE foo(a)\nmumble\n',
116*1b3f573fSAndroid Build Coastguard Worker       'Attempt to redefine macro: '),
117*1b3f573fSAndroid Build Coastguard Worker    ]
118*1b3f573fSAndroid Build Coastguard Worker    for idx, (input_str, expected_prefix) in enumerate(test_list, 1):
119*1b3f573fSAndroid Build Coastguard Worker      f = io.StringIO(input_str)
120*1b3f573fSAndroid Build Coastguard Worker      try:
121*1b3f573fSAndroid Build Coastguard Worker        result = pddm.MacroCollection(f)
122*1b3f573fSAndroid Build Coastguard Worker        self.fail('Should throw exception, entry %d' % idx)
123*1b3f573fSAndroid Build Coastguard Worker      except pddm.PDDMError as e:
124*1b3f573fSAndroid Build Coastguard Worker        self.assertTrue(e.message.startswith(expected_prefix),
125*1b3f573fSAndroid Build Coastguard Worker                        'Entry %d failed: %r' % (idx, e))
126*1b3f573fSAndroid Build Coastguard Worker
127*1b3f573fSAndroid Build Coastguard Worker  def testParseBeginIssues(self):
128*1b3f573fSAndroid Build Coastguard Worker    test_list = [
129*1b3f573fSAndroid Build Coastguard Worker      # 1. No name
130*1b3f573fSAndroid Build Coastguard Worker      ('PDDM-DEFINE\nmumble',
131*1b3f573fSAndroid Build Coastguard Worker       'Failed to parse macro definition: '),
132*1b3f573fSAndroid Build Coastguard Worker      # 2. No name (with spaces)
133*1b3f573fSAndroid Build Coastguard Worker      ('PDDM-DEFINE  \nmumble',
134*1b3f573fSAndroid Build Coastguard Worker       'Failed to parse macro definition: '),
135*1b3f573fSAndroid Build Coastguard Worker      # 3. No open paren
136*1b3f573fSAndroid Build Coastguard Worker      ('PDDM-DEFINE  foo\nmumble',
137*1b3f573fSAndroid Build Coastguard Worker       'Failed to parse macro definition: '),
138*1b3f573fSAndroid Build Coastguard Worker      # 4. No close paren
139*1b3f573fSAndroid Build Coastguard Worker      ('PDDM-DEFINE foo(\nmumble',
140*1b3f573fSAndroid Build Coastguard Worker       'Failed to parse macro definition: '),
141*1b3f573fSAndroid Build Coastguard Worker      # 5. No close paren (with args)
142*1b3f573fSAndroid Build Coastguard Worker      ('PDDM-DEFINE foo(a, b\nmumble',
143*1b3f573fSAndroid Build Coastguard Worker       'Failed to parse macro definition: '),
144*1b3f573fSAndroid Build Coastguard Worker      # 6. No name before args
145*1b3f573fSAndroid Build Coastguard Worker      ('PDDM-DEFINE  (a, b)\nmumble',
146*1b3f573fSAndroid Build Coastguard Worker       'Failed to parse macro definition: '),
147*1b3f573fSAndroid Build Coastguard Worker      # 7. No name before args
148*1b3f573fSAndroid Build Coastguard Worker      ('PDDM-DEFINE foo bar(a, b)\nmumble',
149*1b3f573fSAndroid Build Coastguard Worker       'Failed to parse macro definition: '),
150*1b3f573fSAndroid Build Coastguard Worker      # 8. Empty arg name
151*1b3f573fSAndroid Build Coastguard Worker      ('PDDM-DEFINE foo(a, ,b)\nmumble',
152*1b3f573fSAndroid Build Coastguard Worker       'Empty arg name in macro definition: '),
153*1b3f573fSAndroid Build Coastguard Worker      ('PDDM-DEFINE foo(a,,b)\nmumble',
154*1b3f573fSAndroid Build Coastguard Worker       'Empty arg name in macro definition: '),
155*1b3f573fSAndroid Build Coastguard Worker      # 10. Duplicate name
156*1b3f573fSAndroid Build Coastguard Worker      ('PDDM-DEFINE foo(a,b,a,c)\nmumble',
157*1b3f573fSAndroid Build Coastguard Worker       'Arg name "a" used more than once in macro definition: '),
158*1b3f573fSAndroid Build Coastguard Worker      # 11. Invalid arg name
159*1b3f573fSAndroid Build Coastguard Worker      ('PDDM-DEFINE foo(a b,c)\nmumble',
160*1b3f573fSAndroid Build Coastguard Worker       'Invalid arg name "a b" in macro definition: '),
161*1b3f573fSAndroid Build Coastguard Worker      ('PDDM-DEFINE foo(a.b,c)\nmumble',
162*1b3f573fSAndroid Build Coastguard Worker       'Invalid arg name "a.b" in macro definition: '),
163*1b3f573fSAndroid Build Coastguard Worker      ('PDDM-DEFINE foo(a-b,c)\nmumble',
164*1b3f573fSAndroid Build Coastguard Worker       'Invalid arg name "a-b" in macro definition: '),
165*1b3f573fSAndroid Build Coastguard Worker      ('PDDM-DEFINE foo(a,b,c.)\nmumble',
166*1b3f573fSAndroid Build Coastguard Worker       'Invalid arg name "c." in macro definition: '),
167*1b3f573fSAndroid Build Coastguard Worker      # 15. Extra stuff after the name
168*1b3f573fSAndroid Build Coastguard Worker      ('PDDM-DEFINE foo(a,c) foo\nmumble',
169*1b3f573fSAndroid Build Coastguard Worker       'Failed to parse macro definition: '),
170*1b3f573fSAndroid Build Coastguard Worker      ('PDDM-DEFINE foo(a,c) foo)\nmumble',
171*1b3f573fSAndroid Build Coastguard Worker       'Failed to parse macro definition: '),
172*1b3f573fSAndroid Build Coastguard Worker    ]
173*1b3f573fSAndroid Build Coastguard Worker    for idx, (input_str, expected_prefix) in enumerate(test_list, 1):
174*1b3f573fSAndroid Build Coastguard Worker      f = io.StringIO(input_str)
175*1b3f573fSAndroid Build Coastguard Worker      try:
176*1b3f573fSAndroid Build Coastguard Worker        result = pddm.MacroCollection(f)
177*1b3f573fSAndroid Build Coastguard Worker        self.fail('Should throw exception, entry %d' % idx)
178*1b3f573fSAndroid Build Coastguard Worker      except pddm.PDDMError as e:
179*1b3f573fSAndroid Build Coastguard Worker        self.assertTrue(e.message.startswith(expected_prefix),
180*1b3f573fSAndroid Build Coastguard Worker                        'Entry %d failed: %r' % (idx, e))
181*1b3f573fSAndroid Build Coastguard Worker
182*1b3f573fSAndroid Build Coastguard Worker
183*1b3f573fSAndroid Build Coastguard Workerclass TestExpandingMacros(unittest.TestCase):
184*1b3f573fSAndroid Build Coastguard Worker
185*1b3f573fSAndroid Build Coastguard Worker  def testExpandBasics(self):
186*1b3f573fSAndroid Build Coastguard Worker    f = io.StringIO("""
187*1b3f573fSAndroid Build Coastguard WorkerPDDM-DEFINE noArgs( )
188*1b3f573fSAndroid Build Coastguard Workerbody1
189*1b3f573fSAndroid Build Coastguard Workerbody2
190*1b3f573fSAndroid Build Coastguard Worker
191*1b3f573fSAndroid Build Coastguard WorkerPDDM-DEFINE-END
192*1b3f573fSAndroid Build Coastguard Worker
193*1b3f573fSAndroid Build Coastguard WorkerPDDM-DEFINE oneArg(a)
194*1b3f573fSAndroid Build Coastguard Workerbody3 a
195*1b3f573fSAndroid Build Coastguard Worker
196*1b3f573fSAndroid Build Coastguard WorkerPDDM-DEFINE-END
197*1b3f573fSAndroid Build Coastguard Worker
198*1b3f573fSAndroid Build Coastguard WorkerPDDM-DEFINE twoArgs(b,c)
199*1b3f573fSAndroid Build Coastguard Workerbody4 b c
200*1b3f573fSAndroid Build Coastguard Workerbody5
201*1b3f573fSAndroid Build Coastguard WorkerPDDM-DEFINE-END
202*1b3f573fSAndroid Build Coastguard Worker
203*1b3f573fSAndroid Build Coastguard Worker""")
204*1b3f573fSAndroid Build Coastguard Worker    mc = pddm.MacroCollection(f)
205*1b3f573fSAndroid Build Coastguard Worker    test_list = [
206*1b3f573fSAndroid Build Coastguard Worker      ('noArgs()',
207*1b3f573fSAndroid Build Coastguard Worker       'body1\nbody2\n'),
208*1b3f573fSAndroid Build Coastguard Worker      ('oneArg(wee)',
209*1b3f573fSAndroid Build Coastguard Worker       'body3 wee\n'),
210*1b3f573fSAndroid Build Coastguard Worker      ('twoArgs(having some, fun)',
211*1b3f573fSAndroid Build Coastguard Worker       'body4 having some fun\nbody5'),
212*1b3f573fSAndroid Build Coastguard Worker      # One arg, pass empty.
213*1b3f573fSAndroid Build Coastguard Worker      ('oneArg()',
214*1b3f573fSAndroid Build Coastguard Worker       'body3 \n'),
215*1b3f573fSAndroid Build Coastguard Worker      # Two args, gets empty in each slot.
216*1b3f573fSAndroid Build Coastguard Worker      ('twoArgs(, empty)',
217*1b3f573fSAndroid Build Coastguard Worker       'body4  empty\nbody5'),
218*1b3f573fSAndroid Build Coastguard Worker      ('twoArgs(empty, )',
219*1b3f573fSAndroid Build Coastguard Worker       'body4 empty \nbody5'),
220*1b3f573fSAndroid Build Coastguard Worker      ('twoArgs(, )',
221*1b3f573fSAndroid Build Coastguard Worker       'body4  \nbody5'),
222*1b3f573fSAndroid Build Coastguard Worker    ]
223*1b3f573fSAndroid Build Coastguard Worker    for idx, (input_str, expected) in enumerate(test_list, 1):
224*1b3f573fSAndroid Build Coastguard Worker      result = mc.Expand(input_str)
225*1b3f573fSAndroid Build Coastguard Worker      self.assertEqual(result, expected,
226*1b3f573fSAndroid Build Coastguard Worker                       'Entry %d --\n       Result: %r\n     Expected: %r' %
227*1b3f573fSAndroid Build Coastguard Worker                       (idx, result, expected))
228*1b3f573fSAndroid Build Coastguard Worker
229*1b3f573fSAndroid Build Coastguard Worker  def testExpandArgOptions(self):
230*1b3f573fSAndroid Build Coastguard Worker    f = io.StringIO("""
231*1b3f573fSAndroid Build Coastguard WorkerPDDM-DEFINE bar(a)
232*1b3f573fSAndroid Build Coastguard Workera-a$S-a$l-a$L-a$u-a$U
233*1b3f573fSAndroid Build Coastguard WorkerPDDM-DEFINE-END
234*1b3f573fSAndroid Build Coastguard Worker""")
235*1b3f573fSAndroid Build Coastguard Worker    mc = pddm.MacroCollection(f)
236*1b3f573fSAndroid Build Coastguard Worker
237*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(mc.Expand('bar(xYz)'), 'xYz-   -xYz-xyz-XYz-XYZ')
238*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(mc.Expand('bar(MnoP)'), 'MnoP-    -mnoP-mnop-MnoP-MNOP')
239*1b3f573fSAndroid Build Coastguard Worker    # Test empty
240*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(mc.Expand('bar()'), '-----')
241*1b3f573fSAndroid Build Coastguard Worker
242*1b3f573fSAndroid Build Coastguard Worker  def testExpandSimpleMacroErrors(self):
243*1b3f573fSAndroid Build Coastguard Worker    f = io.StringIO("""
244*1b3f573fSAndroid Build Coastguard WorkerPDDM-DEFINE foo(a, b)
245*1b3f573fSAndroid Build Coastguard Worker<a-z>
246*1b3f573fSAndroid Build Coastguard WorkerPDDM-DEFINE baz(a)
247*1b3f573fSAndroid Build Coastguard Workera - a$z
248*1b3f573fSAndroid Build Coastguard Worker""")
249*1b3f573fSAndroid Build Coastguard Worker    mc = pddm.MacroCollection(f)
250*1b3f573fSAndroid Build Coastguard Worker    test_list = [
251*1b3f573fSAndroid Build Coastguard Worker      # 1. Unknown macro
252*1b3f573fSAndroid Build Coastguard Worker      ('bar()',
253*1b3f573fSAndroid Build Coastguard Worker       'No macro named "bar".'),
254*1b3f573fSAndroid Build Coastguard Worker      ('bar(a)',
255*1b3f573fSAndroid Build Coastguard Worker       'No macro named "bar".'),
256*1b3f573fSAndroid Build Coastguard Worker      # 3. Arg mismatch
257*1b3f573fSAndroid Build Coastguard Worker      ('foo()',
258*1b3f573fSAndroid Build Coastguard Worker       'Expected 2 args, got: "foo()".'),
259*1b3f573fSAndroid Build Coastguard Worker      ('foo(a b)',
260*1b3f573fSAndroid Build Coastguard Worker       'Expected 2 args, got: "foo(a b)".'),
261*1b3f573fSAndroid Build Coastguard Worker      ('foo(a,b,c)',
262*1b3f573fSAndroid Build Coastguard Worker       'Expected 2 args, got: "foo(a,b,c)".'),
263*1b3f573fSAndroid Build Coastguard Worker      # 6. Unknown option in expansion
264*1b3f573fSAndroid Build Coastguard Worker      ('baz(mumble)',
265*1b3f573fSAndroid Build Coastguard Worker       'Unknown arg option "a$z" while expanding "baz(mumble)".'),
266*1b3f573fSAndroid Build Coastguard Worker    ]
267*1b3f573fSAndroid Build Coastguard Worker    for idx, (input_str, expected_err) in enumerate(test_list, 1):
268*1b3f573fSAndroid Build Coastguard Worker      try:
269*1b3f573fSAndroid Build Coastguard Worker        result = mc.Expand(input_str)
270*1b3f573fSAndroid Build Coastguard Worker        self.fail('Should throw exception, entry %d' % idx)
271*1b3f573fSAndroid Build Coastguard Worker      except pddm.PDDMError as e:
272*1b3f573fSAndroid Build Coastguard Worker        self.assertEqual(e.message, expected_err,
273*1b3f573fSAndroid Build Coastguard Worker                        'Entry %d failed: %r' % (idx, e))
274*1b3f573fSAndroid Build Coastguard Worker
275*1b3f573fSAndroid Build Coastguard Worker  def testExpandReferences(self):
276*1b3f573fSAndroid Build Coastguard Worker    f = io.StringIO("""
277*1b3f573fSAndroid Build Coastguard WorkerPDDM-DEFINE StartIt()
278*1b3f573fSAndroid Build Coastguard Workerfoo(abc, def)
279*1b3f573fSAndroid Build Coastguard Workerfoo(ghi, jkl)
280*1b3f573fSAndroid Build Coastguard WorkerPDDM-DEFINE foo(a, b)
281*1b3f573fSAndroid Build Coastguard Workerbar(a, int)
282*1b3f573fSAndroid Build Coastguard Workerbar(b, NSString *)
283*1b3f573fSAndroid Build Coastguard WorkerPDDM-DEFINE bar(n, t)
284*1b3f573fSAndroid Build Coastguard Worker- (t)n;
285*1b3f573fSAndroid Build Coastguard Worker- (void)set##n$u##:(t)value;
286*1b3f573fSAndroid Build Coastguard Worker
287*1b3f573fSAndroid Build Coastguard Worker""")
288*1b3f573fSAndroid Build Coastguard Worker    mc = pddm.MacroCollection(f)
289*1b3f573fSAndroid Build Coastguard Worker    expected = """- (int)abc;
290*1b3f573fSAndroid Build Coastguard Worker- (void)setAbc:(int)value;
291*1b3f573fSAndroid Build Coastguard Worker
292*1b3f573fSAndroid Build Coastguard Worker- (NSString *)def;
293*1b3f573fSAndroid Build Coastguard Worker- (void)setDef:(NSString *)value;
294*1b3f573fSAndroid Build Coastguard Worker
295*1b3f573fSAndroid Build Coastguard Worker- (int)ghi;
296*1b3f573fSAndroid Build Coastguard Worker- (void)setGhi:(int)value;
297*1b3f573fSAndroid Build Coastguard Worker
298*1b3f573fSAndroid Build Coastguard Worker- (NSString *)jkl;
299*1b3f573fSAndroid Build Coastguard Worker- (void)setJkl:(NSString *)value;
300*1b3f573fSAndroid Build Coastguard Worker"""
301*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(mc.Expand('StartIt()'), expected)
302*1b3f573fSAndroid Build Coastguard Worker
303*1b3f573fSAndroid Build Coastguard Worker  def testCatchRecursion(self):
304*1b3f573fSAndroid Build Coastguard Worker    f = io.StringIO("""
305*1b3f573fSAndroid Build Coastguard WorkerPDDM-DEFINE foo(a, b)
306*1b3f573fSAndroid Build Coastguard Workerbar(1, a)
307*1b3f573fSAndroid Build Coastguard Workerbar(2, b)
308*1b3f573fSAndroid Build Coastguard WorkerPDDM-DEFINE bar(x, y)
309*1b3f573fSAndroid Build Coastguard Workerfoo(x, y)
310*1b3f573fSAndroid Build Coastguard Worker""")
311*1b3f573fSAndroid Build Coastguard Worker    mc = pddm.MacroCollection(f)
312*1b3f573fSAndroid Build Coastguard Worker    try:
313*1b3f573fSAndroid Build Coastguard Worker      result = mc.Expand('foo(A,B)')
314*1b3f573fSAndroid Build Coastguard Worker      self.fail('Should throw exception! Test failed to catch recursion.')
315*1b3f573fSAndroid Build Coastguard Worker    except pddm.PDDMError as e:
316*1b3f573fSAndroid Build Coastguard Worker      self.assertEqual(e.message,
317*1b3f573fSAndroid Build Coastguard Worker                       'Found macro recursion, invoking "foo(1, A)":\n...while expanding "bar(1, A)".\n...while expanding "foo(A,B)".')
318*1b3f573fSAndroid Build Coastguard Worker
319*1b3f573fSAndroid Build Coastguard Worker
320*1b3f573fSAndroid Build Coastguard Workerclass TestParsingSource(unittest.TestCase):
321*1b3f573fSAndroid Build Coastguard Worker
322*1b3f573fSAndroid Build Coastguard Worker  def testBasicParse(self):
323*1b3f573fSAndroid Build Coastguard Worker    test_list = [
324*1b3f573fSAndroid Build Coastguard Worker      # 1. no directives
325*1b3f573fSAndroid Build Coastguard Worker      ('a\nb\nc',
326*1b3f573fSAndroid Build Coastguard Worker       (3,) ),
327*1b3f573fSAndroid Build Coastguard Worker      # 2. One define
328*1b3f573fSAndroid Build Coastguard Worker      ('a\n//%PDDM-DEFINE foo()\n//%body\nc',
329*1b3f573fSAndroid Build Coastguard Worker       (1, 2, 1) ),
330*1b3f573fSAndroid Build Coastguard Worker      # 3. Two defines
331*1b3f573fSAndroid Build Coastguard Worker      ('a\n//%PDDM-DEFINE foo()\n//%body\n//%PDDM-DEFINE bar()\n//%body2\nc',
332*1b3f573fSAndroid Build Coastguard Worker       (1, 4, 1) ),
333*1b3f573fSAndroid Build Coastguard Worker      # 4. Two defines with ends
334*1b3f573fSAndroid Build Coastguard Worker      ('a\n//%PDDM-DEFINE foo()\n//%body\n//%PDDM-DEFINE-END\n'
335*1b3f573fSAndroid Build Coastguard Worker       '//%PDDM-DEFINE bar()\n//%body2\n//%PDDM-DEFINE-END\nc',
336*1b3f573fSAndroid Build Coastguard Worker       (1, 6, 1) ),
337*1b3f573fSAndroid Build Coastguard Worker      # 5. One expand, one define (that runs to end of file)
338*1b3f573fSAndroid Build Coastguard Worker      ('a\n//%PDDM-EXPAND foo()\nbody\n//%PDDM-EXPAND-END\n'
339*1b3f573fSAndroid Build Coastguard Worker       '//%PDDM-DEFINE bar()\n//%body2\n',
340*1b3f573fSAndroid Build Coastguard Worker       (1, 1, 2) ),
341*1b3f573fSAndroid Build Coastguard Worker      # 6. One define ended with an expand.
342*1b3f573fSAndroid Build Coastguard Worker      ('a\nb\n//%PDDM-DEFINE bar()\n//%body2\n'
343*1b3f573fSAndroid Build Coastguard Worker       '//%PDDM-EXPAND bar()\nbody2\n//%PDDM-EXPAND-END\n',
344*1b3f573fSAndroid Build Coastguard Worker       (2, 2, 1) ),
345*1b3f573fSAndroid Build Coastguard Worker      # 7. Two expands (one end), one define.
346*1b3f573fSAndroid Build Coastguard Worker      ('a\n//%PDDM-EXPAND foo(1)\nbody\n//%PDDM-EXPAND foo(2)\nbody2\n//%PDDM-EXPAND-END\n'
347*1b3f573fSAndroid Build Coastguard Worker       '//%PDDM-DEFINE foo()\n//%body2\n',
348*1b3f573fSAndroid Build Coastguard Worker       (1, 2, 2) ),
349*1b3f573fSAndroid Build Coastguard Worker    ]
350*1b3f573fSAndroid Build Coastguard Worker    for idx, (input_str, line_counts) in enumerate(test_list, 1):
351*1b3f573fSAndroid Build Coastguard Worker      f = io.StringIO(input_str)
352*1b3f573fSAndroid Build Coastguard Worker      sf = pddm.SourceFile(f)
353*1b3f573fSAndroid Build Coastguard Worker      sf._ParseFile()
354*1b3f573fSAndroid Build Coastguard Worker      self.assertEqual(len(sf._sections), len(line_counts),
355*1b3f573fSAndroid Build Coastguard Worker                       'Entry %d -- %d != %d' %
356*1b3f573fSAndroid Build Coastguard Worker                       (idx, len(sf._sections), len(line_counts)))
357*1b3f573fSAndroid Build Coastguard Worker      for idx2, (sec, expected) in enumerate(zip(sf._sections, line_counts), 1):
358*1b3f573fSAndroid Build Coastguard Worker        self.assertEqual(sec.num_lines_captured, expected,
359*1b3f573fSAndroid Build Coastguard Worker                         'Entry %d, section %d -- %d != %d' %
360*1b3f573fSAndroid Build Coastguard Worker                         (idx, idx2, sec.num_lines_captured, expected))
361*1b3f573fSAndroid Build Coastguard Worker
362*1b3f573fSAndroid Build Coastguard Worker  def testErrors(self):
363*1b3f573fSAndroid Build Coastguard Worker    test_list = [
364*1b3f573fSAndroid Build Coastguard Worker      # 1. Directive within expansion
365*1b3f573fSAndroid Build Coastguard Worker      ('//%PDDM-EXPAND a()\n//%PDDM-BOGUS',
366*1b3f573fSAndroid Build Coastguard Worker       'Ran into directive ("//%PDDM-BOGUS", line 2) while in "//%PDDM-EXPAND a()".'),
367*1b3f573fSAndroid Build Coastguard Worker      ('//%PDDM-EXPAND a()\n//%PDDM-DEFINE a()\n//%body\n',
368*1b3f573fSAndroid Build Coastguard Worker       'Ran into directive ("//%PDDM-DEFINE", line 2) while in "//%PDDM-EXPAND a()".'),
369*1b3f573fSAndroid Build Coastguard Worker      # 3. Expansion ran off end of file
370*1b3f573fSAndroid Build Coastguard Worker      ('//%PDDM-EXPAND a()\na\nb\n',
371*1b3f573fSAndroid Build Coastguard Worker       'Hit the end of the file while in "//%PDDM-EXPAND a()".'),
372*1b3f573fSAndroid Build Coastguard Worker      # 4. Directive within define
373*1b3f573fSAndroid Build Coastguard Worker      ('//%PDDM-DEFINE a()\n//%body\n//%PDDM-BOGUS',
374*1b3f573fSAndroid Build Coastguard Worker       'Ran into directive ("//%PDDM-BOGUS", line 3) while in "//%PDDM-DEFINE a()".'),
375*1b3f573fSAndroid Build Coastguard Worker      ('//%PDDM-DEFINE a()\n//%body\n//%PDDM-EXPAND-END a()',
376*1b3f573fSAndroid Build Coastguard Worker       'Ran into directive ("//%PDDM-EXPAND-END", line 3) while in "//%PDDM-DEFINE a()".'),
377*1b3f573fSAndroid Build Coastguard Worker      # 6. Directives that shouldn't start sections
378*1b3f573fSAndroid Build Coastguard Worker      ('a\n//%PDDM-DEFINE-END a()\n//a\n',
379*1b3f573fSAndroid Build Coastguard Worker       'Unexpected line 2: "//%PDDM-DEFINE-END a()".'),
380*1b3f573fSAndroid Build Coastguard Worker      ('a\n//%PDDM-EXPAND-END a()\n//a\n',
381*1b3f573fSAndroid Build Coastguard Worker       'Unexpected line 2: "//%PDDM-EXPAND-END a()".'),
382*1b3f573fSAndroid Build Coastguard Worker      ('//%PDDM-BOGUS\n//a\n',
383*1b3f573fSAndroid Build Coastguard Worker       'Unexpected line 1: "//%PDDM-BOGUS".'),
384*1b3f573fSAndroid Build Coastguard Worker    ]
385*1b3f573fSAndroid Build Coastguard Worker    for idx, (input_str, expected_err) in enumerate(test_list, 1):
386*1b3f573fSAndroid Build Coastguard Worker      f = io.StringIO(input_str)
387*1b3f573fSAndroid Build Coastguard Worker      try:
388*1b3f573fSAndroid Build Coastguard Worker        pddm.SourceFile(f)._ParseFile()
389*1b3f573fSAndroid Build Coastguard Worker        self.fail('Should throw exception, entry %d' % idx)
390*1b3f573fSAndroid Build Coastguard Worker      except pddm.PDDMError as e:
391*1b3f573fSAndroid Build Coastguard Worker        self.assertEqual(e.message, expected_err,
392*1b3f573fSAndroid Build Coastguard Worker                        'Entry %d failed: %r' % (idx, e))
393*1b3f573fSAndroid Build Coastguard Worker
394*1b3f573fSAndroid Build Coastguard Workerclass TestProcessingSource(unittest.TestCase):
395*1b3f573fSAndroid Build Coastguard Worker
396*1b3f573fSAndroid Build Coastguard Worker  def testBasics(self):
397*1b3f573fSAndroid Build Coastguard Worker    self.maxDiff = None
398*1b3f573fSAndroid Build Coastguard Worker    input_str = """
399*1b3f573fSAndroid Build Coastguard Worker//%PDDM-IMPORT-DEFINES ImportFile
400*1b3f573fSAndroid Build Coastguard Workerfoo
401*1b3f573fSAndroid Build Coastguard Worker//%PDDM-EXPAND mumble(abc)
402*1b3f573fSAndroid Build Coastguard Worker//%PDDM-EXPAND-END
403*1b3f573fSAndroid Build Coastguard Workerbar
404*1b3f573fSAndroid Build Coastguard Worker//%PDDM-EXPAND mumble(def)
405*1b3f573fSAndroid Build Coastguard Worker//%PDDM-EXPAND mumble(ghi)
406*1b3f573fSAndroid Build Coastguard Worker//%PDDM-EXPAND-END
407*1b3f573fSAndroid Build Coastguard Workerbaz
408*1b3f573fSAndroid Build Coastguard Worker//%PDDM-DEFINE mumble(a_)
409*1b3f573fSAndroid Build Coastguard Worker//%a_: getName(a_)
410*1b3f573fSAndroid Build Coastguard Worker"""
411*1b3f573fSAndroid Build Coastguard Worker    input_str2 = """
412*1b3f573fSAndroid Build Coastguard Worker//%PDDM-DEFINE getName(x_)
413*1b3f573fSAndroid Build Coastguard Worker//%do##x_$u##(int x_);
414*1b3f573fSAndroid Build Coastguard Worker
415*1b3f573fSAndroid Build Coastguard Worker"""
416*1b3f573fSAndroid Build Coastguard Worker    expected = """
417*1b3f573fSAndroid Build Coastguard Worker//%PDDM-IMPORT-DEFINES ImportFile
418*1b3f573fSAndroid Build Coastguard Workerfoo
419*1b3f573fSAndroid Build Coastguard Worker//%PDDM-EXPAND mumble(abc)
420*1b3f573fSAndroid Build Coastguard Worker// This block of code is generated, do not edit it directly.
421*1b3f573fSAndroid Build Coastguard Worker// clang-format off
422*1b3f573fSAndroid Build Coastguard Worker
423*1b3f573fSAndroid Build Coastguard Workerabc: doAbc(int abc);
424*1b3f573fSAndroid Build Coastguard Worker// clang-format on
425*1b3f573fSAndroid Build Coastguard Worker//%PDDM-EXPAND-END mumble(abc)
426*1b3f573fSAndroid Build Coastguard Workerbar
427*1b3f573fSAndroid Build Coastguard Worker//%PDDM-EXPAND mumble(def)
428*1b3f573fSAndroid Build Coastguard Worker// This block of code is generated, do not edit it directly.
429*1b3f573fSAndroid Build Coastguard Worker// clang-format off
430*1b3f573fSAndroid Build Coastguard Worker
431*1b3f573fSAndroid Build Coastguard Workerdef: doDef(int def);
432*1b3f573fSAndroid Build Coastguard Worker// clang-format on
433*1b3f573fSAndroid Build Coastguard Worker//%PDDM-EXPAND mumble(ghi)
434*1b3f573fSAndroid Build Coastguard Worker// This block of code is generated, do not edit it directly.
435*1b3f573fSAndroid Build Coastguard Worker// clang-format off
436*1b3f573fSAndroid Build Coastguard Worker
437*1b3f573fSAndroid Build Coastguard Workerghi: doGhi(int ghi);
438*1b3f573fSAndroid Build Coastguard Worker// clang-format on
439*1b3f573fSAndroid Build Coastguard Worker//%PDDM-EXPAND-END (2 expansions)
440*1b3f573fSAndroid Build Coastguard Workerbaz
441*1b3f573fSAndroid Build Coastguard Worker//%PDDM-DEFINE mumble(a_)
442*1b3f573fSAndroid Build Coastguard Worker//%a_: getName(a_)
443*1b3f573fSAndroid Build Coastguard Worker"""
444*1b3f573fSAndroid Build Coastguard Worker    expected_stripped = """
445*1b3f573fSAndroid Build Coastguard Worker//%PDDM-IMPORT-DEFINES ImportFile
446*1b3f573fSAndroid Build Coastguard Workerfoo
447*1b3f573fSAndroid Build Coastguard Worker//%PDDM-EXPAND mumble(abc)
448*1b3f573fSAndroid Build Coastguard Worker//%PDDM-EXPAND-END mumble(abc)
449*1b3f573fSAndroid Build Coastguard Workerbar
450*1b3f573fSAndroid Build Coastguard Worker//%PDDM-EXPAND mumble(def)
451*1b3f573fSAndroid Build Coastguard Worker//%PDDM-EXPAND mumble(ghi)
452*1b3f573fSAndroid Build Coastguard Worker//%PDDM-EXPAND-END (2 expansions)
453*1b3f573fSAndroid Build Coastguard Workerbaz
454*1b3f573fSAndroid Build Coastguard Worker//%PDDM-DEFINE mumble(a_)
455*1b3f573fSAndroid Build Coastguard Worker//%a_: getName(a_)
456*1b3f573fSAndroid Build Coastguard Worker"""
457*1b3f573fSAndroid Build Coastguard Worker    def _Resolver(name):
458*1b3f573fSAndroid Build Coastguard Worker      self.assertEqual(name, 'ImportFile')
459*1b3f573fSAndroid Build Coastguard Worker      return io.StringIO(input_str2)
460*1b3f573fSAndroid Build Coastguard Worker    f = io.StringIO(input_str)
461*1b3f573fSAndroid Build Coastguard Worker    sf = pddm.SourceFile(f, _Resolver)
462*1b3f573fSAndroid Build Coastguard Worker    sf.ProcessContent()
463*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(sf.processed_content, expected)
464*1b3f573fSAndroid Build Coastguard Worker    # Feed it through and nothing should change.
465*1b3f573fSAndroid Build Coastguard Worker    f2 = io.StringIO(sf.processed_content)
466*1b3f573fSAndroid Build Coastguard Worker    sf2 = pddm.SourceFile(f2, _Resolver)
467*1b3f573fSAndroid Build Coastguard Worker    sf2.ProcessContent()
468*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(sf2.processed_content, expected)
469*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(sf2.processed_content, sf.processed_content)
470*1b3f573fSAndroid Build Coastguard Worker    # Test stripping (with the original input and expanded version).
471*1b3f573fSAndroid Build Coastguard Worker    f2 = io.StringIO(input_str)
472*1b3f573fSAndroid Build Coastguard Worker    sf2 = pddm.SourceFile(f2)
473*1b3f573fSAndroid Build Coastguard Worker    sf2.ProcessContent(strip_expansion=True)
474*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(sf2.processed_content, expected_stripped)
475*1b3f573fSAndroid Build Coastguard Worker    f2 = io.StringIO(sf.processed_content)
476*1b3f573fSAndroid Build Coastguard Worker    sf2 = pddm.SourceFile(f2, _Resolver)
477*1b3f573fSAndroid Build Coastguard Worker    sf2.ProcessContent(strip_expansion=True)
478*1b3f573fSAndroid Build Coastguard Worker    self.assertEqual(sf2.processed_content, expected_stripped)
479*1b3f573fSAndroid Build Coastguard Worker
480*1b3f573fSAndroid Build Coastguard Worker  def testProcessFileWithMacroParseError(self):
481*1b3f573fSAndroid Build Coastguard Worker    input_str = """
482*1b3f573fSAndroid Build Coastguard Workerfoo
483*1b3f573fSAndroid Build Coastguard Worker//%PDDM-DEFINE mumble(a_)
484*1b3f573fSAndroid Build Coastguard Worker//%body
485*1b3f573fSAndroid Build Coastguard Worker//%PDDM-DEFINE mumble(x_)
486*1b3f573fSAndroid Build Coastguard Worker//%body2
487*1b3f573fSAndroid Build Coastguard Worker
488*1b3f573fSAndroid Build Coastguard Worker"""
489*1b3f573fSAndroid Build Coastguard Worker    f = io.StringIO(input_str)
490*1b3f573fSAndroid Build Coastguard Worker    sf = pddm.SourceFile(f)
491*1b3f573fSAndroid Build Coastguard Worker    try:
492*1b3f573fSAndroid Build Coastguard Worker      sf.ProcessContent()
493*1b3f573fSAndroid Build Coastguard Worker      self.fail('Should throw exception! Test failed to catch macro parsing error.')
494*1b3f573fSAndroid Build Coastguard Worker    except pddm.PDDMError as e:
495*1b3f573fSAndroid Build Coastguard Worker      self.assertEqual(e.message,
496*1b3f573fSAndroid Build Coastguard Worker                       'Attempt to redefine macro: "PDDM-DEFINE mumble(x_)"\n'
497*1b3f573fSAndroid Build Coastguard Worker                       '...while parsing section that started:\n'
498*1b3f573fSAndroid Build Coastguard Worker                       '  Line 3: //%PDDM-DEFINE mumble(a_)')
499*1b3f573fSAndroid Build Coastguard Worker
500*1b3f573fSAndroid Build Coastguard Worker  def testProcessFileWithExpandError(self):
501*1b3f573fSAndroid Build Coastguard Worker    input_str = """
502*1b3f573fSAndroid Build Coastguard Workerfoo
503*1b3f573fSAndroid Build Coastguard Worker//%PDDM-DEFINE mumble(a_)
504*1b3f573fSAndroid Build Coastguard Worker//%body
505*1b3f573fSAndroid Build Coastguard Worker//%PDDM-EXPAND foobar(x_)
506*1b3f573fSAndroid Build Coastguard Worker//%PDDM-EXPAND-END
507*1b3f573fSAndroid Build Coastguard Worker
508*1b3f573fSAndroid Build Coastguard Worker"""
509*1b3f573fSAndroid Build Coastguard Worker    f = io.StringIO(input_str)
510*1b3f573fSAndroid Build Coastguard Worker    sf = pddm.SourceFile(f)
511*1b3f573fSAndroid Build Coastguard Worker    try:
512*1b3f573fSAndroid Build Coastguard Worker      sf.ProcessContent()
513*1b3f573fSAndroid Build Coastguard Worker      self.fail('Should throw exception! Test failed to catch expand error.')
514*1b3f573fSAndroid Build Coastguard Worker    except pddm.PDDMError as e:
515*1b3f573fSAndroid Build Coastguard Worker      self.assertEqual(e.message,
516*1b3f573fSAndroid Build Coastguard Worker                       'No macro named "foobar".\n'
517*1b3f573fSAndroid Build Coastguard Worker                       '...while expanding "foobar(x_)" from the section that'
518*1b3f573fSAndroid Build Coastguard Worker                       ' started:\n   Line 5: //%PDDM-EXPAND foobar(x_)')
519*1b3f573fSAndroid Build Coastguard Worker
520*1b3f573fSAndroid Build Coastguard Worker
521*1b3f573fSAndroid Build Coastguard Workerif __name__ == '__main__':
522*1b3f573fSAndroid Build Coastguard Worker  unittest.main()
523