Partial migration of data package to Kotlin

This commit is contained in:
inorichi
2016-02-17 01:44:21 +01:00
parent 110df59197
commit c0452038f7
60 changed files with 2012 additions and 1856 deletions

View File

@@ -0,0 +1,15 @@
package eu.kanade.tachiyomi;
public class CustomBuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "eu.kanade.tachiyomi";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "";
public static final int VERSION_CODE = 4;
public static final String VERSION_NAME = "0.1.3";
// Fields from default config.
public static final String BUILD_TIME = "2016-02-19T14:49Z";
public static final String COMMIT_COUNT = "482";
public static final String COMMIT_SHA = "e52c498";
public static final boolean INCLUDE_UPDATER = true;
}

View File

@@ -1,9 +1,24 @@
package eu.kanade.tachiyomi;
import eu.kanade.tachiyomi.injection.component.DaggerAppComponent;
import eu.kanade.tachiyomi.injection.module.AppModule;
public class TestApp extends App {
@Override
protected DaggerAppComponent.Builder prepareAppComponent() {
return DaggerAppComponent.builder()
.appModule(new AppModule(this))
.dataModule(new TestDataModule());
}
@Override
protected void setupEventBus() {
// Do nothing
}
@Override
protected void setupAcra() {
// Do nothing
}
}

View File

@@ -0,0 +1,29 @@
package eu.kanade.tachiyomi;
import android.app.Application;
import org.mockito.Mockito;
import eu.kanade.tachiyomi.data.database.DatabaseHelper;
import eu.kanade.tachiyomi.data.network.NetworkHelper;
import eu.kanade.tachiyomi.data.source.SourceManager;
import eu.kanade.tachiyomi.injection.module.DataModule;
public class TestDataModule extends DataModule {
@Override
public DatabaseHelper provideDatabaseHelper(Application app) {
return Mockito.mock(DatabaseHelper.class, Mockito.RETURNS_DEEP_STUBS);
}
@Override
public NetworkHelper provideNetworkHelper(Application app) {
return Mockito.mock(NetworkHelper.class);
}
@Override
public SourceManager provideSourceManager(Application app) {
return Mockito.mock(SourceManager.class, Mockito.RETURNS_DEEP_STUBS);
}
}

View File

@@ -1,16 +0,0 @@
package eu.kanade.tachiyomi;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by len on 1/10/15.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseModule {
Class value();
}

View File

@@ -0,0 +1,140 @@
package eu.kanade.tachiyomi.data.library;
import android.app.AlarmManager;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.SystemClock;
import org.assertj.core.data.Offset;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowAlarmManager;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.shadows.ShadowPendingIntent;
import eu.kanade.tachiyomi.CustomBuildConfig;
import eu.kanade.tachiyomi.data.preference.PreferencesHelper;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.spy;
import static org.robolectric.Shadows.shadowOf;
@Config(constants = CustomBuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP)
@RunWith(RobolectricGradleTestRunner.class)
public class LibraryUpdateAlarmTest {
ShadowApplication app;
Context context;
ShadowAlarmManager alarmManager;
@Before
public void setup() {
app = ShadowApplication.getInstance();
context = spy(app.getApplicationContext());
alarmManager = shadowOf((AlarmManager) context.getSystemService(Context.ALARM_SERVICE));
}
@Test
public void testLibraryIntentHandling() {
Intent intent = new Intent(LibraryUpdateAlarm.LIBRARY_UPDATE_ACTION);
assertThat(app.hasReceiverForIntent(intent)).isTrue();
}
@Test
public void testAlarmIsNotStarted() {
assertThat(alarmManager.getNextScheduledAlarm()).isNull();
}
@Test
public void testAlarmIsNotStartedWhenBootReceivedAndSettingZero() {
LibraryUpdateAlarm alarm = new LibraryUpdateAlarm();
alarm.onReceive(context, new Intent(Intent.ACTION_BOOT_COMPLETED));
assertThat(alarmManager.getNextScheduledAlarm()).isNull();
}
@Test
public void testAlarmIsStartedWhenBootReceivedAndSettingNotZero() {
PreferencesHelper prefs = new PreferencesHelper(context);
prefs.libraryUpdateInterval().set(1);
LibraryUpdateAlarm alarm = new LibraryUpdateAlarm();
alarm.onReceive(context, new Intent(Intent.ACTION_BOOT_COMPLETED));
assertThat(alarmManager.getNextScheduledAlarm()).isNotNull();
}
@Test
public void testOnlyOneAlarmExists() {
PreferencesHelper prefs = new PreferencesHelper(context);
prefs.libraryUpdateInterval().set(1);
LibraryUpdateAlarm.startAlarm(context);
LibraryUpdateAlarm.startAlarm(context);
LibraryUpdateAlarm.startAlarm(context);
assertThat(alarmManager.getScheduledAlarms()).hasSize(1);
}
@Test
public void testLibraryWillBeUpdatedWhenAlarmFired() {
PreferencesHelper prefs = new PreferencesHelper(context);
prefs.libraryUpdateInterval().set(1);
Intent expectedIntent = new Intent(context, LibraryUpdateAlarm.class);
expectedIntent.setAction(LibraryUpdateAlarm.LIBRARY_UPDATE_ACTION);
LibraryUpdateAlarm.startAlarm(context);
ShadowAlarmManager.ScheduledAlarm scheduledAlarm = alarmManager.getNextScheduledAlarm();
ShadowPendingIntent pendingIntent = shadowOf(scheduledAlarm.operation);
assertThat(pendingIntent.isBroadcastIntent()).isTrue();
assertThat(pendingIntent.getSavedIntents()).hasSize(1);
assertThat(expectedIntent.getComponent()).isEqualTo(pendingIntent.getSavedIntents()[0].getComponent());
assertThat(expectedIntent.getAction()).isEqualTo(pendingIntent.getSavedIntents()[0].getAction());
}
@Test
public void testLibraryUpdateServiceIsStartedWhenUpdateIntentIsReceived() {
Intent intent = new Intent(context, LibraryUpdateService.class);
assertThat(app.getNextStartedService()).isNotEqualTo(intent);
LibraryUpdateAlarm alarm = new LibraryUpdateAlarm();
alarm.onReceive(context, new Intent(LibraryUpdateAlarm.LIBRARY_UPDATE_ACTION));
assertThat(app.getNextStartedService()).isEqualTo(intent);
}
@Test
public void testReceiverDoesntReactToNullActions() {
PreferencesHelper prefs = new PreferencesHelper(context);
prefs.libraryUpdateInterval().set(1);
Intent intent = new Intent(context, LibraryUpdateService.class);
LibraryUpdateAlarm alarm = new LibraryUpdateAlarm();
alarm.onReceive(context, new Intent());
assertThat(app.getNextStartedService()).isNotEqualTo(intent);
assertThat(alarmManager.getScheduledAlarms()).hasSize(0);
}
@Test
public void testAlarmFiresCloseToDesiredTime() {
int hours = 2;
LibraryUpdateAlarm.startAlarm(context, hours);
long shouldRunAt = SystemClock.elapsedRealtime() + (hours * 60 * 60 * 1000);
// Margin error of 3 seconds
Offset<Long> offset = Offset.offset(3 * 1000L);
assertThat(alarmManager.getNextScheduledAlarm().triggerAtTime).isCloseTo(shouldRunAt, offset);
}
}

View File

@@ -0,0 +1,130 @@
package eu.kanade.tachiyomi.data.library;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.util.Pair;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
import java.util.ArrayList;
import java.util.List;
import eu.kanade.tachiyomi.CustomBuildConfig;
import eu.kanade.tachiyomi.data.database.models.Chapter;
import eu.kanade.tachiyomi.data.database.models.Manga;
import eu.kanade.tachiyomi.data.source.base.Source;
import rx.Observable;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@Config(constants = CustomBuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP)
@RunWith(RobolectricGradleTestRunner.class)
public class LibraryUpdateServiceTest {
ShadowApplication app;
Context context;
LibraryUpdateService service;
Source source;
@Before
public void setup() {
app = ShadowApplication.getInstance();
context = app.getApplicationContext();
service = Robolectric.setupService(LibraryUpdateService.class);
source = mock(Source.class);
when(service.sourceManager.get(anyInt())).thenReturn(source);
}
@Test
public void testStartCommand() {
service.onStartCommand(new Intent(), 0, 0);
verify(service.db).getFavoriteMangas();
}
@Test
public void testLifecycle() {
// Smoke test
Robolectric.buildService(LibraryUpdateService.class)
.attach()
.create()
.startCommand(0, 0)
.destroy()
.get();
}
@Test
public void testUpdateManga() {
Manga manga = Manga.create("manga1");
List<Chapter> chapters = createChapters("/chapter1", "/chapter2");
when(source.pullChaptersFromNetwork(manga.url)).thenReturn(Observable.just(chapters));
when(service.db.insertOrRemoveChapters(manga, chapters))
.thenReturn(Observable.just(Pair.create(2, 0)));
service.updateManga(manga).subscribe();
verify(service.db).insertOrRemoveChapters(manga, chapters);
}
@Test
public void testContinuesUpdatingWhenAMangaFails() {
Manga manga1 = Manga.create("manga1");
Manga manga2 = Manga.create("manga2");
Manga manga3 = Manga.create("manga3");
List<Manga> favManga = createManga("manga1", "manga2", "manga3");
List<Chapter> chapters = createChapters("/chapter1", "/chapter2");
List<Chapter> chapters3 = createChapters("/achapter1", "/achapter2");
when(service.db.getFavoriteMangas().executeAsBlocking()).thenReturn(favManga);
// One of the updates will fail
when(source.pullChaptersFromNetwork("manga1")).thenReturn(Observable.just(chapters));
when(source.pullChaptersFromNetwork("manga2")).thenReturn(Observable.error(new Exception()));
when(source.pullChaptersFromNetwork("manga3")).thenReturn(Observable.just(chapters3));
when(service.db.insertOrRemoveChapters(manga1, chapters)).thenReturn(Observable.just(Pair.create(2, 0)));
when(service.db.insertOrRemoveChapters(manga3, chapters)).thenReturn(Observable.just(Pair.create(2, 0)));
service.updateLibrary().subscribe();
// There are 3 network attempts and 2 insertions (1 request failed)
verify(source, times(3)).pullChaptersFromNetwork(any());
verify(service.db, times(2)).insertOrRemoveChapters(any(), any());
verify(service.db, never()).insertOrRemoveChapters(eq(manga2), any());
}
private List<Chapter> createChapters(String... urls) {
List<Chapter> list = new ArrayList<>();
for (String url : urls) {
Chapter c = Chapter.create();
c.url = url;
list.add(c);
}
return list;
}
private List<Manga> createManga(String... urls) {
List<Manga> list = new ArrayList<>();
for (String url : urls) {
Manga m = Manga.create(url);
list.add(m);
}
return list;
}
}