URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [encoding/] [xml/] [xml_test.go] - Rev 747
Compare with Previous | Blame | View Log
// Copyright 2009 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package xmlimport ("io""reflect""strings""testing")const testInput = `<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><body xmlns:foo="ns1" xmlns="ns2" xmlns:tag="ns3" ` +"\r\n\t" + ` ><hello lang="en">World <>'" 白鵬翔</hello><goodbye /><outer foo:attr="value" xmlns:tag="ns4"><inner/></outer><tag:name><![CDATA[Some text here.]]></tag:name></body><!-- missing final newline -->`var rawTokens = []Token{CharData("\n"),ProcInst{"xml", []byte(`version="1.0" encoding="UTF-8"`)},CharData("\n"),Directive(`DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"`),CharData("\n"),StartElement{Name{"", "body"}, []Attr{{Name{"xmlns", "foo"}, "ns1"}, {Name{"", "xmlns"}, "ns2"}, {Name{"xmlns", "tag"}, "ns3"}}},CharData("\n "),StartElement{Name{"", "hello"}, []Attr{{Name{"", "lang"}, "en"}}},CharData("World <>'\" 白鵬翔"),EndElement{Name{"", "hello"}},CharData("\n "),StartElement{Name{"", "goodbye"}, []Attr{}},EndElement{Name{"", "goodbye"}},CharData("\n "),StartElement{Name{"", "outer"}, []Attr{{Name{"foo", "attr"}, "value"}, {Name{"xmlns", "tag"}, "ns4"}}},CharData("\n "),StartElement{Name{"", "inner"}, []Attr{}},EndElement{Name{"", "inner"}},CharData("\n "),EndElement{Name{"", "outer"}},CharData("\n "),StartElement{Name{"tag", "name"}, []Attr{}},CharData("\n "),CharData("Some text here."),CharData("\n "),EndElement{Name{"tag", "name"}},CharData("\n"),EndElement{Name{"", "body"}},Comment(" missing final newline "),}var cookedTokens = []Token{CharData("\n"),ProcInst{"xml", []byte(`version="1.0" encoding="UTF-8"`)},CharData("\n"),Directive(`DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"`),CharData("\n"),StartElement{Name{"ns2", "body"}, []Attr{{Name{"xmlns", "foo"}, "ns1"}, {Name{"", "xmlns"}, "ns2"}, {Name{"xmlns", "tag"}, "ns3"}}},CharData("\n "),StartElement{Name{"ns2", "hello"}, []Attr{{Name{"", "lang"}, "en"}}},CharData("World <>'\" 白鵬翔"),EndElement{Name{"ns2", "hello"}},CharData("\n "),StartElement{Name{"ns2", "goodbye"}, []Attr{}},EndElement{Name{"ns2", "goodbye"}},CharData("\n "),StartElement{Name{"ns2", "outer"}, []Attr{{Name{"ns1", "attr"}, "value"}, {Name{"xmlns", "tag"}, "ns4"}}},CharData("\n "),StartElement{Name{"ns2", "inner"}, []Attr{}},EndElement{Name{"ns2", "inner"}},CharData("\n "),EndElement{Name{"ns2", "outer"}},CharData("\n "),StartElement{Name{"ns3", "name"}, []Attr{}},CharData("\n "),CharData("Some text here."),CharData("\n "),EndElement{Name{"ns3", "name"}},CharData("\n"),EndElement{Name{"ns2", "body"}},Comment(" missing final newline "),}const testInputAltEncoding = `<?xml version="1.0" encoding="x-testing-uppercase"?><TAG>VALUE</TAG>`var rawTokensAltEncoding = []Token{CharData("\n"),ProcInst{"xml", []byte(`version="1.0" encoding="x-testing-uppercase"`)},CharData("\n"),StartElement{Name{"", "tag"}, []Attr{}},CharData("value"),EndElement{Name{"", "tag"}},}var xmlInput = []string{// unexpected EOF cases"<","<t","<t ","<t/","<!","<!-","<!--","<!--c-","<!--c--","<!d","<t></","<t></t","<?","<?p","<t a","<t a=","<t a='","<t a=''","<t/><![","<t/><![C","<t/><![CDATA[d","<t/><![CDATA[d]","<t/><![CDATA[d]]",// other Syntax errors"<>","<t/a","<0 />","<?0 >",// "<!0 >", // let the Token() caller handle"</0>","<t 0=''>","<t a='&'>","<t a='<'>","<t> c;</t>","<t a>","<t a=>","<t a=v>",// "<![CDATA[d]]>", // let the Token() caller handle"<t></e>","<t></>","<t></t!","<t>cdata]]></t>",}func TestRawToken(t *testing.T) {d := NewDecoder(strings.NewReader(testInput))testRawToken(t, d, rawTokens)}type downCaser struct {t *testing.Tr io.ByteReader}func (d *downCaser) ReadByte() (c byte, err error) {c, err = d.r.ReadByte()if c >= 'A' && c <= 'Z' {c += 'a' - 'A'}return}func (d *downCaser) Read(p []byte) (int, error) {d.t.Fatalf("unexpected Read call on downCaser reader")panic("unreachable")}func TestRawTokenAltEncoding(t *testing.T) {sawEncoding := ""d := NewDecoder(strings.NewReader(testInputAltEncoding))d.CharsetReader = func(charset string, input io.Reader) (io.Reader, error) {sawEncoding = charsetif charset != "x-testing-uppercase" {t.Fatalf("unexpected charset %q", charset)}return &downCaser{t, input.(io.ByteReader)}, nil}testRawToken(t, d, rawTokensAltEncoding)}func TestRawTokenAltEncodingNoConverter(t *testing.T) {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 = d.RawToken()if token != nil {t.Errorf("expected a nil token; got %#v", token)}if err == nil {t.Fatalf("expected an error on second RawToken call")}const encoding = "x-testing-uppercase"if !strings.Contains(err.Error(), encoding) {t.Errorf("expected error to contain %q; got error: %v",encoding, err)}}func testRawToken(t *testing.T, d *Decoder, rawTokens []Token) {for i, want := range rawTokens {have, err := d.RawToken()if err != nil {t.Fatalf("token %d: unexpected error: %s", i, err)}if !reflect.DeepEqual(have, want) {t.Errorf("token %d = %#v want %#v", i, have, want)}}}// Ensure that directives (specifically !DOCTYPE) include the complete// text of any nested directives, noting that < and > do not change// nesting depth if they are in single or double quotes.var nestedDirectivesInput = `<!DOCTYPE [<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">]><!DOCTYPE [<!ENTITY xlt ">">]><!DOCTYPE [<!ENTITY xlt "<">]><!DOCTYPE [<!ENTITY xlt '>'>]><!DOCTYPE [<!ENTITY xlt '<'>]><!DOCTYPE [<!ENTITY xlt '">'>]><!DOCTYPE [<!ENTITY xlt "'<">]>`var nestedDirectivesTokens = []Token{CharData("\n"),Directive(`DOCTYPE [<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">]`),CharData("\n"),Directive(`DOCTYPE [<!ENTITY xlt ">">]`),CharData("\n"),Directive(`DOCTYPE [<!ENTITY xlt "<">]`),CharData("\n"),Directive(`DOCTYPE [<!ENTITY xlt '>'>]`),CharData("\n"),Directive(`DOCTYPE [<!ENTITY xlt '<'>]`),CharData("\n"),Directive(`DOCTYPE [<!ENTITY xlt '">'>]`),CharData("\n"),Directive(`DOCTYPE [<!ENTITY xlt "'<">]`),CharData("\n"),}func TestNestedDirectives(t *testing.T) {d := NewDecoder(strings.NewReader(nestedDirectivesInput))for i, want := range nestedDirectivesTokens {have, err := d.Token()if err != nil {t.Fatalf("token %d: unexpected error: %s", i, err)}if !reflect.DeepEqual(have, want) {t.Errorf("token %d = %#v want %#v", i, have, want)}}}func TestToken(t *testing.T) {d := NewDecoder(strings.NewReader(testInput))for i, want := range cookedTokens {have, err := d.Token()if err != nil {t.Fatalf("token %d: unexpected error: %s", i, err)}if !reflect.DeepEqual(have, want) {t.Errorf("token %d = %#v want %#v", i, have, want)}}}func TestSyntax(t *testing.T) {for i := range xmlInput {d := NewDecoder(strings.NewReader(xmlInput[i]))var err errorfor _, err = d.Token(); err == nil; _, err = d.Token() {}if _, ok := err.(*SyntaxError); !ok {t.Fatalf(`xmlInput "%s": expected SyntaxError not received`, xmlInput[i])}}}type allScalars struct {True1 boolTrue2 boolFalse1 boolFalse2 boolInt intInt8 int8Int16 int16Int32 int32Int64 int64Uint intUint8 uint8Uint16 uint16Uint32 uint32Uint64 uint64Uintptr uintptrFloat32 float32Float64 float64String stringPtrString *string}var all = allScalars{True1: true,True2: true,False1: false,False2: false,Int: 1,Int8: -2,Int16: 3,Int32: -4,Int64: 5,Uint: 6,Uint8: 7,Uint16: 8,Uint32: 9,Uint64: 10,Uintptr: 11,Float32: 13.0,Float64: 14.0,String: "15",PtrString: &sixteen,}var sixteen = "16"const testScalarsInput = `<allscalars><True1>true</True1><True2>1</True2><False1>false</False1><False2>0</False2><Int>1</Int><Int8>-2</Int8><Int16>3</Int16><Int32>-4</Int32><Int64>5</Int64><Uint>6</Uint><Uint8>7</Uint8><Uint16>8</Uint16><Uint32>9</Uint32><Uint64>10</Uint64><Uintptr>11</Uintptr><Float>12.0</Float><Float32>13.0</Float32><Float64>14.0</Float64><String>15</String><PtrString>16</PtrString></allscalars>`func TestAllScalars(t *testing.T) {var a allScalarserr := Unmarshal([]byte(testScalarsInput), &a)if err != nil {t.Fatal(err)}if !reflect.DeepEqual(a, all) {t.Errorf("have %+v want %+v", a, all)}}type item struct {Field_a string}func TestIssue569(t *testing.T) {data := `<item><Field_a>abcd</Field_a></item>`var i itemerr := Unmarshal([]byte(data), &i)if err != nil || i.Field_a != "abcd" {t.Fatal("Expecting abcd")}}func TestUnquotedAttrs(t *testing.T) {data := "<tag attr=azAZ09:-_\t>"d := NewDecoder(strings.NewReader(data))d.Strict = falsetoken, err := d.Token()if _, ok := err.(*SyntaxError); ok {t.Errorf("Unexpected error: %v", err)}if token.(StartElement).Name.Local != "tag" {t.Errorf("Unexpected tag name: %v", token.(StartElement).Name.Local)}attr := token.(StartElement).Attr[0]if attr.Value != "azAZ09:-_" {t.Errorf("Unexpected attribute value: %v", attr.Value)}if attr.Name.Local != "attr" {t.Errorf("Unexpected attribute name: %v", attr.Name.Local)}}func TestValuelessAttrs(t *testing.T) {tests := [][3]string{{"<p nowrap>", "p", "nowrap"},{"<p nowrap >", "p", "nowrap"},{"<input checked/>", "input", "checked"},{"<input checked />", "input", "checked"},}for _, test := range tests {d := NewDecoder(strings.NewReader(test[0]))d.Strict = falsetoken, err := d.Token()if _, ok := err.(*SyntaxError); ok {t.Errorf("Unexpected error: %v", err)}if token.(StartElement).Name.Local != test[1] {t.Errorf("Unexpected tag name: %v", token.(StartElement).Name.Local)}attr := token.(StartElement).Attr[0]if attr.Value != test[2] {t.Errorf("Unexpected attribute value: %v", attr.Value)}if attr.Name.Local != test[2] {t.Errorf("Unexpected attribute name: %v", attr.Name.Local)}}}func TestCopyTokenCharData(t *testing.T) {data := []byte("same data")var tok1 Token = CharData(data)tok2 := CopyToken(tok1)if !reflect.DeepEqual(tok1, tok2) {t.Error("CopyToken(CharData) != CharData")}data[1] = 'o'if reflect.DeepEqual(tok1, tok2) {t.Error("CopyToken(CharData) uses same buffer.")}}func TestCopyTokenStartElement(t *testing.T) {elt := StartElement{Name{"", "hello"}, []Attr{{Name{"", "lang"}, "en"}}}var tok1 Token = elttok2 := CopyToken(tok1)if tok1.(StartElement).Attr[0].Value != "en" {t.Error("CopyToken overwrote Attr[0]")}if !reflect.DeepEqual(tok1, tok2) {t.Error("CopyToken(StartElement) != StartElement")}tok1.(StartElement).Attr[0] = Attr{Name{"", "lang"}, "de"}if reflect.DeepEqual(tok1, tok2) {t.Error("CopyToken(CharData) uses same buffer.")}}func TestSyntaxErrorLineNum(t *testing.T) {testInput := "<P>Foo<P>\n\n<P>Bar</>\n"d := NewDecoder(strings.NewReader(testInput))var err errorfor _, err = d.Token(); err == nil; _, err = d.Token() {}synerr, ok := err.(*SyntaxError)if !ok {t.Error("Expected SyntaxError.")}if synerr.Line != 3 {t.Error("SyntaxError didn't have correct line number.")}}func TestTrailingRawToken(t *testing.T) {input := `<FOO></FOO> `d := NewDecoder(strings.NewReader(input))var err errorfor _, err = d.RawToken(); err == nil; _, err = d.RawToken() {}if err != io.EOF {t.Fatalf("d.RawToken() = _, %v, want _, io.EOF", err)}}func TestTrailingToken(t *testing.T) {input := `<FOO></FOO> `d := NewDecoder(strings.NewReader(input))var err errorfor _, err = d.Token(); err == nil; _, err = d.Token() {}if err != io.EOF {t.Fatalf("d.Token() = _, %v, want _, io.EOF", err)}}func TestEntityInsideCDATA(t *testing.T) {input := `<test><![CDATA[ &val=foo ]]></test>`d := NewDecoder(strings.NewReader(input))var err errorfor _, err = d.Token(); err == nil; _, err = d.Token() {}if err != io.EOF {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.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.var characterTests = []struct {in stringerr string}{{"\x12<doc/>", "illegal character code U+0012"},{"<?xml version=\"1.0\"?>\x0b<doc/>", "illegal character code U+000B"},{"\xef\xbf\xbe<doc/>", "illegal character code U+FFFE"},{"<?xml version=\"1.0\"?><doc>\r\n<hiya/>\x07<toots/></doc>", "illegal character code U+0007"},{"<?xml version=\"1.0\"?><doc \x12='value'>what's up</doc>", "expected attribute name in element"},{"<doc>&\x01;</doc>", "invalid character entity &;"},{"<doc>&\xef\xbf\xbe;</doc>", "invalid character entity &;"},}func TestDisallowedCharacters(t *testing.T) {for i, tt := range characterTests {d := NewDecoder(strings.NewReader(tt.in))var err errorfor err == nil {_, err = d.Token()}synerr, ok := err.(*SyntaxError)if !ok {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)}}}type procInstEncodingTest struct {expect, got string}var procInstTests = []struct {input, expect string}{{`version="1.0" encoding="utf-8"`, "utf-8"},{`version="1.0" encoding='utf-8'`, "utf-8"},{`version="1.0" encoding='utf-8' `, "utf-8"},{`version="1.0" encoding=utf-8`, ""},{`encoding="FOO" `, "FOO"},}func TestProcInstEncoding(t *testing.T) {for _, test := range procInstTests {got := procInstEncoding(test.input)if got != test.expect {t.Errorf("procInstEncoding(%q) = %q; want %q", test.input, got, test.expect)}}}
