1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
|
import inspect
import json
import os
import re
from pathlib import Path
import pytest
from lektor_ng.builder import Builder
from lektor_ng.cli.cli_old import cli
from lektor_ng.devserver import run_server
from lektor_ng.project import Project
from lektor_ng.publisher import publish
pytestmark = pytest.mark.skipif(True, reason="RE-ENABLE!")
def test_build_abort_in_existing_nonempty_dir(project_cli_runner):
os.mkdir("build_dir")
with open("build_dir/test", "w", encoding="utf-8"):
pass
result = project_cli_runner.invoke(cli, ["build", "-O", "build_dir"], input="n\n")
assert "Aborted!" in result.output
assert result.exit_code == 1
def test_build_continue_in_existing_nonempty_dir(project_cli_runner):
os.mkdir("build_dir")
with open("build_dir/test", "w", encoding="utf-8"):
pass
result = project_cli_runner.invoke(cli, ["build", "-O", "build_dir"], input="y\n")
assert "Finished prune" in result.output
assert result.exit_code == 0
def test_alias(project_cli_runner):
result = project_cli_runner.invoke(cli, ["pr"]) # short for 'project-info'
assert result.exit_code == 0
assert "Name: Demo Project" in result.output
def test_dev_cmd_alias(isolated_cli_runner):
result = isolated_cli_runner.invoke(cli, ["dev", "s"]) # short for 'shell'
assert result.exit_code == 2
assert "Error: Could not automatically discover a project" in result.output
def test_alias_multiple_matches(project_cli_runner):
result = project_cli_runner.invoke(cli, ["p"]) # short for 'project-info' & 'plugins'
assert result.exit_code == 2
assert "Error: Too many matches" in result.output
def test_alias_no_matches(project_cli_runner):
result = project_cli_runner.invoke(cli, ["z"])
assert result.exit_code == 2
assert "Error: No such command" in result.output
def test_build_no_project(isolated_cli_runner):
result = isolated_cli_runner.invoke(cli, ["build"])
assert result.exit_code == 2
assert "Could not automatically discover a project" in result.output
def test_build(project_cli_runner):
result = project_cli_runner.invoke(cli, ["build"])
assert "files or folders already exist" not in result.output # No warning on fresh build
assert result.exit_code == 0
start_matches = re.findall(r"Started build", result.output)
assert len(start_matches) == 1
finish_matches = re.findall(r"Finished build in \d+\.\d{2} sec", result.output)
assert len(finish_matches) == 1
# rebuild
result = project_cli_runner.invoke(cli, ["build"])
assert "files or folders already exist" not in result.output # No warning on repeat build
assert result.exit_code == 0
def test_build_extra_flag(project_cli_runner, mocker):
mock_builder = mocker.patch("lektor_ng.builder.Builder")
mock_builder.return_value.build_all.return_value = 0
result = project_cli_runner.invoke(cli, ["build", "-f", "webpack"])
assert result.exit_code == 0
assert mock_builder.call_args[1]["extra_flags"] == ("webpack",)
def test_deploy_extra_flag(project_cli_runner, mocker):
mock_publish = mocker.patch("lektor_ng.publisher.publish")
result = project_cli_runner.invoke(cli, ["deploy", "-f", "draft"])
assert result.exit_code == 0
assert mock_publish.call_args[1]["extra_flags"] == ("draft",)
@pytest.fixture
def project_info_data(project_cli_runner):
tree_dir = os.getcwd()
project = Project.from_path(tree_dir)
return {
"name": "Demo Project",
"project_file": os.path.join(tree_dir, "Website.lektorproject"),
"tree": tree_dir,
# punt on computing these independently
"output_path": project.get_output_path(),
"package_cache": str(project.get_package_cache_path()),
}
def test_project_info(project_cli_runner, project_info_data):
result = project_cli_runner.invoke(cli, ["project-info"])
for heading, key in [
("Name", "name"),
("File", "project_file"),
("Tree", "tree"),
("Output", "output_path"),
("Package Cache", "package_cache"),
]:
assert f"{heading}: {project_info_data[key]}\n" in result.stdout
@pytest.mark.parametrize(
"flag",
["--name", "--project-file", "--tree", "--output-path", "--package-cache"],
)
def test_project_info_path_flags(project_cli_runner, flag, project_info_data):
info_key = flag.lstrip("-").replace("-", "_")
result = project_cli_runner.invoke(cli, ["project-info", flag])
assert result.exit_code == 0
assert result.stdout.rstrip() == project_info_data[info_key]
def test_project_info_json(project_cli_runner):
project = Project.from_path(os.getcwd())
result = project_cli_runner.invoke(cli, ["project-info", "--json"])
assert json.loads(result.stdout) == project.to_json()
@pytest.fixture
def deployable_project_data(scratch_project_data):
project_file = next(scratch_project_data.glob("*.lektorproject"))
with project_file.open("a") as fp:
fp.write(
inspect.cleandoc(
"""[servers.default]
name = Default
target = rsync://example.net/
"""
)
)
return scratch_project_data
@pytest.mark.skip(reason="test")
@pytest.mark.parametrize(
"subcommand, to_mock, param_name",
[
("build", Builder, "destination_path"),
("clean", Builder, "destination_path"),
("deploy", publish, "output_path"),
("server", run_server, "output_path"),
],
)
def test_build_output_path_relative_to_cwd(
project_cli_runner,
deployable_project_data,
mocker,
subcommand,
to_mock,
param_name,
):
mock = mocker.patch(f"{to_mock.__module__}.{to_mock.__qualname__}", autospec=True)
args = [
f"--project={deployable_project_data}",
subcommand,
"--output-path=htdocs",
]
project_cli_runner.invoke(cli, args, input="y\n")
args, kwargs = mock.call_args
bound_args = inspect.signature(to_mock).bind(*args, **kwargs).arguments
output_path = bound_args[param_name]
assert output_path == str(Path.cwd().resolve() / "htdocs")
|