Proposal to add test cases to the `strain` problem spec

I was adding the practice exercise strain to the Gleam track and realized that there are no test cases for it in the problem-specifications repository, so I copied the ones that were created for the Elixir track.

I would like to propose that such test cases are added to the problem spec so it’s easier to replicate them.

Links:

2 Likes

I think it’s a great idea and I would love to see and review a PR to the problem-specs repo.

I’m all for adding test data for strain to the problem specs.

I’m not sure how much they differ but it might be worthwhile to try and pull test data from the various repos which do have strain test cases and try to make the problem spec resemble what already exists, assuming they have overlap.

Doesn’t list-ops pretty much supercede strain?

Yes pretty much (except strain has both filter and reject), but list-ops is much wider in scope, I still see the value for strain as a simpler exercise.

Also, I solve them differently, in list-ops , I use a fold to implement most function.

1 Like

Same here.

Does anyone has a convenient way to check which tracks implement the exercise?

Yep, the database! One sec…

  • clojure
  • common-lisp
  • csharp
  • javascript
  • elixir
  • elm
  • erlang
  • fsharp
  • go
  • haskell
  • java
  • kotlin
  • lfe
  • objective-c
  • perl5
  • python
  • ruby
  • scala
  • swift
  • typescript
  • crystal
  • groovy
  • tcl
  • scheme
  • babashka
2 Likes

Given the list of tracks that @ErikSchierboom provided (thanks btw), we’ve got two groups that share the same test cases and a third group that has some overlap:

First group

In summary, these tracks test collections that contain integers, strings, or other collections.

  1. crystal
  2. csharp
  3. elixir
  4. fsharp
  5. javascript
  6. java (deprecated)
  7. kotlin (deprecated)
  8. objective-c
  9. ruby (deprecated)
  10. scala
  11. swift
  12. typescript

List of test cases

Click to expand
description: "keep on empty list returns empty list"
input:
  list: []
  fun: fn(x) -> true
expected: []

description: "keeps everything"
input:
  list: [1, 3, 5]
  fun: fn(x) -> x % 2 == 1
expected: [1, 3, 5]

description: "keeps first and last"
input:
  list: [1, 2, 3]
  fun: fn(x) -> x % 2 == 1
expected: [1, 3]

description: "keeps neither first nor last"
input:
  list: [1, 2, 3]
  fun: fn(x) -> x % 2 == 0
expected: [2]

description: "keeps strings"
input:
  list: ["apple", "zebra", "banana", "zombies", "cherimoya", "zelot"]
  fun: fn(x) -> starts_with(x, "z")
expected: ["zebra", "zombies", "zelot"]

description: "keeps arrays"
input:
  list: [[1, 2, 3], [5, 5, 5], [5, 1, 2], [2, 1, 2], [1, 5, 2], [2, 2, 1], [1, 2, 5]]
  fun: fn(x) -> contains(x, 5)
expected: [[5, 5, 5], [5, 1, 2], [1, 5, 2], [1, 2, 5]]

description: "discard on empty list returns empty list"
input:
  list: []
  fun: fn(x) -> true
expected: []

description: "discards nothing"
input:
  list: [1, 3, 5]
  fun: fn(x) -> x % 2 == 0
expected: [1, 3, 5]

description: "discards first and last"
input:
  list: [1, 2, 3]
  fun: fn(x) -> x % 2 == 1
expected: [2]

description: "discards neither first nor last"
input:
  list: [1, 2, 3]
  fun: fn(x) -> x % 2 == 0
expected: [1, 3]

description: "discards strings"
input:
  list: ["apple", "zebra", "banana", "zombies", "cherimoya", "zelot"]
  fun: fn(x) -> starts_with(x, "z")
expected: ["apple", "banana", "cherimoya"]

description: "discards arrays"
input:
  list: [[1, 2, 3], [5, 5, 5], [5, 1, 2], [2, 1, 2], [1, 5, 2], [2, 2, 1], [1, 2, 5]]
  fun: fn(x) -> contains(x, 5)
expected: [[1, 2, 3], [2, 1, 2], [2, 2, 1]]

Second group

In summary, these tracks test collections that contain integers or strings, but not other collections. They add one extra test for keep and discard that are not in the first group.

  1. common-lisp (beta)
  2. elm
  3. erlang
  4. haskell
  5. lfe
  6. scheme

List of test cases

Click to expand
description: "keep on empty list returns empty list"
input:
  list: []
  fun: fn(x) -> true
expected: []

description: "keeps everything"
input:
  list: [1, 3, 5]
  fun: fn(x) -> x % 2 == 1
expected: [1, 3, 5]

description: "keeps nothing"
input:
  list: [1, 3, 5]
  fun: fn(x) -> x % 2 == 0
expected: []

description: "keeps first and last"
input:
  list: [1, 2, 3]
  fun: fn(x) -> x % 2 == 1
expected: [1, 3]

description: "keeps neither first nor last"
input:
  list: [1, 2, 3]
  fun: fn(x) -> x % 2 == 0
expected: [2]

description: "keeps strings"
input:
  list: ["apple", "zebra", "banana", "zombies", "cherimoya", "zelot"]
  fun: fn(x) -> starts_with(x, "z")
expected: ["zebra", "zombies", "zelot"]

description: "discard on empty list returns empty list"
input:
  list: []
  fun: fn(x) -> true
expected: []

description: "discards everything"
input:
  list: [1, 3, 5]
  fun: fn(x) -> x % 2 == 1
expected: []

description: "discards nothing"
input:
  list: [1, 3, 5]
  fun: fn(x) -> x % 2 == 0
expected: [1, 3, 5]

description: "discards first and last"
input:
  list: [1, 2, 3]
  fun: fn(x) -> x % 2 == 1
expected: [2]

description: "discards neither first nor last"
input:
  list: [1, 2, 3]
  fun: fn(x) -> x % 2 == 0
expected: [1, 3]

description: "discards strings"
input:
  list: ["apple", "zebra", "banana", "zombies", "cherimoya", "zelot"]
  fun: fn(x) -> starts_with(x, "z")
expected: ["apple", "banana", "cherimoya"]

Third group

These are tracks that don’t match any of the other two groups (although they still have some overlap).

  1. babashka
  2. clojure
  3. go
  4. groovy
  5. perl5
  6. python (deprecated)
  7. tcl

With this in mind, what do you guys think is the best way forward?

Personally, I’d go with the first group. It was implemented by the most languages, which means that it should be easiest for those languages to upgrade to the canonical data. I also quite like that you have to deal with a collection of collections.

1 Like

To be clear, the only tests that Haskell includes that are not in the first group are

_ = it "keep nothing" $
  keep even [1, 3, 5, 7] `shouldBe` ([] :: [Int])

_ = it "discard everything" $
  discard (< 10) [1, 2, 3] `shouldBe` ([] :: [Int])

and two other tests that are quite Haskell-specific. Except for effort, these "keep nothing"/"discard everything" tests seem entirely reasonable to me to add to the spec.

Currently the Haskell track does not implement the proposed "keeps arrays" and "discards arrays" tests. Thanks to the type system they aren’t needed, but I’ll happily add them.

Agreed. These would be good to have.

@ErikSchierboom Added the PR. Would you mind having a look, please? :)

Reopened for maintainer feedback :smile:

1 Like

I reviewed! Excellent job.

1 Like