#!/usr/bin/env python3
# friendly.py
# https://github.com/Jelmerro/stagger
#
# Copyright (c) 2022-2022 <NAME>
# Copyright (c) 2009-2011 <NAME>  <<EMAIL>>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
#   notice, this list of conditions and the following disclaimer.
#
# - Redistributions in binary form must reproduce the above copyright
#   notice, this list of conditions and the following disclaimer in
#   the documentation and/or other materials provided with the
#   distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

import unittest
import os.path
import warnings

from stagger.tags import Tag22, Tag23, Tag24
from stagger.id3 import TT2, TIT1, TIT2, TPE1, TPE2, TALB, TCOM, TCON, TSOT
from stagger.id3 import TSOP, TSO2, TSOA, TSOC, TRCK, TPOS, TYE, TDA, TIM, TYER
from stagger.id3 import TDAT, TIME, TDRC, PIC, APIC, COM, COMM
from stagger.errors import Warning


class FriendlyTestCase(unittest.TestCase):
    def testTitle22(self):
        tag = Tag22()

        tag[TT2] = "Foobar"
        self.assertEqual(tag.title, "Foobar")

        tag[TT2] = ("Foo", "Bar")
        self.assertEqual(tag.title, "Foo / Bar")

        tag.title = "Baz"
        self.assertEqual(tag[TT2], TT2(text=["Baz"]))
        self.assertEqual(tag.title, "Baz")

        tag.title = "Quux / Xyzzy"
        self.assertEqual(tag[TT2], TT2(text=["Quux", "Xyzzy"]))
        self.assertEqual(tag.title, "Quux / Xyzzy")

    def testTitle(self):
        for tagcls in Tag23, Tag24:
            tag = tagcls()

            tag[TIT2] = "Foobar"
            self.assertEqual(tag.title, "Foobar")

            tag[TIT2] = ("Foo", "Bar")
            self.assertEqual(tag.title, "Foo / Bar")

            tag.title = "Baz"
            self.assertEqual(tag[TIT2], TIT2(text=["Baz"]))
            self.assertEqual(tag.title, "Baz")

            tag.title = "Quux / Xyzzy"
            self.assertEqual(tag[TIT2], TIT2(text=["Quux", "Xyzzy"]))
            self.assertEqual(tag.title, "Quux / Xyzzy")

    def testTextFrames(self):
        for tagcls in Tag22, Tag23, Tag24:
            tag = tagcls()

            for attr, frame in (("title", TIT2),
                                ("artist", TPE1),
                                ("album_artist", TPE2),
                                ("album", TALB),
                                ("composer", TCOM),
                                ("genre", TCON),
                                ("grouping", TIT1),
                                ("sort_title", TSOT),
                                ("sort_artist", TSOP),
                                ("sort_album_artist", TSO2),
                                ("sort_album", TSOA),
                                ("sort_composer", TSOC)):
                if tagcls == Tag22:
                    frame = frame._v2_frame

                # No frame -> empty string
                self.assertEqual(getattr(tag, attr), "")

                # Set by frameid, check via friendly name
                tag[frame] = "Foobar"
                self.assertEqual(getattr(tag, attr), "Foobar")

                tag[frame] = ("Foo", "Bar")
                self.assertEqual(getattr(tag, attr), "Foo / Bar")

                # Set by friendly name, check via frame id
                setattr(tag, attr, "Baz")
                self.assertEqual(getattr(tag, attr), "Baz")
                self.assertEqual(tag[frame], frame(text=["Baz"]))

                setattr(tag, attr, "Quux / Xyzzy")
                self.assertEqual(getattr(tag, attr), "Quux / Xyzzy")
                self.assertEqual(tag[frame], frame(text=["Quux", "Xyzzy"]))

                # Set to empty string, check frame is gone
                setattr(tag, attr, "")
                self.assertTrue(frame not in tag)

                # Repeat, should not throw KeyError
                setattr(tag, attr, "")
                self.assertTrue(frame not in tag)

    def testTrackFrames(self):
        for tagcls in Tag22, Tag23, Tag24:
            tag = tagcls()
            for track, total, frame in (("track", "track_total", TRCK),
                                        ("disc", "disc_total", TPOS)):
                if tagcls == Tag22:
                    frame = frame._v2_frame

                # No frame -> zero values
                self.assertEqual(getattr(tag, track), 0)
                self.assertEqual(getattr(tag, total), 0)

                # Set by frameid, check via friendly name
                tag[frame] = "12"
                self.assertEqual(getattr(tag, track), 12)
                self.assertEqual(getattr(tag, total), 0)

                tag[frame] = "12/24"
                self.assertEqual(getattr(tag, track), 12)
                self.assertEqual(getattr(tag, total), 24)

                tag[frame] = "Foobar"
                self.assertEqual(getattr(tag, track), 0)
                self.assertEqual(getattr(tag, total), 0)

                # Set by friendly name, check via frame id
                setattr(tag, track, 7)
                self.assertEqual(getattr(tag, track), 7)
                self.assertEqual(getattr(tag, total), 0)
                self.assertEqual(tag[frame], frame(text=["7"]))

                setattr(tag, total, 21)
                self.assertEqual(getattr(tag, track), 7)
                self.assertEqual(getattr(tag, total), 21)
                self.assertEqual(tag[frame], frame(text=["7/21"]))

                # Set to 0/0, check frame is gone
                setattr(tag, total, 0)
                self.assertEqual(getattr(tag, track), 7)
                self.assertEqual(getattr(tag, total), 0)
                self.assertEqual(tag[frame], frame(text=["7"]))

                setattr(tag, track, 0)
                self.assertEqual(getattr(tag, track), 0)
                self.assertEqual(getattr(tag, total), 0)
                self.assertTrue(frame not in tag)

                # Repeat, should not throw
                setattr(tag, track, 0)
                setattr(tag, total, 0)
                self.assertTrue(frame not in tag)

                # Set just the total
                setattr(tag, total, 13)
                self.assertEqual(tag[frame], frame(text=["0/13"]))

    def testDate22_23(self):
        for tagcls, yearframe, dateframe, timeframe in (
            (Tag22, TYE, TDA, TIM), (Tag23, TYER, TDAT, TIME)
        ):
            tag = tagcls()

            # Check empty
            self.assertEqual(tag.date, "")

            # Set to empty
            tag.date = ""
            self.assertEqual(tag.date, "")

            # Set a year
            tag.date = "2009"
            self.assertEqual(tag.date, "2009")
            tag.date = "   2009    "
            self.assertEqual(tag.date, "2009")
            self.assertEqual(tag[yearframe], yearframe("2009"))
            self.assertTrue(dateframe not in tag)
            self.assertTrue(timeframe not in tag)

            # Partial date
            tag.date = "2009-07"
            self.assertEqual(tag.date, "2009")
            self.assertEqual(tag[yearframe], yearframe("2009"))
            self.assertTrue(dateframe not in tag)
            self.assertTrue(timeframe not in tag)

            # Full date
            tag.date = "2009-07-12"
            self.assertEqual(tag.date, "2009-07-12")
            self.assertEqual(tag[yearframe], yearframe("2009"))
            self.assertEqual(tag[dateframe], dateframe("0712"))
            self.assertTrue(timeframe not in tag)

            # Date + time
            tag.date = "2009-07-12 18:01"
            self.assertEqual(tag.date, "2009-07-12 18:01")
            self.assertEqual(tag[yearframe], yearframe("2009"))
            self.assertEqual(tag[dateframe], dateframe("0712"))
            self.assertEqual(tag[timeframe], timeframe("1801"))

            tag.date = "2009-07-12 18:01:23"
            self.assertEqual(tag.date, "2009-07-12 18:01")
            self.assertEqual(tag[yearframe], yearframe("2009"))
            self.assertEqual(tag[dateframe], dateframe("0712"))
            self.assertEqual(tag[timeframe], timeframe("1801"))

            tag.date = "2009-07-12T18:01:23"
            self.assertEqual(tag.date, "2009-07-12 18:01")
            self.assertEqual(tag[yearframe], yearframe("2009"))
            self.assertEqual(tag[dateframe], dateframe("0712"))
            self.assertEqual(tag[timeframe], timeframe("1801"))

            # Truncate to year only
            tag.date = "2009"
            self.assertEqual(tag[yearframe], yearframe("2009"))
            self.assertTrue(dateframe not in tag)
            self.assertTrue(timeframe not in tag)

    def testDate24(self):
        tag = Tag24()

        # Check empty
        self.assertEqual(tag.date, "")

        # Set to empty
        tag.date = ""
        self.assertEqual(tag.date, "")

        # Set a year
        tag.date = "2009"
        self.assertEqual(tag.date, "2009")
        self.assertEqual(tag[TDRC], TDRC(tag.date))
        tag.date = "   2009    "
        self.assertEqual(tag.date, "2009")
        self.assertEqual(tag[TDRC], TDRC(tag.date))

        tag.date = "2009-07"
        self.assertEqual(tag.date, "2009-07")
        self.assertEqual(tag[TDRC], TDRC(tag.date))
        tag.date = "2009-07-12"
        self.assertEqual(tag.date, "2009-07-12")
        self.assertEqual(tag[TDRC], TDRC(tag.date))

        tag.date = "2009-07-12 18:01"
        self.assertEqual(tag.date, "2009-07-12 18:01")
        self.assertEqual(tag[TDRC], TDRC(tag.date))

        tag.date = "2009-07-12 18:01:23"
        self.assertEqual(tag.date, "2009-07-12 18:01:23")
        self.assertEqual(tag[TDRC], TDRC(tag.date))

        tag.date = "2009-07-12T18:01:23"
        self.assertEqual(tag.date, "2009-07-12 18:01:23")
        self.assertEqual(tag[TDRC], TDRC(tag.date))

    def testPicture22(self):
        tag = Tag22()

        # Check empty
        self.assertEqual(tag.picture, "")

        # Set to empty
        tag.picture = ""
        self.assertEqual(tag.picture, "")
        self.assertTrue(PIC not in tag)

        tag.picture = os.path.join(os.path.dirname(
            __file__), "samples", "cover.jpg")
        self.assertEqual(tag[PIC][0].type, 0)
        self.assertEqual(tag[PIC][0].desc, "")
        self.assertEqual(tag[PIC][0].format, "JPG")
        self.assertEqual(len(tag[PIC][0].data), 60511)
        self.assertEqual(tag.picture, "Other(0)::<60511 bytes of jpeg data>")

        # Set to empty
        tag.picture = ""
        self.assertEqual(tag.picture, "")
        self.assertTrue(PIC not in tag)

    def testPicture23_24(self):
        for tagcls in Tag23, Tag24:
            tag = tagcls()

            # Check empty
            self.assertEqual(tag.picture, "")

            # Set to empty
            tag.picture = ""
            self.assertEqual(tag.picture, "")
            self.assertTrue(APIC not in tag)

            # Set picture.
            tag.picture = os.path.join(os.path.dirname(
                __file__), "samples", "cover.jpg")
            self.assertEqual(tag[APIC][0].type, 0)
            self.assertEqual(tag[APIC][0].desc, "")
            self.assertEqual(tag[APIC][0].mime, "image/jpeg")
            self.assertEqual(len(tag[APIC][0].data), 60511)
            self.assertEqual(
                tag.picture, "Other(0)::<60511 bytes of jpeg data>")

            # Set to empty
            tag.picture = ""
            self.assertEqual(tag.picture, "")
            self.assertTrue(APIC not in tag)

    def testComment(self):
        for tagcls, frameid in ((Tag22, COM), (Tag23, COMM), (Tag24, COMM)):
            tag = tagcls()

            # Comment should be the empty string in an empty tag.
            self.assertEqual(tag.comment, "")

            # Try to delete non-existent comment.
            tag.comment = ""
            self.assertEqual(tag.comment, "")
            self.assertTrue(frameid not in tag)

            # Set comment.
            tag.comment = "Foobar"
            self.assertEqual(tag.comment, "Foobar")
            self.assertTrue(frameid in tag)
            self.assertEqual(len(tag[frameid]), 1)
            self.assertEqual(tag[frameid][0].lang, "eng")
            self.assertEqual(tag[frameid][0].desc, "")
            self.assertEqual(tag[frameid][0].text, "Foobar")

            # Override comment.
            tag.comment = "Baz"
            self.assertEqual(tag.comment, "Baz")
            self.assertTrue(frameid in tag)
            self.assertEqual(len(tag[frameid]), 1)
            self.assertEqual(tag[frameid][0].lang, "eng")
            self.assertEqual(tag[frameid][0].desc, "")
            self.assertEqual(tag[frameid][0].text, "Baz")

            # Delete comment.
            tag.comment = ""
            self.assertEqual(tag.comment, "")
            self.assertTrue(frameid not in tag)

    def testCommentWithExtraFrame(self):
        "Test getting/setting the comment when other comments are present."

        for tagcls, frameid in ((Tag22, COM), (Tag23, COMM), (Tag24, COMM)):
            tag = tagcls()
            frame = frameid(lan="eng", desc="foo", text="This is a text")
            tag[frameid] = [frame]

            # Comment should be the empty string.
            self.assertEqual(tag.comment, "")

            # Try to delete non-existent comment.
            tag.comment = ""
            self.assertEqual(tag.comment, "")
            self.assertEqual(len(tag[frameid]), 1)

            # Set comment.
            tag.comment = "Foobar"
            self.assertEqual(tag.comment, "Foobar")
            self.assertEqual(len(tag[frameid]), 2)
            self.assertEqual(tag[frameid][0], frame)
            self.assertEqual(tag[frameid][1].lang, "eng")
            self.assertEqual(tag[frameid][1].desc, "")
            self.assertEqual(tag[frameid][1].text, "Foobar")

            # Override comment.
            tag.comment = "Baz"
            self.assertEqual(tag.comment, "Baz")
            self.assertEqual(len(tag[frameid]), 2)
            self.assertEqual(tag[frameid][0], frame)
            self.assertEqual(tag[frameid][1].lang, "eng")
            self.assertEqual(tag[frameid][1].desc, "")
            self.assertEqual(tag[frameid][1].text, "Baz")

            # Delete comment.
            tag.comment = ""
            self.assertEqual(tag.comment, "")
            self.assertEqual(len(tag[frameid]), 1)
            self.assertEqual(tag[frameid][0], frame)


suite = unittest.TestLoader().loadTestsFromTestCase(FriendlyTestCase)

if __name__ == "__main__":
    warnings.simplefilter("always", Warning)
    unittest.main(defaultTest="suite")

#!/usr/bin/env python3
# friendly.py
# https://github.com/Jelmerro/stagger
#
# Copyright (c) 2022-2022 <NAME>
# Copyright (c) 2009-2011 <NAME>  <<EMAIL>>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
#   notice, this list of conditions and the following disclaimer.
#
# - Redistributions in binary form must reproduce the above copyright
#   notice, this list of conditions and the following disclaimer in
#   the documentation and/or other materials provided with the
#   distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

import unittest
import os.path
import warnings

from stagger.tags import Tag22, Tag23, Tag24
from stagger.id3 import TT2, TIT1, TIT2, TPE1, TPE2, TALB, TCOM, TCON, TSOT
from stagger.id3 import TSOP, TSO2, TSOA, TSOC, TRCK, TPOS, TYE, TDA, TIM, TYER
from stagger.id3 import TDAT, TIME, TDRC, PIC, APIC, COM, COMM
from stagger.errors import Warning


class FriendlyTestCase(unittest.TestCase):
    def testTitle22(self):
        tag = Tag22()

        tag[TT2] = "Foobar"
        self.assertEqual(tag.title, "Foobar")

        tag[TT2] = ("Foo", "Bar")
        self.assertEqual(tag.title, "Foo / Bar")

        tag.title = "Baz"
        self.assertEqual(tag[TT2], TT2(text=["Baz"]))
        self.assertEqual(tag.title, "Baz")

        tag.title = "Quux / Xyzzy"
        self.assertEqual(tag[TT2], TT2(text=["Quux", "Xyzzy"]))
        self.assertEqual(tag.title, "Quux / Xyzzy")

    def testTitle(self):
        for tagcls in Tag23, Tag24:
            tag = tagcls()

            tag[TIT2] = "Foobar"
            self.assertEqual(tag.title, "Foobar")

            tag[TIT2] = ("Foo", "Bar")
            self.assertEqual(tag.title, "Foo / Bar")

            tag.title = "Baz"
            self.assertEqual(tag[TIT2], TIT2(text=["Baz"]))
            self.assertEqual(tag.title, "Baz")

            tag.title = "Quux / Xyzzy"
            self.assertEqual(tag[TIT2], TIT2(text=["Quux", "Xyzzy"]))
            self.assertEqual(tag.title, "Quux / Xyzzy")

    def testTextFrames(self):
        for tagcls in Tag22, Tag23, Tag24:
            tag = tagcls()

            for attr, frame in (("title", TIT2),
                                ("artist", TPE1),
                                ("album_artist", TPE2),
                                ("album", TALB),
                                ("composer", TCOM),
                                ("genre", TCON),
                                ("grouping", TIT1),
                                ("sort_title", TSOT),
                                ("sort_artist", TSOP),
                                ("sort_album_artist", TSO2),
                                ("sort_album", TSOA),
                                ("sort_composer", TSOC)):
                if tagcls == Tag22:
                    frame = frame._v2_frame

                # No frame -> empty string
                self.assertEqual(getattr(tag, attr), "")

                # Set by frameid, check via friendly name
                tag[frame] = "Foobar"
                self.assertEqual(getattr(tag, attr), "Foobar")

                tag[frame] = ("Foo", "Bar")
                self.assertEqual(getattr(tag, attr), "Foo / Bar")

                # Set by friendly name, check via frame id
                setattr(tag, attr, "Baz")
                self.assertEqual(getattr(tag, attr), "Baz")
                self.assertEqual(tag[frame], frame(text=["Baz"]))

                setattr(tag, attr, "Quux / Xyzzy")
                self.assertEqual(getattr(tag, attr), "Quux / Xyzzy")
                self.assertEqual(tag[frame], frame(text=["Quux", "Xyzzy"]))

                # Set to empty string, check frame is gone
                setattr(tag, attr, "")
                self.assertTrue(frame not in tag)

                # Repeat, should not throw KeyError
                setattr(tag, attr, "")
                self.assertTrue(frame not in tag)

    def testTrackFrames(self):
        for tagcls in Tag22, Tag23, Tag24:
            tag = tagcls()
            for track, total, frame in (("track", "track_total", TRCK),
                                        ("disc", "disc_total", TPOS)):
                if tagcls == Tag22:
                    frame = frame._v2_frame

                # No frame -> zero values
                self.assertEqual(getattr(tag, track), 0)
                self.assertEqual(getattr(tag, total), 0)

                # Set by frameid, check via friendly name
                tag[frame] = "12"
                self.assertEqual(getattr(tag, track), 12)
                self.assertEqual(getattr(tag, total), 0)

                tag[frame] = "12/24"
                self.assertEqual(getattr(tag, track), 12)
                self.assertEqual(getattr(tag, total), 24)

                tag[frame] = "Foobar"
                self.assertEqual(getattr(tag, track), 0)
                self.assertEqual(getattr(tag, total), 0)

                # Set by friendly name, check via frame id
                setattr(tag, track, 7)
                self.assertEqual(getattr(tag, track), 7)
                self.assertEqual(getattr(tag, total), 0)
                self.assertEqual(tag[frame], frame(text=["7"]))

                setattr(tag, total, 21)
                self.assertEqual(getattr(tag, track), 7)
                self.assertEqual(getattr(tag, total), 21)
                self.assertEqual(tag[frame], frame(text=["7/21"]))

                # Set to 0/0, check frame is gone
                setattr(tag, total, 0)
                self.assertEqual(getattr(tag, track), 7)
                self.assertEqual(getattr(tag, total), 0)
                self.assertEqual(tag[frame], frame(text=["7"]))

                setattr(tag, track, 0)
                self.assertEqual(getattr(tag, track), 0)
                self.assertEqual(getattr(tag, total), 0)
                self.assertTrue(frame not in tag)

                # Repeat, should not throw
                setattr(tag, track, 0)
                setattr(tag, total, 0)
                self.assertTrue(frame not in tag)

                # Set just the total
                setattr(tag, total, 13)
                self.assertEqual(tag[frame], frame(text=["0/13"]))

    def testDate22_23(self):
        for tagcls, yearframe, dateframe, timeframe in (
            (Tag22, TYE, TDA, TIM), (Tag23, TYER, TDAT, TIME)
        ):
            tag = tagcls()

            # Check empty
            self.assertEqual(tag.date, "")

            # Set to empty
            tag.date = ""
            self.assertEqual(tag.date, "")

            # Set a year
            tag.date = "2009"
            self.assertEqual(tag.date, "2009")
            tag.date = "   2009    "
            self.assertEqual(tag.date, "2009")
            self.assertEqual(tag[yearframe], yearframe("2009"))
            self.assertTrue(dateframe not in tag)
            self.assertTrue(timeframe not in tag)

            # Partial date
            tag.date = "2009-07"
            self.assertEqual(tag.date, "2009")
            self.assertEqual(tag[yearframe], yearframe("2009"))
            self.assertTrue(dateframe not in tag)
            self.assertTrue(timeframe not in tag)

            # Full date
            tag.date = "2009-07-12"
            self.assertEqual(tag.date, "2009-07-12")
            self.assertEqual(tag[yearframe], yearframe("2009"))
            self.assertEqual(tag[dateframe], dateframe("0712"))
            self.assertTrue(timeframe not in tag)

            # Date + time
            tag.date = "2009-07-12 18:01"
            self.assertEqual(tag.date, "2009-07-12 18:01")
            self.assertEqual(tag[yearframe], yearframe("2009"))
            self.assertEqual(tag[dateframe], dateframe("0712"))
            self.assertEqual(tag[timeframe], timeframe("1801"))

            tag.date = "2009-07-12 18:01:23"
            self.assertEqual(tag.date, "2009-07-12 18:01")
            self.assertEqual(tag[yearframe], yearframe("2009"))
            self.assertEqual(tag[dateframe], dateframe("0712"))
            self.assertEqual(tag[timeframe], timeframe("1801"))

            tag.date = "2009-07-12T18:01:23"
            self.assertEqual(tag.date, "2009-07-12 18:01")
            self.assertEqual(tag[yearframe], yearframe("2009"))
            self.assertEqual(tag[dateframe], dateframe("0712"))
            self.assertEqual(tag[timeframe], timeframe("1801"))

            # Truncate to year only
            tag.date = "2009"
            self.assertEqual(tag[yearframe], yearframe("2009"))
            self.assertTrue(dateframe not in tag)
            self.assertTrue(timeframe not in tag)

    def testDate24(self):
        tag = Tag24()

        # Check empty
        self.assertEqual(tag.date, "")

        # Set to empty
        tag.date = ""
        self.assertEqual(tag.date, "")

        # Set a year
        tag.date = "2009"
        self.assertEqual(tag.date, "2009")
        self.assertEqual(tag[TDRC], TDRC(tag.date))
        tag.date = "   2009    "
        self.assertEqual(tag.date, "2009")
        self.assertEqual(tag[TDRC], TDRC(tag.date))

        tag.date = "2009-07"
        self.assertEqual(tag.date, "2009-07")
        self.assertEqual(tag[TDRC], TDRC(tag.date))
        tag.date = "2009-07-12"
        self.assertEqual(tag.date, "2009-07-12")
        self.assertEqual(tag[TDRC], TDRC(tag.date))

        tag.date = "2009-07-12 18:01"
        self.assertEqual(tag.date, "2009-07-12 18:01")
        self.assertEqual(tag[TDRC], TDRC(tag.date))

        tag.date = "2009-07-12 18:01:23"
        self.assertEqual(tag.date, "2009-07-12 18:01:23")
        self.assertEqual(tag[TDRC], TDRC(tag.date))

        tag.date = "2009-07-12T18:01:23"
        self.assertEqual(tag.date, "2009-07-12 18:01:23")
        self.assertEqual(tag[TDRC], TDRC(tag.date))

    def testPicture22(self):
        tag = Tag22()

        # Check empty
        self.assertEqual(tag.picture, "")

        # Set to empty
        tag.picture = ""
        self.assertEqual(tag.picture, "")
        self.assertTrue(PIC not in tag)

        tag.picture = os.path.join(os.path.dirname(
            __file__), "samples", "cover.jpg")
        self.assertEqual(tag[PIC][0].type, 0)
        self.assertEqual(tag[PIC][0].desc, "")
        self.assertEqual(tag[PIC][0].format, "JPG")
        self.assertEqual(len(tag[PIC][0].data), 60511)
        self.assertEqual(tag.picture, "Other(0)::<60511 bytes of jpeg data>")

        # Set to empty
        tag.picture = ""
        self.assertEqual(tag.picture, "")
        self.assertTrue(PIC not in tag)

    def testPicture23_24(self):
        for tagcls in Tag23, Tag24:
            tag = tagcls()

            # Check empty
            self.assertEqual(tag.picture, "")

            # Set to empty
            tag.picture = ""
            self.assertEqual(tag.picture, "")
            self.assertTrue(APIC not in tag)

            # Set picture.
            tag.picture = os.path.join(os.path.dirname(
                __file__), "samples", "cover.jpg")
            self.assertEqual(tag[APIC][0].type, 0)
            self.assertEqual(tag[APIC][0].desc, "")
            self.assertEqual(tag[APIC][0].mime, "image/jpeg")
            self.assertEqual(len(tag[APIC][0].data), 60511)
            self.assertEqual(
                tag.picture, "Other(0)::<60511 bytes of jpeg data>")

            # Set to empty
            tag.picture = ""
            self.assertEqual(tag.picture, "")
            self.assertTrue(APIC not in tag)

    def testComment(self):
        for tagcls, frameid in ((Tag22, COM), (Tag23, COMM), (Tag24, COMM)):
            tag = tagcls()

            # Comment should be the empty string in an empty tag.
            self.assertEqual(tag.comment, "")

            # Try to delete non-existent comment.
            tag.comment = ""
            self.assertEqual(tag.comment, "")
            self.assertTrue(frameid not in tag)

            # Set comment.
            tag.comment = "Foobar"
            self.assertEqual(tag.comment, "Foobar")
            self.assertTrue(frameid in tag)
            self.assertEqual(len(tag[frameid]), 1)
            self.assertEqual(tag[frameid][0].lang, "eng")
            self.assertEqual(tag[frameid][0].desc, "")
            self.assertEqual(tag[frameid][0].text, "Foobar")

            # Override comment.
            tag.comment = "Baz"
            self.assertEqual(tag.comment, "Baz")
            self.assertTrue(frameid in tag)
            self.assertEqual(len(tag[frameid]), 1)
            self.assertEqual(tag[frameid][0].lang, "eng")
            self.assertEqual(tag[frameid][0].desc, "")
            self.assertEqual(tag[frameid][0].text, "Baz")

            # Delete comment.
            tag.comment = ""
            self.assertEqual(tag.comment, "")
            self.assertTrue(frameid not in tag)

    def testCommentWithExtraFrame(self):
        "Test getting/setting the comment when other comments are present."

        for tagcls, frameid in ((Tag22, COM), (Tag23, COMM), (Tag24, COMM)):
            tag = tagcls()
            frame = frameid(lan="eng", desc="foo", text="This is a text")
            tag[frameid] = [frame]

            # Comment should be the empty string.
            self.assertEqual(tag.comment, "")

            # Try to delete non-existent comment.
            tag.comment = ""
            self.assertEqual(tag.comment, "")
            self.assertEqual(len(tag[frameid]), 1)

            # Set comment.
            tag.comment = "Foobar"
            self.assertEqual(tag.comment, "Foobar")
            self.assertEqual(len(tag[frameid]), 2)
            self.assertEqual(tag[frameid][0], frame)
            self.assertEqual(tag[frameid][1].lang, "eng")
            self.assertEqual(tag[frameid][1].desc, "")
            self.assertEqual(tag[frameid][1].text, "Foobar")

            # Override comment.
            tag.comment = "Baz"
            self.assertEqual(tag.comment, "Baz")
            self.assertEqual(len(tag[frameid]), 2)
            self.assertEqual(tag[frameid][0], frame)
            self.assertEqual(tag[frameid][1].lang, "eng")
            self.assertEqual(tag[frameid][1].desc, "")
            self.assertEqual(tag[frameid][1].text, "Baz")

            # Delete comment.
            tag.comment = ""
            self.assertEqual(tag.comment, "")
            self.assertEqual(len(tag[frameid]), 1)
            self.assertEqual(tag[frameid][0], frame)


suite = unittest.TestLoader().loadTestsFromTestCase(FriendlyTestCase)

if __name__ == "__main__":
    warnings.simplefilter("always", Warning)
    unittest.main(defaultTest="suite")

#!/usr/bin/env python3 # friendly.py # https://github.com/Jelmerro/stagger # # Copyright (c) 2022-2022 <NAME> # Copyright (c) 2009-2011 <NAME>  <<EMAIL>> # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # - Redistributions of source code must retain the above copyright #   notice, this list of conditions and the following disclaimer. # # - Redistributions in binary form must reproduce the above copyright #   notice, this list of conditions and the following disclaimer in #   the documentation and/or other materials provided with the #   distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # No frame -> empty string # Set by frameid, check via friendly name # Set by friendly name, check via frame id # Set to empty string, check frame is gone # Repeat, should not throw KeyError # No frame -> zero values # Set by frameid, check via friendly name # Set by friendly name, check via frame id # Set to 0/0, check frame is gone # Repeat, should not throw # Set just the total # Check empty # Set to empty # Set a year # Partial date # Full date # Date + time # Truncate to year only # Check empty # Set to empty # Set a year # Check empty # Set to empty # Set to empty # Check empty # Set to empty # Set picture. # Set to empty # Comment should be the empty string in an empty tag. # Try to delete non-existent comment. # Set comment. # Override comment. # Delete comment. # Comment should be the empty string. # Try to delete non-existent comment. # Set comment. # Override comment. # Delete comment.