"
- d := NewDecoder(strings.NewReader(data))
- d.Strict = false
- token, 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"},
- {"", "input", "checked"},
- {"", "input", "checked"},
- }
- for _, test := range tests {
- d := NewDecoder(strings.NewReader(test[0]))
- d.Strict = false
- token, 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 = elt
- tok2 := 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 := "
Foo
\n\n
Bar>\n"
- d := NewDecoder(strings.NewReader(testInput))
- var err error
- for _, 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 := ` `
- d := NewDecoder(strings.NewReader(input))
- var err error
- for _, 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 := ` `
- d := NewDecoder(strings.NewReader(input))
- var err error
- for _, 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 := ``
- d := NewDecoder(strings.NewReader(input))
- var err error
- for _, err = d.Token(); err == nil; _, err = d.Token() {
- }
- if err != io.EOF {
- t.Fatalf("d.Token() = _, %v, want _, io.EOF", err)
- }
-}
-
-var characterTests = []struct {
- in string
- err string
-}{
- {"\x12", "illegal character code U+0012"},
- {"\x0b", "illegal character code U+000B"},
- {"\xef\xbf\xbe", "illegal character code U+FFFE"},
- {"\r\n\x07", "illegal character code U+0007"},
- {"what's up", "expected attribute name in element"},
- {"&abc\x01;", "invalid character entity &abc (no semicolon)"},
- {"&\x01;", "invalid character entity & (no semicolon)"},
- {"&\xef\xbf\xbe;", "invalid character entity &\uFFFE;"},
- {"&hello;", "invalid character entity &hello;"},
-}
-
-func TestDisallowedCharacters(t *testing.T) {
-
- for i, tt := range characterTests {
- d := NewDecoder(strings.NewReader(tt.in))
- var err error
-
- for 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 %q, got %q", i, tt.err, synerr.Msg)
- }
- }
-}
-
-type procInstEncodingTest struct {
- expect, got string
-}
-
-var procInstTests = []struct {
- input string
- expect [2]string
-}{
- {`version="1.0" encoding="utf-8"`, [2]string{"1.0", "utf-8"}},
- {`version="1.0" encoding='utf-8'`, [2]string{"1.0", "utf-8"}},
- {`version="1.0" encoding='utf-8' `, [2]string{"1.0", "utf-8"}},
- {`version="1.0" encoding=utf-8`, [2]string{"1.0", ""}},
- {`encoding="FOO" `, [2]string{"", "FOO"}},
-}
-
-func TestProcInstEncoding(t *testing.T) {
- for _, test := range procInstTests {
- if got := procInst("version", test.input); got != test.expect[0] {
- t.Errorf("procInst(version, %q) = %q; want %q", test.input, got, test.expect[0])
- }
- if got := procInst("encoding", test.input); got != test.expect[1] {
- t.Errorf("procInst(encoding, %q) = %q; want %q", test.input, got, test.expect[1])
- }
- }
-}
-
-// Ensure that directives with comments include the complete
-// text of any nested directives.
-
-var directivesWithCommentsInput = `
-]>
-]>
- --> --> []>
-`
-
-var directivesWithCommentsTokens = []Token{
- CharData("\n"),
- Directive(`DOCTYPE []`),
- CharData("\n"),
- Directive(`DOCTYPE []`),
- CharData("\n"),
- Directive(`DOCTYPE []`),
- CharData("\n"),
-}
-
-func TestDirectivesWithComments(t *testing.T) {
- d := NewDecoder(strings.NewReader(directivesWithCommentsInput))
-
- for i, want := range directivesWithCommentsTokens {
- 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)
- }
- }
-}
-
-// Writer whose Write method always returns an error.
-type errWriter struct{}
-
-func (errWriter) Write(p []byte) (n int, err error) { return 0, fmt.Errorf("unwritable") }
-
-func TestEscapeTextIOErrors(t *testing.T) {
- expectErr := "unwritable"
- err := EscapeText(errWriter{}, []byte{'A'})
-
- if err == nil || err.Error() != expectErr {
- t.Errorf("have %v, want %v", err, expectErr)
- }
-}
-
-func TestEscapeTextInvalidChar(t *testing.T) {
- input := []byte("A \x00 terminated string.")
- expected := "A \uFFFD terminated string."
-
- buff := new(bytes.Buffer)
- if err := EscapeText(buff, input); err != nil {
- t.Fatalf("have %v, want nil", err)
- }
- text := buff.String()
-
- if text != expected {
- t.Errorf("have %v, want %v", text, expected)
- }
-}
-
-func TestIssue5880(t *testing.T) {
- type T []byte
- data, err := Marshal(T{192, 168, 0, 1})
- if err != nil {
- t.Errorf("Marshal error: %v", err)
- }
- if !utf8.Valid(data) {
- t.Errorf("Marshal generated invalid UTF-8: %x", data)
- }
-}