Package org.apache.commons.digester3

Source Code of org.apache.commons.digester3.TestConfigureDigester

/* $Id: DigesterTestCase.java 1212599 2011-12-09 19:46:42Z simonetripodi $
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.commons.digester3;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.File;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.math.BigDecimal;
import java.net.URL;
import java.util.ArrayList;
import java.util.EmptyStackException;
import java.util.Map;

import org.apache.commons.digester3.Digester;
import org.apache.commons.digester3.ObjectCreateRule;
import org.apache.commons.digester3.Rule;
import org.apache.commons.digester3.RulesBase;
import org.apache.commons.digester3.StackAction;
import org.apache.commons.digester3.Substitutor;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.helpers.AttributesImpl;

/**
* <p>
* Test Case for the Digester class. These tests exercise the individual methods of a Digester, but do not attempt to
* process complete documents.
* </p>
*
* @author Craig R. McClanahan
*/
public class DigesterTestCase
{

    // ----------------------------------------------------- Instance Variables

    /**
     * The digester instance we will be processing.
     */
    protected Digester digester = null;

    /**
     * The set of public identifiers, and corresponding resource names, for the versions of the DTDs that we know about.
     * There <strong>MUST</strong> be an even number of Strings in this array.
     */
    protected static final String registrations[] = { "-//Netscape Communications//DTD RSS 0.9//EN",
        "/org/apache/commons/digester3/rss/rss-0.9.dtd", "-//Netscape Communications//DTD RSS 0.91//EN",
        "/org/apache/commons/digester3/rss/rss-0.91.dtd", };

    // -------------------------------------------------- Overall Test Methods

    /**
     * Set up instance variables required by this test case.
     */
    @Before
    public void setUp()
    {

        digester = new Digester();
        digester.setRules( new RulesBase() );

    }

    /**
     * Tear down instance variables required by this test case.
     */
    @After
    public void tearDown()
    {

        digester = null;

    }

    // ------------------------------------------------ Individual Test Methods

    /**
     * Test <code>null</code> parsing. (should lead to <code>IllegalArgumentException</code>s)
     */
    @Test
    public void testNullFileParse()
        throws Exception
    {

        try
        {
            digester.parse( (File) null );
            fail( "Expected IllegalArgumentException with null argument" );
        }
        catch ( IllegalArgumentException e )
        {
            // expected
        }

    }

    @Test
    public void testNullInputSourceParse()
        throws Exception
    {

        try
        {
            digester.parse( (InputSource) null );
            fail( "Expected IllegalArgumentException with null argument" );
        }
        catch ( IllegalArgumentException e )
        {
            // expected
        }

    }

    @Test
    public void testNullInputStreamParse()
        throws Exception
    {

        try
        {
            digester.parse( (InputStream) null );
            fail( "Expected IllegalArgumentException with null argument" );
        }
        catch ( IllegalArgumentException e )
        {
            // expected
        }

    }

    @Test
    public void testNullReaderParse()
        throws Exception
    {

        try
        {
            digester.parse( (Reader) null );
            fail( "Expected IllegalArgumentException with null argument" );
        }
        catch ( IllegalArgumentException e )
        {
            // expected
        }

    }

    @Test
    public void testNullStringParse()
        throws Exception
    {

        try
        {
            digester.parse( (String) null );
            fail( "Expected IllegalArgumentException with null argument" );
        }
        catch ( IllegalArgumentException e )
        {
            // expected
        }

    }

    @Test
    public void testNullURLParse()
        throws Exception
    {

        try
        {
            digester.parse( (URL) null );
            fail( "Expected IllegalArgumentException with null argument" );
        }
        catch ( IllegalArgumentException e )
        {
            // expected
        }

    }

    /**
     * Test the basic property getters and setters.
     */
    @Test
    public void testProperties()
    {

        assertNull( "Initial error handler is null", digester.getErrorHandler() );
        digester.setErrorHandler( digester );
        assertTrue( "Set error handler is digester", digester.getErrorHandler() == digester );
        digester.setErrorHandler( null );
        assertNull( "Reset error handler is null", digester.getErrorHandler() );

        assertTrue( "Initial namespace aware is false", !digester.getNamespaceAware() );
        digester.setNamespaceAware( true );
        assertTrue( "Set namespace aware is true", digester.getNamespaceAware() );
        digester.setNamespaceAware( false );
        assertTrue( "Reset namespace aware is false", !digester.getNamespaceAware() );

        assertTrue( "Initial validating is false", !digester.getValidating() );
        digester.setValidating( true );
        assertTrue( "Set validating is true", digester.getValidating() );
        digester.setValidating( false );
        assertTrue( "Reset validating is false", !digester.getValidating() );

    }

    /**
     * Test registration of URLs for specified public identifiers.
     */
    @Test
    public void testRegistrations()
    {

        Map<String, URL> map = digester.getRegistrations();
        assertEquals( "Initially zero registrations", 0, map.size() );
        int n = 0;
        for ( int i = 0; i < registrations.length; i += 2 )
        {
            URL url = this.getClass().getResource( registrations[i + 1] );
            if ( url != null )
            {
                digester.register( registrations[i], url );
                n++;
            }
        }
        map = digester.getRegistrations();
        assertEquals( "Registered two URLs", n, map.size() );

        int count[] = new int[n];
        for ( int i = 0; i < n; i++ )
            count[i] = 0;
        for ( String key : map.keySet() )
        {
            for ( int i = 0; i < n; i++ )
            {
                if ( key.equals( registrations[i * 2] ) )
                {
                    count[i]++;
                    break;
                }
            }
        }
        for ( int i = 0; i < n; i++ )
            assertEquals( "Count for key " + registrations[i * 2], 1, count[i] );

    }

    /**
     * Basic test for rule creation and matching.
     */
    @Test
    public void testRules()
    {

        assertEquals( "Initial rules list is empty", 0, digester.getRules().match( null, "a", null, null ).size() );
        digester.addSetProperties( "a" );
        assertEquals( "Add a matching rule", 1, digester.getRules().match( null, "a", null, null ).size() );
        digester.addSetProperties( "b" );
        assertEquals( "Add a non-matching rule", 1, digester.getRules().match( null, "a", null, null ).size() );
        digester.addSetProperties( "a/b" );
        assertEquals( "Add a non-matching nested rule", 1, digester.getRules().match( null, "a", null, null ).size() );
        digester.addSetProperties( "a/b" );
        assertEquals( "Add a second matching rule", 2, digester.getRules().match( null, "a/b", null, null ).size() );

    }

    /**
     * <p>
     * Test matching rules in {@link RulesBase}.
     * </p>
     * <p>
     * Tests:
     * </p>
     * <ul>
     * <li>exact match</li>
     * <li>tail match</li>
     * <li>longest pattern rule</li>
     * </ul>
     */
    @Test
    public void testRulesBase()
    {

        assertEquals( "Initial rules list is empty", 0, digester.getRules().rules().size() );

        // We're going to set up
        digester.addRule( "a/b/c/d", new TestRule( "a/b/c/d" ) );
        digester.addRule( "*/d", new TestRule( "*/d" ) );
        digester.addRule( "*/c/d", new TestRule( "*/c/d" ) );

        // Test exact match
        assertEquals( "Exact match takes precedence 1", 1, digester.getRules().match( null, "a/b/c/d", null, null ).size() );
        assertEquals( "Exact match takes precedence 2", "a/b/c/d",
                      ( (TestRule) digester.getRules().match( null, "a/b/c/d", null, null ).iterator().next() ).getIdentifier() );

        // Test wildcard tail matching
        assertEquals( "Wildcard tail matching rule 1", 1, digester.getRules().match( null, "a/b/d", null, null ).size() );
        assertEquals( "Wildcard tail matching rule 2", "*/d",
                      ( (TestRule) digester.getRules().match( null, "a/b/d", null, null ).iterator().next() ).getIdentifier() );

        // Test the longest matching pattern rule
        assertEquals( "Longest tail rule 1", 1, digester.getRules().match( null, "x/c/d", null, null ).size() );
        assertEquals( "Longest tail rule 2", "*/c/d",
                      ( (TestRule) digester.getRules().match( null, "x/c/d", null, null ).iterator().next() ).getIdentifier() );

    }

    /**
     * Test the basic stack mechanisms.
     */
    @Test
    public void testStackMethods()
    {

        Object value = null;

        // New stack must be empty
        assertEquals( "New stack is empty", 0, digester.getCount() );
        value = digester.peek();
        assertNull( "New stack peek() returns null", value );
        value = digester.pop();
        assertNull( "New stack pop() returns null", value );

        // Test pushing and popping activities
        digester.push( "First Item" );
        assertEquals( "Pushed one item size", 1, digester.getCount() );
        value = digester.peek();
        assertNotNull( "Peeked first item is not null", value );
        assertEquals( "Peeked first item value", "First Item", value );

        digester.push( "Second Item" );
        assertEquals( "Pushed two items size", 2, digester.getCount() );
        value = digester.peek();
        assertNotNull( "Peeked second item is not null", value );
        assertEquals( "Peeked second item value", "Second Item", value );

        value = digester.pop();
        assertEquals( "Popped stack size", 1, digester.getCount() );
        assertNotNull( "Popped second item is not null", value );
        assertEquals( "Popped second item value", "Second Item", value );
        value = digester.peek();
        assertNotNull( "Remaining item is not null", value );
        assertEquals( "Remaining item value", "First Item", value );
        assertEquals( "Remaining stack size", 1, digester.getCount() );

        // Cleared stack is empty
        digester.push( "Dummy Item" );
        digester.clear();
        assertEquals( "Cleared stack is empty", 0, digester.getCount() );
        value = digester.peek();
        assertNull( "Cleared stack peek() returns null", value );
        value = digester.pop();
        assertNull( "Cleared stack pop() returns null", value );

    }

    @Test
    public void testOnceAndOnceOnly()
        throws Exception
    {

        class TestConfigureDigester
            extends Digester
        {
            public int called = 0;

            public TestConfigureDigester()
            {
            }

            @Override
            protected void initialize()
            {
                called++;
            }
        }

        TestConfigureDigester digester = new TestConfigureDigester();

        String xml = "<?xml version='1.0'?><document/>";
        digester.parse( new StringReader( xml ) );

        assertEquals( "Initialize should be called once and only once", 1, digester.called );
    }

    @Test
    public void testBasicSubstitution()
        throws Exception
    {
        class TestSubRule
            extends Rule
        {
            public String body;

            public Attributes attributes;

            @Override
            public void begin( String namespace, String name, Attributes attributes )
            {
                this.attributes = new AttributesImpl( attributes );
            }

            @Override
            public void body( String namespace, String name, String text )
            {
                this.body = text;
            }
        }

        TestSubRule tsr = new TestSubRule();
        Digester digester = new Digester();
        digester.addRule( "alpha/beta", tsr );

        // it's not easy to transform dirty harry into the mighty circus - but let's give it a try
        String xml =
            "<?xml version='1.0'?><alpha><beta forname='Dirty' surname='Harry'>Do you feel luck punk?</beta></alpha>";
        InputSource in = new InputSource( new StringReader( xml ) );

        digester.parse( in );

        assertEquals( "Unsubstituted body text", "Do you feel luck punk?", tsr.body );
        assertEquals( "Unsubstituted number of attributes", 2, tsr.attributes.getLength() );
        assertEquals( "Unsubstituted forname attribute value", "Dirty", tsr.attributes.getValue( "forname" ) );
        assertEquals( "Unsubstituted surname attribute value", "Harry", tsr.attributes.getValue( "surname" ) );

        digester.setSubstitutor( new Substitutor()
        {
            @Override
            public Attributes substitute( Attributes attributes )
            {
                AttributesImpl results = new AttributesImpl();
                results.addAttribute( "", "python", "python", "CDATA", "Cleese" );
                return results;
            }

            @Override
            public String substitute( String bodyText )
            {
                return "And now for something completely different...";
            }
        } );

        // now transform into the full monty
        in = new InputSource( new StringReader( xml ) );
        digester.parse( in );

        assertEquals( "Substituted body text", "And now for something completely different...", tsr.body );
        assertEquals( "Substituted number of attributes", 1, tsr.attributes.getLength() );
        assertEquals( "Substituted python attribute value", "Cleese", tsr.attributes.getValue( "", "python" ) );
    }

    /** Tests the push-peek-pop cycle for a named stack */
    @Test
    public void testNamedStackPushPeekPop()
        throws Exception
    {
        BigDecimal archimedesAveragePi = new BigDecimal( "3.1418" );
        String testStackName = "org.apache.commons.digester3.tests.testNamedStackPushPeekPop";
        Digester digester = new Digester();
        assertTrue( "Stack starts empty:", digester.isEmpty( testStackName ) );
        digester.push( testStackName, archimedesAveragePi );
        assertEquals( "Peeked value:", archimedesAveragePi, digester.peek( testStackName ) );
        assertEquals( "Popped value:", archimedesAveragePi, digester.pop( testStackName ) );
        assertTrue( "Stack ends empty:", digester.isEmpty( testStackName ) );

        digester.push( testStackName, "1" );
        digester.push( testStackName, "2" );
        digester.push( testStackName, "3" );

        assertEquals( "Peek#1", "1", digester.peek( testStackName, 2 ) );
        assertEquals( "Peek#2", "2", digester.peek( testStackName, 1 ) );
        assertEquals( "Peek#3", "3", digester.peek( testStackName, 0 ) );
        assertEquals( "Peek#3a", "3", digester.peek( testStackName ) );

        try
        {
            // peek beyond stack
            digester.peek( testStackName, 3 );
            fail( "Peek#4 failed to throw an exception." );
        }
        catch ( EmptyStackException ex )
        {
            // ok, expected
        }

        try
        {
            // peek a nonexistent named stack
            digester.peek( "no.such.stack", 0 );
            fail( "Peeking a non-existent stack failed to throw an exception." );
        }
        catch ( EmptyStackException ex )
        {
            // ok, expected
        }
    }

    /** Tests that values are stored independently */
    @Test
    public void testNamedIndependence()
    {
        String testStackOneName = "org.apache.commons.digester3.tests.testNamedIndependenceOne";
        String testStackTwoName = "org.apache.commons.digester3.tests.testNamedIndependenceTwo";
        Digester digester = new Digester();
        digester.push( testStackOneName, "Tweedledum" );
        digester.push( testStackTwoName, "Tweedledee" );
        assertEquals( "Popped value one:", "Tweedledum", digester.pop( testStackOneName ) );
        assertEquals( "Popped value two:", "Tweedledee", digester.pop( testStackTwoName ) );
    }

    /** Tests popping named stack not yet pushed */
    @Test
    public void testPopNamedStackNotPushed()
    {
        String testStackName = "org.apache.commons.digester3.tests.testPopNamedStackNotPushed";
        Digester digester = new Digester();
        try
        {

            digester.pop( testStackName );
            fail( "Expected an EmptyStackException" );

        }
        catch ( EmptyStackException e )
        {
            // expected
        }

        try
        {

            digester.peek( testStackName );
            fail( "Expected an EmptyStackException" );

        }
        catch ( EmptyStackException e )
        {
            // expected
        }
    }

    /** Tests for isEmpty */
    @Test
    public void testNamedStackIsEmpty()
    {
        String testStackName = "org.apache.commons.digester3.tests.testNamedStackIsEmpty";
        Digester digester = new Digester();
        assertTrue( "A named stack that has no object pushed onto it yet should be empty",
                    digester.isEmpty( testStackName ) );

        digester.push( testStackName, "Some test value" );
        assertFalse( "A named stack that has an object pushed onto it should be not empty",
                     digester.isEmpty( testStackName ) );

        digester.peek( testStackName );
        assertFalse( "Peek should not effect whether the stack is empty", digester.isEmpty( testStackName ) );

        digester.pop( testStackName );
        assertTrue( "A named stack that has it's last object popped is empty", digester.isEmpty( testStackName ) );
    }

    /**
     * Test the Digester.getRoot method.
     */
    @Test
    public void testGetRoot()
        throws Exception
    {
        Digester digester = new Digester();
        digester.addRule( "root", new ObjectCreateRule( TestBean.class ) );

        String xml = "<root/>";
        InputSource in = new InputSource( new StringReader( xml ) );

        digester.parse( in );

        Object root = digester.getRoot();
        assertNotNull( "root object not retrieved", root );
        assertTrue( "root object not a TestRule instance", ( root instanceof TestBean ) );
    }

    /** Utility class for method testStackAction */
    private static class TrackingStackAction
        implements StackAction
    {
        public ArrayList<String> events = new ArrayList<String>();

        public Object onPush( Digester d, String stackName, Object o )
        {
            String msg = "push:" + stackName + ":" + o.toString();
            events.add( msg );

            String str = o.toString();
            if ( str.startsWith( "replpush" ) )
            {
                return new String( str );
            }
            return o;
        }

        public Object onPop( Digester d, String stackName, Object o )
        {
            String msg = "pop:" + stackName + ":" + o.toString();
            events.add( msg );
            String str = o.toString();
            if ( str.startsWith( "replpop" ) )
            {
                return new String( str );
            }
            return o;
        }
    }

    /**
     * Test custom StackAction subclasses.
     */
    @Test
    public void testStackAction()
    {
        TrackingStackAction action = new TrackingStackAction();

        Object obj1 = new String( "obj1" );
        Object obj2 = new String( "obj2" );
        Object obj3 = new String( "replpop.obj3" );
        Object obj4 = new String( "replpush.obj4" );

        Object obj8 = new String( "obj8" );
        Object obj9 = new String( "obj9" );

        Digester d = new Digester();
        d.setStackAction( action );

        assertEquals( 0, action.events.size() );
        d.push( obj1 );
        d.push( obj2 );
        d.push( obj3 );
        d.push( obj4 );

        assertNotNull( d.peek( 0 ) );
        // for obj4, a copy should have been pushed
        assertNotSame( obj4, d.peek( 0 ) );
        assertEquals( obj4, d.peek( 0 ) );
        // for obj3, replacement only occurs on pop
        assertSame( obj3, d.peek( 1 ) );
        assertSame( obj2, d.peek( 2 ) );
        assertSame( obj1, d.peek( 3 ) );

        Object obj4a = d.pop();
        Object obj3a = d.pop();
        Object obj2a = d.pop();
        Object obj1a = d.pop();

        assertFalse( obj4 == obj4a );
        assertEquals( obj4, obj4a );
        assertFalse( obj3 == obj4a );
        assertEquals( obj3, obj3a );
        assertSame( obj2, obj2a );
        assertSame( obj1, obj1a );

        d.push( "stack1", obj8 );
        d.push( "stack1", obj9 );
        Object obj9a = d.pop( "stack1" );
        Object obj8a = d.pop( "stack1" );

        assertSame( obj8, obj8a );
        assertSame( obj9, obj9a );

        assertEquals( 12, action.events.size() );
        assertEquals( "push:null:obj1", action.events.get( 0 ) );
        assertEquals( "push:null:obj2", action.events.get( 1 ) );
        assertEquals( "push:null:replpop.obj3", action.events.get( 2 ) );
        assertEquals( "push:null:replpush.obj4", action.events.get( 3 ) );
        assertEquals( "pop:null:replpush.obj4", action.events.get( 4 ) );
        assertEquals( "pop:null:replpop.obj3", action.events.get( 5 ) );
        assertEquals( "pop:null:obj2", action.events.get( 6 ) );
        assertEquals( "pop:null:obj1", action.events.get( 7 ) );

        assertEquals( "push:stack1:obj8", action.events.get( 8 ) );
        assertEquals( "push:stack1:obj9", action.events.get( 9 ) );
        assertEquals( "pop:stack1:obj9", action.events.get( 10 ) );
        assertEquals( "pop:stack1:obj8", action.events.get( 11 ) );
    }
}
TOP

Related Classes of org.apache.commons.digester3.TestConfigureDigester

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.