1cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov/*
2cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov * Copyright (C) 2009 The Android Open Source Project
3cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov *
4cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License");
5cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov * you may not use this file except in compliance with the License.
6cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov * You may obtain a copy of the License at
7cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov *
8cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov *      http://www.apache.org/licenses/LICENSE-2.0
9cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov *
10cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov * Unless required by applicable law or agreed to in writing, software
11cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS,
12cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov * See the License for the specific language governing permissions and
14cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov * limitations under the License
15cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov */
168920a04b4a68ed6b548bcdef5ca8736dcf8b69b1Omari Stephens
1781567f4a0f7c9c338506bd82f4d33e83c2ccf159Makoto Onukipackage com.android.providers.contacts.aggregation.util;
1881567f4a0f7c9c338506bd82f4d33e83c2ccf159Makoto Onuki
1938210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport android.test.suitebuilder.annotation.SmallTest;
2038210445730ee04c351c7cc1b3800cfe23e34325Makoto Onuki
2181567f4a0f7c9c338506bd82f4d33e83c2ccf159Makoto Onukiimport com.android.providers.contacts.NameNormalizer;
2281567f4a0f7c9c338506bd82f4d33e83c2ccf159Makoto Onukiimport com.android.providers.contacts.util.Hex;
23cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov
24cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikovimport junit.framework.TestCase;
25cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov
268920a04b4a68ed6b548bcdef5ca8736dcf8b69b1Omari Stephens/**
278920a04b4a68ed6b548bcdef5ca8736dcf8b69b1Omari Stephens * Unit tests for {@link NameDistance}.
288920a04b4a68ed6b548bcdef5ca8736dcf8b69b1Omari Stephens *
298920a04b4a68ed6b548bcdef5ca8736dcf8b69b1Omari Stephens * Run the test like this:
308920a04b4a68ed6b548bcdef5ca8736dcf8b69b1Omari Stephens * <code>
318920a04b4a68ed6b548bcdef5ca8736dcf8b69b1Omari Stephens * adb shell am instrument -e class com.android.providers.contacts.NameDistanceTest -w \
328920a04b4a68ed6b548bcdef5ca8736dcf8b69b1Omari Stephens *         com.android.providers.contacts.tests/android.test.InstrumentationTestRunner
338920a04b4a68ed6b548bcdef5ca8736dcf8b69b1Omari Stephens * </code>
348920a04b4a68ed6b548bcdef5ca8736dcf8b69b1Omari Stephens */
35cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov@SmallTest
36a276d23a70bdb8fdc7c8340a12a64e90696da115Dmitri Plotnikovpublic class NameDistanceTest extends TestCase {
37cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov
38a276d23a70bdb8fdc7c8340a12a64e90696da115Dmitri Plotnikov    private NameDistance mNameDistance;
39cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov
40cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov    @Override
41cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov    protected void setUp() throws Exception {
42cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov        super.setUp();
43cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov
44a276d23a70bdb8fdc7c8340a12a64e90696da115Dmitri Plotnikov        mNameDistance = new NameDistance(30);
45cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov    }
46cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov
47cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov    public void testExactMatch() {
48cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov        assertFloat(1, "Dwayne", "Dwayne");
49cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov    }
50cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov
5128245e1690abbab18b3224e4164a738f6e64d6c0Dmitri Plotnikov    public void testWinklerBonus() {
5228245e1690abbab18b3224e4164a738f6e64d6c0Dmitri Plotnikov        assertFloat(0.961f, "Martha", "Marhta");
5328245e1690abbab18b3224e4164a738f6e64d6c0Dmitri Plotnikov        assertFloat(0.840f, "Dwayne", "Duane");
5428245e1690abbab18b3224e4164a738f6e64d6c0Dmitri Plotnikov        assertFloat(0.813f, "DIXON", "DICKSONX");
55cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov    }
56cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov
5728245e1690abbab18b3224e4164a738f6e64d6c0Dmitri Plotnikov    public void testJaroDistance() {
5828245e1690abbab18b3224e4164a738f6e64d6c0Dmitri Plotnikov        assertFloat(0.600f, "Donny", "Duane");
59cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov    }
60cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov
6128245e1690abbab18b3224e4164a738f6e64d6c0Dmitri Plotnikov    public void testPoorMatch() {
6228245e1690abbab18b3224e4164a738f6e64d6c0Dmitri Plotnikov        assertFloat(0.467f, "Johny", "Duane");
63cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov    }
64cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov
6528245e1690abbab18b3224e4164a738f6e64d6c0Dmitri Plotnikov    public void testNoMatches() {
6628245e1690abbab18b3224e4164a738f6e64d6c0Dmitri Plotnikov        assertFloat(0, "Abcd", "Efgh");
67a276d23a70bdb8fdc7c8340a12a64e90696da115Dmitri Plotnikov    }
68a276d23a70bdb8fdc7c8340a12a64e90696da115Dmitri Plotnikov
69cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov    private void assertFloat(float expected, String name1, String name2) {
70cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov        byte[] s1 = Hex.decodeHex(NameNormalizer.normalize(name1));
71cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov        byte[] s2 = Hex.decodeHex(NameNormalizer.normalize(name2));
72cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov
73a276d23a70bdb8fdc7c8340a12a64e90696da115Dmitri Plotnikov        float actual = mNameDistance.getDistance(s1, s2);
74cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov        assertTrue("Expected Jaro-Winkler distance: " + expected + ", actual: " + actual,
75cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov                Math.abs(actual - expected) < 0.001);
76cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov    }
77cceca0d48bc5b0c7fc20b987439add82f734a8f5Dmitri Plotnikov}
78