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"])