chore: improve unit test coverage for decoder logic area#223
Conversation
|
Hi @HT154 , While working on the decoder tests, I noticed that Current approach: func (d *decoder) Decode(typ reflect.Type) (*reflect.Value, error) {
// ...
switch typ.Kind() {
case reflect.Ptr:
return d.decodePointer(typ)
case reflect.Struct:
return d.decodePklObject(typ, true)
case reflect.Bool:
return d.decodeBool()
// ... 13 more cases
default:
return nil, &InternalError{...}
}
}Proposed approach: type decoderFunc func(typ reflect.Type) (*reflect.Value, error)
// initialized once per decoder instance
kindsDecoders map[reflect.Kind]decoderFunc
func (d *decoder) Decode(typ reflect.Type) (*reflect.Value, error) {
// ...
decoderFunc, found := d.kindsDecoders[typ.Kind()]
if !found {
return nil, &InternalError{...}
}
return decoderFunc(typ)
}Why I think this could be beneficial:
What I'd keep in mind:
Would love to hear your thoughts on whether this direction is welcome before I invest time in it. Thanks! |
7a55097 to
bae8b99
Compare
|
Hello @HT154, could you please enable the CI 🙌 |
|
@HT154, PR now ready for review 👌 |
|
Hello @HT154, really appreciate if you have a chance to review the PR🙏 |
HT154
left a comment
There was a problem hiding this comment.
Mostly clarifying questions for you, plus a bit of housekeeping
|
@HT154, really helpful comments, I have left my justifications, and also addressed all of the comments. |
3c32fcb to
6c661b3
Compare
chore: simplifying the test decoder want assertion against got chore: revert decode_primitives.go copy right chore: refactor tc.data in TestDecoder_Decode chore: fixing CI failures related to linter and copy the right date chore: implementing complete unit tests for the decoder.go chore: implement unit tests for decoding duration chore: implement unit tests for decoding interfaces with strings chore: implement unit tests for decoding slices and maps chore: implement unit tests for decoding pointers chore: revert the float32 handling as pkl relies only on float64 chore: implement decoding for primitive floats chore: implement missing float32 decoding functionality
6c661b3 to
00dbd54
Compare
I don't think we'd be opposed to changing this, but my primary concern with the map approach is performance. If we do take that change, I would want to see benchmarking to show that switching does not cause a performance regression. |
|
@HT154 |
PR Description:
Adding unit tests for the decoder implementation
Summary
Coverage improvement
DecodedecodePklObjectdecodeInt64decodeUint64decodeFloat64decodeMapdecodeSlicedecodeInterfaceparseStructOptsOverall package coverage: 63.9% -> 65.8%
Observation: potential panic in
decodeInterfaceWhile writing tests, I discovered that
decodeInterface(decoder.go:181-182) passes the rawinterface{}type todecodeMapImplwhen it encounters a msgpack map.decodeMapImplcallsreflect.MakeMapWithSize(inType, ...)which panics becauseinterface{}is not a map type.decodePklObjectalready handles this correctly at line 221 by hardcodingmap[any]any{}decodeInterfacelevel, or does it always come wrapped in a Pkl preamble array? If it can occur, the fix would be to default tomap[any]any{}before callingdecodeMapImpl.Test plan
go test ./pkl/ -run TestDecoder_Decode)go test ./pkl/...)