You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
First slice of issue #11 (slide CRUD epic). Lands the in-deck CRUD
operations users have been asking for since 2014; full duplicate(),
cross-deck append_from(), and Sections support stay deferred to
Phases 2–4 in the epic.
New public API
--------------
- `Slides.add_slide(slide_layout, index=None)` — `index=None`
preserves existing append behavior (backwards compatible). Integer
`index` inserts at that zero-based position; `index=len(self)`
is a valid append, negatives raise `IndexError`.
- `Slides.move(slide, new_index)` — reorder a slide in the
presentation's slide sequence. Raises `ValueError` for foreign
slides, `IndexError` for out-of-range `new_index`.
- `Slides.remove(slide)` — drop a slide from the collection. The
presentation→slide relationship is removed; the underlying part
falls out on save. Image and other media parts shared with
surviving slides are preserved (covered by integration test).
- `Slide.delete()` — convenience alias for
`prs.slides.remove(self)`.
API shape mirrors the existing `SlideLayouts.remove(slide_layout)`
shape rather than upstream PR scanny#1029's
`remove_slide(slide_id)` — instance-keyed is more Pythonic and
matches the rest of the library.
Internal additions
------------------
- `CT_SlideIdList.insert_sldId_at(rId, idx)` — index-aware sldId
insertion, with `idx == len` allowed.
- `CT_SlideIdList.move_sldId_to(sldId, new_idx)` — reposition an
existing sldId; no-op when the index already matches.
- `CT_SlideIdList.remove_sldId(sldId)` — bounded remove with a
parent-of check.
Test coverage
-------------
- 32 new unit tests in `tests/test_slide_crud.py` covering oxml
helpers, the Slides CRUD methods, the Slide.delete alias, and four
full-pipeline round-trip integration tests (add-at-index, remove,
delete, move). Plus a shared-image-preservation round-trip and a
`index=len(slides)` boundary test added per advisor review.
- 5 new behave scenarios in `features/sld-crud.feature` exercising
add-at-head, add-in-middle, move, remove, and Slide.delete.
- New UAT script (untracked) at `uat_slide_crud.py` builds a deck
exercising every new entry-point, saves, reopens, and prints a
per-slide read-back so the maintainer can compare in PowerPoint /
Keynote per CLAUDE.md §6.
Tangential test-isolation fix
-----------------------------
`tests/opc/test_package.py:DescribePartFactory` mutates
`PartFactory.part_type_for[CT.PML_SLIDE]` to a class_mock and
never reverts it. The mock leaked into any later test that loaded
slides through `Presentation()` — caught here by the new
round-trip integration tests. Restored via a request finalizer;
isolated to that one test, no behavior change for the production
code path.
Verification
------------
```
$ python3 -m pytest tests/ -q | tail -3
3086 passed in 3.76s
$ ruff check src tests | tail -3
All checks passed!
$ python3 -m behave features/ --no-color | tail -3
986 scenarios passed, 0 failed, 0 skipped
2952 steps passed, 0 failed, 0 skipped
```
Refs #11
0 commit comments