You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ant.apache.org by bo...@apache.org on 2017/12/01 15:49:31 UTC

[08/23] ant git commit: Normalise tabulation and line breaks (cf master)

http://git-wip-us.apache.org/repos/asf/ant/blob/0ed7f4ab/src/tests/junit/org/apache/tools/ant/types/selectors/ModifiedSelectorTest.java
----------------------------------------------------------------------
diff --git a/src/tests/junit/org/apache/tools/ant/types/selectors/ModifiedSelectorTest.java b/src/tests/junit/org/apache/tools/ant/types/selectors/ModifiedSelectorTest.java
index e83c5b7..aa04b09 100644
--- a/src/tests/junit/org/apache/tools/ant/types/selectors/ModifiedSelectorTest.java
+++ b/src/tests/junit/org/apache/tools/ant/types/selectors/ModifiedSelectorTest.java
@@ -1,1062 +1,1062 @@
-/*
- *  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.tools.ant.types.selectors;
-
-
-// Java
-import java.io.File;
-import java.text.RuleBasedCollator;
-import java.util.Comparator;
-import java.util.Iterator;
-
-import org.apache.tools.ant.AntAssert;
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.BuildFileRule;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.Target;
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.types.Parameter;
-import org.apache.tools.ant.types.Path;
-import org.apache.tools.ant.types.selectors.modifiedselector.Algorithm;
-import org.apache.tools.ant.types.selectors.modifiedselector.Cache;
-import org.apache.tools.ant.types.selectors.modifiedselector.ChecksumAlgorithm;
-import org.apache.tools.ant.types.selectors.modifiedselector.DigestAlgorithm;
-import org.apache.tools.ant.types.selectors.modifiedselector.EqualComparator;
-import org.apache.tools.ant.types.selectors.modifiedselector.HashvalueAlgorithm;
-import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector;
-import org.apache.tools.ant.types.selectors.modifiedselector.PropertiesfileCache;
-import org.apache.tools.ant.util.FileUtils;
-import org.junit.Assume;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Rule;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-
-/**
- * Unit tests for ModifiedSelector.
- *
- * @since  Ant 1.6
- */
-public class ModifiedSelectorTest {
-    
-    @Rule
-    public final BaseSelectorRule selectorRule = new BaseSelectorRule();
-
-    /** Utilities used for file operations */
-    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
-
-    //  =====================  attributes  =====================
-
-
-    /** Path where the testclasses are. */
-    private Path testclasses = null;
-
-
-
-
-    //  =====================  JUnit stuff  =====================
-
-
-    @Before
-    public void setUp() {
-        // init the testclasses path object
-        Project prj = selectorRule.getProject();
-        testclasses = new Path(prj, prj.getProperty("build.tests.value"));
-    }
-
-
-    // =======  testcases for the attributes and nested elements of the selector  =====
-
-
-    /** Test right use of cache names. */
-    @Test
-    public void testValidateWrongCache() {
-        String name = "this-is-not-a-valid-cache-name";
-        try {
-            ModifiedSelector.CacheName cacheName = new ModifiedSelector.CacheName();
-            cacheName.setValue(name);
-            fail("CacheSelector.CacheName accepted invalid value.");
-        } catch (BuildException be) {
-            assertEquals(name + " is not a legal value for this attribute",
-                         be.getMessage());
-        }
-    }
-
-
-    /** Test right use of cache names. */
-    @Test
-    public void testValidateWrongAlgorithm() {
-        String name = "this-is-not-a-valid-algorithm-name";
-        try {
-            ModifiedSelector.AlgorithmName algoName
-                = new ModifiedSelector.AlgorithmName();
-            algoName.setValue(name);
-            fail("CacheSelector.AlgorithmName accepted invalid value.");
-        } catch (BuildException be) {
-            assertEquals(name + " is not a legal value for this attribute",
-                         be.getMessage());
-        }
-    }
-
-
-    /** Test right use of comparator names. */
-    @Test
-    public void testValidateWrongComparator() {
-        String name = "this-is-not-a-valid-comparator-name";
-        try {
-            ModifiedSelector.ComparatorName compName
-                = new ModifiedSelector.ComparatorName();
-            compName.setValue(name);
-            fail("ModifiedSelector.ComparatorName accepted invalid value.");
-        } catch (BuildException be) {
-            assertEquals(name + " is not a legal value for this attribute",
-                         be.getMessage());
-        }
-    }
-
-
-    @Test
-    public void testIllegalCustomAlgorithm() {
-        try {
-            getAlgoName("java.lang.Object");
-            fail("Illegal classname used.");
-        } catch (BuildException e) {
-            assertEquals("Wrong exception message.",
-                         "Specified class (java.lang.Object) is not an Algorithm.",
-                         e.getMessage());
-
-        }
-    }
-
-
-    @Test
-    public void testNonExistentCustomAlgorithm() {
-         try {
-            getAlgoName("non.existent.custom.Algorithm");
-            fail("does 'non.existent.custom.Algorithm' really exist?");
-        } catch (BuildException e) {
-            assertEquals("Wrong exception message.",
-                         "Specified class (non.existent.custom.Algorithm) not found.",
-                         e.getMessage());
-
-        }
-    }
-
-    @Test
-    public void testCustomAlgorithm() {
-        String algo = getAlgoName("org.apache.tools.ant.types.selectors.modifiedselector.HashvalueAlgorithm");
-        assertTrue("Wrong algorithm used: "+algo, algo.startsWith("HashvalueAlgorithm"));
-    }
-
-    @Test
-    public void testCustomAlgorithm2() {
-        String algo = getAlgoName("org.apache.tools.ant.types.selectors.MockAlgorithm");
-        assertTrue("Wrong algorithm used: "+algo, algo.startsWith("MockAlgorithm"));
-    }
-
-
-    @Test
-    public void testCustomClasses() {
-        Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home") );
-        BFT bft = new BFT();
-        bft.setUp();
-        try {
-            // do the actions
-            bft.doTarget("modifiedselectortest-customClasses");
-            // do the checks - the buildfile stores the fileset as property
-            String fsFullValue = bft.getProperty("fs.full.value");
-            String fsModValue  = bft.getProperty("fs.mod.value");
-
-            assertNotNull("'fs.full.value' must be set.", fsFullValue);
-            assertTrue("'fs.full.value' must not be null.", !"".equals(fsFullValue));
-            assertTrue("'fs.full.value' must contain ant.bat.", fsFullValue.indexOf("ant.bat")>-1);
-
-            assertNotNull("'fs.mod.value' must be set.", fsModValue);
-            // must be empty according to the Mock* implementations
-            assertTrue("'fs.mod.value' must be empty.", "".equals(fsModValue));
-        // don't catch the JUnit exceptions
-        } finally {
-            bft.doTarget("modifiedselectortest-scenario-clean");
-            bft.deletePropertiesfile();
-            bft.tearDown();
-        }
-    }
-
-
-    @Test
-    public void testDelayUpdateTaskFinished() {
-        doDelayUpdateTest(1);
-    }
-
-
-    @Test
-    public void testDelayUpdateTargetFinished() {
-        doDelayUpdateTest(2);
-    }
-
-
-    @Test
-    public void testDelayUpdateBuildFinished() {
-        doDelayUpdateTest(3);
-    }
-
-
-    public void doDelayUpdateTest(int kind) {
-        // no check for 1<=kind<=3 - only internal use therefore check it
-        // while development
-
-        // readable form of parameter kind
-        String[] kinds = {"task", "target", "build"};
-
-        // setup the "Ant project"
-        MockProject project = new MockProject();
-        File base  = new File("base");
-        File file1 = new File("file1");
-        File file2 = new File("file2");
-
-        // setup the selector
-        ModifiedSelector sel = new ModifiedSelector();
-        sel.setProject(project);
-        sel.setUpdate(true);
-        sel.setDelayUpdate(true);
-        // sorry - otherwise we will get a ClassCastException because the MockCache
-        // is loaded by two different classloader ...
-        sel.setClassLoader(this.getClass().getClassLoader());
-        sel.addClasspath(testclasses);
-
-        sel.setAlgorithmClass("org.apache.tools.ant.types.selectors.MockAlgorithm");
-        sel.setCacheClass("org.apache.tools.ant.types.selectors.MockCache");
-        sel.configure();
-
-        // get the cache, so we can check our things
-        MockCache cache = (MockCache)sel.getCache();
-
-        // the test
-        assertFalse("Cache must not be saved before 1st selection.", cache.saved);
-        sel.isSelected(base, "file1", file1);
-        assertFalse("Cache must not be saved after 1st selection.", cache.saved);
-        sel.isSelected(base, "file2", file2);
-        assertFalse("Cache must not be saved after 2nd selection.", cache.saved);
-        switch (kind) {
-            case 1 : project.fireTaskFinished();   break;
-            case 2 : project.fireTargetFinished(); break;
-            case 3 : project.fireBuildFinished();  break;
-        }
-        assertTrue("Cache must be saved after " + kinds[kind-1] + "Finished-Event.", cache.saved);
-
-        // MockCache doesnt create a file - therefore no cleanup needed
-    }
-
-
-    /**
-     * Extracts the real used algorithm name from the ModifiedSelector using
-     * its toString() method.
-     * @param classname  the classname from the algorithm to use
-     * @return  the algorithm part from the toString() (without brackets)
-     */
-    private String getAlgoName(String classname) {
-        ModifiedSelector sel = new ModifiedSelector();
-        sel.setProject(selectorRule.getProject());
-        // add the test classes to its classpath
-        sel.addClasspath(testclasses);
-        sel.setAlgorithmClass(classname);
-        // let the selector do its checks
-        sel.validate();
-        // extract the algorithm name (and config) from the selectors output
-        String s1 = sel.toString();
-        int posStart = s1.indexOf("algorithm=") + 10;
-        int posEnd   = s1.indexOf(" comparator=");
-        String algo  = s1.substring(posStart, posEnd);
-        // '<' and '>' are only used if the algorithm has properties
-        if (algo.startsWith("<")) algo = algo.substring(1);
-        if (algo.endsWith(">"))   algo = algo.substring(0, algo.length()-1);
-        // return the clean value
-        return algo;
-    }
-
-
-    // ================  testcases for the cache implementations  ================
-
-
-    /**
-     * Propertycache must have a set 'cachefile' attribute.
-     * The default in ModifiedSelector "cache.properties" is set by the selector.
-     */
-    @Test
-    public void testPropcacheInvalid() {
-        Cache cache = new PropertiesfileCache();
-        if (cache.isValid())
-            fail("PropertyfilesCache does not check its configuration.");
-    }
-
-
-    @Test
-    public void testPropertyfileCache() {
-        PropertiesfileCache cache = new PropertiesfileCache();
-        File cachefile = new File("cache.properties");
-        cache.setCachefile(cachefile);
-        doTest(cache);
-        assertFalse("Cache file not deleted.", cachefile.exists());
-    }
-
-
-    /** Checks whether a cache file is created. */
-    @Test
-    public void testCreatePropertiesCacheDirect() {
-        File cachefile = new File(selectorRule.getProject().getBaseDir(), "cachefile.properties");
-
-        PropertiesfileCache cache = new PropertiesfileCache();
-        cache.setCachefile(cachefile);
-
-        cache.put("key", "value");
-        cache.save();
-
-        assertTrue("Cachefile not created.", cachefile.exists());
-
-        cache.delete();
-        assertFalse("Cachefile not deleted.", cachefile.exists());
-    }
-
-
-    /** Checks whether a cache file is created. */
-    @Test
-    public void testCreatePropertiesCacheViaModifiedSelector() {
-        File cachefile = new File(selectorRule.getProject().getBaseDir(), "cachefile.properties");
-    
-        // Configure the selector
-        ModifiedSelector s = new ModifiedSelector();
-        s.setDelayUpdate(false);
-        s.addParam("cache.cachefile", cachefile);
-
-        ModifiedSelector.CacheName cacheName = new ModifiedSelector.CacheName();
-        cacheName.setValue("propertyfile");
-        s.setCache(cacheName);
-
-        s.setUpdate(true);
-
-        selectorRule.selectionString(s);
-
-        // evaluate correctness
-        assertTrue("Cache file is not created.", cachefile.exists());
-        cachefile.delete();
-        
-    }
-
-
-    /**
-     * In earlier implementations there were problems with the <i>order</i>
-     * of the <param>s. The scenario was <pre>
-     *   <custom class="ModifiedSelector">
-     *       <param name="cache.cachefile" value="mycache.properties" />
-     *       <param name="cache" value="propertyfiles" />
-     *   </custom>
-     * </pre> It was important first to set the cache and then to set
-     * the cache's configuration parameters. That results in the reorganized
-     * configure() method of ModifiedSelector. This testcase tests that.
-     */
-    @Test
-    public void testCreatePropertiesCacheViaCustomSelector() {
-        File cachefile = FILE_UTILS.createTempFile("tmp-cache-", ".properties", null, false, false);
-
-        // Configure the selector
-
-        ExtendSelector s = new ExtendSelector();
-        s.setClassname("org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector");
-        s.addParam(createParam("update", "true"));
-        s.addParam(createParam("cache.cachefile", cachefile.getAbsolutePath()));
-        s.addParam(createParam("cache", "propertyfile"));
-
-        selectorRule.selectionString(s);
-
-        // evaluate correctness
-        assertTrue("Cache file is not created.", cachefile.exists());
-        cachefile.delete();
-
-    }
-
-
-    @Test
-    @Ignore("same logic as on algorithm, no testcases created")
-    public void testCustomCache() {
-        // same logic as on algorithm, no testcases created
-    }
-
-
-    /**
-     * Test the interface semantic of Caches.
-     * This method does some common test for cache implementations.
-     * A cache must return a stored value and a valid iterator.
-     * After calling the delete() the cache must be empty.
-     *
-     * @param cache   configured test object
-     */
-    protected void doTest(Cache cache) {
-        assertTrue("Cache not proper configured.", cache.isValid());
-
-        String key1   = "key1";
-        String value1 = "value1";
-        String key2   = "key2";
-        String value2 = "value2";
-
-        // given cache must be empty
-        Iterator it1 = cache.iterator();
-        assertFalse("Cache is not empty", it1.hasNext());
-
-        // cache must return a stored value
-        cache.put(key1, value1);
-        cache.put(key2, value2);
-        assertEquals("cache returned wrong value", value1, cache.get(key1));
-        assertEquals("cache returned wrong value", value2, cache.get(key2));
-
-        // test the iterator
-        Iterator it2 = cache.iterator();
-        Object   returned = it2.next();
-        boolean ok = (key1.equals(returned) || key2.equals(returned));
-        String msg = "Iterator returned unexpected value."
-                   + "  key1.equals(returned)="+key1.equals(returned)
-                   + "  key2.equals(returned)="+key2.equals(returned)
-                   + "  returned="+returned
-                   + "  ok="+ok;
-        assertTrue(msg, ok);
-
-        // clear the cache
-        cache.delete();
-        Iterator it3 = cache.iterator();
-        assertFalse("Cache is not empty", it3.hasNext());
-    }
-
-
-    // ==============  testcases for the algorithm implementations  ==============
-
-
-    @Test
-    public void testHashvalueAlgorithm() {
-        HashvalueAlgorithm algo = new HashvalueAlgorithm();
-        doTest(algo);
-    }
-
-
-    @Test
-    public void testDigestAlgorithmMD5() {
-        DigestAlgorithm algo = new DigestAlgorithm();
-        algo.setAlgorithm("MD5");
-        doTest(algo);
-    }
-
-
-    @Test
-    public void testDigestAlgorithmSHA() {
-        DigestAlgorithm algo = new DigestAlgorithm();
-        algo.setAlgorithm("SHA");
-        doTest(algo);
-    }
-
-
-    @Test
-    public void testChecksumAlgorithm() {
-        ChecksumAlgorithm algo = new ChecksumAlgorithm();
-        doTest(algo);
-    }
-
-
-    @Test
-    public void testChecksumAlgorithmCRC() {
-        ChecksumAlgorithm algo = new ChecksumAlgorithm();
-        algo.setAlgorithm("CRC");
-        doTest(algo);
-    }
-
-
-    @Test
-    public void testChecksumAlgorithmAdler() {
-        ChecksumAlgorithm algo = new ChecksumAlgorithm();
-        algo.setAlgorithm("Adler");
-        doTest(algo);
-    }
-
-
-    /**
-     * Test the interface semantic of Algorithms.
-     * This method does some common test for algorithm implementations.
-     * An algorithm must return always the same value for the same file and
-     * it must not return <i>null</i>.
-     *
-     * @param algo   configured test object
-     */
-    protected void doTest(Algorithm algo) {
-         assertTrue("Algorithm not proper configured.", algo.isValid());
-         for (int i=0; i<selectorRule.getFiles().length; i++) {
-            File file = selectorRule.getFiles()[i];  // must not be a directory
-            if (file.isFile()) {
-                // get the Hashvalues
-                String hash1 = algo.getValue(file);
-                String hash2 = algo.getValue(file);
-                String hash3 = algo.getValue(file);
-                String hash4 = algo.getValue(file);
-                String hash5 = algo.getValue(new File(file.getAbsolutePath()));
-
-                // Assert !=null and equality
-                assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash1);
-                assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash2);
-                assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash3);
-                assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash4);
-                assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash5);
-                assertEquals("getHashvalue() returned different value for "+file.getAbsolutePath(), hash1, hash2);
-                assertEquals("getHashvalue() returned different value for "+file.getAbsolutePath(), hash1, hash3);
-                assertEquals("getHashvalue() returned different value for "+file.getAbsolutePath(), hash1, hash4);
-                assertEquals("getHashvalue() returned different value for "+file.getAbsolutePath(), hash1, hash5);
-            }//if-isFile
-        }//for
-
-    }
-
-
-
-    // ==============  testcases for the comparator implementations  ==============
-
-
-    @Test
-    public void testEqualComparator() {
-        EqualComparator comp = new EqualComparator();
-        doTest(comp);
-    }
-
-
-    @Test
-    public void testRuleComparator() {
-        RuleBasedCollator comp = (RuleBasedCollator)RuleBasedCollator.getInstance();
-        doTest(comp);
-    }
-
-
-    @Test
-    public void testEqualComparatorViaSelector() {
-        ModifiedSelector s = new ModifiedSelector();
-        ModifiedSelector.ComparatorName compName = new ModifiedSelector.ComparatorName();
-        compName.setValue("equal");
-        s.setComparator(compName);
-        try {
-            performTests(s, "TTTTTTTTTTTT");
-        } finally {
-            s.getCache().delete();
-        }
-    }
-
-
-    @Test
-    @Ignore("not yet supported see note in selector")
-    public void testRuleComparatorViaSelector() {
-        ModifiedSelector s = new ModifiedSelector();
-        ModifiedSelector.ComparatorName compName = new ModifiedSelector.ComparatorName();
-        compName.setValue("rule");
-        s.setComparator(compName);
-        try {
-            performTests(s, "TTTTTTTTTTTT");
-        } finally {
-            s.getCache().delete();
-        }
-    }
-
-
-    @Test
-    @Ignore("same logic as on algorithm, no testcases created")
-    public void testCustomComparator() {
-        // same logic as on algorithm, no testcases created
-    }
-
-
-    @Test
-    public void testResourceSelectorSimple() {
-        BFT bft = new BFT();
-        bft.doTarget("modifiedselectortest-ResourceSimple");
-        bft.deleteCachefile();
-        //new File("src/etc/testcases/types/resources/selectors/cache.properties").delete();
-    }
-
-    @Test
-    public void testResourceSelectorSelresTrue() {
-        BFT bft = new BFT();
-        bft.doTarget("modifiedselectortest-ResourceSelresTrue");
-        AntAssert.assertContains("does not provide an InputStream", bft.getLog());
-        bft.deleteCachefile();
-    }
-
-    @Test
-    public void testResourceSelectorSelresFalse() {
-        BFT bft = new BFT();
-        bft.doTarget("modifiedselectortest-ResourceSelresFalse");
-        bft.deleteCachefile();
-    }
-
-    @Test
-    public void testResourceSelectorScenarioSimple() {
-
-        Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home"));
-        BFT bft = new BFT();
-        bft.doTarget("modifiedselectortest-scenario-resourceSimple");
-        bft.doTarget("modifiedselectortest-scenario-clean");
-        bft.deleteCachefile();
-    }
-
-    /**
-     * Test the interface semantic of Comparators.
-     * This method does some common test for comparator implementations.
-     *
-     * @param comp   configured test object
-     */
-    protected void doTest(Comparator comp) {
-        Object o1 = new String("string1");
-        Object o2 = new String("string2");
-        Object o3 = new String("string2"); // really "2"
-
-        assertTrue("Comparator gave wrong value.", comp.compare(o1, o2) != 0);
-        assertTrue("Comparator gave wrong value.", comp.compare(o1, o3) != 0);
-        assertTrue("Comparator gave wrong value.", comp.compare(o2, o3) == 0);
-    }
-
-
-    // =====================  scenario tests  =====================
-
-
-    /**
-     * Tests whether the seldirs attribute is used.
-     */
-    @Test
-    public void testSeldirs() {
-        ModifiedSelector s = new ModifiedSelector();
-        StringBuffer sbTrue  = new StringBuffer();
-        StringBuffer sbFalse = new StringBuffer();
-        for (int i=0; i<selectorRule.getFiles().length; i++) {
-            if (selectorRule.getFiles()[i].isDirectory()) {
-                sbTrue.append("T");
-                sbFalse.append("F");
-            } else {
-                sbTrue.append("T");
-                sbFalse.append("T");
-            }
-        }
-
-        s.setSeldirs(true);
-        performTests(s, sbTrue.toString());
-        s.getCache().delete();
-
-        s.setSeldirs(false);
-        performTests(s, sbFalse.toString());
-        s.getCache().delete();
-
-        s.getCache().delete();
-    }
-
-
-    /**
-     * Complex test scenario using default values (DigestAlgorithm with MD5,
-     * PropertiesfileCache with file=cache.properties, EqualComparator
-     * and update=true). <ol>
-     * <li> try fist time --> should select all </li>
-     * <li> try second time --> should select no files (only directories) </li>
-     * <li> modify timestamp of one file and content of a nother one </li>
-     * <li> try third time --> should select only the file with modified
-     *      content </li>
-     */
-    @Test
-    public void testScenario1() {
-        BFT bft = null;
-        ModifiedSelector s = null;
-        try {
-
-            String results;
-
-            // Configure the selector - only defaults are used
-            s = new ModifiedSelector();
-
-            //
-            // *****  First Run  *****
-            // the first call should get all files, because nothing is in
-            // the cache
-            //
-            performTests(s, "TTTTTTTTTTTT");
-
-            //
-            // *****  Second Run  *****
-            // the second call should get no files, because no content
-            // has changed
-            //
-            performTests(s, "TFFFFFFFFFFT");
-
-            //
-            // *****  make some files dirty  *****
-            //
-
-            // these files are made dirty --> 3+4 with different content
-            String f2name = "tar/bz2/asf-logo-huge.tar.bz2";
-            String f3name = "asf-logo.gif.md5";
-            String f4name = "copy.filterset.filtered";
-
-            // AccessObject to the test-Ant-environment
-            bft = new BFT();
-            // give some values (via property file) to that environment
-            bft.writeProperties("f2name="+f2name);
-            bft.writeProperties("f3name="+f3name);
-            bft.writeProperties("f4name="+f4name);
-            // call the target for making the files dirty
-            bft.doTarget("modifiedselectortest-makeDirty");
-
-            //
-            // *****  Third Run  *****
-            // third call should get only those files, which CONTENT changed
-            // (no timestamp changes required!)
-            results = selectorRule.selectionString(s);
-
-            //
-            // *****  Check the result  *****
-            //
-
-            // Mark all files which should be selected as (T)rue and all others
-            // as (F)alse. Directories are always selected so they always are
-            // (T)rue.
-            StringBuffer expected = new StringBuffer();
-            for (int i=0; i<selectorRule.getFiles().length; i++) {
-                String ch = "F";
-                if (selectorRule.getFiles()[i].isDirectory()) ch = "T";
-                // f2name shouldn't be selected: only timestamp has changed!
-                if (selectorRule.getFilenames()[i].equalsIgnoreCase(f3name)) ch = "T";
-                if (selectorRule.getFilenames()[i].equalsIgnoreCase(f4name)) ch = "T";
-                expected.append(ch);
-            }
-
-            assertEquals(
-                "Wrong files selected. Differing files: "       // info text
-                + resolve(diff(expected.toString(), results)),  // list of files
-                expected.toString(),                            // expected result
-                results                                         // result
-            );
-
-        } finally {
-            // cleanup the environment
-            if (s!=null) s.getCache().delete();
-            if (bft!=null) bft.deletePropertiesfile();
-        }
-    }
-
-
-    /**
-     * This scenario is based on scenario 1, but does not use any
-     * default value and its based on <custom> selector. Used values are:<ul>
-     * <li><b>Cache: </b> Propertyfile,
-     *                    cachefile={java.io.tmpdir}/mycache.txt </li>
-     * <li><b>Algorithm: </b> Digest
-     *                    algorithm=SHA, Provider=null </li>
-     * <li><b>Comparator: </b> java.text.RuleBasedCollator
-     * <li><b>Update: </b> true </li>
-     */
-    @Test
-    @Ignore("RuleBasedCollator not yet supported - see Selector:375 note")
-    public void testScenario2() {
-        ExtendSelector s = new ExtendSelector();
-        BFT bft = new BFT();
-        String cachefile = System.getProperty("java.io.tmpdir")+"/mycache.txt";
-        try {
-
-            s.setClassname("org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector");
-
-            s.addParam(createParam("cache.cachefile", cachefile));
-            //s.addParam(createParam("algorithm.provider","---")); // i don't know any valid
-            s.addParam(createParam("cache","propertyfile"));
-            s.addParam(createParam("update","true"));
-            s.addParam(createParam("comparator","rule"));
-            s.addParam(createParam("algorithm.name","sha"));
-            s.addParam(createParam("algorithm","digest"));
-
-            // first and second run
-            performTests(s, "TTTTTTTTTTTT");
-            performTests(s, "TFFFFFFFFFFT");
-            // make dirty
-            String f2name = "tar/bz2/asf-logo-huge.tar.bz2";
-            String f3name = "asf-logo.gif.md5";
-            String f4name = "copy.filterset.filtered";
-            bft.writeProperties("f2name="+f2name);
-            bft.writeProperties("f3name="+f3name);
-            bft.writeProperties("f4name="+f4name);
-            bft.doTarget("modifiedselectortest-makeDirty");
-            // third run
-            String results = selectorRule.selectionString(s);
-            StringBuffer expected = new StringBuffer();
-            for (int i=0; i<selectorRule.getFilenames().length; i++) {
-                String ch = "F";
-                if (selectorRule.getFiles()[i].isDirectory()) ch = "T";
-                if (selectorRule.getFilenames()[i].equalsIgnoreCase(f3name)) ch = "T";
-                if (selectorRule.getFilenames()[i].equalsIgnoreCase(f4name)) ch = "T";
-                expected.append(ch);
-            }
-            assertEquals(
-                "Wrong files selected. Differing files: "       // info text
-                + resolve(diff(expected.toString(), results)),  // list of files
-                expected.toString(),                            // expected result
-                results                                         // result
-            );
-        } finally {
-            // cleanup the environment
-            (new java.io.File(cachefile)).delete();
-            bft.deletePropertiesfile();
-        }
-    }
-
-
-    @Test
-    public void testScenarioCoreSelectorDefaults() {
-        Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home") );
-        doScenarioTest("modifiedselectortest-scenario-coreselector-defaults", "cache.properties");
-    }
-
-
-    @Test
-    public void testScenarioCoreSelectorSettings() {
-        Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home") );
-        doScenarioTest("modifiedselectortest-scenario-coreselector-settings", "core.cache.properties");
-    }
-
-
-    @Test
-    public void testScenarioCustomSelectorSettings() {
-        Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home") );
-        doScenarioTest("modifiedselectortest-scenario-customselector-settings", "core.cache.properties");
-    }
-
-
-    public void doScenarioTest(String target, String cachefilename) {
-        BFT bft = new BFT();
-        bft.setUp();
-        File cachefile = new File(selectorRule.getProject().getBaseDir(), cachefilename);
-        try {
-            // do the actions
-            bft.doTarget("modifiedselectortest-scenario-clean");
-            bft.doTarget(target);
-
-            // the directories to check
-            File to1 = new File(selectorRule.getOutputDir(), "selectortest/to-1");
-            File to2 = new File(selectorRule.getOutputDir(), "selectortest/to-2");
-            File to3 = new File(selectorRule.getOutputDir(), "selectortest/to-3");
-
-            // do the checks
-            assertTrue("Cache file not created.", cachefile.exists());
-            assertTrue("Not enough files copied on first time.", to1.list().length>5);
-            assertTrue("Too much files copied on second time.", to2.list().length==0);
-            assertTrue("Too much files copied on third time.", to3.list().length==2);
-        // don't catch the JUnit exceptions
-        } finally {
-            bft.doTarget("modifiedselectortest-scenario-clean");
-            bft.deletePropertiesfile();
-            bft.tearDown();
-            cachefile.delete();
-        }
-    }
-
-
-    //  =====================  helper methods and classes  ====================
-
-
-    /**
-     * Creates a configured parameter object.
-     * @param name   name of the parameter
-     * @param value  value of the parameter
-     * @return the parameter object
-     */
-    private Parameter createParam(String name, String value) {
-        Parameter p = new Parameter();
-        p.setName(name);
-        p.setValue(value);
-        return p;
-    }
-
-
-    /**
-     * The BFT class wrapps the selector test-builfile inside an
-     * ant project. It supports target execution
-     * and property transfer to that project.
-     */
-    private class BFT extends BuildFileRule {
-        String buildfile = "src/etc/testcases/types/selectors.xml";
-
-        String propfile = "ModifiedSelectorTest.properties";
-
-        boolean isConfigured = false;
-
-
-        public void setUp() {
-            super.configureProject(buildfile);
-            isConfigured = true;
-        }
-
-
-        /**
-         * This stub teardown is here because the outer class needs to call the
-         * tearDown method, and in the superclass it is protected.
-         */
-        public void tearDown() {
-            super.after();
-
-        }
-
-        public void doTarget(String target) {
-            if (!isConfigured) setUp();
-            executeTarget(target);
-        }
-
-        public String getProperty(String property) {
-            return super.getProject().getProperty(property);
-        }
-
-        public void writeProperties(String line) {
-            if (!isConfigured) setUp();
-            File dir = getProject().getBaseDir();
-            File file = new File(dir, propfile);
-            try {
-                java.io.FileWriter out =
-                    new java.io.FileWriter(file.getAbsolutePath(), true);
-                out.write(line);
-                out.write(System.getProperty("line.separator"));
-                out.flush();
-                out.close();
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-
-        public void deletePropertiesfile() {
-            if (!isConfigured) setUp();
-            new File(getProject().getBaseDir(), propfile).delete();
-        }
-
-        public void deleteCachefile() {
-            File basedir = new File(buildfile).getParentFile();
-            File cacheFile = new File(basedir, "cache.properties");
-            cacheFile.delete();
-        }
-
-    }//class-BFT
-
-
-    /**
-     * MockProject wrappes a very small ant project (one target, one task)
-     * but provides public methods to fire the build events.
-     */
-    private class MockProject extends Project {
-        private Task   task;
-        private Target target;
-
-        public MockProject() {
-            task = new Task(){
-                public void execute() {
-                }
-            };
-            task.setTaskName("testTask");
-            target = new Target();
-            target.setName("testTarget");
-            target.setProject(this);
-            target.addTask(task);
-            task.setOwningTarget(target);
-        }
-
-        public void fireBuildFinished() {
-            super.fireBuildFinished(null);
-        }
-        public void fireSubBuildFinished() {
-            super.fireSubBuildFinished(null);
-        }
-        public void fireTargetStarted() {
-            super.fireTargetStarted(target);
-        }
-        public void fireTargetFinished() {
-            super.fireTargetFinished(target, null);
-        }
-        public void fireTaskStarted() {
-            super.fireTaskStarted(task);
-        }
-        public void fireTaskFinished() {
-            super.fireTaskFinished(task, null);
-        }
-    }//class-MockProject
-
-
-    /**
-     * Does the selection test for a given selector and prints the
-     * filenames of the differing files (selected but shouldn't,
-     * not selected but should).
-     * @param selector  The selector to test
-     * @param expected  The expected result
-     */
-    private void performTests(FileSelector selector, String expected) {
-        String result = selectorRule.selectionString(selector);
-        String diff = diff(expected, result);
-        String resolved = resolve(diff);
-        assertEquals("Differing files: " + resolved, result, expected);
-    }
-    /**
-     *  Checks which files are selected and shouldn't be or which
-     *  are not selected but should.
-     *  @param expected    String containing 'F's and 'T's
-     *  @param result      String containing 'F's and 'T's
-     *  @return Difference as String containing '-' (equal) and
-     *          'X' (difference).
-     */
-    private String diff(String expected, String result) {
-        int length1 = expected.length();
-        int length2 = result.length();
-        int min = (length1 > length2) ? length2 : length1;
-        StringBuffer sb = new StringBuffer();
-        for (int i=0; i<min; i++) {
-            sb.append(
-                    (expected.charAt(i) == result.charAt(i))
-                            ? "-"
-                            : "X"
-            );
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Resolves a diff-String (@see diff()) against the (inherited) filenames-
-     * and files arrays.
-     * @param filelist    Diff-String
-     * @return String containing the filenames for all differing files,
-     *         separated with semicolons ';'
-     */
-    private String resolve(String filelist) {
-        StringBuffer sb = new StringBuffer();
-        int min = (selectorRule.getFilenames().length > filelist.length())
-                ? filelist.length()
-                : selectorRule.getFilenames().length;
-        for (int i=0; i<min; i++) {
-            if ('X'==filelist.charAt(i)) {
-                sb.append(selectorRule.getFilenames()[i]);
-                sb.append(";");
-            }
-        }
-        return sb.toString();
-    }
-
-
-}//class-ModifiedSelectorTest
+/*
+ *  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.tools.ant.types.selectors;
+
+
+// Java
+import java.io.File;
+import java.text.RuleBasedCollator;
+import java.util.Comparator;
+import java.util.Iterator;
+
+import org.apache.tools.ant.AntAssert;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Target;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Parameter;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.selectors.modifiedselector.Algorithm;
+import org.apache.tools.ant.types.selectors.modifiedselector.Cache;
+import org.apache.tools.ant.types.selectors.modifiedselector.ChecksumAlgorithm;
+import org.apache.tools.ant.types.selectors.modifiedselector.DigestAlgorithm;
+import org.apache.tools.ant.types.selectors.modifiedselector.EqualComparator;
+import org.apache.tools.ant.types.selectors.modifiedselector.HashvalueAlgorithm;
+import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector;
+import org.apache.tools.ant.types.selectors.modifiedselector.PropertiesfileCache;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+
+/**
+ * Unit tests for ModifiedSelector.
+ *
+ * @since  Ant 1.6
+ */
+public class ModifiedSelectorTest {
+
+    @Rule
+    public final BaseSelectorRule selectorRule = new BaseSelectorRule();
+
+    /** Utilities used for file operations */
+    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+    //  =====================  attributes  =====================
+
+
+    /** Path where the testclasses are. */
+    private Path testclasses = null;
+
+
+
+
+    //  =====================  JUnit stuff  =====================
+
+
+    @Before
+    public void setUp() {
+        // init the testclasses path object
+        Project prj = selectorRule.getProject();
+        testclasses = new Path(prj, prj.getProperty("build.tests.value"));
+    }
+
+
+    // =======  testcases for the attributes and nested elements of the selector  =====
+
+
+    /** Test right use of cache names. */
+    @Test
+    public void testValidateWrongCache() {
+        String name = "this-is-not-a-valid-cache-name";
+        try {
+            ModifiedSelector.CacheName cacheName = new ModifiedSelector.CacheName();
+            cacheName.setValue(name);
+            fail("CacheSelector.CacheName accepted invalid value.");
+        } catch (BuildException be) {
+            assertEquals(name + " is not a legal value for this attribute",
+                         be.getMessage());
+        }
+    }
+
+
+    /** Test right use of cache names. */
+    @Test
+    public void testValidateWrongAlgorithm() {
+        String name = "this-is-not-a-valid-algorithm-name";
+        try {
+            ModifiedSelector.AlgorithmName algoName
+                = new ModifiedSelector.AlgorithmName();
+            algoName.setValue(name);
+            fail("CacheSelector.AlgorithmName accepted invalid value.");
+        } catch (BuildException be) {
+            assertEquals(name + " is not a legal value for this attribute",
+                         be.getMessage());
+        }
+    }
+
+
+    /** Test right use of comparator names. */
+    @Test
+    public void testValidateWrongComparator() {
+        String name = "this-is-not-a-valid-comparator-name";
+        try {
+            ModifiedSelector.ComparatorName compName
+                = new ModifiedSelector.ComparatorName();
+            compName.setValue(name);
+            fail("ModifiedSelector.ComparatorName accepted invalid value.");
+        } catch (BuildException be) {
+            assertEquals(name + " is not a legal value for this attribute",
+                         be.getMessage());
+        }
+    }
+
+
+    @Test
+    public void testIllegalCustomAlgorithm() {
+        try {
+            getAlgoName("java.lang.Object");
+            fail("Illegal classname used.");
+        } catch (BuildException e) {
+            assertEquals("Wrong exception message.",
+                         "Specified class (java.lang.Object) is not an Algorithm.",
+                         e.getMessage());
+
+        }
+    }
+
+
+    @Test
+    public void testNonExistentCustomAlgorithm() {
+         try {
+            getAlgoName("non.existent.custom.Algorithm");
+            fail("does 'non.existent.custom.Algorithm' really exist?");
+        } catch (BuildException e) {
+            assertEquals("Wrong exception message.",
+                         "Specified class (non.existent.custom.Algorithm) not found.",
+                         e.getMessage());
+
+        }
+    }
+
+    @Test
+    public void testCustomAlgorithm() {
+        String algo = getAlgoName("org.apache.tools.ant.types.selectors.modifiedselector.HashvalueAlgorithm");
+        assertTrue("Wrong algorithm used: "+algo, algo.startsWith("HashvalueAlgorithm"));
+    }
+
+    @Test
+    public void testCustomAlgorithm2() {
+        String algo = getAlgoName("org.apache.tools.ant.types.selectors.MockAlgorithm");
+        assertTrue("Wrong algorithm used: "+algo, algo.startsWith("MockAlgorithm"));
+    }
+
+
+    @Test
+    public void testCustomClasses() {
+        Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home") );
+        BFT bft = new BFT();
+        bft.setUp();
+        try {
+            // do the actions
+            bft.doTarget("modifiedselectortest-customClasses");
+            // do the checks - the buildfile stores the fileset as property
+            String fsFullValue = bft.getProperty("fs.full.value");
+            String fsModValue  = bft.getProperty("fs.mod.value");
+
+            assertNotNull("'fs.full.value' must be set.", fsFullValue);
+            assertTrue("'fs.full.value' must not be null.", !"".equals(fsFullValue));
+            assertTrue("'fs.full.value' must contain ant.bat.", fsFullValue.indexOf("ant.bat")>-1);
+
+            assertNotNull("'fs.mod.value' must be set.", fsModValue);
+            // must be empty according to the Mock* implementations
+            assertTrue("'fs.mod.value' must be empty.", "".equals(fsModValue));
+        // don't catch the JUnit exceptions
+        } finally {
+            bft.doTarget("modifiedselectortest-scenario-clean");
+            bft.deletePropertiesfile();
+            bft.tearDown();
+        }
+    }
+
+
+    @Test
+    public void testDelayUpdateTaskFinished() {
+        doDelayUpdateTest(1);
+    }
+
+
+    @Test
+    public void testDelayUpdateTargetFinished() {
+        doDelayUpdateTest(2);
+    }
+
+
+    @Test
+    public void testDelayUpdateBuildFinished() {
+        doDelayUpdateTest(3);
+    }
+
+
+    public void doDelayUpdateTest(int kind) {
+        // no check for 1<=kind<=3 - only internal use therefore check it
+        // while development
+
+        // readable form of parameter kind
+        String[] kinds = {"task", "target", "build"};
+
+        // setup the "Ant project"
+        MockProject project = new MockProject();
+        File base  = new File("base");
+        File file1 = new File("file1");
+        File file2 = new File("file2");
+
+        // setup the selector
+        ModifiedSelector sel = new ModifiedSelector();
+        sel.setProject(project);
+        sel.setUpdate(true);
+        sel.setDelayUpdate(true);
+        // sorry - otherwise we will get a ClassCastException because the MockCache
+        // is loaded by two different classloader ...
+        sel.setClassLoader(this.getClass().getClassLoader());
+        sel.addClasspath(testclasses);
+
+        sel.setAlgorithmClass("org.apache.tools.ant.types.selectors.MockAlgorithm");
+        sel.setCacheClass("org.apache.tools.ant.types.selectors.MockCache");
+        sel.configure();
+
+        // get the cache, so we can check our things
+        MockCache cache = (MockCache)sel.getCache();
+
+        // the test
+        assertFalse("Cache must not be saved before 1st selection.", cache.saved);
+        sel.isSelected(base, "file1", file1);
+        assertFalse("Cache must not be saved after 1st selection.", cache.saved);
+        sel.isSelected(base, "file2", file2);
+        assertFalse("Cache must not be saved after 2nd selection.", cache.saved);
+        switch (kind) {
+            case 1 : project.fireTaskFinished();   break;
+            case 2 : project.fireTargetFinished(); break;
+            case 3 : project.fireBuildFinished();  break;
+        }
+        assertTrue("Cache must be saved after " + kinds[kind-1] + "Finished-Event.", cache.saved);
+
+        // MockCache doesnt create a file - therefore no cleanup needed
+    }
+
+
+    /**
+     * Extracts the real used algorithm name from the ModifiedSelector using
+     * its toString() method.
+     * @param classname  the classname from the algorithm to use
+     * @return  the algorithm part from the toString() (without brackets)
+     */
+    private String getAlgoName(String classname) {
+        ModifiedSelector sel = new ModifiedSelector();
+        sel.setProject(selectorRule.getProject());
+        // add the test classes to its classpath
+        sel.addClasspath(testclasses);
+        sel.setAlgorithmClass(classname);
+        // let the selector do its checks
+        sel.validate();
+        // extract the algorithm name (and config) from the selectors output
+        String s1 = sel.toString();
+        int posStart = s1.indexOf("algorithm=") + 10;
+        int posEnd   = s1.indexOf(" comparator=");
+        String algo  = s1.substring(posStart, posEnd);
+        // '<' and '>' are only used if the algorithm has properties
+        if (algo.startsWith("<")) algo = algo.substring(1);
+        if (algo.endsWith(">"))   algo = algo.substring(0, algo.length()-1);
+        // return the clean value
+        return algo;
+    }
+
+
+    // ================  testcases for the cache implementations  ================
+
+
+    /**
+     * Propertycache must have a set 'cachefile' attribute.
+     * The default in ModifiedSelector "cache.properties" is set by the selector.
+     */
+    @Test
+    public void testPropcacheInvalid() {
+        Cache cache = new PropertiesfileCache();
+        if (cache.isValid())
+            fail("PropertyfilesCache does not check its configuration.");
+    }
+
+
+    @Test
+    public void testPropertyfileCache() {
+        PropertiesfileCache cache = new PropertiesfileCache();
+        File cachefile = new File("cache.properties");
+        cache.setCachefile(cachefile);
+        doTest(cache);
+        assertFalse("Cache file not deleted.", cachefile.exists());
+    }
+
+
+    /** Checks whether a cache file is created. */
+    @Test
+    public void testCreatePropertiesCacheDirect() {
+        File cachefile = new File(selectorRule.getProject().getBaseDir(), "cachefile.properties");
+
+        PropertiesfileCache cache = new PropertiesfileCache();
+        cache.setCachefile(cachefile);
+
+        cache.put("key", "value");
+        cache.save();
+
+        assertTrue("Cachefile not created.", cachefile.exists());
+
+        cache.delete();
+        assertFalse("Cachefile not deleted.", cachefile.exists());
+    }
+
+
+    /** Checks whether a cache file is created. */
+    @Test
+    public void testCreatePropertiesCacheViaModifiedSelector() {
+        File cachefile = new File(selectorRule.getProject().getBaseDir(), "cachefile.properties");
+
+        // Configure the selector
+        ModifiedSelector s = new ModifiedSelector();
+        s.setDelayUpdate(false);
+        s.addParam("cache.cachefile", cachefile);
+
+        ModifiedSelector.CacheName cacheName = new ModifiedSelector.CacheName();
+        cacheName.setValue("propertyfile");
+        s.setCache(cacheName);
+
+        s.setUpdate(true);
+
+        selectorRule.selectionString(s);
+
+        // evaluate correctness
+        assertTrue("Cache file is not created.", cachefile.exists());
+        cachefile.delete();
+
+    }
+
+
+    /**
+     * In earlier implementations there were problems with the <i>order</i>
+     * of the <param>s. The scenario was <pre>
+     *   <custom class="ModifiedSelector">
+     *       <param name="cache.cachefile" value="mycache.properties" />
+     *       <param name="cache" value="propertyfiles" />
+     *   </custom>
+     * </pre> It was important first to set the cache and then to set
+     * the cache's configuration parameters. That results in the reorganized
+     * configure() method of ModifiedSelector. This testcase tests that.
+     */
+    @Test
+    public void testCreatePropertiesCacheViaCustomSelector() {
+        File cachefile = FILE_UTILS.createTempFile("tmp-cache-", ".properties", null, false, false);
+
+        // Configure the selector
+
+        ExtendSelector s = new ExtendSelector();
+        s.setClassname("org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector");
+        s.addParam(createParam("update", "true"));
+        s.addParam(createParam("cache.cachefile", cachefile.getAbsolutePath()));
+        s.addParam(createParam("cache", "propertyfile"));
+
+        selectorRule.selectionString(s);
+
+        // evaluate correctness
+        assertTrue("Cache file is not created.", cachefile.exists());
+        cachefile.delete();
+
+    }
+
+
+    @Test
+    @Ignore("same logic as on algorithm, no testcases created")
+    public void testCustomCache() {
+        // same logic as on algorithm, no testcases created
+    }
+
+
+    /**
+     * Test the interface semantic of Caches.
+     * This method does some common test for cache implementations.
+     * A cache must return a stored value and a valid iterator.
+     * After calling the delete() the cache must be empty.
+     *
+     * @param cache   configured test object
+     */
+    protected void doTest(Cache cache) {
+        assertTrue("Cache not proper configured.", cache.isValid());
+
+        String key1   = "key1";
+        String value1 = "value1";
+        String key2   = "key2";
+        String value2 = "value2";
+
+        // given cache must be empty
+        Iterator it1 = cache.iterator();
+        assertFalse("Cache is not empty", it1.hasNext());
+
+        // cache must return a stored value
+        cache.put(key1, value1);
+        cache.put(key2, value2);
+        assertEquals("cache returned wrong value", value1, cache.get(key1));
+        assertEquals("cache returned wrong value", value2, cache.get(key2));
+
+        // test the iterator
+        Iterator it2 = cache.iterator();
+        Object   returned = it2.next();
+        boolean ok = (key1.equals(returned) || key2.equals(returned));
+        String msg = "Iterator returned unexpected value."
+                   + "  key1.equals(returned)="+key1.equals(returned)
+                   + "  key2.equals(returned)="+key2.equals(returned)
+                   + "  returned="+returned
+                   + "  ok="+ok;
+        assertTrue(msg, ok);
+
+        // clear the cache
+        cache.delete();
+        Iterator it3 = cache.iterator();
+        assertFalse("Cache is not empty", it3.hasNext());
+    }
+
+
+    // ==============  testcases for the algorithm implementations  ==============
+
+
+    @Test
+    public void testHashvalueAlgorithm() {
+        HashvalueAlgorithm algo = new HashvalueAlgorithm();
+        doTest(algo);
+    }
+
+
+    @Test
+    public void testDigestAlgorithmMD5() {
+        DigestAlgorithm algo = new DigestAlgorithm();
+        algo.setAlgorithm("MD5");
+        doTest(algo);
+    }
+
+
+    @Test
+    public void testDigestAlgorithmSHA() {
+        DigestAlgorithm algo = new DigestAlgorithm();
+        algo.setAlgorithm("SHA");
+        doTest(algo);
+    }
+
+
+    @Test
+    public void testChecksumAlgorithm() {
+        ChecksumAlgorithm algo = new ChecksumAlgorithm();
+        doTest(algo);
+    }
+
+
+    @Test
+    public void testChecksumAlgorithmCRC() {
+        ChecksumAlgorithm algo = new ChecksumAlgorithm();
+        algo.setAlgorithm("CRC");
+        doTest(algo);
+    }
+
+
+    @Test
+    public void testChecksumAlgorithmAdler() {
+        ChecksumAlgorithm algo = new ChecksumAlgorithm();
+        algo.setAlgorithm("Adler");
+        doTest(algo);
+    }
+
+
+    /**
+     * Test the interface semantic of Algorithms.
+     * This method does some common test for algorithm implementations.
+     * An algorithm must return always the same value for the same file and
+     * it must not return <i>null</i>.
+     *
+     * @param algo   configured test object
+     */
+    protected void doTest(Algorithm algo) {
+         assertTrue("Algorithm not proper configured.", algo.isValid());
+         for (int i=0; i<selectorRule.getFiles().length; i++) {
+            File file = selectorRule.getFiles()[i];  // must not be a directory
+            if (file.isFile()) {
+                // get the Hashvalues
+                String hash1 = algo.getValue(file);
+                String hash2 = algo.getValue(file);
+                String hash3 = algo.getValue(file);
+                String hash4 = algo.getValue(file);
+                String hash5 = algo.getValue(new File(file.getAbsolutePath()));
+
+                // Assert !=null and equality
+                assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash1);
+                assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash2);
+                assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash3);
+                assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash4);
+                assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash5);
+                assertEquals("getHashvalue() returned different value for "+file.getAbsolutePath(), hash1, hash2);
+                assertEquals("getHashvalue() returned different value for "+file.getAbsolutePath(), hash1, hash3);
+                assertEquals("getHashvalue() returned different value for "+file.getAbsolutePath(), hash1, hash4);
+                assertEquals("getHashvalue() returned different value for "+file.getAbsolutePath(), hash1, hash5);
+            }//if-isFile
+        }//for
+
+    }
+
+
+
+    // ==============  testcases for the comparator implementations  ==============
+
+
+    @Test
+    public void testEqualComparator() {
+        EqualComparator comp = new EqualComparator();
+        doTest(comp);
+    }
+
+
+    @Test
+    public void testRuleComparator() {
+        RuleBasedCollator comp = (RuleBasedCollator)RuleBasedCollator.getInstance();
+        doTest(comp);
+    }
+
+
+    @Test
+    public void testEqualComparatorViaSelector() {
+        ModifiedSelector s = new ModifiedSelector();
+        ModifiedSelector.ComparatorName compName = new ModifiedSelector.ComparatorName();
+        compName.setValue("equal");
+        s.setComparator(compName);
+        try {
+            performTests(s, "TTTTTTTTTTTT");
+        } finally {
+            s.getCache().delete();
+        }
+    }
+
+
+    @Test
+    @Ignore("not yet supported see note in selector")
+    public void testRuleComparatorViaSelector() {
+        ModifiedSelector s = new ModifiedSelector();
+        ModifiedSelector.ComparatorName compName = new ModifiedSelector.ComparatorName();
+        compName.setValue("rule");
+        s.setComparator(compName);
+        try {
+            performTests(s, "TTTTTTTTTTTT");
+        } finally {
+            s.getCache().delete();
+        }
+    }
+
+
+    @Test
+    @Ignore("same logic as on algorithm, no testcases created")
+    public void testCustomComparator() {
+        // same logic as on algorithm, no testcases created
+    }
+
+
+    @Test
+    public void testResourceSelectorSimple() {
+        BFT bft = new BFT();
+        bft.doTarget("modifiedselectortest-ResourceSimple");
+        bft.deleteCachefile();
+        //new File("src/etc/testcases/types/resources/selectors/cache.properties").delete();
+    }
+
+    @Test
+    public void testResourceSelectorSelresTrue() {
+        BFT bft = new BFT();
+        bft.doTarget("modifiedselectortest-ResourceSelresTrue");
+        AntAssert.assertContains("does not provide an InputStream", bft.getLog());
+        bft.deleteCachefile();
+    }
+
+    @Test
+    public void testResourceSelectorSelresFalse() {
+        BFT bft = new BFT();
+        bft.doTarget("modifiedselectortest-ResourceSelresFalse");
+        bft.deleteCachefile();
+    }
+
+    @Test
+    public void testResourceSelectorScenarioSimple() {
+
+        Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home"));
+        BFT bft = new BFT();
+        bft.doTarget("modifiedselectortest-scenario-resourceSimple");
+        bft.doTarget("modifiedselectortest-scenario-clean");
+        bft.deleteCachefile();
+    }
+
+    /**
+     * Test the interface semantic of Comparators.
+     * This method does some common test for comparator implementations.
+     *
+     * @param comp   configured test object
+     */
+    protected void doTest(Comparator comp) {
+        Object o1 = new String("string1");
+        Object o2 = new String("string2");
+        Object o3 = new String("string2"); // really "2"
+
+        assertTrue("Comparator gave wrong value.", comp.compare(o1, o2) != 0);
+        assertTrue("Comparator gave wrong value.", comp.compare(o1, o3) != 0);
+        assertTrue("Comparator gave wrong value.", comp.compare(o2, o3) == 0);
+    }
+
+
+    // =====================  scenario tests  =====================
+
+
+    /**
+     * Tests whether the seldirs attribute is used.
+     */
+    @Test
+    public void testSeldirs() {
+        ModifiedSelector s = new ModifiedSelector();
+        StringBuffer sbTrue  = new StringBuffer();
+        StringBuffer sbFalse = new StringBuffer();
+        for (int i=0; i<selectorRule.getFiles().length; i++) {
+            if (selectorRule.getFiles()[i].isDirectory()) {
+                sbTrue.append("T");
+                sbFalse.append("F");
+            } else {
+                sbTrue.append("T");
+                sbFalse.append("T");
+            }
+        }
+
+        s.setSeldirs(true);
+        performTests(s, sbTrue.toString());
+        s.getCache().delete();
+
+        s.setSeldirs(false);
+        performTests(s, sbFalse.toString());
+        s.getCache().delete();
+
+        s.getCache().delete();
+    }
+
+
+    /**
+     * Complex test scenario using default values (DigestAlgorithm with MD5,
+     * PropertiesfileCache with file=cache.properties, EqualComparator
+     * and update=true). <ol>
+     * <li> try fist time --> should select all </li>
+     * <li> try second time --> should select no files (only directories) </li>
+     * <li> modify timestamp of one file and content of a nother one </li>
+     * <li> try third time --> should select only the file with modified
+     *      content </li>
+     */
+    @Test
+    public void testScenario1() {
+        BFT bft = null;
+        ModifiedSelector s = null;
+        try {
+
+            String results;
+
+            // Configure the selector - only defaults are used
+            s = new ModifiedSelector();
+
+            //
+            // *****  First Run  *****
+            // the first call should get all files, because nothing is in
+            // the cache
+            //
+            performTests(s, "TTTTTTTTTTTT");
+
+            //
+            // *****  Second Run  *****
+            // the second call should get no files, because no content
+            // has changed
+            //
+            performTests(s, "TFFFFFFFFFFT");
+
+            //
+            // *****  make some files dirty  *****
+            //
+
+            // these files are made dirty --> 3+4 with different content
+            String f2name = "tar/bz2/asf-logo-huge.tar.bz2";
+            String f3name = "asf-logo.gif.md5";
+            String f4name = "copy.filterset.filtered";
+
+            // AccessObject to the test-Ant-environment
+            bft = new BFT();
+            // give some values (via property file) to that environment
+            bft.writeProperties("f2name="+f2name);
+            bft.writeProperties("f3name="+f3name);
+            bft.writeProperties("f4name="+f4name);
+            // call the target for making the files dirty
+            bft.doTarget("modifiedselectortest-makeDirty");
+
+            //
+            // *****  Third Run  *****
+            // third call should get only those files, which CONTENT changed
+            // (no timestamp changes required!)
+            results = selectorRule.selectionString(s);
+
+            //
+            // *****  Check the result  *****
+            //
+
+            // Mark all files which should be selected as (T)rue and all others
+            // as (F)alse. Directories are always selected so they always are
+            // (T)rue.
+            StringBuffer expected = new StringBuffer();
+            for (int i=0; i<selectorRule.getFiles().length; i++) {
+                String ch = "F";
+                if (selectorRule.getFiles()[i].isDirectory()) ch = "T";
+                // f2name shouldn't be selected: only timestamp has changed!
+                if (selectorRule.getFilenames()[i].equalsIgnoreCase(f3name)) ch = "T";
+                if (selectorRule.getFilenames()[i].equalsIgnoreCase(f4name)) ch = "T";
+                expected.append(ch);
+            }
+
+            assertEquals(
+                "Wrong files selected. Differing files: "       // info text
+                + resolve(diff(expected.toString(), results)),  // list of files
+                expected.toString(),                            // expected result
+                results                                         // result
+            );
+
+        } finally {
+            // cleanup the environment
+            if (s!=null) s.getCache().delete();
+            if (bft!=null) bft.deletePropertiesfile();
+        }
+    }
+
+
+    /**
+     * This scenario is based on scenario 1, but does not use any
+     * default value and its based on <custom> selector. Used values are:<ul>
+     * <li><b>Cache: </b> Propertyfile,
+     *                    cachefile={java.io.tmpdir}/mycache.txt </li>
+     * <li><b>Algorithm: </b> Digest
+     *                    algorithm=SHA, Provider=null </li>
+     * <li><b>Comparator: </b> java.text.RuleBasedCollator
+     * <li><b>Update: </b> true </li>
+     */
+    @Test
+    @Ignore("RuleBasedCollator not yet supported - see Selector:375 note")
+    public void testScenario2() {
+        ExtendSelector s = new ExtendSelector();
+        BFT bft = new BFT();
+        String cachefile = System.getProperty("java.io.tmpdir")+"/mycache.txt";
+        try {
+
+            s.setClassname("org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector");
+
+            s.addParam(createParam("cache.cachefile", cachefile));
+            //s.addParam(createParam("algorithm.provider","---")); // i don't know any valid
+            s.addParam(createParam("cache","propertyfile"));
+            s.addParam(createParam("update","true"));
+            s.addParam(createParam("comparator","rule"));
+            s.addParam(createParam("algorithm.name","sha"));
+            s.addParam(createParam("algorithm","digest"));
+
+            // first and second run
+            performTests(s, "TTTTTTTTTTTT");
+            performTests(s, "TFFFFFFFFFFT");
+            // make dirty
+            String f2name = "tar/bz2/asf-logo-huge.tar.bz2";
+            String f3name = "asf-logo.gif.md5";
+            String f4name = "copy.filterset.filtered";
+            bft.writeProperties("f2name="+f2name);
+            bft.writeProperties("f3name="+f3name);
+            bft.writeProperties("f4name="+f4name);
+            bft.doTarget("modifiedselectortest-makeDirty");
+            // third run
+            String results = selectorRule.selectionString(s);
+            StringBuffer expected = new StringBuffer();
+            for (int i=0; i<selectorRule.getFilenames().length; i++) {
+                String ch = "F";
+                if (selectorRule.getFiles()[i].isDirectory()) ch = "T";
+                if (selectorRule.getFilenames()[i].equalsIgnoreCase(f3name)) ch = "T";
+                if (selectorRule.getFilenames()[i].equalsIgnoreCase(f4name)) ch = "T";
+                expected.append(ch);
+            }
+            assertEquals(
+                "Wrong files selected. Differing files: "       // info text
+                + resolve(diff(expected.toString(), results)),  // list of files
+                expected.toString(),                            // expected result
+                results                                         // result
+            );
+        } finally {
+            // cleanup the environment
+            (new java.io.File(cachefile)).delete();
+            bft.deletePropertiesfile();
+        }
+    }
+
+
+    @Test
+    public void testScenarioCoreSelectorDefaults() {
+        Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home") );
+        doScenarioTest("modifiedselectortest-scenario-coreselector-defaults", "cache.properties");
+    }
+
+
+    @Test
+    public void testScenarioCoreSelectorSettings() {
+        Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home") );
+        doScenarioTest("modifiedselectortest-scenario-coreselector-settings", "core.cache.properties");
+    }
+
+
+    @Test
+    public void testScenarioCustomSelectorSettings() {
+        Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home") );
+        doScenarioTest("modifiedselectortest-scenario-customselector-settings", "core.cache.properties");
+    }
+
+
+    public void doScenarioTest(String target, String cachefilename) {
+        BFT bft = new BFT();
+        bft.setUp();
+        File cachefile = new File(selectorRule.getProject().getBaseDir(), cachefilename);
+        try {
+            // do the actions
+            bft.doTarget("modifiedselectortest-scenario-clean");
+            bft.doTarget(target);
+
+            // the directories to check
+            File to1 = new File(selectorRule.getOutputDir(), "selectortest/to-1");
+            File to2 = new File(selectorRule.getOutputDir(), "selectortest/to-2");
+            File to3 = new File(selectorRule.getOutputDir(), "selectortest/to-3");
+
+            // do the checks
+            assertTrue("Cache file not created.", cachefile.exists());
+            assertTrue("Not enough files copied on first time.", to1.list().length>5);
+            assertTrue("Too much files copied on second time.", to2.list().length==0);
+            assertTrue("Too much files copied on third time.", to3.list().length==2);
+        // don't catch the JUnit exceptions
+        } finally {
+            bft.doTarget("modifiedselectortest-scenario-clean");
+            bft.deletePropertiesfile();
+            bft.tearDown();
+            cachefile.delete();
+        }
+    }
+
+
+    //  =====================  helper methods and classes  ====================
+
+
+    /**
+     * Creates a configured parameter object.
+     * @param name   name of the parameter
+     * @param value  value of the parameter
+     * @return the parameter object
+     */
+    private Parameter createParam(String name, String value) {
+        Parameter p = new Parameter();
+        p.setName(name);
+        p.setValue(value);
+        return p;
+    }
+
+
+    /**
+     * The BFT class wrapps the selector test-builfile inside an
+     * ant project. It supports target execution
+     * and property transfer to that project.
+     */
+    private class BFT extends BuildFileRule {
+        String buildfile = "src/etc/testcases/types/selectors.xml";
+
+        String propfile = "ModifiedSelectorTest.properties";
+
+        boolean isConfigured = false;
+
+
+        public void setUp() {
+            super.configureProject(buildfile);
+            isConfigured = true;
+        }
+
+
+        /**
+         * This stub teardown is here because the outer class needs to call the
+         * tearDown method, and in the superclass it is protected.
+         */
+        public void tearDown() {
+            super.after();
+
+        }
+
+        public void doTarget(String target) {
+            if (!isConfigured) setUp();
+            executeTarget(target);
+        }
+
+        public String getProperty(String property) {
+            return super.getProject().getProperty(property);
+        }
+
+        public void writeProperties(String line) {
+            if (!isConfigured) setUp();
+            File dir = getProject().getBaseDir();
+            File file = new File(dir, propfile);
+            try {
+                java.io.FileWriter out =
+                    new java.io.FileWriter(file.getAbsolutePath(), true);
+                out.write(line);
+                out.write(System.getProperty("line.separator"));
+                out.flush();
+                out.close();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+        public void deletePropertiesfile() {
+            if (!isConfigured) setUp();
+            new File(getProject().getBaseDir(), propfile).delete();
+        }
+
+        public void deleteCachefile() {
+            File basedir = new File(buildfile).getParentFile();
+            File cacheFile = new File(basedir, "cache.properties");
+            cacheFile.delete();
+        }
+
+    }//class-BFT
+
+
+    /**
+     * MockProject wrappes a very small ant project (one target, one task)
+     * but provides public methods to fire the build events.
+     */
+    private class MockProject extends Project {
+        private Task   task;
+        private Target target;
+
+        public MockProject() {
+            task = new Task(){
+                public void execute() {
+                }
+            };
+            task.setTaskName("testTask");
+            target = new Target();
+            target.setName("testTarget");
+            target.setProject(this);
+            target.addTask(task);
+            task.setOwningTarget(target);
+        }
+
+        public void fireBuildFinished() {
+            super.fireBuildFinished(null);
+        }
+        public void fireSubBuildFinished() {
+            super.fireSubBuildFinished(null);
+        }
+        public void fireTargetStarted() {
+            super.fireTargetStarted(target);
+        }
+        public void fireTargetFinished() {
+            super.fireTargetFinished(target, null);
+        }
+        public void fireTaskStarted() {
+            super.fireTaskStarted(task);
+        }
+        public void fireTaskFinished() {
+            super.fireTaskFinished(task, null);
+        }
+    }//class-MockProject
+
+
+    /**
+     * Does the selection test for a given selector and prints the
+     * filenames of the differing files (selected but shouldn't,
+     * not selected but should).
+     * @param selector  The selector to test
+     * @param expected  The expected result
+     */
+    private void performTests(FileSelector selector, String expected) {
+        String result = selectorRule.selectionString(selector);
+        String diff = diff(expected, result);
+        String resolved = resolve(diff);
+        assertEquals("Differing files: " + resolved, result, expected);
+    }
+    /**
+     *  Checks which files are selected and shouldn't be or which
+     *  are not selected but should.
+     *  @param expected    String containing 'F's and 'T's
+     *  @param result      String containing 'F's and 'T's
+     *  @return Difference as String containing '-' (equal) and
+     *          'X' (difference).
+     */
+    private String diff(String expected, String result) {
+        int length1 = expected.length();
+        int length2 = result.length();
+        int min = (length1 > length2) ? length2 : length1;
+        StringBuffer sb = new StringBuffer();
+        for (int i=0; i<min; i++) {
+            sb.append(
+                    (expected.charAt(i) == result.charAt(i))
+                            ? "-"
+                            : "X"
+            );
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Resolves a diff-String (@see diff()) against the (inherited) filenames-
+     * and files arrays.
+     * @param filelist    Diff-String
+     * @return String containing the filenames for all differing files,
+     *         separated with semicolons ';'
+     */
+    private String resolve(String filelist) {
+        StringBuffer sb = new StringBuffer();
+        int min = (selectorRule.getFilenames().length > filelist.length())
+                ? filelist.length()
+                : selectorRule.getFilenames().length;
+        for (int i=0; i<min; i++) {
+            if ('X'==filelist.charAt(i)) {
+                sb.append(selectorRule.getFilenames()[i]);
+                sb.append(";");
+            }
+        }
+        return sb.toString();
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/ant/blob/0ed7f4ab/src/tests/junit/org/apache/tools/ant/types/selectors/PresentSelectorTest.java
----------------------------------------------------------------------
diff --git a/src/tests/junit/org/apache/tools/ant/types/selectors/PresentSelectorTest.java b/src/tests/junit/org/apache/tools/ant/types/selectors/PresentSelectorTest.java
index f93e101..f273334 100644
--- a/src/tests/junit/org/apache/tools/ant/types/selectors/PresentSelectorTest.java
+++ b/src/tests/junit/org/apache/tools/ant/types/selectors/PresentSelectorTest.java
@@ -1,137 +1,137 @@
-/*
- *  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.tools.ant.types.selectors;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.types.Mapper;
-import org.junit.Rule;
-import org.junit.Test;
-
-import java.io.File;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-
-/**
- * Tests Present Selectors
- *
- */
-public class PresentSelectorTest {
-
-
-    @Rule
-    public final BaseSelectorRule selectorRule = new BaseSelectorRule();
-
-    /**
-     * Test the code that validates the selector.
-     */
-    @Test
-    public void testValidate() {
-        PresentSelector s = new PresentSelector();
-        try {
-            s.createMapper();
-            s.createMapper();
-            fail("PresentSelector allowed more than one nested mapper.");
-        } catch (BuildException be1) {
-            assertEquals("Cannot define more than one mapper",
-                    be1.getMessage());
-        }
-
-        s = new PresentSelector();
-        try {
-            s.isSelected(selectorRule.getProject().getBaseDir(),selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
-            fail("PresentSelector did not check for required fields");
-        } catch (BuildException be2) {
-            assertEquals("The targetdir attribute is required.",
-                    be2.getMessage());
-        }
-
-    }
-
-    /**
-     * Tests to make sure that the selector is selecting files correctly.
-     */
-    @Test
-    public void testSelectionBehaviour() {
-        PresentSelector s;
-        String results;
-        Mapper m;
-        Mapper.MapperType identity = new Mapper.MapperType();
-        identity.setValue("identity");
-        Mapper.MapperType glob = new Mapper.MapperType();
-        glob.setValue("glob");
-        Mapper.MapperType merge = new Mapper.MapperType();
-        merge.setValue("merge");
-        Mapper.MapperType flatten = new Mapper.MapperType();
-        flatten.setValue("flatten");
-
-        File beddir = selectorRule.getBeddir();
-        
-        s = new PresentSelector();
-        s.setTargetdir(beddir);
-        results = selectorRule.selectionString(s);
-        assertEquals("TTTTTTTTTTTT", results);
-
-        s = new PresentSelector();
-        s.setTargetdir(beddir);
-        m = s.createMapper();
-        m.setType(identity);
-        results = selectorRule.selectionString(s);
-        assertEquals("TTTTTTTTTTTT", results);
-
-        s = new PresentSelector();
-        File subdir = new File(System.getProperty("root"), "src/etc/testcases/taskdefs/expected");
-        s.setTargetdir(subdir);
-        m = s.createMapper();
-        m.setType(flatten);
-        results = selectorRule.selectionString(s);
-        assertEquals("TTTTTTTTTTTF", results);
-
-        s = new PresentSelector();
-        s.setTargetdir(beddir);
-        m = s.createMapper();
-        m.setType(merge);
-        m.setTo("asf-logo.gif.gz");
-        results = selectorRule.selectionString(s);
-        assertEquals("TTTTTTTTTTTT", results);
-
-        s = new PresentSelector();
-        subdir = new File(beddir, "tar/bz2");
-        s.setTargetdir(subdir);
-        m = s.createMapper();
-        m.setType(glob);
-        m.setFrom("*.bz2");
-        m.setTo("*.tar.bz2");
-        results = selectorRule.selectionString(s);
-        assertEquals("FFTFFFFFFFFF", results);
-
-            
-        s = new PresentSelector();
-        subdir = new File(selectorRule.getOutputDir(), "selectortest2");
-        s.setTargetdir(subdir);
-        results = selectorRule.selectionString(s);
-        assertEquals("TTTFFTTTTTTT", results);
-        results = selectorRule.selectionString(s);
-        assertEquals("TTTFFTTTTTTT", results);
-
-
-    }
-
-}
+/*
+ *  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.tools.ant.types.selectors;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Mapper;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+
+/**
+ * Tests Present Selectors
+ *
+ */
+public class PresentSelectorTest {
+
+
+    @Rule
+    public final BaseSelectorRule selectorRule = new BaseSelectorRule();
+
+    /**
+     * Test the code that validates the selector.
+     */
+    @Test
+    public void testValidate() {
+        PresentSelector s = new PresentSelector();
+        try {
+            s.createMapper();
+            s.createMapper();
+            fail("PresentSelector allowed more than one nested mapper.");
+        } catch (BuildException be1) {
+            assertEquals("Cannot define more than one mapper",
+                    be1.getMessage());
+        }
+
+        s = new PresentSelector();
+        try {
+            s.isSelected(selectorRule.getProject().getBaseDir(),selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+            fail("PresentSelector did not check for required fields");
+        } catch (BuildException be2) {
+            assertEquals("The targetdir attribute is required.",
+                    be2.getMessage());
+        }
+
+    }
+
+    /**
+     * Tests to make sure that the selector is selecting files correctly.
+     */
+    @Test
+    public void testSelectionBehaviour() {
+        PresentSelector s;
+        String results;
+        Mapper m;
+        Mapper.MapperType identity = new Mapper.MapperType();
+        identity.setValue("identity");
+        Mapper.MapperType glob = new Mapper.MapperType();
+        glob.setValue("glob");
+        Mapper.MapperType merge = new Mapper.MapperType();
+        merge.setValue("merge");
+        Mapper.MapperType flatten = new Mapper.MapperType();
+        flatten.setValue("flatten");
+
+        File beddir = selectorRule.getBeddir();
+
+        s = new PresentSelector();
+        s.setTargetdir(beddir);
+        results = selectorRule.selectionString(s);
+        assertEquals("TTTTTTTTTTTT", results);
+
+        s = new PresentSelector();
+        s.setTargetdir(beddir);
+        m = s.createMapper();
+        m.setType(identity);
+        results = selectorRule.selectionString(s);
+        assertEquals("TTTTTTTTTTTT", results);
+
+        s = new PresentSelector();
+        File subdir = new File(System.getProperty("root"), "src/etc/testcases/taskdefs/expected");
+        s.setTargetdir(subdir);
+        m = s.createMapper();
+        m.setType(flatten);
+        results = selectorRule.selectionString(s);
+        assertEquals("TTTTTTTTTTTF", results);
+
+        s = new PresentSelector();
+        s.setTargetdir(beddir);
+        m = s.createMapper();
+        m.setType(merge);
+        m.setTo("asf-logo.gif.gz");
+        results = selectorRule.selectionString(s);
+        assertEquals("TTTTTTTTTTTT", results);
+
+        s = new PresentSelector();
+        subdir = new File(beddir, "tar/bz2");
+        s.setTargetdir(subdir);
+        m = s.createMapper();
+        m.setType(glob);
+        m.setFrom("*.bz2");
+        m.setTo("*.tar.bz2");
+        results = selectorRule.selectionString(s);
+        assertEquals("FFTFFFFFFFFF", results);
+
+
+        s = new PresentSelector();
+        subdir = new File(selectorRule.getOutputDir(), "selectortest2");
+        s.setTargetdir(subdir);
+        results = selectorRule.selectionString(s);
+        assertEquals("TTTFFTTTTTTT", results);
+        results = selectorRule.selectionString(s);
+        assertEquals("TTTFFTTTTTTT", results);
+
+
+    }
+
+}