diff --git a/internal/shortie/shortie_test.go b/internal/shortie/shortie_test.go new file mode 100644 index 0000000..c2b106d --- /dev/null +++ b/internal/shortie/shortie_test.go @@ -0,0 +1,246 @@ +package shortie + +import ( + "errors" + "fmt" + "os" + "reflect" + "testing" + + "github.com/patrickmn/go-cache" +) + +var ( + store = map[string]cache.Item{"google": {Object: "https://google.com"}} +) + +func TestGet(t *testing.T) { + Pool = cache.NewFrom(Exp, Cleanup, store) + tt := []struct { + name string + i string + v string + f bool + }{ + { + "Missing", + "test", + "", + false, + }, + { + "Found", + "google", + "https://google.com", + true, + }, + } + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + v, f := get(tc.i) + if !reflect.DeepEqual(v, tc.v) { + t.Fatalf("expected: %v, got %v", tc.v, v) + } + if !reflect.DeepEqual(f, tc.f) { + t.Fatalf("expected: %v, got %v", tc.f, f) + } + }) + } + Pool.Flush() +} + +func TestSet(t *testing.T) { + Pool = cache.New(Exp, Cleanup) + tt := []struct { + name string + k string + v string + f bool + }{ + { + "Set", + "Key", + "Value", + true, + }, + } + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + set(tc.v, tc.k) + v, err := get(tc.k) + if !reflect.DeepEqual(tc.v, v) { + t.Fatalf("expected: %v, got %v", tc.v, v) + } + if !reflect.DeepEqual(err, true) { + t.Fatalf("Key %s not found", tc.k) + } + }) + } + Pool.Flush() +} + +func TestRandStringBytesMaskImprSrc(t *testing.T) { + tt := []struct { + name string + i int + }{ + { + "10", + 10, + }, + { + "1", + 1, + }, + { + "100", + 100, + }, + } + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + s := randStringBytesMaskImprSrc(tc.i) + if len(s) != tc.i { + t.Fatalf("Bad Length, expecting %v got %v", tc.i, len(s)) + } + }) + } +} + +func benchmarkRandStringBytesMasImprSrc(i int, b *testing.B) { + for n := 0; n < b.N; n++ { + randStringBytesMaskImprSrc(i) + } +} + +func BenchmarkRandStringBytesMasImprSrc10(b *testing.B) { + benchmarkRandStringBytesMasImprSrc(10, b) +} + +func BenchmarkRandStringBytesMasImprSrc100(b *testing.B) { + benchmarkRandStringBytesMasImprSrc(100, b) +} + +func BenchmarkRandStringBytesMasImprSrc1000(b *testing.B) { + benchmarkRandStringBytesMasImprSrc(1000, b) +} + +func TestRedirect(t *testing.T) { + Pool = cache.NewFrom(Exp, Cleanup, store) + tt := []struct { + name string + i string + r string + err error + }{ + { + "Not Found", + "badkey", + "", + ErrNotFound, + }, + { + "Found", + "google", + "https://google.com", + nil, + }, + } + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + r, err := redirect(tc.i) + if !errors.Is(tc.err, err) { + t.Fatalf("Bad error, expected %v, got %v", tc.err, err) + } + if !reflect.DeepEqual(tc.r, r) { + t.Fatalf("Bad value, expected %v, got %v", tc.r, r) + } + }) + } +} + +func TestShortener(t *testing.T) { + tt := []struct { + name string + i string + s int + rs int + err error + }{ + { + "Bad Request", + "badurl", + 10, + 0, + ErrBadRequest, + }, + { + "Good Request", + "https://www.google.com", + 10, + 10, + nil, + }, + } + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + r, err := shortener(tc.i, tc.s) + if !errors.Is(tc.err, err) { + t.Fatalf("Bad error, expected %v, got %v", tc.err, err) + } + if len(r) != tc.rs { + t.Fatalf("Bad value, expected %v, got %v (%s)", tc.s, len(r), r) + } + }) + Pool.Flush() + } +} + +func TestDumpDbTOFile(t *testing.T) { + tt := []struct { + name string + p *cache.Cache + r int + f *os.File + err error + }{ + { + "Error", + cache.New(Exp, Cleanup), + 0, + func() *os.File { f, _ := os.Create(fmt.Sprintf("%s/.json", randStringBytesMaskImprSrc(5))); return f }(), + os.ErrInvalid, + }, + { + "0-v", + cache.New(Exp, Cleanup), + 0, + func() *os.File { f, _ := os.Create(fmt.Sprintf("%s.json", randStringBytesMaskImprSrc(5))); return f }(), + nil, + }, + { + "1-v", + cache.NewFrom(Exp, Cleanup, store), + 1, + func() *os.File { f, _ := os.Create(fmt.Sprintf("%s.json", randStringBytesMaskImprSrc(5))); return f }(), + nil, + }, + } + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + Pool = tc.p + r, err := dumpDbTOFile(tc.f) + if !errors.Is(tc.err, err) { + t.Fatalf("Bad error, expected %#v, got %#v", tc.err, err) + } + if tc.r != r { + t.Fatalf("Bad value, expected %#v, got %#v", tc.r, r) + + } + }) + if tc.f != nil { + os.Remove(tc.f.Name()) + } + Pool.Flush() + } +}