Skip to content

Strange behaviour of string(:printable) with min_length opt given #99

Open
@volnyvolnyvolny

Description

@volnyvolnyvolny

Hi! I'm using stream_data to test my Ecto schemas, but I ran into a small problem concerning min_length opt given to StreamData.string(:printable).

property "string(:printable) min_length" do
  # While this works fine, giving 41,41,41,...,44,45,42,43,44,47,44,...
  check all s <- string(:alphanumeric, min_length: 41) do
    IO.inspect(String.length(s))
    assert String.length(s) >= 41
  end

  # This returns 41,41,40,40,...39,40.
  check all s <- string(:printable, min_length: 41) do
    IO.inspect(String.length(s))
    assert String.length(s) >= 41
  end
end

Error:

1) property string string(:printable) min_length (StringTest)
   test/string_test.exs:6
   Failed with generated values (after 4 successful runs):
 
       * Clause:    s <- string(:printable, min_length: 41)
         Generated: "𐀀𐀀𐀀𐀀𐀀ꢴ񭺍񅂤𜚸򫱞򑐑񄧸󫋎󣪣򵧸򙠘𯜬󽳷󁎫򰹡󑳃򭲠񗪙񀌾𐖜󠱺񅖬󔬺񽇾𬆟񘂑񦪥򖀣򍿖񪲲󙭠𛢢񉗒􊠮񏱉򍄓"
 
   Assertion with >= failed
   code:  assert String.length(s) >= 41
   left:  40
   right: 41
   stacktrace:
     test/string_test.exs:15: anonymous fn/2 in StringTest."property string string(:printable) min_length"/1
     (stream_data) lib/stream_data.ex:2063: StreamData.shrink_failure/6
     (stream_data) lib/stream_data.ex:2027: StreamData.check_all/7
     test/string_test.exs:13: (test)

PS> Off topic. Don't want to spam with feature requests, but is it possible to add invert function that reverts generators? So invert(string(:alphanumeric, min_length: 10)) gives us a one_of([string(:alphanumeric, max_length: 9), string(:printable) |> filter(&(not String.match?(&1, ~r/^[0-9A-Za-z]+$/)))])? At the first glance It is always set-theoretically possible and may be very handy.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions