Below is the main.go file for a program that counts words or lines from Standard Input. A flag is used to specific what to count:
package main
import (
"bufio"
"flag"
"fmt"
"io"
"os"
)
func count(r io.Reader, countLines bool) int {
scanner := bufio.NewScanner(r)
if !countLines {
scanner.Split(bufio.ScanWords)
}
wc := 0
// For every word of line scanned, add 1 to the counter
for scanner.Scan() {
wc++
}
return wc
}
func main() {
// Defining a boolean flag -l to count lines instead of words
lines := flag.Bool("l", false, "Count lines")
// Parsing the flags provided by the user
flag.Parse()
// Calling the count function to count the number of words (or lines) received from Standard Input and printing it out
fmt.Println(count(os.Stdin, *lines))
}
Here is the source code for the Go testing files:
package main
import (
"bytes"
"testing"
)
func TestCountLines(t *testing.T) {
b := bytes.NewBufferString("word1 word2 word3\nline2\nline3 word 1")
exp := 3
res := count(b, true)
if res != exp {
t.Errorf("Expected %d, got %d instead.\n", exp, res)
}
}
func TestCountWords(t *testing.T) {
b := bytes.NewBufferString("word1 word2 word3 word4\n")
exp := 4
res := count(b, false)
if res != exp {
t.Errorf("Expected %d, got %d instead.\n", exp, res)
}
}
Here is execution and testing of the program:
❯ cat main.go| ./flags -l
42
❯ go test -v
=== RUN TestCountLines
--- PASS: TestCountLines (0.00s)
=== RUN TestCountWords
--- PASS: TestCountWords (0.00s)
PASS
ok flags 0.305s