From 6f5b6ad6b8337f2f07f12d926e5d898fb5b5c3a6 Mon Sep 17 00:00:00 2001 From: Ryan Ling Date: Tue, 1 Jan 2019 16:45:49 +1100 Subject: [PATCH] feat(spaced): Support configurable spacing (#10) --- README.md | 3 +++ cmd/spaced/main.go | 10 ++------ internal/cmd/spaced.go | 48 +++++++++++++++++++++++++++++++++++++ internal/cmd/spaced_test.go | 42 ++++++++++++++++++++++++++++++++ internal/text/lineFilter.go | 14 +++++++---- 5 files changed, 104 insertions(+), 13 deletions(-) create mode 100644 internal/cmd/spaced.go create mode 100644 internal/cmd/spaced_test.go diff --git a/README.md b/README.md index 5a473a4..4769cc5 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,9 @@ space insertion (ASI). ```shell $ echo 'AESTHETIC' | spaced A E S T H E T I C + +$ echo 'AESTHETIC' | spaced 2 +A E S T H E T I C ``` ### Go diff --git a/cmd/spaced/main.go b/cmd/spaced/main.go index 3b2ee69..431e171 100644 --- a/cmd/spaced/main.go +++ b/cmd/spaced/main.go @@ -1,17 +1,11 @@ package main import ( - "fmt" "os" - "github.com/72636c/hyperspaced/internal/text" - "github.com/72636c/hyperspaced/internal/text/transform" + "github.com/72636c/hyperspaced/internal/cmd" ) func main() { - err := text.LineFilter(transform.Spaced) - if err != nil { - fmt.Fprintln(os.Stderr, "error: ", err) - os.Exit(1) - } + cmd.Spaced(os.Stdin, os.Stdout, os.Args) } diff --git a/internal/cmd/spaced.go b/internal/cmd/spaced.go new file mode 100644 index 0000000..b5506d6 --- /dev/null +++ b/internal/cmd/spaced.go @@ -0,0 +1,48 @@ +package cmd + +import ( + "fmt" + "io" + "os" + "strconv" + + "github.com/72636c/hyperspaced/internal/text" + "github.com/72636c/hyperspaced/internal/text/transform" +) + +var usage = `spaced [n] + n int + number of spaces between each character (default 1) +` + +func Spaced(reader io.Reader, writer io.Writer, args []string) { + n, err := spacesFromArgs(args) + if err != nil { + fmt.Fprintln(os.Stderr, usage) + fmt.Fprintln(os.Stderr, "error:", err) + os.Exit(1) + } + + transformLine := func(str string) string { + return transform.SpacedN(str, n) + } + + err = text.LineFilter(reader, writer, transformLine) + if err != nil { + fmt.Fprintln(os.Stderr, "error:", err) + os.Exit(1) + } +} + +func spacesFromArgs(args []string) (int, error) { + if len(args) < 2 { + return 1, nil + } + + n, err := strconv.Atoi(args[1]) + if err != nil { + return 0, err + } + + return n, nil +} diff --git a/internal/cmd/spaced_test.go b/internal/cmd/spaced_test.go new file mode 100644 index 0000000..e1a7dc8 --- /dev/null +++ b/internal/cmd/spaced_test.go @@ -0,0 +1,42 @@ +package cmd + +import ( + "strings" + "testing" +) + +func Test_Spaced(t *testing.T) { + testCases := []struct { + description string + args []string + input string + expected string + }{ + { + description: "unspecified n", + args: []string{"spaced"}, + input: "AESTHETIC", + expected: "A E S T H E T I C\n", + }, + { + description: "integer n", + args: []string{"spaced", "2"}, + input: "AESTHETIC", + expected: "A E S T H E T I C\n", + }, + } + + for _, testCase := range testCases { + t.Run(testCase.description, func(t *testing.T) { + reader := strings.NewReader(testCase.input) + writer := new(strings.Builder) + + Spaced(reader, writer, testCase.args) + + actual := writer.String() + if actual != testCase.expected { + t.Errorf("expected %s, received %s", testCase.expected, actual) + } + }) + } +} diff --git a/internal/text/lineFilter.go b/internal/text/lineFilter.go index 8e7b3e4..f46a6b5 100644 --- a/internal/text/lineFilter.go +++ b/internal/text/lineFilter.go @@ -3,20 +3,24 @@ package text import ( "bufio" "fmt" - "os" + "io" ) // TransformLine is a function that transforms a line of text. type TransformLine func(string) string -// LineFilter transforms lines of text as they pass from stdin to stdout. -func LineFilter(transform TransformLine) error { - scanner := bufio.NewScanner(os.Stdin) +// LineFilter transforms lines of text as they pass from a reader to a writer. +func LineFilter( + reader io.Reader, + writer io.Writer, + transform TransformLine, +) error { + scanner := bufio.NewScanner(reader) for scanner.Scan() { output := transform(scanner.Text()) - _, err := fmt.Println(output) + _, err := fmt.Fprintln(writer, output) if err != nil { return err }