diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e757848..a48a77e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -232,7 +232,7 @@ See also the next section. These suggestions apply to the development of any Concourse resource. -### Building a new image and ensuring that the pipeline picks it up +### Building a new image and ensuring that the pipeline picks it up After the local tests are passing, the quickest way to test in a pipeline the freshly pushed version of the Docker image used to be the `fly check-resource-type` command. Unfortunately somewhere in the Concourse 7.6.x series this broke (details: [registry-image-resource #316](https://github.com/concourse/registry-image-resource/issues/316)). @@ -248,7 +248,7 @@ You can follow two steps: 1. `fly set-pipeline` with a check_interval for the resource type of 1m instead of the recommended 24h. 2. `fly clear-version`. -For example, assuming that the test pipeline is called `cogito-test`, that the resource in the pipeline is called `cogito` and that there is a job called `motormouse` (all this is true by using the sample pipeline [pipelines/cogito.yml](./pipelines/cogito.yml)), +For example, assuming that the test pipeline is called `cogito-test`, that the resource in the pipeline is called `cogito` and that there is a job called `motormouse` (all this is true by using the sample pipeline [pipelines/cogito.yml](./pipelines/cogito.yml)). Step 1: @@ -268,7 +268,7 @@ Step 2 (the sleep is fundamental to let check_every expire): ``` $ task test:all docker:build docker:smoke docker:push && fly -t cogito clear-versions --resource-type=cogito-test/cogito && - echo "sleeping and hoping :-(" && + echo "sleeping and hoping :-(" && sleep 70 && fly -t cogito trigger-job -j cogito-test/motormouse -w ``` @@ -336,7 +336,7 @@ Update the expired secrets as follows. ## Regenerate your GitHub personal access token (PAT) 1. Go to [Settings | Tokens](https://github.com/settings/tokens) for your account. -2. Create or regenerate a token with name `test-cogito`, with scope "repo:status". Set an expiration of 90 days. +2. Create or regenerate a token with name `test-cogito`, with scope `repo:status`. Set an expiration of 90 days. 3. Copy the token. ## Regenerate a Google Chat hook diff --git a/sets/sets.go b/sets/sets.go index 3c892f8..658b407 100644 --- a/sets/sets.go +++ b/sets/sets.go @@ -105,3 +105,15 @@ func (s *Set[T]) Intersection(x *Set[T]) *Set[T] { } return result } + +// Union returns a set containing all the elements of s and x. +func (s *Set[T]) Union(x *Set[T]) *Set[T] { + result := New[T](max(s.Size(), x.Size())) + for item := range s.items { + result.items[item] = struct{}{} + } + for item := range x.items { + result.items[item] = struct{}{} + } + return result +} diff --git a/sets/sets_test.go b/sets/sets_test.go index 32c3fa5..9f3cfc0 100644 --- a/sets/sets_test.go +++ b/sets/sets_test.go @@ -201,6 +201,65 @@ func TestIntersection(t *testing.T) { } } +func TestUnion(t *testing.T) { + type testCase struct { + name string + s *sets.Set[int] + x *sets.Set[int] + wantList []int + } + + test := func(t *testing.T, tc testCase) { + result := tc.s.Union(tc.x) + sorted := result.OrderedList() + + qt.Assert(t, qt.DeepEquals(sorted, tc.wantList)) + } + + testCases := []testCase{ + { + name: "both empty", + s: sets.From[int](), + x: sets.From[int](), + wantList: []int{}, + }, + { + name: "empty x", + s: sets.From(1, 2), + x: sets.From[int](), + wantList: []int{1, 2}, + }, + { + name: "empty s", + s: sets.From[int](), + x: sets.From(1, 2), + wantList: []int{1, 2}, + }, + { + name: "identical", + s: sets.From(1, 2), + x: sets.From(1, 2), + wantList: []int{1, 2}, + }, + { + name: "all different", + s: sets.From(1, 3), + x: sets.From(2, 4), + wantList: []int{1, 2, 3, 4}, + }, + { + name: "partial overlap", + s: sets.From(1, 3), + x: sets.From(3, 5), + wantList: []int{1, 3, 5}, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { test(t, tc) }) + } +} + func TestRemoveFound(t *testing.T) { type testCase struct { name string