Skip to content

Instantly share code, notes, and snippets.

@ChrisChiasson
Last active December 4, 2020 14:35
Show Gist options
  • Save ChrisChiasson/d4c7f4e974d8a8ac76bc213cd56a8e38 to your computer and use it in GitHub Desktop.
Save ChrisChiasson/d4c7f4e974d8a8ac76bc213cd56a8e38 to your computer and use it in GitHub Desktop.
Very Simple Unit Testing Setup
#ifndef EXPECT_EXPECT_HPP_
#define EXPECT_EXPECT_HPP_
#include <iostream>
#include <stdexcept>
#include <string>
/**
* Expect test functor.
* See this struct's test file for a simple example. */
struct Expect {
///ctor; s is suite name
Expect(std::string const&s):s_(s){};
///dtor throws if result() wasn't called; test fails
~Expect() noexcept(false){
if(!i_) throw std::logic_error("~Expect() called before "
"returning inspection of internal failure state.");
}
///Inspects failure state. Used to return from main.
bool result() {i_=true; return f_;}
/** check expectation
* bool v = true = success
* n is the test name, a string */
void operator()(bool v,std::string const&n){
if(!v){f_=true; std::cerr<<"FAILED: "<<s_<<n<<"\n";}
//The space before PASSED means FAILED stands out,
//though it doesn't matter because the returned nonzero
//error code will still cause the build to stop, so you
//don't have to see it anyway.
//cerr might not make sense for PASSED at first blush.
//However, given that we're testing the rest of the
//application--which may write to cout--we don't want
//to change cout's buffering, and clog isn't the right
//fit because by default it writes to stderr and is
//buffered.
else std::cerr<<" PASSED: "<<s_<<n<<"\n";
}
/**check for exception in op
* op is a lambda function or functor
* n is the test name, a string
* EX is the exception type */
template<class OP,class EX=std::exception>
void exception(OP const&op,std::string const&n,EX=EX()){
bool r(false); //raised exception indicator
try {op();}
catch(EX const&err){r=true;}
//no ... block; test will terminate with nonzero code
(*this)(r,n);
}
/** check for no exception in op
* op is a lambda function or functor
* n is the test name, a string
* EX is the exception type */
template<class OP,class EX=std::exception>
void no_exception(OP const&op,std::string const&n,EX=EX()){
bool r(false); //raised exception indicator
try {op();}
catch(EX const&err){r=true; std::cerr<<err.what();}
//no ... block; test will terminate with nonzero code
(*this)(!r,n);
}
private:
bool i_=false;///<true if failure state was inspected
bool f_=false;///<true if any test fails
std::string const s_;///<test suite name
};
#endif
#include "Expect/Expect.hpp"
int main(){
Expect expect("ExpectTest");
expect(true,"True");
expect.exception([](){throw std::runtime_error("");},"Exception");
expect.exception([](){Expect("");},"Uninspected");
expect.no_exception([](){std::cout<<"";},"NoException");
return expect.result();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment