Make the DBHandler class hierarchy testable; separate init() function
authorKarl O. Pinc <kop@karlpinc.com>
Thu, 31 Dec 2020 22:03:44 +0000 (16:03 -0600)
committerKarl O. Pinc <kop@karlpinc.com>
Sat, 2 Jan 2021 19:56:58 +0000 (13:56 -0600)
src/pgwui_core/core.py

index 0243deaca31ff9b4a01846e2362131bb81da903b..ab17aeec76cf18fb863b76a5d7bd2ef453ca9ad1 100644 (file)
@@ -41,6 +41,7 @@ from __future__ import division
 from csv import reader as csv_reader
 import collections.abc
 import ast
+import attr
 import markupsafe
 import hashlib
 
@@ -1034,7 +1035,8 @@ class ExecuteSQL(DataLineProcessor):
         sqlc.execute(self.cur)
 
 
-class DBHandler(object):
+@attr.s
+class DBHandler():
     '''
     Abstract class of a handler that modifies the db.
 
@@ -1066,13 +1068,15 @@ class DBHandler(object):
       uf            An UploadForm instance
       data          Something (beyond what's on the form) that goes into db
     '''
-    def __init__(self, request):
-        '''
-        request A pyramid request instance
+    request = attr.ib()
+    uf = attr.ib(default=None)
+    data = attr.ib(default=None)
+
+    def init(self):
+        '''Initialize handler
         '''
-        super(DBHandler, self).__init__()
-        self.request = request
         self.uf = self.make_form()
+        return self
 
     def make_form(self):
         '''
@@ -1143,6 +1147,7 @@ class DBHandler(object):
         return response
 
 
+@attr.s
 class SessionDBHandler(DBHandler):
     '''
     A DBHandler that supports sessions.
@@ -1151,12 +1156,14 @@ class SessionDBHandler(DBHandler):
       uf            An UploadForm instance
       session       A pyramid session instance
     '''
-    def __init__(self, request):
+    session = attr.ib(default=None)
+
+    def init(self):
         '''
-        request A pyramid request instance
+        Initialize session db handler
         '''
-        super(SessionDBHandler, self).__init__(request)
         self.session = self.request.session
+        return super().init()
 
     def write(self, result, errors):
         '''
@@ -1176,6 +1183,7 @@ class SessionDBHandler(DBHandler):
         return response
 
 
+@attr.s
 class UploadHandler(SessionDBHandler):
     '''
     Handler for uploading a file.
@@ -1185,12 +1193,6 @@ class UploadHandler(SessionDBHandler):
       uf            An UploadForm instance
       data          (optional) A DBData instance
     '''
-    def __init__(self, request):
-        '''
-        request A pyramid request instance
-        '''
-        super(UploadHandler, self).__init__(request)
-
     def factory(self, ue):
         '''
         Takes an UploadEngine instance
@@ -1283,8 +1285,8 @@ class UploadHandler(SessionDBHandler):
             e_cnt      Number of errors.
             db_changed  Boolean. Whether the db was changed.
         '''
-        response = super(UploadHandler, self).write(result, errors)
-        if hasattr(self, 'data'):
+        response = super().write(result, errors)
+        if self.data is not None:
             response['lines'] = self.data.lineno
         response['e_cnt'] = len(errors)
         response['db_changed'] = (not response['errors']
@@ -1292,6 +1294,7 @@ class UploadHandler(SessionDBHandler):
         return response
 
 
+@attr.s
 class TabularFileUploadHandler(UploadHandler):
     '''
     Handler for uploading a file with rows and columns and column headings.
@@ -1301,12 +1304,6 @@ class TabularFileUploadHandler(UploadHandler):
       uf            An UploadForm instance
       data          An UploadData instance
     '''
-    def __init__(self, request):
-        '''
-        request A pyramid request instance
-        '''
-        super(TabularFileUploadHandler, self).__init__(request)
-
     def cleanup(self):
         '''Finish after processing all lines.'''
         lines = self.ue.data.lineno