Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(json): add option to write json in multiline mode #213

Merged
merged 2 commits into from
May 17, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
use WriteOption
Signed-off-by: DmitriyLewen <dmitriy.lewen@smartforce.io>
  • Loading branch information
DmitriyLewen committed May 17, 2023
commit 755da2841c60f5b6d3c5e4e9721997aece74d813
68 changes: 0 additions & 68 deletions examples/14-tvtomultilinejson/exampletvtomultilinejson.go

This file was deleted.

10 changes: 9 additions & 1 deletion examples/9-tvtojson/exampletvtojson.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,16 @@ func main() {
}
defer w.Close()

var opt []json.WriteOption
// you can use WriteOption to change JSON format
// uncomment the following code to test it
/*
opt = append(opt, json.Indent(" ")) // to create multiline json
opt = append(opt, json.EscapeHTML(true)) // to escape HTML characters
*/

// try to save the document to disk as JSON file
err = json.Write(doc, w)
err = json.Write(doc, w, opt...)
if err != nil {
fmt.Printf("Error while saving %v: %v", fileOut, err)
return
Expand Down
35 changes: 14 additions & 21 deletions json/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,25 @@ import (
"github.com/spdx/tools-golang/spdx/common"
)

// Write takes an SPDX Document and an io.Writer, and writes the document to the writer in JSON format.
func Write(doc common.AnyDocument, w io.Writer) error {
buf, err := json.Marshal(doc)
if err != nil {
return err
}
type WriteOption func(*json.Encoder)

_, err = w.Write(buf)
if err != nil {
return err
func Indent(indent string) WriteOption {
return func(e *json.Encoder) {
e.SetIndent("", indent)
}

return nil
}

// WriteMultiline takes an SPDX Document and an io.Writer, and writes the document to the writer in JSON format with indents (multiline format).
func WriteMultiline(doc common.AnyDocument, w io.Writer) error {
buf, err := json.MarshalIndent(doc, "", " ")
if err != nil {
return err
func EscapeHTML(escape bool) WriteOption {
return func(e *json.Encoder) {
e.SetEscapeHTML(escape)
}
}

_, err = w.Write(buf)
if err != nil {
return err
// Write takes an SPDX Document and an io.Writer, and writes the document to the writer in JSON format.
func Write(doc common.AnyDocument, w io.Writer, opts ...WriteOption) error {
e := json.NewEncoder(w)
for _, opt := range opts {
opt(e)
}

return nil
return e.Encode(doc)
}
82 changes: 82 additions & 0 deletions json/writer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package json_test

import (
"bytes"
"github.com/spdx/tools-golang/json"
"github.com/spdx/tools-golang/spdx/common"
spdx "github.com/spdx/tools-golang/spdx/v2/v2_3"
"github.com/stretchr/testify/assert"
"testing"
)

func Test_Write(t *testing.T) {
tests := []struct {
name string
doc common.AnyDocument
option []json.WriteOption
want string
}{
{
name: "happy path",
doc: spdx.Document{
SPDXVersion: "2.3",
DocumentName: "test_doc",
},
want: `{"spdxVersion":"2.3","dataLicense":"","SPDXID":"SPDXRef-","name":"test_doc","documentNamespace":"","creationInfo":null}
`,
},
{
name: "happy path with Indent option",
doc: spdx.Document{
SPDXVersion: "2.3",
DocumentName: "test_doc",
},
option: []json.WriteOption{json.Indent(" ")},
want: `{
"spdxVersion": "2.3",
"dataLicense": "",
"SPDXID": "SPDXRef-",
"name": "test_doc",
"documentNamespace": "",
"creationInfo": null
}
`,
},
{
name: "happy path with EscapeHTML==true option",
doc: spdx.Document{
SPDXVersion: "2.3",
DocumentName: "test_doc_>",
},
option: []json.WriteOption{json.EscapeHTML(true)},
want: "{\"spdxVersion\":\"2.3\",\"dataLicense\":\"\",\"SPDXID\":\"SPDXRef-\",\"name\":\"test_doc_\\u003e\",\"documentNamespace\":\"\",\"creationInfo\":null}\n",
},
{
name: "happy path with EscapeHTML==false option",
doc: spdx.Document{
SPDXVersion: "2.3",
DocumentName: "test_doc_>",
},
option: []json.WriteOption{json.EscapeHTML(false)},
want: "{\"spdxVersion\":\"2.3\",\"dataLicense\":\"\",\"SPDXID\":\"SPDXRef-\",\"name\":\"test_doc_>\",\"documentNamespace\":\"\",\"creationInfo\":null}\n",
},
{
name: "happy path with EscapeHTML==false option",
doc: spdx.Document{
SPDXVersion: "2.3",
DocumentName: "test_doc_>",
},
option: []json.WriteOption{json.EscapeHTML(false)},
want: "{\"spdxVersion\":\"2.3\",\"dataLicense\":\"\",\"SPDXID\":\"SPDXRef-\",\"name\":\"test_doc_>\",\"documentNamespace\":\"\",\"creationInfo\":null}\n",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
buf := new(bytes.Buffer)
err := json.Write(tt.doc, buf, tt.option...)
assert.NoError(t, err)
assert.Equal(t, tt.want, buf.String())
})
}
}
24 changes: 0 additions & 24 deletions spdx/v2/v2_2/json/json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,30 +92,6 @@ func Test_Write(t *testing.T) {
}
}

func Test_MultilineWrite(t *testing.T) {
want := example.Copy()

w := &bytes.Buffer{}

if err := json.WriteMultiline(&want, w); err != nil {
t.Errorf("Write() error = %v", err.Error())
return
}

// we should be able to parse what the writer wrote, and it should be identical to the original struct we wrote
var got spdx.Document
err := json.ReadInto(bytes.NewReader(w.Bytes()), &got)
if err != nil {
t.Errorf("failed to parse written document: %v", err.Error())
return
}

if !cmp.Equal(want, got, cmpopts.IgnoreUnexported(spdx.Package{})) {
t.Errorf("got incorrect struct after writing and re-parsing JSON example: %s", cmp.Diff(want, got, cmpopts.IgnoreUnexported(spdx.Package{})))
return
}
}

func Test_ShorthandFields(t *testing.T) {
contents := `{
"spdxVersion": "SPDX-2.2",
Expand Down
23 changes: 0 additions & 23 deletions spdx/v2/v2_3/json/json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,29 +81,6 @@ func Test_Write(t *testing.T) {
return
}
}
func Test_MultilineWrite(t *testing.T) {
want := example.Copy()

w := &bytes.Buffer{}

if err := json.WriteMultiline(&want, w); err != nil {
t.Errorf("Write() error = %v", err.Error())
return
}

// we should be able to parse what the writer wrote, and it should be identical to the original struct we wrote
var got spdx.Document
err := json.ReadInto(bytes.NewReader(w.Bytes()), &got)
if err != nil {
t.Errorf("failed to parse written document: %v", err.Error())
return
}

if !cmp.Equal(want, got, cmpopts.IgnoreUnexported(spdx.Package{})) {
t.Errorf("got incorrect struct after writing and re-parsing JSON example: %s", cmp.Diff(want, got, cmpopts.IgnoreUnexported(spdx.Package{})))
return
}
}

func Test_ShorthandFields(t *testing.T) {
contents := `{
Expand Down