diff options
| -rw-r--r-- | generator.go | 14 | ||||
| -rw-r--r-- | generator_test.go | 166 | ||||
| -rw-r--r-- | go.mod | 7 | ||||
| -rw-r--r-- | go.sum | 2 |
4 files changed, 150 insertions, 39 deletions
diff --git a/generator.go b/generator.go index 881ce45..d80bfb1 100644 --- a/generator.go +++ b/generator.go @@ -3,6 +3,7 @@ package bechars import ( "fmt" "strings" + "unicode" "src.userspace.com.au/lexer" ) @@ -22,6 +23,7 @@ type Generator struct { tok *lexer.Token maxRune *rune minRune *rune + graphic bool } // Option functions allows configuration of the generator. @@ -54,6 +56,14 @@ func MinRune(r rune) Option { } } +// OnlyGraphic filters non-visible characters +func OnlyGraphic(b bool) Option { + return func(g *Generator) error { + g.graphic = b + return nil + } +} + func ensureRangeLimits(g *Generator) { if g.maxRune == nil { maxRune := '\u007F' @@ -197,6 +207,10 @@ func (g *Generator) filter(in, exclude string) string { if strings.ContainsRune(exclude, r) { continue } + if g.graphic && !unicode.IsGraphic(r) { + fmt.Println("non-graphic", r) + continue + } out.WriteRune(r) } return out.String() diff --git a/generator_test.go b/generator_test.go index afbee71..6ac4423 100644 --- a/generator_test.go +++ b/generator_test.go @@ -2,59 +2,151 @@ package bechars import ( "testing" + + "github.com/google/go-cmp/cmp" ) func TestGenerator(t *testing.T) { tests := []struct { in string expected string + options []Option }{ - {"[abc]", "abc"}, + { + in: "[abc]", + expected: "abc", + }, // First characters - {"[]", ""}, - {"[-]", "-"}, - {"[]abc]", "]abc"}, + {in: "[]", expected: ""}, + {in: "[-]", expected: "-"}, + {in: "[]abc]", expected: "]abc"}, // Character - {"[\u0e010-2]", "ก012"}, + {in: "[\u0e010-2]", + expected: "ก012", + }, + // Unicode + {in: "[ก0-2]", + expected: "ก012", + }, // Not - {"[^:cntrl::punct:]", " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"}, - {"[^-:cntrl::digit:]", " !\"#$%&'()*+,./:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"}, - {"[^]:cntrl::digit:]", " !\"#$%&'()*+,-./:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\^_`abcdefghijklmnopqrstuvwxyz{|}~"}, + { + in: "[^:cntrl::punct:]", + expected: " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", + }, + { + in: "[^-:cntrl::digit:]", + expected: " !\"#$%&'()*+,./:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", + }, + { + in: "[^]:cntrl::digit:]", + expected: " !\"#$%&'()*+,-./:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\^_`abcdefghijklmnopqrstuvwxyz{|}~", + }, // Classes - {"[:alnum:]", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"}, - {"[:alpha:]", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"}, - {"[:digit:]", "0123456789"}, - {"[:space:]", " \t\n\r\f\v"}, - {"[:blank:]", " \t"}, - {"[:word:]", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_"}, - {"[:cntrl:]", "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\u007f"}, - {"[:lower:]", "abcdefghijklmnopqrstuvwxyz"}, - {"[:upper:]", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"}, - {"[:digit::upper:]", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"}, - {"[:print:]", " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"}, - {"[:graph:]", " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"}, - {"[:punct:]", "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~]"}, - {"[:xdigit:]", "abcdefABCDEF0123456789"}, - {"[:digit::punct::upper:]", "0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~]ABCDEFGHIJKLMNOPQRSTUVWXYZ"}, + { + in: "[:alnum:]", + expected: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", + }, + { + in: "[:alpha:]", + expected: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", + }, + { + in: "[:digit:]", + expected: "0123456789", + }, + { + in: "[:space:]", + expected: " \t\n\r\f\v", + }, + { + in: "[:blank:]", + expected: " \t", + }, + { + in: "[:word:]", + expected: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_", + }, + { + in: "[:cntrl:]", + expected: "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\u007f", + }, + { + in: "[:lower:]", + expected: "abcdefghijklmnopqrstuvwxyz", + }, + { + in: "[:upper:]", + expected: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", + }, + { + in: "[:digit::upper:]", + expected: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", + }, + { + in: "[:print:]", + expected: " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", + }, + { + in: "[:graph:]", + expected: " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", + }, + { + in: "[:punct:]", + expected: "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~]", + }, + { + in: "[:xdigit:]", + expected: "abcdefABCDEF0123456789", + }, + { + in: "[:digit::punct::upper:]", + expected: "0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~]ABCDEFGHIJKLMNOPQRSTUVWXYZ", + }, // Ranges - {"[a-d]", "abcd"}, - {"[\x20-\x7E]", " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"}, + { + in: "[a-d]", + expected: "abcd", + }, + { + in: "[\x20-\x7E]", + expected: " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", + }, // Swapped - {"[\x7E-\x20]", " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"}, + { + in: "[\x7E-\x20]", + expected: " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", + }, + // MaxRune + { + in: "[ก-ฎ]", + expected: "กขฃคฅฆงจฉชซฌญฎ", + options: []Option{MaxRune('\uffff')}, + }, + // // Exclude graphic + // { + // in: "[฿-ๆ็่้๊๋์]", + // expected: "฿เแโใไๅๆ็่้๊๋์", + // options: []Option{MaxRune('\uffff'), OnlyGraphic(true)}, + // }, } for _, tt := range tests { - p, err := New() - if err != nil { - t.Fatalf("New failed with %q", err) - } - actual, err := p.Generate(tt.in) - if err != nil { - t.Errorf("%s => failed with %q", tt.in, err) - } - if actual != tt.expected { - t.Errorf("%s => expected %q, got %q", tt.in, tt.expected, actual) - } + t.Run(tt.in, func(t *testing.T) { + p, err := New(tt.options...) + if err != nil { + t.Fatal(err) + } + actual, err := p.Generate(tt.in) + if err != nil { + t.Fatal(err) + } + if diff := cmp.Diff(actual, tt.expected); diff != "" { + t.Error(diff) + } + if actual != tt.expected { + t.Errorf("got %v, want %v", actual, tt.expected) + } + }) } } @@ -1,5 +1,8 @@ -module src.userspace.com.au/bechars +module userspace.com.au/bechars go 1.12 -require src.userspace.com.au/lexer v0.1.0 +require ( + github.com/google/go-cmp v0.5.9 + src.userspace.com.au/lexer v0.1.0 +) @@ -1,2 +1,4 @@ +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= src.userspace.com.au/lexer v0.1.0 h1:P3xZSajmBenEHdCCRbIzoTxJ/wzMHkvkI1MApEV9Er8= src.userspace.com.au/lexer v0.1.0/go.mod h1:3+mMAyDcck3nia3wTA8cmTYE5So14MNLguYfSxgYneM= |
