# (Excercise 1 - Golang) Numbers statistics- Golang and Ginkgo ## Part 1 - Using Golang and Ginkgo

Your task is to process a sequence of integer numbers to determine the following statistics:

• minimum value
• maximum value
• number of elements in the sequence
• average value

For example: `[6, 9, 15, -2, 92, 11]`

• minimum value = -2
• maximum value = 92
• number of elements in the sequence = 6
• average value = 21.833333

## Start in Ginkgo

In first excercise we'll do everything from scratch. First prepare your tools:

#### Project structure

First create project directory and cwd to it and install testing framework.

```mkdir gobdds
cd gobdds

go get github.com/onsi/ginkgo/ginkgo
go get github.com/onsi/gomega
```

I'm using Ginkgo as BDD framework and Gomega as matcher (assert) library If You are familiar with Mocha or RSpec then tests written in Ginkgo will be similiar.

To simplify tests all files will be in the same folder (I didin't check yet how to organize code with this technique).

```. - your sources
gobdds_suite_test.go
stats.go
stats_test.go
```

If you check PHP or JS sources with the same excercise you can realize that naming (calc `=` stats etc) is little odd it's because I don't have enough time to polish these things up, sorry.

Now we can write some tests. First we create bootstrap like in documentation import bddgo, and bdd framework and matcher next we are doing simple describe for each expectation we should collect new result.

In `It` function we'll define our first `min` calculation expectations.

```package bddgo_test

import (
. "github.com/exu/bddgo"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

var _ = Describe("Stats generator", func() {

})
```

### Our function result:

We create `collect` method which will return object with `min`, `max`, `avg`, `sum`, `count` keys.

### When We have plan, we can start writing specs

#### Prerequisities (creating matcher)

Our first task is to calculate minimum value from given input.

#### Min specification

Now We're ready for specifing. Inside `Describe` function block insert following code:

```var result map[string]int
BeforeEach(func() {
input := []int{3, 3, 4, 5, 6, 99, -99, 7, 8, 64}
result = Collect(input)
})

It("collects min information", func() {
Expect(result["min"]).To(Equal(-99))
})
```
```ginkgo
```

you can run it with standard `go test` command

Ginkgo should fail with message:

```./stats_test.go:30: undefined: Collect
```

#### Other specifications

1. With above technique We'll generate:
```It("collects max information", func() {
Expect(result["max"]).To(Equal(99))
})
It("collects avg information", func() {
Expect(result["avg"]).To(Equal(10))
})
It("collects len information", func() {
Expect(result["len"]).To(Equal(10))
})
It("collects sum information", func() {
Expect(result["sum"]).To(Equal(100))
})
```

### Writing code

Now our spec is ready - it'll be our library documentation - we can start writing code.

Remember to run `ginkgo` after each change.

#### Now it's time to implement minimum calculation from given input

```package bddgo

func Collect(arr []int) map[string]int {
out := make(map[string]int)
min := arr

for _, v := range arr {
if v < min {
min = v
}
}

out["min"] = min

return out
}
```

```\$ ginkgo

collects max information [It]
(/home/exu/go/src/github.com/exu/bddgo/stats_test.go:38)

Expected
<int>: 0
to equal
<int>: 99
```

It looks like first test passed. Now it's time to implement rest You can do it in little steps one by one, after each run `ginkgo` to check if you don't brake something in other tests. (You can run it with `-watch` - Ginkgo will watch your suite and run tests automatically on code change)

#### Now it's time to implement rest of library:

Whole library looks like this one below:

```package bddgo

func Collect(arr []int) map[string]int {
out := make(map[string]int)
min, max, sum, count := arr, arr, 0, len(arr)

for _, v := range arr {
if v < min {
min = v
}
if v > max {
max = v
}

sum += v
}

out["min"] = min
out["len"] = count
out["avg"] = sum / count
out["max"] = max
out["sum"] = max

return out
}
```

Run

```❯ ginkgo

Running Suite: Bddgo Suite
==========================
Random Seed: 1394745662
Will run 5 of 5 specs

••••••••••••••••••
Ran 5 of 5 Specs in 0.004 seconds
SUCCESS! -- 5 Passed | 0 Failed | 0 Pending | 0 Skipped PASS

Ginkgo ran in 4.06565762s
Test Suite Passed
```

Now all tests should go green :D

### Conslusions

You can compare Golang and Ginkgo BDD technique with other in the same excercise