- New compact_sets.py with Pitch, Chord, HarmonicSpace classes - Voice leading graph with change parameter (instead of symdiff) - CLI: --change, --dims, --chord-size, --max-path, --seed - Tests for core functionality - .gitignore for Python/pytest
153 lines
4.7 KiB
Python
153 lines
4.7 KiB
Python
import pytest
|
|
import sys
|
|
import os
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
import compact_sets_optimized_2 as cs
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def reset_dims():
|
|
cs.dims = cs.DIMS_8
|
|
yield
|
|
cs.dims = cs.DIMS_8
|
|
|
|
|
|
class TestPitchConversion:
|
|
def test_hs_array_to_fr_fundamental(self):
|
|
root = (0, 0, 0, 0, 0, 0, 0, 0)
|
|
assert cs.hs_array_to_fr(root) == 1.0
|
|
|
|
def test_hs_array_to_fr_octave(self):
|
|
octave = (1, 0, 0, 0, 0, 0, 0, 0)
|
|
assert cs.hs_array_to_fr(octave) == 2.0
|
|
|
|
def test_hs_array_to_fr_fifth(self):
|
|
fifth = (0, 1, 0, 0, 0, 0, 0, 0)
|
|
assert cs.hs_array_to_fr(fifth) == 3.0
|
|
|
|
def test_hs_array_to_fr_compound(self):
|
|
pitch = (1, 1, 0, 0, 0, 0, 0, 0)
|
|
assert cs.hs_array_to_fr(pitch) == 6.0
|
|
|
|
def test_hs_array_to_cents_fundamental(self):
|
|
root = (0, 0, 0, 0, 0, 0, 0, 0)
|
|
assert cs.hs_array_to_cents(root) == 0.0
|
|
|
|
def test_hs_array_to_cents_octave(self):
|
|
octave = (1, 0, 0, 0, 0, 0, 0, 0)
|
|
assert cs.hs_array_to_cents(octave) == 1200.0
|
|
|
|
|
|
class TestPitchManipulation:
|
|
def test_transpose_pitch(self):
|
|
pitch = (0, 1, 0, 0, 0, 0, 0, 0)
|
|
trans = (1, 0, 0, 0, 0, 0, 0, 0)
|
|
result = cs.transpose_pitch(pitch, trans)
|
|
assert result == (1, 1, 0, 0, 0, 0, 0, 0)
|
|
|
|
def test_transpose_pitch_negative(self):
|
|
pitch = (1, 1, 0, 0, 0, 0, 0, 0)
|
|
trans = (-1, 0, 0, 0, 0, 0, 0, 0)
|
|
result = cs.transpose_pitch(pitch, trans)
|
|
assert result == (0, 1, 0, 0, 0, 0, 0, 0)
|
|
|
|
def test_transpose_chord(self):
|
|
chord = ((0, 0, 0, 0, 0, 0, 0, 0), (0, 1, 0, 0, 0, 0, 0, 0))
|
|
trans = (1, 0, 0, 0, 0, 0, 0, 0)
|
|
result = cs.transpose_chord(chord, trans)
|
|
assert result == ((1, 0, 0, 0, 0, 0, 0, 0), (1, 1, 0, 0, 0, 0, 0, 0))
|
|
|
|
def test_expand_pitch(self):
|
|
pitch = (0, 1, 0, 0, 0, 0, 0, 0)
|
|
result = cs.expand_pitch(pitch)
|
|
assert isinstance(result, tuple)
|
|
|
|
def test_collapse_pitch(self):
|
|
pitch = (3, 1, 0, 0, 0, 0, 0, 0)
|
|
result = cs.collapse_pitch(pitch)
|
|
assert result == (0, 1, 0, 0, 0, 0, 0, 0)
|
|
|
|
def test_collapse_chord(self):
|
|
chord = ((3, 1, 0, 0, 0, 0, 0, 0), (2, 0, 1, 0, 0, 0, 0, 0))
|
|
result = cs.collapse_chord(chord)
|
|
assert result == ((0, 1, 0, 0, 0, 0, 0, 0), (0, 0, 1, 0, 0, 0, 0, 0))
|
|
|
|
|
|
class TestPitchDifference:
|
|
def test_pitch_difference(self):
|
|
p1 = (0, 1, 0, 0, 0, 0, 0, 0)
|
|
p2 = (0, 0, 0, 0, 0, 0, 0, 0)
|
|
result = cs.pitch_difference(p1, p2)
|
|
assert result == (0, 1, 0, 0, 0, 0, 0, 0)
|
|
|
|
def test_cent_difference(self):
|
|
p1 = (0, 0, 0, 0, 0, 0, 0, 0)
|
|
p2 = (1, 0, 0, 0, 0, 0, 0, 0)
|
|
result = cs.cent_difference(p1, p2)
|
|
assert result == 1200.0
|
|
|
|
|
|
class TestCompactSets:
|
|
def test_compact_sets_root(self):
|
|
root = (0, 0, 0, 0)
|
|
result = list(cs.compact_sets(root, 1, 1))
|
|
assert len(result) > 0
|
|
|
|
def test_compact_sets_single_element(self):
|
|
root = (0, 0, 0, 0)
|
|
result = list(cs.compact_sets(root, 1, 1))
|
|
assert all(len(chord) == 1 for chord in result)
|
|
|
|
def test_compact_sets_returns_tuples(self):
|
|
root = (0, 0, 0, 0)
|
|
result = list(cs.compact_sets(root, 1, 1))
|
|
assert all(isinstance(chord, tuple) for chord in result)
|
|
|
|
|
|
class TestStochasticHamiltonian:
|
|
@pytest.mark.skip(reason="Requires full graph setup")
|
|
def test_stochastic_hamiltonian_from_graph(self, mock_write):
|
|
pass
|
|
|
|
@pytest.mark.skip(reason="Requires full chord set setup")
|
|
def test_stochastic_hamiltonian_using_chord_set(self, mock_write):
|
|
pass
|
|
|
|
|
|
class TestWeightFunctions:
|
|
def test_is_bass_rooted_true(self):
|
|
chord = ((0, 0, 0, 0), (0, 1, 0, 0))
|
|
assert cs.is_bass_rooted(chord) == True
|
|
|
|
def test_is_bass_rooted_false(self):
|
|
chord = ((0, 0, 0, 0), (0, 2, 0, 0))
|
|
assert cs.is_bass_rooted(chord) == False
|
|
|
|
@pytest.mark.skip(reason="Requires complete edge structure")
|
|
def test_voice_crossing_weights_no_crossing(self):
|
|
pass
|
|
|
|
def test_contrary_motion_weights(self):
|
|
edge = [
|
|
[
|
|
((0, 0, 0), (0, 1, 0)),
|
|
((0, 0, 0), (0, 2, 0)),
|
|
{
|
|
"transposition": (0, 0, 0),
|
|
"movements": {
|
|
(0, 0, 0): {"cent_difference": -100},
|
|
(0, 1, 0): {"cent_difference": 0},
|
|
(0, 2, 0): {"cent_difference": 100},
|
|
},
|
|
},
|
|
]
|
|
]
|
|
weights = list(cs.contrary_motion_weights(edge))
|
|
assert weights[0] == 10
|
|
|
|
|
|
if __name__ == "__main__":
|
|
pytest.main([__file__, "-v"])
|