Simplified TestCase runner, removed mocking, split off interactive logic that caused...
authorAndres Weber <redacted>
Thu, 1 Nov 2018 05:50:55 +0000 (01:50 -0400)
committerAndres Weber <redacted>
Thu, 1 Nov 2018 05:50:55 +0000 (01:50 -0400)
Added initialize_interactive_run method to isolate number setting logic.

tests/test_xkcdpass.py
xkcdpass/xkcd_password.py

index cc900088e031cb33b803666e1ac57b761a89f7ea..7a5ae55867624c88e7354fe731a734636dd19a02 100644 (file)
@@ -1,6 +1,6 @@
 """ Unit test for `xkcd_password` module. """
 
-import subprocess
+from subprocess import PIPE, Popen
 import argparse
 import io
 import re
@@ -83,12 +83,8 @@ class XkcdPasswordTests(unittest.TestCase):
             testing=True
         )
 
-        self.assertTrue(
-            observed_random_result_1 in (
-                expected_random_result_1_py2, expected_random_result_1_py3))
-        self.assertTrue(
-            observed_random_result_2 in (
-                expected_random_result_2_py2, expected_random_result_2_py3))
+        self.assertIn(observed_random_result_1, (expected_random_result_1_py2, expected_random_result_1_py3))
+        self.assertIn(observed_random_result_2, (expected_random_result_2_py2, expected_random_result_2_py3))
 
 
 class TestEmitPasswords(unittest.TestCase):
@@ -157,18 +153,16 @@ class TestEntropyInformation(unittest.TestCase):
     """ Test cases for function `emit_passwords`. """
 
     @staticmethod
-    def run_xkcdpass_process():
-        test = subprocess.Popen(
-            ["xkcdpass", "-V", "-i"], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
-        return test.communicate()[0]
+    def run_xkcdpass_process(*args):
+        process = Popen(["xkcdpass", "-V", "-i"], stdout=PIPE, stdin=PIPE)
+        return process.communicate('\n'.join(args))[0]
 
-    @mock.patch('__builtin__.input', side_effect=['4', 'y'])
-    def test_entropy_printout_valid_input(self, mock):
-        values = self.run_xkcdpass_process()
-        self.assertIn(
-            'A 4 word password from this list will have roughly 51', values)
+    def test_entropy_printout_valid_input(self):
+        values = self.run_xkcdpass_process('4', 'y')
+        self.assertIn('A 4 word password from this list will have roughly 51', values)
 
 
 if __name__ == '__main__':
-    suites = [unittest.TestLoader().loadTestsFromTestCase(test_case) for test_case in [XkcdPasswordTests, TestEmitPasswords, TestEntropyInformation]]
+    test_cases = [XkcdPasswordTests, TestEmitPasswords, TestEntropyInformation]
+    suites = [unittest.TestLoader().loadTestsFromTestCase(test_case) for test_case in test_cases]
     unittest.TextTestRunner(verbosity=2).run(unittest.TestSuite(suites))
index fe4d8a88a225479f71f1d5a646b0a05b572ae4b3..f958e41e108167513bac67535282f5a58f0ce6b9 100755 (executable)
@@ -328,45 +328,46 @@ def generate_xkcdpassword(wordlist,
     # useful if driving the logic from other code
     if not interactive:
         return gen_passwd()
-
+        
     # else, interactive session
-    # define input validators
+    else:
+        # define input validators
+        def accepted_validator(answer):
+            return answer.lower().strip() in ["y", "yes"]
+
+        # generate passwords until the user accepts
+        accepted = False
+        
+        while not accepted:
+            passwd = gen_passwd()
+            print("Generated: " + passwd)
+            accepted = try_input("Accept? [yN] ", accepted_validator)
+            print('accepted', accepted)
+        return passwd
+        
+
+def initialize_interactive_run(options):
     def n_words_validator(answer):
-        """
-        Validate custom number of words input
-        """
-
-        if isinstance(answer, str) and len(answer) == 0:
-            return numwords
-        try:
-            number = int(answer)
-            if number < 1:
-                raise ValueError
-            return number
-        except ValueError:
-            sys.stderr.write("Please enter a positive integer\n")
-            sys.exit(1)
-
-    def accepted_validator(answer):
-        return answer.lower().strip() in ["y", "yes"]
-
-    if not acrostic:
-        n_words_prompt = ("Enter number of words (default {0}):"
-                          " ".format(numwords))
-
-        numwords = try_input(n_words_prompt, n_words_validator)
+            """
+            Validate custom number of words input
+            """
+            
+            if isinstance(answer, str) and len(answer) == 0:
+                return options.numwords
+            try:
+                number = int(answer)
+                if number < 1:
+                    raise ValueError
+                return number
+            except ValueError:
+                sys.stderr.write("Please enter a positive integer\n")
+                sys.exit(1)
+
+    if not options.acrostic:
+        n_words_prompt = ("Enter number of words (default {0}):\n".format(options.numwords))
+        options.numwords = try_input(n_words_prompt, n_words_validator)
     else:
-        numwords = len(acrostic)
-
-    # generate passwords until the user accepts
-    accepted = False
-
-    while not accepted:
-        passwd = gen_passwd()
-        print("Generated: " + passwd)
-        accepted = try_input("Accept? [yN] ", accepted_validator)
-
-    return passwd
+        options.numwords = len(options.acrostic)
 
 
 def emit_passwords(wordlist, options):
@@ -489,6 +490,9 @@ def main(argv=None):
             max_length=options.max_length,
             valid_chars=options.valid_chars)
 
+        if options.interactive:
+            initialize_interactive_run(options)
+        
         if options.verbose:
             verbose_reports(my_wordlist, options)
 
git clone https://git.99rst.org/PROJECT