Skip to content
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

#110 - Fix Slice bug producing a \n when provided with an empty slice #115

Open
wants to merge 12 commits into
base: master
Choose a base branch
from

Conversation

hsheikhali1
Copy link

see #110 for discussion

Resolved a minor bug where Slice was returning an newline when an empty string slice was passed into it.

The expected behaviour:

// Slice creates a pipe containing each element of the supplied slice of
// strings, one per line

result, err := script.ListFiles("/empty/path/")

// result returns ""

The Actual Behaviour:

result, err := script.ListFiles("/empty/path/")

// result returns "\n"

Use Case for PR

This MR will add logic that will tell Slice to check the length of the incoming string slice (len([]string{ ... })) and if it's less than or equal to 0, or if it's empty, it should tell Slice to return a pipe containing an empty string rather than a "\n"

Slice is used often in the script codebase particularly in ListFiles() where the bug was first discovered. This implementation should resolve it.

Copy link
Owner

@bitfield bitfield left a comment

Choose a reason for hiding this comment

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

Oh dear, apparently I forgot to submit this review. Sorry!

script.go Outdated
@@ -291,6 +291,9 @@ func ListFiles(path string) *Pipe {
// Slice creates a pipe containing each element of the supplied slice of
// strings, one per line.
func Slice(s []string) *Pipe {
if len(s) <= 0 {
Copy link
Owner

Choose a reason for hiding this comment

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

It seems unlikely that len(s) could be less than zero, doesn't it?

Clearly the special case here is where the length equals zero, but it seems a shame to duplicate virtually the whole function for this case. Actually, the difference in behaviour is whether or not we add a final newline. It seems slightly neater to me to isolate just that in the special-case branch.

Copy link
Owner

Choose a reason for hiding this comment

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

And if s has zero elements, there's no need to call strings.Join in any case: there's nothing to join.

Instead, what about:

if len(s) == 0 {
	return NewPipe()
}
return Echo(strings.Join(s, "\n") + "\n")

Copy link
Author

Choose a reason for hiding this comment

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

That's a very good point ! @bitfield thanks!

script_test.go Outdated
@@ -1120,6 +1120,21 @@ func TestSliceProducesElementsOfSpecifiedSliceOnePerLine(t *testing.T) {
}
}

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

Copy link
Owner

Choose a reason for hiding this comment

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

This is great, but it's house style with this project to use no blank lines within functions. To my mind, they just make the function longer without providing any benefit.

Copy link
Author

Choose a reason for hiding this comment

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

This is a thing I have built into muscle memory from my typescript work.. I noticed some Go devs prefer not to have a bunch of blank lines

script_test.go Outdated
@@ -1120,6 +1120,21 @@ func TestSliceProducesElementsOfSpecifiedSliceOnePerLine(t *testing.T) {
}
}

func TestSliceProducesNoElementsWhenProvidedWithAnEmptyList(t *testing.T) {
Copy link
Owner

Choose a reason for hiding this comment

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

Actually, since the result of Slice is a Pipe, maybe we should say something like:

func TestSliceGivenEmptySliceProducesEmptyPipe

Copy link
Owner

Choose a reason for hiding this comment

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

And we could probably use an extra test here for the non-empty slice behaviour, couldn't we? (The fact that we don't have one is entirely on me, but this is a good chance to add it.)

Copy link
Author

Choose a reason for hiding this comment

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

Doesn't this test cover non-empty slice behaviour ?

func TestSliceProducesElementsOfSpecifiedSliceOnePerLine(t *testing.T) {
	t.Parallel()
	want := "1\n2\n3\n"
	got, err := script.Slice([]string{"1", "2", "3"}).String()
	if err != nil {
		t.Fatal(err)
	}
	if !cmp.Equal(want, got) {
		t.Error(cmp.Diff(want, got))
	}
}

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