Repository: fitbenchmarking/fitbenchmarking

Issue:
Bad options error message
When running a fit with a typo in my options file, I got this:
```
Error while running FitBenchmarking. Exiting. See below for more information.
Failed to process options.
Details: The option 'bumps: ['amoeba', 'de', 'dream', 'lm-bumps', 'newton', 'scipy-leastsp']' in the ini file is invalid. bumps must be one or more of ['amoeba', 'lm-bumps', 'newton', 'de', 'scipy-leastsq', 'dream']
```

This could highlight that the `scipy-seastsp` entry is the issue.


Discussion:
coveralls: 
[![Coverage Status](https://coveralls.io/builds/70646971/badge)](https://coveralls.io/builds/70646971)

coverage: 90.208% (-0.006%) from 90.214%
when pulling **adb1440a3a1857e791676a2628237c97623a29fe on RabiyaF:1335-fixed-bad-error-msg**
into **cbbfa71754bb236973ac80ffdf357cf1229ca98c on fitbenchmarking:master**.


Patch:
diff --git a/fitbenchmarking/utils/options.py b/fitbenchmarking/utils/options.py
index 059a23dc..021fe716 100644
--- a/fitbenchmarking/utils/options.py
+++ b/fitbenchmarking/utils/options.py
@@ -709,17 +709,16 @@ class Options:
             value = None
 
         if option in self.VALID[section]:
-            if isinstance(value, list):
-                set1 = set(value)
-                set2 = set(self.VALID[section][option])
-                value_check = set1.issubset(set2)
-            else:
-                value_check = value in self.VALID[section][option]
-            if not value_check:
+            value_list = [value] if not isinstance(value, list) else value
+            invalid_values = [
+                v for v in value_list if v not in self.VALID[section][option]
+            ]
+            if invalid_values:
                 self.error_message.append(
-                    f"The option '{option}: {value}' in the ini file is "
-                    f"invalid. {option} must be one or more of "
-                    f"{self.VALID[section][option]}"
+                    f"The option '{option}: {value}' in the ini "
+                    f"file is invalid. {invalid_values} is not a "
+                    f"valid option. {option} must be one or "
+                    f"more of {self.VALID[section][option]}"
                 )
         return value
 


Test patch:
diff --git a/fitbenchmarking/utils/tests/test_options_minimizers.py b/fitbenchmarking/utils/tests/test_options_minimizers.py
index 09c2c06a..5d7bcc2c 100644
--- a/fitbenchmarking/utils/tests/test_options_minimizers.py
+++ b/fitbenchmarking/utils/tests/test_options_minimizers.py
@@ -339,3 +339,19 @@ class UserMininimizerOptionTests(unittest.TestCase):
         opts_file = self.generate_user_ini_file(options_set, software)
         with self.assertRaises(exceptions.OptionsError):
             Options(opts_file)
+
+    def test_error_msg(self):
+        """
+        Tests the error msg when wrong minimizer is selected.
+        """
+        opts_file = self.generate_user_ini_file(["ameoba", "de"], "bumps")
+        msg = (
+            "Failed to process options.\nDetails: The option 'bumps:"
+            " ['ameoba', 'de']' in the ini file is invalid. ['ameoba']"
+            " is not a valid option. bumps must be one or more of"
+            " ['amoeba', 'lm-bumps', 'newton', 'de', 'scipy-leastsq',"
+            " 'dream']"
+        )
+        with self.assertRaises(exceptions.OptionsError) as exp:
+            Options(opts_file)
+        self.assertEqual(str(exp.exception), msg)