...
1
2
3
4
5 package json
6
7 import (
8 "bytes"
9 "compress/gzip"
10 "io/ioutil"
11 "os"
12 "path/filepath"
13 "sort"
14 "strings"
15 "sync"
16 "testing"
17 "time"
18 )
19
20 type jsonTestdataEntry struct {
21 name string
22 data []byte
23 new func() any
24 }
25
26 var (
27 jsonTestdataOnce sync.Once
28 jsonTestdataLazy []jsonTestdataEntry
29 )
30
31 func jsonTestdata() []jsonTestdataEntry {
32 jsonTestdataOnce.Do(func() {
33 fis, err := ioutil.ReadDir("testdata")
34 if err != nil {
35 panic(err)
36 }
37 sort.Slice(fis, func(i, j int) bool { return fis[i].Name() < fis[j].Name() })
38 for _, fi := range fis {
39 if !strings.HasSuffix(fi.Name(), ".json.gz") {
40 break
41 }
42
43
44 if testing.Short() {
45 fi, err := os.Stat(filepath.Join("testdata", fi.Name()))
46 if err == nil && fi.Size() > 1e3 {
47 continue
48 }
49 }
50
51
52 words := strings.Split(strings.TrimSuffix(fi.Name(), ".json.gz"), "_")
53 for i := range words {
54 words[i] = strings.Title(words[i])
55 }
56 name := strings.Join(words, "")
57
58
59 b, err := ioutil.ReadFile(filepath.Join("testdata", fi.Name()))
60 if err != nil {
61 panic(err)
62 }
63 zr, err := gzip.NewReader(bytes.NewReader(b))
64 if err != nil {
65 panic(err)
66 }
67 data, err := ioutil.ReadAll(zr)
68 if err != nil {
69 panic(err)
70 }
71
72
73 var newFn func() any
74 switch name {
75 case "CanadaGeometry":
76 newFn = func() any { return new(canadaRoot) }
77 case "CitmCatalog":
78 newFn = func() any { return new(citmRoot) }
79 case "GolangSource":
80 newFn = func() any { return new(golangRoot) }
81 case "StringEscaped":
82 newFn = func() any { return new(stringRoot) }
83 case "StringUnicode":
84 newFn = func() any { return new(stringRoot) }
85 case "SyntheaFhir":
86 newFn = func() any { return new(syntheaRoot) }
87 case "TwitterStatus":
88 newFn = func() any { return new(twitterRoot) }
89 }
90
91 jsonTestdataLazy = append(jsonTestdataLazy, jsonTestdataEntry{name, data, newFn})
92 }
93 })
94 return jsonTestdataLazy
95 }
96
97 type (
98 canadaRoot struct {
99 Type string `json:"type"`
100 Features []struct {
101 Type string `json:"type"`
102 Properties struct {
103 Name string `json:"name"`
104 } `json:"properties"`
105 Geometry struct {
106 Type string `json:"type"`
107 Coordinates [][][2]float64 `json:"coordinates"`
108 } `json:"geometry"`
109 } `json:"features"`
110 }
111 )
112
113 type (
114 citmRoot struct {
115 AreaNames map[int64]string `json:"areaNames"`
116 AudienceSubCategoryNames map[int64]string `json:"audienceSubCategoryNames"`
117 BlockNames map[int64]string `json:"blockNames"`
118 Events map[int64]struct {
119 Description string `json:"description"`
120 ID int `json:"id"`
121 Logo string `json:"logo"`
122 Name string `json:"name"`
123 SubTopicIds []int `json:"subTopicIds"`
124 SubjectCode any `json:"subjectCode"`
125 Subtitle any `json:"subtitle"`
126 TopicIds []int `json:"topicIds"`
127 } `json:"events"`
128 Performances []struct {
129 EventID int `json:"eventId"`
130 ID int `json:"id"`
131 Logo any `json:"logo"`
132 Name any `json:"name"`
133 Prices []struct {
134 Amount int `json:"amount"`
135 AudienceSubCategoryID int64 `json:"audienceSubCategoryId"`
136 SeatCategoryID int64 `json:"seatCategoryId"`
137 } `json:"prices"`
138 SeatCategories []struct {
139 Areas []struct {
140 AreaID int `json:"areaId"`
141 BlockIds []any `json:"blockIds"`
142 } `json:"areas"`
143 SeatCategoryID int `json:"seatCategoryId"`
144 } `json:"seatCategories"`
145 SeatMapImage any `json:"seatMapImage"`
146 Start int64 `json:"start"`
147 VenueCode string `json:"venueCode"`
148 } `json:"performances"`
149 SeatCategoryNames map[uint64]string `json:"seatCategoryNames"`
150 SubTopicNames map[uint64]string `json:"subTopicNames"`
151 SubjectNames map[uint64]string `json:"subjectNames"`
152 TopicNames map[uint64]string `json:"topicNames"`
153 TopicSubTopics map[uint64][]uint64 `json:"topicSubTopics"`
154 VenueNames map[string]string `json:"venueNames"`
155 }
156 )
157
158 type (
159 golangRoot struct {
160 Tree *golangNode `json:"tree"`
161 Username string `json:"username"`
162 }
163 golangNode struct {
164 Name string `json:"name"`
165 Kids []golangNode `json:"kids"`
166 CLWeight float64 `json:"cl_weight"`
167 Touches int `json:"touches"`
168 MinT uint64 `json:"min_t"`
169 MaxT uint64 `json:"max_t"`
170 MeanT uint64 `json:"mean_t"`
171 }
172 )
173
174 type (
175 stringRoot struct {
176 Arabic string `json:"Arabic"`
177 ArabicPresentationFormsA string `json:"Arabic Presentation Forms-A"`
178 ArabicPresentationFormsB string `json:"Arabic Presentation Forms-B"`
179 Armenian string `json:"Armenian"`
180 Arrows string `json:"Arrows"`
181 Bengali string `json:"Bengali"`
182 Bopomofo string `json:"Bopomofo"`
183 BoxDrawing string `json:"Box Drawing"`
184 CJKCompatibility string `json:"CJK Compatibility"`
185 CJKCompatibilityForms string `json:"CJK Compatibility Forms"`
186 CJKCompatibilityIdeographs string `json:"CJK Compatibility Ideographs"`
187 CJKSymbolsAndPunctuation string `json:"CJK Symbols and Punctuation"`
188 CJKUnifiedIdeographs string `json:"CJK Unified Ideographs"`
189 CJKUnifiedIdeographsExtensionA string `json:"CJK Unified Ideographs Extension A"`
190 CJKUnifiedIdeographsExtensionB string `json:"CJK Unified Ideographs Extension B"`
191 Cherokee string `json:"Cherokee"`
192 CurrencySymbols string `json:"Currency Symbols"`
193 Cyrillic string `json:"Cyrillic"`
194 CyrillicSupplementary string `json:"Cyrillic Supplementary"`
195 Devanagari string `json:"Devanagari"`
196 EnclosedAlphanumerics string `json:"Enclosed Alphanumerics"`
197 EnclosedCJKLettersAndMonths string `json:"Enclosed CJK Letters and Months"`
198 Ethiopic string `json:"Ethiopic"`
199 GeometricShapes string `json:"Geometric Shapes"`
200 Georgian string `json:"Georgian"`
201 GreekAndCoptic string `json:"Greek and Coptic"`
202 Gujarati string `json:"Gujarati"`
203 Gurmukhi string `json:"Gurmukhi"`
204 HangulCompatibilityJamo string `json:"Hangul Compatibility Jamo"`
205 HangulJamo string `json:"Hangul Jamo"`
206 HangulSyllables string `json:"Hangul Syllables"`
207 Hebrew string `json:"Hebrew"`
208 Hiragana string `json:"Hiragana"`
209 IPAExtentions string `json:"IPA Extentions"`
210 KangxiRadicals string `json:"Kangxi Radicals"`
211 Katakana string `json:"Katakana"`
212 Khmer string `json:"Khmer"`
213 KhmerSymbols string `json:"Khmer Symbols"`
214 Latin string `json:"Latin"`
215 LatinExtendedAdditional string `json:"Latin Extended Additional"`
216 Latin1Supplement string `json:"Latin-1 Supplement"`
217 LatinExtendedA string `json:"Latin-Extended A"`
218 LatinExtendedB string `json:"Latin-Extended B"`
219 LetterlikeSymbols string `json:"Letterlike Symbols"`
220 Malayalam string `json:"Malayalam"`
221 MathematicalAlphanumericSymbols string `json:"Mathematical Alphanumeric Symbols"`
222 MathematicalOperators string `json:"Mathematical Operators"`
223 MiscellaneousSymbols string `json:"Miscellaneous Symbols"`
224 Mongolian string `json:"Mongolian"`
225 NumberForms string `json:"Number Forms"`
226 Oriya string `json:"Oriya"`
227 PhoneticExtensions string `json:"Phonetic Extensions"`
228 SupplementalArrowsB string `json:"Supplemental Arrows-B"`
229 Syriac string `json:"Syriac"`
230 Tamil string `json:"Tamil"`
231 Thaana string `json:"Thaana"`
232 Thai string `json:"Thai"`
233 UnifiedCanadianAboriginalSyllabics string `json:"Unified Canadian Aboriginal Syllabics"`
234 YiRadicals string `json:"Yi Radicals"`
235 YiSyllables string `json:"Yi Syllables"`
236 }
237 )
238
239 type (
240 syntheaRoot struct {
241 Entry []struct {
242 FullURL string `json:"fullUrl"`
243 Request *struct {
244 Method string `json:"method"`
245 URL string `json:"url"`
246 } `json:"request"`
247 Resource *struct {
248 AbatementDateTime time.Time `json:"abatementDateTime"`
249 AchievementStatus syntheaCode `json:"achievementStatus"`
250 Active bool `json:"active"`
251 Activity []struct {
252 Detail *struct {
253 Code syntheaCode `json:"code"`
254 Location syntheaReference `json:"location"`
255 Status string `json:"status"`
256 } `json:"detail"`
257 } `json:"activity"`
258 Address []syntheaAddress `json:"address"`
259 Addresses []syntheaReference `json:"addresses"`
260 AuthoredOn time.Time `json:"authoredOn"`
261 BillablePeriod syntheaRange `json:"billablePeriod"`
262 BirthDate string `json:"birthDate"`
263 CareTeam []struct {
264 Provider syntheaReference `json:"provider"`
265 Reference string `json:"reference"`
266 Role syntheaCode `json:"role"`
267 Sequence int64 `json:"sequence"`
268 } `json:"careTeam"`
269 Category []syntheaCode `json:"category"`
270 Claim syntheaReference `json:"claim"`
271 Class syntheaCoding `json:"class"`
272 ClinicalStatus syntheaCode `json:"clinicalStatus"`
273 Code syntheaCode `json:"code"`
274 Communication []struct {
275 Language syntheaCode `json:"language"`
276 } `json:"communication"`
277 Component []struct {
278 Code syntheaCode `json:"code"`
279 ValueQuantity syntheaCoding `json:"valueQuantity"`
280 } `json:"component"`
281 Contained []struct {
282 Beneficiary syntheaReference `json:"beneficiary"`
283 ID string `json:"id"`
284 Intent string `json:"intent"`
285 Payor []syntheaReference `json:"payor"`
286 Performer []syntheaReference `json:"performer"`
287 Requester syntheaReference `json:"requester"`
288 ResourceType string `json:"resourceType"`
289 Status string `json:"status"`
290 Subject syntheaReference `json:"subject"`
291 Type syntheaCode `json:"type"`
292 } `json:"contained"`
293 Created time.Time `json:"created"`
294 DeceasedDateTime time.Time `json:"deceasedDateTime"`
295 Description syntheaCode `json:"description"`
296 Diagnosis []struct {
297 DiagnosisReference syntheaReference `json:"diagnosisReference"`
298 Sequence int64 `json:"sequence"`
299 Type []syntheaCode `json:"type"`
300 } `json:"diagnosis"`
301 DosageInstruction []struct {
302 AsNeededBoolean bool `json:"asNeededBoolean"`
303 DoseAndRate []struct {
304 DoseQuantity *struct {
305 Value float64 `json:"value"`
306 } `json:"doseQuantity"`
307 Type syntheaCode `json:"type"`
308 } `json:"doseAndRate"`
309 Sequence int64 `json:"sequence"`
310 Timing *struct {
311 Repeat *struct {
312 Frequency int64 `json:"frequency"`
313 Period float64 `json:"period"`
314 PeriodUnit string `json:"periodUnit"`
315 } `json:"repeat"`
316 } `json:"timing"`
317 } `json:"dosageInstruction"`
318 EffectiveDateTime time.Time `json:"effectiveDateTime"`
319 Encounter syntheaReference `json:"encounter"`
320 Extension []syntheaExtension `json:"extension"`
321 Gender string `json:"gender"`
322 Goal []syntheaReference `json:"goal"`
323 ID string `json:"id"`
324 Identifier []struct {
325 System string `json:"system"`
326 Type syntheaCode `json:"type"`
327 Use string `json:"use"`
328 Value string `json:"value"`
329 } `json:"identifier"`
330 Insurance []struct {
331 Coverage syntheaReference `json:"coverage"`
332 Focal bool `json:"focal"`
333 Sequence int64 `json:"sequence"`
334 } `json:"insurance"`
335 Insurer syntheaReference `json:"insurer"`
336 Intent string `json:"intent"`
337 Issued time.Time `json:"issued"`
338 Item []struct {
339 Adjudication []struct {
340 Amount syntheaCurrency `json:"amount"`
341 Category syntheaCode `json:"category"`
342 } `json:"adjudication"`
343 Category syntheaCode `json:"category"`
344 DiagnosisSequence []int64 `json:"diagnosisSequence"`
345 Encounter []syntheaReference `json:"encounter"`
346 InformationSequence []int64 `json:"informationSequence"`
347 LocationCodeableConcept syntheaCode `json:"locationCodeableConcept"`
348 Net syntheaCurrency `json:"net"`
349 ProcedureSequence []int64 `json:"procedureSequence"`
350 ProductOrService syntheaCode `json:"productOrService"`
351 Sequence int64 `json:"sequence"`
352 ServicedPeriod syntheaRange `json:"servicedPeriod"`
353 } `json:"item"`
354 LifecycleStatus string `json:"lifecycleStatus"`
355 ManagingOrganization []syntheaReference `json:"managingOrganization"`
356 MaritalStatus syntheaCode `json:"maritalStatus"`
357 MedicationCodeableConcept syntheaCode `json:"medicationCodeableConcept"`
358 MultipleBirthBoolean bool `json:"multipleBirthBoolean"`
359 Name RawValue `json:"name"`
360 NumberOfInstances int64 `json:"numberOfInstances"`
361 NumberOfSeries int64 `json:"numberOfSeries"`
362 OccurrenceDateTime time.Time `json:"occurrenceDateTime"`
363 OnsetDateTime time.Time `json:"onsetDateTime"`
364 Outcome string `json:"outcome"`
365 Participant []struct {
366 Individual syntheaReference `json:"individual"`
367 Member syntheaReference `json:"member"`
368 Role []syntheaCode `json:"role"`
369 } `json:"participant"`
370 Patient syntheaReference `json:"patient"`
371 Payment *struct {
372 Amount syntheaCurrency `json:"amount"`
373 } `json:"payment"`
374 PerformedPeriod syntheaRange `json:"performedPeriod"`
375 Period syntheaRange `json:"period"`
376 Prescription syntheaReference `json:"prescription"`
377 PrimarySource bool `json:"primarySource"`
378 Priority syntheaCode `json:"priority"`
379 Procedure []struct {
380 ProcedureReference syntheaReference `json:"procedureReference"`
381 Sequence int64 `json:"sequence"`
382 } `json:"procedure"`
383 Provider syntheaReference `json:"provider"`
384 ReasonCode []syntheaCode `json:"reasonCode"`
385 ReasonReference []syntheaReference `json:"reasonReference"`
386 RecordedDate time.Time `json:"recordedDate"`
387 Referral syntheaReference `json:"referral"`
388 Requester syntheaReference `json:"requester"`
389 ResourceType string `json:"resourceType"`
390 Result []syntheaReference `json:"result"`
391 Series []struct {
392 BodySite syntheaCoding `json:"bodySite"`
393 Instance []struct {
394 Number int64 `json:"number"`
395 SopClass syntheaCoding `json:"sopClass"`
396 Title string `json:"title"`
397 UID string `json:"uid"`
398 } `json:"instance"`
399 Modality syntheaCoding `json:"modality"`
400 Number int64 `json:"number"`
401 NumberOfInstances int64 `json:"numberOfInstances"`
402 Started string `json:"started"`
403 UID string `json:"uid"`
404 } `json:"series"`
405 ServiceProvider syntheaReference `json:"serviceProvider"`
406 Started time.Time `json:"started"`
407 Status string `json:"status"`
408 Subject syntheaReference `json:"subject"`
409 SupportingInfo []struct {
410 Category syntheaCode `json:"category"`
411 Sequence int64 `json:"sequence"`
412 ValueReference syntheaReference `json:"valueReference"`
413 } `json:"supportingInfo"`
414 Telecom []map[string]string `json:"telecom"`
415 Text map[string]string `json:"text"`
416 Total RawValue `json:"total"`
417 Type RawValue `json:"type"`
418 Use string `json:"use"`
419 VaccineCode syntheaCode `json:"vaccineCode"`
420 ValueCodeableConcept syntheaCode `json:"valueCodeableConcept"`
421 ValueQuantity syntheaCoding `json:"valueQuantity"`
422 VerificationStatus syntheaCode `json:"verificationStatus"`
423 } `json:"resource"`
424 } `json:"entry"`
425 ResourceType string `json:"resourceType"`
426 Type string `json:"type"`
427 }
428 syntheaCode struct {
429 Coding []syntheaCoding `json:"coding"`
430 Text string `json:"text"`
431 }
432 syntheaCoding struct {
433 Code string `json:"code"`
434 Display string `json:"display"`
435 System string `json:"system"`
436 Unit string `json:"unit"`
437 Value float64 `json:"value"`
438 }
439 syntheaReference struct {
440 Display string `json:"display"`
441 Reference string `json:"reference"`
442 }
443 syntheaAddress struct {
444 City string `json:"city"`
445 Country string `json:"country"`
446 Extension []syntheaExtension `json:"extension"`
447 Line []string `json:"line"`
448 PostalCode string `json:"postalCode"`
449 State string `json:"state"`
450 }
451 syntheaExtension struct {
452 URL string `json:"url"`
453 ValueAddress syntheaAddress `json:"valueAddress"`
454 ValueCode string `json:"valueCode"`
455 ValueDecimal float64 `json:"valueDecimal"`
456 ValueString string `json:"valueString"`
457 Extension []syntheaExtension `json:"extension"`
458 }
459 syntheaRange struct {
460 End time.Time `json:"end"`
461 Start time.Time `json:"start"`
462 }
463 syntheaCurrency struct {
464 Currency string `json:"currency"`
465 Value float64 `json:"value"`
466 }
467 )
468
469 type (
470 twitterRoot struct {
471 Statuses []twitterStatus `json:"statuses"`
472 SearchMetadata struct {
473 CompletedIn float64 `json:"completed_in"`
474 MaxID int64 `json:"max_id"`
475 MaxIDStr int64 `json:"max_id_str,string"`
476 NextResults string `json:"next_results"`
477 Query string `json:"query"`
478 RefreshURL string `json:"refresh_url"`
479 Count int `json:"count"`
480 SinceID int `json:"since_id"`
481 SinceIDStr int `json:"since_id_str,string"`
482 } `json:"search_metadata"`
483 }
484 twitterStatus struct {
485 Metadata struct {
486 ResultType string `json:"result_type"`
487 IsoLanguageCode string `json:"iso_language_code"`
488 } `json:"metadata"`
489 CreatedAt string `json:"created_at"`
490 ID int64 `json:"id"`
491 IDStr int64 `json:"id_str,string"`
492 Text string `json:"text"`
493 Source string `json:"source"`
494 Truncated bool `json:"truncated"`
495 InReplyToStatusID int64 `json:"in_reply_to_status_id"`
496 InReplyToStatusIDStr int64 `json:"in_reply_to_status_id_str,string"`
497 InReplyToUserID int64 `json:"in_reply_to_user_id"`
498 InReplyToUserIDStr int64 `json:"in_reply_to_user_id_str,string"`
499 InReplyToScreenName string `json:"in_reply_to_screen_name"`
500 User twitterUser `json:"user,omitempty"`
501 Geo any `json:"geo"`
502 Coordinates any `json:"coordinates"`
503 Place any `json:"place"`
504 Contributors any `json:"contributors"`
505 RetweeetedStatus *twitterStatus `json:"retweeted_status"`
506 RetweetCount int `json:"retweet_count"`
507 FavoriteCount int `json:"favorite_count"`
508 Entities twitterEntities `json:"entities,omitempty"`
509 Favorited bool `json:"favorited"`
510 Retweeted bool `json:"retweeted"`
511 PossiblySensitive bool `json:"possibly_sensitive"`
512 Lang string `json:"lang"`
513 }
514 twitterUser struct {
515 ID int64 `json:"id"`
516 IDStr string `json:"id_str"`
517 Name string `json:"name"`
518 ScreenName string `json:"screen_name"`
519 Location string `json:"location"`
520 Description string `json:"description"`
521 URL any `json:"url"`
522 Entities twitterEntities `json:"entities"`
523 Protected bool `json:"protected"`
524 FollowersCount int `json:"followers_count"`
525 FriendsCount int `json:"friends_count"`
526 ListedCount int `json:"listed_count"`
527 CreatedAt string `json:"created_at"`
528 FavouritesCount int `json:"favourites_count"`
529 UtcOffset int `json:"utc_offset"`
530 TimeZone string `json:"time_zone"`
531 GeoEnabled bool `json:"geo_enabled"`
532 Verified bool `json:"verified"`
533 StatusesCount int `json:"statuses_count"`
534 Lang string `json:"lang"`
535 ContributorsEnabled bool `json:"contributors_enabled"`
536 IsTranslator bool `json:"is_translator"`
537 IsTranslationEnabled bool `json:"is_translation_enabled"`
538 ProfileBackgroundColor string `json:"profile_background_color"`
539 ProfileBackgroundImageURL string `json:"profile_background_image_url"`
540 ProfileBackgroundImageURLHTTPS string `json:"profile_background_image_url_https"`
541 ProfileBackgroundTile bool `json:"profile_background_tile"`
542 ProfileImageURL string `json:"profile_image_url"`
543 ProfileImageURLHTTPS string `json:"profile_image_url_https"`
544 ProfileBannerURL string `json:"profile_banner_url"`
545 ProfileLinkColor string `json:"profile_link_color"`
546 ProfileSidebarBorderColor string `json:"profile_sidebar_border_color"`
547 ProfileSidebarFillColor string `json:"profile_sidebar_fill_color"`
548 ProfileTextColor string `json:"profile_text_color"`
549 ProfileUseBackgroundImage bool `json:"profile_use_background_image"`
550 DefaultProfile bool `json:"default_profile"`
551 DefaultProfileImage bool `json:"default_profile_image"`
552 Following bool `json:"following"`
553 FollowRequestSent bool `json:"follow_request_sent"`
554 Notifications bool `json:"notifications"`
555 }
556 twitterEntities struct {
557 Hashtags []any `json:"hashtags"`
558 Symbols []any `json:"symbols"`
559 URL *twitterURL `json:"url"`
560 URLs []twitterURL `json:"urls"`
561 UserMentions []struct {
562 ScreenName string `json:"screen_name"`
563 Name string `json:"name"`
564 ID int64 `json:"id"`
565 IDStr int64 `json:"id_str,string"`
566 Indices []int `json:"indices"`
567 } `json:"user_mentions"`
568 Description struct {
569 URLs []twitterURL `json:"urls"`
570 } `json:"description"`
571 Media []struct {
572 ID int64 `json:"id"`
573 IDStr string `json:"id_str"`
574 Indices []int `json:"indices"`
575 MediaURL string `json:"media_url"`
576 MediaURLHTTPS string `json:"media_url_https"`
577 URL string `json:"url"`
578 DisplayURL string `json:"display_url"`
579 ExpandedURL string `json:"expanded_url"`
580 Type string `json:"type"`
581 Sizes map[string]struct {
582 W int `json:"w"`
583 H int `json:"h"`
584 Resize string `json:"resize"`
585 } `json:"sizes"`
586 SourceStatusID int64 `json:"source_status_id"`
587 SourceStatusIDStr int64 `json:"source_status_id_str,string"`
588 } `json:"media"`
589 }
590 twitterURL struct {
591 URL string `json:"url"`
592 URLs []twitterURL `json:"urls"`
593 ExpandedURL string `json:"expanded_url"`
594 DisplayURL string `json:"display_url"`
595 Indices []int `json:"indices"`
596 }
597 )
598
View as plain text