From a824a9732154f9bee2ce530f753d5747de78aa3f Mon Sep 17 00:00:00 2001
From: Paul Duncan <pabs@pablotron.org>
Date: Tue, 1 Feb 2022 01:10:24 -0500
Subject: internal/feed: split out datatype, add tests

---
 internal/feed/datatype.go        | 36 ++++++++++++++++++++++
 internal/feed/datatype_string.go | 23 ++++++++++++++
 internal/feed/datatype_test.go   | 65 ++++++++++++++++++++++++++++++++++++++++
 internal/feed/feed.go            | 29 ++----------------
 4 files changed, 126 insertions(+), 27 deletions(-)
 create mode 100644 internal/feed/datatype.go
 create mode 100644 internal/feed/datatype_string.go
 create mode 100644 internal/feed/datatype_test.go

(limited to 'internal')

diff --git a/internal/feed/datatype.go b/internal/feed/datatype.go
new file mode 100644
index 0000000..6eaa145
--- /dev/null
+++ b/internal/feed/datatype.go
@@ -0,0 +1,36 @@
+package feed
+
+//go:generate stringer -linecomment -type=DataType
+
+import (
+  "encoding/json"
+  "fmt"
+)
+
+// Data type for NVD feeds and feed items.
+type DataType byte
+
+const (
+  CveType DataType = iota // CVE
+)
+
+// Unmarshal DataType from JSON.
+func (me *DataType) UnmarshalJSON(b []byte) error {
+  // decode string, check for error
+  var s string
+  if err := json.Unmarshal(b, &s); err != nil {
+    return err
+  }
+
+  // check value
+  switch s {
+  case "CVE":
+    *me = CveType
+  default:
+    // return error
+    return fmt.Errorf("unknown data type: %s", s)
+  }
+
+  // return success
+  return nil
+}
diff --git a/internal/feed/datatype_string.go b/internal/feed/datatype_string.go
new file mode 100644
index 0000000..f126add
--- /dev/null
+++ b/internal/feed/datatype_string.go
@@ -0,0 +1,23 @@
+// Code generated by "stringer -linecomment -type=DataType"; DO NOT EDIT.
+
+package feed
+
+import "strconv"
+
+func _() {
+	// An "invalid array index" compiler error signifies that the constant values have changed.
+	// Re-run the stringer command to generate them again.
+	var x [1]struct{}
+	_ = x[CveType-0]
+}
+
+const _DataType_name = "CVE"
+
+var _DataType_index = [...]uint8{0, 3}
+
+func (i DataType) String() string {
+	if i >= DataType(len(_DataType_index)-1) {
+		return "DataType(" + strconv.FormatInt(int64(i), 10) + ")"
+	}
+	return _DataType_name[_DataType_index[i]:_DataType_index[i+1]]
+}
diff --git a/internal/feed/datatype_test.go b/internal/feed/datatype_test.go
new file mode 100644
index 0000000..05f6a74
--- /dev/null
+++ b/internal/feed/datatype_test.go
@@ -0,0 +1,65 @@
+package feed
+
+import (
+  "encoding/json"
+  "testing"
+)
+
+func TestDataTypeUnmarshalInvalidData(t *testing.T) {
+  test := []byte(`{}`)
+  var val DataType
+
+  if err := json.Unmarshal(test, &val); err == nil {
+    t.Errorf("got \"%s\", exp error", val)
+  }
+}
+
+func TestDataTypeUnmarshalUnknown(t *testing.T) {
+  test := []byte(`"foo"`)
+  exp := "unknown data type: foo"
+  var val DataType
+
+  err := json.Unmarshal(test, &val)
+  if err == nil {
+    t.Errorf("got \"%s\", exp error", val)
+    return
+  }
+
+  if err.Error() != exp {
+    t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp)
+  }
+}
+
+func TestDataTypeUnmarshalValid(t *testing.T) {
+  test := []byte(`"CVE"`)
+  exp := CveType
+  var got DataType
+
+  if err := json.Unmarshal(test, &got); err != nil {
+    t.Error(err)
+    return
+  }
+
+  if got != exp {
+    t.Errorf("got \"%s\", exp \"%s\"", got, exp)
+  }
+}
+
+func TestDataTypeString(t *testing.T) {
+  tests := []struct {
+    val DataType
+    exp string
+  } {
+    { CveType, "CVE" },
+    { DataType(255), "DataType(255)" },
+  }
+
+  for _, test := range(tests) {
+    t.Run(test.val.String(), func(t *testing.T) {
+      got := test.val.String()
+      if got != test.exp {
+        t.Errorf("got \"%s\", exp \"%s\"", got, test.exp)
+      }
+    })
+  }
+}
diff --git a/internal/feed/feed.go b/internal/feed/feed.go
index 1c15a0a..b4d514b 100644
--- a/internal/feed/feed.go
+++ b/internal/feed/feed.go
@@ -9,8 +9,7 @@ import (
 )
 
 const (
-  CveType = iota  // CVE data type
-  MitreFormat     // MITRE data format
+  MitreFormat = iota    // MITRE data format
   DataVersion40   // Version 4.0
 
   OrNodeOp        // OR operator
@@ -42,31 +41,7 @@ const (
   Single          // Single authentication
 )
 
-// TODO: parse cpe, cvss vectors (v3.x, v2)
-
-// Data type for NVD feeds and feed items.
-type DataType int
-
-// Unmarshal DataType from JSON.
-func (me *DataType) UnmarshalJSON(b []byte) error {
-  // decode string, check for error
-  var s string
-  if err := json.Unmarshal(b, &s); err != nil {
-    return err
-  }
-
-  // check value
-  switch s {
-  case "CVE":
-    *me = CveType
-  default:
-    // return error
-    return fmt.Errorf("unknown data type: %s", s)
-  }
-
-  // return success
-  return nil
-}
+// TODO: parse cpe
 
 // Data format for NVD feeds and feed items.
 type DataFormat int
-- 
cgit v1.2.3