Do not ignore count variable in PreviewParameterProvider - #133
Conversation
Walkthrough
ChangesPreview Parameter Count Capping
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@core/src/main/java/sergio/sastre/composable/preview/scanner/core/preview/mappers/ComposablePreviewWithPreviewParameterMapper.kt`:
- Around line 96-103: In the ComposablePreviewWithPreviewParameterMapper, the
count variable on line 96 eagerly evaluates values.count() as a fallback before
the limit is applied on line 99, which causes premature Sequence traversal and
defeats lazy evaluation. Restructure the logic to avoid calling values.count()
eagerly; instead, apply the limit constraint first by computing
displayedValuesCount as the minimum of the explicitly provided count (defaulting
to Int.MAX_VALUE if not set) and the limit, deferring or eliminating the eager
values.count() call to preserve lazy evaluation for unbounded providers.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: a3d80ad1-d2be-4042-9ebb-1e700982d2da
📒 Files selected for processing (3)
core/src/main/java/sergio/sastre/composable/preview/scanner/core/preview/mappers/ComposablePreviewWithPreviewParameterMapper.kttests/src/main/java/sergio/sastre/composable/preview/scanner/android/previewparameterscount/Composables.kttests/src/test/java/sergio/sastre/composable/preview/scanner/tests/api/main/scanner/AndroidComposablePreviewScannerTest.kt
a37966c to
cfa96fb
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (1)
core/src/main/java/sergio/sastre/composable/preview/scanner/core/preview/mappers/ComposablePreviewWithPreviewParameterMapper.kt (1)
99-100:⚠️ Potential issue | 🟠 Major | ⚡ Quick winAvoid invoking default
countgetter before truncation.Line 99 still eagerly evaluates provider
countvia reflection. For providers that do not overridecount, this calls the default getter (values.count()), which can fully traverse (or never finish traversing) a lazy/unbounded sequence beforetake(...)at Line 106 is applied.Suggested fix
import kotlin.reflect.full.declaredMemberFunctions +import kotlin.reflect.full.declaredMemberProperties import kotlin.reflect.full.memberProperties import kotlin.reflect.full.valueParameters import kotlin.reflect.jvm.isAccessible @@ - val count = getPropertyValue(providerInstance, "count") as? Int - val displayedValuesCount = count?.let { min(it, limit) } ?: limit + val explicitCount = providerInstance::class.declaredMemberProperties + .find { it.name == "count" } + ?.apply { isAccessible = true } + ?.getter + ?.call(providerInstance) as? Int + val displayedValuesCount = explicitCount?.let { min(it, limit) } ?: limit#!/bin/bash # Verify whether count has a default getter that evaluates values.count(), # and whether fixture providers rely on that default or override it. set -euo pipefail echo "== PreviewParameterProvider contract ==" fd -i 'PreviewParameter.kt' --exec sed -n '1,120p' {} echo echo "== Providers in count fixtures (check override val count presence) ==" fd -i 'Composables.kt' --exec sed -n '1,140p' {} echo echo "== Mapper segment under review ==" fd -i 'ComposablePreviewWithPreviewParameterMapper.kt' --exec sed -n '80,130p' {}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@core/src/main/java/sergio/sastre/composable/preview/scanner/core/preview/mappers/ComposablePreviewWithPreviewParameterMapper.kt` around lines 99 - 100, The issue is that line 99 in ComposablePreviewWithPreviewParameterMapper eagerly evaluates the provider's count property via reflection using getPropertyValue, which invokes the default count getter (values.count()) for providers that don't override it, potentially traversing unbounded or lazy sequences before truncation is applied. Instead of retrieving and using count via reflection, directly apply the limit value without pre-fetching the count. Remove the lines that invoke getPropertyValue for count and the displayedValuesCount variable, and use the limit value directly when processing the provider values, allowing the take(...) operation at line 106 to handle truncation without eager evaluation of the full sequence.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In
`@core/src/main/java/sergio/sastre/composable/preview/scanner/core/preview/mappers/ComposablePreviewWithPreviewParameterMapper.kt`:
- Around line 99-100: The issue is that line 99 in
ComposablePreviewWithPreviewParameterMapper eagerly evaluates the provider's
count property via reflection using getPropertyValue, which invokes the default
count getter (values.count()) for providers that don't override it, potentially
traversing unbounded or lazy sequences before truncation is applied. Instead of
retrieving and using count via reflection, directly apply the limit value
without pre-fetching the count. Remove the lines that invoke getPropertyValue
for count and the displayedValuesCount variable, and use the limit value
directly when processing the provider values, allowing the take(...) operation
at line 106 to handle truncation without eager evaluation of the full sequence.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 945a05cf-e7e3-4dbf-bce7-dea39eb59522
⛔ Files ignored due to path filters (15)
tests/src/test/screenshots/android/sergio.sastre.composable.preview.scanner.android.previewparameterscount.ComposablesKt.ExamplePreviewCountGreaterThanLimitProviderInParameterConstructor.count_>_limit_and_limit_=_1_String_0.pngis excluded by!**/*.pngtests/src/test/screenshots/android/sergio.sastre.composable.preview.scanner.android.previewparameterscount.ComposablesKt.ExamplePreviewCountGreaterThanValuesSizeProviderInParameterConstructor.count_>_values_size_String_0.pngis excluded by!**/*.pngtests/src/test/screenshots/android/sergio.sastre.composable.preview.scanner.android.previewparameterscount.ComposablesKt.ExamplePreviewCountGreaterThanValuesSizeProviderInParameterConstructor.count_>_values_size_String_1.pngis excluded by!**/*.pngtests/src/test/screenshots/android/sergio.sastre.composable.preview.scanner.android.previewparameterscount.ComposablesKt.ExamplePreviewCountGreaterThanValuesSizeProviderInParameterConstructor.count_>_values_size_String_2.pngis excluded by!**/*.pngtests/src/test/screenshots/android/sergio.sastre.composable.preview.scanner.android.previewparameterscount.ComposablesKt.ExamplePreviewCountLessThanLimitProviderInParameterConstructor.count_<_limit_and_limit_=_2_String_0.pngis excluded by!**/*.pngtests/src/test/screenshots/sourceset/sergio.sastre.composable.preview.scanner.android.previewparameterscount.ComposablesKt.ExamplePreviewCountGreaterThanLimitProviderInParameterConstructor.count_>_limit_and_limit_=_1_String_0.pngis excluded by!**/*.pngtests/src/test/screenshots/sourceset/sergio.sastre.composable.preview.scanner.android.previewparameterscount.ComposablesKt.ExamplePreviewCountGreaterThanValuesSizeProviderInParameterConstructor.count_>_values_size_String_0.pngis excluded by!**/*.pngtests/src/test/screenshots/sourceset/sergio.sastre.composable.preview.scanner.android.previewparameterscount.ComposablesKt.ExamplePreviewCountGreaterThanValuesSizeProviderInParameterConstructor.count_>_values_size_String_1.pngis excluded by!**/*.pngtests/src/test/screenshots/sourceset/sergio.sastre.composable.preview.scanner.android.previewparameterscount.ComposablesKt.ExamplePreviewCountGreaterThanValuesSizeProviderInParameterConstructor.count_>_values_size_String_2.pngis excluded by!**/*.pngtests/src/test/screenshots/sourceset/sergio.sastre.composable.preview.scanner.android.previewparameterscount.ComposablesKt.ExamplePreviewCountLessThanLimitProviderInParameterConstructor.count_<_limit_and_limit_=_2_String_0.pngis excluded by!**/*.pngtests/src/test/snapshots/images/Paparazzi_Preview_Test_android.previewparameterscount.composableskt.examplepreviewcountgreaterthanlimitproviderinparameterconstructor.count_%3e_limit_and_limit_=_1_string_0.pngis excluded by!**/*.pngtests/src/test/snapshots/images/Paparazzi_Preview_Test_android.previewparameterscount.composableskt.examplepreviewcountgreaterthanvaluessizeproviderinparameterconstructor.count_%3e_values_size_string_0.pngis excluded by!**/*.pngtests/src/test/snapshots/images/Paparazzi_Preview_Test_android.previewparameterscount.composableskt.examplepreviewcountgreaterthanvaluessizeproviderinparameterconstructor.count_%3e_values_size_string_1.pngis excluded by!**/*.pngtests/src/test/snapshots/images/Paparazzi_Preview_Test_android.previewparameterscount.composableskt.examplepreviewcountgreaterthanvaluessizeproviderinparameterconstructor.count_%3e_values_size_string_2.pngis excluded by!**/*.pngtests/src/test/snapshots/images/Paparazzi_Preview_Test_android.previewparameterscount.composableskt.examplepreviewcountlessthanlimitproviderinparameterconstructor.count_%3c_limit_and_limit_=_2_string_0.pngis excluded by!**/*.png
📒 Files selected for processing (1)
core/src/main/java/sergio/sastre/composable/preview/scanner/core/preview/mappers/ComposablePreviewWithPreviewParameterMapper.kt
Summary by CodeRabbit
New Features
countwhen generating preview cases, combined with any annotationlimit, so generated previews are capped to the smaller of the two. Negative counts produce no previews; oversized counts are limited to available values size or the providedlimit.Tests