<commit_before>import os
import sys
import subprocess

import pytest

main_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))

empty_python_output = """\
import prophy
"""

def tr(str_):
    """ Facilitates testing strings output from windows cmd-line programs. """
    return str_.translate(None, '\r')

def call(args):
    popen = subprocess.Popen(["python", "-m", "prophyc"] + args,
                             cwd = main_dir,
                             stdout = subprocess.PIPE,
                             stderr = subprocess.PIPE)
    out, err = popen.communicate()
    return popen.returncode, out, err

def test_showing_version():
    ret, out, err = call(["--version"])
    expected_version = '0.5.1dev'
    assert ret == 0
    assert tr(out) == 'prophyc {}\n'.format(expected_version)
    assert err == ""

def test_missing_input():
    ret, out, err = call([])
    assert ret == 1
    assert out == ""
    assert tr(err) == "prophyc: error: missing input file\n"

def test_no_output_directory(tmpdir_cwd):
    open("input.xml", "w").write("")
    ret, out, err = call(["--python_out", "no_dir",
                          os.path.join(str(tmpdir_cwd), "input_xml")])
    assert ret == 1
    assert out == ""
    assert tr(err) == "prophyc: error: argument --python_out: no_dir directory not found\n"

def test_missing_output(tmpdir_cwd):
    open("input.xml", "w")
    ret, out, err = call(["--isar", os.path.join(str(tmpdir_cwd), "input.xml")])
    assert ret == 1
    assert out == ""
    assert tr(err) == "prophyc: error: missing output directives\n"

def test_passing_isar_and_sack(tmpdir_cwd):
    open("input", "w")
    ret, out, err = call(["--isar", "--sack", "--python_out", ".",
                          os.path.join(str(tmpdir_cwd), "input")])
    assert ret == 1
    assert out == ""
    assert tr(err) == "prophyc: error: argument --sack: not allowed with argument --isar\n"

def test_isar_compiles_single_empty_xml(tmpdir_cwd):
    open("input.xml", "w").write("<struct/>")
    ret, out, err = call(["--isar", "--python_out", str(tmpdir_cwd),
                          os.path.join(str(tmpdir_cwd), "input.xml")])
    assert ret == 0
    assert out == ""
    assert err == ""
    assert empty_python_output == open("input.py").read()

def test_isar_compiles_multiple_empty_xmls(tmpdir_cwd):
    open("input1.xml", "w").write("<struct/>")
    open("input2.xml", "w").write("<struct/>")
    open("input3.xml", "w").write("<struct/>")
    ret, out, err = call(["--isar",
                          "--python_out",
                          str(tmpdir_cwd),
                          os.path.join(str(tmpdir_cwd), "input1.xml"),
                          os.path.join(str(tmpdir_cwd), "input2.xml"),
                          os.path.join(str(tmpdir_cwd), "input3.xml")])
    assert ret == 0
    assert out == ""
    assert err == ""
    assert empty_python_output == open("input1.py").read()
    assert empty_python_output == open("input2.py").read()
    assert empty_python_output == open("input3.py").read()

def test_outputs_to_correct_directory(tmpdir_cwd):
    open("input.xml", "w").write("<struct/>")
    os.mkdir("output")
    ret, out, err = call(["--isar", "--python_out",
                          os.path.join(str(tmpdir_cwd), "output"),
                          os.path.join(str(tmpdir_cwd), "input.xml")])
    assert ret == 0
    assert out == ""
    assert err == ""
    assert empty_python_output == open(os.path.join("output", "input.py")).read()

def test_isar_patch(tmpdir_cwd):
    open("input.xml", "w").write("""\
<x>
    <struct name="B">
        <member name="a" type="u8"/>
    </struct>
    <struct name="A">
        <member name="a" type="u8"/>
    </struct>
</x>
""")

    open("patch", "w").write("""\
B insert 999 b A
B dynamic b a
""")
    ret, out, err = call(["--isar", "--patch",
                          os.path.join(str(tmpdir_cwd), "patch"),
                          "--python_out",
                          str(tmpdir_cwd),
                          os.path.join(str(tmpdir_cwd), "input.xml")])
    assert ret == 0
    assert out == ""
    assert err == ""
    assert empty_python_output + """\

class A(prophy.struct):
    __metaclass__ = prophy.struct_generator
    _descriptor = [('a', prophy.u8)]

class B(prophy.struct):
    __metaclass__ = prophy.struct_generator
    _descriptor = [('a', prophy.u8),
                   ('b', prophy.array(A, bound = 'a'))]
""" == open("input.py").read()

def test_isar_cpp(tmpdir_cwd):
    open("input.xml", "w").write("""
<xml>
    <struct name="Test">
        <member name="x" type="u32">
            <dimension isVariableSize="true"/>
        </member>
    </struct>
</xml>
""")

    ret, out, err = call(["--isar",
                          "--cpp_out", str(tmpdir_cwd),
                          os.path.join(str(tmpdir_cwd), "input.xml")])
    assert ret == 0
    assert out == ""
    assert err == ""
    assert """\
struct Test
{
    uint32_t x_len;
    uint32_t x[1]; /// dynamic array, size in x_len
};
""" in open("input.pp.hpp").read()
    assert """\
template <>
Test* swap<Test>(Test* payload)
{
    swap(&payload->x_len);
    return cast<Test*>(swap_n_fixed(payload->x, payload->x_len));
}
""" in open("input.pp.cpp").read()

def test_isar_warnings(tmpdir_cwd):
    open("input.xml", "w").write("""
<xml>
    <system xmlns:xi="http://www.xyz.com/1984/XInclude">
        <xi:include href="include.xml"/>
    </system>
</xml>
""")

    ret, out, err = call(["--isar",
                          "--python_out", str(tmpdir_cwd),
                          os.path.join(str(tmpdir_cwd), "input.xml")])
    assert ret == 0
    assert out == ""
    assert err == "prophyc: warning: file include.xml not found\n"

def test_isar_with_includes(tmpdir_cwd):
    open("input.xml", "w").write("""
<xml>
    <system xmlns:xi="http://www.xyz.com/1984/XInclude">
        <xi:include href="helper.xml"/>
    </system>
    <struct name="X">
        <member name="a" type="Y"/><commit_msg>fixed failing regression test on windows<commit_after>import os
import sys
import subprocess

import pytest

main_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))

empty_python_output = """\
import prophy
"""

def tr(str_):
    """ Facilitates testing strings output from windows cmd-line programs. """
    return str_.translate(None, '\r')

def call(args):
    popen = subprocess.Popen(["python", "-m", "prophyc"] + args,
                             cwd = main_dir,
                             stdout = subprocess.PIPE,
                             stderr = subprocess.PIPE)
    out, err = popen.communicate()
    return popen.returncode, out, err

def test_showing_version():
    ret, out, err = call(["--version"])
    expected_version = '0.5.1dev'
    assert ret == 0
    assert tr(out) == 'prophyc {}\n'.format(expected_version)
    assert err == ""

def test_missing_input():
    ret, out, err = call([])
    assert ret == 1
    assert out == ""
    assert tr(err) == "prophyc: error: missing input file\n"

def test_no_output_directory(tmpdir_cwd):
    open("input.xml", "w").write("")
    ret, out, err = call(["--python_out", "no_dir",
                          os.path.join(str(tmpdir_cwd), "input_xml")])
    assert ret == 1
    assert out == ""
    assert tr(err) == "prophyc: error: argument --python_out: no_dir directory not found\n"

def test_missing_output(tmpdir_cwd):
    open("input.xml", "w")
    ret, out, err = call(["--isar", os.path.join(str(tmpdir_cwd), "input.xml")])
    assert ret == 1
    assert out == ""
    assert tr(err) == "prophyc: error: missing output directives\n"

def test_passing_isar_and_sack(tmpdir_cwd):
    open("input", "w")
    ret, out, err = call(["--isar", "--sack", "--python_out", ".",
                          os.path.join(str(tmpdir_cwd), "input")])
    assert ret == 1
    assert out == ""
    assert tr(err) == "prophyc: error: argument --sack: not allowed with argument --isar\n"

def test_isar_compiles_single_empty_xml(tmpdir_cwd):
    open("input.xml", "w").write("<struct/>")
    ret, out, err = call(["--isar", "--python_out", str(tmpdir_cwd),
                          os.path.join(str(tmpdir_cwd), "input.xml")])
    assert ret == 0
    assert out == ""
    assert err == ""
    assert empty_python_output == open("input.py").read()

def test_isar_compiles_multiple_empty_xmls(tmpdir_cwd):
    open("input1.xml", "w").write("<struct/>")
    open("input2.xml", "w").write("<struct/>")
    open("input3.xml", "w").write("<struct/>")
    ret, out, err = call(["--isar",
                          "--python_out",
                          str(tmpdir_cwd),
                          os.path.join(str(tmpdir_cwd), "input1.xml"),
                          os.path.join(str(tmpdir_cwd), "input2.xml"),
                          os.path.join(str(tmpdir_cwd), "input3.xml")])
    assert ret == 0
    assert out == ""
    assert err == ""
    assert empty_python_output == open("input1.py").read()
    assert empty_python_output == open("input2.py").read()
    assert empty_python_output == open("input3.py").read()

def test_outputs_to_correct_directory(tmpdir_cwd):
    open("input.xml", "w").write("<struct/>")
    os.mkdir("output")
    ret, out, err = call(["--isar", "--python_out",
                          os.path.join(str(tmpdir_cwd), "output"),
                          os.path.join(str(tmpdir_cwd), "input.xml")])
    assert ret == 0
    assert out == ""
    assert err == ""
    assert empty_python_output == open(os.path.join("output", "input.py")).read()

def test_isar_patch(tmpdir_cwd):
    open("input.xml", "w").write("""\
<x>
    <struct name="B">
        <member name="a" type="u8"/>
    </struct>
    <struct name="A">
        <member name="a" type="u8"/>
    </struct>
</x>
""")

    open("patch", "w").write("""\
B insert 999 b A
B dynamic b a
""")
    ret, out, err = call(["--isar", "--patch",
                          os.path.join(str(tmpdir_cwd), "patch"),
                          "--python_out",
                          str(tmpdir_cwd),
                          os.path.join(str(tmpdir_cwd), "input.xml")])
    assert ret == 0
    assert out == ""
    assert err == ""
    assert empty_python_output + """\

class A(prophy.struct):
    __metaclass__ = prophy.struct_generator
    _descriptor = [('a', prophy.u8)]

class B(prophy.struct):
    __metaclass__ = prophy.struct_generator
    _descriptor = [('a', prophy.u8),
                   ('b', prophy.array(A, bound = 'a'))]
""" == open("input.py").read()

def test_isar_cpp(tmpdir_cwd):
    open("input.xml", "w").write("""
<xml>
    <struct name="Test">
        <member name="x" type="u32">
            <dimension isVariableSize="true"/>
        </member>
    </struct>
</xml>
""")

    ret, out, err = call(["--isar",
                          "--cpp_out", str(tmpdir_cwd),
                          os.path.join(str(tmpdir_cwd), "input.xml")])
    assert ret == 0
    assert out == ""
    assert err == ""
    assert """\
struct Test
{
    uint32_t x_len;
    uint32_t x[1]; /// dynamic array, size in x_len
};
""" in open("input.pp.hpp").read()
    assert """\
template <>
Test* swap<Test>(Test* payload)
{
    swap(&payload->x_len);
    return cast<Test*>(swap_n_fixed(payload->x, payload->x_len));
}
""" in open("input.pp.cpp").read()

def test_isar_warnings(tmpdir_cwd):
    open("input.xml", "w").write("""
<xml>
    <system xmlns:xi="http://www.xyz.com/1984/XInclude">
        <xi:include href="include.xml"/>
    </system>
</xml>
""")

    ret, out, err = call(["--isar",
                          "--python_out", str(tmpdir_cwd),
                          os.path.join(str(tmpdir_cwd), "input.xml")])
    assert ret == 0
    assert out == ""
    assert tr(err) == "prophyc: warning: file include.xml not found\n"

def test_isar_with_includes(tmpdir_cwd):
    open("input.xml", "w").write("""
<xml>
    <system xmlns:xi="http://www.xyz.com/1984/XInclude">
        <xi:include href="helper.xml"/>
    </system>
    <struct name="X">
        <member name="a" type="Y"/>
{'fraction_non_alphanumeric': 0.18524956543332505, 'fraction_numerical': 0.007449714427613608, 'mean_word_length': 2.459908361970218, 'pattern_counts': {'":': 0, '<': 71, '<?xml version=': 0, '>': 77, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 66}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5660830', 'n_tokens_mistral': 4196, 'n_tokens_neox': 4100, 'n_words': 824}