|
| 1 | +import builtins |
1 | 2 | import os
|
| 3 | +import re |
2 | 4 | import subprocess
|
3 | 5 | import sys
|
4 | 6 | import time
|
| 7 | +from collections import OrderedDict |
| 8 | +from contextlib import contextmanager |
5 | 9 | from typing import List
|
6 | 10 |
|
7 | 11 | import py.path
|
|
11 | 15 | from _pytest.config import PytestPluginManager
|
12 | 16 | from _pytest.main import ExitCode
|
13 | 17 | from _pytest.outcomes import Failed
|
| 18 | +from _pytest.pathlib import Path |
14 | 19 | from _pytest.pytester import CwdSnapshot
|
15 | 20 | from _pytest.pytester import HookRecorder
|
16 | 21 | from _pytest.pytester import LineMatcher
|
| 22 | +from _pytest.pytester import MonkeyPatch |
17 | 23 | from _pytest.pytester import SysModulesSnapshot
|
18 | 24 | from _pytest.pytester import SysPathsSnapshot
|
19 | 25 | from _pytest.pytester import Testdir
|
@@ -710,3 +716,53 @@ def test_error2(bad_fixture):
|
710 | 716 | result.assert_outcomes(error=2)
|
711 | 717 |
|
712 | 718 | assert result.parseoutcomes() == {"error": 2}
|
| 719 | + |
| 720 | + |
| 721 | +def test_testdir_makefiles(testdir: Testdir, monkeypatch: MonkeyPatch) -> None: |
| 722 | + tmpdir = testdir.tmpdir |
| 723 | + |
| 724 | + abspath = str(tmpdir / "bar") |
| 725 | + created_paths = testdir.makefiles(OrderedDict({"foo": "", abspath: ""})) |
| 726 | + p1 = created_paths[0] |
| 727 | + assert isinstance(p1, Path) |
| 728 | + relpath = tmpdir / "foo" |
| 729 | + assert str(p1) == str(relpath) |
| 730 | + |
| 731 | + p2 = created_paths[1] |
| 732 | + assert p2.exists() |
| 733 | + assert str(p2) == abspath |
| 734 | + |
| 735 | + assert testdir.makefiles({}) == [] |
| 736 | + |
| 737 | + # Disallows creation outside of tmpdir by default. |
| 738 | + with pytest.raises( |
| 739 | + ValueError, |
| 740 | + match="'/abspath' does not start with '{}'".format(re.escape(str(tmpdir))), |
| 741 | + ): |
| 742 | + testdir.makefiles({"shouldnotbecreated": "", "/abspath": ""}) |
| 743 | + # Validation before creating anything. |
| 744 | + assert not Path("shouldnotbecreated").exists() |
| 745 | + |
| 746 | + # Support writing arbitrary files on request. |
| 747 | + open_calls = [] |
| 748 | + orig_open = builtins.open |
| 749 | + |
| 750 | + @contextmanager |
| 751 | + def mocked_open(*args): |
| 752 | + open_calls.append(["__enter__", args]) |
| 753 | + with orig_open(os.devnull, *args[1:]) as fp: |
| 754 | + yield fp |
| 755 | + |
| 756 | + with monkeypatch.context() as mp: |
| 757 | + mp.setattr(builtins, "open", mocked_open) |
| 758 | + created_paths = testdir.makefiles({"/abspath": ""}, allow_outside_tmpdir=True) |
| 759 | + assert created_paths == [Path("/abspath")] |
| 760 | + assert open_calls == [["__enter__", ("/abspath", "w")]] |
| 761 | + |
| 762 | + # Duplicated files (absolute and relative). |
| 763 | + created_paths = testdir.makefiles(OrderedDict({"bar": "1", abspath: "2"})) |
| 764 | + with open("bar", "r") as fp: |
| 765 | + assert fp.read() == "2" |
| 766 | + created_paths = testdir.makefiles(OrderedDict({abspath: "2", "bar": "1"})) |
| 767 | + with open("bar", "r") as fp: |
| 768 | + assert fp.read() == "1" |
0 commit comments