github.com/unigraph-dev/dgraph@v1.1.1-0.20200923154953-8b52b426f765/chunker/chunk_test.go (about) 1 /* 2 * Copyright 2017-2018 Dgraph Labs, Inc. and Contributors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package chunker 18 19 import ( 20 "bufio" 21 "bytes" 22 "fmt" 23 "io" 24 "strings" 25 "testing" 26 27 "github.com/stretchr/testify/require" 28 ) 29 30 func bufioReader(str string) *bufio.Reader { 31 return bufio.NewReader(strings.NewReader(str)) 32 } 33 34 // Test that problems at the start of the JSON document are caught. 35 func TestJSONLoadStart(t *testing.T) { 36 var tests = []struct { 37 json string 38 desc string 39 }{ 40 {"[,]", "Illegal rune found \",\", expecting {"}, 41 {"[a]", "Illegal rune found \"a\", expecting {"}, 42 {"{}]", "JSON map is followed by an extraneous ]"}, 43 {"These are words.", "file is not JSON"}, 44 {"\x1f\x8b\x08\x08\x3e\xc7\x0a\x5c\x00\x03\x65\x6d\x70\x74\x79\x00", "file is binary"}, 45 } 46 47 for _, test := range tests { 48 chunker := NewChunker(JsonFormat, 1000) 49 _, err := chunker.Chunk(bufioReader(test.json)) 50 require.True(t, err != nil && err != io.EOF, test.desc) 51 } 52 } 53 54 func TestChunkJSONMapAndArray(t *testing.T) { 55 tests := []struct { 56 json string 57 chunks []string 58 }{ 59 {`[]`, []string{"[]"}}, 60 {`[{}]`, []string{"[{}]"}}, 61 {`[{"user": "alice"}]`, []string{`[{"user":"alice"}]`}}, 62 {`[{"user": "alice", "age": 26}]`, []string{`[{"user":"alice","age":26}]`}}, 63 {`[{"user": "alice", "age": 26}, {"name": "bob"}]`, []string{`[{"user":"alice","age":26},{"name":"bob"}]`}}, 64 } 65 66 for _, test := range tests { 67 chunker := NewChunker(JsonFormat, 1000) 68 r := bufioReader(test.json) 69 var chunks []string 70 for { 71 chunkBuf, err := chunker.Chunk(r) 72 if err != nil { 73 require.Equal(t, io.EOF, err, "Received error for %s", test) 74 } 75 76 chunks = append(chunks, chunkBuf.String()) 77 78 if err == io.EOF { 79 break 80 } 81 } 82 83 require.Equal(t, test.chunks, chunks, "Got different chunks") 84 } 85 } 86 87 // Test that problems at the start of the next chunk are caught. 88 func TestJSONLoadReadNext(t *testing.T) { 89 var tests = []struct { 90 json string 91 desc string 92 }{ 93 {"[,]", "no start of JSON map 1"}, 94 {"[ this is not really a json array ]", "no start of JSON map 2"}, 95 {"[{]", "malformed map"}, 96 {"[{}", "malformed array"}, 97 } 98 for _, test := range tests { 99 chunker := NewChunker(JsonFormat, 1000) 100 reader := bufioReader(test.json) 101 chunkBuf, err := chunker.Chunk(reader) 102 if err == nil { 103 err = chunker.Parse(chunkBuf) 104 require.True(t, err != nil && err != io.EOF, test.desc) 105 } else { 106 require.True(t, err != io.EOF, test.desc) 107 } 108 } 109 } 110 111 // Test that loading first chunk succeeds. No need to test that loaded chunk is valid. 112 func TestJSONLoadSuccessFirst(t *testing.T) { 113 var tests = []struct { 114 json string 115 expt string 116 desc string 117 }{ 118 {"[{}]", "[{}]", "empty map"}, 119 {`[{"closingDelimeter":"}"}]`, `[{"closingDelimeter":"}"}]`, "quoted closing brace"}, 120 {`[{"company":"dgraph"}]`, `[{"company":"dgraph"}]`, "simple, compact map"}, 121 { 122 "[\n {\n \"company\" : \"dgraph\"\n }\n]\n", 123 "[{\"company\":\"dgraph\"}]", 124 "simple, pretty map", 125 }, 126 { 127 `[{"professor":"Alastor \"Mad-Eye\" Moody"}]`, 128 `[{"professor":"Alastor \"Mad-Eye\" Moody"}]`, 129 "escaped balanced quotes", 130 }, 131 { 132 133 `[{"something{": "}something"}]`, 134 `[{"something{":"}something"}]`, 135 "escape quoted brackets", 136 }, 137 { 138 `[{"height":"6'0\""}]`, 139 `[{"height":"6'0\""}]`, 140 "escaped unbalanced quote", 141 }, 142 { 143 `[{"house":{"Hermione":"Gryffindor","Cedric":"Hufflepuff","Luna":"Ravenclaw","Draco":"Slytherin",}}]`, 144 `[{"house":{"Hermione":"Gryffindor","Cedric":"Hufflepuff","Luna":"Ravenclaw","Draco":"Slytherin",}}]`, 145 "nested braces", 146 }, 147 } 148 for _, test := range tests { 149 chunker := NewChunker(JsonFormat, 1000) 150 reader := bufioReader(test.json) 151 json, err := chunker.Chunk(reader) 152 if err == io.EOF { 153 // pass 154 } else { 155 require.NoError(t, err, test.desc) 156 } 157 //fmt.Fprintf(os.Stderr, "err = %v, json = %v\n", err, json) 158 require.Equal(t, test.expt, json.String(), test.desc) 159 } 160 } 161 162 // Test that loading all chunks succeeds. No need to test that loaded chunk is valid. 163 func TestJSONLoadSuccessAll(t *testing.T) { 164 var testDoc = ` 165 [ 166 {}, 167 { 168 "closingDelimeter" : "}" 169 }, 170 { 171 "company" : "dgraph", 172 "age": 3 173 }, 174 { 175 "professor" : "Alastor \"Mad-Eye\" Moody", 176 "height" : "6'0\"" 177 }, 178 { 179 "house" : { 180 "Hermione" : "Gryffindor", 181 "Cedric" : "Hufflepuff", 182 "Luna" : "Ravenclaw", 183 "Draco" : "Slytherin" 184 } 185 } 186 ]` 187 var testChunks = []string{ 188 `{}`, 189 `{ 190 "closingDelimeter" : "}" 191 }`, 192 `{ 193 "company" : "dgraph", 194 "age": 3 195 }`, 196 `{ 197 "professor" : "Alastor \"Mad-Eye\" Moody", 198 "height" : "6'0\"" 199 }`, 200 `{ 201 "house" : { 202 "Hermione" : "Gryffindor", 203 "Cedric" : "Hufflepuff", 204 "Luna" : "Ravenclaw", 205 "Draco" : "Slytherin" 206 } 207 }`, 208 } 209 210 chunker := NewChunker(JsonFormat, 1000) 211 reader := bufioReader(testDoc) 212 213 var json *bytes.Buffer 214 var idx int 215 216 var err error 217 for idx = 0; err == nil; idx++ { 218 desc := fmt.Sprintf("reading chunk #%d", idx+1) 219 json, err = chunker.Chunk(reader) 220 //fmt.Fprintf(os.Stderr, "err = %v, json = %v\n", err, json) 221 if err != io.EOF { 222 require.NoError(t, err, desc) 223 require.Equal(t, testChunks[idx], json.String(), desc) 224 } 225 } 226 require.Equal(t, io.EOF, err, "end reading JSON document") 227 }