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

[AN-CONFIG] 초기 세팅 AN_FEAT #6

Merged
merged 20 commits into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from 11 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
42 changes: 23 additions & 19 deletions .github/workflows/Android_PR_Builder.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,35 +38,39 @@ jobs:
#
- name: Create Local Properties
run: touch local.properties
working-directory: android
# - name: Access Local Properties
# env:
# FUNCH_DEBUG_BASE_URL: ${{ secrets.FUNCH_DEBUG_BASE_URL }}
# STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
# KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
# KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
# STORE_FILE: ${{ secrets.STORE_FILE }}
# run: |
# echo FUNCH_DEBUG_BASE_URL=\"FUNCH_DEBUG_BASE_URL\" >> local.properties
# echo STORE_PASSWORD= $STORE_PASSWORD >> local.properties
# echo KEY_PASSWORD= $KEY_PASSWORD >> local.properties
# echo KEY_ALIAS= $KEY_ALIAS >> local.properties
# echo STORE_FILE= $STORE_FILE >> local.properties

# - name: Access Local Properties
# env:
# FUNCH_DEBUG_BASE_URL: ${{ secrets.FUNCH_DEBUG_BASE_URL }}
# STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
# KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
# KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
# STORE_FILE: ${{ secrets.STORE_FILE }}
# run: |
# echo FUNCH_DEBUG_BASE_URL=\"FUNCH_DEBUG_BASE_URL\" >> local.properties
# echo STORE_PASSWORD= $STORE_PASSWORD >> local.properties
# echo KEY_PASSWORD= $KEY_PASSWORD >> local.properties
# echo KEY_ALIAS= $KEY_ALIAS >> local.properties
# echo STORE_FILE= $STORE_FILE >> local.properties

# - name: Create Key Store
# env:
# KEY_STORE_BASE_64: ${{secrets.KEY_STORE_BASE_64}}
# run: |
# echo "$KEY_STORE_BASE_64" | base64 -d > ./funch_key_store.jks
# - name: Create Key Store
# env:
# KEY_STORE_BASE_64: ${{secrets.KEY_STORE_BASE_64}}
# run: |
# echo "$KEY_STORE_BASE_64" | base64 -d > ./funch_key_store.jks

- name: Grant execute permission for gradlew
run: chmod +x gradlew
working-directory: android

- name: Lint Check
run: ./gradlew ktlintCheck
working-directory: android

- name: run rest
run: ./gradlew test
working-directory: android

- name: Build with Gradle
run: ./gradlew build
working-directory: android
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@

.idea/

.DS_Store
89 changes: 70 additions & 19 deletions android/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,48 +1,99 @@
import org.jetbrains.kotlin.konan.properties.Properties

plugins {
alias(libs.plugins.androidApplication)
alias(libs.plugins.jetbrainsKotlinAndroid)
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.kapt)
alias(libs.plugins.kotlinx.serialization)
alias(libs.plugins.android.junit5)
alias(libs.plugins.ktlint)
id("kotlin-parcelize")
}

val properties =
Properties().apply {
load(rootProject.file("local.properties").inputStream())
}

android {
namespace = "poke.rogue.helper"
compileSdk = 34
namespace = libs.versions.applicationId.get()
compileSdk = libs.versions.compileSdk.get().toInt()

defaultConfig {
applicationId = "poke.rogue.helper"
minSdk = 26
targetSdk = 34
versionCode = 1
versionName = "1.0"

applicationId = libs.versions.applicationId.get()
minSdk = libs.versions.minSdk.get().toInt()
targetSdk = libs.versions.targetSdk.get().toInt()
versionName = libs.versions.appVersion.get()
versionCode = libs.versions.versionCode.get().toInt()
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments["runnerBuilder"] =
"de.mannodermaus.junit5.AndroidJUnit5Builder"

// TODO 서버 URL 나오면 설정
// buildConfigField(
// "String",
// "SHOPPING_BASE_URL",
// properties.getProperty("SHOPPING_BASE_URL"),
// )
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
"proguard-rules.pro",
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "1.8"
jvmTarget = JavaVersion.VERSION_17.toString()
}
packaging {
resources {
excludes += "META-INF/**"
excludes += "win32-x86*/**"
}
}
buildFeatures {
buildConfig = true
dataBinding = true
}
testOptions {
animationsDisabled = true
}
}

dependencies {

// androidx
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
implementation(libs.androidx.activity)
implementation(libs.androidx.constraintlayout)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
}
implementation(libs.androidx.startup)
implementation(libs.androidx.lifecycle)
implementation(libs.androidx.lifecycle.viewmodel)
implementation(libs.kotlin.coroutines.android)
implementation(libs.androidx.fragment.ktx)
// retrofit & okhttp
implementation(libs.bundles.retrofit)
implementation(platform(libs.okhttp.bom))
implementation(libs.okhttp.logging.interceptor)
// third party
implementation(libs.kotlin.serialization.json)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

timber 라이브러리를 사용하는 이유가

  1. 클래스명으로 자동 tag 생성
  2. apk 릴리즈 시, 로그 출력을 방지
  3. 충돌 라이브러리와 통합이 용이
    이정도 이유 때문에 사용하는 걸까요?

Copy link
Contributor Author

@murjune murjune Jul 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

클래스명으로 자동 tag 생성
apk 릴리즈 시, 로그 출력을 방지

맞습니다! 디버그용 로그로 사용하기 좋아용

충돌 라이브러리와 통합이 용이

이게 무슨 뜻인가요?!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

충돌 라이브러리와 통합이 용이

이게 무슨 뜻인가요?!

잘은 모르지만.. Sentry ? 같은 에러 모니터링 툴과 같이 사용하기에 용이하다는 뜻으로 이해했어용

implementation(libs.timber)
implementation(libs.coil.core)
implementation(libs.glide)
implementation(libs.splash.screen)
// unit test
testImplementation(libs.bundles.unit.test)
testImplementation(libs.mockk.webserver)
// android test
androidTestImplementation(libs.bundles.android.test)
androidTestRuntimeOnly(libs.junit5.android.test.runner)
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,17 @@
package poke.rogue.helper

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import poke.rogue.helper.util.testContext

import org.junit.Assert.*

/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
val appContext = testContext
assertEquals("poke.rogue.helper", appContext.packageName)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package poke.rogue.helper.util

import android.content.Context
import androidx.test.core.app.ApplicationProvider

val testContext: Context get() = ApplicationProvider.getApplicationContext<Context>()
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package poke.rogue.helper.util

import android.view.View
import androidx.recyclerview.widget.RecyclerView
import androidx.test.espresso.NoMatchingViewException
import androidx.test.espresso.UiController
import androidx.test.espresso.ViewAction
import androidx.test.espresso.ViewAssertion
import io.kotest.matchers.nulls.shouldNotBeNull
import io.kotest.matchers.shouldBe
import org.hamcrest.Matcher

/**
* 리사이클러뷰의 expectedCount만큼 아이템이 있는지 확인하는 ViewAssertion
*/
class RecyclerViewItemCountAssertion(private val expectedCount: Int) : ViewAssertion {
override fun check(
view: View?,
noViewFoundException: NoMatchingViewException?,
) {
if (noViewFoundException != null) {
throw noViewFoundException
murjune marked this conversation as resolved.
Show resolved Hide resolved
}

val recyclerView = view as RecyclerView
murjune marked this conversation as resolved.
Show resolved Hide resolved
val adapter = recyclerView.adapter
adapter.shouldNotBeNull()
adapter.itemCount shouldBe expectedCount
}
}

/**
* 리사이클러뷰의 특정 위치에 있는 아이템을 클릭하는 ViewAction
*
* reference: https://gist.github.com/quentin7b/9c5669fd940865cf2e89
*
* sample
* ```kotlin
* onView(withId(R.id.rv_shopping_cart)).perform(
* RecyclerViewActions.actionOnItemAtPosition<CartAdapter.CartViewHolder>(
* 3, // 3번째 아이템
* clickChildViewWithId(R.id.iv_shooping_cart_delete), // id가 iv_shooping_cart_delete인 뷰 클릭
* ),
* )

* ```
*/
fun clickChildViewWithId(id: Int): ViewAction {
return object : ViewAction {
override fun getConstraints(): Matcher<View>? {
return null
}

override fun getDescription(): String {
return "Click on specific button"
murjune marked this conversation as resolved.
Show resolved Hide resolved
}

override fun perform(
uiController: UiController,
view: View,
) {
val v = view.findViewById<View>(id)
v.performClick()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package poke.rogue.helper.util

import androidx.test.espresso.ViewAssertion
import androidx.test.espresso.assertion.ViewAssertions
import androidx.test.espresso.matcher.ViewMatchers
import org.hamcrest.CoreMatchers

/**
* 자식 뷰의 텍스트를 포함하는 뷰가 있는지 확인하는 ViewAssertion을 반환하는 함수
*
* sample
* ```kotlin
* // 리사이클러뷰의 자식 뷰 중 텍스트에 "텍스트"가 포함된 뷰가 있는지 확인
* onView(withId(R.id.rv_shopping_cart)).check(matchDescendantSoftly("텍스트"))
* ```
*/
fun matchDescendantSoftly(text: String): ViewAssertion {
murjune marked this conversation as resolved.
Show resolved Hide resolved
return ViewAssertions.matches(
ViewMatchers.hasDescendant(
ViewMatchers.withText(
CoreMatchers.containsString(text),
),
),
)
}

/**
* 리사이클러뷰의 아이템 개수를 확인하는 ViewAssertion을 반환하는 함수
*
* sample
* ```kotlin
* // 리사이클러뷰의 아이템 개수가 3개인지 확인
* onView(withId(R.id.rv_shopping_cart)).check(withItemCount(3))
* ```
*/
fun withItemCount(expectedCount: Int): ViewAssertion {
murjune marked this conversation as resolved.
Show resolved Hide resolved
return RecyclerViewItemCountAssertion(expectedCount)
}
murjune marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package poke.rogue.helper.util

import androidx.annotation.IdRes
import androidx.recyclerview.widget.RecyclerView
import androidx.test.espresso.ViewInteraction
import androidx.test.espresso.contrib.RecyclerViewActions
import org.hamcrest.CoreMatchers

inline fun <reified T : RecyclerView.ViewHolder> ViewInteraction.performScrollToHolder(position: Int = 0): ViewInteraction {
return perform(
RecyclerViewActions.scrollToHolder(CoreMatchers.instanceOf(T::class.java))
.atPosition(position),
)
}

fun <T : RecyclerView.ViewHolder> ViewInteraction.performClickHolderAt(
absolutePosition: Int = 0,
@IdRes childViewId: Int,
): ViewInteraction {
return perform(
RecyclerViewActions.actionOnItemAtPosition<T>(
absolutePosition,
clickChildViewWithId(childViewId),
),
)
}
6 changes: 5 additions & 1 deletion android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

<application
android:name=".PokeRogueHelperApp"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
Expand All @@ -13,7 +17,7 @@
android:theme="@style/Theme.PokeRogueHelper"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:name=".HomeActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down
11 changes: 11 additions & 0 deletions android/app/src/main/java/poke/rogue/helper/HomeActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package poke.rogue.helper

import android.os.Bundle
import poke.rogue.helper.databinding.ActivityHomeBinding
import poke.rogue.helper.presentation.base.BindingActivity

class HomeActivity : BindingActivity<ActivityHomeBinding>(R.layout.activity_home) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
}
}
Loading
Loading