CppUnit project page | CppUnit home page |
'_'
.This convention has two main variants: first letter of the name in lower case, and first letter of the name in upper case. If the first letter is part of an acronym, then the acronym is in the same case as the first letter.
Example:
First letter in upper case | First letter in lower case |
TestCase | testCase |
DLLLoader | dllLoader |
File extensions: .cpp
for C++ source file .h/.inl
for C++ headers.
Rational: avoid case issues for case sensitive filesystem, corrupting CVS repository when attempting to change file name case on buggy client.
Example :
testcase.c // OK testcase.h // OK testcase.inl // OK resource.c // OK test_case.c // BAD TestCase.c // BAD TestCase.h // BAD TestCase.C // BAD
'__'
or starts with a single underscore '_'
. Identifiers may only contains the following characters: a..z, A..Z, 0..9
. The usage of '$'
is forbidden. Rationale: such usage of underscore is reserved by the C++ standard.
Notes:
'__'
, therefore using '__'
might result in (silent) linking issues.'_'
for their implementation.The following prefix should be used:
Library | Prefix | |
CppUnit 2 | CPPUT_ | |
CppTL (CppUnit Tool Library) | CPPTL_ | |
JsonCpp | JSON_ | |
OpenTest | OPENTEST_ |
Rationale: macro substitution occurs at preprocessing time without regards to namespace. Prefixing macro names help makes them unique and avoid clash between libraries. The naming conventions are such that no C++ identifier should have a name similar to a macro name. This conventions is widely adopted across all C++ naming conventions, meaning that it also help avoid conflicts with third-parties.
Rationale: defined by java standard naming convention, and a widely spread C++ convention as well. Identifiers starting with an upper case are used to identify ‘Type’ identifiers (enum, class...)
Example:
Test TestCase ExceptionGuard
'_'
. Rationale: defined by java standard naming convention, and a widely spread C++ convention as well. Identifiers starting with a lower case are used to identify ‘value’ identifiers (attribute, variable...)
Example:
int size_; double timeOut_; LightTestRunner runner_;
Rationale: This is a widely spread convention in the Java and C++ community.
Recommendation: when overriding virtual function, specify in which inherited class the virtual function is defined:
Example:
void addChild( const std::string &parentSuiteName, const std::string &childSuiteName ); bool removeChild( const std::string &parentSuiteName, const std::string &childSuiteName ); TestFactoryId add( const std::string &parentSuiteName, const TestFactory &testFactory ); class OPENTEST_API TestRunnerServer : public RemoteMessageServer , private TestRunnerListener { public: TestRunnerServer( TestRunnerInterface &impl ); void attachTransport( const MessageTransportPtr &transport ); public: // overridden from RemoteMessageServer void dispatchPendingMessages( const RemoteMessagePtr &message, MessageTransport &transport ); public: // overridden from TestRunnerListener virtual void testRunStarted( TestRunId testRunId ); virtual void testRunDone( TestRunId testRunId ); virtual void startTesting( TestPlanId testPlanId ); virtual void doneTesting( TestPlanId testPlanId, const ResultStatus &status ); private: // ... };
Rationale: avoid potential clash with macro.
Example:
enum ParameterRequirement
{
noParameter,
optionalParameter,
requiredParameter,
oneOrMoreParameter,
zeroOrMoreParameter
};
Rationale: avoid ambiguity in declaration between type and variable name.
Example:
bool parse( const std::string &document, Value &root, bool collectComments = true );
General code layout:
// An example of constructor TestCase::TestCase( const CppTL::Functor0 &setUp, const CppTL::Functor0 &run, const CppTL::Functor0 &tearDown, const std::string &name ) : AbstractTestCase( name ) , setUp_( setUp ) , run_( run ) , tearDown_( tearDown ) { } // An example of member function definition bool Reader::readComment() { Location commentBegin = current_ - 1; Char c = getNextChar(); bool successful = false; if ( c == '*' ) successful = readCStyleComment(); else if ( c == '/' ) successful = readCppStyleComment(); if ( !successful ) return false; if ( collectComments_ ) { CommentPlacement placement = commentBefore; if ( lastValueEnd_ && !containsNewLine( lastValueEnd_, commentBegin ) ) { if ( c != '*' || !containsNewLine( commentBegin, current_ ) ) placement = commentAfterOnSameLine; } addComment( commentBegin, current_, placement ); } return true; }
config.
of their library or include anything of the library (and therefore include the file config.
indirectly).
XYZ_API
macro, where XYZ
is the library macro prefix (see [Macro names]).
forwards.h
header of the library. using namespace
directive in any headers.
Recommendation: Avoid the using namespace
directive in any sources.
Rational: avoid poluting namespaces of sources including that header; enhance code readability by making obvious from which library a type/function originate from.
Rationale: some older compilers only includes function parameters type in the function signature used for link, resulting in very strange bug if cast style function templtes are used.
Example:
// usage: get<int>( value); template<class ValueType> CppTL::Any &get( const CppTL::Any &value ); // BAD // usage: get(value,CppTL::Type<int>()); template<class ValueType> CppTL::Any &get( const CppTL::Any &value, CppTL::Type<ValueType> ); // OK
Template member functions should be avoided as they are not well supported by older compiler (e.g. VC++ 6.0). Usually, a template free functions can be used instead, taking as first parameter an instance of the class type.
Examples:
class Any { // Limited portability template<class ValueType> void set( const ValueType &newValue ); // BAD }; // Most portable, use class any as first parameter template<class ValueType> CppTL::Any &set( CppTL::Any &value, const ValueType &newValue ); // OK
Strongly recommended reading: “Exceptional C++”, by Herb Sutter. This book contains very detailed examples explaining the some of the techniques exposed below (
Rationale: Compilers don’t deal as the one would expect in face of exception specification. They often generate extra code and may disable inlining. See boost guideline for detailed explanation: http://www.boost.org/more/lib_guide.htm#Exception-specification.
Recommendation: Document exception thrown by functions with comment
Example:
double getValueAt( int index ) throw(IndexError); // BAD // / \exception IndexError is raised if the provided index is invalid. double getValueAt( int index ); // GOOD
In the most simple case, resource is memory. A very common usage of this principle is probably for locking/unlocking exclusive lock.
C++ guaranty that the destructor will always be called if the function returns or an exception is thrown.
CppTL::ScopedPtr and CppTL::Mutex::ScopedLockGuard are examples of such objects.
hosts this site. |
Send comments to: CppUnit Developers |