Skip to content

Commit e159180

Browse files
committed
refactor(params): semantic error testing instead of regex
1 parent b5cf7e0 commit e159180

File tree

2 files changed

+42
-49
lines changed

2 files changed

+42
-49
lines changed

params/json.libevm.go

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ package params
1919
import (
2020
"encoding/json"
2121
"fmt"
22+
23+
"github.com/ava-labs/libevm/internal/libevm/errs"
2224
)
2325

2426
var _ interface {
@@ -43,20 +45,30 @@ func (c *ChainConfig) UnmarshalJSON(data []byte) (err error) {
4345
return UnmarshalChainConfigJSON(data, c, c.extra, ec.reuseJSONRoot)
4446
}
4547

48+
// Internal error identifiers for precise testing.
49+
const (
50+
errIDDecodeJSONIntoCombination errs.ID = iota
51+
errIDDecodeJSONIntoExtra
52+
errIDEncodeJSONCombination
53+
errIDEncodeExtraToRawJSON
54+
errIDEncodeDuplicateJSONKey
55+
errIDNilExtra
56+
)
57+
4658
// UnmarshalChainConfigJSON is equivalent to [ChainConfig.UnmarshalJSON]
4759
// had [Extras] with `C` been registered, but without the need to call
4860
// [RegisterExtras]. The `extra` argument MUST NOT be nil.
4961
func UnmarshalChainConfigJSON[C any](data []byte, config *ChainConfig, extra *C, reuseJSONRoot bool) (err error) {
5062
if extra == nil {
51-
return fmt.Errorf("%T argument is nil; use %T.UnmarshalJSON() directly", extra, config)
63+
return errIDNilExtra.Errorf("%T argument is nil; use %T.UnmarshalJSON() directly", extra, config)
5264
}
5365

5466
if reuseJSONRoot {
5567
if err := json.Unmarshal(data, (*chainConfigWithoutMethods)(config)); err != nil {
5668
return fmt.Errorf("decoding JSON into %T: %s", config, err)
5769
}
5870
if err := json.Unmarshal(data, extra); err != nil {
59-
return fmt.Errorf("decoding JSON into %T: %s", extra, err)
71+
return errIDDecodeJSONIntoExtra.Errorf("decoding JSON into %T: %s", extra, err)
6072
}
6173
return nil
6274
}
@@ -69,7 +81,7 @@ func UnmarshalChainConfigJSON[C any](data []byte, config *ChainConfig, extra *C,
6981
extra,
7082
}
7183
if err := json.Unmarshal(data, &combined); err != nil {
72-
return fmt.Errorf(`decoding JSON into combination of %T and %T (as "extra" key): %s`, config, extra, err)
84+
return errIDDecodeJSONIntoCombination.Errorf(`decoding JSON into combination of %T and %T (as "extra" key): %s`, config, extra, err)
7385
}
7486
return nil
7587
}
@@ -100,7 +112,7 @@ func MarshalChainConfigJSON[C any](config ChainConfig, extra C, reuseJSONRoot bo
100112
}
101113
data, err = json.Marshal(jsonExtra)
102114
if err != nil {
103-
return nil, fmt.Errorf(`encoding combination of %T and %T (as "extra" key) to JSON: %s`, config, extra, err)
115+
return nil, errIDEncodeJSONCombination.Errorf(`encoding combination of %T and %T (as "extra" key) to JSON: %s`, config, extra, err)
104116
}
105117
return data, nil
106118
}
@@ -116,13 +128,13 @@ func MarshalChainConfigJSON[C any](config ChainConfig, extra C, reuseJSONRoot bo
116128
}
117129
extraJSONRaw, err := toJSONRawMessages(extra)
118130
if err != nil {
119-
return nil, fmt.Errorf("converting extra config to JSON raw messages: %s", err)
131+
return nil, errIDEncodeExtraToRawJSON.Errorf("converting extra config to JSON raw messages: %s", err)
120132
}
121133

122134
for k, v := range extraJSONRaw {
123135
_, ok := configJSONRaw[k]
124136
if ok {
125-
return nil, fmt.Errorf("duplicate JSON key %q in ChainConfig and extra %T", k, extra)
137+
return nil, errIDEncodeDuplicateJSONKey.Errorf("duplicate JSON key %q in ChainConfig and extra %T", k, extra)
126138
}
127139
configJSONRaw[k] = v
128140
}

params/json.libevm_test.go

Lines changed: 24 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// You should have received a copy of the GNU Lesser General Public License
1414
// along with the go-ethereum library. If not, see
1515
// <http://www.gnu.org/licenses/>.
16+
1617
package params
1718

1819
import (
@@ -24,6 +25,7 @@ import (
2425
"github.com/stretchr/testify/assert"
2526
"github.com/stretchr/testify/require"
2627

28+
"github.com/ava-labs/libevm/internal/libevm/errs"
2729
"github.com/ava-labs/libevm/libevm/pseudo"
2830
)
2931

@@ -157,42 +159,33 @@ func TestUnmarshalChainConfigJSON_Errors(t *testing.T) {
157159
jsonData string // string for convenience
158160
extra *testExtra
159161
reuseJSONRoot bool
160-
wantConfig ChainConfig
161-
wantExtra any
162-
wantErrRegex string
162+
wantErrID errs.ID
163163
}{
164164
"invalid_json": {
165-
extra: &testExtra{},
166-
wantExtra: &testExtra{},
167-
wantErrRegex: `^decoding JSON into combination of \*.+\.ChainConfig and \*.+\.testExtra \(as "extra" key\): .+$`,
165+
extra: &testExtra{},
166+
wantErrID: errIDDecodeJSONIntoCombination,
168167
},
169168
"nil_extra_at_root_depth": {
170169
jsonData: `{"chainId": 1}`,
171170
extra: nil,
172171
reuseJSONRoot: true,
173-
wantExtra: (*testExtra)(nil),
174-
wantErrRegex: `^\*.+.testExtra argument is nil; use \*.+\.ChainConfig\.UnmarshalJSON\(\) directly$`,
172+
wantErrID: errIDNilExtra,
175173
},
176174
"nil_extra_at_extra_key": {
177-
jsonData: `{"chainId": 1}`,
178-
extra: nil,
179-
wantExtra: (*testExtra)(nil),
180-
wantErrRegex: `^\*.+\.testExtra argument is nil; use \*.+\.ChainConfig.UnmarshalJSON\(\) directly$`,
175+
jsonData: `{"chainId": 1}`,
176+
extra: nil,
177+
wantErrID: errIDNilExtra,
181178
},
182179
"wrong_extra_type_at_extra_key": {
183-
jsonData: `{"chainId": 1, "extra": 1}`,
184-
extra: &testExtra{},
185-
wantConfig: ChainConfig{ChainID: big.NewInt(1)},
186-
wantExtra: &testExtra{},
187-
wantErrRegex: `^decoding JSON into combination of \*.+\.ChainConfig and \*.+\.testExtra \(as "extra" key\): .+$`,
180+
jsonData: `{"chainId": 1, "extra": 1}`,
181+
extra: &testExtra{},
182+
wantErrID: errIDDecodeJSONIntoCombination,
188183
},
189184
"wrong_extra_type_at_root_depth": {
190185
jsonData: `{"chainId": 1, "field": 1}`,
191186
extra: &testExtra{},
192187
reuseJSONRoot: true,
193-
wantConfig: ChainConfig{ChainID: big.NewInt(1)},
194-
wantExtra: &testExtra{},
195-
wantErrRegex: `^decoding JSON into \*.+\.testExtra: .+`,
188+
wantErrID: errIDDecodeJSONIntoExtra,
196189
},
197190
}
198191

@@ -204,14 +197,9 @@ func TestUnmarshalChainConfigJSON_Errors(t *testing.T) {
204197
data := []byte(testCase.jsonData)
205198
config := ChainConfig{}
206199
err := UnmarshalChainConfigJSON(data, &config, testCase.extra, testCase.reuseJSONRoot)
207-
if testCase.wantErrRegex == "" {
208-
require.NoError(t, err)
209-
} else {
210-
require.Error(t, err)
211-
require.Regexp(t, testCase.wantErrRegex, err.Error())
212-
}
213-
assert.Equal(t, testCase.wantConfig, config)
214-
assert.Equal(t, testCase.wantExtra, testCase.extra)
200+
got, ok := errs.IDOf(err)
201+
require.True(t, ok, "errs.IDOf(UnmarshalChainConfigJSON())")
202+
assert.Equalf(t, testCase.wantErrID, got, "UnmarshalChainConfigJSON() got error %v", err)
215203
})
216204
}
217205
}
@@ -223,31 +211,28 @@ func TestMarshalChainConfigJSON_Errors(t *testing.T) {
223211
config ChainConfig
224212
extra any
225213
reuseJSONRoot bool
226-
wantJSONData string // string for convenience
227214
wantErrRegex string
215+
wantErrID errs.ID
228216
}{
229217
"invalid_extra_at_extra_key": {
230218
extra: struct {
231219
Field chan struct{} `json:"field"`
232220
}{},
233-
wantErrRegex: `^encoding combination of .+\.ChainConfig and .+ to JSON: .+$`,
234-
},
235-
"nil_extra_at_extra_key": {
236-
wantJSONData: `{"chainId":null}`,
221+
wantErrID: errIDEncodeJSONCombination,
237222
},
238223
"invalid_extra_at_root_depth": {
239224
extra: struct {
240225
Field chan struct{} `json:"field"`
241226
}{},
242227
reuseJSONRoot: true,
243-
wantErrRegex: "^converting extra config to JSON raw messages: .+$",
228+
wantErrID: errIDEncodeExtraToRawJSON,
244229
},
245230
"duplicate_key": {
246231
extra: struct {
247232
Field string `json:"chainId"`
248233
}{},
249234
reuseJSONRoot: true,
250-
wantErrRegex: `^duplicate JSON key "chainId" in ChainConfig and extra struct .+$`,
235+
wantErrID: errIDEncodeDuplicateJSONKey,
251236
},
252237
}
253238

@@ -257,14 +242,10 @@ func TestMarshalChainConfigJSON_Errors(t *testing.T) {
257242
t.Parallel()
258243

259244
config := ChainConfig{}
260-
data, err := MarshalChainConfigJSON(config, testCase.extra, testCase.reuseJSONRoot)
261-
if testCase.wantErrRegex == "" {
262-
require.NoError(t, err)
263-
} else {
264-
require.Error(t, err)
265-
assert.Regexp(t, testCase.wantErrRegex, err.Error())
266-
}
267-
assert.Equal(t, testCase.wantJSONData, string(data))
245+
_, err := MarshalChainConfigJSON(config, testCase.extra, testCase.reuseJSONRoot)
246+
got, ok := errs.IDOf(err)
247+
require.True(t, ok, "errs.IDOf(MarshalChainConfigJSON())")
248+
assert.Equalf(t, testCase.wantErrID, got, "MarshalChainConfigJSON() got error %v", err)
268249
})
269250
}
270251
}

0 commit comments

Comments
 (0)