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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
|
"""Unit tests for input/output functions"""
import numpy as np
import json
import mir_eval
import warnings
import pathlib
import tempfile
import pytest
def test_load_delimited():
# Test for ValueError when a non-string or file handle is passed
with pytest.raises(IOError):
mir_eval.io.load_delimited(None, [int])
# Test for a value error when the wrong number of columns is passed
with tempfile.TemporaryFile("r+") as f:
f.write("10 20")
f.seek(0)
with pytest.raises(ValueError):
mir_eval.io.load_delimited(f, [int, int, int])
# Test for a value error on conversion failure
with tempfile.TemporaryFile("r+") as f:
f.write("10 a 30")
f.seek(0)
with pytest.raises(ValueError):
mir_eval.io.load_delimited(f, [int, int, int])
def test_load_delimited_commented():
with tempfile.TemporaryFile("r+") as f:
f.write("; some comment\n10 20\n30 50")
f.seek(0)
col1, col2 = mir_eval.io.load_delimited(f, [int, int], comment=";")
assert np.allclose(col1, [10, 30])
assert np.allclose(col2, [20, 50])
# Rewind and try with the default comment character
f.seek(0)
with pytest.raises(ValueError):
mir_eval.io.load_delimited(f, [int, int])
# Rewind and try with no comment support
f.seek(0)
with pytest.raises(ValueError):
mir_eval.io.load_delimited(f, [int, int], comment=None)
def test_load_delimited_nocomment():
with tempfile.TemporaryFile("r+") as f:
f.write("10 20\n30 50")
f.seek(0)
col1, col2 = mir_eval.io.load_delimited(f, [int, int])
assert np.allclose(col1, [10, 30])
assert np.allclose(col2, [20, 50])
# Rewind and try with a different comment char
f.seek(0)
col1, col2 = mir_eval.io.load_delimited(f, [int, int], comment=";")
assert np.allclose(col1, [10, 30])
assert np.allclose(col2, [20, 50])
# Rewind and try with no different comment string
f.seek(0)
col1, col2 = mir_eval.io.load_delimited(f, [int, int], comment=None)
assert np.allclose(col1, [10, 30])
assert np.allclose(col2, [20, 50])
@pytest.mark.parametrize(
"file_or_path", ["data/beat/ref01.txt", pathlib.Path("data/beat/ref01.txt")]
)
def test_load_delimited_file_or_path(file_or_path):
# Tests the load_delimited routine with either a string or a
# pathlib.Path object as the first argument
data = mir_eval.io.load_delimited(file_or_path, [float])
assert len(data) == 635
def test_load_events():
# Test for a warning when invalid events are supplied
with tempfile.TemporaryFile("r+") as f:
with pytest.warns(UserWarning, match="Events should be in increasing order."):
# Non-increasing is invalid
f.write("10\n9")
f.seek(0)
events = mir_eval.io.load_events(f)
# Make sure events were read in correctly
assert np.all(events == [10, 9])
def test_load_labeled_events():
# Test for a value error when invalid labeled events are supplied
with tempfile.TemporaryFile("r+") as f:
with pytest.warns(UserWarning, match="Events should be in increasing order."):
# Non-increasing is invalid
f.write("10 a\n9 b")
f.seek(0)
events, labels = mir_eval.io.load_labeled_events(f)
# Make sure events were read in correctly
assert np.all(events == [10, 9])
# Make sure labels were read in correctly
assert labels == ["a", "b"]
def test_load_intervals():
# Test for a value error when invalid labeled events are supplied
with tempfile.TemporaryFile("r+") as f:
with pytest.warns(
UserWarning, match="All interval durations must be strictly positive"
):
# Non-increasing is invalid
f.write("10 9\n9 10")
f.seek(0)
intervals = mir_eval.io.load_intervals(f)
# Make sure intervals were read in correctly
assert np.all(intervals == [[10, 9], [9, 10]])
def test_load_labeled_intervals():
# Test for a value error when invalid labeled events are supplied
with tempfile.TemporaryFile("r+") as f:
with pytest.warns(
UserWarning, match="All interval durations must be strictly positive"
):
# Non-increasing is invalid
f.write("10 9 a\n9 10 b")
f.seek(0)
intervals, labels = mir_eval.io.load_labeled_intervals(f)
# Make sure intervals were read in correctly
assert np.all(intervals == [[10, 9], [9, 10]])
assert labels == ["a", "b"]
def test_load_valued_intervals():
# Test for a value error when invalid valued events are supplied
with tempfile.TemporaryFile("r+") as f:
with pytest.warns(
UserWarning, match="All interval durations must be strictly positive"
):
# Non-increasing is invalid
f.write("10 9 5\n9 10 6")
f.seek(0)
intervals, values = mir_eval.io.load_valued_intervals(f)
# Make sure intervals were read in correctly
assert np.all(intervals == [[10, 9], [9, 10]])
assert np.all(values == [5, 6])
def test_load_ragged_time_series():
# Test for ValueError when a non-string or file handle is passed
with pytest.raises(IOError):
mir_eval.io.load_ragged_time_series(None, float, header=False)
# Test for a value error on conversion failure
with tempfile.TemporaryFile("r+") as f:
f.write("10 a 30")
f.seek(0)
with pytest.raises(ValueError):
mir_eval.io.load_ragged_time_series(f, float, header=False)
# Test for a value error on invalid time stamp
with tempfile.TemporaryFile("r+") as f:
f.write("a 10 30")
f.seek(0)
with pytest.raises(ValueError):
mir_eval.io.load_ragged_time_series(f, int, header=False)
# Test for a value error on invalid time stamp with header
with tempfile.TemporaryFile("r+") as f:
f.write("x y z\na 10 30")
f.seek(0)
with pytest.raises(ValueError):
mir_eval.io.load_ragged_time_series(f, int, header=True)
with tempfile.TemporaryFile("r+") as f:
f.write("#comment\n0 1 2\n3 4\n# comment\n5 6 7")
f.seek(0)
times, values = mir_eval.io.load_ragged_time_series(
f, int, header=False, comment="#"
)
assert np.allclose(times, [0, 3, 5])
assert np.allclose(values[0], [1, 2])
assert np.allclose(values[1], [4])
assert np.allclose(values[2], [6, 7])
# Rewind with a wrong comment string
f.seek(0)
with pytest.raises(ValueError):
mir_eval.io.load_ragged_time_series(f, int, header=False, comment="%")
# Rewind with no comment string
f.seek(0)
with pytest.raises(ValueError):
mir_eval.io.load_ragged_time_series(f, int, header=False, comment=None)
def test_load_tempo():
# Test the tempo loader
tempi, weight = mir_eval.io.load_tempo("data/tempo/ref01.lab")
assert np.allclose(tempi, [60, 120])
assert weight == 0.5
@pytest.mark.xfail(raises=ValueError)
def test_load_tempo_multiline():
tempi, weight = mir_eval.io.load_tempo("data/tempo/bad00.lab")
@pytest.mark.xfail(raises=ValueError)
def test_load_tempo_badweight():
tempi, weight = mir_eval.io.load_tempo("data/tempo/bad01.lab")
def test_load_bad_tempi():
with pytest.warns(UserWarning, match="non-negative numbers"):
tempi, weight = mir_eval.io.load_tempo("data/tempo/bad02.lab")
|