Skip to content

Commit

Permalink
Implement comparison state checks to replace `TestCheckResourceAttrPt…
Browse files Browse the repository at this point in the history
…r`, `TestCheckResourceAttrPair` and `TestCheckTypeSetElemAttrPair` (#330)

* compare: Add compare package and implementations for ValuesSame, ValuesSameAny, ValuesDiffer, ValuesDifferAny, and ValuesDifferAll

* statecheck: Add CompareValue, CompareValueContains, and CompareValuePairs state checks

* statecheck: Fixing references in tests

* Adding go docs and constructor to compare package types

* Adding go docs for CompareValue state checks

* Refactoring ValueComparer implementations to handle slice and map of interface values

* Refactoring CompareValueCollection to extract nested values

* Adding further test coverage for CompareValueCollection

* Adding compare pkg doc

* Removing ValuesDifferAll, ValuesDifferAny, ValuesSameAny

* Adding website docs for value comparers and compare value state checks

* Amending docs for known value checks

* build(deps): Bump hashicorp/setup-terraform from 3.1.0 to 3.1.1 (#335)

Bumps [hashicorp/setup-terraform](https://github.com/hashicorp/setup-terraform) from 3.1.0 to 3.1.1.
- [Release notes](https://github.com/hashicorp/setup-terraform/releases)
- [Changelog](https://github.com/hashicorp/setup-terraform/blob/main/CHANGELOG.md)
- [Commits](hashicorp/setup-terraform@97f030c...651471c)

---
updated-dependencies:
- dependency-name: hashicorp/setup-terraform
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): Bump hashicorp/setup-copywrite from 1.1.2 to 1.1.3 (#336)

Bumps [hashicorp/setup-copywrite](https://github.com/hashicorp/setup-copywrite) from 1.1.2 to 1.1.3.
- [Release notes](https://github.com/hashicorp/setup-copywrite/releases)
- [Commits](hashicorp/setup-copywrite@867a1a2...32638da)

---
updated-dependencies:
- dependency-name: hashicorp/setup-copywrite
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Result of tsccr-helper -log-level=info gha update -latest . (#337)

Co-authored-by: hashicorp-tsccr[bot] <hashicorp-tsccr[bot]@users.noreply.github.com>

* build(deps): Bump github.com/hashicorp/terraform-json (#338)

Bumps [github.com/hashicorp/terraform-json](https://github.com/hashicorp/terraform-json) from 0.21.0 to 0.22.0.
- [Release notes](https://github.com/hashicorp/terraform-json/releases)
- [Commits](hashicorp/terraform-json@v0.21.0...v0.22.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/terraform-json
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): Bump github.com/hashicorp/terraform-json (#339)

Bumps [github.com/hashicorp/terraform-json](https://github.com/hashicorp/terraform-json) from 0.22.0 to 0.22.1.
- [Release notes](https://github.com/hashicorp/terraform-json/releases)
- [Commits](hashicorp/terraform-json@v0.22.0...v0.22.1)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/terraform-json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): Bump github.com/hashicorp/terraform-exec (#341)

Bumps [github.com/hashicorp/terraform-exec](https://github.com/hashicorp/terraform-exec) from 0.20.0 to 0.21.0.
- [Release notes](https://github.com/hashicorp/terraform-exec/releases)
- [Changelog](https://github.com/hashicorp/terraform-exec/blob/main/CHANGELOG.md)
- [Commits](hashicorp/terraform-exec@v0.20.0...v0.21.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/terraform-exec
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* all: Add deferred action testing support (plan checks, version check, and CLI options) (#331)

* sloppy first commit!

* add version checks and tests

* add changelogs

* update terraform-plugin-go

* spelling fix

* update `terraform-json`

* switch to pointer bool value

* Update changelog

* [CI] Update issue comment triage workflow file

* [CI] Update issue comment triage workflow file

* [CI] Update issue comment triage workflow file

* [CI] Update issue comment triage workflow file

* Result of tsccr-helper -log-level=info gha update -latest . (#342)

Co-authored-by: hashicorp-tsccr[bot] <hashicorp-tsccr[bot]@users.noreply.github.com>

* build(deps): Bump github.com/hashicorp/terraform-plugin-sdk/v2 (#343)

Bumps [github.com/hashicorp/terraform-plugin-sdk/v2](https://github.com/hashicorp/terraform-plugin-sdk) from 2.33.0 to 2.34.0.
- [Release notes](https://github.com/hashicorp/terraform-plugin-sdk/releases)
- [Changelog](https://github.com/hashicorp/terraform-plugin-sdk/blob/main/CHANGELOG.md)
- [Commits](hashicorp/terraform-plugin-sdk@v2.33.0...v2.34.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/terraform-plugin-sdk/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* workflows: Delete old issue label remove workflow (#344)

Replaced by `.github/workflows/issue-comment-triage.yml`

* build(deps): Bump github.com/hashicorp/hc-install from 0.6.4 to 0.7.0 (#345)

updated-dependencies:
- dependency-name: github.com/hashicorp/hc-install
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* [CI] Update lock workflow file

* build(deps): Bump github.com/hashicorp/go-version from 1.6.0 to 1.7.0 (#346)

Bumps [github.com/hashicorp/go-version](https://github.com/hashicorp/go-version) from 1.6.0 to 1.7.0.
- [Release notes](https://github.com/hashicorp/go-version/releases)
- [Changelog](https://github.com/hashicorp/go-version/blob/main/CHANGELOG.md)
- [Commits](hashicorp/go-version@v1.6.0...v1.7.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/go-version
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Result of tsccr-helper -log-level=info gha update -latest . (#348)

Co-authored-by: hashicorp-tsccr[bot] <hashicorp-tsccr[bot]@users.noreply.github.com>

* [CI] terraform-devex-repos automation

* [CI] terraform-devex-repos automation

* [CI] terraform-devex-repos automation

* [CI] terraform-devex-repos automation

* [CI] terraform-devex-repos automation

* [CI] terraform-devex-repos automation

* build(deps): Bump golang.org/x/crypto from 0.23.0 to 0.24.0 (#350)

Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.23.0 to 0.24.0.
- [Commits](golang/crypto@v0.23.0...v0.24.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* [CI] terraform-devex-repos automation

* [CI] terraform-devex-repos automation

* [CI] terraform-devex-repos automation

* [CI] Update lock workflow file

* build(deps): Bump github.com/hashicorp/hcl/v2 from 2.20.1 to 2.21.0 (#352)

Bumps [github.com/hashicorp/hcl/v2](https://github.com/hashicorp/hcl) from 2.20.1 to 2.21.0.
- [Release notes](https://github.com/hashicorp/hcl/releases)
- [Changelog](https://github.com/hashicorp/hcl/blob/main/CHANGELOG.md)
- [Commits](hashicorp/hcl@v2.20.1...v2.21.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/hcl/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* SEC-090: Automated trusted workflow pinning (2024-06-17) (#351)

* Result of tsccr-helper -log-level=info gha update -latest .

* Add version to .goreleaser file

---------

Co-authored-by: hashicorp-tsccr[bot] <hashicorp-tsccr[bot]@users.noreply.github.com>
Co-authored-by: Austin Valle <austinvalle@gmail.com>

* build(deps): Bump github.com/hashicorp/copywrite in /tools (#355)

Bumps [github.com/hashicorp/copywrite](https://github.com/hashicorp/copywrite) from 0.18.0 to 0.19.0.
- [Release notes](https://github.com/hashicorp/copywrite/releases)
- [Changelog](https://github.com/hashicorp/copywrite/blob/main/.goreleaser.yaml)
- [Commits](hashicorp/copywrite@v0.18.0...v0.19.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/copywrite
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Result of tsccr-helper -log-level=info gha update -latest . (#354)

Co-authored-by: hashicorp-tsccr[bot] <hashicorp-tsccr[bot]@users.noreply.github.com>
Co-authored-by: Austin Valle <austinvalle@gmail.com>

* knownvalue: Add `Int32Exact` and `Float32Exact` checks (#356)

* Add `float32exact` and `int32exact` types

* Update website documentation

* Add changelog entries

* Update changelog wording

* build(deps): Bump golang.org/x/crypto from 0.24.0 to 0.25.0 (#358)

Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.24.0 to 0.25.0.
- [Commits](golang/crypto@v0.24.0...v0.25.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Update changelog

* all: Add deferred action testing support (plan checks, version check, and CLI options) (#331)

* sloppy first commit!

* add version checks and tests

* add changelogs

* update terraform-plugin-go

* spelling fix

* update `terraform-json`

* switch to pointer bool value

* Update changelog

* [CI] terraform-devex-repos automation

* [CI] terraform-devex-repos automation

* knownvalue: Add `Int32Exact` and `Float32Exact` checks (#356)

* Add `float32exact` and `int32exact` types

* Update website documentation

* Add changelog entries

* Update changelog wording

* Update changelog

* quick doc fix

* added invalid test case

* adjust compare value collection to work with nested attributes

* add changelogs

* add tfversion skip for protov6

* update example for value comparers

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: hashicorp-tsccr[bot] <129506189+hashicorp-tsccr[bot]@users.noreply.github.com>
Co-authored-by: hashicorp-tsccr[bot] <hashicorp-tsccr[bot]@users.noreply.github.com>
Co-authored-by: Austin Valle <austinvalle@gmail.com>
Co-authored-by: hc-github-team-tf-provider-devex <github-team-tf-provider-devex@hashicorp.com>
Co-authored-by: Service Account - Terraform Provider DevEx <100357958+hc-github-team-tf-provider-devex@users.noreply.github.com>
Co-authored-by: Selena Goods <selena.goods@hashicorp.com>
  • Loading branch information
8 people authored Aug 8, 2024
1 parent 9501a02 commit 5d78aa4
Show file tree
Hide file tree
Showing 25 changed files with 3,506 additions and 12 deletions.
6 changes: 6 additions & 0 deletions .changes/unreleased/FEATURES-20240717-155731.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: FEATURES
body: 'compare: Introduced new `compare` package, which contains interfaces and implementations
for value comparisons in state checks.'
time: 2024-07-17T15:57:31.637692-04:00
custom:
Issue: "330"
6 changes: 6 additions & 0 deletions .changes/unreleased/FEATURES-20240717-160116.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: FEATURES
body: 'statecheck: Added `CompareValue` state check, which compares sequential values of the
specified attribute at the given managed resource, or data source, using the supplied value comparer.'
time: 2024-07-17T16:01:16.194665-04:00
custom:
Issue: "330"
7 changes: 7 additions & 0 deletions .changes/unreleased/FEATURES-20240717-160331.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
kind: FEATURES
body: 'statecheck: Added `CompareValueCollection` state check, which compares each item in
the specified collection (e.g., list, set) attribute, with the second specified
attribute at the given managed resources, or data sources, using the supplied value comparer.'
time: 2024-07-17T16:03:31.77827-04:00
custom:
Issue: "330"
7 changes: 7 additions & 0 deletions .changes/unreleased/FEATURES-20240717-164418.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
kind: FEATURES
body: 'statecheck: Added `CompareValuePairs` state check, which compares the
specified attributes at the given managed resources, or data sources, using
the supplied value comparer.'
time: 2024-07-17T16:44:18.612874-04:00
custom:
Issue: "330"
6 changes: 6 additions & 0 deletions .changes/unreleased/NOTES-20240717-155810.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: NOTES
body: 'compare: The `compare` package is considered experimental and may be altered
or removed in a subsequent release'
time: 2024-07-17T15:58:10.435384-04:00
custom:
Issue: "330"
7 changes: 7 additions & 0 deletions .changes/unreleased/NOTES-20240717-164911.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
kind: NOTES
body: 'statecheck: `CompareValue`, `CompareValueCollection`, and `CompareValuePairs`
state checks are considered experimental and may be altered or removed in a subsequent
release.'
time: 2024-07-17T16:49:11.296585-04:00
custom:
Issue: "330"
5 changes: 5 additions & 0 deletions compare/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

// Package compare contains the value comparer interface, and types implementing the value comparer interface.
package compare
13 changes: 13 additions & 0 deletions compare/value_comparer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package compare

// ValueComparer defines an interface that is implemented to run comparison logic on multiple values. Individual
// implementations determine how the comparison is performed (e.g., values differ, values equal).
type ValueComparer interface {
// CompareValues should assert the given known values against any expectations.
// Values are always ordered in the order they were added. Use the error
// return to signal unexpected values or implementation errors.
CompareValues(values ...any) error
}
31 changes: 31 additions & 0 deletions compare/values_differ.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package compare

import (
"fmt"
"reflect"
)

var _ ValueComparer = valuesDiffer{}

type valuesDiffer struct{}

// CompareValues determines whether each value in the sequence of the supplied values
// differs from the preceding value.
func (v valuesDiffer) CompareValues(values ...any) error {
for i := 1; i < len(values); i++ {
if reflect.DeepEqual(values[i-1], values[i]) {
return fmt.Errorf("expected values to differ, but they are the same: %v == %v", values[i-1], values[i])
}
}

return nil
}

// ValuesDiffer returns a ValueComparer for asserting that each value in the sequence of
// the values supplied to the CompareValues method differs from the preceding value.
func ValuesDiffer() valuesDiffer {
return valuesDiffer{}
}
62 changes: 62 additions & 0 deletions compare/values_differ_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package compare_test

import (
"fmt"
"testing"

"github.com/google/go-cmp/cmp"

"github.com/hashicorp/terraform-plugin-testing/compare"
)

func TestValuesDiffer_CompareValues(t *testing.T) {
t.Parallel()

testCases := map[string]struct {
in []any
expectedError error
}{
"nil": {},
"single-value": {
in: []any{"str"},
},
"non-matching-sequential-values": {
in: []any{"str", "other_str", "str"},
},
"matching-values-string": {
in: []any{"str", "other_str", "other_str"},
expectedError: fmt.Errorf("expected values to differ, but they are the same: other_str == other_str"),
},
"matching-values-slice": {
in: []any{
[]any{"other_str"},
[]any{"other_str"},
},
expectedError: fmt.Errorf("expected values to differ, but they are the same: [other_str] == [other_str]"),
},
"matching-values-map": {
in: []any{
map[string]any{"a": "other_str"},
map[string]any{"a": "other_str"},
},
expectedError: fmt.Errorf("expected values to differ, but they are the same: map[a:other_str] == map[a:other_str]"),
},
}

for name, testCase := range testCases {
name, testCase := name, testCase

t.Run(name, func(t *testing.T) {
t.Parallel()

err := compare.ValuesDiffer().CompareValues(testCase.in...)

if diff := cmp.Diff(err, testCase.expectedError, equateErrorMessage); diff != "" {
t.Errorf("unexpected difference: %s", diff)
}
})
}
}
31 changes: 31 additions & 0 deletions compare/values_same.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package compare

import (
"fmt"
"reflect"
)

var _ ValueComparer = valuesSame{}

type valuesSame struct{}

// CompareValues determines whether each value in the sequence of the supplied values
// is the same as the preceding value.
func (v valuesSame) CompareValues(values ...any) error {
for i := 1; i < len(values); i++ {
if !reflect.DeepEqual(values[i-1], values[i]) {
return fmt.Errorf("expected values to be the same, but they differ: %v != %v", values[i-1], values[i])
}
}

return nil
}

// ValuesSame returns a ValueComparer for asserting that each value in the sequence of
// the values supplied to the CompareValues method is the same as the preceding value.
func ValuesSame() valuesSame {
return valuesSame{}
}
73 changes: 73 additions & 0 deletions compare/values_same_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package compare_test

import (
"fmt"
"testing"

"github.com/google/go-cmp/cmp"

"github.com/hashicorp/terraform-plugin-testing/compare"
)

func TestValuesSame_CompareValues(t *testing.T) {
t.Parallel()

testCases := map[string]struct {
in []any
expectedError error
}{
"nil": {},
"single-value": {
in: []any{"str"},
},
"matching-values": {
in: []any{"str", "str", "str"},
},
"non-matching-values-string": {
in: []any{"str", "str", "other_str"},
expectedError: fmt.Errorf("expected values to be the same, but they differ: str != other_str"),
},
"non-matching-values-slice": {
in: []any{
[]any{"str"},
[]any{"str"},
[]any{"other_str"},
},
expectedError: fmt.Errorf("expected values to be the same, but they differ: [str] != [other_str]"),
},
"non-matching-values-map": {
in: []any{
map[string]any{"a": "str"},
map[string]any{"a": "str"},
map[string]any{"a": "other_str"},
},
expectedError: fmt.Errorf("expected values to be the same, but they differ: map[a:str] != map[a:other_str]"),
},
}

for name, testCase := range testCases {
name, testCase := name, testCase

t.Run(name, func(t *testing.T) {
t.Parallel()

err := compare.ValuesSame().CompareValues(testCase.in...)

if diff := cmp.Diff(err, testCase.expectedError, equateErrorMessage); diff != "" {
t.Errorf("unexpected difference: %s", diff)
}
})
}
}

// equateErrorMessage reports errors to be equal if both are nil
// or both have the same message.
var equateErrorMessage = cmp.Comparer(func(x, y error) bool {
if x == nil || y == nil {
return x == nil && y == nil
}
return x.Error() == y.Error()
})
114 changes: 114 additions & 0 deletions statecheck/compare_value.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package statecheck

import (
"context"
"fmt"

tfjson "github.com/hashicorp/terraform-json"

"github.com/hashicorp/terraform-plugin-testing/compare"
"github.com/hashicorp/terraform-plugin-testing/tfjsonpath"
)

// Resource State Check
var _ StateCheck = &compareValue{}

type compareValue struct {
resourceAddresses []string
attributePaths []tfjsonpath.Path
stateValues []any
comparer compare.ValueComparer
}

func (e *compareValue) AddStateValue(resourceAddress string, attributePath tfjsonpath.Path) StateCheck {
e.resourceAddresses = append(e.resourceAddresses, resourceAddress)
e.attributePaths = append(e.attributePaths, attributePath)

return e
}

// CheckState implements the state check logic.
func (e *compareValue) CheckState(ctx context.Context, req CheckStateRequest, resp *CheckStateResponse) {
var resource *tfjson.StateResource

if req.State == nil {
resp.Error = fmt.Errorf("state is nil")

return
}

if req.State.Values == nil {
resp.Error = fmt.Errorf("state does not contain any state values")

return
}

if req.State.Values.RootModule == nil {
resp.Error = fmt.Errorf("state does not contain a root module")

return
}

// All calls to AddStateValue occur before any TestStep is run, populating the resourceAddresses
// and attributePaths slices. The stateValues slice is populated during execution of each TestStep.
// Each call to CheckState happens sequentially during each TestStep.
// The currentIndex is reflective of the current state value being checked.
currentIndex := len(e.stateValues)

if len(e.resourceAddresses) <= currentIndex {
resp.Error = fmt.Errorf("resource addresses index out of bounds: %d", currentIndex)

return
}

resourceAddress := e.resourceAddresses[currentIndex]

for _, r := range req.State.Values.RootModule.Resources {
if resourceAddress == r.Address {
resource = r

break
}
}

if resource == nil {
resp.Error = fmt.Errorf("%s - Resource not found in state", resourceAddress)

return
}

if len(e.attributePaths) <= currentIndex {
resp.Error = fmt.Errorf("attribute paths index out of bounds: %d", currentIndex)

return
}

attributePath := e.attributePaths[currentIndex]

result, err := tfjsonpath.Traverse(resource.AttributeValues, attributePath)

if err != nil {
resp.Error = err

return
}

e.stateValues = append(e.stateValues, result)

err = e.comparer.CompareValues(e.stateValues...)

if err != nil {
resp.Error = err
}
}

// CompareValue returns a state check that compares values retrieved from state using the
// supplied value comparer.
func CompareValue(comparer compare.ValueComparer) *compareValue {
return &compareValue{
comparer: comparer,
}
}
Loading

0 comments on commit 5d78aa4

Please sign in to comment.