Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop #2

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 19 additions & 17 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
name: Build android
on: [push]
on: [ push ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: 11
- name: Make Gradle executable
run: chmod +x ./gradlew
- name: Kotlin Lint with Gradle
run: ./gradlew ktlint
- name: Kotlin static code analysis with Gradle
run: ./gradlew detekt
- name: Test Debug APK
run: ./gradlew test
- name: Build with Gradle
run: ./gradlew build
- name: Build Debug APK
run: ./gradlew assembleDebug
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: 11
- name: Make Gradle executable
run: chmod +x ./gradlew
- name: Kotlin Lint with Gradle
run: |
echo "MAPS_API_KEY=${{ secrets.MAPS_API_KEY }}" > local.properties
./gradlew ktlint
- name: Kotlin static code analysis with Gradle
run: ./gradlew detekt
- name: Test Debug APK
run: ./gradlew test
- name: Build with Gradle
run: ./gradlew build
- name: Build Debug APK
run: ./gradlew assembleDebug
5 changes: 5 additions & 0 deletions .idea/jarRepositories.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

70 changes: 67 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ plugins {
id 'com.android.application'
id 'kotlin-android'
id "io.gitlab.arturbosch.detekt" version "1.16.0"
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
id 'com.google.secrets_gradle_plugin' version '0.6'
}

apply plugin: "io.gitlab.arturbosch.detekt"
apply plugin: 'dagger.hilt.android.plugin'

android {
compileSdkVersion 30
Expand All @@ -17,7 +21,16 @@ android {
versionCode 1
versionName "21.1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunner "com.deo.compose.TestRunner"
javaCompileOptions {
annotationProcessorOptions {
arguments += [
"room.schemaLocation" : "$projectDir/schemas".toString(),
"room.incremental" : "true",
"room.expandProjection": "true"
]
}
}
}

buildTypes {
Expand All @@ -27,12 +40,34 @@ android {
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
packagingOptions {
// Multiple dependency bring these files in. Exclude them to enable
// our test APK to build (has no effect on our AARs)
excludes += "/META-INF/AL2.0"
excludes += "/META-INF/LGPL2.1"
}
// for spatialite
splits {
abi {
enable true
reset()
include "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
}
}
signingConfigs {
debug {
storeFile rootProject.file('debug.keystore')
storePassword 'android'
keyAlias 'androiddebugkey'
keyPassword 'android'
}
}
}

dependencies {
Expand All @@ -42,14 +77,43 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'

// local unit test
testImplementation 'junit:junit:4.13.2'
testImplementation "com.google.truth:truth:1.1"
// instrumentation test
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
androidTestImplementation 'com.google.dagger:hilt-android-testing:2.31.2-alpha'
// androidx test
androidTestImplementation "androidx.arch.core:core-testing:2.1.0"
// fluent assertions for Java and Android
androidTestImplementation "com.google.truth:truth:1.1"

// Detekt
detektPlugins "io.gitlab.arturbosch.detekt:detekt-formatting:1.16.0"
// Memory leak detection
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'

// coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.3'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.3'
// coroutine test
androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.3"

// room - databases
implementation "androidx.room:room-runtime:2.3.0"
kapt "androidx.room:room-compiler:2.3.0"
implementation "androidx.room:room-ktx:2.3.0"
// spatialite
implementation "com.github.anboralabs:spatia-room:0.1.0"
testImplementation "androidx.room:room-testing:2.3.0"

// dagger hilt
implementation "com.google.dagger:hilt-android:2.31.2-alpha"
kapt "com.google.dagger:hilt-android-compiler:2.31.2-alpha"
// dagger-hilt test
kaptAndroidTest 'com.google.dagger:hilt-android-compiler:2.31.2-alpha'
}

// detekt
Expand Down
58 changes: 58 additions & 0 deletions app/schemas/com.deo.sticky.di.StickyDatabase/1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "6b3f0130269f5981bad585e467ae02c3",
"entities": [
{
"tableName": "places",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT, `latitude` REAL, `longitude` REAL, `geometry` BLOB)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "latitude",
"columnName": "latitude",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "longitude",
"columnName": "longitude",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "geometry",
"columnName": "geometry",
"affinity": "BLOB",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '6b3f0130269f5981bad585e467ae02c3')"
]
}
}
29 changes: 29 additions & 0 deletions app/src/androidTest/java/com/deo/sticky/MainCoroutinesRule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.deo.sticky

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestCoroutineDispatcher
import kotlinx.coroutines.test.TestCoroutineScope
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.setMain
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement

/**
* https://developer.android.com/kotlin/coroutines/coroutines-best-practices?hl=ko
*/
@ExperimentalCoroutinesApi
class MainCoroutinesRule : TestRule, TestCoroutineScope by TestCoroutineScope() {

private val testCoroutinesDispatcher = TestCoroutineDispatcher()

override fun apply(base: Statement?, description: Description?) = object : Statement() {
override fun evaluate() {
Dispatchers.setMain(testCoroutinesDispatcher)
base?.evaluate()
cleanupTestCoroutines()
Dispatchers.resetMain()
}
}
}
18 changes: 18 additions & 0 deletions app/src/androidTest/java/com/deo/sticky/TestRunner.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.deo.compose

import android.app.Application
import android.content.Context
import androidx.test.runner.AndroidJUnitRunner
import dagger.hilt.android.testing.HiltTestApplication

class TestRunner : AndroidJUnitRunner() {
override fun newApplication(
cl: ClassLoader?,
name: String?,
context: Context?
): Application {
return super.newApplication(
cl, HiltTestApplication::class.java.name, context
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.deo.sticky.di

import android.content.Context
import androidx.room.RoomDatabase
import androidx.sqlite.db.SupportSQLiteDatabase
import co.anbora.labs.spatia.builder.SpatiaRoom
import dagger.Module
import dagger.Provides
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import dagger.hilt.testing.TestInstallIn
import javax.inject.Singleton

@TestInstallIn(
components = [SingletonComponent::class],
replaces = [DatabaseModule::class]
)
@Module
class TestDatabaseModule {
/**
* 장소 데이터베이스
*/
@Singleton
@Provides
fun provideSpatiaDatabase(
@ApplicationContext
context: Context
) = SpatiaRoom.databaseBuilder(
context.applicationContext,
StickyDatabase::class.java,
"sticky-test.db"
).addCallback(object : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
}
}).fallbackToDestructiveMigration().build()
// .setTransactionExecutor(
// Executors.newSingleThreadExecutor()
// ).build()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.deo.sticky.features.map.models

import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.test.filters.SmallTest
import com.deo.sticky.MainCoroutinesRule
import com.google.common.truth.Truth.assertThat
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import javax.inject.Inject
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runBlockingTest
import org.junit.Before
import org.junit.Rule
import org.junit.Test

@SmallTest
@HiltAndroidTest
@ExperimentalCoroutinesApi
class PlaceDaoTest {
@get:Rule
var hiltRule = HiltAndroidRule(this)

@get:Rule
val instantExecutorRule = InstantTaskExecutorRule()

@get:Rule
val coroutineRule = MainCoroutinesRule()

@Before
fun setup() {
hiltRule.inject()
}

@Inject
lateinit var placeDao: PlaceDao

@Test
fun `장소 저장하기`() = runBlockingTest {
assertThat(
placeDao.add("강남 12번 출구 커피빈", 37.5092672, 127.026935)
).isAtLeast(1)
}

@Test
fun `반경 내 장소 리스트 불러오기`() = runBlockingTest {
assertThat(placeDao.add("강남 12번 출구 커피빈", 37.5092672, 127.026935))
.isAtLeast(1)
assertThat(placeDao.add("강남 11번 출구 할리스커피", 37.4985584, 127.0278279))
.isAtLeast(1)
assertThat(placeDao.add("강남 1번 출구 스타벅", 37.497721, 127.0269938))
.isAtLeast(1)
// 강남역
assertThat(placeDao.getPlacesWithinRadius(37.4977252, 127.0269938, radius = 1_000))
.hasSize(3)
}
}
12 changes: 11 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,23 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.deo.sticky">

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

<application
android:name='.StickyApplication'
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Androidtemplate">
android:theme="@style/Theme.Sticky">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="${MAPS_API_KEY}" />
<activity android:name="com.deo.sticky.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down
Loading