Repository: zeromicro/go-zero
Pull request #3387 (2023-06-30 09:16:22)

feat: add detail type mismatch info in number fields check (#3386)
add a feature I proposed in #3386 

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/zeromicro/go-zero/pull/3387?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) Report
> Merging [#3387](https://app.codecov.io/gh/zeromicro/go-zero/pull/3387?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (4b3f2b3) into [master](https://app.codecov.io/gh/zeromicro/go-zero/commit/4cbfdb3d747efa64f220f2148398bdb0bc8adba1?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (4cbfdb3) will **decrease** coverage by `0.02%`.
> The diff coverage is `100.00%`.


| [Impacted Files](https://app.codecov.io/gh/zeromicro/go-zero/pull/3387?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | Coverage Δ | |
|---|---|---|
| [core/mapping/unmarshaler.go](https://app.codecov.io/gh/zeromicro/go-zero/pull/3387?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-Y29yZS9tYXBwaW5nL3VubWFyc2hhbGVyLmdv) | `96.36% <100.00%> (+0.01%)` | :arrow_up: |

... and [1 file with indirect coverage changes](https://app.codecov.io/gh/zeromicro/go-zero/pull/3387/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None)

chenquan: Thank you very much for your PR, please add more test cases.
lxy1992: > 

Ok, will do it today, thanks for reply
lxy1992: @chenquan I have add a UT for this function, the coverage is go up
zcong1993: > @chenquan I have add a UT for this function, the coverage is go up

can you add some non primitive type mismatch cases in UT？

Patch:
diff --git a/core/mapping/unmarshaler.go b/core/mapping/unmarshaler.go
index d753d246..24920338 100644
--- a/core/mapping/unmarshaler.go
+++ b/core/mapping/unmarshaler.go
@@ -618,7 +618,7 @@ func (u *Unmarshaler) processFieldPrimitiveWithJSONNumber(fieldType reflect.Type
 
 		target.SetFloat(fValue)
 	default:
-		return newTypeMismatchError(fullName)
+		return newTypeMismatchErrorWithHint(fullName, value.Type().String(), typeKind.String())
 	}
 
 	SetValue(fieldType, value, target)
@@ -1054,6 +1054,10 @@ func newTypeMismatchError(name string) error {
 	return fmt.Errorf("type mismatch for field %q", name)
 }
 
+func newTypeMismatchErrorWithHint(name, errorType, rightType string) error {
+	return fmt.Errorf("type mismatch for field %q, expected %q, got %q", name, rightType, errorType)
+}
+
 func readKeys(key string) []string {
 	cacheKeysLock.Lock()
 	keys, ok := cacheKeys[key]


Test patch:
diff --git a/core/mapping/unmarshaler_test.go b/core/mapping/unmarshaler_test.go
index 72038e4e..fae6f3ef 100644
--- a/core/mapping/unmarshaler_test.go
+++ b/core/mapping/unmarshaler_test.go
@@ -3,6 +3,7 @@ package mapping
 import (
 	"encoding/json"
 	"fmt"
+	"reflect"
 	"strconv"
 	"strings"
 	"testing"
@@ -4981,6 +4982,32 @@ func TestUnmarshaler_Unmarshal(t *testing.T) {
 	})
 }
 
+// TestUnmarshalerProcessFieldPrimitiveWithJSONNumber test the number type check.
+func TestUnmarshalerProcessFieldPrimitiveWithJSONNumber(t *testing.T) {
+	t.Run("wrong type", func(t *testing.T) {
+		expectValue := "1"
+		realValue := 1
+		fieldType := reflect.TypeOf(expectValue)
+		value := reflect.ValueOf(&realValue) // pass a pointer to the value
+		v := json.Number(expectValue)
+		m := NewUnmarshaler("field")
+		err := m.processFieldPrimitiveWithJSONNumber(fieldType, value.Elem(), v, &fieldOptionsWithContext{}, "field")
+		assert.Error(t, err)
+		assert.Equal(t, "type mismatch for field \"field\", expected \"string\", got \"int\"", err.Error())
+	})
+	t.Run("right type", func(t *testing.T) {
+		expectValue := int64(1)
+		realValue := int64(1)
+		fieldType := reflect.TypeOf(expectValue)
+		value := reflect.ValueOf(&realValue) // pass a pointer to the value
+		v := json.Number(strconv.FormatInt(expectValue, 10))
+		m := NewUnmarshaler("field")
+		err := m.processFieldPrimitiveWithJSONNumber(fieldType, value.Elem(), v, &fieldOptionsWithContext{}, "field")
+		assert.NoError(t, err)
+	})
+
+}
+
 func TestGetValueWithChainedKeys(t *testing.T) {
 	t.Run("no key", func(t *testing.T) {
 		_, ok := getValueWithChainedKeys(nil, []string{})