OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [encoding/] [json/] [decode_test.go] - Rev 867

Go to most recent revision | Compare with Previous | Blame | View Log

// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package json

import (
        "bytes"
        "fmt"
        "reflect"
        "strings"
        "testing"
)

type T struct {
        X string
        Y int
        Z int `json:"-"`
}

type tx struct {
        x int
}

var txType = reflect.TypeOf((*tx)(nil)).Elem()

// A type that can unmarshal itself.

type unmarshaler struct {
        T bool
}

func (u *unmarshaler) UnmarshalJSON(b []byte) error {
        *u = unmarshaler{true} // All we need to see that UnmarshalJson is called.
        return nil
}

type ustruct struct {
        M unmarshaler
}

var (
        um0, um1 unmarshaler // target2 of unmarshaling
        ump      = &um1
        umtrue   = unmarshaler{true}
        umslice  = []unmarshaler{{true}}
        umslicep = new([]unmarshaler)
        umstruct = ustruct{unmarshaler{true}}
)

type unmarshalTest struct {
        in  string
        ptr interface{}
        out interface{}
        err error
}

var unmarshalTests = []unmarshalTest{
        // basic types
        {`true`, new(bool), true, nil},
        {`1`, new(int), 1, nil},
        {`1.2`, new(float64), 1.2, nil},
        {`-5`, new(int16), int16(-5), nil},
        {`"a\u1234"`, new(string), "a\u1234", nil},
        {`"http:\/\/"`, new(string), "http://", nil},
        {`"g-clef: \uD834\uDD1E"`, new(string), "g-clef: \U0001D11E", nil},
        {`"invalid: \uD834x\uDD1E"`, new(string), "invalid: \uFFFDx\uFFFD", nil},
        {"null", new(interface{}), nil, nil},
        {`{"X": [1,2,3], "Y": 4}`, new(T), T{Y: 4}, &UnmarshalTypeError{"array", reflect.TypeOf("")}},
        {`{"x": 1}`, new(tx), tx{}, &UnmarshalFieldError{"x", txType, txType.Field(0)}},

        // Z has a "-" tag.
        {`{"Y": 1, "Z": 2}`, new(T), T{Y: 1}, nil},

        // syntax errors
        {`{"X": "foo", "Y"}`, nil, nil, &SyntaxError{"invalid character '}' after object key", 17}},
        {`[1, 2, 3+]`, nil, nil, &SyntaxError{"invalid character '+' after array element", 9}},

        // array tests
        {`[1, 2, 3]`, new([3]int), [3]int{1, 2, 3}, nil},
        {`[1, 2, 3]`, new([1]int), [1]int{1}, nil},
        {`[1, 2, 3]`, new([5]int), [5]int{1, 2, 3, 0, 0}, nil},

        // composite tests
        {allValueIndent, new(All), allValue, nil},
        {allValueCompact, new(All), allValue, nil},
        {allValueIndent, new(*All), &allValue, nil},
        {allValueCompact, new(*All), &allValue, nil},
        {pallValueIndent, new(All), pallValue, nil},
        {pallValueCompact, new(All), pallValue, nil},
        {pallValueIndent, new(*All), &pallValue, nil},
        {pallValueCompact, new(*All), &pallValue, nil},

        // unmarshal interface test
        {`{"T":false}`, &um0, umtrue, nil}, // use "false" so test will fail if custom unmarshaler is not called
        {`{"T":false}`, &ump, &umtrue, nil},
        {`[{"T":false}]`, &umslice, umslice, nil},
        {`[{"T":false}]`, &umslicep, &umslice, nil},
        {`{"M":{"T":false}}`, &umstruct, umstruct, nil},
}

func TestMarshal(t *testing.T) {
        b, err := Marshal(allValue)
        if err != nil {
                t.Fatalf("Marshal allValue: %v", err)
        }
        if string(b) != allValueCompact {
                t.Errorf("Marshal allValueCompact")
                diff(t, b, []byte(allValueCompact))
                return
        }

        b, err = Marshal(pallValue)
        if err != nil {
                t.Fatalf("Marshal pallValue: %v", err)
        }
        if string(b) != pallValueCompact {
                t.Errorf("Marshal pallValueCompact")
                diff(t, b, []byte(pallValueCompact))
                return
        }
}

func TestMarshalBadUTF8(t *testing.T) {
        s := "hello\xffworld"
        b, err := Marshal(s)
        if err == nil {
                t.Fatal("Marshal bad UTF8: no error")
        }
        if len(b) != 0 {
                t.Fatal("Marshal returned data")
        }
        if _, ok := err.(*InvalidUTF8Error); !ok {
                t.Fatalf("Marshal did not return InvalidUTF8Error: %T %v", err, err)
        }
}

func TestUnmarshal(t *testing.T) {
        for i, tt := range unmarshalTests {
                var scan scanner
                in := []byte(tt.in)
                if err := checkValid(in, &scan); err != nil {
                        if !reflect.DeepEqual(err, tt.err) {
                                t.Errorf("#%d: checkValid: %#v", i, err)
                                continue
                        }
                }
                if tt.ptr == nil {
                        continue
                }
                // v = new(right-type)
                v := reflect.New(reflect.TypeOf(tt.ptr).Elem())
                if err := Unmarshal([]byte(in), v.Interface()); !reflect.DeepEqual(err, tt.err) {
                        t.Errorf("#%d: %v want %v", i, err, tt.err)
                        continue
                }
                if !reflect.DeepEqual(v.Elem().Interface(), tt.out) {
                        t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), tt.out)
                        data, _ := Marshal(v.Elem().Interface())
                        println(string(data))
                        data, _ = Marshal(tt.out)
                        println(string(data))
                        continue
                }
        }
}

func TestUnmarshalMarshal(t *testing.T) {
        initBig()
        var v interface{}
        if err := Unmarshal(jsonBig, &v); err != nil {
                t.Fatalf("Unmarshal: %v", err)
        }
        b, err := Marshal(v)
        if err != nil {
                t.Fatalf("Marshal: %v", err)
        }
        if bytes.Compare(jsonBig, b) != 0 {
                t.Errorf("Marshal jsonBig")
                diff(t, b, jsonBig)
                return
        }
}

func TestLargeByteSlice(t *testing.T) {
        s0 := make([]byte, 2000)
        for i := range s0 {
                s0[i] = byte(i)
        }
        b, err := Marshal(s0)
        if err != nil {
                t.Fatalf("Marshal: %v", err)
        }
        var s1 []byte
        if err := Unmarshal(b, &s1); err != nil {
                t.Fatalf("Unmarshal: %v", err)
        }
        if bytes.Compare(s0, s1) != 0 {
                t.Errorf("Marshal large byte slice")
                diff(t, s0, s1)
        }
}

type Xint struct {
        X int
}

func TestUnmarshalInterface(t *testing.T) {
        var xint Xint
        var i interface{} = &xint
        if err := Unmarshal([]byte(`{"X":1}`), &i); err != nil {
                t.Fatalf("Unmarshal: %v", err)
        }
        if xint.X != 1 {
                t.Fatalf("Did not write to xint")
        }
}

func TestUnmarshalPtrPtr(t *testing.T) {
        var xint Xint
        pxint := &xint
        if err := Unmarshal([]byte(`{"X":1}`), &pxint); err != nil {
                t.Fatalf("Unmarshal: %v", err)
        }
        if xint.X != 1 {
                t.Fatalf("Did not write to xint")
        }
}

func TestEscape(t *testing.T) {
        const input = `"foobar"<html>`
        const expected = `"\"foobar\"\u003chtml\u003e"`
        b, err := Marshal(input)
        if err != nil {
                t.Fatalf("Marshal error: %v", err)
        }
        if s := string(b); s != expected {
                t.Errorf("Encoding of [%s] was [%s], want [%s]", input, s, expected)
        }
}

func TestHTMLEscape(t *testing.T) {
        b, err := MarshalForHTML("foobarbaz<>&quux")
        if err != nil {
                t.Fatalf("MarshalForHTML error: %v", err)
        }
        if !bytes.Equal(b, []byte(`"foobarbaz\u003c\u003e\u0026quux"`)) {
                t.Fatalf("Unexpected encoding of \"<>&\": %s", b)
        }
}

// WrongString is a struct that's misusing the ,string modifier.
type WrongString struct {
        Message string `json:"result,string"`
}

type wrongStringTest struct {
        in, err string
}

var wrongStringTests = []wrongStringTest{
        {`{"result":"x"}`, `json: invalid use of ,string struct tag, trying to unmarshal "x" into string`},
        {`{"result":"foo"}`, `json: invalid use of ,string struct tag, trying to unmarshal "foo" into string`},
        {`{"result":"123"}`, `json: invalid use of ,string struct tag, trying to unmarshal "123" into string`},
}

// If people misuse the ,string modifier, the error message should be
// helpful, telling the user that they're doing it wrong.
func TestErrorMessageFromMisusedString(t *testing.T) {
        for n, tt := range wrongStringTests {
                r := strings.NewReader(tt.in)
                var s WrongString
                err := NewDecoder(r).Decode(&s)
                got := fmt.Sprintf("%v", err)
                if got != tt.err {
                        t.Errorf("%d. got err = %q, want %q", n, got, tt.err)
                }
        }
}

func noSpace(c rune) rune {
        if isSpace(c) {
                return -1
        }
        return c
}

type All struct {
        Bool    bool
        Int     int
        Int8    int8
        Int16   int16
        Int32   int32
        Int64   int64
        Uint    uint
        Uint8   uint8
        Uint16  uint16
        Uint32  uint32
        Uint64  uint64
        Uintptr uintptr
        Float32 float32
        Float64 float64

        Foo  string `json:"bar"`
        Foo2 string `json:"bar2,dummyopt"`

        IntStr int64 `json:",string"`

        PBool    *bool
        PInt     *int
        PInt8    *int8
        PInt16   *int16
        PInt32   *int32
        PInt64   *int64
        PUint    *uint
        PUint8   *uint8
        PUint16  *uint16
        PUint32  *uint32
        PUint64  *uint64
        PUintptr *uintptr
        PFloat32 *float32
        PFloat64 *float64

        String  string
        PString *string

        Map   map[string]Small
        MapP  map[string]*Small
        PMap  *map[string]Small
        PMapP *map[string]*Small

        EmptyMap map[string]Small
        NilMap   map[string]Small

        Slice   []Small
        SliceP  []*Small
        PSlice  *[]Small
        PSliceP *[]*Small

        EmptySlice []Small
        NilSlice   []Small

        StringSlice []string
        ByteSlice   []byte

        Small   Small
        PSmall  *Small
        PPSmall **Small

        Interface  interface{}
        PInterface *interface{}

        unexported int
}

type Small struct {
        Tag string
}

var allValue = All{
        Bool:    true,
        Int:     2,
        Int8:    3,
        Int16:   4,
        Int32:   5,
        Int64:   6,
        Uint:    7,
        Uint8:   8,
        Uint16:  9,
        Uint32:  10,
        Uint64:  11,
        Uintptr: 12,
        Float32: 14.1,
        Float64: 15.1,
        Foo:     "foo",
        Foo2:    "foo2",
        IntStr:  42,
        String:  "16",
        Map: map[string]Small{
                "17": {Tag: "tag17"},
                "18": {Tag: "tag18"},
        },
        MapP: map[string]*Small{
                "19": {Tag: "tag19"},
                "20": nil,
        },
        EmptyMap:    map[string]Small{},
        Slice:       []Small{{Tag: "tag20"}, {Tag: "tag21"}},
        SliceP:      []*Small{{Tag: "tag22"}, nil, {Tag: "tag23"}},
        EmptySlice:  []Small{},
        StringSlice: []string{"str24", "str25", "str26"},
        ByteSlice:   []byte{27, 28, 29},
        Small:       Small{Tag: "tag30"},
        PSmall:      &Small{Tag: "tag31"},
        Interface:   5.2,
}

var pallValue = All{
        PBool:      &allValue.Bool,
        PInt:       &allValue.Int,
        PInt8:      &allValue.Int8,
        PInt16:     &allValue.Int16,
        PInt32:     &allValue.Int32,
        PInt64:     &allValue.Int64,
        PUint:      &allValue.Uint,
        PUint8:     &allValue.Uint8,
        PUint16:    &allValue.Uint16,
        PUint32:    &allValue.Uint32,
        PUint64:    &allValue.Uint64,
        PUintptr:   &allValue.Uintptr,
        PFloat32:   &allValue.Float32,
        PFloat64:   &allValue.Float64,
        PString:    &allValue.String,
        PMap:       &allValue.Map,
        PMapP:      &allValue.MapP,
        PSlice:     &allValue.Slice,
        PSliceP:    &allValue.SliceP,
        PPSmall:    &allValue.PSmall,
        PInterface: &allValue.Interface,
}

var allValueIndent = `{
        "Bool": true,
        "Int": 2,
        "Int8": 3,
        "Int16": 4,
        "Int32": 5,
        "Int64": 6,
        "Uint": 7,
        "Uint8": 8,
        "Uint16": 9,
        "Uint32": 10,
        "Uint64": 11,
        "Uintptr": 12,
        "Float32": 14.1,
        "Float64": 15.1,
        "bar": "foo",
        "bar2": "foo2",
        "IntStr": "42",
        "PBool": null,
        "PInt": null,
        "PInt8": null,
        "PInt16": null,
        "PInt32": null,
        "PInt64": null,
        "PUint": null,
        "PUint8": null,
        "PUint16": null,
        "PUint32": null,
        "PUint64": null,
        "PUintptr": null,
        "PFloat32": null,
        "PFloat64": null,
        "String": "16",
        "PString": null,
        "Map": {
                "17": {
                        "Tag": "tag17"
                },
                "18": {
                        "Tag": "tag18"
                }
        },
        "MapP": {
                "19": {
                        "Tag": "tag19"
                },
                "20": null
        },
        "PMap": null,
        "PMapP": null,
        "EmptyMap": {},
        "NilMap": null,
        "Slice": [
                {
                        "Tag": "tag20"
                },
                {
                        "Tag": "tag21"
                }
        ],
        "SliceP": [
                {
                        "Tag": "tag22"
                },
                null,
                {
                        "Tag": "tag23"
                }
        ],
        "PSlice": null,
        "PSliceP": null,
        "EmptySlice": [],
        "NilSlice": null,
        "StringSlice": [
                "str24",
                "str25",
                "str26"
        ],
        "ByteSlice": "Gxwd",
        "Small": {
                "Tag": "tag30"
        },
        "PSmall": {
                "Tag": "tag31"
        },
        "PPSmall": null,
        "Interface": 5.2,
        "PInterface": null
}`

var allValueCompact = strings.Map(noSpace, allValueIndent)

var pallValueIndent = `{
        "Bool": false,
        "Int": 0,
        "Int8": 0,
        "Int16": 0,
        "Int32": 0,
        "Int64": 0,
        "Uint": 0,
        "Uint8": 0,
        "Uint16": 0,
        "Uint32": 0,
        "Uint64": 0,
        "Uintptr": 0,
        "Float32": 0,
        "Float64": 0,
        "bar": "",
        "bar2": "",
        "IntStr": "0",
        "PBool": true,
        "PInt": 2,
        "PInt8": 3,
        "PInt16": 4,
        "PInt32": 5,
        "PInt64": 6,
        "PUint": 7,
        "PUint8": 8,
        "PUint16": 9,
        "PUint32": 10,
        "PUint64": 11,
        "PUintptr": 12,
        "PFloat32": 14.1,
        "PFloat64": 15.1,
        "String": "",
        "PString": "16",
        "Map": null,
        "MapP": null,
        "PMap": {
                "17": {
                        "Tag": "tag17"
                },
                "18": {
                        "Tag": "tag18"
                }
        },
        "PMapP": {
                "19": {
                        "Tag": "tag19"
                },
                "20": null
        },
        "EmptyMap": null,
        "NilMap": null,
        "Slice": null,
        "SliceP": null,
        "PSlice": [
                {
                        "Tag": "tag20"
                },
                {
                        "Tag": "tag21"
                }
        ],
        "PSliceP": [
                {
                        "Tag": "tag22"
                },
                null,
                {
                        "Tag": "tag23"
                }
        ],
        "EmptySlice": null,
        "NilSlice": null,
        "StringSlice": null,
        "ByteSlice": null,
        "Small": {
                "Tag": ""
        },
        "PSmall": null,
        "PPSmall": {
                "Tag": "tag31"
        },
        "Interface": null,
        "PInterface": 5.2
}`

var pallValueCompact = strings.Map(noSpace, pallValueIndent)

func TestRefUnmarshal(t *testing.T) {
        type S struct {
                // Ref is defined in encode_test.go.
                R0 Ref
                R1 *Ref
        }
        want := S{
                R0: 12,
                R1: new(Ref),
        }
        *want.R1 = 12

        var got S
        if err := Unmarshal([]byte(`{"R0":"ref","R1":"ref"}`), &got); err != nil {
                t.Fatalf("Unmarshal: %v", err)
        }
        if !reflect.DeepEqual(got, want) {
                t.Errorf("got %+v, want %+v", got, want)
        }
}

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.