aboutsummaryrefslogtreecommitdiffstats
path: root/native/jni/tests
diff options
context:
space:
mode:
Diffstat (limited to 'native/jni/tests')
-rw-r--r--native/jni/tests/suggest/core/dicnode/dic_node_pool_test.cpp69
-rw-r--r--native/jni/tests/suggest/core/layout/geometry_utils_test.cpp83
-rw-r--r--native/jni/tests/suggest/policyimpl/dictionary/header/header_read_write_utils_test.cpp78
-rw-r--r--native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content_test.cpp79
-rw-r--r--native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/probability_entry_test.cpp2
-rw-r--r--native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table_test.cpp76
-rw-r--r--native/jni/tests/suggest/policyimpl/dictionary/utils/byte_array_utils_test.cpp92
-rw-r--r--native/jni/tests/suggest/policyimpl/dictionary/utils/format_utils_test.cpp97
-rw-r--r--native/jni/tests/suggest/policyimpl/dictionary/utils/sparse_table_test.cpp47
-rw-r--r--native/jni/tests/suggest/policyimpl/dictionary/utils/trie_map_test.cpp28
-rw-r--r--native/jni/tests/suggest/policyimpl/utils/damerau_levenshtein_edit_distance_policy_test.cpp65
-rw-r--r--native/jni/tests/utils/char_utils_test.cpp122
-rw-r--r--native/jni/tests/utils/int_array_view_test.cpp95
-rw-r--r--native/jni/tests/utils/time_keeper_test.cpp38
14 files changed, 958 insertions, 13 deletions
diff --git a/native/jni/tests/suggest/core/dicnode/dic_node_pool_test.cpp b/native/jni/tests/suggest/core/dicnode/dic_node_pool_test.cpp
new file mode 100644
index 000000000..854efdfe6
--- /dev/null
+++ b/native/jni/tests/suggest/core/dicnode/dic_node_pool_test.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#include "suggest/core/dicnode/dic_node_pool.h"
+
+#include <gtest/gtest.h>
+
+namespace latinime {
+namespace {
+
+TEST(DicNodePoolTest, TestGet) {
+ static const int CAPACITY = 10;
+ DicNodePool dicNodePool(CAPACITY);
+
+ for (int i = 0; i < CAPACITY; ++i) {
+ EXPECT_NE(nullptr, dicNodePool.getInstance());
+ }
+ EXPECT_EQ(nullptr, dicNodePool.getInstance());
+}
+
+TEST(DicNodePoolTest, TestPlaceBack) {
+ static const int CAPACITY = 1;
+ DicNodePool dicNodePool(CAPACITY);
+
+ DicNode *const dicNode = dicNodePool.getInstance();
+ EXPECT_NE(nullptr, dicNode);
+ EXPECT_EQ(nullptr, dicNodePool.getInstance());
+ dicNodePool.placeBackInstance(dicNode);
+ EXPECT_EQ(dicNode, dicNodePool.getInstance());
+}
+
+TEST(DicNodePoolTest, TestReset) {
+ static const int CAPACITY_SMALL = 2;
+ static const int CAPACITY_LARGE = 10;
+ DicNodePool dicNodePool(CAPACITY_SMALL);
+
+ for (int i = 0; i < CAPACITY_SMALL; ++i) {
+ EXPECT_NE(nullptr, dicNodePool.getInstance());
+ }
+ EXPECT_EQ(nullptr, dicNodePool.getInstance());
+
+ dicNodePool.reset(CAPACITY_LARGE);
+ for (int i = 0; i < CAPACITY_LARGE; ++i) {
+ EXPECT_NE(nullptr, dicNodePool.getInstance());
+ }
+ EXPECT_EQ(nullptr, dicNodePool.getInstance());
+
+ dicNodePool.reset(CAPACITY_SMALL);
+ for (int i = 0; i < CAPACITY_SMALL; ++i) {
+ EXPECT_NE(nullptr, dicNodePool.getInstance());
+ }
+ EXPECT_EQ(nullptr, dicNodePool.getInstance());
+}
+
+} // namespace
+} // namespace latinime
diff --git a/native/jni/tests/suggest/core/layout/geometry_utils_test.cpp b/native/jni/tests/suggest/core/layout/geometry_utils_test.cpp
new file mode 100644
index 000000000..f5f89ede1
--- /dev/null
+++ b/native/jni/tests/suggest/core/layout/geometry_utils_test.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#include "suggest/core/layout/geometry_utils.h"
+
+#include <gtest/gtest.h>
+
+namespace latinime {
+namespace {
+
+::testing::AssertionResult ExpectAngleDiffEq(const char* expectedExpression,
+ const char* actualExpression, float expected, float actual) {
+ if (actual < 0.0f || M_PI_F < actual) {
+ return ::testing::AssertionFailure()
+ << "Must be in the range of [0.0f, M_PI_F]."
+ << " expected: " << expected
+ << " actual: " << actual;
+ }
+ return ::testing::internal::CmpHelperFloatingPointEQ<float>(
+ expectedExpression, actualExpression, expected, actual);
+}
+
+#define EXPECT_ANGLE_DIFF_EQ(expected, actual) \
+ EXPECT_PRED_FORMAT2(ExpectAngleDiffEq, expected, actual);
+
+TEST(GeometryUtilsTest, testSquareFloat) {
+ const float test_data[] = { 0.0f, 1.0f, 123.456f, -1.0f, -9876.54321f };
+ for (const float value : test_data) {
+ EXPECT_FLOAT_EQ(value * value, GeometryUtils::SQUARE_FLOAT(value));
+ }
+}
+
+TEST(GeometryUtilsTest, testGetAngle) {
+ EXPECT_FLOAT_EQ(0.0f, GeometryUtils::getAngle(0, 0, 0, 0));
+ EXPECT_FLOAT_EQ(0.0f, GeometryUtils::getAngle(100, -10, 100, -10));
+
+ EXPECT_FLOAT_EQ(M_PI_F / 4.0f, GeometryUtils::getAngle(1, 1, 0, 0));
+ EXPECT_FLOAT_EQ(M_PI_F, GeometryUtils::getAngle(-1, 0, 0, 0));
+
+ EXPECT_FLOAT_EQ(GeometryUtils::getAngle(0, 0, -1, 0), GeometryUtils::getAngle(1, 0, 0, 0));
+ EXPECT_FLOAT_EQ(GeometryUtils::getAngle(1, 2, 3, 4),
+ GeometryUtils::getAngle(100, 200, 300, 400));
+}
+
+TEST(GeometryUtilsTest, testGetAngleDiff) {
+ EXPECT_ANGLE_DIFF_EQ(0.0f, GeometryUtils::getAngleDiff(0.0f, 0.0f));
+ EXPECT_ANGLE_DIFF_EQ(0.0f, GeometryUtils::getAngleDiff(10000.0f, 10000.0f));
+ EXPECT_ANGLE_DIFF_EQ(ROUND_FLOAT_10000(M_PI_F),
+ GeometryUtils::getAngleDiff(0.0f, M_PI_F));
+ EXPECT_ANGLE_DIFF_EQ(ROUND_FLOAT_10000(M_PI_F / 6.0f),
+ GeometryUtils::getAngleDiff(M_PI_F / 3.0f, M_PI_F / 2.0f));
+ EXPECT_ANGLE_DIFF_EQ(ROUND_FLOAT_10000(M_PI_F / 2.0f),
+ GeometryUtils::getAngleDiff(0.0f, M_PI_F * 1.5f));
+ EXPECT_ANGLE_DIFF_EQ(0.0f, GeometryUtils::getAngleDiff(0.0f, M_PI_F * 1024.0f));
+ EXPECT_ANGLE_DIFF_EQ(0.0f, GeometryUtils::getAngleDiff(-M_PI_F, M_PI_F));
+}
+
+TEST(GeometryUtilsTest, testGetDistanceInt) {
+ EXPECT_EQ(0, GeometryUtils::getDistanceInt(0, 0, 0, 0));
+ EXPECT_EQ(0, GeometryUtils::getAngle(100, -10, 100, -10));
+
+ EXPECT_EQ(5, GeometryUtils::getDistanceInt(0, 0, 5, 0));
+ EXPECT_EQ(5, GeometryUtils::getDistanceInt(0, 0, 3, 4));
+ EXPECT_EQ(5, GeometryUtils::getDistanceInt(0, -4, 3, 0));
+ EXPECT_EQ(5, GeometryUtils::getDistanceInt(0, 0, -3, -4));
+ EXPECT_EQ(500, GeometryUtils::getDistanceInt(0, 0, 300, -400));
+}
+
+} // namespace
+} // namespace latinime
diff --git a/native/jni/tests/suggest/policyimpl/dictionary/header/header_read_write_utils_test.cpp b/native/jni/tests/suggest/policyimpl/dictionary/header/header_read_write_utils_test.cpp
new file mode 100644
index 000000000..da6a2af27
--- /dev/null
+++ b/native/jni/tests/suggest/policyimpl/dictionary/header/header_read_write_utils_test.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#include "suggest/policyimpl/dictionary/header/header_read_write_utils.h"
+
+#include <gtest/gtest.h>
+
+#include <cstring>
+#include <vector>
+
+#include "suggest/core/policy/dictionary_header_structure_policy.h"
+
+namespace latinime {
+namespace {
+
+TEST(HeaderReadWriteUtilsTest, TestInsertCharactersIntoVector) {
+ DictionaryHeaderStructurePolicy::AttributeMap::key_type vector;
+
+ HeaderReadWriteUtils::insertCharactersIntoVector("", &vector);
+ EXPECT_TRUE(vector.empty());
+
+ static const char *str = "abc-xyz!?";
+ HeaderReadWriteUtils::insertCharactersIntoVector(str, &vector);
+ EXPECT_EQ(strlen(str) , vector.size());
+ for (size_t i = 0; i < vector.size(); ++i) {
+ EXPECT_EQ(str[i], vector[i]);
+ }
+}
+
+TEST(HeaderReadWriteUtilsTest, TestAttributeMapForInt) {
+ DictionaryHeaderStructurePolicy::AttributeMap attributeMap;
+
+ // Returns default value if not exists.
+ EXPECT_EQ(-1, HeaderReadWriteUtils::readIntAttributeValue(&attributeMap, "", -1));
+ EXPECT_EQ(100, HeaderReadWriteUtils::readIntAttributeValue(&attributeMap, "abc", 100));
+
+ HeaderReadWriteUtils::setIntAttribute(&attributeMap, "abc", 10);
+ EXPECT_EQ(10, HeaderReadWriteUtils::readIntAttributeValue(&attributeMap, "abc", 100));
+ HeaderReadWriteUtils::setIntAttribute(&attributeMap, "abc", 20);
+ EXPECT_EQ(20, HeaderReadWriteUtils::readIntAttributeValue(&attributeMap, "abc", 100));
+ HeaderReadWriteUtils::setIntAttribute(&attributeMap, "abcd", 30);
+ EXPECT_EQ(30, HeaderReadWriteUtils::readIntAttributeValue(&attributeMap, "abcd", 100));
+ EXPECT_EQ(20, HeaderReadWriteUtils::readIntAttributeValue(&attributeMap, "abc", 100));
+}
+
+TEST(HeaderReadWriteUtilsTest, TestAttributeMapCodeForPoints) {
+ DictionaryHeaderStructurePolicy::AttributeMap attributeMap;
+
+ // Returns empty vector if not exists.
+ EXPECT_TRUE(HeaderReadWriteUtils::readCodePointVectorAttributeValue(&attributeMap, "").empty());
+ EXPECT_TRUE(HeaderReadWriteUtils::readCodePointVectorAttributeValue(
+ &attributeMap, "abc").empty());
+
+ HeaderReadWriteUtils::setCodePointVectorAttribute(&attributeMap, "abc", {});
+ EXPECT_TRUE(HeaderReadWriteUtils::readCodePointVectorAttributeValue(
+ &attributeMap, "abc").empty());
+
+ const std::vector<int> codePoints = { 0x0, 0x20, 0x1F, 0x100000 };
+ HeaderReadWriteUtils::setCodePointVectorAttribute(&attributeMap, "abc", codePoints);
+ EXPECT_EQ(codePoints, HeaderReadWriteUtils::readCodePointVectorAttributeValue(
+ &attributeMap, "abc"));
+}
+
+} // namespace
+} // namespace latinime
diff --git a/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content_test.cpp b/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content_test.cpp
index 6eef2040b..06f82df52 100644
--- a/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content_test.cpp
+++ b/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content_test.cpp
@@ -18,27 +18,37 @@
#include <gtest/gtest.h>
+#include <array>
+#include <unordered_set>
+
#include "utils/int_array_view.h"
namespace latinime {
namespace {
TEST(LanguageModelDictContentTest, TestUnigramProbability) {
- LanguageModelDictContent LanguageModelDictContent(false /* useHistoricalInfo */);
+ LanguageModelDictContent languageModelDictContent(false /* useHistoricalInfo */);
- const int flag = 0xFF;
+ const int flag = 0xF0;
const int probability = 10;
const int wordId = 100;
const ProbabilityEntry probabilityEntry(flag, probability);
- LanguageModelDictContent.setProbabilityEntry(wordId, &probabilityEntry);
+ languageModelDictContent.setProbabilityEntry(wordId, &probabilityEntry);
const ProbabilityEntry entry =
- LanguageModelDictContent.getProbabilityEntry(wordId);
+ languageModelDictContent.getProbabilityEntry(wordId);
EXPECT_EQ(flag, entry.getFlags());
EXPECT_EQ(probability, entry.getProbability());
+
+ // Remove
+ EXPECT_TRUE(languageModelDictContent.removeProbabilityEntry(wordId));
+ EXPECT_FALSE(languageModelDictContent.getProbabilityEntry(wordId).isValid());
+ EXPECT_FALSE(languageModelDictContent.removeProbabilityEntry(wordId));
+ EXPECT_TRUE(languageModelDictContent.setProbabilityEntry(wordId, &probabilityEntry));
+ EXPECT_TRUE(languageModelDictContent.getProbabilityEntry(wordId).isValid());
}
TEST(LanguageModelDictContentTest, TestUnigramProbabilityWithHistoricalInfo) {
- LanguageModelDictContent LanguageModelDictContent(true /* useHistoricalInfo */);
+ LanguageModelDictContent languageModelDictContent(true /* useHistoricalInfo */);
const int flag = 0xF0;
const int timestamp = 0x3FFFFFFF;
@@ -46,13 +56,66 @@ TEST(LanguageModelDictContentTest, TestUnigramProbabilityWithHistoricalInfo) {
const int count = 10;
const int wordId = 100;
const HistoricalInfo historicalInfo(timestamp, level, count);
- const ProbabilityEntry probabilityEntry(flag, NOT_A_PROBABILITY, &historicalInfo);
- LanguageModelDictContent.setProbabilityEntry(wordId, &probabilityEntry);
- const ProbabilityEntry entry = LanguageModelDictContent.getProbabilityEntry(wordId);
+ const ProbabilityEntry probabilityEntry(flag, &historicalInfo);
+ languageModelDictContent.setProbabilityEntry(wordId, &probabilityEntry);
+ const ProbabilityEntry entry = languageModelDictContent.getProbabilityEntry(wordId);
EXPECT_EQ(flag, entry.getFlags());
EXPECT_EQ(timestamp, entry.getHistoricalInfo()->getTimeStamp());
EXPECT_EQ(level, entry.getHistoricalInfo()->getLevel());
EXPECT_EQ(count, entry.getHistoricalInfo()->getCount());
+
+ // Remove
+ EXPECT_TRUE(languageModelDictContent.removeProbabilityEntry(wordId));
+ EXPECT_FALSE(languageModelDictContent.getProbabilityEntry(wordId).isValid());
+ EXPECT_FALSE(languageModelDictContent.removeProbabilityEntry(wordId));
+ EXPECT_TRUE(languageModelDictContent.setProbabilityEntry(wordId, &probabilityEntry));
+ EXPECT_TRUE(languageModelDictContent.removeProbabilityEntry(wordId));
+}
+
+TEST(LanguageModelDictContentTest, TestIterateProbabilityEntry) {
+ LanguageModelDictContent languageModelDictContent(false /* useHistoricalInfo */);
+
+ const ProbabilityEntry originalEntry(0xFC, 100);
+
+ const int wordIds[] = { 1, 2, 3, 4, 5 };
+ for (const int wordId : wordIds) {
+ languageModelDictContent.setProbabilityEntry(wordId, &originalEntry);
+ }
+ std::unordered_set<int> wordIdSet(std::begin(wordIds), std::end(wordIds));
+ for (const auto entry : languageModelDictContent.getProbabilityEntries(WordIdArrayView())) {
+ EXPECT_EQ(originalEntry.getFlags(), entry.getProbabilityEntry().getFlags());
+ EXPECT_EQ(originalEntry.getProbability(), entry.getProbabilityEntry().getProbability());
+ wordIdSet.erase(entry.getWordId());
+ }
+ EXPECT_TRUE(wordIdSet.empty());
+}
+
+TEST(LanguageModelDictContentTest, TestGetWordProbability) {
+ LanguageModelDictContent languageModelDictContent(false /* useHistoricalInfo */);
+
+ const int flag = 0xFF;
+ const int probability = 10;
+ const int bigramProbability = 20;
+ const int trigramProbability = 30;
+ const int wordId = 100;
+ const std::array<int, 2> prevWordIdArray = {{ 1, 2 }};
+ const WordIdArrayView prevWordIds = WordIdArrayView::fromArray(prevWordIdArray);
+
+ const ProbabilityEntry probabilityEntry(flag, probability);
+ languageModelDictContent.setProbabilityEntry(wordId, &probabilityEntry);
+ const ProbabilityEntry bigramProbabilityEntry(flag, bigramProbability);
+ languageModelDictContent.setProbabilityEntry(prevWordIds[0], &probabilityEntry);
+ languageModelDictContent.setNgramProbabilityEntry(prevWordIds.limit(1), wordId,
+ &bigramProbabilityEntry);
+ EXPECT_EQ(bigramProbability, languageModelDictContent.getWordProbability(prevWordIds, wordId,
+ nullptr /* headerPolicy */));
+ const ProbabilityEntry trigramProbabilityEntry(flag, trigramProbability);
+ languageModelDictContent.setNgramProbabilityEntry(prevWordIds.limit(1),
+ prevWordIds[1], &probabilityEntry);
+ languageModelDictContent.setNgramProbabilityEntry(prevWordIds.limit(2), wordId,
+ &trigramProbabilityEntry);
+ EXPECT_EQ(trigramProbability, languageModelDictContent.getWordProbability(prevWordIds, wordId,
+ nullptr /* headerPolicy */));
}
} // namespace
diff --git a/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/probability_entry_test.cpp b/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/probability_entry_test.cpp
index db94550ef..f0494f355 100644
--- a/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/probability_entry_test.cpp
+++ b/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/probability_entry_test.cpp
@@ -43,7 +43,7 @@ TEST(ProbabilityEntryTest, TestEncodeDecodeWithHistoricalInfo) {
const int count = 10;
const HistoricalInfo historicalInfo(timestamp, level, count);
- const ProbabilityEntry entry(flag, NOT_A_PROBABILITY, &historicalInfo);
+ const ProbabilityEntry entry(flag, &historicalInfo);
const uint64_t encodedEntry = entry.encode(true /* hasHistoricalInfo */);
EXPECT_EQ(0xF03FFFFFFF030Aull, encodedEntry);
diff --git a/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table_test.cpp b/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table_test.cpp
new file mode 100644
index 000000000..23b9c55f7
--- /dev/null
+++ b/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table_test.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#include "suggest/policyimpl/dictionary/structure/v4/content/terminal_position_lookup_table.h"
+
+#include <gtest/gtest.h>
+
+#include <vector>
+
+#include "defines.h"
+#include "suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h"
+
+namespace latinime {
+namespace {
+
+TEST(TerminalPositionLookupTableTest, TestGetFromEmptyTable) {
+ TerminalPositionLookupTable lookupTable;
+
+ EXPECT_EQ(NOT_A_DICT_POS, lookupTable.getTerminalPtNodePosition(0));
+ EXPECT_EQ(NOT_A_DICT_POS, lookupTable.getTerminalPtNodePosition(-1));
+ EXPECT_EQ(NOT_A_DICT_POS, lookupTable.getTerminalPtNodePosition(
+ Ver4DictConstants::NOT_A_TERMINAL_ID));
+}
+
+TEST(TerminalPositionLookupTableTest, TestSetAndGet) {
+ TerminalPositionLookupTable lookupTable;
+
+ EXPECT_TRUE(lookupTable.setTerminalPtNodePosition(10, 100));
+ EXPECT_EQ(100, lookupTable.getTerminalPtNodePosition(10));
+ EXPECT_EQ(NOT_A_DICT_POS, lookupTable.getTerminalPtNodePosition(9));
+ EXPECT_TRUE(lookupTable.setTerminalPtNodePosition(9, 200));
+ EXPECT_EQ(200, lookupTable.getTerminalPtNodePosition(9));
+ EXPECT_TRUE(lookupTable.setTerminalPtNodePosition(10, 300));
+ EXPECT_EQ(300, lookupTable.getTerminalPtNodePosition(10));
+ EXPECT_FALSE(lookupTable.setTerminalPtNodePosition(-1, 400));
+ EXPECT_EQ(NOT_A_DICT_POS, lookupTable.getTerminalPtNodePosition(-1));
+ EXPECT_FALSE(lookupTable.setTerminalPtNodePosition(Ver4DictConstants::NOT_A_TERMINAL_ID, 500));
+ EXPECT_EQ(NOT_A_DICT_POS, lookupTable.getTerminalPtNodePosition(
+ Ver4DictConstants::NOT_A_TERMINAL_ID));
+}
+
+TEST(TerminalPositionLookupTableTest, TestGC) {
+ TerminalPositionLookupTable lookupTable;
+
+ const std::vector<int> terminalIds = { 10, 20, 30 };
+ const std::vector<int> terminalPositions = { 100, 200, 300 };
+
+ for (size_t i = 0; i < terminalIds.size(); ++i) {
+ EXPECT_TRUE(lookupTable.setTerminalPtNodePosition(terminalIds[i], terminalPositions[i]));
+ }
+
+ TerminalPositionLookupTable::TerminalIdMap terminalIdMap;
+ EXPECT_TRUE(lookupTable.runGCTerminalIds(&terminalIdMap));
+
+ for (size_t i = 0; i < terminalIds.size(); ++i) {
+ EXPECT_EQ(static_cast<int>(i), terminalIdMap[terminalIds[i]])
+ << "Terminal id (" << terminalIds[i] << ") should be changed to " << i;
+ EXPECT_EQ(terminalPositions[i], lookupTable.getTerminalPtNodePosition(i));
+ }
+}
+
+} // namespace
+} // namespace latinime
diff --git a/native/jni/tests/suggest/policyimpl/dictionary/utils/byte_array_utils_test.cpp b/native/jni/tests/suggest/policyimpl/dictionary/utils/byte_array_utils_test.cpp
new file mode 100644
index 000000000..a1c310d8a
--- /dev/null
+++ b/native/jni/tests/suggest/policyimpl/dictionary/utils/byte_array_utils_test.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#include "suggest/policyimpl/dictionary/utils/byte_array_utils.h"
+
+#include <gtest/gtest.h>
+
+#include <cstdint>
+
+namespace latinime {
+namespace {
+
+TEST(ByteArrayUtilsTest, TestReadInt) {
+ const uint8_t buffer[] = { 0x1u, 0x8Au, 0x0u, 0xAAu };
+
+ EXPECT_EQ(0x01u, ByteArrayUtils::readUint8(buffer, 0));
+ EXPECT_EQ(0x8Au, ByteArrayUtils::readUint8(buffer, 1));
+ EXPECT_EQ(0x0u, ByteArrayUtils::readUint8(buffer, 2));
+ EXPECT_EQ(0xAAu, ByteArrayUtils::readUint8(buffer, 3));
+
+ EXPECT_EQ(0x018Au, ByteArrayUtils::readUint16(buffer, 0));
+ EXPECT_EQ(0x8A00u, ByteArrayUtils::readUint16(buffer, 1));
+ EXPECT_EQ(0xAAu, ByteArrayUtils::readUint16(buffer, 2));
+
+ EXPECT_EQ(0x18A00AAu, ByteArrayUtils::readUint32(buffer, 0));
+
+ int pos = 0;
+ EXPECT_EQ(0x18A00, ByteArrayUtils::readSint24AndAdvancePosition(buffer, &pos));
+ pos = 1;
+ EXPECT_EQ(-0xA00AA, ByteArrayUtils::readSint24AndAdvancePosition(buffer, &pos));
+}
+
+TEST(ByteArrayUtilsTest, TestWriteAndReadInt) {
+ uint8_t buffer[4];
+
+ int pos = 0;
+ const uint8_t data_1B = 0xC8;
+ ByteArrayUtils::writeUintAndAdvancePosition(buffer, data_1B, 1, &pos);
+ EXPECT_EQ(data_1B, ByteArrayUtils::readUint(buffer, 1, 0));
+
+ pos = 0;
+ const uint32_t data_4B = 0xABCD1234;
+ ByteArrayUtils::writeUintAndAdvancePosition(buffer, data_4B, 4, &pos);
+ EXPECT_EQ(data_4B, ByteArrayUtils::readUint(buffer, 4, 0));
+}
+
+TEST(ByteArrayUtilsTest, TestReadCodePoint) {
+ const uint8_t buffer[] = { 0x10, 0xFF, 0x00u, 0x20u, 0x41u, 0x1Fu, 0x60 };
+
+ EXPECT_EQ(0x10FF00, ByteArrayUtils::readCodePoint(buffer, 0));
+ EXPECT_EQ(0x20, ByteArrayUtils::readCodePoint(buffer, 3));
+ EXPECT_EQ(0x41, ByteArrayUtils::readCodePoint(buffer, 4));
+ EXPECT_EQ(NOT_A_CODE_POINT, ByteArrayUtils::readCodePoint(buffer, 5));
+
+ int pos = 0;
+ int codePointArray[3];
+ EXPECT_EQ(3, ByteArrayUtils::readStringAndAdvancePosition(buffer, MAX_WORD_LENGTH,
+ codePointArray, &pos));
+ EXPECT_EQ(0x10FF00, codePointArray[0]);
+ EXPECT_EQ(0x20, codePointArray[1]);
+ EXPECT_EQ(0x41, codePointArray[2]);
+ EXPECT_EQ(0x60, ByteArrayUtils::readCodePoint(buffer, pos));
+}
+
+TEST(ByteArrayUtilsTest, TestWriteAndReadCodePoint) {
+ uint8_t buffer[10];
+
+ const int codePointArray[] = { 0x10FF00, 0x20, 0x41 };
+ int pos = 0;
+ ByteArrayUtils::writeCodePointsAndAdvancePosition(buffer, codePointArray, 3,
+ true /* writesTerminator */, &pos);
+ EXPECT_EQ(0x10FF00, ByteArrayUtils::readCodePoint(buffer, 0));
+ EXPECT_EQ(0x20, ByteArrayUtils::readCodePoint(buffer, 3));
+ EXPECT_EQ(0x41, ByteArrayUtils::readCodePoint(buffer, 4));
+ EXPECT_EQ(NOT_A_CODE_POINT, ByteArrayUtils::readCodePoint(buffer, 5));
+}
+
+} // namespace
+} // namespace latinime
diff --git a/native/jni/tests/suggest/policyimpl/dictionary/utils/format_utils_test.cpp b/native/jni/tests/suggest/policyimpl/dictionary/utils/format_utils_test.cpp
new file mode 100644
index 000000000..15f560cd1
--- /dev/null
+++ b/native/jni/tests/suggest/policyimpl/dictionary/utils/format_utils_test.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#include "suggest/policyimpl/dictionary/utils/format_utils.h"
+
+#include <gtest/gtest.h>
+
+#include <vector>
+
+#include "utils/byte_array_view.h"
+
+namespace latinime {
+namespace {
+
+TEST(FormatUtilsTest, TestMagicNumber) {
+ EXPECT_EQ(0x9BC13AFE, FormatUtils::MAGIC_NUMBER) << "Magic number must not be changed.";
+}
+
+const std::vector<uint8_t> getBuffer(const int magicNumber, const int version, const uint16_t flags,
+ const size_t headerSize) {
+ std::vector<uint8_t> buffer;
+ buffer.push_back(magicNumber >> 24);
+ buffer.push_back(magicNumber >> 16);
+ buffer.push_back(magicNumber >> 8);
+ buffer.push_back(magicNumber);
+
+ buffer.push_back(version >> 8);
+ buffer.push_back(version);
+
+ buffer.push_back(flags >> 8);
+ buffer.push_back(flags);
+
+ buffer.push_back(headerSize >> 24);
+ buffer.push_back(headerSize >> 16);
+ buffer.push_back(headerSize >> 8);
+ buffer.push_back(headerSize);
+ return buffer;
+}
+
+TEST(FormatUtilsTest, TestDetectFormatVersion) {
+ EXPECT_EQ(FormatUtils::UNKNOWN_VERSION,
+ FormatUtils::detectFormatVersion(ReadOnlyByteArrayView()));
+
+ {
+ const std::vector<uint8_t> buffer =
+ getBuffer(FormatUtils::MAGIC_NUMBER, FormatUtils::VERSION_2, 0, 0);
+ EXPECT_EQ(FormatUtils::VERSION_2, FormatUtils::detectFormatVersion(
+ ReadOnlyByteArrayView(buffer.data(), buffer.size())));
+ }
+ {
+ const std::vector<uint8_t> buffer =
+ getBuffer(FormatUtils::MAGIC_NUMBER, FormatUtils::VERSION_4, 0, 0);
+ EXPECT_EQ(FormatUtils::VERSION_4, FormatUtils::detectFormatVersion(
+ ReadOnlyByteArrayView(buffer.data(), buffer.size())));
+ }
+ {
+ const std::vector<uint8_t> buffer =
+ getBuffer(FormatUtils::MAGIC_NUMBER, FormatUtils::VERSION_4_DEV, 0, 0);
+ EXPECT_EQ(FormatUtils::VERSION_4_DEV, FormatUtils::detectFormatVersion(
+ ReadOnlyByteArrayView(buffer.data(), buffer.size())));
+ }
+
+ {
+ const std::vector<uint8_t> buffer =
+ getBuffer(FormatUtils::MAGIC_NUMBER - 1, FormatUtils::VERSION_2, 0, 0);
+ EXPECT_EQ(FormatUtils::UNKNOWN_VERSION, FormatUtils::detectFormatVersion(
+ ReadOnlyByteArrayView(buffer.data(), buffer.size())));
+ }
+ {
+ const std::vector<uint8_t> buffer =
+ getBuffer(FormatUtils::MAGIC_NUMBER, 100, 0, 0);
+ EXPECT_EQ(FormatUtils::UNKNOWN_VERSION, FormatUtils::detectFormatVersion(
+ ReadOnlyByteArrayView(buffer.data(), buffer.size())));
+ }
+ {
+ const std::vector<uint8_t> buffer =
+ getBuffer(FormatUtils::MAGIC_NUMBER, FormatUtils::VERSION_2, 0, 0);
+ EXPECT_EQ(FormatUtils::UNKNOWN_VERSION, FormatUtils::detectFormatVersion(
+ ReadOnlyByteArrayView(buffer.data(), buffer.size() - 1)));
+ }
+}
+
+} // namespace
+} // namespace latinime
diff --git a/native/jni/tests/suggest/policyimpl/dictionary/utils/sparse_table_test.cpp b/native/jni/tests/suggest/policyimpl/dictionary/utils/sparse_table_test.cpp
new file mode 100644
index 000000000..0b57156a0
--- /dev/null
+++ b/native/jni/tests/suggest/policyimpl/dictionary/utils/sparse_table_test.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#include "suggest/policyimpl/dictionary/utils/sparse_table.h"
+
+#include <gtest/gtest.h>
+
+#include "suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h"
+
+namespace latinime {
+namespace {
+
+TEST(SparseTableTest, TestSetAndGet) {
+ static const int BLOCK_SIZE = 64;
+ static const int DATA_SIZE = 4;
+ BufferWithExtendableBuffer indexTableBuffer(
+ BufferWithExtendableBuffer::DEFAULT_MAX_ADDITIONAL_BUFFER_SIZE);
+ BufferWithExtendableBuffer contentTableBuffer(
+ BufferWithExtendableBuffer::DEFAULT_MAX_ADDITIONAL_BUFFER_SIZE);
+ SparseTable sparseTable(&indexTableBuffer, &contentTableBuffer, BLOCK_SIZE, DATA_SIZE);
+
+ EXPECT_FALSE(sparseTable.contains(10));
+ EXPECT_TRUE(sparseTable.set(10, 100u));
+ EXPECT_EQ(100u, sparseTable.get(10));
+ EXPECT_TRUE(sparseTable.contains(10));
+ EXPECT_TRUE(sparseTable.contains(BLOCK_SIZE - 1));
+ EXPECT_FALSE(sparseTable.contains(BLOCK_SIZE));
+ EXPECT_TRUE(sparseTable.set(11, 101u));
+ EXPECT_EQ(100u, sparseTable.get(10));
+ EXPECT_EQ(101u, sparseTable.get(11));
+}
+
+} // namespace
+} // namespace latinime
diff --git a/native/jni/tests/suggest/policyimpl/dictionary/utils/trie_map_test.cpp b/native/jni/tests/suggest/policyimpl/dictionary/utils/trie_map_test.cpp
index df778b6cf..56b5aa985 100644
--- a/native/jni/tests/suggest/policyimpl/dictionary/utils/trie_map_test.cpp
+++ b/native/jni/tests/suggest/policyimpl/dictionary/utils/trie_map_test.cpp
@@ -40,6 +40,7 @@ TEST(TrieMapTest, TestSetAndGet) {
trieMap.putRoot(11, 1000);
EXPECT_EQ(1000ull, trieMap.getRoot(11).mValue);
const int next = trieMap.getNextLevelBitmapEntryIndex(10);
+ EXPECT_EQ(1000ull, trieMap.getRoot(10).mValue);
trieMap.put(9, 9, next);
EXPECT_EQ(9ull, trieMap.get(9, next).mValue);
EXPECT_FALSE(trieMap.get(11, next).mIsValid);
@@ -47,6 +48,33 @@ TEST(TrieMapTest, TestSetAndGet) {
EXPECT_EQ(0xFFFFFFFFFull, trieMap.getRoot(0).mValue);
}
+TEST(TrieMapTest, TestRemove) {
+ TrieMap trieMap;
+ trieMap.putRoot(10, 10);
+ EXPECT_EQ(10ull, trieMap.getRoot(10).mValue);
+ EXPECT_TRUE(trieMap.remove(10, trieMap.getRootBitmapEntryIndex()));
+ EXPECT_FALSE(trieMap.getRoot(10).mIsValid);
+ for (const auto &element : trieMap.getEntriesInRootLevel()) {
+ EXPECT_TRUE(false);
+ }
+ EXPECT_TRUE(trieMap.putRoot(10, 0x3FFFFF));
+ EXPECT_FALSE(trieMap.remove(11, trieMap.getRootBitmapEntryIndex()))
+ << "Should fail if the key does not exist.";
+ EXPECT_EQ(0x3FFFFFull, trieMap.getRoot(10).mValue);
+ trieMap.putRoot(12, 11);
+ const int nextLevel = trieMap.getNextLevelBitmapEntryIndex(10);
+ trieMap.put(10, 10, nextLevel);
+ EXPECT_EQ(0x3FFFFFull, trieMap.getRoot(10).mValue);
+ EXPECT_EQ(10ull, trieMap.get(10, nextLevel).mValue);
+ EXPECT_TRUE(trieMap.remove(10, trieMap.getRootBitmapEntryIndex()));
+ const TrieMap::Result result = trieMap.getRoot(10);
+ EXPECT_FALSE(result.mIsValid);
+ EXPECT_EQ(TrieMap::INVALID_INDEX, result.mNextLevelBitmapEntryIndex);
+ EXPECT_EQ(11ull, trieMap.getRoot(12).mValue);
+ EXPECT_TRUE(trieMap.putRoot(S_INT_MAX, 0xFFFFFFFFFull));
+ EXPECT_TRUE(trieMap.remove(S_INT_MAX, trieMap.getRootBitmapEntryIndex()));
+}
+
TEST(TrieMapTest, TestSetAndGetLarge) {
static const int ELEMENT_COUNT = 200000;
TrieMap trieMap;
diff --git a/native/jni/tests/suggest/policyimpl/utils/damerau_levenshtein_edit_distance_policy_test.cpp b/native/jni/tests/suggest/policyimpl/utils/damerau_levenshtein_edit_distance_policy_test.cpp
new file mode 100644
index 000000000..d13417964
--- /dev/null
+++ b/native/jni/tests/suggest/policyimpl/utils/damerau_levenshtein_edit_distance_policy_test.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#include "suggest/policyimpl/utils/damerau_levenshtein_edit_distance_policy.h"
+
+#include <gtest/gtest.h>
+
+#include <vector>
+
+#include "suggest/policyimpl/utils/edit_distance.h"
+#include "utils/int_array_view.h"
+
+namespace latinime {
+namespace {
+
+TEST(DamerauLevenshteinEditDistancePolicyTest, TestConstructPolicy) {
+ const std::vector<int> codePoints0 = { 0x20, 0x40, 0x60 };
+ const std::vector<int> codePoints1 = { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60 };
+ DamerauLevenshteinEditDistancePolicy policy(codePoints0.data(), codePoints0.size(),
+ codePoints1.data(), codePoints1.size());
+
+ EXPECT_EQ(static_cast<int>(codePoints0.size()), policy.getString0Length());
+ EXPECT_EQ(static_cast<int>(codePoints1.size()), policy.getString1Length());
+}
+
+float getEditDistance(const std::vector<int> &codePoints0, const std::vector<int> &codePoints1) {
+ DamerauLevenshteinEditDistancePolicy policy(codePoints0.data(), codePoints0.size(),
+ codePoints1.data(), codePoints1.size());
+ return EditDistance::getEditDistance(&policy);
+}
+
+TEST(DamerauLevenshteinEditDistancePolicyTest, TestEditDistance) {
+ EXPECT_FLOAT_EQ(0.0f, getEditDistance({}, {}));
+ EXPECT_FLOAT_EQ(0.0f, getEditDistance({ 1 }, { 1 }));
+ EXPECT_FLOAT_EQ(0.0f, getEditDistance({ 1, 2, 3 }, { 1, 2, 3 }));
+
+ EXPECT_FLOAT_EQ(1.0f, getEditDistance({ 1 }, { }));
+ EXPECT_FLOAT_EQ(1.0f, getEditDistance({}, { 100 }));
+ EXPECT_FLOAT_EQ(5.0f, getEditDistance({}, { 1, 2, 3, 4, 5 }));
+
+ EXPECT_FLOAT_EQ(1.0f, getEditDistance({ 0 }, { 100 }));
+ EXPECT_FLOAT_EQ(5.0f, getEditDistance({ 1, 2, 3, 4, 5 }, { 11, 12, 13, 14, 15 }));
+
+ EXPECT_FLOAT_EQ(1.0f, getEditDistance({ 1 }, { 1, 2 }));
+ EXPECT_FLOAT_EQ(2.0f, getEditDistance({ 1, 2 }, { 0, 1, 2, 3 }));
+ EXPECT_FLOAT_EQ(2.0f, getEditDistance({ 0, 1, 2, 3 }, { 1, 2 }));
+
+ EXPECT_FLOAT_EQ(1.0f, getEditDistance({ 1, 2 }, { 2, 1 }));
+ EXPECT_FLOAT_EQ(2.0f, getEditDistance({ 1, 2, 3, 4 }, { 2, 1, 4, 3 }));
+}
+} // namespace
+} // namespace latinime
diff --git a/native/jni/tests/utils/char_utils_test.cpp b/native/jni/tests/utils/char_utils_test.cpp
new file mode 100644
index 000000000..01d534043
--- /dev/null
+++ b/native/jni/tests/utils/char_utils_test.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#include "utils/char_utils.h"
+
+#include <gtest/gtest.h>
+
+#include "defines.h"
+
+namespace latinime {
+namespace {
+
+TEST(CharUtilsTest, TestIsAsciiUpper) {
+ EXPECT_TRUE(CharUtils::isAsciiUpper('A'));
+ EXPECT_TRUE(CharUtils::isAsciiUpper('Z'));
+ EXPECT_FALSE(CharUtils::isAsciiUpper('a'));
+ EXPECT_FALSE(CharUtils::isAsciiUpper('z'));
+ EXPECT_FALSE(CharUtils::isAsciiUpper('@'));
+ EXPECT_FALSE(CharUtils::isAsciiUpper(' '));
+ EXPECT_FALSE(CharUtils::isAsciiUpper(0x00C0 /* LATIN CAPITAL LETTER A WITH GRAVE */));
+ EXPECT_FALSE(CharUtils::isAsciiUpper(0x00E0 /* LATIN SMALL LETTER A WITH GRAVE */));
+ EXPECT_FALSE(CharUtils::isAsciiUpper(0x03C2 /* GREEK SMALL LETTER FINAL SIGMA */));
+ EXPECT_FALSE(CharUtils::isAsciiUpper(0x0410 /* CYRILLIC CAPITAL LETTER A */));
+ EXPECT_FALSE(CharUtils::isAsciiUpper(0x0430 /* CYRILLIC SMALL LETTER A */));
+ EXPECT_FALSE(CharUtils::isAsciiUpper(0x3042 /* HIRAGANA LETTER A */));
+ EXPECT_FALSE(CharUtils::isAsciiUpper(0x1F36A /* COOKIE */));
+}
+
+TEST(CharUtilsTest, TestToLowerCase) {
+ EXPECT_EQ('a', CharUtils::toLowerCase('A'));
+ EXPECT_EQ('z', CharUtils::toLowerCase('Z'));
+ EXPECT_EQ('a', CharUtils::toLowerCase('a'));
+ EXPECT_EQ('z', CharUtils::toLowerCase('z'));
+ EXPECT_EQ('@', CharUtils::toLowerCase('@'));
+ EXPECT_EQ(' ', CharUtils::toLowerCase(' '));
+ EXPECT_EQ(0x00E0 /* LATIN SMALL LETTER A WITH GRAVE */,
+ CharUtils::toLowerCase(0x00C0 /* LATIN CAPITAL LETTER A WITH GRAVE */));
+ EXPECT_EQ(0x00E0 /* LATIN SMALL LETTER A WITH GRAVE */,
+ CharUtils::toLowerCase(0x00E0 /* LATIN SMALL LETTER A WITH GRAVE */));
+ EXPECT_EQ(0x03C2 /* GREEK SMALL LETTER FINAL SIGMA */,
+ CharUtils::toLowerCase(0x03C2 /* GREEK SMALL LETTER FINAL SIGMA */));
+ EXPECT_EQ(0x0430 /* CYRILLIC SMALL LETTER A */,
+ CharUtils::toLowerCase(0x0410 /* CYRILLIC CAPITAL LETTER A */));
+ EXPECT_EQ(0x0430 /* CYRILLIC SMALL LETTER A */,
+ CharUtils::toLowerCase(0x0430 /* CYRILLIC SMALL LETTER A */));
+ EXPECT_EQ(0x3042 /* HIRAGANA LETTER A */,
+ CharUtils::toLowerCase(0x3042 /* HIRAGANA LETTER A */));
+ EXPECT_EQ(0x1F36A /* COOKIE */, CharUtils::toLowerCase(0x1F36A /* COOKIE */));
+}
+
+TEST(CharUtilsTest, TestToBaseLowerCase) {
+ EXPECT_EQ('a', CharUtils::toBaseLowerCase('A'));
+ EXPECT_EQ('z', CharUtils::toBaseLowerCase('Z'));
+ EXPECT_EQ('a', CharUtils::toBaseLowerCase('a'));
+ EXPECT_EQ('z', CharUtils::toBaseLowerCase('z'));
+ EXPECT_EQ('@', CharUtils::toBaseLowerCase('@'));
+ EXPECT_EQ(' ', CharUtils::toBaseLowerCase(' '));
+ EXPECT_EQ('a', CharUtils::toBaseLowerCase(0x00C0 /* LATIN CAPITAL LETTER A WITH GRAVE */));
+ EXPECT_EQ('a', CharUtils::toBaseLowerCase(0x00E0 /* LATIN SMALL LETTER A WITH GRAVE */));
+ EXPECT_EQ(0x03C2 /* GREEK SMALL LETTER FINAL SIGMA */,
+ CharUtils::toBaseLowerCase(0x03C2 /* GREEK SMALL LETTER FINAL SIGMA */));
+ EXPECT_EQ(0x0430 /* CYRILLIC SMALL LETTER A */,
+ CharUtils::toBaseLowerCase(0x0410 /* CYRILLIC CAPITAL LETTER A */));
+ EXPECT_EQ(0x0430 /* CYRILLIC SMALL LETTER A */,
+ CharUtils::toBaseLowerCase(0x0430 /* CYRILLIC SMALL LETTER A */));
+ EXPECT_EQ(0x3042 /* HIRAGANA LETTER A */,
+ CharUtils::toBaseLowerCase(0x3042 /* HIRAGANA LETTER A */));
+ EXPECT_EQ(0x1F36A /* COOKIE */, CharUtils::toBaseLowerCase(0x1F36A /* COOKIE */));
+}
+
+TEST(CharUtilsTest, TestToBaseCodePoint) {
+ EXPECT_EQ('A', CharUtils::toBaseCodePoint('A'));
+ EXPECT_EQ('Z', CharUtils::toBaseCodePoint('Z'));
+ EXPECT_EQ('a', CharUtils::toBaseCodePoint('a'));
+ EXPECT_EQ('z', CharUtils::toBaseCodePoint('z'));
+ EXPECT_EQ('@', CharUtils::toBaseCodePoint('@'));
+ EXPECT_EQ(' ', CharUtils::toBaseCodePoint(' '));
+ EXPECT_EQ('A', CharUtils::toBaseCodePoint(0x00C0 /* LATIN CAPITAL LETTER A WITH GRAVE */));
+ EXPECT_EQ('a', CharUtils::toBaseCodePoint(0x00E0 /* LATIN SMALL LETTER A WITH GRAVE */));
+ EXPECT_EQ(0x03C2 /* GREEK SMALL LETTER FINAL SIGMA */,
+ CharUtils::toBaseLowerCase(0x03C2 /* GREEK SMALL LETTER FINAL SIGMA */));
+ EXPECT_EQ(0x0410 /* CYRILLIC CAPITAL LETTER A */,
+ CharUtils::toBaseCodePoint(0x0410 /* CYRILLIC CAPITAL LETTER A */));
+ EXPECT_EQ(0x0430 /* CYRILLIC SMALL LETTER A */,
+ CharUtils::toBaseCodePoint(0x0430 /* CYRILLIC SMALL LETTER A */));
+ EXPECT_EQ(0x3042 /* HIRAGANA LETTER A */,
+ CharUtils::toBaseCodePoint(0x3042 /* HIRAGANA LETTER A */));
+ EXPECT_EQ(0x1F36A /* COOKIE */, CharUtils::toBaseCodePoint(0x1F36A /* COOKIE */));
+}
+
+TEST(CharUtilsTest, TestIsIntentionalOmissionCodePoint) {
+ EXPECT_TRUE(CharUtils::isIntentionalOmissionCodePoint('\''));
+ EXPECT_TRUE(CharUtils::isIntentionalOmissionCodePoint('-'));
+ EXPECT_FALSE(CharUtils::isIntentionalOmissionCodePoint('a'));
+ EXPECT_FALSE(CharUtils::isIntentionalOmissionCodePoint('?'));
+ EXPECT_FALSE(CharUtils::isIntentionalOmissionCodePoint('/'));
+}
+
+TEST(CharUtilsTest, TestIsInUnicodeSpace) {
+ EXPECT_FALSE(CharUtils::isInUnicodeSpace(NOT_A_CODE_POINT));
+ EXPECT_FALSE(CharUtils::isInUnicodeSpace(CODE_POINT_BEGINNING_OF_SENTENCE));
+ EXPECT_TRUE(CharUtils::isInUnicodeSpace('a'));
+ EXPECT_TRUE(CharUtils::isInUnicodeSpace(0x0410 /* CYRILLIC CAPITAL LETTER A */));
+ EXPECT_TRUE(CharUtils::isInUnicodeSpace(0x3042 /* HIRAGANA LETTER A */));
+ EXPECT_TRUE(CharUtils::isInUnicodeSpace(0x1F36A /* COOKIE */));
+}
+
+} // namespace
+} // namespace latinime
diff --git a/native/jni/tests/utils/int_array_view_test.cpp b/native/jni/tests/utils/int_array_view_test.cpp
index bd843ab02..487bd04b1 100644
--- a/native/jni/tests/utils/int_array_view_test.cpp
+++ b/native/jni/tests/utils/int_array_view_test.cpp
@@ -18,6 +18,7 @@
#include <gtest/gtest.h>
+#include <array>
#include <vector>
namespace latinime {
@@ -45,17 +46,103 @@ TEST(IntArrayViewTest, TestIteration) {
TEST(IntArrayViewTest, TestConstructFromArray) {
const size_t ARRAY_SIZE = 100;
- int intArray[ARRAY_SIZE];
- const auto intArrayView = IntArrayView::fromFixedSizeArray(intArray);
+ std::array<int, ARRAY_SIZE> intArray;
+ const auto intArrayView = IntArrayView::fromArray(intArray);
EXPECT_EQ(ARRAY_SIZE, intArrayView.size());
}
TEST(IntArrayViewTest, TestConstructFromObject) {
const int object = 10;
- const auto intArrayView = IntArrayView::fromObject(&object);
- EXPECT_EQ(1, intArrayView.size());
+ const auto intArrayView = IntArrayView::singleElementView(&object);
+ EXPECT_EQ(1u, intArrayView.size());
EXPECT_EQ(object, intArrayView[0]);
}
+TEST(IntArrayViewTest, TestContains) {
+ EXPECT_FALSE(IntArrayView().contains(0));
+ EXPECT_FALSE(IntArrayView().contains(1));
+
+ const std::vector<int> intVector = {3, 2, 1, 0, -1, -2};
+ IntArrayView intArrayView(intVector);
+ EXPECT_TRUE(intArrayView.contains(0));
+ EXPECT_TRUE(intArrayView.contains(3));
+ EXPECT_TRUE(intArrayView.contains(-2));
+ EXPECT_FALSE(intArrayView.contains(-3));
+ EXPECT_FALSE(intArrayView.limit(0).contains(3));
+}
+
+TEST(IntArrayViewTest, TestLimit) {
+ const std::vector<int> intVector = {3, 2, 1, 0, -1, -2};
+ IntArrayView intArrayView(intVector);
+
+ EXPECT_TRUE(intArrayView.limit(0).empty());
+ EXPECT_EQ(intArrayView.size(), intArrayView.limit(intArrayView.size()).size());
+ EXPECT_EQ(intArrayView.size(), intArrayView.limit(1000).size());
+
+ IntArrayView subView = intArrayView.limit(4);
+ EXPECT_EQ(4u, subView.size());
+ for (size_t i = 0; i < subView.size(); ++i) {
+ EXPECT_EQ(intVector[i], subView[i]);
+ }
+}
+
+TEST(IntArrayViewTest, TestSkip) {
+ const std::vector<int> intVector = {3, 2, 1, 0, -1, -2};
+ IntArrayView intArrayView(intVector);
+
+ EXPECT_TRUE(intArrayView.skip(intVector.size()).empty());
+ EXPECT_TRUE(intArrayView.skip(intVector.size() + 1).empty());
+ EXPECT_EQ(intArrayView.size(), intArrayView.skip(0).size());
+ EXPECT_EQ(intArrayView.size(), intArrayView.limit(1000).size());
+
+ static const size_t SKIP_COUNT = 2;
+ IntArrayView subView = intArrayView.skip(SKIP_COUNT);
+ EXPECT_EQ(intVector.size() - SKIP_COUNT, subView.size());
+ for (size_t i = 0; i < subView.size(); ++i) {
+ EXPECT_EQ(intVector[i + SKIP_COUNT], subView[i]);
+ }
+}
+
+TEST(IntArrayViewTest, TestCopyToArray) {
+ // "{{" to suppress warning.
+ std::array<int, 7> buffer = {{10, 20, 30, 40, 50, 60, 70}};
+ const std::vector<int> intVector = {3, 2, 1, 0, -1, -2};
+ IntArrayView intArrayView(intVector);
+ intArrayView.limit(0).copyToArray(&buffer, 0);
+ EXPECT_EQ(10, buffer[0]);
+ EXPECT_EQ(20, buffer[1]);
+ intArrayView.limit(1).copyToArray(&buffer, 0);
+ EXPECT_EQ(intVector[0], buffer[0]);
+ EXPECT_EQ(20, buffer[1]);
+ intArrayView.limit(1).copyToArray(&buffer, 1);
+ EXPECT_EQ(intVector[0], buffer[0]);
+ EXPECT_EQ(intVector[0], buffer[1]);
+ intArrayView.copyToArray(&buffer, 0);
+ for (size_t i = 0; i < intArrayView.size(); ++i) {
+ EXPECT_EQ(intVector[i], buffer[i]);
+ }
+ EXPECT_EQ(70, buffer[6]);
+}
+
+TEST(IntArrayViewTest, TestFirstOrDefault) {
+ const std::vector<int> intVector = {3, 2, 1, 0, -1, -2};
+ IntArrayView intArrayView(intVector);
+
+ EXPECT_EQ(3, intArrayView.firstOrDefault(10));
+ EXPECT_EQ(10, intArrayView.limit(0).firstOrDefault(10));
+ EXPECT_EQ(-10, intArrayView.limit(0).firstOrDefault(-10));
+ EXPECT_EQ(10, intArrayView.skip(6).firstOrDefault(10));
+}
+
+TEST(IntArrayViewTest, TestLastOrDefault) {
+ const std::vector<int> intVector = {3, 2, 1, 0, -1, -2};
+ IntArrayView intArrayView(intVector);
+
+ EXPECT_EQ(-2, intArrayView.lastOrDefault(10));
+ EXPECT_EQ(10, intArrayView.limit(0).lastOrDefault(10));
+ EXPECT_EQ(-10, intArrayView.limit(0).lastOrDefault(-10));
+ EXPECT_EQ(10, intArrayView.skip(6).lastOrDefault(10));
+}
+
} // namespace
} // namespace latinime
diff --git a/native/jni/tests/utils/time_keeper_test.cpp b/native/jni/tests/utils/time_keeper_test.cpp
new file mode 100644
index 000000000..3f54b91f1
--- /dev/null
+++ b/native/jni/tests/utils/time_keeper_test.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#include "utils/time_keeper.h"
+
+#include <gtest/gtest.h>
+
+namespace latinime {
+namespace {
+
+TEST(TimeKeeperTest, TestTestMode) {
+ TimeKeeper::setCurrentTime();
+ const int startTime = TimeKeeper::peekCurrentTime();
+ static const int TEST_CURRENT_TIME = 100;
+ TimeKeeper::startTestModeWithForceCurrentTime(TEST_CURRENT_TIME);
+ EXPECT_EQ(TEST_CURRENT_TIME, TimeKeeper::peekCurrentTime());
+ TimeKeeper::setCurrentTime();
+ EXPECT_EQ(TEST_CURRENT_TIME, TimeKeeper::peekCurrentTime());
+ TimeKeeper::stopTestMode();
+ TimeKeeper::setCurrentTime();
+ EXPECT_LE(startTime, TimeKeeper::peekCurrentTime());
+}
+
+} // namespace
+} // namespace latinime