func TestReader(t *testing.T) { s := []byte("abcde") r := NewReader(s) test.Bytes(t, r.Bytes(), s, "reader must return bytes stored") buf := make([]byte, 3) n, err := r.Read(buf) test.Error(t, err, nil, "error must be nil") test.That(t, n == 3, "first read must read 3 characters") test.Bytes(t, buf, []byte("abc"), "first read must match 'abc'") n, err = r.Read(buf) test.Error(t, err, nil, "error must be nil") test.That(t, n == 2, "second read must read 2 characters") test.Bytes(t, buf[:n], []byte("de"), "second read must match 'de'") n, err = r.Read(buf) test.Error(t, err, io.EOF, "error must be io.EOF") test.That(t, n == 0, "third read must read 0 characters") n, err = r.Read(nil) test.Error(t, err, nil, "error must be nil") test.That(t, n == 0, "read to nil buffer must return 0 characters read") r.Reset() n, err = r.Read(buf) test.Error(t, err, nil, "error must be nil") test.That(t, n == 3, "read after reset must read 3 characters") test.Bytes(t, buf, []byte("abc"), "read after reset must match 'abc'") }
func TestShifter(t *testing.T) { s := `Lorem ipsum dolor sit amet, consectetur adipiscing elit.` var z = NewShifter(bytes.NewBufferString(s)) test.That(t, z.IsEOF(), "buffer must be fully in memory") test.Error(t, z.Err(), nil, "buffer is at EOF but must not return EOF until we reach that") test.That(t, z.Pos() == 0, "buffer must start at position 0") test.That(t, z.Peek(0) == 'L', "first character must be 'L'") test.That(t, z.Peek(1) == 'o', "second character must be 'o'") z.Move(1) test.That(t, z.Peek(0) == 'o', "must be 'o' at position 1") test.That(t, z.Peek(1) == 'r', "must be 'r' at position 1") z.MoveTo(6) test.That(t, z.Peek(0) == 'i', "must be 'i' at position 6") test.That(t, z.Peek(1) == 'p', "must be 'p' at position 7") test.Bytes(t, z.Bytes(), []byte("Lorem "), "buffered string must now read 'Lorem ' when at position 6") test.Bytes(t, z.Shift(), []byte("Lorem "), "shift must return the buffered string") test.That(t, z.Pos() == 0, "after shifting position must be 0") test.That(t, z.Peek(0) == 'i', "must be 'i' at position 0 after shifting") test.That(t, z.Peek(1) == 'p', "must be 'p' at position 1 after shifting") test.Error(t, z.Err(), nil, "error must be nil at this point") z.Move(len(s) - len("Lorem ") - 1) test.Error(t, z.Err(), nil, "error must be nil just before the end of the buffer") z.Skip() test.That(t, z.Pos() == 0, "after skipping position must be 0") z.Move(1) test.Error(t, z.Err(), io.EOF, "error must be EOF when past the buffer") z.Move(-1) test.Error(t, z.Err(), nil, "error must be nil just before the end of the buffer, even when it has been past the buffer") }
func TestAdd(t *testing.T) { mAdd := New() r := bytes.NewBufferString("test") w := &bytes.Buffer{} mAdd.Add("dummy/err", &DummyMinifier{}) test.Error(t, mAdd.Minify("dummy/err", nil, nil), errDummy) mAdd.AddRegexp(regexp.MustCompile("err1$"), &DummyMinifier{}) test.Error(t, mAdd.Minify("dummy/err1", nil, nil), errDummy) mAdd.AddFunc("dummy/err", func(m *M, w io.Writer, r io.Reader, _ map[string]string) error { return errDummy }) test.Error(t, mAdd.Minify("dummy/err", nil, nil), errDummy) mAdd.AddFuncRegexp(regexp.MustCompile("err2$"), func(m *M, w io.Writer, r io.Reader, _ map[string]string) error { return errDummy }) test.Error(t, mAdd.Minify("dummy/err2", nil, nil), errDummy) mAdd.AddCmd("dummy/copy", helperCommand(t, "dummy/copy")) mAdd.AddCmd("dummy/err", helperCommand(t, "dummy/err")) mAdd.AddCmdRegexp(regexp.MustCompile("err6$"), helperCommand(t, "werr6")) test.Error(t, mAdd.Minify("dummy/copy", w, r), nil) test.String(t, w.String(), "test", "dummy/copy command returns input") test.String(t, mAdd.Minify("dummy/err", w, r).Error(), "exit status 1", "command returns status 1 for dummy/err") test.String(t, mAdd.Minify("werr6", w, r).Error(), "exit status 2", "command returns status 2 when minifier doesn't exist") test.String(t, mAdd.Minify("stderr6", w, r).Error(), "exit status 2", "command returns status 2 when minifier doesn't exist") }
func TestWriterErrors(t *testing.T) { errorTests := []struct { css string n []int }{ {`@import 'file'`, []int{0, 2}}, {`@media all{}`, []int{0, 2, 3, 4}}, {`a[id^="L"]{margin:2in!important;color:red}`, []int{0, 4, 6, 7, 8, 9, 10, 11}}, {`a{color:rgb(255,0,0)}`, []int{4}}, {`a{color:rgb(255,255,255)}`, []int{4}}, {`a{color:hsl(0,100%,50%)}`, []int{4}}, {`a{color:hsl(360,100%,100%)}`, []int{4}}, {`a{color:f(arg)}`, []int{4}}, {`<!--`, []int{0}}, {`/*!comment*/`, []int{0, 1, 2}}, } m := minify.New() for _, tt := range errorTests { for _, n := range tt.n { r := bytes.NewBufferString(tt.css) w := test.NewErrorWriter(n) test.Error(t, Minify(m, w, r, nil), test.ErrPlain, "return error at write", n, "in", tt.css) } } }
func TestWriterErrors(t *testing.T) { errorTests := []struct { svg string n []int }{ {`<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "foo.dtd" [ <!ENTITY x "bar"> ]>`, []int{0}}, {`abc`, []int{0}}, {`<style>abc</style>`, []int{2}}, {`<![CDATA[ <<<< ]]>`, []int{0}}, {`<![CDATA[ <<<<< ]]>`, []int{0}}, {`<path d="x"/>`, []int{0, 1, 2, 3, 4, 5}}, {`<path></path>`, []int{1}}, {`<svg>x</svg>`, []int{1, 3}}, {`<svg>x</svg >`, []int{3}}, } m := minify.New() for _, tt := range errorTests { for _, n := range tt.n { r := bytes.NewBufferString(tt.svg) w := test.NewErrorWriter(n) test.Error(t, Minify(m, w, r, nil), test.ErrPlain, "return error at write", n, "in", tt.svg) } } }
func TestReader(t *testing.T) { m := New() m.AddFunc("dummy/dummy", func(m *M, w io.Writer, r io.Reader, _ map[string]string) error { _, err := io.Copy(w, r) return err }) m.AddFunc("dummy/err", func(m *M, w io.Writer, r io.Reader, _ map[string]string) error { return errDummy }) w := &bytes.Buffer{} r := bytes.NewBufferString("test") mr := m.Reader("dummy/dummy", r) _, err := io.Copy(w, mr) test.Error(t, err, nil) test.String(t, w.String(), "test", "equal input after dummy minify reader") mr = m.Reader("dummy/err", r) _, err = io.Copy(w, mr) test.Error(t, err, errDummy) }
func TestWriter(t *testing.T) { m := New() m.AddFunc("dummy/dummy", func(m *M, w io.Writer, r io.Reader, _ map[string]string) error { _, err := io.Copy(w, r) return err }) m.AddFunc("dummy/err", func(m *M, w io.Writer, r io.Reader, _ map[string]string) error { return errDummy }) m.AddFunc("dummy/late-err", func(m *M, w io.Writer, r io.Reader, _ map[string]string) error { _, _ = ioutil.ReadAll(r) return errDummy }) var err error w := &bytes.Buffer{} mw := m.Writer("dummy/dummy", w) _, err = mw.Write([]byte("test")) test.Error(t, err, nil) test.Error(t, mw.Close(), nil) test.String(t, w.String(), "test", "equal input after dummy minify writer") mw = m.Writer("dummy/err", w) _, err = mw.Write([]byte("test")) test.Error(t, err, errDummy) test.Error(t, mw.Close(), errDummy) mw = m.Writer("dummy/late-err", w) _, err = mw.Write([]byte("test")) test.Error(t, err, nil) test.Error(t, mw.Close(), errDummy) }
func TestSpecialTagClosing(t *testing.T) { m := minify.New() m.AddFunc("text/html", Minify) m.AddFunc("text/css", func(_ *minify.M, w io.Writer, r io.Reader, _ map[string]string) error { b, err := ioutil.ReadAll(r) test.Error(t, err, nil) test.String(t, string(b), "</script>") _, err = w.Write(b) return err }) html := `<style></script></style>` r := bytes.NewBufferString(html) w := &bytes.Buffer{} test.Minify(t, html, Minify(m, w, r, nil), w.String(), html) }
func TestWriterErrors(t *testing.T) { errorTests := []struct { json string n []int }{ //01 234 56 78 {`{"key":[100,200]}`, []int{0, 1, 2, 3, 4, 5, 7, 8}}, } m := minify.New() for _, tt := range errorTests { for _, n := range tt.n { r := bytes.NewBufferString(tt.json) w := test.NewErrorWriter(n) test.Error(t, Minify(m, w, r, nil), test.ErrPlain, "return error at write", n, "in", tt.json) } } }
func TestWriterErrors(t *testing.T) { errorTests := []struct { js string n []int }{ //01 2345 {"a\n{5 5", []int{0, 1, 4}}, {`/*!comment*/`, []int{0, 1, 2}}, } m := minify.New() for _, tt := range errorTests { for _, n := range tt.n { r := bytes.NewBufferString(tt.js) w := test.NewErrorWriter(n) test.Error(t, Minify(m, w, r, nil), test.ErrPlain, "return error at write", n, "in", tt.js) } } }
func TestMinifyErrors(t *testing.T) { errorTests := []struct { svg string err error }{ {`<style>abc</style>`, test.ErrPlain}, {`<style><![CDATA[abc]]></style>`, test.ErrPlain}, {`<path style="abc"/>`, test.ErrPlain}, } m := minify.New() m.AddFunc("text/css", func(_ *minify.M, w io.Writer, r io.Reader, _ map[string]string) error { return test.ErrPlain }) for _, tt := range errorTests { r := bytes.NewBufferString(tt.svg) w := &bytes.Buffer{} test.Error(t, Minify(m, w, r, nil), tt.err, "return error", tt.err, "in", tt.svg) } }
func TestParseDataURI(t *testing.T) { var dataURITests = []struct { dataURI string expectedMimetype string expectedData string expectedErr error }{ {"www.domain.com", "", "", ErrBadDataURI}, {"data:,", "text/plain", "", nil}, {"data:text/xml,", "text/xml", "", nil}, {"data:,text", "text/plain", "text", nil}, {"data:;base64,dGV4dA==", "text/plain", "text", nil}, {"data:image/svg+xml,", "image/svg+xml", "", nil}, {"data:;base64,()", "", "", base64.CorruptInputError(0)}, } for _, tt := range dataURITests { mimetype, data, err := DataURI([]byte(tt.dataURI)) test.Bytes(t, mimetype, []byte(tt.expectedMimetype), "mimetype") test.Bytes(t, data, []byte(tt.expectedData), "data") test.Error(t, err, tt.expectedErr) } }
func TestMinify(t *testing.T) { test.Error(t, m.Minify("?", nil, nil), ErrNotExist, "minifier doesn't exist") test.Error(t, m.Minify("dummy/nil", nil, nil), nil) test.Error(t, m.Minify("dummy/err", nil, nil), errDummy) b := []byte("test") out, err := m.Bytes("dummy/nil", b) test.Error(t, err, nil) test.Bytes(t, out, []byte{}, "dummy/nil returns empty byte slice") out, err = m.Bytes("?", b) test.Error(t, err, ErrNotExist, "minifier doesn't exist") test.Bytes(t, out, b, "return input when minifier doesn't exist") s := "test" out2, err := m.String("dummy/nil", s) test.Error(t, err, nil) test.String(t, out2, "", "dummy/nil returns empty string") out2, err = m.String("?", s) test.Error(t, err, ErrNotExist, "minifier doesn't exist") test.String(t, out2, s, "return input when minifier doesn't exist") }
func TestWriterErrors(t *testing.T) { errorTests := []struct { html string n []int }{ {`<!doctype>`, []int{0}}, {`text`, []int{0}}, {`<foo attr=val>`, []int{0, 1, 2, 3, 4, 5}}, {`</foo>`, []int{0}}, {`<style>css</style>`, []int{2}}, {`<code>x</code>`, []int{2}}, {`<!--[if comment-->`, []int{0}}, } m := minify.New() for _, tt := range errorTests { for _, n := range tt.n { r := bytes.NewBufferString(tt.html) w := test.NewErrorWriter(n) test.Error(t, Minify(m, w, r, nil), test.ErrPlain, "return error at write", n, "in", tt.html) } } }
func TestWriterErrors(t *testing.T) { errorTests := []struct { xml string n []int }{ {`<!DOCTYPE foo>`, []int{0}}, {`<?xml?>`, []int{0, 1}}, {`<a x=y z="val">`, []int{0, 1, 2, 3, 4, 8, 9}}, {`<foo/>`, []int{1}}, {`</foo>`, []int{0}}, {`<foo></foo>`, []int{1}}, {`<![CDATA[data<<<<<]]>`, []int{0}}, {`text`, []int{0}}, } m := minify.New() for _, tt := range errorTests { for _, n := range tt.n { r := bytes.NewBufferString(tt.xml) w := test.NewErrorWriter(n) test.Error(t, Minify(m, w, r, nil), test.ErrPlain, "return error at write", n, "in", tt.xml) } } }
func TestReaderErrors(t *testing.T) { m := minify.New() r := test.NewErrorReader(0) w := &bytes.Buffer{} test.Error(t, Minify(m, w, r, nil), test.ErrPlain, "return error at first read") }
func TestLexerEmptyReader(t *testing.T) { z := NewLexer(test.NewEmptyReader()) test.That(t, z.Peek(0) == 0, "first character must yield error") test.Error(t, z.Err(), io.EOF, "error must be EOF") test.That(t, z.Peek(0) == 0, "second peek must also yield error") }