diff --git a/.vscode/settings.json b/.vscode/settings.json index 6a0dbdc..ce61a52 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -32,6 +32,7 @@ "gomega", "gomnd", "goreleaser", + "goroutines", "gosec", "gosimple", "goveralls", @@ -62,6 +63,7 @@ "Taskfile", "testcache", "thelper", + "toplevel", "tparallel", "typecheck", "unconvert", diff --git a/Taskfile.yml b/Taskfile.yml index 635c624..f1baea4 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -11,6 +11,22 @@ silent: true dotenv: [".env"] +vars: + FORMAT: json + BINARY_NAME: pants + DEPLOY_DIR: ./locale/deploy + OUT_DIR: ./locale/out + L10N_DIR: ./locale/out/l10n + # + SOURCE_LANG: en-GB + SOURCE_ACTIVE: "active.{{.SOURCE_LANG}}.{{.FORMAT}}" + # + LANGUAGE_US: en-US + US_OUT_DIR: "{{.OUT_DIR}}/{{.LANGUAGE_US}}" + ACTIVE_US: "{{.BINARY_NAME}}.active.en-US.{{.FORMAT}}" + TRANSLATE_US: "{{.BINARY_NAME}}.translate.en-US.{{.FORMAT}}" + TRANSLATE_US_FILEPATH: "{{.US_OUT_DIR}}/{{.TRANSLATE_US}}" + tasks: # === build ================================================ @@ -166,30 +182,39 @@ tasks: clear: cmds: - - rm ./locale/out/* --recursive + - rm -rf {{.OUT_DIR}}/* --recursive # extract i18m messages extract: cmds: + - mkdir -p ./locale/out/l10n - goi18n extract -format json -sourceLanguage "en-GB" -outdir ./locale/out/l10n # new translation + # where is the default? locale/default/li18ngo.active.en-GB.json not populated + # ! creates: locale/out/l10n/active.en-GB.json => extracted output + # ! creates: locale/out/l10n/translate.en-US.json => empty newt: deps: [extract] cmds: - touch ./locale/out/l10n/translate.en-US.json # derive a translation from the default + # ! the default active file does not contain hashes, just the extracted content + # ! the foreign translate file contains the hashes + # ! the active foreign file (locale/out/l10n/active.en-US.json) is empty + # ! pass the translate file(locale/out/l10n/translate.en-US.json) to your translator + # merge: cmds: - goi18n merge -format json -sourceLanguage "en-GB" - -outdir ./locale/out - ./locale/out/active.en-GB.json ./locale/out/l10n/translate.en-US.json + -outdir ./locale/out/l10n + ./locale/out/l10n/active.en-GB.json ./locale/out/l10n/translate.en-US.json # update existing translations # after running this task, the translation file generated will @@ -203,7 +228,7 @@ tasks: -format json -sourceLanguage "en-GB" -outdir ./locale/out - ./locale/out/active.en-GB.json ./locale/deploy/active.en-US.json + ./locale/out/active.en-GB.json ./i18n/deploy/active.en-US.json # run this after manual translation has occurred to integrate it # back into the translation file. Unfortunately, this task doesn't @@ -215,5 +240,5 @@ tasks: - goi18n merge -format json -sourceLanguage "en-US" - -outdir ./locale/temp - ./locale/out/translate.en-US.json ./locale/deploy/active.en-US.json + -outdir ./i18n/temp + ./locale/out/translate.en-US.json ./i18n/deploy/active.en-US.json diff --git a/generic-pool.go b/generic-pool.go index a11a1a2..9694771 100644 --- a/generic-pool.go +++ b/generic-pool.go @@ -2,11 +2,11 @@ package pants import ( "context" - "errors" "time" "github.com/snivilised/pants/internal/ants" "github.com/snivilised/pants/internal/lo" + "github.com/snivilised/pants/locale" ) // functionalPool @@ -130,7 +130,9 @@ func fromOutputInfo[O any](o *Options, oi *outputInfo[O]) *outputInfoW[O] { } } -func respond[O any](ctx context.Context, wi *outputInfoW[O], output *JobOutput[O]) (err error) { +func respond[O any](ctx context.Context, + wi *outputInfoW[O], output *JobOutput[O], +) (err error) { select { case wi.outputCh <- *output: return nil @@ -139,7 +141,7 @@ func respond[O any](ctx context.Context, wi *outputInfoW[O], output *JobOutput[O case <-ctx.Done(): err = ctx.Err() case wi.cancelCh <- CancelWorkSignal{}: - err = errors.New("timeout") + err = locale.ErrTimeout } case <-ctx.Done(): diff --git a/go.mod b/go.mod index 17b3515..3bf46f1 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/nicksnyder/go-i18n/v2 v2.4.0 github.com/onsi/ginkgo/v2 v2.20.0 github.com/onsi/gomega v1.34.1 + github.com/snivilised/li18ngo v0.1.2 ) require ( @@ -13,13 +14,12 @@ require ( github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect - github.com/kr/pretty v0.3.1 // indirect - github.com/rogpeppe/go-internal v1.11.0 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/pkg/errors v0.9.1 // indirect golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/net v0.28.0 // indirect golang.org/x/sys v0.24.0 // indirect golang.org/x/text v0.17.0 // indirect golang.org/x/tools v0.24.0 // indirect - gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index f6fd67c..4d21dd5 100644 --- a/go.sum +++ b/go.sum @@ -21,12 +21,14 @@ github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/snivilised/li18ngo v0.1.2 h1:xiOZnAcIkeHfEVuTy/FBwA1u9IrAfYSjO/DYMC77z/I= +github.com/snivilised/li18ngo v0.1.2/go.mod h1:Or3qUhpR6AM1X51i82RtyCvORWy2/hrxY9lg1i1gFTE= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= diff --git a/internal/ants/ants_test.go b/internal/ants/ants_test.go index 5651cb3..22b6799 100644 --- a/internal/ants/ants_test.go +++ b/internal/ants/ants_test.go @@ -2,6 +2,8 @@ package ants_test import ( "context" + "fmt" + "os" "runtime" "sync" "time" @@ -9,11 +11,43 @@ import ( . "github.com/onsi/ginkgo/v2" //nolint:revive // ok . "github.com/onsi/gomega" //nolint:revive // ok + "github.com/snivilised/li18ngo" "github.com/snivilised/pants" "github.com/snivilised/pants/internal/ants" + "github.com/snivilised/pants/internal/helpers" + "github.com/snivilised/pants/locale" ) -var _ = Describe("Ants", func() { +var _ = Describe("Ants", Ordered, func() { + var ( + repo string + l10nPath string + testTranslationFile li18ngo.TranslationFiles + ) + + BeforeAll(func() { + repo = helpers.Repo("") + l10nPath = helpers.Path(repo, "test/data/l10n") + + _, err := os.Stat(l10nPath) + Expect(err).To(Succeed(), + fmt.Sprintf("l10n '%v' path does not exist", l10nPath), + ) + + testTranslationFile = li18ngo.TranslationFiles{ + li18ngo.Li18ngoSourceID: li18ngo.TranslationSource{Name: "test"}, + } + }) + + BeforeEach(func() { + if err := li18ngo.Use(func(o *li18ngo.UseOptions) { + o.Tag = li18ngo.DefaultLanguage + o.From.Sources = testTranslationFile + }); err != nil { + Fail(err.Error()) + } + }) + Context("NewPool", func() { Context("Submit", func() { When("non-blocking", func() { @@ -49,7 +83,8 @@ var _ = Describe("Ants", func() { Expect(pool.Submit(ctx, fn)).To(Succeed(), "nonblocking submit when pool is not full shouldn't return error", ) - Expect(pool.Submit(ctx, demoFunc)).To(MatchError(ants.ErrPoolOverload.Error()), + Expect(pool.Submit(ctx, demoFunc)).To( + MatchError(locale.ErrPoolOverload.Error()), "nonblocking submit when pool is full should get an ErrPoolOverload", ) @@ -104,7 +139,8 @@ var _ = Describe("Ants", func() { }() time.Sleep(1 * time.Second) // already reached max blocking limit - Expect(pool.Submit(ctx, demoFunc)).To(MatchError(ants.ErrPoolOverload.Error()), + Expect(pool.Submit(ctx, demoFunc)).To( + MatchError(locale.ErrPoolOverload.Error()), "blocking submit when pool reach max blocking submit should return ErrPoolOverload", ) diff --git a/internal/ants/errors.go b/internal/ants/errors.go deleted file mode 100644 index a1528d5..0000000 --- a/internal/ants/errors.go +++ /dev/null @@ -1,29 +0,0 @@ -package ants - -import "errors" - -var ( - // ErrLackPoolFunc will be returned when invokers don't provide function for pool. - ErrLackPoolFunc = errors.New("must provide function for pool") - - // ErrInvalidPoolExpiry will be returned when setting a negative number as the periodic duration to purge goroutines. - ErrInvalidPoolExpiry = errors.New("invalid expiry for pool") - - // ErrPoolClosed will be returned when submitting task to a closed pool. - ErrPoolClosed = errors.New("this pool has been closed") - - // ErrPoolOverload will be returned when the pool is full and no workers available. - ErrPoolOverload = errors.New("too many goroutines blocked on submit or Nonblocking is set") - - // ErrInvalidPreAllocSize will be returned when trying to set up a negative capacity under PreAlloc mode. - ErrInvalidPreAllocSize = errors.New("can not set up a negative capacity under PreAlloc mode") - - // ErrTimeout will be returned after the operations timed out. - ErrTimeout = errors.New("operation timed out") - - // ErrInvalidPoolIndex will be returned when trying to retrieve a pool with an invalid index. - ErrInvalidPoolIndex = errors.New("invalid pool index") - - // ErrInvalidLoadBalancingStrategy will be returned when trying to create a MultiPool with an invalid load-balancing strategy. - ErrInvalidLoadBalancingStrategy = errors.New("invalid load-balancing strategy") -) diff --git a/internal/ants/pool-func.go b/internal/ants/pool-func.go index 65d5f13..eb83635 100644 --- a/internal/ants/pool-func.go +++ b/internal/ants/pool-func.go @@ -30,6 +30,7 @@ import ( "time" "github.com/snivilised/pants/internal/ants/async" + "github.com/snivilised/pants/locale" ) // PoolWithFunc accepts the tasks and process them concurrently, @@ -135,7 +136,7 @@ func NewPoolWithFunc(ctx context.Context, options ...Option, ) (*PoolWithFunc, error) { if pf == nil { - return nil, ErrLackPoolFunc + return nil, locale.ErrLackPoolFunc } opts := NewOptions(options...) @@ -147,7 +148,7 @@ func NewPoolWithFunc(ctx context.Context, if !opts.DisablePurge { if expiry := opts.ExpiryDuration; expiry < 0 { - return nil, ErrInvalidPoolExpiry + return nil, locale.ErrInvalidPoolExpiry } else if expiry == 0 { opts.ExpiryDuration = DefaultCleanIntervalTime } @@ -193,7 +194,7 @@ func NewPoolWithFunc(ctx context.Context, // you should instantiate a PoolWithFunc with ants.WithNonblocking(true). func (p *PoolWithFunc) Invoke(ctx context.Context, job InputParam) error { if p.IsClosed() { - return ErrPoolClosed + return locale.ErrPoolClosed } w, err := p.retrieveWorker() @@ -242,7 +243,7 @@ retry: if p.o.Nonblocking || exceeded { p.lock.Unlock() - return nil, ErrPoolOverload + return nil, locale.ErrPoolOverload } // Otherwise, we'll have to keep them blocked and wait for at least one worker @@ -254,7 +255,7 @@ retry: if p.IsClosed() { p.lock.Unlock() - return nil, ErrPoolClosed + return nil, locale.ErrPoolClosed } goto retry diff --git a/internal/ants/pool.go b/internal/ants/pool.go index 9ee0895..c599523 100644 --- a/internal/ants/pool.go +++ b/internal/ants/pool.go @@ -30,6 +30,7 @@ import ( "time" "github.com/snivilised/pants/internal/ants/async" + "github.com/snivilised/pants/locale" ) // Pool accepts the tasks and process them concurrently, @@ -140,7 +141,7 @@ func NewPool(ctx context.Context, options ...Option) (*Pool, error) { if !opts.DisablePurge { if expiry := opts.ExpiryDuration; expiry < 0 { - return nil, ErrInvalidPoolExpiry + return nil, locale.ErrInvalidPoolExpiry } else if expiry == 0 { opts.ExpiryDuration = DefaultCleanIntervalTime } @@ -188,7 +189,7 @@ func NewPool(ctx context.Context, options ...Option) (*Pool, error) { // a Pool with ants.WithNonblocking(true). func (p *Pool) Submit(ctx context.Context, task TaskFunc) error { if p.IsClosed() { - return ErrPoolClosed + return locale.ErrPoolClosed } w, err := p.retrieveWorker() @@ -239,7 +240,7 @@ retry: if p.o.Nonblocking || exceeded { p.lock.Unlock() - return nil, ErrPoolOverload + return nil, locale.ErrPoolOverload } // Otherwise, we'll have to keep them blocked and wait for at least one @@ -251,7 +252,7 @@ retry: if p.IsClosed() { p.lock.Unlock() - return nil, ErrPoolClosed + return nil, locale.ErrPoolClosed } goto retry diff --git a/internal/ants/worker-loop-queue.go b/internal/ants/worker-loop-queue.go index 6c4cb1b..91d2ad4 100644 --- a/internal/ants/worker-loop-queue.go +++ b/internal/ants/worker-loop-queue.go @@ -25,6 +25,8 @@ package ants import ( "context" "time" + + "github.com/snivilised/pants/locale" ) type loopQueue struct { @@ -65,11 +67,11 @@ func (wq *loopQueue) isEmpty() bool { func (wq *loopQueue) insert(w worker) error { if wq.size == 0 { - return errQueueIsReleased + return locale.ErrQueueIsReleased } if wq.isFull { - return errQueueIsFull + return locale.ErrQueueIsFull } wq.items[wq.tail] = w wq.tail = (wq.tail + 1) % wq.size diff --git a/internal/ants/worker-pool.go b/internal/ants/worker-pool.go index 2367858..822779a 100644 --- a/internal/ants/worker-pool.go +++ b/internal/ants/worker-pool.go @@ -5,6 +5,8 @@ import ( "sync" "sync/atomic" "time" + + "github.com/snivilised/pants/locale" ) type workerPool struct { @@ -118,7 +120,7 @@ func (p *workerPool) Release(ctx context.Context) { func (p *workerPool) ReleaseTimeout(ctx context.Context, timeout time.Duration) error { purge := (!p.o.DisablePurge && p.stopPurge == nil) if p.IsClosed() || purge || p.stopTicktock == nil { - return ErrPoolClosed + return locale.ErrPoolClosed } p.Release(ctx) @@ -132,7 +134,7 @@ func (p *workerPool) ReleaseTimeout(ctx context.Context, timeout time.Duration) time.Sleep(releaseTimeoutInterval * time.Millisecond) } - return ErrTimeout + return locale.ErrTimeout } func (p *workerPool) addRunning(delta int) { diff --git a/internal/ants/worker-queue.go b/internal/ants/worker-queue.go index e4e51ea..ebd0f62 100644 --- a/internal/ants/worker-queue.go +++ b/internal/ants/worker-queue.go @@ -24,18 +24,9 @@ package ants import ( "context" - "errors" "time" ) -var ( - // errQueueIsFull will be returned when the worker queue is full. - errQueueIsFull = errors.New("the queue is full") - - // errQueueIsReleased will be returned when trying to insert item to a released worker queue. - errQueueIsReleased = errors.New("the queue length is zero") -) - type worker interface { run() finish(context.Context) diff --git a/internal/helpers/test-utilities.go b/internal/helpers/test-utilities.go index 2111a9f..09a5704 100644 --- a/internal/helpers/test-utilities.go +++ b/internal/helpers/test-utilities.go @@ -3,8 +3,8 @@ package helpers import ( "fmt" "os" + "os/exec" "path/filepath" - "runtime" "strings" ) @@ -43,8 +43,11 @@ func Root() string { } func Repo(relative string) string { - _, filename, _, _ := runtime.Caller(0) //nolint:dogsled // ignore - return Path(filepath.Dir(filename), relative) + cmd := exec.Command("git", "rev-parse", "--show-toplevel") + output, _ := cmd.Output() + repo := strings.TrimSpace(string(output)) + + return Path(repo, relative) } func Log() string { diff --git a/locale/default/active.en-GB.json b/locale/default/active.en-GB.json new file mode 100644 index 0000000..150124e --- /dev/null +++ b/locale/default/active.en-GB.json @@ -0,0 +1,38 @@ +{ + "invalid-pool-expiry.error": { + "description": "error when negative number set as the periodic duration to purge goroutines", + "other": "invalid expiry for pool" + }, + "invalid-prealloc-size.error": { + "description": "error created when trying to set up a negative capacity under PreAlloc mode", + "other": "can not set up a negative capacity under PreAlloc mode" + }, + "lack-pool-func.error": { + "description": "error when the function for the PoolFunc is missing and needs to be defined", + "other": "must provide function for pool func" + }, + "pool-closed.error": { + "description": "error created when submitting task to a closed pool.", + "other": "this pool has been closed" + }, + "pool-overload.error": { + "description": "will be returned when the pool is full and no workers available.", + "other": "too many goroutines blocked on submit or Nonblocking is set" + }, + "queue-is-full.error": { + "description": "error created when the worker queue is full.", + "other": "the queue is full" + }, + "queue-is-released.error": { + "description": "error created when trying to insert item to a released worker queue.", + "other": "the queue length is zero" + }, + "timeout.error": { + "description": "error created if an operation timed out.", + "other": "operation timed out" + }, + "using-config-file": { + "description": "Message to indicate which config is being used", + "other": "Using config file: {{.ConfigFileName}}" + } +} diff --git a/locale/default/pants.active.en-GB.json b/locale/default/pants.active.en-GB.json deleted file mode 100644 index bb88f60..0000000 --- a/locale/default/pants.active.en-GB.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "root-command-config-file-usage": { - "description": "root command config flag usage", - "other": "config file (default is $HOME/{{.ConfigFileName}}.yml)" - }, - "root-command-language-usage": { - "description": "root command lang usage", - "other": "'lang' defines the language according to IETF BCP 47" - }, - "root-command-long-description": { - "description": "long description for the root command", - "other": "A longer description that spans multiple lines and likely contains\n\t\texamples and usage of using your application. For example:\n\t\t\n\t\tCobra is a CLI library for Go that empowers applications.\n\t\tThis application is a tool to generate the needed files\n\t\tto quickly create a Cobra application." - }, - "root-command-short-description": { - "description": "short description for the root command", - "other": "A brief description of your application" - }, - "using-config-file": { - "description": "Message to indicate which config is being used", - "other": "Using config file: {{.ConfigFileName}}" - } -} \ No newline at end of file diff --git a/locale/deploy/pants.active.en-US.json b/locale/deploy/pants.active.en-US.json index 1bdc419..ed91ad0 100644 --- a/locale/deploy/pants.active.en-US.json +++ b/locale/deploy/pants.active.en-US.json @@ -1,27 +1,47 @@ { - "root-command-config-file-usage": { - "description": "root command config flag usage", - "hash": "sha1-60ec091d99ab2286a4bb4a1e1733c155bca95a9f", - "other": "config file (default is $HOME/{{.ConfigFileName}}.yml)" - }, - "root-command-language-usage": { - "description": "root command lang usage", - "hash": "sha1-13eee706e037f33844c76f1dcdac5786b4089a00", - "other": "'lang' defines the language according to IETF BCP 47" - }, - "root-command-long-description": { - "description": "long description for the root command", - "hash": "sha1-9122dfb1f95d2d00501ca67449df1dcf695f2cc2", - "other": "A longer description that spans multiple lines and likely contains\n\t\texamples and usage of using your application. For example:\n\t\t\n\t\tCobra is a CLI library for Go that empowers applications.\n\t\tThis application is a tool to generate the needed files\n\t\tto quickly create a Cobra application." - }, - "root-command-short-description": { - "description": "short description for the root command", - "hash": "sha1-a88cc9526d5e47f670ce9b089390e65415ab26cc", - "other": "A brief description of your application" + "invalid-pool-expiry.error": { + "description": "error when negative number set as the periodic duration to purge goroutines", + "hash": "sha1-9c630a5539726eab9af81aaffcf60e38462a67fc", + "other": "invalid expiry for pool" + }, + "invalid-prealloc-size.error": { + "description": "error created when trying to set up a negative capacity under PreAlloc mode", + "hash": "sha1-3090c2173e46a0a5b63b4b26b2ed8043e0f5d3f8", + "other": "can not set up a negative capacity under PreAlloc mode" + }, + "lack-pool-func.error": { + "description": "error when the function for the PoolFunc is missing and needs to be defined", + "hash": "sha1-afec4844398d26a19326551477fd21f8e769e070", + "other": "must provide function for pool func" + }, + "pool-closed.error": { + "description": "error created when submitting task to a closed pool.", + "hash": "sha1-def2b9e8a6f411ecf0d3f7293e23b0da1b900103", + "other": "this pool has been closed" + }, + "pool-overload.error": { + "description": "will be returned when the pool is full and no workers available.", + "hash": "sha1-b9f74847c130c3cac4e70e8d8d1de5fa6750102e", + "other": "too many goroutines blocked on submit or Nonblocking is set" + }, + "queue-is-full.error": { + "description": "error created when the worker queue is full.", + "hash": "sha1-bd7045aae4801880d8686bce7bb94e54af9ce21d", + "other": "the queue is full" + }, + "queue-is-released.error": { + "description": "error created when trying to insert item to a released worker queue.", + "hash": "sha1-824f2830639b58b3ff9e86b42a48ab087fc99131", + "other": "the queue length is zero" + }, + "timeout.error": { + "description": "error created if an operation timed out.", + "hash": "sha1-44505c53dddcaa0e5a4bb3dcf2e318697327af2d", + "other": "operation timed out" }, "using-config-file": { "description": "Message to indicate which config is being used", "hash": "sha1-06fd9528f8226d1501ea09bc5d629f4922b4f3c6", "other": "Using config file: {{.ConfigFileName}}" } -} \ No newline at end of file +} diff --git a/locale/locale-defs.go b/locale/locale-defs.go new file mode 100644 index 0000000..287eb5e --- /dev/null +++ b/locale/locale-defs.go @@ -0,0 +1,12 @@ +package locale + +const ( + // PantsSourceID source ID for the pants module + PantsSourceID = "github.com/snivilised/pants" +) + +type pantsTemplData struct{} + +func (td pantsTemplData) SourceID() string { + return PantsSourceID +} diff --git a/locale/messages-errors.go b/locale/messages-errors.go index 4ae579c..b1953cd 100644 --- a/locale/messages-errors.go +++ b/locale/messages-errors.go @@ -1,52 +1,275 @@ package locale -// // ❌ FooBar - -// // FooBarTemplData - TODO: this is a none existent error that should be -// // replaced by the client. Its just defined here to illustrate the pattern -// // that should be used to implement i18n with extendio. Also note, -// // that this message has been removed from the translation files, so -// // it is not useable at run time. -// type FooBarTemplData struct { -// pantsTemplData -// Path string -// Reason error -// } - -// // the ID should use spp/library specific code, so replace astrolib with the -// // name of the library implementing this template project. -// func (td FooBarTemplData) Message() *i18n.Message { -// return &i18n.Message{ -// ID: "foo-bar.astrolib.nav", -// Description: "Foo Bar description", -// Other: "foo bar failure '{{.Path}}' (reason: {{.Reason}})", -// } -// } - -// // FooBarErrorBehaviourQuery used to query if an error is: -// // "Failed to read directory contents from the path specified" -// type FooBarErrorBehaviourQuery interface { -// FooBar() bool -// } - -// type FooBarError struct { -// i18n.LocalisableError -// } - -// // FooBar enables the client to check if error is FooBarError -// // via FooBarErrorBehaviourQuery -// func (e FooBarError) FooBar() bool { -// return true -// } - -// // NewFooBarError creates a FooBarError -// func NewFooBarError(path string, reason error) FooBarError { -// return FooBarError{ -// LocalisableError: i18n.LocalisableError{ -// Data: FooBarTemplData{ -// Path: path, -// Reason: reason, -// }, -// }, -// } -// } +import ( + "github.com/nicksnyder/go-i18n/v2/i18n" + "github.com/snivilised/li18ngo" +) + +// 🔊 snippets help: +// - to invoke the snippet, type the prefix, eg p18e (plain i18n error) +// then type the values of the placeholders, with a to go to the next +// when finished, hit +// - to update snippets, hit --P, Configure User Snippets + +// ❌ ErrLackPoolFunc + +// LackPoolFuncErrorTemplData will be returned when invokers don't provide function for pool. +type LackPoolFuncErrorTemplData struct { + pantsTemplData +} + +// Message +func (td LackPoolFuncErrorTemplData) Message() *i18n.Message { + return &i18n.Message{ + ID: "lack-pool-func.error", + Description: "error when the function for the PoolFunc is missing and needs to be defined", + Other: "must provide function for pool func", + } +} + +type LackPoolFuncError struct { + li18ngo.LocalisableError +} + +var ErrLackPoolFunc = LackPoolFuncError{ + LocalisableError: li18ngo.LocalisableError{ + Data: LackPoolFuncErrorTemplData{}, + }, +} + +// ❌ ErrInvalidPoolExpiry + +// InvalidPoolExpiryErrorTemplData will be returned when setting a negative number as the +// periodic duration to purge goroutines. +type InvalidPoolExpiryErrorTemplData struct { + pantsTemplData +} + +// Message +func (td InvalidPoolExpiryErrorTemplData) Message() *i18n.Message { + return &i18n.Message{ + ID: "invalid-pool-expiry.error", + Description: "error when negative number set as the periodic duration to purge goroutines", + Other: "invalid expiry for pool", + } +} + +type InvalidPoolExpiryError struct { + li18ngo.LocalisableError +} + +var ErrInvalidPoolExpiry = InvalidPoolExpiryError{ + LocalisableError: li18ngo.LocalisableError{ + Data: InvalidPoolExpiryErrorTemplData{}, + }, +} + +// ❌ ErrPoolClosed + +// PoolClosedErrorTemplData will be returned when submitting task to a closed pool. +type PoolClosedErrorTemplData struct { + pantsTemplData +} + +// Message +func (td PoolClosedErrorTemplData) Message() *i18n.Message { + return &i18n.Message{ + ID: "pool-closed.error", + Description: "error created when submitting task to a closed pool.", + Other: "this pool has been closed", + } +} + +type PoolClosedError struct { + li18ngo.LocalisableError +} + +var ErrPoolClosed = PoolClosedError{ + LocalisableError: li18ngo.LocalisableError{ + Data: PoolClosedErrorTemplData{}, + }, +} + +// ❌ ErrPoolOverload + +// PoolOverloadErrorTemplData will be returned when the pool is full and no +// workers available. +type PoolOverloadErrorTemplData struct { + pantsTemplData +} + +// Message +func (td PoolOverloadErrorTemplData) Message() *i18n.Message { + return &i18n.Message{ + ID: "pool-overload.error", + Description: "will be returned when the pool is full and no workers available.", + Other: "too many goroutines blocked on submit or Nonblocking is set", + } +} + +type PoolOverloadError struct { + li18ngo.LocalisableError +} + +var ErrPoolOverload = PoolOverloadError{ + LocalisableError: li18ngo.LocalisableError{ + Data: PoolOverloadErrorTemplData{}, + }, +} + +// ❌ ErrInvalidPreAllocSize + +// InvalidPreAllocSizeErrorTemplData will be returned when trying to set up a +// negative capacity under PreAlloc mode. +type InvalidPreAllocSizeErrorTemplData struct { + pantsTemplData +} + +// Message +func (td InvalidPreAllocSizeErrorTemplData) Message() *i18n.Message { + return &i18n.Message{ + ID: "invalid-prealloc-size.error", + Description: "error created when trying to set up a negative capacity under PreAlloc mode", + Other: "can not set up a negative capacity under PreAlloc mode", + } +} + +type InvalidPreAllocSizeError struct { + li18ngo.LocalisableError +} + +var ErrInvalidPreAllocSize = InvalidPreAllocSizeError{ + LocalisableError: li18ngo.LocalisableError{ + Data: InvalidPreAllocSizeErrorTemplData{}, + }, +} + +// ❌ ErrTimeout + +// TimeoutErrorTemplData will be returned if an operation timed out. +type TimeoutErrorTemplData struct { + pantsTemplData +} + +// Message +func (td TimeoutErrorTemplData) Message() *i18n.Message { + return &i18n.Message{ + ID: "timeout.error", + Description: "error created if an operation timed out.", + Other: "operation timed out", + } +} + +type TimeoutError struct { + li18ngo.LocalisableError +} + +var ErrTimeout = TimeoutError{ + LocalisableError: li18ngo.LocalisableError{ + Data: TimeoutErrorTemplData{}, + }, +} + +// ❌ QueueIsFullTemplData + +// QueueIsFullTemplData error created when the worker queue is full. +type QueueIsFullErrorTemplData struct { + pantsTemplData +} + +// Message +func (td QueueIsFullErrorTemplData) Message() *i18n.Message { + return &i18n.Message{ + ID: "queue-is-full.error", + Description: "error created when the worker queue is full.", + Other: "the queue is full", + } +} + +type QueueIsFullError struct { + li18ngo.LocalisableError +} + +var ErrQueueIsFull = QueueIsFullError{ + LocalisableError: li18ngo.LocalisableError{ + Data: QueueIsFullErrorTemplData{}, + }, +} + +// ❌ QueueIsReleasedTemplData + +// QueueIsReleasedTemplData will be returned when trying to insert item to a +// released worker queue +type QueueIsReleasedErrorTemplData struct { + pantsTemplData +} + +// Message +func (td QueueIsReleasedErrorTemplData) Message() *i18n.Message { + return &i18n.Message{ + ID: "queue-is-released.error", + Description: "error created when trying to insert item to a released worker queue.", + Other: "the queue length is zero", + } +} + +type QueueIsReleasedError struct { + li18ngo.LocalisableError +} + +var ErrQueueIsReleased = QueueIsReleasedError{ + LocalisableError: li18ngo.LocalisableError{ + Data: QueueIsReleasedErrorTemplData{}, + }, +} + +// ❌❌ FooBar + +// FooBarTemplData - TODO: this is a none existent error that should be +// replaced by the client. Its just defined here to illustrate the pattern +// that should be used to implement i18n with extendio. Also note, +// that this message has been removed from the translation files, so +// it is not useable at run time. +type FooBarTemplData struct { + pantsTemplData + Path string + Reason error +} + +// the ID should use spp/library specific code, so replace astrolib with the +// name of the library implementing this template project. +func (td FooBarTemplData) Message() *i18n.Message { + return &i18n.Message{ + ID: "foo-bar.astrolib.nav", + Description: "Foo Bar description", + Other: "foo bar failure '{{.Path}}' (reason: {{.Reason}})", + } +} + +// FooBarErrorBehaviourQuery used to query if an error is: +// "Failed to read directory contents from the path specified" +type FooBarErrorBehaviourQuery interface { + FooBar() bool +} + +type FooBarError struct { + li18ngo.LocalisableError +} + +// FooBar enables the client to check if error is FooBarError +// via FooBarErrorBehaviourQuery +func (e FooBarError) FooBar() bool { + return true +} + +// NewFooBarError creates a FooBarError +func NewFooBarError(path string, reason error) FooBarError { + return FooBarError{ + LocalisableError: li18ngo.LocalisableError{ + Data: FooBarTemplData{ + Path: path, + Reason: reason, + }, + }, + } +} diff --git a/locale/out/active.en-GB.json b/locale/out/active.en-GB.json deleted file mode 100644 index bb88f60..0000000 --- a/locale/out/active.en-GB.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "root-command-config-file-usage": { - "description": "root command config flag usage", - "other": "config file (default is $HOME/{{.ConfigFileName}}.yml)" - }, - "root-command-language-usage": { - "description": "root command lang usage", - "other": "'lang' defines the language according to IETF BCP 47" - }, - "root-command-long-description": { - "description": "long description for the root command", - "other": "A longer description that spans multiple lines and likely contains\n\t\texamples and usage of using your application. For example:\n\t\t\n\t\tCobra is a CLI library for Go that empowers applications.\n\t\tThis application is a tool to generate the needed files\n\t\tto quickly create a Cobra application." - }, - "root-command-short-description": { - "description": "short description for the root command", - "other": "A brief description of your application" - }, - "using-config-file": { - "description": "Message to indicate which config is being used", - "other": "Using config file: {{.ConfigFileName}}" - } -} \ No newline at end of file diff --git a/locale/out/active.en-US.json b/locale/out/active.en-US.json deleted file mode 100644 index 0967ef4..0000000 --- a/locale/out/active.en-US.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/locale/out/en-US/pants.translate.en-US.json b/locale/out/en-US/pants.translate.en-US.json deleted file mode 100644 index e69de29..0000000 diff --git a/locale/out/l10n/active.en-GB.json b/locale/out/l10n/active.en-GB.json new file mode 100644 index 0000000..150124e --- /dev/null +++ b/locale/out/l10n/active.en-GB.json @@ -0,0 +1,38 @@ +{ + "invalid-pool-expiry.error": { + "description": "error when negative number set as the periodic duration to purge goroutines", + "other": "invalid expiry for pool" + }, + "invalid-prealloc-size.error": { + "description": "error created when trying to set up a negative capacity under PreAlloc mode", + "other": "can not set up a negative capacity under PreAlloc mode" + }, + "lack-pool-func.error": { + "description": "error when the function for the PoolFunc is missing and needs to be defined", + "other": "must provide function for pool func" + }, + "pool-closed.error": { + "description": "error created when submitting task to a closed pool.", + "other": "this pool has been closed" + }, + "pool-overload.error": { + "description": "will be returned when the pool is full and no workers available.", + "other": "too many goroutines blocked on submit or Nonblocking is set" + }, + "queue-is-full.error": { + "description": "error created when the worker queue is full.", + "other": "the queue is full" + }, + "queue-is-released.error": { + "description": "error created when trying to insert item to a released worker queue.", + "other": "the queue length is zero" + }, + "timeout.error": { + "description": "error created if an operation timed out.", + "other": "operation timed out" + }, + "using-config-file": { + "description": "Message to indicate which config is being used", + "other": "Using config file: {{.ConfigFileName}}" + } +} diff --git a/locale/out/l10n/translate.en-US.json b/locale/out/l10n/translate.en-US.json new file mode 100644 index 0000000..ed91ad0 --- /dev/null +++ b/locale/out/l10n/translate.en-US.json @@ -0,0 +1,47 @@ +{ + "invalid-pool-expiry.error": { + "description": "error when negative number set as the periodic duration to purge goroutines", + "hash": "sha1-9c630a5539726eab9af81aaffcf60e38462a67fc", + "other": "invalid expiry for pool" + }, + "invalid-prealloc-size.error": { + "description": "error created when trying to set up a negative capacity under PreAlloc mode", + "hash": "sha1-3090c2173e46a0a5b63b4b26b2ed8043e0f5d3f8", + "other": "can not set up a negative capacity under PreAlloc mode" + }, + "lack-pool-func.error": { + "description": "error when the function for the PoolFunc is missing and needs to be defined", + "hash": "sha1-afec4844398d26a19326551477fd21f8e769e070", + "other": "must provide function for pool func" + }, + "pool-closed.error": { + "description": "error created when submitting task to a closed pool.", + "hash": "sha1-def2b9e8a6f411ecf0d3f7293e23b0da1b900103", + "other": "this pool has been closed" + }, + "pool-overload.error": { + "description": "will be returned when the pool is full and no workers available.", + "hash": "sha1-b9f74847c130c3cac4e70e8d8d1de5fa6750102e", + "other": "too many goroutines blocked on submit or Nonblocking is set" + }, + "queue-is-full.error": { + "description": "error created when the worker queue is full.", + "hash": "sha1-bd7045aae4801880d8686bce7bb94e54af9ce21d", + "other": "the queue is full" + }, + "queue-is-released.error": { + "description": "error created when trying to insert item to a released worker queue.", + "hash": "sha1-824f2830639b58b3ff9e86b42a48ab087fc99131", + "other": "the queue length is zero" + }, + "timeout.error": { + "description": "error created if an operation timed out.", + "hash": "sha1-44505c53dddcaa0e5a4bb3dcf2e318697327af2d", + "other": "operation timed out" + }, + "using-config-file": { + "description": "Message to indicate which config is being used", + "hash": "sha1-06fd9528f8226d1501ea09bc5d629f4922b4f3c6", + "other": "Using config file: {{.ConfigFileName}}" + } +} diff --git a/locale/out/translate.en-US.json b/locale/out/translate.en-US.json deleted file mode 100644 index 1bdc419..0000000 --- a/locale/out/translate.en-US.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "root-command-config-file-usage": { - "description": "root command config flag usage", - "hash": "sha1-60ec091d99ab2286a4bb4a1e1733c155bca95a9f", - "other": "config file (default is $HOME/{{.ConfigFileName}}.yml)" - }, - "root-command-language-usage": { - "description": "root command lang usage", - "hash": "sha1-13eee706e037f33844c76f1dcdac5786b4089a00", - "other": "'lang' defines the language according to IETF BCP 47" - }, - "root-command-long-description": { - "description": "long description for the root command", - "hash": "sha1-9122dfb1f95d2d00501ca67449df1dcf695f2cc2", - "other": "A longer description that spans multiple lines and likely contains\n\t\texamples and usage of using your application. For example:\n\t\t\n\t\tCobra is a CLI library for Go that empowers applications.\n\t\tThis application is a tool to generate the needed files\n\t\tto quickly create a Cobra application." - }, - "root-command-short-description": { - "description": "short description for the root command", - "hash": "sha1-a88cc9526d5e47f670ce9b089390e65415ab26cc", - "other": "A brief description of your application" - }, - "using-config-file": { - "description": "Message to indicate which config is being used", - "hash": "sha1-06fd9528f8226d1501ea09bc5d629f4922b4f3c6", - "other": "Using config file: {{.ConfigFileName}}" - } -} \ No newline at end of file diff --git a/locale/translate-defs.go b/locale/translate-defs.go deleted file mode 100644 index ec73f00..0000000 --- a/locale/translate-defs.go +++ /dev/null @@ -1,11 +0,0 @@ -package locale - -// CLIENT-TODO: Should be updated to use url of the implementing project, -// so should not be left as astrolib. (this should be set by auto-check) -const PantsSourceID = "github.com/snivilised/pants" - -type pantsTemplData struct{} - -func (td pantsTemplData) SourceID() string { - return PantsSourceID -} diff --git a/test/data/l10n/test.pants.active.en-US.json b/test/data/l10n/test.pants.active.en-US.json index 5a7a30b..ed91ad0 100644 --- a/test/data/l10n/test.pants.active.en-US.json +++ b/test/data/l10n/test.pants.active.en-US.json @@ -1,7 +1,47 @@ { - "foo-bar.astrolib.test": { - "description": "foo bar", - "hash": "sha1-d53a205a336e07cf9eac45471b3870f9489288ec", - "other": "foo bar" + "invalid-pool-expiry.error": { + "description": "error when negative number set as the periodic duration to purge goroutines", + "hash": "sha1-9c630a5539726eab9af81aaffcf60e38462a67fc", + "other": "invalid expiry for pool" + }, + "invalid-prealloc-size.error": { + "description": "error created when trying to set up a negative capacity under PreAlloc mode", + "hash": "sha1-3090c2173e46a0a5b63b4b26b2ed8043e0f5d3f8", + "other": "can not set up a negative capacity under PreAlloc mode" + }, + "lack-pool-func.error": { + "description": "error when the function for the PoolFunc is missing and needs to be defined", + "hash": "sha1-afec4844398d26a19326551477fd21f8e769e070", + "other": "must provide function for pool func" + }, + "pool-closed.error": { + "description": "error created when submitting task to a closed pool.", + "hash": "sha1-def2b9e8a6f411ecf0d3f7293e23b0da1b900103", + "other": "this pool has been closed" + }, + "pool-overload.error": { + "description": "will be returned when the pool is full and no workers available.", + "hash": "sha1-b9f74847c130c3cac4e70e8d8d1de5fa6750102e", + "other": "too many goroutines blocked on submit or Nonblocking is set" + }, + "queue-is-full.error": { + "description": "error created when the worker queue is full.", + "hash": "sha1-bd7045aae4801880d8686bce7bb94e54af9ce21d", + "other": "the queue is full" + }, + "queue-is-released.error": { + "description": "error created when trying to insert item to a released worker queue.", + "hash": "sha1-824f2830639b58b3ff9e86b42a48ab087fc99131", + "other": "the queue length is zero" + }, + "timeout.error": { + "description": "error created if an operation timed out.", + "hash": "sha1-44505c53dddcaa0e5a4bb3dcf2e318697327af2d", + "other": "operation timed out" + }, + "using-config-file": { + "description": "Message to indicate which config is being used", + "hash": "sha1-06fd9528f8226d1501ea09bc5d629f4922b4f3c6", + "other": "Using config file: {{.ConfigFileName}}" } -} \ No newline at end of file +} diff --git a/wait-group_test.go b/wait-group_test.go index f4d89ac..a320cf1 100644 --- a/wait-group_test.go +++ b/wait-group_test.go @@ -1,16 +1,49 @@ package pants_test import ( + "fmt" + "os" "sync" "time" . "github.com/onsi/ginkgo/v2" //nolint:revive // ginkgo ok . "github.com/onsi/gomega" //nolint:revive // gomega ok + "github.com/snivilised/li18ngo" "github.com/snivilised/pants" + "github.com/snivilised/pants/internal/helpers" ) -var _ = Describe("pants.WaitGroup", func() { +var _ = Describe("pants.WaitGroup", Ordered, func() { + var ( + repo string + l10nPath string + testTranslationFile li18ngo.TranslationFiles + ) + + BeforeAll(func() { + repo = helpers.Repo("") + l10nPath = helpers.Path(repo, "test/data/l10n") + + _, err := os.Stat(l10nPath) + Expect(err).To(Succeed(), + fmt.Sprintf("l10n '%v' path does not exist", l10nPath), + ) + + testTranslationFile = li18ngo.TranslationFiles{ + li18ngo.Li18ngoSourceID: li18ngo.TranslationSource{Name: "test"}, + } + }) + + BeforeEach(func() { + if err := li18ngo.Use(func(o *li18ngo.UseOptions) { + o.Tag = li18ngo.DefaultLanguage + o.From.Sources = testTranslationFile + }); err != nil { + Fail(err.Error()) + } + }) + Context("given: a sync.WaitGroup", func() { It("should: track invocations", func() { var wg sync.WaitGroup diff --git a/worker-pool-func-manifold_test.go b/worker-pool-func-manifold_test.go index 0a1312c..cf56da1 100644 --- a/worker-pool-func-manifold_test.go +++ b/worker-pool-func-manifold_test.go @@ -2,14 +2,18 @@ package pants_test import ( "context" + "fmt" + "os" "runtime" "sync" . "github.com/onsi/ginkgo/v2" //nolint:revive // ginkgo ok . "github.com/onsi/gomega" //nolint:revive // gomega ok + "github.com/snivilised/li18ngo" "github.com/snivilised/pants" "github.com/snivilised/pants/internal/ants" + "github.com/snivilised/pants/internal/helpers" ) func produce(ctx context.Context, @@ -52,7 +56,36 @@ func consume(_ context.Context, } } -var _ = Describe("WorkerPoolFuncManifold", func() { +var _ = Describe("WorkerPoolFuncManifold", Ordered, func() { + var ( + repo string + l10nPath string + testTranslationFile li18ngo.TranslationFiles + ) + + BeforeAll(func() { + repo = helpers.Repo("") + l10nPath = helpers.Path(repo, "test/data/l10n") + + _, err := os.Stat(l10nPath) + Expect(err).To(Succeed(), + fmt.Sprintf("l10n '%v' path does not exist", l10nPath), + ) + + testTranslationFile = li18ngo.TranslationFiles{ + li18ngo.Li18ngoSourceID: li18ngo.TranslationSource{Name: "test"}, + } + }) + + BeforeEach(func() { + if err := li18ngo.Use(func(o *li18ngo.UseOptions) { + o.Tag = li18ngo.DefaultLanguage + o.From.Sources = testTranslationFile + }); err != nil { + Fail(err.Error()) + } + }) + Context("ants", func() { When("NonBlocking", func() { Context("with consumer", func() { diff --git a/worker-pool-func_test.go b/worker-pool-func_test.go index 1b69b4d..a1a53b8 100644 --- a/worker-pool-func_test.go +++ b/worker-pool-func_test.go @@ -2,17 +2,50 @@ package pants_test import ( "context" + "fmt" + "os" "sync" "time" . "github.com/onsi/ginkgo/v2" //nolint:revive // ginkgo ok . "github.com/onsi/gomega" //nolint:revive // gomega ok + "github.com/snivilised/li18ngo" "github.com/snivilised/pants" - "github.com/snivilised/pants/internal/ants" + "github.com/snivilised/pants/internal/helpers" + "github.com/snivilised/pants/locale" ) -var _ = Describe("WorkerPoolFunc", func() { +var _ = Describe("WorkerPoolFunc", Ordered, func() { + var ( + repo string + l10nPath string + testTranslationFile li18ngo.TranslationFiles + ) + + BeforeAll(func() { + repo = helpers.Repo("") + l10nPath = helpers.Path(repo, "test/data/l10n") + + _, err := os.Stat(l10nPath) + Expect(err).To(Succeed(), + fmt.Sprintf("l10n '%v' path does not exist", l10nPath), + ) + + testTranslationFile = li18ngo.TranslationFiles{ + li18ngo.Li18ngoSourceID: li18ngo.TranslationSource{Name: "test"}, + } + }) + + BeforeEach(func() { + if err := li18ngo.Use(func(o *li18ngo.UseOptions) { + o.Tag = li18ngo.DefaultLanguage + o.From.Sources = testTranslationFile + }); err != nil { + Fail(err.Error()) + } + }) + Context("ants", func() { When("NonBlocking", func() { It("should: not fail", func(specCtx SpecContext) { @@ -116,7 +149,8 @@ var _ = Describe("WorkerPoolFunc", func() { }() time.Sleep(1 * time.Second) // already reached max blocking limit - Expect(pool.Post(ctx, Param)).To(MatchError(ants.ErrPoolOverload.Error()), + Expect(pool.Post(ctx, Param)).To( + MatchError(locale.ErrPoolOverload.Error()), "blocking submit when pool reach max blocking submit should return ErrPoolOverload", ) diff --git a/worker-pool-task_test.go b/worker-pool-task_test.go index cc8f5ae..41da905 100644 --- a/worker-pool-task_test.go +++ b/worker-pool-task_test.go @@ -2,17 +2,50 @@ package pants_test import ( "context" + "fmt" + "os" "sync" "time" . "github.com/onsi/ginkgo/v2" //nolint:revive // ginkgo ok . "github.com/onsi/gomega" //nolint:revive // gomega ok + "github.com/snivilised/li18ngo" "github.com/snivilised/pants" - "github.com/snivilised/pants/internal/ants" + "github.com/snivilised/pants/internal/helpers" + "github.com/snivilised/pants/locale" ) -var _ = Describe("WorkerPoolTask", func() { +var _ = Describe("WorkerPoolTask", Ordered, func() { + var ( + repo string + l10nPath string + testTranslationFile li18ngo.TranslationFiles + ) + + BeforeAll(func() { + repo = helpers.Repo("") + l10nPath = helpers.Path(repo, "test/data/l10n") + + _, err := os.Stat(l10nPath) + Expect(err).To(Succeed(), + fmt.Sprintf("l10n '%v' path does not exist", l10nPath), + ) + + testTranslationFile = li18ngo.TranslationFiles{ + li18ngo.Li18ngoSourceID: li18ngo.TranslationSource{Name: "test"}, + } + }) + + BeforeEach(func() { + if err := li18ngo.Use(func(o *li18ngo.UseOptions) { + o.Tag = li18ngo.DefaultLanguage + o.From.Sources = testTranslationFile + }); err != nil { + Fail(err.Error()) + } + }) + Context("ants", func() { When("NonBlocking", func() { It("should: not fail", func(specCtx SpecContext) { @@ -47,7 +80,8 @@ var _ = Describe("WorkerPoolTask", func() { Expect(pool.Post(ctx, fn)).To(Succeed(), "nonblocking submit when pool is not full shouldn't return error", ) - Expect(pool.Post(ctx, demoFunc)).To(MatchError(ants.ErrPoolOverload.Error()), + Expect(pool.Post(ctx, demoFunc)).To( + MatchError(locale.ErrPoolOverload.Error()), "nonblocking submit when pool is full should get an ErrPoolOverload", ) // interrupt fn to get an available worker @@ -105,7 +139,8 @@ var _ = Describe("WorkerPoolTask", func() { time.Sleep(1 * time.Second) // already reached max blocking limit - Expect(pool.Post(ctx, demoFunc)).To(MatchError(ants.ErrPoolOverload.Error()), + Expect(pool.Post(ctx, demoFunc)).To( + MatchError(locale.ErrPoolOverload.Error()), "blocking submit when pool reach max blocking submit should return ErrPoolOverload", )