1# -*- coding: utf-8 -*-
2#
3# Picard, the next-generation MusicBrainz tagger
4#
5# Copyright (C) 2019 Philipp Wolfer
6# Copyright (C) 2020 Laurent Monin
7#
8# This program is free software; you can redistribute it and/or
9# modify it under the terms of the GNU General Public License
10# as published by the Free Software Foundation; either version 2
11# of the License, or (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21
22
23import os.path
24from tempfile import NamedTemporaryFile
25
26from test.picardtestcase import PicardTestCase
27
28from picard.util import emptydir
29
30
31class EmptyDirTestCommon(PicardTestCase):
32
33    def create_temp_dir(self, extra_files=(), extra_dirs=(), ignore_errors=False):
34        tempdir = self.mktmpdir(ignore_errors=ignore_errors)
35        for f in extra_files:
36            open(os.path.join(tempdir, f), 'a').close()
37        for f in extra_dirs:
38            os.mkdir(os.path.join(tempdir, f))
39        return tempdir
40
41
42class EmptyDirTest(EmptyDirTestCommon):
43
44    def test_is_empty_dir_really_empty(self):
45        tempdir = self.create_temp_dir()
46        self.assertTrue(emptydir.is_empty_dir(tempdir))
47
48    def test_is_empty_dir_only_junk_files(self):
49        tempdir = self.create_temp_dir(extra_files=emptydir.JUNK_FILES)
50        self.assertTrue(len(os.listdir(tempdir)) > 0)
51        self.assertTrue(emptydir.is_empty_dir(tempdir))
52
53    def test_is_empty_dir_not_empty(self):
54        tempdir = self.create_temp_dir(extra_files=['.notempty'])
55        self.assertEqual(1, len(os.listdir(tempdir)))
56        self.assertFalse(emptydir.is_empty_dir(tempdir))
57
58    def test_is_empty_dir_custom_ignore_files(self):
59        ignored_files = ['.empty']
60        tempdir = self.create_temp_dir(extra_files=ignored_files)
61        self.assertEqual(1, len(os.listdir(tempdir)))
62        self.assertTrue(emptydir.is_empty_dir(tempdir, ignored_files=ignored_files))
63
64    def test_is_empty_dir_not_empty_child_dir(self):
65        tempdir = self.create_temp_dir(extra_dirs=['childdir'])
66        self.assertEqual(1, len(os.listdir(tempdir)))
67        self.assertFalse(emptydir.is_empty_dir(tempdir))
68
69    def test_is_empty_dir_on_file(self):
70        with NamedTemporaryFile() as f:
71            self.assertRaises(NotADirectoryError, emptydir.is_empty_dir, f.name)
72
73
74class RmEmptyDirTest(EmptyDirTestCommon):
75
76    def test_rm_empty_dir_really_empty(self):
77        tempdir = self.create_temp_dir(ignore_errors=True)
78        self.assertTrue(os.path.isdir(tempdir))
79        emptydir.rm_empty_dir(tempdir)
80        self.assertFalse(os.path.exists(tempdir))
81
82    def test_rm_empty_dir_only_junk_files(self):
83        tempdir = self.create_temp_dir(extra_files=emptydir.JUNK_FILES, ignore_errors=True)
84        self.assertTrue(os.path.isdir(tempdir))
85        emptydir.rm_empty_dir(tempdir)
86        self.assertFalse(os.path.exists(tempdir))
87
88    def test_rm_empty_dir_not_empty(self):
89        tempdir = self.create_temp_dir(['.notempty'])
90        self.assertEqual(1, len(os.listdir(tempdir)))
91        self.assertRaises(emptydir.SkipRemoveDir, emptydir.rm_empty_dir, tempdir)
92
93    def test_rm_empty_dir_is_special(self):
94        tempdir = self.create_temp_dir()
95        orig_portected_dirs = emptydir.PROTECTED_DIRECTORIES
96        emptydir.PROTECTED_DIRECTORIES.add(os.path.realpath(tempdir))
97        self.assertRaises(emptydir.SkipRemoveDir, emptydir.rm_empty_dir, tempdir)
98        emptydir.PROTECTED_DIRECTORIES = orig_portected_dirs
99
100    def test_is_empty_dir_on_file(self):
101        with NamedTemporaryFile() as f:
102            self.assertRaises(NotADirectoryError, emptydir.rm_empty_dir, f.name)
103