def test_empty_extra():
    formatter = AppendJSONFormatter(limit_keys_to=('foo',))
    record = get_record(extra={'bar': 'no'})
    output = formatter.format(record)
    # empty json should not lead to excess whitespace at the end of the line
    assert not output.endswith(' ')
    assert formatter.get_json(record) == ''
def test_repr_fail():
    class A:
        def __repr__(self):
            raise ValueError

    formatter = AppendJSONFormatter()
    record = get_record(extra={'a': A()})
    output = formatter.format(record)
    assert AppendJSONFormatter.REPR_FAIL_PLACEHOLDER in output
def test_limit_keys_to():
    formatter = AppendJSONFormatter(limit_keys_to=('foo', 'bar'))
    record = get_record(extra={'foo': 'yes', 'bar': 'yes', 'baz': 'no'})
    output = formatter.format(record)
    assert output.count('yes') == 2
    assert output.count('no') == 0

    data = json.loads(formatter.get_json(record))
    assert data['foo'] == 'yes'
    assert data['bar'] == 'yes'
    assert 'baz' not in data
def test_force_keys():
    formatter = AppendJSONFormatter(force_keys=('lineno', 'levelname'))
    record = get_record(extra={'foo': 'yes', 'bar': 'yes', 'baz': 'no'})
    output = formatter.format(record)
    assert 'levelname' in output
    assert 'lineno' in output