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>
|