1# -*- coding: utf-8 -*-
2
3import os
4
5from mutagen._compat import BytesIO
6from mutagen.oggopus import OggOpus, OggOpusInfo, delete, error
7from mutagen.ogg import OggPage
8from tests import TestCase, DATA_DIR, get_temp_copy
9from tests.test_ogg import TOggFileTypeMixin
10
11
12class TOggOpus(TestCase, TOggFileTypeMixin):
13    Kind = OggOpus
14
15    def setUp(self):
16        self.filename = get_temp_copy(os.path.join(DATA_DIR, "example.opus"))
17        self.audio = self.Kind(self.filename)
18
19    def tearDown(self):
20        os.unlink(self.filename)
21
22    def test_length(self):
23        self.failUnlessAlmostEqual(self.audio.info.length, 11.35, 2)
24
25    def test_misc(self):
26        self.failUnlessEqual(self.audio.info.channels, 1)
27        self.failUnless(self.audio.tags.vendor.startswith("libopus"))
28
29    def test_module_delete(self):
30        delete(self.filename)
31        self.scan_file()
32        self.failIf(self.Kind(self.filename).tags)
33
34    def test_mime(self):
35        self.failUnless("audio/ogg" in self.audio.mime)
36        self.failUnless("audio/ogg; codecs=opus" in self.audio.mime)
37
38    def test_invalid_not_first(self):
39        with open(self.filename, "rb") as h:
40            page = OggPage(h)
41        page.first = False
42        self.failUnlessRaises(error, OggOpusInfo, BytesIO(page.write()))
43
44    def test_unsupported_version(self):
45        with open(self.filename, "rb") as h:
46            page = OggPage(h)
47        data = bytearray(page.packets[0])
48
49        data[8] = 0x03
50        page.packets[0] = bytes(data)
51        OggOpusInfo(BytesIO(page.write()))
52
53        data[8] = 0x10
54        page.packets[0] = bytes(data)
55        self.failUnlessRaises(error, OggOpusInfo, BytesIO(page.write()))
56
57    def test_preserve_non_padding(self):
58        self.audio["FOO"] = ["BAR"]
59        self.audio.save()
60
61        extra_data = b"\xde\xad\xbe\xef"
62
63        with open(self.filename, "r+b") as fobj:
64            OggPage(fobj)  # header
65            page = OggPage(fobj)
66            data = OggPage.to_packets([page])[0]
67            data = data.rstrip(b"\x00") + b"\x01" + extra_data
68            new_pages = OggPage.from_packets([data], page.sequence)
69            OggPage.replace(fobj, [page], new_pages)
70
71        OggOpus(self.filename).save()
72
73        with open(self.filename, "rb") as fobj:
74            OggPage(fobj)  # header
75            page = OggPage(fobj)
76            data = OggPage.to_packets([page])[0]
77            self.assertTrue(data.endswith(b"\x01" + extra_data))
78
79        self.assertEqual(OggOpus(self.filename).tags._padding, 0)
80
81    def test_init_padding(self):
82        self.assertEqual(self.audio.tags._padding, 196)
83