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