diff --git a/.gitea/workflows/fib-test.yaml b/.gitea/workflows/fib-test.yaml index a4e22e4..c27c82d 100644 --- a/.gitea/workflows/fib-test.yaml +++ b/.gitea/workflows/fib-test.yaml @@ -21,6 +21,7 @@ jobs: with: go-version: '1.24.4' check-latest: true - - name: Build the fib app + - name: Test build run: go build - - run: echo "🍏 This job's status is ${{ job.status }}." + - name: Test functions module + run: go test ./functions -v diff --git a/.gitignore b/.gitignore index 626e811..89b7ade 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ # Ignore everything * +.env # But not these files... !/.gitignore diff --git a/functions/fibonacci.go b/functions/fibonacci.go index 3e1adf2..0a06a25 100644 --- a/functions/fibonacci.go +++ b/functions/fibonacci.go @@ -1,9 +1,18 @@ package functions -func MyFibonacci(count int) (fibonaccivalue int) { +import( + "errors" + "fmt" +) + +func MyFibonacci(count int) (fibonaccivalue int, error error) { fibonaccivalue = 1 + error = nil var prev_fibonacci int = 0 + if count < 1 { + return -1, errors.New(fmt.Sprintf("%d is not a positive integer.",count)) + } for i := 1; i < count; i++ { fibonaccivalue += prev_fibonacci prev_fibonacci = fibonaccivalue - prev_fibonacci diff --git a/functions/flagcheck.go b/functions/flagcheck.go new file mode 100644 index 0000000..97a0be4 --- /dev/null +++ b/functions/flagcheck.go @@ -0,0 +1,15 @@ +package functions + +import ( + "flag" +) + +func FlagSet(name string) (found bool) { + found = false + flag.Visit(func (f *flag.Flag) { + if f.Name == name { + found = true + } + }) + return +} diff --git a/functions/functions_test.go b/functions/functions_test.go new file mode 100644 index 0000000..4a7d96c --- /dev/null +++ b/functions/functions_test.go @@ -0,0 +1,52 @@ +package functions + +import ( + "testing" + "fmt" +) + +// Test fibonacci function + +func TestFibonacci(t *testing.T) { + var sequence = [4]int{1, 3, 5, 9} + var values = [4]int{1, 2, 5, 34} + for i := 0; i < len(sequence); i++ { + var seq, want = sequence[i], values[i] + outcome, error := MyFibonacci(seq) + if error != nil { + t.Errorf("Error trying to Fibonacci %d: %s", seq, error) + } + if outcome != want { + t.Errorf("Invalid outcome: Fibonacci sequence %d should be %d, got %d", + seq, want, outcome) + } + } +} + +func TestFibBadNumber(t *testing.T) { + outcome,error := MyFibonacci(-4) + if error == nil { + t.Errorf("This should be an error, not a %d",outcome) + } +} + +func TestSums(t *testing.T) { + var tests = []struct{ + a, b int + want int + } { + {1, 2, 3}, + {5, 3, 8}, + {9, 4, 13}, + } + + for _, tt := range tests { + testname := fmt.Sprintf("%d+%d",tt.a, tt.b) + t.Run(testname, func(t *testing.T) { + result := sum(tt.a, tt.b) + if result != tt.want { + t.Errorf("Expected %d, got %d", tt.want,result) + } + }) + } +} diff --git a/functions/http.go b/functions/http.go index 31cf310..05096c7 100644 --- a/functions/http.go +++ b/functions/http.go @@ -46,8 +46,14 @@ func HttFibonacci(w http.ResponseWriter, request *http.Request) { } else { fmt.Printf("Received request for Fibonacci Sequence Number %d\n", seq) + value, error := MyFibonacci(seq) + if error != nil { + fmt.Printf("Error trying to Fibonacci %d: %s", seq, error) + fmt.Fprintf(w, "Error trying to Fibonacci %d: %s", seq, error) + } else { fmt.Fprintf(w, "Fibonacci sequence index [%d]: %d\n", - seq, MyFibonacci(seq)) + seq, value) + } } } diff --git a/main.go b/main.go index 1cb4b34..d787c2b 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,7 @@ import ( "net/http" "os" "strconv" + "flag" "github.com/joho/godotenv" @@ -15,7 +16,7 @@ func main() { var port_number int = 8098 // hard default var error error var bind_socket string - fmt.Println("Hello, world. I'm teaching myself Go.") + var seq, port int error = godotenv.Load() // Load .env file if error != nil { @@ -23,16 +24,7 @@ func main() { } port_arg := os.Getenv("FIB_PORT") if port_arg != "" { - fmt.Printf("Loaded port value '%s' from environment.\n", - port_arg) - } - if len(os.Args) > 1 { // commandline overrules env - port_arg = os.Args[1] - fmt.Printf("Loading port value '%s' from command line.\n", - port_arg) - } - - if port_arg != "" { + fmt.Printf("Loaded port value '%s' from environment.\n",port_arg) port_number, error = strconv.Atoi(port_arg) if error != nil { fmt.Printf("I had an error trying to parse '%s' into a number: %s\n", @@ -41,9 +33,28 @@ func main() { os.Exit(0) } } - bind_socket = fmt.Sprintf(":%d", port_number) - http.HandleFunc("/fibonacci", functions.HttFibonacci) - http.HandleFunc("/sum", functions.HttSum) - fmt.Printf("Listening on port %d...\n", port_number) - http.ListenAndServe(bind_socket, nil) + flag.IntVar(&port, "port", 8098, + fmt.Sprintf("Port number to bind to, default %d", port_number)) + flag.IntVar(&seq, "number", 0, + "Fibonacci sequence value to calculate") + flag.Parse() + + if functions.FlagSet("port") { // Command line overrides env + port_number = port + } + + if !functions.FlagSet("number") { + fmt.Printf("Listening on port %d...\n", port_number) + bind_socket = fmt.Sprintf(":%d", port_number) + http.HandleFunc("/fibonacci", functions.HttFibonacci) + http.HandleFunc("/sum", functions.HttSum) + http.ListenAndServe(bind_socket, nil) + } else { + value, error := functions.MyFibonacci(seq) + if error != nil { + fmt.Printf("Failed to Fibonacci %d: %s", seq, error) + } else { + fmt.Printf("%d", value) + } + } }