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 static android.support.test.InstrumentationRegistry.getContext; 20import static org.junit.Assert.assertEquals; 21import static org.junit.Assert.assertTrue; 22 23import com.android.tv.data.Channel; 24import com.android.tv.recommendation.RecommendationUtils.ChannelRecordSortedMapHelper; 25import com.android.tv.recommendation.Recommender.Evaluator; 26import com.android.tv.testing.Utils; 27 28import org.junit.Before; 29 30import java.util.ArrayList; 31import java.util.List; 32 33/** 34 * Base test case for Recommendation Evaluator Unit tests. 35 */ 36public abstract class EvaluatorTestCase<T extends Evaluator> { 37 private static final long INVALID_CHANNEL_ID = -1; 38 39 private static final double SCORE_DELTA = 0.01; 40 41 private ChannelRecordSortedMapHelper mChannelRecordSortedMap; 42 private RecommendationDataManager mDataManager; 43 44 public T mEvaluator; 45 46 @Before 47 public void setUp() { 48 mChannelRecordSortedMap = new ChannelRecordSortedMapHelper(getContext()); 49 mDataManager = RecommendationUtils 50 .createMockRecommendationDataManager(mChannelRecordSortedMap); 51 Recommender mRecommender = new FakeRecommender(); 52 mEvaluator = createEvaluator(); 53 mEvaluator.setRecommender(mRecommender); 54 mChannelRecordSortedMap.setRecommender(mRecommender); 55 mChannelRecordSortedMap.resetRandom(Utils.createTestRandom()); 56 } 57 58 /** 59 * Each evaluator test has to create Evaluator in {@code mEvaluator}. 60 */ 61 public abstract T createEvaluator(); 62 63 public void addChannels(int numberOfChannels) { 64 mChannelRecordSortedMap.addChannels(numberOfChannels); 65 } 66 67 public Channel addChannel() { 68 return mChannelRecordSortedMap.addChannel(); 69 } 70 71 public void addRandomWatchLogs(long watchStartTimeMs, long watchEndTimeMs, 72 long maxWatchDurationMs) { 73 assertTrue(mChannelRecordSortedMap.addRandomWatchLogs(watchStartTimeMs, watchEndTimeMs, 74 maxWatchDurationMs)); 75 } 76 77 public void addWatchLog(long channelId, long watchStartTimeMs, long durationTimeMs) { 78 assertTrue(mChannelRecordSortedMap.addWatchLog(channelId, watchStartTimeMs, 79 durationTimeMs)); 80 } 81 82 public List<Long> getChannelIdListSorted() { 83 return new ArrayList<>(mChannelRecordSortedMap.keySet()); 84 } 85 86 public long getLatestWatchEndTimeMs() { 87 long latestWatchEndTimeMs = 0; 88 for (ChannelRecord channelRecord : mChannelRecordSortedMap.values()) { 89 latestWatchEndTimeMs = Math.max(latestWatchEndTimeMs, 90 channelRecord.getLastWatchEndTimeMs()); 91 } 92 return latestWatchEndTimeMs; 93 } 94 95 /** 96 * Check whether scores of each channels are valid. 97 */ 98 protected void assertChannelScoresValid() { 99 assertEqualScores(Evaluator.NOT_RECOMMENDED, 100 mEvaluator.evaluateChannel(INVALID_CHANNEL_ID)); 101 assertEqualScores(Evaluator.NOT_RECOMMENDED, 102 mEvaluator.evaluateChannel(mChannelRecordSortedMap.size())); 103 104 for (long channelId : mChannelRecordSortedMap.keySet()) { 105 double score = mEvaluator.evaluateChannel(channelId); 106 assertTrue("Channel " + channelId + " score of " + score + "is not valid", 107 score == Evaluator.NOT_RECOMMENDED || (0.0 <= score && score <= 1.0)); 108 } 109 } 110 111 /** 112 * Notify that loading channels and watch logs are finished. 113 */ 114 protected void notifyChannelAndWatchLogLoaded() { 115 mEvaluator.onChannelRecordListChanged(new ArrayList<>(mChannelRecordSortedMap.values())); 116 } 117 118 void assertEqualScores(double expected, double actual) { 119 assertEquals(expected, actual, SCORE_DELTA); 120 } 121 122 void assertEqualScores(String message, double expected, double actual) { 123 assertEquals(message, expected, actual, SCORE_DELTA); 124 } 125 126 private class FakeRecommender extends Recommender { 127 public FakeRecommender() { 128 super(new Recommender.Listener() { 129 @Override 130 public void onRecommenderReady() { 131 } 132 133 @Override 134 public void onRecommendationChanged() { 135 } 136 }, true, mDataManager); 137 } 138 139 @Override 140 public ChannelRecord getChannelRecord(long channelId) { 141 return mChannelRecordSortedMap.get(channelId); 142 } 143 } 144} 145