// Copyright 2018 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package xml2
import (
"bufio"
"bytes"
"encoding/xml"
"io"
"strings"
"testing"
)
func TestEncoderEncodeToken(t *testing.T) {
tests := []struct {
name string
in string
want string
wantErr string
}{
{
name: "xmlnsPrefixForElement",
in: "",
want: "",
},
{
name: "xmlnsPrefixForAttribute",
in: "",
want: "",
},
{
name: "defaultXmlnsAttribute",
in: "",
want: "",
},
{
// The return value of Decoder.Token() makes it
// impossible for a decode then encode of an xml file
// be isomorphic. This is mainly due to the fact that
// xml.Name.Space contains the uri, and xml.Name does
// not store the prefix. Instead, make sure that the
// behavior remains consistent.
//
// That is, the last prefix defined for the space is the
// one applied when encoding the token.
name: "multipleDefsXmlnsPrefixesSameUri",
in: `
`,
want: `
`,
},
{
name: "xmlnsPrefixUsedOnElementButNotDefined",
in: "",
wantErr: "unknown namespace: foo",
},
{
name: "xmlnsPrefixUsedOnAttrButNotDefined",
in: "",
wantErr: "unknown namespace: bar",
},
{
name: "xmlnsPrefixUsedOutsideOfDefiningTag",
in: `
corge
`,
wantErr: "unknown namespace: bar",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
var b bytes.Buffer
e := NewEncoder(bufio.NewWriter(&b))
d := xml.NewDecoder(strings.NewReader(test.in))
for {
tkn, err := d.Token()
if err != nil {
if err == io.EOF {
break
}
t.Fatalf("Unexpected error got: %v while reading: %s", err, test.in)
}
if err := e.EncodeToken(tkn); err != nil {
if test.wantErr != "" && strings.Contains(err.Error(), test.wantErr) {
// Do nothing, error is expected.
} else {
t.Errorf("Unexpected error during encode: %v", err)
}
return
}
}
e.Flush()
if b.String() != test.want {
t.Errorf("got: <%s> expected: <%s>", b.String(), test.want)
}
})
}
}
func TestChildEncoder(t *testing.T) {
// Setup the parent Encoder with the namespace "bar".
d := xml.NewDecoder(strings.NewReader("Hello World"))
tkn, err := d.Token()
if err != nil {
t.Fatalf("Error occurred during decoding, got: %v", err)
}
parentEnc := NewEncoder(&bytes.Buffer{})
if err := parentEnc.EncodeToken(tkn); err != nil {
t.Fatalf("Error occurred while the parent encoder was encoding token %q got: %v", tkn, err)
}
// Without instantiating the Encoder as a child, the "bar" namespace will be unknown and cause an
// error to occur when trying to encode the "bar" namespaced element "".
tkn, err = d.Token()
if err != nil {
t.Fatalf("Error occurred during decoding, got: %v", err)
}
b := &bytes.Buffer{}
childEnc := ChildEncoder(b, parentEnc)
if err := childEnc.EncodeToken(tkn); err != nil {
t.Fatalf("Error occurred while the child encoder was encoding token %q got: %v", tkn, err)
}
childEnc.Flush()
// Verify that the token is not mangled.
if want := ""; b.String() != want {
t.Errorf("Error, got %q, wanted %q", b.String(), want)
}
}