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)