Home | History | Annotate | Download | only in calllog
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.dialer.calllog;
     18 
     19 import static com.google.common.collect.Lists.newArrayList;
     20 
     21 import android.database.MatrixCursor;
     22 import android.test.AndroidTestCase;
     23 import android.test.suitebuilder.annotation.SmallTest;
     24 
     25 import com.android.contacts.common.compat.CompatUtils;
     26 import com.android.dialer.util.AppCompatConstants;
     27 
     28 import java.util.List;
     29 
     30 /**
     31  * Unit tests for {@link CallLogGroupBuilder}
     32  */
     33 @SmallTest
     34 public class CallLogGroupBuilderTest extends AndroidTestCase {
     35     /** A phone number for testing. */
     36     private static final String TEST_NUMBER1 = "14125551234";
     37     /** A phone number for testing. */
     38     private static final String TEST_NUMBER2 = "14125555555";
     39     /** A post-dial string for testing */
     40     private static final String TEST_POST_DIAL_DIGITS = ";12435;0987";
     41 
     42     /** The object under test. */
     43     private CallLogGroupBuilder mBuilder;
     44     /** Records the created groups. */
     45     private FakeGroupCreator mFakeGroupCreator;
     46     /** Cursor to store the values. */
     47     private MatrixCursor mCursor;
     48 
     49     @Override
     50     protected void setUp() throws Exception {
     51         super.setUp();
     52         mFakeGroupCreator = new FakeGroupCreator();
     53         mBuilder = new CallLogGroupBuilder(mFakeGroupCreator);
     54         createCursor();
     55     }
     56 
     57     @Override
     58     protected void tearDown() throws Exception {
     59         mCursor = null;
     60         mBuilder = null;
     61         mFakeGroupCreator = null;
     62         super.tearDown();
     63     }
     64 
     65     public void testAddGroups_NoCalls() {
     66         mBuilder.addGroups(mCursor);
     67         assertEquals(0, mFakeGroupCreator.groups.size());
     68     }
     69 
     70     public void testAddGroups_OneCall() {
     71         addCallLogEntry(TEST_NUMBER1, AppCompatConstants.CALLS_INCOMING_TYPE);
     72         mBuilder.addGroups(mCursor);
     73         assertEquals(1, mFakeGroupCreator.groups.size());
     74     }
     75 
     76     public void testAddGroups_TwoCallsNotMatching() {
     77         addCallLogEntry(TEST_NUMBER1, AppCompatConstants.CALLS_INCOMING_TYPE);
     78         addCallLogEntry(TEST_NUMBER2, AppCompatConstants.CALLS_INCOMING_TYPE);
     79         mBuilder.addGroups(mCursor);
     80         assertEquals(2, mFakeGroupCreator.groups.size());
     81     }
     82 
     83     public void testAddGroups_ThreeCallsMatching() {
     84         addCallLogEntry(TEST_NUMBER1, AppCompatConstants.CALLS_INCOMING_TYPE);
     85         addCallLogEntry(TEST_NUMBER1, AppCompatConstants.CALLS_INCOMING_TYPE);
     86         addCallLogEntry(TEST_NUMBER1, AppCompatConstants.CALLS_INCOMING_TYPE);
     87         mBuilder.addGroups(mCursor);
     88         assertEquals(1, mFakeGroupCreator.groups.size());
     89         assertGroupIs(0, 3, mFakeGroupCreator.groups.get(0));
     90     }
     91 
     92     public void testAddGroups_WithPostDialMatching() {
     93         addCallLogEntryWithPostDialDigits(TEST_NUMBER1, TEST_POST_DIAL_DIGITS,
     94                 AppCompatConstants.CALLS_OUTGOING_TYPE);
     95         addCallLogEntryWithPostDialDigits(TEST_NUMBER1, TEST_POST_DIAL_DIGITS,
     96                 AppCompatConstants.CALLS_OUTGOING_TYPE);
     97         addCallLogEntryWithPostDialDigits(TEST_NUMBER1, "",
     98                 AppCompatConstants.CALLS_OUTGOING_TYPE);
     99 
    100         mBuilder.addGroups(mCursor);
    101 
    102         if (CompatUtils.isNCompatible()) {
    103             assertEquals(2, mFakeGroupCreator.groups.size());
    104             assertGroupIs(0, 2, mFakeGroupCreator.groups.get(0));
    105             assertGroupIs(2, 1, mFakeGroupCreator.groups.get(1));
    106         } else {
    107             assertEquals(1, mFakeGroupCreator.groups.size());
    108             assertGroupIs(0, 3, mFakeGroupCreator.groups.get(0));
    109         }
    110     }
    111 
    112     public void testAddGroups_WithViaNumberMatching() {
    113         addCallLogEntryWithViaNumber(TEST_NUMBER1, TEST_NUMBER2,
    114                 AppCompatConstants.CALLS_OUTGOING_TYPE);
    115         addCallLogEntryWithViaNumber(TEST_NUMBER1, TEST_NUMBER2,
    116                 AppCompatConstants.CALLS_OUTGOING_TYPE);
    117         addCallLogEntryWithViaNumber(TEST_NUMBER1, "",
    118                 AppCompatConstants.CALLS_OUTGOING_TYPE);
    119 
    120         mBuilder.addGroups(mCursor);
    121 
    122         if (CompatUtils.isNCompatible()) {
    123             assertEquals(2, mFakeGroupCreator.groups.size());
    124             assertGroupIs(0, 2, mFakeGroupCreator.groups.get(0));
    125             assertGroupIs(2, 1, mFakeGroupCreator.groups.get(1));
    126         } else {
    127             assertEquals(1, mFakeGroupCreator.groups.size());
    128             assertGroupIs(0, 3, mFakeGroupCreator.groups.get(0));
    129         }
    130     }
    131 
    132     public void testAddGroups_MatchingIncomingAndOutgoing() {
    133         addCallLogEntry(TEST_NUMBER1, AppCompatConstants.CALLS_INCOMING_TYPE);
    134         addCallLogEntry(TEST_NUMBER1, AppCompatConstants.CALLS_OUTGOING_TYPE);
    135         addCallLogEntry(TEST_NUMBER1, AppCompatConstants.CALLS_INCOMING_TYPE);
    136         mBuilder.addGroups(mCursor);
    137         assertEquals(1, mFakeGroupCreator.groups.size());
    138         assertGroupIs(0, 3, mFakeGroupCreator.groups.get(0));
    139     }
    140 
    141     public void testGrouping_Voicemail() {
    142         // Does not group with other types of calls, include voicemail themselves.
    143         assertCallsAreNotGrouped(
    144                 AppCompatConstants.CALLS_VOICEMAIL_TYPE, AppCompatConstants.CALLS_MISSED_TYPE);
    145         assertCallsAreNotGrouped(
    146                 AppCompatConstants.CALLS_VOICEMAIL_TYPE, AppCompatConstants.CALLS_VOICEMAIL_TYPE);
    147         assertCallsAreNotGrouped(
    148                 AppCompatConstants.CALLS_VOICEMAIL_TYPE, AppCompatConstants.CALLS_INCOMING_TYPE);
    149         assertCallsAreNotGrouped(
    150                 AppCompatConstants.CALLS_VOICEMAIL_TYPE, AppCompatConstants.CALLS_OUTGOING_TYPE);
    151     }
    152 
    153     public void testGrouping_VoicemailArchive() {
    154         // Does not group with other types of calls, include voicemail themselves.
    155         assertVoicemailsAreNotGrouped(
    156                 AppCompatConstants.CALLS_VOICEMAIL_TYPE, AppCompatConstants.CALLS_MISSED_TYPE);
    157         assertVoicemailsAreNotGrouped(
    158                 AppCompatConstants.CALLS_VOICEMAIL_TYPE, AppCompatConstants.CALLS_VOICEMAIL_TYPE);
    159         assertVoicemailsAreNotGrouped(
    160                 AppCompatConstants.CALLS_VOICEMAIL_TYPE, AppCompatConstants.CALLS_INCOMING_TYPE);
    161         assertVoicemailsAreNotGrouped(
    162                 AppCompatConstants.CALLS_VOICEMAIL_TYPE, AppCompatConstants.CALLS_OUTGOING_TYPE);
    163     }
    164 
    165     public void testGrouping_Missed() {
    166         // Groups with one or more missed calls.
    167         assertCallsAreGrouped(
    168                 AppCompatConstants.CALLS_MISSED_TYPE, AppCompatConstants.CALLS_MISSED_TYPE);
    169         assertCallsAreGrouped(
    170                 AppCompatConstants.CALLS_MISSED_TYPE,
    171                 AppCompatConstants.CALLS_MISSED_TYPE,
    172                 AppCompatConstants.CALLS_MISSED_TYPE);
    173         // Does not group with other types of calls.
    174         assertCallsAreNotGrouped(
    175                 AppCompatConstants.CALLS_MISSED_TYPE, AppCompatConstants.CALLS_VOICEMAIL_TYPE);
    176         assertCallsAreGrouped(
    177                 AppCompatConstants.CALLS_MISSED_TYPE, AppCompatConstants.CALLS_INCOMING_TYPE);
    178         assertCallsAreGrouped(
    179                 AppCompatConstants.CALLS_MISSED_TYPE, AppCompatConstants.CALLS_OUTGOING_TYPE);
    180     }
    181 
    182     public void testGrouping_Incoming() {
    183         // Groups with one or more incoming or outgoing.
    184         assertCallsAreGrouped(
    185                 AppCompatConstants.CALLS_INCOMING_TYPE, AppCompatConstants.CALLS_INCOMING_TYPE);
    186         assertCallsAreGrouped(
    187                 AppCompatConstants.CALLS_INCOMING_TYPE, AppCompatConstants.CALLS_OUTGOING_TYPE);
    188         assertCallsAreGrouped(
    189                 AppCompatConstants.CALLS_INCOMING_TYPE,
    190                 AppCompatConstants.CALLS_INCOMING_TYPE,
    191                 AppCompatConstants.CALLS_OUTGOING_TYPE);
    192         assertCallsAreGrouped(
    193                 AppCompatConstants.CALLS_INCOMING_TYPE,
    194                 AppCompatConstants.CALLS_OUTGOING_TYPE,
    195                 AppCompatConstants.CALLS_INCOMING_TYPE);
    196         assertCallsAreGrouped(
    197                 AppCompatConstants.CALLS_INCOMING_TYPE, AppCompatConstants.CALLS_MISSED_TYPE);
    198         // Does not group with voicemail and missed calls.
    199         assertCallsAreNotGrouped(
    200                 AppCompatConstants.CALLS_INCOMING_TYPE, AppCompatConstants.CALLS_VOICEMAIL_TYPE);
    201     }
    202 
    203     public void testGrouping_Outgoing() {
    204         // Groups with one or more incoming or outgoing.
    205         assertCallsAreGrouped(
    206                 AppCompatConstants.CALLS_OUTGOING_TYPE, AppCompatConstants.CALLS_INCOMING_TYPE);
    207         assertCallsAreGrouped(
    208                 AppCompatConstants.CALLS_OUTGOING_TYPE, AppCompatConstants.CALLS_OUTGOING_TYPE);
    209         assertCallsAreGrouped(
    210                 AppCompatConstants.CALLS_OUTGOING_TYPE,
    211                 AppCompatConstants.CALLS_INCOMING_TYPE,
    212                 AppCompatConstants.CALLS_OUTGOING_TYPE);
    213         assertCallsAreGrouped(
    214                 AppCompatConstants.CALLS_OUTGOING_TYPE,
    215                 AppCompatConstants.CALLS_OUTGOING_TYPE,
    216                 AppCompatConstants.CALLS_INCOMING_TYPE);
    217         assertCallsAreGrouped(
    218                 AppCompatConstants.CALLS_INCOMING_TYPE, AppCompatConstants.CALLS_MISSED_TYPE);
    219         // Does not group with voicemail and missed calls.
    220         assertCallsAreNotGrouped(
    221                 AppCompatConstants.CALLS_INCOMING_TYPE, AppCompatConstants.CALLS_VOICEMAIL_TYPE);
    222     }
    223 
    224     public void testGrouping_Blocked() {
    225         assertCallsAreNotGrouped(
    226                 AppCompatConstants.CALLS_BLOCKED_TYPE, AppCompatConstants.CALLS_INCOMING_TYPE);
    227         assertCallsAreNotGrouped(
    228                 AppCompatConstants.CALLS_BLOCKED_TYPE, AppCompatConstants.CALLS_OUTGOING_TYPE);
    229         assertCallsAreNotGrouped(
    230                 AppCompatConstants.CALLS_BLOCKED_TYPE, AppCompatConstants.CALLS_MISSED_TYPE);
    231 
    232     }
    233 
    234     public void testAddGroups_Separate() {
    235         addMultipleCallLogEntries(TEST_NUMBER1,
    236                 AppCompatConstants.CALLS_VOICEMAIL_TYPE,    // Group 1: 0
    237                 AppCompatConstants.CALLS_INCOMING_TYPE,     // Group 2: 1
    238                 AppCompatConstants.CALLS_OUTGOING_TYPE,     // Group 3: 2
    239                 AppCompatConstants.CALLS_MISSED_TYPE);      // Group 4: 3
    240         mBuilder.addVoicemailGroups(mCursor);
    241 
    242         assertEquals(4, mFakeGroupCreator.groups.size());
    243         assertGroupIs(0, 1, mFakeGroupCreator.groups.get(0));
    244         assertGroupIs(1, 1, mFakeGroupCreator.groups.get(1));
    245         assertGroupIs(2, 1, mFakeGroupCreator.groups.get(2));
    246         assertGroupIs(3, 1, mFakeGroupCreator.groups.get(3));
    247     }
    248 
    249     public void testAddGroups_Mixed() {
    250         addMultipleCallLogEntries(TEST_NUMBER1,
    251                 AppCompatConstants.CALLS_VOICEMAIL_TYPE,   // Group 1: 0
    252                 AppCompatConstants.CALLS_INCOMING_TYPE,    // Group 2: 1-4
    253                 AppCompatConstants.CALLS_OUTGOING_TYPE,
    254                 AppCompatConstants.CALLS_MISSED_TYPE,
    255                 AppCompatConstants.CALLS_MISSED_TYPE,
    256                 AppCompatConstants.CALLS_VOICEMAIL_TYPE,   // Group 3: 5
    257                 AppCompatConstants.CALLS_INCOMING_TYPE,    // Group 4: 6
    258                 AppCompatConstants.CALLS_VOICEMAIL_TYPE,   // Group 5: 7
    259                 AppCompatConstants.CALLS_MISSED_TYPE,      // Group 6: 8-10
    260                 AppCompatConstants.CALLS_MISSED_TYPE,
    261                 AppCompatConstants.CALLS_OUTGOING_TYPE);
    262         mBuilder.addGroups(mCursor);
    263 
    264         assertEquals(6, mFakeGroupCreator.groups.size());
    265         assertGroupIs(0, 1, mFakeGroupCreator.groups.get(0));
    266         assertGroupIs(1, 4, mFakeGroupCreator.groups.get(1));
    267         assertGroupIs(5, 1, mFakeGroupCreator.groups.get(2));
    268         assertGroupIs(6, 1, mFakeGroupCreator.groups.get(3));
    269         assertGroupIs(7, 1, mFakeGroupCreator.groups.get(4));
    270         assertGroupIs(8, 3, mFakeGroupCreator.groups.get(5));
    271     }
    272 
    273     public void testAddGroups_Blocked() {
    274         addMultipleCallLogEntries(TEST_NUMBER1,
    275                 AppCompatConstants.CALLS_INCOMING_TYPE,     // Group 1: 0-1
    276                 AppCompatConstants.CALLS_OUTGOING_TYPE,
    277                 AppCompatConstants.CALLS_BLOCKED_TYPE,      // Group 2: 2
    278                 AppCompatConstants.CALLS_MISSED_TYPE,       // Group 3: 3
    279                 AppCompatConstants.CALLS_BLOCKED_TYPE,      // Group 4: 4-5
    280                 AppCompatConstants.CALLS_BLOCKED_TYPE);
    281         mBuilder.addGroups(mCursor);
    282 
    283         assertEquals(4, mFakeGroupCreator.groups.size());
    284         assertGroupIs(0, 2, mFakeGroupCreator.groups.get(0));
    285         assertGroupIs(2, 1, mFakeGroupCreator.groups.get(1));
    286         assertGroupIs(3, 1, mFakeGroupCreator.groups.get(2));
    287         assertGroupIs(4, 2, mFakeGroupCreator.groups.get(3));
    288     }
    289 
    290     public void testEqualPhoneNumbers() {
    291         // Identical.
    292         assertTrue(mBuilder.equalNumbers("6505555555", "6505555555"));
    293         assertTrue(mBuilder.equalNumbers("650 555 5555", "650 555 5555"));
    294         // Formatting.
    295         assertTrue(mBuilder.equalNumbers("6505555555", "650 555 5555"));
    296         assertTrue(mBuilder.equalNumbers("6505555555", "(650) 555-5555"));
    297         assertTrue(mBuilder.equalNumbers("650 555 5555", "(650) 555-5555"));
    298         // Short codes.
    299         assertTrue(mBuilder.equalNumbers("55555", "55555"));
    300         assertTrue(mBuilder.equalNumbers("55555", "555 55"));
    301         // Different numbers.
    302         assertFalse(mBuilder.equalNumbers("6505555555", "650555555"));
    303         assertFalse(mBuilder.equalNumbers("6505555555", "6505555551"));
    304         assertFalse(mBuilder.equalNumbers("650 555 5555", "650 555 555"));
    305         assertFalse(mBuilder.equalNumbers("650 555 5555", "650 555 5551"));
    306         assertFalse(mBuilder.equalNumbers("55555", "5555"));
    307         assertFalse(mBuilder.equalNumbers("55555", "55551"));
    308         // SIP addresses.
    309         assertTrue(mBuilder.equalNumbers("6505555555 (at) host.com", "6505555555 (at) host.com"));
    310         assertTrue(mBuilder.equalNumbers("6505555555 (at) host.com", "6505555555 (at) HOST.COM"));
    311         assertTrue(mBuilder.equalNumbers("user (at) host.com", "user (at) host.com"));
    312         assertTrue(mBuilder.equalNumbers("user (at) host.com", "user (at) HOST.COM"));
    313         assertFalse(mBuilder.equalNumbers("USER (at) host.com", "user (at) host.com"));
    314         assertFalse(mBuilder.equalNumbers("user (at) host.com", "user (at) host1.com"));
    315         // SIP address vs phone number.
    316         assertFalse(mBuilder.equalNumbers("6505555555 (at) host.com", "6505555555"));
    317         assertFalse(mBuilder.equalNumbers("6505555555", "6505555555 (at) host.com"));
    318         assertFalse(mBuilder.equalNumbers("user (at) host.com", "6505555555"));
    319         assertFalse(mBuilder.equalNumbers("6505555555", "user (at) host.com"));
    320         // Nulls.
    321         assertTrue(mBuilder.equalNumbers(null, null));
    322         assertFalse(mBuilder.equalNumbers(null, "6505555555"));
    323         assertFalse(mBuilder.equalNumbers("6505555555", null));
    324         assertFalse(mBuilder.equalNumbers(null, "6505555555 (at) host.com"));
    325         assertFalse(mBuilder.equalNumbers("6505555555 (at) host.com", null));
    326     }
    327 
    328     public void testCompareSipAddresses() {
    329         // Identical.
    330         assertTrue(mBuilder.compareSipAddresses("6505555555 (at) host.com", "6505555555 (at) host.com"));
    331         assertTrue(mBuilder.compareSipAddresses("user (at) host.com", "user (at) host.com"));
    332         // Host is case insensitive.
    333         assertTrue(mBuilder.compareSipAddresses("6505555555 (at) host.com", "6505555555 (at) HOST.COM"));
    334         assertTrue(mBuilder.compareSipAddresses("user (at) host.com", "user (at) HOST.COM"));
    335         // Userinfo is case sensitive.
    336         assertFalse(mBuilder.compareSipAddresses("USER (at) host.com", "user (at) host.com"));
    337         // Different hosts.
    338         assertFalse(mBuilder.compareSipAddresses("user (at) host.com", "user (at) host1.com"));
    339         // Different users.
    340         assertFalse(mBuilder.compareSipAddresses("user1 (at) host.com", "user (at) host.com"));
    341         // Nulls.
    342         assertTrue(mBuilder.compareSipAddresses(null, null));
    343         assertFalse(mBuilder.compareSipAddresses(null, "6505555555 (at) host.com"));
    344         assertFalse(mBuilder.compareSipAddresses("6505555555 (at) host.com", null));
    345     }
    346 
    347     /** Creates (or recreates) the cursor used to store the call log content for the tests. */
    348     private void createCursor() {
    349         mCursor = new MatrixCursor(CallLogQuery._PROJECTION);
    350     }
    351 
    352     /** Clears the content of the {@link FakeGroupCreator} used in the tests. */
    353     private void clearFakeGroupCreator() {
    354         mFakeGroupCreator.groups.clear();
    355     }
    356 
    357     /** Asserts that calls of the given types are grouped together into a single group. */
    358     private void assertCallsAreGrouped(int... types) {
    359         createCursor();
    360         clearFakeGroupCreator();
    361         addMultipleCallLogEntries(TEST_NUMBER1, types);
    362         mBuilder.addGroups(mCursor);
    363         assertEquals(1, mFakeGroupCreator.groups.size());
    364         assertGroupIs(0, types.length, mFakeGroupCreator.groups.get(0));
    365 
    366     }
    367 
    368     /** Asserts that calls of the given types are not grouped together at all. */
    369     private void assertCallsAreNotGrouped(int... types) {
    370         createCursor();
    371         clearFakeGroupCreator();
    372         addMultipleCallLogEntries(TEST_NUMBER1, types);
    373         mBuilder.addGroups(mCursor);
    374         assertEquals(types.length, mFakeGroupCreator.groups.size());
    375     }
    376 
    377     /** Asserts that voicemails are not grouped together with other types at all. */
    378     private void assertVoicemailsAreNotGrouped(int... types) {
    379         createCursor();
    380         clearFakeGroupCreator();
    381         addMultipleCallLogEntries(TEST_NUMBER1, types);
    382         mBuilder.addVoicemailGroups(mCursor);
    383         assertEquals(types.length, mFakeGroupCreator.groups.size());
    384     }
    385 
    386     /** Adds a set of calls with the given types, all from the same number, in the old section. */
    387     private void addMultipleCallLogEntries(String number, int... types) {
    388         for (int type : types) {
    389             addCallLogEntry(number, type);
    390         }
    391     }
    392     /** Adds a call log entry with the given number and type to the cursor. */
    393     private void addCallLogEntry(String number, int type) {
    394         addCallLogEntryWithPostDialDigits(number, "", type);
    395     }
    396 
    397     /** Adds a call log entry with the given number, post-dial digits, and type to the cursor. */
    398     private void addCallLogEntryWithPostDialDigits(String number, String postDialDigits, int type) {
    399         mCursor.moveToNext();
    400         Object[] values = CallLogQueryTestUtils.createTestValues();
    401         values[CallLogQuery.ID] = mCursor.getPosition();
    402         values[CallLogQuery.NUMBER] = number;
    403         values[CallLogQuery.CALL_TYPE] = type;
    404         if (CompatUtils.isNCompatible()) {
    405             values[CallLogQuery.POST_DIAL_DIGITS] = postDialDigits;
    406         }
    407         mCursor.addRow(values);
    408     }
    409 
    410     /** Adds a call log entry with the given number, post-dial digits, and type to the cursor. */
    411     private void addCallLogEntryWithViaNumber(String number, String viaNumber, int type) {
    412         mCursor.moveToNext();
    413         Object[] values = CallLogQueryTestUtils.createTestValues();
    414         values[CallLogQuery.ID] = mCursor.getPosition();
    415         values[CallLogQuery.NUMBER] = number;
    416         values[CallLogQuery.CALL_TYPE] = type;
    417         if (CompatUtils.isNCompatible()) {
    418             values[CallLogQuery.VIA_NUMBER] = viaNumber;
    419         }
    420         mCursor.addRow(values);
    421     }
    422 
    423     /** Adds a call log entry with a header to the cursor. */
    424     private void addCallLogHeader(int section) {
    425         mCursor.moveToNext();
    426         Object[] values = CallLogQueryTestUtils.createTestValues();
    427         values[CallLogQuery.ID] = mCursor.getPosition();
    428         mCursor.addRow(values);
    429     }
    430 
    431     /** Asserts that the group matches the given values. */
    432     private void assertGroupIs(int cursorPosition, int size, GroupSpec group) {
    433         assertEquals(cursorPosition, group.cursorPosition);
    434         assertEquals(size, group.size);
    435     }
    436 
    437     /** Defines an added group. Used by the {@link FakeGroupCreator}. */
    438     private static class GroupSpec {
    439         /** The starting position of the group. */
    440         public final int cursorPosition;
    441         /** The number of elements in the group. */
    442         public final int size;
    443 
    444         public GroupSpec(int cursorPosition, int size) {
    445             this.cursorPosition = cursorPosition;
    446             this.size = size;
    447         }
    448     }
    449 
    450     /** Fake implementation of a GroupCreator which stores the created groups in a member field. */
    451     private static class FakeGroupCreator implements CallLogGroupBuilder.GroupCreator {
    452         /** The list of created groups. */
    453         public final List<GroupSpec> groups = newArrayList();
    454 
    455         @Override
    456         public void addGroup(int cursorPosition, int size) {
    457             groups.add(new GroupSpec(cursorPosition, size));
    458         }
    459 
    460         @Override
    461         public void setDayGroup(long rowId, int dayGroup) {
    462             //No-op
    463         }
    464 
    465         @Override
    466         public void clearDayGroups() {
    467             //No-op
    468         }
    469     }
    470 }
    471