PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/onbloc/json/v0

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v0
Namespace
onbloc / json
Files
24 (README)(gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/onbloc/json/v0
gno
0.9

Files (24)

  • README.mdmarkdown
  • gnomod.tomltoml
  • buffer.gnogno
  • builder.gnogno
  • decode.gnogno
  • encode.gnogno
  • errors.gnogno
  • escape.gnogno
  • indent.gnogno
  • internal.gnogno
  • node.gnogno
  • parser.gnogno
  • path.gnogno
  • token.gnogno
  • buffer_test.gnogno
  • builder_test.gnogno
  • decode_test.gnogno
  • encode_test.gnogno
  • escape_test.gnogno
  • indent_test.gnogno
  • node_test.gnogno
  • parser_test.gnogno
  • path_test.gnogno
  • LICENSEother
  • decode_test.gnogno
    1package json23import (4	"bytes"5	"testing"6)78

    Functions

    not supported for pure packages by the node (vm/qfuncs)

    Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.

    type
    testNode
    struct
    {
    9 name string
    10 input []byte
    11 value []byte
    12 _type ValueType
    13}
    14
    15func simpleValid(test *testNode, t *testing.T) {
    16 root, err := Unmarshal(test.input)
    17 if err != nil {
    18 t.Errorf("Error on Unmarshal(%s): %s", test.input, err.Error())
    19 } else if root == nil {
    20 t.Errorf("Error on Unmarshal(%s): root is nil", test.name)
    21 } else if root.nodeType != test._type {
    22 t.Errorf("Error on Unmarshal(%s): wrong type", test.name)
    23 } else if !bytes.Equal(root.source(), test.value) {
    24 t.Errorf("Error on Unmarshal(%s): %s != %s", test.name, root.source(), test.value)
    25 }
    26}
    27
    28func simpleInvalid(test *testNode, t *testing.T) {
    29 root, err := Unmarshal(test.input)
    30 if err == nil {
    31 t.Errorf("Error on Unmarshal(%s): error expected, got '%s'", test.name, root.source())
    32 } else if root != nil {
    33 t.Errorf("Error on Unmarshal(%s): root is not nil", test.name)
    34 }
    35}
    36
    37func simpleCorrupted(name string) *testNode {
    38 return &testNode{name: name, input: []byte(name)}
    39}
    40
    41func TestUnmarshal_StringSimpleSuccess(t *testing.T) {
    42 tests := []*testNode{
    43 {name: "blank", input: []byte("\"\""), _type: String, value: []byte("\"\"")},
    44 {name: "char", input: []byte("\"c\""), _type: String, value: []byte("\"c\"")},
    45 {name: "word", input: []byte("\"cat\""), _type: String, value: []byte("\"cat\"")},
    46 {name: "spaces", input: []byte(" \"good cat or dog\"\r\n "), _type: String, value: []byte("\"good cat or dog\"")},
    47 {name: "backslash", input: []byte("\"good \\\"cat\\\"\""), _type: String, value: []byte("\"good \\\"cat\\\"\"")},
    48 {name: "backslash 2", input: []byte("\"good \\\\\\\"cat\\\"\""), _type: String, value: []byte("\"good \\\\\\\"cat\\\"\"")},
    49 }
    50 for _, test := range tests {
    51 t.Run(test.name, func(t *testing.T) {
    52 simpleValid(test, t)
    53 })
    54 }
    55}
    56
    57func TestUnmarshal_NumericSimpleSuccess(t *testing.T) {
    58 tests := []*testNode{
    59 {name: "1", input: []byte("1"), _type: Number, value: []byte("1")},
    60 {name: "-1", input: []byte("-1"), _type: Number, value: []byte("-1")},
    61
    62 {name: "1234567890", input: []byte("1234567890"), _type: Number, value: []byte("1234567890")},
    63 {name: "-123", input: []byte("-123"), _type: Number, value: []byte("-123")},
    64
    65 {name: "123.456", input: []byte("123.456"), _type: Number, value: []byte("123.456")},
    66 {name: "-123.456", input: []byte("-123.456"), _type: Number, value: []byte("-123.456")},
    67
    68 {name: "1e3", input: []byte("1e3"), _type: Number, value: []byte("1e3")},
    69 {name: "1e+3", input: []byte("1e+3"), _type: Number, value: []byte("1e+3")},
    70 {name: "1e-3", input: []byte("1e-3"), _type: Number, value: []byte("1e-3")},
    71 {name: "-1e3", input: []byte("-1e3"), _type: Number, value: []byte("-1e3")},
    72 {name: "-1e-3", input: []byte("-1e-3"), _type: Number, value: []byte("-1e-3")},
    73
    74 {name: "1.123e3456", input: []byte("1.123e3456"), _type: Number, value: []byte("1.123e3456")},
    75 {name: "1.123e-3456", input: []byte("1.123e-3456"), _type: Number, value: []byte("1.123e-3456")},
    76 {name: "-1.123e3456", input: []byte("-1.123e3456"), _type: Number, value: []byte("-1.123e3456")},
    77 {name: "-1.123e-3456", input: []byte("-1.123e-3456"), _type: Number, value: []byte("-1.123e-3456")},
    78
    79 {name: "1E3", input: []byte("1E3"), _type: Number, value: []byte("1E3")},
    80 {name: "1E-3", input: []byte("1E-3"), _type: Number, value: []byte("1E-3")},
    81 {name: "-1E3", input: []byte("-1E3"), _type: Number, value: []byte("-1E3")},
    82 {name: "-1E-3", input: []byte("-1E-3"), _type: Number, value: []byte("-1E-3")},
    83
    84 {name: "1.123E3456", input: []byte("1.123E3456"), _type: Number, value: []byte("1.123E3456")},
    85 {name: "1.123E-3456", input: []byte("1.123E-3456"), _type: Number, value: []byte("1.123E-3456")},
    86 {name: "-1.123E3456", input: []byte("-1.123E3456"), _type: Number, value: []byte("-1.123E3456")},
    87 {name: "-1.123E-3456", input: []byte("-1.123E-3456"), _type: Number, value: []byte("-1.123E-3456")},
    88
    89 {name: "-1.123E-3456 with spaces", input: []byte(" \r -1.123E-3456 \t\n"), _type: Number, value: []byte("-1.123E-3456")},
    90 }
    91 for _, test := range tests {
    92 t.Run(test.name, func(t *testing.T) {
    93 root, err := Unmarshal(test.input)
    94 if err != nil {
    95 t.Errorf("Error on Unmarshal(%s): %s", test.name, err.Error())
    96 } else if root == nil {
    97 t.Errorf("Error on Unmarshal(%s): root is nil", test.name)
    98 } else if root.nodeType != test._type {
    99 t.Errorf("Error on Unmarshal(%s): wrong type", test.name)
    100 } else if !bytes.Equal(root.source(), test.value) {
    101 t.Errorf("Error on Unmarshal(%s): %s != %s", test.name, root.source(), test.value)
    102 }
    103 })
    104 }
    105}
    106
    107func TestUnmarshal_StringSimpleCorrupted(t *testing.T) {
    108 tests := []*testNode{
    109 {name: "white NL", input: []byte("\"foo\nbar\"")},
    110 {name: "white R", input: []byte("\"foo\rbar\"")},
    111 {name: "white Tab", input: []byte("\"foo\tbar\"")},
    112 {name: "wrong quotes", input: []byte("'cat'")},
    113 {name: "double string", input: []byte("\"Hello\" \"World\"")},
    114 {name: "quotes in quotes", input: []byte("\"good \"cat\"\"")},
    115 }
    116 for _, test := range tests {
    117 t.Run(test.name, func(t *testing.T) {
    118 simpleInvalid(test, t)
    119 })
    120 }
    121}
    122
    123func TestUnmarshal_ObjectSimpleSuccess(t *testing.T) {
    124 tests := []*testNode{
    125 {name: "{}", input: []byte("{}"), _type: Object, value: []byte("{}")},
    126 {name: `{ \r\n }`, input: []byte("{ \r\n }"), _type: Object, value: []byte("{ \r\n }")},
    127 {name: `{"key":1}`, input: []byte(`{"key":1}`), _type: Object, value: []byte(`{"key":1}`)},
    128 {name: `{"key":true}`, input: []byte(`{"key":true}`), _type: Object, value: []byte(`{"key":true}`)},
    129 {name: `{"key":"value"}`, input: []byte(`{"key":"value"}`), _type: Object, value: []byte(`{"key":"value"}`)},
    130 {name: `{"foo":"bar","baz":"foo"}`, input: []byte(`{"foo":"bar", "baz":"foo"}`), _type: Object, value: []byte(`{"foo":"bar", "baz":"foo"}`)},
    131 {name: "spaces", input: []byte(` { "foo" : "bar" , "baz" : "foo" } `), _type: Object, value: []byte(`{ "foo" : "bar" , "baz" : "foo" }`)},
    132 {name: "nested", input: []byte(`{"foo":{"bar":{"baz":{}}}}`), _type: Object, value: []byte(`{"foo":{"bar":{"baz":{}}}}`)},
    133 {name: "array", input: []byte(`{"array":[{},{},{"foo":[{"bar":["baz"]}]}]}`), _type: Object, value: []byte(`{"array":[{},{},{"foo":[{"bar":["baz"]}]}]}`)},
    134 }
    135
    136 for _, test := range tests {
    137 t.Run(test.name, func(t *testing.T) {
    138 simpleValid(test, t)
    139 })
    140 }
    141}
    142
    143func TestUnmarshal_ObjectSimpleCorrupted(t *testing.T) {
    144 tests := []*testNode{
    145 simpleCorrupted("{{{\"key\": \"foo\"{{{{"),
    146 simpleCorrupted("}"),
    147 simpleCorrupted("{ }}}}}}}"),
    148 simpleCorrupted(" }"),
    149 simpleCorrupted("{,}"),
    150 simpleCorrupted("{:}"),
    151 simpleCorrupted("{100000}"),
    152 simpleCorrupted("{1:1}"),
    153 simpleCorrupted("{'1:2,3:4'}"),
    154 simpleCorrupted(`{"d"}`),
    155 simpleCorrupted(`{"foo"}`),
    156 simpleCorrupted(`{"foo":}`),
    157 simpleCorrupted(`{:"foo"}`),
    158 simpleCorrupted(`{"foo":bar}`),
    159 simpleCorrupted(`{"foo":"bar",}`),
    160 simpleCorrupted(`{}{}`),
    161 simpleCorrupted(`{},{}`),
    162 simpleCorrupted(`{[},{]}`),
    163 simpleCorrupted(`{[,]}`),
    164 simpleCorrupted(`{[]}`),
    165 simpleCorrupted(`{}1`),
    166 simpleCorrupted(`1{}`),
    167 simpleCorrupted(`{"x"::1}`),
    168 simpleCorrupted(`{null:null}`),
    169 simpleCorrupted(`{"foo:"bar"}`),
    170 }
    171
    172 for _, test := range tests {
    173 t.Run(test.name, func(t *testing.T) {
    174 simpleInvalid(test, t)
    175 })
    176 }
    177}
    178
    179func TestUnmarshal_NullSimpleCorrupted(t *testing.T) {
    180 tests := []*testNode{
    181 {name: "nul", input: []byte("nul")},
    182 {name: "nil", input: []byte("nil")},
    183 {name: "nill", input: []byte("nill")},
    184 {name: "NILL", input: []byte("NILL")},
    185 {name: "Null", input: []byte("Null")},
    186 {name: "NULL", input: []byte("NULL")},
    187 {name: "spaces", input: []byte("Nu ll")},
    188 {name: "null1", input: []byte("null1")},
    189 {name: "double", input: []byte("null null")},
    190 }
    191
    192 for _, test := range tests {
    193 t.Run(test.name, func(t *testing.T) {
    194 simpleInvalid(test, t)
    195 })
    196 }
    197}
    198
    199func TestUnmarshal_BoolSimpleSuccess(t *testing.T) {
    200 tests := []*testNode{
    201 {name: "lower true", input: []byte("true"), _type: Boolean, value: []byte("true")},
    202 {name: "lower false", input: []byte("false"), _type: Boolean, value: []byte("false")},
    203 {name: "spaces true", input: []byte(" true\r\n "), _type: Boolean, value: []byte("true")},
    204 {name: "spaces false", input: []byte(" false\r\n "), _type: Boolean, value: []byte("false")},
    205 }
    206
    207 for _, test := range tests {
    208 t.Run(test.name, func(t *testing.T) {
    209 simpleValid(test, t)
    210 })
    211 }
    212}
    213
    214func TestUnmarshal_BoolSimpleCorrupted(t *testing.T) {
    215 tests := []*testNode{
    216 simpleCorrupted("tru"),
    217 simpleCorrupted("fals"),
    218 simpleCorrupted("tre"),
    219 simpleCorrupted("fal se"),
    220 simpleCorrupted("true false"),
    221 simpleCorrupted("True"),
    222 simpleCorrupted("TRUE"),
    223 simpleCorrupted("False"),
    224 simpleCorrupted("FALSE"),
    225 }
    226
    227 for _, test := range tests {
    228 t.Run(test.name, func(t *testing.T) {
    229 simpleInvalid(test, t)
    230 })
    231 }
    232}
    233
    234func TestUnmarshal_ArraySimpleSuccess(t *testing.T) {
    235 tests := []*testNode{
    236 {name: "[]", input: []byte("[]"), _type: Array, value: []byte("[]")},
    237 {name: "[1]", input: []byte("[1]"), _type: Array, value: []byte("[1]")},
    238 {name: "[1,2,3]", input: []byte("[1,2,3]"), _type: Array, value: []byte("[1,2,3]")},
    239 {name: "[1, 2, 3]", input: []byte("[1, 2, 3]"), _type: Array, value: []byte("[1, 2, 3]")},
    240 {name: "[1,[2],3]", input: []byte("[1,[2],3]"), _type: Array, value: []byte("[1,[2],3]")},
    241 {name: "[[],[],[]]", input: []byte("[[],[],[]]"), _type: Array, value: []byte("[[],[],[]]")},
    242 {name: "[[[[[]]]]]", input: []byte("[[[[[]]]]]"), _type: Array, value: []byte("[[[[[]]]]]")},
    243 {name: "[true,null,1,\"foo\",[]]", input: []byte("[true,null,1,\"foo\",[]]"), _type: Array, value: []byte("[true,null,1,\"foo\",[]]")},
    244 {name: "spaces", input: []byte("\n\r [\n1\n ]\r\n"), _type: Array, value: []byte("[\n1\n ]")},
    245 }
    246
    247 for _, test := range tests {
    248 t.Run(test.name, func(t *testing.T) {
    249 simpleValid(test, t)
    250 })
    251 }
    252}
    253
    254func TestUnmarshal_ArraySimpleCorrupted(t *testing.T) {
    255 tests := []*testNode{
    256 simpleCorrupted("[,]"),
    257 simpleCorrupted("[]\\"),
    258 simpleCorrupted("[1,]"),
    259 simpleCorrupted("[[]"),
    260 simpleCorrupted("[]]"),
    261 simpleCorrupted("1[]"),
    262 simpleCorrupted("[]1"),
    263 simpleCorrupted("[[]1]"),
    264 }
    265
    266 for _, test := range tests {
    267 t.Run(test.name, func(t *testing.T) {
    268 simpleInvalid(test, t)
    269 })
    270 }
    271}
    272
    273// Examples from https://json.org/example.html
    274func TestUnmarshal(t *testing.T) {
    275 tests := []struct {
    276 name string
    277 value string
    278 }{
    279 {
    280 name: "glossary",
    281 value: `{
    282 "glossary": {
    283 "title": "example glossary",
    284 "GlossDiv": {
    285 "title": "S",
    286 "GlossList": {
    287 "GlossEntry": {
    288 "ID": "SGML",
    289 "SortAs": "SGML",
    290 "GlossTerm": "Standard Generalized Markup Language",
    291 "Acronym": "SGML",
    292 "Abbrev": "ISO 8879:1986",
    293 "GlossDef": {
    294 "para": "A meta-markup language, used to create markup languages such as DocBook.",
    295 "GlossSeeAlso": ["GML", "XML"]
    296 },
    297 "GlossSee": "markup"
    298 }
    299 }
    300 }
    301 }
    302 }`,
    303 },
    304 {
    305 name: "menu",
    306 value: `{"menu": {
    307 "id": "file",
    308 "value": "File",
    309 "popup": {
    310 "menuitem": [
    311 {"value": "New", "onclick": "CreateNewDoc()"},
    312 {"value": "Open", "onclick": "OpenDoc()"},
    313 {"value": "Close", "onclick": "CloseDoc()"}
    314 ]
    315 }
    316 }}`,
    317 },
    318 {
    319 name: "widget",
    320 value: `{"widget": {
    321 "debug": "on",
    322 "window": {
    323 "title": "Sample Konfabulator Widget",
    324 "name": "main_window",
    325 "width": 500,
    326 "height": 500
    327 },
    328 "image": {
    329 "src": "Images/Sun.png",
    330 "name": "sun1",
    331 "hOffset": 250,
    332 "vOffset": 250,
    333 "alignment": "center"
    334 },
    335 "text": {
    336 "data": "Click Here",
    337 "size": 36,
    338 "style": "bold",
    339 "name": "text1",
    340 "hOffset": 250,
    341 "vOffset": 100,
    342 "alignment": "center",
    343 "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
    344 }
    345 }} `,
    346 },
    347 {
    348 name: "web-app",
    349 value: `{"web-app": {
    350 "servlet": [
    351 {
    352 "servlet-name": "cofaxCDS",
    353 "servlet-class": "org.cofax.cds.CDSServlet",
    354 "init-param": {
    355 "configGlossary:installationAt": "Philadelphia, PA",
    356 "configGlossary:adminEmail": "ksm@pobox.com",
    357 "configGlossary:poweredBy": "Cofax",
    358 "configGlossary:poweredByIcon": "/images/cofax.gif",
    359 "configGlossary:staticPath": "/content/static",
    360 "templateProcessorClass": "org.cofax.WysiwygTemplate",
    361 "templateLoaderClass": "org.cofax.FilesTemplateLoader",
    362 "templatePath": "templates",
    363 "templateOverridePath": "",
    364 "defaultListTemplate": "listTemplate.htm",
    365 "defaultFileTemplate": "articleTemplate.htm",
    366 "useJSP": false,
    367 "jspListTemplate": "listTemplate.jsp",
    368 "jspFileTemplate": "articleTemplate.jsp",
    369 "cachePackageTagsTrack": 200,
    370 "cachePackageTagsStore": 200,
    371 "cachePackageTagsRefresh": 60,
    372 "cacheTemplatesTrack": 100,
    373 "cacheTemplatesStore": 50,
    374 "cacheTemplatesRefresh": 15,
    375 "cachePagesTrack": 200,
    376 "cachePagesStore": 100,
    377 "cachePagesRefresh": 10,
    378 "cachePagesDirtyRead": 10,
    379 "searchEngineListTemplate": "forSearchEnginesList.htm",
    380 "searchEngineFileTemplate": "forSearchEngines.htm",
    381 "searchEngineRobotsDb": "WEB-INF/robots.db",
    382 "useDataStore": true,
    383 "dataStoreClass": "org.cofax.SqlDataStore",
    384 "redirectionClass": "org.cofax.SqlRedirection",
    385 "dataStoreName": "cofax",
    386 "dataStoreDriver": "com.microsoft.jdbc.sqlserver.SQLServerDriver",
    387 "dataStoreUrl": "jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon",
    388 "dataStoreUser": "sa",
    389 "dataStorePassword": "dataStoreTestQuery",
    390 "dataStoreTestQuery": "SET NOCOUNT ON;select test='test';",
    391 "dataStoreLogFile": "/usr/local/tomcat/logs/datastore.log",
    392 "dataStoreInitConns": 10,
    393 "dataStoreMaxConns": 100,
    394 "dataStoreConnUsageLimit": 100,
    395 "dataStoreLogLevel": "debug",
    396 "maxUrlLength": 500}},
    397 {
    398 "servlet-name": "cofaxEmail",
    399 "servlet-class": "org.cofax.cds.EmailServlet",
    400 "init-param": {
    401 "mailHost": "mail1",
    402 "mailHostOverride": "mail2"}},
    403 {
    404 "servlet-name": "cofaxAdmin",
    405 "servlet-class": "org.cofax.cds.AdminServlet"},
    406
    407 {
    408 "servlet-name": "fileServlet",
    409 "servlet-class": "org.cofax.cds.FileServlet"},
    410 {
    411 "servlet-name": "cofaxTools",
    412 "servlet-class": "org.cofax.cms.CofaxToolsServlet",
    413 "init-param": {
    414 "templatePath": "toolstemplates/",
    415 "log": 1,
    416 "logLocation": "/usr/local/tomcat/logs/CofaxTools.log",
    417 "logMaxSize": "",
    418 "dataLog": 1,
    419 "dataLogLocation": "/usr/local/tomcat/logs/dataLog.log",
    420 "dataLogMaxSize": "",
    421 "removePageCache": "/content/admin/remove?cache=pages&id=",
    422 "removeTemplateCache": "/content/admin/remove?cache=templates&id=",
    423 "fileTransferFolder": "/usr/local/tomcat/webapps/content/fileTransferFolder",
    424 "lookInContext": 1,
    425 "adminGroupID": 4,
    426 "betaServer": true}}],
    427 "servlet-mapping": {
    428 "cofaxCDS": "/",
    429 "cofaxEmail": "/cofaxutil/aemail/*",
    430 "cofaxAdmin": "/admin/*",
    431 "fileServlet": "/static/*",
    432 "cofaxTools": "/tools/*"},
    433
    434 "taglib": {
    435 "taglib-uri": "cofax.tld",
    436 "taglib-location": "/WEB-INF/tlds/cofax.tld"}}}`,
    437 },
    438 {
    439 name: "SVG Viewer",
    440 value: `{"menu": {
    441 "header": "SVG Viewer",
    442 "items": [
    443 {"id": "Open"},
    444 {"id": "OpenNew", "label": "Open New"},
    445 null,
    446 {"id": "ZoomIn", "label": "Zoom In"},
    447 {"id": "ZoomOut", "label": "Zoom Out"},
    448 {"id": "OriginalView", "label": "Original View"},
    449 null,
    450 {"id": "Quality"},
    451 {"id": "Pause"},
    452 {"id": "Mute"},
    453 null,
    454 {"id": "Find", "label": "Find..."},
    455 {"id": "FindAgain", "label": "Find Again"},
    456 {"id": "Copy"},
    457 {"id": "CopyAgain", "label": "Copy Again"},
    458 {"id": "CopySVG", "label": "Copy SVG"},
    459 {"id": "ViewSVG", "label": "View SVG"},
    460 {"id": "ViewSource", "label": "View Source"},
    461 {"id": "SaveAs", "label": "Save As"},
    462 null,
    463 {"id": "Help"},
    464 {"id": "About", "label": "About Adobe CVG Viewer..."}
    465 ]
    466 }}`,
    467 },
    468 }
    469 for _, test := range tests {
    470 t.Run(test.name, func(t *testing.T) {
    471 _, err := Unmarshal([]byte(test.value))
    472 if err != nil {
    473 t.Errorf("Error on Unmarshal: %s", err.Error())
    474 }
    475 })
    476 }
    477}
    478
    479func TestUnmarshalSafe(t *testing.T) {
    480 json := []byte(`{ "store": {
    481 "book": [
    482 { "category": "reference",
    483 "author": "Nigel Rees",
    484 "title": "Sayings of the Century",
    485 "price": 8.95
    486 },
    487 { "category": "fiction",
    488 "author": "Evelyn Waugh",
    489 "title": "Sword of Honour",
    490 "price": 12.99
    491 },
    492 { "category": "fiction",
    493 "author": "Herman Melville",
    494 "title": "Moby Dick",
    495 "isbn": "0-553-21311-3",
    496 "price": 8.99
    497 },
    498 { "category": "fiction",
    499 "author": "J. R. R. Tolkien",
    500 "title": "The Lord of the Rings",
    501 "isbn": "0-395-19395-8",
    502 "price": 22.99
    503 }
    504 ],
    505 "bicycle": {
    506 "color": "red",
    507 "price": 19.95
    508 }
    509 }
    510 }`)
    511 safe, err := UnmarshalSafe(json)
    512 if err != nil {
    513 t.Errorf("Error on Unmarshal: %s", err.Error())
    514 } else if safe == nil {
    515 t.Errorf("Error on Unmarshal: safe is nil")
    516 } else {
    517 root, err := Unmarshal(json)
    518 if err != nil {
    519 t.Errorf("Error on Unmarshal: %s", err.Error())
    520 } else if root == nil {
    521 t.Errorf("Error on Unmarshal: root is nil")
    522 } else if !bytes.Equal(root.source(), safe.source()) {
    523 t.Errorf("Error on UnmarshalSafe: values not same")
    524 }
    525 }
    526}
    527
    528// BenchmarkGoStdUnmarshal-8 61698 19350 ns/op 288 B/op 6 allocs/op
    529// BenchmarkUnmarshal-8 45620 26165 ns/op 21889 B/op 367 allocs/op
    530//
    531// type bench struct {
    532// Name string `json:"name"`
    533// Value int `json:"value"`
    534// }
    535
    536// func BenchmarkGoStdUnmarshal(b *testing.B) {
    537// data := []byte(webApp)
    538// for i := 0; i < b.N; i++ {
    539// err := json.Unmarshal(data, &bench{})
    540// if err != nil {
    541// b.Fatal(err)
    542// }
    543// }
    544// }
    545
    546// func BenchmarkUnmarshal(b *testing.B) {
    547// data := []byte(webApp)
    548// for i := 0; i < b.N; i++ {
    549// _, err := Unmarshal(data)
    550// if err != nil {
    551// b.Fatal(err)
    552// }
    553// }
    554// }
    555