Coverage: masoniteorm relationships (BelongsToMany, Morph*)#159
Coverage: masoniteorm relationships (BelongsToMany, Morph*)#159tmgbedu wants to merge 4 commits into
Conversation
Cover BelongsToMany, MorphOne, MorphMany, MorphToMany, MorphTo, and the BaseRelationship base class with query-builder/DB mocks. Raises relationship module coverage from 44% to 76% (BelongsToMany 16% to 82%, BaseRelationship to 100%).
Remove unused pytest import (F401) in test_belongs_to_many.py and apply ruff format to satisfy CI. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
✅ Code Review: APPROVE (do not merge — maintainer's call)Formal GitHub approval blocked (same account authored the PR), so recording the verdict as a comment. Reviewed the full diff. Test-only PR — no framework source touched. All 5 files live under Correctness / test quality
Verification
Fix pushed to branchCI was red on Ruff (unused Verdict: approve. Leaving merge to the maintainer. |
The masoniteorm relationship classes are not wired to this fork's async QueryBuilder, so the relationship unit tests mock the builder instead of running against real sqlite. Document the specifics inline (missing QueryBuilder.table()/without_global_scopes()/add_select(), the BaseRelationship.get_builder() no-arg self.fn() TypeError, the attach/detach Pivot chain, and the MorphOne/MorphToMany undefined load_config) so the intent is clear and the framework gaps are traceable. No behavioral or framework changes.
Rewrite six tautological morph relationship tests that only asserted the
mock's canned return value (GET_RESULT/FIRST_RESULT) so they verify the
real arguments the source constructs:
- morph_many/morph_one get_related (single): assert where("record_type", ...)
and where("record_id", pk); MorphOne additionally asserts .first() over .get()
- get_related (collection): assert the "<table>.record_type" filter and that
where_in receives the plucked/unique ids
- get_related with callback: assert the builder passed to the callback and the
where() args, not just callback.called
- morph_one apply_query: keep the .first()-not-.get() check, add real arg asserts
Add autospec=True to the Pivot patches in the BelongsToMany tests so signature
drift is caught instead of masked by bare MagicMock. attach_related() calls a
non-existent Pivot.table() classmethod; the autospec surfaces this as an
AttributeError, marked xfail(strict) pending the framework fix (backlog #738).
tmgbedu
left a comment
There was a problem hiding this comment.
Code Reviewer verdict: APPROVE ✅ (task #746 re-review) — do not merge
(Posted as a comment: gh blocks self-approval since the review agent shares the author's git identity.)
Re-reviewed head 7de5e74d. Morph tests are now genuinely coupled to the source's constructed query args; autospec applied cleanly.
Morph tests de-hollowed (verified vs source + mutation-tested)
MorphMany/MorphOne.get_related(single): assertwhere("record_type", <type>)+where("record_id", <pk>), and.get()vs.first()— matches MorphMany.py / MorphOne.py.- collection paths: assert table-prefixed
"likes.record_type"+ plucked/unique ids towhere_in("record_id", [...]). - callback path: asserts the fully-filtered builder is passed to the callback.
MorphOne.apply_query:.first()called /.get()NOT called + real args.- Mutation: swapping source
morph_idto a wrong literal failstest_morph_many_get_related_single(where('record_id', 3) call not found) → non-tautological.
autospec Pivot
- All
Pivotpatches useautospec=True; suite green (71 passed) → no silent signature drift. attach_related(calls non-existentPivot.table()):xfail(raises=AttributeError, strict=True, reason=... backlog #738)→ shows as XFAIL, not silent pass; flips red when framework is fixed.
Verification
- relationships suite: 71 passed, 1 xfailed.
- full suite (excl. live pg/mysql): 1681 passed, 7 skipped, 1 xfailed.
ruff check+ruff format --check: clean.- coverage 72.96% ≥ 68%.
- diff is test-files-only, no framework source. Branch is behind main — update on main before merge so #156's backup cleanup applies (normal merge drops them; not a blocker).
Summary
Adds unit tests for the ORM relationship classes under
masoniteorm/relationships, which were largely untested. Tests mock the query builder / DB rather than hitting a live database, so they run fast and in isolation.Coverage impact (relationships module: 44% → 76%)
What's covered
__set_name__, builder resolution via the registry, descriptor__get__paths, join clause building, and every abstract method raisingNotImplementedError.set_keys, pivot-table inference,apply_query/make_query/get_relatedhydration,relate,joins,query_has/query_where_exists,get_with_count_query, andattach/detach/attach_related/detach_related(withPivotpatched).set_keysdefaults,apply_query, single-relation and collectionget_relatedpaths,register_related,get_record_key_lookup, andmorph_mapregistry lookups.A shared
conftest.pyprovides a chainable query-builder mock.Testing
uv run pytest tests/masoniteorm/relationships/— 40 new tests pass.Note:
masoniteorm.backupis left untouched as instructed.