tests.files.test_filter   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 236
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 20
eloc 119
dl 0
loc 236
rs 10
c 0
b 0
f 0

16 Methods

Rating   Name   Duplication   Size   Complexity  
A TestFilesFilter.test_modified_file() 0 21 1
A TestFilesFilter.test_get_timestamp_from_datestring() 0 11 2
A TestFilesFilter.test_big_file() 0 14 1
A TestFilesFilter.create_named_file() 0 8 2
A TestFilesFilter.create_modified_file() 0 15 2
A TestFilesFilter.create_test_dir() 0 7 1
A TestFilesFilter.test_creation_date() 0 14 1
A TestFilesFilter.test_empty_filter() 0 8 1
A TestFilesFilter.test_named_file() 0 15 1
A TestFilesFilter.tearDown() 0 6 1
A TestFilesFilter.create_big_file() 0 9 2
A TestFilesFilter.test_non_existent_path() 0 8 1
A TestFilesFilter.setUp() 0 21 1
A TestFilesFilter.test_extension_file() 0 17 1
A TestFilesFilter.test_folders() 0 9 1
A TestFilesFilter.test_files() 0 9 1
1
#!/usr/bin/python
2
# -*- coding: utf-8 -*-
3
import datetime
4
import math
5
import os
6
import re
7
import shutil
8
import unittest
9
import uuid
10
from stat import ST_MTIME, ST_ATIME
11
from time import time, sleep
12
13
from saucenao.files.constraint import Constraint
14
from saucenao.files.filter import Filter
15
16
17
class TestFilesFilter(unittest.TestCase):
18
    """
19
    test cases for the filter in the files submodule
20
    """
21
22
    TEST_BIG_FILE_SIZE = 1024
23
24
    def setUp(self):
25
        """Constructor for the unittest
26
27
        :return:
28
        """
29
        self.dir = os.path.join(os.getcwd(), str(uuid.uuid4()))
30
        os.mkdir(self.dir)
31
        self.create_test_dir()
32
        # no files found for this time
33
        self.time_before_first_creation = time()
34
        sleep(0.1)
35
        self.create_big_file()
36
        # 1 file found
37
        self.time_after_first_creation = time()
38
        self.create_named_file()
39
        # we set the last modified time to 4 hours in the future, add a second
40
        # to get rid of other file operations
41
        self.time_modifying = time()
42
        self.create_modified_file()
43
        # wait for file operations to finish
44
        sleep(0.2)
45
46
    def tearDown(self):
47
        """Destructor for the unittest
48
49
        :return:
50
        """
51
        shutil.rmtree(self.dir)
52
53
    def test_files(self):
54
        """Test for files no folders
55
56
        :return:
57
        """
58
        expected_file_count = len([f for f in os.listdir(self.dir) if os.path.isfile(os.path.join(self.dir, f))])
59
        file_filter = Filter(assert_is_file=True)
60
        file_count = len(list(file_filter.apply(self.dir)))
61
        self.assertTrue(expected_file_count == file_count)
62
63
    def test_folders(self):
64
        """Test for folders no files
65
66
        :return:
67
        """
68
        expected_folder_count = len([f for f in os.listdir(self.dir) if os.path.isdir(os.path.join(self.dir, f))])
69
        folder_filter = Filter(assert_is_folder=True)
70
        folder_count = len(list(folder_filter.apply(self.dir)))
71
        self.assertTrue(folder_count == expected_folder_count)
72
73
    def test_named_file(self):
74
        """Test for regex match
75
76
        :return:
77
        """
78
79
        def test_cmp(value, expected_value):
80
            return expected_value.match(value)
81
82
        # check if we have more than just 1 file in the directory
83
        self.assertTrue(len(os.listdir(self.dir)) > 1)
84
        # set regular expression constraint
85
        file_filter = Filter(name=Constraint(re.compile('named*'), cmp_func=test_cmp))
86
        files = file_filter.apply(directory=self.dir)
87
        self.assertEqual(len(list(files)), 1)
88
89
    def test_extension_file(self):
90
        """Test filter for file extension
91
92
        :return:
93
        """
94
95
        def test_cmp(value, expected_value):
96
            return value in expected_value
97
98
        # we named our named file: named_file.jpg
99
        file_filter = Filter(file_type=Constraint([".png"], cmp_func=test_cmp))
100
        files = file_filter.apply(directory=self.dir)
101
        self.assertEqual(len(list(files)), 0)
102
103
        file_filter = Filter(file_type=Constraint([".jpg", ".png"], cmp_func=test_cmp))
104
        files = file_filter.apply(directory=self.dir)
105
        self.assertEqual(len(list(files)), 1)
106
107
    def test_creation_date(self):
108
        """Test for filtering after creation date
109
110
        :return:
111
        """
112
        date_string = datetime.datetime.fromtimestamp(self.time_modifying).strftime('%d.%m.%Y %H:%M')
113
        file_filter = Filter(
114
            creation_date=Constraint(date_string, cmp_func=Constraint.cmp_value_bigger_or_equal))
115
        files = file_filter.apply(directory=self.dir)
116
        self.assertEqual(len(list(files)), 4)
117
        file_filter = Filter(
118
            creation_date=Constraint(date_string, cmp_func=Constraint.cmp_value_smaller))
119
        files = file_filter.apply(directory=self.dir)
120
        self.assertEqual(len(list(files)), 0)
121
122
    def test_modified_file(self):
123
        """Test for modified file
124
125
        :return:
126
        """
127
        date_string = datetime.datetime.fromtimestamp(self.time_modifying).strftime('%d.%m.%Y %H:%M:%S')
128
129
        # get files created before or at the same time
130
        file_filter = Filter(
131
            modified_date=Constraint(date_string, cmp_func=Constraint.cmp_value_smaller_or_equal))
132
        files = file_filter.apply(directory=self.dir)
133
        len_files_before_modified_date = len(list(files))
134
135
        # get files modified after last file got created
136
        file_filter = Filter(
137
            modified_date=Constraint(date_string, cmp_func=Constraint.cmp_value_bigger))
138
        files = file_filter.apply(directory=self.dir)
139
        len_files_after_modified_date = len(list(files))
140
141
        self.assertTrue(len_files_after_modified_date == 1)
142
        self.assertTrue(len_files_before_modified_date > len_files_after_modified_date)
143
144
    def test_big_file(self):
145
        """Test for file size filter
146
147
        :return:
148
        """
149
        # check if we have more than just 1 file in the directory
150
        self.assertTrue(len(os.listdir(self.dir)) > 1)
151
        # filter now for files >= 1024 bytes
152
        file_filter = Filter(size=Constraint(self.TEST_BIG_FILE_SIZE, cmp_func=Constraint.cmp_value_bigger_or_equal))
153
        files = file_filter.apply(directory=self.dir)
154
        file_list = list(files)
155
        # workaround since scrutinizer has another file in created directories with differencing sizes each run
156
        # normal check would've been to check the file list length == 1
157
        self.assertTrue('big_file' in file_list and 'named_file.jpg' not in file_list)
158
159
    def test_non_existent_path(self):
160
        """Test filter for removing non existent files
161
162
        :return:
163
        """
164
        file_filter = Filter()
165
        files = list(file_filter.apply(directory=self.dir, file_system_objects=['not-existent-file']))
166
        self.assertEqual(files, [])
167
168
    def test_empty_filter(self):
169
        """Test empty filter
170
171
        :return:
172
        """
173
        file_filter = Filter()
174
        files = list(file_filter.apply())
175
        self.assertEqual(files, [])
176
177
    def test_get_timestamp_from_datestring(self):
178
        """Test for date string to timestamp conversion
179
180
        :return:
181
        """
182
        # since I don't like timezones in programming, I'll just expect a returned floating type value
183
        self.assertIsInstance(Filter._get_timestamp_from_datestring("01.01.2017 12:45:45"), float)
184
        self.assertIsInstance(Filter._get_timestamp_from_datestring("01.01.2017 12:45"), float)
185
        self.assertIsInstance(Filter._get_timestamp_from_datestring("01.01.2017"), float)
186
        with self.assertRaises(AttributeError) as _:
187
            Filter._get_timestamp_from_datestring("this is no time string")
188
189
    def create_big_file(self):
190
        """Create a file with a fixed size
191
192
        :return:
193
        """
194
        file_name = os.path.join(self.dir, 'big_file')
195
        with open(file_name, "wb") as file_handler:
196
            file_handler.seek(self.TEST_BIG_FILE_SIZE - 1)
197
            file_handler.write(b"\0")
198
199
    def create_named_file(self):
200
        """Create a file with a specific name
201
202
        :return:
203
        """
204
        file_name = os.path.join(self.dir, 'named_file.jpg')
205
        with open(file_name, "wb") as _:
206
            pass
207
208
    def create_modified_file(self):
209
        """Create a file and change the modification date
210
211
        :return:
212
        """
213
        file_name = os.path.join(self.dir, str(uuid.uuid4()))
214
        # create the file
215
        with open(file_name, "wb") as file_handler:
216
            file_handler.write(b"\0")
217
218
        st = os.stat(file_name)
219
        access_time = st[ST_ATIME]
220
        modified_time = st[ST_MTIME]
221
222
        os.utime(file_name, (access_time, modified_time + (4 * 3600)))
223
224
    def create_test_dir(self):
225
        """Create a subfolder for testing the folder amount
226
227
        :return:
228
        """
229
        dir_path = os.path.join(self.dir, str(uuid.uuid4()))
230
        os.mkdir(dir_path)
231
232
233
if __name__ == '__main__':
234
    suite = unittest.TestLoader().loadTestsFromTestCase(TestFilesFilter)
235
    unittest.TextTestRunner(verbosity=2).run(suite)
236