haf / expecto

A smooth testing lib for F#. APIs made for humans! Strong testing methodologies for everyone!
Apache License 2.0
668 stars 96 forks source link

Sequence contains order assertion #260

Closed haf closed 6 years ago

haf commented 6 years ago

  /// This will pass:
  ///
  /// [ 1; 2; 3; 4; 5; 6 ]
  ///   |> Expect.sequenceContainsOrder "Valid ordering of subsequence" [ 1; 3; 5 ]
  ///
  /// This will fail:
  /// [ 1; 2; 3; 4; 5; 6 ]
  ///   |> Expect.sequenceContainsOrder "Wrong order of 0th and 1th elem" [ 3; 1; 6 ]
  ///
  /// This will fail:
  /// [ 1; 2; 3; 4; 5; 6 ]
  ///   |> Expect.sequenceContainsOrder "Missing 7 from actual" [ 1; 3; 7 ]
  ///
  /// This will pass:
  /// [ 1; 2; 3; 4; 5; 6 ]
  ///   |> Expect.sequenceContainsOrder "Empty list passes" []
  ///
  let sequenceContainsOrder message (expectedSub: #seq<'t>) (actual: #seq<'t>) =
    use ee = expectedSub.GetEnumerator()
    let el = System.Collections.Generic.Queue<'t> expectedSub
    use ae = actual.GetEnumerator()
    let al = ResizeArray<'t>()

    let rec iter i =
      if el.Count = 0 then (* success *) () else
      if not (ae.MoveNext()) then failwithf "Remainder %A of expected enumerable, after going through actual enumerable." el else
      al.Add ae.Current
      let expected = el.Peek()
      if expected = ae.Current then
        ignore (el.Dequeue())
        iter (i + 1)
      else
        iter (i + 1)

    iter 0

/cc @MNie — this is the flipped variant and without printing al, the iterated prefix of the actual enumerable. Would you like to add it and make sure it pretty prints al?

MNie commented 6 years ago

@haf sure. One thing, I think it would be better to have a signature like:

let sequenceContainsOrder actual expected message =

and in a Flip module

let sequenceContainsOrder msg expected actual = Expect.sequenceContainsOrder actual expected msg

So we would be coherent with signatures of other functions in Expecto/Flip module.

MNie commented 6 years ago

@haf I made some base work on this here I think about this a little and maybe it would be great to give an information in an error message to a client that this and this elements are on invalid position? Instead of a generic error message, order is wrong or something.

haf commented 6 years ago

@MNie https://github.com/logary/logary/commit/efa3e1caf74534a42313cad62c85bd4505ccba97#diff-655519f9fa808f075e11f3f57bcc1e6aR250

Contains more explicit printing; can you do some good merge thereof?

MNie commented 6 years ago

@haf sure, will do that today :)