Beispiel #1
0
def test_recursive_formatter_vformat_with_special_tuple():
    """Multiple special types call get_value and supersedes string."""
    special = Mock()
    special.get_value = Mock(return_value=123)

    my_string = MyString('blah')

    d = {
        'one': 1,
        'two': special,
        'three': '{two}',
        'arbkey': 456,
        'my_string': my_string
    }

    format_me = {'k1': '{three}', 'k2': '{my_string}'}

    formatter = RecursiveFormatter(special_types=(Mock, MyString))

    assert formatter.vformat(format_me, None, d) == {
        'k1': 123,
        'k2': '123 456'
    }
    special.get_value.assert_called_once_with(d)
    assert my_string == 'blah'
Beispiel #2
0
def test_recursive_formatter_vformat_with_passthrough_tuple():
    """Multiple passthrough types do not format."""
    d = {
        'one': 1,
        'two': '{one}',
        'three': {
            '{one}': '{two}'
        },
        'four': ['{one}', 'arb']
    }

    formatter = RecursiveFormatter(passthrough_types=(dict, list))
    assert formatter.vformat('{three}', None, d) == {'{one}': '{two}'}
    assert formatter.vformat(d['four'], None, d) == ['{one}', 'arb']
Beispiel #3
0
def test_recursive_formatter_auto_to_manual():
    """Can't switch from manual to auto field numbering."""
    with pytest.raises(ValueError) as err:
        RecursiveFormatter().format('{} {1}', 'a', 'b')

    assert (str(err.value) == (
        'cannot switch from manual field specification to automatic '
        'field numbering'))
Beispiel #4
0
def test_recursive_formatter_iterate_list():
    """Recurse through a list."""
    special = Mock()
    special.get_value = Mock(return_value=123)

    my_string = MyString('blah')
    my_string_derived = MyStringDerived('blah derived')

    d = {
        'one': 1,
        'two': special,
        'three': '{two}',
        'arbkey': 456,
        'my_string': my_string,
        'my_string_derived': my_string_derived
    }

    repeating_item = Mock()
    repeating_item.get_value = Mock(return_value=999)

    passthrough_derived_obj = ValueError('arb')

    input_obj = [
        repeating_item, 'literal string', 'string {one} expression',
        repeating_item, passthrough_derived_obj, special, '{my_string}',
        MyStringDerived,
        set([1, 2, 3, 4, '{arbkey}']), [5, 6, 7], {
            'a': 'b',
            '{one}': MyStringDerived
        }, b'\x00\x10', 890, 1.13
    ]

    formatter = RecursiveFormatter(passthrough_types=(Exception,
                                                      MyStringDerived),
                                   special_types=(Mock, MyString))
    out = formatter.vformat(input_obj, None, d)

    assert out == [
        999, 'literal string', 'string 1 expression', 999,
        passthrough_derived_obj, 123, '123 456', MyStringDerived,
        {1, 2, 3, 4, 456}, [5, 6, 7], {
            'a': 'b',
            1: MyStringDerived
        }, b'\x00\x10', 890, 1.13
    ]
Beispiel #5
0
def test_recursive_formatter_recurse_format_spec_max_exceeded():
    """Recurse on format_spec exceeding max raises."""
    d = {'dash': '-', 'i': 5, 'align': '>', 'fill': '+', 'k3': 123}

    with pytest.raises(ValueError) as err:
        RecursiveFormatter().vformat("a {k3:{fill}{align}{i:{dash}}} b", None,
                                     d)

    assert str(err.value) == 'Max string recursion exceeded'
Beispiel #6
0
def test_recursive_formatter_vformat_with_special_type():
    """Special types call get_value."""
    special = Mock()
    special.get_value = Mock(return_value=123)

    d = {'one': 1, 'two': special, 'three': '{two}'}

    assert RecursiveFormatter(special_types=Mock).vformat('{three}', None,
                                                          d) == 123
    special.get_value.assert_called_once_with(d)
Beispiel #7
0
def test_recursive_format_keep_type_recurse_format_spec_max_exceeded():
    """Recurse on format_spec exceeding max raises.

    This test is a bit arb. Strictly speaking the recursion_depth check here
    won't be hit by any implemented code, because format_spec recursion goes
    through the standard _vformat and not _format_keep_type.

    But derived classes might. So leave a test in anyway.
    """
    d = {'dash': '-', 'i': 5, 'align': '>', 'fill': '+', 'k3': 123}

    with pytest.raises(ValueError) as err:
        RecursiveFormatter()._format_keep_type(
            "a {k3:{fill}{align}{i:{dash}}} b", None, d, set(), -1)

    assert str(err.value) == 'Max string recursion exceeded'
Beispiel #8
0
def test_recursive_formatter_vformat_literal_middle():
    """Literal in middle."""
    assert RecursiveFormatter().vformat('{} literal here {a}', (1, 2),
                                        {'a': 'b'}) == '1 literal here b'
Beispiel #9
0
def test_recursive_formatter_vformat_with_passthrough():
    """Passthrough types do not format."""
    d = {'one': 1, 'two': '{one}', 'three': '{two}'}

    assert RecursiveFormatter(passthrough_types=str).vformat(
        '{three}', None, d) == '{three}'
Beispiel #10
0
def test_recursive_formatter_vformat_single_default_with_formatting():
    """Single expression is recursive & extra standard formatting works."""
    d = {'one': 1, 'two': '{one}', 'three': '{two}'}
    assert RecursiveFormatter().vformat('{three:rf+>3}', None, d) == '++1'
Beispiel #11
0
def test_recursive_formatter_vformat_single_default_with_conversion():
    """Single expression is recursive & conversion works."""
    d = {'one': 1, 'two': '{one}', 'three': '{two}'}
    assert RecursiveFormatter().vformat('{three!r:rf}', None, d) == '1'
Beispiel #12
0
def test_recursive_formatter_vformat_default():
    """Default formatting is standard flat."""
    d = {'one': '1', 'two': '2 {one} 2', 'three': '3 {two} 3'}
    assert RecursiveFormatter().vformat('start {three} end', None,
                                        d) == 'start 3 {two} 3 end'
Beispiel #13
0
def test_recursive_formatter_recurse_format_spec_double():
    """Recurse on format_spec exceeding max double replace."""
    d = {'align': '>', 'fill': '+', 'k3': 123}
    assert RecursiveFormatter().vformat("a {k3:{fill}{align}5} b", None,
                                        d) == 'a ++123 b'
Beispiel #14
0
def test_recursive_formatter_vformat_literal_end():
    """Literal at end."""
    assert RecursiveFormatter().vformat('{} literal here', (1, 2),
                                        {'a': 'b'}) == '1 literal here'
Beispiel #15
0
def test_recursive_formatter_vformat_single_flat():
    """Explicit flat formatting on single expression."""
    d = {'one': '1', 'two': '{one}', 'three': '{two}'}
    assert RecursiveFormatter().vformat('{three:ff}', None, d) == '{two}'
Beispiel #16
0
def test_recursive_formatter_vformat_single_default():
    """Default formatting is for single expression is recursive."""
    d = {'one': '1', 'two': '{one}', 'three': '{two}'}
    assert RecursiveFormatter().vformat('{three}', None, d) == '1'
Beispiel #17
0
def test_recursive_formatter_vformat_rf_to_ff():
    """Explicit recursive formatting until ff, where it stops."""
    d = {'one': '1', 'two': '2 {one} 2', 'three': '3 {two:ff} 3'}
    assert RecursiveFormatter().vformat('start {three:rf} end', None,
                                        d) == 'start 3 2 {one} 2 3 end'
Beispiel #18
0
def test_recursive_formatter_vformat_recursive():
    """Explicit recursive formatting."""
    d = {'one': '1', 'two': '2 {one} 2', 'three': '3 {two} 3'}
    assert RecursiveFormatter().vformat('start {three:rf} end', None,
                                        d) == 'start 3 2 1 2 3 end'
Beispiel #19
0
def test_recursive_formatter_vformat_default_with_formatting_conversion():
    """Flat & standard formatting expression works with conversion."""
    d = {'one': '1', 'two': '2 {one} 2', 'three': [0, 1, '{two}']}
    assert RecursiveFormatter().vformat('start {three!s:+>17} end', None,
                                        d) == "start ++[0, 1, '{two}'] end"
Beispiel #20
0
def test_recursive_formatter_vformat_default_with_formatting():
    """Default formatting is flat & standard formatting expression works."""
    d = {'one': '1', 'two': '2 {one} 2', 'three': '3 {two} 3'}
    assert RecursiveFormatter().vformat('start {three:+>11} end', None,
                                        d) == 'start ++3 {two} 3 end'
Beispiel #21
0
def test_recursive_formatter_vformat_literal_start():
    """Literal at start."""
    assert RecursiveFormatter().vformat('literal here {a}', (1, 2),
                                        {'a': 'b'}) == 'literal here b'
Beispiel #22
0
def test_recursive_formatter_format_empty():
    """Format an empty string."""
    formatter = RecursiveFormatter()
    assert formatter.format('', 'a', 'b', 'c') == ''
Beispiel #23
0
def test_recursive_formatter_recurse_format_spec():
    """Recurse on format_spec works."""
    d = {'k1': 'x', 'k2': 123}
    assert RecursiveFormatter().vformat("a {k2:{k1}} b", None, d) == 'a 7b b'
Beispiel #24
0
def test_recursive_formatter_vformat_literal():
    """Literal only."""
    assert RecursiveFormatter().vformat('literal here', (1, 2),
                                        {'a': 'b'}) == 'literal here'
Beispiel #25
0
def test_recursive_formatter_vformat_single_recursive():
    """Explicit recursive formatting on single formatting."""
    d = {'one': '1', 'two': '{one}', 'three': '{two}'}
    assert RecursiveFormatter().vformat('{three:rf}', None, d) == '1'
Beispiel #26
0
def test_recursive_formatter_vformat_no_literal():
    """No literal, only formatting expressions."""
    assert RecursiveFormatter().vformat('{0}{1}{a}', (1, 2),
                                        {'a': 'b'}) == '12b'
Beispiel #27
0
def test_recursive_formatter_format_none():
    """Format a None."""
    formatter = RecursiveFormatter()
    assert formatter.format(None, 'a', 'b', 'c') is None
Beispiel #28
0
def test_recursive_formatter_vformat_single_default_to_ff():
    """Default recursive formatting on single formatting stops at ff."""
    d = {'one': '1', 'two': '{one}', 'three': '{two:ff}'}
    assert RecursiveFormatter().vformat('{three}', None, d) == '{one}'
Beispiel #29
0
def test_recursive_formatter_format_no_expression():
    """Format a string sans formatting expression."""
    formatter = RecursiveFormatter()
    assert formatter.format('arb string', 'a', 'b', 'c') == 'arb string'
Beispiel #30
0
def test_recursive_formatter_vformat_single_default_keep_type():
    """Default formatting for single expression is recursive & keeps type."""
    d = {'one': 1, 'two': '{one}', 'three': '{two}'}
    assert RecursiveFormatter().vformat('{three}', None, d) == 1