3325710b67e7 — Greg Malcolm 13 years ago
Feature #12: Added Python 3 flavor
M python 2/runner/runner_tests/test_sensei.py +2 -2
@@ 404,5 404,5 @@ class TestSensei(unittest.TestCase):
 
     def test_filter_all_lessons_will_discover_test_classes_if_none_have_been_discovered_yet(self):
         self.sensei.all_lessons = 0
-        self.assertTrue(self.sensei.filter_all_lessons() > 10)
-        self.assertTrue(self.sensei.all_lessons > 10)
+        self.assertTrue(len(self.sensei.filter_all_lessons()) > 10)
+        self.assertTrue(len(self.sensei.all_lessons) > 10)

          
M python 2/runner/sensei.py +1 -4
@@ 3,16 3,13 @@ 
 
 import unittest
 import re
+import glob
 
 import helper
 from mockable_test_result import MockableTestResult
 from runner import path_to_enlightenment
 
 from libs.colorama import init, Fore, Style
-import glob
-
-init()
-
 
 class Sensei(MockableTestResult):
     def __init__(self, stream):

          
M python 3/runner/runner_tests/test_mountain.py +1 -5
@@ 14,12 14,8 @@ class TestMountain(unittest.TestCase):
         self.mountain = Mountain()
         self.mountain.stream.writeln = Mock()
         
-    def test_it_retrieves_some_koans_tests(self):
-        self.mountain.walk_the_path()
-        self.assertTrue(self.mountain.tests, "No test suite")
-        
     def test_it_gets_test_results(self):
         self.mountain.lesson.learn = Mock()
         self.mountain.walk_the_path()
         self.assertTrue(self.mountain.lesson.learn.called)
-        
  No newline at end of file
+        

          
M python 3/runner/runner_tests/test_sensei.py +36 -0
@@ 10,6 10,7 @@ from libs.mock import *
 from runner.sensei import Sensei
 from runner.writeln_decorator import WritelnDecorator
 from runner.mockable_test_result import MockableTestResult
+from runner import path_to_enlightenment
 
 class AboutParrots:
     pass

          
@@ 86,6 87,9 @@ class TestSensei(unittest.TestCase):
     def setUp(self):
         self.sensei = Sensei(WritelnDecorator(sys.stdout))
         self.sensei.stream.writeln = Mock()
+        path_to_enlightenment.koans = Mock()
+        self.tests = Mock()
+        self.tests.countTestCases = Mock()        
         
     def test_that_it_delegates_testing_to_test_cases(self):
         MockableTestResult.startTest = Mock()

          
@@ 229,6 233,15 @@ class TestSensei(unittest.TestCase):
         self.sensei.learn()
         self.assertTrue(self.sensei.stream.writeln.called)
 
+    def test_that_end_report_shows_student_progress(self):
+        self.sensei.errorReport = Mock()
+        self.sensei.total_lessons = Mock()
+        self.sensei.total_koans = Mock()
+
+        self.sensei.learn()
+        self.assertTrue(self.sensei.total_lessons.called)
+        self.assertTrue(self.sensei.total_koans.called)     
+
     def test_that_end_report_shows_the_failure_report(self):
         self.sensei.errorReport = Mock()
         self.sensei.learn()

          
@@ 371,3 384,26 @@ class TestSensei(unittest.TestCase):
         
         m = re.search("Beautiful is better than ugly", words)
         self.assertTrue(m and m.group(0))
+
+    def test_that_total_lessons_return_7_if_there_are_7_lessons(self):
+        self.sensei.filter_all_lessons = Mock()
+        self.sensei.filter_all_lessons.return_value = [1,2,3,4,5,6,7]
+
+        self.assertEqual(7, self.sensei.total_lessons())
+
+    def test_that_total_lessons_return_0_if_all_lessons_is_none(self):
+        self.sensei.filter_all_lessons = Mock()
+        self.sensei.filter_all_lessons.return_value = None
+
+        self.assertEqual(0, self.sensei.total_lessons())
+
+    def test_total_koans_return_43_if_there_are_43_test_cases(self):
+        self.sensei.tests.countTestCases = Mock()
+        self.sensei.tests.countTestCases.return_value = 43
+        
+        self.assertEqual(43, self.sensei.total_koans())
+
+    def test_filter_all_lessons_will_discover_test_classes_if_none_have_been_discovered_yet(self):
+        self.sensei.all_lessons = 0
+        self.assertTrue(len(self.sensei.filter_all_lessons()) > 10)
+        self.assertTrue(len(self.sensei.all_lessons) > 10)        

          
M python 3/runner/sensei.py +35 -3
@@ 3,19 3,23 @@ 
 
 import unittest
 import re
+import glob
 
 from . import helper
 from .mockable_test_result import MockableTestResult
+from runner import path_to_enlightenment
 
 from libs.colorama import init, Fore, Style
 
-
 class Sensei(MockableTestResult):
     def __init__(self, stream):
         unittest.TestResult.__init__(self)
         self.stream = stream
         self.prevTestClassName = None
+        self.tests = path_to_enlightenment.koans()        
         self.pass_count = 0
+        self.lesson_pass_count  = 0
+        self.all_lessons = None
 
     def startTest(self, test):
         MockableTestResult.startTest(self, test)

          
@@ 26,6 30,8 @@ class Sensei(MockableTestResult):
                 self.stream.writeln()
                 self.stream.writeln("{0}{1}Thinking {2}".format(
                     Fore.RESET, Style.NORMAL, helper.cls_name(test)))
+                if helper.cls_name(test) != 'AboutAsserts':
+                    self.lesson_pass_count += 1                
 
     def addSuccess(self, test):
         if self.passesCount():            

          
@@ 76,6 82,8 @@ class Sensei(MockableTestResult):
     
         self.stream.writeln("")
         self.stream.writeln("")
+        self.stream.writeln(self.report_progress())
+        self.stream.writeln("")        
         self.stream.writeln(self.say_something_zenlike())
         
         if self.failures: return

          
@@ 102,8 110,8 @@ class Sensei(MockableTestResult):
         self.stream.writeln("")
         self.stream.writeln("{0}{1}Please meditate on the following code:" \
             .format(Fore.RESET, Style.NORMAL))
-        self.stream.writeln("{0}{1}{2}".format(Fore.YELLOW, Style.BRIGHT, \
-            self.scrapeInterestingStackDump(err)))
+        self.stream.writeln("{0}{1}{2}{3}{4}".format(Fore.YELLOW, Style.BRIGHT, \
+            self.scrapeInterestingStackDump(err), Fore.RESET, Style.NORMAL))
 
     def scrapeAssertionError(self, err):
         if not err: return ""

          
@@ 146,6 154,13 @@ class Sensei(MockableTestResult):
                 scrape += line + '\n'
         return scrape.replace(sep, '\n').strip('\n')
 
+    def report_progress(self):
+        return ("You are now {0}/{1} lessons and {2}/{3} koans away from " \
+                "reaching enlightenment".format(self.lesson_pass_count,
+                                                self.total_lessons(),
+                                                self.pass_count,
+                                                self.total_koans()))      
+
     # Hat's tip to Tim Peters for the zen statements from The Zen
     # of Python (http://www.python.org/dev/peps/pep-0020/)
     #

          
@@ 210,3 225,20 @@ class Sensei(MockableTestResult):
         
         # Hopefully this will never ever happen!
         return "The temple in collapsing! Run!!!"
+
+    def total_lessons(self):
+        all_lessons = self.filter_all_lessons()
+        if all_lessons:
+          return len(all_lessons)
+        else:
+          return 0
+
+    def total_koans(self):
+        return self.tests.countTestCases()
+
+    def filter_all_lessons(self):
+        if not self.all_lessons:
+            self.all_lessons = glob.glob('koans/about*.py')
+            self.all_lessons.remove('koans/about_extra_credit.py')
+
+        return self.all_lessons