Merge pull request 'chore/internal' (#3) from chore/internal into main
Reviewed-on: #3
This commit is contained in:
commit
084f1b7aa9
6
go.mod
6
go.mod
@ -6,10 +6,12 @@ require (
|
||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
|
||||
github.com/fasthttp/router v1.4.9
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/valyala/fasthttp v1.36.0
|
||||
github.com/wolviecb/short/shortie v0.0.0-20220412102501-705312b4dffe
|
||||
github.com/valyala/fasthttp v1.37.0
|
||||
internal/shortie v0.0.0-00010101000000-000000000000
|
||||
)
|
||||
|
||||
replace internal/shortie => ./internal/shortie
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
github.com/klauspost/compress v1.15.4 // indirect
|
||||
|
29
go.sum
29
go.sum
@ -1,20 +1,11 @@
|
||||
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
|
||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
|
||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/fasthttp/router v1.4.8 h1:4zj4sAzXibjA6ZW19MdMe3GaYD1SM+TXrMLzHcVMBOI=
|
||||
github.com/fasthttp/router v1.4.8/go.mod h1:UUtJdXFYlqYRQ32EAtWOvNYIZ1XfyC5JJIknWai6foI=
|
||||
github.com/fasthttp/router v1.4.9 h1:8s1HEqP+GvsC2B8vPdLAPHJegs4s28z7UsraPuHM1K8=
|
||||
github.com/fasthttp/router v1.4.9/go.mod h1:oWPrQCi9QOrzxKC+rZuliS1+JhYj2bpR01J6T8vUDUQ=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.11.6/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A=
|
||||
github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.15.4 h1:1kn4/7MepF/CHmYub99/nNX8az0IJjfSOU/jbnTVfqQ=
|
||||
github.com/klauspost/compress v1.15.4/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||
@ -23,27 +14,13 @@ github.com/savsgio/gotils v0.0.0-20220401102855-e56b59f40436 h1:sfTahD3f2BSjx9U3
|
||||
github.com/savsgio/gotils v0.0.0-20220401102855-e56b59f40436/go.mod h1:Gy+0tqhJvgGlqnTF8CVGP0AaGRjwBtXs/a5PA0Y3+A4=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.19.0/go.mod h1:jjraHZVbKOXftJfsOYoAjaeygpj5hr8ermTRJNroD7A=
|
||||
github.com/valyala/fasthttp v1.35.0 h1:wwkR8mZn2NbigFsaw2Zj5r+xkmzjbrA/lyTmiSlal/Y=
|
||||
github.com/valyala/fasthttp v1.35.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
|
||||
github.com/valyala/fasthttp v1.36.0 h1:NhqfO/cB7Ajn1czkKnWkMHyPYr5nyND14ZGPk23g0/c=
|
||||
github.com/valyala/fasthttp v1.36.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
|
||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
||||
github.com/valyala/fasthttp v1.37.0 h1:7WHCyI7EAkQMVmrfBhWTCOaeROb1aCBiTopx63LkMbE=
|
||||
github.com/valyala/fasthttp v1.37.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
github.com/wolviecb/short/shortie v0.0.0-20210110145449-4edfb0344225 h1:BB+2AaTpi+jtEJaNTmoM12ddkgAwMFgTtNXnVWJMtvY=
|
||||
github.com/wolviecb/short/shortie v0.0.0-20210110145449-4edfb0344225/go.mod h1:MP++yL+vt6bdR5ResHARM9XzrdxEzqYPkyODGTsjFJs=
|
||||
github.com/wolviecb/short/shortie v0.0.0-20220412102501-705312b4dffe h1:3GiAtzvN0/Xig4LOCI5t6MNDI9CY0YQnNyktrXYF3yM=
|
||||
github.com/wolviecb/short/shortie v0.0.0-20220412102501-705312b4dffe/go.mod h1:MP++yL+vt6bdR5ResHARM9XzrdxEzqYPkyODGTsjFJs=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@ -51,8 +28,6 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
@ -1,11 +1,11 @@
|
||||
module github.com/wolviecb/short/shortie
|
||||
module shortie
|
||||
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/valyala/fasthttp v1.36.0
|
||||
github.com/valyala/fasthttp v1.37.0
|
||||
)
|
||||
|
||||
require (
|
@ -9,8 +9,8 @@ github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaR
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.36.0 h1:NhqfO/cB7Ajn1czkKnWkMHyPYr5nyND14ZGPk23g0/c=
|
||||
github.com/valyala/fasthttp v1.36.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
|
||||
github.com/valyala/fasthttp v1.37.0 h1:7WHCyI7EAkQMVmrfBhWTCOaeROb1aCBiTopx63LkMbE=
|
||||
github.com/valyala/fasthttp v1.37.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
@ -4,11 +4,11 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
@ -57,6 +57,9 @@ var (
|
||||
Path string = ""
|
||||
// DumpFile is the file to dump URL data
|
||||
DumpFile string = "urls.json"
|
||||
// Error Definitions
|
||||
ErrBadRequest = fmt.Errorf("bad request")
|
||||
ErrNotFound = fmt.Errorf("not found")
|
||||
)
|
||||
|
||||
// get executes the GET command
|
||||
@ -98,7 +101,7 @@ func redirect(k string) (string, error) {
|
||||
key := rgx.FindString(k)
|
||||
key, status := get(key)
|
||||
if !status {
|
||||
return "", fmt.Errorf("Not Found")
|
||||
return "", ErrNotFound
|
||||
}
|
||||
u, _ := url.Parse(key)
|
||||
if u.Scheme == "" {
|
||||
@ -110,13 +113,12 @@ func redirect(k string) (string, error) {
|
||||
// shortener receive a url, validates the url, generate a random suffix string
|
||||
// of urlSize size, checks if the suffix string is ensure on the kv database
|
||||
// and then writes the kv pair (suffix, url) to the database, returning the suffix
|
||||
func shortener(u []byte, s int) (string, error) {
|
||||
func shortener(u string, s int) (string, error) {
|
||||
var su string
|
||||
us := string(u)
|
||||
if !govalidator.IsURL(string(us)) {
|
||||
return su, fmt.Errorf("Bad Request")
|
||||
if !govalidator.IsURL(string(u)) {
|
||||
return su, ErrBadRequest
|
||||
}
|
||||
pu, _ := url.Parse(us)
|
||||
pu, _ := url.Parse(u)
|
||||
|
||||
for {
|
||||
su = randStringBytesMaskImprSrc(s)
|
||||
@ -131,16 +133,19 @@ func shortener(u []byte, s int) (string, error) {
|
||||
}
|
||||
|
||||
// dumpDbToFile dumps the kv pairs from the in memory database to file
|
||||
func dumpDbTOFile() (int, error) {
|
||||
func dumpDbTOFile(f *os.File) (int, error) {
|
||||
i := Pool.Items()
|
||||
dumpObj, _ := json.Marshal(i)
|
||||
return len(i), ioutil.WriteFile(DumpFile, dumpObj, 0644)
|
||||
if _, err := f.Write(dumpObj); err != nil {
|
||||
return len(i), err
|
||||
}
|
||||
return len(i), nil
|
||||
}
|
||||
|
||||
// loadFromFile loads kv pairs from the dumpFile json to the in memory database
|
||||
func loadFromFile() (int, error) {
|
||||
dumpObj := make(map[string]cache.Item)
|
||||
jsonFile, err := ioutil.ReadFile(DumpFile)
|
||||
jsonFile, err := os.ReadFile(DumpFile)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -154,7 +159,7 @@ func loadFromFile() (int, error) {
|
||||
return len(dumpObj), err
|
||||
}
|
||||
|
||||
// itemsFromPost loads kv pairs from a json POST to the in memory database
|
||||
// loadFromJSON loads kv pairs from a json to the in memory database
|
||||
func loadFromJSON(j []byte) (int, error) {
|
||||
dumpObj := make(map[string]cache.Item)
|
||||
err := json.Unmarshal(j, &dumpObj)
|
||||
@ -195,7 +200,7 @@ func IndexHandler(t *template.Template) func(ctx *fasthttp.RequestCtx) {
|
||||
func Short(t *template.Template) func(ctx *fasthttp.RequestCtx) {
|
||||
return func(ctx *fasthttp.RequestCtx) {
|
||||
ctx.Response.Header.SetCanonical([]byte("Content-Type"), []byte("text/html"))
|
||||
suf, err := shortener(ctx.FormValue("url"), URLSize)
|
||||
suf, err := shortener(string(ctx.FormValue("url")), URLSize)
|
||||
if err != nil {
|
||||
ctx.SetStatusCode(fasthttp.StatusBadRequest)
|
||||
t.Execute(ctx, body{
|
||||
@ -247,7 +252,14 @@ func Redir(t *template.Template) func(ctx *fasthttp.RequestCtx) {
|
||||
// KV db to the DumpFile file
|
||||
func ToFile(t *template.Template) func(ctx *fasthttp.RequestCtx) {
|
||||
return func(ctx *fasthttp.RequestCtx) {
|
||||
i, err := dumpDbTOFile()
|
||||
f, err := os.Create(DumpFile)
|
||||
if err != nil {
|
||||
ctx.SetStatusCode(http.StatusInternalServerError)
|
||||
ctx.Response.Header.SetCanonical([]byte("Content-Type"), []byte("text/html"))
|
||||
t.Execute(ctx, internalError("Failed to create DB dump file", err))
|
||||
return
|
||||
}
|
||||
i, err := dumpDbTOFile(f)
|
||||
if err != nil {
|
||||
ctx.SetStatusCode(http.StatusInternalServerError)
|
||||
ctx.Response.Header.SetCanonical([]byte("Content-Type"), []byte("text/html"))
|
246
internal/shortie/shortie_test.go
Normal file
246
internal/shortie/shortie_test.go
Normal file
@ -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()
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user