Coverage for tests/test_nendo_track.py: 99%

69 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-11-22 16:12 +0100

1# -*- encoding: utf-8 -*- 

2"""Tests for the Nendo Core class `NendoTrack`.""" 

3 

4import os 

5import unittest 

6import uuid 

7from unittest.mock import Mock 

8 

9import numpy as np 

10import sounddevice 

11 

12from nendo import Nendo, NendoConfig, NendoTrack 

13from nendo.schema.core import NendoRelationship, NendoResource 

14 

15nd = Nendo( 

16 config=NendoConfig( 

17 log_level="DEBUG", 

18 library_plugin="default", 

19 library_path="tests/library", 

20 ), 

21) 

22 

23 

24class NendoTrackTests(unittest.TestCase): 

25 """Unit test class for testing the NendoTrack class.""" 

26 

27 def test_has_relationship(self): 

28 """Test the `NendoTrack.has_relationship()` method.""" 

29 resource = NendoResource( 

30 file_path="tests/assets/", 

31 file_name="test.wav", 

32 resource_type="audio", 

33 meta={ 

34 "original_filename": os.path.basename("tests/assets/test.wav"), 

35 }, 

36 ) 

37 track = NendoTrack(id=uuid.uuid4(), user_id=uuid.uuid4(), resource=resource) 

38 

39 relationship = NendoRelationship( 

40 id=uuid.uuid4(), 

41 source_id=track.id, 

42 target_id=uuid.uuid4(), 

43 relationship_type="stem", 

44 meta={}, 

45 ) 

46 

47 track.related_tracks = [relationship] 

48 

49 self.assertTrue(track.has_relationship("stem")) 

50 self.assertFalse(track.has_relationship("outpainting")) 

51 

52 # def test_add_relationship(self): 

53 # resource = NendoResource( 

54 # file_path="tests/assets/", 

55 # file_name="test.wav", 

56 # resource_type="audio", 

57 # meta={ 

58 # "checksum": "file_checksum", 

59 # "original_filename": os.path.basename("tests/assets/test.wav"), 

60 # }, 

61 # ) 

62 # track = NendoTrack(id=uuid.uuid4(), user_id=uuid.uuid4(), resource=resource) 

63 

64 # track.add_relationship(track_id=uuid.uuid4(), relationship_type="stem") 

65 # self.assertTrue(track.has_relationship("stem")) 

66 

67 def test_signal_sr_properties_exist(self): 

68 """Test the `NendoTrack.signal` and `NendoTrack.sr` properties.""" 

69 nd.library.reset(force=True) 

70 track = nd.library.add_track(file_path="tests/assets/test.wav") 

71 self.assertEqual(track.signal.shape, (2, 2676096)) 

72 self.assertEqual(track.sr, 22050) 

73 

74 def test_overlay(self): 

75 """Test the `NendoTrack.overlay()` method.""" 

76 nd.library.reset(force=True) 

77 t1 = nd.library.add_track(file_path="tests/assets/test.wav") 

78 t2 = nd.library.add_track(file_path="tests/assets/test.mp3") 

79 

80 new_track = t1.overlay(t2) 

81 

82 self.assertIsNotNone(new_track) 

83 self.assertEqual(new_track.sr, t1.sr) 

84 self.assertEqual(new_track.signal.shape, t1.signal.shape) 

85 

86 def test_slice(self): 

87 """Test the `NendoTrack.slice()` method.""" 

88 nd.library.reset(force=True) 

89 t1 = nd.library.add_track(file_path="tests/assets/test.wav") 

90 

91 sliced_signal = t1.slice(start=0, end=10) 

92 

93 self.assertIsNotNone(sliced_signal) 

94 self.assertEqual(sliced_signal.shape, (2, 220500)) 

95 

96 def test_play(self): 

97 """Test the playback of `NendoTrack`s.""" 

98 nd.library.reset(force=True) 

99 sounddevice.play = Mock() 

100 sounddevice.wait = Mock() 

101 track = nd.library.add_track(file_path="tests/assets/test.wav") 

102 track.play() 

103 

104 sounddevice.play.assert_called_once() 

105 sounddevice.wait.assert_called_once() 

106 

107 # manually asserting call args because mock.assert_called_once_with() 

108 # doesn't work with numpy arrays 

109 np.testing.assert_array_equal(sounddevice.play.call_args[0][0], track.signal.T) 

110 self.assertEqual(sounddevice.play.call_args[1]["samplerate"], track.sr) 

111 self.assertEqual(sounddevice.play.call_args[1]["loop"], False) 

112 

113 def test_loop(self): 

114 """Test the looping of `NendoTrack`s.""" 

115 nd.library.reset(force=True) 

116 sounddevice.play = Mock() 

117 sounddevice.wait = Mock() 

118 track = nd.library.add_track(file_path="tests/assets/test.wav") 

119 track.loop() 

120 

121 sounddevice.play.assert_called_once() 

122 sounddevice.wait.assert_called_once() 

123 

124 # manually asserting call args because mock.assert_called_once_with() 

125 # doesn't work with numpy arrays 

126 np.testing.assert_array_equal(sounddevice.play.call_args[0][0], track.signal.T) 

127 self.assertEqual(sounddevice.play.call_args[1]["samplerate"], track.sr) 

128 self.assertEqual(sounddevice.play.call_args[1]["loop"], True) 

129 

130 def test_get_relationship_by_id(self): 

131 """Test the accessing of relationships of `NendoTrack`s by their id.""" 

132 resource = NendoResource( 

133 file_path="tests/assets/", 

134 file_name="test.wav", 

135 resource_type="audio", 

136 meta={ 

137 "original_filename": os.path.basename("tests/assets/test.wav"), 

138 }, 

139 ) 

140 track = NendoTrack(id=uuid.uuid4(), user_id=uuid.uuid4(), resource=resource) 

141 

142 relationship_1_id = uuid.uuid4() 

143 relationship_1 = NendoRelationship( 

144 id=uuid.uuid4(), 

145 source_id=track.id, 

146 target_id=relationship_1_id, 

147 relationship_type="stem", 

148 meta={}, 

149 ) 

150 

151 relationship_2_id = uuid.uuid4() 

152 relationship_2 = NendoRelationship( 

153 id=uuid.uuid4(), 

154 source_id=track.id, 

155 target_id=relationship_2_id, 

156 relationship_type="stem", 

157 meta={}, 

158 ) 

159 

160 track.related_tracks = [relationship_1, relationship_2] 

161 

162 

163if __name__ == "__main__": 

164 unittest.main()