mirror of
https://github.com/miniflux/v2.git
synced 2025-07-02 16:38:37 +00:00
First commit
This commit is contained in:
commit
8ffb773f43
2121 changed files with 1118910 additions and 0 deletions
248
vendor/github.com/tdewolff/parse/css/parse_test.go
generated
vendored
Normal file
248
vendor/github.com/tdewolff/parse/css/parse_test.go
generated
vendored
Normal file
|
@ -0,0 +1,248 @@
|
|||
package css // import "github.com/tdewolff/parse/css"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/tdewolff/parse"
|
||||
"github.com/tdewolff/test"
|
||||
)
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
var parseTests = []struct {
|
||||
inline bool
|
||||
css string
|
||||
expected string
|
||||
}{
|
||||
{true, " x : y ; ", "x:y;"},
|
||||
{true, "color: red;", "color:red;"},
|
||||
{true, "color : red;", "color:red;"},
|
||||
{true, "color: red; border: 0;", "color:red;border:0;"},
|
||||
{true, "color: red !important;", "color:red!important;"},
|
||||
{true, "color: red ! important;", "color:red!important;"},
|
||||
{true, "white-space: -moz-pre-wrap;", "white-space:-moz-pre-wrap;"},
|
||||
{true, "display: -moz-inline-stack;", "display:-moz-inline-stack;"},
|
||||
{true, "x: 10px / 1em;", "x:10px/1em;"},
|
||||
{true, "x: 1em/1.5em \"Times New Roman\", Times, serif;", "x:1em/1.5em \"Times New Roman\",Times,serif;"},
|
||||
{true, "x: hsla(100,50%, 75%, 0.5);", "x:hsla(100,50%,75%,0.5);"},
|
||||
{true, "x: hsl(100,50%, 75%);", "x:hsl(100,50%,75%);"},
|
||||
{true, "x: rgba(255, 238 , 221, 0.3);", "x:rgba(255,238,221,0.3);"},
|
||||
{true, "x: 50vmax;", "x:50vmax;"},
|
||||
{true, "color: linear-gradient(to right, black, white);", "color:linear-gradient(to right,black,white);"},
|
||||
{true, "color: calc(100%/2 - 1em);", "color:calc(100%/2 - 1em);"},
|
||||
{true, "color: calc(100%/2--1em);", "color:calc(100%/2--1em);"},
|
||||
{false, "<!-- @charset; -->", "<!--@charset;-->"},
|
||||
{false, "@media print, screen { }", "@media print,screen{}"},
|
||||
{false, "@media { @viewport ; }", "@media{@viewport;}"},
|
||||
{false, "@keyframes 'diagonal-slide' { from { left: 0; top: 0; } to { left: 100px; top: 100px; } }", "@keyframes 'diagonal-slide'{from{left:0;top:0;}to{left:100px;top:100px;}}"},
|
||||
{false, "@keyframes movingbox{0%{left:90%;}50%{left:10%;}100%{left:90%;}}", "@keyframes movingbox{0%{left:90%;}50%{left:10%;}100%{left:90%;}}"},
|
||||
{false, ".foo { color: #fff;}", ".foo{color:#fff;}"},
|
||||
{false, ".foo { ; _color: #fff;}", ".foo{_color:#fff;}"},
|
||||
{false, "a { color: red; border: 0; }", "a{color:red;border:0;}"},
|
||||
{false, "a { color: red; border: 0; } b { padding: 0; }", "a{color:red;border:0;}b{padding:0;}"},
|
||||
{false, "/* comment */", "/* comment */"},
|
||||
|
||||
// extraordinary
|
||||
{true, "color: red;;", "color:red;"},
|
||||
{true, "color:#c0c0c0", "color:#c0c0c0;"},
|
||||
{true, "background:URL(x.png);", "background:URL(x.png);"},
|
||||
{true, "filter: progid : DXImageTransform.Microsoft.BasicImage(rotation=1);", "filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);"},
|
||||
{true, "/*a*/\n/*c*/\nkey: value;", "key:value;"},
|
||||
{true, "@-moz-charset;", "@-moz-charset;"},
|
||||
{true, "--custom-variable: (0;) ;", "--custom-variable: (0;) ;"},
|
||||
{false, "@import;@import;", "@import;@import;"},
|
||||
{false, ".a .b#c, .d<.e { x:y; }", ".a .b#c,.d<.e{x:y;}"},
|
||||
{false, ".a[b~=c]d { x:y; }", ".a[b~=c]d{x:y;}"},
|
||||
// {false, "{x:y;}", "{x:y;}"},
|
||||
{false, "a{}", "a{}"},
|
||||
{false, "a,.b/*comment*/ {x:y;}", "a,.b{x:y;}"},
|
||||
{false, "a,.b/*comment*/.c {x:y;}", "a,.b.c{x:y;}"},
|
||||
{false, "a{x:; z:q;}", "a{x:;z:q;}"},
|
||||
{false, "@font-face { x:y; }", "@font-face{x:y;}"},
|
||||
{false, "a:not([controls]){x:y;}", "a:not([controls]){x:y;}"},
|
||||
{false, "@document regexp('https:.*') { p { color: red; } }", "@document regexp('https:.*'){p{color:red;}}"},
|
||||
{false, "@media all and ( max-width:400px ) { }", "@media all and (max-width:400px){}"},
|
||||
{false, "@media (max-width:400px) { }", "@media(max-width:400px){}"},
|
||||
{false, "@media (max-width:400px)", "@media(max-width:400px);"},
|
||||
{false, "@font-face { ; font:x; }", "@font-face{font:x;}"},
|
||||
{false, "@-moz-font-face { ; font:x; }", "@-moz-font-face{font:x;}"},
|
||||
{false, "@unknown abc { {} lala }", "@unknown abc{{}lala}"},
|
||||
{false, "a[x={}]{x:y;}", "a[x={}]{x:y;}"},
|
||||
{false, "a[x=,]{x:y;}", "a[x=,]{x:y;}"},
|
||||
{false, "a[x=+]{x:y;}", "a[x=+]{x:y;}"},
|
||||
{false, ".cla .ss > #id { x:y; }", ".cla .ss>#id{x:y;}"},
|
||||
{false, ".cla /*a*/ /*b*/ .ss{}", ".cla .ss{}"},
|
||||
{false, "a{x:f(a(),b);}", "a{x:f(a(),b);}"},
|
||||
{false, "a{x:y!z;}", "a{x:y!z;}"},
|
||||
{false, "[class*=\"column\"]+[class*=\"column\"]:last-child{a:b;}", "[class*=\"column\"]+[class*=\"column\"]:last-child{a:b;}"},
|
||||
{false, "@media { @viewport }", "@media{@viewport;}"},
|
||||
{false, "table { @unknown }", "table{@unknown;}"},
|
||||
|
||||
// early endings
|
||||
{false, "selector{", "selector{"},
|
||||
{false, "@media{selector{", "@media{selector{"},
|
||||
|
||||
// bad grammar
|
||||
{true, "~color:red", "~color:red;"},
|
||||
{false, ".foo { *color: #fff;}", ".foo{*color:#fff;}"},
|
||||
{true, "*color: red; font-size: 12pt;", "*color:red;font-size:12pt;"},
|
||||
{true, "_color: red; font-size: 12pt;", "_color:red;font-size:12pt;"},
|
||||
|
||||
// issues
|
||||
{false, "@media print {.class{width:5px;}}", "@media print{.class{width:5px;}}"}, // #6
|
||||
{false, ".class{width:calc((50% + 2em)/2 + 14px);}", ".class{width:calc((50% + 2em)/2 + 14px);}"}, // #7
|
||||
{false, ".class [c=y]{}", ".class [c=y]{}"}, // tdewolff/minify#16
|
||||
{false, "table{font-family:Verdana}", "table{font-family:Verdana;}"}, // tdewolff/minify#22
|
||||
|
||||
// go-fuzz
|
||||
{false, "@-webkit-", "@-webkit-;"},
|
||||
}
|
||||
for _, tt := range parseTests {
|
||||
t.Run(tt.css, func(t *testing.T) {
|
||||
output := ""
|
||||
p := NewParser(bytes.NewBufferString(tt.css), tt.inline)
|
||||
for {
|
||||
grammar, _, data := p.Next()
|
||||
data = parse.Copy(data)
|
||||
if grammar == ErrorGrammar {
|
||||
if err := p.Err(); err != io.EOF {
|
||||
for _, val := range p.Values() {
|
||||
data = append(data, val.Data...)
|
||||
}
|
||||
if perr, ok := err.(*parse.Error); ok && perr.Message == "unexpected token in declaration" {
|
||||
data = append(data, ";"...)
|
||||
}
|
||||
} else {
|
||||
test.T(t, err, io.EOF)
|
||||
break
|
||||
}
|
||||
} else if grammar == AtRuleGrammar || grammar == BeginAtRuleGrammar || grammar == QualifiedRuleGrammar || grammar == BeginRulesetGrammar || grammar == DeclarationGrammar || grammar == CustomPropertyGrammar {
|
||||
if grammar == DeclarationGrammar || grammar == CustomPropertyGrammar {
|
||||
data = append(data, ":"...)
|
||||
}
|
||||
for _, val := range p.Values() {
|
||||
data = append(data, val.Data...)
|
||||
}
|
||||
if grammar == BeginAtRuleGrammar || grammar == BeginRulesetGrammar {
|
||||
data = append(data, "{"...)
|
||||
} else if grammar == AtRuleGrammar || grammar == DeclarationGrammar || grammar == CustomPropertyGrammar {
|
||||
data = append(data, ";"...)
|
||||
} else if grammar == QualifiedRuleGrammar {
|
||||
data = append(data, ","...)
|
||||
}
|
||||
}
|
||||
output += string(data)
|
||||
}
|
||||
test.String(t, output, tt.expected)
|
||||
})
|
||||
}
|
||||
|
||||
test.T(t, ErrorGrammar.String(), "Error")
|
||||
test.T(t, AtRuleGrammar.String(), "AtRule")
|
||||
test.T(t, BeginAtRuleGrammar.String(), "BeginAtRule")
|
||||
test.T(t, EndAtRuleGrammar.String(), "EndAtRule")
|
||||
test.T(t, BeginRulesetGrammar.String(), "BeginRuleset")
|
||||
test.T(t, EndRulesetGrammar.String(), "EndRuleset")
|
||||
test.T(t, DeclarationGrammar.String(), "Declaration")
|
||||
test.T(t, TokenGrammar.String(), "Token")
|
||||
test.T(t, CommentGrammar.String(), "Comment")
|
||||
test.T(t, CustomPropertyGrammar.String(), "CustomProperty")
|
||||
test.T(t, GrammarType(100).String(), "Invalid(100)")
|
||||
}
|
||||
|
||||
func TestParseError(t *testing.T) {
|
||||
var parseErrorTests = []struct {
|
||||
inline bool
|
||||
css string
|
||||
col int
|
||||
}{
|
||||
{false, "selector", 9},
|
||||
{true, "color 0", 8},
|
||||
{true, "--color 0", 10},
|
||||
{true, "--custom-variable:0", 0},
|
||||
}
|
||||
for _, tt := range parseErrorTests {
|
||||
t.Run(tt.css, func(t *testing.T) {
|
||||
p := NewParser(bytes.NewBufferString(tt.css), tt.inline)
|
||||
for {
|
||||
grammar, _, _ := p.Next()
|
||||
if grammar == ErrorGrammar {
|
||||
if tt.col == 0 {
|
||||
test.T(t, p.Err(), io.EOF)
|
||||
} else if perr, ok := p.Err().(*parse.Error); ok {
|
||||
test.T(t, perr.Col, tt.col)
|
||||
} else {
|
||||
test.Fail(t, "bad error:", p.Err())
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReader(t *testing.T) {
|
||||
input := "x:a;"
|
||||
p := NewParser(test.NewPlainReader(bytes.NewBufferString(input)), true)
|
||||
for {
|
||||
grammar, _, _ := p.Next()
|
||||
if grammar == ErrorGrammar {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
type Obj struct{}
|
||||
|
||||
func (*Obj) F() {}
|
||||
|
||||
var f1 func(*Obj)
|
||||
|
||||
func BenchmarkFuncPtr(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
f1 = (*Obj).F
|
||||
}
|
||||
}
|
||||
|
||||
var f2 func()
|
||||
|
||||
func BenchmarkMemFuncPtr(b *testing.B) {
|
||||
obj := &Obj{}
|
||||
for i := 0; i < b.N; i++ {
|
||||
f2 = obj.F
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleNewParser() {
|
||||
p := NewParser(bytes.NewBufferString("color: red;"), true) // false because this is the content of an inline style attribute
|
||||
out := ""
|
||||
for {
|
||||
gt, _, data := p.Next()
|
||||
if gt == ErrorGrammar {
|
||||
break
|
||||
} else if gt == AtRuleGrammar || gt == BeginAtRuleGrammar || gt == BeginRulesetGrammar || gt == DeclarationGrammar {
|
||||
out += string(data)
|
||||
if gt == DeclarationGrammar {
|
||||
out += ":"
|
||||
}
|
||||
for _, val := range p.Values() {
|
||||
out += string(val.Data)
|
||||
}
|
||||
if gt == BeginAtRuleGrammar || gt == BeginRulesetGrammar {
|
||||
out += "{"
|
||||
} else if gt == AtRuleGrammar || gt == DeclarationGrammar {
|
||||
out += ";"
|
||||
}
|
||||
} else {
|
||||
out += string(data)
|
||||
}
|
||||
}
|
||||
fmt.Println(out)
|
||||
// Output: color:red;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue