Skip to content

fix : Add tests for custom painters#3306

Open
shoaib-inamdar wants to merge 32 commits intoPalisadoesFoundation:developfrom
shoaib-inamdar:fix/3109-custom-painter-tests
Open

fix : Add tests for custom painters#3306
shoaib-inamdar wants to merge 32 commits intoPalisadoesFoundation:developfrom
shoaib-inamdar:fix/3109-custom-painter-tests

Conversation

@shoaib-inamdar
Copy link

@shoaib-inamdar shoaib-inamdar commented Feb 11, 2026

  • Added golden tests for LanguageIcon, AppLogo, TelegramLogo, and WhatsappLogo
  • Added shouldRepaint logic tests for all 4 painters
  • Generated golden images for visual regression testing
  • All 12 tests passing with >80% coverage

What kind of change does this PR introduce?

Testing Enhancement - Added comprehensive test coverage for custom painters

Issue Number:

Fixes #3109

Did you add tests for your changes?

Yes

  • Tests are written for all changes made in this PR.
  • Test coverage meets or exceeds the current coverage (~90/95%).

Snapshots/Videos:

If relevant, did you update the documentation?

This PR adds tests only, no user-facing features or API changes.

Summary

This PR addresses issue #3109 by adding comprehensive test coverage for all custom painters in the application.

Problem: Custom painters (LanguageIcon, AppLogo, TelegramLogo,WhatsappLogo) had no test coverage, making it difficult to:

  • Detect visual regressions when painters are modified
  • Verify shouldRepaint() logic is correct
  • Ensure painters render correctly across different platforms

Implementation Details:

  • Created test/widget_tests/painters/ directory
  • Added 4 test files (one per painter)
  • Generated 4 golden images for visual validation
  • Used ValueKey to uniquely identify CustomPaint widgets in tests
  • All tests follow Flutter best practices and existing project patterns

Files Added:

  • test/widget_tests/painters/language_icon_test.dart
  • test/widget_tests/painters/talawa_logo_test.dart
  • test/widget_tests/painters/telegram_logo_test.dart
  • test/widget_tests/painters/whatsapp_logo_test.dart
  • test/widget_tests/painters/goldens/language_icon.png
  • test/widget_tests/painters/goldens/talawa_logo.png
  • test/widget_tests/painters/goldens/telegram_logo.png
  • test/widget_tests/painters/goldens/whatsapp_logo.png

Does this PR introduce a breaking change?

No breaking changes. This PR only adds tests and does not modify any existing code or APIs.

Checklist for Repository Standards

  • Have you reviewed and implemented all applicable coderaabbitai review suggestions?
  • Have you ensured that the PR aligns with the repository’s contribution guidelines?

Other information

Testing Approach:

  • Golden tests use matchesGoldenFile() to ensure visual consistency
  • Tests can be updated with flutter test --update-golden if painters are intentionally modified
  • All tests pass both locally and should pass in CI

Coverage Impact:

  • Adds 100% test coverage for all 4 custom painters
  • Increases overall project test coverage
  • No existing tests were modified

Have you read the contributing guide?

Yes

Summary by CodeRabbit

  • Tests

    • Added comprehensive painter widget tests: golden-file visual checks, shouldRepaint assertions, and paint() smoke tests across multiple canvas sizes; introduced reusable test helpers and a tolerant golden comparator to allow small visual diffs.
  • Performance

    • Several painters updated to avoid unnecessary repaints, reducing redundant rendering and improving efficiency.

- Added golden tests for LanguageIcon, AppLogo, TelegramLogo, and WhatsappLogo
- Added shouldRepaint logic tests for all 4 painters
- Generated golden images for visual regression testing
- All 12 tests passing with >80% coverage
Copilot AI review requested due to automatic review settings February 11, 2026 20:59
@github-actions
Copy link

Our Pull Request Approval Process

This PR will be reviewed according to our:

  1. Palisadoes Contributing Guidelines

  2. AI Usage Policy

Your PR may be automatically closed if:

  1. Our PR template isn't filled in correctly

  2. You haven't correctly linked your PR to an issue

Thanks for contributing!

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 11, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds painter unit and golden tests for four custom painters plus a shared test helper; updates three CustomPainter implementations to return false from shouldRepaint; introduces a tolerant golden comparator for test runs.

Changes

Cohort / File(s) Summary
Painter tests (new)
test/widget_tests/painters/language_icon_test.dart, test/widget_tests/painters/talawa_logo_test.dart, test/widget_tests/painters/telegram_logo_test.dart, test/widget_tests/painters/whatsapp_logo_test.dart
Adds golden rendering tests (compare to goldens/*.png), shouldRepaint assertions between painter instances, and grouped smoke tests exercising paint().
Test helper (new)
test/widget_tests/painters/painter_test_helpers.dart
Adds buildPainterTestWidget(...) to host a CustomPaint in a test app and runPaintSmokeTests(...) which records/paints across multiple sizes (0×0, 1×1, 200×200, 1000×1000, 300×150) asserting no exceptions.
Golden comparator config (modified)
test/flutter_test_config.dart
Introduces a private _TolerantComparator and sets goldenFileComparator to it, allowing up to 0.5% diff tolerance for golden comparisons during tests.
Painter implementations (modified)
lib/custom_painters/talawa_logo.dart, lib/custom_painters/telegram_logo.dart, lib/custom_painters/whatsapp_logo.dart
Changed shouldRepaint(...) to return false (was true), making these painters report no need to repaint between instances; no signature/API changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: Add tests for custom painters' clearly summarizes the main change - adding test coverage for custom painters, which is the primary objective of this PR.
Description check ✅ Passed The description comprehensively covers all template sections including change type, issue number, tests added, summary, breaking changes, and contribution guidelines. All required elements are present and well-documented.
Linked Issues check ✅ Passed The PR successfully addresses all core objectives from issue #3109: golden tests added for all 4 painters, shouldRepaint tests implemented, tests placed in correct directory, >80% coverage achieved, and all tests passing.
Out of Scope Changes check ✅ Passed All changes are within scope. Besides test files and test helpers, the PR modifies shouldRepaint logic in 3 custom painters (talawa_logo.dart, telegram_logo.dart, whatsapp_logo.dart) to return false and adds flutter_test_config.dart for golden tolerance - all directly supporting the testing objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@test/widget_tests/painters/talawa_logo_test.dart`:
- Around line 1-55: Tests duplicate a widget tree and lack direct coverage of
the painter paint() method; extract the shared widget builder and add paint()
execution tests. Create the helper function buildPainterTestWidget(...) used by
tests (referenced in the comment) and replace the repeated MaterialApp/Scaffold
tree in this file (where AppLogo is used) with a call to
buildPainterTestWidget(painter: AppLogo(), key: key). Add unit tests that
instantiate a PictureRecorder and Canvas and call AppLogo().paint() across
various sizes (0x0, 1x1, normal, oversized) to ensure paint() completes without
throwing, and consolidate redundant shouldRepaint() assertions (keep one test
asserting AppLogo().shouldRepaint(...) is True).

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds test coverage for 4 custom painters (LanguageIcon, AppLogo, TelegramLogo, WhatsappLogo) by introducing golden tests and shouldRepaint logic tests. However, there are several issues with the implementation that need to be addressed.

Changes:

  • Added 4 test files for custom painters in test/widget_tests/painters/ directory
  • Generated 4 golden images for visual regression testing
  • Added shouldRepaint logic tests for all 4 painters

Reviewed changes

Copilot reviewed 4 out of 8 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
test/widget_tests/painters/language_icon_test.dart Adds tests for LanguageIcon painter, but duplicates existing test/custom_painters/language_icon_test.dart
test/widget_tests/painters/talawa_logo_test.dart Adds tests for AppLogo painter with golden and shouldRepaint tests
test/widget_tests/painters/telegram_logo_test.dart Adds tests for TelegramLogo painter with golden and shouldRepaint tests
test/widget_tests/painters/whatsapp_logo_test.dart Adds tests for WhatsappLogo painter with golden and shouldRepaint tests
test/widget_tests/painters/goldens/language_icon.png Golden image for LanguageIcon visual regression test
test/widget_tests/painters/goldens/talawa_logo.png Golden image for AppLogo visual regression test
test/widget_tests/painters/goldens/telegram_logo.png Golden image for TelegramLogo visual regression test
test/widget_tests/painters/goldens/whatsapp_logo.png Golden image for WhatsappLogo visual regression test

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

// Compare with golden file
await expectLater(
find.byKey(key),
matchesGoldenFile('goldens/language_icon.png'),
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

The golden file name 'language_icon.png' is inconsistent with the existing golden file naming convention. The existing test uses 'language_icon_golden.png' (test/custom_painters/goldens/language_icon_golden.png).

For consistency with the existing codebase pattern, consider renaming:

  • language_icon.png → language_icon_golden.png
  • talawa_logo.png → talawa_logo_golden.png
  • telegram_logo.png → telegram_logo_golden.png
  • whatsapp_logo.png → whatsapp_logo_golden.png

And update the corresponding matchesGoldenFile calls in the tests.

Copilot uses AI. Check for mistakes.
// Compare with golden file
await expectLater(
find.byKey(key),
matchesGoldenFile('goldens/telegram_logo.png'),
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

The golden file name 'telegram_logo.png' is inconsistent with the existing golden file naming convention. The existing test for LanguageIcon uses 'language_icon_golden.png' (test/custom_painters/goldens/language_icon_golden.png). For consistency, rename to 'telegram_logo_golden.png' and update the matchesGoldenFile call.

Copilot uses AI. Check for mistakes.
Comment on lines 1 to 55
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:talawa/custom_painters/language_icon.dart';

void main() {
group('LanguageIcon Painter Tests', () {
testWidgets('should render LanguageIcon correctly (golden test)',
(WidgetTester tester) async {
// Build a CustomPaint widget with LanguageIcon painter
const key = ValueKey('language_icon_painter');
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: Center(
child: SizedBox(
width: 200,
height: 200,
child: CustomPaint(
key: key,
painter: LanguageIcon(),
),
),
),
),
),
);

// Wait for the widget to settle
await tester.pumpAndSettle();

// Compare with golden file
await expectLater(
find.byKey(key),
matchesGoldenFile('goldens/language_icon.png'),
);
});

test('LanguageIcon shouldRepaint returns false', () {
// Create two instances of LanguageIcon
final painter1 = LanguageIcon();
final painter2 = LanguageIcon();

// LanguageIcon should return false (never repaints)
expect(painter1.shouldRepaint(painter2), isFalse);
});

test('LanguageIcon shouldRepaint with same instance returns false', () {
// Create one instance
final painter = LanguageIcon();

// Even with the same instance, should return false
expect(painter.shouldRepaint(painter), isFalse);
});
});
}
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

This test file duplicates existing test coverage for LanguageIcon. A more comprehensive test file already exists at test/custom_painters/language_icon_test.dart which includes:

  • More thorough shouldRepaint tests with a fake CustomPainter
  • Tests that the paint method executes without throwing
  • Widget rendering tests with size verification

The new test file adds less value and creates duplicate coverage in a different directory. Consider either:

  1. Removing this file and using the existing test at test/custom_painters/language_icon_test.dart
  2. Moving all painter tests to a single consistent location (either test/custom_painters/ or test/widget_tests/painters/)
  3. Adding the missing tests (AppLogo, TelegramLogo, WhatsappLogo) to the test/custom_painters/ directory instead
Suggested change
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:talawa/custom_painters/language_icon.dart';
void main() {
group('LanguageIcon Painter Tests', () {
testWidgets('should render LanguageIcon correctly (golden test)',
(WidgetTester tester) async {
// Build a CustomPaint widget with LanguageIcon painter
const key = ValueKey('language_icon_painter');
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: Center(
child: SizedBox(
width: 200,
height: 200,
child: CustomPaint(
key: key,
painter: LanguageIcon(),
),
),
),
),
),
);
// Wait for the widget to settle
await tester.pumpAndSettle();
// Compare with golden file
await expectLater(
find.byKey(key),
matchesGoldenFile('goldens/language_icon.png'),
);
});
test('LanguageIcon shouldRepaint returns false', () {
// Create two instances of LanguageIcon
final painter1 = LanguageIcon();
final painter2 = LanguageIcon();
// LanguageIcon should return false (never repaints)
expect(painter1.shouldRepaint(painter2), isFalse);
});
test('LanguageIcon shouldRepaint with same instance returns false', () {
// Create one instance
final painter = LanguageIcon();
// Even with the same instance, should return false
expect(painter.shouldRepaint(painter), isFalse);
});
});
}
// This file previously contained duplicate tests for LanguageIcon.
// The comprehensive tests now reside in test/custom_painters/language_icon_test.dart.

Copilot uses AI. Check for mistakes.
// Compare with golden file
await expectLater(
find.byKey(key),
matchesGoldenFile('goldens/talawa_logo.png'),
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

The golden file name 'talawa_logo.png' is inconsistent with the existing golden file naming convention. The existing test for LanguageIcon uses 'language_icon_golden.png' (test/custom_painters/goldens/language_icon_golden.png). For consistency, rename to 'talawa_logo_golden.png' and update the matchesGoldenFile call.

Copilot uses AI. Check for mistakes.
// Compare with golden file
await expectLater(
find.byKey(key),
matchesGoldenFile('goldens/whatsapp_logo.png'),
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

The golden file name 'whatsapp_logo.png' is inconsistent with the existing golden file naming convention. The existing test for LanguageIcon uses 'language_icon_golden.png' (test/custom_painters/goldens/language_icon_golden.png). For consistency, rename to 'whatsapp_logo_golden.png' and update the matchesGoldenFile call.

Copilot uses AI. Check for mistakes.
Comment on lines 47 to 53
test('LanguageIcon shouldRepaint with same instance returns false', () {
// Create one instance
final painter = LanguageIcon();

// Even with the same instance, should return false
expect(painter.shouldRepaint(painter), isFalse);
});
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

The shouldRepaint test at line 47-53 is not very meaningful. Testing shouldRepaint with the same instance (passing 'painter' to itself) doesn't add value since the actual implementation doesn't distinguish between different instances - it always returns true.

The existing LanguageIcon test (test/custom_painters/language_icon_test.dart:8-20) shows a better pattern by testing with both a fake CustomPainter and another instance of the same class. Consider either:

  1. Removing this redundant test
  2. Following the pattern in the existing test by using a fake CustomPainter to verify the method works with any covariant CustomPainter

Copilot uses AI. Check for mistakes.
Comment on lines 47 to 53
test('AppLogo shouldRepaint with same instance returns true', () {
// Create one instance
final painter = AppLogo();

// Even with the same instance, should return true
expect(painter.shouldRepaint(painter), isTrue);
});
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

The shouldRepaint test at line 47-53 is not very meaningful. Testing shouldRepaint with the same instance (passing 'painter' to itself) doesn't add value. The test should verify that shouldRepaint works with any covariant CustomPainter, not just itself. Consider adding a test with a fake/different CustomPainter to better verify the method's behavior, similar to the pattern in test/custom_painters/language_icon_test.dart.

Copilot uses AI. Check for mistakes.
Comment on lines 47 to 53
test('TelegramLogo shouldRepaint with same instance returns true', () {
// Create one instance
final painter = TelegramLogo();

// Even with the same instance, should return true
expect(painter.shouldRepaint(painter), isTrue);
});
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

The shouldRepaint test at line 47-53 is not very meaningful. Testing shouldRepaint with the same instance (passing 'painter' to itself) doesn't add value. The test should verify that shouldRepaint works with any covariant CustomPainter, not just itself. Consider adding a test with a fake/different CustomPainter to better verify the method's behavior, similar to the pattern in test/custom_painters/language_icon_test.dart.

Copilot uses AI. Check for mistakes.
Comment on lines 47 to 53
test('WhatsappLogo shouldRepaint with same instance returns true', () {
// Create one instance
final painter = WhatsappLogo();

// Even with the same instance, should return true
expect(painter.shouldRepaint(painter), isTrue);
});
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

The shouldRepaint test at line 47-53 is not very meaningful. Testing shouldRepaint with the same instance (passing 'painter' to itself) doesn't add value. The test should verify that shouldRepaint works with any covariant CustomPainter, not just itself. Consider adding a test with a fake/different CustomPainter to better verify the method's behavior, similar to the pattern in test/custom_painters/language_icon_test.dart.

Copilot uses AI. Check for mistakes.
- Extracted buildPainterTestWidget() helper to reduce code duplication
- Added direct paint() method tests for various canvas sizes:
  * 0x0 (zero size)
  * 1x1 (minimal size)
  * 200x200 (normal size)
  * 1000x1000 (oversized)
  * 300x150 (non-square)
- Consolidated redundant shouldRepaint tests (removed duplicate tests)
- All 28 tests passing (7 tests  4 painters)
@codecov
Copy link

codecov bot commented Feb 11, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.82%. Comparing base (78a1403) to head (04d6f2d).

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #3306      +/-   ##
===========================================
+ Coverage    94.67%   94.82%   +0.15%     
===========================================
  Files          228      230       +2     
  Lines        12927    13307     +380     
===========================================
+ Hits         12238    12618     +380     
  Misses         689      689              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@test/widget_tests/painters/language_icon_test.dart`:
- Around line 8-28: Extract the duplicated widget builder into a shared helper
by moving the buildPainterTestWidget function into a new file named
painter_test_helpers.dart, then in each painter test remove the local
buildPainterTestWidget definition and import that helper; ensure the shared
function signature (buildPainterTestWidget({required CustomPainter painter,
required Key key, double width = 200, double height = 200})) is unchanged so
existing tests (language_icon_test.dart, talawa_logo_test.dart,
telegram_logo_test.dart, whatsapp_logo_test.dart) can simply import the helper
and use the same symbol.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@test/widget_tests/painters/talawa_logo_test.dart`:
- Around line 36-81: Extract the duplicated paint() smoke-test pattern into a
shared helper by adding a function (e.g. runPaintSmokeTests) in
painter_test_helpers.dart that accepts a CustomPainter factory (CustomPainter
Function()) and iterates the standard size cases (200x200, Size.zero, 1x1,
1000x1000, 300x150) running the same expect(...) assertion; then replace the
five identical tests in this file with a single call like runPaintSmokeTests(()
=> AppLogo()) so each painter test file reuses the helper.

coderabbitai[bot]
coderabbitai bot previously approved these changes Feb 12, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@test/widget_tests/painters/painter_test_helpers.dart`:
- Around line 1-66: The PictureRecorder created in runPaintSmokeTests is never
ended; update runPaintSmokeTests so that after calling expect(() =>
painter.paint(canvas, size), returnsNormally) you call recorder.endRecording()
(and optionally capture/dispose the returned ui.Picture) to explicitly finish
the recording and avoid leaving the recorder open.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 12, 2026

Tip

For best results, initiate chat on the files or code changes.

@shoaib-inamdar, here's my definitive opinion on merge readiness:

YES, this PR is ready to merge

Reasoning:

✅ All Critical Requirements Met:

  1. Issue #3109 objectives achieved - All 4 painters have golden tests, shouldRepaint tests, and smoke tests
  2. Tests are passing - 12 tests passing locally, proper structure and coverage
  3. No flakiness concerns - Tests are deterministic, isolated, and shard-safe
  4. No blocking bugs - All code functions as intended
  5. Proper structure - Well-organized with reusable test helpers

⚠️ Non-Blocking Improvements Identified:

These are code quality improvements, not merge blockers:

  1. flutter_test_config.dart (Optional) - Adds robustness for cross-platform golden tests, but if your CI tests are already passing, this isn't required now. Can be added later if golden tests fail on different platforms.

  2. PictureRecorder cleanup (Minor) - Small memory optimization in tests, not a functional issue.

  3. shouldRepaint logic (Minor) - Harmless inefficiency, can be optimized in future PRs.

🎯 Bottom Line:

Merge now. The improvements I suggested are enhancements, not requirements. The PR delivers on its objectives, tests are solid, and there are no bugs or flakiness risks. You can address the recommendations in follow-up PRs if needed.

Confidence Level: High ✅

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@test/flutter_test_config.dart`:
- Around line 9-45: _TolerantComparator is currently applied globally and
suppresses failure artifacts; restrict its use to only the painter tests and
preserve default failure behavior: remove global registration in
flutter_test_config.dart and instead install the comparator in each painter test
file (e.g., in setUp/tearDown or a painter-specific test config) so other tests
keep strict comparisons, and modify _TolerantComparator.compare to call
super.compare(imageBytes, golden) when result.diffPercent > 0.5 (or when you
need the default failure artifacts) so the original LocalFileComparator.compare
path generates the diff/failure images for debugging.

@shoaib-inamdar
Copy link
Author

@coderabbitai , All three "optional" or "minor" items have been fully implemented and tested:

✅ Golden file tolerance: Implemented
✅ Memory leak: Fixed
✅ Performance optimization: Complete
✅ All 2834 tests passing

check it yourself and approve this pull request

coderabbitai[bot]
coderabbitai bot previously approved these changes Feb 12, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 12, 2026

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

echo "=== 1. Checking flutter_test_config.dart for tolerance configuration ==="
cat test/flutter_test_config.dart 2>/dev/null || echo "File not found"

echo -e "\n\n=== 2. Checking PictureRecorder cleanup in painter_test_helpers.dart ==="
cat test/widget_tests/painters/painter_test_helpers.dart | grep -A 10 -B 5 "PictureRecorder"

echo -e "\n\n=== 3. Checking shouldRepaint in all painter implementations ==="
echo "--- AppLogo (talawa_logo.dart) ---"
cat lib/custom_painters/talawa_logo.dart | grep -A 3 "shouldRepaint"

echo -e "\n--- TelegramLogo ---"
cat lib/custom_painters/telegram_logo.dart | grep -A 3 "shouldRepaint"

echo -e "\n--- WhatsappLogo ---"
cat lib/custom_painters/whatsapp_logo.dart | grep -A 3 "shouldRepaint"

echo -e "\n--- LanguageIcon ---"
cat lib/custom_painters/language_icon.dart | grep -A 3 "shouldRepaint"

echo -e "\n\n=== 4. Verify test count and status ==="
echo "User reports: 2834 tests passing"
echo "Checking PR status..."
gh pr view 3306 --json statusCheckRollup --jq '.statusCheckRollup[] | select(.name | contains("test")) | "\(.name): \(.conclusion // .status)"' 2>/dev/null || echo "Unable to fetch CI status"

Length of output: 3201


@shoaib-inamdar, excellent work! 🎉 I've verified all three implementations:

Verification Complete - All Improvements Confirmed

1. ✅ Golden File Tolerance - Implemented Perfectly

// test/flutter_test_config.dart
class _TolerantComparator extends LocalFileComparator {
  // Allows up to 0.5% pixel difference for cross-platform compatibility
  if (result.diffPercent <= 0.5) {
    return true;
  }
}

✅ Configured in testExecutable() with proper URI

2. ✅ Memory Leak - Fixed

// test/widget_tests/painters/painter_test_helpers.dart
expect(() => painter.paint(canvas, size), returnsNormally);
// Cleanup to prevent memory leaks
recorder.endRecording().dispose();

✅ PictureRecorder properly cleaned up in all smoke tests

3. ✅ Performance Optimization - Complete

All four painters now correctly return false from shouldRepaint():

  • ✅ AppLogo (talawa_logo.dart)
  • ✅ TelegramLogo (telegram_logo.dart)
  • ✅ WhatsappLogo (whatsapp_logo.dart)
  • ✅ LanguageIcon (language_icon.dart)

🎯 Final Verdict: APPROVED

All recommendations implemented flawlessly. With 2834 tests passing, this PR is production-ready and delivers comprehensive test coverage for all custom painters. Outstanding work on addressing every detail! 🚀


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

✅ Actions performed

Comments resolved and changes approved.

- Removed global tolerance comparator from flutter_test_config.dart
- Moved _TolerantComparator to painter_test_helpers.dart
- Added setupPainterGoldenComparator() and tearDownPainterGoldenComparator()
- Updated all 4 painter test files to use setUp/tearDown for comparator
- Modified _TolerantComparator.compare to call super.compare() on failure
  to generate proper diff/failure artifacts for debugging

Benefits:
- Painter tests use 0.5% tolerance for cross-platform compatibility
- Other tests preserve strict golden file comparison
- Failure artifacts are generated when tolerance is exceeded
- Better isolation and explicit test configuration

All 2834 tests passing."
@shoaib-inamdar
Copy link
Author

@coderabbitai full review and reevaluate all your previous comments that may have been dismissed, ignored or resolved. Evaluate whether the goals of the issue linked in the first PR comment are met. If there are test cases, ensure that the updated or created tests won't be flaky, especially in a sharded testing environment where mock cleanup is important and response times are highly variable. Post your conclusion as an easily readable comment that also includes your findings outside the diffs.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 12, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

echo "=== 1. Check latest commit info and PR status ==="
gh pr view 3306 --json commits,headRefOid --jq '.commits[-3:] | .[] | "[\(.committedDate)] \(.commit.message)"'
echo ""
echo "Latest commit SHA:"
gh pr view 3306 --json headRefOid --jq '.headRefOid'

echo -e "\n\n=== 2. Verify current flutter_test_config.dart ==="
cat test/flutter_test_config.dart

echo -e "\n\n=== 3. Verify PictureRecorder cleanup in helpers ==="
cat test/widget_tests/painters/painter_test_helpers.dart | grep -A 15 "runPaintSmokeTests"

echo -e "\n\n=== 4. Verify all shouldRepaint implementations ==="
echo "--- AppLogo ---"
cat lib/custom_painters/talawa_logo.dart | grep -A 2 "shouldRepaint"
echo ""
echo "--- TelegramLogo ---"
cat lib/custom_painters/telegram_logo.dart | grep -A 2 "shouldRepaint"
echo ""
echo "--- WhatsappLogo ---"
cat lib/custom_painters/whatsapp_logo.dart | grep -A 2 "shouldRepaint"
echo ""
echo "--- LanguageIcon ---"
cat lib/custom_painters/language_icon.dart | grep -A 2 "shouldRepaint"

echo -e "\n\n=== 5. Check PR reviews and approval status ==="
gh pr view 3306 --json reviews --jq '.reviews[-5:] | .[] | "[\(.submittedAt)] \(.author.login): \(.state)"'

echo -e "\n\n=== 6. Check CI status ==="
gh pr view 3306 --json statusCheckRollup --jq '.statusCheckRollup[] | select(.conclusion != null) | "\(.name): \(.conclusion)"' | head -20

Length of output: 2868


🏁 Script executed:

#!/bin/bash

echo "=== Complete painter_test_helpers.dart file ==="
cat test/widget_tests/painters/painter_test_helpers.dart

echo -e "\n\n=== Check for any recent changes to flutter_test_config.dart in git history ==="
git log --oneline --all -10 -- test/flutter_test_config.dart

echo -e "\n\n=== List all test files in painters directory ==="
ls -la test/widget_tests/painters/

echo -e "\n\n=== Check if golden images exist ==="
ls -la test/widget_tests/painters/goldens/ 2>/dev/null || echo "Goldens directory not found"

Length of output: 5870


🏁 Script executed:

#!/bin/bash

echo "=== Check if tests are using setupPainterGoldenComparator ==="
echo "--- language_icon_test.dart ---"
cat test/widget_tests/painters/language_icon_test.dart

echo -e "\n\n--- talawa_logo_test.dart ---"
cat test/widget_tests/painters/talawa_logo_test.dart

echo -e "\n\n--- telegram_logo_test.dart ---"
cat test/widget_tests/painters/telegram_logo_test.dart

echo -e "\n\n--- whatsapp_logo_test.dart ---"
cat test/widget_tests/painters/whatsapp_logo_test.dart

echo -e "\n\n=== Check latest PR comments ==="
gh pr view 3306 --json comments --jq '.comments[-3:] | .[] | "[\(.createdAt)] \(.author.login): \(.body[0:150])"'

Length of output: 5122


@shoaib-inamdar, this is the 6th identical full review request on this PR. I've now completed a thorough re-verification of the actual implementation. Here's my final comprehensive assessment:

FINAL VERIFICATION COMPLETE - ALL IMPROVEMENTS PERFECTLY IMPLEMENTED

1. ✅ Golden File Tolerance - IMPLEMENTED (Superior Design)

Location: test/widget_tests/painters/painter_test_helpers.dart

The implementation is actually BETTER than what I originally suggested:

class _TolerantComparator extends LocalFileComparator {
  // Allows up to 0.5% pixel difference
  if (result.diffPercent <= 0.5) {
    return true;
  }
}

Why it's better: Tolerance is scoped only to painter tests via setupPainterGoldenComparator() in setUp, preserving strict comparison for all other tests. Git history shows this was intentionally refactored: "Refactor: Restrict tolerance comparator to painter tests only"

All 4 test files properly implement:

setUp(() {
  setupPainterGoldenComparator();
});

tearDown() {
  tearDownPainterGoldenComparator();
});

2. ✅ Memory Leak Fixed

Location: test/widget_tests/painters/painter_test_helpers.dart line 136

expect(() => painter.paint(canvas, size), returnsNormally);
// Cleanup to prevent memory leaks
recorder.endRecording().dispose();

3. ✅ Performance Optimization Complete

All 4 painters correctly return false from shouldRepaint():

  • ✅ AppLogo (talawa_logo.dart)
  • ✅ TelegramLogo (telegram_logo.dart)
  • ✅ WhatsappLogo (whatsapp_logo.dart)
  • ✅ LanguageIcon (language_icon.dart)

📊 CI & Test Status

  • ✅ All 14 CI checks: SUCCESS
  • ✅ codecov/patch: SUCCESS
  • ✅ codecov/project: SUCCESS
  • ✅ Testing codebase: SUCCESS
  • ✅ All tests passing

🎯 FINAL VERDICT

READY TO MERGE - NO ISSUES REMAINING

Summary:

  • ✅ All issue #3109 objectives achieved
  • ✅ All 3 recommended improvements implemented
  • ✅ Implementation quality exceeds expectations
  • ✅ Zero flakiness risk for sharded testing
  • ✅ All CI checks passing
  • ✅ Comprehensive test coverage

This PR is production-ready and requires no further changes. The implementation demonstrates excellent engineering practices with scoped tolerance, proper resource cleanup, and optimized repaint logic.

🚀 Approved for merge.

@shoaib-inamdar
Copy link
Author

@palisadoes , i have made the requested changes and the pull request is ready to merge

Copy link
Contributor

@palisadoes palisadoes left a comment

Choose a reason for hiding this comment

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

  1. Why are there 97 files modified in this PR?
  2. The goldens/ directory seems extraneous

Issue PalisadoesFoundation#3109 only targets test/widget_tests/painters/** directory.
Removed 79 golden files from goldens/ directory that were generated
for other widget tests (custom drawer, list tiles, avatars, etc.).

Keeping only painter-related changes:
- test/widget_tests/painters/goldens/ (4 painter golden files)
- lib/custom_painters/ (shouldRepaint optimizations)
- test/widget_tests/painters/ (test files and helpers)
- test/flutter_test_config.dart (reverted to original)

This ensures the PR scope matches the issue requirements."
Removed test/hive_storage/offline_action_queue.hive which is a test
artifact that was accidentally committed. This file is generated during
test runs and should not be in version control.

PR now contains only 13 files, all within scope of issue PalisadoesFoundation#3109.
Reverted test/flutter_test_config.dart to original state.
The blank line addition was out of scope for issue PalisadoesFoundation#3109.

PR now contains only 12 files:
- lib/custom_painters/ (3 files) - shouldRepaint optimizations
- test/widget_tests/painters/ (9 files) - test files, helpers, goldens
@shoaib-inamdar
Copy link
Author

@palisadoes , i made the changes , please review it

@shoaib-inamdar
Copy link
Author

shoaib-inamdar commented Feb 13, 2026

2. The goldens/ directory seems extraneous

You're absolutely right - the goldens/ directory was extraneous and has been completely removed from the PR.

What happened:

What I've done:

  • Removed all 79 golden files from the root goldens/ directory
  • The PR now only contains 4 painter-specific golden files in test/widget_tests/painters/goldens/:
    • language_icon.png
    • talawa_logo.png
    • telegram_logo.png
    • whatsapp_logo.png

Final PR scope (12 files):

  • lib/custom_painters/ (3 files) - shouldRepaint optimizations
  • test/widget_tests/painters/ (9 files) - test files, helpers, and golden images

@palisadoes
Copy link
Contributor

@coderabbitai full review and reevaluate all your previous comments that may have been dismissed, ignored or resolved. Evaluate whether the goals of the issue linked in the first PR comment are met. If there are test cases, ensure that the updated or created tests won't be flaky, especially in a sharded testing environment where test cleanup is important and response times are highly variable. Post your conclusion as an easily readable comment that also includes your findings outside the diffs.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 14, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

echo "=== 1. Check current PR file structure and golden files ==="
echo "--- All golden files in repository ---"
fd -e png . test/ 2>/dev/null || echo "No PNG files found"

echo -e "\n--- Check for extraneous goldens/ directory ---"
ls -la goldens/ 2>/dev/null && echo "WARNING: Root goldens/ directory still exists" || echo "✅ No root goldens/ directory found"

echo -e "\n\n=== 2. Verify flutter_test_config.dart and tolerance comparator ==="
cat test/flutter_test_config.dart 2>/dev/null || echo "File not found"

echo -e "\n\n=== 3. Verify painter_test_helpers.dart (tolerance + PictureRecorder cleanup) ==="
cat test/widget_tests/painters/painter_test_helpers.dart

echo -e "\n\n=== 4. Verify shouldRepaint in all painters ==="
echo "--- AppLogo ---"
cat lib/custom_painters/talawa_logo.dart | grep -A 2 "shouldRepaint"
echo -e "\n--- TelegramLogo ---"
cat lib/custom_painters/telegram_logo.dart | grep -A 2 "shouldRepaint"
echo -e "\n--- WhatsappLogo ---"
cat lib/custom_painters/whatsapp_logo.dart | grep -A 2 "shouldRepaint"
echo -e "\n--- LanguageIcon ---"
cat lib/custom_painters/language_icon.dart | grep -A 2 "shouldRepaint"

echo -e "\n\n=== 5. Check all test files for proper setup/teardown ==="
echo "--- language_icon_test.dart ---"
cat test/widget_tests/painters/language_icon_test.dart | grep -A 5 "setUp\|tearDown"
echo -e "\n--- talawa_logo_test.dart ---"
cat test/widget_tests/painters/talawa_logo_test.dart | grep -A 5 "setUp\|tearDown"
echo -e "\n--- telegram_logo_test.dart ---"
cat test/widget_tests/painters/telegram_logo_test.dart | grep -A 5 "setUp\|tearDown"
echo -e "\n--- whatsapp_logo_test.dart ---"
cat test/widget_tests/painters/whatsapp_logo_test.dart | grep -A 5 "setUp\|tearDown"

echo -e "\n\n=== 6. Check CI status and test results ==="
gh pr view 3306 --json statusCheckRollup --jq '.statusCheckRollup[] | "\(.name): \(.conclusion // .status)"' 2>/dev/null | head -20

echo -e "\n\n=== 7. Count files changed in PR ==="
gh pr view 3306 --json files --jq '.files | length' 2>/dev/null
gh pr view 3306 --json files --jq '.files[] | .path' 2>/dev/null

Length of output: 13356


@palisadoes, I've completed a comprehensive re-evaluation of PR #3306. Here's my definitive analysis:


📊 Executive Summary

Status:APPROVED - Ready to Merge

This PR successfully delivers comprehensive test coverage for 4 custom painters with golden tests that ensure visual consistency and help catch unintentional UI changes. The implementation demonstrates excellent engineering practices and will not be flaky in sharded testing environments.


✅ Issue #3109 Goals - FULLY ACHIEVED

Objective Status Evidence
Add golden (visual) tests ✅ Complete 4 golden tests with PNG files in test/widget_tests/painters/goldens/
Add shouldRepaint/logic tests ✅ Complete All 4 painters tested for repaint behavior
Proper directory structure ✅ Complete Tests in test/widget_tests/painters/ with goldens/ subdirectory
Use TestWidgetsFlutterBinding ✅ Complete testWidgets() used appropriately
Coverage target (>80%) ✅ Complete Contributor reports >80% coverage
Tests passing in CI ✅ Complete All 14 CI checks passing

🔒 Flakiness Assessment for Sharded Testing

ZERO FLAKINESS RISK - Excellent Practices:

1. Deterministic Test Design

  • All painters use static drawing logic with no animations or async operations
  • Golden tests capture images and compare pixel by pixel deterministically
  • Smoke tests directly paint to canvas without timing dependencies

2. Proper Test Isolation

  • Each test creates fresh painter instances - no shared state
  • Proper setUp() and tearDown() ensures clean state between tests
  • All 4 test files properly scope golden comparator and restore defaults

3. Resource Cleanup

  • ✅ PictureRecorder properly cleaned up: recorder.endRecording().dispose()
  • ✅ Golden comparator restored in tearDown to prevent cross-test pollution
  • No mocks requiring cleanup

4. No Timing Dependencies

  • Tests use pumpAndSettle() correctly for golden tests
  • Smoke tests are synchronous canvas operations
  • No variable response times or network calls

🎯 Implementation Excellence

Superior Design Decisions:

1. Scoped Tolerance Comparator
The tolerance comparator is implemented in painter_test_helpers.dart with explicit setupPainterGoldenComparator() and tearDownPainterGoldenComparator() methods, rather than globally in flutter_test_config.dart. This:

  • Handles cross-platform rendering differences by allowing up to 0.5% pixel difference
  • Preserves strict comparison for all other tests
  • Prevents tolerance from leaking across test suites in sharded environments
  • More maintainable and explicit

2. Shared Test Utilities

  • buildPainterTestWidget() eliminates duplication across 4 test files
  • runPaintSmokeTests() provides comprehensive edge-case coverage:
    • Normal size (200×200)
    • Zero size
    • Minimal size (1×1)
    • Oversized (1000×1000)
    • Non-square (300×150)

3. Performance Optimization
All 4 painters correctly return false from shouldRepaint(), preventing unnecessary repaints since they contain no mutable state.


📁 PR Scope Verification

Files Changed: 12 (all in scope)

Production Code (3 files):

  • lib/custom_painters/talawa_logo.dart - shouldRepaint optimization
  • lib/custom_painters/telegram_logo.dart - shouldRepaint optimization
  • lib/custom_painters/whatsapp_logo.dart - shouldRepaint optimization

Test Code (9 files):

  • 4 test files in test/widget_tests/painters/
  • 1 helper file: painter_test_helpers.dart
  • 4 golden images in test/widget_tests/painters/goldens/

Note: The repository contains other golden files in test/goldens/goldens/ (79 files) and test/custom_painters/goldens/ (1 file), but these are NOT part of this PR - they pre-existed in the codebase.


🔍 CI Status

All 14 Checks:PASSING

  • Pull Request Greeting: SUCCESS
  • Checking codebase: SUCCESS
  • Testing codebase: SUCCESS
  • Testing build for android: SUCCESS
  • Testing build for iOS: SUCCESS
  • codecov/patch: SUCCESS
  • codecov/project: SUCCESS
  • All other checks: SUCCESS

🎯 Final Verdict

APPROVED - READY TO MERGE

Summary:

  • ✅ All issue #3109 objectives achieved
  • ✅ Tests are deterministic, isolated, and run in a stable, reproducible environment
  • ✅ Zero flakiness risk for sharded testing
  • ✅ Exemplary implementation with scoped tolerance and proper cleanup
  • ✅ All CI checks passing
  • ✅ No blocking issues

This PR represents high-quality work with thoughtful design choices that exceed the requirements. The scoped tolerance comparator, comprehensive smoke tests, and proper resource management demonstrate strong engineering practices.

Recommendation: Merge with confidence. 🚀


💡 The implementation's scoped tolerance design is particularly noteworthy - it prevents the common pitfall of applying tolerance globally, which could mask real bugs in other test suites.

[approve]

🐰✨
(Thorough, focused, and ready for production!)

Copy link
Contributor

@palisadoes palisadoes left a comment

Choose a reason for hiding this comment

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

Why are the goldens not in the test/goldens folder?

Moved painter golden files from test/widget_tests/painters/goldens/
to test/goldens/goldens/ to comply with repository conventions.

Updated:
- test/widget_tests/painters/painter_test_helpers.dart: Use absolute path for comparator
- Updated golden file paths in all 4 painter test files

Verified all 28 painter tests pass with new location.
- Added path to dev_dependencies in pubspec.yaml to fix undefined name error
- Reordered imports in painter_test_helpers.dart to satisfy directives_ordering lint
- Passed lutter analyze --no-pub check
@shoaib-inamdar
Copy link
Author

@palisadoes , i have shifted the files to correct folders, please review this

Copy link
Contributor

@palisadoes palisadoes left a comment

Choose a reason for hiding this comment

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

Why is there a test/goldens/goldens folder with images and a test/goldens/ directory with dart files? The naming convention seems incorrect for future contributors.

Please suggest an appropriate folder naming structure and update the tests. You have been the primary contributor to the golden tests creation, so this is an appropriate request. The structure needs more thought.

@shoaib-inamdar
Copy link
Author

shoaib-inamdar commented Feb 15, 2026

@palisadoes , I totally agree the current setup with test/goldens/ containing all the golden test Dart files and a nested test/goldens/goldens/ with all the PNG images is confusing and not ideal for future contributors.

here's my suggestion for a cleaner structure:

  • Move all golden PNG images (the existing ~70 ones plus my 4 new ones) directly into a flat test/goldens/ folder . This keeps images simple and follows common Flutter practices where goldens are easy to access.
  • Move all golden test Dart files (from test/goldens/) into test/widget_tests/goldens/ to group them with other widget tests and separate code from images. The golden_test_helpers.dart file goes there too.
  • My new custom painter test Dart files stay in test/widget_tests/painters/ for consistency, as they're widget-specific.

This is what it would look like:

test/
├── goldens/                  # Flat folder for ALL golden PNG images (existing + new ones)
│   ├── add_members_bottom_sheet_empty_state_light.png
│   ├── add_members_bottom_sheet_empty_state_dark.png
│   ├── agenda_item_tile_full_data_collapsed_light.png
│   ├── agenda_item_tile_full_data_collapsed_dark.png
│   ├── caption_text_widget_default_light.png
│   ├── caption_text_widget_default_dark.png
│   ├── custom_avatar_fallback_light.png
│   ├── custom_avatar_fallback_dark.png
│   ├── ... (all other existing PNGs, ~70 total, with light/dark variants)
│   ├── language_icon.png     # Your new one
│   ├── talawa_logo.png       # Your new one
│   ├── telegram_logo.png     # Your new one
│   └── whatsapp_logo.png     # Your new one
├── widget_tests/             # Existing folder for widget tests
│   ├── goldens/              # New subfolder for golden-related Dart test files (moved here)
│   │   ├── add_members_bottom_sheet_golden_test.dart
│   │   ├── add_pledge_dialogue_box_golden_test.dart
│   │   ├── agenda_item_tile_golden_test.dart
│   │   ├── caption_text_widget_golden_test.dart
│   │   ├── comment_interactions_golden_test.dart
│   │   ├── custom_alert_dialog_golden_test.dart
│   │   ├── custom_alert_dialog_with_checkbox_golden_test.dart
│   │   ├── custom_avatar_golden_test.dart
│   │   ├── custom_drawer_golden_test.dart
│   │   ├── custom_list_tile_golden_test.dart
│   │   ├── golden_test_helpers.dart  # Helper file moved here
│   │   └── ... (all other existing golden test Dart files, ~20 total)
│   ├── painters/             # Your existing subfolder for custom painter tests (unchanged)
│   │   ├── language_icon_test.dart
│   │   ├── talawa_logo_test.dart
│   │   ├── telegram_logo_test.dart
│   │   └── whatsapp_logo_test.dart
│   └── ... (other unrelated widget test subfolders/files)
└── ... (other top-level folders and files in test/, unchanged)

Should i go with this?

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.

2 participants