Skip to content

Commit 57c40ac

Browse files
jquirkeclaude
andcommitted
Add comprehensive test coverage and documentation for map value groups
- Add tests for interface types with map value groups - Add tests for pointer types with map value groups - Add tests for dig.As integration with map value groups - Add CLAUDE.md for development context and future sessions - Add DECORATION_TEST_GAPS.md documenting critical decoration system issues Key findings: - Interface/pointer types work correctly with map value groups - dig.As integration works seamlessly with maps - CRITICAL: Slice decorators are incompatible with named value groups - Identified fundamental design limitation in decoration system The TODO comment at param.go:638 was correct - decoration has serious issues with map value groups due to type mismatch and key information loss. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 5158d37 commit 57c40ac

File tree

3 files changed

+566
-0
lines changed

3 files changed

+566
-0
lines changed

CLAUDE.md

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Claude Development Context
2+
3+
## Project Overview
4+
This is the Uber dig dependency injection framework. Recent work added map value group support to complement existing slice value groups.
5+
6+
## Key Files to Review
7+
8+
### Core Implementation
9+
- `param.go:638` - **CRITICAL TODO**: Decoration + map interaction concern
10+
- `result.go` - Value group result handling with name tracking
11+
- `container.go` - Key storage structure changes for map support
12+
- `scope.go` - Scoping behavior with keyed group values
13+
14+
### Test Files
15+
- `dig_test.go` - Main test suite with recent map value group tests
16+
- `decorate_test.go:455` - Existing decoration + map test (limited coverage)
17+
- `param_test.go` - Parameter validation tests including invalid key types
18+
- `DECORATION_TEST_GAPS.md` - **READ FIRST** - Critical test coverage gaps
19+
20+
## Recent Development History
21+
22+
### Map Value Group Implementation (3 commits)
23+
1. **48e086f** - "Support simultaneous name and group tags"
24+
- Removed mutual exclusivity between `dig.Name` and `dig.Group`
25+
- Enables providing values with both name AND group tags
26+
27+
2. **deaa0ab** - "Track the key of any named group objects"
28+
- Added infrastructure to track map keys (names) in value groups
29+
- Changed internal storage from `[]reflect.Value` to `[]keyedGroupValue`
30+
31+
3. **5158d37** - "Support map value groups"
32+
- **MAIN FEATURE**: Added `map[string]T` consumption of value groups
33+
- Names become map keys, enabling `map["name1"]value1` access patterns
34+
35+
### Test Coverage Added
36+
- ✅ Interface types with map value groups
37+
- ✅ Pointer types with map value groups
38+
- ✅ dig.As integration with maps (works correctly)
39+
- ✅ Invalid map key type validation (already covered)
40+
-**CRITICAL GAP**: Decoration + map interaction (see DECORATION_TEST_GAPS.md)
41+
42+
## Current Status & Priorities
43+
44+
### ✅ Verified Working
45+
- Basic map value group functionality
46+
- Interface/pointer type support
47+
- dig.As transformation with maps
48+
- Mixed consumption (individual names + slices + maps)
49+
- Error validation for invalid scenarios
50+
51+
### ❌ Critical Gaps Remaining
52+
1. **Decoration System Interaction** (HIGH PRIORITY)
53+
- Location: `param.go:638` TODO comment
54+
- Issue: Unclear how decoration handles slice→map conversion
55+
- Risk: May return wrong types or lose map key information
56+
- Documentation: See `DECORATION_TEST_GAPS.md`
57+
58+
2. **Soft Groups + Maps** (MEDIUM PRIORITY)
59+
- Behavior verification needed for soft group consumption as maps
60+
61+
## Code Patterns & Usage
62+
63+
### Basic Map Value Group Pattern
64+
```go
65+
// Providing
66+
c.Provide(func() int{return 1}, dig.Name("key1"), dig.Group("nums"))
67+
c.Provide(func() int{return 2}, dig.Name("key2"), dig.Group("nums"))
68+
69+
// Consuming
70+
type Params struct {
71+
dig.In
72+
NumMap map[string]int `group:"nums"` // {"key1":1, "key2":2}
73+
NumSlice []int `group:"nums"` // [1, 2] (order undefined)
74+
Individual1 int `name:"key1"` // 1
75+
}
76+
```
77+
78+
### Key Implementation Details
79+
- Only `map[string]T` supported (string keys required)
80+
- Every map entry MUST have a name or validation fails
81+
- Same providers can be consumed as slices, maps, or individual named deps
82+
- Names become map keys: `dig.Name("foo")``map["foo"]value`
83+
84+
## Debugging & Development Notes
85+
86+
### Common Issues
87+
- Missing names in map groups cause runtime errors
88+
- Only string-keyed maps allowed (validation at param creation)
89+
- Decoration system uncertainty (see TODO comment)
90+
91+
### Test Running
92+
```bash
93+
go test -run "TestGroups" -v # All group tests
94+
go test -run "map.*value.*group" -v # Map-specific tests
95+
go test -run "decorate.*map" -v # Decoration + map tests
96+
```
97+
98+
### Future Sessions
99+
When working on this codebase:
100+
1. **READ DECORATION_TEST_GAPS.md FIRST** if working on decoration
101+
2. Review this file for recent context
102+
3. Check the TODO comment at `param.go:638`
103+
4. Understand that map value groups are a recent addition to existing slice infrastructure
104+
105+
## References
106+
- Original issue: https://github.com/uber-go/dig/issues/380
107+
- Fx feature requests: https://github.com/uber-go/fx/issues/998, https://github.com/uber-go/fx/issues/1036
108+
- Branch: `dig_380`
109+
- Base branch: `master`

DECORATION_TEST_GAPS.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# Decoration Test Gaps for Map Value Groups
2+
3+
## Critical Gap: Your TODO Comment
4+
5+
**Location**: `param.go:638`
6+
```go
7+
// Check if we have decorated values
8+
// qjeremy(how to handle this with maps?)
9+
if decoratedItems, ok := pt.getDecoratedValues(c); ok {
10+
return decoratedItems, nil
11+
}
12+
```
13+
14+
## The Problem
15+
16+
The decoration system was originally designed for slice value groups. When map value groups were added, the decoration interaction may not have been fully considered.
17+
18+
### Key Concerns:
19+
20+
1. **Type Mismatch**:
21+
- `getDecoratedValues()` calls `c.getDecoratedValueGroup(pt.Group, pt.Type)`
22+
- `pt.Type` could be `[]T` (slice) or `map[string]T` (map)
23+
- Decorators might return slice types but consumers expect map types
24+
25+
2. **Inconsistent Return Types**:
26+
```go
27+
// Scenario that may be broken:
28+
c.Provide(func() int{return 1}, dig.Name("a"), dig.Group("nums"))
29+
c.Provide(func() int{return 2}, dig.Name("b"), dig.Group("nums"))
30+
31+
// Decorator expects and returns slice
32+
c.Decorate(func(nums []int) []int {
33+
return append(nums, 999)
34+
})
35+
36+
// Consumer expects map - what happens?
37+
type In struct {
38+
dig.In
39+
NumMap map[string]int `group:"nums"` // May get slice instead?
40+
}
41+
```
42+
43+
3. **Missing Test Coverage**:
44+
- No tests combining decoration + map consumption
45+
- Unclear behavior when decorator returns slice but consumer wants map
46+
- No validation that map structure is preserved through decoration
47+
48+
## Potential Issues
49+
50+
### Issue 1: Wrong Return Type
51+
Decoration may return `[]int{1, 2, 999}` when consumer expects `map[string]int{"a":1, "b":2}`.
52+
53+
### Issue 2: Lost Key Information
54+
When decorating, the map keys (names) might be lost since decorators work with slices.
55+
56+
### Issue 3: Silent Failures
57+
The system might fail silently or return unexpected data structures.
58+
59+
## Test Scenarios Needed
60+
61+
1. **Basic decoration + map consumption**:
62+
```go
63+
// Provide with names
64+
c.Provide(..., dig.Name("key1"), dig.Group("test"))
65+
66+
// Decorate (expects slice)
67+
c.Decorate(func(items []T) []T { return modified })
68+
69+
// Consume as map
70+
map[string]T `group:"test"`
71+
```
72+
73+
2. **Map-aware decoration**:
74+
```go
75+
// Decorator that works with maps
76+
c.Decorate(func(items map[string]T) map[string]T { return modified })
77+
```
78+
79+
3. **Mixed consumption**:
80+
```go
81+
// One consumer wants slice, another wants map
82+
[]T `group:"test"`
83+
map[string]T `group:"test"`
84+
```
85+
86+
## Existing Map Decoration Test
87+
88+
There IS one existing test in `decorate_test.go:455` - "decorate with map value groups". However, this test:
89+
- Uses `map[string]string` for both input AND output of decorator
90+
- May not test the problematic slice→map conversion path
91+
- Doesn't test mixed slice/map consumption scenarios
92+
93+
## CRITICAL DISCOVERY ⚠️
94+
95+
**ROOT CAUSE IDENTIFIED**: Slice decorators are fundamentally incompatible with named value groups.
96+
97+
### What Works ✅
98+
- **Unnamed groups** + **slice decorators** + **slice consumers**
99+
- **Named groups** + **map decorators** + **map consumers** (existing test: `decorate_test.go:455`)
100+
101+
### What's Broken ❌
102+
- **Named groups** + **slice decorators** + **any consumers**
103+
104+
### The Problem
105+
When you provide values with names (`dig.Name()`) and then use a slice decorator (`func([]T) []T`), the decorator strips away the key information needed to reconstruct maps. The slice decorator only sees `[value1, value2]` without knowing which value corresponds to which name.
106+
107+
### Evidence
108+
```go
109+
// This pattern is BROKEN:
110+
c.Provide(func() int{return 1}, dig.Name("a"), dig.Group("nums"))
111+
c.Provide(func() int{return 2}, dig.Name("b"), dig.Group("nums"))
112+
113+
c.Decorate(func(nums []int) []int {
114+
// This sees [1, 2] but has NO KNOWLEDGE of names "a", "b"
115+
return modified_slice
116+
})
117+
118+
// Consumers get UNDECORATED values:
119+
map[string]int `group:"nums"` // Gets original: {"a":1, "b":2}
120+
[]int `group:"nums"` // Gets original: [1, 2]
121+
```
122+
123+
### Why This Happens
124+
1. **Storage**: Decorated values stored under slice type `[]T`
125+
2. **Lookup**: Map consumers look for type `map[string]T`
126+
3. **Mismatch**: No decorated values found, falls back to original providers
127+
4. **Result**: Both slice AND map consumers get undecorated values
128+
129+
## Resolution Priority
130+
131+
**CRITICAL** - This represents a fundamental design limitation where two major features (named value groups + slice decorators) are mutually incompatible.
132+
133+
## Recommended Actions
134+
135+
1. **Document the limitation**: Slice decorators don't work with named value groups
136+
2. **Update TODO comment**: Explain the fundamental incompatibility
137+
3. **Consider design options**:
138+
- Forbid slice decorators when names are present (breaking change)
139+
- Support map decorators as the primary pattern for named groups
140+
- Implement key-preserving slice decoration (complex)
141+
4. **Update tests**: Add tests that demonstrate the limitation and expected behavior

0 commit comments

Comments
 (0)