1 /* 2 * Copyright (C) 2010 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.calendar; 18 19 import com.android.calendar.Utils; 20 import com.android.calendar.CalendarUtils.TimeZoneUtils; 21 22 import android.content.Context; 23 import android.content.res.Configuration; 24 import android.content.res.Resources; 25 import android.content.res.Resources.NotFoundException; 26 import android.database.MatrixCursor; 27 import android.provider.CalendarContract.CalendarCache; 28 import android.test.mock.MockResources; 29 import android.test.suitebuilder.annotation.SmallTest; 30 import android.test.suitebuilder.annotation.Smoke; 31 import android.text.Spannable; 32 import android.text.SpannableString; 33 import android.text.format.Time; 34 import android.text.style.URLSpan; 35 import android.util.DisplayMetrics; 36 import android.util.Log; 37 import android.view.Display; 38 import android.view.View; 39 import android.view.WindowManager; 40 import android.view.ViewGroup.LayoutParams; 41 import android.widget.TextView; 42 43 import java.util.ArrayList; 44 import java.util.Arrays; 45 import java.util.HashMap; 46 import java.util.Iterator; 47 import java.util.Locale; 48 49 import junit.framework.TestCase; 50 51 /** 52 * Test class for verifying helper functions in Calendar's Utils 53 * 54 * You can run these tests with the following command: 55 * "adb shell am instrument -w -e class com.android.calendar.UtilsTests 56 * com.android.calendar.tests/android.test.InstrumentationTestRunner" 57 */ 58 public class UtilsTests extends TestCase { 59 HashMap<String, Boolean> mIsDuplicateName; 60 HashMap<String, Boolean> mIsDuplicateNameExpected; 61 MatrixCursor mDuplicateNameCursor; 62 private DbTestUtils dbUtils; 63 private final TimeZoneUtils timezoneUtils = new TimeZoneUtils(Utils.SHARED_PREFS_NAME); 64 65 private static final int NAME_COLUMN = 0; 66 private static final String[] DUPLICATE_NAME_COLUMNS = new String[] { "name" }; 67 private static final String[][] DUPLICATE_NAMES = new String[][] { 68 {"Pepper Pots"}, 69 {"Green Goblin"}, 70 {"Pepper Pots"}, 71 {"Peter Parker"}, 72 {"Silver Surfer"}, 73 {"John Jameson"}, 74 {"John Jameson"}, 75 {"Pepper Pots"} 76 }; 77 // First date is Thursday, Jan 1st, 1970. 78 private static final int[] JULIAN_DAYS = {2440588, 2440589, 2440590, 2440591, 2440592, 2440593, 79 2440594, 2440595, 2440596, 2440597, 2440598, 2440599, 2440600, 2440601 80 }; 81 private static final int[] EXPECTED_WEEK_MONDAY_START = { 82 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2 }; 83 private static final int[] EXPECTED_WEEK_SUNDAY_START = { 84 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2 }; 85 private static final int[] EXPECTED_WEEK_SATURDAY_START = { 86 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2 }; 87 private static final int[] WEEKS_FOR_JULIAN_MONDAYS = {1, 2}; 88 private static final int[] EXPECTED_JULIAN_MONDAYS = {2440592, 2440599}; 89 90 private static final int NOW_MONTH = 3; // April 91 private static final int NOW_DAY = 10; 92 private static final int NOW_YEAR = 2012; 93 private static final long NOW_TIME = createTimeInMillis(5, 5, 5, NOW_DAY, NOW_MONTH, NOW_YEAR); 94 private static final String DEFAULT_TIMEZONE = Time.getCurrentTimezone(); 95 96 /** 97 * Mock resources. Add translation strings for test here. 98 */ 99 private static class ResourcesForTest extends MockResources { 100 @Override getString(int id)101 public String getString(int id) { 102 if (id == R.string.today) { 103 return "Today"; 104 } 105 if (id == R.string.tomorrow) { 106 return "Tomorrow"; 107 } 108 throw new IllegalArgumentException("unexpected resource ID: " + id); 109 } 110 111 @Override getString(int id, Object... formatArgs)112 public String getString(int id, Object... formatArgs) { 113 if (id == R.string.today_at_time_fmt) { 114 return String.format("Today at %s", formatArgs); 115 } 116 if (id == R.string.tomorrow_at_time_fmt) { 117 return String.format("Tomorrow at %s", formatArgs); 118 } 119 if (id == R.string.date_time_fmt) { 120 return String.format("%s, %s", formatArgs); 121 } 122 throw new IllegalArgumentException("unexpected resource ID: " + id); 123 } 124 125 @Override getConfiguration()126 public Configuration getConfiguration() { 127 Configuration config = new Configuration(); 128 config.locale = Locale.getDefault(); 129 return config; 130 } 131 132 @Override getDisplayMetrics()133 public DisplayMetrics getDisplayMetrics(){ 134 DisplayMetrics metrics = new DisplayMetrics(); 135 metrics.density = 2.0f; 136 return metrics; 137 } 138 } 139 createTimeInMillis(int second, int minute, int hour, int monthDay, int month, int year)140 private static long createTimeInMillis(int second, int minute, int hour, int monthDay, 141 int month, int year) { 142 return createTimeInMillis(second, minute, hour, monthDay, month, year, 143 Time.getCurrentTimezone()); 144 } 145 createTimeInMillis(int second, int minute, int hour, int monthDay, int month, int year, String timezone)146 private static long createTimeInMillis(int second, int minute, int hour, int monthDay, 147 int month, int year, String timezone) { 148 Time t = new Time(timezone); 149 t.set(second, minute, hour, monthDay, month, year); 150 t.normalize(false); 151 return t.toMillis(false); 152 } 153 setTimezone(String tz)154 private void setTimezone(String tz) { 155 timezoneUtils.setTimeZone(dbUtils.getContext(), tz); 156 } 157 158 @Override setUp()159 public void setUp() { 160 mIsDuplicateName = new HashMap<String, Boolean> (); 161 mDuplicateNameCursor = new MatrixCursor(DUPLICATE_NAME_COLUMNS); 162 for (int i = 0; i < DUPLICATE_NAMES.length; i++) { 163 mDuplicateNameCursor.addRow(DUPLICATE_NAMES[i]); 164 } 165 166 mIsDuplicateNameExpected = new HashMap<String, Boolean> (); 167 mIsDuplicateNameExpected.put("Pepper Pots", true); 168 mIsDuplicateNameExpected.put("Green Goblin", false); 169 mIsDuplicateNameExpected.put("Peter Parker", false); 170 mIsDuplicateNameExpected.put("Silver Surfer", false); 171 mIsDuplicateNameExpected.put("John Jameson", true); 172 173 // Set up fake db. 174 dbUtils = new DbTestUtils(new ResourcesForTest()); 175 dbUtils.getContentResolver().addProvider("settings", dbUtils.getContentProvider()); 176 dbUtils.getContentResolver().addProvider(CalendarCache.URI.getAuthority(), 177 dbUtils.getContentProvider()); 178 179 setTimezone(DEFAULT_TIMEZONE); 180 } 181 182 @Override tearDown()183 public void tearDown() { 184 mDuplicateNameCursor.close(); 185 186 // Must reset the timezone here, because even though the fake provider will be 187 // recreated/cleared, TimeZoneUtils statically holds on to a cached value. 188 setTimezone(Time.getCurrentTimezone()); 189 } 190 191 @Smoke 192 @SmallTest testCheckForDuplicateNames()193 public void testCheckForDuplicateNames() { 194 Utils.checkForDuplicateNames(mIsDuplicateName, mDuplicateNameCursor, NAME_COLUMN); 195 assertEquals(mIsDuplicateNameExpected, mIsDuplicateName); 196 } 197 198 @Smoke 199 @SmallTest testGetWeeksSinceEpochFromJulianDay()200 public void testGetWeeksSinceEpochFromJulianDay() { 201 for (int i = 0; i < JULIAN_DAYS.length; i++) { 202 assertEquals(EXPECTED_WEEK_MONDAY_START[i], 203 Utils.getWeeksSinceEpochFromJulianDay(JULIAN_DAYS[i], Time.MONDAY)); 204 assertEquals(EXPECTED_WEEK_SUNDAY_START[i], 205 Utils.getWeeksSinceEpochFromJulianDay(JULIAN_DAYS[i], Time.SUNDAY)); 206 assertEquals(EXPECTED_WEEK_SATURDAY_START[i], 207 Utils.getWeeksSinceEpochFromJulianDay(JULIAN_DAYS[i], Time.SATURDAY)); 208 } 209 } 210 211 @Smoke 212 @SmallTest testGetJulianMondayFromWeeksSinceEpoch()213 public void testGetJulianMondayFromWeeksSinceEpoch() { 214 for (int i = 0; i < WEEKS_FOR_JULIAN_MONDAYS.length; i++) { 215 assertEquals(EXPECTED_JULIAN_MONDAYS[i], 216 Utils.getJulianMondayFromWeeksSinceEpoch(WEEKS_FOR_JULIAN_MONDAYS[i])); 217 } 218 } 219 220 @Smoke 221 @SmallTest testEquals()222 public void testEquals() { 223 assertTrue(Utils.equals(null, null)); 224 assertFalse(Utils.equals("", null)); 225 assertFalse(Utils.equals(null, "")); 226 assertTrue(Utils.equals("","")); 227 228 Integer int1 = new Integer(1); 229 Integer int2 = new Integer(1); 230 assertTrue(Utils.equals(int1, int2)); 231 } 232 233 234 // Helper function to create test events for BusyBits testing buildTestEvent(int startTime, int endTime, boolean allDay, int startDay, int endDay)235 Event buildTestEvent(int startTime, int endTime, boolean allDay, int startDay, int endDay) { 236 Event e = new Event(); 237 e.startTime = startTime; 238 e.endTime = endTime; 239 e.allDay = allDay; 240 e.startDay = startDay; 241 e.endDay = endDay; 242 e.startMillis = e.startDay * 1000L * 3600L * 24L + e.startTime * 60L * 1000L; 243 e.endMillis = e.endDay * 1000L * 3600L * 24L + e.endTime * 60L * 1000L; 244 return e; 245 } 246 247 @Smoke 248 @SmallTest testCreateBusyBitSegments()249 public void testCreateBusyBitSegments() { 250 251 /* ArrayList<Event> events = new ArrayList<Event>(); 252 253 // Test cases that should return null 254 // Empty events list 255 assertEquals(null, Utils.createBusyBitSegments(10, 30, 100, 200, 0, events)); 256 // No events list 257 assertEquals(null, Utils.createBusyBitSegments(10, 30, 100, 200, 0, null)); 258 259 events.add(buildTestEvent(100, 130, false, 1, 1)); 260 events.add(buildTestEvent(1000, 1030, false, 1, 1)); 261 // Illegal pixel positions 262 assertEquals(null, Utils.createBusyBitSegments(30, 10, 100, 200, 1, events)); 263 // Illegal start and end times 264 assertEquals(null, Utils.createBusyBitSegments(10, 30, 200, 100, 1, events)); 265 assertEquals(null, Utils.createBusyBitSegments(10, 30, -10, 100, 1, events)); 266 assertEquals(null, Utils.createBusyBitSegments(10, 30, 24 * 60 + 100, 24 * 60 + 200, 1, 267 events)); 268 assertEquals(null, Utils.createBusyBitSegments(10, 30, 200, 24 * 60 + 100, 1, events)); 269 assertEquals(null, Utils.createBusyBitSegments(10, 30, 200, -100, 1, events)); 270 // No Events in time frame 271 assertEquals(null, Utils.createBusyBitSegments(10, 30, 500, 900, 1, events)); 272 273 // Test event that spans over the day 274 events.clear(); 275 events.add(buildTestEvent(100, 300, false, 1, 5)); 276 ArrayList<BusyBitsSegment> segments = new ArrayList<BusyBitsSegment>(); 277 assertEquals(null, Utils.createBusyBitSegments(0, 250, 200, 1200, 3, events)); 278 279 // test zero times events, events that are partially in the time span 280 // and all day events 281 events.clear(); 282 events.add(buildTestEvent(100, 300, false, 1, 1)); 283 events.add(buildTestEvent(1100, 1300, false, 1, 1)); 284 events.add(buildTestEvent(500, 600, true, 1, 1)); 285 events.add(buildTestEvent(700, 700, false, 1, 1)); 286 segments.clear(); 287 segments.add(new BusyBitsSegment(0, 10, false)); 288 segments.add(new BusyBitsSegment(90, 100, false)); 289 assertEquals(segments, Utils.createBusyBitSegments(0, 100, 200, 1200, 1, events)); 290 291 // Test event that spans over 2 days but start and end time do not 292 // overlap fully with tested time span 293 294 events.clear(); 295 events.add(buildTestEvent(23 * 60, 120, false, 1, 2)); 296 segments.clear(); 297 segments.add(new BusyBitsSegment(0, 120, false)); 298 assertEquals(segments, Utils.createBusyBitSegments(0, 240, 60, 180, 2, events)); 299 300 // Test overlapped events (two draw sizes) 301 events.clear(); 302 events.add(buildTestEvent(10, 200, false, 1, 1)); 303 events.add(buildTestEvent(150, 250, false, 1, 1)); 304 events.add(buildTestEvent(150, 250, false, 1, 1)); 305 events.add(buildTestEvent(200, 400, false, 1, 1)); 306 events.add(buildTestEvent(500, 700, false, 1, 1)); 307 events.add(buildTestEvent(550, 600, false, 1, 1)); 308 events.add(buildTestEvent(550, 580, false, 1, 1)); 309 events.add(buildTestEvent(560, 570, false, 1, 1)); 310 events.add(buildTestEvent(600, 700, false, 1, 1)); 311 events.add(buildTestEvent(620, 700, false, 1, 1)); 312 events.add(buildTestEvent(650, 700, false, 1, 1)); 313 events.add(buildTestEvent(800, 900, false, 1, 1)); 314 events.add(buildTestEvent(800, 900, false, 1, 1)); 315 events.add(buildTestEvent(800, 850, false, 1, 1)); 316 events.add(buildTestEvent(1000, 1200, false, 1, 1)); 317 events.add(buildTestEvent(1000, 1200, false, 1, 1)); 318 segments.clear(); 319 segments.add(new BusyBitsSegment(100, 149, false)); 320 segments.add(new BusyBitsSegment(150, 250, true)); 321 segments.add(new BusyBitsSegment(251, 400, false)); 322 segments.add(new BusyBitsSegment(500, 549, false)); 323 segments.add(new BusyBitsSegment(550, 700, true)); 324 segments.add(new BusyBitsSegment(800, 900, true)); 325 segments.add(new BusyBitsSegment(1000, 1100, true)); 326 assertEquals(segments, Utils.createBusyBitSegments(100, 1100, 100, 1100, 1, events)); 327 segments.clear(); 328 segments.add(new BusyBitsSegment(100, 111, false)); 329 segments.add(new BusyBitsSegment(112, 137, true)); 330 segments.add(new BusyBitsSegment(138, 175, false)); 331 segments.add(new BusyBitsSegment(200, 211, false)); 332 segments.add(new BusyBitsSegment(212, 250, true)); 333 segments.add(new BusyBitsSegment(275, 300, true)); 334 segments.add(new BusyBitsSegment(325, 350, true)); 335 assertEquals(segments, Utils.createBusyBitSegments(100, 350, 100, 1100, 1, events)); 336 */ 337 } 338 339 /** 340 * Tests the findNanpPhoneNumbers function. 341 */ 342 @SmallTest testFindNanpPhoneNumber()343 public void testFindNanpPhoneNumber() { 344 final String[] NO_NUMBERS = new String[] {}; 345 346 findPhoneNumber("", NO_NUMBERS); 347 findPhoneNumber(" ", NO_NUMBERS); 348 findPhoneNumber("123", NO_NUMBERS); 349 findPhoneNumber("how much wood", NO_NUMBERS); 350 findPhoneNumber("abc1-650-555-1212", NO_NUMBERS); 351 findPhoneNumber("abc 5551212 def", new String[] { "5551212" }); 352 findPhoneNumber("1234567", NO_NUMBERS); 353 findPhoneNumber(" 2345678 ", new String[] { "2345678" }); 354 findPhoneNumber("1234567890", NO_NUMBERS); 355 findPhoneNumber("12345678901", new String[] { "12345678901" }); 356 findPhoneNumber("123456789012", NO_NUMBERS); 357 findPhoneNumber("+1-555-1212", NO_NUMBERS); 358 findPhoneNumber("+1 (650) 555-1212", new String[] { "+1 (650) 555-1212" }); 359 findPhoneNumber("(650) 555-1212, (650) 555-1213", 360 new String[] { "(650) 555-1212", "(650) 555-1213" }); 361 findPhoneNumber("Call 555-1212, 555-1213 and also 555-1214.", 362 new String[] { "555-1212", "555-1213", "555-1214." }); 363 findPhoneNumber("555-1212,555-1213,555-1214", new String[] { "555-1212" }); 364 findPhoneNumber("123 (650) 555-1212", new String[] { "(650) 555-1212" }); 365 findPhoneNumber("1-650-555-1212", new String[] { "1-650-555-1212" }); 366 findPhoneNumber("1650-555-1212", new String[] { "1650-555-1212" }); 367 findPhoneNumber("1650 555-1212", new String[] { "1650 555-1212" }); 368 findPhoneNumber("1650/555-1212", NO_NUMBERS); 369 findPhoneNumber("1650-555 1212", NO_NUMBERS); 370 findPhoneNumber("8-650-555-1212", NO_NUMBERS); 371 findPhoneNumber("8 650-555-1212", new String[] { "650-555-1212" }); 372 findPhoneNumber("650.555.1212", new String[] { "650.555.1212" }); 373 findPhoneNumber(" *#650.555.1212#*!", new String[] { "*#650.555.1212#*" }); 374 findPhoneNumber("555.1212", new String[] { "555.1212" }); 375 findPhoneNumber("6505551212 x123, 555-1212", new String[] { "6505551212", "555-1212" }); 376 findPhoneNumber("6505551212x123", new String[] { "6505551212" }); 377 findPhoneNumber("http://example.com/6505551212/", NO_NUMBERS); 378 findPhoneNumber("Mountain View, CA 94043 (650) 555-1212", new String[]{ "(650) 555-1212" }); 379 findPhoneNumber("New York, NY 10001-0001", NO_NUMBERS); 380 } 381 382 /** 383 * Finds the numbers in a block of text, and checks to see if the positions of the numbers 384 * match the expected values. 385 * 386 * @param text The text to search. 387 * @param matches Pairs of start/end positions. 388 */ findPhoneNumber(String text, String[] matches)389 private static void findPhoneNumber(String text, String[] matches) { 390 int[] results = Utils.findNanpPhoneNumbers(text); 391 392 assertEquals(0, results.length % 2); 393 394 if (results.length / 2 != matches.length) { 395 fail("Text '" + text + "': expected " + matches.length 396 + " matches, found " + results.length / 2); 397 } 398 399 for (int i = 0; i < results.length / 2; i++) { 400 CharSequence seq = text.subSequence(results[i*2], results[i*2 + 1]); 401 assertEquals(matches[i], seq); 402 } 403 } 404 405 /** 406 * Tests the linkify section of event locations. 407 */ 408 @SmallTest testExtendedLinkify()409 public void testExtendedLinkify() { 410 final URLSpan[] NO_LINKS = new URLSpan[] {}; 411 URLSpan span_tel01 = new URLSpan("tel:6505551234"); 412 URLSpan span_tel02 = new URLSpan("tel:5555678"); 413 URLSpan span_tel03 = new URLSpan("tel:+16505551234"); 414 URLSpan span_tel04 = new URLSpan("tel:16505551234"); 415 URLSpan span_web = new URLSpan("http://www.google.com"); 416 URLSpan span_geo01 = 417 new URLSpan("geo:0,0?q=1600+Amphitheatre+Parkway%2C+Mountain+View+CA+94043"); 418 URLSpan span_geo02 = 419 new URLSpan("geo:0,0?q=37.422081°, -122.084576°"); 420 URLSpan span_geo03 = 421 new URLSpan("geo:0,0?q=37.422081,-122.084576"); 422 URLSpan span_geo04 = 423 new URLSpan("geo:0,0?q=+37°25'19.49\", -122°5'4.47\""); 424 URLSpan span_geo05 = 425 new URLSpan("geo:0,0?q=37°25'19.49\"N, 122°5'4.47\"W"); 426 URLSpan span_geo06 = 427 new URLSpan("geo:0,0?q=N 37° 25' 19.49\", W 122° 5' 4.47\""); 428 URLSpan span_geo07 = new URLSpan("geo:0,0?q=non-specified address"); 429 430 431 // First test without the last-ditch geo attempt. 432 // Phone spans. 433 findLinks("", NO_LINKS, false); 434 findLinks("(650) 555-1234", new URLSpan[]{span_tel01}, false); 435 findLinks("94043", NO_LINKS, false); 436 findLinks("123456789012", NO_LINKS, false); 437 findLinks("+1 (650) 555-1234", new URLSpan[]{span_tel03}, false); 438 findLinks("(650) 555 1234", new URLSpan[]{span_tel01}, false); 439 findLinks("1-650-555-1234", new URLSpan[]{span_tel04}, false); 440 findLinks("*#650.555.1234#*!", new URLSpan[]{span_tel01}, false); 441 findLinks("555.5678", new URLSpan[]{span_tel02}, false); 442 443 // Web spans. 444 findLinks("http://www.google.com", new URLSpan[]{span_web}, false); 445 446 // Geo spans. 447 findLinks("1600 Amphitheatre Parkway, Mountain View CA 94043", 448 new URLSpan[]{span_geo01}, false); 449 findLinks("37.422081°, -122.084576°", new URLSpan[]{span_geo02}, false); 450 findLinks("37.422081,-122.084576", new URLSpan[]{span_geo03}, false); 451 findLinks("+37°25'19.49\", -122°5'4.47\"", new URLSpan[]{span_geo04}, false); 452 findLinks("37°25'19.49\"N, 122°5'4.47\"W", new URLSpan[]{span_geo05}, false); 453 findLinks("N 37° 25' 19.49\", W 122° 5' 4.47\"", new URLSpan[]{span_geo06}, false); 454 455 // Multiple spans. 456 findLinks("(650) 555-1234 1600 Amphitheatre Parkway, Mountain View CA 94043", 457 new URLSpan[]{span_tel01, span_geo01}, false); 458 findLinks("(650) 555-1234, 555-5678", new URLSpan[]{span_tel01, span_tel02}, false); 459 460 461 // Now test using the last-ditch geo attempt. 462 findLinks("", NO_LINKS, true); 463 findLinks("(650) 555-1234", new URLSpan[]{span_tel01}, true); 464 findLinks("http://www.google.com", new URLSpan[]{span_web}, true); 465 findLinks("1600 Amphitheatre Parkway, Mountain View CA 94043", 466 new URLSpan[]{span_geo01}, true); 467 findLinks("37.422081°, -122.084576°", new URLSpan[]{span_geo02}, true); 468 findLinks("37.422081,-122.084576", new URLSpan[]{span_geo03}, true); 469 findLinks("+37°25'19.49\", -122°5'4.47\"", new URLSpan[]{span_geo04}, true); 470 findLinks("37°25'19.49\"N, 122°5'4.47\"W", new URLSpan[]{span_geo05}, true); 471 findLinks("N 37° 25' 19.49\", W 122° 5' 4.47\"", new URLSpan[]{span_geo06}, true); 472 findLinks("non-specified address", new URLSpan[]{span_geo07}, true); 473 } 474 findLinks(String text, URLSpan[] matches, boolean lastDitchGeo)475 private static void findLinks(String text, URLSpan[] matches, boolean lastDitchGeo) { 476 Spannable spanText = Utils.extendedLinkify(text, lastDitchGeo); 477 URLSpan[] spansFound = spanText.getSpans(0, spanText.length(), URLSpan.class); 478 assertEquals(matches.length, spansFound.length); 479 480 // Make sure the expected matches list of URLs is the same as that returned by linkify. 481 ArrayList<URLSpan> matchesArrayList = new ArrayList<URLSpan>(Arrays.asList(matches)); 482 for (URLSpan spanFound : spansFound) { 483 Iterator<URLSpan> matchesIt = matchesArrayList.iterator(); 484 boolean removed = false; 485 while (matchesIt.hasNext()) { 486 URLSpan match = matchesIt.next(); 487 if (match.getURL().equals(spanFound.getURL())) { 488 matchesIt.remove(); 489 removed = true; 490 break; 491 } 492 } 493 if (!removed) { 494 // If a match was not found for the current spanFound, the lists aren't equal. 495 fail("No match found for span: "+spanFound.getURL()); 496 } 497 } 498 499 // As a sanity check, ensure the matches list is empty, as each item should have been 500 // removed by going through the spans returned by linkify. 501 assertTrue(matchesArrayList.isEmpty()); 502 } 503 504 @SmallTest testGetDisplayedDatetime_differentYear()505 public void testGetDisplayedDatetime_differentYear() { 506 // 4/12/2000 5pm - 4/12/2000 6pm 507 long start = createTimeInMillis(0, 0, 17, 12, 3, 2000); 508 long end = createTimeInMillis(0, 0, 18, 12, 3, 2000); 509 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 510 false, dbUtils.getContext()); 511 assertEquals("Wednesday, April 12, 2000, 5:00PM \u2013 6:00PM", result); 512 513 // 12/31/2012 5pm - 1/1/2013 6pm 514 start = createTimeInMillis(0, 0, 17, 31, 11, 2012); 515 end = createTimeInMillis(0, 0, 18, 1, 0, 2013); 516 result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 517 false, dbUtils.getContext()); 518 assertEquals("Mon, Dec 31, 2012, 5:00PM – Tue, Jan 1, 2013, 6:00PM", result); 519 } 520 521 @SmallTest testGetDisplayedDatetime_sameYear()522 public void testGetDisplayedDatetime_sameYear() { 523 // 4/12/2012 5pm - 4/12/2012 6pm 524 long start = createTimeInMillis(0, 0, 17, 12, 3, 2012); 525 long end = createTimeInMillis(0, 0, 18, 12, 3, 2012); 526 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 527 false, dbUtils.getContext()); 528 assertEquals("Thursday, April 12, 2012, 5:00PM \u2013 6:00PM", result); 529 } 530 531 @SmallTest testGetDisplayedDatetime_today()532 public void testGetDisplayedDatetime_today() { 533 // 4/10/2012 5pm - 4/10/2012 6pm 534 long start = createTimeInMillis(0, 0, 17, NOW_DAY, NOW_MONTH, NOW_YEAR); 535 long end = createTimeInMillis(0, 0, 18, NOW_DAY, NOW_MONTH, NOW_YEAR); 536 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 537 false, dbUtils.getContext()); 538 assertEquals("Today at 5:00PM \u2013 6:00PM", result); 539 } 540 541 @SmallTest testGetDisplayedDatetime_todayMidnight()542 public void testGetDisplayedDatetime_todayMidnight() { 543 // 4/10/2012 5pm - 4/11/2012 12am 544 long start = createTimeInMillis(0, 0, 17, NOW_DAY, NOW_MONTH, NOW_YEAR); 545 long end = createTimeInMillis(0, 0, 0, NOW_DAY + 1, NOW_MONTH, NOW_YEAR); 546 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 547 false, dbUtils.getContext()); 548 assertEquals("Today at 5:00PM \u2013 midnight", result); 549 } 550 551 @SmallTest testGetDisplayedDatetime_tomorrow()552 public void testGetDisplayedDatetime_tomorrow() { 553 // 4/11/2012 12:01AM - 4/11/2012 11:59pm 554 long start = createTimeInMillis(0, 1, 0, NOW_DAY + 1, NOW_MONTH, NOW_YEAR); 555 long end = createTimeInMillis(0, 59, 23, NOW_DAY + 1, NOW_MONTH, NOW_YEAR); 556 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 557 false, dbUtils.getContext()); 558 assertEquals("Tomorrow at 12:01AM \u2013 11:59PM", result); 559 } 560 561 @SmallTest testGetDisplayedDatetime_yesterday()562 public void testGetDisplayedDatetime_yesterday() { 563 // 4/9/2012 5pm - 4/9/2012 6pm 564 long start = createTimeInMillis(0, 0, 17, 9, 3, 2012); 565 long end = createTimeInMillis(0, 0, 18, 9, 3, 2012); 566 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 567 false, dbUtils.getContext()); 568 assertEquals("Monday, April 9, 2012, 5:00PM \u2013 6:00PM", result); 569 } 570 571 @SmallTest testGetDisplayedDatetime_multiDay()572 public void testGetDisplayedDatetime_multiDay() { 573 // 4/10/2012 12:01AM - 4/11/2012 12:01AM 574 long start = createTimeInMillis(0, 1, 0, NOW_DAY, NOW_MONTH, NOW_YEAR); 575 long end = createTimeInMillis(0, 1, 0, NOW_DAY + 1, NOW_MONTH, NOW_YEAR); 576 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 577 false, dbUtils.getContext()); 578 assertEquals("Tue, Apr 10, 2012, 12:01AM \u2013 Wed, Apr 11, 2012, 12:01AM", result); 579 } 580 581 @SmallTest testGetDisplayedDatetime_allDay()582 public void testGetDisplayedDatetime_allDay() { 583 // 4/2/2012 12:00AM - 4/3/2012 12:00AM 584 long start = createTimeInMillis(0, 0, 0, 2, 3, NOW_YEAR, Time.TIMEZONE_UTC); 585 long end = createTimeInMillis(0, 0, 0, 3, 3, NOW_YEAR, Time.TIMEZONE_UTC); 586 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 587 true, dbUtils.getContext()); 588 assertEquals("Monday, April 2, 2012", result); 589 } 590 591 @SmallTest testGetDisplayedDatetime_allDayToday()592 public void testGetDisplayedDatetime_allDayToday() { 593 // 4/10/2012 12:00AM - 4/11/2012 12:00AM 594 long start = createTimeInMillis(0, 0, 0, NOW_DAY, NOW_MONTH, NOW_YEAR, Time.TIMEZONE_UTC); 595 long end = createTimeInMillis(0, 0, 0, NOW_DAY + 1, NOW_MONTH, NOW_YEAR, Time.TIMEZONE_UTC); 596 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 597 true, dbUtils.getContext()); 598 assertEquals("Today", result); 599 } 600 601 @SmallTest testGetDisplayedDatetime_allDayMultiday()602 public void testGetDisplayedDatetime_allDayMultiday() { 603 // 4/10/2012 12:00AM - 4/13/2012 12:00AM 604 long start = createTimeInMillis(0, 0, 0, NOW_DAY, NOW_MONTH, NOW_YEAR, Time.TIMEZONE_UTC); 605 long end = createTimeInMillis(0, 0, 0, NOW_DAY + 3, NOW_MONTH, NOW_YEAR, Time.TIMEZONE_UTC); 606 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, DEFAULT_TIMEZONE, 607 true, dbUtils.getContext()); 608 assertEquals("Tuesday, April 10, 2012 \u2013 Thursday, April 12, 2012", result); 609 } 610 611 @SmallTest testGetDisplayedDatetime_differentTimezone()612 public void testGetDisplayedDatetime_differentTimezone() { 613 String localTz = "America/New_York"; 614 String eventTz = "America/Los_Angeles"; 615 setTimezone(localTz); 616 617 // 4/12/2012 5pm - 4/12/2012 6pm (Pacific) 618 long start = createTimeInMillis(0, 0, 17, 12, 3, 2012, eventTz); 619 long end = createTimeInMillis(0, 0, 18, 12, 3, 2012, eventTz); 620 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, localTz, false, 621 dbUtils.getContext()); 622 assertEquals("Thursday, April 12, 2012, 8:00PM \u2013 9:00PM", result); 623 } 624 625 @SmallTest testGetDisplayedDatetime_allDayDiffTimezone()626 public void testGetDisplayedDatetime_allDayDiffTimezone() { 627 String localTz = "America/New_York"; 628 setTimezone(localTz); 629 630 // 4/2/2012 12:00AM - 4/3/2012 12:00AM 631 long start = createTimeInMillis(0, 0, 0, 2, 3, NOW_YEAR, Time.TIMEZONE_UTC); 632 long end = createTimeInMillis(0, 0, 0, 3, 3, NOW_YEAR, Time.TIMEZONE_UTC); 633 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, localTz, true, 634 dbUtils.getContext()); 635 assertEquals("Monday, April 2, 2012", result); 636 } 637 638 @SmallTest testGetDisplayedDatetime_allDayTomorrowDiffTimezone()639 public void testGetDisplayedDatetime_allDayTomorrowDiffTimezone() { 640 String localTz = "America/New_York"; 641 setTimezone(localTz); 642 643 // 4/2/2012 12:00AM - 4/3/2012 12:00AM 644 long start = createTimeInMillis(0, 0, 0, NOW_DAY + 1, NOW_MONTH, NOW_YEAR, 645 Time.TIMEZONE_UTC); 646 long end = createTimeInMillis(0, 0, 0, NOW_DAY + 2, NOW_MONTH, NOW_YEAR, 647 Time.TIMEZONE_UTC); 648 String result = Utils.getDisplayedDatetime(start, end, NOW_TIME, localTz, true, 649 dbUtils.getContext()); 650 assertEquals("Tomorrow", result); 651 } 652 653 // TODO: add tests for army time. 654 655 @SmallTest testGetDisplayedTimezone_sameTimezone()656 public void testGetDisplayedTimezone_sameTimezone() { 657 String localTz = "America/New_York"; 658 setTimezone(localTz); 659 660 // 4/12/2012 5pm 661 long start = createTimeInMillis(0, 0, 17, 12, 3, 2012, localTz); 662 assertNull(Utils.getDisplayedTimezone(start, localTz, localTz)); 663 } 664 665 @SmallTest testGetDisplayedTimezone_differentTimezone()666 public void testGetDisplayedTimezone_differentTimezone() { 667 String localTz = "America/New_York"; 668 String eventTz = "America/Los_Angeles"; 669 setTimezone(localTz); 670 671 // 1/12/2012 5pm (not daylight savings) 672 long start = createTimeInMillis(0, 0, 17, 12, 0, 2012, eventTz); 673 assertEquals("EST", Utils.getDisplayedTimezone(start, localTz, eventTz)); 674 } 675 676 @SmallTest testGetDisplayedTimezone_differentTimezoneDst()677 public void testGetDisplayedTimezone_differentTimezoneDst() { 678 String localTz = "America/New_York"; 679 String eventTz = "America/Los_Angeles"; 680 setTimezone(localTz); 681 682 // 4/12/2012 5pm (daylight savings) 683 long start = createTimeInMillis(0, 0, 17, 12, 3, 2012, eventTz); 684 assertEquals("EDT", Utils.getDisplayedTimezone(start, localTz, eventTz)); 685 } 686 } 687