
from translate.storage.placeables import general


def test_placeable_numbers():
    """Check the correct functioning of number placeables"""
    assert general.NumberPlaceable(["25"]) in general.NumberPlaceable.parse("Here is a 25 number")
    assert general.NumberPlaceable(["-25"]) in general.NumberPlaceable.parse("Here is a -25 number")
    assert general.NumberPlaceable(["+25"]) in general.NumberPlaceable.parse("Here is a +25 number")
    assert general.NumberPlaceable(["25.00"]) in general.NumberPlaceable.parse("Here is a 25.00 number")
    assert general.NumberPlaceable(["2,500.00"]) in general.NumberPlaceable.parse("Here is a 2,500.00 number")
    assert general.NumberPlaceable(["1\u00a0000,99"]) in general.NumberPlaceable.parse("Here is a 1\u00a0000,99 number")


def test_placeable_newline():
    assert general.NewlinePlaceable.parse("A newline\n")[1] == general.NewlinePlaceable(["\n"])
    assert general.NewlinePlaceable.parse("First\nSecond")[1] == general.NewlinePlaceable(["\n"])


def test_placeable_alt_attr():
    assert general.AltAttrPlaceable.parse('Click on the <img src="image.jpg" alt="Image">')[1] == general.AltAttrPlaceable(['alt="Image"'])


def test_placeable_qt_formatting():
    assert general.QtFormattingPlaceable.parse('One %1 %99 %L1 are all valid')[1] == general.QtFormattingPlaceable(['%1'])
    assert general.QtFormattingPlaceable.parse('One %1 %99 %L1 are all valid')[3] == general.QtFormattingPlaceable(['%99'])
    assert general.QtFormattingPlaceable.parse('One %1 %99 %L1 are all valid')[5] == general.QtFormattingPlaceable(['%L1'])


def test_placeable_camelcase():
    assert general.CamelCasePlaceable.parse('CamelCase')[0] == general.CamelCasePlaceable(['CamelCase'])
    assert general.CamelCasePlaceable.parse('iPod')[0] == general.CamelCasePlaceable(['iPod'])
    assert general.CamelCasePlaceable.parse('DokuWiki')[0] == general.CamelCasePlaceable(['DokuWiki'])
    assert general.CamelCasePlaceable.parse('KBabel')[0] == general.CamelCasePlaceable(['KBabel'])
    assert general.CamelCasePlaceable.parse('_Bug') is None
    assert general.CamelCasePlaceable.parse('NOTCAMEL') is None


def test_placeable_space():
    assert general.SpacesPlaceable.parse(' Space at start')[0] == general.SpacesPlaceable([' '])
    assert general.SpacesPlaceable.parse('Space at end ')[1] == general.SpacesPlaceable([' '])
    assert general.SpacesPlaceable.parse('Double  space')[1] == general.SpacesPlaceable(['  '])


def test_placeable_punctuation():
    assert general.PunctuationPlaceable.parse('These, are not. Special: punctuation; marks! Or are "they"?') is None
    assert general.PunctuationPlaceable.parse('Downloading…')[1] == general.PunctuationPlaceable(['…'])


def test_placeable_xml_entity():
    assert general.XMLEntityPlaceable.parse('&brandShortName;')[0] == general.XMLEntityPlaceable(['&brandShortName;'])
    assert general.XMLEntityPlaceable.parse('&#1234;')[0] == general.XMLEntityPlaceable(['&#1234;'])
    assert general.XMLEntityPlaceable.parse('&xDEAD;')[0] == general.XMLEntityPlaceable(['&xDEAD;'])


def test_placeable_xml_tag():
    assert general.XMLTagPlaceable.parse('<a>koei</a>')[0] == general.XMLTagPlaceable(['<a>'])
    assert general.XMLTagPlaceable.parse('<a>koei</a>')[2] == general.XMLTagPlaceable(['</a>'])
    assert general.XMLTagPlaceable.parse('<Exif.XResolution>')[0] == general.XMLTagPlaceable(['<Exif.XResolution>'])
    assert general.XMLTagPlaceable.parse('<tag_a>')[0] == general.XMLTagPlaceable(['<tag_a>'])
    assert general.XMLTagPlaceable.parse('<img src="koei.jpg" />')[0] == general.XMLTagPlaceable(['<img src="koei.jpg" />'])
    # We don't want this to be recognised, so we test for None - not sure if that is a stable assumption
    assert general.XMLTagPlaceable.parse('<important word>') is None
    assert general.XMLTagPlaceable.parse('<img ="koei.jpg" />') is None
    assert general.XMLTagPlaceable.parse('<img "koei.jpg" />') is None
    assert general.XMLTagPlaceable.parse('<span xml:space="preserve">')[0] == general.XMLTagPlaceable(['<span xml:space="preserve">'])
    assert general.XMLTagPlaceable.parse('<img src="http://translate.org.za/blogs/friedel/sites/translate.org.za.blogs.friedel/files/virtaal-7f_help.png" alt="Virtaal met lêernaam-pseudovertaling" style="border: 1px dotted grey;" />')[0] == general.XMLTagPlaceable(['<img src="http://translate.org.za/blogs/friedel/sites/translate.org.za.blogs.friedel/files/virtaal-7f_help.png" alt="Virtaal met lêernaam-pseudovertaling" style="border: 1px dotted grey;" />'])
    # Bug 933
    assert general.XMLTagPlaceable.parse('This entry expires in %days% days. Would you like to <a href="%href%?PHPSESSID=5d59c559cf4eb9f1d278918271fbe68a" title="Renew this Entry Now">Renew this Entry Now</a> ?')[1] == general.XMLTagPlaceable(['<a href="%href%?PHPSESSID=5d59c559cf4eb9f1d278918271fbe68a" title="Renew this Entry Now">'])
    assert general.XMLTagPlaceable.parse('''<span weight='bold' size='larger'>Your Google Account is locked</span>''')[0] == general.XMLTagPlaceable(['''<span weight='bold' size='larger'>'''])


def test_placeable_option():
    assert general.OptionPlaceable.parse('Type --help for this help')[1] == general.OptionPlaceable(['--help'])
    assert general.OptionPlaceable.parse('Short -S ones also')[1] == general.OptionPlaceable(['-S'])


def test_placeable_file():
    assert general.FilePlaceable.parse('Store in /home/user')[1] == general.FilePlaceable(['/home/user'])
    assert general.FilePlaceable.parse('Store in ~/Download directory')[1] == general.FilePlaceable(['~/Download'])


def test_placeable_email():
    assert general.EmailPlaceable.parse('Send email to info@example.com')[1] == general.EmailPlaceable(['info@example.com'])
    assert general.EmailPlaceable.parse('Send email to mailto:info@example.com')[1] == general.EmailPlaceable(['mailto:info@example.com'])


def test_placeable_caps():
    assert general.CapsPlaceable.parse('Use the HTML page')[1] == general.CapsPlaceable(['HTML'])
    assert general.CapsPlaceable.parse('I am') is None
    assert general.CapsPlaceable.parse('Use the A4 paper') is None
    assert general.CapsPlaceable.parse('In GTK+')[1] == general.CapsPlaceable(['GTK+'])
#    assert general.CapsPlaceable.parse('GNOME-stuff')[0] == general.CapsPlaceable(['GNOME'])
    assert general.CapsPlaceable.parse('with XDG_USER_DIRS')[1] == general.CapsPlaceable(['XDG_USER_DIRS'])


def test_placeable_formatting():
    fp = general.FormattingPlaceable
    assert fp.parse('There were %d cows')[1] == fp(['%d'])
    assert fp.parse('There were %Id cows')[1] == fp(['%Id'])
    assert fp.parse('There were %d %s')[3] == fp(['%s'])
    assert fp.parse('%1$s was kicked by %2$s')[0] == fp(['%1$s'])
    assert fp.parse('There were %Id cows')[1] == fp(['%Id'])
    assert fp.parse('There were % d cows')[1] == fp(['% d'])
    # only a real space is allowed as formatting flag
    assert fp.parse('There were %\u00a0d cows') is None
    assert fp.parse("There were %'f cows")[1] == fp(["%'f"])
    assert fp.parse("There were %#x cows")[1] == fp(["%#x"])

    # field width
    assert fp.parse('There were %3d cows')[1] == fp(['%3d'])
    assert fp.parse('There were %33d cows')[1] == fp(['%33d'])
    assert fp.parse('There were %*d cows')[1] == fp(['%*d'])

    # numbered variables
    assert fp.parse('There were %1$d cows')[1] == fp(['%1$d'])


def test_placeable_doubleat():
    dap = general.DoubleAtPlaceable
    assert dap.parse('There were @@number@@ cows')[1] == dap(['@@number@@'])
    assert dap.parse('There were @@number1@@ cows and @@number2@@ sheep')[1] == dap(['@@number1@@'])
    assert dap.parse('There were @@number1@@ cows and @@number2@@ sheep')[3] == dap(['@@number2@@'])


def test_placeable_brace():
    bp = general.BracePlaceable
    # Double braces
    assert bp.parse('There were {{number}} cows')[1] == bp(['{{number}}'])
    assert bp.parse('There were {{number1}} cows and {{number2}} sheep')[1] == bp(['{{number1}}'])
    assert bp.parse('There were {{number1}} cows and {{number2}} sheep')[3] == bp(['{{number2}}'])

    # Single braces
    assert bp.parse('There were {number} cows')[1] == bp(['{number}'])
    assert bp.parse('There were {number1} cows and {number2} sheep')[1] == bp(['{number1}'])
    assert bp.parse('There were {number1} cows and {number2} sheep')[3] == bp(['{number2}'])

    # Mixed single and double braces
    assert bp.parse('There were {number1} cows and {{number2}} sheep')[1] == bp(['{number1}'])
    assert bp.parse('There were {number1} cows and {{number2}} sheep')[3] == bp(['{{number2}}'])
    assert bp.parse('There were {{number1}} cows and {number2} sheep')[1] == bp(['{{number1}}'])
    assert bp.parse('There were {{number1}} cows and {number2} sheep')[3] == bp(['{number2}'])


def test_python_placeable():
    pfp = general.PythonFormattingPlaceable
    # No conversion
    assert pfp.parse('100%% correct')[1] == pfp(['%%'])

    # Mapping keys
    assert pfp.parse('There were %(number)d cows')[1] == pfp(['%(number)d'])
    assert pfp.parse('There were %(cows.number)d cows')[1] == pfp(['%(cows.number)d'])
    assert pfp.parse('There were %(number of cows)d cows')[1] == pfp(['%(number of cows)d'])

    # Conversion flags
    assert pfp.parse('There were %(number)03d cows')[1] == pfp(['%(number)03d'])
    assert pfp.parse('There were %(number) 3d cows')[1] == pfp(['%(number) 3d'])

    # Minimum field width
    assert pfp.parse('There were %(number)*d cows')[1] == pfp(['%(number)*d'])

    # Precision
    assert pfp.parse('There were %(number)3.1d cows')[1] == pfp(['%(number)3.1d'])

    # Length modifier
    assert pfp.parse('There were %(number)Ld cows')[1] == pfp(['%(number)Ld'])


# TODO: JavaMessageFormatPlaceable, UrlPlaceable, XMLTagPlaceable
