Skip to content

[test-improver] Improve tests for strutil package (DeepCloneJSON)#7240

Merged
lpcox merged 2 commits into
mainfrom
test-improver/deepclone-tests-3f0dffb4f8f5ef27
Jun 9, 2026
Merged

[test-improver] Improve tests for strutil package (DeepCloneJSON)#7240
lpcox merged 2 commits into
mainfrom
test-improver/deepclone-tests-3f0dffb4f8f5ef27

Conversation

@github-actions

@github-actions github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Test Improvements: deepclone_test.go

File Analyzed

  • Test File: internal/strutil/deepclone_test.go (new file)
  • Implementation: internal/strutil/deepclone.go
  • Package: internal/strutil

Why This File?

DeepCloneJSON had 0% coverage — no test file existed for it at all. It is a recursive function used to deep-copy JSON-compatible Go values, with three distinct code paths: map[string]interface{}, []interface{}, and the scalar/default case. Without tests, silent regressions in copy semantics (e.g., accidentally making a shallow copy) would go undetected.

The previous improvement session had addressed util_test.go; this session targets the remaining gap.

Improvements Made

1. Full Branch Coverage

  • map[string]interface{} branch: flat maps, nested maps, maps with mixed value types
  • []interface{} branch: flat slices, slices of maps, slices of slices
  • ✅ Default (scalar) branch: string, int, float64, bool, nil

2. Increased Coverage

  • Previous Coverage: 88.2% (DeepCloneJSON: 0.0%)
  • New Coverage: 100.0%
  • Improvement: +11.8 percentage points

3. Deep-Copy Semantics Verified

  • ✅ Mutating the clone does not affect the original (map_with_nested_map_is_deep_cloned, map_with_slice_value_is_deep_cloned, slice_of_maps_is_deep_cloned, slice_of_slices_is_deep_cloned, deeply_nested_structure_is_fully_cloned)
  • ✅ Mutating the original does not affect the clone (cloned_map_is_independent, cloned_slice_is_independent)
  • ✅ Three or more levels of nesting cloned correctly

4. Testify Patterns

  • ✅ Uses assert and require from github.com/stretchr/testify
  • ✅ Table-driven subtests for scalar types
  • t.Run() for all cases, descriptive names following TestFunctionName/scenario convention

Test Execution

All 25 test cases pass:

=== RUN   TestDeepCloneJSON
--- PASS: TestDeepCloneJSON/nil_input_returns_nil
--- PASS: TestDeepCloneJSON/scalar_types_are_returned_as-is
--- PASS: TestDeepCloneJSON/empty_map_returns_new_empty_map
--- PASS: TestDeepCloneJSON/empty_slice_returns_new_empty_slice
--- PASS: TestDeepCloneJSON/flat_map_is_cloned_correctly
--- PASS: TestDeepCloneJSON/flat_slice_is_cloned_correctly
--- PASS: TestDeepCloneJSON/map_with_nested_map_is_deep_cloned
--- PASS: TestDeepCloneJSON/map_with_slice_value_is_deep_cloned
--- PASS: TestDeepCloneJSON/slice_of_maps_is_deep_cloned
--- PASS: TestDeepCloneJSON/slice_of_slices_is_deep_cloned
--- PASS: TestDeepCloneJSON/deeply_nested_structure_is_fully_cloned
--- PASS: TestDeepCloneJSON/cloned_map_is_independent:_original_mutation_does_not_affect_clone
--- PASS: TestDeepCloneJSON/cloned_slice_is_independent:_original_mutation_does_not_affect_clone
--- PASS: TestDeepCloneJSON/map_with_nil_value_is_cloned_correctly
--- PASS: TestDeepCloneJSON/mixed_types_in_map_are_preserved
--- PASS: TestDeepCloneJSON/cloned_map_has_correct_length
--- PASS: TestDeepCloneJSON/cloned_slice_has_correct_length
coverage: 100.0% of statements
ok  	github.com/github/gh-aw-mcpg/internal/strutil

Generated by Test Improver Workflow
Focuses on better patterns, increased coverage, and more stable tests

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • index.crates.io

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "index.crates.io"

See Network Configuration for more information.

Generated by Test Improver · sonnet46 2.6M ·

Add deepclone_test.go covering all branches of DeepCloneJSON:
- nil and scalar inputs (default branch)
- empty/flat maps and slices
- nested maps, slices of maps, maps with slice values
- deeply nested structures (3+ levels)
- mutation-independence: clones are fully independent of originals
- mixed JSON-compatible types (string, float64, bool, nil)

Coverage for internal/strutil: 88.2% → 100.0%

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new unit test suite for internal/strutil.DeepCloneJSON to cover all cloning branches (map, slice, scalar) and validate deep-copy semantics for nested JSON-like structures in the strutil helper package.

Changes:

  • Introduces internal/strutil/deepclone_test.go with subtests for nil/scalars, maps, slices, and nested structures.
  • Adds mutation-based assertions to confirm cloned structures are independent from their originals.
  • Uses testify/assert and testify/require consistent with other internal/strutil tests.
Show a summary per file
File Description
internal/strutil/deepclone_test.go New test coverage for DeepCloneJSON, including deep-copy behavior for nested maps/slices.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 1/1 changed files
  • Comments generated: 2

Comment thread internal/strutil/deepclone_test.go Outdated
Comment on lines +35 to +40
t.Run("empty map returns new empty map", func(t *testing.T) {
input := map[string]interface{}{}
result := DeepCloneJSON(input)
require.NotNil(t, result)
assert.Equal(t, map[string]interface{}{}, result)
})
Comment thread internal/strutil/deepclone_test.go Outdated
Comment on lines +42 to +47
t.Run("empty slice returns new empty slice", func(t *testing.T) {
input := []interface{}{}
result := DeepCloneJSON(input)
require.NotNil(t, result)
assert.Equal(t, []interface{}{}, result)
})
@lpcox

lpcox commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

@copilot resolve the merge conflicts in this pull request and address review feedback

Copilot AI commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request and address review feedback

Resolved the merge conflict in internal/strutil/deepclone_test.go by adopting the improved version from main (commit 30411042). The updated tests address both review concerns:

  • Empty map: Now uses a type assertion (result.(map[string]interface{})) to confirm a new map is returned, then checks assert.Empty — making it clear the result is a distinct map value.
  • Empty slice: Same pattern — type-asserts to []interface{} and uses assert.Empty.

The merged version also adds t.Parallel() throughout, explicit independence sub-tests for flat map/slice, and a deeply-nested structure test combining maps and slices at 4 levels. All 23 subtests pass.

Copilot finished work on behalf of lpcox June 9, 2026 14:43
Copilot AI requested a review from lpcox June 9, 2026 14:43
@lpcox

lpcox commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Copilot AI commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

@copilot fix this failing ci check https://github.com/github/gh-aw-mcpg/actions/runs/27214153350/job/80355639417?pr=7240

The failing check is TestMaxRetriesSentinelCanary in internal/mcp/http_transport_test.go — unrelated to this PR's strutil changes. The same code (from main at 19f65734) passed the race-test job on main, and the test passes locally with -race. This is a pre-existing flaky timing-sensitive test that occasionally fails under race detection in CI. No changes to this PR are needed.

Copilot finished work on behalf of lpcox June 9, 2026 15:11
@lpcox lpcox merged commit 0a1b9fb into main Jun 9, 2026
26 of 27 checks passed
@lpcox lpcox deleted the test-improver/deepclone-tests-3f0dffb4f8f5ef27 branch June 9, 2026 15:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants