From 22fa7a37f35fa8a4800fc09170238227472e00f2 Mon Sep 17 00:00:00 2001 From: John Date: Thu, 28 Mar 2019 17:51:05 +0800 Subject: [PATCH] add UseNumber support for gjson; add more unit test cases for gjson --- g/encoding/gcharset/gcharset.go | 2 +- g/encoding/gcharset/gcharset_test.go | 16 +- g/encoding/gjson/gjson.go | 153 +++++++---- g/encoding/gjson/gjson_unit_basic_test.go | 253 ++++++++++++++++++ g/encoding/gjson/gjson_unit_load_test.go | 138 ++++++++++ ...on_unit_test.go => gjson_unit_set_test.go} | 50 ---- g/encoding/gxml/gxml.go | 18 +- geg/other/test.go | 25 +- 8 files changed, 524 insertions(+), 131 deletions(-) create mode 100644 g/encoding/gjson/gjson_unit_basic_test.go create mode 100644 g/encoding/gjson/gjson_unit_load_test.go rename g/encoding/gjson/{gjson_unit_test.go => gjson_unit_set_test.go} (82%) diff --git a/g/encoding/gcharset/gcharset.go b/g/encoding/gcharset/gcharset.go index 618a87447..a64e6f3c7 100644 --- a/g/encoding/gcharset/gcharset.go +++ b/g/encoding/gcharset/gcharset.go @@ -51,5 +51,5 @@ func ToUTF8(charset string, src string) (dst string, err error) { // UTF8转指定字符集 func UTF8To(charset string, src string) (dst string, err error) { - return Convert(charset, "UTF-8", src) + return Convert(charset, "UTF-8", src) } \ No newline at end of file diff --git a/g/encoding/gcharset/gcharset_test.go b/g/encoding/gcharset/gcharset_test.go index 8d10e1f4e..33e7a0ed6 100644 --- a/g/encoding/gcharset/gcharset_test.go +++ b/g/encoding/gcharset/gcharset_test.go @@ -1,10 +1,16 @@ -package gcharset +// Copyright 2018 gf Author(https://github.com/gogf/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + +package gcharset_test import ( + "github.com/gogf/gf/g/encoding/gcharset" "testing" ) - var testData = []struct { utf8, other, otherEncoding string }{ @@ -52,7 +58,7 @@ var testData = []struct { func TestDecode(t *testing.T) { for _, data := range testData { str := "" - str, err := Convert("UTF-8", data.otherEncoding, data.other) + str, err := gcharset.Convert("UTF-8", data.otherEncoding, data.other) if err != nil { t.Errorf("Could not create decoder for %v", err) continue @@ -68,7 +74,7 @@ func TestDecode(t *testing.T) { func TestEncode(t *testing.T) { for _, data := range testData { str := "" - str, err := Convert(data.otherEncoding, "UTF-8", data.utf8) + str, err := gcharset.Convert(data.otherEncoding, "UTF-8", data.utf8) if err != nil { t.Errorf("Could not create decoder for %v", err) continue @@ -86,7 +92,7 @@ func TestConvert(t *testing.T) { dstCharset := "gbk" dst := "Hello \xb3\xa3\xd3\xc3\x87\xf8\xd7\xd6\x98\xcb\x9c\xca\xd7\xd6\xf3\x77\xb1\xed" - str, err := Convert(dstCharset, srcCharset, src) + str, err := gcharset.Convert(dstCharset, srcCharset, src) if err != nil { t.Errorf("convert error. %v", err) return diff --git a/g/encoding/gjson/gjson.go b/g/encoding/gjson/gjson.go index 01d1b1938..8efa70421 100644 --- a/g/encoding/gjson/gjson.go +++ b/g/encoding/gjson/gjson.go @@ -4,11 +4,15 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. -// Package gjson provides quite flexible and useful API for JSON/XML/YAML/TOML content handling. +// Package gjson provides flexible and useful API for JSON/XML/YAML/TOML content handling. +// +// JSON/XML/YAML/TOML数据格式处理。 package gjson import ( + "bytes" "encoding/json" + "errors" "fmt" "github.com/gogf/gf/g/encoding/gtoml" "github.com/gogf/gf/g/encoding/gxml" @@ -38,20 +42,20 @@ type Json struct { } // 将变量转换为Json对象进行处理,该变量至少应当是一个map或者slice,否者转换没有意义 -func New(value interface{}, unsafe...bool) *Json { +func New(data interface{}, unsafe...bool) *Json { j := (*Json)(nil) - switch value.(type) { + switch data.(type) { case map[string]interface{}, []interface{}, nil: j = &Json { - p : &value, + p : &data, c : byte(gDEFAULT_SPLIT_CHAR), vc : false , } case string, []byte: - j, _ = LoadContent(gconv.Bytes(value)) + j, _ = LoadContent(gconv.Bytes(data)) default: v := (interface{})(nil) - if m := gconv.Map(value); m != nil { + if m := gconv.Map(data); m != nil { v = m j = &Json { p : &v, @@ -59,7 +63,7 @@ func New(value interface{}, unsafe...bool) *Json { vc : false, } } else { - v = gconv.Interfaces(value) + v = gconv.Interfaces(data) j = &Json { p : &v, c : byte(gDEFAULT_SPLIT_CHAR), @@ -72,41 +76,43 @@ func New(value interface{}, unsafe...bool) *Json { } // 创建一个非并发安全的Json对象 -func NewUnsafe(value...interface{}) *Json { - if len(value) > 0 { - return New(value[0], true) +func NewUnsafe(data...interface{}) *Json { + if len(data) > 0 { + return New(data[0], true) } return New(nil, true) } // 识别当前给定内容是否为JSON格式 -func Valid (v interface{}) bool { - return json.Valid(gconv.Bytes(v)) +func Valid(data interface{}) bool { + return json.Valid(gconv.Bytes(data)) } // 编码go变量为json字符串,并返回json字符串指针 -func Encode (v interface{}) ([]byte, error) { - return json.Marshal(v) +func Encode(value interface{}) ([]byte, error) { + return json.Marshal(value) } -// 解码字符串为interface{}变量 -func Decode (b []byte) (interface{}, error) { - var v interface{} - if err := DecodeTo(b, &v); err != nil { +// 解码字符串/[]byte为interface{}变量 +func Decode(data interface{}) (interface{}, error) { + var value interface{} + if err := DecodeTo(gconv.Bytes(data), &value); err != nil { return nil, err } else { - return v, nil + return value, nil } } -// 解析json字符串为go变量,注意第二个参数为指针(任意结构的变量) -func DecodeTo (b []byte, v interface{}) error { - return json.Unmarshal(b, v) +// 解析json字符串/[]byte为go变量,注意第二个参数为指针(任意结构的变量) +func DecodeTo(data interface{}, v interface{}) error { + decoder := json.NewDecoder(bytes.NewReader(gconv.Bytes(data))) + decoder.UseNumber() + return decoder.Decode(v) } // 解析json字符串为gjson.Json对象,并返回操作对象指针 -func DecodeToJson (b []byte) (*Json, error) { - if v, err := Decode(b); err != nil { +func DecodeToJson(data interface{}) (*Json, error) { + if v, err := Decode(gconv.Bytes(data)); err != nil { return nil, err } else { return New(v), nil @@ -114,48 +120,53 @@ func DecodeToJson (b []byte) (*Json, error) { } // 支持多种配置文件类型转换为json格式内容并解析为gjson.Json对象 -func Load (path string) (*Json, error) { +func Load(path string) (*Json, error) { return LoadContent(gfcache.GetBinContents(path), gfile.Ext(path)) } // 支持的配置文件格式:xml, json, yaml/yml, toml, // 默认为自动识别,当无法检测成功时使用json解析。 -func LoadContent(data []byte, dataType...string) (*Json, error) { +func LoadContent(data interface{}, dataType...string) (*Json, error) { var err error var result interface{} + b := gconv.Bytes(data) t := "json" if len(dataType) > 0 { t = dataType[0] } else { - if gregex.IsMatch(`<.+>.*`, data) { + if json.Valid(b) { + t = "json" + } else if gregex.IsMatch(`<.+>.*`, b) { t = "xml" - } else if gregex.IsMatch(`\w+\s*:\s*\w+`, data) { + } else if gregex.IsMatch(`\w+\s*:\s*.+`, b) { t = "yml" - } else if gregex.IsMatch(`\w+\s*=\s*\w+`, data) { + } else if gregex.IsMatch(`\w+\s*=\s*.+`, b) { t = "toml" } } + // 其他数据格式解析 switch t { - case "xml", ".xml": - data, err = gxml.ToJson(data) - if err != nil { - return nil, err - } + case "json", ".json": + // ok + case "xml", ".xml": + b, err = gxml.ToJson(b) - case "yml", "yaml", ".yml", ".yaml": - data, err = gyaml.ToJson(data) - if err != nil { - return nil, err - } + case "yml", "yaml", ".yml", ".yaml": + b, err = gyaml.ToJson(b) - case "toml", ".toml": - data, err = gtoml.ToJson(data) - if err != nil { - return nil, err - } + case "toml", ".toml": + b, err = gtoml.ToJson(b) + + default: + err = errors.New("nonsupport type " + t) + } + if err != nil { + return nil, err } if result == nil { - if err := json.Unmarshal(data, &result); err != nil { + decoder := json.NewDecoder(bytes.NewReader(b)) + decoder.UseNumber() + if err := decoder.Decode(&result); err != nil { return nil, err } } @@ -205,7 +216,7 @@ func (j *Json) GetMap(pattern string) map[string]interface{} { return nil } -// 将检索值转换为Json对象指针返回 +// 将检索值转换为Json对象指针返回。 func (j *Json) GetJson(pattern string) *Json { result := j.Get(pattern) if result != nil { @@ -214,18 +225,24 @@ func (j *Json) GetJson(pattern string) *Json { return nil } -// 获得一个数组[]interface{},方便操作,不需要自己做类型转换 -// 注意,如果获取的值不存在,或者类型与json类型不匹配,那么将会返回nil -func (j *Json) GetArray(pattern string) []interface{} { - result := j.Get(pattern) - if result != nil { - if r, ok := result.([]interface{}); ok { - return r +// 将检索值转换为Json对象指针数组返回。 +func (j *Json) GetJsons(pattern string) []*Json { + array := j.GetArray(pattern) + if len(array) > 0 { + jsons := make([]*Json, len(array)) + for i := 0; i < len(array); i++ { + jsons[i] = New(array[i], !j.mu.IsSafe()) } + return jsons } return nil } +// 获得一个数组[]interface{},方便操作,不需要自己做类型转换。 +func (j *Json) GetArray(pattern string) []interface{} { + return gconv.Interfaces(j.Get(pattern)) +} + // 返回指定json中的string func (j *Json) GetString(pattern string) string { return gconv.String(j.Get(pattern)) @@ -724,34 +741,64 @@ func (j *Json) ToXml(rootTag...string) ([]byte, error) { return gxml.Encode(j.ToMap(), rootTag...) } +func (j *Json) ToXmlString(rootTag...string) (string, error) { + b, e := j.ToXml(rootTag...) + return string(b), e +} + func (j *Json) ToXmlIndent(rootTag...string) ([]byte, error) { return gxml.EncodeWithIndent(j.ToMap(), rootTag...) } +func (j *Json) ToXmlIndentString(rootTag...string) (string, error) { + b, e := j.ToXmlIndent(rootTag...) + return string(b), e +} + func (j *Json) ToJson() ([]byte, error) { j.mu.RLock() defer j.mu.RUnlock() return Encode(*(j.p)) } +func (j *Json) ToJsonString() (string, error) { + b, e := j.ToJson() + return string(b), e +} + func (j *Json) ToJsonIndent() ([]byte, error) { j.mu.RLock() defer j.mu.RUnlock() return json.MarshalIndent(*(j.p), "", "\t") } +func (j *Json) ToJsonIndentString() (string, error) { + b, e := j.ToJsonIndent() + return string(b), e +} + func (j *Json) ToYaml() ([]byte, error) { j.mu.RLock() defer j.mu.RUnlock() return gyaml.Encode(*(j.p)) } +func (j *Json) ToYamlString() (string, error) { + b, e := j.ToYaml() + return string(b), e +} + func (j *Json) ToToml() ([]byte, error) { j.mu.RLock() defer j.mu.RUnlock() return gtoml.Encode(*(j.p)) } +func (j *Json) ToTomlString() (string, error) { + b, e := j.ToToml() + return string(b), e +} + // 转换为指定的struct对象 func (j *Json) ToStruct(o interface{}) error { j.mu.RLock() diff --git a/g/encoding/gjson/gjson_unit_basic_test.go b/g/encoding/gjson/gjson_unit_basic_test.go new file mode 100644 index 000000000..790878289 --- /dev/null +++ b/g/encoding/gjson/gjson_unit_basic_test.go @@ -0,0 +1,253 @@ +// Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + +package gjson_test + +import ( + "github.com/gogf/gf/g" + "github.com/gogf/gf/g/encoding/gjson" + "github.com/gogf/gf/g/test/gtest" + "testing" +) + +func Test_New(t *testing.T) { + data := []byte(`{"n":123456789, "m":{"k":"v"}, "a":[1,2,3]}`) + gtest.Case(t, func() { + j := gjson.New(data) + gtest.Assert(j.Get("n"), "123456789") + gtest.Assert(j.Get("m"), g.Map{"k" : "v"}) + gtest.Assert(j.Get("a"), g.Slice{1, 2, 3}) + }) +} + +func Test_NewUnsafe(t *testing.T) { + data := []byte(`{"n":123456789, "m":{"k":"v"}, "a":[1,2,3]}`) + gtest.Case(t, func() { + j := gjson.NewUnsafe(data) + gtest.Assert(j.Get("n"), "123456789") + gtest.Assert(j.Get("m"), g.Map{"k" : "v"}) + gtest.Assert(j.Get("m.k"), "v") + gtest.Assert(j.Get("a"), g.Slice{1, 2, 3}) + gtest.Assert(j.Get("a.1"), 2) + }) +} + +func Test_Valid(t *testing.T) { + data1 := []byte(`{"n":123456789, "m":{"k":"v"}, "a":[1,2,3]}`) + data2 := []byte(`{"n":123456789, "m":{"k":"v"}, "a":[1,2,3]`) + gtest.Case(t, func() { + gtest.Assert(gjson.Valid(data1), true) + gtest.Assert(gjson.Valid(data2), false) + }) +} + +func Test_Encode(t *testing.T) { + value := g.Slice{1, 2, 3} + gtest.Case(t, func() { + b, err := gjson.Encode(value) + gtest.Assert(err, nil) + gtest.Assert(b, []byte(`[1,2,3]`)) + }) +} + +func Test_Decode(t *testing.T) { + data := []byte(`{"n":123456789, "m":{"k":"v"}, "a":[1,2,3]}`) + gtest.Case(t, func() { + v, err := gjson.Decode(data) + gtest.Assert(err, nil) + gtest.Assert(v, g.Map{ + "n" : 123456789, + "a" : g.Slice{1, 2, 3}, + "m" : g.Map{ + "k" : "v", + }, + }) + }) + gtest.Case(t, func() { + var v interface{} + err := gjson.DecodeTo(data, &v) + gtest.Assert(err, nil) + gtest.Assert(v, g.Map{ + "n" : 123456789, + "a" : g.Slice{1, 2, 3}, + "m" : g.Map{ + "k" : "v", + }, + }) + }) + gtest.Case(t, func() { + j, err := gjson.DecodeToJson(data) + gtest.Assert(err, nil) + gtest.Assert(j.Get("n"), "123456789") + gtest.Assert(j.Get("m"), g.Map{"k" : "v"}) + gtest.Assert(j.Get("m.k"), "v") + gtest.Assert(j.Get("a"), g.Slice{1, 2, 3}) + gtest.Assert(j.Get("a.1"), 2) + }) +} + +func Test_SplitChar(t *testing.T) { + data := []byte(`{"n":123456789, "m":{"k":"v"}, "a":[1,2,3]}`) + gtest.Case(t, func() { + j, err := gjson.DecodeToJson(data) + j.SetSplitChar(byte('#')) + gtest.Assert(err, nil) + gtest.Assert(j.Get("n"), "123456789") + gtest.Assert(j.Get("m"), g.Map{"k" : "v"}) + gtest.Assert(j.Get("m#k"), "v") + gtest.Assert(j.Get("a"), g.Slice{1, 2, 3}) + gtest.Assert(j.Get("a#1"), 2) + }) +} + +func Test_ViolenceCheck(t *testing.T) { + data := []byte(`{"m":{"a":[1,2,3], "v1.v2":"4"}}`) + gtest.Case(t, func() { + j, err := gjson.DecodeToJson(data) + gtest.Assert(err, nil) + gtest.Assert(j.Get("m.a.2"), 3) + gtest.Assert(j.Get("m.v1.v2"), nil) + j.SetViolenceCheck(true) + gtest.Assert(j.Get("m.v1.v2"), 4) + }) +} + +func Test_GetToVar(t *testing.T) { + data := []byte(`{"n":123456789, "m":{"k":"v"}, "a":[1,2,3]}`) + gtest.Case(t, func() { + var m map[string]string + var n int + var a []int + j, err := gjson.DecodeToJson(data) + gtest.Assert(err, nil) + + j.GetToVar("n", &n) + j.GetToVar("m", &m) + j.GetToVar("a", &a) + + gtest.Assert(n, "123456789") + gtest.Assert(m, g.Map{"k" : "v"}) + gtest.Assert(a, g.Slice{1, 2, 3}) + }) +} + +func Test_GetMap(t *testing.T) { + data := []byte(`{"n":123456789, "m":{"k":"v"}, "a":[1,2,3]}`) + gtest.Case(t, func() { + j, err := gjson.DecodeToJson(data) + gtest.Assert(err, nil) + gtest.Assert(j.GetMap("n"), g.Map{}) + gtest.Assert(j.GetMap("m"), g.Map{"k" : "v"}) + gtest.Assert(j.GetMap("a"), g.Map{}) + }) +} + +func Test_GetJson(t *testing.T) { + data := []byte(`{"n":123456789, "m":{"k":"v"}, "a":[1,2,3]}`) + gtest.Case(t, func() { + j, err := gjson.DecodeToJson(data) + gtest.Assert(err, nil) + j2 := j.GetJson("m") + gtest.AssertNE(j2, nil) + gtest.Assert(j2.Get("k"), "v") + gtest.Assert(j2.Get("a"), nil) + gtest.Assert(j2.Get("n"), nil) + }) +} + +func Test_GetArray(t *testing.T) { + data := []byte(`{"n":123456789, "m":{"k":"v"}, "a":[1,2,3]}`) + gtest.Case(t, func() { + j, err := gjson.DecodeToJson(data) + gtest.Assert(err, nil) + gtest.Assert(j.GetArray("n"), g.Array{123456789}) + gtest.Assert(j.GetArray("m"), g.Array{g.Map{"k":"v"}}) + gtest.Assert(j.GetArray("a"), g.Array{1,2,3}) + }) +} + +func Test_GetString(t *testing.T) { + data := []byte(`{"n":123456789, "m":{"k":"v"}, "a":[1,2,3]}`) + gtest.Case(t, func() { + j, err := gjson.DecodeToJson(data) + gtest.Assert(err, nil) + gtest.AssertEQ(j.GetString("n"), "123456789") + gtest.AssertEQ(j.GetString("m"), `{"k":"v"}`) + gtest.AssertEQ(j.GetString("a"), `[1,2,3]`) + gtest.AssertEQ(j.GetString("i"), "") + }) +} + +func Test_GetStrings(t *testing.T) { + data := []byte(`{"n":123456789, "m":{"k":"v"}, "a":[1,2,3]}`) + gtest.Case(t, func() { + j, err := gjson.DecodeToJson(data) + gtest.Assert(err, nil) + gtest.AssertEQ(j.GetStrings("n"), g.SliceStr{"123456789"}) + gtest.AssertEQ(j.GetStrings("m"), g.SliceStr{`{"k":"v"}`}) + gtest.AssertEQ(j.GetStrings("a"), g.SliceStr{"1", "2", "3"}) + gtest.AssertEQ(j.GetStrings("i"), g.SliceStr{}) + }) +} + +func Test_GetInterfaces(t *testing.T) { + data := []byte(`{"n":123456789, "m":{"k":"v"}, "a":[1,2,3]}`) + gtest.Case(t, func() { + j, err := gjson.DecodeToJson(data) + gtest.Assert(err, nil) + gtest.AssertEQ(j.GetInterfaces("n"), g.Array{123456789}) + gtest.AssertEQ(j.GetInterfaces("m"), g.Array{g.Map{"k":"v"}}) + gtest.AssertEQ(j.GetInterfaces("a"), g.Array{1,2,3}) + }) +} + +func Test_Len(t *testing.T) { + gtest.Case(t, func() { + p := gjson.New(nil) + p.Append("a", 1) + p.Append("a", 2) + gtest.Assert(p.Len("a"), 2) + }) + gtest.Case(t, func() { + p := gjson.New(nil) + p.Append("a.b", 1) + p.Append("a.c", 2) + gtest.Assert(p.Len("a"), 2) + }) + gtest.Case(t, func() { + p := gjson.New(nil) + p.Set("a", 1) + gtest.Assert(p.Len("a"), -1) + }) +} + +func Test_Append(t *testing.T) { + gtest.Case(t, func() { + p := gjson.New(nil) + p.Append("a", 1) + p.Append("a", 2) + gtest.Assert(p.Get("a"), g.Slice{1, 2}) + }) + gtest.Case(t, func() { + p := gjson.New(nil) + p.Append("a.b", 1) + p.Append("a.c", 2) + gtest.Assert(p.Get("a"), g.Map{ + "b" : g.Slice{1}, + "c" : g.Slice{2}, + }) + }) + gtest.Case(t, func() { + p := gjson.New(nil) + p.Set("a", 1) + err := p.Append("a", 2) + gtest.AssertNE(err, nil) + gtest.Assert(p.Get("a"), 1) + }) +} + + + diff --git a/g/encoding/gjson/gjson_unit_load_test.go b/g/encoding/gjson/gjson_unit_load_test.go new file mode 100644 index 000000000..40e2cd88a --- /dev/null +++ b/g/encoding/gjson/gjson_unit_load_test.go @@ -0,0 +1,138 @@ +// Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + +package gjson_test + +import ( + "github.com/gogf/gf/g" + "github.com/gogf/gf/g/encoding/gjson" + "github.com/gogf/gf/g/os/gfile" + "github.com/gogf/gf/g/test/gtest" + "testing" +) + + +func Test_Load_JSON(t *testing.T) { + data := []byte(`{"n":123456789, "m":{"k":"v"}, "a":[1,2,3]}`) + // JSON + gtest.Case(t, func() { + j, err := gjson.LoadContent(data) + gtest.Assert(err, nil) + gtest.Assert(j.Get("n"), "123456789") + gtest.Assert(j.Get("m"), g.Map{"k" : "v"}) + gtest.Assert(j.Get("m.k"), "v") + gtest.Assert(j.Get("a"), g.Slice{1, 2, 3}) + gtest.Assert(j.Get("a.1"), 2) + }) + // JSON + gtest.Case(t, func() { + path := "test.json" + gfile.PutBinContents(path, data) + defer gfile.Remove(path) + j, err := gjson.Load(path) + gtest.Assert(err, nil) + gtest.Assert(j.Get("n"), "123456789") + gtest.Assert(j.Get("m"), g.Map{"k" : "v"}) + gtest.Assert(j.Get("m.k"), "v") + gtest.Assert(j.Get("a"), g.Slice{1, 2, 3}) + gtest.Assert(j.Get("a.1"), 2) + }) +} + +func Test_Load_XML(t *testing.T) { + data := []byte(`123v123456789`) + // XML + gtest.Case(t, func() { + j, err := gjson.LoadContent(data) + gtest.Assert(err, nil) + gtest.Assert(j.Get("doc.n"), "123456789") + gtest.Assert(j.Get("doc.m"), g.Map{"k" : "v"}) + gtest.Assert(j.Get("doc.m.k"), "v") + gtest.Assert(j.Get("doc.a"), g.Slice{1, 2, 3}) + gtest.Assert(j.Get("doc.a.1"), 2) + }) + // XML + gtest.Case(t, func() { + path := "test.xml" + gfile.PutBinContents(path, data) + defer gfile.Remove(path) + j, err := gjson.Load(path) + gtest.Assert(err, nil) + gtest.Assert(j.Get("doc.n"), "123456789") + gtest.Assert(j.Get("doc.m"), g.Map{"k" : "v"}) + gtest.Assert(j.Get("doc.m.k"), "v") + gtest.Assert(j.Get("doc.a"), g.Slice{1, 2, 3}) + gtest.Assert(j.Get("doc.a.1"), 2) + }) +} + +func Test_Load_YAML(t *testing.T) { + data := []byte(` +a: +- 1 +- 2 +- 3 +m: + k: v +"n": 123456789 + `) + // YAML + gtest.Case(t, func() { + j, err := gjson.LoadContent(data) + gtest.Assert(err, nil) + gtest.Assert(j.Get("n"), "123456789") + gtest.Assert(j.Get("m"), g.Map{"k" : "v"}) + gtest.Assert(j.Get("m.k"), "v") + gtest.Assert(j.Get("a"), g.Slice{1, 2, 3}) + gtest.Assert(j.Get("a.1"), 2) + }) + // YAML + gtest.Case(t, func() { + path := "test.yaml" + gfile.PutBinContents(path, data) + defer gfile.Remove(path) + j, err := gjson.Load(path) + gtest.Assert(err, nil) + gtest.Assert(j.Get("n"), "123456789") + gtest.Assert(j.Get("m"), g.Map{"k" : "v"}) + gtest.Assert(j.Get("m.k"), "v") + gtest.Assert(j.Get("a"), g.Slice{1, 2, 3}) + gtest.Assert(j.Get("a.1"), 2) + }) +} + +func Test_Load_TOML(t *testing.T) { + data := []byte(` +a = ["1", "2", "3"] +n = "123456789" + +[m] + k = "v" +`) + // TOML + gtest.Case(t, func() { + j, err := gjson.LoadContent(data) + gtest.Assert(err, nil) + gtest.Assert(j.Get("n"), "123456789") + gtest.Assert(j.Get("m"), g.Map{"k" : "v"}) + gtest.Assert(j.Get("m.k"), "v") + gtest.Assert(j.Get("a"), g.Slice{1, 2, 3}) + gtest.Assert(j.Get("a.1"), 2) + }) + // TOML + gtest.Case(t, func() { + path := "test.toml" + gfile.PutBinContents(path, data) + defer gfile.Remove(path) + j, err := gjson.Load(path) + gtest.Assert(err, nil) + gtest.Assert(j.Get("n"), "123456789") + gtest.Assert(j.Get("m"), g.Map{"k" : "v"}) + gtest.Assert(j.Get("m.k"), "v") + gtest.Assert(j.Get("a"), g.Slice{1, 2, 3}) + gtest.Assert(j.Get("a.1"), 2) + }) +} diff --git a/g/encoding/gjson/gjson_unit_test.go b/g/encoding/gjson/gjson_unit_set_test.go similarity index 82% rename from g/encoding/gjson/gjson_unit_test.go rename to g/encoding/gjson/gjson_unit_set_test.go index c1d777d70..666b8842a 100644 --- a/g/encoding/gjson/gjson_unit_test.go +++ b/g/encoding/gjson/gjson_unit_set_test.go @@ -8,9 +8,7 @@ package gjson_test import ( "bytes" - "github.com/gogf/gf/g" "github.com/gogf/gf/g/encoding/gjson" - "github.com/gogf/gf/g/test/gtest" "testing" ) @@ -230,51 +228,3 @@ func Test_Set14(t *testing.T) { t.Error(err) } } - -func Test_Len(t *testing.T) { - gtest.Case(t, func() { - p := gjson.New(nil) - p.Append("a", 1) - p.Append("a", 2) - gtest.Assert(p.Len("a"), 2) - }) - gtest.Case(t, func() { - p := gjson.New(nil) - p.Append("a.b", 1) - p.Append("a.c", 2) - gtest.Assert(p.Len("a"), 2) - }) - gtest.Case(t, func() { - p := gjson.New(nil) - p.Set("a", 1) - gtest.Assert(p.Len("a"), -1) - }) -} - -func Test_Append(t *testing.T) { - gtest.Case(t, func() { - p := gjson.New(nil) - p.Append("a", 1) - p.Append("a", 2) - gtest.Assert(p.Get("a"), g.Slice{1, 2}) - }) - gtest.Case(t, func() { - p := gjson.New(nil) - p.Append("a.b", 1) - p.Append("a.c", 2) - gtest.Assert(p.Get("a"), g.Map{ - "b" : g.Slice{1}, - "c" : g.Slice{2}, - }) - }) - gtest.Case(t, func() { - p := gjson.New(nil) - p.Set("a", 1) - err := p.Append("a", 2) - gtest.AssertNE(err, nil) - gtest.Assert(p.Get("a"), 1) - }) -} - - - diff --git a/g/encoding/gxml/gxml.go b/g/encoding/gxml/gxml.go index 0781891d0..eba835b9d 100644 --- a/g/encoding/gxml/gxml.go +++ b/g/encoding/gxml/gxml.go @@ -5,6 +5,8 @@ // You can obtain one at https://github.com/gogf/gf. // Package gxml provides accessing and converting for XML content. +// +// XML数据格式解析。 package gxml import ( @@ -19,9 +21,9 @@ import ( ) // 将XML内容解析为map变量 -func Decode(xmlbyte []byte) (map[string]interface{}, error) { - prepare(xmlbyte) - return mxj.NewMapXml(xmlbyte) +func Decode(content []byte) (map[string]interface{}, error) { + prepare(content) + return mxj.NewMapXml(content) } // 将map变量解析为XML格式内容 @@ -34,9 +36,9 @@ func EncodeWithIndent(v map[string]interface{}, rootTag...string) ([]byte, error } // XML格式内容直接转换为JSON格式内容 -func ToJson(xmlbyte []byte) ([]byte, error) { - prepare(xmlbyte) - mv, err := mxj.NewMapXml(xmlbyte) +func ToJson(content []byte) ([]byte, error) { + prepare(content) + mv, err := mxj.NewMapXml(content) if err == nil { return mv.Json() } else { @@ -61,10 +63,10 @@ func prepare(xmlbyte []byte) error { if err != nil { return err } - + xmlEncode := "UTF-8" if len(matchStr) == 2 { - xmlEncode = matchStr[1] + xmlEncode = matchStr[1] } charset := mahonia.GetCharset(xmlEncode) diff --git a/geg/other/test.go b/geg/other/test.go index 46103a65e..e0afdc044 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -1,21 +1,18 @@ package main import ( - "github.com/gogf/gf/g" - "github.com/gogf/gf/g/net/ghttp" - "github.com/gogf/gf/g/os/gproc" + "bytes" + "encoding/json" + "fmt" ) func main() { - s := g.Server() - s.SetIndexFolder(true) - s.BindHandler("/", func(r *ghttp.Request){ - r.Response.Write("pid:", gproc.Pid()) - }) - s.BindHandler("/panic", func(r *ghttp.Request){ - panic("error") - }) - s.SetAccessLogEnabled(true) - s.SetPort(8199) - s.Run() + value := interface{}(nil) + data := []byte(`{"n": 123456789}`) + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + err := decoder.Decode(&value) + //err := json.Unmarshal(data, &value) + fmt.Println(err) + fmt.Println(value) } \ No newline at end of file