"test all types of option default values for options, add new option in a descr"
import autopath

from py.test import raises
from tiramisu.config import *
from tiramisu.option import *
from tiramisu.error import MandatoryError

def make_description():
    gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
    gcdummy = BoolOption('dummy', 'dummy', default=False)
    objspaceoption = ChoiceOption('objspace', 'Object space',
                                ['std', 'thunk'], 'std')
    booloption = BoolOption('bool', 'Test boolean option', default=True)
    intoption = IntOption('int', 'Test int option', default=0)
    floatoption = FloatOption('float', 'Test float option', default=2.3)
    stroption = StrOption('str', 'Test string option', default="abc")
    boolop = BoolOption('boolop', 'Test boolean option op', default=True)
    wantref_option = BoolOption('wantref', 'Test requires', default=False,
                                    requires=['boolop'])
    wantframework_option = BoolOption('wantframework', 'Test requires',
                                      default=False,
                                      requires=['boolop'])

    gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption])
    descr = OptionDescription('tiramisu', '', [gcgroup, booloption, objspaceoption,
                                           wantref_option, stroption,
                                           wantframework_option,
                                           intoption, boolop])
    return descr

#____________________________________________________________
# default values
def test_default_is_none():
    """
    Most constructors take a ``default`` argument that specifies the default
    value of the option. If this argument is not supplied the default value is
    assumed to be ``None``.
    """
    dummy1 = BoolOption('dummy1', 'doc dummy')
    dummy2 = BoolOption('dummy2', 'doc dummy')
    group = OptionDescription('group', '', [dummy1, dummy2])
    config = Config(group)
    # so when the default value is not set, there is actually a default value
    assert config.dummy1 == None
    assert config.dummy2 == None

def test_set_defaut_value_from_option_object():
    """Options have an available default setting and can give it back"""
    b = BoolOption("boolean", "", default=False)
    assert b.getdefault() == False

def test_mandatory():
    dummy1 = BoolOption('dummy1', 'doc dummy', properties=('mandatory', ))
    dummy2 = BoolOption('dummy2', 'doc dummy', properties=('mandatory', ))
    group = OptionDescription('group', '', [dummy1, dummy2])
    config = Config(group)
    setting = config.cfgimpl_get_settings()
    setting.read_only()
#    config.setoption('dummy1', True)
    raises(MandatoryError, 'config.dummy1')
    setting.read_write()
    config.dummy1 = True
    setting.read_only()
    assert config.dummy1 == True
    raises(MandatoryError, 'config.dummy2 == None')
#    raises(MandatoryError, "config.override({'dummy2':None})")
    setting.read_write()
    config.set(dummy2=True)
    config.dummy2 = False
    setting.read_only()
    assert config.dummy2 == False

def test_force_default_on_freeze():
    "a frozen option wich is forced returns his default"
    dummy1 = BoolOption('dummy1', 'doc dummy', default=False, properties=('force_default_on_freeze',))
    dummy2 = BoolOption('dummy2', 'doc dummy', default=True)
    group = OptionDescription('group', '', [dummy1, dummy2])
    config = Config(group)
    config.dummy1 = True
    config.dummy2 = False
    config.cfgimpl_get_settings().add_property('frozen', dummy1)
    config.cfgimpl_get_settings().add_property('frozen', dummy2)
    assert config.dummy1 == False
    assert config.dummy2 == False

#def test_override_are_defaults():
#    descr = make_description()
#    config = Config(descr)
#    config.bool = False
#    config.gc.dummy = True
#    assert config._cfgimpl_values['gc']._cfgimpl_values.owners['dummy'] == 'user'
#    #Options have an available default setting and can give it back
#    assert config._cfgimpl_descr._children[0]._children[1].getdefault() == False
##    config.override({'gc.dummy':True})
#    #assert config.gc.dummy == True
#    #assert config._cfgimpl_descr._children[0]._children[1].getdefault() == True
#    #assert config._cfgimpl_values['gc']._cfgimpl_value_owners['dummy'] == 'default'

def test_overrides_changes_option_value():
    "with config.override(), the default is changed and the value is changed"
    descr = OptionDescription("test", "", [
        BoolOption("b", "", default=False)])
    config = Config(descr)
    config.b = True
#    config.override({'b': False})
#    assert config.b == False
#____________________________________________________________
# test various option types
def test_choice_with_no_default():
    descr = OptionDescription("test", "", [
        ChoiceOption("backend", "", ("c", "cli"))])
    config = Config(descr)
    assert config.backend is None
    config.backend = "c"

def test_choice_with_default():
    descr = OptionDescription("test", "", [
        ChoiceOption("backend", "", ("c", "cli"), default="cli")])
    config = Config(descr)
    assert config.backend == "cli"

#def test_arbitrary_option():
#    descr = OptionDescription("top", "", [
#        ArbitraryOption("a", "no help", default=None)
#    ])
#    config = Config(descr)
#    config.a = []
#    config.a.append(1)
#    assert config.a == [1]

#    descr = OptionDescription("top", "", [
#        ArbitraryOption("a", "no help", defaultfactory=list)
#    ])
#    c1 = Config(descr)
#    c2 = Config(descr)
#    c1.a.append(1)
#    assert c2.a == []
#    assert c1.a == [1]