encoding/xml: bring API closer to other packages

Includes gofix module. The only case not covered should be
xml.Unmarshal, since it remains with a similar interface, and
would require introspecting the type of its first argument
better.

Fixes #2626.

R=golang-dev, rsc, gustavo
CC=golang-dev
https://golang.org/cl/5574053
This commit is contained in:
Gustavo Niemeyer 2012-01-24 01:10:32 -02:00
parent 6d7e9382b4
commit 0442087f93
11 changed files with 494 additions and 349 deletions

View file

@ -5,7 +5,6 @@
package xml
import (
"bytes"
"io"
"reflect"
"strings"
@ -155,8 +154,8 @@ var xmlInput = []string{
}
func TestRawToken(t *testing.T) {
p := NewParser(strings.NewReader(testInput))
testRawToken(t, p, rawTokens)
d := NewDecoder(strings.NewReader(testInput))
testRawToken(t, d, rawTokens)
}
type downCaser struct {
@ -179,27 +178,27 @@ func (d *downCaser) Read(p []byte) (int, error) {
func TestRawTokenAltEncoding(t *testing.T) {
sawEncoding := ""
p := NewParser(strings.NewReader(testInputAltEncoding))
p.CharsetReader = func(charset string, input io.Reader) (io.Reader, error) {
d := NewDecoder(strings.NewReader(testInputAltEncoding))
d.CharsetReader = func(charset string, input io.Reader) (io.Reader, error) {
sawEncoding = charset
if charset != "x-testing-uppercase" {
t.Fatalf("unexpected charset %q", charset)
}
return &downCaser{t, input.(io.ByteReader)}, nil
}
testRawToken(t, p, rawTokensAltEncoding)
testRawToken(t, d, rawTokensAltEncoding)
}
func TestRawTokenAltEncodingNoConverter(t *testing.T) {
p := NewParser(strings.NewReader(testInputAltEncoding))
token, err := p.RawToken()
d := NewDecoder(strings.NewReader(testInputAltEncoding))
token, err := d.RawToken()
if token == nil {
t.Fatalf("expected a token on first RawToken call")
}
if err != nil {
t.Fatal(err)
}
token, err = p.RawToken()
token, err = d.RawToken()
if token != nil {
t.Errorf("expected a nil token; got %#v", token)
}
@ -213,9 +212,9 @@ func TestRawTokenAltEncodingNoConverter(t *testing.T) {
}
}
func testRawToken(t *testing.T, p *Parser, rawTokens []Token) {
func testRawToken(t *testing.T, d *Decoder, rawTokens []Token) {
for i, want := range rawTokens {
have, err := p.RawToken()
have, err := d.RawToken()
if err != nil {
t.Fatalf("token %d: unexpected error: %s", i, err)
}
@ -258,10 +257,10 @@ var nestedDirectivesTokens = []Token{
}
func TestNestedDirectives(t *testing.T) {
p := NewParser(strings.NewReader(nestedDirectivesInput))
d := NewDecoder(strings.NewReader(nestedDirectivesInput))
for i, want := range nestedDirectivesTokens {
have, err := p.Token()
have, err := d.Token()
if err != nil {
t.Fatalf("token %d: unexpected error: %s", i, err)
}
@ -272,10 +271,10 @@ func TestNestedDirectives(t *testing.T) {
}
func TestToken(t *testing.T) {
p := NewParser(strings.NewReader(testInput))
d := NewDecoder(strings.NewReader(testInput))
for i, want := range cookedTokens {
have, err := p.Token()
have, err := d.Token()
if err != nil {
t.Fatalf("token %d: unexpected error: %s", i, err)
}
@ -287,9 +286,9 @@ func TestToken(t *testing.T) {
func TestSyntax(t *testing.T) {
for i := range xmlInput {
p := NewParser(strings.NewReader(xmlInput[i]))
d := NewDecoder(strings.NewReader(xmlInput[i]))
var err error
for _, err = p.Token(); err == nil; _, err = p.Token() {
for _, err = d.Token(); err == nil; _, err = d.Token() {
}
if _, ok := err.(*SyntaxError); !ok {
t.Fatalf(`xmlInput "%s": expected SyntaxError not received`, xmlInput[i])
@ -368,8 +367,7 @@ const testScalarsInput = `<allscalars>
func TestAllScalars(t *testing.T) {
var a allScalars
buf := bytes.NewBufferString(testScalarsInput)
err := Unmarshal(buf, &a)
err := Unmarshal([]byte(testScalarsInput), &a)
if err != nil {
t.Fatal(err)
@ -386,8 +384,7 @@ type item struct {
func TestIssue569(t *testing.T) {
data := `<item><Field_a>abcd</Field_a></item>`
var i item
buf := bytes.NewBufferString(data)
err := Unmarshal(buf, &i)
err := Unmarshal([]byte(data), &i)
if err != nil || i.Field_a != "abcd" {
t.Fatal("Expecting abcd")
@ -396,9 +393,9 @@ func TestIssue569(t *testing.T) {
func TestUnquotedAttrs(t *testing.T) {
data := "<tag attr=azAZ09:-_\t>"
p := NewParser(strings.NewReader(data))
p.Strict = false
token, err := p.Token()
d := NewDecoder(strings.NewReader(data))
d.Strict = false
token, err := d.Token()
if _, ok := err.(*SyntaxError); ok {
t.Errorf("Unexpected error: %v", err)
}
@ -422,9 +419,9 @@ func TestValuelessAttrs(t *testing.T) {
{"<input checked />", "input", "checked"},
}
for _, test := range tests {
p := NewParser(strings.NewReader(test[0]))
p.Strict = false
token, err := p.Token()
d := NewDecoder(strings.NewReader(test[0]))
d.Strict = false
token, err := d.Token()
if _, ok := err.(*SyntaxError); ok {
t.Errorf("Unexpected error: %v", err)
}
@ -472,9 +469,9 @@ func TestCopyTokenStartElement(t *testing.T) {
func TestSyntaxErrorLineNum(t *testing.T) {
testInput := "<P>Foo<P>\n\n<P>Bar</>\n"
p := NewParser(strings.NewReader(testInput))
d := NewDecoder(strings.NewReader(testInput))
var err error
for _, err = p.Token(); err == nil; _, err = p.Token() {
for _, err = d.Token(); err == nil; _, err = d.Token() {
}
synerr, ok := err.(*SyntaxError)
if !ok {
@ -487,41 +484,41 @@ func TestSyntaxErrorLineNum(t *testing.T) {
func TestTrailingRawToken(t *testing.T) {
input := `<FOO></FOO> `
p := NewParser(strings.NewReader(input))
d := NewDecoder(strings.NewReader(input))
var err error
for _, err = p.RawToken(); err == nil; _, err = p.RawToken() {
for _, err = d.RawToken(); err == nil; _, err = d.RawToken() {
}
if err != io.EOF {
t.Fatalf("p.RawToken() = _, %v, want _, io.EOF", err)
t.Fatalf("d.RawToken() = _, %v, want _, io.EOF", err)
}
}
func TestTrailingToken(t *testing.T) {
input := `<FOO></FOO> `
p := NewParser(strings.NewReader(input))
d := NewDecoder(strings.NewReader(input))
var err error
for _, err = p.Token(); err == nil; _, err = p.Token() {
for _, err = d.Token(); err == nil; _, err = d.Token() {
}
if err != io.EOF {
t.Fatalf("p.Token() = _, %v, want _, io.EOF", err)
t.Fatalf("d.Token() = _, %v, want _, io.EOF", err)
}
}
func TestEntityInsideCDATA(t *testing.T) {
input := `<test><![CDATA[ &val=foo ]]></test>`
p := NewParser(strings.NewReader(input))
d := NewDecoder(strings.NewReader(input))
var err error
for _, err = p.Token(); err == nil; _, err = p.Token() {
for _, err = d.Token(); err == nil; _, err = d.Token() {
}
if err != io.EOF {
t.Fatalf("p.Token() = _, %v, want _, io.EOF", err)
t.Fatalf("d.Token() = _, %v, want _, io.EOF", err)
}
}
// The last three tests (respectively one for characters in attribute
// names and two for character entities) pass not because of code
// changed for issue 1259, but instead pass with the given messages
// from other parts of xml.Parser. I provide these to note the
// from other parts of xml.Decoder. I provide these to note the
// current behavior of situations where one might think that character
// range checking would detect the error, but it does not in fact.
@ -541,15 +538,15 @@ var characterTests = []struct {
func TestDisallowedCharacters(t *testing.T) {
for i, tt := range characterTests {
p := NewParser(strings.NewReader(tt.in))
d := NewDecoder(strings.NewReader(tt.in))
var err error
for err == nil {
_, err = p.Token()
_, err = d.Token()
}
synerr, ok := err.(*SyntaxError)
if !ok {
t.Fatalf("input %d p.Token() = _, %v, want _, *SyntaxError", i, err)
t.Fatalf("input %d d.Token() = _, %v, want _, *SyntaxError", i, err)
}
if synerr.Msg != tt.err {
t.Fatalf("input %d synerr.Msg wrong: want '%s', got '%s'", i, tt.err, synerr.Msg)