| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542 | 
							- <!DOCTYPE html>
 
- <html>
 
-   <head>
 
-     <title>Virtual World Framework</title>
 
-     <script type="text/javascript" src="qunit.js"></script>
 
-     <script type="text/javascript" src="../lib/require.js"></script>
 
-     <script type="text/javascript">
 
-       require( {
 
-         baseUrl: "../lib"
 
-       }, [
 
-         "domReady",
 
-         "vwf/utility",
 
-       ], function( ready, utility ) {
 
-         // Test utility module functions.
 
-         ready( function() {
 
-           // == transform ==========================================================================
 
-           test( "Identity", function() {
 
-             // Transformation function
 
-             var transformation = function( object ) {
 
-               return object; // no change
 
-             };
 
-             // Scalars
 
-             equal( utility.transform( true, transformation ), true, "bool" );
 
-             equal( utility.transform( 1, transformation ), 1, "number" );
 
-             equal( utility.transform( "string", transformation ), "string", "string" );
 
-             // Objects
 
-             var object = {};
 
-             equal( utility.transform( object, transformation ), object, "Object" );
 
-             var array = [];
 
-             equal( utility.transform( array, transformation ), array, "Array" );
 
-           } );
 
-          
 
-           test( "Container substitution", function() {
 
-             // Transformation function
 
-             var transformation = function( object ) {
 
-               return typeof object == "object" ? "replaced" : object; // replace Objects and Arrays
 
-             };
 
-             // Scalars
 
-             equal( utility.transform( true, transformation ), true, "bool unchanged" );
 
-             equal( utility.transform( 1, transformation ), 1, "number unchanged" );
 
-             equal( utility.transform( "string", transformation ), "string", "string unchanged" );
 
-             // Objects
 
-             var object = {};
 
-             equal( utility.transform( object, transformation ), "replaced", "object replaced" );
 
-             var array = [];
 
-             equal( utility.transform( array, transformation ), "replaced", "array replaced" );
 
-           } );
 
-           test( "Element substitution", function() {
 
-             // Transformation function
 
-             var transformation = function( object ) {
 
-               return object.replace ? { replaced: true } : object; // replace Objects having a "replace" field
 
-             };
 
-             // Test elements
 
-             var elements = [ { replace: true }, {} ];
 
-             // Object container
 
-             var object = { zero: elements[0], one: elements[1] };
 
-             var transformedObject = utility.transform( object, transformation );
 
-             notEqual( transformedObject, object, "object container replaced" );
 
-             notEqual( transformedObject.zero, elements[0], "object targeted element replaced" );
 
-             equal( transformedObject.one, elements[1], "object untargeted element unchanged" );
 
-             equal( object.zero, elements[0], "object original container unchanged" );
 
-             equal( object.one, elements[1], "object original container unchanged" );
 
-             // Array container
 
-             var array = [ elements[0], elements[1] ];
 
-             var transformedArray = utility.transform( array, transformation );
 
-             notEqual( transformedArray, array, "array container replaced" );
 
-             notEqual( transformedArray[0], elements[0], "array targeted element replaced" );
 
-             equal( transformedArray[1], elements[1], "array untargeted element unchanged" );
 
-             equal( array[0], elements[0], "array original container unchanged" );
 
-             equal( array[1], elements[1], "array original container unchanged" );
 
-           } );
 
-           test( "Container recursion", function() {
 
-             // Transformation function
 
-             var transformation = function( object ) {
 
-               if ( object.replace ) {
 
-                 return { replaced: true }; // replace Objects having a "replace" field
 
-               } else if ( object.container_object ) {
 
-                 return [ { replace: true } ]; // replace tagged Object containers with Array containers
 
-               } else if ( object.container_array ) {
 
-                 return { zero: { replace: true } }; // replace tagged Array containers with Object containers
 
-               } else {
 
-                 return object;
 
-               }
 
-             };
 
-             // Test elements
 
-             var elements = [ { replace: true }, {} ];
 
-             // Array to object to element.
 
-             var arrayContainingObject = [ { zero: elements[0], one: elements[1] } ];
 
-             var transformedArrayContainingObject = utility.transform( arrayContainingObject, transformation );
 
-             notEqual( transformedArrayContainingObject, arrayContainingObject, "outer array container replaced" );
 
-             notEqual( transformedArrayContainingObject[0], arrayContainingObject[0], "inner object container replaced" );
 
-             ok( transformedArrayContainingObject[0].zero.replaced, "contained element replaced" );
 
-             equal( arrayContainingObject[0].zero, elements[0], "original container unchanged" );
 
-             equal( arrayContainingObject[0].one, elements[1], "original container unchanged" );
 
-             // Object to array to element.
 
-             var objectContainingArray = { inner: [ elements[0], elements[1] ] };
 
-             var transformedObjectContainingArray = utility.transform( objectContainingArray, transformation );
 
-             notEqual( transformedObjectContainingArray, objectContainingArray, "outer object container replaced" );
 
-             notEqual( transformedObjectContainingArray.inner, objectContainingArray.inner, "inner array container replaced" );
 
-             ok( transformedObjectContainingArray.inner[0].replaced, "contained element replaced" );
 
-             equal( objectContainingArray.inner[0], elements[0], "original container unchanged" );
 
-             equal( objectContainingArray.inner[1], elements[1], "original container unchanged" );
 
-             // Object, transformed into array, to element: { container_object: true } => [ { replace: true } ] => [ { replaced: true } ]
 
-             var objectBecomingArray = {};
 
-             objectBecomingArray.container_object = true;
 
-             var transformedObjectBecomingArray = utility.transform( objectBecomingArray, transformation );
 
-             notEqual( transformedObjectBecomingArray, objectBecomingArray, "object container replaced" );
 
-             ok( transformedObjectBecomingArray[0].replaced, "replacement array container traversed and contained element replaced" );
 
-             // Array, transformed into object, to element: [ container_array: true ] => { zero: { replace: true } } => { zero: { replaced: true } }
 
-             var arrayBecomingObject = [];
 
-             arrayBecomingObject.container_array = true;
 
-             var transformedArrayBecomingObject = utility.transform( arrayBecomingObject, transformation );
 
-             notEqual( transformedArrayBecomingObject, arrayBecomingObject, "array container replaced" );
 
-             ok( transformedArrayBecomingObject.zero.replaced, "replacement object container traversed and contained element replaced" );
 
-           } );
 
-           // == exceptionMessage ===================================================================
 
-           // TODO
 
-           // == resolveURI =========================================================================
 
-           // TODO
 
-           // == xpath.resolve ======================================================================
 
-           test ( "XPath resolved", function() {
 
-             deepEqual( utility.xpath.resolve( "element()", "root", "start", xpathResolver ), [ "start children matching element()" ], "element()" );
 
-             deepEqual( utility.xpath.resolve( "element(*)", "root", "start", xpathResolver ), [ "start children matching element()" ], "element(*)" );
 
-             deepEqual( utility.xpath.resolve( "element(a)", "root", "start", xpathResolver ), [ "start children matching element() named a" ], "element(a)" );
 
-             deepEqual( utility.xpath.resolve( "element(*,t)", "root", "start", xpathResolver ), [ "start children matching element() typed t" ], "element(*,t)" );
 
-             deepEqual( utility.xpath.resolve( "element(a,t)", "root", "start", xpathResolver ), [ "start children matching element() named a typed t" ], "element(a,t)" );
 
-             deepEqual( utility.xpath.resolve( "a/child::*", "root", "start", xpathResolver ), [ "start children named a children matching element()" ], "a/child::*" );
 
-             deepEqual( utility.xpath.resolve( "a/child::b", "root", "start", xpathResolver ), [ "start children named a children named b" ], "a/child::b" );
 
-             deepEqual( utility.xpath.resolve( "a/ancestor::b", "root", "start", xpathResolver ), [ "start children named a ancestors named b" ], "a/ancestor::b" );
 
-             deepEqual( utility.xpath.resolve( "a/ancestor-or-self::b", "root", "start", xpathResolver ), [ "start children named a and ancestors named b" ], "a/ancestor-or-self::b" );
 
-             deepEqual( utility.xpath.resolve( "a/descendant::b", "root", "start", xpathResolver ), [ "start children named a descendants named b" ], "a/descendant::b" );
 
-             deepEqual( utility.xpath.resolve( "a/descendant-or-self::b", "root", "start", xpathResolver ), [ "start children named a and descendants named b" ], "a/descendant-or-self::b" );
 
-             deepEqual( utility.xpath.resolve( "//", "root", "start", xpathResolver ), [ "root and descendants" ], "//" );
 
-             deepEqual( utility.xpath.resolve( "/", "root", "start", xpathResolver ), [ "root" ], "/" );
 
-             deepEqual( utility.xpath.resolve( "", "root", "start", xpathResolver ), [ "start" ], "empty string" );
 
-             deepEqual( utility.xpath.resolve( [ "" ], "root", "root", xpathResolver ), [ "root and descendants" ], "//, pre-split" );
 
-             deepEqual( utility.xpath.resolve( [], "root", "root", xpathResolver ), [ "root" ], "/, pre-split" );
 
-             deepEqual( utility.xpath.resolve( [], "root", "start", xpathResolver ), [ "start" ], "empty string, pre-split" );
 
-             deepEqual( utility.xpath.resolve( "'*'", "root", "start", xpathResolver ), [ "start children named *" ], "'*', quoted special character" );
 
-             deepEqual( utility.xpath.resolve( "*", "root", "start", xpathResolver ), [ "start children matching element()" ], "*" );
 
-             deepEqual( utility.xpath.resolve( "a", "root", "start", xpathResolver ), [ "start children named a" ], "a" );
 
-             deepEqual( utility.xpath.resolve( [ "*" ], "root", "start", xpathResolver ), [ "start children matching element()" ], "*, pre-split" );
 
-             deepEqual( utility.xpath.resolve( [ "a" ], "root", "start", xpathResolver ), [ "start children named a" ], "a, pre-split" );
 
-             deepEqual( utility.xpath.resolve( "a/*", "root", "start", xpathResolver ), [ "start children named a children matching element()" ], "a/*" );
 
-             deepEqual( utility.xpath.resolve( "a/b", "root", "start", xpathResolver ), [ "start children named a children named b" ], "a/b" );
 
-             deepEqual( utility.xpath.resolve( "a//*", "root", "start", xpathResolver ), [ "start children named a and descendants children matching element()" ], "a//*" );
 
-             deepEqual( utility.xpath.resolve( "a//b", "root", "start", xpathResolver ), [ "start children named a and descendants children named b" ], "a//b" );
 
-             deepEqual( utility.xpath.resolve( "a/./b", "root", "start", xpathResolver ), [ "start children named a children named b" ], "a/./b" );
 
-             deepEqual( utility.xpath.resolve( "a/../b", "root", "start", xpathResolver ), [ "start children named a parent children named b" ], "a/../b" );
 
-             deepEqual( utility.xpath.resolve( [ "a", "*" ], "root", "start", xpathResolver ), [ "start children named a children matching element()" ], "a/*, pre-split" );
 
-             deepEqual( utility.xpath.resolve( [ "a", "b" ], "root", "start", xpathResolver ), [ "start children named a children named b" ], "a/b, pre-split" );
 
-             deepEqual( utility.xpath.resolve( [ "a", "", "*" ], "root", "start", xpathResolver ), [ "start children named a and descendants children matching element()" ], "a//*, pre-split" );
 
-             deepEqual( utility.xpath.resolve( [ "a", "", "b" ], "root", "start", xpathResolver ), [ "start children named a and descendants children named b" ], "a//b, pre-split" );
 
-             deepEqual( utility.xpath.resolve( [ "a", ".", "b" ], "root", "start", xpathResolver ), [ "start children named a children named b" ], "a/./b, pre-split" );
 
-             deepEqual( utility.xpath.resolve( [ "a", "..", "b" ], "root", "start", xpathResolver ), [ "start children named a parent children named b" ], "a/../b, pre-split" );
 
-             deepEqual( utility.xpath.resolve( [ { axis: "child", name: "a" }, { axis: "child", kind: "element" } ], "root", "start", xpathResolver ), [ "start children named a children matching element()" ], "a/*, pre-parsed" );
 
-             deepEqual( utility.xpath.resolve( [ { axis: "child", name: "a" }, { axis: "child", name: "b" } ], "root", "start", xpathResolver ), [ "start children named a children named b" ], "a/b, pre-parsed" );
 
-             deepEqual( utility.xpath.resolve( [ { axis: "child", name: "a" }, { axis: "descendant-or-self", kind: "node" }, { axis: "child", kind: "element" } ], "root", "start", xpathResolver ), [ "start children named a and descendants children matching element()" ], "a//*, pre-parsed" );
 
-             deepEqual( utility.xpath.resolve( [ { axis: "child", name: "a" }, { axis: "descendant-or-self", kind: "node" }, { axis: "child", name: "b" } ], "root", "start", xpathResolver ), [ "start children named a and descendants children named b" ], "a//b, pre-parsed" );
 
-             deepEqual( utility.xpath.resolve( [ { axis: "child", name: "a" }, { axis: "self",  kind: "node" }, { axis: "child", name: "b" } ], "root", "start", xpathResolver ), [ "start children named a children named b" ], "a/./b, pre-parsed" );
 
-             deepEqual( utility.xpath.resolve( [ { axis: "child", name: "a" }, { axis: "parent", kind: "node" }, { axis: "child", name: "b" } ], "root", "start", xpathResolver ), [ "start children named a parent children named b" ], "a/../b, pre-parsed" );
 
-             deepEqual( utility.xpath.resolve( "@*", "root", "start", xpathResolver ), [ "start attributes matching attribute()" ], "*" );
 
-             deepEqual( utility.xpath.resolve( "@r", "root", "start", xpathResolver ), [ "start attributes named r" ], "r" );
 
-             deepEqual( utility.xpath.resolve( "a/@*", "root", "start", xpathResolver ), [ "start children named a attributes matching attribute()" ], "*" );
 
-             deepEqual( utility.xpath.resolve( "a/@r", "root", "start", xpathResolver ), [ "start children named a attributes named r" ], "r" );
 
-             deepEqual( utility.xpath.resolve( "a", "root", [ "alpha" ], xpathResolver ), [ "alpha children named a" ], "a, original context as array" );
 
-             deepEqual( utility.xpath.resolve( "a", "root", [ "beta", "gamma" ], xpathResolver ), [ "beta children named a", "gamma children named a" ], "a, plural original context" );
 
-             // Examples from http://www.w3.org/TR/xpath20/#unabbrev
 
-             deepEqual( utility.xpath.resolve( "child::para", "root", "start", xpathResolver ), [ "start children named para" ], "child::para" );
 
-             deepEqual( utility.xpath.resolve( "child::*", "root", "start", xpathResolver ), [ "start children matching element()" ], "child::*" );
 
-             deepEqual( utility.xpath.resolve( "child::text()", "root", "start", xpathResolver ), [ "start children matching text()" ], "child::text()" );
 
-             deepEqual( utility.xpath.resolve( "child::node()", "root", "start", xpathResolver ), [ "start children" ], "child::node()" );
 
-             deepEqual( utility.xpath.resolve( "attribute::name", "root", "start", xpathResolver ), [ "start attributes named name" ], "attribute::name" );
 
-             deepEqual( utility.xpath.resolve( "attribute::*", "root", "start", xpathResolver ), [ "start attributes matching attribute()" ], "attribute::*" );
 
-             deepEqual( utility.xpath.resolve( "parent::node()", "root", "start", xpathResolver ), [ "start parent" ], "parent::node()" );
 
-             deepEqual( utility.xpath.resolve( "descendant::para", "root", "start", xpathResolver ), [ "start descendants named para" ], "descendant::para" );
 
-             deepEqual( utility.xpath.resolve( "ancestor::div", "root", "start", xpathResolver ), [ "start ancestors named div" ], "ancestor::div" );
 
-             deepEqual( utility.xpath.resolve( "ancestor-or-self::div", "root", "start", xpathResolver ), [ "start and ancestors named div" ], "ancestor-or-self::div" );
 
-             deepEqual( utility.xpath.resolve( "descendant-or-self::para", "root", "start", xpathResolver ), [ "start and descendants named para" ], "descendant-or-self::para" );
 
-             deepEqual( utility.xpath.resolve( "self::para", "root", "start", xpathResolver ), [ "start named para" ], "self::para" );
 
-             deepEqual( utility.xpath.resolve( "child::chapter/descendant::para", "root", "start", xpathResolver ), [ "start children named chapter descendants named para" ], "child::chapter/descendant::para" );
 
-             deepEqual( utility.xpath.resolve( "child::*/child::para", "root", "start", xpathResolver ), [ "start children matching element() children named para" ], "child::*/child::para" );
 
-             deepEqual( utility.xpath.resolve( "/", "root", "start", xpathResolver ), [ "root" ], "/" );
 
-             deepEqual( utility.xpath.resolve( "/descendant::para", "root", "start", xpathResolver ), [ "root descendants named para" ], "/descendant::para" );
 
-             deepEqual( utility.xpath.resolve( "/descendant::list/child::member", "root", "start", xpathResolver ), [ "root descendants named list children named member" ], "/descendant::list/child::member" );
 
-             // n/a: predicate+expression -- deepEqual( utility.xpath.resolve( "child::para[fn:position() = 1]", "root", "start", xpathResolver ), [ "n/a" ], "child::para[fn:position() = 1]" );
 
-             // n/a: predicate+expression -- deepEqual( utility.xpath.resolve( "child::para[fn:position() = fn:last()]", "root", "start", xpathResolver ), [ "n/a" ], "child::para[fn:position() = fn:last()]" );
 
-             // n/a: predicate+expression -- deepEqual( utility.xpath.resolve( "child::para[fn:position() = fn:last()-1]", "root", "start", xpathResolver ), [ "n/a" ], "child::para[fn:position() = fn:last()-1]" );
 
-             // n/a: predicate+expression -- deepEqual( utility.xpath.resolve( "child::para[fn:position() > 1]", "root", "start", xpathResolver ), [ "n/a" ], "child::para[fn:position() > 1]" );
 
-             // n/a: predicate+expression -- deepEqual( utility.xpath.resolve( "following-sibling::chapter[fn:position() = 1]", "root", "start", xpathResolver ), [ "n/a" ], "following-sibling::chapter[fn:position() = 1]" );
 
-             // n/a: predicate+expression -- deepEqual( utility.xpath.resolve( "preceding-sibling::chapter[fn:position() = 1]", "root", "start", xpathResolver ), [ "n/a" ], "preceding-sibling::chapter[fn:position() = 1]" );
 
-             // n/a: predicate+expression -- deepEqual( utility.xpath.resolve( "/descendant::figure[fn:position() = 42]", "root", "start", xpathResolver ), [ "n/a" ], "/descendant::figure[fn:position() = 42]" );
 
-             // n/a: predicate+expression -- deepEqual( utility.xpath.resolve( "/child::book/child::chapter[fn:position() = 5]/child::section[fn:position() = 2]", "root", "start", xpathResolver ), [ "n/a" ], "/child::book/child::chapter[fn:position() = 5]/child::section[fn:position() = 2]" );
 
-             // n/a: predicate+expression -- deepEqual( utility.xpath.resolve( "child::para[attribute::type eq 'warning]", "root", "start", xpathResolver ), [ "n/a" ], "child::para[attribute::type eq 'warning]" );
 
-             // n/a: predicate+expression -- deepEqual( utility.xpath.resolve( "child::para[attribute::type eq 'warning'][fn:position() = 5]", "root", "start", xpathResolver ), [ "n/a" ], "child::para[attribute::type eq 'warning'][fn:position() = 5]" );
 
-             // n/a: predicate+expression -- deepEqual( utility.xpath.resolve( "child::para[fn:position() = 5][attribute::type eq 'warning']", "root", "start", xpathResolver ), [ "n/a" ], "child::para[fn:position() = 5][attribute::type eq 'warning']" );
 
-             // n/a: predicate+expression -- deepEqual( utility.xpath.resolve( "child::chapter[child::title = 'Introduction']", "root", "start", xpathResolver ), [ "n/a" ], "child::chapter[child::title = 'Introduction']" );
 
-             // n/a: predicate -- deepEqual( utility.xpath.resolve( "child::chapter[child::title]", "root", "start", xpathResolver ), [ "n/a" ], "child::chapter[child::title]" );
 
-             // n/a: predicate+expression -- deepEqual( utility.xpath.resolve( "child::*[self::chapter or self::appendix]", "root", "start", xpathResolver ), [ "n/a" ], "child::*[self::chapter or self::appendix]" );
 
-             // n/a: predicate+expression -- deepEqual( utility.xpath.resolve( "child::*[self::chapter or self::appendix][fn:position() = fn:last()]", "root", "start", xpathResolver ), [ "n/a" ], "child::*[self::chapter or self::appendix][fn:position() = fn:last()]" );
 
-             // Examples from http://www.w3.org/TR/xpath20/#abbrev
 
-             deepEqual( utility.xpath.resolve( "para", "root", "start", xpathResolver ), [ "start children named para" ], "para" );
 
-             deepEqual( utility.xpath.resolve( "*", "root", "start", xpathResolver ), [ "start children matching element()" ], "*" );
 
-             deepEqual( utility.xpath.resolve( "text()", "root", "start", xpathResolver ), [ "start children matching text()" ], "text()" );
 
-             deepEqual( utility.xpath.resolve( "@name", "root", "start", xpathResolver ), [ "start attributes named name" ], "@name" );
 
-             deepEqual( utility.xpath.resolve( "@*", "root", "start", xpathResolver ), [ "start attributes matching attribute()" ], "@*" );
 
-             // n/a: predicate -- deepEqual( utility.xpath.resolve( "para[1]", "root", "start", xpathResolver ), [ "n/a" ], "para[1]" );
 
-             // n/a: predicate+expression -- deepEqual( utility.xpath.resolve( "para[fn:last()]", "root", "start", xpathResolver ), [ "n/a" ], "para[fn:last()]" );
 
-             deepEqual( utility.xpath.resolve( "*/para", "root", "start", xpathResolver ), [ "start children matching element() children named para" ], "*/para" );
 
-             // n/a: predicate+expression -- deepEqual( utility.xpath.resolve( "/book/chapter[5]/section[2]", "root", "start", xpathResolver ), [ "n/a" ], "/book/chapter[5]/section[2]" );
 
-             deepEqual( utility.xpath.resolve( "chapter//para", "root", "start", xpathResolver ), [ "start children named chapter and descendants children named para" ], "chapter//para" );
 
-             deepEqual( utility.xpath.resolve( "//para", "root", "start", xpathResolver ), [ "root and descendants children named para" ], "//para" );
 
-             deepEqual( utility.xpath.resolve( "//@version", "root", "start", xpathResolver ), [ "root and descendants attributes named version" ], "//@version" );
 
-             deepEqual( utility.xpath.resolve( "//list/member", "root", "start", xpathResolver ), [ "root and descendants children named list children named member" ], "//list/member" );
 
-             deepEqual( utility.xpath.resolve( ".//para", "root", "start", xpathResolver ), [ "start and descendants children named para" ], ".//para" );
 
-             deepEqual( utility.xpath.resolve( "..", "root", "start", xpathResolver ), [ "start parent" ], ".." );
 
-             deepEqual( utility.xpath.resolve( "../@lang", "root", "start", xpathResolver ), [ "start parent attributes named lang" ], "../@lang" );
 
-             // n/a: predicate+expression -- deepEqual( utility.xpath.resolve( "para[@type='warning']", "root", "start", xpathResolver ), [ "n/a" ], "para[@type='warning']" );
 
-             // n/a: predicate+expression -- deepEqual( utility.xpath.resolve( "para[@type='warning'][5]", "root", "start", xpathResolver ), [ "n/a" ], "para[@type='warning'][5]" );
 
-             // n/a: predicate+expression -- deepEqual( utility.xpath.resolve( "para[5][@type='warning']", "root", "start", xpathResolver ), [ "n/a" ], "para[5][@type='warning']" );
 
-             // n/a: predicate+expression -- deepEqual( utility.xpath.resolve( "chapter[title='Introduction']", "root", "start", xpathResolver ), [ "n/a" ], "chapter[title='Introduction']" );
 
-             // n/a: predicate -- deepEqual( utility.xpath.resolve( "chapter[title]", "root", "start", xpathResolver ), [ "n/a" ], "chapter[title]" );
 
-             // n/a: predicate+expression -- deepEqual( utility.xpath.resolve( "employee[@secretary and @assistant]", "root", "start", xpathResolver ), [ "n/a" ], "employee[@secretary and @assistant]" );
 
-             // n/a: expression -- deepEqual( utility.xpath.resolve( "book/(chapter|appendix)/section", "root", "start", xpathResolver ), [ "n/a" ], "book/(chapter|appendix)/section" );
 
-           } );
 
-           // == xpath.parse ========================================================================
 
-           test( "XPath parsed", function() {
 
-             var result = [ { axis: "child", kind: undefined, name: "a", type: undefined }, { axis: "child", kind: undefined, name: "b", type: undefined } ];
 
-             deepEqual( utility.xpath.parse( "a/b" ), result, "string" );
 
-             deepEqual( utility.xpath.parse( [ "a", "b" ] ), result, "pre-split" );
 
-             deepEqual( utility.xpath.parse( result ), result, "pre-parsed" );
 
-           } );
 
-           // == xpath.parseStep ====================================================================
 
-           test( "XPath steps", function() {
 
-             deepEqual( utility.xpath.parseStep( "" ), { axis: "descendant-or-self", kind: "node", name: undefined, type: undefined }, "AbbreviatedRelativeLocationPath" ); // http://www.w3.org/TR/xpath/#NT-AbbreviatedRelativeLocationPath
 
-             deepEqual( utility.xpath.parseStep( "." ), { axis: "self",  kind: "node", name: undefined, type: undefined }, "AbbreviatedStep, self" ); // http://www.w3.org/TR/xpath/#NT-AbbreviatedStep
 
-             deepEqual( utility.xpath.parseStep( ".." ), { axis: "parent", kind: "node", name: undefined, type: undefined }, "AbbreviatedStep, parent" ); // http://www.w3.org/TR/xpath/#NT-AbbreviatedStep
 
-             deepEqual( utility.xpath.parseStep( "child::a" ), { axis: "child", kind: undefined, name: "a", type: undefined }, "AxisSpecifier, child" ); // http://www.w3.org/TR/xpath/#NT-AxisSpecifier
 
-             deepEqual( utility.xpath.parseStep( "a" ), { axis: "child", kind: undefined, name: "a", type: undefined }, "AbbreviatedAxisSpecifier, child" ); // http://www.w3.org/TR/xpath/#NT-AbbreviatedAxisSpecifier
 
-             deepEqual( utility.xpath.parseStep( "attribute::a" ), { axis: "attribute", kind: undefined, name: "a", type: undefined }, "AxisSpecifier, attribute" ); // http://www.w3.org/TR/xpath/#NT-AxisSpecifier
 
-             deepEqual( utility.xpath.parseStep( "@a" ), { axis: "attribute", kind: undefined, name: "a", type: undefined }, "AbbreviatedAxisSpecifier, attribute" ); // http://www.w3.org/TR/xpath/#NT-AbbreviatedAxisSpecifier
 
-             deepEqual( utility.xpath.parseStep( "child::*" ), { axis: "child", kind: "element", name: undefined, type: undefined }, "AxisSpecifier+NameTest, wildcard" ); // http://www.w3.org/TR/xpath/#NT-NameTest
 
-             deepEqual( utility.xpath.parseStep( "*" ), { axis: "child", kind: "element", name: undefined, type: undefined }, "AbbreviatedAxisSpecifier+NameTest, wildcard" ); // http://www.w3.org/TR/xpath/#NT-NameTest
 
-             deepEqual( utility.xpath.parseStep( "node()" ), { axis: "child", kind: "node", name: undefined, type: undefined }, "KindTest" ); // http://www.w3.org/TR/xpath20/#prod-xpath-KindTest
 
-             deepEqual( utility.xpath.parseStep( "node(b)" ), { axis: "child", kind: "node", name: "b", type: undefined }, "KindTest, node name" ); // http://www.w3.org/TR/xpath20/#prod-xpath-KindTest
 
-             deepEqual( utility.xpath.parseStep( "node(b,t)" ), { axis: "child", kind: "node", name: "b", type: "t" }, "KindTest, node name, node type" ); // http://www.w3.org/TR/xpath20/#prod-xpath-KindTest
 
-             deepEqual( utility.xpath.parseStep( "'a+b'" ), { axis: "child", kind: undefined, name: "a+b", type: undefined }, "quoted NameTest, single quotes" );
 
-             deepEqual( utility.xpath.parseStep( "'a\\'\"\\+\"\\'b'" ), { axis: "child", kind: undefined, name: "a'\"\\+\"'b", type: undefined }, "quoted NameTest, single quotes with embedded escapes" );
 
-             deepEqual( utility.xpath.parseStep( '"a+a"' ), { axis: "child", kind: undefined, name: "a+a", type: undefined }, "quoted NameTest, double quotes" );
 
-             deepEqual( utility.xpath.parseStep( '"a\'\\"\\+\\"\'a"' ), { axis: "child", kind: undefined, name: "a'\"\\+\"'a", type: undefined }, "quoted NameTest, double quotes with embedded escapes" );
 
-             deepEqual( utility.xpath.parseStep( 'node("b+b")' ), { axis: "child", kind: "node", name: "b+b", type: undefined }, "KindTest, quoted node name" );
 
-             deepEqual( utility.xpath.parseStep( 'node(b,"http://vwf.example.com/node.vwf")' ), { axis: "child", kind: "node", name: "b", type: "http://vwf.example.com/node.vwf" }, "KindTest, node name, quoted node type" );
 
-             deepEqual( utility.xpath.parseStep( '"."' ), { axis: "child", kind: undefined, name: ".", type: undefined }, "quoted NameTest, xpath token: abbreviated step self" );
 
-             deepEqual( utility.xpath.parseStep( '".."' ), { axis: "child", kind: undefined, name: "..", type: undefined }, "quoted NameTest, xpath token: abbreviated step parent" );
 
-             deepEqual( utility.xpath.parseStep( '"@a"' ), { axis: "child", kind: undefined, name: "@a", type: undefined }, "quoted NameTest, xpath token: abbreviated axis attribute" );
 
-             deepEqual( utility.xpath.parseStep( '"axis::"' ), { axis: "child", kind: undefined, name: "axis::", type: undefined }, "quoted NameTest, xpath token: axis" );
 
-             deepEqual( utility.xpath.parseStep( '"*"' ), { axis: "child", kind: undefined, name: "*", type: undefined }, "quoted NameTest, xpath token: wildcard" );
 
-           } );
 
-           // == xpath.parsePredicate ===============================================================
 
-           test( "XPath predicates", function() {
 
-             var xpath;
 
-             deepEqual( utility.xpath.parsePredicate( "" ), undefined, "empty" );
 
-             deepEqual( utility.xpath.parsePredicate( "a" ), undefined, "step" );
 
-             deepEqual( utility.xpath.parsePredicate( "/" ), undefined, "separator" );
 
-             xpath = "[a]";
 
-             deepEqual( utility.xpath.parsePredicate( xpath ), [ { axis: "child", kind: undefined, name: "a", type: undefined } ], "string" );
 
-             xpath = { string: "[a]", index: 0 };
 
-             deepEqual( utility.xpath.parsePredicate( xpath ), [ { axis: "child", kind: undefined, name: "a", type: undefined } ], "object" );
 
-             deepEqual( xpath, { string: "[a]", index: 3 }, "object" );
 
-             xpath = { string: "['[]']", index: 0 };
 
-             deepEqual( utility.xpath.parsePredicate( xpath ), [ { axis: "child", kind: undefined, name: "[]", type: undefined } ], "quoted brackets" );
 
-             deepEqual( xpath, { string: "['[]']", index: 6 }, "quoted brackets" );
 
-             xpath = { string: "[a][b]", index: 0 };
 
-             deepEqual( utility.xpath.parsePredicate( xpath ), [ { axis: "child", kind: undefined, name: "a", type: undefined } ], "predicate terminator" );
 
-             deepEqual( xpath, { string: "[a][b]", index: 3 }, "predicate terminator" );
 
-             // not implemented: xpath = { string: "[a[b]]", index: 0 };
 
-             // not implemented: deepEqual( utility.xpath.parsePredicate( xpath ), [ { axis: "child", kind: undefined, name: "a", type: undefined, predicates: [ { axis: "child", kind: undefined, name: "b", type: undefined } ] } ], "nested" );
 
-             // not implemented: deepEqual( xpath, { string: "[a[b]]", index: 6 }, "nested" );
 
-             xpath = { string: "[a]/", index: 0 };
 
-             deepEqual( utility.xpath.parsePredicate( xpath ), [ { axis: "child", kind: undefined, name: "a", type: undefined } ], "separator terminator" );
 
-             deepEqual( xpath, { string: "[a]/", index: 3 }, "separator terminator" );
 
-           } );
 
-           // == xpath.parseSeparator ===============================================================
 
-           test( "XPath separator", function() {
 
-             var xpath;
 
-             xpath = "/";
 
-             equal( utility.xpath.parseSeparator( xpath ), true, "string" );
 
-             xpath = { string: "/", index: 0 };
 
-             equal( utility.xpath.parseSeparator( xpath ), true, "object" );
 
-             xpath = { string: "/", index: 0 };
 
-             equal( utility.xpath.parseSeparator( xpath ), true, "single" );
 
-             deepEqual( xpath, { string: "/", index: 1 }, "single" );
 
-             xpath = { string: "a/b", index: 1 };
 
-             equal( utility.xpath.parseSeparator( xpath ), true, "middle" );
 
-             deepEqual( xpath, { string: "a/b", index: 2 }, "middle" );
 
-             xpath = { string: "a", index: 0 };
 
-             equal( utility.xpath.parseSeparator( xpath ), undefined, "missing" );
 
-             deepEqual( xpath, { string: "a", index: 0 }, "missing" );
 
-             xpath = { string: "", index: 0 };
 
-             equal( utility.xpath.parseSeparator( xpath ), undefined, "empty" );
 
-             deepEqual( xpath, { string: "", index: 0 }, "empty" );
 
-           } );
 
-           // == xpath.quoteName, xpath.unquoteName =================================================
 
-           test( "XPath quoting", function() {
 
-             deepEqual( utility.xpath.quoteName( 'a' ), '"a"', "plain" );
 
-             deepEqual( utility.xpath.quoteName( "'a'" ), '"\'a\'"', "embedded single quote" );
 
-             deepEqual( utility.xpath.quoteName( '"a"' ), '"\\"a\\""', "embedded double quote" );
 
-             deepEqual( utility.xpath.quoteName( '\\a\\' ), '"\\\\a\\\\"', "embedded escape" );
 
-             deepEqual( utility.xpath.unquoteName( '"a"' ), 'a', "plain" );
 
-             deepEqual( utility.xpath.unquoteName( '"\'a\'"' ), "'a'", "embedded single quote" );
 
-             deepEqual( utility.xpath.unquoteName( '"\\"a\\""' ), '"a"', "embedded double quote" );
 
-             deepEqual( utility.xpath.unquoteName( '"\\\\a\\\\"' ), '\\a\\', "embedded escape" );
 
-           } );
 
-           // == Helper functions ===================================================================
 
-           // Resolve an xpath step with a description of the work to be done.
 
-           function xpathResolver( step, id ) {
 
-             var result = id;
 
-             switch ( step.axis ) {
 
-               // case "preceding":
 
-               // case "preceding-sibling":
 
-               case "ancestor-or-self":
 
-                 result += " and ancestors";
 
-                 break;
 
-               case "ancestor":
 
-                 result += " ancestors";
 
-                 break;
 
-               case "parent":
 
-                 result += " parent";
 
-                 break;
 
-               case "self":
 
-                 break;
 
-               case "child":
 
-                 result += " children";
 
-                 break;
 
-               case "descendant":
 
-                 result += " descendants";
 
-                 break;
 
-               case "descendant-or-self":
 
-                 result += " and descendants";
 
-                 break;
 
-               // case "following-sibling":
 
-               // case "following":
 
-               case "attribute":
 
-                 result += " attributes";
 
-                 break;
 
-               // case "namespace":
 
-             }
 
-             if ( step.kind && step.kind != "node" ) {
 
-               result += " matching " + step.kind + "()";
 
-             }
 
-             if ( step.name ) result += " named " + step.name;
 
-             if ( step.type ) result += " typed " + step.type;
 
-             return [ result ];
 
-           }
 
-         } );
 
-       } );
 
-     </script>
 
-     <link rel="stylesheet" type="text/css" href="qunit.css" />
 
-   </head>
 
-   <body>
 
-     <h1 id="qunit-header">Virtual World Framework</h1>
 
-     <h2 id="qunit-banner"></h2>
 
-     <div id="qunit-testrunner-toolbar"></div>
 
-     <h2 id="qunit-userAgent"></h2>
 
-     <ol id="qunit-tests"></ol>
 
-     <div id="qunit-fixture">test markup, will be hidden</div>
 
-   </body>
 
- </html>
 
 
  |