RoutineWatchEvaluatorTest.java revision 816a4be1a0f34f6a48877c8afd3dbbca19eac435
1/*
2 * Copyright (C) 2015 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
17package com.android.tv.recommendation;
18
19import android.test.MoreAsserts;
20
21import com.android.tv.data.Program;
22import com.android.tv.recommendation.RoutineWatchEvaluator.ProgramTime;
23
24import java.util.Calendar;
25import java.util.List;
26import java.util.concurrent.TimeUnit;
27
28public class RoutineWatchEvaluatorTest extends EvaluatorTestCase<RoutineWatchEvaluator> {
29
30    public RoutineWatchEvaluator createEvaluator() {
31        return new RoutineWatchEvaluator();
32    }
33
34    public void testSplitTextToWords() {
35        assertSplitTextToWords("");
36        assertSplitTextToWords("Google", "Google");
37        assertSplitTextToWords("The Big Bang Theory", "The", "Big", "Bang", "Theory");
38        assertSplitTextToWords("Hello, world!", "Hello", "world");
39        assertSplitTextToWords("Adam's Rib", "Adam's", "Rib");
40        assertSplitTextToWords("G.I. Joe", "G.I", "Joe");
41        assertSplitTextToWords("A.I.", "A.I");
42    }
43
44    public void testCalculateMaximumMatchedWordSequenceLength() {
45        assertMaximumMatchedWordSequenceLength(0, "", "Google");
46        assertMaximumMatchedWordSequenceLength(2, "The Big Bang Theory", "Big Bang");
47        assertMaximumMatchedWordSequenceLength(2, "The Big Bang Theory", "Theory Of Big Bang");
48        assertMaximumMatchedWordSequenceLength(4, "The Big Bang Theory", "The Big Bang Theory");
49        assertMaximumMatchedWordSequenceLength(1, "Modern Family", "Family Guy");
50        assertMaximumMatchedWordSequenceLength(1, "The Simpsons", "The Walking Dead");
51        assertMaximumMatchedWordSequenceLength(3, "Game Of Thrones 1", "Game Of Thrones 6");
52        assertMaximumMatchedWordSequenceLength(0, "Dexter", "Friends");
53    }
54
55    public void testProgramTime_createFromProgram() {
56        Calendar time = Calendar.getInstance();
57        int todayDayOfWeek = time.get(Calendar.DAY_OF_WEEK);
58        // Value of DayOfWeek is between 1 and 7 (inclusive).
59        int tomorrowDayOfWeek = (todayDayOfWeek % 7) + 1;
60
61        // Today 00:00 - 01:00.
62        ProgramTime programTimeToday0000_0100 = ProgramTime.createFromProgram(
63                createDummyProgram(todayAtHourMin(0, 0), TimeUnit.HOURS.toMillis(1)));
64        assertProgramTime(todayDayOfWeek, hourMinuteToSec(0, 0), hourMinuteToSec(1, 0),
65                programTimeToday0000_0100);
66
67        // Today 23:30 - 24:30.
68        ProgramTime programTimeToday2330_2430 = ProgramTime.createFromProgram(
69                createDummyProgram(todayAtHourMin(23, 30), TimeUnit.HOURS.toMillis(1)));
70        assertProgramTime(todayDayOfWeek, hourMinuteToSec(23, 30), hourMinuteToSec(24, 30),
71                programTimeToday2330_2430);
72
73        // Tomorrow 00:00 - 01:00.
74        ProgramTime programTimeTomorrow0000_0100 = ProgramTime.createFromProgram(
75                createDummyProgram(tomorrowAtHourMin(0, 0), TimeUnit.HOURS.toMillis(1)));
76        assertProgramTime(tomorrowDayOfWeek, hourMinuteToSec(0, 0), hourMinuteToSec(1, 0),
77                programTimeTomorrow0000_0100);
78
79        // Tomorrow 23:30 - 24:30.
80        ProgramTime programTimeTomorrow2330_2430 = ProgramTime.createFromProgram(
81                createDummyProgram(tomorrowAtHourMin(23, 30), TimeUnit.HOURS.toMillis(1)));
82        assertProgramTime(tomorrowDayOfWeek, hourMinuteToSec(23, 30), hourMinuteToSec(24, 30),
83                programTimeTomorrow2330_2430);
84
85        // Today 18:00 - Tomorrow 12:00.
86        ProgramTime programTimeToday1800_3600 = ProgramTime.createFromProgram(
87                createDummyProgram(todayAtHourMin(18, 0), TimeUnit.HOURS.toMillis(18)));
88        // Maximum duration of ProgramTime is 12 hours.
89        // So, this program looks like it ends at Tomorrow 06:00 (30:00).
90        assertProgramTime(todayDayOfWeek, hourMinuteToSec(18, 0), hourMinuteToSec(30, 0),
91                programTimeToday1800_3600);
92    }
93
94    public void testCalculateOverlappedIntervalScore() {
95        // Today 21:00 - 24:00.
96        ProgramTime programTimeToday2100_2400 = ProgramTime.createFromProgram(
97                createDummyProgram(todayAtHourMin(21, 0), TimeUnit.HOURS.toMillis(3)));
98        // Today 22:00 - 01:00.
99        ProgramTime programTimeToday2200_0100 = ProgramTime.createFromProgram(
100                createDummyProgram(todayAtHourMin(22, 0), TimeUnit.HOURS.toMillis(3)));
101        // Tomorrow 00:00 - 03:00.
102        ProgramTime programTimeTomorrow0000_0300 = ProgramTime.createFromProgram(
103                createDummyProgram(tomorrowAtHourMin(0, 0), TimeUnit.HOURS.toMillis(3)));
104        // Tomorrow 20:00 - Tomorrow 23:00.
105        ProgramTime programTimeTomorrow2000_2300 = ProgramTime.createFromProgram(
106                createDummyProgram(tomorrowAtHourMin(20, 0), TimeUnit.HOURS.toMillis(3)));
107
108        // Check intersection time and commutative law in all cases.
109        int oneHourInSec = hourMinuteToSec(1, 0);
110        assertOverlappedIntervalScore(2 * oneHourInSec, true,
111                programTimeToday2100_2400, programTimeToday2200_0100);
112        assertOverlappedIntervalScore(0, false,
113                programTimeToday2100_2400, programTimeTomorrow0000_0300);
114        assertOverlappedIntervalScore(2 * oneHourInSec, false,
115                programTimeToday2100_2400, programTimeTomorrow2000_2300);
116        assertOverlappedIntervalScore(oneHourInSec, true,
117                programTimeToday2200_0100, programTimeTomorrow0000_0300);
118        assertOverlappedIntervalScore(oneHourInSec, false,
119                programTimeToday2200_0100, programTimeTomorrow2000_2300);
120        assertOverlappedIntervalScore(0, false,
121                programTimeTomorrow0000_0300, programTimeTomorrow2000_2300);
122    }
123
124    public void testGetTimeOfDayInSec() {
125        // Time was set as 00:00:00. So, getTimeOfDay must returns 0 (= 0 * 60 * 60 + 0 * 60 + 0).
126        assertEquals("TimeOfDayInSec", hourMinuteToSec(0, 0),
127                RoutineWatchEvaluator.getTimeOfDayInSec(todayAtHourMin(0, 0)));
128
129        // Time was set as 23:59:59. So, getTimeOfDay must returns 23 * 60 + 60 + 59 * 60 + 59.
130        assertEquals("TimeOfDayInSec", hourMinuteSecondToSec(23, 59, 59),
131                RoutineWatchEvaluator.getTimeOfDayInSec(todayAtHourMinSec(23, 59, 59)));
132    }
133
134    private void assertSplitTextToWords(String text, String... words) {
135        List<String> wordList = RoutineWatchEvaluator.splitTextToWords(text);
136        MoreAsserts.assertContentsInOrder(wordList, words);
137    }
138
139    private void assertMaximumMatchedWordSequenceLength(int expectedLength,
140            String text1, String text2) {
141        List<String> wordList1 = RoutineWatchEvaluator.splitTextToWords(text1);
142        List<String> wordList2 = RoutineWatchEvaluator.splitTextToWords(text2);
143        assertEquals("MaximumMatchedWordSequenceLength", expectedLength,
144                mEvaluator.calculateMaximumMatchedWordSequenceLength(wordList1, wordList2));
145        assertEquals("MaximumMatchedWordSequenceLength", expectedLength,
146                mEvaluator.calculateMaximumMatchedWordSequenceLength(wordList2, wordList1));
147    }
148
149    private void assertProgramTime(int expectedWeekDay, int expectedStartTimeOfDayInSec,
150            int expectedEndTimeOfDayInSec, ProgramTime actualProgramTime) {
151        assertEquals("Weekday", expectedWeekDay, actualProgramTime.weekDay);
152        assertEquals("StartTimeOfDayInSec",
153                expectedStartTimeOfDayInSec, actualProgramTime.startTimeOfDayInSec);
154        assertEquals("EndTimeOfDayInSec",
155                expectedEndTimeOfDayInSec, actualProgramTime.endTimeOfDayInSec);
156    }
157
158    private void assertOverlappedIntervalScore(int expectedSeconds, boolean overlappedOnSameDay,
159            ProgramTime t1, ProgramTime t2) {
160        double score = (double) expectedSeconds;
161        if (!overlappedOnSameDay) {
162            score *= RoutineWatchEvaluator.MULTIPLIER_FOR_UNMATCHED_DAY_OF_WEEK;
163        }
164        // Two tests for testing commutative law.
165        assertEquals("OverlappedIntervalScore",
166                score, mEvaluator.calculateOverlappedIntervalScore(t1, t2));
167        assertEquals("OverlappedIntervalScore",
168                score, mEvaluator.calculateOverlappedIntervalScore(t2, t1));
169    }
170
171    private int hourMinuteToSec(int hour, int minute) {
172        return hourMinuteSecondToSec(hour, minute, 0);
173    }
174
175    private int hourMinuteSecondToSec(int hour, int minute, int second) {
176        return hour * 60 * 60 + minute * 60 + second;
177    }
178
179    private Calendar todayAtHourMin(int hour, int minute) {
180        return todayAtHourMinSec(hour, minute, 0);
181    }
182
183    private Calendar todayAtHourMinSec(int hour, int minute, int second) {
184        Calendar time = Calendar.getInstance();
185        time.set(Calendar.HOUR_OF_DAY, hour);
186        time.set(Calendar.MINUTE, minute);
187        time.set(Calendar.SECOND, second);
188        return time;
189    }
190
191    private Calendar tomorrowAtHourMin(int hour, int minute) {
192        Calendar time = todayAtHourMin(hour, minute);
193        time.add(Calendar.DATE, 1);
194        return time;
195    }
196
197    private Program createDummyProgram(Calendar startTime, long programDurationMs) {
198        long startTimeMs = startTime.getTimeInMillis();
199
200        return new Program.Builder()
201                .setStartTimeUtcMillis(startTimeMs)
202                .setEndTimeUtcMillis(startTimeMs + programDurationMs)
203                .build();
204    }
205}
206