From 617e142fc1f2b499875cd8a8d53902806cd7cee5 Mon Sep 17 00:00:00 2001 From: Robinson Date: Tue, 4 Jul 2023 00:07:54 +0200 Subject: [PATCH] Added ByteArray unit tests, converted tests to kotlin --- test/dorkbox/fsm/TestDoubleArrayByteTrie.kt | 168 ++++++++ test/dorkbox/fsm/TestDoubleArrayStringTrie.kt | 384 ++++++++---------- 2 files changed, 341 insertions(+), 211 deletions(-) create mode 100644 test/dorkbox/fsm/TestDoubleArrayByteTrie.kt diff --git a/test/dorkbox/fsm/TestDoubleArrayByteTrie.kt b/test/dorkbox/fsm/TestDoubleArrayByteTrie.kt new file mode 100644 index 0000000..c91f20c --- /dev/null +++ b/test/dorkbox/fsm/TestDoubleArrayByteTrie.kt @@ -0,0 +1,168 @@ +/* + * Copyright 2023 dorkbox, llc + * + * Licensed 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 dorkbox.fsm + +import dorkbox.fsm.FiniteStateMachine.build +import org.junit.Assert +import org.junit.Test +import java.io.* +import java.nio.file.Files +import java.nio.file.Paths +import java.util.* + +/** + * @author hankcs + */ +class TestDoubleArrayByteTrie { + private fun buildASimpleDoubleArrayByteArrayTrie(): DoubleArrayByteArrayTrie { + // Collect test data set + val map = mutableMapOf() + val keyArray = arrayOf("hers", "his", "she", "he") + keyArray.forEach { key -> + map[key.toByteArray()] = key + } + // Build an DoubleArrayStringTrie + return build(map) + } + + private fun validateASimpleDoubleArrayByteArrayTrie(acdat: DoubleArrayByteArrayTrie) { + // Test it + val bytes = "uhers".toByteArray() + acdat.parseBytes(bytes, object : IHit { + override fun hit(begin: Int, end: Int, value: String) { + System.out.printf("[%d:%d]=%s\n", begin, end, value) + + Assert.assertEquals(String(bytes.copyOfRange(begin, end)), value) + } + }) + + // Or simply use + val wordList = acdat.parseBytes(bytes) + println(wordList) + } + + @Test + @Throws(Exception::class) + fun testBuildAndParseSimply() { + val acdat = buildASimpleDoubleArrayByteArrayTrie() + validateASimpleDoubleArrayByteArrayTrie(acdat) + } + + private class CountHits internal constructor(private val countAll: Boolean) : IHitCancellable { + var count = 0 + private set + + override fun hit(begin: Int, end: Int, value: String): Boolean { + count += 1 + return countAll + } + } + + @Test + fun testMatches() { + val map: MutableMap = HashMap() + map["space"] = 1 + map["keyword"] = 2 + map["ch"] = 3 + val trie = build(map) + Assert.assertTrue(trie.matches("space")) + Assert.assertTrue(trie.matches("keyword")) + Assert.assertTrue(trie.matches("ch")) + Assert.assertTrue(trie.matches(" ch")) + Assert.assertTrue(trie.matches("chkeyword")) + Assert.assertTrue(trie.matches("oooospace2")) + Assert.assertFalse(trie.matches("c")) + Assert.assertFalse(trie.matches("")) + Assert.assertFalse(trie.matches("spac")) + Assert.assertFalse(trie.matches("nothing")) + } + + @Test + fun testFirstMatch() { + val map: MutableMap = HashMap() + map["space"] = 1 + map["keyword"] = 2 + map["ch"] = 3 + val trie = build(map) + var hit = trie.findFirst("space") + Assert.assertEquals(0, hit!!.begin.toLong()) + Assert.assertEquals(5, hit.end.toLong()) + Assert.assertEquals( + 1, hit.value.toLong() + ) + hit = trie.findFirst("a lot of garbage in the space ch") + Assert.assertEquals(24, hit!!.begin.toLong()) + Assert.assertEquals(29, hit.end.toLong()) + Assert.assertEquals( + 1, hit.value.toLong() + ) + Assert.assertNull(trie.findFirst("")) + Assert.assertNull(trie.findFirst("value")) + Assert.assertNull(trie.findFirst("keywork")) + Assert.assertNull(trie.findFirst(" no pace")) + } + + @Test + @Throws(Exception::class) + fun testCancellation() { + // Collect test data set + val map = TreeMap() + val keyArray = arrayOf("foo", "bar") + for (key in keyArray) { + map[key] = key + } + // Build an DoubleArrayStringTrie + val acdat = build(map) + + // count matches + val haystack = "sfwtfoowercwbarqwrcq" + val cancellingMatcher = CountHits(false) + val countingMatcher = CountHits(true) + + println("Testing cancellation") + acdat.parseText(haystack, cancellingMatcher) + acdat.parseText(haystack, countingMatcher) + Assert.assertEquals(cancellingMatcher.count.toLong(), 1) + Assert.assertEquals(countingMatcher.count.toLong(), 2) + } + + @Suppress("UNCHECKED_CAST") + @Test + @Throws(Exception::class) + fun testSaveAndLoad() { + var acdat = buildASimpleDoubleArrayByteArrayTrie() + val tmpPath = System.getProperty("java.io.tmpdir").replace("\\\\", "/") + "/acdat.tmp" + + println("Saving acdat to: $tmpPath") + val out = ObjectOutputStream(Files.newOutputStream(Paths.get(tmpPath))) + out.writeObject(acdat) + out.close() + + println("Loading acdat from: $tmpPath") + val `in` = ObjectInputStream(Files.newInputStream(Paths.get(tmpPath))) + acdat = `in`.readObject() as DoubleArrayByteArrayTrie + validateASimpleDoubleArrayByteArrayTrie(acdat) + } + + @Test + fun testBuildEmptyTrie() { + val map = TreeMap() + val acdat = build(map) + Assert.assertEquals(0, acdat.size.toLong()) + val hits = acdat.parseText("uhers") + Assert.assertEquals(0, hits.size.toLong()) + } +} diff --git a/test/dorkbox/fsm/TestDoubleArrayStringTrie.kt b/test/dorkbox/fsm/TestDoubleArrayStringTrie.kt index f4104b6..f313949 100644 --- a/test/dorkbox/fsm/TestDoubleArrayStringTrie.kt +++ b/test/dorkbox/fsm/TestDoubleArrayStringTrie.kt @@ -13,284 +13,246 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package dorkbox.fsm -package dorkbox.fsm; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.TreeSet; - -import org.junit.Test; +import dorkbox.fsm.FiniteStateMachine.build +import org.junit.Assert +import org.junit.Test +import java.io.* +import java.nio.file.Files +import java.nio.file.Paths +import java.util.* /** * @author hankcs */ -public class TestDoubleArrayStringTrie { - private - DoubleArrayStringTrie buildASimpleDoubleArrayStringTrie() { + private fun buildASimpleDoubleArrayStringTrie(): DoubleArrayStringTrie { // Collect test data set - TreeMap map = new TreeMap(); - String[] keyArray = new String[] {"hers", "his", "she", "he"}; - for (String key : keyArray) { - map.put(key, key); + val map = TreeMap() + val keyArray = arrayOf("hers", "his", "she", "he") + for (key in keyArray) { + map[key] = key } // Build an DoubleArrayStringTrie - return FiniteStateMachine.INSTANCE.build(map); + return build(map) } - private - void validateASimpleDoubleArrayStringTrie(DoubleArrayStringTrie acdat) { + private fun validateASimpleDoubleArrayStringTrie(acdat: DoubleArrayStringTrie) { // Test it - final String text = "uhers"; - acdat.parseText(text, new IHit() { - @Override - public - void hit(int begin, int end, String value) { - System.out.printf("[%d:%d]=%s\n", begin, end, value); - assertEquals(text.substring(begin, end), value); + val text = "uhers" + acdat.parseText(text, object : IHit { + override fun hit(begin: Int, end: Int, value: String) { + System.out.printf("[%d:%d]=%s\n", begin, end, value) + Assert.assertEquals(text.substring(begin, end), value) } - }); + }) // Or simply use - List> wordList = acdat.parseText(text); - System.out.println(wordList); + val wordList = acdat.parseText(text) + println(wordList) } @Test - public - void testBuildAndParseSimply() throws Exception { - DoubleArrayStringTrie acdat = buildASimpleDoubleArrayStringTrie(); - validateASimpleDoubleArrayStringTrie(acdat); + @Throws(Exception::class) + fun testBuildAndParseSimply() { + val acdat = buildASimpleDoubleArrayStringTrie() + validateASimpleDoubleArrayStringTrie(acdat) } @Test - public - void testBuildVeryLongWord() throws Exception { - TreeMap map = new TreeMap(); - - int longWordLength = 20000; - - String word = loadText("dorkbox/fsm/text.txt"); - map.put(word.substring(10, longWordLength), word.substring(10, longWordLength)); - map.put(word.substring(30, 40), null); + @Throws(Exception::class) + fun testBuildVeryLongWord() { + val map = TreeMap() + val longWordLength = 20000 + val word = loadText("dorkbox/fsm/text.txt") + map[word.substring(10, longWordLength)] = word.substring(10, longWordLength) + map[word.substring(30, 40)] = null // word = loadText("en/text.txt"); // map.put(word.substring(10, longWordLength), word.substring(10, longWordLength)); // map.put(word.substring(30, 40), null); // Build an DoubleArrayStringTrie - DoubleArrayStringTrie acdat = FiniteStateMachine.INSTANCE.build(map); + val acdat: DoubleArrayStringTrie = build(map) - List> result = acdat.parseText(word); - - assertEquals(2, result.size()); - assertEquals(30, - result.get(0) - .getBegin()); - assertEquals(40, - result.get(0) - .getEnd()); - assertEquals(10, - result.get(1) - .getBegin()); - assertEquals(longWordLength, - result.get(1) - .getEnd()); + val result = acdat.parseText(word) + Assert.assertEquals(2, result.size.toLong()) + Assert.assertEquals( + 30, result[0].begin.toLong() + ) + Assert.assertEquals( + 40, result[0].end.toLong() + ) + Assert.assertEquals( + 10, result[1].begin.toLong() + ) + Assert.assertEquals( + longWordLength.toLong(), result[1].end.toLong() + ) } @Test - public - void testBuildAndParseWithBigFile() throws Exception { + @Throws(Exception::class) + fun testBuildAndParseWithBigFile() { // Load test data from disk - Set dictionary = loadDictionary("dorkbox/fsm/dictionary.txt"); - final String text = loadText("dorkbox/fsm/text.txt"); + val dictionary = loadDictionary("dorkbox/fsm/dictionary.txt") + + val text = loadText("dorkbox/fsm/text.txt") // You can use any type of Map to hold data - Map map = new TreeMap(); -// Map map = new HashMap(); + val map: MutableMap = TreeMap() + // Map map = new HashMap(); // Map map = new LinkedHashMap(); - for (String key : dictionary) { - map.put(key, key); + for (key in dictionary) { + map[key] = key } // Build an DoubleArrayStringTrie - DoubleArrayStringTrie acdat = FiniteStateMachine.INSTANCE.build(map); + val acdat = build(map) + // Test it - acdat.parseText(text, new IHit() { - @Override - public - void hit(int begin, int end, String value) { - assertEquals(text.substring(begin, end), value); + acdat.parseText(text, object : IHit { + override fun hit(begin: Int, end: Int, value: String) { + Assert.assertEquals(text.substring(begin, end), value) } - }); + }) } - private static - class CountHits implements IHitCancellable { - private int count; - private boolean countAll; + private class CountHits internal constructor(private val countAll: Boolean) : IHitCancellable { + var count = 0 + private set - CountHits(boolean countAll) { - this.count = 0; - this.countAll = countAll; - } - - public - int getCount() { - return count; - } - - @Override - public - boolean hit(int begin, int end, String value) { - count += 1; - return countAll; + override fun hit(begin: Int, end: Int, value: String): Boolean { + count += 1 + return countAll } } @Test - public - void testMatches() { - Map map = new HashMap(); - map.put("space", 1); - map.put("keyword", 2); - map.put("ch", 3); - DoubleArrayStringTrie trie = FiniteStateMachine.INSTANCE.build(map); - - assertTrue(trie.matches("space")); - assertTrue(trie.matches("keyword")); - assertTrue(trie.matches("ch")); - assertTrue(trie.matches(" ch")); - assertTrue(trie.matches("chkeyword")); - assertTrue(trie.matches("oooospace2")); - assertFalse(trie.matches("c")); - assertFalse(trie.matches("")); - assertFalse(trie.matches("spac")); - assertFalse(trie.matches("nothing")); + fun testMatches() { + val map: MutableMap = HashMap() + map["space"] = 1 + map["keyword"] = 2 + map["ch"] = 3 + val trie = build(map) + Assert.assertTrue(trie.matches("space")) + Assert.assertTrue(trie.matches("keyword")) + Assert.assertTrue(trie.matches("ch")) + Assert.assertTrue(trie.matches(" ch")) + Assert.assertTrue(trie.matches("chkeyword")) + Assert.assertTrue(trie.matches("oooospace2")) + Assert.assertFalse(trie.matches("c")) + Assert.assertFalse(trie.matches("")) + Assert.assertFalse(trie.matches("spac")) + Assert.assertFalse(trie.matches("nothing")) } @Test - public - void testFirstMatch() { - Map map = new HashMap(); - map.put("space", 1); - map.put("keyword", 2); - map.put("ch", 3); - DoubleArrayStringTrie trie = FiniteStateMachine.INSTANCE.build(map); - - Hit hit = trie.findFirst("space"); - assertEquals(0, hit.getBegin()); - assertEquals(5, hit.getEnd()); - assertEquals(1, - hit.getValue() - .intValue()); - - hit = trie.findFirst("a lot of garbage in the space ch"); - assertEquals(24, hit.getBegin()); - assertEquals(29, hit.getEnd()); - assertEquals(1, - hit.getValue() - .intValue()); - - assertNull(trie.findFirst("")); - assertNull(trie.findFirst("value")); - assertNull(trie.findFirst("keywork")); - assertNull(trie.findFirst(" no pace")); + fun testFirstMatch() { + val map: MutableMap = HashMap() + map["space"] = 1 + map["keyword"] = 2 + map["ch"] = 3 + val trie = build(map) + var hit = trie.findFirst("space") + Assert.assertEquals(0, hit!!.begin.toLong()) + Assert.assertEquals(5, hit.end.toLong()) + Assert.assertEquals( + 1, hit.value.toLong() + ) + hit = trie.findFirst("a lot of garbage in the space ch") + Assert.assertEquals(24, hit!!.begin.toLong()) + Assert.assertEquals(29, hit.end.toLong()) + Assert.assertEquals( + 1, hit.value.toLong() + ) + Assert.assertNull(trie.findFirst("")) + Assert.assertNull(trie.findFirst("value")) + Assert.assertNull(trie.findFirst("keywork")) + Assert.assertNull(trie.findFirst(" no pace")) } @Test - public - void testCancellation() throws Exception { + @Throws(Exception::class) + fun testCancellation() { // Collect test data set - TreeMap map = new TreeMap(); - String[] keyArray = new String[] {"foo", "bar"}; - for (String key : keyArray) { - map.put(key, key); + val map = TreeMap() + val keyArray = arrayOf("foo", "bar") + for (key in keyArray) { + map[key] = key } // Build an DoubleArrayStringTrie - DoubleArrayStringTrie acdat = FiniteStateMachine.INSTANCE.build(map); + val acdat = build(map) + // count matches - String haystack = "sfwtfoowercwbarqwrcq"; - CountHits cancellingMatcher = new CountHits(false); - CountHits countingMatcher = new CountHits(true); - System.out.println("Testing cancellation"); - acdat.parseText(haystack, cancellingMatcher); - acdat.parseText(haystack, countingMatcher); - assertEquals(cancellingMatcher.count, 1); - assertEquals(countingMatcher.count, 2); + val haystack = "sfwtfoowercwbarqwrcq" + val cancellingMatcher = CountHits(false) + val countingMatcher = CountHits(true) + + println("Testing cancellation") + acdat.parseText(haystack, cancellingMatcher) + acdat.parseText(haystack, countingMatcher) + Assert.assertEquals(cancellingMatcher.count.toLong(), 1) + Assert.assertEquals(countingMatcher.count.toLong(), 2) } - private - String loadText(String path) throws IOException { - StringBuilder sbText = new StringBuilder(); - BufferedReader br = new BufferedReader(new InputStreamReader(Thread.currentThread() - .getContextClassLoader() - .getResourceAsStream(path), "UTF-8")); - String line; - while ((line = br.readLine()) != null) { - sbText.append(line) - .append("\n"); + @Throws(IOException::class) + private fun loadText(path: String): String { + val sbText = StringBuilder() + val br = BufferedReader( + InputStreamReader( + Thread.currentThread().contextClassLoader.getResourceAsStream(path), "UTF-8" + ) + ) + var line: String? + while (br.readLine().also { line = it } != null) { + sbText.append(line).append("\n") } - br.close(); - - return sbText.toString(); + br.close() + return sbText.toString() } - private - Set loadDictionary(String path) throws IOException { - Set dictionary = new TreeSet(); - BufferedReader br = new BufferedReader(new InputStreamReader(Thread.currentThread() - .getContextClassLoader() - .getResourceAsStream(path), "UTF-8")); - String line; - while ((line = br.readLine()) != null) { - dictionary.add(line); + @Throws(IOException::class) + private fun loadDictionary(path: String): Set { + + val dictionary: MutableSet = TreeSet() + val br = BufferedReader( + InputStreamReader( + Thread.currentThread().contextClassLoader.getResourceAsStream(path), "UTF-8" + ) + ) + + + var line: String? + while (br.readLine().also { line = it } != null) { + dictionary.add(line!!) } - br.close(); - - return dictionary; + br.close() + return dictionary } - @SuppressWarnings("unchecked") + @Suppress("UNCHECKED_CAST") @Test - public - void testSaveAndLoad() throws Exception { - DoubleArrayStringTrie acdat = buildASimpleDoubleArrayStringTrie(); - final String tmpPath = System.getProperty("java.io.tmpdir") - .replace("\\\\", "/") + "/acdat.tmp"; - System.out.println("Saving acdat to: " + tmpPath); + @Throws(Exception::class) + fun testSaveAndLoad() { + var acdat = buildASimpleDoubleArrayStringTrie() + val tmpPath = System.getProperty("java.io.tmpdir").replace("\\\\", "/") + "/acdat.tmp" - ObjectOutputStream out = new ObjectOutputStream(Files.newOutputStream(Paths.get(tmpPath))); - out.writeObject(acdat); - out.close(); - System.out.println("Loading acdat from: " + tmpPath); + println("Saving acdat to: $tmpPath") + val out = ObjectOutputStream(Files.newOutputStream(Paths.get(tmpPath))) + out.writeObject(acdat) + out.close() - ObjectInputStream in = new ObjectInputStream(Files.newInputStream(Paths.get(tmpPath))); - - acdat = (DoubleArrayStringTrie) in.readObject(); - validateASimpleDoubleArrayStringTrie(acdat); + println("Loading acdat from: $tmpPath") + val `in` = ObjectInputStream(Files.newInputStream(Paths.get(tmpPath))) + acdat = `in`.readObject() as DoubleArrayStringTrie + validateASimpleDoubleArrayStringTrie(acdat) } @Test - public - void testBuildEmptyTrie() { - TreeMap map = new TreeMap(); - DoubleArrayStringTrie acdat = FiniteStateMachine.INSTANCE.build(map); - assertEquals(0, acdat.getSize()); - List> hits = acdat.parseText("uhers"); - assertEquals(0, hits.size()); + fun testBuildEmptyTrie() { + val map = TreeMap() + val acdat = build(map) + Assert.assertEquals(0, acdat.size.toLong()) + val hits = acdat.parseText("uhers") + Assert.assertEquals(0, hits.size.toLong()) } }