Skip to content

fix: resolve assert.Contains failure for byte slices #1721

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

debug-ing
Copy link

Summary

Fixes assertion failure when using assert.Contains on byte slices.

Changes

  1. Updated assertion logic to properly handle []byte.
  2. Ensured assert.Contains correctly detects byte slice containment.
  3. Added test cases to verify the fix.

Motivation

The previous implementation caused false negatives when checking for byte slice containment with assert.Contains. This fix ensures proper handling and improves test reliability.

Related issues

issue #1720

@debug-ing
Copy link
Author

cc: @brackendawson

@debug-ing
Copy link
Author

cc: @ccoVeille

Copy link
Collaborator

@ccoVeille ccoVeille left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me share here what I previously sent privately to @brackendawson

I'm unsure how these two differs:

Because for me both are about:

Comment on lines +932 to +948
if listType.Elem().Kind() == reflect.Uint8 {
if elementType, ok := element.(string); ok {
return true, bytes.Contains(listValue.Bytes(), []byte(elementType))
}
if elementType, ok := element.([]byte); ok {
return true, bytes.Contains(listValue.Bytes(), elementType)
}
}

if elementValue.Kind() == reflect.Slice {
for i := 0; i <= listValue.Len()-elementValue.Len(); i++ {
if ObjectsAreEqual(listValue.Slice(i, i+elementValue.Len()).Interface(), element) {
return true, true
}
}
return true, false
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check on same fields but with different values, means it should be a switch

switch listType.Elem().Kind() {
case reflect.Uint8:

case reflect.Slice:
}

Comment on lines +933 to +938
if elementType, ok := element.(string); ok {
return true, bytes.Contains(listValue.Bytes(), []byte(elementType))
}
if elementType, ok := element.([]byte); ok {
return true, bytes.Contains(listValue.Bytes(), elementType)
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use a switch with type assertion here

Suggested change
if elementType, ok := element.(string); ok {
return true, bytes.Contains(listValue.Bytes(), []byte(elementType))
}
if elementType, ok := element.([]byte); ok {
return true, bytes.Contains(listValue.Bytes(), elementType)
}
switch elementType := element.(type) {
case string:
return true, bytes.Contains(listValue.Bytes(), []byte(elementType))
case []byte:
return true, bytes.Contains(listValue.Bytes(), elementType)
}

this is pseudo code written on a phone, please adapt 😬

@@ -927,6 +927,26 @@ func containsElement(list interface{}, element interface{}) (ok, found bool) {
return true, false
}

if listKind == reflect.Slice {
elementValue := reflect.ValueOf(element)
if listType.Elem().Kind() == reflect.Uint8 {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get the check on Uint8 type 🤔

Is it about checking its a byte?

Comment on lines +942 to +947
for i := 0; i <= listValue.Len()-elementValue.Len(); i++ {
if ObjectsAreEqual(listValue.Slice(i, i+elementValue.Len()).Interface(), element) {
return true, true
}
}
return true, false
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please comment this, its purpose is quite obscure. Especially the check that is made

@@ -1217,6 +1217,7 @@ func Test_containsElement(t *testing.T) {

list1 := []string{"Foo", "Bar"}
list2 := []int{1, 2}
list3 := []byte(`Hello World Hello`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let be consistent here and below:

Suggested change
list3 := []byte(`Hello World Hello`)
list3 := []byte("Hello World Hello")

@@ -1251,6 +1252,14 @@ func Test_containsElement(t *testing.T) {
True(t, ok)
False(t, found)

ok, found = containsElement(list3, []byte(`World`))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ok, found = containsElement(list3, []byte(`World`))
ok, found = containsElement(list3, []byte("World"))

True(t, ok)
True(t, found)

ok, found = containsElement(list3, []byte(`Foo`))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ok, found = containsElement(list3, []byte(`Foo`))
ok, found = containsElement(list3, []byte("Foo"))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants