`},
{``, ``},
{`text
text`, `text
text`}, // #122
{`text text`, `text text`}, // #89
{`text text`, `text text`}, // #89
{` a b
`, ` a b
`}, // #82
{``, ``}, // #67
}
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 {
_, err := io.Copy(w, r)
return err
})
m.AddFunc("text/javascript", func(_ *minify.M, w io.Writer, r io.Reader, _ map[string]string) error {
_, err := io.Copy(w, r)
return err
})
for _, tt := range htmlTests {
t.Run(tt.html, func(t *testing.T) {
r := bytes.NewBufferString(tt.html)
w := &bytes.Buffer{}
err := Minify(m, w, r, nil)
test.Minify(t, tt.html, err, w.String(), tt.expected)
})
}
}
func TestHTMLKeepEndTags(t *testing.T) {
htmlTests := []struct {
html string
expected string
}{
{``, ``},
{``, ``},
}
m := minify.New()
htmlMinifier := &Minifier{KeepEndTags: true}
for _, tt := range htmlTests {
t.Run(tt.html, func(t *testing.T) {
r := bytes.NewBufferString(tt.html)
w := &bytes.Buffer{}
err := htmlMinifier.Minify(m, w, r, nil)
test.Minify(t, tt.html, err, w.String(), tt.expected)
})
}
}
func TestHTMLKeepConditionalComments(t *testing.T) {
htmlTests := []struct {
html string
expected string
}{
{``, ``},
{` `, ``},
}
m := minify.New()
htmlMinifier := &Minifier{KeepConditionalComments: true}
for _, tt := range htmlTests {
t.Run(tt.html, func(t *testing.T) {
r := bytes.NewBufferString(tt.html)
w := &bytes.Buffer{}
err := htmlMinifier.Minify(m, w, r, nil)
test.Minify(t, tt.html, err, w.String(), tt.expected)
})
}
}
func TestHTMLKeepWhitespace(t *testing.T) {
htmlTests := []struct {
html string
expected string
}{
{`cats and dogs `, `cats and dogs`},
{` test test
`, ` test test
`},
{`x y`, `x y`},
{`x y`, `x y`},
{"x \ny", "x \ny"},
{`x
y`, `x
y`},
{`x y
`, `x y`},
{`
`, ``}, // spaces before html and at the start of html are dropped
{`
x
y`, `
x
y`},
{`
x y`, `
x y`},
{`a code
b`, `a code
b`},
{`a
b`, `a
b`},
{`a b`, `a b`},
{"text\n\ntext", "text\ntext"},
{"text\ntext text", "text\ntext text"},
{"abc\n\ndef", "abc\ndef"},
{"\n\n", "\n"},
{"", ""},
}
m := minify.New()
htmlMinifier := &Minifier{KeepWhitespace: true}
for _, tt := range htmlTests {
t.Run(tt.html, func(t *testing.T) {
r := bytes.NewBufferString(tt.html)
w := &bytes.Buffer{}
err := htmlMinifier.Minify(m, w, r, nil)
test.Minify(t, tt.html, err, w.String(), tt.expected)
})
}
}
func TestHTMLURL(t *testing.T) {
htmlTests := []struct {
url string
html string
expected string
}{
{`http://example.com/`, `link`, `link`},
{`https://example.com/`, `link`, `link`},
{`http://example.com/`, `link`, `link`},
{`https://example.com/`, `link`, `link`},
{`http://example.com/`, `x`, `x`},
{`http://example.com/`, ``, ``},
{`http://example.com/`, ` `,
``},
{`http://example.com/`, ``, ``},
{`https://example.com/`, ``, ``},
{`http://example.com/`, ``, ``},
{`https://example.com/`, ``, ``},
}
m := minify.New()
m.AddFunc("text/html", Minify)
for _, tt := range htmlTests {
t.Run(tt.url, func(t *testing.T) {
r := bytes.NewBufferString(tt.html)
w := &bytes.Buffer{}
m.URL, _ = url.Parse(tt.url)
err := Minify(m, w, r, nil)
test.Minify(t, tt.html, err, w.String(), tt.expected)
})
}
}
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), "")
_, err = w.Write(b)
return err
})
html := ``
r := bytes.NewBufferString(html)
w := &bytes.Buffer{}
err := Minify(m, w, r, nil)
test.Minify(t, html, err, w.String(), html)
}
func TestReaderErrors(t *testing.T) {
r := test.NewErrorReader(0)
w := &bytes.Buffer{}
m := minify.New()
err := Minify(m, w, r, nil)
test.T(t, err, test.ErrPlain, "return error at first read")
}
func TestWriterErrors(t *testing.T) {
errorTests := []struct {
html string
n []int
}{
{``, []int{0}},
{`text`, []int{0}},
{``, []int{0, 1, 2, 3, 4, 5}},
{``, []int{0}},
{``, []int{2}},
{``, []int{2}},
{`x
`, []int{2}},
{`x
`, []int{2}},
{``, []int{0}},
{``, []int{0}},
{``, []int{0, 1, 2}},
{` text `, []int{0}},
}
m := minify.New()
m.Add("text/html", &Minifier{
KeepConditionalComments: true,
})
for _, tt := range errorTests {
for _, n := range tt.n {
t.Run(fmt.Sprint(tt.html, " ", tt.n), func(t *testing.T) {
r := bytes.NewBufferString(tt.html)
w := test.NewErrorWriter(n)
err := m.Minify("text/html", w, r)
test.T(t, err, test.ErrPlain)
})
}
}
}
func TestMinifyErrors(t *testing.T) {
errorTests := []struct {
html string
err error
}{
{``, test.ErrPlain},
{``, test.ErrPlain},
{``, test.ErrPlain},
{``, test.ErrPlain},
{``, 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
})
m.AddFunc("text/javascript", func(_ *minify.M, w io.Writer, r io.Reader, _ map[string]string) error {
return test.ErrPlain
})
m.AddFunc("image/svg+xml", func(_ *minify.M, w io.Writer, r io.Reader, _ map[string]string) error {
return test.ErrPlain
})
m.AddFunc("application/mathml+xml", func(_ *minify.M, w io.Writer, r io.Reader, _ map[string]string) error {
return test.ErrPlain
})
for _, tt := range errorTests {
t.Run(tt.html, func(t *testing.T) {
r := bytes.NewBufferString(tt.html)
w := &bytes.Buffer{}
err := Minify(m, w, r, nil)
test.T(t, err, tt.err)
})
}
}
////////////////////////////////////////////////////////////////
func ExampleMinify() {
m := minify.New()
m.AddFunc("text/html", Minify)
m.AddFunc("text/css", css.Minify)
m.AddFunc("text/javascript", js.Minify)
m.AddFunc("image/svg+xml", svg.Minify)
m.AddFuncRegexp(regexp.MustCompile("[/+]json$"), json.Minify)
m.AddFuncRegexp(regexp.MustCompile("[/+]xml$"), xml.Minify)
// set URL to minify link locations too
m.URL, _ = url.Parse("https://www.example.com/")
if err := m.Minify("text/html", os.Stdout, os.Stdin); err != nil {
panic(err)
}
}
func ExampleMinify_options() {
m := minify.New()
m.Add("text/html", &Minifier{
KeepDefaultAttrVals: true,
KeepWhitespace: true,
})
if err := m.Minify("text/html", os.Stdout, os.Stdin); err != nil {
panic(err)
}
}
func ExampleMinify_reader() {
b := bytes.NewReader([]byte("Example
"))
m := minify.New()
m.Add("text/html", &Minifier{})
r := m.Reader("text/html", b)
if _, err := io.Copy(os.Stdout, r); err != nil {
panic(err)
}
// Output: Example
}
func ExampleMinify_writer() {
m := minify.New()
m.Add("text/html", &Minifier{})
w := m.Writer("text/html", os.Stdout)
w.Write([]byte("Example
"))
w.Close()
// Output: Example
}