Skip to content

Conversation

@pietern
Copy link
Contributor

@pietern pietern commented Jan 29, 2026

Changes

Implements conversion support for SDK native types across the dyn package conversion layer (FromTyped, ToTyped, Normalize). Supports three SDK types that use custom JSON marshaling:

  • duration.Duration: Protobuf duration format (e.g., "300s")
  • time.Time: RFC3339 timestamp format (e.g., "2023-12-25T10:30:00Z")
  • fieldmask.FieldMask: Comma-separated paths (e.g., "name,age,email")

The implementation uses a generic approach with all SDK-specific code in sdk_native_types.go and sdk_native_types_test.go.

Why

The new Postgres APIs use these types and need the to/from conversion to work.

Also see databricks/databricks-sdk-go#1271.

pietern and others added 2 commits January 28, 2026 17:08
Implements conversion support for SDK native types across the dyn
package conversion layer (FromTyped, ToTyped, Normalize). Supports
three SDK types that use custom JSON marshaling:

- duration.Duration: Protobuf duration format (e.g., "300s")
- time.Time: RFC3339 timestamp format (e.g., "2023-12-25T10:30:00Z")
- fieldmask.FieldMask: Comma-separated paths (e.g., "name,age,email")

The implementation uses a generic approach with all SDK-specific code
in sdk_native_types.go and sdk_native_types_test.go. All SDK type
imports are prefixed with "sdk" for clarity.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Adds comprehensive round-trip tests using actual SDK types from the
postgres service (BranchSpec and UpdateBranchRequest) to verify that
serialization and deserialization work correctly in real-world usage.

Tests cover:
- BranchSpec with time.Time and duration.Duration fields
- UpdateRequest with fieldmask.FieldMask field
- Full round-trip FromTyped -> dyn.Value -> ToTyped
- Normalization with SDK types

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
return dyn.InvalidValue, err
}

// The JSON marshaling produces a quoted string, unmarshal to get the raw string.
Copy link
Contributor

Choose a reason for hiding this comment

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

This only handles types that are encoded via string; Are all SDK Native types encoded via string?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

At the moment, yes.

Copy link
Contributor

@hectorcast-db hectorcast-db Jan 30, 2026

Choose a reason for hiding this comment

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

From a Proto point of view, there is Value, which represents an arbitrary JSON.
https://protobuf.dev/reference/protobuf/google.protobuf/#value

But we do represent it using a json.RawMessage in the SDK, so it may not need special handling here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@hectorcast-db Is that used in any of our structs today?

If there is an example we can figure out how to make it work here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Currently, no team is using it. Someone just tried to introduce it, but it is not supported in the Rust backend, so it was postponed. (Java/Scala backends are supported).
We do have one instance not as a normal resource, but as part of the Operation object in LRO.
https://github.com/databricks/databricks-sdk-go/blob/98181c316a238887661235d656818dfbdcafc92f/service/postgres/model.go#L258
It is not something that the CLI usually sees, but it may help to understand how data is transferred and stored.

switch src.Kind() {
case dyn.KindString:
// Use JSON unmarshaling since SDK native types implement json.Unmarshaler.
jsonStr := fmt.Sprintf("%q", src.MustString())
Copy link
Contributor

Choose a reason for hiding this comment

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

This uses go string representation, not JSON, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right, fixed to use json.Marshal of the string to produce the unmarshallable representation.

assert.Equal(t, dyn.V("300s"), nv)
}

func TestFromTypedDurationPointer(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This says Pointer in the name, but I don't see a pointer, where is it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed with the table test.


err := ToTyped(&out, v)
require.NoError(t, err)
assert.Equal(t, 300*time.Second, out.AsDuration())
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there any way to organize these tests as
a) table tests
b) automatically checking roundtrip

so you can specify
{
typed: sdkduration.Duration(300*time.Second),
string: "300s"
}

and it checks both fromType and toTyped as well as pointer to typed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adding a table test.

@eng-dev-ecosystem-bot
Copy link
Collaborator

eng-dev-ecosystem-bot commented Jan 29, 2026

Commit: df65828

Run: 21511502672

Env 🟨​KNOWN 🔄​flaky 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
🟨​ aws linux 7 1 7 442 708 25:10
🟨​ aws windows 7 1 7 414 716 21:24
🟨​ aws-ucws linux 5 8 5 641 578 96:17
🟨​ aws-ucws windows 5 2 8 5 608 587 83:45
💚​ azure linux 2 9 442 707 28:08
💚​ azure windows 2 9 414 715 23:09
🟨​ azure-ucws linux 3 4 7 637 577 95:15
🟨​ azure-ucws windows 3 4 7 606 586 82:02
💚​ gcp linux 2 9 431 713 22:36
💚​ gcp windows 2 9 403 721 20:34
20 interesting tests: 9 KNOWN, 5 SKIP, 4 RECOVERED, 2 flaky
Test Name aws linux aws windows aws-ucws linux aws-ucws windows azure linux azure windows azure-ucws linux azure-ucws windows gcp linux gcp windows
🟨​ TestAccept 🟨​K 🟨​K 🟨​K 🟨​K 💚​R 💚​R 🟨​K 🟨​K 💚​R 💚​R
🙈​ TestAccept/bundle/deployment/bind/alert 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/generate/alert 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestAccept/bundle/invariant/no_drift 🙈​S 🙈​S 🟨​K 🟨​K 🙈​S 🙈​S 🟨​K 🟨​K 🙈​S 🙈​S
🟨​ TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=alert.yml.tmpl 🟨​K 🟨​K 🟨​K 🟨​K
🙈​ TestAccept/bundle/resources/alerts/basic 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/alerts/with_file 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/permissions 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions 🟨​K 🟨​K 🟨​K 🟨​K 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions/DATABRICKS_BUNDLE_ENGINE=direct 🟨​K 🟨​K 🟨​K 🟨​K
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions/DATABRICKS_BUNDLE_ENGINE=terraform 🟨​K 🟨​K 💚​R 💚​R
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions 🟨​K 🟨​K 💚​R 💚​R 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=direct 🟨​K 🟨​K 💚​R 💚​R
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=terraform 🟨​K 🟨​K 💚​R 💚​R
💚​ TestAccept/bundle/resources/synced_database_tables/basic 🙈​S 🙈​S 💚​R 💚​R 🙈​S 🙈​S 💚​R 💚​R 🙈​S 🙈​S
💚​ TestAccept/bundle/resources/synced_database_tables/basic/DATABRICKS_BUNDLE_ENGINE=direct 💚​R 💚​R 💚​R 💚​R
💚​ TestAccept/bundle/resources/synced_database_tables/basic/DATABRICKS_BUNDLE_ENGINE=terraform 💚​R 💚​R 💚​R 💚​R
💚​ TestAccept/ssh/connection 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
🔄​ TestFilerWorkspaceNotebook ✅​p ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p
🔄​ TestFilerWorkspaceNotebook/rNb.r ✅​p ✅​p ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p
Top 50 slowest tests (at least 2 minutes):
duration env testname
8:41 azure-ucws linux TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=synced_database_table.yml.tmpl
7:34 aws-ucws linux TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=synced_database_table.yml.tmpl
7:24 aws-ucws linux TestAccept/bundle/resources/synced_database_tables/basic/DATABRICKS_BUNDLE_ENGINE=direct
7:10 aws-ucws linux TestAccept/bundle/resources/synced_database_tables/basic/DATABRICKS_BUNDLE_ENGINE=terraform
6:59 aws-ucws linux TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=database_instance.yml.tmpl
6:41 aws-ucws windows TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=database_instance.yml.tmpl
6:38 aws-ucws linux TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=database_catalog.yml.tmpl
6:10 aws-ucws windows TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=database_catalog.yml.tmpl
5:55 aws-ucws windows TestAccept/bundle/resources/synced_database_tables/basic/DATABRICKS_BUNDLE_ENGINE=direct
5:44 aws-ucws windows TestAccept/bundle/resources/synced_database_tables/basic/DATABRICKS_BUNDLE_ENGINE=terraform
5:39 aws-ucws windows TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=synced_database_table.yml.tmpl
5:39 aws-ucws linux TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=terraform
5:38 azure-ucws linux TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=direct
5:22 gcp windows TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=direct
5:20 aws-ucws linux TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=direct
5:09 gcp linux TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=direct
4:36 azure-ucws linux TestAccept/bundle/resources/synced_database_tables/basic/DATABRICKS_BUNDLE_ENGINE=direct
4:34 azure-ucws windows TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=synced_database_table.yml.tmpl
4:34 azure-ucws linux TestAccept/bundle/resources/synced_database_tables/basic/DATABRICKS_BUNDLE_ENGINE=terraform
4:30 azure-ucws linux TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=database_catalog.yml.tmpl
4:15 azure-ucws windows TestAccept/bundle/resources/synced_database_tables/basic/DATABRICKS_BUNDLE_ENGINE=direct
4:09 azure-ucws windows TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=database_instance.yml.tmpl
3:54 azure-ucws linux TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=terraform
3:45 azure windows TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=direct
3:38 gcp linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:26 gcp windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:22 azure-ucws linux TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=database_instance.yml.tmpl
3:18 gcp windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:16 azure windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:14 azure-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:10 gcp linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:01 azure-ucws windows TestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=database_catalog.yml.tmpl
2:49 azure-ucws linux TestAccept/bundle/resources/registered_models/basic/DATABRICKS_BUNDLE_ENGINE=terraform
2:49 azure-ucws windows TestAccept/bundle/resources/synced_database_tables/basic/DATABRICKS_BUNDLE_ENGINE=terraform
2:48 aws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:48 aws-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:46 aws-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:45 aws-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:45 aws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:44 aws linux TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=terraform
2:43 aws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:43 aws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:39 azure windows TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=terraform
2:38 azure-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:38 aws linux TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=direct
2:37 azure-ucws linux TestAccept/bundle/templates/default-python/combinations/serverless/DATABRICKS_BUNDLE_ENGINE=terraform/DLT=yes/NBOOK=yes/PY=yes/READPLAN=
2:28 aws windows TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=terraform
2:27 aws-ucws windows TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=direct
2:26 gcp linux TestAccept
2:25 aws-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct

pietern and others added 10 commits January 29, 2026 10:15
Update test code to follow linter recommendations including struct field
alignment and using assert.True for boolean assertions.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1. Clarified that all SDK native types marshal to JSON strings with
   improved comments explaining the conversion process.

2. Fixed JSON encoding in toTypedSDKNative to use json.Marshal instead
   of fmt.Sprintf("%q") for proper JSON string literal creation.

3. Fixed TestFromTypedDurationPointer to actually test with a pointer
   instead of a value.

4. Added comprehensive table-driven roundtrip tests with reusable
   equality check functions for all three SDK types (Duration, Time,
   FieldMask) testing both value and pointer variants.

5. Removed redundant basic tests that are now covered by the roundtrip
   tests, while keeping edge case tests for nil, zero, error cases,
   normalization, and in-struct scenarios.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Removed 18 tests that are now covered by the comprehensive roundtrip
tests. The remaining tests focus on unique edge cases:
- Nil value handling (one per type)
- Zero values
- Error cases (invalid format, wrong type)
- Empty values (FieldMask)
- Normalize with nil (important edge case)
- End-to-end tests with real postgres types

This keeps test coverage while improving maintainability.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Converted 13 individual edge case tests into 3 table-driven tests:
- TestSDKNativeTypesNilValues: Tests nil handling for FromTyped and
  Normalize across all 3 SDK types (6 subtests)
- TestSDKNativeTypesErrors: Tests error handling for ToTyped with
  invalid inputs across all 3 types (4 subtests)
- TestSDKNativeTypesSpecialCases: Tests zero values and empty
  FieldMask (3 subtests)

Final test suite for SDK native types:
- 1 comprehensive roundtrip test (18 subtests)
- 3 edge case table tests (13 subtests)
- 3 end-to-end tests with real postgres types

This improves maintainability while preserving full test coverage.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Split TestSDKNativeTypesRoundtrip into three type-specific tests:
- TestDurationRoundtrip (3 cases: 5min, 7days, 1hour)
- TestTimeRoundtrip (3 cases: no_nanos, with_nanos, epoch)
- TestFieldMaskRoundtrip (3 cases: single, multiple, nested)

Benefits:
- No more type switches or 'any' types in test tables
- Each test is strongly typed with specific field names
- Clearer test structure and better type safety
- Still maintains same coverage (18 subtests total)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Removed the three helper functions (assertDurationEqual, assertTimeEqual,
assertFieldMaskEqual) and inlined their logic directly where used:
- Duration: assert.Equal(t, src.AsDuration(), out.AsDuration())
- Time: assert.Equal(t, src.AsTime(), out.AsTime())
- FieldMask: assert.Equal(t, src.Paths, out.Paths)

Benefits:
- Simpler code with fewer abstractions
- Easier to understand what's being compared
- No need for 'any' types or type assertions in helpers
- Still maintains same test coverage

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Replaced testFunc callback pattern with simple subtests:

Before (fake table tests):
- TestSDKNativeTypesNilValues with testFunc callbacks
- TestSDKNativeTypesErrors with testFunc callbacks
- TestSDKNativeTypesSpecialCases with testFunc callbacks

After (simple subtests):
- TestNilValuesFromTyped - 3 subtests, one per type
- TestNilValuesNormalize - 3 subtests, one per type
- TestToTypedErrors - 4 subtests for error cases
- TestSpecialCases - 3 subtests for edge cases

Benefits:
- No testFunc callbacks - just straightforward t.Run subtests
- Each test is self-contained and easy to read
- Reduced repetition (e.g., wrongTypeInput shared in TestToTypedErrors)
- Simplified diagnostic assertions (just check key fields)
- Same test coverage with clearer structure

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove duplicate and stale comments.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@pietern pietern temporarily deployed to test-trigger-is January 30, 2026 09:46 — with GitHub Actions Inactive
func TestTimeRoundtrip(t *testing.T) {
tests := []struct {
name string
time time.Time
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not replace time time.Time with obj any and handle all type conversion in a single test?

The ToTyped/FromTyped functions are already any-based, so that aligns well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Two reasons: the target type in ToTyped is defined inline, changing it means using more reflection, and the equality test needs a different function call for every type. Moving that into a single test means adding a switch/case on type, defying the purpose.

Copy link
Contributor

Choose a reason for hiding this comment

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

Two reasons: the target type in ToTyped is defined inline, changing it means using more reflection,

I don't insist, but reflection can be avoided, out can be another entry in table test:

e.g. out: &sdktime.Time{}, (did not test).

the equality test needs a different function call for every type.

For my understanding, are you referring to this?

  		assert.Equal(t, src.AsTime(), out.AsTime())
  		assert.Equal(t, src.Paths, out.Paths)

why not do assert.Equal(t, src, out) in both cases?

}

// Handle SDK native types using JSON unmarshaling.
if isSDKNativeType(dstv.Type()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there any way we can incorporate this into switch below? It's nice to see overview for each type and this hides it.

If it must be handled outside, can you add an explanation comment, why it's special-cased here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, looking into it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's not possible to inline it into the switch because it switches on the Kind() which is always reflect.Struct.

Inlining the isSDKNativeType is not worth it because it duplicates the logic between FromTyped and ToTyped.

@pietern pietern requested a review from denik January 30, 2026 14:16
Copy link
Contributor

@denik denik left a comment

Choose a reason for hiding this comment

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

Stamping, but I think there are a few more opportunities to reduce LOC in tests by switching to table tests. Claude should be able to convert if prompted explicitly.

})
}

func TestNilValuesNormalize(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This and previous tests look like they can be written as a single table test.

// All SDK native types marshal to JSON strings. Unmarshal to get the raw string value.
// For example: duration.Duration(300s) -> JSON "300s" -> string "300s"
var str string
if err := json.Unmarshal(jsonBytes, &str); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

can this be a variable reference?

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.

5 participants