Repository: ioos/compliance-checker

Issue:
Enhance ACDD's attr/val checks to return messages indicating failures



Discussion:

Resolving patch:
diff --git a/compliance_checker/acdd.py b/compliance_checker/acdd.py
--- a/compliance_checker/acdd.py
+++ b/compliance_checker/acdd.py
@@ -96,25 +96,32 @@ def _get_vars(self, ds, attr_filter=None):
 
         return vars
 
+    def _get_msg(self, vpair, attr):
+        vval, vname = vpair
+        if vval is None:
+            return ["Var %s missing attr %s" % (vname, attr)]
+
+        return []
+
     @score_group('varattr')
     def check_var_long_name(self, ds):
         vars = self._get_vars(ds, 'long_name')
 
-        retval = [Result(BaseCheck.HIGH, v[0] is not None, (v[1], "var_long_name")) for v in vars]
+        retval = [Result(BaseCheck.HIGH, v[0] is not None, (v[1], "var_long_name"), self._get_msg(v, 'long_name')) for v in vars]
         return retval
 
     @score_group('varattr')
     def check_var_standard_name(self, ds):
         vars = self._get_vars(ds, 'standard_name')
 
-        retval = [Result(BaseCheck.HIGH, v[0] is not None, (v[1], "var_std_name")) for v in vars]
+        retval = [Result(BaseCheck.HIGH, v[0] is not None, (v[1], "var_std_name"), self._get_msg(v, 'standard_name')) for v in vars]
         return retval
 
     @score_group('varattr')
     def check_var_units(self, ds):
         vars = self._get_vars(ds, 'units')
 
-        retval = [Result(BaseCheck.HIGH, v[0] is not None, (v[1], "var_units")) for v in vars]
+        retval = [Result(BaseCheck.HIGH, v[0] is not None, (v[1], "var_units"), self._get_msg(v, 'units')) for v in vars]
         return retval
 
     @score_group('varattr')
@@ -122,8 +129,28 @@ def check_var_coverage_content_type(self, ds):
         vars = self._get_vars(ds, 'coverage_content_type')
         allowed = ['image','thematicClassification','physicalMeasurement','auxiliaryInformation','qualityInformation','referenceInformation','modelResult','coordinate']
 
-        retval = [Result(BaseCheck.HIGH, v[0] is not None and v[0] in allowed, (v[1], "var_coverage_content_type")) for v in vars]
-        return retval
+        ret_val = []
+        for v in vars:
+            vval, vname = v
+            msgs = []
+
+            count = 0
+            if vval is not None:
+                count += 1
+
+                if vval in allowed:
+                    count += 1
+                else:
+                    msgs.append("coverage_content_type present but value (%s) not in allowed values (%s)" % (vval, allowed))
+            else:
+                msgs.append("Var %s missing attr %s" % (vname, 'coverage_content_type'))
+
+            ret_val.append(Result(BaseCheck.HIGH,
+                                  (count, 2),
+                                  (v[1], "var_coverage_content_type"),
+                                  msgs))
+
+        return ret_val
 
 class ACDDNCCheck(BaseNCCheck, ACDDBaseCheck):
     @classmethod
diff --git a/compliance_checker/base.py b/compliance_checker/base.py
--- a/compliance_checker/base.py
+++ b/compliance_checker/base.py
@@ -133,21 +133,26 @@ def __repr__(self):
         return ret
 
 def std_check_in(dataset_dogma, name, allowed_vals):
-    #return name in dataset_dogma.variables and dataset_dogma.variables[name] in allowed_vals
+    """
+    Returns 0 if attr not present, 1 if present but not in correct value, 2 if good
+    """
+    if not hasattr(dataset_dogma, name):
+        return 0
+
+    ret_val = 1
     try:
-        return hasattr(dataset_dogma, name) and getattr(dataset_dogma, name) in allowed_vals
+        if getattr(dataset_dogma, name) in allowed_vals:
+            ret_val += 1
     except DogmaGetterSetterException:
         pass
 
-    return False
+    return ret_val
 
 def std_check(dataset_dogma, name):
-    #return name in dataset_dogma.variables
     if hasattr(dataset_dogma, name):
         getattr(dataset_dogma, name)
         return True
 
-    #raise StandardError("NO CAN DO %s" % name)
     return False
 
 def check_has(priority=BaseCheck.HIGH):
@@ -158,13 +163,22 @@ def _dec(s, ds):
 
             ret_val = []
             for l in list_vars:
+                msgs = []
                 if isinstance(l, tuple):
                     name, allowed = l
-                    ret_val.append(Result(priority, std_check_in(ds.dogma, name, allowed), name))
+                    res = std_check_in(ds.dogma, name, allowed)
+                    if res == 0:
+                        msgs.append("Attr %s not present" % name)
+                    elif res == 1:
+                        msgs.append("Attr %s present but not in expected value list (%s)" % (name, allowed))
 
-                else:
-                    ret_val.append(Result(priority, std_check(ds.dogma, l), l))
+                    ret_val.append(Result(priority, (res, 2), name, msgs))
 
+                else:
+                    res = std_check(ds.dogma, l)
+                    if not res:
+                        msgs = ["Attr %s not present" % l]
+                    ret_val.append(Result(priority, res, l, msgs))
 
             return ret_val
 


Test patch: