
  Demonstrating some of Project #1 Requirements
 ===============================================
  Req #1 - Use C++
 ------------------
  c:\su\temp\TestUtilitiesDemo-Inheritance\TestUtilities
    FileSystem.cpp
    FileSystem.h
    TestUtilitiesDemo.cpp
    TestUtilitiesDemo.h

  passed -- "TestReq1"

  Req #2a - use std::streams - see line 15
 ------------------------------------------
  c:\su\temp\TestUtilitiesDemo-Inheritance\TestUtilities\TestUtilitiesDemo.cpp
     1 ///////////////////////////////////////////////////////////////////////
     2 // TestUtilitiesDemo.cpp - facilities for single-user test harness   //
     3 // ver 2.0                                                           //
     4 // Language:    C++, Visual Studio 2017                              //
     5 // Application: Most Projects, CSE687 - Object Oriented Design       //
     6 // Author:      Jim Fawcett, Syracuse University, CST 4-187          //
     7 //              jfawcett@twcny.rr.com                                //
     8 ///////////////////////////////////////////////////////////////////////
     9 
    10 #include <cctype>
    11 #include <iostream>
    12 #include <memory>
    13 #include "TestUtilitiesDemo.h"
    14 
    15 std::ostream& out = std::cout;
    16 
    17 #ifdef TEST_TESTUTILITIESDEMO
    18 
    19 namespace Utilities
    20 {

  passed -- "TestReq2a"

  Req #2b - use new and delete
 ------------------------------
  c:\su\temp\TestUtilitiesDemo-Inheritance\TestUtilities\TestUtilitiesDemo.cpp
   102 
   103   TestExecutive::TestItem ti1;
   104   ti1.pTest = std::shared_ptr<ITest>(new TestPasses());
   105   ti1.testName = "test_always_passes";
   106 
   107   TestExecutive::TestItem ti2 = { std::shared_ptr<ITest>(new TestFails), "test_always_fails" };
   108   TestExecutive::TestItem ti3 = { std::shared_ptr<ITest>(new TestThrows), "test_always_throws" };
   109   TestExecutive::TestItem ti4 = { std::shared_ptr<ITest>(new TestCode("#1")), "testing CodeToTest" };
   110   TestExecutive::TestItem ti5 = { std::shared_ptr<ITest>(new TestCode("#2")), "testing CodeToTest" };
   111 

  passed -- "TestReq2b"

  Req #3 - tests implement ITest interface
 ------------------------------------------
  c:\su\temp\TestUtilitiesDemo-Inheritance\TestUtilities\TestUtilitiesDemo.cpp
    25 
    26   class TestPasses : public ITest
    27   {
    28   public:
    29     bool test() { return true; }
    30     virtual ~TestPasses() { out << "\n  -- deleting TestPasses"; }
    31   };
    32 

  passed -- "TestReq3"

  Req #4a - provides test container - see line 119 and line 126
 ---------------------------------------------------------------
  c:\su\temp\TestUtilitiesDemo-Inheritance\TestUtilities\TestUtilitiesDemo.h
   112   class TestExecutive
   113   {
   114   public:
   115     using TestItem = struct {
   116       std::shared_ptr<ITest> pTest;
   117       std::string testName;
   118     };
   119     using Tests = std::vector<TestItem>;
   120 
   121     bool doTests();
   122     void registerTest(std::shared_ptr<ITest> pTest, const std::string& testName);
   123     void registerTest(const TestItem& ts);
   124     void clearTests();
   125   private:
   126     Tests tests_;  // collection of test items
   127   };

  passed -- "TestReq4a"

  Req #4b - provides test container - shows where this demo's tests are registered
 ----------------------------------------------------------------------------------
  c:\su\temp\TestUtilitiesDemo-Inheritance\DemoSomeReqs\DemoReqs.cpp
    34   Utilities::Title("Demonstrating some of Project #1 Requirements");
    35 
    36   TestExecutive te;
    37   
    38   TestExecutive::TestItem ti1 = { SPtr(new TestReq1(path)), "TestReq1" };
    39   te.registerTest(ti1);
    40 
    41   TestExecutive::TestItem ti2a = { SPtr(new TestReq2a(path)), "TestReq2a" };
    42   te.registerTest(ti2a);
    43 
    44   TestExecutive::TestItem ti2b = { SPtr(new TestReq2b(path)), "TestReq2b" };
    45   te.registerTest(ti2b);
    46 
    47   TestExecutive::TestItem ti3 = { SPtr(new TestReq3(path)), "TestReq3" };
    48   te.registerTest(ti3);
    49 
    50   TestExecutive::TestItem ti4a = { SPtr(new TestReq4a(path)), "TestReq4a" };
    51   te.registerTest(ti4a);
    52 
    53   TestExecutive::TestItem ti4b = { SPtr(new TestReq4b(path)), "TestReq4b" };
    54   te.registerTest(ti4b);
    55 
    56   TestExecutive::TestItem ti5 = { SPtr(new TestReq5(path)), "TestReq5" };
    57   te.registerTest(ti5);
    58 
    59   bool results = te.doTests();

  passed -- "TestReq4b"

  Req #5 - function that executes tests within try-catch block
 --------------------------------------------------------------
  c:\su\temp\TestUtilitiesDemo-Inheritance\TestUtilities\TestUtilitiesDemo.h
    81   bool TestExecutor::execute(std::shared_ptr<ITest> pTest, const std::string& name, std::ostream& out)
    82   {
    83     bool result = false;
    84     try
    85     {
    86       result = pTest->test();  // execute test which may throw an exception
    87       check(result, out);
    88       out << " -- \"" << name << "\"\n";
    89     }
    90     catch (std::exception& ex)
    91     {
    92       check(false, out);
    93       out << " -- \"" << name << "\"\n";
    94       out << ex.what();
    95     }
    96     return result;
    97   }

  using test framework to run test that always passes
  passed -- "TestPasses"

  using test framework to run test that always fails
  failed -- "TestFails"

  using test framework to run test that always throws
  failed -- "TestThrows"

  -- this test always throws -- 
  -- deleting TestThrows
  -- deleting TestFails
  -- deleting TestPasses

  passed -- "TestReq5"

  deleting TestReq1
  deleting TestReq2a
  deleting TestReq2b
  deleting TestReq3
  deleting TestReq4a
  deleting TestReq4b
  deleting TestReq5
