Skip to content

Commit

Permalink
document tests, improve on naming and comments
Browse files Browse the repository at this point in the history
  • Loading branch information
paulperegud committed Nov 25, 2019
1 parent d0f1014 commit c0e6914
Showing 1 changed file with 20 additions and 7 deletions.
27 changes: 20 additions & 7 deletions test/ex_rlp/property_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,30 @@ defmodule ExRLP.PropTest do
use PropCheck
use ExUnit.Case

def safe_decode(t) do
def safe_decode(binary) do
try do
ExRLP.decode(t)
ExRLP.decode(binary)
rescue
_ -> false
_ -> :decoder_crashed
end
end

# Looks for cases where decoding is not one-to-one. Note: no claims about the encoder are checked here!
# If we will find two distinct binaries that decode to the same elixir value, we've found our counterexample.
# Lists and sorting are used as a performance optimization.
# This allows us to do n^2 effective checks in search space while making just n runs of generator,
# 2n runs of the decoder and n*log(n) value comparisons.
property "decoding is one to one", [1000, :verbose, max_size: 100, constraint_tries: 100_000] do
gen = such_that(bin <- binary(), when: false != safe_decode(bin))
# This generator will generate random binaries until one will decode or constraint_tries.
decodable_binary_generator =
such_that(bin <- binary(), when: :decoder_crashed != safe_decode(bin))

forall l <- list(gen) do
mapsto = for item <- :lists.usort(l), do: ExRLP.decode(item)
:lists.sort(mapsto) == :lists.usort(mapsto)
forall list_of_decodable_binaries <- list(decodable_binary_generator) do
# Make sure there are no duplicates in encoded values.
list_of_decodable_binaries = :lists.usort(list_of_decodable_binaries)
decoded_items = for item <- list_of_decodable_binaries, do: ExRLP.decode(item)
# Assert that list of decoded structures contain no duplicates.
:lists.sort(decoded_items) == :lists.usort(decoded_items)
end
end

Expand All @@ -29,6 +39,9 @@ defmodule ExRLP.PropTest do
end
end

# This test searches in at most 3 layers of nesting for lists because of lack of
# support for recursive types in propcheck.
# For details see: https://github.com/alfert/propcheck/issues/5 and related issues / PRs.
property "for lists encoding is one to one", [1000, :verbose, max_size: 100] do
forall l <-
union([
Expand Down

0 comments on commit c0e6914

Please sign in to comment.