Skip to content

Commit 5587a29

Browse files
committed
chore: update agents.md
1 parent 438ecf1 commit 5587a29

1 file changed

Lines changed: 81 additions & 1 deletion

File tree

AGENTS.md

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,46 @@ class TestClassName:
131131
assert isinstance(obj.attr, int) # runtime check SECOND
132132
```
133133

134+
#### Signature Verification
135+
136+
**⚠️ Critical**: Signature tests must verify that stub parameters **exactly match** runtime parameters. This catches:
137+
- Missing parameters in stubs
138+
- Extra parameters in stubs that don't exist at runtime
139+
- Wrong parameter order
140+
141+
```python
142+
def test_init_signature(self) -> None:
143+
sig = inspect.signature(mod.ClassName.__init__)
144+
params = list(sig.parameters.keys())
145+
# EXACT match - catches stub/runtime mismatches
146+
assert params == ["self", "param1", "param2", "kwargs"]
147+
148+
def test_method_signature(self) -> None:
149+
sig = inspect.signature(mod.ClassName.method_name)
150+
params = list(sig.parameters.keys())
151+
assert params == ["self", "arg1", "arg2"]
152+
```
153+
154+
#### Instance Attribute Verification
155+
156+
Test instance attributes to ensure stub types match runtime types:
157+
158+
```python
159+
def test_instance_attributes(self) -> None:
160+
obj = mod.ClassName(...)
161+
# Test each attribute declared in the stub
162+
assert hasattr(obj, "attr_name")
163+
assert_type(obj.attr_name, ExpectedType) # stub check
164+
# Runtime type check (when value is not None)
165+
if obj.attr_name is not None:
166+
assert isinstance(obj.attr_name, ExpectedType)
167+
168+
def test_optional_attribute(self) -> None:
169+
obj = mod.ClassName(...)
170+
# For Optional[X] or X | None types
171+
assert_type(obj.optional_attr, ExpectedType | None)
172+
```
173+
134174
---
135175

136176
### Testing Functions
@@ -146,14 +186,35 @@ class TestFunctionName:
146186
def test_signature(self) -> None:
147187
sig = inspect.signature(mod.function_name)
148188
params = list(sig.parameters.keys())
149-
assert "param1" in params
189+
# EXACT match required
190+
assert params == ["param1", "param2", "kwargs"]
150191

151192
def test_return_type(self) -> None:
152193
result = mod.function_name(...)
153194
assert_type(result, ExpectedType) # stub check FIRST
154195
assert isinstance(result, ExpectedType) # runtime check SECOND
155196
```
156197

198+
#### Method Signature Testing
199+
200+
For class methods, verify signatures match runtime exactly:
201+
202+
```python
203+
def test_method_signature(self) -> None:
204+
sig = inspect.signature(mod.ClassName.method_name)
205+
params = list(sig.parameters.keys())
206+
# Verify exact parameter list
207+
assert params == ["self", "event", "data", "namespace", "timeout"]
208+
209+
def test_method_has_parameter(self) -> None:
210+
sig = inspect.signature(mod.ClassName.method_name)
211+
# Check specific parameter exists
212+
assert "timeout" in sig.parameters
213+
# Check parameter default if relevant
214+
param = sig.parameters["timeout"]
215+
assert param.default is None # Verify default matches stub
216+
```
217+
157218
---
158219

159220
### Testing Type Aliases
@@ -235,9 +296,28 @@ class TestFactory:
235296
|------|-------------|
236297
| **assert_type first** | Always before isinstance (narrowing hides errors) |
237298
| **Dual validation** | `assert_type` (stub) + `isinstance` (runtime) for values |
299+
| **Exact signature match** | Signature tests must use `== ["param1", "param2"]`, not `in params` |
238300
| **Runtime-only** | `hasattr`, `issubclass`, `inspect.isclass` (boolean results) |
239301
| **Single import** | `import socketio.x as mod`, access via `mod.Y` |
240302
| **Test all fields** | NamedTuples: test each field's type individually |
303+
| **Test instance attrs** | Verify all stub-declared instance attributes exist and have correct types |
304+
305+
#### ⚠️ Common Testing Mistakes
306+
307+
```python
308+
# ❌ WRONG - "in" doesn't catch extra/missing params
309+
assert "param1" in params
310+
311+
# ✅ CORRECT - exact match catches stub/runtime mismatches
312+
assert params == ["self", "param1", "param2"]
313+
314+
# ❌ WRONG - doesn't verify attribute exists at runtime
315+
assert_type(obj.attr, int)
316+
317+
# ✅ CORRECT - verify both existence and type
318+
assert hasattr(obj, "attr")
319+
assert_type(obj.attr, int)
320+
```
241321

242322
---
243323

0 commit comments

Comments
 (0)