1# -*- coding: utf-8 -*-
2"""Testing dirstack"""
3from __future__ import unicode_literals, print_function
4
5from contextlib import contextmanager
6from functools import wraps
7import os
8import builtins
9
10import pytest
11
12from xonsh import dirstack
13from xonsh.environ import Env
14from xonsh.built_ins import load_builtins
15
16
17HERE = os.path.abspath(os.path.dirname(__file__))
18PARENT = os.path.dirname(HERE)
19
20
21@contextmanager
22def chdir(adir):
23    old_dir = os.getcwd()
24    os.chdir(adir)
25    yield
26    os.chdir(old_dir)
27
28
29def test_simple(xonsh_builtins):
30    xonsh_builtins.__xonsh_env__ = Env(CDPATH=PARENT, PWD=PARENT)
31    with chdir(PARENT):
32        assert os.getcwd() != HERE
33        dirstack.cd(["tests"])
34        assert os.getcwd() == HERE
35
36
37def test_cdpath_simple(xonsh_builtins):
38    xonsh_builtins.__xonsh_env__ = Env(CDPATH=PARENT, PWD=HERE)
39    with chdir(os.path.normpath("/")):
40        assert os.getcwd() != HERE
41        dirstack.cd(["tests"])
42        assert os.getcwd() == HERE
43
44
45def test_cdpath_collision(xonsh_builtins):
46    xonsh_builtins.__xonsh_env__ = Env(CDPATH=PARENT, PWD=HERE)
47    sub_tests = os.path.join(HERE, "tests")
48    if not os.path.exists(sub_tests):
49        os.mkdir(sub_tests)
50    with chdir(HERE):
51        assert os.getcwd() == HERE
52        dirstack.cd(["tests"])
53        assert os.getcwd() == os.path.join(HERE, "tests")
54
55
56def test_cdpath_expansion(xonsh_builtins):
57    xonsh_builtins.__xonsh_env__ = Env(HERE=HERE, CDPATH=("~", "$HERE"))
58    test_dirs = (
59        os.path.join(HERE, "xonsh-test-cdpath-here"),
60        os.path.expanduser("~/xonsh-test-cdpath-home"),
61    )
62    try:
63        for d in test_dirs:
64            if not os.path.exists(d):
65                os.mkdir(d)
66            assert os.path.exists(
67                dirstack._try_cdpath(d)
68            ), "dirstack._try_cdpath: could not resolve {0}".format(d)
69    finally:
70        for d in test_dirs:
71            if os.path.exists(d):
72                os.rmdir(d)
73
74
75def test_cdpath_events(xonsh_builtins, tmpdir):
76    xonsh_builtins.__xonsh_env__ = Env(CDPATH=PARENT, PWD=os.getcwd())
77    target = str(tmpdir)
78
79    ev = None
80
81    @xonsh_builtins.events.on_chdir
82    def handler(olddir, newdir, **kw):
83        nonlocal ev
84        ev = olddir, newdir
85
86    old_dir = os.getcwd()
87    try:
88        dirstack.cd([target])
89    except:
90        raise
91    else:
92        assert (old_dir, target) == ev
93    finally:
94        # Use os.chdir() here so dirstack.cd() doesn't fire events (or fail again)
95        os.chdir(old_dir)
96
97
98def test_cd_autopush(xonsh_builtins, tmpdir):
99    xonsh_builtins.__xonsh_env__ = Env(CDPATH=PARENT, PWD=os.getcwd(), AUTO_PUSHD=True)
100    target = str(tmpdir)
101
102    old_dir = os.getcwd()
103    old_ds_size = len(dirstack.DIRSTACK)
104
105    assert target != old_dir
106
107    try:
108        dirstack.cd([target])
109        assert target == os.getcwd()
110        assert old_ds_size + 1 == len(dirstack.DIRSTACK)
111        dirstack.popd([])
112    except:
113        raise
114    finally:
115        while len(dirstack.DIRSTACK) > old_ds_size:
116            dirstack.popd([])
117
118    assert old_dir == os.getcwd()
119