Add pipeline: codeAnalysis, tests and clean up gradle
This commit is contained in:
parent
472b7591f5
commit
516b097e9e
27 changed files with 681 additions and 394 deletions
10
.github/dependabot.yml
vendored
Normal file
10
.github/dependabot.yml
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: gradle
|
||||||
|
directory: "/"
|
||||||
|
target-branch: "develop"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
day: "monday"
|
||||||
|
time: "12:00"
|
||||||
|
open-pull-requests-limit: 15
|
||||||
71
.github/workflows/pull-request-jobs.yml
vendored
Normal file
71
.github/workflows/pull-request-jobs.yml
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
name: Verify Pull request is publishable
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- develop
|
||||||
|
|
||||||
|
env:
|
||||||
|
GITHUB_USERNAME: "fknives"
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
run-code-analysis:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Setup Java
|
||||||
|
uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
distribution: 'adopt'
|
||||||
|
java-version: '11'
|
||||||
|
- name: Run clean
|
||||||
|
run: ./gradlew clean
|
||||||
|
- name: Run detekt
|
||||||
|
run: ./gradlew detekt
|
||||||
|
- name: Upload Detekt Results
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Detekt Results
|
||||||
|
path: build/reports/detekt/detekt.html
|
||||||
|
retention-days: 1
|
||||||
|
- name: Run ktlint
|
||||||
|
run: ./gradlew ktlintCheck
|
||||||
|
- name: Upload ktLint Results
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: ktLint Results
|
||||||
|
path: ./**/build/reports/ktlint/**/*ktlint*Check.txt
|
||||||
|
retention-days: 1
|
||||||
|
- name: Run Lint
|
||||||
|
run: ./gradlew lint
|
||||||
|
- name: Upload Lint Results
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Lint Results
|
||||||
|
path: ./**/build/reports/*lint-results*.html
|
||||||
|
retention-days: 1
|
||||||
|
|
||||||
|
run-tests:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Setup Java
|
||||||
|
uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
distribution: 'adopt'
|
||||||
|
java-version: '11'
|
||||||
|
- name: Run Unit Tests
|
||||||
|
run: ./gradlew testReleaseUnit
|
||||||
|
- name: Upload Test Results
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Unit Test Results
|
||||||
|
path: ./**/build/reports/tests/**/index.html
|
||||||
|
retention-days: 1
|
||||||
|
|
@ -6,7 +6,6 @@ plugins {
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 30
|
compileSdkVersion 30
|
||||||
buildToolsVersion "30.0.3"
|
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "org.fnives.test.showcase"
|
applicationId "org.fnives.test.showcase"
|
||||||
|
|
@ -25,16 +24,10 @@ android {
|
||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compileOptions {
|
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
|
||||||
}
|
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
viewBinding true
|
viewBinding true
|
||||||
}
|
}
|
||||||
kotlinOptions {
|
|
||||||
jvmTarget = '1.8'
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
androidTest {
|
androidTest {
|
||||||
|
|
@ -46,19 +39,6 @@ android {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
testOptions.unitTests.all {
|
|
||||||
useJUnitPlatform()
|
|
||||||
testLogging {
|
|
||||||
events 'started', 'passed', 'skipped', 'failed'
|
|
||||||
exceptionFormat "full"
|
|
||||||
showStandardStreams true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
testOptions {
|
|
||||||
unitTests {
|
|
||||||
includeAndroidResources = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// needed for androidTest
|
// needed for androidTest
|
||||||
packagingOptions {
|
packagingOptions {
|
||||||
exclude 'META-INF/LGPL2.1'
|
exclude 'META-INF/LGPL2.1'
|
||||||
|
|
@ -66,14 +46,6 @@ android {
|
||||||
exclude 'META-INF/LICENSE.md'
|
exclude 'META-INF/LICENSE.md'
|
||||||
exclude 'META-INF/LICENSE-notice.md'
|
exclude 'META-INF/LICENSE-notice.md'
|
||||||
}
|
}
|
||||||
|
|
||||||
lintOptions {
|
|
||||||
warningsAsErrors true
|
|
||||||
abortOnError true
|
|
||||||
textReport true
|
|
||||||
ignore 'Overdraw'
|
|
||||||
textOutput "stdout"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
afterEvaluate {
|
afterEvaluate {
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,8 @@
|
||||||
android:name=".TestShowcaseApplication"
|
android:name=".TestShowcaseApplication"
|
||||||
android:theme="@style/Theme.TestShowCase"
|
android:theme="@style/Theme.TestShowCase"
|
||||||
tools:ignore="AllowBackup">
|
tools:ignore="AllowBackup">
|
||||||
<activity android:name=".ui.splash.SplashActivity">
|
<activity android:name=".ui.splash.SplashActivity"
|
||||||
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,11 @@ package org.fnives.test.showcase.favourite
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.flow.take
|
import kotlinx.coroutines.flow.take
|
||||||
import kotlinx.coroutines.flow.toList
|
import kotlinx.coroutines.flow.toList
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.test.TestCoroutineDispatcher
|
import kotlinx.coroutines.test.TestCoroutineDispatcher
|
||||||
import kotlinx.coroutines.test.TestCoroutineScope
|
|
||||||
import kotlinx.coroutines.test.runBlockingTest
|
|
||||||
import org.fnives.test.showcase.core.storage.content.FavouriteContentLocalStorage
|
import org.fnives.test.showcase.core.storage.content.FavouriteContentLocalStorage
|
||||||
import org.fnives.test.showcase.model.content.ContentId
|
import org.fnives.test.showcase.model.content.ContentId
|
||||||
import org.fnives.test.showcase.storage.database.DatabaseInitialization
|
import org.fnives.test.showcase.storage.database.DatabaseInitialization
|
||||||
|
|
@ -44,25 +41,26 @@ internal class FavouriteContentLocalStorageImplTest : KoinTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun GIVEN_content_id_WHEN_added_to_Favourite_THEN_it_can_be_read_out() = runBlocking {
|
fun GIVEN_content_id_WHEN_added_to_Favourite_THEN_it_can_be_read_out() = runBlocking {
|
||||||
val expected = listOf(ContentId("a"))
|
val expected = listOf(ContentId("a"))
|
||||||
|
|
||||||
sut.markAsFavourite(ContentId("a"))
|
sut.markAsFavourite(ContentId("a"))
|
||||||
val actual = sut.observeFavourites().first()
|
|
||||||
|
|
||||||
Assert.assertEquals(expected, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun GIVEN_content_id_added_WHEN_removed_to_Favourite_THEN_it_no_longer_can_be_read_out() = runBlocking {
|
|
||||||
val expected = listOf<ContentId>()
|
|
||||||
sut.markAsFavourite(ContentId("b"))
|
|
||||||
|
|
||||||
sut.deleteAsFavourite(ContentId("b"))
|
|
||||||
val actual = sut.observeFavourites().first()
|
val actual = sut.observeFavourites().first()
|
||||||
|
|
||||||
Assert.assertEquals(expected, actual)
|
Assert.assertEquals(expected, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun GIVEN_content_id_added_WHEN_removed_to_Favourite_THEN_it_no_longer_can_be_read_out() =
|
||||||
|
runBlocking {
|
||||||
|
val expected = listOf<ContentId>()
|
||||||
|
sut.markAsFavourite(ContentId("b"))
|
||||||
|
|
||||||
|
sut.deleteAsFavourite(ContentId("b"))
|
||||||
|
val actual = sut.observeFavourites().first()
|
||||||
|
|
||||||
|
Assert.assertEquals(expected, actual)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun GIVEN_empty_database_WHILE_observing_content_WHEN_favourite_added_THEN_change_is_emitted() =
|
fun GIVEN_empty_database_WHILE_observing_content_WHEN_favourite_added_THEN_change_is_emitted() =
|
||||||
runBlocking<Unit> {
|
runBlocking<Unit> {
|
||||||
|
|
|
||||||
|
|
@ -27,24 +27,20 @@ class CodeKataAuthViewModel {
|
||||||
@DisplayName("GIVEN_initialized_viewModel_WHEN_observed_THEN_loading_false_other_fields_are_empty")
|
@DisplayName("GIVEN_initialized_viewModel_WHEN_observed_THEN_loading_false_other_fields_are_empty")
|
||||||
@Test
|
@Test
|
||||||
fun initialSetup() {
|
fun initialSetup() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN_password_text_WHEN_onPasswordChanged_is_called_THEN_password_livedata_is_updated")
|
@DisplayName("GIVEN_password_text_WHEN_onPasswordChanged_is_called_THEN_password_livedata_is_updated")
|
||||||
@Test
|
@Test
|
||||||
fun whenPasswordChangedLiveDataIsUpdated() {
|
fun whenPasswordChangedLiveDataIsUpdated() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN_username_text_WHEN_onUsernameChanged_is_called_THEN_username_livedata_is_updated")
|
@DisplayName("GIVEN_username_text_WHEN_onUsernameChanged_is_called_THEN_username_livedata_is_updated")
|
||||||
@Test
|
@Test
|
||||||
fun whenUsernameChangedLiveDataIsUpdated() {
|
fun whenUsernameChangedLiveDataIsUpdated() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN_no_password_or_username_WHEN_login_is_Called_THEN_empty_credentials_are_used_in_usecase")
|
@DisplayName("GIVEN_no_password_or_username_WHEN_login_is_Called_THEN_empty_credentials_are_used_in_usecase")
|
||||||
@Test
|
@Test
|
||||||
fun noPasswordUsesEmptyStringInLoginUseCase() {
|
fun noPasswordUsesEmptyStringInLoginUseCase() {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,41 +1,29 @@
|
||||||
package org.fnives.test.showcase.ui.splash
|
package org.fnives.test.showcase.ui.splash
|
||||||
|
|
||||||
import org.fnives.test.showcase.core.login.IsUserLoggedInUseCase
|
|
||||||
import org.fnives.test.showcase.testutils.InstantExecutorExtension
|
|
||||||
import org.fnives.test.showcase.testutils.TestMainDispatcher
|
|
||||||
import org.fnives.test.showcase.ui.shared.Event
|
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Disabled
|
import org.junit.jupiter.api.Disabled
|
||||||
import org.junit.jupiter.api.DisplayName
|
import org.junit.jupiter.api.DisplayName
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.extension.ExtendWith
|
|
||||||
import org.mockito.kotlin.doReturn
|
|
||||||
import org.mockito.kotlin.mock
|
|
||||||
import org.mockito.kotlin.whenever
|
|
||||||
|
|
||||||
@Disabled("CodeKata")
|
@Disabled("CodeKata")
|
||||||
internal class CodeKataSplashViewModelTest {
|
internal class CodeKataSplashViewModelTest {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN not logged in user WHEN splash started THEN after half a second navigated to authentication")
|
@DisplayName("GIVEN not logged in user WHEN splash started THEN after half a second navigated to authentication")
|
||||||
@Test
|
@Test
|
||||||
fun loggedOutUserGoesToAuthentication() {
|
fun loggedOutUserGoesToAuthentication() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN logged in user WHEN splash started THEN after half a second navigated to home")
|
@DisplayName("GIVEN logged in user WHEN splash started THEN after half a second navigated to home")
|
||||||
@Test
|
@Test
|
||||||
fun loggedInUserGoestoHome() {
|
fun loggedInUserGoestoHome() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN not logged in user WHEN splash started THEN before half a second no event is sent")
|
@DisplayName("GIVEN not logged in user WHEN splash started THEN before half a second no event is sent")
|
||||||
@Test
|
@Test
|
||||||
fun withoutEnoughTimeNoNavigationHappens() {
|
fun withoutEnoughTimeNoNavigationHappens() {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
41
build.gradle
41
build.gradle
|
|
@ -1,49 +1,22 @@
|
||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = "1.5.30"
|
ext.kotlin_version = "1.5.30"
|
||||||
ext.detekt_version = "1.16.0"
|
ext.detekt_version = "1.18.1"
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
google()
|
google()
|
||||||
maven { url "https://plugins.gradle.org/m2/" }
|
maven { url "https://plugins.gradle.org/m2/" }
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath "com.android.tools.build:gradle:4.1.3"
|
classpath 'com.android.tools.build:gradle:7.0.2'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
classpath "org.jlleitschuh.gradle:ktlint-gradle:10.0.0"
|
classpath "org.jlleitschuh.gradle:ktlint-gradle:10.2.0"
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
|
||||||
// in the individual module build.gradle files
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//apply plugin: "io.gitlab.arturbosch.detekt" version "$detekt_version"
|
|
||||||
plugins {
|
plugins {
|
||||||
id "io.gitlab.arturbosch.detekt" version "$detekt_version"
|
id "io.gitlab.arturbosch.detekt" version "$detekt_version"
|
||||||
}
|
}
|
||||||
detekt {
|
|
||||||
toolVersion = "$detekt_version"
|
|
||||||
|
|
||||||
input = files(
|
|
||||||
"$projectDir/app/src/main/java",
|
|
||||||
"$projectDir/core/src/main/java",
|
|
||||||
"$projectDir/mockserver/src/main/java",
|
|
||||||
"$projectDir/model/src/main/java",
|
|
||||||
"$projectDir/network/src/main/java"
|
|
||||||
)
|
|
||||||
config = files("$projectDir/detekt/detekt.yml")
|
|
||||||
baseline = file("$projectDir/detekt/baseline.xml")
|
|
||||||
reports {
|
|
||||||
txt {
|
|
||||||
enabled = true
|
|
||||||
destination = file("build/reports/detekt.txt")
|
|
||||||
}
|
|
||||||
html {
|
|
||||||
enabled = true
|
|
||||||
destination = file("build/reports/detekt.html")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
|
|
@ -52,10 +25,6 @@ allprojects {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
subprojects {
|
|
||||||
apply plugin: "org.jlleitschuh.gradle.ktlint"
|
|
||||||
}
|
|
||||||
|
|
||||||
task clean(type: Delete) {
|
task clean(type: Delete) {
|
||||||
delete rootProject.buildDir
|
delete rootProject.buildDir
|
||||||
}
|
}
|
||||||
|
|
@ -71,3 +40,7 @@ task androidTests(dependsOn: "app:connectedAndroidTest"){
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: 'gradlescripts/versions.gradle'
|
apply from: 'gradlescripts/versions.gradle'
|
||||||
|
apply from: 'gradlescripts/detekt.config.gradle'
|
||||||
|
apply from: 'gradlescripts/ktlint.gradle'
|
||||||
|
apply from: 'gradlescripts/lint.gradle'
|
||||||
|
apply from: 'gradlescripts/testoptions.gradle'
|
||||||
|
|
@ -8,15 +8,6 @@ java {
|
||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
|
||||||
useJUnitPlatform()
|
|
||||||
testLogging {
|
|
||||||
events 'started', 'passed', 'skipped', 'failed'
|
|
||||||
exceptionFormat "full"
|
|
||||||
showStandardStreams true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
compileKotlin {
|
compileKotlin {
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
|
freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
|
||||||
|
|
|
||||||
|
|
@ -1,75 +1,50 @@
|
||||||
package org.fnives.test.showcase.core.content
|
package org.fnives.test.showcase.core.content
|
||||||
|
|
||||||
import kotlinx.coroutines.CompletableDeferred
|
|
||||||
import kotlinx.coroutines.async
|
|
||||||
import kotlinx.coroutines.flow.take
|
|
||||||
import kotlinx.coroutines.flow.toList
|
|
||||||
import kotlinx.coroutines.test.TestCoroutineDispatcher
|
|
||||||
import kotlinx.coroutines.test.runBlockingTest
|
import kotlinx.coroutines.test.runBlockingTest
|
||||||
import org.fnives.test.showcase.core.shared.UnexpectedException
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.fnives.test.showcase.model.content.Content
|
import org.junit.jupiter.api.Disabled
|
||||||
import org.fnives.test.showcase.model.content.ContentId
|
import org.junit.jupiter.api.DisplayName
|
||||||
import org.fnives.test.showcase.model.content.ImageUrl
|
import org.junit.jupiter.api.Test
|
||||||
import org.fnives.test.showcase.model.shared.Resource
|
|
||||||
import org.fnives.test.showcase.network.content.ContentRemoteSource
|
|
||||||
import org.junit.jupiter.api.*
|
|
||||||
import org.mockito.kotlin.doAnswer
|
|
||||||
import org.mockito.kotlin.doReturn
|
|
||||||
import org.mockito.kotlin.doSuspendableAnswer
|
|
||||||
import org.mockito.kotlin.doThrow
|
|
||||||
import org.mockito.kotlin.mock
|
|
||||||
import org.mockito.kotlin.times
|
|
||||||
import org.mockito.kotlin.verify
|
|
||||||
import org.mockito.kotlin.verifyNoMoreInteractions
|
|
||||||
import org.mockito.kotlin.whenever
|
|
||||||
|
|
||||||
@Disabled("CodeKata")
|
@Disabled("CodeKata")
|
||||||
class CodeKataContentRepositoryTest {
|
class CodeKataContentRepositoryTest {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN no interaction THEN remote source is not called")
|
@DisplayName("GIVEN no interaction THEN remote source is not called")
|
||||||
@Test
|
@Test
|
||||||
fun fetchingIsLazy() {
|
fun fetchingIsLazy() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN content response WHEN content observed THEN loading AND data is returned")
|
@DisplayName("GIVEN content response WHEN content observed THEN loading AND data is returned")
|
||||||
@Test
|
@Test
|
||||||
fun happyFlow() = runBlockingTest {
|
fun happyFlow() = runBlockingTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN content error WHEN content observed THEN loading AND data is returned")
|
@DisplayName("GIVEN content error WHEN content observed THEN loading AND data is returned")
|
||||||
@Test
|
@Test
|
||||||
fun errorFlow() = runBlockingTest {
|
fun errorFlow() = runBlockingTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN saved cache WHEN collected THEN cache is returned")
|
@DisplayName("GIVEN saved cache WHEN collected THEN cache is returned")
|
||||||
@Test
|
@Test
|
||||||
fun verifyCaching() = runBlockingTest {
|
fun verifyCaching() = runBlockingTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN no response from remote source WHEN content observed THEN loading is returned")
|
@DisplayName("GIVEN no response from remote source WHEN content observed THEN loading is returned")
|
||||||
@Test
|
@Test
|
||||||
fun loadingIsShownBeforeTheRequestIsReturned() = runBlockingTest {
|
fun loadingIsShownBeforeTheRequestIsReturned() = runBlockingTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN content response THEN error WHEN fetched THEN returned states are loading data loading error")
|
@DisplayName("GIVEN content response THEN error WHEN fetched THEN returned states are loading data loading error")
|
||||||
@Test
|
@Test
|
||||||
fun whenFetchingRequestIsCalledAgain() = runBlockingTest {
|
fun whenFetchingRequestIsCalledAgain() = runBlockingTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN content response THEN error WHEN fetched THEN only 4 items are emitted")
|
@DisplayName("GIVEN content response THEN error WHEN fetched THEN only 4 items are emitted")
|
||||||
@Test
|
@Test
|
||||||
fun noAdditionalItemsEmitted() {
|
fun noAdditionalItemsEmitted() {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -16,7 +16,15 @@ import org.junit.jupiter.api.Assertions
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.DisplayName
|
import org.junit.jupiter.api.DisplayName
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.mockito.kotlin.*
|
import org.mockito.kotlin.doAnswer
|
||||||
|
import org.mockito.kotlin.doReturn
|
||||||
|
import org.mockito.kotlin.doSuspendableAnswer
|
||||||
|
import org.mockito.kotlin.doThrow
|
||||||
|
import org.mockito.kotlin.mock
|
||||||
|
import org.mockito.kotlin.times
|
||||||
|
import org.mockito.kotlin.verify
|
||||||
|
import org.mockito.kotlin.verifyNoMoreInteractions
|
||||||
|
import org.mockito.kotlin.whenever
|
||||||
|
|
||||||
@Suppress("TestFunctionName")
|
@Suppress("TestFunctionName")
|
||||||
internal class ContentRepositoryTest {
|
internal class ContentRepositoryTest {
|
||||||
|
|
@ -43,10 +51,19 @@ internal class ContentRepositoryTest {
|
||||||
@Test
|
@Test
|
||||||
fun happyFlow() = runBlockingTest {
|
fun happyFlow() = runBlockingTest {
|
||||||
val expected = listOf(
|
val expected = listOf(
|
||||||
Resource.Loading(),
|
Resource.Loading(),
|
||||||
Resource.Success(listOf(Content(ContentId("a"), "", "", ImageUrl(""))))
|
Resource.Success(listOf(Content(ContentId("a"), "", "", ImageUrl(""))))
|
||||||
|
)
|
||||||
|
whenever(mockContentRemoteSource.get()).doReturn(
|
||||||
|
listOf(
|
||||||
|
Content(
|
||||||
|
ContentId("a"),
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
ImageUrl("")
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
whenever(mockContentRemoteSource.get()).doReturn(listOf(Content(ContentId("a"), "", "", ImageUrl(""))))
|
|
||||||
|
|
||||||
val actual = sut.contents.take(2).toList()
|
val actual = sut.contents.take(2).toList()
|
||||||
|
|
||||||
|
|
@ -58,8 +75,8 @@ internal class ContentRepositoryTest {
|
||||||
fun errorFlow() = runBlockingTest {
|
fun errorFlow() = runBlockingTest {
|
||||||
val exception = RuntimeException()
|
val exception = RuntimeException()
|
||||||
val expected = listOf(
|
val expected = listOf(
|
||||||
Resource.Loading(),
|
Resource.Loading(),
|
||||||
Resource.Error<List<Content>>(UnexpectedException(exception))
|
Resource.Error<List<Content>>(UnexpectedException(exception))
|
||||||
)
|
)
|
||||||
whenever(mockContentRemoteSource.get()).doThrow(exception)
|
whenever(mockContentRemoteSource.get()).doThrow(exception)
|
||||||
|
|
||||||
|
|
@ -101,27 +118,27 @@ internal class ContentRepositoryTest {
|
||||||
@DisplayName("GIVEN content response THEN error WHEN fetched THEN returned states are loading data loading error")
|
@DisplayName("GIVEN content response THEN error WHEN fetched THEN returned states are loading data loading error")
|
||||||
@Test
|
@Test
|
||||||
fun whenFetchingRequestIsCalledAgain() =
|
fun whenFetchingRequestIsCalledAgain() =
|
||||||
runBlockingTest(testDispatcher) {
|
runBlockingTest(testDispatcher) {
|
||||||
val exception = RuntimeException()
|
val exception = RuntimeException()
|
||||||
val expected = listOf(
|
val expected = listOf(
|
||||||
Resource.Loading(),
|
Resource.Loading(),
|
||||||
Resource.Success(emptyList()),
|
Resource.Success(emptyList()),
|
||||||
Resource.Loading(),
|
Resource.Loading(),
|
||||||
Resource.Error<List<Content>>(UnexpectedException(exception))
|
Resource.Error<List<Content>>(UnexpectedException(exception))
|
||||||
)
|
)
|
||||||
var first = true
|
var first = true
|
||||||
whenever(mockContentRemoteSource.get()).doAnswer {
|
whenever(mockContentRemoteSource.get()).doAnswer {
|
||||||
if (first) emptyList<Content>().also { first = false } else throw exception
|
if (first) emptyList<Content>().also { first = false } else throw exception
|
||||||
}
|
|
||||||
|
|
||||||
val actual = async(testDispatcher) { sut.contents.take(4).toList() }
|
|
||||||
testDispatcher.advanceUntilIdle()
|
|
||||||
sut.fetch()
|
|
||||||
testDispatcher.advanceUntilIdle()
|
|
||||||
|
|
||||||
Assertions.assertEquals(expected, actual.await())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val actual = async(testDispatcher) { sut.contents.take(4).toList() }
|
||||||
|
testDispatcher.advanceUntilIdle()
|
||||||
|
sut.fetch()
|
||||||
|
testDispatcher.advanceUntilIdle()
|
||||||
|
|
||||||
|
Assertions.assertEquals(expected, actual.await())
|
||||||
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN content response THEN error WHEN fetched THEN only 4 items are emitted")
|
@DisplayName("GIVEN content response THEN error WHEN fetched THEN only 4 items are emitted")
|
||||||
@Test
|
@Test
|
||||||
fun noAdditionalItemsEmitted() {
|
fun noAdditionalItemsEmitted() {
|
||||||
|
|
@ -129,10 +146,10 @@ internal class ContentRepositoryTest {
|
||||||
runBlockingTest(testDispatcher) {
|
runBlockingTest(testDispatcher) {
|
||||||
val exception = RuntimeException()
|
val exception = RuntimeException()
|
||||||
val expected = listOf(
|
val expected = listOf(
|
||||||
Resource.Loading(),
|
Resource.Loading(),
|
||||||
Resource.Success(emptyList()),
|
Resource.Success(emptyList()),
|
||||||
Resource.Loading(),
|
Resource.Loading(),
|
||||||
Resource.Error<List<Content>>(UnexpectedException(exception))
|
Resource.Error<List<Content>>(UnexpectedException(exception))
|
||||||
)
|
)
|
||||||
var first = true
|
var first = true
|
||||||
whenever(mockContentRemoteSource.get()).doAnswer {
|
whenever(mockContentRemoteSource.get()).doAnswer {
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,9 @@
|
||||||
package org.fnives.test.showcase.core.login
|
package org.fnives.test.showcase.core.login
|
||||||
|
|
||||||
import kotlinx.coroutines.test.runBlockingTest
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.fnives.test.showcase.core.shared.UnexpectedException
|
import org.junit.jupiter.api.Disabled
|
||||||
import org.fnives.test.showcase.core.storage.UserDataLocalStorage
|
import org.junit.jupiter.api.DisplayName
|
||||||
import org.fnives.test.showcase.model.auth.LoginCredentials
|
import org.junit.jupiter.api.Test
|
||||||
import org.fnives.test.showcase.model.auth.LoginStatus
|
|
||||||
import org.fnives.test.showcase.model.session.Session
|
|
||||||
import org.fnives.test.showcase.model.shared.Answer
|
|
||||||
import org.fnives.test.showcase.network.auth.LoginRemoteSource
|
|
||||||
import org.fnives.test.showcase.network.auth.model.LoginStatusResponses
|
|
||||||
import org.junit.jupiter.api.*
|
|
||||||
import org.mockito.kotlin.*
|
|
||||||
|
|
||||||
@Disabled("CodeKata")
|
@Disabled("CodeKata")
|
||||||
class CodeKataSecondLoginUseCaseTest {
|
class CodeKataSecondLoginUseCaseTest {
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,14 @@ import org.junit.jupiter.api.Assertions
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.DisplayName
|
import org.junit.jupiter.api.DisplayName
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.mockito.kotlin.*
|
import org.mockito.kotlin.doReturn
|
||||||
import java.util.stream.Stream
|
import org.mockito.kotlin.doThrow
|
||||||
|
import org.mockito.kotlin.mock
|
||||||
|
import org.mockito.kotlin.times
|
||||||
|
import org.mockito.kotlin.verify
|
||||||
|
import org.mockito.kotlin.verifyNoMoreInteractions
|
||||||
|
import org.mockito.kotlin.verifyZeroInteractions
|
||||||
|
import org.mockito.kotlin.whenever
|
||||||
|
|
||||||
@Suppress("TestFunctionName")
|
@Suppress("TestFunctionName")
|
||||||
internal class LoginUseCaseTest {
|
internal class LoginUseCaseTest {
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,6 @@
|
||||||
package org.fnives.test.showcase.core.session
|
package org.fnives.test.showcase.core.session
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach
|
|
||||||
import org.junit.jupiter.api.Disabled
|
import org.junit.jupiter.api.Disabled
|
||||||
import org.junit.jupiter.api.DisplayName
|
|
||||||
import org.junit.jupiter.api.Test
|
|
||||||
import org.mockito.kotlin.*
|
|
||||||
|
|
||||||
@Disabled("CodeKata")
|
@Disabled("CodeKata")
|
||||||
class CodeKataFirstSessionExpirationAdapterTest {
|
class CodeKataFirstSessionExpirationAdapterTest
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,56 +1,79 @@
|
||||||
build:
|
build:
|
||||||
maxIssues: 15
|
maxIssues: 0
|
||||||
|
excludeCorrectable: false
|
||||||
weights:
|
weights:
|
||||||
# complexity: 2
|
# complexity: 2
|
||||||
# LongParameterList: 1
|
# LongParameterList: 1
|
||||||
# style: 1
|
# style: 1
|
||||||
# comments: 1
|
# comments: 1
|
||||||
|
|
||||||
config:
|
config:
|
||||||
validation: true
|
validation: true
|
||||||
# when writing own rules with new properties, exclude the property path e.g.: "my_rule_set,.*>.*>[my_property]"
|
warningsAsErrors: false
|
||||||
excludes: ""
|
# when writing own rules with new properties, exclude the property path e.g.: 'my_rule_set,.*>.*>[my_property]'
|
||||||
|
excludes: ''
|
||||||
|
|
||||||
processors:
|
processors:
|
||||||
active: true
|
active: true
|
||||||
exclude:
|
exclude:
|
||||||
# - 'DetektProgressListener'
|
- 'DetektProgressListener'
|
||||||
|
# - 'KtFileCountProcessor'
|
||||||
|
# - 'PackageCountProcessor'
|
||||||
|
# - 'ClassCountProcessor'
|
||||||
# - 'FunctionCountProcessor'
|
# - 'FunctionCountProcessor'
|
||||||
# - 'PropertyCountProcessor'
|
# - 'PropertyCountProcessor'
|
||||||
# - 'ClassCountProcessor'
|
# - 'ProjectComplexityProcessor'
|
||||||
# - 'PackageCountProcessor'
|
# - 'ProjectCognitiveComplexityProcessor'
|
||||||
# - 'KtFileCountProcessor'
|
# - 'ProjectLLOCProcessor'
|
||||||
|
# - 'ProjectCLOCProcessor'
|
||||||
|
# - 'ProjectLOCProcessor'
|
||||||
|
# - 'ProjectSLOCProcessor'
|
||||||
|
# - 'LicenseHeaderLoaderExtension'
|
||||||
|
|
||||||
console-reports:
|
console-reports:
|
||||||
active: true
|
active: true
|
||||||
exclude:
|
exclude:
|
||||||
# - 'ProjectStatisticsReport'
|
- 'ProjectStatisticsReport'
|
||||||
# - 'ComplexityReport'
|
- 'ComplexityReport'
|
||||||
# - 'NotificationReport'
|
- 'NotificationReport'
|
||||||
# - 'FindingsReport'
|
# - 'FindingsReport'
|
||||||
- 'FileBasedFindingsReport'
|
- 'FileBasedFindingsReport'
|
||||||
# - 'BuildFailureReport'
|
|
||||||
|
output-reports:
|
||||||
|
active: true
|
||||||
|
exclude:
|
||||||
|
# - 'TxtOutputReport'
|
||||||
|
# - 'XmlOutputReport'
|
||||||
|
# - 'HtmlOutputReport'
|
||||||
|
|
||||||
comments:
|
comments:
|
||||||
active: true
|
active: true
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
AbsentOrWrongFileLicense:
|
||||||
|
active: false
|
||||||
|
licenseTemplateFile: 'license.template'
|
||||||
|
licenseTemplateIsRegex: false
|
||||||
CommentOverPrivateFunction:
|
CommentOverPrivateFunction:
|
||||||
active: false
|
active: false
|
||||||
CommentOverPrivateProperty:
|
CommentOverPrivateProperty:
|
||||||
active: false
|
active: false
|
||||||
|
DeprecatedBlockTag:
|
||||||
|
active: false
|
||||||
EndOfSentenceFormat:
|
EndOfSentenceFormat:
|
||||||
active: false
|
active: false
|
||||||
endOfSentenceFormat: ([.?!][ \t\n\r\f<])|([.?!:]$)
|
endOfSentenceFormat: '([.?!][ \t\n\r\f<])|([.?!:]$)'
|
||||||
UndocumentedPublicClass:
|
UndocumentedPublicClass:
|
||||||
active: false
|
active: false
|
||||||
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
searchInNestedClass: true
|
searchInNestedClass: true
|
||||||
searchInInnerClass: true
|
searchInInnerClass: true
|
||||||
searchInInnerObject: true
|
searchInInnerObject: true
|
||||||
searchInInnerInterface: true
|
searchInInnerInterface: true
|
||||||
UndocumentedPublicFunction:
|
UndocumentedPublicFunction:
|
||||||
active: false
|
active: false
|
||||||
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
UndocumentedPublicProperty:
|
UndocumentedPublicProperty:
|
||||||
active: false
|
active: false
|
||||||
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
|
|
||||||
complexity:
|
complexity:
|
||||||
active: true
|
active: true
|
||||||
|
|
@ -61,57 +84,86 @@ complexity:
|
||||||
active: false
|
active: false
|
||||||
threshold: 10
|
threshold: 10
|
||||||
includeStaticDeclarations: false
|
includeStaticDeclarations: false
|
||||||
|
includePrivateDeclarations: false
|
||||||
ComplexMethod:
|
ComplexMethod:
|
||||||
active: true
|
active: true
|
||||||
threshold: 25
|
threshold: 15
|
||||||
ignoreSingleWhenExpression: false
|
ignoreSingleWhenExpression: false
|
||||||
ignoreSimpleWhenEntries: false
|
ignoreSimpleWhenEntries: false
|
||||||
ignoreNestingFunctions: false
|
ignoreNestingFunctions: false
|
||||||
nestingFunctions: run,let,apply,with,also,use,forEach,isNotNull,ifNull
|
nestingFunctions:
|
||||||
|
- 'also'
|
||||||
|
- 'apply'
|
||||||
|
- 'forEach'
|
||||||
|
- 'isNotNull'
|
||||||
|
- 'ifNull'
|
||||||
|
- 'let'
|
||||||
|
- 'run'
|
||||||
|
- 'use'
|
||||||
|
- 'with'
|
||||||
LabeledExpression:
|
LabeledExpression:
|
||||||
active: false
|
active: false
|
||||||
ignoredLabels: ""
|
ignoredLabels: []
|
||||||
LargeClass:
|
LargeClass:
|
||||||
active: true
|
active: true
|
||||||
threshold: 600
|
threshold: 600
|
||||||
LongMethod:
|
LongMethod:
|
||||||
active: true
|
active: true
|
||||||
threshold: 200
|
threshold: 60
|
||||||
|
ignoreAnnotated: []
|
||||||
LongParameterList:
|
LongParameterList:
|
||||||
active: true
|
active: true
|
||||||
functionThreshold: 6
|
functionThreshold: 6
|
||||||
constructorThreshold: 6
|
constructorThreshold: 7
|
||||||
ignoreDefaultParameters: false
|
ignoreDefaultParameters: false
|
||||||
|
ignoreDataClasses: true
|
||||||
|
ignoreAnnotated: []
|
||||||
MethodOverloading:
|
MethodOverloading:
|
||||||
active: false
|
active: false
|
||||||
threshold: 6
|
threshold: 6
|
||||||
|
NamedArguments:
|
||||||
|
active: false
|
||||||
|
threshold: 3
|
||||||
NestedBlockDepth:
|
NestedBlockDepth:
|
||||||
active: true
|
active: true
|
||||||
threshold: 100
|
threshold: 4
|
||||||
|
ReplaceSafeCallChainWithRun:
|
||||||
|
active: false
|
||||||
StringLiteralDuplication:
|
StringLiteralDuplication:
|
||||||
active: false
|
active: false
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
threshold: 3
|
threshold: 3
|
||||||
ignoreAnnotation: true
|
ignoreAnnotation: true
|
||||||
excludeStringsWithLessThan5Characters: true
|
excludeStringsWithLessThan5Characters: true
|
||||||
ignoreStringsRegex: '$^'
|
ignoreStringsRegex: '$^'
|
||||||
TooManyFunctions:
|
TooManyFunctions:
|
||||||
active: true
|
active: true
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
thresholdInFiles: 25
|
thresholdInFiles: 11
|
||||||
thresholdInClasses: 25
|
thresholdInClasses: 11
|
||||||
thresholdInInterfaces: 25
|
thresholdInInterfaces: 11
|
||||||
thresholdInObjects: 25
|
thresholdInObjects: 11
|
||||||
thresholdInEnums: 25
|
thresholdInEnums: 11
|
||||||
ignoreDeprecated: false
|
ignoreDeprecated: false
|
||||||
ignorePrivate: false
|
ignorePrivate: false
|
||||||
ignoreOverridden: false
|
ignoreOverridden: false
|
||||||
|
|
||||||
|
coroutines:
|
||||||
|
active: true
|
||||||
|
GlobalCoroutineUsage:
|
||||||
|
active: false
|
||||||
|
RedundantSuspendModifier:
|
||||||
|
active: false
|
||||||
|
SleepInsteadOfDelay:
|
||||||
|
active: false
|
||||||
|
SuspendFunWithFlowReturnType:
|
||||||
|
active: false
|
||||||
|
|
||||||
empty-blocks:
|
empty-blocks:
|
||||||
active: true
|
active: true
|
||||||
EmptyCatchBlock:
|
EmptyCatchBlock:
|
||||||
active: true
|
active: true
|
||||||
allowedExceptionNameRegex: "^(_|(ignore|expected).*)"
|
allowedExceptionNameRegex: '_|(ignore|expected).*'
|
||||||
EmptyClassBlock:
|
EmptyClassBlock:
|
||||||
active: true
|
active: true
|
||||||
EmptyDefaultConstructor:
|
EmptyDefaultConstructor:
|
||||||
|
|
@ -135,6 +187,8 @@ empty-blocks:
|
||||||
active: true
|
active: true
|
||||||
EmptySecondaryConstructor:
|
EmptySecondaryConstructor:
|
||||||
active: true
|
active: true
|
||||||
|
EmptyTryBlock:
|
||||||
|
active: true
|
||||||
EmptyWhenBlock:
|
EmptyWhenBlock:
|
||||||
active: true
|
active: true
|
||||||
EmptyWhileBlock:
|
EmptyWhileBlock:
|
||||||
|
|
@ -143,53 +197,73 @@ empty-blocks:
|
||||||
exceptions:
|
exceptions:
|
||||||
active: true
|
active: true
|
||||||
ExceptionRaisedInUnexpectedLocation:
|
ExceptionRaisedInUnexpectedLocation:
|
||||||
active: false
|
active: true
|
||||||
methodNames: 'toString,hashCode,equals,finalize'
|
methodNames:
|
||||||
|
- 'equals'
|
||||||
|
- 'finalize'
|
||||||
|
- 'hashCode'
|
||||||
|
- 'toString'
|
||||||
InstanceOfCheckForException:
|
InstanceOfCheckForException:
|
||||||
active: false
|
active: false
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
NotImplementedDeclaration:
|
NotImplementedDeclaration:
|
||||||
active: false
|
active: false
|
||||||
|
ObjectExtendsThrowable:
|
||||||
|
active: false
|
||||||
PrintStackTrace:
|
PrintStackTrace:
|
||||||
active: false
|
active: true
|
||||||
RethrowCaughtException:
|
RethrowCaughtException:
|
||||||
active: false
|
active: true
|
||||||
ReturnFromFinally:
|
ReturnFromFinally:
|
||||||
active: false
|
active: true
|
||||||
ignoreLabeled: false
|
ignoreLabeled: false
|
||||||
SwallowedException:
|
SwallowedException:
|
||||||
active: false
|
active: true
|
||||||
ignoredExceptionTypes: 'InterruptedException,NumberFormatException,ParseException,MalformedURLException'
|
ignoredExceptionTypes:
|
||||||
allowedExceptionNameRegex: "^(_|(ignore|expected).*)"
|
- 'InterruptedException'
|
||||||
|
- 'MalformedURLException'
|
||||||
|
- 'NumberFormatException'
|
||||||
|
- 'ParseException'
|
||||||
|
allowedExceptionNameRegex: '_|(ignore|expected).*'
|
||||||
ThrowingExceptionFromFinally:
|
ThrowingExceptionFromFinally:
|
||||||
active: false
|
active: true
|
||||||
ThrowingExceptionInMain:
|
ThrowingExceptionInMain:
|
||||||
active: false
|
active: false
|
||||||
ThrowingExceptionsWithoutMessageOrCause:
|
ThrowingExceptionsWithoutMessageOrCause:
|
||||||
active: true
|
active: true
|
||||||
exceptions: 'IllegalArgumentException,IllegalStateException,IOException'
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
|
exceptions:
|
||||||
|
- 'ArrayIndexOutOfBoundsException'
|
||||||
|
- 'Exception'
|
||||||
|
- 'IllegalArgumentException'
|
||||||
|
- 'IllegalMonitorStateException'
|
||||||
|
- 'IllegalStateException'
|
||||||
|
- 'IndexOutOfBoundsException'
|
||||||
|
- 'NullPointerException'
|
||||||
|
- 'RuntimeException'
|
||||||
|
- 'Throwable'
|
||||||
ThrowingNewInstanceOfSameException:
|
ThrowingNewInstanceOfSameException:
|
||||||
active: true
|
active: true
|
||||||
TooGenericExceptionCaught:
|
TooGenericExceptionCaught:
|
||||||
active: true
|
active: true
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
exceptionNames:
|
exceptionNames:
|
||||||
- ArrayIndexOutOfBoundsException
|
- 'ArrayIndexOutOfBoundsException'
|
||||||
- Error
|
- 'Error'
|
||||||
- Exception
|
- 'Exception'
|
||||||
- IllegalMonitorStateException
|
- 'IllegalMonitorStateException'
|
||||||
- NullPointerException
|
- 'IndexOutOfBoundsException'
|
||||||
- IndexOutOfBoundsException
|
- 'NullPointerException'
|
||||||
- RuntimeException
|
- 'RuntimeException'
|
||||||
- Throwable
|
- 'Throwable'
|
||||||
allowedExceptionNameRegex: "^(_|(ignore|expected).*)"
|
allowedExceptionNameRegex: '_|(ignore|expected).*'
|
||||||
TooGenericExceptionThrown:
|
TooGenericExceptionThrown:
|
||||||
active: true
|
active: true
|
||||||
exceptionNames:
|
exceptionNames:
|
||||||
- Error
|
- 'Error'
|
||||||
- Exception
|
- 'Exception'
|
||||||
- Throwable
|
- 'RuntimeException'
|
||||||
- RuntimeException
|
- 'Throwable'
|
||||||
|
|
||||||
formatting:
|
formatting:
|
||||||
active: true
|
active: true
|
||||||
|
|
@ -198,28 +272,42 @@ formatting:
|
||||||
AnnotationOnSeparateLine:
|
AnnotationOnSeparateLine:
|
||||||
active: false
|
active: false
|
||||||
autoCorrect: true
|
autoCorrect: true
|
||||||
|
AnnotationSpacing:
|
||||||
|
active: false
|
||||||
|
autoCorrect: true
|
||||||
|
ArgumentListWrapping:
|
||||||
|
active: false
|
||||||
|
autoCorrect: true
|
||||||
|
indentSize: 4
|
||||||
|
maxLineLength: 120
|
||||||
ChainWrapping:
|
ChainWrapping:
|
||||||
active: true
|
active: true
|
||||||
autoCorrect: true
|
autoCorrect: true
|
||||||
CommentSpacing:
|
CommentSpacing:
|
||||||
active: true
|
active: true
|
||||||
autoCorrect: true
|
autoCorrect: true
|
||||||
|
EnumEntryNameCase:
|
||||||
|
active: false
|
||||||
|
autoCorrect: true
|
||||||
Filename:
|
Filename:
|
||||||
active: true
|
active: true
|
||||||
FinalNewline:
|
FinalNewline:
|
||||||
active: true
|
active: true
|
||||||
autoCorrect: true
|
autoCorrect: true
|
||||||
|
insertFinalNewLine: true
|
||||||
ImportOrdering:
|
ImportOrdering:
|
||||||
active: true
|
active: false
|
||||||
autoCorrect: true
|
autoCorrect: true
|
||||||
|
layout: '*,java.**,javax.**,kotlin.**,^'
|
||||||
Indentation:
|
Indentation:
|
||||||
active: true
|
active: false
|
||||||
autoCorrect: true
|
autoCorrect: true
|
||||||
indentSize: 4
|
indentSize: 4
|
||||||
continuationIndentSize: 4
|
continuationIndentSize: 4
|
||||||
MaximumLineLength:
|
MaximumLineLength:
|
||||||
active: true
|
active: true
|
||||||
maxLineLength: 250
|
maxLineLength: 120
|
||||||
|
ignoreBackTickedIdentifier: false
|
||||||
ModifierOrdering:
|
ModifierOrdering:
|
||||||
active: true
|
active: true
|
||||||
autoCorrect: true
|
autoCorrect: true
|
||||||
|
|
@ -235,6 +323,9 @@ formatting:
|
||||||
NoEmptyClassBody:
|
NoEmptyClassBody:
|
||||||
active: true
|
active: true
|
||||||
autoCorrect: true
|
autoCorrect: true
|
||||||
|
NoEmptyFirstLineInMethodBlock:
|
||||||
|
active: false
|
||||||
|
autoCorrect: true
|
||||||
NoLineBreakAfterElse:
|
NoLineBreakAfterElse:
|
||||||
active: true
|
active: true
|
||||||
autoCorrect: true
|
autoCorrect: true
|
||||||
|
|
@ -265,6 +356,10 @@ formatting:
|
||||||
active: true
|
active: true
|
||||||
autoCorrect: true
|
autoCorrect: true
|
||||||
indentSize: 4
|
indentSize: 4
|
||||||
|
maxLineLength: 120
|
||||||
|
SpacingAroundAngleBrackets:
|
||||||
|
active: false
|
||||||
|
autoCorrect: true
|
||||||
SpacingAroundColon:
|
SpacingAroundColon:
|
||||||
active: true
|
active: true
|
||||||
autoCorrect: true
|
autoCorrect: true
|
||||||
|
|
@ -277,6 +372,9 @@ formatting:
|
||||||
SpacingAroundDot:
|
SpacingAroundDot:
|
||||||
active: true
|
active: true
|
||||||
autoCorrect: true
|
autoCorrect: true
|
||||||
|
SpacingAroundDoubleColon:
|
||||||
|
active: false
|
||||||
|
autoCorrect: true
|
||||||
SpacingAroundKeyword:
|
SpacingAroundKeyword:
|
||||||
active: true
|
active: true
|
||||||
autoCorrect: true
|
autoCorrect: true
|
||||||
|
|
@ -289,85 +387,108 @@ formatting:
|
||||||
SpacingAroundRangeOperator:
|
SpacingAroundRangeOperator:
|
||||||
active: true
|
active: true
|
||||||
autoCorrect: true
|
autoCorrect: true
|
||||||
|
SpacingAroundUnaryOperator:
|
||||||
|
active: false
|
||||||
|
autoCorrect: true
|
||||||
|
SpacingBetweenDeclarationsWithAnnotations:
|
||||||
|
active: false
|
||||||
|
autoCorrect: true
|
||||||
|
SpacingBetweenDeclarationsWithComments:
|
||||||
|
active: false
|
||||||
|
autoCorrect: true
|
||||||
StringTemplate:
|
StringTemplate:
|
||||||
active: true
|
active: true
|
||||||
autoCorrect: true
|
autoCorrect: true
|
||||||
|
|
||||||
naming:
|
naming:
|
||||||
active: true
|
active: true
|
||||||
|
BooleanPropertyNaming:
|
||||||
|
active: false
|
||||||
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
|
allowedPattern: '^(is|has|are)'
|
||||||
ClassNaming:
|
ClassNaming:
|
||||||
active: true
|
active: true
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
classPattern: '[A-Z$][a-zA-Z0-9$]*'
|
classPattern: '[A-Z][a-zA-Z0-9]*'
|
||||||
ConstructorParameterNaming:
|
ConstructorParameterNaming:
|
||||||
active: true
|
active: true
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
parameterPattern: '[a-z][A-Za-z0-9]*'
|
parameterPattern: '[a-z][A-Za-z0-9]*'
|
||||||
privateParameterPattern: '[a-z][A-Za-z0-9]*'
|
privateParameterPattern: '[a-z][A-Za-z0-9]*'
|
||||||
excludeClassPattern: '$^'
|
excludeClassPattern: '$^'
|
||||||
|
ignoreOverridden: true
|
||||||
EnumNaming:
|
EnumNaming:
|
||||||
active: true
|
active: true
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
enumEntryPattern: '^[A-Z][_a-zA-Z0-9]*'
|
enumEntryPattern: '[A-Z][_a-zA-Z0-9]*'
|
||||||
ForbiddenClassName:
|
ForbiddenClassName:
|
||||||
active: false
|
active: false
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
forbiddenName: ''
|
forbiddenName: []
|
||||||
FunctionMaxLength:
|
FunctionMaxLength:
|
||||||
active: false
|
active: false
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
maximumFunctionNameLength: 30
|
maximumFunctionNameLength: 30
|
||||||
FunctionMinLength:
|
FunctionMinLength:
|
||||||
active: false
|
active: false
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
minimumFunctionNameLength: 3
|
minimumFunctionNameLength: 3
|
||||||
FunctionNaming:
|
FunctionNaming:
|
||||||
active: true
|
active: true
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
functionPattern: '^([a-z$][a-zA-Z$0-9]*)|(`.*`)$'
|
functionPattern: '([a-z][a-zA-Z0-9]*)|(`.*`)'
|
||||||
excludeClassPattern: '$^'
|
excludeClassPattern: '$^'
|
||||||
ignoreOverridden: true
|
ignoreOverridden: true
|
||||||
|
ignoreAnnotated:
|
||||||
|
- 'Composable'
|
||||||
FunctionParameterNaming:
|
FunctionParameterNaming:
|
||||||
active: true
|
active: true
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
parameterPattern: '[a-z][A-Za-z0-9]*'
|
parameterPattern: '[a-z][A-Za-z0-9]*'
|
||||||
excludeClassPattern: '$^'
|
excludeClassPattern: '$^'
|
||||||
ignoreOverridden: true
|
ignoreOverridden: true
|
||||||
InvalidPackageDeclaration:
|
InvalidPackageDeclaration:
|
||||||
active: false
|
active: false
|
||||||
|
excludes: ['**/*.kts']
|
||||||
rootPackage: ''
|
rootPackage: ''
|
||||||
MatchingDeclarationName:
|
MatchingDeclarationName:
|
||||||
active: true
|
active: true
|
||||||
|
mustBeFirst: true
|
||||||
MemberNameEqualsClassName:
|
MemberNameEqualsClassName:
|
||||||
active: true
|
active: true
|
||||||
ignoreOverridden: true
|
ignoreOverridden: true
|
||||||
|
NoNameShadowing:
|
||||||
|
active: false
|
||||||
|
NonBooleanPropertyPrefixedWithIs:
|
||||||
|
active: false
|
||||||
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
ObjectPropertyNaming:
|
ObjectPropertyNaming:
|
||||||
active: true
|
active: true
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
constantPattern: '[A-Za-z][_A-Za-z0-9]*'
|
constantPattern: '[A-Za-z][_A-Za-z0-9]*'
|
||||||
propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
|
propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
|
||||||
privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*'
|
privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*'
|
||||||
PackageNaming:
|
PackageNaming:
|
||||||
active: false
|
active: true
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
packagePattern: '^[a-z]+(\.[a-z][A-Za-z0-9]*)*$'
|
packagePattern: '[a-z]+(\.[a-z][A-Za-z0-9]*)*'
|
||||||
TopLevelPropertyNaming:
|
TopLevelPropertyNaming:
|
||||||
active: true
|
active: true
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
constantPattern: '[A-Z][_A-Z0-9]*'
|
constantPattern: '[A-Z][_A-Z0-9]*'
|
||||||
propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
|
propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
|
||||||
privatePropertyPattern: '_?[A-Za-z][_A-Za-z0-9]*'
|
privatePropertyPattern: '_?[A-Za-z][_A-Za-z0-9]*'
|
||||||
VariableMaxLength:
|
VariableMaxLength:
|
||||||
active: false
|
active: false
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
maximumVariableNameLength: 64
|
maximumVariableNameLength: 64
|
||||||
VariableMinLength:
|
VariableMinLength:
|
||||||
active: false
|
active: false
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
minimumVariableNameLength: 1
|
minimumVariableNameLength: 1
|
||||||
VariableNaming:
|
VariableNaming:
|
||||||
active: true
|
active: true
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
variablePattern: '[a-z][A-Za-z0-9]*'
|
variablePattern: '[a-z][A-Za-z0-9]*'
|
||||||
privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*'
|
privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*'
|
||||||
excludeClassPattern: '$^'
|
excludeClassPattern: '$^'
|
||||||
|
|
@ -379,29 +500,52 @@ performance:
|
||||||
active: true
|
active: true
|
||||||
ForEachOnRange:
|
ForEachOnRange:
|
||||||
active: true
|
active: true
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
SpreadOperator:
|
SpreadOperator:
|
||||||
active: true
|
active: true
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
UnnecessaryTemporaryInstantiation:
|
UnnecessaryTemporaryInstantiation:
|
||||||
active: true
|
active: true
|
||||||
|
|
||||||
potential-bugs:
|
potential-bugs:
|
||||||
active: true
|
active: true
|
||||||
|
AvoidReferentialEquality:
|
||||||
|
active: false
|
||||||
|
forbiddenTypePatterns:
|
||||||
|
- 'kotlin.String'
|
||||||
|
CastToNullableType:
|
||||||
|
active: false
|
||||||
Deprecation:
|
Deprecation:
|
||||||
active: false
|
active: false
|
||||||
|
DontDowncastCollectionTypes:
|
||||||
|
active: false
|
||||||
|
DoubleMutabilityForCollection:
|
||||||
|
active: false
|
||||||
DuplicateCaseInWhenExpression:
|
DuplicateCaseInWhenExpression:
|
||||||
active: true
|
active: true
|
||||||
EqualsAlwaysReturnsTrueOrFalse:
|
EqualsAlwaysReturnsTrueOrFalse:
|
||||||
active: true
|
active: true
|
||||||
EqualsWithHashCodeExist:
|
EqualsWithHashCodeExist:
|
||||||
active: true
|
active: true
|
||||||
|
ExitOutsideMain:
|
||||||
|
active: false
|
||||||
ExplicitGarbageCollectionCall:
|
ExplicitGarbageCollectionCall:
|
||||||
active: true
|
active: true
|
||||||
HasPlatformType:
|
HasPlatformType:
|
||||||
active: false
|
active: false
|
||||||
ImplicitDefaultLocale:
|
IgnoredReturnValue:
|
||||||
active: false
|
active: false
|
||||||
|
restrictToAnnotatedMethods: true
|
||||||
|
returnValueAnnotations:
|
||||||
|
- '*.CheckResult'
|
||||||
|
- '*.CheckReturnValue'
|
||||||
|
ignoreReturnValueAnnotations:
|
||||||
|
- '*.CanIgnoreReturnValue'
|
||||||
|
ImplicitDefaultLocale:
|
||||||
|
active: true
|
||||||
|
ImplicitUnitReturnType:
|
||||||
|
active: false
|
||||||
|
allowExplicitReturnType: true
|
||||||
InvalidRange:
|
InvalidRange:
|
||||||
active: true
|
active: true
|
||||||
IteratorHasNextCallsNextMethod:
|
IteratorHasNextCallsNextMethod:
|
||||||
|
|
@ -410,20 +554,33 @@ potential-bugs:
|
||||||
active: true
|
active: true
|
||||||
LateinitUsage:
|
LateinitUsage:
|
||||||
active: false
|
active: false
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
excludeAnnotatedProperties: ""
|
excludeAnnotatedProperties: []
|
||||||
ignoreOnClassesPattern: ""
|
ignoreOnClassesPattern: ''
|
||||||
|
MapGetWithNotNullAssertionOperator:
|
||||||
|
active: false
|
||||||
MissingWhenCase:
|
MissingWhenCase:
|
||||||
active: true
|
active: true
|
||||||
|
allowElseExpression: true
|
||||||
|
NullableToStringCall:
|
||||||
|
active: false
|
||||||
RedundantElseInWhen:
|
RedundantElseInWhen:
|
||||||
active: true
|
active: true
|
||||||
UnconditionalJumpStatementInLoop:
|
UnconditionalJumpStatementInLoop:
|
||||||
active: false
|
active: false
|
||||||
|
UnnecessaryNotNullOperator:
|
||||||
|
active: true
|
||||||
|
UnnecessarySafeCall:
|
||||||
|
active: true
|
||||||
|
UnreachableCatchBlock:
|
||||||
|
active: false
|
||||||
UnreachableCode:
|
UnreachableCode:
|
||||||
active: true
|
active: true
|
||||||
UnsafeCallOnNullableType:
|
UnsafeCallOnNullableType:
|
||||||
active: true
|
active: true
|
||||||
UnsafeCast:
|
UnsafeCast:
|
||||||
|
active: true
|
||||||
|
UnusedUnaryOperator:
|
||||||
active: false
|
active: false
|
||||||
UselessPostfixExpression:
|
UselessPostfixExpression:
|
||||||
active: false
|
active: false
|
||||||
|
|
@ -432,30 +589,51 @@ potential-bugs:
|
||||||
|
|
||||||
style:
|
style:
|
||||||
active: true
|
active: true
|
||||||
|
ClassOrdering:
|
||||||
|
active: false
|
||||||
CollapsibleIfStatements:
|
CollapsibleIfStatements:
|
||||||
active: true
|
active: false
|
||||||
DataClassContainsFunctions:
|
DataClassContainsFunctions:
|
||||||
active: true
|
active: false
|
||||||
conversionFunctionPrefix: 'to'
|
conversionFunctionPrefix: 'to'
|
||||||
DataClassShouldBeImmutable:
|
DataClassShouldBeImmutable:
|
||||||
active: false
|
active: false
|
||||||
|
DestructuringDeclarationWithTooManyEntries:
|
||||||
|
active: false
|
||||||
|
maxDestructuringEntries: 3
|
||||||
EqualsNullCall:
|
EqualsNullCall:
|
||||||
active: true
|
active: true
|
||||||
EqualsOnSignatureLine:
|
EqualsOnSignatureLine:
|
||||||
active: false
|
active: false
|
||||||
|
ExplicitCollectionElementAccessMethod:
|
||||||
|
active: false
|
||||||
ExplicitItLambdaParameter:
|
ExplicitItLambdaParameter:
|
||||||
active: false
|
active: false
|
||||||
ExpressionBodySyntax:
|
ExpressionBodySyntax:
|
||||||
active: true
|
active: false
|
||||||
includeLineWrapping: false
|
includeLineWrapping: false
|
||||||
ForbiddenComment:
|
ForbiddenComment:
|
||||||
active: true
|
active: true
|
||||||
values: 'TODO:,FIXME:,STOPSHIP:'
|
values:
|
||||||
allowedPatterns: ""
|
- 'FIXME:'
|
||||||
|
- 'STOPSHIP:'
|
||||||
|
- 'TODO:'
|
||||||
|
allowedPatterns: ''
|
||||||
ForbiddenImport:
|
ForbiddenImport:
|
||||||
active: false
|
active: false
|
||||||
imports: ''
|
imports: []
|
||||||
forbiddenPatterns: ""
|
forbiddenPatterns: ''
|
||||||
|
ForbiddenMethodCall:
|
||||||
|
active: false
|
||||||
|
methods:
|
||||||
|
- 'kotlin.io.print'
|
||||||
|
- 'kotlin.io.println'
|
||||||
|
ForbiddenPublicDataClass:
|
||||||
|
active: true
|
||||||
|
excludes: ['**']
|
||||||
|
ignorePackages:
|
||||||
|
- '*.internal'
|
||||||
|
- '*.internal.*'
|
||||||
ForbiddenVoid:
|
ForbiddenVoid:
|
||||||
active: false
|
active: false
|
||||||
ignoreOverridden: false
|
ignoreOverridden: false
|
||||||
|
|
@ -463,30 +641,44 @@ style:
|
||||||
FunctionOnlyReturningConstant:
|
FunctionOnlyReturningConstant:
|
||||||
active: true
|
active: true
|
||||||
ignoreOverridableFunction: true
|
ignoreOverridableFunction: true
|
||||||
excludedFunctions: 'describeContents'
|
ignoreActualFunction: true
|
||||||
excludeAnnotatedFunction: "dagger.Provides"
|
excludedFunctions: ''
|
||||||
|
excludeAnnotatedFunction:
|
||||||
|
- 'dagger.Provides'
|
||||||
LibraryCodeMustSpecifyReturnType:
|
LibraryCodeMustSpecifyReturnType:
|
||||||
active: true
|
active: true
|
||||||
|
excludes: ['**']
|
||||||
|
LibraryEntitiesShouldNotBePublic:
|
||||||
|
active: true
|
||||||
|
excludes: ['**']
|
||||||
LoopWithTooManyJumpStatements:
|
LoopWithTooManyJumpStatements:
|
||||||
active: true
|
active: true
|
||||||
maxJumpCount: 1
|
maxJumpCount: 1
|
||||||
MagicNumber:
|
MagicNumber:
|
||||||
active: true
|
active: true
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
ignoreNumbers: '-1,0,1,2'
|
ignoreNumbers:
|
||||||
|
- '-1'
|
||||||
|
- '0'
|
||||||
|
- '1'
|
||||||
|
- '2'
|
||||||
ignoreHashCodeFunction: true
|
ignoreHashCodeFunction: true
|
||||||
ignorePropertyDeclaration: false
|
ignorePropertyDeclaration: false
|
||||||
|
ignoreLocalVariableDeclaration: false
|
||||||
ignoreConstantDeclaration: true
|
ignoreConstantDeclaration: true
|
||||||
ignoreCompanionObjectPropertyDeclaration: true
|
ignoreCompanionObjectPropertyDeclaration: true
|
||||||
ignoreAnnotation: false
|
ignoreAnnotation: false
|
||||||
ignoreNamedArgument: true
|
ignoreNamedArgument: true
|
||||||
ignoreEnums: false
|
ignoreEnums: false
|
||||||
ignoreRanges: false
|
ignoreRanges: false
|
||||||
|
ignoreExtensionFunctions: true
|
||||||
MandatoryBracesIfStatements:
|
MandatoryBracesIfStatements:
|
||||||
active: true
|
active: false
|
||||||
|
MandatoryBracesLoops:
|
||||||
|
active: false
|
||||||
MaxLineLength:
|
MaxLineLength:
|
||||||
active: true
|
active: true
|
||||||
maxLineLength: 160 #default: 120
|
maxLineLength: 120
|
||||||
excludePackageStatements: true
|
excludePackageStatements: true
|
||||||
excludeImportStatements: true
|
excludeImportStatements: true
|
||||||
excludeCommentStatements: false
|
excludeCommentStatements: false
|
||||||
|
|
@ -494,12 +686,16 @@ style:
|
||||||
active: true
|
active: true
|
||||||
ModifierOrder:
|
ModifierOrder:
|
||||||
active: true
|
active: true
|
||||||
NestedClassesVisibility:
|
MultilineLambdaItParameter:
|
||||||
active: false
|
active: false
|
||||||
|
NestedClassesVisibility:
|
||||||
|
active: true
|
||||||
NewLineAtEndOfFile:
|
NewLineAtEndOfFile:
|
||||||
active: true
|
active: true
|
||||||
NoTabs:
|
NoTabs:
|
||||||
active: false
|
active: false
|
||||||
|
ObjectLiteralToLambda:
|
||||||
|
active: false
|
||||||
OptionalAbstractKeyword:
|
OptionalAbstractKeyword:
|
||||||
active: true
|
active: true
|
||||||
OptionalUnit:
|
OptionalUnit:
|
||||||
|
|
@ -507,29 +703,32 @@ style:
|
||||||
OptionalWhenBraces:
|
OptionalWhenBraces:
|
||||||
active: false
|
active: false
|
||||||
PreferToOverPairSyntax:
|
PreferToOverPairSyntax:
|
||||||
active: true
|
active: false
|
||||||
ProtectedMemberInFinalClass:
|
ProtectedMemberInFinalClass:
|
||||||
active: true
|
active: true
|
||||||
RedundantExplicitType:
|
RedundantExplicitType:
|
||||||
active: true
|
active: false
|
||||||
|
RedundantHigherOrderMapUsage:
|
||||||
|
active: false
|
||||||
RedundantVisibilityModifierRule:
|
RedundantVisibilityModifierRule:
|
||||||
active: false
|
active: false
|
||||||
ReturnCount:
|
ReturnCount:
|
||||||
active: true
|
active: true
|
||||||
max: 5
|
max: 2
|
||||||
excludedFunctions: "equals"
|
excludedFunctions: 'equals'
|
||||||
excludeLabeled: false
|
excludeLabeled: false
|
||||||
excludeReturnFromLambda: true
|
excludeReturnFromLambda: true
|
||||||
excludeGuardClauses: false
|
excludeGuardClauses: false
|
||||||
SafeCast:
|
SafeCast:
|
||||||
active: true
|
active: true
|
||||||
SerialVersionUIDInSerializableClass:
|
SerialVersionUIDInSerializableClass:
|
||||||
active: false
|
active: true
|
||||||
SpacingBetweenPackageAndImports:
|
SpacingBetweenPackageAndImports:
|
||||||
active: false
|
active: false
|
||||||
ThrowsCount:
|
ThrowsCount:
|
||||||
active: true
|
active: true
|
||||||
max: 10
|
max: 2
|
||||||
|
excludeGuardClauses: false
|
||||||
TrailingWhitespace:
|
TrailingWhitespace:
|
||||||
active: false
|
active: false
|
||||||
UnderscoresInNumericLiterals:
|
UnderscoresInNumericLiterals:
|
||||||
|
|
@ -537,43 +736,62 @@ style:
|
||||||
acceptableDecimalLength: 5
|
acceptableDecimalLength: 5
|
||||||
UnnecessaryAbstractClass:
|
UnnecessaryAbstractClass:
|
||||||
active: true
|
active: true
|
||||||
excludeAnnotatedClasses: "dagger.Module"
|
excludeAnnotatedClasses:
|
||||||
|
- 'dagger.Module'
|
||||||
|
UnnecessaryAnnotationUseSiteTarget:
|
||||||
|
active: false
|
||||||
UnnecessaryApply:
|
UnnecessaryApply:
|
||||||
active: true
|
active: true
|
||||||
|
UnnecessaryFilter:
|
||||||
|
active: false
|
||||||
UnnecessaryInheritance:
|
UnnecessaryInheritance:
|
||||||
active: true
|
active: true
|
||||||
UnnecessaryLet:
|
UnnecessaryLet:
|
||||||
active: true
|
active: false
|
||||||
UnnecessaryParentheses:
|
UnnecessaryParentheses:
|
||||||
active: true
|
active: false
|
||||||
UntilInsteadOfRangeTo:
|
UntilInsteadOfRangeTo:
|
||||||
active: false
|
active: false
|
||||||
UnusedImports:
|
UnusedImports:
|
||||||
active: true
|
active: false
|
||||||
UnusedPrivateClass:
|
UnusedPrivateClass:
|
||||||
active: true
|
active: true
|
||||||
UnusedPrivateMember:
|
UnusedPrivateMember:
|
||||||
active: true
|
active: true
|
||||||
allowedNames: "(_|ignored|expected|serialVersionUID)"
|
allowedNames: '(_|ignored|expected|serialVersionUID)'
|
||||||
UseArrayLiteralsInAnnotations:
|
UseArrayLiteralsInAnnotations:
|
||||||
active: false
|
active: false
|
||||||
|
UseCheckNotNull:
|
||||||
|
active: false
|
||||||
UseCheckOrError:
|
UseCheckOrError:
|
||||||
active: false
|
active: false
|
||||||
UseDataClass:
|
UseDataClass:
|
||||||
active: false
|
active: false
|
||||||
excludeAnnotatedClasses: ""
|
excludeAnnotatedClasses: []
|
||||||
allowVars: false
|
allowVars: false
|
||||||
|
UseEmptyCounterpart:
|
||||||
|
active: false
|
||||||
|
UseIfEmptyOrIfBlank:
|
||||||
|
active: false
|
||||||
UseIfInsteadOfWhen:
|
UseIfInsteadOfWhen:
|
||||||
active: false
|
active: false
|
||||||
|
UseIsNullOrEmpty:
|
||||||
|
active: false
|
||||||
|
UseOrEmpty:
|
||||||
|
active: false
|
||||||
UseRequire:
|
UseRequire:
|
||||||
active: false
|
active: false
|
||||||
|
UseRequireNotNull:
|
||||||
|
active: false
|
||||||
UselessCallOnNotNull:
|
UselessCallOnNotNull:
|
||||||
active: true
|
active: true
|
||||||
UtilityClassWithPublicConstructor:
|
UtilityClassWithPublicConstructor:
|
||||||
active: true
|
active: true
|
||||||
VarCouldBeVal:
|
VarCouldBeVal:
|
||||||
active: false
|
active: true
|
||||||
WildcardImport:
|
WildcardImport:
|
||||||
active: true
|
active: true
|
||||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||||
excludeImports: 'java.util.*,kotlinx.android.synthetic.*'
|
excludeImports:
|
||||||
|
- 'java.util.*'
|
||||||
|
- 'kotlinx.android.synthetic.*'
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,6 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
# Automatically convert third-party libraries to use AndroidX
|
# Automatically convert third-party libraries to use AndroidX
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
android.jetifier.blacklist=bcprov-jdk15on
|
android.jetifier.ignorelist=bcprov-jdk15on
|
||||||
# Kotlin code style for this project: "official" or "obsolete":
|
# Kotlin code style for this project: "official" or "obsolete":
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip
|
||||||
|
|
|
||||||
24
gradlescripts/detekt.config.gradle
Normal file
24
gradlescripts/detekt.config.gradle
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
|
||||||
|
detekt {
|
||||||
|
toolVersion = "$detekt_version"
|
||||||
|
|
||||||
|
source = files(
|
||||||
|
"$projectDir/app/src/main/java",
|
||||||
|
"$projectDir/core/src/main/java",
|
||||||
|
"$projectDir/mockserver/src/main/java",
|
||||||
|
"$projectDir/model/src/main/java",
|
||||||
|
"$projectDir/network/src/main/java"
|
||||||
|
)
|
||||||
|
config = files("$projectDir/detekt/detekt.yml")
|
||||||
|
baseline = file("$projectDir/detekt/baseline.xml")
|
||||||
|
reports {
|
||||||
|
txt {
|
||||||
|
enabled = true
|
||||||
|
destination = file("build/reports/detekt.txt")
|
||||||
|
}
|
||||||
|
html {
|
||||||
|
enabled = true
|
||||||
|
destination = file("build/reports/detekt.html")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
gradlescripts/ktlint.gradle
Normal file
3
gradlescripts/ktlint.gradle
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
subprojects {
|
||||||
|
apply plugin: "org.jlleitschuh.gradle.ktlint"
|
||||||
|
}
|
||||||
34
gradlescripts/lint.gradle
Normal file
34
gradlescripts/lint.gradle
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
subprojects { module ->
|
||||||
|
plugins.withType(JavaPlugin).whenPluginAdded {
|
||||||
|
configure(module) {
|
||||||
|
apply plugin: "com.android.lint"
|
||||||
|
lintOptions {
|
||||||
|
warningsAsErrors true
|
||||||
|
abortOnError true
|
||||||
|
textReport true
|
||||||
|
ignore 'Overdraw'
|
||||||
|
textOutput "stdout"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins.withId("com.android.application") {
|
||||||
|
module.android.lintOptions {
|
||||||
|
warningsAsErrors true
|
||||||
|
abortOnError true
|
||||||
|
textReport true
|
||||||
|
ignore 'Overdraw'
|
||||||
|
textOutput "stdout"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins.withId("com.android.library") {
|
||||||
|
module.android.lintOptions {
|
||||||
|
warningsAsErrors true
|
||||||
|
abortOnError true
|
||||||
|
textReport true
|
||||||
|
ignore 'Overdraw'
|
||||||
|
textOutput "stdout"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
44
gradlescripts/testoptions.gradle
Normal file
44
gradlescripts/testoptions.gradle
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
subprojects { module ->
|
||||||
|
plugins.withType(JavaPlugin).whenPluginAdded {
|
||||||
|
module.test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
testLogging {
|
||||||
|
events 'started', 'passed', 'skipped', 'failed'
|
||||||
|
exceptionFormat "full"
|
||||||
|
showStandardStreams true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins.withId("com.android.application") {
|
||||||
|
module.android.testOptions.unitTests.all {
|
||||||
|
useJUnitPlatform()
|
||||||
|
testLogging {
|
||||||
|
events 'started', 'passed', 'skipped', 'failed'
|
||||||
|
exceptionFormat "full"
|
||||||
|
showStandardStreams true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.android.testOptions {
|
||||||
|
unitTests {
|
||||||
|
includeAndroidResources = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins.withId("com.android.library") {
|
||||||
|
module.android.testOptions.unitTests.all {
|
||||||
|
useJUnitPlatform()
|
||||||
|
testLogging {
|
||||||
|
events 'started', 'passed', 'skipped', 'failed'
|
||||||
|
exceptionFormat "full"
|
||||||
|
showStandardStreams true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.android.testOptions {
|
||||||
|
unitTests {
|
||||||
|
includeAndroidResources = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,9 +7,3 @@ java {
|
||||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
|
||||||
compileKotlin {
|
|
||||||
kotlinOptions {
|
|
||||||
freeCompilerArgs += "-Xinline-classes"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -9,15 +9,6 @@ java {
|
||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
|
||||||
useJUnitPlatform()
|
|
||||||
testLogging {
|
|
||||||
events 'started', 'passed', 'skipped', 'failed'
|
|
||||||
exceptionFormat "full"
|
|
||||||
showStandardStreams true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,11 @@
|
||||||
package org.fnives.test.showcase.network.auth
|
package org.fnives.test.showcase.network.auth
|
||||||
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import okhttp3.mockwebserver.MockResponse
|
import org.junit.jupiter.api.AfterEach
|
||||||
import okhttp3.mockwebserver.MockWebServer
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.fnives.test.showcase.model.auth.LoginCredentials
|
import org.junit.jupiter.api.Disabled
|
||||||
import org.fnives.test.showcase.model.network.BaseUrl
|
import org.junit.jupiter.api.DisplayName
|
||||||
import org.fnives.test.showcase.model.session.Session
|
import org.junit.jupiter.api.Test
|
||||||
import org.fnives.test.showcase.network.auth.model.LoginStatusResponses
|
|
||||||
import org.fnives.test.showcase.network.di.createNetworkModules
|
|
||||||
import org.fnives.test.showcase.network.session.NetworkSessionLocalStorage
|
|
||||||
import org.fnives.test.showcase.network.shared.exceptions.NetworkException
|
|
||||||
import org.fnives.test.showcase.network.shared.exceptions.ParsingException
|
|
||||||
import org.junit.jupiter.api.*
|
|
||||||
import org.koin.core.context.startKoin
|
|
||||||
import org.koin.core.context.stopKoin
|
|
||||||
import org.koin.test.KoinTest
|
|
||||||
import org.koin.test.inject
|
|
||||||
import org.mockito.kotlin.mock
|
|
||||||
import org.skyscreamer.jsonassert.JSONAssert
|
|
||||||
import org.skyscreamer.jsonassert.JSONCompareMode
|
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
import java.io.InputStreamReader
|
import java.io.InputStreamReader
|
||||||
|
|
||||||
|
|
@ -27,54 +14,46 @@ class CodeKataLoginRemoteSourceTest {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
fun tearDown() {
|
fun tearDown() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN successful response WHEN request is fired THEN login status success is returned")
|
@DisplayName("GIVEN successful response WHEN request is fired THEN login status success is returned")
|
||||||
@Test
|
@Test
|
||||||
fun successResponseIsParsedProperly() = runBlocking {
|
fun successResponseIsParsedProperly() = runBlocking {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN successful response WHEN request is fired THEN the request is setup properly")
|
@DisplayName("GIVEN successful response WHEN request is fired THEN the request is setup properly")
|
||||||
@Test
|
@Test
|
||||||
fun requestProperlySetup() = runBlocking {
|
fun requestProperlySetup() = runBlocking {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN bad request response WHEN request is fired THEN login status invalid credentials is returned")
|
@DisplayName("GIVEN bad request response WHEN request is fired THEN login status invalid credentials is returned")
|
||||||
@Test
|
@Test
|
||||||
fun badRequestMeansInvalidCredentials() = runBlocking {
|
fun badRequestMeansInvalidCredentials() = runBlocking {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN_internal_error_response_WHEN_request_is_fired_THEN_network_exception_is_thrown")
|
@DisplayName("GIVEN_internal_error_response_WHEN_request_is_fired_THEN_network_exception_is_thrown")
|
||||||
@Test
|
@Test
|
||||||
fun genericErrorMeansNetworkError() {
|
fun genericErrorMeansNetworkError() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN invalid json response WHEN request is fired THEN network exception is thrown")
|
@DisplayName("GIVEN invalid json response WHEN request is fired THEN network exception is thrown")
|
||||||
@Test
|
@Test
|
||||||
fun invalidJsonMeansParsingException() {
|
fun invalidJsonMeansParsingException() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN malformed json response WHEN request is fired THEN network exception is thrown")
|
@DisplayName("GIVEN malformed json response WHEN request is fired THEN network exception is thrown")
|
||||||
@Test
|
@Test
|
||||||
fun malformedJsonMeansParsingException() {
|
fun malformedJsonMeansParsingException() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
internal fun Any.readResourceFile(filePath: String): String = try {
|
internal fun Any.readResourceFile(filePath: String): String = try {
|
||||||
BufferedReader(InputStreamReader(this.javaClass.classLoader.getResourceAsStream(filePath)!!))
|
BufferedReader(InputStreamReader(this.javaClass.classLoader.getResourceAsStream(filePath)!!))
|
||||||
.readLines().joinToString("\n")
|
.readLines().joinToString("\n")
|
||||||
} catch (nullPointerException: NullPointerException) {
|
} catch (nullPointerException: NullPointerException) {
|
||||||
throw IllegalArgumentException("$filePath file not found!", nullPointerException)
|
throw IllegalArgumentException("$filePath file not found!", nullPointerException)
|
||||||
}
|
}
|
||||||
|
|
@ -87,6 +66,5 @@ class CodeKataLoginRemoteSourceTest {
|
||||||
} while (true)
|
} while (true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -12,7 +12,11 @@ import org.fnives.test.showcase.network.session.NetworkSessionLocalStorage
|
||||||
import org.fnives.test.showcase.network.shared.MockServerScenarioSetupExtensions
|
import org.fnives.test.showcase.network.shared.MockServerScenarioSetupExtensions
|
||||||
import org.fnives.test.showcase.network.shared.exceptions.NetworkException
|
import org.fnives.test.showcase.network.shared.exceptions.NetworkException
|
||||||
import org.fnives.test.showcase.network.shared.exceptions.ParsingException
|
import org.fnives.test.showcase.network.shared.exceptions.ParsingException
|
||||||
import org.junit.jupiter.api.*
|
import org.junit.jupiter.api.AfterEach
|
||||||
|
import org.junit.jupiter.api.Assertions
|
||||||
|
import org.junit.jupiter.api.BeforeEach
|
||||||
|
import org.junit.jupiter.api.DisplayName
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension
|
import org.junit.jupiter.api.extension.RegisterExtension
|
||||||
import org.koin.core.context.startKoin
|
import org.koin.core.context.startKoin
|
||||||
import org.koin.core.context.stopKoin
|
import org.koin.core.context.stopKoin
|
||||||
|
|
@ -26,6 +30,7 @@ import org.skyscreamer.jsonassert.JSONCompareMode
|
||||||
class LoginRemoteSourceTest : KoinTest {
|
class LoginRemoteSourceTest : KoinTest {
|
||||||
|
|
||||||
private val sut by inject<LoginRemoteSource>()
|
private val sut by inject<LoginRemoteSource>()
|
||||||
|
|
||||||
@RegisterExtension
|
@RegisterExtension
|
||||||
@JvmField
|
@JvmField
|
||||||
val mockServerScenarioSetupExtensions = MockServerScenarioSetupExtensions()
|
val mockServerScenarioSetupExtensions = MockServerScenarioSetupExtensions()
|
||||||
|
|
@ -76,7 +81,11 @@ class LoginRemoteSourceTest : KoinTest {
|
||||||
Assertions.assertEquals(null, request.getHeader("Authorization"))
|
Assertions.assertEquals(null, request.getHeader("Authorization"))
|
||||||
Assertions.assertEquals("/login", request.path)
|
Assertions.assertEquals("/login", request.path)
|
||||||
val loginRequest = createExpectedLoginRequestJson("a", "b")
|
val loginRequest = createExpectedLoginRequestJson("a", "b")
|
||||||
JSONAssert.assertEquals(loginRequest, request.body.readUtf8(), JSONCompareMode.NON_EXTENSIBLE)
|
JSONAssert.assertEquals(
|
||||||
|
loginRequest,
|
||||||
|
request.body.readUtf8(),
|
||||||
|
JSONCompareMode.NON_EXTENSIBLE
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN bad request response WHEN request is fired THEN login status invalid credentials is returned")
|
@DisplayName("GIVEN bad request response WHEN request is fired THEN login status invalid credentials is returned")
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,21 @@
|
||||||
package org.fnives.test.showcase.network.content
|
package org.fnives.test.showcase.network.content
|
||||||
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import okhttp3.mockwebserver.MockResponse
|
|
||||||
import okhttp3.mockwebserver.MockWebServer
|
import okhttp3.mockwebserver.MockWebServer
|
||||||
import org.fnives.test.showcase.model.network.BaseUrl
|
import org.fnives.test.showcase.model.network.BaseUrl
|
||||||
import org.fnives.test.showcase.model.session.Session
|
|
||||||
import org.fnives.test.showcase.network.auth.CodeKataLoginRemoteSourceTest.Companion.readResourceFile
|
|
||||||
import org.fnives.test.showcase.network.di.createNetworkModules
|
import org.fnives.test.showcase.network.di.createNetworkModules
|
||||||
import org.fnives.test.showcase.network.session.NetworkSessionExpirationListener
|
import org.fnives.test.showcase.network.session.NetworkSessionExpirationListener
|
||||||
import org.fnives.test.showcase.network.session.NetworkSessionLocalStorage
|
import org.fnives.test.showcase.network.session.NetworkSessionLocalStorage
|
||||||
import org.fnives.test.showcase.network.shared.exceptions.NetworkException
|
import org.junit.jupiter.api.AfterEach
|
||||||
import org.junit.jupiter.api.*
|
import org.junit.jupiter.api.BeforeEach
|
||||||
|
import org.junit.jupiter.api.Disabled
|
||||||
|
import org.junit.jupiter.api.DisplayName
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
import org.koin.core.context.startKoin
|
import org.koin.core.context.startKoin
|
||||||
import org.koin.core.context.stopKoin
|
import org.koin.core.context.stopKoin
|
||||||
import org.koin.test.KoinTest
|
import org.koin.test.KoinTest
|
||||||
import org.koin.test.inject
|
import org.koin.test.inject
|
||||||
import org.mockito.kotlin.*
|
import org.mockito.kotlin.mock
|
||||||
|
|
||||||
@Disabled("CodeKata")
|
@Disabled("CodeKata")
|
||||||
class CodeKataSessionExpirationTest : KoinTest {
|
class CodeKataSessionExpirationTest : KoinTest {
|
||||||
|
|
@ -33,12 +33,12 @@ class CodeKataSessionExpirationTest : KoinTest {
|
||||||
mockNetworkSessionExpirationListener = mock()
|
mockNetworkSessionExpirationListener = mock()
|
||||||
startKoin {
|
startKoin {
|
||||||
modules(
|
modules(
|
||||||
createNetworkModules(
|
createNetworkModules(
|
||||||
baseUrl = BaseUrl(mockWebServer.url("mockserver/").toString()),
|
baseUrl = BaseUrl(mockWebServer.url("mockserver/").toString()),
|
||||||
enableLogging = true,
|
enableLogging = true,
|
||||||
networkSessionExpirationListenerProvider = { mockNetworkSessionExpirationListener },
|
networkSessionExpirationListenerProvider = { mockNetworkSessionExpirationListener },
|
||||||
networkSessionLocalStorageProvider = { mockNetworkSessionLocalStorage }
|
networkSessionLocalStorageProvider = { mockNetworkSessionLocalStorage }
|
||||||
).toList()
|
).toList()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -57,6 +57,5 @@ class CodeKataSessionExpirationTest : KoinTest {
|
||||||
@DisplayName("GIVEN 401 THEN failing refresh WHEN content requested THE error is returned and callback is Called")
|
@DisplayName("GIVEN 401 THEN failing refresh WHEN content requested THE error is returned and callback is Called")
|
||||||
@Test
|
@Test
|
||||||
fun failingRefreshResultsInSessionExpiration() = runBlocking {
|
fun failingRefreshResultsInSessionExpiration() = runBlocking {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -11,7 +11,11 @@ import org.fnives.test.showcase.network.session.NetworkSessionExpirationListener
|
||||||
import org.fnives.test.showcase.network.session.NetworkSessionLocalStorage
|
import org.fnives.test.showcase.network.session.NetworkSessionLocalStorage
|
||||||
import org.fnives.test.showcase.network.shared.MockServerScenarioSetupExtensions
|
import org.fnives.test.showcase.network.shared.MockServerScenarioSetupExtensions
|
||||||
import org.fnives.test.showcase.network.shared.exceptions.NetworkException
|
import org.fnives.test.showcase.network.shared.exceptions.NetworkException
|
||||||
import org.junit.jupiter.api.*
|
import org.junit.jupiter.api.AfterEach
|
||||||
|
import org.junit.jupiter.api.Assertions
|
||||||
|
import org.junit.jupiter.api.BeforeEach
|
||||||
|
import org.junit.jupiter.api.DisplayName
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension
|
import org.junit.jupiter.api.extension.RegisterExtension
|
||||||
import org.koin.core.context.startKoin
|
import org.koin.core.context.startKoin
|
||||||
import org.koin.core.context.stopKoin
|
import org.koin.core.context.stopKoin
|
||||||
|
|
@ -64,35 +68,39 @@ class SessionExpirationTest : KoinTest {
|
||||||
@DisplayName("GIVEN_401_THEN_refresh_token_ok_response_WHEN_content_requested_THE_tokens_are_refreshed_and_request_retried_with_new_tokens")
|
@DisplayName("GIVEN_401_THEN_refresh_token_ok_response_WHEN_content_requested_THE_tokens_are_refreshed_and_request_retried_with_new_tokens")
|
||||||
@Test
|
@Test
|
||||||
fun successRefreshResultsInRequestRetry() = runBlocking {
|
fun successRefreshResultsInRequestRetry() = runBlocking {
|
||||||
var sessionToReturnByMock: Session? = ContentData.loginSuccessResponse
|
var sessionToReturnByMock: Session? = ContentData.loginSuccessResponse
|
||||||
mockServerScenarioSetup.setScenario(
|
mockServerScenarioSetup.setScenario(
|
||||||
ContentScenario.Unauthorized(false)
|
ContentScenario.Unauthorized(false)
|
||||||
.then(ContentScenario.Success(true)),
|
.then(ContentScenario.Success(true)),
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
mockServerScenarioSetup.setScenario(RefreshTokenScenario.Success, false)
|
mockServerScenarioSetup.setScenario(RefreshTokenScenario.Success, false)
|
||||||
whenever(mockNetworkSessionLocalStorage.session).doAnswer { sessionToReturnByMock }
|
whenever(mockNetworkSessionLocalStorage.session).doAnswer { sessionToReturnByMock }
|
||||||
doAnswer { sessionToReturnByMock = it.arguments[0] as Session? }
|
doAnswer { sessionToReturnByMock = it.arguments[0] as Session? }
|
||||||
.whenever(mockNetworkSessionLocalStorage).session = anyOrNull()
|
.whenever(mockNetworkSessionLocalStorage).session = anyOrNull()
|
||||||
|
|
||||||
sut.get()
|
sut.get()
|
||||||
|
|
||||||
mockServerScenarioSetup.takeRequest()
|
mockServerScenarioSetup.takeRequest()
|
||||||
val refreshRequest = mockServerScenarioSetup.takeRequest()
|
val refreshRequest = mockServerScenarioSetup.takeRequest()
|
||||||
val retryAfterTokenRefreshRequest = mockServerScenarioSetup.takeRequest()
|
val retryAfterTokenRefreshRequest = mockServerScenarioSetup.takeRequest()
|
||||||
|
|
||||||
Assertions.assertEquals("PUT", refreshRequest.method)
|
Assertions.assertEquals("PUT", refreshRequest.method)
|
||||||
Assertions.assertEquals("/login/${ContentData.loginSuccessResponse.refreshToken}", refreshRequest.path)
|
Assertions.assertEquals(
|
||||||
Assertions.assertEquals(null, refreshRequest.getHeader("Authorization"))
|
"/login/${ContentData.loginSuccessResponse.refreshToken}",
|
||||||
Assertions.assertEquals("Android", refreshRequest.getHeader("Platform"))
|
refreshRequest.path
|
||||||
Assertions.assertEquals("", refreshRequest.body.readUtf8())
|
)
|
||||||
Assertions.assertEquals(
|
Assertions.assertEquals(null, refreshRequest.getHeader("Authorization"))
|
||||||
ContentData.refreshSuccessResponse.accessToken,
|
Assertions.assertEquals("Android", refreshRequest.getHeader("Platform"))
|
||||||
retryAfterTokenRefreshRequest.getHeader("Authorization")
|
Assertions.assertEquals("", refreshRequest.body.readUtf8())
|
||||||
)
|
Assertions.assertEquals(
|
||||||
verify(mockNetworkSessionLocalStorage, times(1)).session = ContentData.refreshSuccessResponse
|
ContentData.refreshSuccessResponse.accessToken,
|
||||||
verifyZeroInteractions(mockNetworkSessionExpirationListener)
|
retryAfterTokenRefreshRequest.getHeader("Authorization")
|
||||||
}
|
)
|
||||||
|
verify(mockNetworkSessionLocalStorage, times(1)).session =
|
||||||
|
ContentData.refreshSuccessResponse
|
||||||
|
verifyZeroInteractions(mockNetworkSessionExpirationListener)
|
||||||
|
}
|
||||||
|
|
||||||
@DisplayName("GIVEN 401 THEN failing refresh WHEN content requested THE error is returned and callback is Called")
|
@DisplayName("GIVEN 401 THEN failing refresh WHEN content requested THE error is returned and callback is Called")
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue