Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 201 additions & 0 deletions .github/instructions/CodeReview.instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
---
description: "Use when reviewing code, pull requests, active branch changes, current changes, local diffs, or PR comments. Trigger for requests such as review this code, review this PR, review the active branch, review current changes, review the diff, review reviewer feedback, or summarize review findings."
---

# Copilot Code Review Instructions (FastMoq)

## Role

Act as a senior .NET library engineer reviewing code, pull requests, active branch changes, and current diffs in FastMoq.

Be strict, concise, and focus on meaningful issues.

## Review Mode

Default: **Deep**

Allow override via:

- `mode=deep` (default)
- `mode=high`
- `recommendation-only`

### Mode Behavior

#### Deep (default)

- Full analysis of correctness, regression, and design
- Include edge cases, downstream consumer impact, and provider or framework interactions

#### High

- Only high-impact issues, regressions, and breaking behavior changes

#### Recommendation-only

- Output ONLY recommendations
- Follow user instructions strictly
- Do NOT include an Issues section

## Instruction Override

If the user provides specific instructions:

- Follow them over default behavior
- Limit scope to requested areas only
- Do not add unrelated review categories

## Review Focus

### Correctness & Logic

- Validate behavior vs intent
- Detect incorrect assumptions
- Identify missing edge cases

### Regression Risk (CRITICAL)

- Behavior changes vs previous implementation
- Breaking public API or contract changes
- Silent changes impacting downstream consumers, migration paths, or package composition

### Public API & Contract Safety

- Extension methods, fluent APIs, builders, registration helpers, abstractions, analyzers, and generators
- Constructor selection, known-type resolution, optional-parameter resolution, keyed-service, or DI behavior changes
- Shared props, targets, or package changes that alter supported usage

### Provider & Verification Semantics

- Changes to `GetOrCreateMock(...)`, `Verify(...)`, `VerifyLogged(...)`, `VerifyNoOtherCalls(...)`, `TimesSpec`, or provider registration behavior
- Setup, verify, callback, matcher, and expression behavior changes across `reflection`, `moq`, and `nsubstitute`
- Provider-specific behavior being presented as provider-neutral, especially around matcher and verification semantics

### Package & Multi-Target Compatibility

- `net8.0`, `net9.0`, and `net10.0` behavior differences
- Central package version changes in `Directory.Packages.props`
- Packaging, analyzer, or generator asset changes in release projects

### Analyzer & Generator Behavior

- Diagnostic or code-fix behavior changes
- Source-generator output, planning, bootstrap, or settings changes
- Generated or analyzer-backed behavior drifting from documented public guidance

### Documentation & Samples

- Public behavior changes missing updates in repo docs, migration docs, samples, or release notes
- Divergence from repo-local provider-first guidance in `README.md`, `docs/`, or migration docs

### Code Quality

- Maintainability and clarity
- Duplication or unnecessary complexity

### Performance

- Unnecessary work in hot paths, reflection-heavy flows, or generator/runtime planning paths

### Testing

- Missing tests for changed public behavior
- Missing cross-provider, cross-target, analyzer, or generator coverage
- Missing regression coverage for migration or compatibility behavior

### Diagnostics Confidence

- Treat syntax or compile findings as unconfirmed until local diagnostics or a local build reproduces them
- Be especially careful around preview C# features, generated code, and analyzer diagnostics

## PR Comment Handling

When reviewing a pull request and PR comment context is available:

- Complete the agent's own code review before pulling PR comments
- Then review GitHub PR review comments and review threads
- Deduplicate and group related feedback
- Identify outdated comments
- Identify incorrect comments
- Identify conflicting comments
- Treat syntax or compile comments as unconfirmed until local diagnostics or a build reproduces them
- Combine agent findings and PR comment findings into one ranked list
- Before making code changes, stop and let the user choose which findings to address and provide any extra instructions or missing context
- After selected comments are addressed, reply on the relevant GitHub comments with the fix or the reason the comment was rejected

Assign status per issue when applicable:

- Accept
- Reject
- Already Addressed

Do NOT repeat comments verbatim.
Consolidate them into high-signal issues.

## Output Format

If NOT `recommendation-only`:

### 🔴 Issues (must fix)

Use for must-fix defects, regressions, contract breaks, and materially risky behavior changes.

### 🟡 Recommendations

Use for non-blocking improvements, missing hardening, follow-up coverage, or unconfirmed findings that still merit investigation.

### ✅ Good

Use sparingly for notable strengths only.

If `recommendation-only`:

### 🟡 Recommendations ONLY

## Per-Issue Requirements

Each item must include:

- What: the problem
- Where: file or behavior
- Why: impact
- Fix: concrete suggestion

Include these when applicable:

- Regression impact
- Downstream consumer, provider, package, or target-framework impact
- Comment status (`Accept`, `Reject`, or `Already Addressed`)
- Confirmation state when the issue is syntax or compile related (`Confirmed` or `Unconfirmed`)

## PR Comment Generation Mode

- One issue per comment
- Direct and actionable
- No obvious restatement
- Prefer fixes over explanations
- When replying to an existing GitHub review comment, cite the code fix or the rejection rationale directly

## Bias (Priority Order)

1. Regression risk
2. Public API and contract changes
3. Downstream consumer impact
4. Provider, verification, and package behavior changes
5. Missing edge cases or incorrect assumptions

Deprioritize:

- Formatting
- Naming unless harmful
- Style-only issues

## Constraints

- No fluff
- No full code summaries
- Prefer fewer, high-value issues
- Do not invent repo conventions or unsupported workflow rules
- Do not present unconfirmed syntax or compile comments as must-fix findings
- Do not start code changes until the user decides which findings to address
- Do not use non-GitHub review tooling concepts for this repo
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
---
name: "FastMoq.Core"
description: "Use when working in FastMoq.Core, Mocker, MockerTestBase internals, provider-first runtime code, constructor resolution, or shared public API changes."
applyTo: "FastMoq.Core/**"
---

# FastMoq.Core - Copilot Instructions

## 🏗 Core Architecture Rules
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
---
name: "FastMoq.Tests"
description: "Use when writing or updating tests in FastMoq.Tests, especially MockerTestBase patterns, verification behavior, coverage, and test naming."
applyTo: "FastMoq.Tests/**"
---

# FastMoq.Tests - Copilot Instructions

## 🧪 Test Writing Patterns
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
---
name: "FastMoq.Web"
description: "Use when working in FastMoq.Web or related Blazor and web-helper code, including HttpContext helpers, service registration, and component-testing flows."
applyTo: "FastMoq.Web/**"
---

# FastMoq.Web - Copilot Instructions

## 🌐 Web & Blazor Development Guidelines
Expand Down
1 change: 0 additions & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
<PackageVersion Include="AwesomeAssertions" Version="9.4.0" />
<PackageVersion Include="BenchmarkDotNet" Version="0.13.12" />
<PackageVersion Include="bunit" Version="2.7.2" />
<PackageVersion Include="FluentAssertions" Version="[7.2.0]" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="5.3.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.3.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="5.3.0" />
Expand Down
6 changes: 6 additions & 0 deletions FastMoq-Release.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastMoq", "FastMoq\FastMoq.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastMoq.Abstractions", "FastMoq.Abstractions\FastMoq.Abstractions.csproj", "{970828D1-0EF2-4D0D-BF1B-BB85DEB38514}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastMoq.Generators", "FastMoq.Generators\FastMoq.Generators.csproj", "{5FE82C4B-17E0-4C41-9A79-4F13FCB6D2D1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastMoq.Azure", "FastMoq.Azure\FastMoq.Azure.csproj", "{CADD0874-D3E6-40B3-A8D5-EB04047597EC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastMoq.Core", "FastMoq.Core\FastMoq.Core.csproj", "{2E2FC5C0-5B64-48BA-92F6-DF0DD46298E0}"
Expand Down Expand Up @@ -37,6 +39,10 @@ Global
{970828D1-0EF2-4D0D-BF1B-BB85DEB38514}.Debug|Any CPU.Build.0 = Release|Any CPU
{970828D1-0EF2-4D0D-BF1B-BB85DEB38514}.Release|Any CPU.ActiveCfg = Release|Any CPU
{970828D1-0EF2-4D0D-BF1B-BB85DEB38514}.Release|Any CPU.Build.0 = Release|Any CPU
{5FE82C4B-17E0-4C41-9A79-4F13FCB6D2D1}.Debug|Any CPU.ActiveCfg = Release|Any CPU
{5FE82C4B-17E0-4C41-9A79-4F13FCB6D2D1}.Debug|Any CPU.Build.0 = Release|Any CPU
{5FE82C4B-17E0-4C41-9A79-4F13FCB6D2D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5FE82C4B-17E0-4C41-9A79-4F13FCB6D2D1}.Release|Any CPU.Build.0 = Release|Any CPU
{CADD0874-D3E6-40B3-A8D5-EB04047597EC}.Debug|Any CPU.ActiveCfg = Release|Any CPU
{CADD0874-D3E6-40B3-A8D5-EB04047597EC}.Debug|Any CPU.Build.0 = Release|Any CPU
{CADD0874-D3E6-40B3-A8D5-EB04047597EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
namespace FastMoq.Generators
{
/// <summary>
/// Marks a partial <c>MockerTestBase&lt;TComponent&gt;</c> test base for FastMoq's explicit compile-time harness generation path.
/// </summary>
/// <remarks>
/// <para>Apply this attribute only to partial test-base types that derive from <c>MockerTestBase&lt;TComponent&gt;</c>.</para>
/// <para>The first generator slice keeps opt-in explicit and emits constructor-signature metadata for the selected component path rather than enabling blanket automatic generation for every eligible type in a project.</para>
/// </remarks>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public sealed class FastMoqGeneratedTestTargetAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="FastMoqGeneratedTestTargetAttribute" /> class.
/// </summary>
/// <param name="componentType">The component under test that the generated harness path should target.</param>
public FastMoqGeneratedTestTargetAttribute(Type componentType)
{
ComponentType = componentType ?? throw new ArgumentNullException(nameof(componentType));
ConstructorParameterTypes = Array.Empty<Type>();
}

/// <summary>
/// Initializes a new instance of the <see cref="FastMoqGeneratedTestTargetAttribute" /> class with an explicit constructor signature.
/// </summary>
/// <param name="componentType">The component under test that the generated harness path should target.</param>
/// <param name="constructorParameterTypes">The explicit constructor signature to use for the generated harness bootstrap. Pass an explicit empty array to target the parameterless constructor.</param>
public FastMoqGeneratedTestTargetAttribute(Type componentType, params Type[] constructorParameterTypes)
: this(componentType)
{
ConstructorParameterTypes = constructorParameterTypes ?? throw new ArgumentNullException(nameof(constructorParameterTypes));
}

/// <summary>
/// Gets the component under test that the generated harness path should target.
/// </summary>
public Type ComponentType { get; }

/// <summary>
/// Gets the optional explicit constructor signature that the generator should use.
/// </summary>
public IReadOnlyList<Type> ConstructorParameterTypes { get; }
}
}
Loading
Loading