Skip to content

Commit c4df8b3

Browse files
committed
test: adds test for result entry
1 parent 9e34e5e commit c4df8b3

File tree

10 files changed

+483
-10
lines changed

10 files changed

+483
-10
lines changed

nibel-compiler/src/main/kotlin/nibel/compiler/generator/ComposableGenerator.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import nibel.compiler.template.composableEntryWithNoArgsTemplate
1010
import nibel.compiler.template.composableExternalEntryFactoryTemplate
1111
import nibel.compiler.template.composableInternalEntryFactoryTemplate
1212
import nibel.compiler.template.composableResultInternalEntryFactoryTemplate
13+
import nibel.compiler.template.composableExternalResultEntryFactoryTemplate
1314
import nibel.compiler.template.composableResultEntryWithArgsTemplate
1415
import nibel.compiler.template.composableResultEntryWithNoArgsTemplate
1516

@@ -88,9 +89,14 @@ class ComposableGenerator(
8889
}
8990
}
9091
is ExternalEntryMetadata -> {
91-
// For external entries, we still use the same factory for now
92-
// TODO: Add external result entry factory support if needed
93-
composableEntryFactory
92+
// For external result entries, create result-specific factory
93+
composableExternalResultEntryFactoryTemplate(
94+
composableHolderName = composableHolderName,
95+
destinationQualifiedName = metadata.destinationQualifiedName,
96+
hasArgs = metadata.argsQualifiedName != null,
97+
argsQualifiedName = metadata.argsQualifiedName,
98+
resultQualifiedName = resultQualifiedName,
99+
)
94100
}
95101
}
96102

nibel-compiler/src/main/kotlin/nibel/compiler/template/ComposableEntryFactoryTemplate.kt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,32 @@ fun composableResultInternalEntryFactoryMethodTemplate(
132132
| return entry
133133
| }
134134
""".trimMargin("|")
135+
136+
// External result entry factory template
137+
138+
@Suppress("LongParameterList", "MaxLineLength")
139+
fun composableExternalResultEntryFactoryTemplate(
140+
composableHolderName: String,
141+
destinationQualifiedName: String,
142+
hasArgs: Boolean,
143+
argsQualifiedName: String?,
144+
resultQualifiedName: String,
145+
) = """
146+
| companion object: ComposableEntryFactory<$destinationQualifiedName> {
147+
|
148+
| override fun newInstance(destination: $destinationQualifiedName): ComposableEntry<${if (hasArgs) argsQualifiedName else "*"}> {
149+
| val entry = $composableHolderName(
150+
| ${if (hasArgs) "args = destination.args," else ""}
151+
| name = nibel.runtime.buildRouteName($composableHolderName::class.qualifiedName!!, ${if (hasArgs) "destination.args" else "null"}),
152+
| )
153+
| return entry
154+
| }
155+
${
156+
if (hasArgs) {
157+
composableResultInternalEntryFactoryMethodTemplate(composableHolderName, argsQualifiedName!!, resultQualifiedName)
158+
} else {
159+
composableResultInternalEntryFactoryMethodTemplate(composableHolderName, resultQualifiedName)
160+
}
161+
}
162+
| }
163+
""".trimMargin("|")

tests/build.gradle.kts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,12 @@ android {
1111

1212
dependencies {
1313
ksp(projects.nibelCompiler)
14+
kspTest(projects.nibelCompiler)
15+
implementation(projects.nibelAnnotations)
16+
testImplementation(projects.nibelAnnotations)
1417
implementation(libs.androidx.fragment)
15-
implementation(libs.nibel.runtime)
18+
implementation(projects.nibelRuntime)
19+
testImplementation(projects.nibelRuntime)
1620
implementation(libs.junit)
1721
implementation(libs.kotest.assertions)
1822
}

tests/src/test/kotlin/nibel/tests/codegen/ExternalEntryCompileTest.kt

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,76 @@ import nibel.annotations.DestinationWithNoArgs
88
import nibel.annotations.ImplementationType
99
import nibel.annotations.UiExternalEntry
1010

11+
/**
12+
* Compilation tests for @UiExternalEntry annotation (external entries).
13+
*
14+
* These tests verify that the KSP annotation processor can successfully generate entry classes
15+
* for external (inter-module) navigation targets. External entries are defined in one module
16+
* but can be used from other modules, requiring explicit destination declarations.
17+
*
18+
* Test coverage:
19+
* - Fragment external entries with and without arguments
20+
* - Composable external entries with and without arguments
21+
* - Proper destination class generation and factory methods
22+
* - Cross-module navigation support
23+
*
24+
* The tests pass if the annotated functions compile successfully and generate
25+
* the corresponding Entry classes with proper factory companion objects.
26+
*/
27+
28+
/**
29+
* Destination for Fragment external entry without arguments
30+
*/
1131
object Destination1 : DestinationWithNoArgs
1232

33+
/**
34+
* Tests Fragment-based external entry without arguments.
35+
* Should generate: FragmentExternalEntryWithNoArgsEntry class with factory companion
36+
*/
1337
@UiExternalEntry(ImplementationType.Fragment, Destination1::class)
1438
@Composable
1539
fun FragmentExternalEntryWithNoArgs() = Unit
1640

17-
41+
/**
42+
* Destination for Fragment external entry with arguments
43+
*/
1844
data class Destination2(override val args: TestArgs) : DestinationWithArgs<TestArgs>
1945

46+
/**
47+
* Tests Fragment-based external entry with arguments.
48+
* Should generate: FragmentExternalEntryWithArgsEntry class with factory companion taking TestArgs
49+
*/
2050
@UiExternalEntry(ImplementationType.Fragment, Destination2::class)
2151
@Composable
2252
fun FragmentExternalEntryWithArgs() = Unit
2353

24-
54+
/**
55+
* Destination for Composable external entry without arguments
56+
*/
2557
object Destination3 : DestinationWithNoArgs
2658

59+
/**
60+
* Tests Composable-based external entry without arguments.
61+
* Should generate: ComposableExternalEntryWithNoArgsEntry class extending ComposableEntry<*>
62+
*/
2763
@UiExternalEntry(ImplementationType.Composable, Destination3::class)
2864
@Composable
2965
fun ComposableExternalEntryWithNoArgs() = Unit
3066

31-
67+
/**
68+
* Destination for Composable external entry with arguments
69+
*/
3270
data class Destination4(override val args: TestArgs) : DestinationWithArgs<TestArgs>
3371

72+
/**
73+
* Tests Composable-based external entry with arguments.
74+
* Should generate: ComposableExternalEntryWithArgsEntry class extending ComposableEntry<TestArgs>
75+
*/
3476
@UiExternalEntry(ImplementationType.Composable, Destination4::class)
3577
@Composable
3678
fun ComposableExternalEntryWithArgs() = Unit
3779

38-
80+
/**
81+
* Unused destination for completeness in test coverage
82+
*/
3983
object Destination5 : DestinationWithNoArgs

tests/src/test/kotlin/nibel/tests/codegen/ExternalEntryParamCompileTest.kt

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,35 @@ import nibel.annotations.ImplementationType
99
import nibel.annotations.UiExternalEntry
1010
import nibel.runtime.NavigationController
1111

12+
/**
13+
* Compilation tests for @UiExternalEntry annotation with additional parameters (external entries).
14+
*
15+
* These tests verify that the KSP annotation processor can successfully generate entry classes
16+
* for external entries that have additional Composable function parameters beyond args.
17+
* The processor should properly handle:
18+
* - Navigation controller injection in cross-module scenarios
19+
* - Implementation type parameters for external entries
20+
* - Parameters with default values in external entry contexts
21+
* - Mixed parameter types in generated ComposableContent() calls for external entries
22+
*
23+
* Test coverage:
24+
* - External Fragment/Composable entries with and without args + additional parameters
25+
* - Proper parameter passing in generated ComposableContent() for external entries
26+
* - Cross-module parameter injection and factory method generation
27+
*
28+
* The tests pass if the annotated functions compile successfully and generate
29+
* Entry classes with proper external factory companions that inject additional parameters.
30+
*/
31+
32+
/**
33+
* Destination for Fragment external entry without args but with parameters
34+
*/
1235
object ParamsDestination1 : DestinationWithNoArgs
1336

37+
/**
38+
* Tests Fragment-based external entry without args but with additional parameters.
39+
* Should generate factory companion and proper ComposableContent() with parameter injection
40+
*/
1441
@UiExternalEntry(ImplementationType.Fragment, ParamsDestination1::class)
1542
@Composable
1643
fun FragmentExternalEntryWithNoArgsWithParams(
@@ -19,9 +46,15 @@ fun FragmentExternalEntryWithNoArgsWithParams(
1946
paramWithDefaultValue: String = ""
2047
) = Unit
2148

22-
49+
/**
50+
* Destination for Composable external entry without args but with parameters
51+
*/
2352
object ParamsDestination2 : DestinationWithNoArgs
2453

54+
/**
55+
* Tests Composable-based external entry without args but with additional parameters.
56+
* Should generate factory companion and proper ComposableContent() with parameter injection
57+
*/
2558
@UiExternalEntry(ImplementationType.Composable, ParamsDestination2::class)
2659
@Composable
2760
fun ComposableExternalEntryWithNoArgsWithParams(
@@ -30,9 +63,15 @@ fun ComposableExternalEntryWithNoArgsWithParams(
3063
paramWithDefaultValue: String = ""
3164
) = Unit
3265

33-
66+
/**
67+
* Destination for Fragment external entry with args and parameters
68+
*/
3469
data class ParamsDestination3(override val args: TestArgs) : DestinationWithArgs<TestArgs>
3570

71+
/**
72+
* Tests Fragment-based external entry with args and additional parameters.
73+
* Should generate factory companion and proper ComposableContent() with args and parameter injection
74+
*/
3675
@UiExternalEntry(ImplementationType.Fragment, ParamsDestination3::class)
3776
@Composable
3877
fun FragmentExternalEntryWithArgsWithParams(
@@ -42,8 +81,15 @@ fun FragmentExternalEntryWithArgsWithParams(
4281
paramWithDefaultValue: String = ""
4382
) = Unit
4483

84+
/**
85+
* Destination for Composable external entry with args and parameters
86+
*/
4587
data class ParamsDestination4(override val args: TestArgs) : DestinationWithArgs<TestArgs>
4688

89+
/**
90+
* Tests Composable-based external entry with args and additional parameters.
91+
* Should generate factory companion and proper ComposableContent() with args and parameter injection
92+
*/
4793
@UiExternalEntry(ImplementationType.Composable, ParamsDestination4::class)
4894
@Composable
4995
fun ComposableExternalEntryWithArgsWithParams(

tests/src/test/kotlin/nibel/tests/codegen/InternalEntryCompileTest.kt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,50 @@ import androidx.compose.runtime.Composable
66
import nibel.annotations.ImplementationType
77
import nibel.annotations.UiEntry
88

9+
/**
10+
* Compilation tests for @UiEntry annotation (internal entries).
11+
*
12+
* These tests verify that the KSP annotation processor can successfully generate entry classes
13+
* for internal (intra-module) navigation targets. Internal entries are defined in the same
14+
* module where they are used and don't require external destination declarations.
15+
*
16+
* Test coverage:
17+
* - Fragment entries with and without arguments
18+
* - Composable entries with and without arguments
19+
* - Proper code generation for basic internal entry patterns
20+
*
21+
* The tests pass if the annotated functions compile successfully and generate
22+
* the corresponding Entry classes without compilation errors.
23+
*/
924

25+
/**
26+
* Tests Fragment-based internal entry without arguments.
27+
* Should generate: FragmentEntryWithNoArgsEntry class extending FragmentEntry
28+
*/
1029
@UiEntry(ImplementationType.Fragment)
1130
@Composable
1231
fun FragmentEntryWithNoArgs() = Unit
1332

33+
/**
34+
* Tests Fragment-based internal entry with arguments.
35+
* Should generate: FragmentEntryWithArgsEntry class extending FragmentEntry with TestArgs parameter
36+
*/
1437
@UiEntry(ImplementationType.Fragment, TestArgs::class)
1538
@Composable
1639
fun FragmentEntryWithArgs() = Unit
1740

41+
/**
42+
* Tests Composable-based internal entry without arguments.
43+
* Should generate: ComposableEntryWithNoArgsEntry class extending ComposableEntry<Parcelable>
44+
*/
1845
@UiEntry(ImplementationType.Composable)
1946
@Composable
2047
fun ComposableEntryWithNoArgs() = Unit
2148

49+
/**
50+
* Tests Composable-based internal entry with arguments.
51+
* Should generate: ComposableEntryWithArgsEntry class extending ComposableEntry<TestArgs>
52+
*/
2253
@UiEntry(ImplementationType.Composable, TestArgs::class)
2354
@Composable
2455
fun ComposableEntryWithArgs() = Unit

tests/src/test/kotlin/nibel/tests/codegen/InternalEntryParamCompileTest.kt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,30 @@ import nibel.annotations.ImplementationType
77
import nibel.annotations.UiEntry
88
import nibel.runtime.NavigationController
99

10+
/**
11+
* Compilation tests for @UiEntry annotation with additional parameters (internal entries).
12+
*
13+
* These tests verify that the KSP annotation processor can successfully generate entry classes
14+
* for internal entries that have additional Composable function parameters beyond args.
15+
* The processor should properly handle:
16+
* - Navigation controller injection
17+
* - Implementation type parameters
18+
* - Parameters with default values
19+
* - Mixed parameter types in generated ComposableContent() calls
20+
*
21+
* Test coverage:
22+
* - Fragment/Composable entries with and without args + additional parameters
23+
* - Proper parameter passing in generated ComposableContent() implementations
24+
* - Support for default parameter values
25+
*
26+
* The tests pass if the annotated functions compile successfully and generate
27+
* Entry classes that properly inject the additional parameters.
28+
*/
29+
30+
/**
31+
* Tests Fragment-based internal entry without args but with additional parameters.
32+
* Should generate proper ComposableContent() that provides navigator, type, and default values
33+
*/
1034
@UiEntry(ImplementationType.Fragment)
1135
@Composable
1236
fun FragmentEntryWithNoArgsWithParams(
@@ -15,6 +39,10 @@ fun FragmentEntryWithNoArgsWithParams(
1539
paramWithDefaultValue: String = ""
1640
) = Unit
1741

42+
/**
43+
* Tests Composable-based internal entry without args but with additional parameters.
44+
* Should generate proper ComposableContent() that provides navigator, type, and default values
45+
*/
1846
@UiEntry(ImplementationType.Composable)
1947
@Composable
2048
fun ComposableEntryWithNoArgsWithParams(
@@ -23,6 +51,10 @@ fun ComposableEntryWithNoArgsWithParams(
2351
paramWithDefaultValue: String = ""
2452
) = Unit
2553

54+
/**
55+
* Tests Fragment-based internal entry with args and additional parameters.
56+
* Should generate proper ComposableContent() that provides args, navigator, type, and default values
57+
*/
2658
@UiEntry(ImplementationType.Fragment, TestArgs::class)
2759
@Composable
2860
fun FragmentEntryWithArgsWithParams(
@@ -32,6 +64,10 @@ fun FragmentEntryWithArgsWithParams(
3264
paramWithDefaultValue: String = ""
3365
) = Unit
3466

67+
/**
68+
* Tests Composable-based internal entry with args and additional parameters.
69+
* Should generate proper ComposableContent() that provides args, navigator, type, and default values
70+
*/
3571
@UiEntry(ImplementationType.Composable, TestArgs::class)
3672
@Composable
3773
fun ComposableEntryWithArgsWithParams(

0 commit comments

Comments
 (0)