Creating Simple Calculator CLI app using Golang with TDD approach

Search for a command to run...

No comments yet. Be the first to comment.
Introduction A matrix represents a linear transformation. In other words, a matrix represents a transformation that you apply to the vectors in your coordinate space. Say, you apply the matrix: $$A =

Motivation Recently, I tried to learn some low-level system programming stuff. I am a Mac user, and I thought that everything that works on Linux should also work on Mac. After all, Mac is a Unix-based system 😊. I guess we all heard this. Oh boy! I ...

Problem Statement While working on a Nestjs project, I encountered a weird problem related to the database column. I was trying to insert a record into a MySQL table using TypeORM. The error I was experiencing stated that a specific column “cannot be...

Recently, I was exploring design patterns courses on my LinkedIn Learning subscription. I came across a course, Node.js: Design Patterns by Alex Banks. It is a wonderful, easy-to-understand course. I started with the Builder Pattern, and the explanat...

Suppose you are working on a table in a LiveView project. This table has limited static data of not more than one page (you can avoid questions about pagination in the comment section 😊). From a user's point of view, it becomes hard to look into the...

"Go is an open-source programming language that makes it easy to build simple, reliable, and efficient software" as advertised by Google on their official website. It is an excellent choice to develop reliable APIs, microservices, CLI apps, etc. I've played recently with Golang for some automation work as a CLI app. Before Golang my choice would have been a shell/bash script or maybe javascript. This time I tried something with Golang because of its big community, efficiency, package support, and most importantly its easiness of Testing. Golang has good support for developing CLI apps along with that it helps developers to test their code with ease which makes it an excellent choice for developing CLI apps. In this blog, we will develop a simple CLI app using the Golang testing package with TDD approach.
We are going to build a Calculator application with basic operation of "addition", "subtraction", "multiplication", "division". We will build the code and generate an executable file that will run on all platforms. We will execute that file with the flag of -add, -subtract, -multiply, and -div. Refer to the diagram below you will get some idea.

calculator_app(or whatever you want to name) where we are going to add our code and module. go mod init calculator_app. This will generate a file go.mod.
[ About .mod file: .mod refers to the module. It is a kind of dependency management and it is created at the root of the project directory. It has dependency requirements of the modules that have been used. For a simple analogy, it is similar to package.json in javascript.]calculator.go where we will have all of our code related to our calculator logic.calculator.go. package main
import (
"fmt"
)
func main() {
fmt.Println("Calculator app")
}
go run calcuator.go in the root of the directory and you can see the message Calculator app on the screen.To initiate testing, we will create a file calculator_test.go in the root of the directory and add the following code.
package main
import (
"testing"
)
func TestAdd(t *testing.T) {
exp := 5
res := addition(2, 3)
if res != exp {
t.Errorf("%d was expect but got %d .\n", exp, res)
}
}
TestAdd with pointer reference totesting as the parameter.Add function (which does not exist yet).Test... So, every testing function should initiate with the Test keyword.exp variable with value 5 and res with addition(2,3) (this is referring to addition function).if res != exp checks if the expected value and result are the same or not.go test -v and you will see the following errors in the console.
undefined: addition means that function addition is not implemented yet.addition function in main.go.func addition(a int, b int) int {
return a + b
}
go test -v. Hurray!! our test pass and you will see something like below in your terminal.
We have added the test for addition and implemented the function later. Similarly, we will add tests for other functions as follows.
func TestSubtract(t *testing.T) {
exp := 2
res := subtract(5, 3)
if res != exp {
t.Errorf("%d was expect but got %d .\n", exp, res)
}
}
func TestMultiply(t *testing.T) {
exp := 10
res := multiply(2, 5)
if res != exp {
t.Errorf("%d was expect but got %d .\n", exp, res)
}
}
func TestDivision(t *testing.T) {
exp := 2
res := division(6, 3)
if res != exp {
t.Errorf("%d was expect but got %d .\n", exp, res)
}
}
Similarly, add the functions of the above functions in calculator.go as follows
func subtract(a int, b int) int {
return a - b
}
func multiply(a int, b int) int {
return a * b
}
func division(a int, b int) int {
return a / b
}

-add, -sub etc flag to do the specific operation.flag package to input flag from user at runtime.calculator.go file main function. func main() {
add := flag.Bool("add", false, "Add two numbers")
subs := flag.Bool("subtract", false, "Subtract two numbers")
mult := flag.Bool("multiply", false, "Multiply two numbers")
div := flag.Bool("divide", false, "Divide two numbers")
flag.Parse()
flag package has Bool function which takes flag 3 parameters (flag-name, default value, description). flag.Parse() is to parse the command line into the defined flags.flag.Parse() line. var first, second int
fmt.Println("Enter 1st Number: ")
fmt.Scan(&first)
fmt.Println("Enter 2nd Number: ")
fmt.Scan(&second)
switch case for ease. switch {
case *add:
fmt.Printf("Additon: %d \n", addition(a, b))
case *subs:
fmt.Printf("Difference: %d \n", subtract(a, b))
case *mult:
fmt.Printf("Product: %d \n", multiply(a, b))
case *div:
fmt.Printf("Division: %d \n", division(a, b))
default:
fmt.Fprintln(os.Stderr, "Wrong option try with add, subtract, div and multply")
os.Exit(1)
}
os.Exit(1) which means to abort the program immediately.calcualtor.go file looks like below. package main
import (
"flag"
"fmt"
"os"
)
func main() {
add := flag.Bool("add", false, "Add two numbers")
subs := flag.Bool("subtract", false, "Subtract two numbers")
mult := flag.Bool("multiply", false, "Multiply two numbers")
div := flag.Bool("divide", false, "Divide two numbers")
flag.Parse()
var a, b int
fmt.Println("Enter 1st Number: ")
fmt.Scan(&a)
fmt.Println("Enter 2nd Number: ")
fmt.Scan(&b)
switch {
case *add:
fmt.Printf("Additon: %d \n", addition(a, b))
case *subs:
fmt.Printf("Difference: %d \n", subtract(a, b))
case *mult:
fmt.Printf("Product: %d \n", multiply(a, b))
case *div:
fmt.Printf("Division: %d \n", division(a, b))
default:
fmt.Fprintln(os.Stderr, "Wrong option try with add, subtract, div and multply")
os.Exit(1)
}
}
func addition(a int, b int) int {
return a + b
}
func subtract(a int, b int) int {
return a - b
}
func multiply(a int, b int) int {
return a * b
}
func division(a int, b int) int {
return a / b
}
go build. This will generate a calculator file in the directory. GOOS=windows go build, this will generate the calculator.exe file../calculator -add. It will ask for two numbers as inputs. Enter them and you will see the out as below.

So, this is your final running calculator CLI app with some taste of testing. I hope you like this blog. I am myself exploring Golang yet, if there is any way to improve the code or if you have any questions then please comment below. Thanks for reading 😊.