# This file is part of Hypothesis, which may be found at
# https://github.com/HypothesisWorks/hypothesis/
#
# Most of this work is copyright (C) 2013-2021 David R. MacIver
# (david@drmaciver.com), but it contains contributions by others. See
# CONTRIBUTING.rst for a full list of people who may hold copyright, and
# consult the git log if you need to determine who owns an individual
# contribution.
#
# This Source Code Form is subject to the terms of the Mozilla Public License,
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at https://mozilla.org/MPL/2.0/.
#
# END HEADER
#
# SPDX-License-Identifier: MPL-2.0

"""This file demonstrates testing a binary search.

It's a useful example because the result of the binary search is so clearly
determined by the invariants it must satisfy, so we can simply test for those
invariants.

It also demonstrates the useful testing technique of testing how the answer
should change (or not) in response to movements in the underlying data.
"""

from hypothesis import given, strategies as st


def binary_search(ls, v):
    """Take a list ls and a value v such that ls is sorted and v is comparable
    with the elements of ls.

    Return an index i such that 0 <= i <= len(v) with the properties:

    1. ls.insert(i, v) is sorted
    2. ls.insert(j, v) is not sorted for j < i
    """
    # Without this check we will get an index error on the next line when the
    # list is empty.
    if not ls:
        return 0

    # Without this check we will miss the case where the insertion point should
    # be zero: The invariant we maintain in the next section is that lo is
    # always strictly lower than the insertion point.
    if v <= ls[0]:
        return 0

    # Invariant: There is no insertion point i with i <= lo
    lo = 0

    # Invariant: There is an insertion point i with i <= hi
    hi = len(ls)
    while lo + 1 < hi:
        mid = (lo + hi) // 2
        if v > ls[mid]:
            # Inserting v anywhere below mid would result in an unsorted list
            # because it's > the value at mid. Therefore mid is a valid new lo
            lo = mid
        # Uncommenting the following lines will cause this to return a valid
        # insertion point which is not always minimal.
        # elif v == ls[mid]:
        #   return mid
        else:
            # Either v == ls[mid] in which case mid is a valid insertion point
            # or v < ls[mid], in which case all valid insertion points must be
            # < hi. Either way, mid is a valid new hi.
            hi = mid
    assert lo + 1 == hi
    # We now know that there is a valid insertion point <= hi and there is no
    # valid insertion point < hi because hi - 1 is lo. Therefore hi is the
    # answer we were seeking
    return hi


def is_sorted(ls):
    """Is this list sorted?"""
    for i in range(len(ls) - 1):
        if ls[i] > ls[i + 1]:
            return False
    return True


Values = st.integers()

# We generate arbitrary lists and turn this into generating sorting lists
# by just sorting them.
SortedLists = st.lists(Values).map(sorted)

# We could also do it this way, but that would be a bad idea:
# SortedLists = st.lists(Values).filter(is_sorted)
# The problem is that Hypothesis will only generate long sorted lists with very
# low probability, so we are much better off post-processing values into the
# form we want than filtering them out.


@given(ls=SortedLists, v=Values)
def test_insert_is_sorted(ls, v):
    """We test the first invariant: binary_search should return an index such
    that inserting the value provided at that index would result in a sorted
    set."""
    ls.insert(binary_search(ls, v), v)
    assert is_sorted(ls)


@given(ls=SortedLists, v=Values)
def test_is_minimal(ls, v):
    """We test the second invariant: binary_search should return an index such
    that no smaller index is a valid insertion point for v."""
    for i in range(binary_search(ls, v)):
        ls2 = list(ls)
        ls2.insert(i, v)
        assert not is_sorted(ls2)


@given(ls=SortedLists, v=Values)
def test_inserts_into_same_place_twice(ls, v):
    """In this we test a *consequence* of the second invariant: When we insert
    a value into a list twice, the insertion point should be the same both
    times. This is because we know that v is > the previous element and == the
    next element.

    In theory if the former passes, this should always pass. In practice,
    failures are detected by this test with much higher probability because it
    deliberately puts the data into a shape that is likely to trigger a
    failure.

    This is an instance of a good general category of test: Testing how the
    function moves in responses to changes in the underlying data.
    """
    i = binary_search(ls, v)
    ls.insert(i, v)
    assert binary_search(ls, v) == i
