github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/standard_compatible_test.go (about)

     1  package jzon
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"os"
     7  	"reflect"
     8  	"strings"
     9  	"testing"
    10  	"unsafe"
    11  
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  var (
    16  	compatibleOnError = os.Getenv("COMPATIBLE_ON_ERROR") == "1"
    17  )
    18  
    19  func nestedArray1(count int) string {
    20  	return strings.Repeat(" [", count) + " [ ] " +
    21  		strings.Repeat("] ", count)
    22  }
    23  
    24  func nestedArray2(count int) string {
    25  	return strings.Repeat(" [ [ ], ", count) + " [ ] " +
    26  		strings.Repeat("] ", count)
    27  }
    28  
    29  func nestedArrayWithObject(count int) string {
    30  	return strings.Repeat(" [ { }, ", count) + " [ ] " +
    31  		strings.Repeat("] ", count)
    32  }
    33  
    34  func nestedObject(count int) string {
    35  	return strings.Repeat(` { "a" : { }, "b": `, count) + " { } " +
    36  		strings.Repeat("} ", count)
    37  }
    38  
    39  func nestedObjectWithArray(count int) string {
    40  	return strings.Repeat(` { "a" : [ ], "b": `, count) + " [ ] " +
    41  		strings.Repeat("} ", count)
    42  }
    43  
    44  type printValueKey struct {
    45  	rtype rtype
    46  	ptr   uintptr
    47  }
    48  
    49  func (pk printValueKey) String() string {
    50  	return fmt.Sprintf("<%x %x>", pk.rtype, pk.ptr)
    51  }
    52  
    53  func printValue(t *testing.T, prefix string, o interface{}) {
    54  	prefix += " "
    55  	if o == nil {
    56  		t.Logf(prefix + "nil")
    57  		return
    58  	}
    59  	visited := map[printValueKey]bool{}
    60  	oV := reflect.ValueOf(o)
    61  	for indent := prefix; ; indent += "  " {
    62  		i := oV.Interface()
    63  		ef := (*eface)(unsafe.Pointer(&i))
    64  		vk := printValueKey{ef.rtype, uintptr(ef.data)}
    65  
    66  		k := oV.Kind()
    67  		t.Logf(indent+"%+v %+v %v", oV.Type(), oV, vk)
    68  
    69  		if k != reflect.Interface && k != reflect.Ptr {
    70  			break
    71  		}
    72  		if oV.IsNil() {
    73  			break
    74  		}
    75  
    76  		if visited[vk] {
    77  			t.Logf(indent + "  visited...")
    78  			break
    79  		}
    80  		visited[vk] = true
    81  
    82  		oV = oV.Elem()
    83  	}
    84  }
    85  
    86  func checkDecodeWithStandard(t *testing.T, decCfg *DecoderConfig, data string, ex error, exp, got interface{}) {
    87  	b := []byte(data)
    88  	expErr := json.Unmarshal(b, exp)
    89  	gotErr := decCfg.Unmarshal(b, got)
    90  	t.Logf("\nexpErr: %+v\ngotErr: %+v", expErr, gotErr)
    91  	noError := expErr == nil
    92  	if noError {
    93  		printValue(t, "exp", reflect.ValueOf(exp).Elem().Interface())
    94  	}
    95  	require.Equal(t, noError, gotErr == nil,
    96  		"exp %+v\ngot %+v", expErr, gotErr)
    97  	require.Equalf(t, noError, ex == nil, "exp err: %v\ngot err: %v", ex, gotErr)
    98  	if ex != nil {
    99  		checkError(t, ex, gotErr)
   100  		// if reflect.TypeOf(errors.New("")) == reflect.TypeOf(ex) {
   101  		// 	require.Equalf(t, ex, gotErr, "exp err:%v\ngot err:%v", ex, gotErr)
   102  		// } else {
   103  		// 	require.IsTypef(t, ex, gotErr, "exp err:%v\ngot err:%v", ex, gotErr)
   104  		// }
   105  	}
   106  	if !noError && !compatibleOnError {
   107  		return
   108  	}
   109  	if exp == nil {
   110  		require.Equal(t, nil, got)
   111  		return
   112  	}
   113  	expV := reflect.ValueOf(exp)
   114  	gotV := reflect.ValueOf(got)
   115  	if expV.IsNil() {
   116  		require.True(t, gotV.IsNil())
   117  		return
   118  	}
   119  	expI := expV.Elem().Interface()
   120  	gotI := gotV.Elem().Interface()
   121  	printValue(t, "got", gotI)
   122  	require.Equalf(t, expI, gotI, "exp %+v\ngot %+v", expI, gotI)
   123  }
   124  
   125  func TestValid(t *testing.T) {
   126  	f := func(t *testing.T, s string) {
   127  		data := localStringToBytes(s)
   128  		require.Equal(t, json.Valid(data), Valid(data))
   129  	}
   130  	t.Run("empty", func(t *testing.T) {
   131  		f(t, "")
   132  	})
   133  	t.Run("empty object", func(t *testing.T) {
   134  		f(t, "{}")
   135  	})
   136  	t.Run("data remained", func(t *testing.T) {
   137  		f(t, "{}1")
   138  	})
   139  }
   140  
   141  func TestUnmarshal(t *testing.T) {
   142  	t.Run("data remained", func(t *testing.T) {
   143  		var i, i2 interface{}
   144  		checkDecodeWithStandard(t, DefaultDecoderConfig, "{}{", ErrDataRemained, &i, &i2)
   145  	})
   146  }
   147  
   148  func TestMarshal(t *testing.T) {
   149  	b, err := Marshal("123")
   150  	require.NoError(t, err)
   151  	require.Equal(t, []byte(`"123"`), b)
   152  }