Skip to content

Commit

Permalink
Merge pull request #41 from amoghrajesh/title-casing
Browse files Browse the repository at this point in the history
Add abbreviations for title case
  • Loading branch information
dnnrly authored Oct 3, 2023
2 parents 3068d3f + f87af8c commit 958e2cc
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 0 deletions.
41 changes: 41 additions & 0 deletions cmd/title.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright © 2018 Pascal Dennerly
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
"fmt"
"github.com/dnnrly/abbreviate/domain"
"github.com/spf13/cobra"
)

// titleCmd represents the title command
var titleCmd = &cobra.Command{
Use: "title [string]",
Short: "Abbreviate a string and convert it to title case",
Long: `Abbreviate a string and convert it to title case.`,
Args: validateArgPresent,
Run: func(cmd *cobra.Command, args []string) {
abbr := domain.ToTitle(abbreviator, args[0], optMax, optFrmFront, optRemoveStopwords)

fmt.Printf("%s", abbr)
if optNewline {
fmt.Printf("\n")
}
},
}

func init() {
rootCmd.AddCommand(titleCmd)
}
21 changes: 21 additions & 0 deletions domain/shorteners.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,3 +282,24 @@ func shorten(sequences Sequences, max int, frmFront bool, shorten func(int)) Seq
}
return sequences
}

func ToTitle(abbr Abbreviator, original string, max int, frmFront bool, rmvStop bool) string {
if original == "" {
return ""
}

ab := AsPascal(abbr, original, max, frmFront, rmvStop)
s := ab

if len(ab) > 0 {
s = string(ab[0])
for i := 1; i < len(ab); i++ {
if string(ab[i]) == strings.ToUpper(string(ab[i])) {
s += " "
}
s += string(ab[i])
}
}

return s
}
49 changes: 49 additions & 0 deletions domain/shorteners_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,3 +293,52 @@ ltd=limited`)
})
}
}

func TestToTitle(t *testing.T) {
matcher := NewMatcherFromString(`a=aaa
b=bbb
c=ccc
d=ddd
stg=strategy
ltd=limited`)
tests := []struct {
name string
original string
max int
frmFront bool
rmvStop bool
want string
}{
{name: "Length longer than origin with '-'", original: "aaa-bbb-ccc", max: 99, want: "Aaa Bbb Ccc"},
{name: "Length is 0 with '-'", original: "aaa-bbb-ccc", max: 0, want: "A B C"},
{name: "Partial abbreviation with '-'", original: "aaa-bbb-ccc", max: 8, want: "Aaa Bbb C"},
{name: "Partial abbreviation with '-', start from the front", original: "aaa-bbb-ccc", max: 8, frmFront: true, want: "A Bbb Ccc"},
{name: "Length longer than origin with camel case", original: "AaaBbbCcc", max: 99, want: "Aaa Bbb Ccc"},
{name: "Length is 0 with camel case", original: "AaaBbbCcc", max: 0, want: "A B C"},
{name: "Length is 0 with camel case, matching case", original: "aaaBbbCcc", max: 0, want: "A B C"},
{name: "Partial abbreviation with camel case", original: "AaaBbbCcc", max: 8, want: "Aaa Bbb C"},
{name: "Partial abbreviation with camel case, start from the front", original: "AaaBbbCcc", max: 8, frmFront: true, want: "A Bbb Ccc"},
{name: "Doesn't match wrong casing", original: "AaaBBbCcc", max: 0, want: "A B Bb C"},
{name: "Mixed camel case and non word separators", original: "AaaBbb-ccc", max: 0, want: "A B C"},
{name: "Mixed camel case and non word separators with same borders", original: "Aaa-Bbb-Ccc", max: 0, want: "A B C"},
{name: "Real example, full short", original: "strategy-limited", max: 0, want: "Stg Ltd"},
{name: "Real example, shorter than total", original: "strategy-limited", max: 13, want: "Strategy Ltd"},
{name: "Real example, shorter than total, start from the front", original: "strategy-limited", max: 13, frmFront: true, want: "Stg Limited"},
{name: "Real example, max same as shorted", original: "strategy-limited", max: 12, want: "Strategy Ltd"},
{name: "Real example, max same as shorted", original: "strategy-limited", max: 12, frmFront: true, want: "Stg Limited"},
{name: "Real example, max on separator", original: "strategy-limited", max: 9, want: "Stg Ltd"},
{name: "Real example, max shorter than first word", original: "strategy-limited", max: 6, want: "Stg Ltd"},
{name: "Real example, no short", original: "strategy-limited", max: 99, want: "Strategy Limited"},
{name: "Real example, with numbers #1", original: "strategy-limited99", max: 15, want: "Strategy Ltd 9 9"},
{name: "Real example, with numbers #2", original: "strategy-limited-99", max: 15, want: "Strategy Ltd 9 9"},
{name: "Real example, with numbers #1, start from the front", original: "strategy-limited99", max: 15, frmFront: true, want: "Stg Limited 9 9"},
{name: "Real example, with numbers #2, start from the front", original: "strategy-limited-99", max: 15, frmFront: true, want: "Stg Limited 9 9"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := ToTitle(matcher, tt.original, tt.max, tt.frmFront, tt.rmvStop); got != tt.want {
t.Errorf("AsPascal('%s', %d) = '%v', want '%v'", tt.original, tt.max, got, tt.want)
}
})
}
}
6 changes: 6 additions & 0 deletions test/features/cli.feature
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ Feature: Simple CLI commands
When the app runs with parameters "kebab --max 15 strategy_limited"
Then the app exits without error
And the app output contains exactly "strategy-ltd"

@Acceptance
Scenario: Title case
When the app runs with parameters "title --max 14 strategy_limited"
Then the app exits without error
And the app output contains exactly "Strategy Ltd"

@Acceptance
Scenario: Pascal case
Expand Down

0 comments on commit 958e2cc

Please sign in to comment.