Skip to content

Do not ignore count variable in PreviewParameterProvider - #133

Merged
sergio-sastre merged 5 commits into
masterfrom
bugfix/preview_parameter_count_ignored
Jun 18, 2026
Merged

Do not ignore count variable in PreviewParameterProvider#133
sergio-sastre merged 5 commits into
masterfrom
bugfix/preview_parameter_count_ignored

Conversation

@sergio-sastre

@sergio-sastre sergio-sastre commented Jun 17, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Preview parameters now honor the provider’s count when generating preview cases, combined with any annotation limit, 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 provided limit.
  • Tests

    • Added coverage for negative counts, counts larger than values size, counts larger than an explicit limit, and counts smaller than an explicit limit.

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

ComposablePreviewWithPreviewParameterMapper now caps the number of generated previews to min(provider.count, annotation.limit), falling back to annotation.limit when no explicit count is set. Four new provider fixture classes and matching @Preview composables are added as test targets, and four new JUnit tests validate the count boundary behaviors.

Changes

Preview Parameter Count Capping

Layer / File(s) Summary
Mapper count capping logic
core/src/main/java/sergio/sastre/composable/preview/scanner/core/preview/mappers/ComposablePreviewWithPreviewParameterMapper.kt
Adds kotlin.math.min import and computes displayedValuesCount = min(count, limit), then applies take(max(0, displayedValuesCount)) to cap the preview value sequence.
Test provider fixtures and preview composables
tests/src/main/java/sergio/sastre/composable/preview/scanner/android/previewparameterscount/Composables.kt
Defines stringValues, four PreviewParameterProvider<String?> subclasses with varying count values, the Example composable, and four grouped @Preview functions using each provider/limit configuration.
JUnit boundary tests
tests/src/test/java/sergio/sastre/composable/preview/scanner/tests/api/main/scanner/AndroidComposablePreviewScannerTest.kt
Imports the four new provider classes and adds four tests asserting correct preview list sizes for negative count, count > values size, count > limit, and count < limit scenarios.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 Hoppity-hop through the preview parade,
Too many values? No worries, I've weighed!
min(count, limit) keeps the list neat and small,
No overflowing sequence—just the right haul.
With four tests to prove it, I thump with delight,
The mapper now counts every preview just right! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: fixing the handling of the count variable in PreviewParameterProvider, which was previously being ignored.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bugfix/preview_parameter_count_ignored

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 1949eb0 and a37966c.

📒 Files selected for processing (3)
  • core/src/main/java/sergio/sastre/composable/preview/scanner/core/preview/mappers/ComposablePreviewWithPreviewParameterMapper.kt
  • tests/src/main/java/sergio/sastre/composable/preview/scanner/android/previewparameterscount/Composables.kt
  • tests/src/test/java/sergio/sastre/composable/preview/scanner/tests/api/main/scanner/AndroidComposablePreviewScannerTest.kt

@sergio-sastre
sergio-sastre force-pushed the bugfix/preview_parameter_count_ignored branch from a37966c to cfa96fb Compare June 17, 2026 19:35

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
core/src/main/java/sergio/sastre/composable/preview/scanner/core/preview/mappers/ComposablePreviewWithPreviewParameterMapper.kt (1)

99-100: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid invoking default count getter before truncation.

Line 99 still eagerly evaluates provider count via reflection. For providers that do not override count, this calls the default getter (values.count()), which can fully traverse (or never finish traversing) a lazy/unbounded sequence before take(...) 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

📥 Commits

Reviewing files that changed from the base of the PR and between cfa96fb and 6a44d72.

⛔ 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.png is excluded by !**/*.png
  • tests/src/test/screenshots/android/sergio.sastre.composable.preview.scanner.android.previewparameterscount.ComposablesKt.ExamplePreviewCountGreaterThanValuesSizeProviderInParameterConstructor.count_>_values_size_String_0.png is excluded by !**/*.png
  • tests/src/test/screenshots/android/sergio.sastre.composable.preview.scanner.android.previewparameterscount.ComposablesKt.ExamplePreviewCountGreaterThanValuesSizeProviderInParameterConstructor.count_>_values_size_String_1.png is excluded by !**/*.png
  • tests/src/test/screenshots/android/sergio.sastre.composable.preview.scanner.android.previewparameterscount.ComposablesKt.ExamplePreviewCountGreaterThanValuesSizeProviderInParameterConstructor.count_>_values_size_String_2.png is excluded by !**/*.png
  • tests/src/test/screenshots/android/sergio.sastre.composable.preview.scanner.android.previewparameterscount.ComposablesKt.ExamplePreviewCountLessThanLimitProviderInParameterConstructor.count_<_limit_and_limit_=_2_String_0.png is excluded by !**/*.png
  • tests/src/test/screenshots/sourceset/sergio.sastre.composable.preview.scanner.android.previewparameterscount.ComposablesKt.ExamplePreviewCountGreaterThanLimitProviderInParameterConstructor.count_>_limit_and_limit_=_1_String_0.png is excluded by !**/*.png
  • tests/src/test/screenshots/sourceset/sergio.sastre.composable.preview.scanner.android.previewparameterscount.ComposablesKt.ExamplePreviewCountGreaterThanValuesSizeProviderInParameterConstructor.count_>_values_size_String_0.png is excluded by !**/*.png
  • tests/src/test/screenshots/sourceset/sergio.sastre.composable.preview.scanner.android.previewparameterscount.ComposablesKt.ExamplePreviewCountGreaterThanValuesSizeProviderInParameterConstructor.count_>_values_size_String_1.png is excluded by !**/*.png
  • tests/src/test/screenshots/sourceset/sergio.sastre.composable.preview.scanner.android.previewparameterscount.ComposablesKt.ExamplePreviewCountGreaterThanValuesSizeProviderInParameterConstructor.count_>_values_size_String_2.png is excluded by !**/*.png
  • tests/src/test/screenshots/sourceset/sergio.sastre.composable.preview.scanner.android.previewparameterscount.ComposablesKt.ExamplePreviewCountLessThanLimitProviderInParameterConstructor.count_<_limit_and_limit_=_2_String_0.png is excluded by !**/*.png
  • tests/src/test/snapshots/images/Paparazzi_Preview_Test_android.previewparameterscount.composableskt.examplepreviewcountgreaterthanlimitproviderinparameterconstructor.count_%3e_limit_and_limit_=_1_string_0.png is excluded by !**/*.png
  • tests/src/test/snapshots/images/Paparazzi_Preview_Test_android.previewparameterscount.composableskt.examplepreviewcountgreaterthanvaluessizeproviderinparameterconstructor.count_%3e_values_size_string_0.png is excluded by !**/*.png
  • tests/src/test/snapshots/images/Paparazzi_Preview_Test_android.previewparameterscount.composableskt.examplepreviewcountgreaterthanvaluessizeproviderinparameterconstructor.count_%3e_values_size_string_1.png is excluded by !**/*.png
  • tests/src/test/snapshots/images/Paparazzi_Preview_Test_android.previewparameterscount.composableskt.examplepreviewcountgreaterthanvaluessizeproviderinparameterconstructor.count_%3e_values_size_string_2.png is excluded by !**/*.png
  • tests/src/test/snapshots/images/Paparazzi_Preview_Test_android.previewparameterscount.composableskt.examplepreviewcountlessthanlimitproviderinparameterconstructor.count_%3c_limit_and_limit_=_2_string_0.png is excluded by !**/*.png
📒 Files selected for processing (1)
  • core/src/main/java/sergio/sastre/composable/preview/scanner/core/preview/mappers/ComposablePreviewWithPreviewParameterMapper.kt

@sergio-sastre
sergio-sastre merged commit 2f4fb2c into master Jun 18, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant