Skip to content

Commit

Permalink
Merge branch 'release/v0.0.1-beta' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
juniorgarcia committed Dec 28, 2020
2 parents 1edbbfe + bc58a69 commit da87336
Show file tree
Hide file tree
Showing 5 changed files with 260 additions and 0 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# ASCII Banner CLI

## A simple tool to create ASCII Banners

### Install

1. Make sure [Go is installed on your machine](https://golang.org/doc/install#download)
2. Run on terminal `$ go install https://github.com/juniorgarcia/ascii-banner-cli`

### Usage

With the CLI installed, you can run `ascii-banner-cli -h` to obtain help on how
to use it. It's really simple.

### Suggestions

Since this a repository only to play around and learn more Go, you may open issues
to comment about improvements, best code practices, bugs, etc. I'll be glad to talk to you.
100 changes: 100 additions & 0 deletions banner/banner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Package banner contains general utilities to display a banner
package banner

import (
"fmt"
"strings"
)

// Banner The Banner layout properties
type Banner struct {
TlChar, // top left char
TrChar, // top right char
BlChar, // bottom left char
BrChar, // bottom right char
DashesChar,
SidesChar,
Message string
Padding uint8
}

// HorLineType A banner horizontal line types
type HorLineType int

const (
// HorLineTypeTop the top line of a banner
HorLineTypeTop = iota
// HorLineTypeBottom the bottom line of a banner
HorLineTypeBottom = iota
)

// NewBanner Creates a new banner instance
func NewBanner(tlChar, trChar, blChar, brChar, dashesChar, sidesChar string, message string, padding uint8) Banner {
return Banner{
TlChar: tlChar,
TrChar: trChar,
BlChar: blChar,
BrChar: brChar,
DashesChar: dashesChar,
SidesChar: sidesChar,
Message: message,
Padding: padding,
}
}

// NewDefaultBanner Creates a banner with the default options
func NewDefaultBanner(msg string) Banner {
return NewBanner("+", "*", "*", "+", "-", "|", msg, 2)
}

// errInvalidBannerHorLineType Invalid banner horizontal type
type errInvalidBannerHorLineType int

func (e errInvalidBannerHorLineType) Error() string {
return fmt.Sprintf("Invalid horizontal line type: %d", e)
}

// PrintHorizontalEdges Prints the banner's horizontal edges
func (b Banner) PrintHorizontalEdges(line HorLineType) (string, error) {
msgLen := len(b.Message)
var lcChar, rcChar string // left corner and right corner chars
switch line {
case HorLineTypeTop:
lcChar = b.TlChar
rcChar = b.TrChar
case HorLineTypeBottom:
lcChar = b.BlChar
rcChar = b.BrChar
default:
return "", errInvalidBannerHorLineType(line)
}

result := fmt.Sprintf("%s%s%s",
lcChar,
strings.Repeat(b.DashesChar, msgLen+int(b.Padding)*2), rcChar)

return result, nil
}

// PrintMiddle Prints the middle of the banner
func (b Banner) PrintMiddle() string {
paddingsRep := strings.Repeat(" ", int(b.Padding))
return fmt.Sprintf("%s%s%s%s%s", b.SidesChar, paddingsRep, b.Message, paddingsRep, b.SidesChar)
}

// PrintFullBanner Prints the complete banner
func (b Banner) PrintFullBanner() (string, error) {
horLineTop, err := b.PrintHorizontalEdges(HorLineTypeTop)
if err != nil {
return "", err
}

horLineBottom, err := b.PrintHorizontalEdges(HorLineTypeBottom)
if err != nil {
return "", err
}

middle := b.PrintMiddle()

return fmt.Sprintf("%s\n%s\n%s", horLineTop, middle, horLineBottom), nil
}
95 changes: 95 additions & 0 deletions banner/banner_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package banner

import (
"testing"
)

func TestPrintHorizontalEdges(t *testing.T) {
cases := []struct {
in, out string
}{
{"Hello, world!", "+-----------------*"},
{"Lorem ipsum dolor sit amet", "+------------------------------*"},
}

b := NewDefaultBanner("")

for _, c := range cases {
b.Message = c.in
r, err := b.PrintHorizontalEdges(HorLineTypeTop)
if err != nil {
t.Errorf("PrintTop(b) generated error: %s", err)
}
if r != c.out {
t.Errorf("PrintTop(b) expected \"%s\". Got: \"%s\"", c.in, c.out)
}
}
}

func BenchmarkPrintHorizontalEdges(b *testing.B) {
for i := 0; i < b.N; i++ {
NewDefaultBanner("Hello, World").PrintHorizontalEdges(HorLineTypeBottom)
}
}

func TestPrintMiddle(t *testing.T) {
cases := []struct {
in, out string
}{
{"Hello, world!", "| Hello, world! |"},
{"Lorem ipsum dolor sit amet", "| Lorem ipsum dolor sit amet |"},
}

b := NewDefaultBanner("")

for _, c := range cases {
b.Message = c.in
if b.PrintMiddle() != c.out {
t.Errorf("PrintTop(b) expected \"%s\". Got: \"%s\"", c.in, c.out)
}
}
}

func BenchmarkPrintMiddle(b *testing.B) {
for i := 0; i < b.N; i++ {
NewDefaultBanner("Hello, world!").PrintMiddle()
}
}

func TestPrintFullBanner(t *testing.T) {
cases := []struct {
in, out string
}{
{
"Hello, world!",
"+-----------------*\n" +
"| Hello, world! |\n" +
"*-----------------+",
},
{
"Foo Bar",
"+-----------*\n" +
"| Foo Bar |\n" +
"*-----------+",
},
}

b := NewDefaultBanner("")

for _, c := range cases {
b.Message = c.in
banner, err := b.PrintFullBanner()
if err != nil {
t.Errorf("PrintFullBanner() raised an error: %w", err)
}
if banner != c.out {
t.Errorf("PrintFullBanner() expected: \n\"%s\". \n Got: \n\"%s\"", c.out, banner)
}
}
}

func BenchmarkPrintFullBanner(b *testing.B) {
for i := 0; i < b.N; i++ {
NewDefaultBanner("Hello, world!").PrintFullBanner()
}
}
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/juniorgarcia/ascii-banner-cli

go 1.15
44 changes: 44 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package main

import (
"flag"
"fmt"

"github.com/juniorgarcia/ascii-banner-cli/banner"
)

const appName = "ASCII Banner Generator"

func main() {

msg := flag.String("m", "Hello world!", "The banner message")
tl := flag.String("tl", "+", "The top left char")
tr := flag.String("tr", "*", "The top right char")
bl := flag.String("bl", "*", "The bottom left char")
br := flag.String("br", "*", "The bottom right char")
d := flag.String("d", "-", "The dashes character")
s := flag.String("s", "|", "The sides character")
p := flag.Int("p", 2, "Individual side padding")
h := flag.Bool("h", false, "Show help")

flag.Parse()

if *h {
printHelp()
return
}

b := banner.NewBanner(*tl, *tr, *bl, *br, *d, *s, *msg, uint8(*p))

bStr, err := b.PrintFullBanner()
if err != nil {
panic(err)
}

fmt.Println(bStr)
}

func printHelp() {
fmt.Fprintf(flag.CommandLine.Output(), "Usage of %s:\n", appName)
flag.PrintDefaults()
}

0 comments on commit da87336

Please sign in to comment.