Skip to content

Commit c797422

Browse files
authored
Merge pull request #33 from nexB/27-check-objects-in-constructor
Move object checks to class constructors #27
2 parents c953d27 + 4363b4f commit c797422

5 files changed

Lines changed: 103 additions & 88 deletions

File tree

src/deltacode/__init__.py

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
from collections import OrderedDict
2929

30+
from deltacode.models import File
3031
from deltacode.models import Scan
3132
from deltacode import utils
3233

@@ -42,7 +43,15 @@ class DeltaCode(object):
4243
def __init__(self, new_path, old_path):
4344
self.new = Scan(new_path)
4445
self.old = Scan(old_path)
45-
self.deltas = self.determine_delta()
46+
self.deltas = OrderedDict([
47+
('added', []),
48+
('removed', []),
49+
('modified', []),
50+
('unmodified', [])
51+
])
52+
53+
if self.new.path != '' and self.old.path != '':
54+
self.determine_delta()
4655

4756
def align_scan(self):
4857
"""
@@ -65,16 +74,6 @@ def determine_delta(self):
6574
the objects under the keys 'added', 'modified', 'removed' or 'unmodified'.
6675
Return None if no File objects can be loaded from either scan.
6776
"""
68-
if self.new.files is None or self.old.files is None:
69-
return None
70-
71-
deltas = OrderedDict([
72-
('added', []),
73-
('removed', []),
74-
('modified', []),
75-
('unmodified', [])
76-
])
77-
7877
# align scan and create our index
7978
self.align_scan()
8079
new_index = self.new.index_files()
@@ -95,7 +94,7 @@ def determine_delta(self):
9594
try:
9695
delta_old_files = old_index[path]
9796
except KeyError:
98-
deltas['added'].append(Delta(new_file, None, 'added'))
97+
self.deltas['added'].append(Delta(new_file, None, 'added'))
9998
continue
10099

101100
# at this point, we have a delta_old_file.
@@ -104,11 +103,11 @@ def determine_delta(self):
104103
for f in delta_old_files:
105104
# TODO: make sure sha1 is NOT empty
106105
if new_file.sha1 == f.sha1:
107-
deltas['unmodified'].append(Delta(new_file, f, 'unmodified'))
106+
self.deltas['unmodified'].append(Delta(new_file, f, 'unmodified'))
108107
continue
109108
else:
110109
delta = Delta(new_file, f, 'modified')
111-
deltas['modified'].append(delta)
110+
self.deltas['modified'].append(delta)
112111

113112
# now time to find the added.
114113
for path, old_files in old_index.items():
@@ -122,15 +121,13 @@ def determine_delta(self):
122121
# This file already classified as 'modified' or 'unmodified' so do nothing
123122
new_index[path]
124123
except KeyError:
125-
deltas['removed'].append(Delta(None, old_file, 'removed'))
124+
self.deltas['removed'].append(Delta(None, old_file, 'removed'))
126125
continue
127126

128127
# make sure everything is accounted for
129128
assert new_files_to_visit == 0
130129
assert old_files_to_visit == 0
131130

132-
return deltas
133-
134131
def get_stats(self):
135132
"""
136133
Given a list of Delta objects, return a 'counts' dictionary keyed by
@@ -152,9 +149,6 @@ def to_dict(self):
152149
objects grouping the objects under the keys 'added', 'removed',
153150
'modified' or 'unmodified'.
154151
"""
155-
if self.deltas is None:
156-
return
157-
158152
return OrderedDict([
159153
('added', [d.to_dict() for d in self.deltas.get('added')]),
160154
('removed', [d.to_dict() for d in self.deltas.get('removed')]),
@@ -170,10 +164,9 @@ class Delta(object):
170164
'added', 'modified', 'removed' or 'unmodified'.
171165
"""
172166
def __init__(self, new_file=None, old_file=None, delta_type=None):
173-
# TODO: add check to ensure both are File objects
174-
self.new_file = new_file
175-
self.old_file = old_file
176-
self.category = delta_type
167+
self.new_file = new_file if new_file else File()
168+
self.old_file = old_file if old_file else File()
169+
self.category = delta_type if delta_type else ''
177170

178171
# Change the Delta object's 'category' attribute to
179172
# 'license change' if a substantial license change has been detected.
@@ -187,9 +180,6 @@ def _license_diff(self, cutoff_score=50):
187180
'license change' if those details differ and the cutoff score test is
188181
satisfied.
189182
"""
190-
if not self.new_file or not self.old_file:
191-
return
192-
193183
new_licenses = self.new_file.licenses or []
194184
new_keys = set(l.key for l in new_licenses if l.score >= cutoff_score)
195185

@@ -204,9 +194,6 @@ def to_dict(self):
204194
Check the 'category' attribute of the Delta object and return an
205195
OrderedDict comprising the 'category' and 'path' of the object.
206196
"""
207-
if self.new_file is None and self.old_file is None:
208-
return
209-
210197
if self.category == 'added':
211198
return OrderedDict([
212199
('category', 'added'),

src/deltacode/cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def cli(new, old, csv_file, json_file):
7878
option is selected, print the JSON results to the console.
7979
"""
8080
# do the delta
81-
delta = DeltaCode(new, old)
81+
delta = DeltaCode(new, old).determine_delta()
8282

8383
# output to csv
8484
if csv_file:

src/deltacode/models.py

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,19 @@ class Scan(object):
3838
selected key.
3939
"""
4040
def __init__(self, path=''):
41-
self.path = '' if path is None else path
42-
self.files_count = self.get_files_count(self.path)
43-
self.files = self.load_files(self.path)
44-
self.options = self.get_options(self.path)
41+
if path is None:
42+
path = ''
43+
44+
if not self.is_valid_scan(path):
45+
self.path = ''
46+
self.files_count = 0
47+
self.files = []
48+
self.options = {}
49+
else:
50+
self.path = path
51+
self.files_count = self.get_files_count(path)
52+
self.files = self.load_files(path)
53+
self.options = self.get_options(path)
4554

4655
def get_options(self, path):
4756
"""
@@ -145,18 +154,15 @@ class File(object):
145154
File object created from an ABCD formatted 'file' dictionary.
146155
"""
147156
def __init__(self, dictionary={}):
148-
self.path = dictionary.get('path')
149-
self.type = dictionary.get('type')
150-
self.name = dictionary.get('name')
151-
self.size = dictionary.get('size')
152-
self.sha1 = dictionary.get('sha1')
157+
self.path = dictionary.get('path', '')
158+
self.type = dictionary.get('type', '')
159+
self.name = dictionary.get('name', '')
160+
self.size = dictionary.get('size', '')
161+
self.sha1 = dictionary.get('sha1', '')
153162
self.original_path = ''
154-
self.licenses = self.get_licenses(dictionary)
163+
self.licenses = self.get_licenses(dictionary) if dictionary.get('licenses') else []
155164

156165
def get_licenses(self, dictionary):
157-
if dictionary.get('licenses') == None:
158-
return None
159-
160166
if dictionary.get('licenses') == []:
161167
return []
162168
else:
@@ -173,7 +179,7 @@ def to_dict(self):
173179
])
174180

175181
# TODO: disable this for now due to high memory usage
176-
#if self.licenses:
182+
# if self.licenses:
177183
# d['licenses'] = [l.to_dict() for l in self.licenses]
178184

179185
return d

tests/test_deltacode.py

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -345,49 +345,48 @@ def test_DeltaCode_to_dict_empty(self):
345345

346346
result = delta.to_dict()
347347

348-
assert result == None
348+
assert result == OrderedDict([('added', []), ('removed', []), ('modified', []), ('unmodified', [])])
349349

350350
def test_DeltaCode_invalid_paths(self):
351351
test_path_1 = '/some/invalid/path/1.json'
352352
test_path_2 = '/some/invalid/path/2.json'
353353

354354
result = DeltaCode(test_path_1, test_path_2)
355355

356-
assert result.new.path == '/some/invalid/path/1.json'
357-
assert result.new.files_count == None
358-
assert result.new.files == None
356+
assert result.new.path == ''
357+
assert result.new.files_count == 0
358+
assert result.new.files == []
359359

360-
assert result.old.path == '/some/invalid/path/2.json'
361-
assert result.new.files_count == None
362-
assert result.old.files == None
360+
assert result.old.path == ''
361+
assert result.old.files_count == 0
362+
assert result.old.files == []
363363

364-
assert result.deltas == None
364+
assert result.deltas == OrderedDict([('added', []), ('removed', []), ('modified', []), ('unmodified', [])])
365365

366366
def test_DeltaCode_empty_paths(self):
367367
result = DeltaCode('', '')
368368

369369
assert result.new.path == ''
370-
assert result.new.files_count == None
371-
assert result.new.files == None
370+
assert result.new.files_count == 0
371+
assert result.new.files == []
372372

373373
assert result.old.path == ''
374-
assert result.new.files_count == None
375-
assert result.old.files == None
374+
assert result.old.files_count == 0
375+
assert result.old.files == []
376376

377-
assert result.deltas == None
377+
assert result.deltas == OrderedDict([('added', []), ('removed', []), ('modified', []), ('unmodified', [])])
378378

379379
def test_DeltaCode_None_paths(self):
380380
result = DeltaCode(None, None)
381381

382382
assert result.new.path == ''
383-
assert result.new.files_count == None
384-
assert result.new.files == None
383+
assert result.new.files_count == 0
384+
assert result.new.files == []
385385

386386
assert result.old.path == ''
387-
assert result.new.files_count == None
388-
assert result.old.files == None
389-
390-
assert result.deltas == None
387+
assert result.old.files_count == 0
388+
assert result.old.files == []
389+
assert result.deltas == OrderedDict([('added', []), ('removed', []), ('modified', []), ('unmodified', [])])
391390

392391
def test_Delta_license_diff_new_no_license_info(self):
393392
new_file = models.File({'path': 'new/path.txt'})
@@ -493,9 +492,9 @@ def test_Delta_license_diff_one_None(self):
493492
def test_Delta_license_diff_None_files(self):
494493
delta = deltacode.Delta(None, None, None)
495494

496-
assert delta.new_file == None
497-
assert delta.old_file == None
498-
assert delta.category == None
495+
assert type(delta.new_file) == type(models.File())
496+
assert type(delta.old_file) == type(models.File())
497+
assert delta.category == ''
499498

500499
def test_DeltaCode_license_modified_low_score(self):
501500
new_scan = self.get_test_loc('deltacode/scan_modified_new_license_added_low_score.json')
@@ -678,15 +677,15 @@ def test_Delta_to_dict_unmodified(self):
678677
def test_Delta_to_dict_empty(self):
679678
delta = deltacode.Delta()
680679

681-
assert delta.to_dict() == None
680+
assert delta.to_dict() == OrderedDict([('category', 'unmodified'), ('path', '')])
682681

683682
def test_Delta_create_object_removed(self):
684683
new = None
685684
old = models.File({'path': 'path/removed.txt'})
686685

687686
delta = deltacode.Delta(new, old, 'removed')
688687

689-
assert delta.new_file == None
688+
assert type(delta.new_file) == type(models.File())
690689
assert delta.old_file.path == 'path/removed.txt'
691690
assert delta.category == 'removed'
692691

@@ -697,7 +696,7 @@ def test_Delta_create_object_added(self):
697696
delta = deltacode.Delta(new, old, 'added')
698697

699698
assert delta.new_file.path == 'path/added.txt'
700-
assert delta.old_file == None
699+
assert type(delta.old_file) == type(models.File())
701700
assert delta.category == 'added'
702701

703702
def test_Delta_create_object_modified(self):
@@ -727,6 +726,6 @@ def test_Delta_create_object_unmodified(self):
727726
def test_Delta_create_object_empty(self):
728727
delta = deltacode.Delta()
729728

730-
assert delta.new_file == None
731-
assert delta.old_file == None
732-
assert delta.category == None
729+
assert type(delta.new_file) == type(models.File())
730+
assert type(delta.old_file) == type(models.File())
731+
assert delta.category == ''

tests/test_models.py

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -344,26 +344,26 @@ def test_Scan_invalid_path(self):
344344

345345
result = models.Scan(test_path)
346346

347-
assert result.path == '/some/invalid/path.json'
348-
assert result.files_count == None
349-
assert result.files == None
350-
assert result.options == None
347+
assert result.path == ''
348+
assert result.files_count == 0
349+
assert result.files == []
350+
assert result.options == {}
351351

352352
def test_Scan_empty_path(self):
353353
result = models.Scan('')
354354

355355
assert result.path == ''
356-
assert result.files_count == None
357-
assert result.files == None
358-
assert result.options == None
356+
assert result.files_count == 0
357+
assert result.files == []
358+
assert result.options == {}
359359

360360
def test_Scan_None_path(self):
361361
result = models.Scan(None)
362362

363363
assert result.path == ''
364-
assert result.files_count == None
365-
assert result.files == None
366-
assert result.options == None
364+
assert result.files_count == 0
365+
assert result.files == []
366+
assert result.options == {}
367367

368368
def test_License_to_dict_simple(self):
369369
data = {
@@ -549,11 +549,11 @@ def test_File_to_dict_empty(self):
549549
empty_file = models.File()
550550

551551
expected = {
552-
'path': None,
553-
'type': None,
554-
'name': None,
555-
'size': None,
556-
'sha1': None,
552+
'path': '',
553+
'type': '',
554+
'name': '',
555+
'size': '',
556+
'sha1': '',
557557
'original_path': ''
558558
}
559559

@@ -621,6 +621,29 @@ def test_File_create_object_license_none(self):
621621
assert '26d82f1931cbdbd83c2a6871b2cecd5cbcc8c26b' == result.sha1
622622
assert [] == result.licenses
623623

624+
def test_File_create_object_license_missing(self):
625+
data = {
626+
'path': 'a/b/file1.txt',
627+
'type': 'file',
628+
'name': 'file1.txt',
629+
'size': 20,
630+
'sha1': '26d82f1931cbdbd83c2a6871b2cecd5cbcc8c26b',
631+
}
632+
633+
result = models.File(data)
634+
635+
assert [] == result.licenses
636+
637+
def test_File_empty(self):
638+
empty_file = models.File()
639+
640+
assert empty_file.path == ''
641+
assert empty_file.type == ''
642+
assert empty_file.name == ''
643+
assert empty_file.size == ''
644+
assert empty_file.sha1 == ''
645+
assert empty_file.licenses == []
646+
624647
def test_File_create_object(self):
625648
data = {
626649
'path': 'a/b/file1.txt',

0 commit comments

Comments
 (0)