Repository: jena
Updated Branches:
  refs/heads/master 692118f9d -> 1320f8dbe


http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/test/java/org/apache/jena/atlas/lib/TestCache.java
----------------------------------------------------------------------
diff --git a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestCache.java 
b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestCache.java
new file mode 100644
index 0000000..05513fe
--- /dev/null
+++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestCache.java
@@ -0,0 +1,149 @@
+/*
+ * 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.jena.atlas.lib;
+
+import java.util.Arrays ;
+import java.util.Collection ;
+import java.util.List ;
+
+import org.apache.jena.atlas.iterator.Iter ;
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.apache.jena.atlas.lib.Cache ;
+import org.apache.jena.atlas.lib.CacheFactory ;
+import org.junit.Before ;
+import org.junit.Test ;
+import org.junit.runner.RunWith ;
+import org.junit.runners.Parameterized ;
+import org.junit.runners.Parameterized.Parameters ;
+
+@RunWith(Parameterized.class)
+public class TestCache extends BaseTest
+{
+    // Tests do not apply to cache1.
+    private static interface CacheMaker<K,V> { Cache<K,V> make(int size) ; 
String name() ; } 
+
+    private static CacheMaker<Integer, Integer> simple = 
+        new CacheMaker<Integer, Integer>()
+        { 
+        @Override
+        public Cache<Integer, Integer> make(int size) { return 
CacheFactory.createSimpleCache(size) ; }
+        @Override
+        public String name() { return "Simple" ; } 
+        } 
+    ;
+
+    private static CacheMaker<Integer, Integer> standard = 
+        new CacheMaker<Integer, Integer>()
+        {
+        @Override
+        public Cache<Integer, Integer> make(int size) { return 
CacheFactory.createCache(size) ; }
+        @Override
+        public String name() { return "Standard" ; } 
+        }
+    ;
+
+    @Parameters
+    public static Collection<Object[]> cacheMakers()
+    {
+        return Arrays.asList(new Object[][] {
+            { simple , 10 }
+            , { simple , 2 } 
+            , { simple , 1 }
+            , { standard , 10 }
+            , { standard , 2 }
+            , { standard , 1 }
+        } ) ; 
+    }
+
+    Cache<Integer, Integer> cache ;
+    CacheMaker<Integer,Integer> cacheMaker ;
+    int size ;
+    
+    
+    public TestCache(CacheMaker<Integer,Integer> cacheMaker, int size)
+    {
+        this.cacheMaker = cacheMaker ;
+        this.size = size ;
+        
+    }
+    
+    @Before public void before() { cache = cacheMaker.make(size) ; }
+    
+    @Test public void cache_00()
+    {
+        assertEquals(0, cache.size()) ;
+        assertTrue(cache.isEmpty()) ;
+    }
+    
+    @Test public void cache_01()
+    {
+        Integer x = cache.getIfPresent(7) ;
+        cache.put(7, 7) ;
+        assertEquals(1, cache.size()) ;
+        assertNull(x) ;
+        assertTrue(cache.containsKey(7)) ;
+        assertEquals(Integer.valueOf(7), cache.getIfPresent(7)) ;
+    }
+    
+    @Test public void cache_02()
+    {
+        cache.put(7, 7) ;
+        cache.put(8, 8) ;
+        // Not true for Cache1.
+        if ( size > 2 )
+            assertEquals(2, cache.size()) ;
+        if ( size > 2 )
+            assertTrue(cache.containsKey(7)) ;
+        
+        if ( size > 2 )
+            assertEquals(Integer.valueOf(7), cache.getIfPresent(7)) ;
+        
+        assertTrue(cache.containsKey(8)) ;
+        assertEquals(Integer.valueOf(8), cache.getIfPresent(8)) ;
+    }
+    
+    @Test public void cache_03()
+    {
+        cache.put(7, 7) ;
+        Integer x1 = cache.getIfPresent(7) ;
+        cache.put(7, 18) ;
+        assertEquals(1, cache.size()) ;
+        assertEquals(7, x1.intValue()) ;
+        assertTrue(cache.containsKey(7)) ;
+        assertEquals(Integer.valueOf(18), cache.getIfPresent(7)) ;
+    }
+    
+    @Test public void cache_04()
+    {
+        cache.clear() ;
+        cache.put(7, 77) ;
+        List<Integer> x = Iter.toList(cache.keys()) ;
+        assertEquals(1, x.size()) ;
+        assertEquals(Integer.valueOf(7), x.get(0)) ;
+    }
+    
+    @Test public void cache_05()
+    {
+        cache.clear() ;
+        cache.put(7, 77) ;
+        cache.clear() ;
+        assertEquals(0, cache.size()) ; 
+        assertTrue(cache.isEmpty()) ;
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/test/java/org/apache/jena/atlas/lib/TestCache2.java
----------------------------------------------------------------------
diff --git a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestCache2.java 
b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestCache2.java
new file mode 100644
index 0000000..2e640f3
--- /dev/null
+++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestCache2.java
@@ -0,0 +1,88 @@
+/*
+ * 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.jena.atlas.lib;
+
+import java.util.concurrent.Callable ;
+
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.apache.jena.atlas.lib.Cache ;
+import org.apache.jena.atlas.lib.CacheFactory ;
+import org.apache.jena.atlas.lib.cache.Cache1 ;
+import org.junit.Test ;
+
+// Non-parameterized tests
+public class TestCache2 extends BaseTest
+{
+    // Cache1
+    @Test public void cache_10()
+    {
+        Cache<Integer, String> cache = new Cache1<>() ;
+        String str = cache.getIfPresent(1) ;
+        assertNull(str) ;
+
+        cache.put(1, "1") ;
+        str = cache.getIfPresent(1) ;
+        assertEquals("1", str) ;
+
+        cache.put(2, "2") ;
+        str = cache.getIfPresent(1) ;
+        assertNull(str) ;
+        
+        cache.put(1, "1") ;
+        str = cache.getIfPresent(2) ;
+        assertNull(str) ;
+        str = cache.getIfPresent(1) ;
+        assertEquals("1", str) ;
+    }
+    
+    
+    
+    static Callable<String> getter(final Integer key) {
+        return new Callable<String>() {
+            @Override
+            public String call() {
+                return key.toString() ; }
+        } ;
+    }
+
+    // Cache + getters
+    @Test public void cacheGetter_1()
+    {
+        Cache<Integer, String> cache = CacheFactory.createCache(2) ;
+        String str = cache.getOrFill(1,  getter(1)) ;
+        assertEquals("1", str) ;
+    }
+    
+    // Cache + getters
+    @Test public void cacheGetter_2()
+    {
+        Cache<Integer, String> cache = CacheFactory.createCache(2) ;
+        String str1 = cache.getOrFill(1, getter(1)) ;
+        String str2 = cache.getOrFill(2, getter(2)) ;
+        String str3 = cache.getOrFill(3, getter(3)) ;
+        assertEquals("1", str1) ;
+        assertEquals("2", str2) ;
+        assertEquals("3", str3) ;
+        cache.put(1, "10") ;
+        str1 = cache.getIfPresent(1) ;
+        assertEquals("10", str1) ;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/test/java/org/apache/jena/atlas/lib/TestColumnMap.java
----------------------------------------------------------------------
diff --git 
a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestColumnMap.java 
b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestColumnMap.java
new file mode 100644
index 0000000..fb44166
--- /dev/null
+++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestColumnMap.java
@@ -0,0 +1,107 @@
+/*
+ * 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.jena.atlas.lib;
+
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.apache.jena.atlas.lib.ColumnMap ;
+import org.apache.jena.atlas.lib.Tuple ;
+import static org.apache.jena.atlas.lib.Tuple.* ;
+import org.junit.Test ;
+
+public class TestColumnMap extends BaseTest
+{
+    @Test public void remap1() 
+    {
+        ColumnMap x = new ColumnMap("SPO->POS", 2,0,1) ;   // S->2 etc
+        
+        Integer[] array = {0,1,2 } ;
+        assertEquals(Integer.valueOf(2), x.mapSlot(0, array) ) ;   
+        assertEquals(Integer.valueOf(0), x.mapSlot(1, array) ) ; 
+        assertEquals(Integer.valueOf(1), x.mapSlot(2, array) ) ; 
+    }
+    
+    @Test public void remap2() 
+    {
+        ColumnMap x = new ColumnMap("SPO->POS", 2,0,1) ;
+        Integer[] array = { 0,1,2 } ;
+        assertEquals(Integer.valueOf(1), x.fetchSlot(0, array)) ;   // The 
index 1 comes from position 0.
+        assertEquals(Integer.valueOf(2), x.fetchSlot(1, array)) ;
+        assertEquals(Integer.valueOf(0), x.fetchSlot(2, array)) ;
+    }
+
+    @Test public void remap3() 
+    {
+        ColumnMap x = new ColumnMap("POS", 2,0,1) ;
+        Tuple<String> tuple = createTuple("S", "P", "O") ;
+        Tuple<String> mapped = x.map(tuple) ;
+        Tuple<String> expected = createTuple("P", "O", "S") ;
+        assertEquals(expected, mapped) ;
+    }
+    
+    @Test public void remap4() 
+    {
+        ColumnMap x = new ColumnMap("POS", 2,0,1) ;
+        Tuple<String> tuple = createTuple("S", "P", "O") ;
+        Tuple<String> tuple2 = x.map(tuple) ;
+        tuple2 = x.unmap(tuple2) ;
+        assertEquals(tuple, tuple2) ;
+    }
+    
+    @Test public void compile1()
+    {
+        int[] x = ColumnMap.compileMapping("SPO", "POS") ;
+        // SPO -> POS so col 0 goes to col 2, col 1 goes to col 0 and col 2 
goes to col 1
+        int[] expected = { 2,0,1 } ;
+        assertArrayEquals(expected, x) ;
+    }
+
+    @Test public void compile2()
+    {
+        int[] x = ColumnMap.compileMapping("SPOG", "GOPS") ;
+        int[] expected = { 3, 2, 1, 0 } ;
+        assertArrayEquals(expected, x) ;
+    }
+
+    @Test public void map1()
+    {
+        ColumnMap cmap = new ColumnMap("GSPO", "OSPG") ;
+        Tuple<String> tuple = createTuple("G", "S", "P", "O") ;
+        Tuple<String> mapped = cmap.map(tuple) ;
+        Tuple<String> expected = createTuple("O", "S", "P", "G") ;
+        assertEquals(expected, mapped) ;
+        Tuple<String> unmapped = cmap.unmap(mapped) ;
+        assertEquals(createTuple("G", "S", "P", "O"), unmapped) ;
+    }
+
+    @Test public void map2()
+    {
+        String[] x = { "G", "S", "P", "O" } ;
+        String[] y = { "O", "S", "P", "G" } ;
+        
+        ColumnMap cmap = new ColumnMap("Test", x, y) ;
+        Tuple<String> tuple = Tuple.create(x) ;
+        Tuple<String> mapped = cmap.map(tuple) ;
+        
+        Tuple<String> expected = Tuple.create(y) ;
+        assertEquals(expected, mapped) ;
+        Tuple<String> unmapped = cmap.unmap(mapped) ;
+        assertEquals(Tuple.create(x), unmapped) ;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/test/java/org/apache/jena/atlas/lib/TestDateTimeUtils.java
----------------------------------------------------------------------
diff --git 
a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestDateTimeUtils.java 
b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestDateTimeUtils.java
new file mode 100644
index 0000000..8aae32b
--- /dev/null
+++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestDateTimeUtils.java
@@ -0,0 +1,82 @@
+/*
+ * 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.jena.atlas.lib;
+
+import static org.junit.Assert.*;
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+import org.apache.jena.atlas.lib.DateTimeUtils ;
+import org.junit.Test;
+
+public class TestDateTimeUtils {
+
+       @Test
+       public void testCalendarToXSDDateTimeString_1() throws Exception {
+               Calendar cal = createCalendar(1984, Calendar.MARCH, 22, 14, 32, 
1, 0, "Z") ;
+               assertEquals("1984-03-22T14:32:01+00:00", 
DateTimeUtils.calendarToXSDDateTimeString(cal));
+               cal.setTimeZone(TimeZone.getTimeZone("MST"));
+               assertEquals("1984-03-22T07:32:01-07:00", 
DateTimeUtils.calendarToXSDDateTimeString(cal));
+       }
+
+    @Test
+    public void testCalendarToXSDDateTimeString_2() throws Exception {
+        Calendar cal = createCalendar(1984, Calendar.MARCH, 22, 14, 32, 1, 50, 
"Z") ;
+        assertEquals("1984-03-22T14:32:01.050+00:00", 
DateTimeUtils.calendarToXSDDateTimeString(cal));
+        cal.setTimeZone(TimeZone.getTimeZone("MST"));
+        assertEquals("1984-03-22T07:32:01.050-07:00", 
DateTimeUtils.calendarToXSDDateTimeString(cal));
+    }
+
+
+    @Test
+       public void testCalendarToXSDDateString() throws Exception {
+               Calendar cal = createCalendar(1984, Calendar.MARCH, 22, 23, 59, 
1, 0, "Z");
+               cal.setTimeZone(TimeZone.getTimeZone("Z")) ;
+               assertEquals("1984-03-22+00:00", 
DateTimeUtils.calendarToXSDDateString(cal));
+               cal.setTimeZone(TimeZone.getTimeZone("MST"));
+               assertEquals("1984-03-22-07:00", 
DateTimeUtils.calendarToXSDDateString(cal));
+       }
+    
+    @Test
+       public void testCalendarToXSDTimeString_1() throws Exception {
+               Calendar cal = createCalendar(1984, Calendar.MARCH, 22, 14, 32, 
1, 0, "GMT+01:00");
+               assertEquals("14:32:01+01:00", 
DateTimeUtils.calendarToXSDTimeString(cal));
+               // Different timezone - moves the cal point-in-time.
+               cal.setTimeZone(TimeZone.getTimeZone("MST"));
+               assertEquals("06:32:01-07:00", 
DateTimeUtils.calendarToXSDTimeString(cal));
+       }
+       
+    @Test
+    public void testCalendarToXSDTimeString_2() throws Exception {
+        Calendar cal = createCalendar(1984, Calendar.MARCH, 22, 14, 32, 1, 
500, "GMT+01:00");
+        assertEquals("14:32:01.500+01:00", 
DateTimeUtils.calendarToXSDTimeString(cal));
+        // Different timezone - moves the cal point-in-time.
+        cal.setTimeZone(TimeZone.getTimeZone("MST"));
+        assertEquals("06:32:01.500-07:00", 
DateTimeUtils.calendarToXSDTimeString(cal));
+    }
+    
+       private static Calendar createCalendar(int year, int month, int 
dayOfMonth, int hourOfDay,
+                                              int minute, int second, int 
milli, String tz) {
+           GregorianCalendar cal = new 
GregorianCalendar(TimeZone.getTimeZone(tz)) ;
+           cal.set(year, month, dayOfMonth, hourOfDay, minute, second) ;
+           cal.set(Calendar.MILLISECOND, milli) ;
+           return cal ;
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/test/java/org/apache/jena/atlas/lib/TestFileOps.java
----------------------------------------------------------------------
diff --git a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestFileOps.java 
b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestFileOps.java
new file mode 100644
index 0000000..92538f7
--- /dev/null
+++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestFileOps.java
@@ -0,0 +1,78 @@
+/*
+ * 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.jena.atlas.lib;
+
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.apache.jena.atlas.lib.FileOps ;
+import org.apache.jena.atlas.lib.Tuple ;
+import org.junit.Test ;
+
+public class TestFileOps extends BaseTest
+{
+    /*
+     * t("") ;
+        t("/a/b/c") ;
+        t("/aa/bb/cc.ext") ;
+        t("cc.ext") ;
+        t("/cc.ext") ;
+        t("/") ;
+        t("xyz") ;
+        t("xyz/") ;
+     */
+
+    static void test(String fn, String path, String basename, String ext)
+    {
+        Tuple<String> t = FileOps.splitDirBaseExt(fn) ;
+        assertEquals(path, t.get(0)) ;
+        assertEquals(basename, t.get(1)) ;
+        assertEquals(ext, t.get(2)) ;
+        
+        if ( basename != null ) 
+            assertEquals(basename, FileOps.basename(fn)) ;
+        if ( ext != null ) 
+            assertEquals(ext, FileOps.extension(fn)) ;
+    }
+    
+    @Test public void split01() 
+    { test("/aa/bb/cc.ext", "/aa/bb", "cc", "ext") ; }
+
+    @Test public void split02() 
+    { test("/a/b/c", "/a/b", "c", null) ; }
+    
+    @Test public void split03() 
+    { test("cc.ext", null, "cc", "ext") ; }
+    
+    @Test public void split04() 
+    { test("/cc.ext", "", "cc", "ext") ; }
+    
+    @Test public void split05() 
+    { test("/", "", "", null) ; }
+    
+    @Test public void split06() 
+    { test("", null, "", null) ; }
+    
+    @Test public void split07() 
+    { test("xyz", null, "xyz", null) ; }
+    
+    @Test public void split08() 
+    { test("/xyz", "", "xyz", null) ; }
+    
+    @Test public void split09() 
+    { test("xyz/", "xyz", "", null) ; }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/test/java/org/apache/jena/atlas/lib/TestFilenameProcessing.java
----------------------------------------------------------------------
diff --git 
a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestFilenameProcessing.java 
b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestFilenameProcessing.java
new file mode 100644
index 0000000..7782c55
--- /dev/null
+++ 
b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestFilenameProcessing.java
@@ -0,0 +1,136 @@
+/*
+ * 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.jena.atlas.lib;
+
+import java.io.File ;
+
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.junit.Test ;
+
+public class TestFilenameProcessing extends BaseTest
+{
+    // See also TestFunction2 for tests for encode_for_uri
+    @Test public void encode_1() { encodeComponent("abc", "abc") ; }
+    @Test public void encode_2() { encodeComponent("", "") ; }
+    @Test public void encode_3() { encodeComponent(":/", "%3A%2F") ; }
+
+    // ---- Main tests.
+    // Portablility
+    
+    private static String cwd = new File(".").getAbsolutePath() ;
+    // Without trailing slash.
+    static { cwd = cwd.substring(0, cwd.length()-2) ; }
+    
+    @Test public void fileIRI_1()
+    {
+        String uri = testFileIRI("D.ttl") ; 
+        assertTrue(uri.endsWith("D.ttl")) ;
+    }
+    
+    @Test public void fileIRI_2()
+    {
+        String uri = testFileIRI("file:/D.ttl") ; 
+        assertTrue(uri.endsWith("D.ttl")) ;
+    }
+    
+    @Test public void fileIRI_3()
+    {
+        String uri = testFileIRI("file://D.ttl") ; 
+        assertTrue(uri.endsWith("D.ttl")) ;
+    }
+
+    @Test public void fileIRI_4()
+    {
+        String iri = testFileIRI("file:///D.ttl") ;
+        // Even on windows, this is used as-is so no drive letter. 
+        assertEquals("file:///D.ttl", iri) ;
+    }
+    
+    private static String testFileIRI(String fn)
+    {
+        String uri1 = IRILib.filenameToIRI(fn) ;
+        assertTrue(uri1.startsWith("file:///")) ;
+        String uri2 = IRILib.filenameToIRI(uri1) ;
+        assertEquals(uri1, uri2) ;
+        return uri1 ;
+    }
+
+    
+    @Test public void fileURL_1() { assertNotEquals(cwd, "") ; 
assertNotNull(cwd) ; filenameToIRI("abc", "file://"+cwd+"/abc" ) ; }
+    
+    @Test public void fileURL_2() { filenameToIRI("/abc", "file:///abc" ) ; }
+    
+    static boolean isWindows = File.pathSeparator.equals(";") ;
+
+    
+    @Test public void fileURL_3()
+    { 
+        if ( isWindows )
+            filenameToIRI("c:/Program File/App File", 
"file:///c:/Program%20File/App%20File") ; 
+        else
+            filenameToIRI("/Program File/App File", 
"file:///Program%20File/App%20File") ;
+    }
+
+    @Test public void fileURL_4()
+    { 
+        if ( isWindows )
+            filenameToIRI("c:/Program File/App Dir/", 
"file:///c:/Program%20File/App%20Dir/") ; 
+        else
+            filenameToIRI("/Program File/App Dir/", 
"file:///Program%20File/App%20Dir/") ;
+    }
+    
+    @Test public void fileURL_5()
+    {
+        if ( isWindows )
+            filenameToIRI("c:\\Windows\\Path", "file:///c:/Windows/Path") ;
+        else
+            filenameToIRI("c:\\Windows\\Path", 
"file://"+cwd+"/c:%5CWindows%5CPath") ;
+        
+    }
+    
+    @Test public void fileURL_6() { filenameToIRI("~user", 
"file://"+cwd+"/~user") ; }
+    @Test public void fileURL_7() { filenameToIRI(".", "file://"+cwd) ; }
+    
+    @Test public void fileURL_10() { filenameToIRI("file:abc", 
"file://"+cwd+"/abc" ) ; }
+    @Test public void fileURL_11() { filenameToIRI("file:/abc", "file:///abc" 
) ; }
+    @Test public void fileURL_12() { filenameToIRI("file:", "file://"+cwd ) ; }
+    
+    @Test public void fileURL_13() { filenameToIRI("file:.", "file://"+cwd+"" 
) ; }
+    @Test public void fileURL_14() {
+        String x = cwd ;
+        if ( isWindows )
+            x = x.replace('\\', '/') ; 
+        x = cwd.replaceAll("/[^/]*$", "") ;
+        filenameToIRI("file:..", "file://"+x ) ;
+    }
+
+    
+    private static void encodeComponent(String string, String result)
+    {
+        String r = IRILib.encodeUriComponent(string) ;
+        assertEquals(result, r) ;
+    }
+    
+    private static void filenameToIRI(String string, String result)
+    {
+        String r = IRILib.filenameToIRI(string) ;
+        assertEquals(result, r) ;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/test/java/org/apache/jena/atlas/lib/TestHex.java
----------------------------------------------------------------------
diff --git a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestHex.java 
b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestHex.java
new file mode 100644
index 0000000..e092e60
--- /dev/null
+++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestHex.java
@@ -0,0 +1,81 @@
+/*
+ * 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.jena.atlas.lib;
+
+
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.apache.jena.atlas.lib.Hex ;
+import org.junit.Test ;
+
+public class TestHex extends BaseTest
+{
+    @Test public void hex_01()
+    {
+        byte[] b = new byte[16] ;
+        test(0L, 0, b, 16) ;
+    }
+    
+    @Test public void hex_02()
+    {
+        byte[] b = new byte[16] ;
+        test(1L, 0, b, 16) ;
+    }
+
+    @Test public void hex_03()
+    {
+        byte[] b = new byte[16] ;
+        test(Long.MAX_VALUE, 0, b, 16) ;
+    }
+    
+    @Test public void hex_04()
+    {
+        byte[] b = new byte[16] ;
+        test(Long.MIN_VALUE, 0, b, 16) ;
+    }
+    
+    @Test public void hex_05()
+    {
+        byte[] b = new byte[16] ;
+        // -1L
+        test(0xFFFFFFFFFFFFFFFFL, 0, b, 16) ;
+    }
+
+    @Test public void hex_06()
+    {
+        byte[] b = new byte[16] ;
+        test(-1L, 0, b, 16) ;
+    }
+
+    private static void test(long value, int idx, byte[] b, int width)
+    {
+        int x = Hex.formatUnsignedLongHex(b, idx, value, width) ;
+        assertEquals(width, x) ;
+        for ( int i = 0 ; i < width ; i++ )
+        {
+            int v = b[i] ;
+            if ( v >= '0' && v <= '9' ) continue ;
+            if ( v >= 'a' && v <= 'f' ) continue ;
+            if ( v >= 'A' && v <= 'F' ) continue ;
+            fail(String.format("Not a hex digit: %02X",b[i])) ;
+        }
+        
+        long v = Hex.getLong(b, idx) ;
+        assertEquals(value, v) ;
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/test/java/org/apache/jena/atlas/lib/TestListUtils.java
----------------------------------------------------------------------
diff --git 
a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestListUtils.java 
b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestListUtils.java
new file mode 100644
index 0000000..ccaa56a
--- /dev/null
+++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestListUtils.java
@@ -0,0 +1,79 @@
+/*
+ * 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.jena.atlas.lib;
+
+import static org.apache.jena.atlas.lib.ListUtils.unique ;
+
+import java.util.ArrayList ;
+import java.util.Arrays ;
+import java.util.List ;
+
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.junit.Test ;
+
+public class TestListUtils extends BaseTest
+{
+    @Test public void list01() 
+    {
+        List<Integer> x = Arrays.asList(1,2,3) ;
+        x = unique(x) ;
+        assertEquals(3, x.size()) ;
+        test(x, 1,2,3) ;
+    }
+
+    @Test public void list02() 
+    {
+        List<Integer> x = Arrays.asList(1,2,3,1,3,2) ;
+        x = unique(x) ;
+        assertEquals(3, x.size()) ;
+        test(x, 1,2,3) ;
+    }
+
+    @Test public void list03() 
+    {
+        List<Integer> x = new ArrayList<>() ;
+        x = unique(x) ;
+        assertEquals(0, x.size()) ;
+        test(x) ;
+    }
+
+    @Test public void list04() 
+    {
+        List<Integer> x = Arrays.asList(99) ;
+        x = unique(x) ;
+        assertEquals(1, x.size()) ;
+        test(x, 99) ;
+    }
+
+    @Test public void list05() 
+    {
+        List<Integer> x = Arrays.asList(1,1,2,3,1,1,3) ;
+        x = unique(x) ;
+        assertEquals(3, x.size()) ;
+        test(x, 1,2,3) ;
+    }
+
+    private void test(List<Integer> x, int... args)
+    {
+        assertEquals(args.length, x.size()) ;
+        
+        for ( int i = 0; i < args.length ; i++ )
+            assertEquals(args[i], x.get(i).intValue()) ;
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/test/java/org/apache/jena/atlas/lib/TestMultiSet.java
----------------------------------------------------------------------
diff --git 
a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestMultiSet.java 
b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestMultiSet.java
new file mode 100644
index 0000000..477386b
--- /dev/null
+++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestMultiSet.java
@@ -0,0 +1,143 @@
+/*
+ * 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.jena.atlas.lib;
+
+import java.util.Arrays ;
+import java.util.Collections ;
+import java.util.List ;
+
+import org.apache.jena.atlas.iterator.Iter ;
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.apache.jena.atlas.lib.MultiSet ;
+import org.junit.Test ;
+
+
+public class TestMultiSet extends BaseTest
+{
+    @Test public void multiSet_01()
+    {
+        MultiSet<String> x = new MultiSet<>() ;
+        assertTrue(x.isEmpty()) ;
+        assertEquals(0, x.count("A")) ;
+    }
+
+    @Test public void multiSet_02()
+    {
+        MultiSet<String> x = new MultiSet<>() ;
+        x.add("A") ;
+        assertFalse(x.isEmpty()) ;
+        assertEquals(1, x.count("A") ) ;
+        x.add("A") ;
+        assertEquals(2, x.count("A") ) ;
+    }
+
+    @Test public void multiSet_03()
+    {
+        MultiSet<String> x = new MultiSet<>() ;
+        x.add("A") ;
+        x.add("A") ;
+        x.remove("A") ;
+        assertEquals(1, x.count("A") ) ;
+        assertTrue(x.contains("A")) ;
+        x.remove("A") ;
+        assertEquals(0, x.count("A") ) ;
+        assertFalse(x.contains("A")) ;
+    }
+
+    @Test public void multiSet_04()
+    {
+        String[] data = { } ;
+        iterTest(data) ;
+    }
+
+
+    @Test public void multiSet_05()
+    {
+        String[] data = { "A" } ;
+        iterTest(data) ;
+    }
+
+    @Test public void multiSet_06()
+    {
+        String[] data = { "A", "B", "C" } ;
+        iterTest(data) ;
+    }
+
+
+    @Test public void multiSet_07()
+    {
+        String[] data = { "A", "B", "C", "A" } ;
+        iterTest(data) ;
+    }
+
+    @Test public void multiSet_08()
+    {
+        String[] data = {  } ;
+        MultiSet<String> x = add(data) ;
+        assertEquals(0, x.size()) ;
+    }
+    
+    @Test public void multiSet_09()
+    {
+        String[] data = { "A", "A" } ;
+        MultiSet<String> x = add(data) ;
+        assertEquals(2, x.size()) ;
+    }
+
+    @Test public void multiSet_10()
+    {
+        String[] data = { "A", "A" } ;
+        MultiSet<String> x = add(data) ;
+        x.remove("A") ;
+        assertEquals(1, x.size()) ;
+        x.remove("A") ;
+        assertEquals(0, x.size()) ;
+        x.remove("A") ;
+        assertEquals(0, x.size()) ;
+    }
+    
+    @Test public void multiSet_11()
+    {
+        String[] data = { "A", "A" } ;
+        MultiSet<String> x = add(data) ;
+        long c = Iter.count(x.elements()) ;
+        assertEquals(1, c) ;
+    }
+    
+    private static MultiSet<String> add(String[] data)
+    {
+        MultiSet<String> x = new MultiSet<>() ;
+        for ( String str : data )
+            x.add(str) ;
+        return x ;
+    }
+    
+    private static void iterTest(String[] data)
+    {
+        List<String> expected = Arrays.asList(data) ;
+        MultiSet<String> x = new MultiSet<>() ;
+        for ( String str : data )
+            x.add(str) ;
+        List<String> actual = Iter.toList(x.iterator()) ;
+        Collections.sort(expected) ;
+        Collections.sort(actual) ;
+        assertEquals(expected, actual) ;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/test/java/org/apache/jena/atlas/lib/TestNumberUtils.java
----------------------------------------------------------------------
diff --git 
a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestNumberUtils.java 
b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestNumberUtils.java
new file mode 100644
index 0000000..62c93da
--- /dev/null
+++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestNumberUtils.java
@@ -0,0 +1,106 @@
+/*
+ * 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.jena.atlas.lib;
+
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.apache.jena.atlas.lib.NumberUtils ;
+import org.junit.Test ;
+
+public class TestNumberUtils extends BaseTest
+{
+    @Test public void int_format_01() { testInt(1, 1, "1") ; } 
+
+    @Test public void int_format_02() { testInt(1, 2, "01") ; } 
+    
+    @Test public void int_format_03() { testInt(0, 1, "0") ; }
+    
+    @Test public void int_format_04() { testInt(0, 2, "00") ; }
+
+    @Test public void int_format_05() { testInt(-1, 2, "-1") ; }
+   
+    @Test public void int_format_06() { testInt(-1, 3, "-01") ; }
+
+
+    @Test public void int_format_11() { testSigned(1, 2, "+1") ; } 
+    
+    @Test public void int_format_12() { testSigned(1, 3, "+01") ; } 
+
+    @Test public void int_format_13() { testSigned(0, 2, "+0") ; }
+    
+    @Test public void int_format_14() { testSigned(0, 3, "+00") ; }
+
+    @Test public void int_format_15() { testSigned(-1, 2, "-1") ; }
+   
+    @Test public void int_format_16() { testSigned(-1, 3, "-01") ; }
+    
+    @Test public void int_format_21() { testInt(1, "1") ; } 
+
+    @Test public void int_format_22() { testInt(0, "0") ; } 
+    
+    @Test public void int_format_23() { testInt(-1, "-1") ; }
+    
+    @Test public void int_format_24() { testInt(10, "10") ; }
+
+    @Test public void int_format_25() { testInt(100, "100") ; }
+
+    @Test public void int_format_26() { testInt(-10, "-10") ; }
+
+    @Test public void int_format_27() { testInt(-100, "-100") ; }
+
+
+    @Test public void int_format_31() { testUnsigned(1, 2, "01") ; } 
+    
+    @Test public void int_format_32() { testUnsigned(1, 1, "1") ; } 
+
+    @Test public void int_format_33() { testUnsigned(0, 1, "0") ; }
+
+    
+    private static void testInt(int value, String expected)
+    {
+        StringBuilder sb = new StringBuilder() ;
+        NumberUtils.formatInt(sb, value) ;
+        String result = sb.toString();
+        assertEquals(expected, result) ;
+    }
+
+    private static void testInt(int value, int width, String expected)
+    {
+        StringBuilder sb = new StringBuilder() ;
+        NumberUtils.formatInt(sb, value, width) ;
+        String result = sb.toString();
+        assertEquals(expected, result) ;
+    }
+
+    private static void testSigned(int value, int width, String expected)
+    {
+        StringBuilder sb = new StringBuilder() ;
+        NumberUtils.formatSignedInt(sb, value, width) ;
+        String result = sb.toString();
+        assertEquals(expected, result) ;
+    }
+    
+    private static void testUnsigned(int value, int width, String expected)
+    {
+        StringBuilder sb = new StringBuilder() ;
+        NumberUtils.formatUnsignedInt(sb, value, width) ;
+        String result = sb.toString();
+        assertEquals(expected, result) ;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/test/java/org/apache/jena/atlas/lib/TestRefLong.java
----------------------------------------------------------------------
diff --git a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestRefLong.java 
b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestRefLong.java
new file mode 100644
index 0000000..88e683a
--- /dev/null
+++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestRefLong.java
@@ -0,0 +1,70 @@
+/*
+ * 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.jena.atlas.lib;
+
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.apache.jena.atlas.lib.RefLong ;
+import org.junit.Test ;
+
+
+public class TestRefLong extends BaseTest
+{
+    @Test public void ref_01()
+    {
+        RefLong ref1 = new RefLong() ;
+        assertEquals(0, ref1.value()) ;
+        RefLong ref2 = new RefLong() ;
+        assertNotSame(ref1, ref2) ;
+    }
+    
+    @Test public void ref_02()
+    {
+        RefLong ref = new RefLong() ;
+        assertEquals(0, ref.value()) ;
+        ref.inc() ;
+        assertEquals(1, ref.value()) ;
+        ref.dec() ;
+        assertEquals(0, ref.value()) ;
+    }
+    
+    @Test public void ref_03()
+    {
+        RefLong ref = new RefLong(99) ;
+        assertEquals(99, ref.value()) ;
+        long x = ref.incAndGet() ;
+        assertEquals(100, x) ;
+        assertEquals(100, ref.value()) ;
+        x = ref.getAndInc() ;
+        assertEquals(100, x) ;
+        assertEquals(101, ref.value()) ;
+    }
+    
+    @Test public void ref_04()
+    {
+        RefLong ref = new RefLong(99) ;
+        assertEquals(99, ref.value()) ;
+        long x = ref.decAndGet() ;
+        assertEquals(98, x) ;
+        assertEquals(98, ref.value()) ;
+        x = ref.getAndDec() ;
+        assertEquals(98, x) ;
+        assertEquals(97, ref.value()) ;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/test/java/org/apache/jena/atlas/lib/TestReverseComparator.java
----------------------------------------------------------------------
diff --git 
a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestReverseComparator.java 
b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestReverseComparator.java
new file mode 100644
index 0000000..80b9c0d
--- /dev/null
+++ 
b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestReverseComparator.java
@@ -0,0 +1,91 @@
+/*
+ * 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.jena.atlas.lib;
+
+
+import java.util.ArrayList ;
+import java.util.Arrays ;
+import java.util.Collections ;
+import java.util.Comparator ;
+import java.util.List ;
+
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.apache.jena.atlas.lib.ReverseComparator ;
+import org.junit.Test ;
+
+public class TestReverseComparator extends BaseTest
+{
+    static Comparator<String> normal = new Comparator<String>()
+    {
+        @Override
+        public int compare(String o1, String o2)
+        {
+            return o1.compareTo(o2);
+        }
+    };
+    
+    static Comparator<String> reverse = new ReverseComparator<>(normal);
+    
+    
+    static Comparator<String> maxMin = new Comparator<String>()
+    {
+        @Override
+        public int compare(String o1, String o2)
+        {
+            int value = o1.compareTo(o2);
+            if (value > 0)
+                return Integer.MAX_VALUE;
+            else if (value < 0)
+                return Integer.MIN_VALUE;
+            else
+                return 0;
+        }
+    };
+    
+    static Comparator<String> reverseMaxMin = new ReverseComparator<>(maxMin);
+    
+    static List<String> items = Arrays.asList("a", "b", "c", "d");
+    static List<String> itemsReverse = Arrays.asList("d", "c", "b", "a");
+    
+    @Test public void reverse_01()
+    {
+        List<String> modified = new ArrayList<>(items);
+        Collections.sort(modified, reverse);
+        
+        test(itemsReverse, modified);
+    }
+    
+    @Test public void reverse_02()
+    {
+        List<String> modified = new ArrayList<>(items);
+        Collections.sort(modified, reverseMaxMin);
+        
+        test(itemsReverse, modified);
+    }
+    
+    private void test(List<?> expected, List<?> actual)
+    {
+        assertEquals(expected.size(), actual.size());
+        
+        for (int i=0; i<expected.size(); i++)
+        {
+            assertEquals(expected.get(i), actual.get(i)) ;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/test/java/org/apache/jena/atlas/lib/TestSetUtils.java
----------------------------------------------------------------------
diff --git 
a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestSetUtils.java 
b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestSetUtils.java
new file mode 100644
index 0000000..d147262
--- /dev/null
+++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestSetUtils.java
@@ -0,0 +1,146 @@
+/*
+ * 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.jena.atlas.lib;
+
+import static org.apache.jena.atlas.lib.ListUtils.asList ;
+
+import java.util.HashSet ;
+import java.util.List ;
+import java.util.Set ;
+
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.apache.jena.atlas.lib.SetUtils ;
+import org.junit.Test ;
+
+public class TestSetUtils extends BaseTest
+{
+    @Test public void set01() 
+    {
+        Set<Integer> x = set(1,2,3) ;
+        test(x,1,2,3) ;
+    }
+
+    @Test public void set02() 
+    {
+        Set<Integer> x1 = set(1,2,3) ;
+        Set<Integer> x2 = set(1,2,3) ;
+        Set<Integer> x3 = SetUtils.intersection(x1, x2) ;
+        test(x3, 1,2,3) ;
+        x3 = SetUtils.intersection(x2, x1) ;
+        test(x3, 1,2,3) ;
+    }
+
+    @Test public void set03() 
+    {
+        Set<Integer> x1 = set(1,2,3) ;
+        Set<Integer> x2 = set(2,9) ;
+        Set<Integer> x3 = SetUtils.intersection(x1, x2) ;
+        test(x3, 2) ;
+        x3 = SetUtils.intersection(x2, x1) ;
+        test(x3, 2) ;
+    }
+
+    @Test public void set04() 
+    {
+        Set<Integer> x1 = set(1,2,3) ;
+        Set<Integer> x2 = set(6,7,8) ;
+        Set<Integer> x3 = SetUtils.intersection(x1, x2) ;
+        test(x3) ;
+        x3 = SetUtils.intersection(x2, x1) ;
+        test(x3) ;
+    }
+
+    @Test public void set05() 
+    {
+        Set<Integer> x1 = set(1,2,3) ;
+        Set<Integer> x2 = set(1,2,3) ;
+        Set<Integer> x3 = SetUtils.union(x1, x2) ;
+        test(x3, 1,2,3) ;
+        x3 = SetUtils.union(x2, x1) ;
+        test(x3, 1,2,3) ;
+    }
+
+    @Test public void set06() 
+    {
+        Set<Integer> x1 = set(1,2,3) ;
+        Set<Integer> x2 = set(2,9) ;
+        Set<Integer> x3 = SetUtils.union(x1, x2) ;
+        test(x3, 1,2,3,9) ;
+        x3 = SetUtils.union(x2, x1) ;
+        test(x3, 1,2,3,9) ;
+    }
+
+    @Test public void set07() 
+    {
+        Set<Integer> x1 = set(1,2,3) ;
+        Set<Integer> x2 = set() ;
+        Set<Integer> x3 = SetUtils.union(x1, x2) ;
+        test(x3,1,2,3) ;
+        x3 = SetUtils.union(x2, x1) ;
+        test(x3,1,2,3) ;
+    }
+
+    @Test public void set08() 
+    {
+        Set<Integer> x1 = set(1,2,3) ;
+        Set<Integer> x2 = set() ;
+        Set<Integer> x3 = SetUtils.difference(x1, x2) ;
+        test(x3,1,2,3) ;
+        x3 = SetUtils.difference(x2, x1) ;
+        test(x3) ;
+    }
+
+    @Test public void set09() 
+    {
+        Set<Integer> x1 = set(1,2,3) ;
+        Set<Integer> x2 = set(3) ;
+        Set<Integer> x3 = SetUtils.difference(x1, x2) ;
+        test(x3,1,2) ;
+        x3 = SetUtils.difference(x2, x1) ;
+        test(x3) ;
+    }
+
+    @Test public void set10() 
+    {
+        Set<Integer> x1 = set(1,2,3) ;
+        Set<Integer> x2 = set(4,5,6) ;
+        Set<Integer> x3 = SetUtils.difference(x1, x2) ;
+        test(x3,1,2,3) ;
+        x3 = SetUtils.difference(x2, x1) ;
+        test(x3,4,5,6) ;
+    }
+    
+    // --------
+    
+    private static Set<Integer> set(int... values)
+    {
+        return new HashSet<>(asList(values)) ;
+    }
+
+    private void test(Set<Integer> x, int...values)
+    {
+        List<Integer> y = asList(values) ;
+        assertEquals(y.size(), x.size()) ;
+
+        for ( Integer aY : y )
+        {
+            assertTrue( x.contains( aY ) );
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/test/java/org/apache/jena/atlas/lib/TestStrUtils.java
----------------------------------------------------------------------
diff --git 
a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestStrUtils.java 
b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestStrUtils.java
new file mode 100644
index 0000000..ff1e8c6
--- /dev/null
+++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestStrUtils.java
@@ -0,0 +1,59 @@
+/*
+ * 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.jena.atlas.lib;
+
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.apache.jena.atlas.lib.StrUtils ;
+import org.junit.Test ;
+
+public class TestStrUtils extends BaseTest
+{
+    static char marker = '_' ;
+    static char esc[] = { ' ' , '_' } ; 
+    
+    static void test(String x)
+    {
+        test(x, null) ;
+    }
+    
+    static void test(String x, String z)
+    {
+        String y = StrUtils.encodeHex(x, marker, esc) ;
+        if ( z != null )
+            assertEquals(z, y) ;
+        String x2 = StrUtils.decodeHex(y, marker) ;
+        assertEquals(x, x2) ;
+    }
+    
+    @Test public void enc01() { test("abc") ; } 
+
+    @Test public void enc02() { test("") ; } 
+
+    @Test public void enc03() { test("_", "_5F" ) ; } 
+    
+    @Test public void enc04() { test(" ", "_20" ) ; } 
+    
+    @Test public void enc05() { test("_ _", "_5F_20_5F" ) ; } 
+    
+    @Test public void enc06() { test("_5F", "_5F5F" ) ; } 
+    
+    @Test public void enc07() { test("_2") ; } 
+    
+    @Test public void enc08() { test("AB_CD", "AB_5FCD") ; } 
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/test/java/org/apache/jena/atlas/lib/TestTrie.java
----------------------------------------------------------------------
diff --git a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestTrie.java 
b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestTrie.java
new file mode 100644
index 0000000..1cb9e2e
--- /dev/null
+++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestTrie.java
@@ -0,0 +1,346 @@
+/*
+ * 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.jena.atlas.lib;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Tests for the {@link Trie} class
+ * 
+ */
+public class TestTrie {
+
+    /**
+     * Add a single key value
+     */
+    @Test
+    public void trie_add_01() {
+        Trie<Integer> trie = new Trie<>();
+        trie.add("test", 123);
+        Assert.assertTrue(trie.contains("test"));
+        Assert.assertEquals((Integer) 123, trie.get("test"));
+    }
+
+    /**
+     * Add two key values
+     */
+    @Test
+    public void trie_add_02() {
+        Trie<Integer> trie = new Trie<>();
+        trie.add("test", 123);
+        trie.add("other", 456);
+        Assert.assertTrue(trie.contains("test"));
+        Assert.assertTrue(trie.contains("other"));
+        Assert.assertEquals((Integer) 123, trie.get("test"));
+        Assert.assertEquals((Integer) 456, trie.get("other"));
+    }
+
+    /**
+     * Replace an existing key value
+     */
+    @Test
+    public void trie_add_03() {
+        Trie<Integer> trie = new Trie<>();
+        trie.add("test", 123);
+        trie.add("test", 456);
+        Assert.assertTrue(trie.contains("test"));
+        Assert.assertEquals((Integer) 456, trie.get("test"));
+    }
+
+    /**
+     * Adding a null value is ignored
+     */
+    @Test
+    public void trie_add_04() {
+        Trie<Integer> trie = new Trie<>();
+        trie.add("test", null);
+        Assert.assertFalse(trie.contains("test"));
+    }
+    
+    /**
+     * Adding a null key is permitted - provides access to root of Trie
+     */
+    @Test
+    public void trie_add_05() {
+        Trie<Integer> trie = new Trie<>();
+        trie.add(null, 123);
+        Assert.assertTrue(trie.contains(null));
+        Assert.assertEquals((Integer)123, trie.get(null));
+    }
+    
+    /**
+     * Adding an empty key is permitted - provides access to root of Trie 
+     */
+    @Test
+    public void trie_add_06() {
+        Trie<Integer> trie = new Trie<>();
+        trie.add("", 123);
+        Assert.assertTrue(trie.contains(""));
+        Assert.assertEquals((Integer)123, trie.get(""));
+    }
+    
+    /**
+     * Test for non-existent key
+     */
+    @Test
+    public void trie_contains_01() {
+        Trie<Integer> trie = new Trie<>();
+        Assert.assertFalse(trie.contains("test"));
+    }
+
+    /**
+     * Test for keys with and without values required
+     */
+    @Test
+    public void trie_contains_02() {
+        Trie<Integer> trie = new Trie<>();
+        trie.add("test", 123);
+        Assert.assertTrue(trie.contains("test"));
+        Assert.assertTrue(trie.contains("test", true));
+        Assert.assertTrue(trie.contains("test", 123));
+
+        // Any prefix of an added key exists if we don't require it to have a
+        // value
+        Assert.assertFalse(trie.contains("t"));
+        Assert.assertTrue(trie.contains("t", false));
+    }
+    
+    /**
+     * Test for non-existent null key
+     */
+    @Test
+    public void trie_contains_03() {
+        Trie<Integer> trie = new Trie<>();
+        Assert.assertFalse(trie.contains(null));
+        Assert.assertTrue(trie.contains(null, false));
+    }
+    
+    /**
+     * Test for empty key
+     */
+    @Test
+    public void trie_contains_04() {
+        Trie<Integer> trie = new Trie<>();
+        Assert.assertFalse(trie.contains(""));
+        Assert.assertTrue(trie.contains("", false));
+    }
+
+    /**
+     * Removing a key value
+     */
+    @Test
+    public void trie_remove_01() {
+        Trie<Integer> trie = new Trie<>();
+        trie.add("test", 123);
+        Assert.assertTrue(trie.contains("test"));
+        Assert.assertEquals((Integer) 123, trie.get("test"));
+
+        // Removing does not fully remove the key it merely nulls the value
+        trie.remove("test");
+        Assert.assertFalse(trie.contains("test"));
+        Assert.assertTrue(trie.contains("test", false));
+        Assert.assertNull(trie.get("test"));
+    }
+
+    /**
+     * Removing a key value, removing a key which is a prefix of another leaves
+     * the other intact
+     */
+    @Test
+    public void trie_remove_02() {
+        Trie<Integer> trie = new Trie<>();
+        trie.add("test", 123);
+        trie.add("testing", 456);
+        Assert.assertTrue(trie.contains("test"));
+        Assert.assertEquals((Integer) 123, trie.get("test"));
+        Assert.assertTrue(trie.contains("testing"));
+        Assert.assertEquals((Integer) 456, trie.get("testing"));
+
+        // Removing does not fully remove the key it merely nulls the value
+        trie.remove("test");
+        Assert.assertFalse(trie.contains("test"));
+        Assert.assertTrue(trie.contains("test", false));
+        Assert.assertNull(trie.get("test"));
+
+        // It also does not remove any keys who had the removed key as a prefix
+        Assert.assertTrue(trie.contains("testing"));
+        Assert.assertEquals((Integer) 456, trie.get("testing"));
+    }
+    
+    /**
+     * Test for removing null key - provides access to trie root
+     */
+    @Test
+    public void trie_remove_03() {
+        Trie<Integer> trie = new Trie<>();
+        trie.add(null, 123);
+        Assert.assertTrue(trie.contains(null));
+        Assert.assertEquals((Integer)123, trie.get(null));
+        
+        trie.remove(null);
+        Assert.assertFalse(trie.contains(null));
+    }
+    
+    /**
+     * Test for removing null key - provides access to trie root
+     */
+    @Test
+    public void trie_remove_04() {
+        Trie<Integer> trie = new Trie<>();
+        trie.add("", 123);
+        Assert.assertTrue(trie.contains(""));
+        Assert.assertEquals((Integer)123, trie.get(""));
+        
+        trie.remove("");
+        Assert.assertFalse(trie.contains(""));
+    }
+    
+    /**
+     * Test prefix search
+     */
+    @Test
+    public void trie_prefix_search_01() {
+        Trie<Integer> trie = new Trie<>();
+        trie.add("test", 123);
+        trie.add("testing", 456);
+        
+        //Prefix search on "test" should return two values
+        List<Integer> matches = trie.prefixSearch("test");
+        Assert.assertEquals(2, matches.size());
+        
+        //Prefix search on "testi" should return one value
+        matches = trie.prefixSearch("testi");
+        Assert.assertEquals(1, matches.size());
+        
+        //Prefix search on "testingly" should return no values
+        matches = trie.prefixSearch("testingly");
+        Assert.assertEquals(0, matches.size());
+        
+        //Prefix search on null key should give two values
+        matches = trie.prefixSearch(null);
+        Assert.assertEquals(2, matches.size());
+    }
+    
+    /**
+     * Test partial search
+     */
+    @Test
+    public void trie_partial_search_01() {
+        Trie<Integer> trie = new Trie<>();
+        trie.add("test", 123);
+        trie.add("testing", 456);
+        
+        //Partial search on "test" should return one values
+        List<Integer> matches = trie.partialSearch("test");
+        Assert.assertEquals(1, matches.size());
+        
+        //Prefix search on "testi" should return one values
+        matches = trie.partialSearch("testi");
+        Assert.assertEquals(1, matches.size());
+        
+        //Prefix search on "testingly" should return two values
+        matches = trie.partialSearch("testingly");
+        Assert.assertEquals(2, matches.size());
+        
+        //Prefix search on null key should give no values
+        matches = trie.partialSearch(null);
+        Assert.assertEquals(0, matches.size());
+    }
+    
+    /**
+     * Test longest match
+     */
+    @Test
+    public void trie_longest_match_01() {
+        Trie<Integer> trie = new Trie<>();
+        trie.add("test", 123);
+        trie.add("testing", 456);
+        Assert.assertTrue(trie.contains("test"));
+        Assert.assertTrue(trie.contains("testing"));
+        
+        Assert.assertEquals((Integer)456, trie.longestMatch("testing"));
+    }
+    
+    /**
+     * Test longest match
+     */
+    @Test
+    public void trie_longest_match_02() {
+        Trie<Integer> trie = new Trie<>();
+        trie.add("test", 123);
+        trie.add("testing", 456);
+        
+        Assert.assertEquals((Integer)456, trie.longestMatch("testingly"));
+    }
+    
+    /**
+     * Test longest match
+     */
+    @Test
+    public void trie_longest_match_03() {
+        Trie<Integer> trie = new Trie<>();
+        trie.add("test", 123);
+        trie.add("testing", 456);
+        trie.remove("testing");
+        
+        Assert.assertEquals((Integer)123, trie.longestMatch("testing"));
+    }
+    
+    /**
+     * Test shortest match
+     */
+    @Test
+    public void trie_shortest_match_01() {
+        Trie<Integer> trie = new Trie<>();
+        trie.add("test", 123);
+        trie.add("testing", 456);
+        Assert.assertTrue(trie.contains("test"));
+        Assert.assertTrue(trie.contains("testing"));
+        
+        Assert.assertEquals((Integer)123, trie.shortestMatch("testing"));
+    }
+    
+    /**
+     * Test shortest match
+     */
+    @Test
+    public void trie_shortest_match_02() {
+        Trie<Integer> trie = new Trie<>();
+        trie.add("test", 123);
+        trie.add("testing", 456);
+        
+        Assert.assertEquals((Integer)123, trie.shortestMatch("testingly"));
+    }
+    
+    /**
+     * Test shortest match
+     */
+    @Test
+    public void trie_shortest_match_03() {
+        Trie<Integer> trie = new Trie<>();
+        trie.add("test", 123);
+        trie.add("testing", 456);
+        trie.remove("test");
+        
+        Assert.assertEquals((Integer)456, trie.shortestMatch("testing"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/test/java/org/apache/jena/atlas/lib/TestXMLLib.java
----------------------------------------------------------------------
diff --git a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestXMLLib.java 
b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestXMLLib.java
new file mode 100644
index 0000000..cae99ef
--- /dev/null
+++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestXMLLib.java
@@ -0,0 +1,47 @@
+/*
+ * 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.jena.atlas.lib;
+
+import org.apache.jena.atlas.lib.XMLLib ;
+import org.junit.Assert ;
+import org.junit.Test ;
+
+/** XML related functionality */
+public class TestXMLLib
+{
+    @Test public void ws_collapse_01()  { test("abc", "abc") ; }
+    @Test public void ws_collapse_02()  { test(" abc", "abc") ; }
+    @Test public void ws_collapse_03()  { test(" abc ", "abc") ; }
+    @Test public void ws_collapse_04()  { test(" a b c ", "a b c") ; }
+    @Test public void ws_collapse_05()  { test("\babc", "\babc") ; }
+    @Test public void ws_collapse_06()  { test("", "") ; }
+    @Test public void ws_collapse_07()  { test(" ", "") ; }
+    @Test public void ws_collapse_08()  { test(" \t\t\t\t\t\t\t   ", "") ; }
+    
+    // String.trim : "Returns a copy of the string, with leading and trailing 
whitespace omitted."
+    // but later says it trims anything <= 0x20.  There are lots of control 
characters in x01-x1F. 
+    // We only want to trim \n \r \t and space. 
+    
+    private static void test(String str1, String str2)
+    {
+        String result = XMLLib.WScollapse(str1) ;
+        Assert.assertEquals(str2, result) ;
+    }
+
+}

Reply via email to