Skip to content
This repository was archived by the owner on Aug 9, 2018. It is now read-only.

Commit 861ddcf

Browse files
committed
Test JSON decoding and fix implentation
Add a test that decodes a JSON object, and detect links in it. Then encode it again and it must match the original file. The test failed (because the link was a map[string]interface{} instead of a Node). The fix post-process the result of the JSON decoder to convert map[string]interface{} to Node.
1 parent e2e1c76 commit 861ddcf

File tree

5 files changed

+126
-5
lines changed

5 files changed

+126
-5
lines changed

coding/Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,9 @@ pb/testfile:
99
pb/bin/multicodec:
1010
$(MAKE) -C pb bin/multicodec
1111

12+
json.testfile: pb/bin/multicodec Makefile
13+
: >$@
14+
pb/bin/multicodec header /multicodec >>$@
15+
pb/bin/multicodec header /json >>$@
16+
echo '{"@codec":"/json","abc":{"mlink":"QmXg9Pp2ytZ14xgmQjYEiHjVjMFXzCVVEcRTWJBmLgR39V"}}' >>$@
17+

coding/coding.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package ipfsld
33
import (
44
mc "github.com/jbenet/go-multicodec"
55
mccbor "github.com/jbenet/go-multicodec/cbor"
6-
mcjson "github.com/jbenet/go-multicodec/json"
76
mcmux "github.com/jbenet/go-multicodec/mux"
87

98
ipld "github.com/ipfs/go-ipld"
@@ -24,7 +23,7 @@ func init() {
2423
defaultCodec = string(mc.HeaderPath(mccbor.Header))
2524
muxCodec = mcmux.MuxMulticodec([]mc.Multicodec{
2625
mccbor.Multicodec(),
27-
mcjson.Multicodec(false),
26+
jsonMulticodec(),
2827
pb.Multicodec(),
2928
}, selectCodec)
3029
}
@@ -61,8 +60,6 @@ func codecKey(n ipld.Node) (string, error) {
6160
if !ok {
6261
// if no codec is defined, use our default codec
6362
chdr = defaultCodec
64-
65-
// except, if it looks like an old, style protobuf object
6663
}
6764

6865
chdrs, ok := chdr.(string)

coding/coding_test.go

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package ipfsld
33
import (
44
"bytes"
55
"testing"
6+
"reflect"
67
"io/ioutil"
78

89
ipld "github.com/ipfs/go-ipld"
@@ -11,14 +12,18 @@ import (
1112
mctest "github.com/jbenet/go-multicodec/test"
1213
)
1314

14-
var testfile []byte
15+
var testfile, json_testfile []byte
1516

1617
func init() {
1718
var err error
1819
testfile, err = ioutil.ReadFile("testfile")
1920
if err != nil {
2021
panic("could not read testfile. please run: make testfile")
2122
}
23+
json_testfile, err = ioutil.ReadFile("json.testfile")
24+
if err != nil {
25+
panic("could not read json.testfile. please run: make json.testfile")
26+
}
2227
}
2328

2429
type TC struct {
@@ -125,3 +130,42 @@ func TestPbDecodeEncode(t *testing.T) {
125130
t.Log(encoded)
126131
}
127132
}
133+
134+
// Test decoding and encoding a json file
135+
func TestJsonDecodeEncode(t *testing.T) {
136+
var n ipld.Node
137+
codec := Multicodec()
138+
139+
if err := mc.Unmarshal(codec, json_testfile, &n); err != nil {
140+
t.Log(json_testfile)
141+
t.Error(err)
142+
return
143+
}
144+
145+
linksExpected := map[string]ipld.Link{
146+
"abc": ipld.Link {
147+
"mlink": "QmXg9Pp2ytZ14xgmQjYEiHjVjMFXzCVVEcRTWJBmLgR39V",
148+
},
149+
}
150+
linksActual := ipld.Links(n)
151+
if !reflect.DeepEqual(linksExpected, linksActual) {
152+
t.Log(linksExpected)
153+
t.Log(linksActual)
154+
t.Logf("node: %#v\n", n)
155+
t.Fatalf("Links are not expected")
156+
}
157+
158+
encoded, err := mc.Marshal(codec, &n)
159+
if err != nil {
160+
t.Error(err)
161+
return
162+
}
163+
164+
if !bytes.Equal(json_testfile, encoded) {
165+
t.Error("marshalled values not equal")
166+
t.Log(string(json_testfile))
167+
t.Log(string(encoded))
168+
t.Log(json_testfile)
169+
t.Log(encoded)
170+
}
171+
}

coding/json.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package ipfsld
2+
3+
import (
4+
"io"
5+
6+
mc "github.com/jbenet/go-multicodec"
7+
mcjson "github.com/jbenet/go-multicodec/json"
8+
ipld "github.com/ipfs/go-ipld"
9+
)
10+
11+
type codec struct {
12+
mc.Multicodec
13+
}
14+
15+
type decoder struct {
16+
mc.Decoder
17+
}
18+
19+
func jsonMulticodec() mc.Multicodec {
20+
return &codec{mcjson.Multicodec(false)}
21+
}
22+
23+
func (c *codec) Decoder(r io.Reader) mc.Decoder {
24+
return &decoder{ c.Multicodec.Decoder(r) }
25+
}
26+
27+
func (c *decoder) Decode(v interface{}) error {
28+
err := c.Decoder.Decode(v)
29+
if err == nil {
30+
convert(v)
31+
}
32+
return err
33+
}
34+
35+
func convert(val interface{}) interface{} {
36+
switch val.(type) {
37+
case *map[string]interface{}:
38+
vmi := val.(*map[string]interface{})
39+
n := ipld.Node{}
40+
for k, v := range *vmi {
41+
n[k] = convert(v)
42+
(*vmi)[k] = convert(v)
43+
}
44+
return &n
45+
case map[string]interface{}:
46+
vmi := val.(map[string]interface{})
47+
n := ipld.Node{}
48+
for k, v := range vmi {
49+
n[k] = convert(v)
50+
vmi[k] = convert(v)
51+
}
52+
return n
53+
case *[]interface{}:
54+
convert(*val.(*[]interface{}))
55+
case []interface{}:
56+
slice := val.([]interface{})
57+
for k, v := range slice {
58+
slice[k] = convert(v)
59+
}
60+
case *ipld.Node:
61+
convert(*val.(*ipld.Node))
62+
case ipld.Node:
63+
n := val.(ipld.Node)
64+
for k, v := range n {
65+
n[k] = convert(v)
66+
}
67+
default:
68+
}
69+
return val
70+
}
71+

coding/json.testfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/multicodec
2+
/json
3+
{"@codec":"/json","abc":{"mlink":"QmXg9Pp2ytZ14xgmQjYEiHjVjMFXzCVVEcRTWJBmLgR39V"}}

0 commit comments

Comments
 (0)