github.com/jxskiss/gopkg/v2@v2.14.9-0.20240514120614-899f3e7952b4/easy/json_test.go (about)

     1  package easy
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/tidwall/gjson"
    11  )
    12  
    13  func TestJSONMarshalMapInterfaceInterface(t *testing.T) {
    14  	m := make(map[any]any)
    15  	m[1] = "1"
    16  	m["2"] = 2
    17  	got := JSON(m)
    18  	want := `{"1":"1","2":2}`
    19  	assert.Equal(t, want, got)
    20  }
    21  
    22  func TestJSONDisableEscapeHTML(t *testing.T) {
    23  	m := map[string]string{
    24  		"html": "<html></html>",
    25  	}
    26  
    27  	stdRet, err := json.Marshal(m)
    28  	assert.Nil(t, err)
    29  	assert.Equal(t, `{"html":"\u003chtml\u003e\u003c/html\u003e"}`, string(stdRet))
    30  
    31  	got := JSON(m)
    32  	assert.Equal(t, `{"html":"<html></html>"}`, got)
    33  }
    34  
    35  func TestLazyJSON(t *testing.T) {
    36  	var x = &testObject{A: 123, B: "abc"}
    37  	got1 := JSON(x)
    38  	got2 := fmt.Sprintf("%v", LazyJSON(x))
    39  	assert.Equal(t, got1, got2)
    40  }
    41  
    42  func TestLasyFunc(t *testing.T) {
    43  	var x = &testObject{A: 123, B: "abc"}
    44  	got1 := Pretty2(x)
    45  	got2 := fmt.Sprint(LazyFunc(x, Pretty2))
    46  	assert.Equal(t, got1, got2)
    47  }
    48  
    49  var prettyTestWant = strings.TrimSpace(`
    50  {
    51      "1": 123,
    52      "b": "<html>"
    53  }`)
    54  
    55  func TestPretty(t *testing.T) {
    56  	test := map[string]any{
    57  		"1": 123,
    58  		"b": "<html>",
    59  	}
    60  	jsonString := JSON(test)
    61  	assert.Equal(t, `{"1":123,"b":"<html>"}`, jsonString)
    62  
    63  	got1 := Pretty(test)
    64  	assert.Equal(t, prettyTestWant, got1)
    65  
    66  	got2 := Pretty(jsonString)
    67  	assert.Equal(t, prettyTestWant, got2)
    68  
    69  	test3 := []byte("<fff> not a json object")
    70  	got3 := Pretty(test3)
    71  	assert.Equal(t, string(test3), got3)
    72  
    73  	test4 := []byte{
    74  		255, 253, 189, 240, 128, 200, 202, 204,
    75  	}
    76  	got4 := Pretty(test4)
    77  	assert.Equal(t, "<pretty: non-printable bytes of length 8>", got4)
    78  
    79  	got5 := Pretty2(map[string]any{"1": 123, "b": "<html>"})
    80  	want5 := "{\n  \"1\": 123,\n  \"b\": \"<html>\"\n}"
    81  	assert.Equal(t, want5, got5)
    82  }
    83  
    84  var parseJSONRecordsTestData = `
    85  {
    86      "files": [
    87          {
    88              "displayName": "README.md",
    89              "repoName": "gopkg",
    90              "refName": "master",
    91              "path": "README.md",
    92              "preferredFileType": "readme",
    93              "tabName": "README",
    94              "loaded": true,
    95              "timedOut": false,
    96              "errorMessage": null,
    97              "headerInfo": {
    98                  "toc": [
    99                      {
   100                          "level": 1,
   101                          "text": "gopkg",
   102                          "anchor": "gopkg",
   103                          "htmlText": "gopkg"
   104                      },
   105                      {
   106                          "level": 2,
   107                          "text": "Status",
   108                          "anchor": "status",
   109                          "htmlText": "Status"
   110                      },
   111                      {
   112                          "level": 2,
   113                          "text": "Code layout",
   114                          "anchor": "code-layout",
   115                          "htmlText": "Code layout"
   116                      },
   117                      {
   118                          "level": 2,
   119                          "text": "Packages",
   120                          "anchor": "packages",
   121                          "htmlText": "Packages"
   122                      }
   123                  ],
   124              }
   125          },
   126          {
   127              "displayName": "LICENSE",
   128              "repoName": "gopkg",
   129              "refName": "master",
   130              "path": "LICENSE",
   131              "preferredFileType": "license",
   132              "tabName": "License",
   133              "loaded": true,
   134              "timedOut": false,
   135              "errorMessage": null,
   136              "headerInfo": {
   137                  "toc": [],
   138              }
   139          }
   140      ],
   141      "processingTime": 31.543533999999998
   142  }`
   143  
   144  func TestParseJSONRecordsWithMapping(t *testing.T) {
   145  	mapping := JSONPathMapping{
   146  		{"DisplayName", "displayName"},
   147  		{"RepoName", "repoName"},
   148  		{"Loaded", "loaded", "bool"},
   149  		{"HeaderInfo", "headerInfo", "map"},
   150  		{"HeaderInfoLevels", `headerInfo.toc.#(anchor="gopkg")#.level`, "array"},
   151  	}
   152  
   153  	j := gjson.Parse(parseJSONRecordsTestData).Get("files")
   154  	got := ParseJSONRecordsWithMapping(j.Array(), mapping)
   155  	assert.Len(t, got, 2)
   156  	assert.Equal(t, "README.md", got[0]["DisplayName"])
   157  	assert.Equal(t, "LICENSE", got[1]["DisplayName"])
   158  	assert.Equal(t, true, got[0]["Loaded"])
   159  	assert.Equal(t, true, got[1]["Loaded"])
   160  	assert.Equal(t, 4, len(got[0]["HeaderInfo"].(map[string]any)["toc"].([]any)))
   161  	assert.Equal(t, 1, len(got[1]["HeaderInfo"].(map[string]any)))
   162  	assert.Equal(t, []any{float64(1)}, got[0]["HeaderInfoLevels"])
   163  	assert.Equal(t, 0, len(got[1]["HeaderInfoLevels"].([]any)))
   164  }
   165  
   166  func TestParseJSONRecords(t *testing.T) {
   167  	type HeaderInfo struct {
   168  		Level int    `mapping:"level"`
   169  		Text  string `mapping:"text"`
   170  	}
   171  	type File struct {
   172  		DisplayName        string                    `mapping:"displayName"`
   173  		RepoName           string                    `mapping:"repoName"`
   174  		Loaded             bool                      `mapping:"loaded"`
   175  		HeaderInfo_1       map[string]*HeaderInfo    `mapping:"{\"toc\":headerInfo.toc.0}"`
   176  		HeaderInfo_2       map[string]map[string]any `mapping:"{\"toc\":headerInfo.toc.1}"`
   177  		HeaderInfoTOC_1    []*HeaderInfo             `mapping:"headerInfo.toc"`
   178  		HeaderInfoTOC_2    []map[string]any          `mapping:"headerInfo.toc"`
   179  		HeaderInfoLevels_1 []int                     `mapping:"headerInfo.toc.#(text=\"Code layout\")#.level"`
   180  		HeaderInfoLevels_2 []any                     `mapping:"headerInfo.toc.#(anchor=\"code-layout\")#.level"`
   181  	}
   182  
   183  	j := gjson.Parse(parseJSONRecordsTestData).Get("files")
   184  
   185  	var got []*File
   186  	err := ParseJSONRecords(&got, j.Array())
   187  	assert.Nil(t, err)
   188  	assert.Len(t, got, 2)
   189  
   190  	assert.Equal(t, "README.md", got[0].DisplayName)
   191  	assert.Equal(t, "LICENSE", got[1].DisplayName)
   192  	assert.Equal(t, true, got[0].Loaded)
   193  
   194  	assert.Equal(t, 1, len(got[0].HeaderInfo_1))
   195  	assert.Equal(t, HeaderInfo{1, "gopkg"}, *got[0].HeaderInfo_1["toc"])
   196  	assert.Equal(t, 1, len(got[0].HeaderInfo_2))
   197  	assert.Equal(t,
   198  		map[string]any{"level": float64(2), "text": "Status", "anchor": "status", "htmlText": "Status"},
   199  		got[0].HeaderInfo_2["toc"])
   200  
   201  	assert.Equal(t, 4, len(got[0].HeaderInfoTOC_1))
   202  	assert.Equal(t, HeaderInfo{1, "gopkg"}, *got[0].HeaderInfoTOC_1[0])
   203  	assert.Equal(t, 4, len(got[0].HeaderInfoTOC_2))
   204  	assert.Equal(t,
   205  		map[string]any{"level": float64(2), "text": "Status", "anchor": "status", "htmlText": "Status"},
   206  		got[0].HeaderInfoTOC_2[1],
   207  	)
   208  
   209  	assert.Equal(t, []int{2}, got[0].HeaderInfoLevels_1)
   210  	assert.Equal(t, []any{float64(2)}, got[0].HeaderInfoLevels_2)
   211  }
   212  
   213  func TestTestParseJSONRecords_Options(t *testing.T) {
   214  	type HeaderInfo struct {
   215  		Level int    `mapping:"__HeaderInfo_Level"`
   216  		Text  string `mapping:"text"`
   217  	}
   218  	type File struct {
   219  		DisplayName        string `mapping:"displayName"`
   220  		RepoName           string `mapping:"repoName"`
   221  		Loaded             bool   `mapping:"loaded"`
   222  		HeaderInfo_1       map[string]*HeaderInfo
   223  		HeaderInfo_2       map[string]map[string]any `mapping:"__File_HeaderInfo_2"`
   224  		HeaderInfoLevels_1 []int
   225  		HeaderInfoLevels_2 []any `mapping:"__File_HeaderInfoLevels_2"`
   226  	}
   227  
   228  	j := gjson.Parse(parseJSONRecordsTestData).Get("files")
   229  
   230  	var got []*File
   231  	err := ParseJSONRecords(&got, j.Array(),
   232  		WithDynamicJSONMapping(map[string]string{
   233  			"__HeaderInfo_Level":        "level",
   234  			"HeaderInfo_1":              `{"toc":headerInfo.toc.0}`,
   235  			"__File_HeaderInfo_2":       `{"toc":headerInfo.toc.1}`,
   236  			"HeaderInfoLevels_1":        `headerInfo.toc.#(text="Code layout")#.level`,
   237  			"__File_HeaderInfoLevels_2": fmt.Sprintf("headerInfo.toc.#(anchor=%q)#.level", "code-layout"),
   238  		}))
   239  	assert.Nil(t, err)
   240  	assert.Len(t, got, 2)
   241  
   242  	assert.Equal(t, 1, len(got[0].HeaderInfo_1))
   243  	assert.Equal(t, HeaderInfo{1, "gopkg"}, *got[0].HeaderInfo_1["toc"])
   244  	assert.Equal(t, 1, len(got[0].HeaderInfo_2))
   245  	assert.Equal(t,
   246  		map[string]any{"level": float64(2), "text": "Status", "anchor": "status", "htmlText": "Status"},
   247  		got[0].HeaderInfo_2["toc"])
   248  	assert.Equal(t, []int{2}, got[0].HeaderInfoLevels_1)
   249  	assert.Equal(t, []any{float64(2)}, got[0].HeaderInfoLevels_2)
   250  }
   251  
   252  func TestParseJSONRecords_Recursive(t *testing.T) {
   253  	type Person struct {
   254  		A          string
   255  		Parent     *Person
   256  		Children1  []*Person `mapping:"Children_1"`
   257  		Children_2 map[string]*Person
   258  	}
   259  	testData := `[
   260  	{
   261  		"A": "test",
   262  		"Parent": {
   263  			"A": "parent"
   264  		},
   265  		"Children_1": [
   266  			{
   267  				"A": "child_1",
   268  				"Parent": {"A": "test_child_1"}
   269  			},
   270  			{
   271  				"A": "child_2",
   272  				"Parent": {"A": "test_child_2"},
   273  				"Children_1": [
   274  					{"A": "child_2_1"},
   275  					{"A": "child_2_2"}
   276  				]
   277  			}
   278  		],
   279  		"Children_2": {
   280  			"child_1": {
   281  				"A": "child_1",
   282  				"Parent": {"A": "test_child_1"}
   283  			},
   284  			"child_2": {
   285  				"A": "child_2",
   286  				"Parent": {"A": "test_child_2"},
   287  				"Children_2": {
   288  					"child_2_1": {"A": "child_2_1"},
   289  					"child_2_2": {"A": "child_2_2"}
   290  				}
   291  			}
   292  		}
   293  	}
   294  ]`
   295  	var got []*Person
   296  	err := ParseJSONRecords(&got, gjson.Parse(testData).Array())
   297  	assert.Nil(t, err)
   298  	assert.Len(t, got, 1)
   299  
   300  	assert.Equal(t, "test", got[0].A)
   301  	assert.Equal(t, "parent", got[0].Parent.A)
   302  	assert.Equal(t, ([]*Person)(nil), got[0].Parent.Children1)
   303  	assert.Equal(t, (map[string]*Person)(nil), got[0].Parent.Children_2)
   304  
   305  	assert.Equal(t, "child_1", got[0].Children1[0].A)
   306  	assert.Equal(t, "test_child_1", got[0].Children1[0].Parent.A)
   307  	assert.Equal(t, ([]*Person)(nil), got[0].Children1[0].Children1)
   308  	assert.Equal(t, (map[string]*Person)(nil), got[0].Children1[0].Children_2)
   309  
   310  	assert.Equal(t, 2, len(got[0].Children1))
   311  	assert.Equal(t, "child_2", got[0].Children1[1].A)
   312  	assert.Equal(t, "test_child_2", got[0].Children1[1].Parent.A)
   313  	assert.Equal(t, 2, len(got[0].Children1[1].Children1))
   314  	assert.Equal(t, (map[string]*Person)(nil), got[0].Children1[0].Children_2)
   315  
   316  	assert.Equal(t, 2, len(got[0].Children_2))
   317  	assert.Equal(t, "child_1", got[0].Children_2["child_1"].A)
   318  	assert.Equal(t, "test_child_1", got[0].Children_2["child_1"].Parent.A)
   319  	assert.Equal(t, ([]*Person)(nil), got[0].Children_2["child_1"].Children1)
   320  	assert.Equal(t, (map[string]*Person)(nil), got[0].Children_2["child_1"].Children_2)
   321  	assert.Equal(t, "child_2", got[0].Children_2["child_2"].A)
   322  	assert.Equal(t, "test_child_2", got[0].Children_2["child_2"].Parent.A)
   323  	assert.Equal(t, "child_2_1", got[0].Children_2["child_2"].Children_2["child_2_1"].A)
   324  	assert.Equal(t, "child_2_2", got[0].Children_2["child_2"].Children_2["child_2_2"].A)
   325  }