diff --git a/CHANGELOG.md b/CHANGELOG.md index 345878c..3a95b59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] +### Added +- User settings for caching (pokeapi.CacheSettings) + - CustomExpire: set a custom cache expiration (in minutes) + - UseCache: turn caching on/off + ## [1.3.2] / 2020.04.03 ### Added - Current version to README. diff --git a/Makefile b/Makefile index 09280e8..f65a7b9 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,9 @@ deps: tidy vend test: ${GOTEST} -v -race ${CODECOVFLAGS} ./... +test-client: + ${GOTEST} -v ./. + tidy: ${GOMOD} tidy -v diff --git a/README.md b/README.md index f9530b0..41934c5 100644 --- a/README.md +++ b/README.md @@ -1000,6 +1000,35 @@ As an alternative to `pokeapi.Resource()`, you can use Search to filter resource ### Caching -Calls are automatically cached to cut down on API traffic to PokeAPI, with subsequent calls (up to five minutes currently) returning local data. You can clear *all* existing cache data with `pokeapi.ClearCache()`. +Calls are automatically cached to cut down on API traffic to PokeAPI, with subsequent calls returning local data. -Forced non-cached calls and custom cache expiration coming soon. +#### Clearing Cache + +```go +// Clear all existing cache entries. +pokeapi.ClearCache() +``` + +#### Custom Expiration + +Custom cache expiration remains for all calls until changed or unset. + +```go +// Set cache expiration to twenty minutes. +pokeapi.CacheSettings.CustomExpire = 20 +// Turn custom expiration back off. +pokeapi.CacheSettings.CustomExpire = 0 +``` + +#### Disable Cache + +_Please be considerate of PokeAPI and be sure to always operate within this requested limits._ + +As with custom expiration, this setting remains for all calls until changed or unset. + +```go +// Disable checking for cached data +pokeapi.CacheSettings.UseCache = false +// Re-enable checking for cached data +pokeapi.CacheSettings.UseCache = true +``` diff --git a/cache.go b/cache.go new file mode 100644 index 0000000..36685eb --- /dev/null +++ b/cache.go @@ -0,0 +1,39 @@ +package pokeapi + +import "time" + +var CacheSettings = Settings{ + CustomExpire: 0, + UseCache: true, +} + +var defaultCacheSettings = defaultSettings{ + MaxExpire: 10 * time.Minute, + MinExpire: 5 * time.Minute, +} + +// defaultSettings are settings not meant to be changed. +type defaultSettings struct { + MaxExpire time.Duration + MinExpire time.Duration +} + +// CacheSettings are user settings for cache expiration. +type Settings struct { + CustomExpire time.Duration + UseCache bool +} + +// ClearCache clears all cached data. +func ClearCache() { + c.Flush() +} + +// setCache adds new item to local cache. +func setCache(endpoint string, body []byte) { + if CacheSettings.CustomExpire != 0 { + c.Set(endpoint, body, CacheSettings.CustomExpire * time.Minute) + } else { + c.SetDefault(endpoint, body) + } +} \ No newline at end of file diff --git a/client.go b/client.go index e675d75..28dcba0 100644 --- a/client.go +++ b/client.go @@ -10,23 +10,16 @@ import ( ) const apiurl = "https://pokeapi.co/api/v2/" -const cachemin = 5 -const cachemax = 10 var c *cache.Cache func init() { - c = cache.New(cachemin*time.Minute, cachemax*time.Minute) -} - -// ClearCache clears all cached data. -func ClearCache() { - c.Flush() + c = cache.New(defaultCacheSettings.MinExpire, defaultCacheSettings.MaxExpire) } func do(endpoint string, obj interface{}) error { cached, found := c.Get(endpoint) - if found { + if found && CacheSettings.UseCache { return json.Unmarshal(cached.([]byte), &obj) } @@ -47,6 +40,6 @@ func do(endpoint string, obj interface{}) error { return err } - c.Set(endpoint, body, cache.DefaultExpiration) + setCache(endpoint, body) return json.Unmarshal(body, &obj) } diff --git a/client_test.go b/client_test.go index 6f970cb..f8ae1fd 100644 --- a/client_test.go +++ b/client_test.go @@ -3,6 +3,7 @@ package pokeapi import ( "encoding/json" "testing" + "time" "github.com/mtslzr/pokeapi-go/structs" "github.com/stretchr/testify/assert" @@ -49,3 +50,34 @@ func TestClearCache(t *testing.T) { assert.Equal(t, nil, nocache, "Expect no data after flushing cache.") } + +func TestCustomExpiration(t *testing.T) { + ClearCache() + defaultExpire := time.Now().Add(defaultCacheSettings.MinExpire).Minute() + _ = do(endpoint, &mockResource) + _, expires1, _ := c.GetWithExpiration(endpoint) + assert.Equal(t, defaultExpire, expires1.Minute(), + "Expect expiration time to match default setting.") + + ClearCache() + CacheSettings.CustomExpire = 20 + customExpire := time.Now().Add(CacheSettings.CustomExpire * time.Minute).Minute() + _ = do(endpoint, &mockResource) + _, expires2, _ := c.GetWithExpiration(endpoint) + assert.Equal(t, customExpire, expires2.Minute(), + "Expect expiration time to match custom setting.") +} + +func TestNoCache(t *testing.T) { + ClearCache() + _ = do(endpoint, &mockResource) + _, expires1, found1 := c.GetWithExpiration(endpoint) + assert.Equal(t, true, found1, + "Expect to have cached data after first call.") + + CacheSettings.UseCache = false + _ = do(endpoint, &mockResource) + _, expires2, _ := c.GetWithExpiration(endpoint) + assert.NotEqual(t, expires1, expires2, + "Expect cache expiration not to match first call.") +}