Skip to content

Conversation

yuto-trd
Copy link
Member

@yuto-trd yuto-trd commented Sep 14, 2025

This PR adds unit tests covering Beutl.Configuration and preferences logic.

Changes:

  • DefaultPreferences: set/get/remove/clear, persistence, invalid JSON handling, unsupported type exceptions.
  • ViewConfig: recent files/projects ordering, window size/position round-trip, ConfigurationChanged events.
  • GlobalConfiguration: save format verification, auto-save on sub-config change.
  • ExtensionConfig: serialize/deserialize editor extension map and decoder priority.
  • FontConfig: directory synchronization on deserialize.
  • TelemetryConfig & BackupConfig: ConfigurationChanged events.
  • EditorConfig: LibraryTabDisplayModes round-trip.

Project file:

  • tests/Beutl.UnitTests/Beutl.UnitTests.csproj: add project reference to Beutl.Configuration.

Notes:

  • Tests write artifacts only under tests/Artifacts via ArtifactProvider.
  • Locally ran filtered tests: 15/15 passed.

No production code changed.

- Add tests for DefaultPreferences
- Add ViewConfig serialization and events tests
- Add GlobalConfiguration save/auto-save tests
- Add ExtensionConfig, FontConfig tests
- Add TelemetryConfig/BackupConfig event tests
- Add EditorConfig serialization tests

These improve coverage for settings/serialization and event propagation.
@Copilot Copilot AI review requested due to automatic review settings September 14, 2025 14:04
Copy link
Contributor

@Copilot 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 comprehensive unit tests for the Beutl.Configuration module to improve test coverage and validate configuration functionality.

  • Adds unit tests for all major configuration classes including DefaultPreferences, ViewConfig, GlobalConfiguration, and specialized configs
  • Tests cover serialization/deserialization, event handling, persistence, and error scenarios
  • Adds project reference to Beutl.Configuration to enable testing

Reviewed Changes

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

Show a summary per file
File Description
tests/Beutl.UnitTests/Configuration/ViewConfigTests.cs Tests for ViewConfig recent files/projects management and window state serialization
tests/Beutl.UnitTests/Configuration/TelemetryAndBackupConfigTests.cs Tests for ConfigurationChanged event handling in TelemetryConfig and BackupConfig
tests/Beutl.UnitTests/Configuration/GlobalConfigurationTests.cs Tests for GlobalConfiguration save functionality and auto-save behavior
tests/Beutl.UnitTests/Configuration/FontConfigTests.cs Tests for FontConfig directory synchronization during deserialization
tests/Beutl.UnitTests/Configuration/ExtensionConfigTests.cs Tests for ExtensionConfig serialization/deserialization of editor extensions and decoder priority
tests/Beutl.UnitTests/Configuration/EditorConfigTests.cs Tests for EditorConfig LibraryTabDisplayModes serialization round-trip
tests/Beutl.UnitTests/Configuration/DefaultPreferencesTests.cs Tests for DefaultPreferences CRUD operations, persistence, and error handling
tests/Beutl.UnitTests/Beutl.UnitTests.csproj Adds project reference to Beutl.Configuration

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

- TypeFormat round-trip (non-generic) and global-namespace type
- BeutlEnvironment paths and BEUTL_HOME behavior
- Preferences.Default uses BEUTL_HOME and persists
- FFmpeg extension settings raise ConfigurationChanged via AffectsConfig

Also reference Extensibility and FFmpeg extension in test project.
- NotAutoSerialized exclusion in CoreObject serialization
- Property-level JsonConverter path exercised with custom converter
- Default override via CoreProperty.OverrideDefaultValue in derived type
- Hierarchical attachment/detachment events from BeutlApplication and Project items
- JsonSerializationContext collection (IDictionary/arrays) round-trips
- JsonDeepClone produces independent copies

Note: Removed a flaky DataAnnotations validation check; will revisit with Rational-based validator later.
- CoreObjectExtensions: GetObservable, GetPropertyChangedObservable, FindById
- RecordableCommands: Create/Append/ToCommand/WithStoables

Ran coverage; small overall increase (repo is large).
@b-editor b-editor deleted a comment from claude bot Sep 15, 2025
@b-editor b-editor deleted a comment from claude bot Sep 15, 2025
@b-editor b-editor deleted a comment from claude bot Sep 15, 2025
- LibraryRegistrar: ensure registration wiring for Source/Drawable/Effects and FindItem
- EnumExtensions: HasAllFlags/HasAnyFlag across underlying sizes
- CultureNameValidation: basic valid/invalid culture names
- CorePropertyJsonConverter: round-trip by name and owner
- HierarchicalExtensions: find root/parent and enumerate children
- ProjectItemContainer: TryGetOrCreateItem cache, restore-on-newer-file, typed generic, remove/isCreated
- Project: save items as relative paths and variables, restore rebuilds items and variables, auto-save on collection change
- ReferenceResolver: waits for root attach and descendant attach to resolve
- Remove flaky CoreObject property-graph find test

All targeted tests passing.
@b-editor b-editor deleted a comment from claude bot Sep 15, 2025
@b-editor b-editor deleted a comment from claude bot Sep 15, 2025
@b-editor b-editor deleted a comment from claude bot Sep 15, 2025
@b-editor b-editor deleted a comment from claude bot Sep 15, 2025
- JsonSerializationContext: IReference<Obj> serialized to Guid and deserialized back
- Remove invalid CoreObject property graph test

All new tests passing.
Copy link

claude bot commented Sep 15, 2025

Code Review: Configuration and Preferences Unit Tests

✅ Overall Assessment

This PR does an excellent job adding comprehensive unit test coverage for the configuration and preferences system. The tests are well-structured, thorough, and follow good testing practices.

👍 Strengths

Code Quality

  • Tests are well-organized into logical groups by functionality
  • Clear, descriptive test names that follow the Method_Scenario_ExpectedOutcome pattern
  • Good use of AAA (Arrange/Act/Assert) pattern throughout
  • Tests properly isolate to the tests/Artifacts directory via ArtifactProvider

Test Coverage

  • Comprehensive coverage of configuration classes including edge cases
  • Tests both happy path and error scenarios (invalid JSON, unsupported types)
  • Proper verification of event handling (ConfigurationChanged events)
  • Good coverage of serialization/deserialization roundtrips

Best Practices

  • Proper cleanup in tests (file deletion, environment variable restoration)
  • Use of try/finally blocks to ensure configuration values are restored
  • Tests are isolated and don't affect global state

🔍 Minor Suggestions for Improvement

  1. Test Organization: Consider grouping related tests using [TestFixture] classes if the test framework supports it, to better organize the large number of tests being added.

  2. Mock/Stub Usage: Some tests modify GlobalConfiguration.Instance directly. While properly restored in finally blocks, consider if dependency injection or mocking could make these tests more isolated.

  3. Test Data: For tests that write JSON files, consider extracting test data to constants or helper methods to improve readability:

    private const string InvalidJson = "{invalid json}";
  4. Assertion Messages: While NUnit's constraint model provides good default messages, consider adding custom messages for complex assertions to aid debugging:

    Assert.That(cfg2.LibraryTabDisplayModes.ToArray(), 
                Is.EquivalentTo(cfg.LibraryTabDisplayModes.ToArray()),
                "Library tab display modes should match after serialization roundtrip");

✅ Security & Performance

  • No security concerns identified
  • Test performance should be good as tests use local file I/O in isolated directories
  • No production code changes, so no runtime performance impact

📝 Test Coverage Analysis

The PR adds tests for:

  • DefaultPreferences - basic operations, persistence, error handling ✅
  • ViewConfig - recent files/projects, window settings, events ✅
  • GlobalConfiguration - save/load, auto-save behavior ✅
  • ExtensionConfig - editor extensions, decoder priority ✅
  • FontConfig - font directory synchronization ✅
  • TelemetryConfig & BackupConfig - configuration change events ✅
  • EditorConfig - library tab display modes ✅
  • Core functionality - environment variables, hierarchical events, serialization ✅

🎯 Conclusion

This is a high-quality PR that significantly improves test coverage for the configuration system. The tests are well-written, comprehensive, and follow established patterns. The minor suggestions above are optional improvements that could enhance maintainability but are not blocking issues.

Recommendation: ✅ Approve

Great work on improving the test coverage! The tests will help catch regressions and make the configuration system more robust.

- GroupLibraryItem: merge behavior combines same-name groups and items
- Remove flaky CoreObjectFind tests

All tests green.
Copy link

claude bot commented Sep 15, 2025

Pull Request Review

Thank you for this comprehensive addition of unit tests for the Configuration and Core modules! This is a valuable contribution that enhances the test coverage of the Beutl project.

✅ Strengths

Code Quality

  • Well-structured tests: Tests follow a clear naming convention and are well-organized by component
  • Good use of test isolation: Each test properly isolates its setup using ArtifactProvider.GetArtifactDirectory() to avoid side effects
  • Comprehensive coverage: Tests cover both happy paths and edge cases (invalid JSON handling, file system errors)
  • Proper resource cleanup: Tests clean up created files and restore original settings where needed

Test Design

  • Clear test names: Methods follow the pattern MethodName_Scenario_ExpectedResult which makes them self-documenting
  • Good assertion patterns: Using NUnit constraint model (Is.EqualTo, Is.True, etc.) for readable assertions
  • Testing both serialization and deserialization: Round-trip tests ensure data integrity

🔍 Observations & Suggestions

1. Potential Race Conditions

In GlobalConfigurationTests.cs lines 58-77, the auto-save test modifies global singleton state. Consider adding [NonParallelizable] attribute if tests might run concurrently.

2. Environment Variable Cleanup

In PreferencesDefaultTests.cs and BeutlEnvironmentTests.cs, environment variables are modified but not always restored. Consider wrapping in try/finally blocks to ensure cleanup.

3. Async Test Pattern

In ReferenceResolverTests.cs, ensure all async tests properly await their operations and handle potential timeouts.

4. Magic Numbers

Consider extracting magic numbers to named constants for better maintainability and self-documentation.

5. Test Data Builders

For complex object creation (like in ViewConfigTests.cs), consider using the builder pattern to reduce duplication.

🐛 Potential Issues

1. Observable Handler Count

In CoreObjectExtensionsTests.cs lines 36-40, the comment mentions "handler attached twice" resulting in 3 events. Verify if this is expected behavior.

2. File System Dependencies

Some tests directly interact with the file system. Consider:

  • Adding retry logic for file operations that might fail due to timing
  • Ensuring all created directories are cleaned up in teardown

3. Static State Dependencies

Tests depending on BeutlApplication.Current and GlobalConfiguration.Instance might have ordering dependencies. Consider resetting these between tests.

🎯 Performance Considerations

  • File I/O operations in tests could be slow. Consider grouping file-based tests
  • Serialization/deserialization tests could benefit from benchmarking to prevent performance regression

🔒 Security

  • No security issues identified
  • Proper use of temporary directories for test artifacts
  • No hardcoded credentials or sensitive data

📋 Test Coverage Gaps

Consider adding tests for:

  • Concurrent access scenarios for shared configuration
  • Error recovery when configuration files are corrupted mid-write
  • Permission-related failures (read-only files/directories)
  • Large data scenarios (many preferences, large JSON objects)

✅ Overall Assessment

This PR significantly improves test coverage and follows good testing practices. The tests are well-written, maintainable, and provide excellent coverage of configuration and core functionality. With the minor improvements suggested above, this will be an excellent addition to the codebase.

Recommendation: Approve with minor suggestions

Great work on improving the test coverage! The tests are thorough and well-structured. 🎉

- JsonSerializationContext.Resolve immediate branch covered
- RectOperator/TextBlockOperator/GeometryOperator default property values verified using property adapters

All tests passing.],
Copy link
Contributor

No TODO comments were found.

Copy link
Contributor

Code Coverage

Package Line Rate Branch Rate Complexity Health
Beutl.Embedding.FFmpeg 2% 0% 427
Beutl.ProjectSystem 14% 7% 2075
Beutl.Engine 31% 28% 9527
Beutl.Core 45% 39% 3058
Beutl.Language 7% 25% 636
Beutl.Threading 100% 94% 118
Beutl.Extensibility 2% 0% 106
Beutl.Configuration 69% 52% 283
Beutl.Operators 57% 0% 58
Beutl.Utilities 73% 67% 360
Summary 31% (12541 / 40119) 28% (3272 / 11605) 16648

Minimum allowed line rate is 0%

Copy link

claude bot commented Sep 15, 2025

Code Review: Unit Tests for Configuration and Preferences

Thank you for this comprehensive test suite addition! The PR adds 1578 lines of valuable unit tests covering configuration, preferences, and core functionality. Here is my detailed review:

✅ Strengths

Code Quality & Best Practices:

  • Well-organized test structure with clear separation of concerns (Configuration, Core, Extensibility, Operators)
  • Good use of descriptive test names following the pattern MethodName_Scenario_ExpectedBehavior
  • Proper test isolation using ArtifactProvider for file system operations
  • Comprehensive coverage of both happy paths and edge cases

Test Coverage:

  • Excellent coverage of configuration serialization/deserialization
  • Good testing of event propagation (ConfigurationChanged events)
  • Proper validation of file persistence and round-trip operations
  • Edge cases like invalid JSON handling and non-existent directories

🔍 Areas for Improvement

1. Resource Management:
While tests clean up files at the start, consider implementing IDisposable patterns or [TearDown] methods to ensure cleanup even when tests fail.

2. Environment Variable Isolation:
Tests modify global environment variables (e.g., BEUTL_HOME) which could affect parallel test execution. Consider saving and restoring original values or using test fixtures that isolate environment changes.

3. Potential Race Conditions:
The GlobalConfiguration tests use a singleton instance which might cause issues with parallel test execution. Consider adding [NonParallelizable] attribute or refactoring to use test-specific instances.

🐛 Potential Issues

1. Directory Creation Without Cleanup:
Some tests create directories but do not ensure cleanup in BeutlEnvironmentTests.cs and PreferencesDefaultTests.cs

2. Type Safety in Assertions:
Some assertions like "Assert.That(changed, Is.GreaterThanOrEqualTo(1))" could be more specific. Consider using exact counts when the expected behavior is deterministic.

💡 Suggestions

1. Test Data Builders:
For complex objects like ViewConfig, consider creating test data builders to reduce duplication and improve readability.

2. Parameterized Tests:
Some tests could benefit from [TestCase] attributes for testing multiple scenarios with primitive types.

3. Thread Safety Testing:
Given that configuration might be accessed from multiple threads, consider adding concurrency tests.

🔒 Security Considerations

  • Good practice avoiding hardcoded paths and using ArtifactProvider
  • No sensitive data or credentials exposed in tests
  • Proper validation of file operations

✅ Performance Considerations

  • Tests are lightweight and focused
  • File I/O is properly scoped to test directories
  • No unnecessary delays or sleeps

Overall Assessment

This is a high-quality test suite that significantly improves the project test coverage. The tests are well-written, comprehensive, and follow good testing practices. With the minor improvements suggested above (particularly around resource cleanup and environment isolation), this will be an excellent addition to the codebase.

Recommendation: Approve with minor suggestions

The PR achieves its goal of adding comprehensive unit tests for configuration and preferences. The issues mentioned are minor and do not block merging, but addressing them would make the test suite more robust.

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