github.com/graemephi/kahugo@v0.62.3-0.20211121071557-d78c0423784d/tpl/transform/unmarshal_test.go (about) 1 // Copyright 2019 The Hugo Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package transform 15 16 import ( 17 "fmt" 18 "math/rand" 19 "strings" 20 "testing" 21 22 "github.com/gohugoio/hugo/config" 23 24 "github.com/gohugoio/hugo/common/hugio" 25 "github.com/gohugoio/hugo/resources/resource" 26 27 "github.com/gohugoio/hugo/media" 28 29 qt "github.com/frankban/quicktest" 30 ) 31 32 const ( 33 testJSON = ` 34 35 { 36 "ROOT_KEY": { 37 "title": "example glossary", 38 "GlossDiv": { 39 "title": "S", 40 "GlossList": { 41 "GlossEntry": { 42 "ID": "SGML", 43 "SortAs": "SGML", 44 "GlossTerm": "Standard Generalized Markup Language", 45 "Acronym": "SGML", 46 "Abbrev": "ISO 8879:1986", 47 "GlossDef": { 48 "para": "A meta-markup language, used to create markup languages such as DocBook.", 49 "GlossSeeAlso": ["GML", "XML"] 50 }, 51 "GlossSee": "markup" 52 } 53 } 54 } 55 } 56 } 57 58 ` 59 ) 60 61 var _ resource.ReadSeekCloserResource = (*testContentResource)(nil) 62 63 type testContentResource struct { 64 content string 65 mime media.Type 66 67 key string 68 } 69 70 func (t testContentResource) ReadSeekCloser() (hugio.ReadSeekCloser, error) { 71 return hugio.NewReadSeekerNoOpCloserFromString(t.content), nil 72 } 73 74 func (t testContentResource) MediaType() media.Type { 75 return t.mime 76 } 77 78 func (t testContentResource) Key() string { 79 return t.key 80 } 81 82 func TestUnmarshal(t *testing.T) { 83 v := config.New() 84 ns := New(newDeps(v)) 85 c := qt.New(t) 86 87 assertSlogan := func(m map[string]interface{}) { 88 c.Assert(m["slogan"], qt.Equals, "Hugo Rocks!") 89 } 90 91 for _, test := range []struct { 92 data interface{} 93 options interface{} 94 expect interface{} 95 }{ 96 {`{ "slogan": "Hugo Rocks!" }`, nil, func(m map[string]interface{}) { 97 assertSlogan(m) 98 }}, 99 {`slogan: "Hugo Rocks!"`, nil, func(m map[string]interface{}) { 100 assertSlogan(m) 101 }}, 102 {`slogan = "Hugo Rocks!"`, nil, func(m map[string]interface{}) { 103 assertSlogan(m) 104 }}, 105 {testContentResource{key: "r1", content: `slogan: "Hugo Rocks!"`, mime: media.YAMLType}, nil, func(m map[string]interface{}) { 106 assertSlogan(m) 107 }}, 108 {testContentResource{key: "r1", content: `{ "slogan": "Hugo Rocks!" }`, mime: media.JSONType}, nil, func(m map[string]interface{}) { 109 assertSlogan(m) 110 }}, 111 {testContentResource{key: "r1", content: `slogan = "Hugo Rocks!"`, mime: media.TOMLType}, nil, func(m map[string]interface{}) { 112 assertSlogan(m) 113 }}, 114 {testContentResource{key: "r1", content: `1997,Ford,E350,"ac, abs, moon",3000.00 115 1999,Chevy,"Venture ""Extended Edition""","",4900.00`, mime: media.CSVType}, nil, func(r [][]string) { 116 c.Assert(len(r), qt.Equals, 2) 117 first := r[0] 118 c.Assert(len(first), qt.Equals, 5) 119 c.Assert(first[1], qt.Equals, "Ford") 120 }}, 121 {testContentResource{key: "r1", content: `a;b;c`, mime: media.CSVType}, map[string]interface{}{"delimiter": ";"}, func(r [][]string) { 122 c.Assert([][]string{{"a", "b", "c"}}, qt.DeepEquals, r) 123 }}, 124 {"a,b,c", nil, func(r [][]string) { 125 c.Assert([][]string{{"a", "b", "c"}}, qt.DeepEquals, r) 126 }}, 127 {"a;b;c", map[string]interface{}{"delimiter": ";"}, func(r [][]string) { 128 c.Assert([][]string{{"a", "b", "c"}}, qt.DeepEquals, r) 129 }}, 130 {testContentResource{key: "r1", content: ` 131 % This is a comment 132 a;b;c`, mime: media.CSVType}, map[string]interface{}{"DElimiter": ";", "Comment": "%"}, func(r [][]string) { 133 c.Assert([][]string{{"a", "b", "c"}}, qt.DeepEquals, r) 134 }}, 135 // errors 136 {"thisisnotavaliddataformat", nil, false}, 137 {testContentResource{key: "r1", content: `invalid&toml"`, mime: media.TOMLType}, nil, false}, 138 {testContentResource{key: "r1", content: `unsupported: MIME"`, mime: media.CalendarType}, nil, false}, 139 {"thisisnotavaliddataformat", nil, false}, 140 {`{ notjson }`, nil, false}, 141 {tstNoStringer{}, nil, false}, 142 } { 143 144 ns.cache.Clear() 145 146 var args []interface{} 147 148 if test.options != nil { 149 args = []interface{}{test.options, test.data} 150 } else { 151 args = []interface{}{test.data} 152 } 153 154 result, err := ns.Unmarshal(args...) 155 156 if b, ok := test.expect.(bool); ok && !b { 157 c.Assert(err, qt.Not(qt.IsNil)) 158 } else if fn, ok := test.expect.(func(m map[string]interface{})); ok { 159 c.Assert(err, qt.IsNil) 160 m, ok := result.(map[string]interface{}) 161 c.Assert(ok, qt.Equals, true) 162 fn(m) 163 } else if fn, ok := test.expect.(func(r [][]string)); ok { 164 c.Assert(err, qt.IsNil) 165 r, ok := result.([][]string) 166 c.Assert(ok, qt.Equals, true) 167 fn(r) 168 } else { 169 c.Assert(err, qt.IsNil) 170 c.Assert(result, qt.Equals, test.expect) 171 } 172 173 } 174 } 175 176 func BenchmarkUnmarshalString(b *testing.B) { 177 v := config.New() 178 ns := New(newDeps(v)) 179 180 const numJsons = 100 181 182 var jsons [numJsons]string 183 for i := 0; i < numJsons; i++ { 184 jsons[i] = strings.Replace(testJSON, "ROOT_KEY", fmt.Sprintf("root%d", i), 1) 185 } 186 187 b.ResetTimer() 188 for i := 0; i < b.N; i++ { 189 result, err := ns.Unmarshal(jsons[rand.Intn(numJsons)]) 190 if err != nil { 191 b.Fatal(err) 192 } 193 if result == nil { 194 b.Fatal("no result") 195 } 196 } 197 } 198 199 func BenchmarkUnmarshalResource(b *testing.B) { 200 v := config.New() 201 ns := New(newDeps(v)) 202 203 const numJsons = 100 204 205 var jsons [numJsons]testContentResource 206 for i := 0; i < numJsons; i++ { 207 key := fmt.Sprintf("root%d", i) 208 jsons[i] = testContentResource{key: key, content: strings.Replace(testJSON, "ROOT_KEY", key, 1), mime: media.JSONType} 209 } 210 211 b.ResetTimer() 212 for i := 0; i < b.N; i++ { 213 result, err := ns.Unmarshal(jsons[rand.Intn(numJsons)]) 214 if err != nil { 215 b.Fatal(err) 216 } 217 if result == nil { 218 b.Fatal("no result") 219 } 220 } 221 }