@@ -116,43 +116,89 @@ type TestType struct {
116116
117117func (s * MySuite ) TestDecoder (c * C ) {
118118 reader , err := Open ("test-data/test-data/MaxMind-DB-test-decoder.mmdb" )
119- if err != nil {
120- c .Logf ("unexpected error while opening database: %v" , err )
121- c .Fail ()
122- }
119+ c .Assert (err , IsNil )
120+
121+ verify := func (result TestType ) {
122+ c .Assert (result .Array , DeepEquals , []uint {uint (1 ), uint (2 ), uint (3 )})
123+ c .Assert (result .Boolean , Equals , true )
124+ c .Assert (result .Bytes , DeepEquals , []byte {0x00 , 0x00 , 0x00 , 0x2a })
125+ c .Assert (result .Double , Equals , 42.123456 )
126+ c .Assert (result .Float , Equals , float32 (1.1 ))
127+ c .Assert (result .Int32 , Equals , int32 (- 268435456 ))
128+
129+ c .Assert (result .Map , DeepEquals ,
130+ map [string ]interface {}{
131+ "mapX" : map [string ]interface {}{
132+ "arrayX" : []interface {}{uint64 (7 ), uint64 (8 ), uint64 (9 )},
133+ "utf8_stringX" : "hello" ,
134+ }})
135+
136+ c .Assert (result .Uint16 , Equals , uint16 (100 ))
137+ c .Assert (result .Uint32 , Equals , uint32 (268435456 ))
138+ c .Assert (result .Uint64 , Equals , uint64 (1152921504606846976 ))
139+ c .Assert (result .Utf8String , Equals , "unicode! ☯ - ♫" )
140+ bigInt := new (big.Int )
141+ bigInt .SetString ("1329227995784915872903807060280344576" , 10 )
142+ c .Assert (& result .Uint128 , DeepEquals , bigInt )
143+ }
144+
145+ {
146+ // Directly lookup and decode.
147+ var result TestType
148+ c .Assert (reader .Lookup (net .ParseIP ("::1.1.1.0" ), & result ), IsNil )
149+ verify (result )
150+ }
151+ {
152+ // Lookup record offset, then Decode.
153+ var result TestType
154+ offset , err := reader .LookupOffset (net .ParseIP ("::1.1.1.0" ))
155+ c .Assert (err , IsNil )
156+ c .Assert (offset , Not (Equals ), NotFound )
157+
158+ c .Assert (reader .Decode (offset , & result ), IsNil )
159+ verify (result )
160+ }
161+
162+ c .Assert (reader .Close (), IsNil )
163+ }
123164
124- var result TestType
125- err = reader .Lookup (net .ParseIP ("::1.1.1.0" ), & result )
126- if err != nil {
127- c .Log (err )
128- c .Fail ()
129- }
165+ func (s * MySuite ) TestNestedOffsetDecode (c * C ) {
166+ db , err := Open ("test-data/test-data/GeoIP2-City-Test.mmdb" )
167+ c .Assert (err , IsNil )
130168
131- c .Assert (result .Array , DeepEquals , []uint {uint (1 ), uint (2 ), uint (3 )})
132- c .Assert (result .Boolean , Equals , true )
133- c .Assert (result .Bytes , DeepEquals , []byte {0x00 , 0x00 , 0x00 , 0x2a })
134- c .Assert (result .Double , Equals , 42.123456 )
135- c .Assert (result .Float , Equals , float32 (1.1 ))
136- c .Assert (result .Int32 , Equals , int32 (- 268435456 ))
169+ off , err := db .LookupOffset (net .ParseIP ("81.2.69.142" ))
170+ c .Assert (off , Not (Equals ), NotFound )
171+ c .Check (err , IsNil )
137172
138- c .Assert (result .Map , DeepEquals ,
139- map [string ]interface {}{
140- "mapX" : map [string ]interface {}{
141- "arrayX" : []interface {}{uint64 (7 ), uint64 (8 ), uint64 (9 )},
142- "utf8_stringX" : "hello" ,
143- }})
173+ var root struct {
174+ CountryOffset uintptr `maxminddb:"country"`
144175
145- c .Assert (result .Uint16 , Equals , uint16 (100 ))
146- c .Assert (result .Uint32 , Equals , uint32 (268435456 ))
147- c .Assert (result .Uint64 , Equals , uint64 (1152921504606846976 ))
148- c .Assert (result .Utf8String , Equals , "unicode! ☯ - ♫" )
149- bigInt := new (big.Int )
150- bigInt .SetString ("1329227995784915872903807060280344576" , 10 )
151- c .Assert (& result .Uint128 , DeepEquals , bigInt )
176+ Location struct {
177+ Latitude float64 `maxminddb:"latitude"`
178+ // Longitude is directly nested within the parent map.
179+ LongitudeOffset uintptr `maxminddb:"longitude"`
180+ // TimeZone is indirected via a pointer.
181+ TimeZoneOffset uintptr `maxminddb:"time_zone"`
182+ } `maxminddb:"location"`
183+ }
184+ c .Check (db .Decode (off , & root ), IsNil )
185+ c .Check (root .Location .Latitude , Equals , 51.5142 )
152186
153- if err = reader .Close (); err != nil {
154- c .Assert (err , nil , "no error on close" )
187+ var longitude float64
188+ c .Check (db .Decode (root .Location .LongitudeOffset , & longitude ), IsNil )
189+ c .Check (longitude , Equals , - 0.0931 )
190+
191+ var timeZone string
192+ c .Check (db .Decode (root .Location .TimeZoneOffset , & timeZone ), IsNil )
193+ c .Check (timeZone , Equals , "Europe/London" )
194+
195+ var country struct {
196+ IsoCode string `maxminddb:"iso_code"`
155197 }
198+ c .Check (db .Decode (root .CountryOffset , & country ), IsNil )
199+ c .Check (country .IsoCode , Equals , "GB" )
200+
201+ c .Check (db .Close (), IsNil )
156202}
157203
158204func (s * MySuite ) TestDecodingUint16IntoInt (c * C ) {
0 commit comments