~samwhited/xmpp

157ee5108b7e256898aeaac8c006fbd0f61bf881 — Sam Whited 1 year, 11 months ago 0aa80af
internal/decl: new XML declaration package
6 files changed, 103 insertions(+), 6 deletions(-)

M examples/echobot/go.mod
M examples/echobot/go.sum
M go.mod
M go.sum
A internal/decl/decl.go
A internal/decl/decl_test.go
M examples/echobot/go.mod => examples/echobot/go.mod +1 -1
@@ 4,7 4,7 @@ go 1.13

require (
	mellium.im/sasl v0.2.1
	mellium.im/xmlstream v0.13.6
	mellium.im/xmlstream v0.14.0
	mellium.im/xmpp v0.0.0
)


M examples/echobot/go.sum => examples/echobot/go.sum +2 -2
@@ 17,5 17,5 @@ mellium.im/reader v0.1.0 h1:UUEMev16gdvaxxZC7fC08j7IzuDKh310nB6BlwnxTww=
mellium.im/reader v0.1.0/go.mod h1:F+X5HXpkIfJ9EE1zHQG9lM/hO946iYAmU7xjg5dsQHI=
mellium.im/sasl v0.2.1 h1:nspKSRg7/SyO0cRGY71OkfHab8tf9kCts6a6oTDut0w=
mellium.im/sasl v0.2.1/go.mod h1:ROaEDLQNuf9vjKqE1SrAfnsobm2YKXT1gnN1uDp1PjQ=
mellium.im/xmlstream v0.13.6 h1:8DDGJJItrzecdNkqAUXrTDa4f/RkqxNz/lPbr2Uikz8=
mellium.im/xmlstream v0.13.6/go.mod h1:O7wqreSmFi1LOh4RiK7r2j4H4pYDgzo1qv5ZkYJZ7Ns=
mellium.im/xmlstream v0.14.0 h1:vTljQmcFQq7LEb+LJQV0VI8wnuFnzBy1AnfUbA4SrL8=
mellium.im/xmlstream v0.14.0/go.mod h1:O7wqreSmFi1LOh4RiK7r2j4H4pYDgzo1qv5ZkYJZ7Ns=

M go.mod => go.mod +1 -1
@@ 8,5 8,5 @@ require (
	golang.org/x/net v0.0.0-20190724013045-ca1201d0de80
	golang.org/x/text v0.3.2
	mellium.im/sasl v0.2.1
	mellium.im/xmlstream v0.13.6
	mellium.im/xmlstream v0.14.0
)

M go.sum => go.sum +2 -2
@@ 17,5 17,5 @@ mellium.im/reader v0.1.0 h1:UUEMev16gdvaxxZC7fC08j7IzuDKh310nB6BlwnxTww=
mellium.im/reader v0.1.0/go.mod h1:F+X5HXpkIfJ9EE1zHQG9lM/hO946iYAmU7xjg5dsQHI=
mellium.im/sasl v0.2.1 h1:nspKSRg7/SyO0cRGY71OkfHab8tf9kCts6a6oTDut0w=
mellium.im/sasl v0.2.1/go.mod h1:ROaEDLQNuf9vjKqE1SrAfnsobm2YKXT1gnN1uDp1PjQ=
mellium.im/xmlstream v0.13.6 h1:8DDGJJItrzecdNkqAUXrTDa4f/RkqxNz/lPbr2Uikz8=
mellium.im/xmlstream v0.13.6/go.mod h1:O7wqreSmFi1LOh4RiK7r2j4H4pYDgzo1qv5ZkYJZ7Ns=
mellium.im/xmlstream v0.14.0 h1:vTljQmcFQq7LEb+LJQV0VI8wnuFnzBy1AnfUbA4SrL8=
mellium.im/xmlstream v0.14.0/go.mod h1:O7wqreSmFi1LOh4RiK7r2j4H4pYDgzo1qv5ZkYJZ7Ns=

A internal/decl/decl.go => internal/decl/decl.go +35 -0
@@ 0,0 1,35 @@
// Copyright 2019 The Mellium Contributors.
// Use of this source code is governed by the BSD 2-clause
// license that can be found in the LICENSE file.

// Package decl contains functionality related to XML declarations.
package decl

import (
	"encoding/xml"
)

type skipper struct {
	r       xml.TokenReader
	started bool
}

// Token implements xml.TokenReader for Reader.
func (r *skipper) Token() (xml.Token, error) {
	tok, err := r.r.Token()
	if tok != nil && !r.started {
		r.started = true
		if proc, ok := tok.(xml.ProcInst); ok && proc.Target == "xml" {
			if err != nil {
				return nil, err
			}
			return r.r.Token()
		}
	}
	return tok, err
}

// Skip wraps a token reader and skips any XML declaration.
func Skip(r xml.TokenReader) xml.TokenReader {
	return &skipper{r: r}
}

A internal/decl/decl_test.go => internal/decl/decl_test.go +62 -0
@@ 0,0 1,62 @@
// Copyright 2019 The Mellium Contributors.
// Use of this source code is governed by the BSD 2-clause
// license that can be found in the LICENSE file.

package decl_test

import (
	"bytes"
	"encoding/xml"
	"io"
	"strconv"
	"strings"
	"testing"

	"mellium.im/xmlstream"
	"mellium.im/xmpp/internal/decl"
)

var skipTests = [...]struct {
	in  string
	out string
}{
	0: {},
	1: {in: "<a/>", out: "<a></a>"},
	2: {in: xml.Header + "<a/>", out: "\n<a></a>"},
	3: {in: `<?xml?><a/>`, out: "<a></a>"},
	4: {in: `<?sgml?><a/>`, out: "<?sgml?><a></a>"},
	5: {in: `<?xml?>`},
}

func TestDecl(t *testing.T) {
	for i, tc := range skipTests {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			d := decl.Skip(xml.NewDecoder(strings.NewReader(tc.in)))
			buf := &bytes.Buffer{}
			e := xml.NewEncoder(buf)
			if _, err := xmlstream.Copy(e, d); err != nil {
				t.Fatalf("Error copying tokens: %q", err)
			}
			if err := e.Flush(); err != nil {
				t.Fatalf("Error flushing tokens: %q", err)
			}
			if s := buf.String(); s != tc.out {
				t.Errorf("Output does not match: want=%q, got=%q", tc.out, s)
			}
		})
	}
}

func TestImmediateEOF(t *testing.T) {
	d := decl.Skip(xmlstream.Token(xml.ProcInst{Target: "xml"}))

	for i := 0; i < 2; i++ {
		tok, err := d.Token()
		if err != io.EOF {
			t.Errorf("Expected EOF on %d but got %q", i, err)
		}
		if tok != nil {
			t.Errorf("Did not expect token on %d but got %T %[2]v", i, tok)
		}
	}
}