From ffaf6cb688270d2cd336307e290468b9e1d40ddc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9rard=20Paligot?= Date: Thu, 3 Aug 2023 09:42:48 +0200 Subject: [PATCH] feat(text-inputs): create dedicated artifact to test components. (#169) --- appbars/build.gradle.kts | 1 + badges/build.gradle.kts | 1 + buildSrc/build.gradle.kts | 4 + .../compose/VitaminComposeLibraryPlugin.kt | 5 - .../vitamin/compose/VitaminQualityPlugin.kt | 15 ++ buttons/build.gradle.kts | 1 + cards/build.gradle.kts | 1 + checkboxes/build.gradle.kts | 1 + chips/build.gradle.kts | 1 + dividers/build.gradle.kts | 1 + fabs/build.gradle.kts | 1 + foundation/foundation-assets/build.gradle.kts | 1 + foundation/foundation-icons/build.gradle.kts | 1 + foundation/foundation/build.gradle.kts | 1 + menus/build.gradle.kts | 1 + modals/build.gradle.kts | 1 + prices/build.gradle.kts | 1 + progressbars/build.gradle.kts | 1 + quantity-pickers/build.gradle.kts | 1 + radiobuttons/build.gradle.kts | 1 + ratings/build.gradle.kts | 1 + scaffolds/build.gradle.kts | 1 + settings.gradle.kts | 4 +- skeletons/build.gradle.kts | 1 + snackbars/build.gradle.kts | 1 + switches/build.gradle.kts | 1 + tabs/build.gradle.kts | 1 + tags/build.gradle.kts | 1 + .../.gitignore | 0 .../build.gradle.kts | 10 + .../gradle.properties | 3 + .../src/main/AndroidManifest.xml | 2 + .../compose/textinputs/SemanticsProperties.kt | 15 ++ .../TextInputSemanticsProperties.kt | 10 + text-inputs/text-inputs-test/.gitignore | 1 + text-inputs/text-inputs-test/README.md | 206 ++++++++++++++++++ text-inputs/text-inputs-test/build.gradle.kts | 11 + .../text-inputs-test/gradle.properties | 3 + .../src/main/AndroidManifest.xml | 2 + .../compose/textinputs/testing/Assertions.kt | 30 +++ .../compose/textinputs/testing/Filters.kt | 12 + .../compose/textinputs/testing/Selectors.kt | 55 +++++ .../textinputs/testing/SemanticsMatchers.kt | 64 ++++++ text-inputs/text-inputs/.gitignore | 1 + text-inputs/{ => text-inputs}/README.md | 7 + .../{ => text-inputs}/build.gradle.kts | 3 + .../{ => text-inputs}/gradle.properties | 0 .../{ => text-inputs}/proguard-rules.pro | 0 .../textinputs/TextInputFilteringTest.kt | 190 ++++++++++++++++ .../TextInputHelperTextCounterTest.kt | 107 +++++++++ .../compose/textinputs/TextInputStateTest.kt | 118 ++++++++++ .../textinputs/TextInputTrailingIconTest.kt | 49 +++++ .../src/main/AndroidManifest.xml | 0 .../compose/textinputs/TextInputsState.kt | 0 .../textinputs/TextInputsTransformations.kt | 0 .../textinputs/VitaminTextInputModifiers.kt | 21 ++ .../compose/textinputs/VitaminTextInputs.kt | 22 +- .../src/main/res/values/strings.xml | 0 .../VitaminTextInputsPrimaryTest.kt | 0 .../utils/TextInputVariantsFactory.kt | 0 .../vitamin/compose/textinputs/utils/Theme.kt | 0 .../compose/textinputs/utils/Variant.kt | 0 ...xtInputsPrimaryTest_error[Filled,Dark].png | Bin ...tInputsPrimaryTest_error[Filled,Light].png | Bin ...PrimaryTest_error[FilledDropdown,Dark].png | Bin ...rimaryTest_error[FilledDropdown,Light].png | Bin ...InputsPrimaryTest_error[Outlined,Dark].png | Bin ...nputsPrimaryTest_error[Outlined,Light].png | Bin ...imaryTest_error[OutlinedDropdown,Dark].png | Bin ...maryTest_error[OutlinedDropdown,Light].png | Bin ...tInputsPrimaryTest_normal[Filled,Dark].png | Bin ...InputsPrimaryTest_normal[Filled,Light].png | Bin ...rimaryTest_normal[FilledDropdown,Dark].png | Bin ...imaryTest_normal[FilledDropdown,Light].png | Bin ...nputsPrimaryTest_normal[Outlined,Dark].png | Bin ...putsPrimaryTest_normal[Outlined,Light].png | Bin ...maryTest_normal[OutlinedDropdown,Dark].png | Bin ...aryTest_normal[OutlinedDropdown,Light].png | Bin ...InputsPrimaryTest_success[Filled,Dark].png | Bin ...nputsPrimaryTest_success[Filled,Light].png | Bin ...imaryTest_success[FilledDropdown,Dark].png | Bin ...maryTest_success[FilledDropdown,Light].png | Bin ...putsPrimaryTest_success[Outlined,Dark].png | Bin ...utsPrimaryTest_success[Outlined,Light].png | Bin ...aryTest_success[OutlinedDropdown,Dark].png | Bin ...ryTest_success[OutlinedDropdown,Light].png | Bin vitamin/build.gradle.kts | 3 +- 87 files changed, 986 insertions(+), 11 deletions(-) create mode 100644 buildSrc/src/main/kotlin/com/decathlon/vitamin/compose/VitaminQualityPlugin.kt rename text-inputs/{ => text-inputs-test-semantics}/.gitignore (100%) create mode 100644 text-inputs/text-inputs-test-semantics/build.gradle.kts create mode 100644 text-inputs/text-inputs-test-semantics/gradle.properties create mode 100644 text-inputs/text-inputs-test-semantics/src/main/AndroidManifest.xml create mode 100644 text-inputs/text-inputs-test-semantics/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/SemanticsProperties.kt create mode 100644 text-inputs/text-inputs-test-semantics/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/TextInputSemanticsProperties.kt create mode 100644 text-inputs/text-inputs-test/.gitignore create mode 100644 text-inputs/text-inputs-test/README.md create mode 100644 text-inputs/text-inputs-test/build.gradle.kts create mode 100644 text-inputs/text-inputs-test/gradle.properties create mode 100644 text-inputs/text-inputs-test/src/main/AndroidManifest.xml create mode 100644 text-inputs/text-inputs-test/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/testing/Assertions.kt create mode 100644 text-inputs/text-inputs-test/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/testing/Filters.kt create mode 100644 text-inputs/text-inputs-test/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/testing/Selectors.kt create mode 100644 text-inputs/text-inputs-test/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/testing/SemanticsMatchers.kt create mode 100644 text-inputs/text-inputs/.gitignore rename text-inputs/{ => text-inputs}/README.md (97%) rename text-inputs/{ => text-inputs}/build.gradle.kts (71%) rename text-inputs/{ => text-inputs}/gradle.properties (100%) rename text-inputs/{ => text-inputs}/proguard-rules.pro (100%) create mode 100644 text-inputs/text-inputs/src/androidTest/kotlin/com/decathlon/vitamin/compose/textinputs/TextInputFilteringTest.kt create mode 100644 text-inputs/text-inputs/src/androidTest/kotlin/com/decathlon/vitamin/compose/textinputs/TextInputHelperTextCounterTest.kt create mode 100644 text-inputs/text-inputs/src/androidTest/kotlin/com/decathlon/vitamin/compose/textinputs/TextInputStateTest.kt create mode 100644 text-inputs/text-inputs/src/androidTest/kotlin/com/decathlon/vitamin/compose/textinputs/TextInputTrailingIconTest.kt rename text-inputs/{ => text-inputs}/src/main/AndroidManifest.xml (100%) rename text-inputs/{ => text-inputs}/src/main/java/com/decathlon/vitamin/compose/textinputs/TextInputsState.kt (100%) rename text-inputs/{ => text-inputs}/src/main/java/com/decathlon/vitamin/compose/textinputs/TextInputsTransformations.kt (100%) create mode 100644 text-inputs/text-inputs/src/main/java/com/decathlon/vitamin/compose/textinputs/VitaminTextInputModifiers.kt rename text-inputs/{ => text-inputs}/src/main/java/com/decathlon/vitamin/compose/textinputs/VitaminTextInputs.kt (96%) rename text-inputs/{ => text-inputs}/src/main/res/values/strings.xml (100%) rename text-inputs/{ => text-inputs}/src/test/kotlin/com/decathlon/vitamin/compose/textinputs/VitaminTextInputsPrimaryTest.kt (100%) rename text-inputs/{ => text-inputs}/src/test/kotlin/com/decathlon/vitamin/compose/textinputs/utils/TextInputVariantsFactory.kt (100%) rename text-inputs/{ => text-inputs}/src/test/kotlin/com/decathlon/vitamin/compose/textinputs/utils/Theme.kt (100%) rename text-inputs/{ => text-inputs}/src/test/kotlin/com/decathlon/vitamin/compose/textinputs/utils/Variant.kt (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[Filled,Dark].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[Filled,Light].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[FilledDropdown,Dark].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[FilledDropdown,Light].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[Outlined,Dark].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[Outlined,Light].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[OutlinedDropdown,Dark].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[OutlinedDropdown,Light].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[Filled,Dark].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[Filled,Light].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[FilledDropdown,Dark].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[FilledDropdown,Light].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[Outlined,Dark].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[Outlined,Light].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[OutlinedDropdown,Dark].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[OutlinedDropdown,Light].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[Filled,Dark].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[Filled,Light].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[FilledDropdown,Dark].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[FilledDropdown,Light].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[Outlined,Dark].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[Outlined,Light].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[OutlinedDropdown,Dark].png (100%) rename text-inputs/{ => text-inputs}/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[OutlinedDropdown,Light].png (100%) diff --git a/appbars/build.gradle.kts b/appbars/build.gradle.kts index 2edfcc68..7864aa18 100644 --- a/appbars/build.gradle.kts +++ b/appbars/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") } diff --git a/badges/build.gradle.kts b/badges/build.gradle.kts index 71406ec9..674f4ec8 100644 --- a/badges/build.gradle.kts +++ b/badges/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") id("app.cash.paparazzi") } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index b1c326a9..743fe748 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -19,6 +19,10 @@ gradlePlugin { id = "VitaminComposeLibraryPlugin" implementationClass = "com.decathlon.vitamin.compose.VitaminComposeLibraryPlugin" } + plugins.register("VitaminQualityPlugin") { + id = "VitaminQualityPlugin" + implementationClass = "com.decathlon.vitamin.compose.VitaminQualityPlugin" + } } dependencies { diff --git a/buildSrc/src/main/kotlin/com/decathlon/vitamin/compose/VitaminComposeLibraryPlugin.kt b/buildSrc/src/main/kotlin/com/decathlon/vitamin/compose/VitaminComposeLibraryPlugin.kt index 8ed6a8f2..b56b3b56 100644 --- a/buildSrc/src/main/kotlin/com/decathlon/vitamin/compose/VitaminComposeLibraryPlugin.kt +++ b/buildSrc/src/main/kotlin/com/decathlon/vitamin/compose/VitaminComposeLibraryPlugin.kt @@ -14,11 +14,6 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile class VitaminComposeLibraryPlugin : Plugin { override fun apply(target: Project) { - target.apply(plugin = "app.cash.licensee") - target.configure { - allow("Apache-2.0") - allow("MIT") - } target.repositories { google() mavenCentral() diff --git a/buildSrc/src/main/kotlin/com/decathlon/vitamin/compose/VitaminQualityPlugin.kt b/buildSrc/src/main/kotlin/com/decathlon/vitamin/compose/VitaminQualityPlugin.kt new file mode 100644 index 00000000..6b92be49 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/decathlon/vitamin/compose/VitaminQualityPlugin.kt @@ -0,0 +1,15 @@ +package com.decathlon.vitamin.compose + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.apply +import org.gradle.kotlin.dsl.configure + +class VitaminQualityPlugin : Plugin { + override fun apply(target: Project) { + target.apply(plugin = "app.cash.licensee") + target.configure { + allow("Apache-2.0") + } + } +} diff --git a/buttons/build.gradle.kts b/buttons/build.gradle.kts index 8635c2f8..6dd524c0 100644 --- a/buttons/build.gradle.kts +++ b/buttons/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") id("app.cash.paparazzi") } diff --git a/cards/build.gradle.kts b/cards/build.gradle.kts index 8f745405..448865d6 100644 --- a/cards/build.gradle.kts +++ b/cards/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") id("app.cash.paparazzi") } diff --git a/checkboxes/build.gradle.kts b/checkboxes/build.gradle.kts index 8f745405..448865d6 100644 --- a/checkboxes/build.gradle.kts +++ b/checkboxes/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") id("app.cash.paparazzi") } diff --git a/chips/build.gradle.kts b/chips/build.gradle.kts index eb016c48..a7d336f4 100644 --- a/chips/build.gradle.kts +++ b/chips/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") id("app.cash.paparazzi") } diff --git a/dividers/build.gradle.kts b/dividers/build.gradle.kts index 8f745405..448865d6 100644 --- a/dividers/build.gradle.kts +++ b/dividers/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") id("app.cash.paparazzi") } diff --git a/fabs/build.gradle.kts b/fabs/build.gradle.kts index 55fe4551..a2fa8dda 100644 --- a/fabs/build.gradle.kts +++ b/fabs/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") id("app.cash.paparazzi") } diff --git a/foundation/foundation-assets/build.gradle.kts b/foundation/foundation-assets/build.gradle.kts index f66522fe..9c4dd6a1 100644 --- a/foundation/foundation-assets/build.gradle.kts +++ b/foundation/foundation-assets/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") } diff --git a/foundation/foundation-icons/build.gradle.kts b/foundation/foundation-icons/build.gradle.kts index f66522fe..9c4dd6a1 100644 --- a/foundation/foundation-icons/build.gradle.kts +++ b/foundation/foundation-icons/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") } diff --git a/foundation/foundation/build.gradle.kts b/foundation/foundation/build.gradle.kts index f66522fe..9c4dd6a1 100644 --- a/foundation/foundation/build.gradle.kts +++ b/foundation/foundation/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") } diff --git a/menus/build.gradle.kts b/menus/build.gradle.kts index 57e63ffc..51f959c5 100644 --- a/menus/build.gradle.kts +++ b/menus/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") } diff --git a/modals/build.gradle.kts b/modals/build.gradle.kts index 0e04b717..69d44d4c 100644 --- a/modals/build.gradle.kts +++ b/modals/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") id("app.cash.paparazzi") } diff --git a/prices/build.gradle.kts b/prices/build.gradle.kts index 8f745405..448865d6 100644 --- a/prices/build.gradle.kts +++ b/prices/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") id("app.cash.paparazzi") } diff --git a/progressbars/build.gradle.kts b/progressbars/build.gradle.kts index 8f745405..448865d6 100644 --- a/progressbars/build.gradle.kts +++ b/progressbars/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") id("app.cash.paparazzi") } diff --git a/quantity-pickers/build.gradle.kts b/quantity-pickers/build.gradle.kts index 8635c2f8..6dd524c0 100644 --- a/quantity-pickers/build.gradle.kts +++ b/quantity-pickers/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") id("app.cash.paparazzi") } diff --git a/radiobuttons/build.gradle.kts b/radiobuttons/build.gradle.kts index 8f745405..448865d6 100644 --- a/radiobuttons/build.gradle.kts +++ b/radiobuttons/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") id("app.cash.paparazzi") } diff --git a/ratings/build.gradle.kts b/ratings/build.gradle.kts index 769d624e..411dbda1 100644 --- a/ratings/build.gradle.kts +++ b/ratings/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") } diff --git a/scaffolds/build.gradle.kts b/scaffolds/build.gradle.kts index 5eaba896..aeacea78 100644 --- a/scaffolds/build.gradle.kts +++ b/scaffolds/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") id("app.cash.paparazzi") } diff --git a/settings.gradle.kts b/settings.gradle.kts index aae421f2..d132ff2b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -20,7 +20,9 @@ include(":foundation:foundation") include(":foundation:foundation-icons") include(":foundation:foundation-assets") include(":buttons") -include(":text-inputs") +include(":text-inputs:text-inputs") +include(":text-inputs:text-inputs-test-semantics") +include(":text-inputs:text-inputs-test") include(":switches") include(":appbars") include(":radiobuttons") diff --git a/skeletons/build.gradle.kts b/skeletons/build.gradle.kts index 62c01c90..6d743063 100644 --- a/skeletons/build.gradle.kts +++ b/skeletons/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") id("app.cash.paparazzi") } diff --git a/snackbars/build.gradle.kts b/snackbars/build.gradle.kts index e79a34e2..7764c489 100644 --- a/snackbars/build.gradle.kts +++ b/snackbars/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") id("app.cash.paparazzi") } diff --git a/switches/build.gradle.kts b/switches/build.gradle.kts index 8f745405..448865d6 100644 --- a/switches/build.gradle.kts +++ b/switches/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") id("app.cash.paparazzi") } diff --git a/tabs/build.gradle.kts b/tabs/build.gradle.kts index 71406ec9..674f4ec8 100644 --- a/tabs/build.gradle.kts +++ b/tabs/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") id("app.cash.paparazzi") } diff --git a/tags/build.gradle.kts b/tags/build.gradle.kts index 8635c2f8..6dd524c0 100644 --- a/tags/build.gradle.kts +++ b/tags/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") id("app.cash.paparazzi") } diff --git a/text-inputs/.gitignore b/text-inputs/text-inputs-test-semantics/.gitignore similarity index 100% rename from text-inputs/.gitignore rename to text-inputs/text-inputs-test-semantics/.gitignore diff --git a/text-inputs/text-inputs-test-semantics/build.gradle.kts b/text-inputs/text-inputs-test-semantics/build.gradle.kts new file mode 100644 index 00000000..79e22058 --- /dev/null +++ b/text-inputs/text-inputs-test-semantics/build.gradle.kts @@ -0,0 +1,10 @@ +plugins { + id("com.android.library") + id("kotlin-android") + id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") +} + +dependencies { + implementation(AndroidX.compose.ui) +} diff --git a/text-inputs/text-inputs-test-semantics/gradle.properties b/text-inputs/text-inputs-test-semantics/gradle.properties new file mode 100644 index 00000000..2f0e67b1 --- /dev/null +++ b/text-inputs/text-inputs-test-semantics/gradle.properties @@ -0,0 +1,3 @@ +POM_ARTIFACT_ID=text-inputs-test-semantics +POM_NAME=Vitamin TextInputs semantics +POM_DESCRIPTION=Custom semantics created for test artifact \ No newline at end of file diff --git a/text-inputs/text-inputs-test-semantics/src/main/AndroidManifest.xml b/text-inputs/text-inputs-test-semantics/src/main/AndroidManifest.xml new file mode 100644 index 00000000..1e620701 --- /dev/null +++ b/text-inputs/text-inputs-test-semantics/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/text-inputs/text-inputs-test-semantics/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/SemanticsProperties.kt b/text-inputs/text-inputs-test-semantics/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/SemanticsProperties.kt new file mode 100644 index 00000000..1c0fc645 --- /dev/null +++ b/text-inputs/text-inputs-test-semantics/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/SemanticsProperties.kt @@ -0,0 +1,15 @@ +package com.decathlon.vitamin.compose.textinputs + +import androidx.compose.ui.semantics.SemanticsProperties +import androidx.compose.ui.semantics.SemanticsPropertyKey +import androidx.compose.ui.semantics.SemanticsPropertyReceiver + +val SemanticsProperties.EditableHelperText: SemanticsPropertyKey + get() = TextInputSemanticsProperties.EditableHelperText + +val SemanticsProperties.EditableCounter: SemanticsPropertyKey> + get() = TextInputSemanticsProperties.EditableCounter + +var SemanticsPropertyReceiver.editableHelperText by TextInputSemanticsProperties.EditableHelperText + +var SemanticsPropertyReceiver.editableCounter by TextInputSemanticsProperties.EditableCounter diff --git a/text-inputs/text-inputs-test-semantics/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/TextInputSemanticsProperties.kt b/text-inputs/text-inputs-test-semantics/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/TextInputSemanticsProperties.kt new file mode 100644 index 00000000..c5a28061 --- /dev/null +++ b/text-inputs/text-inputs-test-semantics/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/TextInputSemanticsProperties.kt @@ -0,0 +1,10 @@ +package com.decathlon.vitamin.compose.textinputs + +import androidx.compose.ui.semantics.SemanticsPropertyKey + +internal object TextInputSemanticsProperties { + val EditableHelperText: SemanticsPropertyKey = + SemanticsPropertyKey(name = "EditableHelperText") + val EditableCounter: SemanticsPropertyKey> = + SemanticsPropertyKey(name = "EditableCounter") +} diff --git a/text-inputs/text-inputs-test/.gitignore b/text-inputs/text-inputs-test/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/text-inputs/text-inputs-test/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/text-inputs/text-inputs-test/README.md b/text-inputs/text-inputs-test/README.md new file mode 100644 index 00000000..343a2a0f --- /dev/null +++ b/text-inputs/text-inputs-test/README.md @@ -0,0 +1,206 @@ +# TextInput test artifact + +## Usage + +If you want to test easier the component in your junit compose test, this artifact will help +you by providing you selectors and assertions that encapsulate the internal implementation of +the component. To use it, declare the test dependency in your Gradle file: + +```kotlin +androidTestImplementation("com.decathlon.vitamin.compose:text-inputs-test:") +``` + +## Find the component + +### Find by label + +If you want to find your semantic EditableText node by its label, you have selectors dedicated to +this usage: + +```kotlin +/** + * Finds a EditableText semantics node that matches the given label attached to the TextInput. + * + * For usage patterns and semantics concepts see [SemanticsNodeInteraction] + * + * @param label Label attached to the TextInput + * @see onAllEditableTextNodeWithLabel to work with multiple elements + */ +fun SemanticsNodeInteractionsProvider.onEditableTextNodeWithLabel(label: String): SemanticsNodeInteraction + +/** + * Finds all EditableText semantics nodes that match the given label attached to the TextInput. + * + * If you are working with elements that are not supposed to occur multiple times use + * [onEditableTextNodeWithLabel] instead. + * + * For usage patterns and semantics concepts see [SemanticsNodeInteraction] + * + * @param label Label attached to the TextInput + * @see onEditableTextNodeWithLabel + */ +fun SemanticsNodeInteractionsProvider.onAllEditableTextNodeWithLabel(label: String): SemanticsNodeInteractionCollection +``` + +They can be used directly from a `ComposeContentTestRule` instance: + +```kotlin +composeTestRule.onEditableTextNodeWithLabel("My label") +composeTestRule.onAllEditableTextNodeWithLabel("My label") +``` + +### Find by value + +If you want to find your semantic EditableText node by its value, you have selectors dedicated to +this usage: + +```kotlin +/** + * Finds a EditableText semantics node that matches the given value filled in the TextInput. + * + * For usage patterns and semantics concepts see [SemanticsNodeInteraction] + * + * @param value Value filled in the content of the TextInput + * @see onAllEditableTextNodesWithValue to work with multiple elements + */ +fun SemanticsNodeInteractionsProvider.onEditableTextNodeWithValue(value: String): SemanticsNodeInteraction + +/** + * Finds all EditableText semantics nodes that match the given value filled in the TextInput. + * + * If you are working with elements that are not supposed to occur multiple times use + * [onEditableTextNodeWithValue] instead. + * + * For usage patterns and semantics concepts see [SemanticsNodeInteraction] + * + * @param value Value filled in the content of the TextInput + * @see onEditableTextNodeWithValue + */ +fun SemanticsNodeInteractionsProvider.onAllEditableTextNodesWithValue(value: String): SemanticsNodeInteractionCollection +``` + +They can be used directly from a `ComposeContentTestRule` instance: + +```kotlin +composeTestRule.onEditableTextNodeWithValue("My value") +composeTestRule.onAllEditableTextNodesWithValue("My value") +``` + +## Assertions + +### Check the value + +If you want to check the value from a semantic EditableText node, you have dedicated assertions for +this usage: + +```kotlin +/** + * Asserts that the node's edittext contains the given [values] and nothing else. + * + * @param value Value to match + * @see SemanticsProperties.EditableText + */ +fun SemanticsNodeInteraction.assertEditableTextValueEquals(value: String): SemanticsNodeInteraction +``` + +They can be used when you find your EditableText node with selectors described in a previous section: + +```kotlin +composeTestRule.onEditableTextNodeWithLabel("My label") + .assertEditableTextValueEquals("My value") +``` + +### Check modes + +If you want to check normal, error and success mode of the EditableText node, you have dedicated +assertions to check if the mode is in error or not: + +```kotlin +/** + * Asserts that the current semantics node is in error. + * + * Throws [AssertionError] if the node is in error or not. + */ +fun SemanticsNodeInteraction.assertIsError(description: String = "Invalid input"): SemanticsNodeInteraction + +/** + * Asserts that the current semantics node is in error. + * + * Throws [AssertionError] if the node is in error or not. + */ +fun SemanticsNodeInteraction.assertIsNotError(description: String = "Invalid input"): SemanticsNodeInteraction +``` + +Note that the normal and success mode have the exact same semantic and should be tested by the same +way. These functions can be used when you find your EditableText node with selectors described in a +previous section: + +```kotlin +composeTestRule.onEditableTextNodeWithLabel("My label") + .assertIsError() // is in error mode + .assertIsNotError() // is in normal or success mode +``` + +## Semantic Matchers + +### Check helper text and counter + +If you want to check the helper text or counter content, uou have dedicated semantic matchers for +this usage: + +```kotlin +/** + * Returns whether the node's editable text helper text contains the given value. + * + * @param helperText Helper text to match the editable text helper text from semantic tree + * @see SemanticsProperties.EditableHelperText + */ +fun hasEditableTextHelperText(helperText: String): SemanticsMatcher + +/** + * Returns whether the node's editable counter pair contains the given value. + * + * @param counter Counter to match the editable text counter from semantic tree + * @see SemanticsProperties.EditableCounter + */ +fun hasEditableTextCounter(counter: Pair): SemanticsMatcher +``` + +They can be used when you find your EditableText node with selectors described in a previous section: + +```kotlin +composeTestRule.onEditableTextNodeWithLabel("My label") + .assert(hasEditableTextHelperText("Helper text")) + .assert(hasEditableTextCounter(Pair(4, 2))) +``` + +## Out of the scope + +### Check trailing icon action + +Because the trailing icon action is declared outside the Vitamin component, there is no dedicated +selectors, assertions or semantic matchers to find the icon and check if they is any click action +on it but you can easily use the native compose test api to find your icon by its content +description and check if it is clickable. + +```kotlin +composeTestRule.setContent { + VitaminTheme { + VitaminTextInputs.Outlined( + value = "My value", + label = "My label", + onValueChange = {}, + icon = { + IconButton(onClick = { }) { + Icon( + imageVector = VitaminIcons.Line.Check, + contentDescription = "check" + ) + } + } + ) + } +} +composeTestRule.onNodeWithContentDescription(label = "check") + .assertHasClickAction() +``` diff --git a/text-inputs/text-inputs-test/build.gradle.kts b/text-inputs/text-inputs-test/build.gradle.kts new file mode 100644 index 00000000..0987eb5e --- /dev/null +++ b/text-inputs/text-inputs-test/build.gradle.kts @@ -0,0 +1,11 @@ +plugins { + id("com.android.library") + id("kotlin-android") + id("VitaminComposeLibraryPlugin") +} + +dependencies { + implementation(AndroidX.compose.ui.test) + implementation(AndroidX.test.espresso.core) + implementation(project(":text-inputs:text-inputs-test-semantics")) +} diff --git a/text-inputs/text-inputs-test/gradle.properties b/text-inputs/text-inputs-test/gradle.properties new file mode 100644 index 00000000..b1d96395 --- /dev/null +++ b/text-inputs/text-inputs-test/gradle.properties @@ -0,0 +1,3 @@ +POM_ARTIFACT_ID=text-inputs-test +POM_NAME=Vitamin TextInputs test artifact +POM_DESCRIPTION=Selectors and assertions to test easilier text inputs \ No newline at end of file diff --git a/text-inputs/text-inputs-test/src/main/AndroidManifest.xml b/text-inputs/text-inputs-test/src/main/AndroidManifest.xml new file mode 100644 index 00000000..b180daef --- /dev/null +++ b/text-inputs/text-inputs-test/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/text-inputs/text-inputs-test/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/testing/Assertions.kt b/text-inputs/text-inputs-test/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/testing/Assertions.kt new file mode 100644 index 00000000..33338a3b --- /dev/null +++ b/text-inputs/text-inputs-test/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/testing/Assertions.kt @@ -0,0 +1,30 @@ +package com.decathlon.vitamin.compose.textinputs.testing + +import androidx.compose.ui.semantics.SemanticsProperties +import androidx.compose.ui.test.SemanticsNodeInteraction +import androidx.compose.ui.test.assert + +/** + * Asserts that the current semantics node is in error. + * + * Throws [AssertionError] if the node is in error or not. + */ +fun SemanticsNodeInteraction.assertIsError(description: String = "Invalid input"): SemanticsNodeInteraction = + assert(isError(description)) + +/** + * Asserts that the current semantics node is in error. + * + * Throws [AssertionError] if the node is in error or not. + */ +fun SemanticsNodeInteraction.assertIsNotError(description: String = "Invalid input"): SemanticsNodeInteraction = + assert(isError(description).not()) + +/** + * Asserts that the node's edittext contains the given [values] and nothing else. + * + * @param value Value to match + * @see SemanticsProperties.EditableText + */ +fun SemanticsNodeInteraction.assertEditableTextValueEquals(value: String): SemanticsNodeInteraction = + assert(hasEditableTextValue(value)) diff --git a/text-inputs/text-inputs-test/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/testing/Filters.kt b/text-inputs/text-inputs-test/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/testing/Filters.kt new file mode 100644 index 00000000..18a61513 --- /dev/null +++ b/text-inputs/text-inputs-test/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/testing/Filters.kt @@ -0,0 +1,12 @@ +package com.decathlon.vitamin.compose.textinputs.testing + +import androidx.compose.ui.semantics.SemanticsProperties +import androidx.compose.ui.test.SemanticsMatcher + +/** + * Returns whether the node is in error mode. + * + * @see SemanticsProperties.Error + */ +fun isError(description: String): SemanticsMatcher = + SemanticsMatcher.expectValue(SemanticsProperties.Error, description) diff --git a/text-inputs/text-inputs-test/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/testing/Selectors.kt b/text-inputs/text-inputs-test/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/testing/Selectors.kt new file mode 100644 index 00000000..6dbbf23c --- /dev/null +++ b/text-inputs/text-inputs-test/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/testing/Selectors.kt @@ -0,0 +1,55 @@ +package com.decathlon.vitamin.compose.textinputs.testing + +import androidx.compose.ui.test.SemanticsNodeInteraction +import androidx.compose.ui.test.SemanticsNodeInteractionCollection +import androidx.compose.ui.test.SemanticsNodeInteractionsProvider + +/** + * Finds a EditableText semantics node that matches the given label attached to the TextInput. + * + * For usage patterns and semantics concepts see [SemanticsNodeInteraction] + * + * @param label Label attached to the TextInput + * @see onAllEditableTextNodeWithLabel to work with multiple elements + */ +fun SemanticsNodeInteractionsProvider.onEditableTextNodeWithLabel(label: String) + : SemanticsNodeInteraction = onNode(hasEditableTextLabel(label)) + +/** + * Finds all EditableText semantics nodes that match the given label attached to the TextInput. + * + * If you are working with elements that are not supposed to occur multiple times use + * [onEditableTextNodeWithLabel] instead. + * + * For usage patterns and semantics concepts see [SemanticsNodeInteraction] + * + * @param label Label attached to the TextInput + * @see onEditableTextNodeWithLabel + */ +fun SemanticsNodeInteractionsProvider.onAllEditableTextNodeWithLabel(label: String) + : SemanticsNodeInteractionCollection = onAllNodes(hasEditableTextLabel(label)) + +/** + * Finds a EditableText semantics node that matches the given value filled in the TextInput. + * + * For usage patterns and semantics concepts see [SemanticsNodeInteraction] + * + * @param value Value filled in the content of the TextInput + * @see onAllEditableTextNodesWithValue to work with multiple elements + */ +fun SemanticsNodeInteractionsProvider.onEditableTextNodeWithValue(value: String) + : SemanticsNodeInteraction = onNode(hasEditableTextValue(value)) + +/** + * Finds all EditableText semantics nodes that match the given value filled in the TextInput. + * + * If you are working with elements that are not supposed to occur multiple times use + * [onEditableTextNodeWithValue] instead. + * + * For usage patterns and semantics concepts see [SemanticsNodeInteraction] + * + * @param value Value filled in the content of the TextInput + * @see onEditableTextNodeWithValue + */ +fun SemanticsNodeInteractionsProvider.onAllEditableTextNodesWithValue(value: String) + : SemanticsNodeInteractionCollection = onAllNodes(hasEditableTextValue(value)) diff --git a/text-inputs/text-inputs-test/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/testing/SemanticsMatchers.kt b/text-inputs/text-inputs-test/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/testing/SemanticsMatchers.kt new file mode 100644 index 00000000..152befec --- /dev/null +++ b/text-inputs/text-inputs-test/src/main/kotlin/com/decathlon/vitamin/compose/textinputs/testing/SemanticsMatchers.kt @@ -0,0 +1,64 @@ +package com.decathlon.vitamin.compose.textinputs.testing + +import androidx.compose.ui.semantics.SemanticsActions +import androidx.compose.ui.semantics.SemanticsProperties +import androidx.compose.ui.semantics.getOrNull +import androidx.compose.ui.test.SemanticsMatcher +import com.decathlon.vitamin.compose.textinputs.EditableCounter +import com.decathlon.vitamin.compose.textinputs.EditableHelperText + +/** + * Returns whether the node's editable text label contains the given value. + * + * @param label Label to match the editable text label from semantic tree + * @param ignoreCase Whether case should be ignored. + * @see SemanticsProperties.Text + * @see SemanticsProperties.EditableText + */ +fun hasEditableTextLabel(label: String, ignoreCase: Boolean = false): SemanticsMatcher { + return SemanticsMatcher("${SemanticsProperties.Text.name} = '$label'") { + val hasSetTextAction = SemanticsActions.SetText in it.config + val isInTextValue = it.config.getOrNull(SemanticsProperties.Text) + ?.any { item -> item.text.equals(label, ignoreCase) } ?: false + hasSetTextAction && isInTextValue + } +} + +/** + * Returns whether the node's editable text value contains the given value. + * + * @param value Value to match the editable text value from semantic tree + * @see SemanticsProperties.EditableText + */ +fun hasEditableTextValue(value: String): SemanticsMatcher { + return SemanticsMatcher("${SemanticsProperties.EditableText.name} = '$value'") { + val hasSetTextAction = SemanticsActions.SetText in it.config + val isInEditableTextValue = it.config.getOrNull(SemanticsProperties.EditableText) + ?.text?.equals(value) ?: false + hasSetTextAction && isInEditableTextValue + } +} + +/** + * Returns whether the node's editable text helper text contains the given value. + * + * @param helperText Helper text to match the editable text helper text from semantic tree + * @see SemanticsProperties.EditableHelperText + */ +fun hasEditableTextHelperText(helperText: String): SemanticsMatcher { + return SemanticsMatcher("${SemanticsProperties.EditableHelperText.name} = '$helperText'") { + it.config.getOrNull(SemanticsProperties.EditableHelperText) == helperText + } +} + +/** + * Returns whether the node's editable counter pair contains the given value. + * + * @param counter Counter to match the editable text counter from semantic tree + * @see SemanticsProperties.EditableCounter + */ +fun hasEditableTextCounter(counter: Pair): SemanticsMatcher { + return SemanticsMatcher("${SemanticsProperties.EditableCounter.name} = '$counter'") { + it.config.getOrNull(SemanticsProperties.EditableCounter) == counter + } +} diff --git a/text-inputs/text-inputs/.gitignore b/text-inputs/text-inputs/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/text-inputs/text-inputs/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/text-inputs/README.md b/text-inputs/text-inputs/README.md similarity index 97% rename from text-inputs/README.md rename to text-inputs/text-inputs/README.md index 2542d50c..78384268 100644 --- a/text-inputs/README.md +++ b/text-inputs/text-inputs/README.md @@ -4,6 +4,13 @@ You can find the design specs on [decathlon.design](https://www.decathlon.design/). +## Testing + +If you want to add Compose tests in your own project, you can use the dedicated test artifact +for this component in your test dependencies which provides selectors and assertions that +encapsulate the internal implementation of the component. +[Check the documentation here.](../text-inputs-test/README.md) + ## Usage If you want to use components of this module in your android mobile application, you should diff --git a/text-inputs/build.gradle.kts b/text-inputs/text-inputs/build.gradle.kts similarity index 71% rename from text-inputs/build.gradle.kts rename to text-inputs/text-inputs/build.gradle.kts index 905d4df9..ceef5e0f 100644 --- a/text-inputs/build.gradle.kts +++ b/text-inputs/text-inputs/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") id("app.cash.paparazzi") } @@ -10,6 +11,8 @@ dependencies { api(project(":foundation:foundation")) api(project(":foundation:foundation-icons")) api(project(":menus")) + implementation(project(":text-inputs:text-inputs-test-semantics")) implementation(AndroidX.compose.ui.tooling) testImplementation("com.google.testparameterinjector:test-parameter-injector:1.8") + androidTestImplementation(project(":text-inputs:text-inputs-test")) } diff --git a/text-inputs/gradle.properties b/text-inputs/text-inputs/gradle.properties similarity index 100% rename from text-inputs/gradle.properties rename to text-inputs/text-inputs/gradle.properties diff --git a/text-inputs/proguard-rules.pro b/text-inputs/text-inputs/proguard-rules.pro similarity index 100% rename from text-inputs/proguard-rules.pro rename to text-inputs/text-inputs/proguard-rules.pro diff --git a/text-inputs/text-inputs/src/androidTest/kotlin/com/decathlon/vitamin/compose/textinputs/TextInputFilteringTest.kt b/text-inputs/text-inputs/src/androidTest/kotlin/com/decathlon/vitamin/compose/textinputs/TextInputFilteringTest.kt new file mode 100644 index 00000000..fe89de13 --- /dev/null +++ b/text-inputs/text-inputs/src/androidTest/kotlin/com/decathlon/vitamin/compose/textinputs/TextInputFilteringTest.kt @@ -0,0 +1,190 @@ +package com.decathlon.vitamin.compose.textinputs + +import androidx.compose.foundation.layout.Column +import androidx.compose.material.Text +import androidx.compose.ui.test.assertAll +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.junit4.createComposeRule +import com.decathlon.vitamin.compose.foundation.VitaminTheme +import com.decathlon.vitamin.compose.textinputs.testing.assertEditableTextValueEquals +import com.decathlon.vitamin.compose.textinputs.testing.hasEditableTextLabel +import com.decathlon.vitamin.compose.textinputs.testing.hasEditableTextValue +import com.decathlon.vitamin.compose.textinputs.testing.onAllEditableTextNodeWithLabel +import com.decathlon.vitamin.compose.textinputs.testing.onAllEditableTextNodesWithValue +import com.decathlon.vitamin.compose.textinputs.testing.onEditableTextNodeWithLabel +import com.decathlon.vitamin.compose.textinputs.testing.onEditableTextNodeWithValue +import org.junit.Rule +import org.junit.Test + +class TextInputFilteringTest { + @get:Rule + val composeTestRule = createComposeRule() + + /** + * Given Vitamin TextInput with a label + * When we compose the component tree + * Then we can filtering the text input by its label + */ + @Test + fun checkFilteringTextInputByLabel() { + composeTestRule.setContent { + VitaminTheme { + VitaminTextInputs.Outlined( + value = "My value", + label = "My label", + onValueChange = { + }, + colors = TextInputsState.normal() + ) + } + } + composeTestRule.onEditableTextNodeWithLabel("My label") + .assertEditableTextValueEquals("My value") + composeTestRule.onEditableTextNodeWithLabel("Unknown label") + .assertDoesNotExist() + } + + /** + * Given two Vitamin TextInputs with the same label + * When we compose the component tree + * Then we can filtering the text inputs by their label + */ + @Test + fun checkFilteringAllTextInputsByLabel() { + composeTestRule.setContent { + VitaminTheme { + Column { + VitaminTextInputs.Outlined( + value = "My value", + label = "My label", + onValueChange = { + }, + colors = TextInputsState.normal() + ) + VitaminTextInputs.Outlined( + value = "My value", + label = "My label", + onValueChange = { + }, + colors = TextInputsState.normal() + ) + } + } + } + composeTestRule.onAllEditableTextNodeWithLabel("My label") + .assertAll(hasEditableTextValue("My value")) + } + + /** + * Given Vitamin TextInput with a value + * When we compose the component tree + * Then we can filtering the text input by its value + */ + @Test + fun checkFilteringTextInputByValue() { + composeTestRule.setContent { + VitaminTheme { + VitaminTextInputs.Outlined( + value = "My value", + label = "My label", + onValueChange = { + }, + colors = TextInputsState.normal() + ) + } + } + composeTestRule.onEditableTextNodeWithValue("My value") + .assertIsDisplayed() + composeTestRule.onEditableTextNodeWithValue("Unknown value") + .assertDoesNotExist() + } + + /** + * Given two Vitamin TextInput with the same value + * When we compose the component tree + * Then we can filtering the text inputs by their value + */ + @Test + fun checkFilteringAllTextInputsByValue() { + composeTestRule.setContent { + VitaminTheme { + Column { + VitaminTextInputs.Outlined( + value = "My value", + label = "My label", + onValueChange = { + }, + colors = TextInputsState.normal() + ) + VitaminTextInputs.Outlined( + value = "My value", + label = "My label", + onValueChange = { + }, + colors = TextInputsState.normal() + ) + } + } + } + composeTestRule.onAllEditableTextNodesWithValue("My value") + .assertAll(hasEditableTextLabel("My label")) + } + + /** + * Given two Vitamin TextInput with different label + * When we compose the component tree + * Then we can filtering each Vitamin TextInput + */ + @Test + fun checkCanDistinctMultipleTextInputWithDifferentLabel() { + composeTestRule.setContent { + VitaminTheme { + Column { + VitaminTextInputs.Outlined( + value = "My value", + label = "My label", + onValueChange = { + }, + colors = TextInputsState.normal() + ) + VitaminTextInputs.Outlined( + value = "My value", + label = "My label 2", + onValueChange = { + }, + colors = TextInputsState.normal() + ) + } + } + } + composeTestRule.onEditableTextNodeWithLabel("My label") + .assertEditableTextValueEquals("My value") + composeTestRule.onEditableTextNodeWithLabel("My label 2") + .assertEditableTextValueEquals("My value") + } + + /** + * Given a text and a Vitamin TextInput with the same value + * When we compose the component tree + * Then the rule should only find the Vitamin TextInput instead of crash + */ + @Test + fun checkCanDistinctTextInputWithAnotherComponentWithSameValue() { + composeTestRule.setContent { + VitaminTheme { + Column { + Text("My value") + VitaminTextInputs.Outlined( + value = "My value", + label = "My label", + onValueChange = { + }, + colors = TextInputsState.normal() + ) + } + } + } + composeTestRule.onEditableTextNodeWithValue("My value") + .assertIsDisplayed() + } +} diff --git a/text-inputs/text-inputs/src/androidTest/kotlin/com/decathlon/vitamin/compose/textinputs/TextInputHelperTextCounterTest.kt b/text-inputs/text-inputs/src/androidTest/kotlin/com/decathlon/vitamin/compose/textinputs/TextInputHelperTextCounterTest.kt new file mode 100644 index 00000000..04e28516 --- /dev/null +++ b/text-inputs/text-inputs/src/androidTest/kotlin/com/decathlon/vitamin/compose/textinputs/TextInputHelperTextCounterTest.kt @@ -0,0 +1,107 @@ +package com.decathlon.vitamin.compose.textinputs + +import androidx.compose.ui.test.assert +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.test.onNodeWithText +import com.decathlon.vitamin.compose.foundation.VitaminTheme +import com.decathlon.vitamin.compose.textinputs.testing.hasEditableTextCounter +import com.decathlon.vitamin.compose.textinputs.testing.hasEditableTextHelperText +import com.decathlon.vitamin.compose.textinputs.testing.onEditableTextNodeWithLabel +import org.junit.Rule +import org.junit.Test + +class TextInputHelperTextCounterTest { + @get:Rule + val composeTestRule = createComposeRule() + + /** + * Given Vitamin TextInput with an helper text + * When we compose the component tree + * Then we can check in the semantic props if the helper text is available + */ + @Test + fun checkHelperTextIsAccessibleAndDisplayed() { + composeTestRule.setContent { + VitaminTheme { + VitaminTextInputs.Outlined( + value = "My value", + label = "My label", + onValueChange = { + }, + helperText = "Short description" + ) + } + } + composeTestRule.onEditableTextNodeWithLabel("My label") + .assert(hasEditableTextHelperText("Short description")) + } + + /** + * Given Vitamin TextInput with an helper text + * When we compose the component tree + * Then we can check if the helper text Text is accessible for Talkback + */ + @Test + fun checkHelperTextIsAccessibleForTalkback() { + composeTestRule.setContent { + VitaminTheme { + VitaminTextInputs.Outlined( + value = "My value", + label = "My label", + onValueChange = { + }, + helperText = "Short description" + ) + } + } + composeTestRule.onNodeWithText("Short description") + .assertExists() + .assertIsDisplayed() + } + + /** + * Given Vitamin TextInput with an helper text + * When we compose the component tree + * Then we can check in the semantic props if the helper text is available + */ + @Test + fun checkCounterIsAccessibleAndDisplayed() { + composeTestRule.setContent { + VitaminTheme { + VitaminTextInputs.Outlined( + value = "My value", + label = "My label", + onValueChange = { + }, + counter = Pair(4, 2) + ) + } + } + composeTestRule.onEditableTextNodeWithLabel("My label") + .assert(hasEditableTextCounter(Pair(4, 2))) + } + + /** + * Given Vitamin TextInput with a counter + * When we compose the component tree + * Then we can check if the counter Text is accessible for Talkback + */ + @Test + fun checkCounterIsAccessibleForTalkback() { + composeTestRule.setContent { + VitaminTheme { + VitaminTextInputs.Outlined( + value = "My value", + label = "My label", + onValueChange = { + }, + counter = Pair(4, 2) + ) + } + } + composeTestRule.onNodeWithText("4/2") + .assertExists() + .assertIsDisplayed() + } +} diff --git a/text-inputs/text-inputs/src/androidTest/kotlin/com/decathlon/vitamin/compose/textinputs/TextInputStateTest.kt b/text-inputs/text-inputs/src/androidTest/kotlin/com/decathlon/vitamin/compose/textinputs/TextInputStateTest.kt new file mode 100644 index 00000000..ebcaed07 --- /dev/null +++ b/text-inputs/text-inputs/src/androidTest/kotlin/com/decathlon/vitamin/compose/textinputs/TextInputStateTest.kt @@ -0,0 +1,118 @@ +package com.decathlon.vitamin.compose.textinputs + +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.assertIsNotEnabled +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.test.onNodeWithText +import com.decathlon.vitamin.compose.foundation.VitaminTheme +import com.decathlon.vitamin.compose.textinputs.testing.assertIsError +import com.decathlon.vitamin.compose.textinputs.testing.assertIsNotError +import com.decathlon.vitamin.compose.textinputs.testing.onEditableTextNodeWithLabel +import com.decathlon.vitamin.compose.textinputs.testing.onEditableTextNodeWithValue +import org.junit.Rule +import org.junit.Test + +class TextInputStateTest { + @get:Rule + val composeTestRule = createComposeRule() + + /** + * Given a VitaminTextInput in normal mode + * When we compose the component tree + * Then it should be displayed but not in error mode + */ + @Test + fun checkTextInputIsNotInError() { + composeTestRule.setContent { + VitaminTheme { + VitaminTextInputs.Outlined( + value = "My value", + label = "My label", + onValueChange = { + }, + colors = TextInputsState.normal() + ) + } + } + composeTestRule.onEditableTextNodeWithValue("My value") + .assertIsDisplayed() + composeTestRule.onEditableTextNodeWithValue("My value") + .assertIsNotError() + } + + /** + * Given a VitaminTextInput in error mode + * When we compose the component tree + * Then it should be displayed and in error mode + */ + @Test + fun checkTextInputIsInError() { + composeTestRule.setContent { + VitaminTheme { + VitaminTextInputs.Outlined( + value = "My value", + label = "My label", + onValueChange = { + }, + colors = TextInputsState.error() + ) + } + } + composeTestRule.onEditableTextNodeWithValue("My value") + .assertIsDisplayed() + composeTestRule.onEditableTextNodeWithValue("My value") + .assertIsError() + } + + /** + * Given a VitaminTextInput in success mode + * When we compose the component tree + * Then it should be the same as normal + */ + @Test + fun checkTextInputIsInSuccess() { + composeTestRule.setContent { + VitaminTheme { + VitaminTextInputs.Outlined( + value = "My value", + label = "My label", + onValueChange = { + }, + colors = TextInputsState.success() + ) + } + } + composeTestRule.onEditableTextNodeWithValue("My value") + .assertIsDisplayed() + composeTestRule.onEditableTextNodeWithValue("My value") + .assertIsNotError() + } + + /** + * Given a VitaminTextInput disabled + * When we compose the component tree + * Then text input, helper text and counter should be tagged as disable + */ + @Test + fun checkTextInputIsDisabled() { + composeTestRule.setContent { + VitaminTheme { + VitaminTextInputs.Outlined( + value = "My value", + label = "My label", + onValueChange = { + }, + helperText = "My helper text", + counter = Pair(4, 2), + enabled = false + ) + } + } + composeTestRule.onEditableTextNodeWithLabel("My label") + .assertIsNotEnabled() + composeTestRule.onNodeWithText("My helper text") + .assertIsNotEnabled() + composeTestRule.onNodeWithText("4/2") + .assertIsNotEnabled() + } +} diff --git a/text-inputs/text-inputs/src/androidTest/kotlin/com/decathlon/vitamin/compose/textinputs/TextInputTrailingIconTest.kt b/text-inputs/text-inputs/src/androidTest/kotlin/com/decathlon/vitamin/compose/textinputs/TextInputTrailingIconTest.kt new file mode 100644 index 00000000..4886fa7d --- /dev/null +++ b/text-inputs/text-inputs/src/androidTest/kotlin/com/decathlon/vitamin/compose/textinputs/TextInputTrailingIconTest.kt @@ -0,0 +1,49 @@ +package com.decathlon.vitamin.compose.textinputs + +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.ui.test.assertHasClickAction +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.test.onNodeWithContentDescription +import com.decathlon.vitamin.compose.VitaminIcons +import com.decathlon.vitamin.compose.foundation.VitaminTheme +import com.decathlon.vitamin.compose.vitaminicons.Line +import com.decathlon.vitamin.compose.vitaminicons.line.Check +import org.junit.Rule +import org.junit.Test + +class TextInputTrailingIconTest { + @get:Rule + val composeTestRule = createComposeRule() + + /** + * Given a TextInput with a trailing icon + * When we compose the component tree + * Then we can find the icon by content description and click on it + */ + @Test + fun checkIconButtonDeclaredInTextInputCanBeClickable() { + composeTestRule.setContent { + VitaminTheme { + VitaminTextInputs.Outlined( + value = "My value", + label = "My label", + onValueChange = { + }, + icon = { + IconButton(onClick = { }) { + Icon( + imageVector = VitaminIcons.Line.Check, + contentDescription = "check" + ) + } + } + ) + } + } + composeTestRule.onNodeWithContentDescription(label = "check") + .assertIsDisplayed() + .assertHasClickAction() + } +} diff --git a/text-inputs/src/main/AndroidManifest.xml b/text-inputs/text-inputs/src/main/AndroidManifest.xml similarity index 100% rename from text-inputs/src/main/AndroidManifest.xml rename to text-inputs/text-inputs/src/main/AndroidManifest.xml diff --git a/text-inputs/src/main/java/com/decathlon/vitamin/compose/textinputs/TextInputsState.kt b/text-inputs/text-inputs/src/main/java/com/decathlon/vitamin/compose/textinputs/TextInputsState.kt similarity index 100% rename from text-inputs/src/main/java/com/decathlon/vitamin/compose/textinputs/TextInputsState.kt rename to text-inputs/text-inputs/src/main/java/com/decathlon/vitamin/compose/textinputs/TextInputsState.kt diff --git a/text-inputs/src/main/java/com/decathlon/vitamin/compose/textinputs/TextInputsTransformations.kt b/text-inputs/text-inputs/src/main/java/com/decathlon/vitamin/compose/textinputs/TextInputsTransformations.kt similarity index 100% rename from text-inputs/src/main/java/com/decathlon/vitamin/compose/textinputs/TextInputsTransformations.kt rename to text-inputs/text-inputs/src/main/java/com/decathlon/vitamin/compose/textinputs/TextInputsTransformations.kt diff --git a/text-inputs/text-inputs/src/main/java/com/decathlon/vitamin/compose/textinputs/VitaminTextInputModifiers.kt b/text-inputs/text-inputs/src/main/java/com/decathlon/vitamin/compose/textinputs/VitaminTextInputModifiers.kt new file mode 100644 index 00000000..e081c419 --- /dev/null +++ b/text-inputs/text-inputs/src/main/java/com/decathlon/vitamin/compose/textinputs/VitaminTextInputModifiers.kt @@ -0,0 +1,21 @@ +package com.decathlon.vitamin.compose.textinputs + +import androidx.compose.ui.Modifier +import androidx.compose.ui.semantics.semantics + +/** + * Apply custom semantics to Vitamin TextInput components. + * @param helperText Optional helper text attached to the TextInput + * @param counter Optional counter attached to the TextInput + */ +internal fun Modifier.vtmnSemantics( + helperText: String?, + counter: Pair? +) = semantics { + if (helperText != null) { + this.editableHelperText = helperText + } + if (counter != null) { + this.editableCounter = counter + } +} diff --git a/text-inputs/src/main/java/com/decathlon/vitamin/compose/textinputs/VitaminTextInputs.kt b/text-inputs/text-inputs/src/main/java/com/decathlon/vitamin/compose/textinputs/VitaminTextInputs.kt similarity index 96% rename from text-inputs/src/main/java/com/decathlon/vitamin/compose/textinputs/VitaminTextInputs.kt rename to text-inputs/text-inputs/src/main/java/com/decathlon/vitamin/compose/textinputs/VitaminTextInputs.kt index 9000b1a2..6427f8af 100644 --- a/text-inputs/src/main/java/com/decathlon/vitamin/compose/textinputs/VitaminTextInputs.kt +++ b/text-inputs/text-inputs/src/main/java/com/decathlon/vitamin/compose/textinputs/VitaminTextInputs.kt @@ -27,6 +27,8 @@ import androidx.compose.ui.geometry.Size import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.disabled +import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.style.TextOverflow @@ -127,7 +129,7 @@ object VitaminTextInputs { keyboardActions = keyboardActions, singleLine = singleLine, maxLines = maxLines, - modifier = Modifier.fillMaxWidth(), + modifier = Modifier.fillMaxWidth().vtmnSemantics(helperText, counter), enabled = enabled, readOnly = readOnly, isError = colors.state == State.ERROR, @@ -296,7 +298,7 @@ object VitaminTextInputs { keyboardActions = keyboardActions, singleLine = singleLine, maxLines = maxLines, - modifier = Modifier.fillMaxWidth(), + modifier = Modifier.fillMaxWidth().vtmnSemantics(helperText, counter), enabled = enabled, isError = colors.state == State.ERROR, readOnly = readOnly, @@ -401,7 +403,9 @@ internal fun VitaminTextInputLayoutImpl( ) { textInput() } - Row(modifier = Modifier.padding(vertical = 1.dp, horizontal = 4.dp)) { + Row( + modifier = Modifier.padding(vertical = 1.dp, horizontal = 4.dp) + ) { helperText?.let { val color = if (!enabled) colors.helperColor.copy(ContentAlpha.disabled) else if (colors.state == State.ERROR) colors.textColor @@ -414,7 +418,12 @@ internal fun VitaminTextInputLayoutImpl( overflow = TextOverflow.Ellipsis, modifier = Modifier .weight(1f) - .padding(end = 4.dp), + .padding(end = 4.dp) + .semantics { + if (!enabled) { + this.disabled() + } + } ) } counter?.let { @@ -424,6 +433,11 @@ internal fun VitaminTextInputLayoutImpl( text = "${it.first}/${it.second}", style = VitaminTheme.typography.caption, color = color, + modifier = Modifier.semantics { + if (!enabled) { + this.disabled() + } + } ) } } diff --git a/text-inputs/src/main/res/values/strings.xml b/text-inputs/text-inputs/src/main/res/values/strings.xml similarity index 100% rename from text-inputs/src/main/res/values/strings.xml rename to text-inputs/text-inputs/src/main/res/values/strings.xml diff --git a/text-inputs/src/test/kotlin/com/decathlon/vitamin/compose/textinputs/VitaminTextInputsPrimaryTest.kt b/text-inputs/text-inputs/src/test/kotlin/com/decathlon/vitamin/compose/textinputs/VitaminTextInputsPrimaryTest.kt similarity index 100% rename from text-inputs/src/test/kotlin/com/decathlon/vitamin/compose/textinputs/VitaminTextInputsPrimaryTest.kt rename to text-inputs/text-inputs/src/test/kotlin/com/decathlon/vitamin/compose/textinputs/VitaminTextInputsPrimaryTest.kt diff --git a/text-inputs/src/test/kotlin/com/decathlon/vitamin/compose/textinputs/utils/TextInputVariantsFactory.kt b/text-inputs/text-inputs/src/test/kotlin/com/decathlon/vitamin/compose/textinputs/utils/TextInputVariantsFactory.kt similarity index 100% rename from text-inputs/src/test/kotlin/com/decathlon/vitamin/compose/textinputs/utils/TextInputVariantsFactory.kt rename to text-inputs/text-inputs/src/test/kotlin/com/decathlon/vitamin/compose/textinputs/utils/TextInputVariantsFactory.kt diff --git a/text-inputs/src/test/kotlin/com/decathlon/vitamin/compose/textinputs/utils/Theme.kt b/text-inputs/text-inputs/src/test/kotlin/com/decathlon/vitamin/compose/textinputs/utils/Theme.kt similarity index 100% rename from text-inputs/src/test/kotlin/com/decathlon/vitamin/compose/textinputs/utils/Theme.kt rename to text-inputs/text-inputs/src/test/kotlin/com/decathlon/vitamin/compose/textinputs/utils/Theme.kt diff --git a/text-inputs/src/test/kotlin/com/decathlon/vitamin/compose/textinputs/utils/Variant.kt b/text-inputs/text-inputs/src/test/kotlin/com/decathlon/vitamin/compose/textinputs/utils/Variant.kt similarity index 100% rename from text-inputs/src/test/kotlin/com/decathlon/vitamin/compose/textinputs/utils/Variant.kt rename to text-inputs/text-inputs/src/test/kotlin/com/decathlon/vitamin/compose/textinputs/utils/Variant.kt diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[Filled,Dark].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[Filled,Dark].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[Filled,Dark].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[Filled,Dark].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[Filled,Light].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[Filled,Light].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[Filled,Light].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[Filled,Light].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[FilledDropdown,Dark].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[FilledDropdown,Dark].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[FilledDropdown,Dark].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[FilledDropdown,Dark].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[FilledDropdown,Light].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[FilledDropdown,Light].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[FilledDropdown,Light].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[FilledDropdown,Light].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[Outlined,Dark].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[Outlined,Dark].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[Outlined,Dark].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[Outlined,Dark].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[Outlined,Light].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[Outlined,Light].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[Outlined,Light].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[Outlined,Light].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[OutlinedDropdown,Dark].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[OutlinedDropdown,Dark].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[OutlinedDropdown,Dark].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[OutlinedDropdown,Dark].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[OutlinedDropdown,Light].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[OutlinedDropdown,Light].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[OutlinedDropdown,Light].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_error[OutlinedDropdown,Light].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[Filled,Dark].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[Filled,Dark].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[Filled,Dark].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[Filled,Dark].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[Filled,Light].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[Filled,Light].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[Filled,Light].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[Filled,Light].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[FilledDropdown,Dark].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[FilledDropdown,Dark].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[FilledDropdown,Dark].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[FilledDropdown,Dark].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[FilledDropdown,Light].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[FilledDropdown,Light].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[FilledDropdown,Light].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[FilledDropdown,Light].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[Outlined,Dark].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[Outlined,Dark].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[Outlined,Dark].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[Outlined,Dark].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[Outlined,Light].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[Outlined,Light].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[Outlined,Light].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[Outlined,Light].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[OutlinedDropdown,Dark].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[OutlinedDropdown,Dark].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[OutlinedDropdown,Dark].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[OutlinedDropdown,Dark].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[OutlinedDropdown,Light].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[OutlinedDropdown,Light].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[OutlinedDropdown,Light].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_normal[OutlinedDropdown,Light].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[Filled,Dark].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[Filled,Dark].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[Filled,Dark].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[Filled,Dark].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[Filled,Light].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[Filled,Light].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[Filled,Light].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[Filled,Light].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[FilledDropdown,Dark].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[FilledDropdown,Dark].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[FilledDropdown,Dark].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[FilledDropdown,Dark].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[FilledDropdown,Light].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[FilledDropdown,Light].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[FilledDropdown,Light].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[FilledDropdown,Light].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[Outlined,Dark].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[Outlined,Dark].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[Outlined,Dark].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[Outlined,Dark].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[Outlined,Light].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[Outlined,Light].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[Outlined,Light].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[Outlined,Light].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[OutlinedDropdown,Dark].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[OutlinedDropdown,Dark].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[OutlinedDropdown,Dark].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[OutlinedDropdown,Dark].png diff --git a/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[OutlinedDropdown,Light].png b/text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[OutlinedDropdown,Light].png similarity index 100% rename from text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[OutlinedDropdown,Light].png rename to text-inputs/text-inputs/src/test/snapshots/images/com.decathlon.vitamin.compose.textinputs_VitaminTextInputsPrimaryTest_success[OutlinedDropdown,Light].png diff --git a/vitamin/build.gradle.kts b/vitamin/build.gradle.kts index baa6a239..1b4b174d 100644 --- a/vitamin/build.gradle.kts +++ b/vitamin/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") id("kotlin-android") id("VitaminComposeLibraryPlugin") + id("VitaminQualityPlugin") id("com.vanniktech.maven.publish") } @@ -28,7 +29,7 @@ dependencies { api(project(":switches")) api(project(":tabs")) api(project(":tags")) - api(project(":text-inputs")) + api(project(":text-inputs:text-inputs")) api(project(":quantity-pickers")) api(project(":scaffolds")) }