morvix 0.1.0__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 (94) hide show
  1. morvix-0.1.0/.github/workflows/ci.yml +86 -0
  2. morvix-0.1.0/.github/workflows/publish.yml +38 -0
  3. morvix-0.1.0/.gitignore +23 -0
  4. morvix-0.1.0/CLAUDE.md +81 -0
  5. morvix-0.1.0/LICENSE +21 -0
  6. morvix-0.1.0/PKG-INFO +126 -0
  7. morvix-0.1.0/README.md +83 -0
  8. morvix-0.1.0/documentation.md +831 -0
  9. morvix-0.1.0/morvix/__init__.py +10 -0
  10. morvix-0.1.0/morvix/__main__.py +8 -0
  11. morvix-0.1.0/morvix/adapters/__init__.py +117 -0
  12. morvix-0.1.0/morvix/adapters/c.py +85 -0
  13. morvix-0.1.0/morvix/adapters/cpp.py +83 -0
  14. morvix-0.1.0/morvix/adapters/java.py +108 -0
  15. morvix-0.1.0/morvix/adapters/nasm.py +94 -0
  16. morvix-0.1.0/morvix/adapters/python.py +53 -0
  17. morvix-0.1.0/morvix/adapters/rust.py +70 -0
  18. morvix-0.1.0/morvix/app.py +75 -0
  19. morvix-0.1.0/morvix/banner.py +22 -0
  20. morvix-0.1.0/morvix/cases.py +129 -0
  21. morvix-0.1.0/morvix/commands/__init__.py +1 -0
  22. morvix-0.1.0/morvix/commands/bruteforce_cmd.py +45 -0
  23. morvix-0.1.0/morvix/commands/clean_cmd.py +53 -0
  24. morvix-0.1.0/morvix/commands/config_cmd.py +179 -0
  25. morvix-0.1.0/morvix/commands/exit_cmd.py +14 -0
  26. morvix-0.1.0/morvix/commands/gen_cmd.py +219 -0
  27. morvix-0.1.0/morvix/commands/help_cmd.py +99 -0
  28. morvix-0.1.0/morvix/commands/import_cmd.py +86 -0
  29. morvix-0.1.0/morvix/commands/init_cmd.py +111 -0
  30. morvix-0.1.0/morvix/commands/model_cmd.py +56 -0
  31. morvix-0.1.0/morvix/commands/open_cmd.py +69 -0
  32. morvix-0.1.0/morvix/commands/package_cmd.py +109 -0
  33. morvix-0.1.0/morvix/commands/reference_cmd.py +60 -0
  34. morvix-0.1.0/morvix/commands/result_cmd.py +228 -0
  35. morvix-0.1.0/morvix/commands/run_cmd.py +139 -0
  36. morvix-0.1.0/morvix/commands/runner_cmd.py +327 -0
  37. morvix-0.1.0/morvix/commands/status_cmd.py +75 -0
  38. morvix-0.1.0/morvix/commands/workflow_cmd.py +140 -0
  39. morvix-0.1.0/morvix/comparators.py +108 -0
  40. morvix-0.1.0/morvix/compare.py +110 -0
  41. morvix-0.1.0/morvix/components/__init__.py +1 -0
  42. morvix-0.1.0/morvix/components/choice.py +33 -0
  43. morvix-0.1.0/morvix/components/confirm.py +41 -0
  44. morvix-0.1.0/morvix/components/form.py +254 -0
  45. morvix-0.1.0/morvix/components/progress.py +45 -0
  46. morvix-0.1.0/morvix/components/selection.py +235 -0
  47. morvix-0.1.0/morvix/components/table.py +114 -0
  48. morvix-0.1.0/morvix/context.py +74 -0
  49. morvix-0.1.0/morvix/errors.py +45 -0
  50. morvix-0.1.0/morvix/execmodels/__init__.py +3 -0
  51. morvix-0.1.0/morvix/execmodels/args.py +36 -0
  52. morvix-0.1.0/morvix/execmodels/file.py +60 -0
  53. morvix-0.1.0/morvix/execmodels/interactive.py +157 -0
  54. morvix-0.1.0/morvix/execmodels/library.py +119 -0
  55. morvix-0.1.0/morvix/generators.py +313 -0
  56. morvix-0.1.0/morvix/help_text.py +178 -0
  57. morvix-0.1.0/morvix/judge.py +203 -0
  58. morvix-0.1.0/morvix/layout.py +48 -0
  59. morvix-0.1.0/morvix/manifest.py +95 -0
  60. morvix-0.1.0/morvix/messages.py +57 -0
  61. morvix-0.1.0/morvix/models.py +124 -0
  62. morvix-0.1.0/morvix/packaging.py +167 -0
  63. morvix-0.1.0/morvix/process.py +337 -0
  64. morvix-0.1.0/morvix/project.py +250 -0
  65. morvix-0.1.0/morvix/readme.py +151 -0
  66. morvix-0.1.0/morvix/registry.py +178 -0
  67. morvix-0.1.0/morvix/results.py +161 -0
  68. morvix-0.1.0/morvix/runner_build.py +82 -0
  69. morvix-0.1.0/morvix/runner_core/morvix_runner.py +1245 -0
  70. morvix-0.1.0/morvix/runner_core/run.sh +36 -0
  71. morvix-0.1.0/morvix/shapes.py +249 -0
  72. morvix-0.1.0/morvix/shell.py +196 -0
  73. morvix-0.1.0/morvix/suggestions.py +113 -0
  74. morvix-0.1.0/morvix/theme.py +75 -0
  75. morvix-0.1.0/morvix/version.py +7 -0
  76. morvix-0.1.0/morvix/workflow.py +89 -0
  77. morvix-0.1.0/pyproject.toml +47 -0
  78. morvix-0.1.0/test_project.zip +0 -0
  79. morvix-0.1.0/tests/conftest.py +56 -0
  80. morvix-0.1.0/tests/test_commands.py +180 -0
  81. morvix-0.1.0/tests/test_compare.py +204 -0
  82. morvix-0.1.0/tests/test_generators.py +139 -0
  83. morvix-0.1.0/tests/test_java_multifile.py +62 -0
  84. morvix-0.1.0/tests/test_judge.py +201 -0
  85. morvix-0.1.0/tests/test_manifest.py +152 -0
  86. morvix-0.1.0/tests/test_packaging.py +146 -0
  87. morvix-0.1.0/tests/test_process.py +158 -0
  88. morvix-0.1.0/tests/test_readme_honesty.py +37 -0
  89. morvix-0.1.0/tests/test_regressions.py +71 -0
  90. morvix-0.1.0/tests/test_runner_core.py +251 -0
  91. morvix-0.1.0/tests/test_runner_stdlib.py +45 -0
  92. morvix-0.1.0/tests/test_rust.py +43 -0
  93. morvix-0.1.0/tests/test_shapes.py +208 -0
  94. morvix-0.1.0/tests/test_valgrind.py +77 -0
@@ -0,0 +1,86 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ${{ matrix.os }}
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ os: [ubuntu-latest, macos-latest]
15
+ python: ["3.9", "3.12"]
16
+ steps:
17
+ - uses: actions/checkout@v6
18
+ - uses: actions/setup-python@v6
19
+ with:
20
+ python-version: ${{ matrix.python }}
21
+ - uses: actions/setup-java@v5
22
+ with:
23
+ distribution: temurin
24
+ java-version: "21"
25
+ # valgrind is Linux-only; install it so the memory-correctness test runs
26
+ # for real rather than skipping. gcc/g++ and rustc are preinstalled on the
27
+ # GitHub runners, so the C/C++/Rust adapter tests run too.
28
+ - name: Install valgrind (Linux)
29
+ if: runner.os == 'Linux'
30
+ run: sudo apt-get update && sudo apt-get install -y valgrind
31
+ - run: pip install -e ".[dev]"
32
+ - run: pytest -q
33
+
34
+ # The sacred path: prove a Receiver can run a package with ONLY system
35
+ # python3 - no Morvix install anywhere. One job builds a package; a second,
36
+ # deliberately Morvix-free, job unpacks it and runs ./run.sh.
37
+ build-package:
38
+ runs-on: ubuntu-latest
39
+ steps:
40
+ - uses: actions/checkout@v6
41
+ - uses: actions/setup-python@v6
42
+ with:
43
+ python-version: "3.12"
44
+ - run: pip install -e .
45
+ - name: Build a shareable package
46
+ run: |
47
+ mkdir demo && cd demo
48
+ printf 'import sys\nprint(sum(int(x) for x in sys.stdin.read().split()))\n' > sol.py
49
+ morvix init --name demo --language python
50
+ morvix import sol.py
51
+ morvix reference sol.py
52
+ morvix gen --random --shape ints --count 5 --seed 1
53
+ morvix gen --expected
54
+ morvix package --zip --out ../pkg.zip
55
+ cp sol.py ../sol.py
56
+ - uses: actions/upload-artifact@v7
57
+ with:
58
+ name: receiver-package
59
+ path: |
60
+ pkg.zip
61
+ sol.py
62
+
63
+ receiver-clean:
64
+ needs: build-package
65
+ runs-on: ubuntu-latest
66
+ steps:
67
+ - uses: actions/setup-python@v6
68
+ with:
69
+ python-version: "3.12"
70
+ - uses: actions/download-artifact@v8
71
+ with:
72
+ name: receiver-package
73
+ # No checkout, no pip install: Morvix must not be present on this runner.
74
+ - name: Confirm Morvix is absent
75
+ run: |
76
+ if python3 -c "import morvix" 2>/dev/null; then
77
+ echo "morvix is importable here - this job must be Morvix-free"; exit 1
78
+ fi
79
+ echo "morvix is absent - good"
80
+ - name: Unpack and run ./run.sh with only system python3
81
+ run: |
82
+ mkdir r && cd r
83
+ unzip ../pkg.zip
84
+ cp ../sol.py .
85
+ sh run.sh sol.py | tee out.txt
86
+ grep -q "passed" out.txt
@@ -0,0 +1,38 @@
1
+ name: Publish to PyPI
2
+
3
+ # Publishes to PyPI when you create a GitHub Release. Uses PyPI Trusted
4
+ # Publishing (OIDC) - no API token is stored anywhere. The build and the
5
+ # upload are split so the upload job is the only one with id-token permission.
6
+
7
+ on:
8
+ release:
9
+ types: [published]
10
+ workflow_dispatch: # lets you trigger a publish by hand too
11
+
12
+ jobs:
13
+ build:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v6
17
+ - uses: actions/setup-python@v6
18
+ with:
19
+ python-version: "3.12"
20
+ - run: pip install build
21
+ - run: python -m build
22
+ - uses: actions/upload-artifact@v7
23
+ with:
24
+ name: dist
25
+ path: dist/
26
+
27
+ publish:
28
+ needs: build
29
+ runs-on: ubuntu-latest
30
+ environment: pypi # must match the environment set on PyPI's publisher
31
+ permissions:
32
+ id-token: write # required for trusted publishing (OIDC)
33
+ steps:
34
+ - uses: actions/download-artifact@v8
35
+ with:
36
+ name: dist
37
+ path: dist/
38
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,23 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .eggs/
6
+ build/
7
+ dist/
8
+ .venv/
9
+ venv/
10
+
11
+ # Tooling
12
+ .pytest_cache/
13
+ .mypy_cache/
14
+ .ruff_cache/
15
+ .coverage
16
+ htmlcov/
17
+
18
+ # OS
19
+ .DS_Store
20
+
21
+ # Local scratch / sandboxes used while testing morvix by hand
22
+ /scratch/
23
+ /sandbox/
morvix-0.1.0/CLAUDE.md ADDED
@@ -0,0 +1,81 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## What this is
6
+
7
+ Morvix is a Python CLI that lets a student build test cases from their own solution, run their code
8
+ against them, and package the harness to share with classmates. The full design lives in
9
+ `documentation.md` (831 lines) - read the relevant section before changing behavior; the code is
10
+ organized to mirror it and many comments cite section numbers (e.g. "Section 14.6").
11
+
12
+ ## Dev commands
13
+
14
+ ```sh
15
+ python3 -m venv .venv && .venv/bin/pip install -e ".[dev]" # set up
16
+ .venv/bin/morvix # interactive shell
17
+ .venv/bin/morvix <cmd> ... # one-shot (same verbs as the shell)
18
+ .venv/bin/python -m compileall -q morvix # quick syntax check of everything
19
+ .venv/bin/pytest # run the test suite
20
+ .venv/bin/pytest tests/test_x.py::test_y # a single test
21
+ ```
22
+
23
+ The toolchains used by the language adapters (`gcc`/`g++`, `nasm`, `javac`/`java`, `rustc`,
24
+ `valgrind`) must be on PATH to exercise those paths. `rustc` and `valgrind` are commonly absent on
25
+ macOS; those features degrade with an honest warning rather than faking results.
26
+
27
+ ## The architecture that matters
28
+
29
+ Everything hangs on **three orthogonal axes that never multiply against each other** (Section 4.1).
30
+ When adding capability, add to exactly one axis:
31
+
32
+ - **Language adapter** (`morvix/adapters/<lang>.py`) - turns source into something runnable. Knows
33
+ nothing about tests. Subclass `Adapter`, implement `build/run_spec/describe`, call `register()`.
34
+ - **Execution model** (`morvix/models.py` for `stdio`; `morvix/execmodels/<name>.py` for the rest) -
35
+ how a runnable thing is driven and what its observable output is. A function
36
+ `(case, env, limits) -> Observation` registered with `register_model`.
37
+ - **Comparison strategy** (`morvix/compare.py` for exact/whitespace; `morvix/comparators.py` for
38
+ float/hash/checker) - given output + expected, decide pass/fail. A function
39
+ `(CompareInput) -> Verdict` registered with `register_comparator`.
40
+
41
+ `morvix/judge.py` is the engine that ties them together: build once, run each case through the
42
+ model, then combine the enabled dimensions (output match + expected exit/signal + memory) so a case
43
+ can require all of them at once (Section 14.7). `morvix/process.py` is the bottom layer (spawn,
44
+ rlimits, timing, `wait4`-based per-child memory, `LC_ALL=C` locale) and is the single place that
45
+ papers over Linux/macOS differences.
46
+
47
+ The stack, top to bottom: shell/CLI (`app`, `shell`, `registry`) -> shared components
48
+ (`components/`) -> commands (`commands/`) -> orchestration (`project`, `generators`, `manifest`,
49
+ `packaging`, `workflow`, `results`) -> the three axes -> `process`.
50
+
51
+ ## Key conventions and invariants
52
+
53
+ - **Two entry points, one vocabulary.** `morvix/registry.py` builds one argparse parser used by both
54
+ the REPL and one-shot mode. Each command module exposes `NAME`, `configure(parser)`,
55
+ `run(ctx, args) -> int`, and an optional `complete(ctx, prev_words, word)`. Errors raise (they do
56
+ not `sys.exit`) so the shell survives them.
57
+ - **One shared UI layer.** Commands never hand-roll a menu, prompt, table, or message. They compose
58
+ from `morvix/components/` (selection, choice, form, confirm, table, progress) and print only via
59
+ `ctx.messenger`. Each component has a non-interactive fallback driven by `ctx.interactive`.
60
+ - **The directory is the state.** No database. `config/project.json` + `config/cases.json` +
61
+ `config/runners/*.json` are the editable truth; `morvix.json` is the generated, shareable manifest
62
+ regenerated on every `ctx.save_project()`. Config is JSON throughout.
63
+ - **The runner core is sacred and standalone.** `morvix/runner_core/morvix_runner.py` ships verbatim
64
+ inside packages, must import **nothing** from `morvix`, must be **stdlib-only**, and must run on a
65
+ clean machine with just Python 3. It re-implements the judge logic; if you change judging behavior
66
+ in `judge.py`/`process.py`/`compare.py`, keep the runner core in sync. `run.sh` is its wrapper and
67
+ is placed at the package root by `packaging.py` so `./run.sh` works.
68
+ - **A package never contains the author's source** (`solutions/`), the brute-force reference, or
69
+ `config/`. See `packaging.build_package`.
70
+ - **Honesty is a feature.** Expected answers come from one peer's solution, not an authority. The
71
+ correctness disclaimer is always included in the generated README (`readme.py`). Smart suggestions
72
+ (`suggestions.py`) explain and ask - they never change behavior silently.
73
+ - **Help text has one home.** `morvix/help_text.py` powers both `help` and the autocomplete meta
74
+ column; keep summaries there in sync with what a command actually does.
75
+
76
+ ## Style
77
+
78
+ Comments are plain-English header blocks per file/function with occasional `# - bullet` lists for
79
+ multi-step logic; sparse inline comments; no heavy docstrings. Keep code simple - this is open
80
+ source and meant to be readable by a newcomer. Commit messages are conventional (`feat:`, `fix:`,
81
+ `chore:`, `refactor:`, `docs:`, `test:`), lowercase, no body or trailers.
morvix-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Krzysztof Adamczyk
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
morvix-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,126 @@
1
+ Metadata-Version: 2.4
2
+ Name: morvix
3
+ Version: 0.1.0
4
+ Summary: A test-authoring, test-running, and test-sharing CLI for university programming assignments.
5
+ Project-URL: Homepage, https://github.com/Krzysztof-Ad/morvix
6
+ Project-URL: Repository, https://github.com/Krzysztof-Ad/morvix
7
+ Author: Krzysztof Adamczyk
8
+ License: MIT License
9
+
10
+ Copyright (c) 2026 Krzysztof Adamczyk
11
+
12
+ Permission is hereby granted, free of charge, to any person obtaining a copy
13
+ of this software and associated documentation files (the "Software"), to deal
14
+ in the Software without restriction, including without limitation the rights
15
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
+ copies of the Software, and to permit persons to whom the Software is
17
+ furnished to do so, subject to the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be included in all
20
+ copies or substantial portions of the Software.
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
+ SOFTWARE.
29
+ License-File: LICENSE
30
+ Keywords: assignments,cli,education,judge,testing,university
31
+ Classifier: Development Status :: 4 - Beta
32
+ Classifier: Environment :: Console
33
+ Classifier: Intended Audience :: Education
34
+ Classifier: License :: OSI Approved :: MIT License
35
+ Classifier: Programming Language :: Python :: 3
36
+ Classifier: Topic :: Software Development :: Testing
37
+ Requires-Python: >=3.9
38
+ Requires-Dist: prompt-toolkit>=3.0
39
+ Requires-Dist: rich>=13.0
40
+ Provides-Extra: dev
41
+ Requires-Dist: pytest>=7.0; extra == 'dev'
42
+ Description-Content-Type: text/markdown
43
+
44
+ # Morvix
45
+
46
+ A test-authoring, test-running, and test-sharing CLI for university programming assignments.
47
+
48
+ Most courses don't hand out test suites, so students end up writing their own: they build test
49
+ cases from their own solution, run their program against them, and share the cases on GitHub so
50
+ classmates can check their code too. Morvix automates that whole loop - building, running, and
51
+ sharing these self-made test harnesses - quickly and consistently, across languages and platforms.
52
+
53
+ It's an honest tool. The "expected answers" come from one student's own solution, so passing every
54
+ test does **not** prove a solution is correct - it proves it agrees with that one reference on the
55
+ cases tried. Morvix says so plainly (it's baked into every package's README) and makes the real
56
+ signal - lots of independent solutions agreeing - easy to see.
57
+
58
+ > Morvix is not an online judge, not a grading server, and not an AI tool. It runs locally and
59
+ > offline. Linux and macOS are the primary targets; Windows works on a best-effort basis.
60
+
61
+ ## Install
62
+
63
+ ```sh
64
+ pip install morvix # or, from a clone:
65
+ pip install .
66
+ ```
67
+
68
+ Needs Python 3.9+. The only dependencies are `prompt_toolkit` and `rich`. The runner that ships
69
+ inside shared packages is pure standard library, so whoever you share with needs nothing but
70
+ Python 3.
71
+
72
+ ## Quick start (the Author)
73
+
74
+ Run `morvix` with no arguments to open the interactive shell (live autocomplete, history, a status
75
+ bar), or use any command one-shot from your normal shell. What you can do one way is identical the
76
+ other way.
77
+
78
+ ```sh
79
+ cd my-assignment
80
+ morvix init # create a project here (guided)
81
+ morvix config cpp # how to build/run your language
82
+ morvix import solution.cpp # the solution under test
83
+ morvix reference solution.cpp # it also defines the expected answers
84
+ morvix gen --random --count 100 # generate inputs from the built-in shapes
85
+ morvix gen --expected # compute answers by running the reference
86
+ morvix run --all # build, run, judge - with a live table
87
+ morvix runner new full # a named, shareable run profile
88
+ morvix package --zip # bundle it up to share (your source is left out)
89
+ ```
90
+
91
+ ## Quick start (the Receiver)
92
+
93
+ You got a package from a classmate. You don't need Morvix at all:
94
+
95
+ ```sh
96
+ unzip their-tests.zip && cd their-tests
97
+ ./run.sh my_solution.cpp # builds your code, runs every test, reports
98
+ ```
99
+
100
+ If you *do* have Morvix, open it in the unpacked directory and you get the rich view - browse the
101
+ tests, re-run selectively, and diff your per-case results against the author's.
102
+
103
+ ## What's in the box
104
+
105
+ - **Languages**: C, C++, NASM, Python, Java, Rust - each a small adapter. Adding one is one file.
106
+ - **Execution models**: `stdio`, `library` (link & assert), `args`, `file`, `interactive`.
107
+ - **Comparison**: byte-exact, whitespace-insensitive, float-tolerant, hash, a custom checker, and
108
+ expected exit status / crash - combinable per case.
109
+ - **Limits & checks**: wall/CPU time, peak memory (approximate), hard memory caps, output caps, and
110
+ an optional valgrind memory-correctness pass.
111
+ - **Generation**: a built-in random-shape library, custom generators, stress testing against a
112
+ brute force, and crash-case candidates.
113
+ - **Sharing**: zip / tar / tar.gz / tar.xz packages with an auto-generated README and a manifest.
114
+ - **Workflows**: record a sequence of commands and replay it on the next assignment.
115
+
116
+ These three axes - language, execution model, comparison - are kept independent, so they never
117
+ multiply against each other. That's the design decision everything else hangs on.
118
+
119
+ ## Design
120
+
121
+ The full design is in [documentation.md](documentation.md): the architecture, every command, the
122
+ file formats, and the reasoning behind each choice.
123
+
124
+ ## License
125
+
126
+ [MIT](LICENSE) (c) Krzysztof Adamczyk
morvix-0.1.0/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # Morvix
2
+
3
+ A test-authoring, test-running, and test-sharing CLI for university programming assignments.
4
+
5
+ Most courses don't hand out test suites, so students end up writing their own: they build test
6
+ cases from their own solution, run their program against them, and share the cases on GitHub so
7
+ classmates can check their code too. Morvix automates that whole loop - building, running, and
8
+ sharing these self-made test harnesses - quickly and consistently, across languages and platforms.
9
+
10
+ It's an honest tool. The "expected answers" come from one student's own solution, so passing every
11
+ test does **not** prove a solution is correct - it proves it agrees with that one reference on the
12
+ cases tried. Morvix says so plainly (it's baked into every package's README) and makes the real
13
+ signal - lots of independent solutions agreeing - easy to see.
14
+
15
+ > Morvix is not an online judge, not a grading server, and not an AI tool. It runs locally and
16
+ > offline. Linux and macOS are the primary targets; Windows works on a best-effort basis.
17
+
18
+ ## Install
19
+
20
+ ```sh
21
+ pip install morvix # or, from a clone:
22
+ pip install .
23
+ ```
24
+
25
+ Needs Python 3.9+. The only dependencies are `prompt_toolkit` and `rich`. The runner that ships
26
+ inside shared packages is pure standard library, so whoever you share with needs nothing but
27
+ Python 3.
28
+
29
+ ## Quick start (the Author)
30
+
31
+ Run `morvix` with no arguments to open the interactive shell (live autocomplete, history, a status
32
+ bar), or use any command one-shot from your normal shell. What you can do one way is identical the
33
+ other way.
34
+
35
+ ```sh
36
+ cd my-assignment
37
+ morvix init # create a project here (guided)
38
+ morvix config cpp # how to build/run your language
39
+ morvix import solution.cpp # the solution under test
40
+ morvix reference solution.cpp # it also defines the expected answers
41
+ morvix gen --random --count 100 # generate inputs from the built-in shapes
42
+ morvix gen --expected # compute answers by running the reference
43
+ morvix run --all # build, run, judge - with a live table
44
+ morvix runner new full # a named, shareable run profile
45
+ morvix package --zip # bundle it up to share (your source is left out)
46
+ ```
47
+
48
+ ## Quick start (the Receiver)
49
+
50
+ You got a package from a classmate. You don't need Morvix at all:
51
+
52
+ ```sh
53
+ unzip their-tests.zip && cd their-tests
54
+ ./run.sh my_solution.cpp # builds your code, runs every test, reports
55
+ ```
56
+
57
+ If you *do* have Morvix, open it in the unpacked directory and you get the rich view - browse the
58
+ tests, re-run selectively, and diff your per-case results against the author's.
59
+
60
+ ## What's in the box
61
+
62
+ - **Languages**: C, C++, NASM, Python, Java, Rust - each a small adapter. Adding one is one file.
63
+ - **Execution models**: `stdio`, `library` (link & assert), `args`, `file`, `interactive`.
64
+ - **Comparison**: byte-exact, whitespace-insensitive, float-tolerant, hash, a custom checker, and
65
+ expected exit status / crash - combinable per case.
66
+ - **Limits & checks**: wall/CPU time, peak memory (approximate), hard memory caps, output caps, and
67
+ an optional valgrind memory-correctness pass.
68
+ - **Generation**: a built-in random-shape library, custom generators, stress testing against a
69
+ brute force, and crash-case candidates.
70
+ - **Sharing**: zip / tar / tar.gz / tar.xz packages with an auto-generated README and a manifest.
71
+ - **Workflows**: record a sequence of commands and replay it on the next assignment.
72
+
73
+ These three axes - language, execution model, comparison - are kept independent, so they never
74
+ multiply against each other. That's the design decision everything else hangs on.
75
+
76
+ ## Design
77
+
78
+ The full design is in [documentation.md](documentation.md): the architecture, every command, the
79
+ file formats, and the reasoning behind each choice.
80
+
81
+ ## License
82
+
83
+ [MIT](LICENSE) (c) Krzysztof Adamczyk