github.com/tomwright/dasel@v1.27.3/storage/parser_test.go (about) 1 package storage_test 2 3 import ( 4 "bytes" 5 "errors" 6 "github.com/tomwright/dasel/storage" 7 "reflect" 8 "strings" 9 "testing" 10 ) 11 12 func TestUnknownParserErr_Error(t *testing.T) { 13 if exp, got := "unknown parser: x", (&storage.UnknownParserErr{Parser: "x"}).Error(); exp != got { 14 t.Errorf("expected error %s, got %s", exp, got) 15 } 16 } 17 18 func TestNewReadParserFromString(t *testing.T) { 19 tests := []struct { 20 In string 21 Out storage.Parser 22 Err error 23 }{ 24 {In: "json", Out: &storage.JSONParser{}}, 25 {In: "yaml", Out: &storage.YAMLParser{}}, 26 {In: "yml", Out: &storage.YAMLParser{}}, 27 {In: "toml", Out: &storage.TOMLParser{}}, 28 {In: "xml", Out: &storage.XMLParser{}}, 29 {In: "csv", Out: &storage.CSVParser{}}, 30 {In: "bad", Out: nil, Err: &storage.UnknownParserErr{Parser: "bad"}}, 31 {In: "-", Out: nil, Err: &storage.UnknownParserErr{Parser: "-"}}, 32 } 33 34 for _, testCase := range tests { 35 tc := testCase 36 t.Run(tc.In, func(t *testing.T) { 37 got, err := storage.NewReadParserFromString(tc.In) 38 if tc.Err == nil && err != nil { 39 t.Errorf("expected err %v, got %v", tc.Err, err) 40 return 41 } 42 if tc.Err != nil && err == nil { 43 t.Errorf("expected err %v, got %v", tc.Err, err) 44 return 45 } 46 if tc.Err != nil && err != nil && err.Error() != tc.Err.Error() { 47 t.Errorf("expected err %v, got %v", tc.Err, err) 48 return 49 } 50 if tc.Out != got { 51 t.Errorf("expected result %v, got %v", tc.Out, got) 52 } 53 }) 54 } 55 } 56 57 func TestNewWriteParserFromString(t *testing.T) { 58 tests := []struct { 59 In string 60 Out storage.Parser 61 Err error 62 }{ 63 {In: "json", Out: &storage.JSONParser{}}, 64 {In: "yaml", Out: &storage.YAMLParser{}}, 65 {In: "yml", Out: &storage.YAMLParser{}}, 66 {In: "toml", Out: &storage.TOMLParser{}}, 67 {In: "xml", Out: &storage.XMLParser{}}, 68 {In: "csv", Out: &storage.CSVParser{}}, 69 {In: "-", Out: &storage.PlainParser{}}, 70 {In: "plain", Out: &storage.PlainParser{}}, 71 {In: "bad", Out: nil, Err: &storage.UnknownParserErr{Parser: "bad"}}, 72 } 73 74 for _, testCase := range tests { 75 tc := testCase 76 t.Run(tc.In, func(t *testing.T) { 77 got, err := storage.NewWriteParserFromString(tc.In) 78 if tc.Err == nil && err != nil { 79 t.Errorf("expected err %v, got %v", tc.Err, err) 80 return 81 } 82 if tc.Err != nil && err == nil { 83 t.Errorf("expected err %v, got %v", tc.Err, err) 84 return 85 } 86 if tc.Err != nil && err != nil && err.Error() != tc.Err.Error() { 87 t.Errorf("expected err %v, got %v", tc.Err, err) 88 return 89 } 90 if tc.Out != got { 91 t.Errorf("expected result %v, got %v", tc.Out, got) 92 } 93 }) 94 } 95 } 96 97 func TestNewReadParserFromFilename(t *testing.T) { 98 tests := []struct { 99 In string 100 Out storage.Parser 101 Err error 102 }{ 103 {In: "a.json", Out: &storage.JSONParser{}}, 104 {In: "a.yaml", Out: &storage.YAMLParser{}}, 105 {In: "a.yml", Out: &storage.YAMLParser{}}, 106 {In: "a.toml", Out: &storage.TOMLParser{}}, 107 {In: "a.xml", Out: &storage.XMLParser{}}, 108 {In: "a.csv", Out: &storage.CSVParser{}}, 109 {In: "a.txt", Out: nil, Err: &storage.UnknownParserErr{Parser: ".txt"}}, 110 } 111 112 for _, testCase := range tests { 113 tc := testCase 114 t.Run(tc.In, func(t *testing.T) { 115 got, err := storage.NewReadParserFromFilename(tc.In) 116 if tc.Err == nil && err != nil { 117 t.Errorf("expected err %v, got %v", tc.Err, err) 118 return 119 } 120 if tc.Err != nil && err == nil { 121 t.Errorf("expected err %v, got %v", tc.Err, err) 122 return 123 } 124 if tc.Err != nil && err != nil && err.Error() != tc.Err.Error() { 125 t.Errorf("expected err %v, got %v", tc.Err, err) 126 return 127 } 128 if tc.Out != got { 129 t.Errorf("expected result %v, got %v", tc.Out, got) 130 } 131 }) 132 } 133 } 134 135 func TestNewWriteParserFromFilename(t *testing.T) { 136 tests := []struct { 137 In string 138 Out storage.Parser 139 Err error 140 }{ 141 {In: "a.json", Out: &storage.JSONParser{}}, 142 {In: "a.yaml", Out: &storage.YAMLParser{}}, 143 {In: "a.yml", Out: &storage.YAMLParser{}}, 144 {In: "a.toml", Out: &storage.TOMLParser{}}, 145 {In: "a.xml", Out: &storage.XMLParser{}}, 146 {In: "a.csv", Out: &storage.CSVParser{}}, 147 {In: "a.txt", Out: nil, Err: &storage.UnknownParserErr{Parser: ".txt"}}, 148 } 149 150 for _, testCase := range tests { 151 tc := testCase 152 t.Run(tc.In, func(t *testing.T) { 153 got, err := storage.NewWriteParserFromFilename(tc.In) 154 if tc.Err == nil && err != nil { 155 t.Errorf("expected err %v, got %v", tc.Err, err) 156 return 157 } 158 if tc.Err != nil && err == nil { 159 t.Errorf("expected err %v, got %v", tc.Err, err) 160 return 161 } 162 if tc.Err != nil && err != nil && err.Error() != tc.Err.Error() { 163 t.Errorf("expected err %v, got %v", tc.Err, err) 164 return 165 } 166 if tc.Out != got { 167 t.Errorf("expected result %v, got %v", tc.Out, got) 168 } 169 }) 170 } 171 } 172 173 var jsonData = map[string]interface{}{ 174 "name": "Tom", 175 "preferences": map[string]interface{}{ 176 "favouriteColour": "red", 177 }, 178 "colours": []interface{}{"red", "green", "blue"}, 179 "colourCodes": []interface{}{ 180 map[string]interface{}{ 181 "name": "red", 182 "rgb": "ff0000", 183 }, 184 map[string]interface{}{ 185 "name": "green", 186 "rgb": "00ff00", 187 }, 188 map[string]interface{}{ 189 "name": "blue", 190 "rgb": "0000ff", 191 }, 192 }, 193 } 194 195 func TestLoadFromFile(t *testing.T) { 196 t.Run("ValidJSON", func(t *testing.T) { 197 data, err := storage.LoadFromFile("../tests/assets/example.json", &storage.JSONParser{}) 198 if err != nil { 199 t.Errorf("unexpected error: %s", err) 200 return 201 } 202 exp := &storage.BasicSingleDocument{Value: jsonData} 203 if !reflect.DeepEqual(exp, data) { 204 t.Errorf("data does not match: exp %v, got %v", exp, data) 205 } 206 }) 207 t.Run("BaseFilePath", func(t *testing.T) { 208 _, err := storage.LoadFromFile("x.json", &storage.JSONParser{}) 209 if err == nil || !strings.Contains(err.Error(), "could not open file") { 210 t.Errorf("unexpected error: %v", err) 211 return 212 } 213 }) 214 } 215 216 func TestLoad(t *testing.T) { 217 t.Run("ReaderErrHandled", func(t *testing.T) { 218 if _, err := storage.Load(&storage.JSONParser{}, &failingReader{}); !errors.Is(err, errFailingReaderErr) { 219 t.Errorf("unexpected error: %v", err) 220 return 221 } 222 }) 223 } 224 225 var errFailingParserErr = errors.New("i am meant to fail at parsing") 226 227 type failingParser struct { 228 } 229 230 func (fp *failingParser) FromBytes(_ []byte) (interface{}, error) { 231 return nil, errFailingParserErr 232 } 233 234 func (fp *failingParser) ToBytes(_ interface{}, options ...storage.ReadWriteOption) ([]byte, error) { 235 return nil, errFailingParserErr 236 } 237 238 var errFailingWriterErr = errors.New("i am meant to fail at writing") 239 240 type failingWriter struct { 241 } 242 243 func (fp *failingWriter) Write(_ []byte) (int, error) { 244 return 0, errFailingWriterErr 245 } 246 247 var errFailingReaderErr = errors.New("i am meant to fail at reading") 248 249 type failingReader struct { 250 } 251 252 func (fp *failingReader) Read(_ []byte) (n int, err error) { 253 return 0, errFailingReaderErr 254 } 255 256 func TestWrite(t *testing.T) { 257 t.Run("Success", func(t *testing.T) { 258 var buf bytes.Buffer 259 if err := storage.Write(&storage.JSONParser{}, map[string]interface{}{"name": "Tom"}, nil, &buf); err != nil { 260 t.Errorf("unexpected error: %s", err) 261 return 262 } 263 264 if exp, got := `{ 265 "name": "Tom" 266 } 267 `, buf.String(); exp != got { 268 t.Errorf("unexpected output:\n%s\ngot:\n%s", exp, got) 269 } 270 }) 271 272 t.Run("ParserErrHandled", func(t *testing.T) { 273 var buf bytes.Buffer 274 if err := storage.Write(&failingParser{}, map[string]interface{}{"name": "Tom"}, nil, &buf); !errors.Is(err, errFailingParserErr) { 275 t.Errorf("unexpected error: %v", err) 276 return 277 } 278 }) 279 280 t.Run("WriterErrHandled", func(t *testing.T) { 281 if err := storage.Write(&storage.JSONParser{}, map[string]interface{}{"name": "Tom"}, nil, &failingWriter{}); !errors.Is(err, errFailingWriterErr) { 282 t.Errorf("unexpected error: %v", err) 283 return 284 } 285 }) 286 }