import pytest

from .. bvclass import BitValue


VAL1 = 'Value1'
VAL2 = 'Value2'
VAL3 = 'Value3'

VALUE = {
    'Value1': 5,
    'Value2': 100,
    'Value3': 30,
}


def test_sanity():
    bv = BitValue(VALUE)

def test_init_error():
    with pytest.raises(TypeError):
        bv = BitValue([])
    with pytest.raises(ValueError):
        bv = BitValue({})

def test_internal_explode_val():
    bv = BitValue(VALUE)
    assert bv._val[VAL1] == dict(length=3, max=5, value=0)
    assert bv._val[VAL2] == dict(length=7, max=100, value=0)
    assert bv._val[VAL3] == dict(length=5, max=30, value=0)

def test_internal_explode_val_existing_value():
    bv = BitValue(VALUE, 31525)
    assert bv._val[VAL1] == dict(length=3, max=5, value=5)
    assert bv._val[VAL2] == dict(length=7, max=100, value=100)
    assert bv._val[VAL3] == dict(length=5, max=30, value=30)

def test_get_and_set_value_by_dict():
    bv = BitValue(VALUE)
    bv[VAL1] = 4
    assert bv[VAL1] == 4
    with pytest.raises(KeyError):
        bv['meong']

def test_get_and_set_value_by_attribute():
    bv = BitValue(VALUE)
    bv.Value1 = 4
    assert bv['Value1'] == 4
    with pytest.raises(KeyError):
        bv.XXX = 10

def test_set_error():
    bv = BitValue(VALUE)
    with pytest.raises(ValueError):
        bv[VAL1] = 6
    with pytest.raises(TypeError):
        bv[VAL1] = 'dsdsa'
    with pytest.raises(ValueError):
        bv[VAL1] = -2

def test_as_int():
    bv = BitValue(VALUE)
    bv.Value1 = 5
    bv.Value2 = 100
    bv.Value3 = 30
    assert bv.as_int() == 31525

def test_as_dict():
    bv = BitValue(VALUE, 31525)
    assert bv.as_dict() == VALUE

def test_as_list():
    bv = BitValue(VALUE, 31525)
    dval = [
        ('Value1', 5),
        ('Value2', 100),
        ('Value3', 30),
    ]
    assert bv.as_list() == dval

def test_max_value():
    bv = BitValue(VALUE)
    with pytest.raises(ValueError):
        bv.Value1 = 6
    with pytest.raises(ValueError):
        bv.Value3 = 35

def test_64bit():
    OVER64BIt = {
        'val1': 4000000000,
        'val2': 4000000000,
        'val3': 4000000000,
    }
    with pytest.raises(OverflowError):
        bv = BitValue(OVER64BIt)

def test_compare():
    bv = BitValue(VALUE)
    assert bv.compare(31525) == VALUE
    assert bv.as_int() == 0

def test_update():
    bv = BitValue(VALUE)
    assert bv.update(31525) == VALUE
    assert bv.as_int() == 31525