001/* $Id: RulesBaseTestCase.java 1212599 2011-12-09 19:46:42Z simonetripodi $
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one or more
004 * contributor license agreements.  See the NOTICE file distributed with
005 * this work for additional information regarding copyright ownership.
006 * The ASF licenses this file to You under the Apache License, Version 2.0
007 * (the "License"); you may not use this file except in compliance with
008 * the License.  You may obtain a copy of the License at
009 *
010 *      http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.apache.commons.digester3;
020
021import static org.junit.Assert.assertEquals;
022
023import java.util.Iterator;
024import java.util.List;
025
026import org.apache.commons.digester3.Digester;
027import org.apache.commons.digester3.Rule;
028import org.apache.commons.digester3.Rules;
029import org.apache.commons.digester3.RulesBase;
030import org.junit.After;
031import org.junit.Before;
032import org.junit.Test;
033
034/**
035 * <p>
036 * Test Case for the RulesBase matching rules. Most of this material was original contained in the digester test case
037 * but was moved into this class so that extensions of the basic matching rules behaviour can extend this test case.
038 * </p>
039 *
040 * @author Craig R. McClanahan
041 */
042public class RulesBaseTestCase
043{
044
045    // ----------------------------------------------------- Instance Variables
046
047    /**
048     * The digester instance we will be processing.
049     */
050    protected Digester digester = null;
051
052    // -------------------------------------------------- Overall Test Methods
053
054    /**
055     * Set up instance variables required by this test case.
056     */
057    @Before
058    public void setUp()
059    {
060
061        digester = new Digester();
062        digester.setRules( createMatchingRulesForTest() );
063
064    }
065
066    /**
067     * <p>
068     * This should be overriden by subclasses.
069     *
070     * @return the matching rules to be tested.
071     */
072    protected Rules createMatchingRulesForTest()
073    {
074        return new RulesBase();
075    }
076
077    /**
078     * Tear down instance variables required by this test case.
079     */
080    @After
081    public void tearDown()
082    {
083
084        digester = null;
085
086    }
087
088    // ------------------------------------------------ Individual Test Methods
089
090    /**
091     * Basic test for rule creation and matching.
092     */
093    @Test
094    public void testRules()
095    {
096
097        // clear any existing rules
098        digester.getRules().clear();
099
100        // perform tests
101
102        assertEquals( "Initial rules list is empty", 0, digester.getRules().match( null, "a", null, null ).size() );
103        digester.addSetProperties( "a" );
104        assertEquals( "Add a matching rule", 1, digester.getRules().match( null, "a", null, null ).size() );
105        digester.addSetProperties( "b" );
106        assertEquals( "Add a non-matching rule", 1, digester.getRules().match( null, "a", null, null ).size() );
107        digester.addSetProperties( "a/b" );
108        assertEquals( "Add a non-matching nested rule", 1, digester.getRules().match( null, "a", null, null ).size() );
109        digester.addSetProperties( "a/b" );
110        assertEquals( "Add a second matching rule", 2, digester.getRules().match( null, "a/b", null, null ).size() );
111
112        // clean up
113        digester.getRules().clear();
114
115    }
116
117    /**
118     * <p>
119     * Test matching rules in {@link RulesBase}.
120     * </p>
121     * <p>
122     * Tests:
123     * </p>
124     * <ul>
125     * <li>exact match</li>
126     * <li>tail match</li>
127     * <li>longest pattern rule</li>
128     * </ul>
129     */
130    @Test
131    public void testRulesBase()
132    {
133
134        // clear any existing rules
135        digester.getRules().clear();
136
137        assertEquals( "Initial rules list is empty", 0, digester.getRules().rules().size() );
138
139        // We're going to set up
140        digester.addRule( "a/b/c/d", new TestRule( "a/b/c/d" ) );
141        digester.addRule( "*/d", new TestRule( "*/d" ) );
142        digester.addRule( "*/c/d", new TestRule( "*/c/d" ) );
143
144        // Test exact match
145        assertEquals( "Exact match takes precedence 1", 1, digester.getRules().match( null, "a/b/c/d", null, null ).size() );
146        assertEquals( "Exact match takes precedence 2", "a/b/c/d",
147                      ( (TestRule) digester.getRules().match( null, "a/b/c/d", null, null ).iterator().next() ).getIdentifier() );
148
149        // Test wildcard tail matching
150        assertEquals( "Wildcard tail matching rule 1", 1, digester.getRules().match( null, "a/b/d", null, null ).size() );
151        assertEquals( "Wildcard tail matching rule 2", "*/d",
152                      ( (TestRule) digester.getRules().match( null, "a/b/d", null, null ).iterator().next() ).getIdentifier() );
153
154        // Test the longest matching pattern rule
155        assertEquals( "Longest tail rule 1", 1, digester.getRules().match( null, "x/c/d", null, null ).size() );
156        assertEquals( "Longest tail rule 2", "*/c/d",
157                      ( (TestRule) digester.getRules().match( null, "x/c/d", null, null ).iterator().next() ).getIdentifier() );
158
159        // Test wildcard tail matching at the top level,
160        // i.e. the wildcard is nothing
161        digester.addRule( "*/a", new TestRule( "*/a" ) );
162        assertEquals( "Wildcard tail matching rule 3", 1, digester.getRules().match( null, "a", null, null ).size() );
163
164        assertEquals( "Wildcard tail matching rule 3 (match too much)", 0,
165                      digester.getRules().match( null, "aa", null, null ).size() );
166        // clean up
167        digester.getRules().clear();
168
169    }
170
171    /**
172     * Test basic matchings involving namespaces.
173     */
174    @Test
175    public void testBasicNamespaceMatching()
176    {
177
178        List<Rule> list = null;
179        Iterator<Rule> it = null;
180
181        // clear any existing rules
182        digester.getRules().clear();
183
184        assertEquals( "Initial rules list is empty", 0, digester.getRules().rules().size() );
185
186        // Set up rules
187        digester.addRule( "alpha/beta/gamma", new TestRule( "No-Namespace" ) );
188        digester.addRule( "alpha/beta/gamma", new TestRule( "Euclidean-Namespace", "euclidean" ) );
189
190        list = digester.getRules().rules();
191
192        // test that matching null namespace brings back namespace and non-namespace rules
193        list = digester.getRules().match( null, "alpha/beta/gamma", null, null );
194
195        assertEquals( "Null namespace match (A)", 2, list.size() );
196
197        it = list.iterator();
198        assertEquals( "Null namespace match (B)", "No-Namespace", ( (TestRule) it.next() ).getIdentifier() );
199        assertEquals( "Null namespace match (C)", "Euclidean-Namespace", ( (TestRule) it.next() ).getIdentifier() );
200
201        // test that matching euclid namespace brings back namespace and non-namespace rules
202        list = digester.getRules().match( "euclidean", "alpha/beta/gamma", null, null );
203
204        assertEquals( "Matching namespace match (A)", 2, list.size() );
205
206        it = list.iterator();
207        assertEquals( "Matching namespace match (B)", "No-Namespace", ( (TestRule) it.next() ).getIdentifier() );
208        assertEquals( "Matching namespace match (C)", "Euclidean-Namespace", ( (TestRule) it.next() ).getIdentifier() );
209
210        // test that matching another namespace brings back only non-namespace rule
211        list = digester.getRules().match( "hyperbolic", "alpha/beta/gamma", null, null );
212
213        assertEquals( "Non matching namespace match (A)", 1, list.size() );
214
215        it = list.iterator();
216        assertEquals( "Non matching namespace match (B)", "No-Namespace", ( (TestRule) it.next() ).getIdentifier() );
217
218        // clean up
219        digester.getRules().clear();
220
221    }
222
223    /**
224     * Rules must always be returned in the correct order.
225     */
226    @Test
227    public void testOrdering()
228    {
229
230        // clear any existing rules
231        digester.getRules().clear();
232
233        assertEquals( "Initial rules list is empty", 0, digester.getRules().rules().size() );
234
235        // Set up rules
236        digester.addRule( "alpha/beta/gamma", new TestRule( "one" ) );
237        digester.addRule( "alpha/beta/gamma", new TestRule( "two" ) );
238        digester.addRule( "alpha/beta/gamma", new TestRule( "three" ) );
239
240        // test that rules are returned in set order
241        List<Rule> list = digester.getRules().match( null, "alpha/beta/gamma", null, null );
242
243        assertEquals( "Testing ordering mismatch (A)", 3, list.size() );
244
245        Iterator<Rule> it = list.iterator();
246        assertEquals( "Testing ordering mismatch (B)", "one", ( (TestRule) it.next() ).getIdentifier() );
247        assertEquals( "Testing ordering mismatch (C)", "two", ( (TestRule) it.next() ).getIdentifier() );
248        assertEquals( "Testing ordering mismatch (D)", "three", ( (TestRule) it.next() ).getIdentifier() );
249
250        // clean up
251        digester.getRules().clear();
252
253    }
254
255    /** Tests the behaviour when a rule is added with a trailing slash */
256    @Test
257    public void testTrailingSlash()
258    {
259        // clear any existing rules
260        digester.getRules().clear();
261
262        assertEquals( "Initial rules list is empty", 0, digester.getRules().rules().size() );
263
264        // Set up rules
265        digester.addRule( "alpha/beta/gamma/", new TestRule( "one" ) );
266        digester.addRule( "alpha/beta/", new TestRule( "two" ) );
267        digester.addRule( "beta/gamma/alpha", new TestRule( "three" ) );
268
269        // test that rules are returned in set order
270        List<Rule> list = digester.getRules().match( null, "alpha/beta/gamma", null, null );
271
272        assertEquals( "Testing number of matches", 1, list.size() );
273
274        Iterator<Rule> it = list.iterator();
275        assertEquals( "Testing ordering (A)", "one", ( (TestRule) it.next() ).getIdentifier() );
276
277        // clean up
278        digester.getRules().clear();
279    }
280}