Added tests and saving for Snippet section

Signed-off-by: Steve Winslow <swinslow@gmail.com>
diff --git a/v0/tvsaver/saver2v1/save_snippet.go b/v0/tvsaver/saver2v1/save_snippet.go
new file mode 100644
index 0000000..a9c9ff7
--- /dev/null
+++ b/v0/tvsaver/saver2v1/save_snippet.go
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package saver2v1
+
+import (
+	"fmt"
+	"io"
+
+	"github.com/swinslow/spdx-go/v0/spdx"
+)
+
+func renderSnippet2_1(sn *spdx.Snippet2_1, w io.Writer) error {
+	if sn.SnippetSPDXIdentifier != "" {
+		fmt.Fprintf(w, "SnippetSPDXIdentifier: %s\n", sn.SnippetSPDXIdentifier)
+	}
+	if sn.SnippetFromFileSPDXIdentifier != "" {
+		fmt.Fprintf(w, "SnippetFromFileSPDXID: %s\n", sn.SnippetFromFileSPDXIdentifier)
+	}
+	if sn.SnippetByteRangeStart != 0 && sn.SnippetByteRangeEnd != 0 {
+		fmt.Fprintf(w, "SnippetByteRange: %d:%d\n", sn.SnippetByteRangeStart, sn.SnippetByteRangeEnd)
+	}
+	if sn.SnippetLineRangeStart != 0 && sn.SnippetLineRangeEnd != 0 {
+		fmt.Fprintf(w, "SnippetLineRange: %d:%d\n", sn.SnippetLineRangeStart, sn.SnippetLineRangeEnd)
+	}
+	if sn.SnippetLicenseConcluded != "" {
+		fmt.Fprintf(w, "SnippetLicenseConcluded: %s\n", sn.SnippetLicenseConcluded)
+	}
+	for _, s := range sn.LicenseInfoInSnippet {
+		fmt.Fprintf(w, "LicenseInfoInSnippet: %s\n", s)
+	}
+	if sn.SnippetLicenseComments != "" {
+		fmt.Fprintf(w, "SnippetLicenseComments: %s\n", sn.SnippetLicenseComments)
+	}
+	if sn.SnippetCopyrightText != "" {
+		fmt.Fprintf(w, "SnippetCopyrightText: %s\n", sn.SnippetCopyrightText)
+	}
+	if sn.SnippetComment != "" {
+		fmt.Fprintf(w, "SnippetComment: %s\n", sn.SnippetComment)
+	}
+	if sn.SnippetName != "" {
+		fmt.Fprintf(w, "SnippetName: %s\n", sn.SnippetName)
+	}
+
+	fmt.Fprintf(w, "\n")
+
+	return nil
+}
diff --git a/v0/tvsaver/saver2v1/save_snippet_test.go b/v0/tvsaver/saver2v1/save_snippet_test.go
new file mode 100644
index 0000000..55a33ab
--- /dev/null
+++ b/v0/tvsaver/saver2v1/save_snippet_test.go
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package saver2v1
+
+import (
+	"bytes"
+	"testing"
+
+	"github.com/swinslow/spdx-go/v0/spdx"
+)
+
+// ===== Creation Info section Saver tests =====
+func TestSaver2_1SnippetSavesText(t *testing.T) {
+	sn := &spdx.Snippet2_1{
+		SnippetSPDXIdentifier:         "SPDXRef-Snippet17",
+		SnippetFromFileSPDXIdentifier: "SPDXRef-File292",
+		SnippetByteRangeStart:         17,
+		SnippetByteRangeEnd:           209,
+		SnippetLineRangeStart:         3,
+		SnippetLineRangeEnd:           8,
+		SnippetLicenseConcluded:       "GPL-2.0-or-later",
+		LicenseInfoInSnippet: []string{
+			"GPL-2.0-or-later",
+			"MIT",
+		},
+		SnippetLicenseComments: "this is a comment(s) about the snippet license",
+		SnippetCopyrightText:   "Copyright (c) John Doe 20x6",
+		SnippetComment:         "this is a snippet comment",
+		SnippetName:            "from John's program",
+	}
+
+	// what we want to get, as a buffer of bytes
+	want := bytes.NewBufferString(`SnippetSPDXIdentifier: SPDXRef-Snippet17
+SnippetFromFileSPDXID: SPDXRef-File292
+SnippetByteRange: 17:209
+SnippetLineRange: 3:8
+SnippetLicenseConcluded: GPL-2.0-or-later
+LicenseInfoInSnippet: GPL-2.0-or-later
+LicenseInfoInSnippet: MIT
+SnippetLicenseComments: this is a comment(s) about the snippet license
+SnippetCopyrightText: Copyright (c) John Doe 20x6
+SnippetComment: this is a snippet comment
+SnippetName: from John's program
+
+`)
+
+	// render as buffer of bytes
+	var got bytes.Buffer
+	err := renderSnippet2_1(sn, &got)
+	if err != nil {
+		t.Errorf("Expected nil error, got %v", err)
+	}
+
+	// check that they match
+	c := bytes.Compare(want.Bytes(), got.Bytes())
+	if c != 0 {
+		t.Errorf("Expected %v, got %v", want.String(), got.String())
+	}
+}
+
+func TestSaver2_1SnippetOmitsOptionalFieldsIfEmpty(t *testing.T) {
+	sn := &spdx.Snippet2_1{
+		SnippetSPDXIdentifier:         "SPDXRef-Snippet17",
+		SnippetFromFileSPDXIdentifier: "SPDXRef-File292",
+		SnippetByteRangeStart:         17,
+		SnippetByteRangeEnd:           209,
+		SnippetLicenseConcluded:       "GPL-2.0-or-later",
+		SnippetCopyrightText:          "Copyright (c) John Doe 20x6",
+	}
+
+	// what we want to get, as a buffer of bytes
+	want := bytes.NewBufferString(`SnippetSPDXIdentifier: SPDXRef-Snippet17
+SnippetFromFileSPDXID: SPDXRef-File292
+SnippetByteRange: 17:209
+SnippetLicenseConcluded: GPL-2.0-or-later
+SnippetCopyrightText: Copyright (c) John Doe 20x6
+
+`)
+
+	// render as buffer of bytes
+	var got bytes.Buffer
+	err := renderSnippet2_1(sn, &got)
+	if err != nil {
+		t.Errorf("Expected nil error, got %v", err)
+	}
+
+	// check that they match
+	c := bytes.Compare(want.Bytes(), got.Bytes())
+	if c != 0 {
+		t.Errorf("Expected %v, got %v", want.String(), got.String())
+	}
+}