from indent_io import IndentIO
from cStringIO import StringIO
from pyast import *
import pytest

ast_output_tests = [

(While(BinOp(Const(4), '==', Const(1)),
    [While(Const(False),
        [Const(True),
         Const(4)])]),
"""while (4 == 1):
    while False:
        True
        4"""),

(For('x', Const(4), [Pass()]),
"""for x in 4:
    pass"""),

]

ast_no_validate_tests = [
        While(Pass(), Pass()),
]

@pytest.mark.parametrize('ast,output', ast_output_tests)
def test_output(ast, output):
    ast.check()
    outbuf = StringIO()
    outio = IndentIO(outbuf)
    ast.write_to(outio)
    outbuf.seek(0)
    # We strip whitespace off of the actual output here; Otherwise we will often
    # get trailing whitespace on an empty line, which is weird to look at here
    # given that it matters semantically for the tests, and it doesn't affect
    # the python semantics, so we don't care.
    assert outbuf.read().strip() == output


@pytest.mark.parametrize('ast', ast_no_validate_tests)
def test_no_validate(ast):
    with pytest.raises(ValidationError):
        ast.check()


def test_indent_io():
    outbuf = StringIO()
    io = IndentIO(outbuf)

    io.write('%d\n' % io.level)
    with io.indent():
        io.write('%d\n' % io.level)
        with io.indent():
            io.write('%d-' % io.level)
            io.write('%d\n' % io.level)
            with io.indent():
                io.write('%d\n' % io.level)
            io.write('%d\n' % io.level)
        io.write('%d\n' % io.level)
    io.write('%d\n' % io.level)

    outbuf.seek(0)
    assert outbuf.read() ==\
"""0
    1
        2-2
            3
        2
    1
0
"""

@@ -117,302 +117,805 @@
 %5B%0A%0A(
-While(BinOp(Const(4), '==', Const(1)),%0A    %5BWhile(Const(False),%0A        %5BConst(True),%0A         Const(4)%5D)%5D),%0A%22%22%22while (4 == 1):%0A    while False:%0A        True%0A        4%22%22%22),%0A%0A(For('x', Const(4), %5BPass()%5D),%0A%22%22%22for x in 4:%0A    pass%22%22%22),%0A%0A%5D%0A%0Aast_no_validate_tests = %5B%0A        While(Pass(), Pass()),
+Const(0), %220%22),%0A(Const('Hello'), %22'Hello'%22),%0A(Const(True), 'True'),%0A(Const(4.2), '4.2'),%0A%0A(BinOp(Const(4), '+', Const(2)),%0A    %22(4 + 2)%22),%0A(BinOp(BinOp(Const(4), '+', Const(2)), '%3C', Const(7)),%0A    %22((4 + 2) %3C 7)%22),%0A%0A(Pass(), %22pass%22),%0A%0A(While(Const(True), %5BPass()%5D),%0A%22%22%22while True:%0A    pass%22%22%22),%0A%0A(While(BinOp(Const(4), '==', Const(1)),%0A    %5BWhile(Const(False),%0A        %5BConst(True),%0A         Const(4)%5D)%5D),%0A%22%22%22while (4 == 1):%0A    while False:%0A        True%0A        4%22%22%22),%0A%0A(For('x', Const(4), %5BPass()%5D),%0A%22%22%22for x in 4:%0A    pass%22%22%22),%0A%0A(For('x', Const(4), %5BPass(), Const(False)%5D),%0A%22%22%22for x in 4:%0A    pass%0A    False%22%22%22),%0A%0A%5D%0A%0Aast_no_validate_tests = %5B%0A%0A        Const(BinOp(Const(4), '+', Const(2))),%0A%0A        Const(Pass()),%0A%0A        While(Pass(), Pass()),%0A%0A        BinOp(Const(4), Const(5), Const(6)),%0A
 %0A%5D%0A%0A

Add more tests