First version with 100% test coverage

This commit is contained in:
Jan-Lukas Else 2021-05-25 21:06:15 +02:00
parent 1e9929301a
commit a9c1d50f42
6 changed files with 193 additions and 2 deletions

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) <year> <copyright holders>
Copyright (c) 2021 Jan-Lukas Else
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View File

@ -1,3 +1,7 @@
# go-geouri
Parse geo URI (RFC 5870) with Go
Parse geo URI (RFC 5870) with Go
https://datatracker.ietf.org/doc/html/rfc5870
Just the basics so far, doesn't check all the rules yet.

62
geouri.go Normal file
View File

@ -0,0 +1,62 @@
package gogeouri
import (
"errors"
"strconv"
"strings"
)
type Geo struct {
Latitude, Longitude, Altitude float64
Parameters map[string][]string
}
const scheme = "geo"
func Parse(uri string) (*Geo, error) {
g := &Geo{
Parameters: map[string][]string{},
}
if !strings.HasPrefix(uri, scheme+":") {
return nil, errors.New("no or wrong scheme")
}
uri = strings.TrimPrefix(uri, scheme+":")
uriParts := strings.Split(uri, ";")
if len(strings.TrimSpace(uriParts[0])) < 1 {
return nil, errors.New("empty path")
}
coords := strings.Split(uriParts[0], ",")
if l := len(coords); l < 2 || l > 3 {
return nil, errors.New("wrong number of coordinates")
}
if f, e := strconv.ParseFloat(coords[0], 64); e == nil {
g.Latitude = f
} else {
return nil, errors.New("can't parse latitude")
}
if f, e := strconv.ParseFloat(coords[1], 64); e == nil {
g.Longitude = f
} else {
return nil, errors.New("can't parse longitude")
}
if len(coords) == 3 {
if f, e := strconv.ParseFloat(coords[2], 64); e == nil {
g.Altitude = f
} else {
return nil, errors.New("can't parse altitude")
}
}
for _, p := range uriParts[1:] {
pParts := strings.Split(p, "=")
if l := len(pParts); l == 1 {
if _, ok := g.Parameters[pParts[0]]; !ok {
g.Parameters[pParts[0]] = []string{}
}
} else if l == 2 {
g.Parameters[pParts[0]] = append(g.Parameters[pParts[0]], pParts[1])
} else {
return nil, errors.New("wrong parameter")
}
}
return g, nil
}

122
geouri_test.go Normal file
View File

@ -0,0 +1,122 @@
package gogeouri
import (
"reflect"
"testing"
)
func TestParse(t *testing.T) {
type args struct {
uri string
}
type testCase struct {
name string
args args
want *Geo
wantErr bool
}
tests := []testCase{
// Positive
{
name: "Simple",
args: args{"geo:37.786971,-122.399677"},
want: &Geo{
Latitude: 37.786971,
Longitude: -122.399677,
Parameters: map[string][]string{},
},
wantErr: false,
},
{
name: "Altitude",
args: args{"geo:37.786971,-122.399677,-123.456"},
want: &Geo{
Latitude: 37.786971,
Longitude: -122.399677,
Altitude: -123.456,
Parameters: map[string][]string{},
},
wantErr: false,
},
{
name: "Indigenous",
args: args{"geo:51.5258325,-0.1359825,0.0;name=london;url=https://hwclondon.co.uk"},
want: &Geo{
Latitude: 51.5258325,
Longitude: -0.1359825,
Altitude: 0.0,
Parameters: map[string][]string{
"name": {"london"},
"url": {"https://hwclondon.co.uk"},
},
},
wantErr: false,
},
{
name: "Parameter without value",
args: args{"geo:51.5258325,-0.1359825,0.0;name"},
want: &Geo{
Latitude: 51.5258325,
Longitude: -0.1359825,
Altitude: 0.0,
Parameters: map[string][]string{
"name": {},
},
},
wantErr: false,
},
// Negative
{
name: "Missing scheme",
args: args{"37.786971,-122.399677"},
wantErr: true,
},
{
name: "Missing path",
args: args{"geo:"},
wantErr: true,
},
{
name: "1 coordinate",
args: args{"geo:37.786971"},
wantErr: true,
},
{
name: "4 coordinates",
args: args{"geo:123,123,123,123"},
wantErr: true,
},
{
name: "Malformed latitude",
args: args{"geo:12x,123"},
wantErr: true,
},
{
name: "Malformed longitude",
args: args{"geo:123,12x"},
wantErr: true,
},
{
name: "Malformed altitude",
args: args{"geo:123,123,12x"},
wantErr: true,
},
{
name: "Malformed parameter",
args: args{"geo:123,123;a=a=a"},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := Parse(tt.args.uri)
if (err != nil) != tt.wantErr {
t.Errorf("Parse() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("Parse() = %v, want %v", got, tt.want)
}
})
}
}

3
go.mod Normal file
View File

@ -0,0 +1,3 @@
module git.jlel.se/jlelse/go-geouri
go 1.16

0
go.sum Normal file
View File