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

Unit Test #6

Merged
merged 36 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
b6bb842
set up build logic plugins
ndiritumichael Jun 5, 2024
92486a1
set up build logic plugins
ndiritumichael Jun 5, 2024
754a90c
set up build logic plugins
ndiritumichael Jun 5, 2024
90b2275
set up domain module
ndiritumichael Jun 5, 2024
959e8af
set up network module
ndiritumichael Jun 5, 2024
a170ae3
set up buildlogic
ndiritumichael Jun 5, 2024
d15113a
set up database module
ndiritumichael Jun 5, 2024
d51bb8e
set up linting rules
ndiritumichael Jun 6, 2024
f0a42da
setup data module
ndiritumichael Jun 6, 2024
0c8e5bf
add schema for calorie database
ndiritumichael Jun 6, 2024
1fb2672
setup common ui module
ndiritumichael Jun 6, 2024
272561e
setup database module
ndiritumichael Jun 6, 2024
19dea2b
setup network module
ndiritumichael Jun 6, 2024
38ae020
chore:setup food details feature
ndiritumichael Jun 6, 2024
7038053
chore:setup saved items feature
ndiritumichael Jun 6, 2024
2a69ee7
chore:setup search screen feature
ndiritumichael Jun 6, 2024
1d7a76a
chore:setup dependencies
ndiritumichael Jun 6, 2024
d9535bc
chore:setup data module
ndiritumichael Jun 6, 2024
0b5bc15
chore:setup app module
ndiritumichael Jun 6, 2024
ff8572d
chore:setup main module
ndiritumichael Jun 6, 2024
40b3f53
chore: improve workflows
ndiritumichael Jun 6, 2024
5d67116
Update androidbuild.yml
ndiritumichael Jun 6, 2024
ab3fb75
Merge pull request #5 from ndiritumichael/buildlogic
ndiritumichael Jun 6, 2024
a649aa7
setup database tests
ndiritumichael Jun 7, 2024
2bc4646
add saved items to navigation
ndiritumichael Jun 7, 2024
11bb557
create core testing module
ndiritumichael Jun 7, 2024
e662f7c
implemement database tests
ndiritumichael Jun 7, 2024
13950e7
implemement network layer tests
ndiritumichael Jun 7, 2024
1c5134a
implement data layer tests
ndiritumichael Jun 7, 2024
baff145
set up core app logic in domain from data layer
ndiritumichael Jun 7, 2024
40f7c3e
implement food details feature
ndiritumichael Jun 7, 2024
307a12e
resolve failing tests in search feature
ndiritumichael Jun 7, 2024
2d1cc85
code cleanup
ndiritumichael Jun 7, 2024
6ec2d2f
add more components to common ui
ndiritumichael Jun 7, 2024
2979435
code cleanup
ndiritumichael Jun 7, 2024
cf9cf99
code cleanup
ndiritumichael Jun 7, 2024
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
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[*.{kt,kts}]
insert_final_newline=true
max_line_length=off
ktlint_disabled_rules=no-wildcard-imports,import-ordering,trailing-comma-on-call-site
ktlint_disabled_rules=no-wildcard-imports,import-ordering,trailing-comma-on-call-site,indent
ktlint_function_naming_ignore_when_annotated_with=Composable

ij_kotlin_allow_trailing_comma = true
Expand Down
16 changes: 16 additions & 0 deletions .github/workflows/androidbuild.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@ jobs:
distribution: 'adopt'
- name: Make gradlew executable
run: chmod +x ./gradlew

- name: Get local.properties from secrets
run: echo "${{secrets.LOCAL_PROPERTIES }}" > $GITHUB_WORKSPACE/local.properties

- name: Run ktlintFormat on the codebase
run: ./gradlew ktlintFormat

- name: Run ktlintCheck on the codebase
run: ./gradlew ktlintCheck

- name: Run Unit Tests
run: ./gradlew clean test

- name: Run debug Build
run: ./gradlew assembleDebug

- name : Build With Gradle
run: ./gradlew build

Expand Down
51 changes: 13 additions & 38 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.compose.compiler)

alias(libs.plugins.caloriebytez.application.compose)
alias(libs.plugins.caloriebytez.android.hilt)
}

android {
Expand All @@ -10,7 +10,7 @@ android {

defaultConfig {
applicationId = "com.devmike.caloriebytez"
minSdk = 24
minSdk = 26
targetSdk = 34
versionCode = 1
versionName = "1.0"
Expand All @@ -21,48 +21,23 @@ android {
}
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro",
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
buildFeatures {
compose = true
buildConfig = true
}

packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
merges += "META-INF/LICENSE.md"
merges += "META-INF/LICENSE-notice.md"
}
}
}

dependencies {

implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
dependencies {
implementation(project(":feature:search"))
implementation(project(":feature:foodDetails"))
implementation(project(":feature:savedItems"))
implementation(project(":domain"))
}
}
3 changes: 3 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<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=".CalorieApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
Expand Down
16 changes: 16 additions & 0 deletions app/src/main/java/com/devmike/caloriebytez/CalorieApplication.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.devmike.caloriebytez

import android.app.Application
import dagger.hilt.android.HiltAndroidApp
import timber.log.Timber

@HiltAndroidApp
class CalorieApplication : Application() {
override fun onCreate() {
super.onCreate()

if (BuildConfig.DEBUG) {
Timber.plant(Timber.DebugTree())
}
}
}
41 changes: 22 additions & 19 deletions app/src/main/java/com/devmike/caloriebytez/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,45 +1,48 @@
package com.devmike.caloriebytez

import android.annotation.SuppressLint
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.devmike.caloriebytez.navigation.AppNavigation
import com.devmike.caloriebytez.navigation.CalorieBottomBar
import com.devmike.caloriebytez.ui.theme.CalorieBytezTheme
import dagger.hilt.android.AndroidEntryPoint

@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
CalorieBytezTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding),
)
}
CalorieApp()
}
}
}
}

@Composable
fun Greeting(
name: String,
modifier: Modifier = Modifier,
) {
Text(text = "Hello $name!", modifier = modifier)
}
fun CalorieApp() {
val navHostController: NavHostController = rememberNavController()

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
CalorieBytezTheme { Greeting("Android") }
Scaffold(bottomBar = {
CalorieBottomBar(navHostController)
}) {
AppNavigation(
modifier =
Modifier.padding(
bottom = it.calculateBottomPadding(),
),
navController = navHostController,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.devmike.caloriebytez.navigation

import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import com.devmike.domain.models.AppDestinations
import com.devmike.fooddetails.FoodDetailsScreen
import com.devmike.saveditems.SavedItemsScreen
import com.devmike.search.SearchScreen

@Composable
fun AppNavigation(
modifier: Modifier = Modifier,
navController: NavHostController,
startDestination: AppDestinations = AppDestinations.SearchScreen,
) {
NavHost(modifier = modifier, navController = navController, startDestination = startDestination) {
composable<AppDestinations.SearchScreen> {
SearchScreen { foodName ->
navController.navigate(AppDestinations.FoodDetails(name = foodName))
}
}

composable<AppDestinations.FoodDetails> { backStackEntry ->
FoodDetailsScreen {
navController.navigateUp()
}
}

composable<AppDestinations.SavedFood> {
SavedItemsScreen { foodName ->
navController.navigate(AppDestinations.FoodDetails(name = foodName))
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.devmike.caloriebytez.navigation

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.Icon
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.navigation.NavDestination
import androidx.navigation.NavDestination.Companion.hasRoute
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState

@Composable
fun CalorieBottomBar(navController: NavHostController) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination: NavDestination? = navBackStackEntry?.destination

val showBottomNav =
TopLevelDestinations.entries.map { it.route::class }.any { route ->
currentDestination?.hierarchy?.any {
it.hasRoute(route)
} == true
}

AnimatedVisibility(visible = showBottomNav) {
BottomAppBar {
TopLevelDestinations.entries.map { bottomNavigationItem ->
val isSelected =
currentDestination?.hierarchy?.any { it.hasRoute(bottomNavigationItem.route::class) } == true

if (currentDestination != null) {
NavigationBarItem(
selected = isSelected,
onClick = {
navController.navigate(bottomNavigationItem.route) {
popUpTo(navController.graph.startDestinationId) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
},
icon = {
Icon(
imageVector =
if (isSelected) {
bottomNavigationItem.selectedIcon
} else {
bottomNavigationItem.unselectedIcon
},
contentDescription = bottomNavigationItem.label,
)
},
alwaysShowLabel = isSelected,
label = {
Text(bottomNavigationItem.label)
},
)
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.devmike.caloriebytez.navigation

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Bookmarks
import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.outlined.Bookmarks
import androidx.compose.material.icons.outlined.Search
import androidx.compose.ui.graphics.vector.ImageVector
import com.devmike.domain.models.AppDestinations

enum class TopLevelDestinations(
val label: String,
val selectedIcon: ImageVector,
val unselectedIcon: ImageVector,
val route: AppDestinations,
) {
Search(
label = "Search",
selectedIcon = Icons.Filled.Search,
unselectedIcon = Icons.Outlined.Search,
route = AppDestinations.SearchScreen,
),

SavedItems(
label = "Saved",
selectedIcon = Icons.Filled.Bookmarks,
unselectedIcon = Icons.Outlined.Bookmarks,
route = AppDestinations.SavedFood,
),
}
2 changes: 2 additions & 0 deletions build-logic/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.gradle
/convention/build
Loading