mirror of
https://github.com/golang/go
synced 2024-11-18 15:04:44 -07:00
encoding/xml: add more EncodeToken tests.
There are no behavior changes in this CL, only specifying the status quo. A follow-up CL, https://go-review.googlesource.com/#/c/2660/, will change the EncodeToken behavior. Change-Id: I6ecbcfb05ae681de71fa1099d054df2826ed4acb Reviewed-on: https://go-review.googlesource.com/4167 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
2978ebbc7b
commit
a9dddb53f7
@ -1194,41 +1194,363 @@ func TestStructPointerMarshal(t *testing.T) {
|
||||
}
|
||||
|
||||
var encodeTokenTests = []struct {
|
||||
tok Token
|
||||
desc string
|
||||
toks []Token
|
||||
want string
|
||||
ok bool
|
||||
}{
|
||||
{StartElement{Name{"space", "local"}, nil}, "<local xmlns=\"space\">", true},
|
||||
{StartElement{Name{"space", ""}, nil}, "", false},
|
||||
{EndElement{Name{"space", ""}}, "", false},
|
||||
{CharData("foo"), "foo", true},
|
||||
{Comment("foo"), "<!--foo-->", true},
|
||||
{Comment("foo-->"), "", false},
|
||||
{ProcInst{"Target", []byte("Instruction")}, "<?Target Instruction?>", true},
|
||||
{ProcInst{"", []byte("Instruction")}, "", false},
|
||||
{ProcInst{"Target", []byte("Instruction?>")}, "", false},
|
||||
{Directive("foo"), "<!foo>", true},
|
||||
{Directive("foo>"), "", false},
|
||||
}
|
||||
err string
|
||||
}{{
|
||||
desc: "start element with name space",
|
||||
toks: []Token{
|
||||
StartElement{Name{"space", "local"}, nil},
|
||||
},
|
||||
want: `<local xmlns="space">`,
|
||||
}, {
|
||||
desc: "start element with no name",
|
||||
toks: []Token{
|
||||
StartElement{Name{"space", ""}, nil},
|
||||
},
|
||||
err: "xml: start tag with no name",
|
||||
}, {
|
||||
desc: "end element with no name",
|
||||
toks: []Token{
|
||||
EndElement{Name{"space", ""}},
|
||||
},
|
||||
err: "xml: end tag with no name",
|
||||
}, {
|
||||
desc: "char data",
|
||||
toks: []Token{
|
||||
CharData("foo"),
|
||||
},
|
||||
want: `foo`,
|
||||
}, {
|
||||
desc: "char data with escaped chars",
|
||||
toks: []Token{
|
||||
CharData(" \t\n"),
|
||||
},
|
||||
want: ` 	
`,
|
||||
}, {
|
||||
desc: "comment",
|
||||
toks: []Token{
|
||||
Comment("foo"),
|
||||
},
|
||||
want: `<!--foo-->`,
|
||||
}, {
|
||||
desc: "comment with invalid content",
|
||||
toks: []Token{
|
||||
Comment("foo-->"),
|
||||
},
|
||||
err: "xml: EncodeToken of Comment containing --> marker",
|
||||
}, {
|
||||
desc: "proc instruction",
|
||||
toks: []Token{
|
||||
ProcInst{"Target", []byte("Instruction")},
|
||||
},
|
||||
want: `<?Target Instruction?>`,
|
||||
}, {
|
||||
desc: "proc instruction with empty target",
|
||||
toks: []Token{
|
||||
ProcInst{"", []byte("Instruction")},
|
||||
},
|
||||
err: "xml: EncodeToken of ProcInst with invalid Target",
|
||||
}, {
|
||||
desc: "proc instruction with bad content",
|
||||
toks: []Token{
|
||||
ProcInst{"", []byte("Instruction?>")},
|
||||
},
|
||||
err: "xml: EncodeToken of ProcInst with invalid Target",
|
||||
}, {
|
||||
desc: "directive",
|
||||
toks: []Token{
|
||||
Directive("foo"),
|
||||
},
|
||||
want: `<!foo>`,
|
||||
}, {
|
||||
desc: "directive instruction with bad name",
|
||||
toks: []Token{
|
||||
Directive("foo>"),
|
||||
},
|
||||
err: "xml: EncodeToken of Directive containing > marker",
|
||||
}, {
|
||||
desc: "end tag without start tag",
|
||||
toks: []Token{
|
||||
EndElement{Name{"foo", "bar"}},
|
||||
},
|
||||
err: "xml: end tag </bar> without start tag",
|
||||
}, {
|
||||
desc: "mismatching end tag local name",
|
||||
toks: []Token{
|
||||
StartElement{Name{"", "foo"}, nil},
|
||||
EndElement{Name{"", "bar"}},
|
||||
},
|
||||
err: "xml: end tag </bar> does not match start tag <foo>",
|
||||
want: `<foo>`,
|
||||
}, {
|
||||
desc: "mismatching end tag namespace",
|
||||
toks: []Token{
|
||||
StartElement{Name{"space", "foo"}, nil},
|
||||
EndElement{Name{"another", "foo"}},
|
||||
},
|
||||
err: "xml: end tag </foo> in namespace another does not match start tag <foo> in namespace space",
|
||||
want: `<foo xmlns="space">`,
|
||||
}, {
|
||||
desc: "start element with explicit namespace",
|
||||
toks: []Token{
|
||||
StartElement{Name{"space", "local"}, []Attr{
|
||||
{Name{"xmlns", "x"}, "space"},
|
||||
{Name{"space", "foo"}, "value"},
|
||||
}},
|
||||
},
|
||||
want: `<local xmlns="space" xmlns:_xmlns="xmlns" _xmlns:x="space" xmlns:space="space" space:foo="value">`,
|
||||
}, {
|
||||
desc: "start element with explicit namespace and colliding prefix",
|
||||
toks: []Token{
|
||||
StartElement{Name{"space", "local"}, []Attr{
|
||||
{Name{"xmlns", "x"}, "space"},
|
||||
{Name{"space", "foo"}, "value"},
|
||||
{Name{"x", "bar"}, "other"},
|
||||
}},
|
||||
},
|
||||
want: `<local xmlns="space" xmlns:_xmlns="xmlns" _xmlns:x="space" xmlns:space="space" space:foo="value" xmlns:x="x" x:bar="other">`,
|
||||
}, {
|
||||
desc: "start element using previously defined namespace",
|
||||
toks: []Token{
|
||||
StartElement{Name{"", "local"}, []Attr{
|
||||
{Name{"xmlns", "x"}, "space"},
|
||||
}},
|
||||
StartElement{Name{"space", "foo"}, []Attr{
|
||||
{Name{"space", "x"}, "y"},
|
||||
}},
|
||||
},
|
||||
want: `<local xmlns:_xmlns="xmlns" _xmlns:x="space"><foo xmlns="space" xmlns:space="space" space:x="y">`,
|
||||
}, {
|
||||
desc: "nested name space with same prefix",
|
||||
toks: []Token{
|
||||
StartElement{Name{"", "foo"}, []Attr{
|
||||
{Name{"xmlns", "x"}, "space1"},
|
||||
}},
|
||||
StartElement{Name{"", "foo"}, []Attr{
|
||||
{Name{"xmlns", "x"}, "space2"},
|
||||
}},
|
||||
StartElement{Name{"", "foo"}, []Attr{
|
||||
{Name{"space1", "a"}, "space1 value"},
|
||||
{Name{"space2", "b"}, "space2 value"},
|
||||
}},
|
||||
EndElement{Name{"", "foo"}},
|
||||
EndElement{Name{"", "foo"}},
|
||||
StartElement{Name{"", "foo"}, []Attr{
|
||||
{Name{"space1", "a"}, "space1 value"},
|
||||
{Name{"space2", "b"}, "space2 value"},
|
||||
}},
|
||||
},
|
||||
want: `<foo xmlns:_xmlns="xmlns" _xmlns:x="space1"><foo _xmlns:x="space2"><foo xmlns:space1="space1" space1:a="space1 value" xmlns:space2="space2" space2:b="space2 value"></foo></foo><foo xmlns:space1="space1" space1:a="space1 value" xmlns:space2="space2" space2:b="space2 value">`,
|
||||
}, {
|
||||
desc: "start element defining several prefixes for the same name space",
|
||||
toks: []Token{
|
||||
StartElement{Name{"space", "foo"}, []Attr{
|
||||
{Name{"xmlns", "a"}, "space"},
|
||||
{Name{"xmlns", "b"}, "space"},
|
||||
{Name{"space", "x"}, "value"},
|
||||
}},
|
||||
},
|
||||
want: `<foo xmlns="space" xmlns:_xmlns="xmlns" _xmlns:a="space" _xmlns:b="space" xmlns:space="space" space:x="value">`,
|
||||
}, {
|
||||
desc: "nested element redefines name space",
|
||||
toks: []Token{
|
||||
StartElement{Name{"", "foo"}, []Attr{
|
||||
{Name{"xmlns", "x"}, "space"},
|
||||
}},
|
||||
StartElement{Name{"space", "foo"}, []Attr{
|
||||
{Name{"xmlns", "y"}, "space"},
|
||||
{Name{"space", "a"}, "value"},
|
||||
}},
|
||||
},
|
||||
want: `<foo xmlns:_xmlns="xmlns" _xmlns:x="space"><foo xmlns="space" _xmlns:y="space" xmlns:space="space" space:a="value">`,
|
||||
}, {
|
||||
desc: "nested element creates alias for default name space",
|
||||
toks: []Token{
|
||||
StartElement{Name{"space", "foo"}, []Attr{
|
||||
{Name{"", "xmlns"}, "space"},
|
||||
}},
|
||||
StartElement{Name{"space", "foo"}, []Attr{
|
||||
{Name{"xmlns", "y"}, "space"},
|
||||
{Name{"space", "a"}, "value"},
|
||||
}},
|
||||
},
|
||||
want: `<foo xmlns="space" xmlns="space"><foo xmlns="space" xmlns:_xmlns="xmlns" _xmlns:y="space" xmlns:space="space" space:a="value">`,
|
||||
}, {
|
||||
desc: "nested element defines default name space with existing prefix",
|
||||
toks: []Token{
|
||||
StartElement{Name{"", "foo"}, []Attr{
|
||||
{Name{"xmlns", "x"}, "space"},
|
||||
}},
|
||||
StartElement{Name{"space", "foo"}, []Attr{
|
||||
{Name{"", "xmlns"}, "space"},
|
||||
{Name{"space", "a"}, "value"},
|
||||
}},
|
||||
},
|
||||
want: `<foo xmlns:_xmlns="xmlns" _xmlns:x="space"><foo xmlns="space" xmlns="space" xmlns:space="space" space:a="value">`,
|
||||
}, {
|
||||
desc: "nested element uses empty attribute name space when default ns defined",
|
||||
toks: []Token{
|
||||
StartElement{Name{"space", "foo"}, []Attr{
|
||||
{Name{"", "xmlns"}, "space"},
|
||||
}},
|
||||
StartElement{Name{"space", "foo"}, []Attr{
|
||||
{Name{"", "attr"}, "value"},
|
||||
}},
|
||||
},
|
||||
want: `<foo xmlns="space" xmlns="space"><foo xmlns="space" attr="value">`,
|
||||
}, {
|
||||
desc: "redefine xmlns",
|
||||
toks: []Token{
|
||||
StartElement{Name{"", "foo"}, []Attr{
|
||||
{Name{"foo", "xmlns"}, "space"},
|
||||
}},
|
||||
},
|
||||
want: `<foo xmlns:foo="foo" foo:xmlns="space">`,
|
||||
}, {
|
||||
desc: "xmlns with explicit name space #1",
|
||||
toks: []Token{
|
||||
StartElement{Name{"space", "foo"}, []Attr{
|
||||
{Name{"xml", "xmlns"}, "space"},
|
||||
}},
|
||||
},
|
||||
want: `<foo xmlns="space" xmlns:_xml="xml" _xml:xmlns="space">`,
|
||||
}, {
|
||||
desc: "xmlns with explicit name space #2",
|
||||
toks: []Token{
|
||||
StartElement{Name{"space", "foo"}, []Attr{
|
||||
{Name{xmlURL, "xmlns"}, "space"},
|
||||
}},
|
||||
},
|
||||
want: `<foo xmlns="space" xml:xmlns="space">`,
|
||||
}, {
|
||||
desc: "empty name space declaration is ignored",
|
||||
toks: []Token{
|
||||
StartElement{Name{"", "foo"}, []Attr{
|
||||
{Name{"xmlns", "foo"}, ""},
|
||||
}},
|
||||
},
|
||||
want: `<foo xmlns:_xmlns="xmlns" _xmlns:foo="">`,
|
||||
}, {
|
||||
desc: "attribute with no name is ignored",
|
||||
toks: []Token{
|
||||
StartElement{Name{"", "foo"}, []Attr{
|
||||
{Name{"", ""}, "value"},
|
||||
}},
|
||||
},
|
||||
want: `<foo>`,
|
||||
}, {
|
||||
desc: "namespace URL with non-valid name",
|
||||
toks: []Token{
|
||||
StartElement{Name{"/34", "foo"}, []Attr{
|
||||
{Name{"/34", "x"}, "value"},
|
||||
}},
|
||||
},
|
||||
want: `<foo xmlns="/34" xmlns:_="/34" _:x="value">`,
|
||||
}, {
|
||||
desc: "nested element resets default namespace to empty",
|
||||
toks: []Token{
|
||||
StartElement{Name{"space", "foo"}, []Attr{
|
||||
{Name{"", "xmlns"}, "space"},
|
||||
}},
|
||||
StartElement{Name{"", "foo"}, []Attr{
|
||||
{Name{"", "xmlns"}, ""},
|
||||
{Name{"", "x"}, "value"},
|
||||
{Name{"space", "x"}, "value"},
|
||||
}},
|
||||
},
|
||||
want: `<foo xmlns="space" xmlns="space"><foo xmlns="" x="value" xmlns:space="space" space:x="value">`,
|
||||
}, {
|
||||
desc: "nested element requires empty default name space",
|
||||
toks: []Token{
|
||||
StartElement{Name{"space", "foo"}, []Attr{
|
||||
{Name{"", "xmlns"}, "space"},
|
||||
}},
|
||||
StartElement{Name{"", "foo"}, nil},
|
||||
},
|
||||
want: `<foo xmlns="space" xmlns="space"><foo>`,
|
||||
}, {
|
||||
desc: "attribute uses name space from xmlns",
|
||||
toks: []Token{
|
||||
StartElement{Name{"some/space", "foo"}, []Attr{
|
||||
{Name{"", "attr"}, "value"},
|
||||
{Name{"some/space", "other"}, "other value"},
|
||||
}},
|
||||
},
|
||||
want: `<foo xmlns="some/space" attr="value" xmlns:space="some/space" space:other="other value">`,
|
||||
}, {
|
||||
desc: "default name space should not be used by attributes",
|
||||
toks: []Token{
|
||||
StartElement{Name{"space", "foo"}, []Attr{
|
||||
{Name{"", "xmlns"}, "space"},
|
||||
{Name{"xmlns", "bar"}, "space"},
|
||||
{Name{"space", "baz"}, "foo"},
|
||||
}},
|
||||
StartElement{Name{"space", "baz"}, nil},
|
||||
EndElement{Name{"space", "baz"}},
|
||||
EndElement{Name{"space", "foo"}},
|
||||
},
|
||||
want: `<foo xmlns="space" xmlns="space" xmlns:_xmlns="xmlns" _xmlns:bar="space" xmlns:space="space" space:baz="foo"><baz xmlns="space"></baz></foo>`,
|
||||
}, {
|
||||
desc: "default name space not used by attributes, not explicitly defined",
|
||||
toks: []Token{
|
||||
StartElement{Name{"space", "foo"}, []Attr{
|
||||
{Name{"", "xmlns"}, "space"},
|
||||
{Name{"space", "baz"}, "foo"},
|
||||
}},
|
||||
StartElement{Name{"space", "baz"}, nil},
|
||||
EndElement{Name{"space", "baz"}},
|
||||
EndElement{Name{"space", "foo"}},
|
||||
},
|
||||
want: `<foo xmlns="space" xmlns="space" xmlns:space="space" space:baz="foo"><baz xmlns="space"></baz></foo>`,
|
||||
}, {
|
||||
desc: "impossible xmlns declaration",
|
||||
toks: []Token{
|
||||
StartElement{Name{"", "foo"}, []Attr{
|
||||
{Name{"", "xmlns"}, "space"},
|
||||
}},
|
||||
StartElement{Name{"space", "bar"}, []Attr{
|
||||
{Name{"space", "attr"}, "value"},
|
||||
}},
|
||||
},
|
||||
want: `<foo xmlns="space"><bar xmlns="space" xmlns:space="space" space:attr="value">`,
|
||||
}}
|
||||
|
||||
func TestEncodeToken(t *testing.T) {
|
||||
for _, tt := range encodeTokenTests {
|
||||
loop:
|
||||
for i, tt := range encodeTokenTests {
|
||||
var buf bytes.Buffer
|
||||
enc := NewEncoder(&buf)
|
||||
err := enc.EncodeToken(tt.tok)
|
||||
var err error
|
||||
for j, tok := range tt.toks {
|
||||
err = enc.EncodeToken(tok)
|
||||
if err != nil && j < len(tt.toks)-1 {
|
||||
t.Errorf("#%d %s token #%d: %v", i, tt.desc, j, err)
|
||||
continue loop
|
||||
}
|
||||
}
|
||||
errorf := func(f string, a ...interface{}) {
|
||||
t.Errorf("#%d %s token #%d:%s", i, tt.desc, len(tt.toks)-1, fmt.Sprintf(f, a...))
|
||||
}
|
||||
switch {
|
||||
case !tt.ok && err == nil:
|
||||
t.Errorf("enc.EncodeToken(%#v): expected error; got none", tt.tok)
|
||||
case tt.ok && err != nil:
|
||||
t.Fatalf("enc.EncodeToken: %v", err)
|
||||
case !tt.ok && err != nil:
|
||||
// expected error, got one
|
||||
case tt.err != "" && err == nil:
|
||||
errorf(" expected error; got none")
|
||||
continue
|
||||
case tt.err == "" && err != nil:
|
||||
errorf(" got error: %v", err)
|
||||
continue
|
||||
case tt.err != "" && err != nil && tt.err != err.Error():
|
||||
errorf(" error mismatch; got %v, want %v", err, tt.err)
|
||||
continue
|
||||
}
|
||||
if err := enc.Flush(); err != nil {
|
||||
t.Fatalf("enc.EncodeToken: %v", err)
|
||||
errorf(" %v", err)
|
||||
continue
|
||||
}
|
||||
if got := buf.String(); got != tt.want {
|
||||
t.Errorf("enc.EncodeToken = %s; want: %s", got, tt.want)
|
||||
errorf("\ngot %v\nwant %v", got, tt.want)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user