3 from __future__ 
import print_function
     8 from xml.dom.minidom 
import parseString
    15 from cStringIO 
import StringIO
    16 from contextlib 
import contextmanager
    20 whitespace = re.compile(
r'\s+')
    23     if len(a.attributes) != len(b.attributes):
    24         print(
"Different number of attributes")
    26     a_atts = [(a.attributes.item(i).name, a.attributes.item(i).value) 
for i 
in range(len(a.attributes))]
    27     b_atts = [(b.attributes.item(i).name, b.attributes.item(i).value) 
for i 
in range(len(b.attributes))]
    31     for i 
in range(len(a_atts)):
    32         if a_atts[i][0] != b_atts[i][0]:
    33             print(
"Different attribute names: %s and %s" % (a_atts[i][0], b_atts[i][0]))
    36             if abs(float(a_atts[i][1]) - float(b_atts[i][1])) > 1.0e-9:
    37                 print(
"Different attribute values: %s and %s" % (a_atts[i][1], b_atts[i][1]))
    40             if a_atts[i][1] != b_atts[i][1]:
    41                 print(
"Different attribute values: %s and %s" % (a_atts[i][1], b_atts[i][1]))
    47     a_norm = whitespace.sub(
' ', a)
    48     b_norm = whitespace.sub(
' ', b)
    49     if a_norm.strip() == b_norm.strip(): 
return True    50     print(
"Different text values: '%s' and '%s'" % (a, b))
    59     if a.nodeType != b.nodeType:
    60         print(
"Different node types: %s and %s" % (a, b))
    64     if a.nodeType 
in [xml.dom.Node.TEXT_NODE,
    65                       xml.dom.Node.CDATA_SECTION_NODE,
    66                       xml.dom.Node.COMMENT_NODE]:
    70     if a.nodeType != xml.dom.Node.ELEMENT_NODE:
    74     if a.nodeName != b.nodeName:
    75         print(
"Different element names: %s and %s" % (a.nodeName, b.nodeName))
    87                ((a.nodeType 
in ignore_nodes) 
or    88                 (a.nodeType == xml.dom.Node.TEXT_NODE 
and whitespace.sub(
'', a.data) == 
""))):
    91                ((b.nodeType 
in ignore_nodes) 
or    92                 (b.nodeType == xml.dom.Node.TEXT_NODE 
and whitespace.sub(
'', b.data) == 
""))):
    98         if a: a = a.nextSibling
    99         if b: b = b.nextSibling
   105     if isinstance(a, str):
   106         return xml_matches(parseString(a).documentElement, b, ignore_nodes)
   107     if isinstance(b, str):
   108         return xml_matches(a, parseString(b).documentElement, ignore_nodes)
   109     if a.nodeType == xml.dom.Node.DOCUMENT_NODE:
   110         return xml_matches(a.documentElement, b, ignore_nodes)
   111     if b.nodeType == xml.dom.Node.DOCUMENT_NODE:
   112         return xml_matches(a, b.documentElement, ignore_nodes)
   115         print(
"Match failed:")
   116         a.writexml(sys.stdout)
   119         b.writexml(sys.stdout)
   128   old, sys.stderr = sys.stderr, StringIO()  
   129   result = function(*args, **kwargs)
   131   yield (result, sys.stderr.read())
   139         self.assertTrue(
text_matches(
" foo bar ", 
"foo \t\n\r bar"))
   142         self.assertTrue(
xml_matches(
'''<foo/>''', 
'''<foo> \t\n\r </foo>'''))
   144         self.assertTrue(
xml_matches(
'''<foo> \t\n\r </foo>''', 
'''<foo/>'''))
   146         self.assertTrue(
xml_matches(
'''<a><b/></a>''', 
'''<a>\n<b> </b> </a>'''))
   149         self.assertTrue(
xml_matches(
'''<a><b/><!-- foo --> <!-- bar --></a>''',
   150                                     '''<a><b/></a>''', [xml.dom.Node.COMMENT_NODE]))
   169         content = {
'xacro:simple': 
'simple'}
   170         ns2 = dict({k: v+
'2' for k,v 
in content.iteritems()})
   171         ns1 = dict({k: v+
'1' for k,v 
in content.iteritems()})
   173         macros = dict(content)
   174         macros.update(ns1=ns1)
   186         self.assertEqual(p, param, msg=
"'{0}' != '{1}' parsing {2}".format(p, param, s))
   187         if forward 
or default:
   188             self.assertTrue(v 
is not None)
   189             self.assertEqual(v[0], forward, msg=
"'{0}' != '{1}' parsing {2}".format(v[0], forward, s))
   190             self.assertEqual(v[1], default, msg=
"'{0}' != '{1}' parsing {2}".format(v[1], default, s))
   192             self.assertTrue(v 
is None)
   193         self.assertEqual(r, rest, msg=
"'{0}' != '{1}' parsing {2}".format(r, rest, s))
   196         for forward 
in [
'', 
'^', 
'^|']:
   197             defaults = [
'', 
"f('some string','some other')", 
"f('a b')"]
   198             if forward == 
'^': defaults = [
'']
   199             for default 
in defaults:
   200                 seps = [
'=', 
':='] 
if forward 
or default 
else [
'']
   202                     for rest 
in [
'', 
' ', 
' bar', 
' bar=42']:
   203                         s = 
'foo{0}{1}{2}{3}'.format(sep, forward, default, rest)
   205                                              default 
if default 
else None,
   208         for ws 
in [
'  ', 
' \t ', 
' \n ']:
   209             self.
check_macro_arg(ws + 
'foo' + ws + 
'bar=42' + ws, 
'foo', 
None, 
None, 
'bar=42' + ws)
   214         super(TestXacroBase, self).
__init__(*args, **kwargs)
   225             args.update(vars(opts))  
   226         args.update(dict(in_order = self.
in_order))  
   236             args.append(
'--inorder')
   237         test_dir = os.path.abspath(os.path.dirname(__file__))
   238         xacro_path = os.path.join(test_dir, 
'..', 
'scripts', 
'xacro')
   239         subprocess.call([xacro_path, input_path] + args)
   245         super(TestXacroCommentsIgnored, self).
__init__(*args, **kwargs)
   250         test_dir= os.path.abspath(os.path.dirname(__file__))
   251         pr2_xacro_path = os.path.join(test_dir, 
'robots', 
'pr2', 
'pr2.urdf.xacro')
   252         pr2_golden_parse_path = os.path.join(test_dir, 
'robots', 
'pr2', 
'pr2_1.11.4.xml')
   254                 xml.dom.minidom.parse(pr2_golden_parse_path),
   261         super(TestXacroCommentsIgnored, self).
__init__(*args, **kwargs)
   265         src = 
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   266         <xacro:property name="invalid.name"/></a>'''   270         src = 
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   271   <xacro:macro name="foo"><a>foo</a></xacro:macro>   272   <xacro:macro name="bar"><b>bar</b></xacro:macro>   273   <xacro:property name="var" value="%s"/>   274   <xacro:call macro="${var}"/></a>'''   275         res = 
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">%s</a>'''   280         src = 
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   281   <xacro:macro name="foo"><a name="foo"/></xacro:macro>   282   <xacro:macro name="call"><a name="bar"/></xacro:macro>   286         res = 
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro"><a name="bar"/></a>'''   291             self.assertTrue(
"deprecated use of macro name 'call'" in output)
   296                           '''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   297                           <xacro:call macro="foo"/></a>''')
   302                           '''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   303                           <xacro:undefined><foo/><bar/></xacro:undefined></a>''')
   306         src = 
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   307   <xacro:macro name="foo" params="name"><xacro:element xacro:name="${name}"/></xacro:macro>   308   <xacro:foo name="A"/>   309   <xacro:foo name="B"/>   311         res = 
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro"><A/><B/></a>'''   315         src = 
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   316   <xacro:macro name="foo" params="name value">   317   <tag><xacro:attribute name="${name}" value="${value}"/></tag>   319   <xacro:foo name="A" value="foo"/>   320   <xacro:foo name="B" value="bar"/>   322         res = 
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro"><tag A="foo"/><tag B="bar"/></a>'''   326         src = 
'''<xml xmlns:xacro="http://www.ros.org/wiki/xacro">   327   <xacro:property name="foo" value="1.0"/>   328   <xacro:macro name="m" params="foo"><a foo="${foo}"/></xacro:macro>   329   <xacro:m foo="1 ${foo}"/>   330   <!-- now redefining the property and macro -->   331   <xacro:property name="foo" value="2.0"/>   332   <xacro:macro name="m" params="foo"><b bar="${foo}"/></xacro:macro>   333   <xacro:m foo="2 ${foo}"/>   336 <xml xmlns:xacro="http://www.ros.org/wiki/xacro">   342 <xml xmlns:xacro="http://www.ros.org/wiki/xacro">   351                 self.
quick_xacro(
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   352 <xacro:macro name="inner" params="*the_block">   353   <in_the_inner><xacro:insert_block name="the_block" /></in_the_inner>   355 <xacro:macro name="outer" params="*the_block">   356   <in_the_outer><xacro:inner><xacro:insert_block name="the_block" /></xacro:inner></in_the_outer>   358 <xacro:outer><woot /></xacro:outer></a>'''),
   359                 '''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   360 <in_the_outer><in_the_inner><woot /></in_the_inner></in_the_outer></a>''')
   364   <xacro:macro name="foo" params="lst">${lst[-1]}</xacro:macro>   365   <foo lst="${[1,2,3]}"/></a>'''),
   366         '''<a xmlns:xacro="http://www.ros.org/wiki/xacro">3</a>''')
   370                 self.
quick_xacro(
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   371   <xacro:property name="foo" value="42" />   372   <the_foo result="${foo}" />   374                 '''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   375   <the_foo result="42" />   380   <xacro:macro name="foo" params="factor">   381   <xacro:property name="foo" value="${21*factor}" scope="parent"/>   383   <xacro:foo factor="2"/><a foo="${foo}"/></a>'''),
   384         '''<a xmlns:xacro="http://www.ros.org/wiki/xacro"><a foo="42"/></a>''')
   388   <xacro:macro name="foo" params="factor">   389     <xacro:macro name="bar">   390       <xacro:property name="foo" value="${21*factor}" scope="global"/>   394   <xacro:foo factor="2"/><a foo="${foo}"/></a>'''),
   395         '''<a xmlns:xacro="http://www.ros.org/wiki/xacro"><a foo="42"/></a>''')
   399                 self.
quick_xacro(
'''<a><f v="${0.9 / 2 - 0.2}" /></a>'''),
   400                 '''<a><f v="0.25" /></a>''')
   404                 self.
quick_xacro(
'''<a><f v="$(find xacro)/test/test_xacro.py" /></a>'''),
   405                 '''<a><f v="''' + os.path.abspath((__file__).replace(
".pyc",
".py") + 
'''" /></a>'''))
   409                 self.
quick_xacro(
'''<a><f v="$(arg sub_arg)" /></a>''', cli=[
'sub_arg:=my_arg']),
   410                 '''<a><f v="my_arg" /></a>''')
   414                 self.
quick_xacro(
'''<a b="$${foo}" c="$$${foo}" />'''),
   415                 '''<a b="${foo}" c="$${foo}" />''')
   424                 self.
quick_xacro(
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   425 <xacro:macro name="foo" params="*block">   426   <xacro:insert_block name="block" />   427   <xacro:insert_block name="block" />   433                 '''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   439         src = 
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   440 <xacro:macro name="foo" params="*block{A} *block{B}">   441   <xacro:insert_block name="block1" />   442   <xacro:insert_block name="block2" />   449         res = 
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   454         for d 
in [dict(A=
'1', B=
'2'), dict(A=
'2', B=
'1')]:
   459                 self.
quick_xacro(
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   460 <xacro:macro name="m" params="num">   461   <test number="${num}" />   463 <xacro:m num="100" />   465                 '''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   466   <test number="100" />   471                 self.
quick_xacro(
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   472 <xacro:macro name="bar">bar</xacro:macro>   473 <xacro:property name="val" value="2" />   474 <xacro:property name="some_block">   475   <some_block attr="${val}"><xacro:bar/></some_block>   478   <xacro:insert_block name="some_block" />   481                 '''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   482 <foo><some_block attr="2">bar</some_block></foo>   487 <a xmlns:xacro="http://www.ros.org/xacro">   488   <xacro:include filename="include1.xml" /></a>'''),
   489                         '''<a xmlns:xacro="http://www.ros.org/xacro"><inc1/></a>''')
   492         input  = 
'''<a xmlns:xacro="http://www.ros.org/xacro">   493                     <xacro:include filename="include{glob}.xml"/></a>'''   494         result = 
'<a xmlns:xacro="http://www.ros.org/xacro"><inc1/><inc2/></a>'   495         for pattern 
in [
'*', 
'?', 
'[1-2]']:
   500                           self.
quick_xacro, 
'''<a xmlns:xacro="http://www.ros.org/xacro">   501                              <xacro:include filename="include-nada.xml" /></a>''')
   505         src = 
'''<a><include filename="nada"><tag/></include></a>'''   508             self.assertEqual(output, 
'')
   511         doc = 
'''<a xmlns:xacro="http://www.ros.org/xacro">   512         <xacro:property name="file" value="include1.xml"/>   513         <xacro:include filename="${file}" /></a>'''   516                 '''<a xmlns:xacro="http://www.ros.org/xacro"><inc1/></a>''')
   522 <a xmlns:xacro="http://www.ros.org/xacro">   523     <xacro:include filename="include1.xml"/>   524     <xacro:include filename="./include1.xml"/>   525     <xacro:include filename="subdir/include-recursive.xacro"/>   527 '''<a xmlns:xacro="http://www.ros.org/xacro">   529 <subdir_inc1/><subdir_inc1/><inc1/></a>''')
   533 <a xmlns:xacro="http://www.ros.org/wiki/xacro">   534   <xacro:property name="var" value="main"/>   535   <xacro:include filename="include1.xacro" ns="A"/>   536   <xacro:include filename="include2.xacro" ns="B"/>   538   <main var="${var}" A="${2*A.var}" B="${B.var+1}"/>   541 <a xmlns:xacro="http://www.ros.org/wiki/xacro">   542     <inc1/><inc2/><main var="main" A="2" B="3"/>   553 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   554   <xacro:if value="false">   557   <xacro:if value="true">   562 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   569                           '''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   570                           <xacro:if value="nonsense"><foo/></xacro:if></a>''')
   575 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   576   <xacro:if value="${0*42}">   582   <xacro:if value="${0}">   585   <xacro:if value="${1*2+3}">   590 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   597 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   598   <xacro:if value="${3*0.0}">   601   <xacro:if value="${3*0.1}">   606 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   613 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   614   <xacro:property name="condT" value="${True}"/>   615   <xacro:property name="condF" value="${False}"/>   616   <xacro:if value="${condF}"><a /></xacro:if>   617   <xacro:if value="${condT}"><b /></xacro:if>   618   <xacro:if value="${True}"><c /></xacro:if>   621 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   627 <a xmlns:xacro="http://www.ros.org/wiki/xacro">   628   <xacro:if value="1"><xacro:if value="0"><a>bar</a></xacro:if></xacro:if>   630 '''<a xmlns:xacro="http://www.ros.org/wiki/xacro"/>''')
   634 <a xmlns:xacro="http://www.ros.org/wiki/xacro">   635   <xacro:property name="var" value="useit"/>   636   <xacro:if value="${var == 'useit'}"><foo>bar</foo></xacro:if>   637   <xacro:if value="${'use' in var}"><bar>foo</bar></xacro:if>   639 '''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   646 <a xmlns:xacro="http://www.ros.org/wiki/xacro">   647   <xacro:property name="xyz" value="5 -2"/>   650 '''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   656 <a xmlns:xacro="http://www.ros.org/wiki/xacro">   657   <foo function="${1. + sin(pi)}"/>   659 '''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   660   <foo function="1.0"/>   665 <a xmlns:xacro="http://www.ros.org/wiki/xacro">   666   <xacro:if value="1"><!-- comment --> text <b>bar</b></xacro:if>   668 '''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   669 <!-- comment --> text <b>bar</b></a>''')
   673                 self.
quick_xacro(
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   674 <xacro:macro name="foo" params="*block">   677   <xacro:insert_block name="block" />   680   <!-- ignored comment -->   685                 '''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   693 <a xmlns:xacro="http://www.ros.org/wiki/xacro">   696   <!-- ignore multiline comments before any xacro tag -->   698   <xacro:property name="foo" value="1"/>   700   <xacro:if value="1"><!-- B --></xacro:if>   702   <xacro:macro name="foo"><!-- C --></xacro:macro>   706 '''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   707 <!-- A --><!-- B --><!-- C --></a>''')
   712 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   713   <xacro:property name="a" value=" 42 "/>   714   <xacro:property name="a2" value="${ 2 * a }"/>   718 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   725 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   726   <xacro:property name="a2" value="${2*a}"/>   727   <xacro:property name="a" value="42"/>   731 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   738 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   739   <xacro:property name="a" value="${a2}"/>   740   <xacro:property name="a2" value="${2*a}"/>   747 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   748   <xacro:property name="a" value="1"/>   749   <xacro:property name="b" value="2"/>   750   <xacro:property name="c" value="3"/>   751   <xacro:property name="product" value="${a*b*c}"/>   752   <answer product="${product}"/>   755 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   756   <answer product="6"/>   762 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   763   <xacro:property name="a" value="42"/>   764   <xacro:property name="b" value="${a}"/>   765   <xacro:property name="b" value="${-a}"/>   766   <xacro:property name="b" value="${a}"/>   767   <answer b="${b} ${b} ${b}"/>   770 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   771   <answer b="42 42 42"/>   777 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   778   <xacro:property name="a" value="42"/>   779   <xacro:property name="b" value="${a}"/>   780   <xacro:property name="c" value="${b}"/>   781   <xacro:property name="d" value="${c}"/>   785 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   792 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   793   <xacro:property name="a" value="42"/>   794   <xacro:property name="b" value="2.1"/>   795   <xacro:property name="c" value="${a}"/>   796   <xacro:property name="d" value="${b}"/>   797   <xacro:property name="f" value="${c*d}"/>   801 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   808 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   809   <xacro:property name="x" value="42"/>   810   <xacro:property name="wheel_width" value="${x}"/>   811   <link name="my_link">   812     <origin xyz="0 0 ${wheel_width/2}"/>   816 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   817   <link name="my_link">   818     <origin xyz="0 0 21.0"/>   825 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   826   <xacro:property name="x" value="0"/>   827   <tag badness="${1/x}"/>   833 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   834   <xacro:macro name="fixed_link" params="parent_link:=base_link child_link *joint_pose">   835     <link name="${child_link}"/>   836     <joint name="${child_link}_joint" type="fixed">   837       <xacro:insert_block name="joint_pose" />   838       <parent link="${parent_link}"/>   839       <child link="${child_link}" />   842   <xacro:fixed_link child_link="foo">   843     <origin xyz="0 0 0" rpy="0 0 0" />   847 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   849   <joint name="foo_joint" type="fixed">   850     <origin rpy="0 0 0" xyz="0 0 0"/>   851     <parent link="base_link"/>   859 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   860   <xacro:macro name="fixed_link" params="parent_link:=base_link child_link *joint_pose">   861     <link name="${child_link}"/>   862     <joint name="${child_link}_joint" type="fixed">   863       <xacro:insert_block name="joint_pose" />   864       <parent link="${parent_link}"/>   865       <child link="${child_link}" />   868   <xacro:fixed_link child_link="foo" parent_link="bar">   869     <origin xyz="0 0 0" rpy="0 0 0" />   873 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   875   <joint name="foo_joint" type="fixed">   876     <origin rpy="0 0 0" xyz="0 0 0"/>   885 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   886   <xacro:macro name="fixed_link" params="parent_link child_link *joint_pose">   887     <link name="${child_link}"/>   888     <joint name="${child_link}_joint" type="fixed">   889       <xacro:insert_block name="joint_pose" />   890       <parent link="${parent_link}"/>   891       <child link="${child_link}" />   894   <xacro:fixed_link child_link="foo">   895     <origin xyz="0 0 0" rpy="0 0 0" />   902 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   903   <xacro:arg name="foo" default="2"/>   904   <link name="my_link">   905     <origin xyz="0 0 $(arg foo)"/>   909 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   910   <link name="my_link">   911     <origin xyz="0 0 2"/>   918 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   919   <xacro:arg name="foo" default="2"/>   920   <link name="my_link">   921     <origin xyz="0 0 $(arg foo)"/>   924 ''', [
'foo:=4']),
'''\   925 <robot xmlns:xacro="http://www.ros.org/wiki/xacro">   926   <link name="my_link">   927     <origin xyz="0 0 4"/>   932         self.assertRaises(Exception,
   934 <a xmlns:xacro="http://www.ros.org/wiki/xacro">   935   <a arg="$(arg foo)"/>   941 <a xmlns:xacro="http://www.ros.org/wiki/xacro">   942 <xacro:arg name="foo" default=""/>$(arg foo)</a>'''),
   943                             '''<a xmlns:xacro="http://www.ros.org/wiki/xacro"/>''')
   948         tmp_dir_name = tempfile.mkdtemp() 
   949         output_path = os.path.join(tmp_dir_name, 
"should_not_exist")
   950         self.
run_xacro(
'broken.xacro', 
'-o', output_path)
   952         output_file_created = os.path.isfile(output_path)
   953         shutil.rmtree(tmp_dir_name) 
   955         self.assertFalse(output_file_created)
   960         tmp_dir_name = tempfile.mkdtemp() 
   961         shutil.rmtree(tmp_dir_name) 
   962         output_path = os.path.join(tmp_dir_name, 
"out")
   963         self.
run_xacro(
'include1.xml', 
'-o', output_path)
   965         output_file_created = os.path.isfile(output_path)
   966         shutil.rmtree(tmp_dir_name) 
   968         self.assertTrue(output_file_created)
   973 <a xmlns:xacro="http://www.ros.org/wiki/xacro">   974   <xacro:property name="list" value="[0, 1+1, 2]"/>   975   <xacro:property name="tuple" value="(0,1+1,2)"/>   976   <xacro:property name="dict" value="{'a':0, 'b':1+1, 'c':2}"/>   977   <a list="${list}" tuple="${tuple}" dict="${dict}"/>   979 '''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   980   <a list="[0, 1+1, 2]" tuple="(0,1+1,2)" dict="{'a':0, 'b':1+1, 'c':2}"/>   986 <a xmlns:xacro="http://www.ros.org/wiki/xacro">   987   <xacro:property name="list" value="${[0, 1+1, 2]}"/>   988   <xacro:property name="tuple" value="${(0,1+1,2)}"/>   989   <xacro:property name="dic" value="${dict(a=0, b=1+1, c=2)}"/>   990   <a list="${list}" tuple="${tuple}" dict="${dic}"/>   992 '''<a xmlns:xacro="http://www.ros.org/wiki/xacro">   993   <a list="[0, 2, 2]" tuple="(0, 2, 2)" dict="{'a': 0, 'c': 2, 'b': 2}"/>   999 <a xmlns:xacro="http://www.ros.org/wiki/xacro">  1000   <arg name="foo" value="bar"/>  1001   <include filename="foo"/>  1002 </a>''', xacro_ns=
False),
  1004 <a xmlns:xacro="http://www.ros.org/wiki/xacro">  1005   <arg name="foo" value="bar"/>  1006   <include filename="foo"/>  1015 <a xmlns:xacro="http://www.ros.org/wiki/xacro">  1016   <xacro:arg name="foo" default="0.5"/>  1017   <xacro:property name="prop" value="$(arg foo)" />  1018   <a prop="${prop-0.3}"/>  1021 <a xmlns:xacro="http://www.ros.org/wiki/xacro">  1028 <a xmlns:xacro="http://www.ros.org/wiki/xacro">  1029   <xacro:arg name="foo" default="0.5"/>  1030   <xacro:arg name="bar" default="$(arg foo)"/>  1031   <xacro:property name="prop" value="$(arg bar)" />  1032   <a prop="${prop-0.3}"/>  1035 <a xmlns:xacro="http://www.ros.org/wiki/xacro">  1040         src = 
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">  1041         <xacro:macro name="xacro:my_macro"><foo/></xacro:macro>  1044         res = 
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro"><foo/></a>'''  1048         src = 
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">  1049         <xacro:property name="pi"  value="3.14"/></a>'''  1051             self.
assert_matches(result, 
'<a xmlns:xacro="http://www.ros.org/wiki/xacro"/>')
  1052             self.assertTrue(output)
  1056 <a xmlns:xacro="http://www.ros.org/xacro">  1057   <xacro:macro name="foo" params="a b:=${a} c:=$${a}"> a=${a} b=${b} c=${c} </xacro:macro>  1058   <xacro:property name="a" value="1"/>  1059   <xacro:property name="d" value="$${a}"/>  1060   <d d="${d}"><foo a="2"/></d>  1062         res = 
'''<a xmlns:xacro="http://www.ros.org/xacro"><d d="${a}"> a=2 b=1 c=${a} </d></a>'''  1066         src=
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">  1067         <xacro:property name="arg" value="42"/>  1068         <xacro:macro name="foo" params="arg:=^%s">${arg}</xacro:macro>  1071         res=
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">%s</a>'''  1077         src=
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">${2*'$(arg var)'}</a>'''  1078         res=
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">%s</a>'''  1082         src=
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">$(arg ${'v'+'ar'})</a>'''  1083         res=
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">%s</a>'''  1089         super(TestXacroInorder, self).
__init__(*args, **kwargs)
  1093         doc = (
'''<a xmlns:xacro="http://www.ros.org/xacro">  1094         <xacro:if value="false"><xacro:include filename="non-existent"/></xacro:if></a>''')
  1096                         '''<a xmlns:xacro="http://www.ros.org/xacro"/>''')
  1101 <a xmlns:xacro="http://www.ros.org/wiki/xacro">  1102   <xacro:arg name="has_stuff" default="false"/>  1103   <xacro:if value="$(arg has_stuff)">  1104     <xacro:include file="$(find nonexistent_package)/stuff.urdf" />  1107 '<a xmlns:xacro="http://www.ros.org/wiki/xacro"/>')
  1111 <a xmlns:xacro="http://www.ros.org/wiki/xacro">  1112   <xacro:property name="settings" value="${load_yaml('settings.yaml')}"/>  1113   <xacro:property name="type" value="$(arg type)"/>  1114   <xacro:include filename="${settings['arms'][type]['file']}"/>  1115   <xacro:call macro="${settings['arms'][type]['macro']}"/>  1117         res = 
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro"><{tag}/></a>'''  1118         for i 
in [
'inc1', 
'inc2']:
  1123         src=
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">  1124 <xacro:macro name="foo" params="arg:=${2*foo}">  1125     <xacro:property name="foo" value="-"/>  1128 <xacro:property name="foo" value="${3*7}"/>  1130 <xacro:property name="foo" value="*"/>  1133         res=
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">  1134 <f val="42"/><f val="**"/></a>'''  1138         src = 
'''<a xmlns:xacro="http://www.ros.org/wiki/xacro">  1139 <xacro:property name="bar" value="unused"/>  1140 <xacro:property name="foo" value="unused"/>  1141 <xacro:macro name="foo" params="arg:=${foo}">  1145 <xacro:property name="bar" value="dummy"/>  1146 <xacro:property name="foo" value="21"/></a>'''  1148             self.assertTrue(
"Document is incompatible to --inorder processing." in output)
  1149             self.assertTrue(
"foo" in output)  
  1150             self.assertTrue(
"bar" not in output)  
  1154         <a xmlns:xacro="http://www.ros.org/xacro">  1155             <xacro:property name="prop" default="false"/>  1156             <xacro:unless value="${prop}">  1158                 <xacro:property name="prop" value="true"/>  1161             <!-- second foo should be ignored -->  1162             <xacro:unless value="${prop}">  1164                 <xacro:property name="prop" value="true"/>  1167         res = 
'''<a xmlns:xacro="http://www.ros.org/xacro"><foo/></a>'''  1171 if __name__ == 
'__main__':
 def test_from_issue(self)
 
def parse(inp, filename=None)
 
def test_include_lazy(self)
 
def test_multiple_blocks(self)
 
def test_extension_in_expression(self)
 
def test_normalize_whitespace_nested(self)
 
def test_default_arg_empty(self)
 
def test_xacro_attribute(self)
 
def test_include_from_variable(self)
 
def test_recursive_bad_math(self)
 
def test_whitespace_vs_empty_node(self)
 
def __init__(self, args, kwargs)
 
def assert_matches(self, a, b)
 
def test_property_scope_global(self)
 
def test_include_deprecated(self)
 
def test_equality_expression_in_if_statement(self)
 
def test_parse_macro_whitespace(self)
 
def test_default_param_override(self)
 
def test_multiple_definition_and_evaluation(self)
 
def process_doc(doc, in_order=False, just_deps=False, just_includes=False, mappings=None, xacro_ns=True, kwargs)
 
def test_evaluate_macro_params_before_body(self)
 
def test_broken_input_doesnt_create_empty_output_file(self)
 
def test_math_ignores_spaces(self)
 
def test_include_recursive(self)
 
def test_multiple_insert_blocks(self)
 
def test_math_expressions(self)
 
def test_boolean_if_statement(self)
 
def test_param_missing(self)
 
def test_consider_non_elements_block(self)
 
def test_recursive_evaluation_wrong_order(self)
 
def test_integer_if_statement(self)
 
def __init__(self, args, kwargs)
 
def test_overwrite_globals(self)
 
def capture_stderr(function, args, kwargs)
 
def test_default_property(self)
 
def resolve_macro(fullname, macros)
 
def test_consecutive_if(self)
 
def test_is_valid_name(self)
 
def test_issue_63_fixed_with_inorder_processing(self)
 
def test_recursive_definition(self)
 
def test_macro_name_with_colon(self)
 
def test_default_param(self)
 
def test_yaml_support(self)
 
def test_property_forwarding(self)
 
def test_create_subdirs(self)
 
def test_invalid_property_name(self)
 
def test_transitive_evaluation(self)
 
def run_xacro(self, input_path, args)
 
def test_no_evaluation(self)
 
def test_parse_macro_arg(self)
 
def test_multi_tree_evaluation(self)
 
def test_include_nonexistent(self)
 
def test_float_if_statement(self)
 
def xml_matches(a, b, ignore_nodes=[])
 
def test_substitution_args_arg(self)
 
def test_default_arg_override(self)
 
def test_iterable_literals_eval(self)
 
def test_include_glob(self)
 
def test_macro_default_param_evaluation_order(self)
 
def test_consider_non_elements_if(self)
 
def test_integer_stays_integer(self)
 
def test_macro_undefined(self)
 
def test_multiple_recursive_evaluation(self)
 
def all_attributes_match(a, b)
 
def test_dynamic_macro_name_clash(self)
 
def test_substitution_args_find(self)
 
def test_insert_block_property(self)
 
def test_include_with_namespace(self)
 
def test_default_arg(self)
 
def test_recursive_evaluation(self)
 
def test_property_scope_parent(self)
 
def test_no_double_evaluation(self)
 
def test_normalize_whitespace_text(self)
 
def test_expression_in_extension(self)
 
def process_args(argv, require_input=True)
 
def test_transitive_arg_evaluation(self)
 
def test_xacro_element(self)
 
def test_property_replacement(self)
 
def test_ignore_comments(self)
 
def test_enforce_xacro_ns(self)
 
def test_ignore_xacro_comments(self)
 
def test_dynamic_macro_names(self)
 
def test_inorder_processing(self)
 
def test_issue_68_numeric_arg(self)
 
def test_invalid_if_statement(self)
 
def test_just_a_dollar_sign(self)
 
def test_should_replace_before_macroexpand(self)
 
def test_normalize_whitespace_trim(self)
 
def test_empty_node_vs_whitespace(self)
 
def test_escaping_dollar_braces(self)
 
def quick_xacro(self, xml, cli=None, kwargs)
 
def check_macro_arg(self, s, param, forward, default, rest)
 
def test_dynamic_macro_undefined(self)
 
def test_resolve_macro(self)
 
def __init__(self, args, kwargs)
 
def test_default_arg_missing(self)
 
def test_iterable_literals_plain(self)
 
def test_check_order_warning(self)
 
def nodes_match(a, b, ignore_nodes)