Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 24 additions & 0 deletions .claude/rules/yooasset-extensions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# YooAsset Extension Sample Maintenance

YooAsset ships Extension Samples under `Assets/Samples/YooAsset/`. These are vendor-provided examples that JEngine customizes. When YooAsset is updated and its Extension Samples change, our customizations may be overwritten.

## Custom Modifications to Track

### PreprocessBuildCatalog (Decryption Support)

**File**: `Assets/Samples/YooAsset/*/Extension Sample/Editor/PreprocessBuild/PreprocessBuildCatalog.cs`

**What we changed**: The upstream code calls `CatalogTools.CreateCatalogFile(null, ...)` with a `//TODO 自行处理解密` comment, which causes a NRE when manifests are encrypted. We replaced this with a try-all approach that attempts each `IManifestRestoreServices` from `EncryptionMapping.Mapping` until one succeeds.

**Why**: See [YooAsset#730](https://github.com/tuyoogame/YooAsset/issues/730). The YooAsset author confirmed this is an intentional extension point for consumers to customize.

**On YooAsset update**: Verify that `PreprocessBuildCatalog.cs` still contains our `TryCreateCatalogFile` / `TryCreate` helper methods and the `using JEngine.Core.Encrypt` import. If the sample was overwritten by the update, reapply the decryption try-all logic.

## Update Checklist

When updating YooAsset or its Extension Samples:

- [ ] Diff the new Extension Sample files against our customized versions
- [ ] Reapply any overwritten JEngine customizations listed above
- [ ] Verify catalog generation works with both encrypted and unencrypted manifests
- [ ] Add any new upstream extension points to this file if customized
11 changes: 11 additions & 0 deletions .github/instructions/code-review.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,19 @@ Avoid LINQ in hot paths and UI code for performance:
- Use array/list indexing instead of `.First()` / `.Last()`
- LINQ allocates iterators and delegates - avoid in frequently called code

### 7. Unit Test Coverage
New features and new logic in non-core packages (JEngine.UI, JEngine.Util, and any future packages) MUST include unit tests:
- Target **93%+ code coverage** for all new/modified code
- **Applies to**: All `Packages/com.jasonxudeveloper.jengine.*` packages **except** `jengine.core`
- Prefer **EditMode tests** (`Tests/Editor/`) for most logic
- Use **PlayMode tests** (`Tests/Runtime/`) when runtime behavior requires it (MonoBehaviour lifecycle, scene loading, etc.) — these must run **non-interactively** (no user input, no manual scene setup)
- Cover: constructors, public API, fluent chaining, edge cases, event handlers
- Use reflection to test private methods (e.g. `OnAttachToPanel`, hover handlers) when they contain meaningful logic
- Verify tests exercise both happy paths and error/boundary conditions

## Common Issues to Flag

- Missing or insufficient unit tests for new features
- Missing XML documentation on public APIs
- Direct `Debug.Log` (should use proper logging)
- `Task` instead of `UniTask`
Expand Down
79 changes: 79 additions & 0 deletions .github/instructions/jengine.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,84 @@ internal class MyEditorClass
}
```

## Unit Testing

### Scope
Unit tests are required for all non-core JEngine packages — i.e. any package under `Packages/com.jasonxudeveloper.jengine.*` **except** `jengine.core`. This includes JEngine.UI, JEngine.Util, and any future packages.

### Coverage Requirement
New features and new logic MUST include unit tests targeting **93%+ code coverage**:
- All public methods, properties, and constructors
- Fluent API chaining
- Edge cases and error conditions
- Event handlers and callbacks (use reflection for private handlers)

### Test Modes
- **EditMode tests** (`Tests/Editor/`): Preferred for most logic — fast, no scene required.
- **PlayMode tests** (`Tests/Runtime/`): Use when the test needs a running game loop, MonoBehaviour lifecycle, or scene loading. PlayMode tests **must run non-interactively** (no user input, no manual scene setup). Use `[UnityTest]` with `UniTask.ToCoroutine()` for async PlayMode tests.

### Test Location
Tests mirror the source structure under each package's test folders:
```
Packages/com.jasonxudeveloper.jengine.ui/Editor/Components/Button/JButton.cs
→ Packages/com.jasonxudeveloper.jengine.ui/Tests/Editor/Components/Button/JButtonTests.cs

Packages/com.jasonxudeveloper.jengine.util/Runtime/JAction.cs
→ Packages/com.jasonxudeveloper.jengine.util/Tests/Editor/JActionTests.cs

# PlayMode tests when runtime behavior requires it:
Packages/com.jasonxudeveloper.jengine.util/Runtime/SomeFeature.cs
→ Packages/com.jasonxudeveloper.jengine.util/Tests/Runtime/SomeFeatureTests.cs
```

### EditMode Test Pattern
```csharp
[TestFixture]
public class MyComponentTests
{
private MyComponent _component;

[SetUp]
public void SetUp()
{
_component = new MyComponent();
}

[Test]
public void Constructor_Default_AddsBaseClass()
{
Assert.IsTrue(_component.ClassListContains("my-component"));
}
}
```

### PlayMode Test Pattern
PlayMode tests must be fully automated — no interactive input or manual scene setup:
```csharp
[TestFixture]
public class MyRuntimeTests
{
[UnityTest]
public IEnumerator MyAsyncTest() => UniTask.ToCoroutine(async () =>
{
var go = new GameObject();
var component = go.AddComponent<MyBehaviour>();
await UniTask.DelayFrame(1);
Assert.IsTrue(component.IsInitialized);
Object.Destroy(go);
});
}
```

### Testing Private Methods via Reflection
For private event handlers and internal styling methods:
```csharp
var method = typeof(MyComponent).GetMethod("OnMouseEnter",
BindingFlags.NonPublic | BindingFlags.Instance);
method.Invoke(_component, new object[] { null });
Assert.AreEqual(expectedColor, _component.style.backgroundColor.value);
```

## Review Focus Areas

When reviewing JEngine code, check:
Expand All @@ -110,3 +188,4 @@ When reviewing JEngine code, check:
3. Resource cleanup (ScriptableObjects, events)
4. Thread safety for callback-accessed state
5. Proper namespace usage
6. Unit tests with 93%+ coverage for new features/logic
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
@.claude/rules/commit-conventions.md
@.claude/rules/package-creation.md
@.claude/rules/plugin-maintenance.md
@.claude/rules/yooasset-extensions.md

## Project Overview

Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Loading