Releases · rjmurillo/moq.analyzers · GitHub
Skip to content

Releases: rjmurillo/moq.analyzers

v0.4.2

Choose a tag to compare

@github-actions github-actions released this 11 Mar 20:29
80cffee

Moq.Analyzers 0.4.2 🎉

This is a focused patch release with one mission: squash a false positive that was getting in the way of real-world LINQ-to-Mocks usage. If you've been seeing Moq1302 warnings on perfectly valid code, this one's for you. 🎯

A big thank you to @abatishchev for reporting the issue with a clear, actionable reproduction. Community reports like this make all the difference.

🐛 False Positive Fix for Moq1302

What was happening

If you were using Mock.Of with a comparison expression — something totally normal like this:

Mock.Of<Response>(static r => r.Status == StatusCodes.Status200OK)

…you'd get a warning:

⚠️ Moq1302: Invalid member 'StatusCodes.Status200OK' in LINQ to Mocks expression

But there's nothing wrong with that code. It compiles, it runs, and it's how LINQ-to-Mocks expressions are supposed to work. The right-hand side of the comparison (StatusCodes.Status200OK) is just a constant — it's not a mock setup member. The analyzer shouldn't have been looking at it at all. 😬

The same false positive appeared with enum values, static fields, external locals, and other non-mock expressions on the right-hand side of ==, &&, or || comparisons.

How it was fixed

The fix introduces a lambda parameter guard: before the analyzer flags a member access, it now walks the receiver chain to check whether the operation is actually rooted in the lambda parameter (i.e., the r in r => r.Status == ...).

A new IsRootedInLambdaParameter() extension method traces the receiver chain — through property accesses, method calls, and conversions — all the way back to the lambda parameter. If the chain doesn't terminate in the lambda parameter, the member is silently skipped. Static members, constants, and external references pass right through without a warning.

The guard is applied only to leaf member operations (property references, method calls). Composite operations like && and || still get decomposed normally, so chained comparisons like r.Prop == "a" && r.Other == "b" continue to be fully analyzed. No false negatives.

As a bonus, MoqKnownSymbols is now threaded through the entire analysis chain instead of being recreated mid-analysis, and nested Mock.Of calls are excluded early to prevent false positives from inner mock expressions.

🧪 Comprehensive Test Coverage

This release adds 961 new lines of test code covering the full surface area of the fix (#1020):

  • ✅ Static members and constants on the right-hand side of comparisons
  • ✅ Enum value comparisons
  • ✅ Chained && / || expressions
  • ✅ Nested Mock.Of calls
  • ✅ Deep receiver chain walking edge cases

👥 Contributors

Thank you to everyone who reported bugs and provided reproduction cases:

📋 All Changes

  • fix: filter non-lambda-rooted members in Moq1302 to eliminate false positives (#1017)
  • test(Moq1302): comprehensive coverage for false positive fix (#1020)
  • build: version bump to 0.4.2

🔗 Resources

💬 Feedback

If you encounter any issues or have suggestions:

Thank you for using Moq.Analyzers!

v0.4.1

Choose a tag to compare

@rjmurillo rjmurillo released this 21 Feb 09:11

Moq.Analyzers 0.4.1

This is a patch release addressing critical bugs reported after v0.4.0.

🐛 Bug Fixes

Moq1203 False Positives

  • #849 - Fixed incorrect Moq1203 flagging after upgrading to v0.4.0. The analyzer now correctly resolves delegate-overload resolution for ReturnsAsync, Callback, and similar chained methods. (#886, #919)
  • #887 - Fixed Moq1203 false positive when the Setup call is wrapped in parentheses. (#895)

Parenthesized Expression Handling

  • #896 - Fixed parenthesized expressions breaking syntax chain walking in Moq1100 and Moq1206 analyzers. (#907)

Assembly Loading

  • #850 - Resolved CS8032 warning caused by System.Collections.Immutable assembly version mismatch. (#888)

🤝 Contributors

Thank you to everyone who reported bugs, provided reproduction cases, and engaged in issue discussions to help make this release possible:

🔗 Resources

💬 Feedback

If you encounter any issues or have suggestions:

Thank you for using Moq.Analyzers!

v0.4.1-alpha

v0.4.1-alpha Pre-release
Pre-release

Choose a tag to compare

@rjmurillo rjmurillo released this 17 Feb 03:31

v0.4.1-alpha

Prerelease containing 3 bug fixes since v0.4.0 to rebuild confidence with users.

Bug Fixes

  • fix: Moq1203 false positives for ReturnsAsync and Callback chaining (#886)
  • fix: resolve CS8032 assembly version mismatch (#850) (#888)
  • fix: Moq1203 false positive when Setup call is wrapped in parentheses (#895)

Critical: CS8032 Fix

v0.4.0 shipped DLLs that referenced System.Collections.Immutable versions incompatible with .NET 8 SDK hosts, causing CS8032 warnings on every build. This release downgrades the transitive dependency pins and adds CI load tests to prevent recurrence.

v0.4.0

Choose a tag to compare

@rjmurillo rjmurillo released this 13 Nov 03:55
2af4f56

Moq.Analyzers 0.4.0

Welcome to Moq.Analyzers 0.4.0! This major release brings significant improvements to code quality analysis, introduces new analyzers for better Moq usage patterns, and includes comprehensive updates to our infrastructure and dependencies.

✨ Highlights

New Analyzers

This release introduces three powerful new analyzers to help you write better Moq tests:

  • [Moq1207] - SetupSequence validation analyzer ensures sequential setups are used correctly
  • [Moq1420] - Times usage validation helps you use verification times specifications properly
  • [Moq1500] - Raise method validation catches incorrect event argument patterns

Enhanced Diagnostic Messages

We've improved diagnostic messages across all analyzers to include specific type and member names, making it easier to identify and fix issues. Every analyzer now provides clearer, more actionable feedback.

Symbol-Based Detection

Replaced string-based detection with comprehensive symbol-based analysis for the Raises method, improving accuracy and performance of event-related analyzers.

Infrastructure Modernization

  • Migrated to .NET 10 SDK for the latest tooling improvements
  • ARM64 runners for faster CI/CD on modern hardware
  • Enhanced performance testing with nightly regression detection
  • Automated dependency management with Renovate

🎯 Breaking Changes

Minimum SDK Version

Moq.Analyzers now requires minimum .NET SDK 8 for development. This aligns with the long-term support release and enables us to leverage modern C# features.

🔧 Analyzer Improvements

Coverage Expansion

We've significantly expanded test coverage for all Moq patterns:

  • Event patterns: Comprehensive coverage for SetupAdd, SetupRemove, Raises, and RaisesAsync
  • Async methods: Full support for Task/ValueTask patterns
  • LINQ to Mocks: Complete validation of query expressions
  • MockRepository: Validation for repository-based mock creation
  • Argument matching: Coverage for all It.* and custom matcher patterns
  • Protected members: Validation for .Protected().Setup() patterns
  • Callback signatures: Advanced callback pattern support including generic scenarios

Moq 4.16+ Compatibility

Added comprehensive test suites ensuring compatibility with Moq 4.16 and later versions, including new features like SetupProperty patterns.

Enhanced Validation

  • Moq1101: Now covers SetupProperty patterns in addition to existing validations
  • Moq1210: Improved verification pattern detection for non-overridable members
  • Moq1100: Validated support for advanced callback patterns

📊 Code Quality Enhancements

Improved Test Coverage

Achieved significant code coverage improvements through:

  • Data-driven test pattern adoption across all analyzers
  • Doppelganger tests to validate analyzer registration
  • Comprehensive edge case testing
  • Performance benchmark tests

Reduced Complexity

  • Eliminated duplicate code in MockBehavior analyzers
  • Reduced CRAP scores in event handling and symbol extensions
  • Refactored NoSealedClassMocksAnalyzer for better nullable type handling
  • Optimized DefaultIfNotSingle loop performance

Better Error Handling

Improved defensive checks and error handling throughout the codebase based on comprehensive code review feedback.

🚀 Performance

Analyzer Optimizations

  • Converted SetupShouldOnlyBeUsedForOverridableMembersAnalyzer to IOperation-based analysis
  • Converted NoSealedClassMocksAnalyzer to IOperation-based analysis
  • Implemented symbol-based detection for improved accuracy and speed

CI/CD Performance

  • Nightly performance validation with automated regression detection
  • ARM64 runners for faster build times
  • Modular performance testing tools
  • Comprehensive performance documentation

📚 Documentation

Enhanced Guidelines

  • Updated rule documentation with clearer examples and guidance
  • Added generic type parameter scenarios for Moq1300
  • Documented generic callback limitations in Moq1100
  • Comprehensive investigation of symbol detection patterns

AI-Assisted Development

Strengthened GitHub Copilot instructions for better collaboration:

  • Enhanced instruction files for different file types
  • Better project navigation guidelines
  • Improved coding standards documentation
  • Task management and completion protocols

🔄 Dependency Updates

This release includes 200+ dependency updates to keep the project secure and up-to-date:

Major Updates

  • Verify.Xunit: 28.7.0 → 31.6.1
  • Polyfill: 7.8.0 → 9.x
  • Meziantou.Analyzer: 2.0.183 → 2.0.252
  • SonarAnalyzer.CSharp: 10.4.0 → 10.15.0
  • Microsoft.NET.Test.Sdk: 17.12.0 → 18.0.1
  • ReportGenerator: 5.4.2 → 5.5.0
  • Nerdbank.GitVersioning: 3.7.112 → 3.9.50
  • Microsoft.CodeAnalysis.* analyzers: 3.11.0-beta → 4.14.0

Package Management

  • All dependencies now managed through Renovate for automated updates
  • Security vulnerability scanning on all PRs
  • Semantic PR validation

🛠️ Infrastructure

CI/CD Improvements

  • Removed CodeQL in favor of comprehensive static analysis suite
  • Added BuildCheck integration for MSBuild validation
  • Automated performance regression detection
  • Semantic PR title validation
  • Enhanced dependency review process

Build System

  • Ubuntu-based release builds for consistency
  • Improved artifact handling
  • Better code coverage reporting with qlty.sh
  • Enhanced report generation with licensing

Development Tools

  • Cross-platform performance testing (Linux and Windows)
  • Improved PerfDiff regression detection
  • Better baseline comparison tools
  • Enhanced debugging capabilities

🐛 Bug Fixes

Code Fixes

  • [#701] Fixed exception in explicit mock behavior code fix
  • [#714] Improved defensive checks preventing null reference exceptions
  • [#456] Fixed duplicate test cases causing xUnit to skip tests
  • [#407] Fixed SetupShouldBeUsedOnlyForOverridableMembersAnalyzer to properly flag field and event setup calls
  • [#467] Fixed path casing for PerfDiff project in comparison script

Analyzer Corrections

  • Fixed method check for callback and returns patterns
  • Corrected dictionary creation in multiple analyzers
  • Improved null handling in EnumerableExtensions
  • Removed unnecessary IsAnalyzerSuppressed check

🤝 Contributors

Huge thanks to all our contributors who made this release possible:

Special thanks to our new contributors:

📈 Statistics

  • 200+ pull requests merged
  • 150+ dependency updates processed
  • 3 new analyzers added
  • 20+ analyzers with improved diagnostics
  • Significant code coverage improvements
  • Zero security vulnerabilities at release

🔗 Resources

💬 Feedback

We'd love to hear from you! If you encounter any issues or have suggestions for improvements, please:

Thank you for using Moq.Analyzers! 🎉

v0.3.1

Choose a tag to compare

@rjmurillo rjmurillo released this 19 Sep 22:24

Minor Bug Fix

fix: exception in code fix of explicit mock behavior (#701) @Youssef1313 #701

Full Changelog: v0.3.0...v0.3.1

v0.3.0

Choose a tag to compare

@rjmurillo rjmurillo released this 21 Jan 17:20
5b00626

Moq.Analyzers v0.3.0 🎄

Holidays are coming and it's time for the last release of the year! 🎉

There's a lot that has gone into this release, mostly housekeeping and bug fixes that are transparent to you. However, there are two new diagnostics included in this release.

This will be the last release until we move to v1.0.0

Analyzer Behavior Changes

  • Remove false positive for Moq1200 when using parameterized lambda by @rjmurillo in #301
  • Add new rule to enforce MockBehavior.Strict (Moq1410) by @rjmurillo in #302

What's Changed

Full Changelog: v0.2.0...v0.3.0

v0.3.0-alpha.1

v0.3.0-alpha.1 Pre-release
Pre-release

Choose a tag to compare

@rjmurillo rjmurillo released this 21 Jan 17:14

This is a small update to include a bug fix for code analyzers crashing in the IDE.

Full list of What's Changed

Full Changelog: v0.3.0-alpha...v0.3.0-alpha.1

v0.3.0-alpha

v0.3.0-alpha Pre-release
Pre-release

Choose a tag to compare

@rjmurillo rjmurillo released this 24 Dec 22:34

Moq.Analyzers v0.3.0 🎄

Holidays are coming and it's time for the last release of the year! 🎉

There's a lot that has gone into this release, mostly housekeeping and bug fixes that are transparent to you. However, there are two new diagnostics included in this release.

This will be the last release until we move to v1.0.0

Analyzer Behavior Changes

  • Remove false positive for Moq1200 when using parameterized lambda by @rjmurillo in #301
  • Add new rule to enforce MockBehavior.Strict (Moq1410) by @rjmurillo in #302

Full List of What's Changed

Full Changelog: v0.2.0...v0.3.0-alpha

v0.2.0

Choose a tag to compare

@rjmurillo rjmurillo released this 24 Dec 21:58

Changes

Housekeeping

Full Changelog: v0.1.2...v0.2.0

v0.1.2

Choose a tag to compare

@rjmurillo rjmurillo released this 24 Dec 22:36
38d26b5

What's Changed

Lots of housekeeping and a couple of fixes and enhancements.

Enhancements and Bug fixes

  • Add Mock.Of and MockRepository support to ConstructorArgumentsShouldMatchAnalyzer by @rjmurillo in #140
  • Moq1100 incorrectly firing on nullable parameters by @marcovr @rjmurillo in #187

Other Changes

Full Changelog: v0.1.1...v0.1.2