...

Source file src/github.com/joshdk/go-junit/parse_test.go

Documentation: github.com/joshdk/go-junit

     1  // Copyright Josh Komoroske. All rights reserved.
     2  // Use of this source code is governed by the MIT license,
     3  // a copy of which can be found in the LICENSE.txt file.
     4  
     5  package junit
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/xml"
    10  	"fmt"
    11  	"io/ioutil"
    12  	"testing"
    13  
    14  	"github.com/stretchr/testify/assert"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  func TestReparent(t *testing.T) {
    19  	tests := []struct {
    20  		title    string
    21  		input    []byte
    22  		expected string
    23  	}{
    24  		{
    25  			title:    "nil input",
    26  			expected: "<fake-root></fake-root>",
    27  		},
    28  		{
    29  			title:    "empty input",
    30  			input:    []byte(""),
    31  			expected: "<fake-root></fake-root>",
    32  		},
    33  		{
    34  			title:    "xml input",
    35  			input:    []byte(`<testcase name="unit tests" />`),
    36  			expected: `<fake-root><testcase name="unit tests" /></fake-root>`,
    37  		},
    38  	}
    39  
    40  	for index, test := range tests {
    41  		name := fmt.Sprintf("#%d - %s", index+1, test.title)
    42  
    43  		t.Run(name, func(t *testing.T) {
    44  			reader := reparentXML(bytes.NewReader(test.input))
    45  			actual, err := ioutil.ReadAll(reader)
    46  			assert.NoError(t, err)
    47  
    48  			assert.Equal(t, test.expected, string(actual))
    49  		})
    50  	}
    51  }
    52  
    53  func TestParse(t *testing.T) {
    54  	tests := []struct {
    55  		title    string
    56  		input    []byte
    57  		expected []xmlNode
    58  	}{
    59  		{
    60  			title: "nil input",
    61  		},
    62  		{
    63  			title: "empty input",
    64  			input: []byte(``),
    65  		},
    66  		{
    67  			title: "plaintext input",
    68  			input: []byte(`This is some data that does not look like xml.`),
    69  		},
    70  		{
    71  			title: "json input",
    72  			input: []byte(`{"This is some data": "that looks like json"}`),
    73  		},
    74  		{
    75  			title: "single xml node",
    76  			input: []byte(`<this-is-a-tag/>`),
    77  			expected: []xmlNode{
    78  				{
    79  					XMLName: xml.Name{
    80  						Local: "this-is-a-tag",
    81  					},
    82  				},
    83  			},
    84  		},
    85  		{
    86  			title: "multiple xml nodes",
    87  			input: []byte(`
    88  				<this-is-a-tag/>
    89  				<this-is-also-a-tag/>
    90  			`),
    91  			expected: []xmlNode{
    92  				{
    93  					XMLName: xml.Name{
    94  						Local: "this-is-a-tag",
    95  					},
    96  				},
    97  				{
    98  					XMLName: xml.Name{
    99  						Local: "this-is-also-a-tag",
   100  					},
   101  				},
   102  			},
   103  		},
   104  		{
   105  			title: "single xml node with content",
   106  			input: []byte(`<this-is-a-tag>This is some content.</this-is-a-tag>`),
   107  			expected: []xmlNode{
   108  				{
   109  					XMLName: xml.Name{
   110  						Local: "this-is-a-tag",
   111  					},
   112  					Content: []byte("This is some content."),
   113  				},
   114  			},
   115  		},
   116  		{
   117  			title: "single xml node with encoded content",
   118  			input: []byte(`<this-is-a-tag>&lt;sender&gt;John Smith&lt;/sender&gt;</this-is-a-tag>`),
   119  			expected: []xmlNode{
   120  				{
   121  					XMLName: xml.Name{
   122  						Local: "this-is-a-tag",
   123  					},
   124  					Content: []byte("<sender>John Smith</sender>"),
   125  				},
   126  			},
   127  		},
   128  		{
   129  			title: "single xml node with cdata content",
   130  			input: []byte(`<this-is-a-tag><![CDATA[<sender>John Smith</sender>]]></this-is-a-tag>`),
   131  			expected: []xmlNode{
   132  				{
   133  					XMLName: xml.Name{
   134  						Local: "this-is-a-tag",
   135  					},
   136  					Content: []byte("<sender>John Smith</sender>"),
   137  				},
   138  			},
   139  		},
   140  		{
   141  			title: "single xml node with attributes",
   142  			input: []byte(`<this-is-a-tag name="my name" status="passed"></this-is-a-tag>`),
   143  			expected: []xmlNode{
   144  				{
   145  					XMLName: xml.Name{
   146  						Local: "this-is-a-tag",
   147  					},
   148  					Attrs: map[string]string{
   149  						"name":   "my name",
   150  						"status": "passed",
   151  					},
   152  				},
   153  			},
   154  		},
   155  		{
   156  			title: "single xml node with encoded attributes",
   157  			input: []byte(`<this-is-a-tag name="&lt;sender&gt;John Smith&lt;/sender&gt;"></this-is-a-tag>`),
   158  			expected: []xmlNode{
   159  				{
   160  					XMLName: xml.Name{
   161  						Local: "this-is-a-tag",
   162  					},
   163  					Attrs: map[string]string{
   164  						"name": "<sender>John Smith</sender>",
   165  					},
   166  				},
   167  			},
   168  		},
   169  	}
   170  
   171  	for index, test := range tests {
   172  		name := fmt.Sprintf("#%d - %s", index+1, test.title)
   173  
   174  		t.Run(name, func(t *testing.T) {
   175  			actual, err := parse(bytes.NewReader(test.input))
   176  			require.Nil(t, err)
   177  
   178  			assert.Equal(t, test.expected, actual)
   179  		})
   180  	}
   181  }
   182  
   183  func TestExtract(t *testing.T) {
   184  	tests := []struct {
   185  		title    string
   186  		input    []byte
   187  		expected []byte
   188  		err      string
   189  	}{
   190  		{
   191  			title: "nil content",
   192  		},
   193  		{
   194  			title: "empty content",
   195  			input: []byte(""),
   196  		},
   197  		{
   198  			title:    "simple content",
   199  			input:    []byte("hello world"),
   200  			expected: []byte("hello world"),
   201  		},
   202  		{
   203  			title:    "complex content",
   204  			input:    []byte("No bugs 🐜"),
   205  			expected: []byte("No bugs 🐜"),
   206  		},
   207  		{
   208  			title:    "simple encoded content",
   209  			input:    []byte("I &lt;/3 XML"),
   210  			expected: []byte("I </3 XML"),
   211  		},
   212  		{
   213  			title:    "complex encoded content",
   214  			input:    []byte(`&lt;[[&apos;/\&quot;]]&gt;`),
   215  			expected: []byte(`<[['/\"]]>`),
   216  		},
   217  		{
   218  			title: "empty cdata content",
   219  			input: []byte("<![CDATA[]]>"),
   220  		},
   221  		{
   222  			title:    "simple cdata content",
   223  			input:    []byte("<![CDATA[hello world]]>"),
   224  			expected: []byte("hello world"),
   225  		},
   226  		{
   227  			title:    "complex cdata content",
   228  			input:    []byte("<![CDATA[I </3 XML]]>"),
   229  			expected: []byte("I </3 XML"),
   230  		},
   231  		{
   232  			title:    "complex encoded cdata content",
   233  			input:    []byte("<![CDATA[I &lt;/3 XML]]>"),
   234  			expected: []byte("I &lt;/3 XML"),
   235  		},
   236  		{
   237  			title:    "encoded content then cdata content",
   238  			input:    []byte("I want to say that <![CDATA[I </3 XML]]>"),
   239  			expected: []byte("I want to say that I </3 XML"),
   240  		},
   241  		{
   242  			title:    "cdata content then encoded content",
   243  			input:    []byte("<![CDATA[I </3 XML]]> a lot"),
   244  			expected: []byte("I </3 XML a lot"),
   245  		},
   246  		{
   247  			title:    "mixture of encoded and cdata content",
   248  			input:    []byte("I &lt;/3 XML <![CDATA[a lot]]>. 🐜 You probably <![CDATA[</3 XML]]> too."),
   249  			expected: []byte("I </3 XML a lot. 🐜 You probably </3 XML too."),
   250  		},
   251  		{
   252  			title: "unmatched cdata start tag",
   253  			input: []byte("<![CDATA["),
   254  			err:   "unmatched CDATA start tag",
   255  		},
   256  		{
   257  			title: "unmatched cdata end tag",
   258  			input: []byte("]]>"),
   259  			err:   "unmatched CDATA end tag",
   260  		},
   261  	}
   262  
   263  	for index, test := range tests {
   264  		name := fmt.Sprintf("#%d - %s", index+1, test.title)
   265  
   266  		t.Run(name, func(t *testing.T) {
   267  			actual, err := extractContent(test.input)
   268  
   269  			checkError(t, test.err, err)
   270  			assert.Equal(t, test.expected, actual)
   271  		})
   272  	}
   273  }
   274  
   275  func checkError(t *testing.T, expected string, actual error) {
   276  	t.Helper()
   277  
   278  	switch {
   279  	case expected == "" && actual == nil:
   280  		return
   281  	case expected == "" && actual != nil:
   282  		t.Fatalf("expected no error but got %q", actual.Error())
   283  	case expected != "" && actual == nil:
   284  		t.Fatalf("expected %q but got nil", expected)
   285  	case expected == actual.Error():
   286  		return
   287  	default:
   288  		t.Fatalf("expected %q but got %q", expected, actual.Error())
   289  	}
   290  }
   291  

View as plain text