Skip to content

refactor(platform): tighten EvaluatorResponse — ExecTime, ScriptExeID, AsMap#141

Open
robbyt wants to merge 4 commits into
mainfrom
claude/review-repo-improvements-NDaxm
Open

refactor(platform): tighten EvaluatorResponse — ExecTime, ScriptExeID, AsMap#141
robbyt wants to merge 4 commits into
mainfrom
claude/review-repo-improvements-NDaxm

Conversation

@robbyt
Copy link
Copy Markdown
Owner

@robbyt robbyt commented May 20, 2026

Summary

Three breaking changes to platform.EvaluatorResponse:

  1. GetScriptExeID() stringScriptExeID() string — drop the Get prefix per Go style
  2. GetExecTime() stringExecTime() time.Duration — stop stringifying a Duration at the API boundary; all three implementations already stored time.Duration internally
  3. New AsMap() (map[string]any, error) — returns the result as a typed map, with an error of the form "AsMap: expected map[string]any, got <T>" when the underlying value has a different shape

Per the user's calls: only AsMap is added (other typed shapes — AsString, AsBool, AsInt, AsSlice — had zero current usage, so YAGNI applies). Return shape is error rather than (value, ok).

The migration converts 40+ existing result.Interface().(map[string]any); require.True(t, ok) test sites to result.AsMap(); require.NoError(t, err), which validates the helper's value.

Files touched:

  • platform/evaluatorResponse.go — interface (added time import)
  • engines/{extism,risor,starlark}/evaluator/response.go — implementations
  • platform/mocks_test.go, polyscript_mocks_test.go — mock impls (added time import, new AsMap)
  • engines/{extism,risor,starlark}/evaluator/response_test.go — rename calls, switch Duration assertions
  • engines/integration_test.go, readme_test.go, polyscript_*_test.go, engines/extism/new_test.go, engines/extism/evaluator/evaluator_test.goAsMap() migration
  • platform/evaluatorResponse_test.go, platform/evaluator_test.go — mock setup + Duration assertions
  • CHANGELOG.md[Unreleased] > Changed entry

Closes #86.

Test plan

  • go build ./... clean
  • go vet ./... clean
  • go test -race -count=1 ./... full suite green
  • grep -rn 'GetExecTime\|GetScriptExeID' --include='*.go' . returns zero hits
  • grep -rn 'Interface().(map\[string\]any)' --include='*.go' . returns zero hits (down from 43+)
  • CI: SonarQube, dependency-review, Copilot review

https://claude.ai/code/session_01C61VEAmjxSnX5Xhbab8NvL


Generated by Claude Code

…, AsMap

Three breaking changes to the platform.EvaluatorResponse interface:

1. GetScriptExeID() string → ScriptExeID() string (drop Get prefix)
2. GetExecTime() string → ExecTime() time.Duration (no longer stringified
   at the boundary; implementations already stored time.Duration internally)
3. New AsMap() (map[string]any, error) — returns the result as a typed map,
   with an error of the form "AsMap: expected map[string]any, got <T>" when
   the underlying value has a different shape

Migrates 40+ existing `result.Interface().(map[string]any); require.True(t, ok)`
test sites to `result.AsMap(); require.NoError(t, err)`, which validates the
helper's value. Other typed accessors (AsString, AsBool, AsInt, AsSlice) are
not added — they have zero current usage and YAGNI applies.

Updates the three implementations (extism, risor, starlark) and all consuming
tests/mocks (platform/mocks_test.go, polyscript_mocks_test.go,
engines/integration_test.go, readme_test.go, polyscript_*_test.go).

Closes #86.

https://claude.ai/code/session_01C61VEAmjxSnX5Xhbab8NvL
Copilot AI review requested due to automatic review settings May 20, 2026 04:22
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 20, 2026

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR tightens the platform.EvaluatorResponse API by removing Go-anti-idiomatic getter names, returning execution time as time.Duration, and adding a typed AsMap() accessor to reduce Interface().(map[string]any) casting boilerplate across the test suite.

Changes:

  • Renamed metadata getters to ScriptExeID() and ExecTime() (now time.Duration) across the interface, engine implementations, mocks, and tests.
  • Added AsMap() (map[string]any, error) to EvaluatorResponse and implemented it in Extism/Risor/Starlark responses.
  • Migrated many tests from Interface().(map[string]any) to AsMap() and updated duration assertions.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
platform/evaluatorResponse.go Updates the public EvaluatorResponse interface (rename getters, ExecTime() returns time.Duration, adds AsMap()).
engines/extism/evaluator/response.go Implements ScriptExeID(), ExecTime() time.Duration, and AsMap() for Extism results.
engines/risor/evaluator/response.go Implements ScriptExeID(), ExecTime() time.Duration, and AsMap() for Risor results.
engines/starlark/evaluator/response.go Implements ScriptExeID(), ExecTime() time.Duration, and AsMap() for Starlark results.
platform/mocks_test.go Updates test mocks to satisfy the new interface (including AsMap() and time.Duration exec time).
polyscript_mocks_test.go Updates polyscript test mocks to satisfy the new interface (including AsMap() and time.Duration exec time).
platform/evaluatorResponse_test.go Updates interface conformance tests for renamed methods and duration type.
platform/evaluator_test.go Updates evaluator interface tests to use ScriptExeID() and ExecTime() time.Duration.
engines/extism/evaluator/response_test.go Updates Extism response tests for renamed methods and duration assertions.
engines/risor/evaluator/response_test.go Updates Risor response tests for renamed methods and duration assertions.
engines/starlark/evaluator/response_test.go Updates Starlark response tests for renamed methods and duration assertions.
engines/extism/evaluator/evaluator_test.go Migrates evaluator tests to use AsMap() instead of map type assertions.
engines/extism/new_test.go Migrates end-to-end loader test to use AsMap().
engines/integration_test.go Migrates integration tests to use AsMap() broadly.
readme_test.go Migrates README example tests to use AsMap().
polyscript_test.go Migrates polyscript tests to use AsMap().
polyscript_options_test.go Migrates options tests to use AsMap().
polyscript_extism_test.go Migrates Extism polyscript tests to use AsMap().
CHANGELOG.md Documents the breaking changes to EvaluatorResponse and the new AsMap() helper.

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

Comment thread platform/mocks_test.go
Comment thread polyscript_mocks_test.go
Comment thread platform/evaluatorResponse.go
claude added 3 commits May 20, 2026 04:26
SonarQube reported 30% coverage on new code (required ≥80%) because
the AsMap() error branch (non-map underlying value) was unexercised.
The 40+ migrated test sites cover only the success path.

Adds TestExecResultAsMap to each engine's response_test.go with three
subtests:
- success: underlying value is a real map
- error on string: returns the typed error message
- error on nil/int: confirms the %T format string reports the actual type

Per-package coverage after these tests:
- extism/evaluator: 96.2%
- risor/evaluator:  90.8%
- starlark/evaluator: 83.5%

https://claude.ai/code/session_01C61VEAmjxSnX5Xhbab8NvL
Per Copilot review on #141 — the mock previously discarded the type
assertion result and could return (nil, nil) when a test author
configured a non-map Return value, silently diverging from the real
AsMap contract.

The mock now:
- Returns (nil, nil) only when explicitly configured with nil + nil
- Returns the configured error when the asserted value isn't a map but
  an error was provided
- Synthesizes the production error format ("AsMap: expected
  map[string]any, got %T") when the asserted value isn't a map and no
  error was provided

Applies to both platform/mocks_test.go and polyscript_mocks_test.go.

https://claude.ai/code/session_01C61VEAmjxSnX5Xhbab8NvL
Replaces the inline `fmt.Errorf("AsMap: expected map[string]any, got %T", v)`
with a wrapped sentinel in each engine's evaluator package:

- engines/extism/evaluator.ErrAsMapTypeMismatch
  = "extism: AsMap expected map[string]any"
- engines/risor/evaluator.ErrAsMapTypeMismatch
  = "risor: AsMap expected map[string]any"
- engines/starlark/evaluator.ErrAsMapTypeMismatch
  = "starlark: AsMap expected map[string]any"

Each AsMap now returns `fmt.Errorf("%w, got %T", ErrAsMapTypeMismatch, v)`,
so callers can `errors.Is(err, evaluator.ErrAsMapTypeMismatch)` for the
type-mismatch case and still read the concrete Go type from err.Error().

Matches the existing per-package sentinel pattern in
engines/{extism,risor,starlark}/compiler/errors.go.

Tests switched from substring assertions on the full message to
require.ErrorIs(t, err, ErrAsMapTypeMismatch) + a smaller substring
assertion on just the "got <T>" tail.

https://claude.ai/code/session_01C61VEAmjxSnX5Xhbab8NvL
@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[v1][breaking] Tighten EvaluatorResponse interface (typed accessors, time.Duration, drop Get prefix)

3 participants