Files
ozu.io/shortner/shortner_test.go
Jim Myhrberg 27bd7d32ed Use a mock store in Shortner tests
And also add benchmarks for shortner.Shorten and shortner.Lookup
functions.
2016-07-06 14:37:58 +01:00

163 lines
3.0 KiB
Go

package shortner
import (
"errors"
"strconv"
"sync"
"testing"
"github.com/jimeh/ozu.io/storage"
"github.com/stretchr/testify/suite"
)
// Test Cases
var shortenExamples = []struct {
uid string
url string
normalized string
}{
{uid: "ig", url: "google.com", normalized: "http://google.com/"},
{uid: "ih", url: "https://google.com", normalized: "https://google.com/"},
{uid: "ig", url: "http://google.com", normalized: "http://google.com/"},
{uid: "ih", url: "https://google.com/"},
{uid: "ig", url: "google.com/", normalized: "http://google.com/"},
{uid: "ii", url: "https://github.com/"},
{uid: "ij", url: "https://gist.github.com/"},
}
// Mocks
func NewMockStore() *MockStore {
return &MockStore{
Data: map[string][]byte{},
Sequence: 1000,
}
}
type MockStore struct {
sync.RWMutex
Data map[string][]byte
Sequence int
}
func (s *MockStore) Close() error {
return nil
}
func (s *MockStore) Get(key []byte) ([]byte, error) {
s.RLock()
defer s.RUnlock()
value := s.Data[string(key)]
if value == nil {
return nil, errors.New("not found")
}
return value, nil
}
func (s *MockStore) Set(key []byte, value []byte) error {
s.Lock()
defer s.Unlock()
s.Data[string(key)] = value
return nil
}
func (s *MockStore) Delete(key []byte) error {
s.Lock()
defer s.Unlock()
delete(s.Data, string(key))
return nil
}
func (s *MockStore) NextSequence() (int, error) {
s.Lock()
defer s.Unlock()
s.Sequence++
return s.Sequence, nil
}
// Setup Suite
type ShortnerSuite struct {
suite.Suite
shortner *Shortner
store storage.Store
}
func (s *ShortnerSuite) SetupTest() {
s.store = NewMockStore()
s.shortner = New(s.store)
}
func (s *ShortnerSuite) Seed() {
r := s.Require()
for _, e := range shortenExamples {
uid, url, err := s.shortner.Shorten([]byte(e.url))
r.Equal([]byte(e.uid), uid)
if e.normalized != "" {
r.Equal([]byte(e.normalized), url)
} else {
r.Equal([]byte(e.url), url)
}
r.NoError(err)
}
}
// Tests
func (s *ShortnerSuite) TestShorten() {
for _, e := range shortenExamples {
uid, url, err := s.shortner.Shorten([]byte(e.url))
s.Equal(nil, err)
s.Equal([]byte(e.uid), uid)
if e.normalized != "" {
s.Equal([]byte(e.normalized), url)
} else {
s.Equal([]byte(e.url), url)
}
}
}
func (s *ShortnerSuite) TestLookup() {
s.Seed()
for _, e := range shortenExamples {
url, err := s.shortner.Lookup([]byte(e.uid))
s.NoError(err)
if e.normalized != "" {
s.Equal([]byte(e.normalized), url)
} else {
s.Equal([]byte(e.url), url)
}
}
}
// Run Suite
func TestShortnerSuite(t *testing.T) {
suite.Run(t, new(ShortnerSuite))
}
// Benchmarks
func BenchmarkShorten(b *testing.B) {
shortner := New(NewMockStore())
rawURL := []byte("https://google.com/")
for n := 0; n < b.N; n++ {
_, _, _ = shortner.Shorten(append(rawURL, strconv.Itoa(n)...))
}
}
func BenchmarkLookup(b *testing.B) {
shortner := New(NewMockStore())
rawURL := []byte("https://google.com/")
uid, _, _ := shortner.Shorten(rawURL)
for n := 0; n < b.N; n++ {
_, _ = shortner.Lookup(uid)
}
}