Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
hitherejoe committed Dec 30, 2017
0 parents commit 8ded9ac
Show file tree
Hide file tree
Showing 46 changed files with 1,069 additions and 0 deletions.
20 changes: 20 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
*.apk
*.ap_
*.dex
*.class
bin/
gen/
out/
build/
workspace.xml
.idea
local.properties
ks.properties
.classpath
.project
.DS_Store
lint.xml
protected_strings.xml
.gradle
/dist
*.iml
3 changes: 3 additions & 0 deletions Domain/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/build
*iml
*.iml
17 changes: 17 additions & 0 deletions Domain/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apply plugin: 'kotlin'

dependencies {
def domainDependencies = rootProject.ext.domainDependencies
def domainTestDependencies = rootProject.ext.domainTestDependencies

implementation domainDependencies.javaxAnnotation
implementation domainDependencies.javaxInject
implementation domainDependencies.rxJava

testImplementation domainTestDependencies.junit
testImplementation domainTestDependencies.mockito
testImplementation domainTestDependencies.assertj
}

sourceCompatibility = "1.6"
targetCompatibility = "1.6"
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package co.joebirch.domain.executor

import io.reactivex.Scheduler

interface PostExecutionThread {
val scheduler: Scheduler
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package co.joebirch.domain.interactor

import co.joebirch.domain.executor.PostExecutionThread
import io.reactivex.Completable
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.observers.DisposableCompletableObserver
import io.reactivex.schedulers.Schedulers

abstract class CompletableUseCase<in Params> constructor(
private val postExecutionThread: PostExecutionThread) {

private val disposables = CompositeDisposable()

protected abstract fun buildUseCaseCompletable(params: Params? = null): Completable

open fun execute(observer: DisposableCompletableObserver, params: Params? = null) {
val completable = this.buildUseCaseCompletable(params)
.subscribeOn(Schedulers.io())
.observeOn(postExecutionThread.scheduler)
addDisposable(completable.subscribeWith(observer))
}

fun addDisposable(disposable: Disposable) {
disposables.add(disposable)
}

fun dispose() {
if (!disposables.isDisposed) disposables.dispose()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package co.joebirch.domain.interactor

import co.joebirch.domain.executor.PostExecutionThread
import io.reactivex.Single
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.observers.DisposableSingleObserver
import io.reactivex.schedulers.Schedulers

abstract class SingleUseCase<T, in Params> constructor(
private val postExecutionThread: PostExecutionThread) {

private val disposables = CompositeDisposable()

protected abstract fun buildUseCaseSingle(params: Params? = null): Single<T>

open fun execute(singleObserver: DisposableSingleObserver<T>, params: Params? = null) {
val single = this.buildUseCaseSingle(params)
.subscribeOn(Schedulers.io())
.observeOn(postExecutionThread.scheduler)
addDisposable(single.subscribeWith(singleObserver))
}

fun addDisposable(disposable: Disposable) {
disposables.add(disposable)
}

fun dispose() {
if (!disposables.isDisposed) disposables.dispose()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package co.joebirch.domain.interactor.bookmarked

import co.joebirch.domain.executor.PostExecutionThread
import co.joebirch.domain.interactor.SingleUseCase
import co.joebirch.domain.model.Project
import co.joebirch.domain.repository.ProjectsRepository
import io.reactivex.Single
import javax.inject.Inject

open class GetBookmarkedProjects @Inject constructor(
private val projectsRepository: ProjectsRepository,
postExecutionThread: PostExecutionThread)
: SingleUseCase<List<Project>, Nothing>(postExecutionThread) {

public override fun buildUseCaseSingle(params: Nothing?): Single<List<Project>> {
return projectsRepository.getBookmarkedProjects()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package co.joebirch.domain.interactor.browse

import co.joebirch.domain.executor.PostExecutionThread
import co.joebirch.domain.interactor.CompletableUseCase
import co.joebirch.domain.repository.ProjectsRepository
import io.reactivex.Completable
import javax.inject.Inject

class BookmarkProject @Inject constructor(private val projectsRepository: ProjectsRepository,
postExecutionThread: PostExecutionThread)
: CompletableUseCase<BookmarkProject.Params>(postExecutionThread) {

public override fun buildUseCaseCompletable(params: Params?): Completable {
if (params == null) throw IllegalArgumentException("Params can't be null!")
return projectsRepository.bookmarkProject(params.projectId)
}

data class Params constructor(val projectId: String) {
companion object {
fun forProject(projectId: String): Params {
return Params(projectId)
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package co.joebirch.domain.interactor.browse

import co.joebirch.domain.executor.PostExecutionThread
import co.joebirch.domain.interactor.SingleUseCase
import co.joebirch.domain.model.Project
import co.joebirch.domain.repository.ProjectsRepository
import io.reactivex.Single
import javax.inject.Inject

class GetProjects @Inject constructor(private val projectsRepository: ProjectsRepository,
postExecutionThread: PostExecutionThread)
: SingleUseCase<List<Project>, Nothing>(postExecutionThread) {

public override fun buildUseCaseSingle(params: Nothing?): Single<List<Project>> {
return projectsRepository.getProjects()
}
}
5 changes: 5 additions & 0 deletions Domain/src/main/java/co/joebirch/domain/model/Project.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package co.joebirch.domain.model

class Project(val id: String, val name: String, val fullName: String,
val starCount: String, val dateCreated: String,
val ownerName: String, val ownerAvatar: String)
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package co.joebirch.domain.repository

import co.joebirch.domain.model.Project
import io.reactivex.Completable
import io.reactivex.Single

interface ProjectsRepository {

fun getProjects(): Single<List<Project>>

fun bookmarkProject(projectId: String): Completable

fun getBookmarkedProjects(): Single<List<Project>>

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package co.joebirch.githubtrending.bookmarked

import co.joebirch.domain.executor.PostExecutionThread
import co.joebirch.domain.interactor.bookmarked.GetBookmarkedProjects
import co.joebirch.domain.model.Project
import co.joebirch.domain.repository.ProjectsRepository
import co.joebirch.githubtrending.test.ProjectDataFactory
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.whenever
import io.reactivex.Single
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import org.mockito.junit.MockitoJUnitRunner

@RunWith(MockitoJUnitRunner::class)
class GetBookmarkedProjectsTest {

private lateinit var getBookmarkedProjects: GetBookmarkedProjects
@Mock lateinit var projectsRepository: ProjectsRepository
@Mock lateinit var postExecutionThread: PostExecutionThread

@Before
fun setup() {
MockitoAnnotations.initMocks(this)
getBookmarkedProjects = GetBookmarkedProjects(projectsRepository, postExecutionThread)
}

@Test
fun getBookmarkedProjectsCompletes() {
stubProjectsRepositoryGetBookmarkedProjects(
Single.just(ProjectDataFactory.makeProjectList(2)))

val testObserver = getBookmarkedProjects.buildUseCaseSingle().test()
testObserver.assertComplete()
}

@Test
fun getBookmarkProjectsCallsRepository() {
stubProjectsRepositoryGetBookmarkedProjects(
Single.just(ProjectDataFactory.makeProjectList(2)))

getBookmarkedProjects.buildUseCaseSingle().test()
verify(projectsRepository).getBookmarkedProjects()
}

private fun stubProjectsRepositoryGetBookmarkedProjects(single: Single<List<Project>>) {
whenever(projectsRepository.getBookmarkedProjects())
.thenReturn(single)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package co.joebirch.githubtrending.browse

import co.joebirch.domain.executor.PostExecutionThread
import co.joebirch.domain.interactor.browse.BookmarkProject
import co.joebirch.domain.repository.ProjectsRepository
import co.joebirch.githubtrending.test.ProjectDataFactory
import com.nhaarman.mockito_kotlin.any
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.whenever
import io.reactivex.Completable
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import org.mockito.junit.MockitoJUnitRunner

@RunWith(MockitoJUnitRunner::class)
class BookmarkProjectTest {

private lateinit var bookmarkProject: BookmarkProject
@Mock lateinit var projectsRepository: ProjectsRepository
@Mock lateinit var postExecutionThread: PostExecutionThread

@Before
fun setup() {
MockitoAnnotations.initMocks(this)
bookmarkProject = BookmarkProject(projectsRepository, postExecutionThread)
}

@Test
fun bookmarkProjectCompletes() {
stubProjectsRepositoryBookmarkProject(Completable.complete())

val testObserver = bookmarkProject.buildUseCaseCompletable(
BookmarkProject.Params(ProjectDataFactory.randomUuid())).test()
testObserver.assertComplete()
}

@Test(expected = IllegalArgumentException::class)
fun bookmarkProjectThrowsException() {
bookmarkProject.buildUseCaseCompletable().test()
}

@Test
fun bookmarkProjectRepository() {
val projectId = ProjectDataFactory.randomUuid()
stubProjectsRepositoryBookmarkProject(Completable.complete())

bookmarkProject.buildUseCaseCompletable(BookmarkProject.Params(projectId)).test()
verify(projectsRepository).bookmarkProject(projectId)
}

private fun stubProjectsRepositoryBookmarkProject(completable: Completable) {
whenever(projectsRepository.bookmarkProject(any()))
.thenReturn(completable)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package co.joebirch.githubtrending.browse

import co.joebirch.domain.executor.PostExecutionThread
import co.joebirch.domain.interactor.browse.GetProjects
import co.joebirch.domain.model.Project
import co.joebirch.domain.repository.ProjectsRepository
import co.joebirch.githubtrending.test.ProjectDataFactory
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.whenever
import io.reactivex.Single
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import org.mockito.junit.MockitoJUnitRunner

@RunWith(MockitoJUnitRunner::class)
class GetProjectsTest {

private lateinit var getProjects: GetProjects
@Mock lateinit var projectsRepository: ProjectsRepository
@Mock lateinit var postExecutionThread: PostExecutionThread

@Before
fun setup() {
MockitoAnnotations.initMocks(this)
getProjects = GetProjects(projectsRepository, postExecutionThread)
}

@Test
fun getProjectsCompletes() {
stubProjectsRepositoryGetProjects(
Single.just(ProjectDataFactory.makeProjectList(2)))

val testObserver = getProjects.buildUseCaseSingle().test()
testObserver.assertComplete()
}

@Test
fun getProjectsCallsRepository() {
stubProjectsRepositoryGetProjects(
Single.just(ProjectDataFactory.makeProjectList(2)))

getProjects.buildUseCaseSingle().test()
verify(projectsRepository).getProjects()
}

@Test
fun getProjectsReturnsData() {
val projects = ProjectDataFactory.makeProjectList(2)
stubProjectsRepositoryGetProjects(
Single.just(projects))

val testObserver = getProjects.buildUseCaseSingle().test()
testObserver.assertValue(projects)
}

private fun stubProjectsRepositoryGetProjects(single: Single<List<Project>>) {
whenever(projectsRepository.getProjects())
.thenReturn(single)
}

}
Loading

0 comments on commit 8ded9ac

Please sign in to comment.