Spinning Topp Logo BlackTopp Studios
inc
consolelogic.cpp
Go to the documentation of this file.
1 // © Copyright 2010 - 2016 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 #ifndef _consolelogic_cpp
41 #define _consolelogic_cpp
42 
43 /// @file
44 /// @brief The implementation of items important a commandline tool to work correctly without need to be available to test developers.
45 
46 #include "consolelogic.h"
48 
49 #include <vector>
50 #include <sstream>
51 
52 #ifdef _MEZZ_THREAD_WIN32_
53  #ifndef WIN32_LEAN_AND_MEAN
54  #define WIN32_LEAN_AND_MEAN
55  #define __UNDEF_LEAN_AND_MEAN
56  #endif
57  #include <windows.h>
58  #ifdef __UNDEF_LEAN_AND_MEAN
59  #undef WIN32_LEAN_AND_MEAN
60  #undef __UNDEF_LEAN_AND_MEAN
61  #endif
62 #else
63  #include <unistd.h>
64 #endif
65 
66 
67 using namespace Mezzanine;
68 using namespace std;
69 
70 namespace Mezzanine
71 {
72  namespace Testing
73  {
74  int Usage(Mezzanine::String ThisName, CoreTestGroup& TestGroups)
75  {
76  cout << std::endl << "Usage: " << ThisName << " [help] [summary] [testlist] [interactive|automatic] [all]\n\t[skipfile] Test Group Names ..." << std::endl << std::endl
77  << "All: All test groups will be run." << std::endl
78  << "Interactive: Only interactive tests will be performed on specified test groups." << std::endl
79  << "Automatic: Only automated tests will be performed on specified test groups." << std::endl
80  //<< "Interactive and Automatic: All tests will be run on specificied test groups." << std::endl << std::endl
81  << "Summary: Only display a count of failures and successes." << std::endl
82  << "testlist: Output a list of all tests, one per line." << std::endl
83  << "skipfile: Do not store a copy of the results in TestResults.txt." << std::endl
84  << "debugtests: Run tests in the current process. Skips crash protection, but eases test debugging." << std::endl
85  << "Help: Display this message." << std::endl << std::endl
86  << "If only test group names are entered, then all tests in those groups are run." << std::endl
87  << "This command is not case sensitive." << std::endl << std::endl
88  << "Current Test Groups: " << std::endl;
89 
90  Mezzanine::Whole LongestName = 0;
91  for(std::map<Mezzanine::String,UnitTestGroup*>::iterator Iter=TestGroups.begin(); Iter!=TestGroups.end(); ++Iter)
92  {
93  if(Iter->first.size()>LongestName)
94  { LongestName=Iter->first.size();}
95  }
96 
97  // This presumes the console it 80 chars wide
98  Mezzanine::Whole TargetWidth=80;
99  Mezzanine::Whole ColumnWidth = LongestName+1;
100  Mezzanine::Whole Column = 0;
101  Mezzanine::Whole CurrentWidth=0;
102  for(std::map<Mezzanine::String,UnitTestGroup*>::iterator Iter=TestGroups.begin(); Iter!=TestGroups.end(); ++Iter)
103  {
104  if(0==Column)
105  {
106  cout << " ";
107  CurrentWidth = 2;
108  } else {
109  cout << " ";
110  CurrentWidth ++;
111  }
112 
113  cout << Iter->second->Name() << " ";
114  CurrentWidth += Iter->first.size() + 1;
115  Column++;
116  for(Mezzanine::Whole SpaceD=Iter->first.size()+1; SpaceD<=ColumnWidth; SpaceD++)
117  {
118  cout << " ";
119  CurrentWidth++;
120  }
121 
122  if(CurrentWidth>TargetWidth-LongestName-1)
123  {
124  cout << std::endl;
125  Column = 0;
126  CurrentWidth = 0;
127  }
128 
129  }
130  cout << std::endl;
131 
132  return ExitInvalidArguments;
133  }
134 
135  TestResult GetTestAnswerFromStdin(Mezzanine::String Question, Boole FailStatusOnIncorrect)
136  {
137  Mezzanine::String Input;
138  char Answer;
139 
140  while(true)
141  {
142  cout << Question;
143  getline(std::cin, Input);
144  std::stringstream InputStream(Input);
145  if (InputStream >> Answer)
146  {
147  Answer=tolower(Answer);
148  if (Answer=='t' || Answer=='y' || Answer=='f' || Answer=='n' || Answer=='c' || Answer=='u' || Answer=='i')
149  { break; }
150  }
151 
152  cout << std::endl << "Expected (T)rue/(Y)es for Success, (F)alse/(N)o for Failure," << std::endl << " (C)anceled to cancel this test, or (U)nsure/(I)nconclusive if you don't know." << std::endl << std::endl;
153  }
154 
155  switch(Answer)
156  {
157  case 't': case 'y':
158  return Testing::Success;
159  case 'f': case 'n':
160  if(FailStatusOnIncorrect)
161  { return Testing::Failed; }
162  else
163  { return Testing::Warning; }
164  case 'c':
165  return Testing::Cancelled;
166  case 'u': case 'i':
167  return Testing::Inconclusive;
168  default:
169  return Testing::Unknown;
170  }
171  }
172 
174  {
175  Command += " > CommandResults.txt";
176  system(Command.c_str());
177  std::ifstream File("CommandResults.txt");
178  return String( std::istreambuf_iterator<char>(File), std::istreambuf_iterator<char>());
179  }
180 
181  void sleep_for(UInt32 MicroSeconds)
182  {
183  #if defined(_MEZZ_THREAD_WIN32_)
184  Sleep(MicroSeconds/1000);
185  #else
186  usleep(MicroSeconds);
187  #endif
188  }
189 
190  }// Testing
191 }// Mezzanine
192 
193 #endif
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
Some string manipulation functions geared towards console output for use in the Unit Tests...
std::map< Mezzanine::String, UnitTestGroup * > CoreTestGroup
A group of testnames and the Actual test that implement those test(s).
Definition: testdata.h:108
At least some invalid args were passed on the command line.
STL namespace.
int Usage(Mezzanine::String ThisName, CoreTestGroup &TestGroups)
Print a message for the user onf the standard output that briefly describes hwo to use this...
uint32_t UInt32
An 32-bit unsigned integer.
Definition: datatypes.h:126
Since we don't know what happened this is the worst kind of failure.
Technically the test passed but there is something that is not quite right.
TestResult
Return values from tests.
String GetCommandResults(String Command)
Execute a command in a process, piping its standard output to a file.
If a user answers that with "don't know" in a test that involved interaction, The user knows there is...
The definition of a few command line tools.
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
Was canceled by user, so success is unknown, but user knows test was canceled.
unsigned long Whole
Whole is an unsigned integer, it will be at least 32bits in size.
Definition: datatypes.h:151
TestResult GetTestAnswerFromStdin(Mezzanine::String Question, Boole FailStatusOnIncorrect)
Asked the user a question on the std output and get a TestResult as an answer.
Test was ran and appeared to work.
void sleep_for(UInt32 MicroSeconds)
Sleeps the current thread for an amount of microseconds.
std::string String
A datatype used to a series of characters.
Definition: datatypes.h:159