Coverage for tests/test_context.py: 100.00%

63 statements  

« prev     ^ index     » next       coverage.py v7.6.3, created at 2024-10-17 17:18 +0200

1"""Tests for the `context` module.""" 

2 

3from __future__ import annotations 

4 

5from collections import namedtuple 

6from pathlib import Path 

7 

8import pytest 

9 

10from duty import context 

11from duty.exceptions import DutyFailure 

12 

13RunResult = namedtuple("RunResult", "code output") # noqa: PYI024 

14 

15 

16def test_allow_overrides(monkeypatch: pytest.MonkeyPatch) -> None: 

17 """Test the `allow_overrides` option. 

18 

19 Parameters: 

20 monkeypatch: A Pytest fixture to monkeypatch objects. 

21 """ 

22 ctx = context.Context({"a": 1}, {"a": 2}) 

23 records = [] 

24 monkeypatch.setattr(context, "failprint_run", lambda _, **opts: RunResult(records.append(opts), "")) # type: ignore[func-returns-value] 

25 ctx.run("") 

26 ctx.run("", allow_overrides=False) 

27 ctx.run("", allow_overrides=True) 

28 ctx.run("", allow_overrides=False, a=3) 

29 assert records[0]["a"] == 2 

30 assert records[1]["a"] == 1 

31 assert records[2]["a"] == 2 

32 assert records[3]["a"] == 3 

33 

34 

35def test_options_context_manager(monkeypatch: pytest.MonkeyPatch) -> None: 

36 """Test changing options using the context manager. 

37 

38 Parameters: 

39 monkeypatch: A Pytest fixture to monkeypatch objects. 

40 """ 

41 ctx = context.Context({"a": 1}, {"a": 2}) 

42 records = [] 

43 monkeypatch.setattr(context, "failprint_run", lambda _, **opts: RunResult(records.append(opts), "")) # type: ignore[func-returns-value] 

44 

45 with ctx.options(a=3): 

46 ctx.run("") # should be overridden by 2 

47 with ctx.options(a=4, allow_overrides=False): 

48 ctx.run("") # should be 4 

49 ctx.run("", allow_overrides=True) # should be 2 

50 ctx.run("", allow_overrides=False) # should be 3 

51 

52 assert records[0]["a"] == 2 

53 assert records[1]["a"] == 4 

54 assert records[2]["a"] == 2 

55 assert records[3]["a"] == 3 

56 

57 

58def test_workdir(monkeypatch: pytest.MonkeyPatch) -> None: 

59 """Test the `workdir` option. 

60 

61 Parameters: 

62 monkeypatch: A Pytest fixture to monkeypatch objects. 

63 """ 

64 ctx = context.Context({}) 

65 monkeypatch.setattr(context, "failprint_run", lambda _: RunResult(len(Path.cwd().parts), "")) 

66 records = [] 

67 with pytest.raises(DutyFailure) as failure: 

68 ctx.run("") 

69 records.append(failure.value.code) 

70 with pytest.raises(DutyFailure) as failure: 

71 ctx.run("", workdir="..") 

72 records.append(failure.value.code) 

73 assert records[0] == records[1] + 1 

74 

75 

76def test_workdir_as_context_manager(monkeypatch: pytest.MonkeyPatch) -> None: 

77 """Test the `workdir` option as a context manager, and the `cd` context manager. 

78 

79 Parameters: 

80 monkeypatch: A Pytest fixture to monkeypatch objects. 

81 """ 

82 ctx = context.Context({}) 

83 monkeypatch.setattr(context, "failprint_run", lambda _: RunResult(len(Path.cwd().parts), "")) 

84 records = [] 

85 with pytest.raises(DutyFailure) as failure, ctx.options(workdir=".."): 

86 ctx.run("") 

87 records.append(failure.value.code) 

88 with pytest.raises(DutyFailure) as failure, ctx.cd("../.."): 

89 ctx.run("") 

90 records.append(failure.value.code) 

91 with pytest.raises(DutyFailure) as failure, ctx.cd(".."), ctx.options(workdir="../.."): 

92 ctx.run("") 

93 records.append(failure.value.code) 

94 with pytest.raises(DutyFailure) as failure, ctx.cd("../../.."): 

95 ctx.run("", workdir="..") 

96 records.append(failure.value.code) 

97 

98 base = records[0] 

99 

100 # If the repository is checked out near the root of the filesystem, the working directory will 

101 # eventually be the root, so cap the lowest depth at 1. 

102 expected_depths = [max(1, base - offset) for offset in range(len(records))] 

103 assert records == expected_depths