pl-e2e-test 0.1.1__tar.gz → 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. {pl_e2e_test-0.1.1/src/pl_e2e_test.egg-info → pl_e2e_test-0.1.2}/PKG-INFO +15 -11
  2. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/README.md +14 -10
  3. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/pyproject.toml +2 -5
  4. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2/src/pl_e2e_test.egg-info}/PKG-INFO +15 -11
  5. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/pl_e2e_test.egg-info/SOURCES.txt +2 -0
  6. pl_e2e_test-0.1.2/src/pl_e2e_test.egg-info/entry_points.txt +2 -0
  7. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/prairielearn_e2e/__main__.py +1 -1
  8. pl_e2e_test-0.1.2/src/prairielearn_e2e/cli.py +56 -0
  9. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/prairielearn_e2e/fuzz.py +2 -2
  10. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/prairielearn_e2e/regression.py +1 -1
  11. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/prairielearn_e2e/reporting.py +3 -2
  12. pl_e2e_test-0.1.2/tests/test_cli.py +81 -0
  13. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/tests/test_fuzz.py +1 -1
  14. pl_e2e_test-0.1.1/src/pl_e2e_test.egg-info/entry_points.txt +0 -5
  15. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/LICENSE +0 -0
  16. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/MANIFEST.in +0 -0
  17. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/setup.cfg +0 -0
  18. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/pl_e2e_test.egg-info/dependency_links.txt +0 -0
  19. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/pl_e2e_test.egg-info/requires.txt +0 -0
  20. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/pl_e2e_test.egg-info/top_level.txt +0 -0
  21. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/prairielearn_e2e/__init__.py +0 -0
  22. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/prairielearn_e2e/_git.py +0 -0
  23. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/prairielearn_e2e/backend.py +0 -0
  24. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/prairielearn_e2e/config.json +0 -0
  25. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/prairielearn_e2e/config.py +0 -0
  26. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/prairielearn_e2e/contract.py +0 -0
  27. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/prairielearn_e2e/discovery.py +0 -0
  28. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/prairielearn_e2e/errors.py +0 -0
  29. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/prairielearn_e2e/harness.py +0 -0
  30. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/prairielearn_e2e/html_checks.py +0 -0
  31. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/prairielearn_e2e/metadata.py +0 -0
  32. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/prairielearn_e2e/pytest_plugin.py +0 -0
  33. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/prairielearn_e2e/question_tests.py +0 -0
  34. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/prairielearn_e2e/repository.py +0 -0
  35. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/prairielearn_e2e/runner.py +0 -0
  36. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/prairielearn_e2e/server.py +0 -0
  37. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/src/prairielearn_e2e/sharding.py +0 -0
  38. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/tests/__init__.py +0 -0
  39. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/tests/conftest.py +0 -0
  40. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/tests/stub_git.py +0 -0
  41. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/tests/test_contract.py +0 -0
  42. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/tests/test_discovery.py +0 -0
  43. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/tests/test_git.py +0 -0
  44. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/tests/test_harness.py +0 -0
  45. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/tests/test_html_checks.py +0 -0
  46. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/tests/test_metadata.py +0 -0
  47. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/tests/test_publish_version.py +0 -0
  48. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/tests/test_pytest_plugin.py +0 -0
  49. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/tests/test_regression.py +0 -0
  50. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/tests/test_reporting.py +0 -0
  51. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/tests/test_repository.py +0 -0
  52. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/tests/test_server.py +0 -0
  53. {pl_e2e_test-0.1.1 → pl_e2e_test-0.1.2}/tests/test_sharding.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pl-e2e-test
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: Fuzz PrairieLearn question lifecycles against the real Python element runtime
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/PrairieLearn/pl-e2e-test
@@ -28,12 +28,16 @@ generate, prepare, render, parse, grade, test, and file phases. It was extracted
28
28
  from the `pl-oer-lv102` course so that courses can install one uv-managed tool
29
29
  instead of copying the harness and its support scripts.
30
30
 
31
- The package installs the reusable `prairielearn_e2e` Python API and these commands:
31
+ The package installs the reusable `prairielearn_e2e` Python API and a single
32
+ `pl-e2e-test` command:
32
33
 
33
- - `pl-e2e-test` runs the installed lifecycle pytest suite.
34
- - `pl-e2e-test-diff` fuzzes questions selected from a Git diff.
35
- - `pl-e2e-add-regression-seed` records a failing concrete variant seed.
36
- - `pl-e2e-merge-reports` merges parallel shard results into terminal and JUnit reports.
34
+ - `pl-e2e-test` (no command, or any pytest/harness options) runs the installed
35
+ lifecycle pytest suite.
36
+ - `pl-e2e-test diff` fuzzes questions selected from a Git diff.
37
+ - `pl-e2e-test add-seed` records a failing concrete variant seed.
38
+ - `pl-e2e-test reports` merges parallel shard results into terminal and JUnit reports.
39
+ - `pl-e2e-test version` prints the installed version.
40
+ - `pl-e2e-test help [COMMAND]` prints top-level help, or one command's help.
37
41
 
38
42
  ## Requirements and installation
39
43
 
@@ -105,7 +109,7 @@ same checkout and arguments. Sharded fuzz runs must also use one explicit shared
105
109
  merge them into a combined terminal summary and JUnit report:
106
110
 
107
111
  ```sh
108
- uv run pl-e2e-merge-reports e2e-reports \
112
+ uv run pl-e2e-test reports e2e-reports \
109
113
  --junitxml pl-e2e-results.xml
110
114
  ```
111
115
 
@@ -161,7 +165,7 @@ jobs:
161
165
  merge-multiple: true
162
166
  - name: Merge reports
163
167
  run: |
164
- uv run pl-e2e-merge-reports e2e-reports \
168
+ uv run pl-e2e-test reports e2e-reports \
165
169
  --junitxml pl-e2e-results.xml
166
170
  - name: Upload merged JUnit report
167
171
  if: ${{ always() }}
@@ -208,7 +212,7 @@ questions automatically skip only the grade check.
208
212
  Record the concrete seed shown in a failing pytest case with:
209
213
 
210
214
  ```sh
211
- uv run pl-e2e-add-regression-seed \
215
+ uv run pl-e2e-test add-seed \
212
216
  questions/chapter/example 1843927501
213
217
  ```
214
218
 
@@ -221,7 +225,7 @@ The diff runner tests changed question directories. A non-ignored changed file o
221
225
  `questions/` selects every question:
222
226
 
223
227
  ```sh
224
- uv run pl-e2e-test-diff \
228
+ uv run pl-e2e-test diff \
225
229
  --base origin/main \
226
230
  --head HEAD \
227
231
  --seed-count 10
@@ -247,7 +251,7 @@ To migrate from `.question-e2e.diffignore`, copy its non-comment rules into the
247
251
 
248
252
  In pull-request CI, fetch the base commit before running the command and pass the
249
253
  appropriate base and head SHAs. Set `--fuzz-seed` to replay a reported run.
250
- `pl-e2e-test-diff` accepts the same `--shard` and `--shard-report` options. If a diff
254
+ `pl-e2e-test diff` accepts the same `--shard` and `--shard-report` options. If a diff
251
255
  selects no questions, it writes a successful empty shard report so the merge job can
252
256
  still verify that every matrix job completed.
253
257
 
@@ -5,12 +5,16 @@ generate, prepare, render, parse, grade, test, and file phases. It was extracted
5
5
  from the `pl-oer-lv102` course so that courses can install one uv-managed tool
6
6
  instead of copying the harness and its support scripts.
7
7
 
8
- The package installs the reusable `prairielearn_e2e` Python API and these commands:
8
+ The package installs the reusable `prairielearn_e2e` Python API and a single
9
+ `pl-e2e-test` command:
9
10
 
10
- - `pl-e2e-test` runs the installed lifecycle pytest suite.
11
- - `pl-e2e-test-diff` fuzzes questions selected from a Git diff.
12
- - `pl-e2e-add-regression-seed` records a failing concrete variant seed.
13
- - `pl-e2e-merge-reports` merges parallel shard results into terminal and JUnit reports.
11
+ - `pl-e2e-test` (no command, or any pytest/harness options) runs the installed
12
+ lifecycle pytest suite.
13
+ - `pl-e2e-test diff` fuzzes questions selected from a Git diff.
14
+ - `pl-e2e-test add-seed` records a failing concrete variant seed.
15
+ - `pl-e2e-test reports` merges parallel shard results into terminal and JUnit reports.
16
+ - `pl-e2e-test version` prints the installed version.
17
+ - `pl-e2e-test help [COMMAND]` prints top-level help, or one command's help.
14
18
 
15
19
  ## Requirements and installation
16
20
 
@@ -82,7 +86,7 @@ same checkout and arguments. Sharded fuzz runs must also use one explicit shared
82
86
  merge them into a combined terminal summary and JUnit report:
83
87
 
84
88
  ```sh
85
- uv run pl-e2e-merge-reports e2e-reports \
89
+ uv run pl-e2e-test reports e2e-reports \
86
90
  --junitxml pl-e2e-results.xml
87
91
  ```
88
92
 
@@ -138,7 +142,7 @@ jobs:
138
142
  merge-multiple: true
139
143
  - name: Merge reports
140
144
  run: |
141
- uv run pl-e2e-merge-reports e2e-reports \
145
+ uv run pl-e2e-test reports e2e-reports \
142
146
  --junitxml pl-e2e-results.xml
143
147
  - name: Upload merged JUnit report
144
148
  if: ${{ always() }}
@@ -185,7 +189,7 @@ questions automatically skip only the grade check.
185
189
  Record the concrete seed shown in a failing pytest case with:
186
190
 
187
191
  ```sh
188
- uv run pl-e2e-add-regression-seed \
192
+ uv run pl-e2e-test add-seed \
189
193
  questions/chapter/example 1843927501
190
194
  ```
191
195
 
@@ -198,7 +202,7 @@ The diff runner tests changed question directories. A non-ignored changed file o
198
202
  `questions/` selects every question:
199
203
 
200
204
  ```sh
201
- uv run pl-e2e-test-diff \
205
+ uv run pl-e2e-test diff \
202
206
  --base origin/main \
203
207
  --head HEAD \
204
208
  --seed-count 10
@@ -224,7 +228,7 @@ To migrate from `.question-e2e.diffignore`, copy its non-comment rules into the
224
228
 
225
229
  In pull-request CI, fetch the base commit before running the command and pass the
226
230
  appropriate base and head SHAs. Set `--fuzz-seed` to replay a reported run.
227
- `pl-e2e-test-diff` accepts the same `--shard` and `--shard-report` options. If a diff
231
+ `pl-e2e-test diff` accepts the same `--shard` and `--shard-report` options. If a diff
228
232
  selects no questions, it writes a successful empty shard report so the merge job can
229
233
  still verify that every matrix job completed.
230
234
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pl-e2e-test"
7
- version = "0.1.1"
7
+ version = "0.1.2"
8
8
  description = "Fuzz PrairieLearn question lifecycles against the real Python element runtime"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
@@ -31,10 +31,7 @@ Issues = "https://github.com/PrairieLearn/pl-e2e-test/issues"
31
31
  Repository = "https://github.com/PrairieLearn/pl-e2e-test"
32
32
 
33
33
  [project.scripts]
34
- pl-e2e-test = "prairielearn_e2e.runner:main"
35
- pl-e2e-test-diff = "prairielearn_e2e.fuzz:main"
36
- pl-e2e-add-regression-seed = "prairielearn_e2e.regression:main"
37
- pl-e2e-merge-reports = "prairielearn_e2e.reporting:main"
34
+ pl-e2e-test = "prairielearn_e2e.cli:main"
38
35
 
39
36
  [tool.setuptools.packages.find]
40
37
  where = ["src"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pl-e2e-test
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: Fuzz PrairieLearn question lifecycles against the real Python element runtime
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/PrairieLearn/pl-e2e-test
@@ -28,12 +28,16 @@ generate, prepare, render, parse, grade, test, and file phases. It was extracted
28
28
  from the `pl-oer-lv102` course so that courses can install one uv-managed tool
29
29
  instead of copying the harness and its support scripts.
30
30
 
31
- The package installs the reusable `prairielearn_e2e` Python API and these commands:
31
+ The package installs the reusable `prairielearn_e2e` Python API and a single
32
+ `pl-e2e-test` command:
32
33
 
33
- - `pl-e2e-test` runs the installed lifecycle pytest suite.
34
- - `pl-e2e-test-diff` fuzzes questions selected from a Git diff.
35
- - `pl-e2e-add-regression-seed` records a failing concrete variant seed.
36
- - `pl-e2e-merge-reports` merges parallel shard results into terminal and JUnit reports.
34
+ - `pl-e2e-test` (no command, or any pytest/harness options) runs the installed
35
+ lifecycle pytest suite.
36
+ - `pl-e2e-test diff` fuzzes questions selected from a Git diff.
37
+ - `pl-e2e-test add-seed` records a failing concrete variant seed.
38
+ - `pl-e2e-test reports` merges parallel shard results into terminal and JUnit reports.
39
+ - `pl-e2e-test version` prints the installed version.
40
+ - `pl-e2e-test help [COMMAND]` prints top-level help, or one command's help.
37
41
 
38
42
  ## Requirements and installation
39
43
 
@@ -105,7 +109,7 @@ same checkout and arguments. Sharded fuzz runs must also use one explicit shared
105
109
  merge them into a combined terminal summary and JUnit report:
106
110
 
107
111
  ```sh
108
- uv run pl-e2e-merge-reports e2e-reports \
112
+ uv run pl-e2e-test reports e2e-reports \
109
113
  --junitxml pl-e2e-results.xml
110
114
  ```
111
115
 
@@ -161,7 +165,7 @@ jobs:
161
165
  merge-multiple: true
162
166
  - name: Merge reports
163
167
  run: |
164
- uv run pl-e2e-merge-reports e2e-reports \
168
+ uv run pl-e2e-test reports e2e-reports \
165
169
  --junitxml pl-e2e-results.xml
166
170
  - name: Upload merged JUnit report
167
171
  if: ${{ always() }}
@@ -208,7 +212,7 @@ questions automatically skip only the grade check.
208
212
  Record the concrete seed shown in a failing pytest case with:
209
213
 
210
214
  ```sh
211
- uv run pl-e2e-add-regression-seed \
215
+ uv run pl-e2e-test add-seed \
212
216
  questions/chapter/example 1843927501
213
217
  ```
214
218
 
@@ -221,7 +225,7 @@ The diff runner tests changed question directories. A non-ignored changed file o
221
225
  `questions/` selects every question:
222
226
 
223
227
  ```sh
224
- uv run pl-e2e-test-diff \
228
+ uv run pl-e2e-test diff \
225
229
  --base origin/main \
226
230
  --head HEAD \
227
231
  --seed-count 10
@@ -247,7 +251,7 @@ To migrate from `.question-e2e.diffignore`, copy its non-comment rules into the
247
251
 
248
252
  In pull-request CI, fetch the base commit before running the command and pass the
249
253
  appropriate base and head SHAs. Set `--fuzz-seed` to replay a reported run.
250
- `pl-e2e-test-diff` accepts the same `--shard` and `--shard-report` options. If a diff
254
+ `pl-e2e-test diff` accepts the same `--shard` and `--shard-report` options. If a diff
251
255
  selects no questions, it writes a successful empty shard report so the merge job can
252
256
  still verify that every matrix job completed.
253
257
 
@@ -12,6 +12,7 @@ src/prairielearn_e2e/__init__.py
12
12
  src/prairielearn_e2e/__main__.py
13
13
  src/prairielearn_e2e/_git.py
14
14
  src/prairielearn_e2e/backend.py
15
+ src/prairielearn_e2e/cli.py
15
16
  src/prairielearn_e2e/config.json
16
17
  src/prairielearn_e2e/config.py
17
18
  src/prairielearn_e2e/contract.py
@@ -32,6 +33,7 @@ src/prairielearn_e2e/sharding.py
32
33
  tests/__init__.py
33
34
  tests/conftest.py
34
35
  tests/stub_git.py
36
+ tests/test_cli.py
35
37
  tests/test_contract.py
36
38
  tests/test_discovery.py
37
39
  tests/test_fuzz.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ pl-e2e-test = prairielearn_e2e.cli:main
@@ -1,3 +1,3 @@
1
- from .runner import main
1
+ from .cli import main
2
2
 
3
3
  raise SystemExit(main())
@@ -0,0 +1,56 @@
1
+ """Top-level command dispatch for the ``pl-e2e-test`` console script."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+ from collections.abc import Sequence
7
+ from importlib.metadata import version
8
+
9
+ from . import fuzz, regression, reporting, runner
10
+
11
+ _SUBCOMMANDS = {
12
+ "diff": fuzz.main,
13
+ "add-seed": regression.main,
14
+ "reports": reporting.main,
15
+ }
16
+
17
+ _TOP_LEVEL_HELP = """\
18
+ usage: pl-e2e-test [COMMAND] [ARGS...]
19
+
20
+ With no COMMAND, runs the installed PrairieLearn question lifecycle test
21
+ suite; any arguments (pytest options, --question-path, --seed-count, ...)
22
+ are passed straight through to pytest.
23
+
24
+ Commands:
25
+ diff fuzz questions changed between two Git refs
26
+ add-seed record a concrete regression seed for a question
27
+ reports merge parallel shard reports into one terminal/JUnit report
28
+ version show the installed pl-e2e-test version
29
+ help show this message, or `pl-e2e-test help COMMAND` for one command
30
+ """
31
+
32
+
33
+ def _version_command(_argv: Sequence[str]) -> int:
34
+ print(f"pl-e2e-test {version('pl-e2e-test')}")
35
+ return 0
36
+
37
+
38
+ def _help_command(argv: Sequence[str]) -> int:
39
+ if argv and argv[0] in _SUBCOMMANDS:
40
+ return _SUBCOMMANDS[argv[0]](["--help"])
41
+ print(_TOP_LEVEL_HELP, end="")
42
+ return 0
43
+
44
+
45
+ _COMMANDS = {**_SUBCOMMANDS, "version": _version_command, "help": _help_command}
46
+
47
+
48
+ def main(argv: Sequence[str] | None = None) -> int:
49
+ arguments = list(sys.argv[1:] if argv is None else argv)
50
+ if arguments and arguments[0] in _COMMANDS:
51
+ return _COMMANDS[arguments[0]](arguments[1:])
52
+ return runner.main(arguments)
53
+
54
+
55
+ if __name__ == "__main__":
56
+ raise SystemExit(main())
@@ -195,7 +195,7 @@ def positive_integer(value: str) -> int:
195
195
 
196
196
 
197
197
  def main(argv: Sequence[str] | None = None) -> int:
198
- parser = argparse.ArgumentParser(description=__doc__)
198
+ parser = argparse.ArgumentParser(prog="pl-e2e-test diff", description=__doc__)
199
199
  parser.add_argument("--course-root", type=Path)
200
200
  parser.add_argument("--base", default="main", help="base Git ref (default: main)")
201
201
  parser.add_argument("--head", default="HEAD", help="head Git ref (default: HEAD)")
@@ -274,7 +274,7 @@ def main(argv: Sequence[str] | None = None) -> int:
274
274
  seeds = variant_seeds({}, args.seed_count, fuzz_seed)
275
275
  print(f"E2E fuzz seed: {fuzz_seed}")
276
276
  print(f"Variant seeds: {', '.join(str(seed) for seed in seeds)}")
277
- replay_arguments = ["pl-e2e-test-diff", "--fuzz-seed", str(fuzz_seed)]
277
+ replay_arguments = ["pl-e2e-test", "diff", "--fuzz-seed", str(fuzz_seed)]
278
278
  test_arguments: list[str] = []
279
279
  if args.prairielearn_path is not None:
280
280
  replay_arguments.extend(
@@ -96,7 +96,7 @@ def add_regression_seed(course_root: Path, question_path: Path, seed: int) -> bo
96
96
 
97
97
 
98
98
  def main(argv: Sequence[str] | None = None) -> int:
99
- parser = argparse.ArgumentParser(description=__doc__)
99
+ parser = argparse.ArgumentParser(prog="pl-e2e-test add-seed", description=__doc__)
100
100
  parser.add_argument("question_path", type=Path)
101
101
  parser.add_argument("variant_seed", type=_variant_seed)
102
102
  parser.add_argument("--course-root", type=Path)
@@ -659,7 +659,8 @@ def merge_reports(inputs: Sequence[Path], junitxml: Path) -> int:
659
659
 
660
660
  def main(argv: Sequence[str] | None = None) -> int:
661
661
  parser = argparse.ArgumentParser(
662
- description="Merge pl-e2e-test shard reports into one terminal and JUnit report."
662
+ prog="pl-e2e-test reports",
663
+ description="Merge pl-e2e-test shard reports into one terminal and JUnit report.",
663
664
  )
664
665
  parser.add_argument("reports", nargs="+", type=Path)
665
666
  parser.add_argument("--junitxml", type=Path, default=Path("pl-e2e-results.xml"))
@@ -667,7 +668,7 @@ def main(argv: Sequence[str] | None = None) -> int:
667
668
  try:
668
669
  return merge_reports(args.reports, args.junitxml)
669
670
  except (OSError, ReportError) as exc:
670
- print(f"pl-e2e-merge-reports: error: {exc}", file=sys.stderr)
671
+ print(f"pl-e2e-test reports: error: {exc}", file=sys.stderr)
671
672
  return 2
672
673
 
673
674
 
@@ -0,0 +1,81 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Sequence
4
+ from importlib.metadata import version
5
+
6
+ import pytest
7
+
8
+ from prairielearn_e2e import cli
9
+
10
+
11
+ def _stub(calls: list[Sequence[str]], result: int = 0):
12
+ def _main(argv: Sequence[str]) -> int:
13
+ calls.append(list(argv))
14
+ return result
15
+
16
+ return _main
17
+
18
+
19
+ @pytest.mark.parametrize("command", ["diff", "add-seed", "reports"])
20
+ def test_dispatches_known_commands_to_their_module(
21
+ monkeypatch: pytest.MonkeyPatch, command: str
22
+ ) -> None:
23
+ calls: list[Sequence[str]] = []
24
+ monkeypatch.setitem(cli._COMMANDS, command, _stub(calls, result=3))
25
+
26
+ assert cli.main([command, "--example", "value"]) == 3
27
+ assert calls == [["--example", "value"]]
28
+
29
+
30
+ def test_no_command_falls_through_to_the_test_runner(
31
+ monkeypatch: pytest.MonkeyPatch,
32
+ ) -> None:
33
+ calls: list[Sequence[str]] = []
34
+ monkeypatch.setattr(cli, "runner", type("_Runner", (), {"main": _stub(calls)}))
35
+
36
+ assert cli.main(["--question-path", "questions/example", "-k", "sample"]) == 0
37
+ assert calls == [["--question-path", "questions/example", "-k", "sample"]]
38
+
39
+
40
+ def test_bare_invocation_falls_through_to_the_test_runner(
41
+ monkeypatch: pytest.MonkeyPatch,
42
+ ) -> None:
43
+ calls: list[Sequence[str]] = []
44
+ monkeypatch.setattr(cli, "runner", type("_Runner", (), {"main": _stub(calls)}))
45
+
46
+ assert cli.main([]) == 0
47
+ assert calls == [[]]
48
+
49
+
50
+ def test_version_command_prints_the_installed_version(
51
+ capsys: pytest.CaptureFixture[str],
52
+ ) -> None:
53
+ assert cli.main(["version"]) == 0
54
+ assert capsys.readouterr().out == f"pl-e2e-test {version('pl-e2e-test')}\n"
55
+
56
+
57
+ def test_help_command_with_no_argument_prints_top_level_help(
58
+ capsys: pytest.CaptureFixture[str],
59
+ ) -> None:
60
+ assert cli.main(["help"]) == 0
61
+ out = capsys.readouterr().out
62
+ assert "Commands:" in out
63
+ for command in ("diff", "add-seed", "reports", "version", "help"):
64
+ assert command in out
65
+
66
+
67
+ def test_help_command_delegates_to_a_known_subcommand(
68
+ monkeypatch: pytest.MonkeyPatch,
69
+ ) -> None:
70
+ calls: list[Sequence[str]] = []
71
+ monkeypatch.setitem(cli._SUBCOMMANDS, "diff", _stub(calls))
72
+
73
+ assert cli.main(["help", "diff"]) == 0
74
+ assert calls == [["--help"]]
75
+
76
+
77
+ def test_help_command_with_unknown_argument_prints_top_level_help(
78
+ capsys: pytest.CaptureFixture[str],
79
+ ) -> None:
80
+ assert cli.main(["help", "not-a-command"]) == 0
81
+ assert "Commands:" in capsys.readouterr().out
@@ -278,7 +278,7 @@ def test_main_uses_managed_cache_when_prairielearn_path_is_omitted(
278
278
  for line in capsys.readouterr().out.splitlines()
279
279
  if line.startswith("Replay")
280
280
  )
281
- assert replay == "Replay with: pl-e2e-test-diff --fuzz-seed 9876"
281
+ assert replay == "Replay with: pl-e2e-test diff --fuzz-seed 9876"
282
282
 
283
283
 
284
284
  def test_empty_diff_does_not_generate_a_seed(
@@ -1,5 +0,0 @@
1
- [console_scripts]
2
- pl-e2e-add-regression-seed = prairielearn_e2e.regression:main
3
- pl-e2e-merge-reports = prairielearn_e2e.reporting:main
4
- pl-e2e-test = prairielearn_e2e.runner:main
5
- pl-e2e-test-diff = prairielearn_e2e.fuzz:main
File without changes
File without changes
File without changes