# Copyright 2009-2022 Joshua Bronson. All rights reserved.
#
# 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 http://mozilla.org/MPL/2.0/.

Test for consistency in ordered bidicts after handling duplicate keys/values:

    >>> from bidict import OrderedBidict, RAISE, DROP_OLD, OnDup
    >>> b = OrderedBidict([(0, 1)])

    >>> b.update([(0, 2), (3, 4), (5, 4)])
    Traceback (most recent call last):
      ...
    bidict.ValueDuplicationError: 4

    >>> b
    OrderedBidict([(0, 1)])
    >>> b.inv
    OrderedBidict([(1, 0)])

    >>> b.putall([(2, 1), (2, 3)], OnDup(key=RAISE, val=DROP_OLD))
    Traceback (most recent call last):
      ...
    bidict.KeyDuplicationError: 2

    >>> b
    OrderedBidict([(0, 1)])
    >>> list(b._node_by_korv)
    [0]
    >>> b.inv
    OrderedBidict([(1, 0)])

    >>> b.forceupdate([(0, 1), (2, 3), (0, 3)])
    >>> b
    OrderedBidict([(0, 3)])
    >>> list(b._node_by_korv)
    [0]
    >>> b.inv
    OrderedBidict([(3, 0)])

Test for consistency updating an ordered bidict's inverse:

    >>> b.inv[3] = 'UPDATED-KEY'
    >>> b
    OrderedBidict([('UPDATED-KEY', 3)])
    >>> list(b._node_by_korv)
    ['UPDATED-KEY']
    >>> b.inv
    OrderedBidict([(3, 'UPDATED-KEY')])

    >>> b.inv.forceput('UPDATED-VAL', 'UPDATED-KEY')
    >>> b
    OrderedBidict([('UPDATED-KEY', 'UPDATED-VAL')])
    >>> list(b._node_by_korv)
    ['UPDATED-KEY']
    >>> b.inv
    OrderedBidict([('UPDATED-VAL', 'UPDATED-KEY')])

    >>> b.inv['NEW-VAL'] = 'NEW-KEY'
    >>> b
    OrderedBidict([('UPDATED-KEY', 'UPDATED-VAL'), ('NEW-KEY', 'NEW-VAL')])
    >>> list(b._node_by_korv)
    ['UPDATED-KEY', 'NEW-KEY']
    >>> b.inv
    OrderedBidict([('UPDATED-VAL', 'UPDATED-KEY'), ('NEW-VAL', 'NEW-KEY')])

    >>> b.inv.forceput('NEW-VAL', 'UPDATED-KEY')
    >>> b
    OrderedBidict([('UPDATED-KEY', 'NEW-VAL')])
    >>> list(b._node_by_korv)
    ['UPDATED-KEY']
    >>> b.inv
    OrderedBidict([('NEW-VAL', 'UPDATED-KEY')])

    >>> b.inv.update([('NEWER-VAL', 'NEWER-KEY'), ('NEW-VAL', 'NEW-KEY'), ('FAIL!', 'NEW-KEY')])
    Traceback (most recent call last):
      ...
    bidict.ValueDuplicationError: NEW-KEY
    >>> b
    OrderedBidict([('UPDATED-KEY', 'NEW-VAL')])
    >>> b.inv
    OrderedBidict([('NEW-VAL', 'UPDATED-KEY')])

    >>> b.inv.forceupdate([('NEWER-VAL', 'NEWER-KEY'), ('NEW-VAL', 'NEW-KEY'), ('SUCCESS!', 'NEW-KEY')])
    >>> b
    OrderedBidict([('NEW-KEY', 'SUCCESS!'), ('NEWER-KEY', 'NEWER-VAL')])
    >>> b.inv
    OrderedBidict([('SUCCESS!', 'NEW-KEY'), ('NEWER-VAL', 'NEWER-KEY')])

Test the following here so it shows up in pytest's coverage report
(the hypothesis tests may not always hit all code paths,
and the doctests in the Sphinx docs don't get counted in the coverage report):

    >>> b.move_to_end('NEW-KEY')
    >>> b
    OrderedBidict([('NEWER-KEY', 'NEWER-VAL'), ('NEW-KEY', 'SUCCESS!')])
    >>> b.inverse.move_to_end('SUCCESS!', last=False)
    >>> b
    OrderedBidict([('NEW-KEY', 'SUCCESS!'), ('NEWER-KEY', 'NEWER-VAL')])
    >>> b.move_to_end('NOT-FOUND')
    Traceback (most recent call last):
      ...
    KeyError: 'NOT-FOUND'
    >>> b.inverse.move_to_end('NOT-FOUND')
    Traceback (most recent call last):
      ...
    KeyError: 'NOT-FOUND'

    >>> b.popitem(last=False)
    ('NEW-KEY', 'SUCCESS!')
    >>> b.inverse.popitem(last=True)
    ('NEWER-VAL', 'NEWER-KEY')
    >>> b.popitem()
    Traceback (most recent call last):
      ...
    KeyError: 'OrderedBidict is empty'
    >>> b.inverse.popitem()
    Traceback (most recent call last):
      ...
    KeyError: 'OrderedBidict is empty'

    >>> b._update(arg=())
    >>> b
    OrderedBidict()

    >>> OrderedBidict({0: 1}).pop(0)
    1
    >>> OrderedBidict({0: 1}).inverse.pop(1)
    0
    >>> OrderedBidict().pop(0)
    Traceback (most recent call last):
      ...
    KeyError: 0
    >>> OrderedBidict().inverse.pop(1)
    Traceback (most recent call last):
      ...
    KeyError: 1

The views returned by .keys(), values(), and items() are reversible:

    >>> b = OrderedBidict([(0, 1), (2, 3)])
    >>> list(reversed(b.keys()))
    [2, 0]
    >>> list(reversed(b.values()))
    [3, 1]
    >>> list(reversed(b.items()))
    [(2, 3), (0, 1)]

And they compare as expected:

    >>> b1 = OrderedBidict([(0, 1)])
    >>> b2 = OrderedBidict([(0, 1)])
    >>> b1.items() == b2.items()
    True

    >>> b1 = OrderedBidict([(False, None)]).inverse
    >>> b2 = b1.copy()
    >>> list(b1.items()) == list(b2.items())
    True
