mirror of https://github.com/dmarkham/enumer.git
Remove autotrimprefix option; add basic tests for -trimprefix.
This commit is contained in:
parent
e1f9d08449
commit
bd9938fa86
|
@ -104,7 +104,7 @@ the JSON related methods will be generated. Similarly if the yaml flag is set to
|
|||
the YAML related methods will be generated. And if the sql flag is set to true, the Scanner and Valuer interface will
|
||||
be implemented to seamlessly use the enum in a database model.
|
||||
|
||||
For enum string representation transformation the `transform`, `trimprefix` and `autotrimprefix` flags
|
||||
For enum string representation transformation the `transform` and `trimprefix` flags
|
||||
were added (i.e. `enumer -type=MyType -json -transform=snake`).
|
||||
Possible transform values are `snake` and `kebab` for transformation to snake_case and kebab-case accordingly.
|
||||
The default value for `transform` flag is `noop` which means no transformation will be performed.
|
||||
|
@ -112,8 +112,6 @@ The default value for `transform` flag is `noop` which means no transformation w
|
|||
If a prefix is provided via the `trimprefix` flag that will be trimmed from the start of each name (before
|
||||
it is transformed). If a name doesn't have the prefix it will be passed unchanged.
|
||||
|
||||
If the `autotrimprefix` flag is set then if all the names in an enum have a common prefix that prefix will be removed.
|
||||
|
||||
## Inspiring projects
|
||||
* [Stringer](https://godoc.org/golang.org/x/tools/cmd/stringer)
|
||||
* [jsonenums](https://github.com/campoy/jsonenums)
|
||||
|
|
|
@ -46,6 +46,10 @@ var goldenJSONAndSQL = []Golden{
|
|||
{"prime", prime_json_and_sql_in, prime_json_and_sql_out},
|
||||
}
|
||||
|
||||
var goldenPrefix = []Golden{
|
||||
{"prefix", prefix_in, day_out},
|
||||
}
|
||||
|
||||
// Each example starts with "type XXX [u]int", with a single space separating them.
|
||||
|
||||
// Simple test: enumeration of type int starting at 0.
|
||||
|
@ -751,25 +755,40 @@ func (i *Prime) Scan(value interface{}) error {
|
|||
}
|
||||
`
|
||||
|
||||
const prefix_in = `type Day int
|
||||
const (
|
||||
DayMonday Day = iota
|
||||
DayTuesday
|
||||
DayWednesday
|
||||
DayThursday
|
||||
DayFriday
|
||||
DaySaturday
|
||||
DaySunday
|
||||
)
|
||||
`
|
||||
|
||||
func TestGolden(t *testing.T) {
|
||||
for _, test := range golden {
|
||||
runGoldenTest(t, test, false, false, false)
|
||||
runGoldenTest(t, test, false, false, false, "")
|
||||
}
|
||||
for _, test := range goldenJSON {
|
||||
runGoldenTest(t, test, true, false, false)
|
||||
runGoldenTest(t, test, true, false, false, "")
|
||||
}
|
||||
for _, test := range goldenYAML {
|
||||
runGoldenTest(t, test, false, true, false)
|
||||
runGoldenTest(t, test, false, true, false, "")
|
||||
}
|
||||
for _, test := range goldenSQL {
|
||||
runGoldenTest(t, test, false, false, true)
|
||||
runGoldenTest(t, test, false, false, true, "")
|
||||
}
|
||||
for _, test := range goldenJSONAndSQL {
|
||||
runGoldenTest(t, test, true, false, true)
|
||||
runGoldenTest(t, test, true, false, true, "")
|
||||
}
|
||||
for _, test := range goldenPrefix {
|
||||
runGoldenTest(t, test, false, false, false, "Day")
|
||||
}
|
||||
}
|
||||
|
||||
func runGoldenTest(t *testing.T, test Golden, generateJSON, generateYAML, generateSQL bool) {
|
||||
func runGoldenTest(t *testing.T, test Golden, generateJSON, generateYAML, generateSQL bool, prefix string) {
|
||||
var g Generator
|
||||
input := "package test\n" + test.input
|
||||
file := test.name + ".go"
|
||||
|
@ -779,7 +798,7 @@ func runGoldenTest(t *testing.T, test Golden, generateJSON, generateYAML, genera
|
|||
if len(tokens) != 3 {
|
||||
t.Fatalf("%s: need type declaration on first line", test.name)
|
||||
}
|
||||
g.generate(tokens[1], generateJSON, generateYAML, generateSQL, "noop")
|
||||
g.generate(tokens[1], generateJSON, generateYAML, generateSQL, "noop", prefix)
|
||||
got := string(g.format())
|
||||
if got != test.output {
|
||||
t.Errorf("%s: got\n====\n%s====\nexpected\n====%s", test.name, got, test.output)
|
||||
|
|
16
stringer.go
16
stringer.go
|
@ -94,7 +94,6 @@ var (
|
|||
output = flag.String("output", "", "output file name; default srcdir/<type>_string.go")
|
||||
transformMethod = flag.String("transform", "noop", "enum item name transformation method. Default: noop")
|
||||
trimPrefix = flag.String("trimprefix", "", "transform each item name by removing a prefix. Default: \"\"")
|
||||
autoTrimPrefix = flag.Bool("autotrimprefix", false, "if true, remove a common prefix from each item name. Default: false")
|
||||
)
|
||||
|
||||
// Usage is a replacement usage function for the flags package.
|
||||
|
@ -157,7 +156,7 @@ func main() {
|
|||
|
||||
// Run generate for each type.
|
||||
for _, typeName := range types {
|
||||
g.generate(typeName, *json, *yaml, *sql, *transformMethod, *trimPrefix, *autoTrimPrefix)
|
||||
g.generate(typeName, *json, *yaml, *sql, *transformMethod, *trimPrefix)
|
||||
}
|
||||
|
||||
// Format the output.
|
||||
|
@ -308,8 +307,15 @@ func (g *Generator) transformValueNames(values []Value, transformMethod string)
|
|||
}
|
||||
}
|
||||
|
||||
// trimValueNames removes a prefix from each name
|
||||
func (g *Generator) trimValueNames(values []Value, prefix string) {
|
||||
for i := range values {
|
||||
values[i].name = strings.TrimPrefix(values[i].name, prefix)
|
||||
}
|
||||
}
|
||||
|
||||
// generate produces the String method for the named type.
|
||||
func (g *Generator) generate(typeName string, includeJSON, includeYAML, includeSQL bool, transformMethod string, trimPrefix string, autoTrimPrefix bool) {
|
||||
func (g *Generator) generate(typeName string, includeJSON, includeYAML, includeSQL bool, transformMethod string, trimPrefix string) {
|
||||
values := make([]Value, 0, 100)
|
||||
for _, file := range g.pkg.files {
|
||||
// Set the state for this run of the walker.
|
||||
|
@ -327,10 +333,6 @@ func (g *Generator) generate(typeName string, includeJSON, includeYAML, includeS
|
|||
|
||||
g.trimValueNames(values, trimPrefix)
|
||||
|
||||
if autoTrimPrefix {
|
||||
g.autoTrimValueNames(values)
|
||||
}
|
||||
|
||||
g.transformValueNames(values, transformMethod)
|
||||
|
||||
runs := splitIntoRuns(values)
|
||||
|
|
47
trim.go
47
trim.go
|
@ -1,47 +0,0 @@
|
|||
package main
|
||||
|
||||
import "strings"
|
||||
|
||||
func longestCommonPrefix(values []Value) string {
|
||||
// LCP of min and max (lexigraphically)
|
||||
// is the LCP of the whole set.
|
||||
min := values[0].name
|
||||
max := min
|
||||
for _, s := range values[1:] {
|
||||
switch {
|
||||
case s.name < min:
|
||||
min = s.name
|
||||
case s.name > max:
|
||||
max = s.name
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(min) && i < len(max); i++ {
|
||||
if min[i] != max[i] {
|
||||
return min[:i]
|
||||
}
|
||||
}
|
||||
// If all the bytes are equal but the lengths aren't then
|
||||
// min is a prefix of max, and hence the lcp
|
||||
return min
|
||||
}
|
||||
|
||||
func autoPrefix(values []Value) string {
|
||||
// Can't trim a single value
|
||||
if len(values) < 2 {
|
||||
return ""
|
||||
}
|
||||
prefix := longestCommonPrefix(values)
|
||||
|
||||
return prefix
|
||||
}
|
||||
|
||||
func (g *Generator) trimValueNames(values []Value, prefix string) {
|
||||
for i := range values {
|
||||
values[i].name = strings.TrimPrefix(values[i].name, prefix)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Generator) autoTrimValueNames(values []Value) {
|
||||
prefix := autoPrefix(values)
|
||||
g.trimValueNames(values, prefix)
|
||||
}
|
32
trim_test.go
32
trim_test.go
|
@ -1,32 +0,0 @@
|
|||
package main
|
||||
|
||||
import "testing"
|
||||
|
||||
var lcpTests = []struct {
|
||||
expected string
|
||||
in []string
|
||||
}{
|
||||
{"Proto", []string{"ProtoOne", "ProtoTwo", "ProtoThree"}},
|
||||
// An empty string is OK when one value is the prefix
|
||||
{"Proto", []string{"Proto", "ProtoLonger"}},
|
||||
{"", []string{}},
|
||||
{"", []string{"aardvark"}},
|
||||
{"", []string{"abc", "def", "deg"}},
|
||||
{"ab", []string{"ab", "abc", "abcd"}},
|
||||
}
|
||||
|
||||
// TestLcp checks that the longest common prefix is generated correctly
|
||||
func TestLcp(t *testing.T) {
|
||||
for _, tt := range lcpTests {
|
||||
values := make([]Value, len(tt.in))
|
||||
for i := range tt.in {
|
||||
values[i] = Value{
|
||||
name: tt.in[i],
|
||||
}
|
||||
}
|
||||
prefix := autoPrefix(values)
|
||||
if prefix != tt.expected {
|
||||
t.Errorf("%q => %s, expected %s", tt.in, tt.expected, prefix)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue