diff --git a/.gitignore b/.gitignore index daf913b..13e3457 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ _testmain.go *.exe *.test *.prof + +coverage.out diff --git a/.travis.yml b/.travis.yml index 96b40c3..d49d423 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ go: before_install: - go get github.com/mattn/goveralls script: - - go test -v -covermode=count -coverprofile=coverage.out + - go test ./cap -v -covermode=count -coverprofile=coverage.out - $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci -repotoken $COVERALLS_TOKEN env: global: diff --git a/atom.go b/cap/atom.go similarity index 100% rename from atom.go rename to cap/atom.go diff --git a/atom_test.go b/cap/atom_test.go similarity index 99% rename from atom_test.go rename to cap/atom_test.go index 8c9bb6f..6fde971 100644 --- a/atom_test.go +++ b/cap/atom_test.go @@ -10,7 +10,7 @@ import ( ) func getNwsAtomFeedExample() (*NWSAtomFeed, error) { - xmlData, err := ioutil.ReadFile("examples/nws_atom.xml") + xmlData, err := ioutil.ReadFile("../examples/nws_atom.xml") if err != nil { return nil, err diff --git a/cap.go b/cap/cap.go similarity index 85% rename from cap.go rename to cap/cap.go index a17e3e9..409bbd7 100644 --- a/cap.go +++ b/cap/cap.go @@ -1,6 +1,9 @@ package cap -import "encoding/xml" +import ( + "encoding/xml" + "time" +) // Alert provides basic information about the current message: its purpose, its source and its status type Alert struct { @@ -85,6 +88,32 @@ type NamedValue struct { Value string `xml:"value"` } +// ParseAlert parses XML bytes into a CAP 1.2 Alert +func ParseAlert(xmlData []byte) (*Alert, error) { + var alert Alert + + err := xml.Unmarshal(xmlData, &alert) + + if err != nil { + return nil, err + } + + return &alert, nil +} + +// ParseAlert parses XML bytes into a CAP 1.1 Alert +func ParseAlert11(xmlData []byte) (*Alert11, error) { + var alert Alert11 + + err := xml.Unmarshal(xmlData, &alert) + + if err != nil { + return nil, err + } + + return &alert, nil +} + // search checks a slice of NamedValues for the first value with a specific name func search(nva *[]NamedValue, name string) string { for _, element := range *nva { @@ -135,3 +164,11 @@ func (a *Area) AddGeocode(name string, value string) { geocode := NamedValue{ValueName: name, Value: value} a.Geocodes = append(a.Geocodes, geocode) } + +// CAPDate is the form specified by the DateTime Data Type in 3.3.2 of the CAP specificaftion +const CAPDate string = "2006-01-02T15:04:05-07:00" + +// ParseCAPDate parses a string into a CAPDate formatted value +func ParseCAPDate(dtValue string) (time.Time, error) { + return time.Parse(CAPDate, dtValue) +} diff --git a/cap_test.go b/cap/cap_test.go similarity index 77% rename from cap_test.go rename to cap/cap_test.go index df6ba6e..4a4a953 100644 --- a/cap_test.go +++ b/cap/cap_test.go @@ -1,27 +1,20 @@ package cap import ( - "encoding/xml" + "fmt" "io/ioutil" + "os" "testing" ) func getCAPAlertExample() (*Alert11, error) { - xmlData, err := ioutil.ReadFile("examples/nws_alert.xml") + xmlData, err := ioutil.ReadFile("../examples/nws_alert.xml") if err != nil { return nil, err } - var alert Alert11 - - err = xml.Unmarshal(xmlData, &alert) - - if err != nil { - return nil, err - } - - return &alert, nil + return ParseAlert11(xmlData) } func TestUnmarshalAlertHasProperValues(t *testing.T) { @@ -294,3 +287,54 @@ func TestAreaGecodeReturnsEmptyStringIfNotFound(t *testing.T) { geocodeValue := area.Geocode("not-a-real-key") assertEqual(t, geocodeValue, "", "Geocode did not return an empty string") } + +func TestParseCAPDateReturnsCorrectValue(t *testing.T) { + alert, err := getCAPAlertExample() + + if err != nil { + t.Fatal(err) + } + + info := alert.Infos[0] + dt, _ := ParseCAPDate(info.EffectiveDate) + _, zoneOffset := dt.Zone() + zoneOffsetHours := zoneOffset / 3600 + + // 2015-08-15T20:45:00-05:00 + assertEqual(t, 2015, int(dt.Year()), "Year does not equal expected value") + assertEqual(t, 8, int(dt.Month()), "Month does not equal expected value") + assertEqual(t, 15, int(dt.Day()), "Day does not equal expected value") + assertEqual(t, 20, int(dt.Hour()), "Hour does not equal expected value") + assertEqual(t, 45, int(dt.Minute()), "Minute does not equal expected value") + assertEqual(t, 0, int(dt.Second()), "Second does not equal expected value") + assertEqual(t, -5, zoneOffsetHours, "TZ offset does not equal expected value") +} + +func TestABC(t *testing.T) { + var xmlData = []byte(` + + NOAA-NWS-ALERTS-AR1253BA3B00A4.FloodWarning.1253BA3D4A94AR.LZKFLSLZK.342064b5a5aafb8265dfc3707d6a3b09 + w-nws.webmaster@noaa.gov + 2015-08-15T20:45:00-05:00 + Actual + Alert + Public + + Met + Flood Warning + Expected + Moderate + Likely + + `) + + alert, err := ParseAlert(xmlData) + + if err != nil { + fmt.Errorf(err.Error()) + os.Exit(1) + } + + fmt.Println(alert.MessageID) + fmt.Println(alert.Infos[0].EventType) +} diff --git a/utils_test.go b/cap/utils_test.go similarity index 100% rename from utils_test.go rename to cap/utils_test.go