File size: 3,900 Bytes
b2e4883
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# Test harness for gp5_to_keyswitched_mid.py

This directory holds the test suite that validates the Guitar Pro 5 β†’ keyswitched MIDI conversion script. The goal is to catch regressions before they break a recording session.

## What it tests

For each track in each song, the suite verifies:

1. **Conductor tempo** β€” must match the source GP file's BPM (was off by 60,000,000Γ·x in earlier versions).
2. **Conductor time signature** β€” must be 4/4 for the test corpus (was 4/16 when we read the wrong field).
3. **First event at tick 0** β€” no empty intro bars (the 35-bar silent intro was a real bug).
4. **Channel preserved** β€” output channel matches the GP file's channel assignment.
5. **Keyswitch counts exact** β€” every PalmDown, SlideIn, SlideUp, SlideDown, Hammer, Bend, Harm, Sustain key counted and matched against the baseline.
6. **Total keyswitchs** β€” sanity check on the count.
7. **Not empty** β€” placeholder MIDIs (54 bytes) are rejected.
8. **Track count** β€” exactly 2 tracks (conductor + audio).
9. **MIDI Type 1** β€” multi-track format.
10. **960 ticks per beat** β€” matches PyGuitarPro's resolution.

## How to run

```bash
cd D:/CODE/unstable-drums
python -m pytest tests/
```

A clean run takes ~2 minutes (the script regenerates every track). A focused run with `-k`:

```bash
python -m pytest tests/ -k "Dany_Rhythm_Guitar"
```

## How to add a new song

1. Copy the GP5 file into `D:/CODE/unstable-drums/gp5_songs/`.
2. Re-run the baseline recorder:
   ```bash
   python tests/record_expected.py
   ```
   This regenerates `tests/expected/baseline.yaml` with the current script's output.
3. Inspect the YAML to confirm the keyswitch counts and structural facts look right.
4. Commit the updated baseline.yaml.

## How to add a new test scenario

If you find a new edge case (e.g., a new articulation the script doesn't handle yet), add a test function to `tests/test_gp5_conversion.py` and re-run the suite. The test should run against every track in the baseline. Example:

```python
def test_my_new_scenario(track_setup):
    """Every track should have ... whatever."""
    actual = ...
    expected = ...
    assert actual == expected, f"{track_setup['song_name']}/{...}"
```

The new test runs against every (song, track) pair automatically β€” no need to parametrize manually.

## How to update the baseline

The baseline is the *contract*. When you fix the GP file (e.g., add 5 more grace notes), the baseline's keyswitch counts become stale. Re-run `record_expected.py` to update them, then commit the new YAML.

The expected YAML is **not** a measurement of "what the script does" β€” it's a measurement of "what the script should do, given the user's intent for the GP file." If you change the GP file on purpose, you update the baseline on purpose.

## How the script handles things

The script writes outputs to subfolders named after the song:
- `D:/CODE/unstable-drums/The Summoning Aug 2026/*.mid`
- `D:/CODE/unstable-drums/Sacrifice ReDrum Full v2 gracenotes/*.mid`

These directories are gitignored. The test suite regenerates them on every run.

## How regressions are caught

The tests re-run the script for every track before testing. If a code change breaks the keyswitch counts, the test fails with a clear message like:

```
Sacrifice ReDrum Full v2 gracenotes/Dany Rhythm Guitar: keyswitch counts mismatch
  Missing (expected but not emitted): {'PalmDown': 2}
  Extra (emitted but not expected): {'C1(SlideUp)': 2}
```

That tells you exactly which song, which track, and which keyswitch is wrong.

## When the test fails for a "good" reason

If the user changes the GP file deliberately, the baseline is stale. Run `python tests/record_expected.py` to refresh the baseline, review the diff, and commit.

If the test fails because the script has a bug, fix the script and re-run the tests. The baseline shouldn't change for a bug fix.