/* Copyright (c) 2006 Ricebridge. All Rights Reserved.
 *
 * This file is available under the terms and conditions of the
 * Ricebridge "Open Source API" policy; Ricebridge grants use of this
 * copyrighted work under the terms of a BSD-style license only. See
 * http://www.opensource.org/licenses/bsd-license.php for more
 * information.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 *  - Redistributions of source code must retain the above copyright
 *  notice, this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above
 *  copyright notice, this list of conditions and the following
 *  disclaimer in the documentation and/or other materials provided
 *  with the distribution.
 *
 *  - Neither the name of the Ricebridge nor the names of its
 *  contributors may be used to endorse or promote products derived
 *  from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.  
 */

package com.ricebridge.xmlman.in.test;


import com.ricebridge.xmlman.*;
import com.ricebridge.xmlman.XmlManagerException;
import com.ricebridge.xmlman.in.*;

import org.jostraca.util.*;

import junit.framework.*;
import junit.textui.*;

import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;

import java.util.*;
import java.io.*;


/** Test cases for supported XPath axes. 
 *    <p>Test file is <a href="axis.xml">axis.xml</a>.</p>
 *    <p>The <b><a href="AxisTest.java.html">Source Code</a></b> of this Java class 
 *    is available under a <a href="http://www.opensource.org/licenses/bsd-license.php">BSD-style license</a>.</p>
 */
public class AxisTest extends TestCase {

  // test framework
  
  public AxisTest( String pName ) {
    super( pName );
  }

  public static TestSuite suite() {
    return new TestSuite( AxisTest.class );
  }

  public static void main( String[] pArgs ) {
    TestRunner.run( suite() );
  }



  private static ArrayList sRecordSpecList = new ArrayList();
  private static ArrayList sRecordDataList = new ArrayList();


  static {
    ArrayList records;

    sRecordSpecList.add( new RecordSpec( "/descendant::que", new String[] { "@name", "/foo/@name", "rb:trim(/foo)" } ) );
    records = new ArrayList();
    records.add( new String[] { "que1", "foo1", "ft1\n  ft2" } );
    records.add( new String[] { "que2", "foo1", "ft1\n  ft2" } );
    records.add( new String[] { "que3", "foo1", "ft1\n  ft2" } );
    sRecordDataList.add( records );



    sRecordSpecList.add( new RecordSpec( "/foo/bar", new String[] { "@name", 

                                                                    // if these were absolute, the values would persist
                                                                    ".//que//noo/@name",
                                                                    ".//que[@color='green']//noo/@name",
                                                                    ".//que[//noo]//noo/@name",
                                                                    ".//que[//noo//boo]//noo/@name", 
    } ) );
    sRecordDataList.add( ListUtil.make( new String[] { "bar1", "noo1", "noo1", "noo1", "noo1" },
                                        new String[] { "bar2", "", "", "", "" },
                                        new String[] { "bar3", "", "", "", "" } ) );


    sRecordSpecList.add( new RecordSpec( "/foo/bar", new String[] { "//noo/@name", 
                                                                    ".//noo/@name"  } ) );
    sRecordDataList.add( ListUtil.make( new String[] { "noo1", "noo1" },
                                        new String[] { "noo1", "" },
                                        new String[] { "noo1", "" }  ) );

    // que before empty bar
    sRecordSpecList.add( new RecordSpec( "/foo/bar", new String[] { "//que/@name" } ) );
    sRecordDataList.add( ListUtil.make( new String[] { "que1" },
                                        new String[] { "que2" },
                                        new String[] { "que2" }  ) );

    // last bar has no que
    sRecordSpecList.add( new RecordSpec( "/foo/bar", new String[] { ".//que/@name" } ) );
    sRecordDataList.add( ListUtil.make( new String[] { "que1" },
                                        new String[] { "que2" },
                                        new String[] { "" } ) );

    sRecordSpecList.add( new RecordSpec( "//foo//bar//que", new String[] { "@name" } ) );
    sRecordDataList.add( ListUtil.make( new String[] { "que1" },
                                        new String[] { "que2" } ) );


    sRecordSpecList.add( new RecordSpec( "//foo//bar", new String[] { "@name" } ) );
    sRecordDataList.add( ListUtil.make( new String[] { "bar1" },
                                        new String[] { "bar2" },
                                        new String[] { "bar3" } ) );


    sRecordSpecList.add( new RecordSpec( "//foo", new String[] { "@name" } ) );
    sRecordDataList.add( ListUtil.make( new String[] { "foo2" },
                                        new String[] { "foo1" } ) );


    sRecordSpecList.add( new RecordSpec( "/foo/entry", new String[] { "@name", 
                                                                      "/foo/link[not(@rel)]/@href", 
                                                                      "/foo/link[@rel]/@href", 
                                                                      "//que/@name",
                                                                      "/foo/que/@name" } ) );
    sRecordDataList.add( ListUtil.make( new String[] { "e1", "href1", "href2", "que3", "que3" } ) );

    sRecordSpecList.add( new RecordSpec( "/foo/bar/que", new String[] { "@name", "/foo/bar/@name" }  ) );
    sRecordDataList.add( ListUtil.make( new String[] { "que1", "bar1" },
                                        new String[] { "que2", "bar2" } ) );

    sRecordSpecList.add( new RecordSpec( "/*", new String[] { "@name" }  ) );
    sRecordDataList.add( ListUtil.make( new String[] { "foo1" } ) );

    sRecordSpecList.add( new RecordSpec( "//*", new String[] { "@name" }  ) );
    records = new ArrayList();
    records.add( new String[] { "foo2" } );
    records.add( new String[] { "boo1" } );
    records.add( new String[] { "noo1" } );
    records.add( new String[] { "que1" } );
    records.add( new String[] { "bar1" } );
    records.add( new String[] { "que2" } );
    records.add( new String[] { "bar2" } );
    records.add( new String[] { "bar3" } );
    records.add( new String[] { "que4" } );
    records.add( new String[] { "que3" } );
    records.add( new String[] { "" } );  // link elements have no name
    records.add( new String[] { "" } );
    records.add( new String[] { "e1" } );
    records.add( new String[] { "foo1" } );
    sRecordDataList.add( records );

    sRecordSpecList.add( new RecordSpec( "/foo/*", new String[] { "@name" }  ) );
    records = new ArrayList();
    records.add( new String[] { "foo2" } );
    records.add( new String[] { "bar1" } );
    records.add( new String[] { "bar2" } );
    records.add( new String[] { "bar3" } );
    records.add( new String[] { "que3" } );
    records.add( new String[] { "" } );  // link elements have no name
    records.add( new String[] { "" } );
    records.add( new String[] { "e1" } );
    sRecordDataList.add( records );

    sRecordSpecList.add( new RecordSpec( "/*/bar", new String[] { "@name" }  ) );
    records = new ArrayList();
    records.add( new String[] { "bar1" } );
    records.add( new String[] { "bar2" } );
    records.add( new String[] { "bar3" } );
    sRecordDataList.add( records );
    
    sRecordSpecList.add( new RecordSpec( "/foo/bar/que", new String[] { "@name" }  ) );
    records = new ArrayList();
    records.add( new String[] { "que1" } );
    records.add( new String[] { "que2" } );
    sRecordDataList.add( records );

    sRecordSpecList.add( new RecordSpec( "/foo/*/que", new String[] { "@name" }  ) );
    records = new ArrayList();
    records.add( new String[] { "que1" } );
    records.add( new String[] { "que2" } );
    records.add( new String[] { "que4" } );
    sRecordDataList.add( records );

    sRecordSpecList.add( new RecordSpec( "/foo", new String[] { "@*", "name(@*)", "namespace-uri(@*)" }  ) );
    records = new ArrayList();
    records.add( new String[] { "foo1", "name", "" } );
    sRecordDataList.add( records );


    sRecordSpecList.add( new RecordSpec( "//bar", new String[] { "@name" } ) );
    records = new ArrayList();
    records.add( new String[] { "bar1" } );
    records.add( new String[] { "bar2" } );
    records.add( new String[] { "bar3" } );
    sRecordDataList.add( records );

    sRecordSpecList.add( new RecordSpec( "/descendant::bar", new String[] { "@name" } ) );
    records = new ArrayList();
    records.add( new String[] { "bar1" } );
    records.add( new String[] { "bar2" } );
    records.add( new String[] { "bar3" } );
    sRecordDataList.add( records );

    sRecordSpecList.add( new RecordSpec( "//bar[1]", new String[] { "@name" } ) );
    records = new ArrayList();
    records.add( new String[] { "bar1" } );
    sRecordDataList.add( records );

    sRecordSpecList.add( new RecordSpec( "/descendant::bar[1]", new String[] { "@name" } ) );
    records = new ArrayList();
    records.add( new String[] { "bar1" } );
    sRecordDataList.add( records );


    sRecordSpecList.add( new RecordSpec( "//que", new String[] { "@name" } ) );
    records = new ArrayList();
    records.add( new String[] { "que1" } );
    records.add( new String[] { "que2" } );
    records.add( new String[] { "que4" } );
    records.add( new String[] { "que3" } );
    sRecordDataList.add( records );
   

    sRecordSpecList.add( new RecordSpec( "/que", new String[] { "@name" } ) );
    records = new ArrayList();
    sRecordDataList.add( records );


    sRecordSpecList.add( new RecordSpec( "/descendant::que", new String[] { "@name", "/foo/@name", "rb:trim(/foo/text()[1])" } ) );
    records = new ArrayList();
    records.add( new String[] { "que1", "foo1", "ft1" } );
    records.add( new String[] { "que2", "foo1", "ft1" } );
    records.add( new String[] { "que3", "foo1", "ft1" } );
    sRecordDataList.add( records );

    
    sRecordSpecList.add( new RecordSpec( "//que[1]", new String[] { "@name" } ) );
    records = new ArrayList();
    records.add( new String[] { "que1" } );
    records.add( new String[] { "que2" } );
    records.add( new String[] { "que4" } );
    records.add( new String[] { "que3" } );
    sRecordDataList.add( records );

    // spec requires that we return que3,
    // but this is impossible without look ahead (which we don't have)
    // our implementation just prevents que sub matches (que4)

    sRecordSpecList.add( new RecordSpec( "/descendant::que[1]", new String[] { "@name" } ) );
    records = new ArrayList();
    records.add( new String[] { "que1" } );
    records.add( new String[] { "que2" } );
    records.add( new String[] { "que3" } );
    sRecordDataList.add( records );

  } 
  


  // test methods

  public void testUnsupAxis() {

    String[] parents = new String[] { "..", 
                                      "../foo", "foo/..", 
                                      "/../foo", "/foo/..", 
                                      "/foo/bar/..", "/foo/../bar" };

    for( int pI = 0; pI < parents.length; pI++ ) {
      try {
        TestUtil.testRecordSpec( new RecordSpec( parents[pI], new String[]{} ) );
        fail( parents[pI] );
      }
      catch( XmlManagerException xme ) {
        System.out.println( xme );
        assertEquals( XmlManagerException.CODE_unsup_axis, xme.getCode() );
      }
    } 


    String[] unsupaxis = new String[] { "parent", 
                                        "ancestor", "ancestor-or-self", 
                                        "following-sibling", "preceding-sibling", 
                                        "following", 
                                        "preceding" };

    for( int aI = 0; aI < unsupaxis.length; aI++ ) {
      try {
        TestUtil.testRecordSpec( new RecordSpec( "/"+unsupaxis[aI]+"::foo", new String[]{} ) );
        fail( unsupaxis[aI] );
      }
      catch( XmlManagerException xme ) {
        System.out.println( xme );
        assertEquals( XmlManagerException.CODE_unsup_axis, xme.getCode() );
      }
    } 

      try {
        String parenexpr = "(//foo)[1]";
        TestUtil.testRecordSpec( new RecordSpec( parenexpr, new String[]{} ) );
        fail( parenexpr );
      }
      catch( XmlManagerException xme ) {
        assertEquals( XmlManagerException.CODE_filter_expr, xme.getCode() );
      }

  }

  
  public void testAxis() throws Exception {
    TestUtil.testRecords( "com/ricebridge/xmlman/in/test/axis.xml", sRecordSpecList, sRecordDataList, this );
  }

}





Syntax Highlighting created using the com.Ostermiller.Syntax package.
Thursday, February 23 2006 at 16:47