1package simplejson 2 3import ( 4 "encoding/json" 5 "testing" 6 7 "github.com/bmizerany/assert" 8) 9 10func TestSimplejson(t *testing.T) { 11 var ok bool 12 var err error 13 14 js, err := NewJson([]byte(`{ 15 "test": { 16 "string_array": ["asdf", "ghjk", "zxcv"], 17 "string_array_null": ["abc", null, "efg"], 18 "array": [1, "2", 3], 19 "arraywithsubs": [{"subkeyone": 1}, 20 {"subkeytwo": 2, "subkeythree": 3}], 21 "int": 10, 22 "float": 5.150, 23 "string": "simplejson", 24 "bool": true, 25 "sub_obj": {"a": 1} 26 } 27 }`)) 28 29 assert.NotEqual(t, nil, js) 30 assert.Equal(t, nil, err) 31 32 _, ok = js.CheckGet("test") 33 assert.Equal(t, true, ok) 34 35 _, ok = js.CheckGet("missing_key") 36 assert.Equal(t, false, ok) 37 38 aws := js.Get("test").Get("arraywithsubs") 39 assert.NotEqual(t, nil, aws) 40 var awsval int 41 awsval, _ = aws.GetIndex(0).Get("subkeyone").Int() 42 assert.Equal(t, 1, awsval) 43 awsval, _ = aws.GetIndex(1).Get("subkeytwo").Int() 44 assert.Equal(t, 2, awsval) 45 awsval, _ = aws.GetIndex(1).Get("subkeythree").Int() 46 assert.Equal(t, 3, awsval) 47 48 i, _ := js.Get("test").Get("int").Int() 49 assert.Equal(t, 10, i) 50 51 f, _ := js.Get("test").Get("float").Float64() 52 assert.Equal(t, 5.150, f) 53 54 s, _ := js.Get("test").Get("string").String() 55 assert.Equal(t, "simplejson", s) 56 57 b, _ := js.Get("test").Get("bool").Bool() 58 assert.Equal(t, true, b) 59 60 mi := js.Get("test").Get("int").MustInt() 61 assert.Equal(t, 10, mi) 62 63 mi2 := js.Get("test").Get("missing_int").MustInt(5150) 64 assert.Equal(t, 5150, mi2) 65 66 ms := js.Get("test").Get("string").MustString() 67 assert.Equal(t, "simplejson", ms) 68 69 ms2 := js.Get("test").Get("missing_string").MustString("fyea") 70 assert.Equal(t, "fyea", ms2) 71 72 ma2 := js.Get("test").Get("missing_array").MustArray([]interface{}{"1", 2, "3"}) 73 assert.Equal(t, ma2, []interface{}{"1", 2, "3"}) 74 75 msa := js.Get("test").Get("string_array").MustStringArray() 76 assert.Equal(t, msa[0], "asdf") 77 assert.Equal(t, msa[1], "ghjk") 78 assert.Equal(t, msa[2], "zxcv") 79 80 msa2 := js.Get("test").Get("string_array").MustStringArray([]string{"1", "2", "3"}) 81 assert.Equal(t, msa2[0], "asdf") 82 assert.Equal(t, msa2[1], "ghjk") 83 assert.Equal(t, msa2[2], "zxcv") 84 85 msa3 := js.Get("test").Get("missing_array").MustStringArray([]string{"1", "2", "3"}) 86 assert.Equal(t, msa3, []string{"1", "2", "3"}) 87 88 mm2 := js.Get("test").Get("missing_map").MustMap(map[string]interface{}{"found": false}) 89 assert.Equal(t, mm2, map[string]interface{}{"found": false}) 90 91 strs, err := js.Get("test").Get("string_array").StringArray() 92 assert.Equal(t, err, nil) 93 assert.Equal(t, strs[0], "asdf") 94 assert.Equal(t, strs[1], "ghjk") 95 assert.Equal(t, strs[2], "zxcv") 96 97 strs2, err := js.Get("test").Get("string_array_null").StringArray() 98 assert.Equal(t, err, nil) 99 assert.Equal(t, strs2[0], "abc") 100 assert.Equal(t, strs2[1], "") 101 assert.Equal(t, strs2[2], "efg") 102 103 gp, _ := js.GetPath("test", "string").String() 104 assert.Equal(t, "simplejson", gp) 105 106 gp2, _ := js.GetPath("test", "int").Int() 107 assert.Equal(t, 10, gp2) 108 109 assert.Equal(t, js.Get("test").Get("bool").MustBool(), true) 110 111 js.Set("float2", 300.0) 112 assert.Equal(t, js.Get("float2").MustFloat64(), 300.0) 113 114 js.Set("test2", "setTest") 115 assert.Equal(t, "setTest", js.Get("test2").MustString()) 116 117 js.Del("test2") 118 assert.NotEqual(t, "setTest", js.Get("test2").MustString()) 119 120 js.Get("test").Get("sub_obj").Set("a", 2) 121 assert.Equal(t, 2, js.Get("test").Get("sub_obj").Get("a").MustInt()) 122 123 js.GetPath("test", "sub_obj").Set("a", 3) 124 assert.Equal(t, 3, js.GetPath("test", "sub_obj", "a").MustInt()) 125} 126 127func TestStdlibInterfaces(t *testing.T) { 128 val := new(struct { 129 Name string `json:"name"` 130 Params *Json `json:"params"` 131 }) 132 val2 := new(struct { 133 Name string `json:"name"` 134 Params *Json `json:"params"` 135 }) 136 137 raw := `{"name":"myobject","params":{"string":"simplejson"}}` 138 139 assert.Equal(t, nil, json.Unmarshal([]byte(raw), val)) 140 141 assert.Equal(t, "myobject", val.Name) 142 assert.NotEqual(t, nil, val.Params.data) 143 s, _ := val.Params.Get("string").String() 144 assert.Equal(t, "simplejson", s) 145 146 p, err := json.Marshal(val) 147 assert.Equal(t, nil, err) 148 assert.Equal(t, nil, json.Unmarshal(p, val2)) 149 assert.Equal(t, val, val2) // stable 150} 151 152func TestSet(t *testing.T) { 153 js, err := NewJson([]byte(`{}`)) 154 assert.Equal(t, nil, err) 155 156 js.Set("baz", "bing") 157 158 s, err := js.GetPath("baz").String() 159 assert.Equal(t, nil, err) 160 assert.Equal(t, "bing", s) 161} 162 163func TestReplace(t *testing.T) { 164 js, err := NewJson([]byte(`{}`)) 165 assert.Equal(t, nil, err) 166 167 err = js.UnmarshalJSON([]byte(`{"baz":"bing"}`)) 168 assert.Equal(t, nil, err) 169 170 s, err := js.GetPath("baz").String() 171 assert.Equal(t, nil, err) 172 assert.Equal(t, "bing", s) 173} 174 175func TestSetPath(t *testing.T) { 176 js, err := NewJson([]byte(`{}`)) 177 assert.Equal(t, nil, err) 178 179 js.SetPath([]string{"foo", "bar"}, "baz") 180 181 s, err := js.GetPath("foo", "bar").String() 182 assert.Equal(t, nil, err) 183 assert.Equal(t, "baz", s) 184} 185 186func TestSetPathNoPath(t *testing.T) { 187 js, err := NewJson([]byte(`{"some":"data","some_number":1.0,"some_bool":false}`)) 188 assert.Equal(t, nil, err) 189 190 f := js.GetPath("some_number").MustFloat64(99.0) 191 assert.Equal(t, f, 1.0) 192 193 js.SetPath([]string{}, map[string]interface{}{"foo": "bar"}) 194 195 s, err := js.GetPath("foo").String() 196 assert.Equal(t, nil, err) 197 assert.Equal(t, "bar", s) 198 199 f = js.GetPath("some_number").MustFloat64(99.0) 200 assert.Equal(t, f, 99.0) 201} 202 203func TestPathWillAugmentExisting(t *testing.T) { 204 js, err := NewJson([]byte(`{"this":{"a":"aa","b":"bb","c":"cc"}}`)) 205 assert.Equal(t, nil, err) 206 207 js.SetPath([]string{"this", "d"}, "dd") 208 209 cases := []struct { 210 path []string 211 outcome string 212 }{ 213 { 214 path: []string{"this", "a"}, 215 outcome: "aa", 216 }, 217 { 218 path: []string{"this", "b"}, 219 outcome: "bb", 220 }, 221 { 222 path: []string{"this", "c"}, 223 outcome: "cc", 224 }, 225 { 226 path: []string{"this", "d"}, 227 outcome: "dd", 228 }, 229 } 230 231 for _, tc := range cases { 232 s, err := js.GetPath(tc.path...).String() 233 assert.Equal(t, nil, err) 234 assert.Equal(t, tc.outcome, s) 235 } 236} 237 238func TestPathWillOverwriteExisting(t *testing.T) { 239 // notice how "a" is 0.1 - but then we'll try to set at path a, foo 240 js, err := NewJson([]byte(`{"this":{"a":0.1,"b":"bb","c":"cc"}}`)) 241 assert.Equal(t, nil, err) 242 243 js.SetPath([]string{"this", "a", "foo"}, "bar") 244 245 s, err := js.GetPath("this", "a", "foo").String() 246 assert.Equal(t, nil, err) 247 assert.Equal(t, "bar", s) 248} 249