Protocol.UndefinedError String.Chars not implemented

Running a property testing :

property "when a & b are arbitrary json objects; patch(a, diff(a,b)) == b" do
    check all(
            map_a <- map_of(term(), term()),
            map_b <- map_of(term(), term())
          ) do

            IO.inspect(" This is map a #{inspect(map_a)}")
            IO.inspect("This is map b #{inspect(map_b)}")
            IO.inspect("This is the diff of a and b #{inspect(JsonDiffEx.diff(map_a, map_b))}")

      assert map_b == JsonDiffEx.patch(map_a,JsonDiffEx.diff(map_a, map_b))

It runs successfully for like 20-30 times before returning this error.

Protocol.UndefinedError) protocol String.Chars not implemented for {#Reference<0.2396724294.953679873.147789>, :GiFYV, -10} of type Tuple. This protocol is implemented for the following type(s): Atom, BitString, Date, DateTime, Decimal, ExJsonSchema.Validator.Error.AdditionalItems, ExJsonSchema.Validator.Error.AdditionalProperties, ExJsonSchema.Validator.Error.AllOf, ExJsonSchema.Validator.Error.AnyOf, ExJsonSchema.Validator.Error.Const, ExJsonSchema.Validator.Error.Contains, ExJsonSchema.Validator.Error.ContentEncoding, ExJsonSchema.Validator.Error.ContentMediaType, ExJsonSchema.Validator.Error.Dependencies, ExJsonSchema.Validator.Error.Enum, ExJsonSchema.Validator.Error.False, ExJsonSchema.Validator.Error.Format, ExJsonSchema.Validator.Error.IfThenElse, ExJsonSchema.Validator.Error.ItemsNotAllowed, ExJsonSchema.Validator.Error.MaxItems, ExJsonSchema.Validator.Error.MaxLength, ExJsonSchema.Validator.Error.MaxProperties, ExJsonSchema.Validator.Error.Maximum, ExJsonSchema.Validator.Error.MinItems, ExJsonSchema.Validator.Error.MinLength, ExJsonSchema.Validator.Error.MinProperties, ExJsonSchema.Validator.Error.Minimum, ExJsonSchema.Validator.Error.MultipleOf, ExJsonSchema.Validator.Error.Not, ExJsonSchema.Validator.Error.OneOf, ExJsonSchema.Validator.Error.Pattern, ExJsonSchema.Validator.Error.PropertyNames, ExJsonSchema.Validator.Error.Required, ExJsonSchema.Validator.Error.Type, ExJsonSchema.Validator.Error.UniqueItems, Float, Integer, List, NaiveDateTime, Phoenix.LiveComponent.CID, Postgrex.Copy, Postgrex.INET, Postgrex.MACADDR, Postgrex.Query, Time, URI, Version, Version.Requirement

Here is the stacktrace :

(elixir 1.13.2) lib/string/chars.ex:3: String.Chars.impl_for!/1
       (elixir 1.13.2) lib/string/chars.ex:22: String.Chars.to_string/1
       (elixir 1.13.2) lib/enum.ex:3828: Enum.join_non_empty_list/3
       (elixir 1.13.2) lib/enum.ex:4109: Enum.join_list/2
       (json_diff_ex 0.6.6) lib/json_diff_ex.ex:320: JsonDiffEx.correct_lists/2
       (json_diff_ex 0.6.6) lib/json_diff_ex.ex:294: JsonDiffEx.do_patch_merge/3
       (elixir 1.13.2) lib/map.ex:617: Map.update/4
       (stdlib 3.17) maps.erl:410: :maps.fold_1/3
       (json_diff_ex 0.6.6) lib/json_diff_ex.ex:288: JsonDiffEx.do_patch/2
       hidden/hidden/hidden/difftesting_test.exs:17: anonymous fn/3 in DifftestingTest."property when a & b are arbitrary json objects; patch(a, diff(a,b)) == b"/1
       (stream_data 0.5.0) lib/stream_data.ex:2148: StreamData.shrink_failure/6
       (stream_data 0.5.0) lib/stream_data.ex:2108: StreamData.check_all/7
       test/hidden/hidden/difftesting_test.exs:8: (test)

Thank you in advance! Not sure what the problem is, still learning how to debug elixir code.

1 Like

You’re trying to test a property about arbitrary json objects, but term() can generate values that are NOT valid json objects, like a reference or a tuple. Thus when JsonDiffEx tries to do a diff, it errors.


Thank you for the response. Should I filter for only valid json objects such as integers, strings …etc? Thank you in advance, I appreciate the help.

You can filter, but it’s less efficient because your generator is gonna generate a high percentage of maps that are not legal json. Instead I’d try to craft a generator that only emits valid JSON to start with.

1 Like

When I do something like this

 property "when a & b are arbitrary json objects; patch(a, diff(a,b)) == b" do
    check all(
            map_a <- map_of(one_of([integer(), string(:printable), boolean(), nil]), one_of([integer(), string(:printable), boolean(), nil])),
            map_b <- map_of(one_of([integer(), string(:printable), boolean(), nil]), one_of([integer(), string(:printable), boolean(), nil]))
          ) do

      assert map_b == JsonDiffEx.patch(map_a,JsonDiffEx.diff(map_a, map_b))

I get this error, how would I avoid this?

* (StreamData.TooManyDuplicatesError) too many (10) non-unique elements were generated consecutively. Make sure to avoid generating from a small space of data (such as only a handful of terms) and make sure a small generation size doesn't affect uniqueness too heavily. There were still 1 elements left to generate, while the generated elements were:
     #MapSet<[[#StreamData<45.35859701/2 in StreamData.integer/0>, #StreamData<88.35859701/2 in StreamData.string_from_codepoint_data/2>, #StreamData<21.35859701/2 in StreamData.boolean/0>, nil]]>
     code: check all(
       (stream_data 0.5.0) lib/stream_data.ex:1035: StreamData.uniq_list_of/9
       (stream_data 0.5.0) lib/stream_data.ex:1006: anonymous fn/6 in StreamData.uniq_list_of/2
       (stream_data 0.5.0) lib/stream_data.ex:202:
       (stream_data 0.5.0) lib/stream_data.ex:282: anonymous fn/3 in StreamData.map_of/3
       (stream_data 0.5.0) lib/stream_data.ex:202: StreamData.bind_filter/5
       (stream_data 0.5.0) lib/stream_data.ex:351: anonymous fn/5 in StreamData.bind_filter/3
       (stream_data 0.5.0) lib/stream_data.ex:202: StreamData.check_all/7
       test/hidden/hidden/difftesting_test.exs:7: (test)