truncate_plan should truncate each app separately
# Context
I have a project with multiple apps (Ex: App A and app B).
I once in a while code migrations with tests based on the state of the DB at that time.
Lately I added a new `nullable` field on my Old model in app A, a migration to fill the field then make it `non-nullable`. Everything was working properly except one thing, an old migration test started to fail.
The old migration tests for app B started to fail because back then that field did not exist but my app A was being fully migrated.
It did not make any sense until I realized `truncate_plan` only truncate the end of the migrations plan and not the apps separately.
# Explanations
Lets say I have migrations in each apps that were added in that chronological order:
```python
A1
B1
A2
B2
A3
B3 (has explicit dependency to A3 here)
A4
B4
A5
B5 (this is a custom migration)
B6
A6 (Add new nullable field here)
A7 (Migration to fill the field in the DB)
A8 (Migration to make field non-nullable)
```
The migration test is specified like this:
```python
migration_from = [
("A", "4"),
("B", "4"),
]
migrate_to = [
("B", "5"),
]
```
However in practice when the test is ran the full plan looks like this:
```python
A1
A2
A3
A4
A5
A6 (Add new nullable field here)
A7 (Migration to fill the field in the DB)
A8 (Migration to make field non-nullable)
B1
B2
B3 (has explicit dependency to A3 here)
B4
B5 (this is a custom migration)
B6
```
The truncate plan A4 B4 will result to start dropping everything after index of B4 with the [current implementation](https://github.com/wemake-services/django-test-migrations/blob/128efac0494185d150df5c940baa0f6204bfc359/django_test_migrations/plan.py#L115-L116):
```python
A1
A2
A3
A4
A5
A6 (Add new nullable field here)
A7 (Migration to fill the field in the DB)
A8 (Migration to make field non-nullable)
B1
B2
B3 (has explicit dependency to A3 here)
B4
# B5 (this is a custom migration) <- REMOVAL FROM PLAN BEGINS AT THIS INDEX
# B6
```
However I would expect `truncate_plan` A4 B4 to truncate per app independently like this:
```python
A1
A2
A3
A4
# A5 <- REMOVED BECAUSE IT IS ABOVE A4
# A6 (Add new nullable field here) <- REMOVED FROM PLAN BECAUSE IT IS ABOVE A4
# A7 (Migration to fill the field in the DB) <- REMOVED FROM PLAN BECAUSE IT IS ABOVE A4
# A8 (Migration to make field non-nullable) <- REMOVED FROM PLAN BECAUSE IT IS ABOVE A4
B1
B2
B3 (has explicit dependency to A3 here)
B4
# B5 (this is a custom migration) <- REMOVED FROM PLAN BECAUSE IT IS ABOVE B4
# B6 <- REMOVED FROM PLAN BECAUSE IT IS ABOVE B4
```
3 条评论