amine@2: ''' amine@2: @author: Amine Sehili amine@2: September 2015 amine@2: amine@2: ''' amine@2: import unittest amine@2: amine@2: from auditok import BufferAudioSource amine@2: amine@2: amine@2: class TestBufferAudioSource_SR10_SW1_CH1(unittest.TestCase): amine@71: amine@2: def setUp(self): amine@2: self.signal = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345" amine@2: self.audio_source = BufferAudioSource(data_buffer=self.signal, amine@71: sampling_rate=10, sample_width=1, channels=1) amine@2: self.audio_source.open() amine@71: amine@2: def tearDown(self): amine@2: self.audio_source.close() amine@2: amine@2: def test_sr10_sw1_ch1_read_1(self): amine@71: amine@2: block = self.audio_source.read(1) amine@2: self.assertEqual(block, "A", msg="wrong block, expected: 'A', found: {0} ".format(block)) amine@71: amine@2: def test_sr10_sw1_ch1_read_6(self): amine@71: amine@2: block = self.audio_source.read(6) amine@2: self.assertEqual(block, "ABCDEF", msg="wrong block, expected: 'ABCDEF', found: {0} ".format(block)) amine@71: amine@2: def test_sr10_sw1_ch1_read_multiple(self): amine@71: amine@2: block = self.audio_source.read(1) amine@2: self.assertEqual(block, "A", msg="wrong block, expected: 'A', found: {0} ".format(block)) amine@71: amine@2: block = self.audio_source.read(6) amine@2: self.assertEqual(block, "BCDEFG", msg="wrong block, expected: 'BCDEFG', found: {0} ".format(block)) amine@71: amine@2: block = self.audio_source.read(13) amine@2: self.assertEqual(block, "HIJKLMNOPQRST", msg="wrong block, expected: 'HIJKLMNOPQRST', found: {0} ".format(block)) amine@71: amine@2: block = self.audio_source.read(9999) amine@2: self.assertEqual(block, "UVWXYZ012345", msg="wrong block, expected: 'UVWXYZ012345', found: {0} ".format(block)) amine@71: amine@2: def test_sr10_sw1_ch1_read_all(self): amine@2: block = self.audio_source.read(9999) amine@2: self.assertEqual(block, self.signal, msg="wrong block, expected: {0}, found: {1} ".format(self.signal, block)) amine@71: amine@2: block = self.audio_source.read(1) amine@2: self.assertEqual(block, None, msg="wrong block, expected: {0}, found: {1} ".format(None, block)) amine@71: amine@2: def test_sr10_sw1_ch1_get_sampling_rate(self): amine@71: amine@2: srate = self.audio_source.get_sampling_rate() amine@2: self.assertEqual(srate, 10, msg="wrong sampling rate, expected: 10, found: {0} ".format(srate)) amine@71: amine@2: def test_sr10_sw1_ch1_get_sample_width(self): amine@71: amine@2: swidth = self.audio_source.get_sample_width() amine@2: self.assertEqual(swidth, 1, msg="wrong sample width, expected: 1, found: {0} ".format(swidth)) amine@71: amine@2: def test_sr10_sw1_ch1_get_channels(self): amine@71: amine@2: channels = self.audio_source.get_channels() amine@2: self.assertEqual(channels, 1, msg="wrong number of channels, expected: 1, found: {0} ".format(channels)) amine@71: amine@2: def test_sr10_sw1_ch1_get_position_0(self): amine@71: amine@2: pos = self.audio_source.get_position() amine@2: self.assertEqual(pos, 0, msg="wrong position, expected: 0, found: {0} ".format(pos)) amine@71: amine@2: def test_sr10_sw1_ch1_get_position_5(self): amine@71: amine@2: self.audio_source.read(5) amine@2: pos = self.audio_source.get_position() amine@2: self.assertEqual(pos, 5, msg="wrong position, expected: 5, found: {0} ".format(pos)) amine@71: amine@2: def test_sr10_sw1_ch1_get_position_25(self): amine@71: amine@2: self.audio_source.read(5) amine@2: self.audio_source.read(20) amine@71: amine@2: pos = self.audio_source.get_position() amine@2: self.assertEqual(pos, 25, msg="wrong position, expected: 5, found: {0} ".format(pos)) amine@71: amine@2: def test_sr10_sw1_ch1_set_position_0(self): amine@71: amine@2: self.audio_source.read(10) amine@2: self.audio_source.set_position(0) amine@2: pos = self.audio_source.get_position() amine@2: self.assertEqual(pos, 0, msg="wrong position, expected: 0, found: {0} ".format(pos)) amine@71: amine@2: def test_sr10_sw1_ch1_set_position_10(self): amine@71: amine@2: self.audio_source.set_position(10) amine@2: pos = self.audio_source.get_position() amine@2: self.assertEqual(pos, 10, msg="wrong position, expected: 10, found: {0} ".format(pos)) amine@71: amine@2: def test_sr10_sw1_ch1_get_time_position_0(self): amine@71: amine@2: tp = self.audio_source.get_time_position() amine@2: self.assertEqual(tp, 0.0, msg="wrong time position, expected: 0.0, found: {0} ".format(tp)) amine@71: amine@2: def test_sr10_sw1_ch1_get_time_position_1(self): amine@71: amine@2: srate = self.audio_source.get_sampling_rate() amine@2: # read one second amine@2: self.audio_source.read(srate) amine@2: tp = self.audio_source.get_time_position() amine@2: self.assertEqual(tp, 1.0, msg="wrong time position, expected: 1.0, found: {0} ".format(tp)) amine@71: amine@2: def test_sr10_sw1_ch1_get_time_position_2_5(self): amine@71: amine@2: # read 2.5 seconds amine@2: self.audio_source.read(25) amine@2: tp = self.audio_source.get_time_position() amine@2: self.assertEqual(tp, 2.5, msg="wrong time position, expected: 2.5, found: {0} ".format(tp)) amine@71: amine@2: def test_sr10_sw1_ch1_set_time_position_0(self): amine@71: amine@2: self.audio_source.read(10) amine@2: self.audio_source.set_time_position(0) amine@2: tp = self.audio_source.get_time_position() amine@2: self.assertEqual(tp, 0.0, msg="wrong time position, expected: 0.0, found: {0} ".format(tp)) amine@71: amine@2: def test_sr10_sw1_ch1_set_time_position_1(self): amine@2: amine@2: self.audio_source.set_time_position(1) amine@2: tp = self.audio_source.get_time_position() amine@2: self.assertEqual(tp, 1.0, msg="wrong time position, expected: 1.0, found: {0} ".format(tp)) amine@71: amine@2: def test_sr10_sw1_ch1_set_time_position_end(self): amine@2: amine@2: self.audio_source.set_time_position(100) amine@2: tp = self.audio_source.get_time_position() amine@2: self.assertEqual(tp, 3.2, msg="wrong time position, expected: 3.2, found: {0} ".format(tp)) amine@71: amine@2: def test_sr10_sw1_ch1_rewind(self): amine@71: amine@2: self.audio_source.read(10) amine@2: self.audio_source.rewind() amine@2: tp = self.audio_source.get_position() amine@2: self.assertEqual(tp, 0, msg="wrong position, expected: 0.0, found: {0} ".format(tp)) amine@71: amine@2: def test_sr10_sw1_ch1_set_data(self): amine@2: self.audio_source.set_data("12345") amine@2: block = self.audio_source.read(9999) amine@2: self.assertEqual(block, "12345", msg="wrong block, expected: '12345', found: {0} ".format(block)) amine@71: amine@2: def test_sr10_sw1_ch1_read_closed(self): amine@2: self.audio_source.close() amine@2: with self.assertRaises(Exception): amine@2: self.audio_source.read(1) amine@71: amine@2: amine@2: class TestBufferAudioSource_SR16_SW2_CH1(unittest.TestCase): amine@71: amine@2: def setUp(self): amine@2: self.signal = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345" amine@2: self.audio_source = BufferAudioSource(data_buffer=self.signal, amine@71: sampling_rate=16, sample_width=2, channels=1) amine@2: self.audio_source.open() amine@71: amine@2: def tearDown(self): amine@2: self.audio_source.close() amine@2: amine@2: def test_sr16_sw2_ch1_read_1(self): amine@71: amine@2: block = self.audio_source.read(1) amine@2: self.assertEqual(block, "AB", msg="wrong block, expected: 'AB', found: {0} ".format(block)) amine@71: amine@2: def test_sr16_sw2_ch1_read_6(self): amine@71: amine@2: block = self.audio_source.read(6) amine@2: self.assertEqual(block, "ABCDEFGHIJKL", msg="wrong block, expected: 'ABCDEFGHIJKL', found: {0} ".format(block)) amine@71: amine@2: def test_sr16_sw2_ch1_read_multiple(self): amine@71: amine@2: block = self.audio_source.read(1) amine@2: self.assertEqual(block, "AB", msg="wrong block, expected: 'AB', found: {0} ".format(block)) amine@71: amine@2: block = self.audio_source.read(6) amine@2: self.assertEqual(block, "CDEFGHIJKLMN", msg="wrong block, expected: 'CDEFGHIJKLMN', found: {0} ".format(block)) amine@71: amine@2: block = self.audio_source.read(5) amine@2: self.assertEqual(block, "OPQRSTUVWX", msg="wrong block, expected: 'OPQRSTUVWX', found: {0} ".format(block)) amine@71: amine@2: block = self.audio_source.read(9999) amine@2: self.assertEqual(block, "YZ012345", msg="wrong block, expected: 'YZ012345', found: {0} ".format(block)) amine@71: amine@2: def test_sr16_sw2_ch1_read_all(self): amine@2: block = self.audio_source.read(9999) amine@2: self.assertEqual(block, self.signal, msg="wrong block, expected: {0}, found: {1} ".format(self.signal, block)) amine@71: amine@2: block = self.audio_source.read(1) amine@2: self.assertEqual(block, None, msg="wrong block, expected: {0}, found: {1} ".format(None, block)) amine@71: amine@2: def test_sr16_sw2_ch1_get_sampling_rate(self): amine@71: amine@2: srate = self.audio_source.get_sampling_rate() amine@2: self.assertEqual(srate, 16, msg="wrong sampling rate, expected: 10, found: {0} ".format(srate)) amine@71: amine@2: def test_sr16_sw2_ch1_get_sample_width(self): amine@71: amine@2: swidth = self.audio_source.get_sample_width() amine@2: self.assertEqual(swidth, 2, msg="wrong sample width, expected: 1, found: {0} ".format(swidth)) amine@71: amine@2: def test_sr16_sw2_ch1_get_channels(self): amine@71: amine@2: channels = self.audio_source.get_channels() amine@2: self.assertEqual(channels, 1, msg="wrong number of channels, expected: 1, found: {0} ".format(channels)) amine@71: amine@2: def test_sr16_sw2_ch1_get_position_0(self): amine@71: amine@2: pos = self.audio_source.get_position() amine@2: self.assertEqual(pos, 0, msg="wrong position, expected: 0, found: {0} ".format(pos)) amine@71: amine@2: def test_sr16_sw2_ch1_get_position_5(self): amine@71: amine@2: self.audio_source.read(5) amine@2: pos = self.audio_source.get_position() amine@2: self.assertEqual(pos, 5, msg="wrong position, expected: 5, found: {0} ".format(pos)) amine@71: amine@2: def test_sr16_sw2_ch1_get_position_15(self): amine@71: amine@2: self.audio_source.read(5) amine@2: self.audio_source.read(10) amine@71: amine@2: pos = self.audio_source.get_position() amine@2: self.assertEqual(pos, 15, msg="wrong position, expected: 5, found: {0} ".format(pos)) amine@71: amine@2: def test_sr16_sw2_ch1_set_position_0(self): amine@71: amine@2: self.audio_source.read(10) amine@2: self.audio_source.set_position(0) amine@2: pos = self.audio_source.get_position() amine@2: self.assertEqual(pos, 0, msg="wrong position, expected: 0, found: {0} ".format(pos)) amine@71: amine@2: def test_sr16_sw2_ch1_set_position_10(self): amine@71: amine@2: self.audio_source.set_position(10) amine@2: pos = self.audio_source.get_position() amine@2: self.assertEqual(pos, 10, msg="wrong position, expected: 10, found: {0} ".format(pos)) amine@71: amine@2: def test_sr16_sw2_ch1_get_time_position_0(self): amine@71: amine@2: tp = self.audio_source.get_time_position() amine@2: self.assertEqual(tp, 0.0, msg="wrong time position, expected: 0.0, found: {0} ".format(tp)) amine@71: amine@2: def test_sr16_sw2_ch1_get_time_position_1(self): amine@71: amine@2: srate = self.audio_source.get_sampling_rate() amine@2: # read one second amine@2: self.audio_source.read(srate) amine@2: tp = self.audio_source.get_time_position() amine@2: self.assertEqual(tp, 1.0, msg="wrong time position, expected: 1.0, found: {0} ".format(tp)) amine@71: amine@2: def test_sr16_sw2_ch1_get_time_position_0_75(self): amine@71: amine@2: # read 2.5 seconds amine@2: self.audio_source.read(12) amine@2: tp = self.audio_source.get_time_position() amine@2: self.assertEqual(tp, 0.75, msg="wrong time position, expected: 0.75, found: {0} ".format(tp)) amine@71: amine@2: def test_sr16_sw2_ch1_set_time_position_0(self): amine@71: amine@2: self.audio_source.read(10) amine@2: self.audio_source.set_time_position(0) amine@2: tp = self.audio_source.get_time_position() amine@2: self.assertEqual(tp, 0.0, msg="wrong time position, expected: 0.0, found: {0} ".format(tp)) amine@71: amine@2: def test_sr16_sw2_ch1_set_time_position_1(self): amine@2: amine@2: self.audio_source.set_time_position(1) amine@2: tp = self.audio_source.get_time_position() amine@2: self.assertEqual(tp, 1.0, msg="wrong time position, expected: 1.0, found: {0} ".format(tp)) amine@71: amine@2: def test_sr16_sw2_ch1_set_time_position_end(self): amine@2: amine@2: self.audio_source.set_time_position(100) amine@2: tp = self.audio_source.get_time_position() amine@2: self.assertEqual(tp, 1.0, msg="wrong time position, expected: 1.0, found: {0} ".format(tp)) amine@71: amine@2: def test_sr16_sw2_ch1_rewind(self): amine@71: amine@2: self.audio_source.read(10) amine@2: self.audio_source.rewind() amine@2: tp = self.audio_source.get_position() amine@2: self.assertEqual(tp, 0, msg="wrong position, expected: 0.0, found: {0} ".format(tp)) amine@71: amine@2: def test_sr16_sw2_ch1_set_data(self): amine@71: amine@2: self.audio_source.set_data("abcdef") amine@2: block = self.audio_source.read(9999) amine@2: self.assertEqual(block, "abcdef", msg="wrong block, expected: 'abcdef', found: {0} ".format(block)) amine@71: amine@2: def test_sr16_sw2_ch1_set_data_exception(self): amine@71: amine@2: with self.assertRaises(Exception): amine@2: self.assertRaises(ValueError, self.audio_source.set_data("abcde")) amine@71: amine@2: amine@2: class TestBufferAudioSource_SR11_SW4_CH1(unittest.TestCase): amine@71: amine@2: def setUp(self): amine@2: self.signal = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefgh" amine@2: self.audio_source = BufferAudioSource(data_buffer=self.signal, amine@71: sampling_rate=11, sample_width=4, channels=1) amine@2: self.audio_source.open() amine@71: amine@2: def tearDown(self): amine@2: self.audio_source.close() amine@2: amine@2: def test_sr11_sw4_ch1_read_1(self): amine@71: amine@2: block = self.audio_source.read(1) amine@2: self.assertEqual(block, "ABCD", msg="wrong block, expected: 'ABCD', found: {0} ".format(block)) amine@71: amine@2: def test_sr11_sw4_ch1_read_6(self): amine@71: amine@2: block = self.audio_source.read(6) amine@71: self.assertEqual(block, "ABCDEFGHIJKLMNOPQRSTUVWX", amine@71: msg="wrong block, expected: 'ABCDEFGHIJKLMNOPQRSTUVWX', found: {0} ".format(block)) amine@71: amine@2: def test_sr11_sw4_ch1_read_multiple(self): amine@71: amine@2: block = self.audio_source.read(1) amine@2: self.assertEqual(block, "ABCD", msg="wrong block, expected: 'AB', found: {0} ".format(block)) amine@71: amine@2: block = self.audio_source.read(6) amine@71: self.assertEqual(block, "EFGHIJKLMNOPQRSTUVWXYZ01", amine@71: msg="wrong block, expected: 'EFGHIJKLMNOPQRSTUVWXYZ01', found: {0} ".format(block)) amine@71: amine@2: block = self.audio_source.read(3) amine@2: self.assertEqual(block, "23456789abcd", msg="wrong block, expected: '23456789abcd', found: {0} ".format(block)) amine@71: amine@2: block = self.audio_source.read(9999) amine@2: self.assertEqual(block, "efgh", msg="wrong block, expected: 'efgh', found: {0} ".format(block)) amine@71: amine@2: def test_sr11_sw4_ch1_read_all(self): amine@2: block = self.audio_source.read(9999) amine@2: self.assertEqual(block, self.signal, msg="wrong block, expected: {0}, found: {1} ".format(self.signal, block)) amine@71: amine@2: block = self.audio_source.read(1) amine@2: self.assertEqual(block, None, msg="wrong block, expected: {0}, found: {1} ".format(None, block)) amine@71: amine@2: def test_sr11_sw4_ch1_get_sampling_rate(self): amine@71: amine@2: srate = self.audio_source.get_sampling_rate() amine@2: self.assertEqual(srate, 11, msg="wrong sampling rate, expected: 10, found: {0} ".format(srate)) amine@71: amine@2: def test_sr11_sw4_ch1_get_sample_width(self): amine@71: amine@2: swidth = self.audio_source.get_sample_width() amine@2: self.assertEqual(swidth, 4, msg="wrong sample width, expected: 1, found: {0} ".format(swidth)) amine@71: amine@2: def test_sr11_sw4_ch1_get_channels(self): amine@71: amine@2: channels = self.audio_source.get_channels() amine@2: self.assertEqual(channels, 1, msg="wrong number of channels, expected: 1, found: {0} ".format(channels)) amine@71: amine@2: def test_sr11_sw4_ch1_get_position_0(self): amine@71: amine@2: pos = self.audio_source.get_position() amine@2: self.assertEqual(pos, 0, msg="wrong position, expected: 0, found: {0} ".format(pos)) amine@71: amine@2: def test_sr11_sw4_ch1_get_position_5(self): amine@71: amine@2: self.audio_source.read(5) amine@2: pos = self.audio_source.get_position() amine@2: self.assertEqual(pos, 5, msg="wrong position, expected: 5, found: {0} ".format(pos)) amine@71: amine@2: def test_sr11_sw4_ch1_get_position_9(self): amine@71: amine@2: self.audio_source.read(5) amine@2: self.audio_source.read(4) amine@71: amine@2: pos = self.audio_source.get_position() amine@2: self.assertEqual(pos, 9, msg="wrong position, expected: 5, found: {0} ".format(pos)) amine@71: amine@2: def test_sr11_sw4_ch1_set_position_0(self): amine@71: amine@2: self.audio_source.read(10) amine@2: self.audio_source.set_position(0) amine@2: pos = self.audio_source.get_position() amine@2: self.assertEqual(pos, 0, msg="wrong position, expected: 0, found: {0} ".format(pos)) amine@71: amine@2: def test_sr11_sw4_ch1_set_position_10(self): amine@71: amine@2: self.audio_source.set_position(10) amine@2: pos = self.audio_source.get_position() amine@2: self.assertEqual(pos, 10, msg="wrong position, expected: 10, found: {0} ".format(pos)) amine@71: amine@2: def test_sr11_sw4_ch1_get_time_position_0(self): amine@71: amine@2: tp = self.audio_source.get_time_position() amine@2: self.assertEqual(tp, 0.0, msg="wrong time position, expected: 0.0, found: {0} ".format(tp)) amine@71: amine@2: def test_sr11_sw4_ch1_get_time_position_1(self): amine@71: amine@2: srate = self.audio_source.get_sampling_rate() amine@2: # read one second amine@2: self.audio_source.read(srate) amine@2: tp = self.audio_source.get_time_position() amine@2: self.assertEqual(tp, 1.0, msg="wrong time position, expected: 1.0, found: {0} ".format(tp)) amine@71: amine@2: def test_sr11_sw4_ch1_get_time_position_0_63(self): amine@71: amine@2: # read 2.5 seconds amine@2: self.audio_source.read(7) amine@2: tp = self.audio_source.get_time_position() amine@2: self.assertAlmostEqual(tp, 0.636363636364, msg="wrong time position, expected: 0.636363636364, found: {0} ".format(tp)) amine@71: amine@2: def test_sr11_sw4_ch1_set_time_position_0(self): amine@71: amine@2: self.audio_source.read(10) amine@2: self.audio_source.set_time_position(0) amine@2: tp = self.audio_source.get_time_position() amine@2: self.assertEqual(tp, 0.0, msg="wrong time position, expected: 0.0, found: {0} ".format(tp)) amine@71: amine@2: def test_sr11_sw4_ch1_set_time_position_1(self): amine@2: amine@2: self.audio_source.set_time_position(1) amine@2: tp = self.audio_source.get_time_position() amine@2: self.assertEqual(tp, 1.0, msg="wrong time position, expected: 1.0, found: {0} ".format(tp)) amine@71: amine@2: def test_sr11_sw4_ch1_set_time_position_end(self): amine@2: amine@2: self.audio_source.set_time_position(100) amine@2: tp = self.audio_source.get_time_position() amine@2: self.assertEqual(tp, 1.0, msg="wrong time position, expected: 1.0, found: {0} ".format(tp)) amine@71: amine@2: def test_sr11_sw4_ch1_rewind(self): amine@71: amine@2: self.audio_source.read(10) amine@2: self.audio_source.rewind() amine@2: tp = self.audio_source.get_position() amine@2: self.assertEqual(tp, 0, msg="wrong position, expected: 0.0, found: {0} ".format(tp)) amine@71: amine@2: def test_sr11_sw4_ch1_set_data(self): amine@71: amine@2: self.audio_source.set_data("abcdefgh") amine@2: block = self.audio_source.read(9999) amine@2: self.assertEqual(block, "abcdefgh", msg="wrong block, expected: 'abcdef', found: {0} ".format(block)) amine@71: amine@2: def test_sr11_sw4_ch1_set_data_exception(self): amine@71: amine@2: with self.assertRaises(Exception): amine@2: self.assertRaises(ValueError, self.audio_source.set_data("abcdef")) amine@71: amine@71: amine@71: class TestAudioSourceProperties(unittest.TestCase): amine@71: amine@71: def test_read_properties(self): amine@71: amine@71: data = "" amine@71: sampling_rate = 8000 amine@71: sample_width = 2 amine@71: channels = 1 amine@71: a_source = BufferAudioSource(data, sampling_rate, sample_width, channels) amine@71: amine@71: self.assertEqual(a_source.sampling_rate, sampling_rate) amine@71: self.assertEqual(a_source.sample_width, sample_width) amine@71: self.assertEqual(a_source.channels, channels) amine@71: amine@71: def test_set_readonly_properties_exception(self): amine@71: amine@71: data = "" amine@71: sampling_rate = 8000 amine@71: sample_width = 2 amine@71: channels = 1 amine@71: a_source = BufferAudioSource(data, sampling_rate, sample_width, channels) amine@71: amine@71: with self.assertRaises(AttributeError): amine@71: a_source.sampling_rate = 16000 amine@71: a_source.sample_width = 1 amine@71: a_source.channels = 2 amine@2: amine@2: amine@73: class TestAudioSourceShortProperties(unittest.TestCase): amine@73: amine@73: def test_read_short_properties(self): amine@73: amine@73: data = "" amine@73: sampling_rate = 8000 amine@73: sample_width = 2 amine@73: channels = 1 amine@73: a_source = BufferAudioSource(data, sampling_rate, sample_width, channels) amine@73: amine@73: self.assertEqual(a_source.sr, sampling_rate) amine@73: self.assertEqual(a_source.sw, sample_width) amine@73: self.assertEqual(a_source.ch, channels) amine@73: amine@73: def test_set_readonly_short_properties_exception(self): amine@73: amine@73: data = "" amine@73: sampling_rate = 8000 amine@73: sample_width = 2 amine@73: channels = 1 amine@73: a_source = BufferAudioSource(data, sampling_rate, sample_width, channels) amine@73: amine@73: with self.assertRaises(AttributeError): amine@73: a_source.sr = 16000 amine@73: a_source.sw = 1 amine@73: a_source.ch = 2 amine@73: amine@73: amine@2: if __name__ == "__main__": amine@2: unittest.main()