Skip to content

Commit 6a28814

Browse files
authored
Merge pull request #1526 from vector-im/feature/bma/konsist
Konsist
2 parents 7c6397d + 7c5a41f commit 6a28814

File tree

159 files changed

+1580
-985
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

159 files changed

+1580
-985
lines changed

.idea/dictionaries/shared.xml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

CONTRIBUTING.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
* [knit](#knit)
1919
* [lint](#lint)
2020
* [Unit tests](#unit-tests)
21+
* [konsist](#konsist)
2122
* [Tests](#tests)
2223
* [Accessibility](#accessibility)
2324
* [Jetpack Compose](#jetpack-compose)
@@ -156,6 +157,10 @@ Make sure the following commands execute without any error:
156157
./gradlew test
157158
</pre>
158159

160+
#### konsist
161+
162+
[konsist](https://github.com/LemonAppDev/konsist) is setup in the project to check that the architecture and the naming rules are followed. Konsist tests are classical Unit tests.
163+
159164
### Tests
160165

161166
Element X is currently supported on Android Marshmallow (API 23+): please test your change on an Android device (or Android emulator) running with API 23. Many issues can happen (including crashes) on older devices.

app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ dependencies {
230230
testImplementation(libs.test.truth)
231231
testImplementation(libs.test.turbine)
232232
testImplementation(projects.libraries.matrix.test)
233+
testImplementation(libs.test.konsist)
233234

234235
ksp(libs.showkase.processor)
235236
}

app/src/main/kotlin/io/element/android/x/MainActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import com.bumble.appyx.core.integrationpoint.NodeComponentActivity
3434
import com.bumble.appyx.core.plugin.NodeReadyObserver
3535
import io.element.android.libraries.architecture.bindings
3636
import io.element.android.libraries.core.log.logger.LoggerTag
37-
import io.element.android.libraries.designsystem.utils.LocalSnackbarDispatcher
37+
import io.element.android.libraries.designsystem.utils.snackbar.LocalSnackbarDispatcher
3838
import io.element.android.libraries.theme.ElementTheme
3939
import io.element.android.x.di.AppBindings
4040
import io.element.android.x.intent.SafeUriHandler

app/src/main/kotlin/io/element/android/x/di/AppBindings.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ package io.element.android.x.di
1818

1919
import com.squareup.anvil.annotations.ContributesTo
2020
import io.element.android.features.rageshake.api.reporter.BugReporter
21-
import io.element.android.libraries.designsystem.utils.SnackbarDispatcher
21+
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
2222
import io.element.android.libraries.di.AppScope
2323
import io.element.android.libraries.matrix.api.tracing.TracingService
2424

app/src/main/kotlin/io/element/android/x/di/AppModule.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import io.element.android.features.messages.impl.timeline.components.customreact
2828
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
2929
import io.element.android.libraries.core.meta.BuildMeta
3030
import io.element.android.libraries.core.meta.BuildType
31-
import io.element.android.libraries.designsystem.utils.SnackbarDispatcher
31+
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
3232
import io.element.android.libraries.di.AppScope
3333
import io.element.android.libraries.di.ApplicationContext
3434
import io.element.android.libraries.di.DefaultPreferences
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/*
2+
* Copyright (c) 2023 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.element.android.app
18+
19+
import androidx.compose.runtime.Composable
20+
import com.lemonappdev.konsist.api.KoModifier
21+
import com.lemonappdev.konsist.api.Konsist
22+
import com.lemonappdev.konsist.api.ext.list.constructors
23+
import com.lemonappdev.konsist.api.ext.list.modifierprovider.withoutModifier
24+
import com.lemonappdev.konsist.api.ext.list.modifierprovider.withoutOverrideModifier
25+
import com.lemonappdev.konsist.api.ext.list.parameters
26+
import com.lemonappdev.konsist.api.ext.list.properties
27+
import com.lemonappdev.konsist.api.ext.list.withAllAnnotationsOf
28+
import com.lemonappdev.konsist.api.ext.list.withAllParentsOf
29+
import com.lemonappdev.konsist.api.ext.list.withNameEndingWith
30+
import com.lemonappdev.konsist.api.ext.list.withReturnType
31+
import com.lemonappdev.konsist.api.ext.list.withTopLevel
32+
import com.lemonappdev.konsist.api.ext.list.withoutName
33+
import com.lemonappdev.konsist.api.ext.list.withoutNameEndingWith
34+
import com.lemonappdev.konsist.api.verify.assertFalse
35+
import com.lemonappdev.konsist.api.verify.assertTrue
36+
import io.element.android.libraries.architecture.Presenter
37+
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
38+
import org.junit.Test
39+
40+
class KonsistTest {
41+
42+
@Test
43+
fun `Classes extending 'Presenter' should have 'Presenter' suffix`() {
44+
Konsist.scopeFromProject()
45+
.classes()
46+
.withAllParentsOf(Presenter::class)
47+
.assertTrue {
48+
it.name.endsWith("Presenter")
49+
}
50+
}
51+
52+
@Test
53+
fun `Functions with '@PreviewsDayNight' annotation should have 'Preview' suffix`() {
54+
Konsist
55+
.scopeFromProject()
56+
.functions()
57+
.withAllAnnotationsOf(PreviewsDayNight::class)
58+
.assertTrue {
59+
it.hasNameEndingWith("Preview") &&
60+
it.hasNameEndingWith("LightPreview").not() &&
61+
it.hasNameEndingWith("DarkPreview").not()
62+
}
63+
}
64+
65+
@Test
66+
fun `Top level function with '@Composable' annotation starting with a upper case should be placed in a file with the same name`() {
67+
Konsist
68+
.scopeFromProject()
69+
.functions()
70+
.withTopLevel()
71+
.withoutModifier(KoModifier.PRIVATE)
72+
.withoutNameEndingWith("Preview")
73+
.withAllAnnotationsOf(Composable::class)
74+
.withoutName(
75+
// Add some exceptions...
76+
"OutlinedButton",
77+
"TextButton",
78+
"SimpleAlertDialogContent",
79+
)
80+
.assertTrue(
81+
additionalMessage =
82+
"""
83+
Please check the filename. It should match the top level Composable function. If the filename is correct:
84+
- consider making the Composable private or moving it to its own file
85+
- at last resort, you can add an exception in the Konsist test
86+
""".trimIndent()
87+
) {
88+
if (it.name.first().isLowerCase()) {
89+
true
90+
} else {
91+
val fileName = it.containingFile.name.removeSuffix(".kt")
92+
fileName == it.name
93+
}
94+
}
95+
}
96+
97+
@Test
98+
fun `Data class state MUST not have default value`() {
99+
Konsist
100+
.scopeFromProject()
101+
.classes()
102+
.withNameEndingWith("State")
103+
.withoutName(
104+
"CameraPositionState",
105+
)
106+
.constructors
107+
.parameters
108+
.assertTrue { parameterDeclaration ->
109+
parameterDeclaration.defaultValue == null &&
110+
// Using parameterDeclaration.defaultValue == null is not enough apparently,
111+
// Also check that the text does not contain an equal sign
112+
parameterDeclaration.text.contains("=").not()
113+
}
114+
}
115+
116+
@Test
117+
fun `Function which creates Presenter in test MUST be named 'createPresenterName'`() {
118+
Konsist
119+
.scopeFromTest()
120+
.functions()
121+
.withReturnType { it.name.endsWith("Presenter") }
122+
.withoutOverrideModifier()
123+
.assertTrue { functionDeclaration ->
124+
functionDeclaration.name == "create${functionDeclaration.returnType?.name}"
125+
}
126+
}
127+
128+
@Test
129+
fun `no field should have 'm' prefix`() {
130+
Konsist
131+
.scopeFromProject()
132+
.classes()
133+
.properties()
134+
.assertFalse {
135+
val secondCharacterIsUppercase = it.name.getOrNull(1)?.isUpperCase() ?: false
136+
it.name.startsWith('m') && secondCharacterIsUppercase
137+
}
138+
}
139+
}

appnav/src/main/kotlin/io/element/android/appnav/LoggedInEventProcessor.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616

1717
package io.element.android.appnav
1818

19-
import io.element.android.libraries.designsystem.utils.SnackbarDispatcher
20-
import io.element.android.libraries.designsystem.utils.SnackbarMessage
19+
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
20+
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
2121
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
2222
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
2323
import io.element.android.libraries.matrix.api.verification.VerificationFlowState

appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ import io.element.android.libraries.architecture.animation.rememberDefaultTransi
5858
import io.element.android.libraries.architecture.createNode
5959
import io.element.android.libraries.architecture.waitForChildAttached
6060
import io.element.android.libraries.deeplink.DeeplinkData
61-
import io.element.android.libraries.designsystem.utils.SnackbarDispatcher
61+
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
6262
import io.element.android.libraries.di.SessionScope
6363
import io.element.android.libraries.matrix.api.MatrixClient
6464
import io.element.android.libraries.matrix.api.core.MAIN_SPACE

appnav/src/test/kotlin/io/element/android/appnav/RootPresenterTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class RootPresenterTest {
4242

4343
@Test
4444
fun `present - initial state`() = runTest {
45-
val presenter = createPresenter()
45+
val presenter = createRootPresenter()
4646
moleculeFlow(RecompositionMode.Immediate) {
4747
presenter.present()
4848
}.test {
@@ -54,7 +54,7 @@ class RootPresenterTest {
5454

5555
@Test
5656
fun `present - passes app error state`() = runTest {
57-
val presenter = createPresenter(
57+
val presenter = createRootPresenter(
5858
appErrorService = DefaultAppErrorStateService().apply {
5959
showError("Bad news", "Something bad happened")
6060
}
@@ -75,7 +75,7 @@ class RootPresenterTest {
7575
}
7676
}
7777

78-
private fun createPresenter(
78+
private fun createRootPresenter(
7979
appErrorService: AppErrorStateService = DefaultAppErrorStateService()
8080
): RootPresenter {
8181
val crashDataStore = FakeCrashDataStore()

appnav/src/test/kotlin/io/element/android/appnav/loggedin/LoggedInPresenterTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class LoggedInPresenterTest {
4242

4343
@Test
4444
fun `present - initial state`() = runTest {
45-
val presenter = createPresenter()
45+
val presenter = createLoggedInPresenter()
4646
moleculeFlow(RecompositionMode.Immediate) {
4747
presenter.present()
4848
}.test {
@@ -54,7 +54,7 @@ class LoggedInPresenterTest {
5454
@Test
5555
fun `present - show sync spinner`() = runTest {
5656
val roomListService = FakeRoomListService()
57-
val presenter = createPresenter(roomListService, NetworkStatus.Online)
57+
val presenter = createLoggedInPresenter(roomListService, NetworkStatus.Online)
5858
moleculeFlow(RecompositionMode.Immediate) {
5959
presenter.present()
6060
}.test {
@@ -66,7 +66,7 @@ class LoggedInPresenterTest {
6666
}
6767
}
6868

69-
private fun createPresenter(
69+
private fun createLoggedInPresenter(
7070
roomListService: RoomListService = FakeRoomListService(),
7171
networkStatus: NetworkStatus = NetworkStatus.Offline
7272
): LoggedInPresenter {

changelog.d/1526.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add some Konsist tests.

features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleView.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ fun AddPeopleView(
8484

8585
@OptIn(ExperimentalMaterial3Api::class)
8686
@Composable
87-
fun AddPeopleViewTopBar(
87+
private fun AddPeopleViewTopBar(
8888
hasSelectedUsers: Boolean,
8989
modifier: Modifier = Modifier,
9090
onBackPressed: () -> Unit = {},

features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ fun ConfigureRoomView(
181181

182182
@OptIn(ExperimentalMaterial3Api::class)
183183
@Composable
184-
fun ConfigureRoomToolbar(
184+
private fun ConfigureRoomToolbar(
185185
isNextActionEnabled: Boolean,
186186
modifier: Modifier = Modifier,
187187
onBackPressed: () -> Unit = {},
@@ -207,7 +207,7 @@ fun ConfigureRoomToolbar(
207207
}
208208

209209
@Composable
210-
fun RoomNameWithAvatar(
210+
private fun RoomNameWithAvatar(
211211
avatarUri: Uri?,
212212
roomName: String,
213213
modifier: Modifier = Modifier,
@@ -235,7 +235,7 @@ fun RoomNameWithAvatar(
235235
}
236236

237237
@Composable
238-
fun RoomTopic(
238+
private fun RoomTopic(
239239
topic: String,
240240
modifier: Modifier = Modifier,
241241
onTopicChanged: (String) -> Unit = {},
@@ -254,7 +254,7 @@ fun RoomTopic(
254254
}
255255

256256
@Composable
257-
fun RoomPrivacyOptions(
257+
private fun RoomPrivacyOptions(
258258
selected: RoomPrivacy?,
259259
modifier: Modifier = Modifier,
260260
onOptionSelected: (RoomPrivacyItem) -> Unit = {},

features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ fun CreateRoomRootView(
126126

127127
@OptIn(ExperimentalMaterial3Api::class)
128128
@Composable
129-
fun CreateRoomRootViewTopBar(
129+
private fun CreateRoomRootViewTopBar(
130130
modifier: Modifier = Modifier,
131131
onClosePressed: () -> Unit = {},
132132
) {
@@ -148,7 +148,7 @@ fun CreateRoomRootViewTopBar(
148148
}
149149

150150
@Composable
151-
fun CreateRoomActionButtonsList(
151+
private fun CreateRoomActionButtonsList(
152152
state: CreateRoomRootState,
153153
modifier: Modifier = Modifier,
154154
onNewRoomClicked: () -> Unit = {},
@@ -169,7 +169,7 @@ fun CreateRoomActionButtonsList(
169169
}
170170

171171
@Composable
172-
fun CreateRoomActionButton(
172+
private fun CreateRoomActionButton(
173173
@DrawableRes iconRes: Int,
174174
text: String,
175175
modifier: Modifier = Modifier,

features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListState.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ import kotlinx.collections.immutable.ImmutableList
2525
@Immutable
2626
data class InviteListState(
2727
val inviteList: ImmutableList<InviteListInviteSummary>,
28-
val declineConfirmationDialog: InviteDeclineConfirmationDialog = InviteDeclineConfirmationDialog.Hidden,
29-
val acceptedAction: Async<RoomId> = Async.Uninitialized,
30-
val declinedAction: Async<Unit> = Async.Uninitialized,
31-
val eventSink: (InviteListEvents) -> Unit = {}
28+
val declineConfirmationDialog: InviteDeclineConfirmationDialog,
29+
val acceptedAction: Async<RoomId>,
30+
val declinedAction: Async<Unit>,
31+
val eventSink: (InviteListEvents) -> Unit
3232
)
3333

3434
sealed interface InviteDeclineConfirmationDialog {

features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListStateProvider.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ open class InviteListStateProvider : PreviewParameterProvider<InviteListState> {
3939

4040
internal fun aInviteListState() = InviteListState(
4141
inviteList = aInviteListInviteSummaryList(),
42+
declineConfirmationDialog = InviteDeclineConfirmationDialog.Hidden,
43+
acceptedAction = Async.Uninitialized,
44+
declinedAction = Async.Uninitialized,
45+
eventSink = {},
4246
)
4347

4448
internal fun aInviteListInviteSummaryList(): ImmutableList<InviteListInviteSummary> {

features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListView.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ fun InviteListView(
111111

112112
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
113113
@Composable
114-
fun InviteListContent(
114+
private fun InviteListContent(
115115
state: InviteListState,
116116
modifier: Modifier = Modifier,
117117
onBackClicked: () -> Unit = {},

features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/components/InviteSummaryRow.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ internal fun InviteSummaryRow(
7777
}
7878

7979
@Composable
80-
internal fun DefaultInviteSummaryRow(
80+
private fun DefaultInviteSummaryRow(
8181
invite: InviteListInviteSummary,
8282
onAcceptClicked: () -> Unit = {},
8383
onDeclineClicked: () -> Unit = {},

0 commit comments

Comments
 (0)