1#!/pxrpythonsubst
2#
3# Copyright 2017 Pixar
4#
5# Licensed under the Apache License, Version 2.0 (the "Apache License")
6# with the following modification; you may not use this file except in
7# compliance with the Apache License and the following modification to it:
8# Section 6. Trademarks. is deleted and replaced with:
9#
10# 6. Trademarks. This License does not grant permission to use the trade
11#    names, trademarks, service marks, or product names of the Licensor
12#    and its affiliates, except as required to comply with Section 4(c) of
13#    the License and to reproduce the content of the NOTICE file.
14#
15# You may obtain a copy of the Apache License at
16#
17#     http://www.apache.org/licenses/LICENSE-2.0
18#
19# Unless required by applicable law or agreed to in writing, software
20# distributed under the Apache License with the above modification is
21# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
22# KIND, either express or implied. See the Apache License for the specific
23# language governing permissions and limitations under the Apache License.
24
25import sys, os, traceback, unittest
26from pxr import Sdf, Tf
27
28EmptyType = 1
29RootType = 2
30PrimType = 4
31PropertyType = 8
32PrimPropertyType = 16
33RelationalAttributeType = 32
34TargetType = 64
35MapperType = 128
36MapperArgType = 256
37ExpressionType = 512
38NamespacedPropertyType = 1024
39
40def _CheckPath(path, path2, parentPath, pathStr, pathElems, pathFlags, name, targetPath):
41    # Check absolute root.
42    if pathStr == "/":
43        assert path.IsAbsoluteRootPath()
44    else:
45        assert not path.IsAbsoluteRootPath()
46
47    # Check equality with another one constructed the same way
48    assert path == path2
49
50    # Check properties
51    assert path.pathString == pathStr
52    assert path.name == name
53    assert path.pathElementCount == len(pathElems)
54    assert path.targetPath == targetPath
55
56    # Check queries
57    assert path.IsAbsolutePath() == pathStr.startswith("/")
58    assert path.IsPrimPath() == (((pathFlags & PrimType) or (path == Sdf.Path.reflexiveRelativePath)) != 0 )
59    if path.IsPrimPath():
60        assert not path.ContainsPropertyElements()
61    assert path.IsRootPrimPath() == ((pathFlags & PrimType) != 0 and (len(pathElems) is 1))
62    assert path.IsPropertyPath() == ((pathFlags & PropertyType) != 0)
63    if (pathFlags & NamespacedPropertyType) != 0:
64        assert path.IsNamespacedPropertyPath() == ((pathFlags & NamespacedPropertyType) != 0)
65        assert path.ContainsPropertyElements()
66    if (pathFlags & PrimPropertyType) != 0:
67        assert path.IsPrimPropertyPath() == ((pathFlags & PrimPropertyType) != 0)
68        assert path.ContainsPropertyElements()
69    if (pathFlags & RelationalAttributeType) != 0:
70        assert path.IsRelationalAttributePath() == ((pathFlags & RelationalAttributeType) != 0)
71        assert path.IsTargetPath() == ((pathFlags & TargetType) != 0)
72        assert path.IsMapperPath() == ((pathFlags & MapperType) != 0)
73        assert path.IsMapperArgPath() == ((pathFlags & MapperArgType) != 0)
74        assert path.IsExpressionPath() == ((pathFlags & ExpressionType) != 0)
75        assert path.ContainsPropertyElements()
76
77    if pathFlags & (TargetType | MapperType | MapperArgType):
78        assert path.ContainsTargetPath()
79        assert path.ContainsPropertyElements()
80
81    # Check path elements
82    prefixes = Sdf._PathElemsToPrefixes(path.IsAbsolutePath(), pathElems)
83    assert path.GetPrefixes() == prefixes
84
85    # Check parent
86    assert path.GetParentPath() == parentPath
87
88    # Make sure all parent prefixes are recognized as prefixes, and that
89    # each prefix (including terminal) is reconstructible from its string
90    # element representation
91    currPath = path
92    while (parentPath != Sdf.Path.emptyPath) and (parentPath.name != Sdf.Path.parentPathElement):
93        currElement = currPath.elementString
94        reconPath = parentPath.AppendElementString(currElement)
95        assert(path.HasPrefix(parentPath))
96        assert reconPath == currPath
97        currPath = parentPath
98        parentPath = parentPath.GetParentPath()
99
100def CheckEmptyPath(path):
101    _CheckPath(path, Sdf.Path.emptyPath, Sdf.Path.emptyPath, "", [], EmptyType, "", Sdf.Path.emptyPath)
102    assert path == Sdf.Path()
103
104def CheckRootPath(path, path2, pathStr):
105    if pathStr == "/":
106        parent = Sdf.Path.emptyPath
107    else:
108        parent = path.AppendChild(Sdf.Path.parentPathElement)
109    _CheckPath(path, path2, parent, pathStr, [], RootType, pathStr, Sdf.Path.emptyPath)
110
111def CheckPrimPath(path, path2, parentPath, pathStr, pathElems, name):
112    _CheckPath(path, path2, parentPath, pathStr, pathElems, PrimType, name, Sdf.Path.emptyPath)
113
114def CheckPrimPropertyPath(path, path2, parentPath, pathStr, pathElems, name):
115    _CheckPath(path, path2, parentPath, pathStr, pathElems, PropertyType | PrimPropertyType, name, Sdf.Path.emptyPath)
116
117def CheckPrimNamespacedPropertyPath(path, path2, parentPath, pathStr, pathElems, name):
118    _CheckPath(path, path2, parentPath, pathStr, pathElems, PropertyType | PrimPropertyType | NamespacedPropertyType, name, Sdf.Path.emptyPath)
119
120def CheckTargetPath(path, path2, parentPath, pathStr, pathElems, targetPath):
121    _CheckPath(path, path2, parentPath, pathStr, pathElems, TargetType, "", targetPath)
122
123def CheckRelationalAttributePath(path, path2, parentPath, pathStr, pathElems, name):
124    _CheckPath(path, path2, parentPath, pathStr, pathElems, PropertyType | RelationalAttributeType, name, parentPath.targetPath)
125
126def CheckRelationalNamespacedAttributePath(path, path2, parentPath, pathStr, pathElems, name):
127    _CheckPath(path, path2, parentPath, pathStr, pathElems, PropertyType | RelationalAttributeType | NamespacedPropertyType, name, parentPath.targetPath)
128
129def CheckMapperPath(path, path2, parentPath, pathStr, pathElems, targetPath):
130    _CheckPath(path, path2, parentPath, pathStr, pathElems, MapperType, "", targetPath)
131
132def CheckMapperArgPath(path, path2, parentPath, pathStr, pathElems, name):
133    _CheckPath(path, path2, parentPath, pathStr, pathElems, MapperArgType, name, parentPath.targetPath)
134
135def CheckExpressionPath(path, path2, parentPath, pathStr, pathElems):
136    _CheckPath(path, path2, parentPath, pathStr, pathElems, ExpressionType, "expression", parentPath.targetPath)
137
138def CheckOrdering(*args):
139    for i in range(len(args)-1):
140        assert args[i] < args[i+1], "Expected <%s> to compare less-than <%s>, but it did not"%(args[i], args[i+1])
141
142class TestSdfPath2(unittest.TestCase):
143    def test_Basic(self):
144        # ========================================================================
145        # Test some basic construction
146        # ========================================================================
147
148        # --- Check Empty path
149        empty = Sdf.Path.emptyPath
150
151        CheckEmptyPath(empty)
152        self.assertFalse(empty.IsPrimPropertyPath())
153        self.assertFalse(empty.IsNamespacedPropertyPath())
154        self.assertFalse(empty.IsRelationalAttributePath())
155        self.assertFalse(empty < empty, "Less-than check failed")
156
157        # --- Check absolute root path
158        absRoot = Sdf.Path.absoluteRootPath
159
160        CheckRootPath(absRoot, Sdf.Path.absoluteRootPath, "/")
161        CheckOrdering(empty, absRoot)
162
163        # --- Check relative root path
164        relRoot = Sdf.Path.reflexiveRelativePath
165
166        CheckRootPath(relRoot, Sdf.Path.reflexiveRelativePath, ".")
167        CheckOrdering(empty, absRoot, relRoot)
168
169        # --- Make a root prim path
170        rootPrim = absRoot.AppendChild("Foo")
171
172        CheckPrimPath(rootPrim, absRoot.AppendChild("Foo"), absRoot, "/Foo", ["Foo"], "Foo")
173        CheckOrdering(empty, absRoot, rootPrim, relRoot)
174
175        # --- Make another root prim path
176        rootPrim2 = absRoot.AppendChild("Bar")
177
178        CheckPrimPath(rootPrim2, absRoot.AppendChild("Bar"), absRoot, "/Bar", ["Bar"], "Bar")
179        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, relRoot)
180
181        # --- Make a prim child of the root prim path
182        childPrim = rootPrim.AppendChild("Bar")
183
184        CheckPrimPath(childPrim, rootPrim.AppendChild("Bar"), rootPrim, "/Foo/Bar", ["Foo", "Bar"], "Bar")
185        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, childPrim, relRoot)
186
187        # --- Make another prim child of the root prim path
188        childPrim2 = rootPrim.AppendChild("Foo")
189
190        CheckPrimPath(childPrim2, rootPrim.AppendChild("Foo"), rootPrim, "/Foo/Foo", ["Foo", "Foo"], "Foo")
191        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, childPrim, childPrim2, relRoot)
192
193        # --- Make a property of the root prim path
194        rootProp = rootPrim.AppendProperty("prop1")
195
196        CheckPrimPropertyPath(rootProp, rootPrim.AppendProperty("prop1"), rootPrim, "/Foo.prop1", ["Foo", ".prop1"], "prop1")
197        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, childPrim, childPrim2, relRoot)
198
199        # --- Make another property of the root prim path
200        rootProp2 = rootPrim.AppendProperty("prop2")
201
202        CheckPrimPropertyPath(rootProp2, rootPrim.AppendProperty("prop2"), rootPrim, "/Foo.prop2", ["Foo", ".prop2"], "prop2")
203        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, rootProp2, childPrim, childPrim2, relRoot)
204
205        # --- Make a namespaced property of the root prim path
206        rootProp3 = rootPrim.AppendProperty("prop3:bar:baz")
207
208        CheckPrimNamespacedPropertyPath(rootProp3, rootPrim.AppendProperty("prop3:bar:baz"), rootPrim, "/Foo.prop3:bar:baz", ["Foo", ".prop3:bar:baz"], "prop3:bar:baz")
209        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, rootProp3, childPrim, childPrim2, relRoot)
210
211        # --- Make a property of the child prim path
212        childProp = childPrim.AppendProperty("foo")
213
214        CheckPrimPropertyPath(childProp, childPrim.AppendProperty("foo"), childPrim, "/Foo/Bar.foo", ["Foo", "Bar", ".foo"], "foo")
215        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, childPrim, childProp, childPrim2, relRoot)
216
217        # --- Make another property of the child prim path
218        childProp2 = childPrim.AppendProperty("bar")
219
220        CheckPrimPropertyPath(childProp2, childPrim.AppendProperty("bar"), childPrim, "/Foo/Bar.bar", ["Foo", "Bar", ".bar"], "bar")
221        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, childPrim, childProp2, childProp, childPrim2, relRoot)
222
223        # --- Make a target of the root property path
224        rootPropTarg = rootProp.AppendTarget("/Target1")
225
226        CheckTargetPath(rootPropTarg, rootProp.AppendTarget("/Target1"), rootProp, "/Foo.prop1[/Target1]", ["Foo", ".prop1", "[/Target1]"], "/Target1")
227        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, rootPropTarg, childPrim, childPrim2, relRoot)
228
229        # --- Make another target of the root property path
230        rootPropTarg2 = rootProp.AppendTarget("/FooTarget.bar")
231
232        CheckTargetPath(rootPropTarg2, rootProp.AppendTarget("/FooTarget.bar"), rootProp, "/Foo.prop1[/FooTarget.bar]", ["Foo", ".prop1", "[/FooTarget.bar]"], "/FooTarget.bar")
233        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, rootPropTarg2, rootPropTarg, childPrim, childPrim2, relRoot)
234
235        # --- Make a rel attr of the root property target path
236        rootPropRelAttr = rootPropTarg.AppendRelationalAttribute("fooAttr")
237
238        CheckRelationalAttributePath(rootPropRelAttr, rootPropTarg.AppendRelationalAttribute("fooAttr"), rootPropTarg, "/Foo.prop1[/Target1].fooAttr", ["Foo", ".prop1", "[/Target1]", ".fooAttr"], "fooAttr")
239        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, rootPropTarg2, rootPropTarg, rootPropRelAttr, childPrim, childPrim2, relRoot)
240
241        # --- Make another rel attr of the root property path, same target
242        rootPropRelAttr2 = rootPropTarg.AppendRelationalAttribute("barAttr")
243
244        CheckRelationalAttributePath(rootPropRelAttr2, rootPropTarg.AppendRelationalAttribute("barAttr"), rootPropTarg, "/Foo.prop1[/Target1].barAttr", ["Foo", ".prop1", "[/Target1]", ".barAttr"], "barAttr")
245        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, rootPropTarg2, rootPropTarg, rootPropRelAttr2, rootPropRelAttr, childPrim, childPrim2, relRoot)
246
247        # --- Make another rel attr of the root property path, 2nd target
248        rootPropRelAttr3 = rootPropTarg2.AppendRelationalAttribute("barAttr")
249
250        CheckRelationalAttributePath(rootPropRelAttr3, rootPropTarg2.AppendRelationalAttribute("barAttr"), rootPropTarg2, "/Foo.prop1[/FooTarget.bar].barAttr", ["Foo", ".prop1", "[/FooTarget.bar]", ".barAttr"], "barAttr")
251        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, rootPropTarg2, rootPropRelAttr3, rootPropTarg, rootPropRelAttr2, rootPropRelAttr, childPrim, childPrim2, relRoot)
252
253        # --- Make yet another rel attr of the root property path, 2nd target
254        rootPropRelAttr4 = rootPropTarg2.AppendRelationalAttribute("fooAttr")
255
256        CheckRelationalAttributePath(rootPropRelAttr4, rootPropTarg2.AppendRelationalAttribute("fooAttr"), rootPropTarg2, "/Foo.prop1[/FooTarget.bar].fooAttr", ["Foo", ".prop1", "[/FooTarget.bar]", ".fooAttr"], "fooAttr")
257        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, rootPropTarg2, rootPropRelAttr3, rootPropRelAttr4, rootPropTarg, rootPropRelAttr2, rootPropRelAttr, childPrim, childPrim2, relRoot)
258
259        # --- Make a namespaced rel attr of the root property path, 2nd target
260        rootPropRelAttr5 = rootPropTarg2.AppendRelationalAttribute("fooAttr:bar:baz")
261
262        CheckRelationalAttributePath(rootPropRelAttr5, rootPropTarg2.AppendRelationalAttribute("fooAttr:bar:baz"), rootPropTarg2, "/Foo.prop1[/FooTarget.bar].fooAttr:bar:baz", ["Foo", ".prop1", "[/FooTarget.bar]", ".fooAttr:bar:baz"], "fooAttr:bar:baz")
263        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, rootPropTarg2, rootPropRelAttr3, rootPropRelAttr5, rootPropTarg, rootPropRelAttr2, rootPropRelAttr, childPrim, childPrim2, relRoot)
264
265        # --- Make a target of a rel attr path
266        rootPropRelAttrTarget = rootPropRelAttr.AppendTarget("/ConnTarget1.attr")
267
268        CheckTargetPath(rootPropRelAttrTarget, rootPropRelAttr.AppendTarget("/ConnTarget1.attr"), rootPropRelAttr, "/Foo.prop1[/Target1].fooAttr[/ConnTarget1.attr]", ["Foo", ".prop1", "[/Target1]", ".fooAttr", "[/ConnTarget1.attr]"], "/ConnTarget1.attr")
269        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, rootPropTarg2, rootPropRelAttr3, rootPropRelAttr4, rootPropTarg, rootPropRelAttr2, rootPropRelAttr, rootPropRelAttrTarget, childPrim, childPrim2, relRoot)
270
271        # --- Make another target of a rel attr path
272        rootPropRelAttrTarget2 = rootPropRelAttr.AppendTarget("/ConnTarget2.attr")
273
274        CheckTargetPath(rootPropRelAttrTarget2, rootPropRelAttr.AppendTarget("/ConnTarget2.attr"), rootPropRelAttr, "/Foo.prop1[/Target1].fooAttr[/ConnTarget2.attr]", ["Foo", ".prop1", "[/Target1]", ".fooAttr", "[/ConnTarget2.attr]"], "/ConnTarget2.attr")
275        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, rootPropTarg2, rootPropRelAttr3, rootPropRelAttr4, rootPropTarg, rootPropRelAttr2, rootPropRelAttr, rootPropRelAttrTarget, rootPropRelAttrTarget2, childPrim, childPrim2, relRoot)
276
277        # --- Make a mapper path on a prim property
278        rootPropMapper1 = rootProp.AppendMapper("/ConnTarget1.attr")
279
280        CheckMapperPath(rootPropMapper1, rootProp.AppendMapper("/ConnTarget1.attr"), rootProp, "/Foo.prop1.mapper[/ConnTarget1.attr]", ["Foo", ".prop1", ".mapper[/ConnTarget1.attr]"], "/ConnTarget1.attr")
281        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, rootPropTarg2, rootPropRelAttr3, rootPropRelAttr4, rootPropTarg, rootPropRelAttr2, rootPropRelAttr, rootPropRelAttrTarget, rootPropRelAttrTarget2, rootPropMapper1, childPrim, childPrim2, relRoot)
282
283        # --- Make another mapper path on a prim property
284        rootPropMapper2 = rootProp.AppendMapper("/ConnTarget2.attr")
285
286        CheckMapperPath(rootPropMapper2, rootProp.AppendMapper("/ConnTarget2.attr"), rootProp, "/Foo.prop1.mapper[/ConnTarget2.attr]", ["Foo", ".prop1", ".mapper[/ConnTarget2.attr]"], "/ConnTarget2.attr")
287        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, rootPropTarg2, rootPropRelAttr3, rootPropRelAttr4, rootPropTarg, rootPropRelAttr2, rootPropRelAttr, rootPropRelAttrTarget, rootPropRelAttrTarget2, rootPropMapper1, rootPropMapper2, childPrim, childPrim2, relRoot)
288
289        # --- Make an expression path on a prim property
290        rootPropExpression = rootProp.AppendExpression()
291
292        CheckExpressionPath(rootPropExpression, rootProp.AppendExpression(), rootProp, "/Foo.prop1.expression", ["Foo", ".prop1", ".expression"])
293        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, rootPropTarg2, rootPropRelAttr3, rootPropRelAttr4, rootPropTarg, rootPropRelAttr2, rootPropRelAttr, rootPropRelAttrTarget, rootPropRelAttrTarget2, rootPropMapper1, rootPropMapper2, rootPropExpression, childPrim, childPrim2, relRoot)
294
295        # --- Make a mapper arg path on a prim property
296        rootPropMapperArg1 = rootPropMapper1.AppendMapperArg("fooArg")
297
298        CheckMapperArgPath(rootPropMapperArg1, rootPropMapper1.AppendMapperArg("fooArg"), rootPropMapper1, "/Foo.prop1.mapper[/ConnTarget1.attr].fooArg", ["Foo", ".prop1", ".mapper[/ConnTarget1.attr]", ".fooArg"], "fooArg")
299        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, rootPropTarg2, rootPropRelAttr3, rootPropRelAttr4, rootPropTarg, rootPropRelAttr2, rootPropRelAttr, rootPropRelAttrTarget, rootPropRelAttrTarget2, rootPropMapper1, rootPropMapperArg1, rootPropMapper2, rootPropExpression, childPrim, childPrim2, relRoot)
300
301        # --- Make another mapper arg path on a prim property
302        rootPropMapperArg2 = rootPropMapper1.AppendMapperArg("barArg")
303
304        CheckMapperArgPath(rootPropMapperArg2, rootPropMapper1.AppendMapperArg("barArg"), rootPropMapper1, "/Foo.prop1.mapper[/ConnTarget1.attr].barArg", ["Foo", ".prop1", ".mapper[/ConnTarget1.attr]", ".barArg"], "barArg")
305        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, rootPropTarg2, rootPropRelAttr3, rootPropRelAttr4, rootPropTarg, rootPropRelAttr2, rootPropRelAttr, rootPropRelAttrTarget, rootPropRelAttrTarget2, rootPropMapper1, rootPropMapperArg2, rootPropMapperArg1, rootPropMapper2, rootPropExpression, childPrim, childPrim2, relRoot)
306
307        # --- Make a mapper path on a rel attr
308        rootPropRelAttrMapper1 = rootPropRelAttr.AppendMapper("/ConnTarget1.attr")
309
310        CheckMapperPath(rootPropRelAttrMapper1, rootPropRelAttr.AppendMapper("/ConnTarget1.attr"), rootPropRelAttr, "/Foo.prop1[/Target1].fooAttr.mapper[/ConnTarget1.attr]", ["Foo", ".prop1", "[/Target1]", ".fooAttr", ".mapper[/ConnTarget1.attr]"], "/ConnTarget1.attr")
311        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, rootPropTarg2, rootPropRelAttr3, rootPropRelAttr4, rootPropTarg, rootPropRelAttr2, rootPropRelAttr, rootPropRelAttrTarget, rootPropRelAttrTarget2, rootPropRelAttrMapper1, rootPropMapper1, rootPropMapperArg2, rootPropMapperArg1, rootPropMapper2, rootPropExpression, childPrim, childPrim2, relRoot)
312
313        # --- Make another mapper path on a rel attr
314        rootPropRelAttrMapper2 = rootPropRelAttr.AppendMapper("/ConnTarget2.attr")
315
316        CheckMapperPath(rootPropRelAttrMapper2, rootPropRelAttr.AppendMapper("/ConnTarget2.attr"), rootPropRelAttr, "/Foo.prop1[/Target1].fooAttr.mapper[/ConnTarget2.attr]", ["Foo", ".prop1", "[/Target1]", ".fooAttr", ".mapper[/ConnTarget2.attr]"], "/ConnTarget2.attr")
317        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, rootPropTarg2, rootPropRelAttr3, rootPropRelAttr4, rootPropTarg, rootPropRelAttr2, rootPropRelAttr, rootPropRelAttrTarget, rootPropRelAttrTarget2, rootPropRelAttrMapper1, rootPropRelAttrMapper2, rootPropMapper1, rootPropMapperArg2, rootPropMapperArg1, rootPropMapper2, rootPropExpression, childPrim, childPrim2, relRoot)
318
319        # --- Make a expression path on a rel attr
320        rootPropRelAttrExpression = rootPropRelAttr.AppendExpression()
321
322        CheckExpressionPath(rootPropRelAttrExpression, rootPropRelAttr.AppendExpression(), rootPropRelAttr, "/Foo.prop1[/Target1].fooAttr.expression", ["Foo", ".prop1", "[/Target1]", ".fooAttr", ".expression"])
323        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, rootPropTarg2, rootPropRelAttr3, rootPropRelAttr4, rootPropTarg, rootPropRelAttr2, rootPropRelAttr, rootPropRelAttrTarget, rootPropRelAttrTarget2, rootPropRelAttrMapper1, rootPropRelAttrMapper2, rootPropRelAttrExpression, rootPropMapper1, rootPropMapperArg2, rootPropMapperArg1, rootPropMapper2, rootPropExpression, childPrim, childPrim2, relRoot)
324
325        # --- Make a mapper arg path on a rel attr
326        rootPropRelAttrMapperArg1 = rootPropRelAttrMapper1.AppendMapperArg("fooArg")
327
328        CheckMapperArgPath(rootPropRelAttrMapperArg1, rootPropRelAttrMapper1.AppendMapperArg("fooArg"), rootPropRelAttrMapper1, "/Foo.prop1[/Target1].fooAttr.mapper[/ConnTarget1.attr].fooArg", ["Foo", ".prop1", "[/Target1]", ".fooAttr", ".mapper[/ConnTarget1.attr]", ".fooArg"], "fooArg")
329        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, rootPropTarg2, rootPropRelAttr3, rootPropRelAttr4, rootPropTarg, rootPropRelAttr2, rootPropRelAttr, rootPropRelAttrTarget, rootPropRelAttrTarget2, rootPropRelAttrMapper1, rootPropRelAttrMapperArg1, rootPropRelAttrMapper2, rootPropRelAttrExpression, rootPropMapper1, rootPropMapperArg2, rootPropMapperArg1, rootPropMapper2, rootPropExpression, childPrim, childPrim2, relRoot)
330
331        # --- Make another mapper arg path on a rel attr
332        rootPropRelAttrMapperArg2 = rootPropRelAttrMapper1.AppendMapperArg("barArg")
333
334        CheckMapperArgPath(rootPropRelAttrMapperArg2, rootPropRelAttrMapper1.AppendMapperArg("barArg"), rootPropRelAttrMapper1, "/Foo.prop1[/Target1].fooAttr.mapper[/ConnTarget1.attr].barArg", ["Foo", ".prop1", "[/Target1]", ".fooAttr", ".mapper[/ConnTarget1.attr]", ".barArg"], "barArg")
335        CheckOrdering(empty, absRoot, rootPrim2, rootPrim, rootProp, rootPropTarg2, rootPropRelAttr3, rootPropRelAttr4, rootPropTarg, rootPropRelAttr2, rootPropRelAttr, rootPropRelAttrTarget, rootPropRelAttrTarget2, rootPropRelAttrMapper1, rootPropRelAttrMapperArg2, rootPropRelAttrMapperArg1, rootPropRelAttrMapper2, rootPropRelAttrExpression, rootPropMapper1, rootPropMapperArg2, rootPropMapperArg1, rootPropMapper2, rootPropExpression, childPrim, childPrim2, relRoot)
336
337        # test GetPrimPath
338
339        # self.assertEqual(Path(".").GetPrimPath(),                   ".")
340        self.assertEqual(Sdf.Path("foo").GetPrimPath(),                 "foo")
341        self.assertEqual(Sdf.Path("foo/bar").GetPrimPath(),             "foo/bar")
342        self.assertEqual(Sdf.Path("foo.bar").GetPrimPath(),             "foo")
343        self.assertEqual(Sdf.Path("foo.bar[foo].bar").GetPrimPath(),    "foo")
344
345        # test ReplacePrefix
346
347        self.assertEqual(Sdf.Path("/a").ReplacePrefix("/a", "/b"), "/b")
348        self.assertEqual(Sdf.Path("/a/b").ReplacePrefix("/a", "/b"), "/b/b")
349        self.assertEqual(Sdf.Path("a").ReplacePrefix("a", "b"), "b")
350        self.assertEqual(Sdf.Path("foo/bar").ReplacePrefix("foo", "bar"), "bar/bar")
351        self.assertEqual(Sdf.Path("foo.bar").ReplacePrefix("foo", "bar"), "bar.bar")
352        self.assertEqual(Sdf.Path("foo.bar:baz").ReplacePrefix("foo", "bar"), "bar.bar:baz")
353        self.assertEqual(Sdf.Path("foo.bar[/foo].attr").ReplacePrefix("foo.bar", "a.b"), "a.b[/foo].attr")
354        self.assertEqual(Sdf.Path("/foo.bar[foo.bar].attr").ReplacePrefix("foo.bar", "a.b"), "/foo.bar[a.b].attr")
355        self.assertEqual(Sdf.Path("/foo.bar[foo.bar].attr:baz").ReplacePrefix("foo.bar", "a.b"), "/foo.bar[a.b].attr:baz")
356        self.assertEqual(Sdf.Path("/foo.bar[/foo.bar].attr").ReplacePrefix("/foo.bar", "/a.b"), "/a.b[/a.b].attr")
357        self.assertEqual(Sdf.Path("/foo.bar[/foo.bar[/foo.bar].attr].attr").ReplacePrefix("/foo.bar", "/a.b"), "/a.b[/a.b[/a.b].attr].attr")
358        self.assertEqual(Sdf.Path("/foo.rel[/foo/prim].relAttr.mapper[/foo/prim.attr]").ReplacePrefix("/foo", "/a/b"), "/a/b.rel[/a/b/prim].relAttr.mapper[/a/b/prim.attr]")
359        self.assertEqual(Sdf.Path("bar.rel[/foo/prim].relAttr.mapper[/foo/prim.attr]").ReplacePrefix("/foo", "/a/b"), "bar.rel[/a/b/prim].relAttr.mapper[/a/b/prim.attr]")
360        self.assertEqual(Sdf.Path("../bar").ReplacePrefix("..", "bar"), "bar/bar")
361
362        # test GetCommonPrefix
363
364        self.assertEqual(Sdf.Path("/a").GetCommonPrefix("/a"), "/a")
365        self.assertEqual(Sdf.Path("/a/b").GetCommonPrefix("/a/b"), "/a/b")
366        self.assertEqual(Sdf.Path("/a.b").GetCommonPrefix("/a.b"), "/a.b")
367        self.assertEqual(Sdf.Path("/a/b").GetCommonPrefix("/b/a"), "/")
368        self.assertEqual(Sdf.Path("/a/b/c").GetCommonPrefix("/a/b"), "/a/b")
369        self.assertEqual(Sdf.Path("/a/b").GetCommonPrefix("/a/b/c"), "/a/b")
370        self.assertEqual(Sdf.Path("/a/b.c").GetCommonPrefix("/a/b"), "/a/b")
371        self.assertEqual(Sdf.Path("/a/b").GetCommonPrefix("/a/b.c"), "/a/b")
372        self.assertEqual(Sdf.Path("/foo.bar[/foo].attr").GetCommonPrefix("/foo.foo[/foo].attr"), "/foo")
373        self.assertEqual(Sdf.Path("/foo.rel[/foo/prim].relAttr.mapper[/foo/prim.attr]").GetCommonPrefix("/foo.rel[/foo/prim].relAttr.mapper[/foo/prim.attr]"), "/foo.rel[/foo/prim].relAttr.mapper[/foo/prim.attr]")
374        self.assertEqual(Sdf.Path("/foo.rel[/foo/prim].relAttr.mapper[/foo/prim.attr].x").GetCommonPrefix("/foo.rel[/foo/prim].relAttr.mapper[/foo/prim.attr].y"), "/foo.rel[/foo/prim].relAttr.mapper[/foo/prim.attr]")
375        self.assertEqual(Sdf.Path("/foo.rel[/foo/prim].relAttr.mapper[/foo/prim.attr1]").GetCommonPrefix("/foo.rel[/foo/prim].relAttr.mapper[/foo/prim.attr2]"), "/foo.rel[/foo/prim].relAttr")
376        self.assertEqual(Sdf.Path("/foo.rel[/foo/prim].relAttr.mapper[/foo/prim.attr]").GetCommonPrefix("/foo.rel[/foo/prim2].relAttr.mapper[/foo/prim.attr]"), "/foo.rel")
377
378        # test MakeAbsolutePath
379
380        self.assertEqual(Sdf.Path("..").MakeAbsolutePath("/foo/bar"), "/foo")
381        self.assertEqual(Sdf.Path("/A/B/C/D.rel[../../E.rel[F.attr].attr].attr").MakeAbsolutePath("/A/B"), "/A/B/C/D.rel[/A/B/E.rel[/A/B/E/F.attr].attr].attr")
382        self.assertEqual(Sdf.Path("C/D.rel[../../E.rel[F.attr].attr].attr").MakeAbsolutePath("/A/B"), "/A/B/C/D.rel[/A/B/E.rel[/A/B/E/F.attr].attr].attr")
383        self.assertEqual(Sdf.Path("../.attr").MakeAbsolutePath("/foo/bar"), "/foo.attr")
384        self.assertEqual(Sdf.Path("../.attr[1 & 2]").MakeAbsolutePath("/foo/bar"), "/foo.attr[1 & 2]")
385        self.assertEqual(Sdf.Path.emptyPath.MakeAbsolutePath("/foo/bar"), Sdf.Path.emptyPath)
386        self.assertEqual(Sdf.Path(".attr.mapper[/connection.target]").MakeAbsolutePath("/foo/bar"), "/foo/bar.attr.mapper[/connection.target]")
387        self.assertEqual(Sdf.Path(".attr.mapper[/connection.target].arg").MakeAbsolutePath("/foo/bar"), "/foo/bar.attr.mapper[/connection.target].arg")
388        self.assertEqual(Sdf.Path(".attr.expression").MakeAbsolutePath("/foo/bar"), "/foo/bar.attr.expression")
389
390        # test MakeRelativePath
391
392
393        self.assertEqual(Sdf.Path("/foo/bar").MakeRelativePath("/foo"), "bar")
394        self.assertEqual(Sdf.Path("/foo").MakeRelativePath("/foo"), ".")
395        self.assertEqual(Sdf.Path("/foo").MakeRelativePath("/foo/bar"), "..")
396        self.assertEqual(Sdf.Path.emptyPath.MakeRelativePath("/foo/bar"), Sdf.Path.emptyPath)
397
398        # test GetPrefixes
399
400        self.assertEqual(Sdf.Path("/foo/bar/goo/loo").GetPrefixes(),
401           ["/foo", "/foo/bar", "/foo/bar/goo", "/foo/bar/goo/loo"])
402
403        # test ReplaceTargetPath
404
405        self.assertEqual(Sdf.Path("/prim.rel[foo].attr").ReplaceTargetPath("bar"), "/prim.rel[bar].attr")
406        self.assertEqual(Sdf.Path("/prim.rel[foo].attr:baz").ReplaceTargetPath("bar"), "/prim.rel[bar].attr:baz")
407        self.assertEqual(Sdf.Path("/prim.rel[foo].attr[1]").ReplaceTargetPath("bar"), "/prim.rel[bar].attr[1]")
408        self.assertEqual(Sdf.Path("foo").ReplaceTargetPath("bar"), "foo")
409        self.assertEqual(Sdf.Path("/prim.attr.mapper[/foo.target]").ReplaceTargetPath("/bar.target"), "/prim.attr.mapper[/bar.target]")
410        self.assertEqual(Sdf.Path("/prim.attr.mapper[/foo.target].arg").ReplaceTargetPath("/bar.target"), "/prim.attr.mapper[/bar.target].arg")
411        self.assertEqual(Sdf.Path("/prim.rel[foo].attr.expression").ReplaceTargetPath("bar"), "/prim.rel[bar].attr.expression")
412        self.assertEqual(Sdf.Path("/prim.rel[foo].attr.expression").ReplaceTargetPath("bar:baz"), "/prim.rel[bar:baz].attr.expression")
413        self.assertEqual(Sdf.Path("/prim.rel[/prim].relAttr.mapper[/prim.attr]").ReplaceTargetPath("/bar.attr"), "/prim.rel[/prim].relAttr.mapper[/bar.attr]")
414        self.assertEqual(Sdf.Path("/prim.rel[/prim].relAttr.mapper[/prim.attr]").ReplaceTargetPath("/bar.attr:baz"), "/prim.rel[/prim].relAttr.mapper[/bar.attr:baz]")
415
416        # test AppendPath
417
418        self.assertEqual(Sdf.Path("/prim").AppendPath("."), "/prim")
419        self.assertEqual(Sdf.Path("/").AppendPath("foo/bar.attr"), "/foo/bar.attr")
420        self.assertEqual(Sdf.Path("/").AppendPath("foo/bar.attr:argle:bargle"), "/foo/bar.attr:argle:bargle")
421        self.assertEqual(Sdf.Path("/foo").AppendPath("bar.attr"), "/foo/bar.attr")
422        self.assertEqual(Sdf.Path("/foo").AppendPath("bar.attr:argle:bargle"), "/foo/bar.attr:argle:bargle")
423        self.assertEqual(Sdf.Path("/foo").AppendPath("bar.rel[/target].attr"), "/foo/bar.rel[/target].attr")
424        self.assertEqual(Sdf.Path("/foo").AppendPath("bar.rel[/target].attr:argle:bargle"), "/foo/bar.rel[/target].attr:argle:bargle")
425        self.assertEqual(Sdf.Path("/foo").AppendPath("bar.attr[/target.attr]"), "/foo/bar.attr[/target.attr]")
426        self.assertEqual(Sdf.Path("/foo").AppendPath("bar.attr[/target.attr:argle:bargle]"), "/foo/bar.attr[/target.attr:argle:bargle]")
427        self.assertEqual(Sdf.Path("/foo").AppendPath("bar.attr.mapper[/target].arg"), "/foo/bar.attr.mapper[/target].arg")
428
429        self.assertEqual(Sdf.Path("/prim").AppendPath("/absolute"), empty)
430        self.assertEqual(Sdf.Path("/prim.attr").AppendPath("prim"), empty)
431        self.assertEqual(Sdf.Path("/").AppendPath(".prop"), empty)
432
433        # test various error cases
434        self.assertEqual( Sdf.Path(".").GetPrimPath(), empty )
435        self.assertEqual( Sdf.Path(".foo").GetPrimPath(), empty )
436        self.assertEqual( Sdf.Path("foo.bar").AppendChild("a"), empty )
437        self.assertEqual( Sdf.Path("foo.bar").AppendProperty("a"), empty )
438        self.assertEqual( Sdf.Path("foo").AppendTarget("/foo"), empty )
439        self.assertEqual( Sdf.Path("foo").ReplacePrefix("bar", "bar"), Sdf.Path("foo") )
440        self.assertEqual( Sdf.Path("foo").ReplacePrefix(empty, "bar"), empty )
441        self.assertEqual( Sdf.Path("foo").ReplacePrefix("foo", empty), empty )
442        self.assertEqual( Sdf.Path("foo").GetCommonPrefix(empty), empty )
443        self.assertEqual( Sdf.Path("foo").MakeAbsolutePath("foo"), empty )
444        self.assertEqual( Sdf.Path("foo").MakeAbsolutePath(empty), empty )
445        self.assertEqual( Sdf.Path("foo").MakeRelativePath("foo"), empty )
446        self.assertEqual( Sdf.Path("foo").MakeRelativePath(empty ), empty )
447        self.assertEqual( Sdf.Path("foo").targetPath, empty )
448        self.assertEqual( Sdf.Path("foo").ReplaceTargetPath(empty), empty)
449        self.assertEqual( empty.ReplaceTargetPath("foo"), empty)
450        self.assertEqual( Sdf.Path("foo").AppendChild("!@#$$>."), empty)
451        self.assertEqual( Sdf.Path("foo").AppendProperty("."), empty )
452        self.assertEqual( Sdf.Path("foo.prop[foo]").AppendRelationalAttribute("."), empty )
453        self.assertEqual( Sdf.Path("foo").AppendMapper("/conn.target"), empty )
454        self.assertEqual( Sdf.Path("foo.attr").AppendMapper(empty), empty )
455        self.assertEqual( Sdf.Path("foo.attr.mapper[/conn.target]").AppendMapperArg("./bad"), empty )
456        self.assertEqual( Sdf.Path("foo").AppendMapperArg("arg"), empty )
457        self.assertEqual( Sdf.Path("foo").AppendExpression(), empty )
458
459        self.assertEqual(Sdf.Path("foo.bar").AppendTarget(empty), empty)
460        self.assertEqual(Sdf.Path().MakeRelativePath("foo"), empty)
461
462        # Retest all of the above Append negatives with the equivalent AppendElementString()
463        self.assertEqual( Sdf.Path("foo.bar").AppendElementString("a"), empty )
464        self.assertEqual( Sdf.Path("foo.bar").AppendElementString(".a"), empty )
465        self.assertEqual( Sdf.Path("foo").AppendElementString("[/foo]"), empty )
466        self.assertEqual( Sdf.Path("foo").AppendElementString("!@#$$>."), empty)
467        self.assertEqual( Sdf.Path("foo").AppendElementString(".."), empty )
468        self.assertEqual( Sdf.Path("foo.prop[foo]").AppendElementString("[.]"), empty )
469        self.assertEqual( Sdf.Path("foo").AppendElementString(".mapper[/conn.target]"), empty )
470        self.assertEqual( Sdf.Path("foo.attr").AppendElementString(".mapper[]"), empty )
471        self.assertEqual( Sdf.Path("foo.attr.mapper[/conn.target]").AppendElementString("./bad"), empty )
472        # The following tests don't translate to element appending, because the
473        # textual syntax for mapper args is the same as for ordinary properties,
474        # which *are* legal to append to prims, and "expression" *is* a legal
475        # property name for a prim.
476        #self.assertEqual( Sdf.Path("foo").AppendElementString(".arg"), empty )
477        #self.assertEqual( Sdf.Path("foo").AppendElementString(".expression"), empty )
478        self.assertEqual(Sdf.Path("foo.bar").AppendElementString("[]"), empty)
479
480
481        self.assertEqual(Sdf.Path("/foo").targetPath, empty)
482
483        # test GetVariantSelection,
484        #      IsPrimVariantSelectionPath,
485        #      ContainsPrimVariantSelection
486        #      StripAllVariantSelections
487
488        self.assertFalse(Sdf.Path('/foo/bar').ContainsPrimVariantSelection())
489        self.assertFalse(Sdf.Path('/foo/bar').ContainsPropertyElements())
490        self.assertTrue(Sdf.Path('/foo/bar{var=sel}').ContainsPrimVariantSelection())
491        self.assertFalse(Sdf.Path('/foo/bar{var=sel}').ContainsPropertyElements())
492        self.assertTrue(Sdf.Path('/foo/bar{var=sel}').IsPrimVariantSelectionPath())
493        self.assertTrue(Sdf.Path('/foo{var=sel}bar').ContainsPrimVariantSelection())
494        self.assertTrue(not Sdf.Path('/foo{var=sel}bar').IsPrimVariantSelectionPath())
495        self.assertEqual(Sdf.Path('/foo{var=sel}bar').GetVariantSelection(), ('', ''))
496        self.assertEqual(Sdf.Path('/foo{var=sel}bar').GetParentPath().GetVariantSelection(), ('var', 'sel'))
497        self.assertEqual(Sdf.Path('/foo/bar{var=sel}').GetVariantSelection(), ('var', 'sel'))
498        self.assertEqual(Sdf.Path('/foo/bar').StripAllVariantSelections(), (Sdf.Path('/foo/bar')))
499        self.assertEqual(Sdf.Path('/foo/bar{var=sel}').StripAllVariantSelections(),
500              (Sdf.Path('/foo/bar')))
501
502        # XXX work around Path parser failure:
503        p = Sdf.Path('/foo/bar{var=sel}baz/frob')
504        self.assertEqual(p.StripAllVariantSelections(), Sdf.Path('/foo/bar/baz/frob'))
505        p = Sdf.Path('/foo{bond=connery}bar{captain=picard}baz/frob{doctor=tennent}')
506        self.assertEqual(p.StripAllVariantSelections(), Sdf.Path('/foo/bar/baz/frob'))
507
508        self.assertEqual(Sdf.Path.TokenizeIdentifier(""), [])
509        self.assertEqual(Sdf.Path.TokenizeIdentifier("foo"), ["foo"])
510        self.assertEqual(Sdf.Path.TokenizeIdentifier("foo::baz"), [])
511        self.assertEqual(Sdf.Path.TokenizeIdentifier("foo:bar:baz"), ["foo","bar","baz"])
512
513        self.assertEqual(Sdf.Path.JoinIdentifier([]), "")
514        self.assertEqual(Sdf.Path.JoinIdentifier(["foo"]), "foo")
515        self.assertEqual(Sdf.Path.JoinIdentifier(["foo","bar","baz"]), "foo:bar:baz")
516        self.assertEqual(Sdf.Path.JoinIdentifier(["foo","","baz"]), "foo:baz")
517        self.assertEqual(Sdf.Path.JoinIdentifier(["foo","bar",""]), "foo:bar")
518        self.assertEqual(Sdf.Path.JoinIdentifier(["","bar","baz"]), "bar:baz")
519        self.assertEqual(Sdf.Path.JoinIdentifier(["","bar",""]), "bar")
520
521        self.assertEqual(Sdf.Path.StripNamespace(Sdf.Path.JoinIdentifier([])), "")
522        self.assertEqual(Sdf.Path.StripNamespace(Sdf.Path.JoinIdentifier(["foo"])), "foo")
523        self.assertEqual(Sdf.Path.StripNamespace(Sdf.Path.JoinIdentifier(["foo","bar","baz"])), "baz")
524
525        self.assertEqual(Sdf.Path.StripPrefixNamespace(
526              Sdf.Path.JoinIdentifier([]), ""),
527              ("", False))
528        self.assertEqual(Sdf.Path.StripPrefixNamespace(
529              Sdf.Path.JoinIdentifier(["foo"]), "foo"),
530              ("foo", False))
531        self.assertEqual(Sdf.Path.StripPrefixNamespace(
532              Sdf.Path.JoinIdentifier(["foo", "bar"]), "foo"),
533              ("bar", True))
534        self.assertEqual(Sdf.Path.StripPrefixNamespace(
535              Sdf.Path.JoinIdentifier(["foo", "bar"]), "foo:"),
536              ("bar", True))
537        self.assertEqual(Sdf.Path.StripPrefixNamespace(
538              Sdf.Path.JoinIdentifier(["foo", "bar"]), "f"),
539              ("foo:bar", False))
540        self.assertEqual(Sdf.Path.StripPrefixNamespace(
541              Sdf.Path.JoinIdentifier(["foo", "bar", "baz"]), "foo:"),
542              ("bar:baz", True))
543        self.assertEqual(Sdf.Path.StripPrefixNamespace(
544              Sdf.Path.JoinIdentifier(["foo", "bar", "baz"]), "foo:bar"),
545              ("baz", True))
546        self.assertEqual(Sdf.Path.StripPrefixNamespace(
547              Sdf.Path.JoinIdentifier(["foo", "bar", "baz"]), "foo:bar:"),
548              ("baz", True))
549        self.assertEqual(Sdf.Path.StripPrefixNamespace(
550              Sdf.Path.JoinIdentifier(["foo", "bar", "baz"]), "nothere:"),
551              ("foo:bar:baz", False))
552
553        self.assertEqual(Sdf.Path.JoinIdentifier("", ""), "")
554        self.assertEqual(Sdf.Path.JoinIdentifier("foo", ""), "foo")
555        self.assertEqual(Sdf.Path.JoinIdentifier("", "foo"), "foo")
556        self.assertEqual(Sdf.Path.JoinIdentifier("foo","bar"), "foo:bar")
557        self.assertEqual(Sdf.Path.JoinIdentifier("foo:bar","baz"), "foo:bar:baz")
558        self.assertEqual(Sdf.Path.JoinIdentifier("foo","baz:blah"), "foo:baz:blah")
559        self.assertEqual(Sdf.Path.JoinIdentifier("foo:bar","baz:blah"), "foo:bar:baz:blah")
560
561        ########################################################################
562        #
563        # Nested variant selections
564        #
565
566        p1 = Sdf.Path('/a')
567        p2 = p1.AppendVariantSelection('x','a')
568        p3 = p2.AppendVariantSelection('y','b')
569
570        # It is allowable to make repeated selections for the same variant set.
571        p2x = p2.AppendVariantSelection('x','a')
572        p3x = p3.AppendVariantSelection('x','a')
573        self.assertEqual( p2x, Sdf.Path('/a{x=a}{x=a}') )
574        self.assertEqual( p3x, Sdf.Path('/a{x=a}{y=b}{x=a}') )
575
576        self.assertTrue( not p1.ContainsPrimVariantSelection() )
577        self.assertTrue( p2.ContainsPrimVariantSelection() )
578        self.assertTrue( p3.ContainsPrimVariantSelection() )
579
580        self.assertEqual( p2.GetVariantSelection(), ('x','a') )
581        self.assertEqual( p3.GetVariantSelection(), ('y','b') )
582
583        self.assertEqual( p1, Sdf.Path('/a') )
584        self.assertEqual( p2, Sdf.Path('/a{x=a}') )
585        self.assertEqual( p3, Sdf.Path('/a{x=a}{y=b}') )
586
587        self.assertEqual( p1, eval(repr(p1)) )
588        self.assertEqual( p2, eval(repr(p2)) )
589        self.assertEqual( p3, eval(repr(p3)) )
590
591        self.assertEqual( p1, p2.GetParentPath() )
592        self.assertEqual( p2, p3.GetParentPath() )
593
594        self.assertTrue( p3.HasPrefix(p2) )
595        self.assertTrue( p2.HasPrefix(p1) )
596
597        self.assertEqual( p3.ReplacePrefix(p2, '/b'), Sdf.Path('/b{y=b}') )
598
599if __name__ == "__main__":
600    unittest.main()
601