Beispiel #1
0
def test_import_from_workdir_py(tmpdir):
    """Test that workdir.py file is read and added to the workdir"""
    contents = textwrap.dedent("""
        import os
        
        def jambalaya(a,b):
            import sys
            return a+b
            
        print("JAMBALAYA")
        
        
        class Jambalaya(object):
            pass
        """)
    with open(tmpdir / "workdir.py", "w") as pyfile:
        pyfile.write(contents)
    wd = WorkDir(tmpdir)
    assert hasattr(wd, "jambalaya")
    assert hasattr(wd, "Jambalaya")
    assert callable(wd.jambalaya)
    assert isinstance(wd.Jambalaya, type)
    assert not hasattr(wd, "sys")
    assert not hasattr(wd, "os")
    assert wd.jambalaya(2, 5) == 7
Beispiel #2
0
def test_log_errors(tmpdir):
    """Test if errors are written to the logfile."""
    wd = WorkDir(tmpdir, logfile="mylog.txt", loglevel_file=logging.INFO)
    wd.log("Hello", logging.DEBUG)
    with pytest.raises(AssertionError):
        with wd:
            assert False
    with open(tmpdir / "mylog.txt") as f:
        assert "AssertionError" in f.read()
Beispiel #3
0
def test_failure_import_with_workdir(tmpdir):
    """Test that bugs in the functions are detected."""
    contents = textwrap.dedent("""
        def jambalaya(a, b):
            assert hasattr(wave, "Chunk")  # to make sure that top level imports are recognized
            return a+b
        """)
    with open(tmpdir / "workdir.py", "w") as pyfile:
        pyfile.write(contents)
    wd = WorkDir(tmpdir)
    with pytest.raises(NameError):
        wd.jambalaya(2, 5)
Beispiel #4
0
def test_function_added_as_method(tmpdir):
    """Test that workdir is accessible for functions that use workdir"""
    contents = textwrap.dedent("""
        def jambalaya(a, workdir, b):
            return workdir.path, a+b
        """)
    with open(tmpdir / "workdir.py", "w") as pyfile:
        pyfile.write(contents)
    wd = WorkDir(tmpdir)
    path, sum = wd.jambalaya(2, 5)
    assert isinstance(path, pathlib.Path)
    assert str(path) == str(tmpdir)
Beispiel #5
0
def test_create_directory(tmpdir):
    """Check mkdir parameter"""
    dir = tmpdir / "subdir"
    wd = WorkDir(dir, mkdir=False)
    assert not wd.path.exists()
    wd = WorkDir(dir, mkdir=True)
    assert wd.path.exists()
    wd = WorkDir(dir, mkdir=True)
    # check failures
    (wd.path / "a").touch()
    with pytest.raises(WorkDirException):
        WorkDir(wd.path / "a", mkdir=True)
Beispiel #6
0
def test_import_imports(tmpdir):
    """Test that top-level imports are known to the function."""
    contents = textwrap.dedent("""
        import wave

        def jambalaya(a,b):
            assert hasattr(wave, "Chunk")  # to make sure that top level imports are recognized
            return a+b
        """)
    with open(tmpdir / "workdir.py", "w") as pyfile:
        pyfile.write(contents)
    wd = WorkDir(tmpdir)
    assert hasattr(wd, "jambalaya")
    assert wd.jambalaya(2, 5) == 7
Beispiel #7
0
def test_commandline_workdir_option(tmpdir):
    contents = textwrap.dedent("""
        import click

        @click.option("-s")
        @click.option("-p")
        def things(s, workdir, here, p):
            print(s)
            print(here/"here.tmp")
            print(workdir/"test.tmp")
            print(p)
        
        @click.option("-s")
        def hello(s):
            print("Hello", s)
        """)
    with open(tmpdir / "workdir.py", "w") as f:
        f.write(contents)
    main = forge_command_line_interface(directory=tmpdir)
    runner = CliRunner(env={"PWD": str(tmpdir)})
    result = runner.invoke(main, "--help")
    assert "things" in result.output
    assert "hello" in result.output
    result = runner.invoke(main, ["things", "-p", "thing2", "-s", "thing1"])
    print(result.output)
    wd = WorkDir(tmpdir)
    assert result.exit_code == 0
    assert result.output == '\n'.join(
        ["thing1",
         str(wd / "here.tmp"),
         str(wd / "test.tmp"), "thing2", ""])
Beispiel #8
0
def forge_command_line_interface(*args, **kwargs):
    """
    Forge the click.Group that holds all commands defined in workdir.py
    All arguments are forwarded to the constructor of WorkDir.

    Returns
    -------
    A click.Group that defines one command for every custom function in the WorkDir.
    """
    wd = WorkDir(*args, **kwargs)
    main = click.Group(
        name="workdir",
        help=textwrap.dedent(
            """
            Commands in this working directory.
            Add commands by defining functions in workdir.py;
            decorate them with "@click.option(...)" to define function parameters as command line options.
            """)
    )
    # add version option
    main = click.version_option(version=pyworkdir.__version__, prog_name="pyworkdir")(main)
    # collect commands
    for attribute in wd.custom_attributes:
        object = getattr(wd, attribute)
        if inspect.isfunction(object) and not hasattr(object, "__nocli__"):
            main.command()(object)
    for command in wd.commands:
        bash, doc = wd.commands[command].split("//")
        cmd = click.Command(command, callback=bash_function(bash), help=doc)
        main.add_command(cmd)
    # default commands
    main.command()(forge_method(wd, show, replace_args={"workdir": wd}, add=False))
    return main
Beispiel #9
0
def test_vars_and_classes_from_pyfile(tmpdir):
    """Test that variables and classes from python files get added """
    contents = textwrap.dedent("""
        import pyworkdir
        
        a = 2
        
        class A(pyworkdir.WorkDir):
            pass
        """)
    with open(tmpdir / "workdir.py", "w") as pyfile:
        pyfile.write(contents)
    wd = WorkDir(tmpdir)
    assert hasattr(wd, "A")
    assert hasattr(wd, "a")
    assert wd.a == 2
    assert issubclass(wd.A, WorkDir)
    assert isinstance(wd.A(), WorkDir)
Beispiel #10
0
def test_terminal_command(tmpdir):
    with WorkDir(tmpdir) as wd:
        assert len(wd.commands) == 0
    content = textwrap.dedent("""
        commands:
             echo: echo Hello > {{ here/"out.txt" }} // print something
        """)
    with open(tmpdir / "workdir.yml", 'w') as f:
        f.write(content)
    with WorkDir(tmpdir) as wd:
        assert len(wd.commands) == 1
        assert wd.commands[
            "echo"] == f"echo Hello > {str(tmpdir/'out.txt')} // print something"

    with WorkDir(tmpdir):
        wd.echo()
        assert os.path.isfile(tmpdir / "out.txt")
        with open(tmpdir / "out.txt", "r") as f:
            assert f.read().strip() == "Hello"
Beispiel #11
0
def test_files(tmpdir):
    """Test WorkDir.files()"""
    with WorkDir(tmpdir) as wd:
        (wd.path / "a").touch()
        (wd.path / "b").touch()
        (wd.path / "c").touch()
        os.mkdir(wd / "dir")
        assert len([f for f in wd.files()]) == 3
        assert all(isinstance(f, pathlib.Path) for f in wd.files())
        assert all(os.path.dirname(f) == "" for f in wd.files())
        assert all(
            os.path.dirname(f) == str(tmpdir) for f in wd.files(abs=True))
Beispiel #12
0
def test_environment():
    """Test that environment variables are changed"""
    os.environ["JAMBAPATH"] = "set"
    wd = WorkDir(environment={"jambalayalaya": "1", "JAMBAPATH": "."})
    assert not "jambalayalaya" in os.environ
    assert "JAMBAPATH" in os.environ
    with wd:
        assert "jambalayalaya" in os.environ
        assert os.environ["jambalayalaya"] == "1"
        assert os.environ["JAMBAPATH"] == "."
    assert not "jambalayalaya" in os.environ
    assert "JAMBAPATH" in os.environ
    assert os.environ["JAMBAPATH"] == "set"
Beispiel #13
0
def test_logging(tmpdir):
    """Test logging with default configuration."""
    wd = WorkDir(tmpdir)
    assert wd.logger is None
    assert not os.path.isfile(tmpdir / "workdir.log")
    wd.log("Hi")
    # File is created with first log
    assert os.path.isfile(tmpdir / "workdir.log")
    wd.log("Hello", logging.DEBUG)
    wd.log("Bye", logging.WARN)
    with open(tmpdir / "workdir.log") as f:
        lines = f.readlines()
        assert "Hi" in lines[0]
        assert "Hello" in lines[1]
        assert "Bye" in lines[2]
Beispiel #14
0
def test_yml_environment(tmpdir):
    """Test that environment variables can be set through the yml files."""
    contents = textwrap.dedent("""
    environment:
        a: 1
        b: 2
    """)
    with open(tmpdir / "workdir.yml", "w") as f:
        f.write(contents)
    with WorkDir(tmpdir):
        assert "a" in os.environ
        assert "b" in os.environ
        assert os.environ["a"] == "1"
        assert os.environ["b"] == "2"
Beispiel #15
0
def test_option(tmpdir):
    """Test if functions with options are parsed"""
    content = textwrap.dedent("""
        import click
        
        @click.option("--path")
        def parentdirr(path, workdir):
            return (workdir/path).parent
        """)
    with open(tmpdir / "workdir.py", 'w') as f:
        f.write(content)
    wd = WorkDir(tmpdir)
    assert hasattr(wd, "parentdirr")
    assert list(wd.custom_attributes.keys()) == ["parentdirr"]
Beispiel #16
0
def test_custom_loglevel_and_file(tmpdir):
    """Test if custom logging settings are effective."""
    wd = WorkDir(tmpdir, logfile="mylog.txt", loglevel_file=logging.INFO)
    wd.log("Hello", logging.DEBUG)
    wd.log("Bye", logging.WARN)
    assert os.path.isfile(tmpdir / "mylog.txt")
    with open(tmpdir / "mylog.txt") as f:
        lines = f.readlines()
        assert "Bye" in lines[0]
Beispiel #17
0
def test_redefine_function_arguments_locally(tmpdir):
    """Test if non-local functions are parsed when defining them with function arguments."""
    content = textwrap.dedent("""
        from os.path import dirname
        from click import option
        
        option("--path")(
            dirname
        )
        """)
    with open(tmpdir / "workdir.py", 'w') as f:
        f.write(content)
    wd = WorkDir(tmpdir)
    assert hasattr(wd, "dirname")
    assert list(wd.custom_attributes.keys()) == ["dirname"]
Beispiel #18
0
def test_yml_templates(tmpdir):
    """Test that templates are resolved in yml files."""
    contents = textwrap.dedent("""
    environment:
        a: {{ workdir.__len__() }}
    attributes:
        jambalayalaya: {{ here/"file.tmp" }}
    """)
    with open(tmpdir / "workdir.yml", "w") as f:
        f.write(contents)
    with WorkDir(tmpdir) as wd:
        assert "a" in os.environ
        assert os.environ["a"] == "1"
        assert hasattr(wd, "jambalayalaya")
        assert wd.jambalayalaya == tmpdir / "file.tmp"
Beispiel #19
0
def test_yml_attributes(tmpdir):
    """Test that attributes can be set from yml files."""
    contents = textwrap.dedent("""
    environment:
        a: 1
    attributes:
        jambalayalaya: 2
    """)
    with open(tmpdir / "workdir.yml", "w") as f:
        f.write(contents)
    with WorkDir(tmpdir) as wd:
        assert "a" in os.environ
        assert not "jambalayalaya" in os.environ
        assert hasattr(wd, "jambalayalaya")
        assert wd.jambalayalaya == 2
Beispiel #20
0
def test_recursive_pyfile(tmpdir):
    """Test that pyfiles are loaded recursively and that more specific settings override more general ones."""
    contents = textwrap.dedent("""
        a = 2
        b = 2
        """)
    contents_parent = textwrap.dedent("""
        a = 3
        c = 3
        """)
    os.mkdir(tmpdir / "subdir")
    with open(tmpdir / "subdir/workdir.py", "w") as f:
        f.write(contents)
    with open(tmpdir / "workdir.py", "w") as f:
        f.write(contents_parent)
    wd = WorkDir(tmpdir / "subdir")
    assert hasattr(wd, "a")
    assert hasattr(wd, "b")
    assert hasattr(wd, "c")
    assert wd.a == 2
    assert wd.b == 2
    assert wd.c == 3
    # test custom attributes dict
    assert wd.custom_attributes["a"] == os.path.realpath(tmpdir /
                                                         "subdir/workdir.py")
    assert wd.custom_attributes["b"] == os.path.realpath(tmpdir /
                                                         "subdir/workdir.py")
    assert wd.custom_attributes["c"] == os.path.realpath(tmpdir / "workdir.py")

    # assert non-recursive
    wd = WorkDir(tmpdir / "subdir", python_files_recursion=0)
    assert not hasattr(wd, "c")

    # assert non-recursive
    wd = WorkDir(tmpdir / "subdir", python_files_recursion=1)
    assert hasattr(wd, "c")
Beispiel #21
0
def test_import_local_modules_in_pyfile(tmpdir):
    """Check if local imports are resolved in workdir.py"""
    content = textwrap.dedent("""
    import library
    b = library.a
    """)
    library_content = textwrap.dedent("""
    a = 1
    """)
    with open(tmpdir / "workdir.py", 'w') as f:
        f.write(content)
    with open(tmpdir / "library.py", 'w') as f:
        f.write(library_content)
    wd = WorkDir(tmpdir)
    assert hasattr(wd, "b")
    assert wd.b == 1
Beispiel #22
0
def test_terminal_command(tmpdir):
    content = textwrap.dedent("""
        commands:
            echo: echo Hello  > {{ here/"out.txt" }}  // print something
        """)
    with open(tmpdir / "workdir.yml", 'w') as f:
        f.write(content)
    runner = CliRunner(env={"PWD": str(tmpdir)})
    main = forge_command_line_interface(directory=tmpdir)
    result = runner.invoke(main, "--help")
    assert "echo" in result.output and "print something" in result.output

    with WorkDir(tmpdir):
        os.system("workdir echo")
        assert os.path.isfile(tmpdir / "out.txt")
        with open(tmpdir / "out.txt", "r") as f:
            assert f.read().strip() == "Hello"
Beispiel #23
0
def test_here_argument(tmpdir):
    """Test that the `here` parameter is replaced by the directory of the workdir.py"""
    contents = textwrap.dedent("""
        def some_path(here, workdir, filename):
            return workdir/filename, here/filename
        """)
    with open(tmpdir / "workdir.py", "w") as f:
        f.write(contents)
    subdir = WorkDir(tmpdir / "subdir")
    wd = WorkDir(tmpdir)
    sub_wd, sub_here = subdir.some_path("file.txt")
    parent_wd, parent_here = wd.some_path("file.txt")
    assert str(parent_here) == os.path.join(tmpdir, "file.txt")
    assert sub_here == parent_here
    assert parent_here == parent_wd
    assert sub_wd == subdir.path / "file.txt"
Beispiel #24
0
def test_show(tmpdir):
    content = textwrap.dedent("""
        a = 1
        def b(s):
            print(s)
        """)
    with open(tmpdir / "workdir.py", 'w') as f:
        f.write(content)
    content = textwrap.dedent("""
        environment:
            A: 1
        commands:
            echo: echo // echo
        attributes: 
            c: a
        """)
    with open(tmpdir / "workdir.yml", 'w') as f:
        f.write(content)
    with WorkDir(tmpdir) as wd:
        out = StringIO()
        show(wd,
             variables=True,
             environment=True,
             commands=True,
             sources=True,
             functions=True,
             out=out)
        dictionary = yaml.load(out.getvalue(), yaml.SafeLoader)
        attributes = set(dictionary["attributes"].keys())
        functions = set(dictionary["functions"])
        customs = attributes.union(functions)
        environment = set(dictionary["environment"])
        name = dictionary["name"]
        sources = dictionary["sources"]
        commands = dictionary["commands"]
        assert customs == set(wd.custom_attributes.keys())
        assert environment == set(wd.environment)
        assert name == str(tmpdir)
        assert sources == wd.custom_attributes
        assert commands == wd.commands
Beispiel #25
0
def test_competing_local_import_in_pyfile(tmpdir):
    """Check that local imports work as expect (import from here, not subdir)."""
    content = textwrap.dedent("""
    import library
    b = library.a
    """)
    library_content = textwrap.dedent("""
    a = 1
    """)
    library_sub_content = textwrap.dedent("""
    a = 2
    """)
    os.mkdir(tmpdir / "subdir")
    with open(tmpdir / "workdir.py", 'w') as f:
        f.write(content)
    with open(tmpdir / "library.py", 'w') as f:
        f.write(library_content)
    with open(tmpdir / "subdir/library.py", 'w') as f:
        f.write(library_sub_content)
    wd = WorkDir(tmpdir)
    assert hasattr(wd, "b")
    assert wd.b == 1
    assert list(wd.custom_attributes.keys()) == ["b"]
Beispiel #26
0
def test_error_in_context(tmpdir):
    """Test that an exception in the context is forwarded."""
    with pytest.raises(AssertionError):
        with WorkDir(tmpdir):
            assert False
Beispiel #27
0
def test_truediv(tmpdir):
    """Test the division operator."""
    with WorkDir(tmpdir) as wd:
        assert str(wd / "file.txt") == tmpdir / "file.txt"
Beispiel #28
0
def test_change_directory(tmpdir):
    """Test that the working directory changes the directory correctly"""
    surrounding_path = os.getcwd()
    with WorkDir(tmpdir):
        assert os.getcwd() == str(tmpdir)
    assert os.getcwd() == surrounding_path
Beispiel #29
0
def test_str(tmpdir):
    wd = WorkDir(tmpdir)
    assert str(wd) == str(tmpdir)
Beispiel #30
0
def test_len(tmpdir):
    """Test length operator"""
    with WorkDir(tmpdir) as wd:
        assert len(wd) == 0
        os.mkdir(wd / "a")
        assert len(wd) == 1