Total Complexity | 43 |
Total Lines | 181 |
Duplicated Lines | 54.14 % |
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:
Complex classes like often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | """Integration tests for the package.""" |
||
154 | class TestStandard: |
||
155 | """Integration tests for standard attribute types.""" |
||
156 | |||
157 | @yorm.attr(status=yorm.types.Boolean) |
||
158 | class StatusDictionary(Dictionary): |
||
159 | pass |
||
160 | |||
161 | def test_decorator(self, tmpdir): |
||
162 | """Verify standard attribute types dump/load correctly (decorator).""" |
||
163 | tmpdir.chdir() |
||
164 | sample = SampleStandardDecorated('sample') |
||
165 | assert "path/to/default/sample.yml" == sample.__mapper__.path |
||
166 | |||
167 | log.info("Checking object default values...") |
||
168 | assert {} == sample.object |
||
169 | assert [] == sample.array |
||
170 | assert "" == sample.string |
||
171 | assert 0 == sample.number_int |
||
172 | assert 0.0 == sample.number_real |
||
173 | assert True is sample.truthy |
||
174 | assert False is sample.falsey |
||
175 | assert None is sample.null |
||
176 | |||
177 | log.info("Changing object values...") |
||
178 | sample.object = {'key2': 'value'} |
||
179 | sample.array = [0, 1, 2] |
||
180 | sample.string = "Hello, world!" |
||
181 | sample.number_int = 42 |
||
182 | sample.number_real = 4.2 |
||
183 | sample.truthy = False |
||
184 | sample.falsey = True |
||
185 | |||
186 | log.info("Checking file contents...") |
||
187 | assert strip(""" |
||
188 | array: |
||
189 | - 0 |
||
190 | - 1 |
||
191 | - 2 |
||
192 | falsey: true |
||
193 | number_int: 42 |
||
194 | number_real: 4.2 |
||
195 | object: {} |
||
196 | string: Hello, world! |
||
197 | truthy: false |
||
198 | """) == sample.__mapper__.text |
||
199 | |||
200 | log.info("Changing file contents...") |
||
201 | refresh_file_modification_times() |
||
202 | sample.__mapper__.text = strip(""" |
||
203 | array: [4, 5, 6] |
||
204 | falsey: null |
||
205 | number_int: 42 |
||
206 | number_real: '4.2' |
||
207 | object: {'status': false} |
||
208 | string: "abc" |
||
209 | truthy: null |
||
210 | """) |
||
211 | |||
212 | log.info("Checking object values...") |
||
213 | assert {'status': False} == sample.object |
||
214 | assert [4, 5, 6] == sample.array |
||
215 | assert "abc" == sample.string |
||
216 | assert 42 == sample.number_int |
||
217 | assert 4.2 == sample.number_real |
||
218 | assert False is sample.truthy |
||
219 | assert False is sample.falsey |
||
220 | |||
221 | View Code Duplication | def test_function(self, tmpdir): |
|
222 | """Verify standard attribute types dump/load correctly (function).""" |
||
223 | tmpdir.chdir() |
||
224 | _sample = SampleStandard() |
||
225 | attrs = {'object': self.StatusDictionary, |
||
226 | 'array': IntegerList, |
||
227 | 'string': String, |
||
228 | 'number_int': Integer, |
||
229 | 'number_real': Float, |
||
230 | 'truthy': Boolean, |
||
231 | 'falsey': Boolean} |
||
232 | sample = yorm.sync(_sample, "path/to/directory/sample.yml", attrs) |
||
233 | assert "path/to/directory/sample.yml" == sample.__mapper__.path |
||
234 | |||
235 | # check defaults |
||
236 | assert {'status': False} == sample.object |
||
237 | assert [] == sample.array |
||
238 | assert "" == sample.string |
||
239 | assert 0 == sample.number_int |
||
240 | assert 0.0 == sample.number_real |
||
241 | assert True is sample.truthy |
||
242 | assert False is sample.falsey |
||
243 | assert None is sample.null |
||
244 | |||
245 | # change object values |
||
246 | sample.object = {'key': 'value'} |
||
247 | sample.array = [1, 2, 3] |
||
248 | sample.string = "Hello, world!" |
||
249 | sample.number_int = 42 |
||
250 | sample.number_real = 4.2 |
||
251 | sample.truthy = None |
||
252 | sample.falsey = 1 |
||
253 | |||
254 | # check file values |
||
255 | assert strip(""" |
||
256 | array: |
||
257 | - 1 |
||
258 | - 2 |
||
259 | - 3 |
||
260 | falsey: true |
||
261 | number_int: 42 |
||
262 | number_real: 4.2 |
||
263 | object: |
||
264 | status: false |
||
265 | string: Hello, world! |
||
266 | truthy: false |
||
267 | """) == sample.__mapper__.text |
||
268 | |||
269 | View Code Duplication | def test_function_to_json(self, tmpdir): |
|
270 | """Verify standard attribute types dump/load correctly (function).""" |
||
271 | tmpdir.chdir() |
||
272 | _sample = SampleStandard() |
||
273 | attrs = {'object': self.StatusDictionary, |
||
274 | 'array': IntegerList, |
||
275 | 'string': String, |
||
276 | 'number_int': Integer, |
||
277 | 'number_real': Float, |
||
278 | 'truthy': Boolean, |
||
279 | 'falsey': Boolean} |
||
280 | sample = yorm.sync(_sample, "path/to/directory/sample.json", attrs) |
||
281 | assert "path/to/directory/sample.json" == sample.__mapper__.path |
||
282 | |||
283 | # check defaults |
||
284 | assert {'status': False} == sample.object |
||
285 | assert [] == sample.array |
||
286 | assert "" == sample.string |
||
287 | assert 0 == sample.number_int |
||
288 | assert 0.0 == sample.number_real |
||
289 | assert True is sample.truthy |
||
290 | assert False is sample.falsey |
||
291 | assert None is sample.null |
||
292 | |||
293 | # change object values |
||
294 | sample.object = {'key': 'value'} |
||
295 | sample.array = [1, 2, 3] |
||
296 | sample.string = "Hello, world!" |
||
297 | sample.number_int = 42 |
||
298 | sample.number_real = 4.2 |
||
299 | sample.truthy = None |
||
300 | sample.falsey = 1 |
||
301 | |||
302 | # check file values |
||
303 | assert strip(""" |
||
304 | { |
||
305 | "array": [ |
||
306 | 1, |
||
307 | 2, |
||
308 | 3 |
||
309 | ], |
||
310 | "falsey": true, |
||
311 | "number_int": 42, |
||
312 | "number_real": 4.2, |
||
313 | "object": { |
||
314 | "status": false |
||
315 | }, |
||
316 | "string": "Hello, world!", |
||
317 | "truthy": false |
||
318 | } |
||
319 | """, tabs=2, end='') == sample.__mapper__.text |
||
320 | |||
321 | def test_auto_off(self, tmpdir): |
||
322 | """Verify file updates are disabled with auto save off.""" |
||
323 | tmpdir.chdir() |
||
324 | sample = SampleDecoratedAutoOff() |
||
325 | |||
326 | sample.string = "hello" |
||
327 | assert "" == sample.__mapper__.text |
||
328 | |||
329 | sample.__mapper__.auto_store = True |
||
330 | sample.string = "world" |
||
331 | |||
332 | assert strip(""" |
||
333 | string: world |
||
334 | """) == sample.__mapper__.text |
||
335 | |||
486 |