Completed
Branch master (9117d2)
by Steffen
03:33 queued 12s
created

TestFilesFilter   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 211
Duplicated Lines 16.59 %

Importance

Changes 6
Bugs 1 Features 2
Metric Value
c 6
b 1
f 2
dl 35
loc 211
rs 10
wmc 26

17 Methods

Rating   Name   Duplication   Size   Complexity  
A test_cmp() 0 2 1
A setUp() 0 21 1
A test_folders() 0 9 3
A test_files() 0 9 3
A test_named_file() 0 15 2
A test_extension_file() 0 17 2
A tearDown() 0 6 1
A create_test_dir() 0 7 1
A test_modified_file() 21 21 1
A test_big_file() 0 11 1
A test_empty_filter() 0 8 1
A test_get_timestamp_from_datestring() 0 11 2
A test_creation_date() 14 14 1
A create_named_file() 0 8 2
A create_modified_file() 0 15 2
A create_big_file() 0 9 2
A test_non_existent_path() 0 8 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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 View Code Duplication
    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 View Code Duplication
    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
        self.assertEqual(len(list(files)), 1)
155
156
    def test_non_existent_path(self):
157
        """Test filter for removing non existent files
158
159
        :return:
160
        """
161
        file_filter = Filter()
162
        files = list(file_filter.apply(directory=self.dir, file_system_objects=['not-existent-file']))
163
        self.assertEqual(files, [])
164
165
    def test_empty_filter(self):
166
        """Test empty filter
167
168
        :return:
169
        """
170
        file_filter = Filter()
171
        files = list(file_filter.apply())
172
        self.assertEqual(files, [])
173
174
    def test_get_timestamp_from_datestring(self):
175
        """Test for date string to timestamp conversion
176
177
        :return:
178
        """
179
        # since I don't like timezones in programming, I'll just expect a returned floating type value
180
        self.assertIsInstance(Filter._get_timestamp_from_datestring("01.01.2017 12:45:45"), float)
181
        self.assertIsInstance(Filter._get_timestamp_from_datestring("01.01.2017 12:45"), float)
182
        self.assertIsInstance(Filter._get_timestamp_from_datestring("01.01.2017"), float)
183
        with self.assertRaises(AttributeError) as _:
184
            Filter._get_timestamp_from_datestring("this is no time string")
185
186
    def create_big_file(self):
187
        """Create a file with a fixed size
188
189
        :return:
190
        """
191
        file_name = os.path.join(self.dir, str(uuid.uuid4()))
192
        with open(file_name, "wb") as file_handler:
193
            file_handler.seek(self.TEST_BIG_FILE_SIZE - 1)
194
            file_handler.write(b"\0")
195
196
    def create_named_file(self):
197
        """Create a file with a specific name
198
199
        :return:
200
        """
201
        file_name = os.path.join(self.dir, 'named_file.jpg')
202
        with open(file_name, "wb") as _:
203
            pass
204
205
    def create_modified_file(self):
206
        """Create a file and change the modification date
207
208
        :return:
209
        """
210
        file_name = os.path.join(self.dir, str(uuid.uuid4()))
211
        # create the file
212
        with open(file_name, "wb") as file_handler:
213
            file_handler.write(b"\0")
214
215
        st = os.stat(file_name)
216
        access_time = st[ST_ATIME]
217
        modified_time = st[ST_MTIME]
218
219
        os.utime(file_name, (access_time, modified_time + (4 * 3600)))
220
221
    def create_test_dir(self):
222
        """Create a subfolder for testing the folder amount
223
224
        :return:
225
        """
226
        dir_path = os.path.join(self.dir, str(uuid.uuid4()))
227
        os.mkdir(dir_path)
228
229
230
if __name__ == '__main__':
231
    suite = unittest.TestLoader().loadTestsFromTestCase(TestFilesFilter)
232
    unittest.TextTestRunner(verbosity=2).run(suite)
233