Hold My Emoji
Tags: tutorial, algorithms, go, testing
Published: 2019-08-12 14:33:39

Let's create a random emoji generator in `package emoji`.

Prepare a list of funny emoji codes 

:bike: :frog: :blowfish: :tada: :laughing: :clap: :surfer: :underage: :chocolate_bar: :beach_umbrella: :whale: :100: :nerd_face: :full_moon_with_face: :metal: :rofl: :cookie: :blossom: :bell: :santa: :mushroom: :red_car: :unicorn: :jack_o_lantern: :point_left: :trollface: :monkey: :sun_with_face: :octocat: :point_down: :pig_nose: :shopping: :baby_bottle: :feelsgood: :beers: :scream_cat: :eyes: :snowman_with_snow: :hatching_chick: :rocket: :cow: :nail_care: :bangbang: :helicopter: 

```go
var (
  AvailEmojies = []string{
    ":bike:",
    ":frog:",
    ":blowfish:",
    ":tada:",
    ":laughing:",
    ":clap:",
    ":surfer:",
    ":underage:",
    ":chocolate_bar:",
    ":beach_umbrella:",
    ":whale:",
    ":100:",
    ":nerd_face:",
    ":full_moon_with_face:",
    ":metal:",
    ":rofl:",
    ":cookie:",
    ":blossom:",
    ":bell:",
    ":santa:",
    ":mushroom:",
    ":red_car:",
    ":unicorn:",
    ":jack_o_lantern:",
    ":point_left:",
    ":trollface:",
    ":monkey:",
    ":sun_with_face:",
    ":octocat:",
    ":point_down:",
    ":pig_nose:",
    ":shopping:",
    ":baby_bottle:",
    ":feelsgood:",
    ":beers:",
    ":scream_cat:",
    ":eyes:",
    ":snowman_with_snow:",
    ":hatching_chick:",
    ":rocket:",
    ":cow:",
    ":nail_care:",
    ":bangbang:",
    ":helicopter:",
  }
)
```

Prepare a helper function to generate a code every time being called. Using a random integer generation function in `math/rand`
```go
func RndEmoji() string {
  return AvailEmojies[rand.New(rand.NewSource(time.Now().UnixNano())).Intn(len(AvailEmojies))]
}
```

Almost done, for now, you can use it somewhere else for fun. Here I'd like to use the test feature provided by `go`.
Now, create a test file with suffix `_test` in the same location as emoji.go, called `emoji_test.go`

```go
import (
  "testing"
)

func TestEmoji(t *testing.T) {
  for i := 0; i < 10; i++ {
    t.Log(RndEmoji())
  }
}
```

Simple. Isn't it?
To run the test just `go test` it, use verbose mode to allow `Log` level info to print.
   `go test -v <GOPATH>/holdmyemoji`

```bash
=== RUN   TestEmoji
--- PASS: TestEmoji (0.01s)
    emoji_test.go:9: :whale:
    emoji_test.go:9: :unicorn:
    emoji_test.go:9: :metal:
    emoji_test.go:9: :octocat:
    emoji_test.go:9: :monkey:
    emoji_test.go:9: :sun_with_face:
    emoji_test.go:9: :nail_care:
    emoji_test.go:9: :helicopter:
    emoji_test.go:9: :unicorn:
    emoji_test.go:9: :bell:
PASS
```

The test can also be built first by `go test <GOPATH>/rndemoji -c -o emoji`, then you can run `./emoji -test.v` multiple times. 
```bash
=== RUN   TestEmoji
--- PASS: TestEmoji (0.01s)
    emoji_test.go:9: :santa:
    emoji_test.go:9: :tada:
    emoji_test.go:9: :pig_nose:
    emoji_test.go:9: :rocket:
    emoji_test.go:9: :eyes:
    emoji_test.go:9: :full_moon_with_face:
    emoji_test.go:9: :100:
    emoji_test.go:9: :trollface:
    emoji_test.go:9: :pig_nose:
    emoji_test.go:9: :bangbang:
PASS
```

Also, to have more fun, shuffle the list every time before generating, the list changes from time to time. It, of course, will cost more computation.
```go
  for i := range AvailEmojies {
    j := rand.New(rand.NewSource(time.Now().UnixNano())).Intn(i+1)
    AvailEmojies[j], AvailEmojies[i] = AvailEmojies[i], AvailEmojies[j]
  }
```
---
Use your funny list, play with it :rocket: