1# -*- coding: utf-8 -*- 2# Copyright 2014 Ben Ockmore 3# 4# This program is free software; you can redistribute it and/or modify 5# it under the terms of the GNU General Public License as published by 6# the Free Software Foundation; either version 2 of the License, or 7# (at your option) any later version. 8 9"""Tests for mid3cp tool. Since the tool is quite simple, most of the 10functionality is covered by the mutagen package tests - these simply test 11usage. 12""" 13 14import os 15from tempfile import mkstemp 16import shutil 17 18import mutagen.id3 19from mutagen.id3 import ID3, ParseID3v1 20from mutagen._senf import fsnative as fsn 21 22from tests.test_tools import _TTools 23from tests import DATA_DIR 24 25 26class TMid3cp(_TTools): 27 28 TOOL_NAME = u"mid3cp" 29 30 def setUp(self): 31 super(TMid3cp, self).setUp() 32 original = os.path.join(DATA_DIR, fsn(u'silence-44-s.mp3')) 33 fd, self.filename = mkstemp(suffix=fsn(u'öäü.mp3')) 34 os.close(fd) 35 shutil.copy(original, self.filename) 36 37 fd, self.blank_file = mkstemp(suffix=fsn(u'.mp3')) 38 os.close(fd) 39 40 def tearDown(self): 41 super(TMid3cp, self).tearDown() 42 os.unlink(self.filename) 43 os.unlink(self.blank_file) 44 45 def test_merge(self): 46 id3 = ID3(self.filename) 47 id3.delete() 48 id3.add(mutagen.id3.TALB(text=[u"foo"])) 49 id3.save(v2_version=3) 50 51 target = ID3() 52 target.add(mutagen.id3.TPE1(text=[u"bar", u"quux"])) 53 target.save(self.blank_file, v2_version=4) 54 55 res, out, err = self.call2( 56 self.filename, self.blank_file, fsn(u"--merge")) 57 assert not any([res, out, err]) 58 59 result = ID3(self.blank_file) 60 assert result.version == (2, 4, 0) 61 assert result.getall("TALB")[0].text == [u"foo"] 62 assert result.getall("TPE1")[0].text == [u"bar", u"quux"] 63 64 def test_merge_dst_no_tag(self): 65 id3 = ID3(self.filename) 66 id3.delete() 67 id3.save(v2_version=3) 68 69 with open(self.blank_file, "wb") as h: 70 h.write(b"SOMEDATA") 71 res, out, err = self.call2( 72 self.filename, self.blank_file, fsn(u"--merge")) 73 assert not any([res, out, err]) 74 75 result = ID3(self.blank_file) 76 assert result.version == (2, 3, 0) 77 78 def test_noop(self): 79 res, out, err = self.call2() 80 self.assertNotEqual(res, 0) 81 self.failUnless("Usage:" in err) 82 83 def test_src_equal_dst(self): 84 res = self.call2(self.filename, self.filename)[0] 85 self.assertEqual(res, 0) 86 87 def test_copy(self): 88 res = self.call(self.filename, self.blank_file)[0] 89 self.failIf(res) 90 91 original_id3 = ID3(self.filename) 92 copied_id3 = ID3(self.blank_file) 93 self.assertEqual(copied_id3.version, (2, 3, 0)) 94 95 # XXX: the v2.3 frame contains duplicate TPE1 frames which get merged 96 # when saving to v2.3 again 97 frame = copied_id3["TPE1"] 98 frame.text = frame.text[0].split("/") 99 100 self.failUnlessEqual(original_id3, copied_id3) 101 102 for key in original_id3: 103 # Go through every tag in the original file, and check that it's 104 # present and correct in the copy 105 self.failUnless(key in copied_id3) 106 self.failUnlessEqual(copied_id3[key], original_id3[key]) 107 108 def test_include_id3v1(self): 109 self.call(fsn(u'--write-v1'), self.filename, self.blank_file) 110 111 with open(self.blank_file, 'rb') as fileobj: 112 fileobj.seek(-128, 2) 113 frames = ParseID3v1(fileobj.read(128)) 114 115 # If ID3v1 frames are present, assume they've been written correctly by 116 # mutagen, so no need to check them 117 self.failUnless(frames) 118 119 def test_exclude_tag_unicode(self): 120 self.call(fsn(u'-x'), fsn(u''), self.filename, self.blank_file) 121 122 def test_exclude_single_tag(self): 123 self.call(fsn(u'-x'), fsn(u'TLEN'), self.filename, self.blank_file) 124 125 original_id3 = ID3(self.filename) 126 copied_id3 = ID3(self.blank_file) 127 128 self.failUnless('TLEN' in original_id3) 129 self.failIf('TLEN' in copied_id3) 130 131 def test_exclude_multiple_tag(self): 132 self.call(fsn(u'-x'), fsn(u'TLEN'), fsn(u'-x'), fsn(u'TCON'), 133 fsn(u'-x'), fsn(u'TALB'), self.filename, self.blank_file) 134 135 original_id3 = ID3(self.filename) 136 copied_id3 = ID3(self.blank_file) 137 138 self.failUnless('TLEN' in original_id3) 139 self.failUnless('TCON' in original_id3) 140 self.failUnless('TALB' in original_id3) 141 self.failIf('TLEN' in copied_id3) 142 self.failIf('TCON' in copied_id3) 143 self.failIf('TALB' in copied_id3) 144 145 def test_no_src_header(self): 146 fd, blank_file2 = mkstemp(suffix=fsn(u'.mp3')) 147 os.close(fd) 148 try: 149 err = self.call2(self.blank_file, blank_file2)[2] 150 self.failUnless("No ID3 header found" in err) 151 finally: 152 os.unlink(blank_file2) 153 154 def test_verbose(self): 155 err = self.call2(self.filename, fsn(u"--verbose"), self.blank_file)[2] 156 self.failUnless('mp3 contains:' in err) 157 self.failUnless('Successfully saved' in err) 158 159 def test_quiet(self): 160 out = self.call(self.filename, self.blank_file)[1] 161 self.failIf(out) 162 163 def test_exit_status(self): 164 status, out, err = self.call2(self.filename) 165 self.assertTrue(status) 166 167 status, out, err = self.call2(self.filename, self.filename) 168 self.assertFalse(status) 169 170 status, out, err = self.call2(self.blank_file, self.filename) 171 self.assertTrue(status) 172 173 status, out, err = self.call2(fsn(u""), self.filename) 174 self.assertTrue(status) 175 176 status, out, err = self.call2(self.filename, self.blank_file) 177 self.assertFalse(status) 178 179 def test_v23_v24(self): 180 self.assertEqual(ID3(self.filename).version, (2, 3, 0)) 181 self.call(self.filename, self.blank_file) 182 self.assertEqual(ID3(self.blank_file).version, (2, 3, 0)) 183 184 ID3(self.filename).save() 185 self.call(self.filename, self.blank_file) 186 self.assertEqual(ID3(self.blank_file).version, (2, 4, 0)) 187