From 89744b3e498c96c5566f5c86c032207ff49c3b96 Mon Sep 17 00:00:00 2001 From: Paul Gier Date: Tue, 17 Dec 2019 09:22:31 -0600 Subject: [PATCH 1/6] combine pluralization and singularization rules (#30) * combine pluralization and singularization rules Combines the rules for pluralization and singularization into a single set for improved consistency and maintenance. Suffix rules are now ordered with most specific matches (longest suffixes) matched before shorter suffixes. Also fixed pluralization of "you", should be "you" instead of "yous". And added some extra cases for better handling of some words ending with "us". * remove unused rule The rule for "appendix" suffix is not used because it's already in the list of full words. * alphabetize single to plural word map --- flect_test.go | 4 + name/name_test.go | 4 +- name/tablize_test.go | 4 +- plural_rules.go | 307 +++++++++++++++++++++++++------------------ singular_rules.go | 99 -------------- singularize.go | 3 + 6 files changed, 187 insertions(+), 234 deletions(-) diff --git a/flect_test.go b/flect_test.go index 232686e..adf81ba 100644 --- a/flect_test.go +++ b/flect_test.go @@ -172,6 +172,10 @@ var singlePluralAssertions = []tt{ {"prize", "prizes"}, {"edge", "edges"}, {"database", "databases"}, + {"circus", "circuses"}, + {"plus", "pluses"}, + {"fuse", "fuses"}, + {"prometheus", "prometheuses"}, } var pluralSingularAssertions = []tt{} diff --git a/name/name_test.go b/name/name_test.go index a0f201a..42be425 100644 --- a/name/name_test.go +++ b/name/name_test.go @@ -20,9 +20,9 @@ func Test_Name(t *testing.T) { {"Widget_ID", "WidgetID"}, {"Widget_Id", "WidgetID"}, {"Widget_id", "WidgetID"}, - {"Nice to see you!", "NiceToSeeYou"}, + {"Nice to see you today!", "NiceToSeeYouToday"}, {"*hello*", "Hello"}, - {"i've read a book! have you?", "IveReadABookHaveYou"}, + {"i've read a book! have you read it?", "IveReadABookHaveYouReadIt"}, {"This is `code` ok", "ThisIsCodeOK"}, {"foo_bar", "FooBar"}, {"admin/widget", "AdminWidget"}, diff --git a/name/tablize_test.go b/name/tablize_test.go index ea4b7d1..f3dd8c0 100644 --- a/name/tablize_test.go +++ b/name/tablize_test.go @@ -10,9 +10,9 @@ func Test_Tableize(t *testing.T) { table := []tt{ {"", ""}, {"bob dylan", "bob_dylans"}, - {"Nice to see you!", "nice_to_see_yous"}, + {"Nice to see you!", "nice_to_see_you"}, {"*hello*", "hellos"}, - {"i've read a book! have you?", "ive_read_a_book_have_yous"}, + {"i've read a book! have you?", "ive_read_a_book_have_you"}, {"This is `code` ok", "this_is_code_oks"}, {"foo_bar", "foo_bars"}, {"admin/widget", "admin_widgets"}, diff --git a/plural_rules.go b/plural_rules.go index 1010719..86fca8c 100644 --- a/plural_rules.go +++ b/plural_rules.go @@ -21,36 +21,8 @@ func AddPlural(suffix string, repl string) { } var singleToPlural = map[string]string{ - "human": "humans", - "matrix": "matrices", - "vertix": "vertices", - "index": "indices", - "mouse": "mice", - "louse": "lice", - "ress": "resses", - "ox": "oxen", - "quiz": "quizzes", - "series": "series", - "octopus": "octopi", - "equipment": "equipment", - "information": "information", - "rice": "rice", - "money": "money", - "species": "species", - "fish": "fish", - "sheep": "sheep", - "jeans": "jeans", - "police": "police", - "dear": "dear", - "goose": "geese", - "tooth": "teeth", - "foot": "feet", - "bus": "buses", - "fez": "fezzes", - "piano": "pianos", - "halo": "halos", - "photo": "photos", "aircraft": "aircraft", + "alias": "aliases", "alumna": "alumnae", "alumnus": "alumni", "analysis": "analyses", @@ -65,48 +37,84 @@ var singleToPlural = map[string]string{ "beau": "beaus", "bison": "bison", "bureau": "bureaus", + "bus": "buses", "campus": "campuses", + "caucus": "caucuses", "château": "châteaux", + "circus": "circuses", "codex": "codices", "concerto": "concertos", "corpus": "corpora", "crisis": "crises", "curriculum": "curriculums", + "datum": "data", + "dear": "dear", "deer": "deer", "diagnosis": "diagnoses", "die": "dice", "dwarf": "dwarves", "ellipsis": "ellipses", + "equipment": "equipment", "erratum": "errata", "faux pas": "faux pas", + "fez": "fezzes", + "fish": "fish", "focus": "foci", + "foo": "foos", + "foot": "feet", "formula": "formulas", "fungus": "fungi", "genus": "genera", + "goose": "geese", "graffito": "graffiti", "grouse": "grouse", "half": "halves", + "halo": "halos", "hoof": "hooves", + "human": "humans", "hypothesis": "hypotheses", + "index": "indices", + "information": "information", + "jeans": "jeans", "larva": "larvae", "libretto": "librettos", "loaf": "loaves", "locus": "loci", + "louse": "lice", + "matrix": "matrices", "minutia": "minutiae", + "money": "money", "moose": "moose", + "mouse": "mice", "nebula": "nebulae", + "news": "news", "nucleus": "nuclei", "oasis": "oases", + "octopus": "octopi", "offspring": "offspring", "opus": "opera", + "ovum": "ova", + "ox": "oxen", "parenthesis": "parentheses", "phenomenon": "phenomena", + "photo": "photos", "phylum": "phyla", + "piano": "pianos", + "plus": "pluses", + "police": "police", "prognosis": "prognoses", + "prometheus": "prometheuses", + "quiz": "quizzes", "radius": "radiuses", "referendum": "referendums", + "ress": "resses", + "rice": "rice", "salmon": "salmon", + "series": "series", + "sheep": "sheep", + "shoe": "shoes", "shrimp": "shrimp", + "species": "species", "stimulus": "stimuli", "stratum": "strata", "swine": "swine", @@ -114,23 +122,20 @@ var singleToPlural = map[string]string{ "symposium": "symposiums", "synopsis": "synopses", "tableau": "tableaus", + "testis": "testes", "thesis": "theses", "thief": "thieves", + "tooth": "teeth", "trout": "trout", "tuna": "tuna", "vertebra": "vertebrae", + "vertix": "vertices", "vita": "vitae", "vortex": "vortices", "wharf": "wharves", "wife": "wives", "wolf": "wolves", - "datum": "data", - "testis": "testes", - "alias": "aliases", - "shoe": "shoes", - "news": "news", - "ovum": "ova", - "foo": "foos", + "you": "you", } var pluralToSingle = map[string]string{} @@ -140,100 +145,140 @@ func init() { pluralToSingle[v] = k } } + +type singularToPluralSuffix struct { + singular string + plural string +} + +var singularToPluralSuffixList = []singularToPluralSuffix{ + {"iterion", "iteria"}, + {"campus", "campuses"}, + {"genera", "genus"}, + {"person", "people"}, + {"phylum", "phyla"}, + {"randum", "randa"}, + {"actus", "acti"}, + {"adium", "adia"}, + {"alias", "aliases"}, + {"basis", "basis"}, + {"child", "children"}, + {"chive", "chives"}, + {"focus", "foci"}, + {"hello", "hellos"}, + {"jeans", "jeans"}, + {"louse", "lice"}, + {"mouse", "mice"}, + {"movie", "movies"}, + {"oasis", "oasis"}, + {"atum", "ata"}, + {"atus", "atuses"}, + {"base", "bases"}, + {"cess", "cesses"}, + {"dium", "diums"}, + {"eses", "esis"}, + {"half", "halves"}, + {"hive", "hives"}, + {"iano", "ianos"}, + {"irus", "iri"}, + {"isis", "ises"}, + {"leus", "li"}, + {"mnus", "mni"}, + {"move", "moves"}, + {"news", "news"}, + {"odex", "odice"}, + {"oose", "eese"}, + {"ouse", "ouses"}, + {"ovum", "ova"}, + {"rion", "ria"}, + {"shoe", "shoes"}, + {"stis", "stes"}, + {"tive", "tives"}, + {"wife", "wives"}, + {"afe", "aves"}, + {"bfe", "bves"}, + {"box", "boxes"}, + {"cfe", "cves"}, + {"dfe", "dves"}, + {"dge", "dges"}, + {"efe", "eves"}, + {"gfe", "gves"}, + {"hfe", "hves"}, + {"ife", "ives"}, + {"itz", "itzes"}, + {"ium", "ia"}, + {"ize", "izes"}, + {"jfe", "jves"}, + {"kfe", "kves"}, + {"man", "men"}, + {"mfe", "mves"}, + {"nfe", "nves"}, + {"nna", "nnas"}, + {"oaf", "oaves"}, + {"oci", "ocus"}, + {"ode", "odes"}, + {"ofe", "oves"}, + {"oot", "eet"}, + {"pfe", "pves"}, + {"pse", "psis"}, + {"qfe", "qves"}, + {"quy", "quies"}, + {"rfe", "rves"}, + {"sfe", "sves"}, + {"tfe", "tves"}, + {"tum", "ta"}, + {"tus", "tuses"}, + {"ufe", "uves"}, + {"ula", "ulae"}, + {"ula", "ulas"}, + {"uli", "ulus"}, + {"use", "uses"}, + {"uss", "usses"}, + {"vfe", "vves"}, + {"wfe", "wves"}, + {"xfe", "xves"}, + {"yfe", "yves"}, + {"you", "you"}, + {"zfe", "zves"}, + {"by", "bies"}, + {"ch", "ches"}, + {"cy", "cies"}, + {"dy", "dies"}, + {"ex", "ices"}, + {"fy", "fies"}, + {"gy", "gies"}, + {"hy", "hies"}, + {"io", "ios"}, + {"jy", "jies"}, + {"ky", "kies"}, + {"ld", "ldren"}, + {"lf", "lves"}, + {"ly", "lies"}, + {"my", "mies"}, + {"ny", "nies"}, + {"ox", "oxen"}, + {"py", "pies"}, + {"qy", "qies"}, + {"rf", "rves"}, + {"ry", "ries"}, + {"sh", "shes"}, + {"ss", "sses"}, + {"sy", "sies"}, + {"ty", "ties"}, + {"tz", "tzes"}, + {"va", "vae"}, + {"vy", "vies"}, + {"wy", "wies"}, + {"xy", "xies"}, + {"zy", "zies"}, + {"zz", "zzes"}, + {"o", "oes"}, + {"x", "xes"}, +} + func init() { - AddPlural("campus", "campuses") - AddPlural("man", "men") - AddPlural("tz", "tzes") - AddPlural("alias", "aliases") - AddPlural("oasis", "oasis") - AddPlural("wife", "wives") - AddPlural("basis", "basis") - AddPlural("atum", "ata") - AddPlural("adium", "adia") - AddPlural("actus", "acti") - AddPlural("irus", "iri") - AddPlural("iterion", "iteria") - AddPlural("dium", "diums") - AddPlural("ovum", "ova") - AddPlural("ize", "izes") - AddPlural("dge", "dges") - AddPlural("focus", "foci") - AddPlural("child", "children") - AddPlural("oaf", "oaves") - AddPlural("randum", "randa") - AddPlural("base", "bases") - AddPlural("atus", "atuses") - AddPlural("ode", "odes") - AddPlural("person", "people") - AddPlural("hello", "hellos") - AddPlural("va", "vae") - AddPlural("leus", "li") - AddPlural("oot", "eet") - AddPlural("oose", "eese") - AddPlural("box", "boxes") - AddPlural("ium", "ia") - AddPlural("sis", "ses") - AddPlural("nna", "nnas") - AddPlural("eses", "esis") - AddPlural("stis", "stes") - AddPlural("ex", "ices") - AddPlural("ula", "ulae") - AddPlural("isis", "ises") - AddPlural("use", "uses") - AddPlural("lf", "lves") - AddPlural("rf", "rves") - AddPlural("afe", "aves") - AddPlural("bfe", "bves") - AddPlural("cfe", "cves") - AddPlural("dfe", "dves") - AddPlural("efe", "eves") - AddPlural("gfe", "gves") - AddPlural("hfe", "hves") - AddPlural("ife", "ives") - AddPlural("jfe", "jves") - AddPlural("kfe", "kves") - AddPlural("lfe", "lves") - AddPlural("mfe", "mves") - AddPlural("nfe", "nves") - AddPlural("ofe", "oves") - AddPlural("pfe", "pves") - AddPlural("qfe", "qves") - AddPlural("rfe", "rves") - AddPlural("sfe", "sves") - AddPlural("tfe", "tves") - AddPlural("ufe", "uves") - AddPlural("vfe", "vves") - AddPlural("wfe", "wves") - AddPlural("xfe", "xves") - AddPlural("yfe", "yves") - AddPlural("zfe", "zves") - AddPlural("hive", "hives") - AddPlural("quy", "quies") - AddPlural("by", "bies") - AddPlural("cy", "cies") - AddPlural("dy", "dies") - AddPlural("fy", "fies") - AddPlural("gy", "gies") - AddPlural("hy", "hies") - AddPlural("jy", "jies") - AddPlural("ky", "kies") - AddPlural("ly", "lies") - AddPlural("my", "mies") - AddPlural("ny", "nies") - AddPlural("py", "pies") - AddPlural("qy", "qies") - AddPlural("ry", "ries") - AddPlural("sy", "sies") - AddPlural("ty", "ties") - AddPlural("vy", "vies") - AddPlural("wy", "wies") - AddPlural("xy", "xies") - AddPlural("zy", "zies") - AddPlural("x", "xes") - AddPlural("ch", "ches") - AddPlural("ss", "sses") - AddPlural("sh", "shes") - AddPlural("oe", "oes") - AddPlural("io", "ios") - AddPlural("o", "oes") + for _, suffix := range singularToPluralSuffixList { + AddPlural(suffix.singular, suffix.plural) + AddSingular(suffix.plural, suffix.singular) + } } diff --git a/singular_rules.go b/singular_rules.go index 14b471c..b20371b 100644 --- a/singular_rules.go +++ b/singular_rules.go @@ -21,102 +21,3 @@ func AddSingular(ext string, repl string) { }, }) } - -func init() { - AddSingular("ria", "rion") - AddSingular("news", "news") - AddSingular("halves", "half") - AddSingular("appendix", "appendix") - AddSingular("zzes", "zz") - AddSingular("ulas", "ula") - AddSingular("psis", "pse") - AddSingular("genus", "genera") - AddSingular("phyla", "phylum") - AddSingular("odice", "odex") - AddSingular("oxen", "ox") - AddSingular("ianos", "iano") - AddSingular("ulus", "uli") - AddSingular("mice", "mouse") - AddSingular("ouses", "ouse") - AddSingular("mni", "mnus") - AddSingular("ocus", "oci") - AddSingular("shoes", "shoe") - AddSingular("oasis", "oasis") - AddSingular("lice", "louse") - AddSingular("men", "man") - AddSingular("ta", "tum") - AddSingular("ia", "ium") - AddSingular("tives", "tive") - AddSingular("ldren", "ld") - AddSingular("people", "person") - AddSingular("aves", "afe") - AddSingular("uses", "us") - AddSingular("bves", "bfe") - AddSingular("cves", "cfe") - AddSingular("dves", "dfe") - AddSingular("eves", "efe") - AddSingular("gves", "gfe") - AddSingular("hves", "hfe") - AddSingular("chives", "chive") - AddSingular("ives", "ife") - AddSingular("movies", "movie") - AddSingular("jeans", "jeans") - AddSingular("cesses", "cess") - AddSingular("cess", "cess") - AddSingular("acti", "actus") - AddSingular("itzes", "itz") - AddSingular("usses", "uss") - AddSingular("uss", "uss") - AddSingular("jves", "jfe") - AddSingular("kves", "kfe") - AddSingular("mves", "mfe") - AddSingular("nves", "nfe") - AddSingular("moves", "move") - AddSingular("oves", "ofe") - AddSingular("pves", "pfe") - AddSingular("qves", "qfe") - AddSingular("sves", "sfe") - AddSingular("tves", "tfe") - AddSingular("uves", "ufe") - AddSingular("vves", "vfe") - AddSingular("wves", "wfe") - AddSingular("xves", "xfe") - AddSingular("yves", "yfe") - AddSingular("zves", "zfe") - AddSingular("hives", "hive") - AddSingular("lves", "lf") - AddSingular("rves", "rf") - AddSingular("quies", "quy") - AddSingular("bies", "by") - AddSingular("cies", "cy") - AddSingular("dies", "dy") - AddSingular("fies", "fy") - AddSingular("gies", "gy") - AddSingular("hies", "hy") - AddSingular("jies", "jy") - AddSingular("kies", "ky") - AddSingular("lies", "ly") - AddSingular("mies", "my") - AddSingular("nies", "ny") - AddSingular("pies", "py") - AddSingular("qies", "qy") - AddSingular("ries", "ry") - AddSingular("sies", "sy") - AddSingular("ties", "ty") - AddSingular("vies", "vy") - AddSingular("wies", "wy") - AddSingular("xies", "xy") - AddSingular("zies", "zy") - AddSingular("xes", "x") - AddSingular("ches", "ch") - AddSingular("sses", "ss") - AddSingular("shes", "sh") - AddSingular("oes", "o") - AddSingular("ress", "ress") - AddSingular("iri", "irus") - AddSingular("irus", "irus") - AddSingular("tuses", "tus") - AddSingular("tus", "tus") - AddSingular("s", "") - AddSingular("ss", "ss") -} diff --git a/singularize.go b/singularize.go index a08cbd5..a0f8545 100644 --- a/singularize.go +++ b/singularize.go @@ -40,5 +40,8 @@ func (i Ident) Singularize() Ident { } } + if strings.HasSuffix(s, "s") { + return New(s[:len(s)-1]) + } return i } From 42c7425753a0d8f22b9b1c2ec2cf61d9b6e494e2 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Tue, 17 Dec 2019 10:27:07 -0500 Subject: [PATCH 2/6] github actions (#31) --- .github/FUNDING.yml | 4 +++ .github/workflows/tests.yml | 22 ++++++++++++ azure-pipelines.yml | 71 ------------------------------------- azure-tests.yml | 19 ---------- go.mod | 7 ++-- go.sum | 10 +++--- 6 files changed, 34 insertions(+), 99 deletions(-) create mode 100644 .github/FUNDING.yml create mode 100644 .github/workflows/tests.yml delete mode 100644 azure-pipelines.yml delete mode 100644 azure-tests.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..65b45f1 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms + +github: markbates +patreon: buffalo diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..68804c1 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,22 @@ +name: Tests +on: [push] +jobs: + + tests-on: + name: ${{matrix.go-version}} ${{matrix.os}} + runs-on: ${{ matrix.os }} + strategy: + matrix: + go-version: [1.12.x, 1.13.x] + os: [macos-latest, windows-latest, ubuntu-latest] + steps: + - name: Checkout Code + uses: actions/checkout@v1 + with: + fetch-depth: 1 + - name: Test + run: | + go mod tidy -v + go test -race ./... + + diff --git a/azure-pipelines.yml b/azure-pipelines.yml deleted file mode 100644 index 417e2c5..0000000 --- a/azure-pipelines.yml +++ /dev/null @@ -1,71 +0,0 @@ -variables: - GOBIN: "$(GOPATH)/bin" # Go binaries path - GOPATH: "$(system.defaultWorkingDirectory)/gopath" # Go workspace path - modulePath: "$(GOPATH)/src/github.com/$(build.repository.name)" # Path to the module"s code - -jobs: -- job: Windows - pool: - vmImage: "vs2017-win2016" - strategy: - matrix: - go 1.10: - go_version: "1.10" - go 1.11 (on): - go_version: "1.11.5" - GO111MODULE: "on" - go 1.11 (off): - go_version: "1.11.5" - GO111MODULE: "off" - go 1.12 (on): - go_version: "1.12" - GO111MODULE: "on" - go 1.12 (off): - go_version: "1.12" - GO111MODULE: "off" - steps: - - template: azure-tests.yml - -- job: macOS - pool: - vmImage: "macOS-10.13" - strategy: - matrix: - go 1.10: - go_version: "1.10" - go 1.11 (on): - go_version: "1.11.5" - GO111MODULE: "on" - go 1.11 (off): - go_version: "1.11.5" - GO111MODULE: "off" - go 1.12 (on): - go_version: "1.12" - GO111MODULE: "on" - go 1.12 (off): - go_version: "1.12" - GO111MODULE: "off" - steps: - - template: azure-tests.yml - -- job: Linux - pool: - vmImage: "ubuntu-16.04" - strategy: - matrix: - go 1.10: - go_version: "1.10" - go 1.11 (on): - go_version: "1.11.5" - GO111MODULE: "on" - go 1.11 (off): - go_version: "1.11.5" - GO111MODULE: "off" - go 1.12 (on): - go_version: "1.12" - GO111MODULE: "on" - go 1.12 (off): - go_version: "1.12" - GO111MODULE: "off" - steps: - - template: azure-tests.yml diff --git a/azure-tests.yml b/azure-tests.yml deleted file mode 100644 index eea5822..0000000 --- a/azure-tests.yml +++ /dev/null @@ -1,19 +0,0 @@ -steps: - - task: GoTool@0 - inputs: - version: $(go_version) - - task: Bash@3 - inputs: - targetType: inline - script: | - mkdir -p "$(GOBIN)" - mkdir -p "$(GOPATH)/pkg" - mkdir -p "$(modulePath)" - shopt -s extglob - mv !(gopath) "$(modulePath)" - displayName: "Setup Go Workspace" - - script: | - go get -t -v ./... - go test -race ./... - workingDirectory: "$(modulePath)" - displayName: "Tests" diff --git a/go.mod b/go.mod index cd02d07..7c8d049 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,5 @@ module github.com/gobuffalo/flect -go 1.12 +go 1.13 -require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/stretchr/testify v1.3.0 -) +require github.com/stretchr/testify v1.4.0 diff --git a/go.sum b/go.sum index 4f76e62..8fdee58 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,11 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From 21c4dbc3612bd8a25d813706ff8ef7643335cd54 Mon Sep 17 00:00:00 2001 From: Antonio Pagano Date: Thu, 13 Feb 2020 15:29:02 -0500 Subject: [PATCH 3/6] Adding child as irregular and adding few other words --- flect_test.go | 2 ++ plural_rules.go | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/flect_test.go b/flect_test.go index adf81ba..257e4e1 100644 --- a/flect_test.go +++ b/flect_test.go @@ -176,6 +176,8 @@ var singlePluralAssertions = []tt{ {"plus", "pluses"}, {"fuse", "fuses"}, {"prometheus", "prometheuses"}, + {"field", "fields"}, + {"custom_field", "custom_fields"}, } var pluralSingularAssertions = []tt{} diff --git a/plural_rules.go b/plural_rules.go index 86fca8c..65cf4d5 100644 --- a/plural_rules.go +++ b/plural_rules.go @@ -40,6 +40,7 @@ var singleToPlural = map[string]string{ "bus": "buses", "campus": "campuses", "caucus": "caucuses", + "child": "children", "château": "châteaux", "circus": "circuses", "codex": "codices", @@ -130,10 +131,12 @@ var singleToPlural = map[string]string{ "tuna": "tuna", "vertebra": "vertebrae", "vertix": "vertices", + "vertex": "vertices", "vita": "vitae", "vortex": "vortices", "wharf": "wharves", "wife": "wives", + "woman": "women", "wolf": "wolves", "you": "you", } @@ -251,7 +254,6 @@ var singularToPluralSuffixList = []singularToPluralSuffix{ {"io", "ios"}, {"jy", "jies"}, {"ky", "kies"}, - {"ld", "ldren"}, {"lf", "lves"}, {"ly", "lies"}, {"my", "mies"}, From a860933340d730581e9c479ea01bab09048c1f7f Mon Sep 17 00:00:00 2001 From: Antonio Pagano Date: Thu, 13 Feb 2020 15:31:58 -0500 Subject: [PATCH 4/6] adding few more words --- plural_rules.go | 1 + 1 file changed, 1 insertion(+) diff --git a/plural_rules.go b/plural_rules.go index 65cf4d5..4cf88bc 100644 --- a/plural_rules.go +++ b/plural_rules.go @@ -111,6 +111,7 @@ var singleToPlural = map[string]string{ "ress": "resses", "rice": "rice", "salmon": "salmon", + "sex": "sexes", "series": "series", "sheep": "sheep", "shoe": "shoes", From 15127be35a6115cbb7467d46c6138c9d382bf2c7 Mon Sep 17 00:00:00 2001 From: Antonio Pagano Date: Thu, 13 Feb 2020 15:47:44 -0500 Subject: [PATCH 5/6] removing extra rule --- plural_rules.go | 1 - 1 file changed, 1 deletion(-) diff --git a/plural_rules.go b/plural_rules.go index 4cf88bc..4c88b62 100644 --- a/plural_rules.go +++ b/plural_rules.go @@ -132,7 +132,6 @@ var singleToPlural = map[string]string{ "tuna": "tuna", "vertebra": "vertebrae", "vertix": "vertices", - "vertex": "vertices", "vita": "vitae", "vortex": "vortices", "wharf": "wharves", From 222210ed979a58ddec5522bbeab7b50d0900b070 Mon Sep 17 00:00:00 2001 From: Tom <17813371+AtomicNibble@users.noreply.github.com> Date: Tue, 3 Mar 2020 15:43:44 +0000 Subject: [PATCH 6/6] Make New/Underscore a bit faster. (#38) Co-authored-by: Mark Bates --- ident.go | 29 ++++++++++++++++------------- ident_test.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ underscore.go | 11 ++++++----- underscore_test.go | 19 +++++++++++++++++++ 4 files changed, 87 insertions(+), 18 deletions(-) diff --git a/ident.go b/ident.go index 78b51d4..da3560b 100644 --- a/ident.go +++ b/ident.go @@ -38,9 +38,9 @@ func toParts(s string) []string { return []string{strings.ToUpper(s)} } var prev rune - var x string + var x strings.Builder + x.Grow(len(s)) for _, c := range s { - cs := string(c) // fmt.Println("### cs ->", cs) // fmt.Println("### unicode.IsControl(c) ->", unicode.IsControl(c)) // fmt.Println("### unicode.IsDigit(c) ->", unicode.IsDigit(c)) @@ -58,35 +58,38 @@ func toParts(s string) []string { } if isSpace(c) { - parts = xappend(parts, x) - x = cs + parts = xappend(parts, x.String()) + x.Reset() + x.WriteRune(c) prev = c continue } if unicode.IsUpper(c) && !unicode.IsUpper(prev) { - parts = xappend(parts, x) - x = cs + parts = xappend(parts, x.String()) + x.Reset() + x.WriteRune(c) prev = c continue } - if unicode.IsUpper(c) && baseAcronyms[strings.ToUpper(x)] { - parts = xappend(parts, x) - x = cs + if unicode.IsUpper(c) && baseAcronyms[strings.ToUpper(x.String())] { + parts = xappend(parts, x.String()) + x.Reset() + x.WriteRune(c) prev = c continue } if unicode.IsLetter(c) || unicode.IsDigit(c) || unicode.IsPunct(c) || c == '`' { prev = c - x += cs + x.WriteRune(c) continue } - parts = xappend(parts, x) - x = "" + parts = xappend(parts, x.String()) + x.Reset() prev = c } - parts = xappend(parts, x) + parts = xappend(parts, x.String()) return parts } diff --git a/ident_test.go b/ident_test.go index 034acb0..3994d29 100644 --- a/ident_test.go +++ b/ident_test.go @@ -64,3 +64,49 @@ func Test_MarshalText(t *testing.T) { r.NoError((&n).UnmarshalText([]byte("bates"))) r.Equal("bates", n.String()) } + +func Benchmark_New(b *testing.B) { + + table := []string{ + "", + "widget", + "widget_id", + "WidgetID", + "Widget_ID", + "widget_ID", + "widget/ID", + "widgetID", + "widgetName", + "JWTName", + "JWTname", + "jwtname", + "sql", + "sQl", + "id", + "Id", + "iD", + "html", + "Html", + "HTML", + "with `code` inside", + "Donald E. Knuth", + "Random text with *(bad)* characters", + "Allow_Under_Scores", + "Trailing bad characters!@#", + "!@#Leading bad characters", + "Squeeze separators", + "Test with + sign", + "Malmö", + "Garçons", + "Opsů", + "Ærøskøbing", + "Aßlar", + "Japanese: 日本語", + } + + for n := 0; n < b.N; n++ { + for i := range table { + New(table[i]) + } + } +} diff --git a/underscore.go b/underscore.go index b92488a..e1466d9 100644 --- a/underscore.go +++ b/underscore.go @@ -18,16 +18,17 @@ func Underscore(s string) string { // Nice to see you! = nice_to_see_you // widgetID = widget_id func (i Ident) Underscore() Ident { - var out []string + out := make([]string, 0, len(i.Parts)) for _, part := range i.Parts { - var x string + var x strings.Builder + x.Grow(len(part)) for _, c := range part { if unicode.IsLetter(c) || unicode.IsDigit(c) { - x += string(c) + x.WriteRune(c) } } - if x != "" { - out = append(out, x) + if x.Len() > 0 { + out = append(out, x.String()) } } return New(strings.ToLower(strings.Join(out, "_"))) diff --git a/underscore_test.go b/underscore_test.go index 2425738..7122e9d 100644 --- a/underscore_test.go +++ b/underscore_test.go @@ -27,3 +27,22 @@ func Test_Underscore(t *testing.T) { }) } } + +func Benchmark_Underscore(b *testing.B) { + + table := []string{ + "", + "bob dylan", + "Nice to see you!", + "*hello*", + "i've read a book! have you?", + "This is `code` ok", + "TLCForm", + } + + for n := 0; n < b.N; n++ { + for i := range table { + Underscore(table[i]) + } + } +}