diff options
author | vrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb> | 2015-04-02 10:04:13 +0000 |
---|---|---|
committer | vrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb> | 2015-04-02 10:04:13 +0000 |
commit | ee079994aca5953c741433fa3077a2c565f4ab30 (patch) | |
tree | 930351556baf8c4365766b58268f5ba379785cc2 | |
parent | 87032aea5bf14683d964ecd30bd9d744da975e1b (diff) | |
parent | dccd985e8a0654f71cb5898035b1309bb8e76eb7 (diff) |
Merge xunit branch back into trunk
git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@537 636b058d-ea47-450e-bf9e-a15bfbe3eedb
Former-commit-id: 1d7c35db28bfead8c5f93dde47c5c695e5ec5c68
-rw-r--r-- | CMakeLists.txt | 26 | ||||
-rwxr-xr-x | scripts/check_code_coverage.sh | 40 | ||||
-rw-r--r-- | scripts/cpplint.py | 524 | ||||
-rwxr-xr-x | scripts/cpplint_to_cppcheckxml.py | 66 | ||||
-rw-r--r-- | src/Alpha_shapes/test/Alpha_shapes_unit_test.cpp | 2 | ||||
-rw-r--r-- | src/Alpha_shapes/test/CMakeLists.txt | 26 | ||||
-rw-r--r-- | src/Alpha_shapes/test/README | 4 | ||||
-rw-r--r-- | src/Bottleneck/test/CMakeLists.txt | 32 | ||||
-rw-r--r-- | src/Persistent_cohomology/test/CMakeLists.txt | 44 | ||||
-rw-r--r-- | src/Persistent_cohomology/test/README | 6 | ||||
-rw-r--r-- | src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp | 5 | ||||
-rw-r--r-- | src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp | 5 | ||||
-rw-r--r-- | src/Simplex_tree/test/CMakeLists.txt | 32 | ||||
-rw-r--r-- | src/Simplex_tree/test/README | 4 | ||||
-rw-r--r-- | src/Simplex_tree/test/simplex_tree_unit_test.cpp | 2 | ||||
-rw-r--r-- | src/Skeleton_blocker/test/CMakeLists.txt | 24 |
16 files changed, 536 insertions, 306 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 89440490..f30c1785 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,28 +32,16 @@ endif() find_package(CGAL) # Required programs for unitary tests purpose -FIND_PROGRAM( LCOV_PATH lcov ) -if (LCOV_PATH) - message("lcov found in ${LCOV_PATH}") +FIND_PROGRAM( GCOVR_PATH gcovr ) +if (GCOVR_PATH) + message("gcovr found in ${GCOVR_PATH}") endif() - -FIND_PROGRAM( PYTHON_PATH python ) -if (PYTHON_PATH) - message("python found in ${PYTHON_PATH}") +# Required programs for unitary tests purpose +FIND_PROGRAM( GPROF_PATH gprof ) +if (GPROF_PATH) + message("gprof found in ${GPROF_PATH}") endif() -# Function to add_test cpplint on each header file of the Gudhi module -function(cpplint_add_tests the_directory) - if (PYTHON_PATH) - # Cpplint tests on coding style - file(GLOB files "${the_directory}/*.h" "${the_directory}/*/*.h") - foreach(filename ${files}) - message(${filename}) - add_test("${filename}.cpplint" ${CMAKE_SOURCE_DIR}/scripts/check_google_style.sh ${filename} ${CMAKE_SOURCE_DIR}/scripts/cpplint.py) - endforeach() - endif() -endfunction(cpplint_add_tests) - if(NOT Boost_FOUND) message(FATAL_ERROR "NOTICE: This demo requires Boost and will not be compiled.") diff --git a/scripts/check_code_coverage.sh b/scripts/check_code_coverage.sh deleted file mode 100755 index ef4aeb76..00000000 --- a/scripts/check_code_coverage.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash -#usage bash check_google_style.sh - -# UNITARY TEST DIRECTORY CHECK -ROOT_DIR=.. -UT_DIR_TO_CHECK="$1" -LCOV_DIR=$UT_DIR_TO_CHECK/lcov -COVERAGE_FILE=$LCOV_DIR/coverage.info -LOG_FILE=$LCOV_DIR/coverage.log -MIN_PERCENT=86 - -rm -rf $LCOV_DIR -mkdir $LCOV_DIR - -lcov --capture --directory $UT_DIR_TO_CHECK --no-external --output-file $COVERAGE_FILE 2>&1 | tee -a $LOG_FILE -lcov --summary $COVERAGE_FILE 2>&1 | tee -a $LOG_FILE -genhtml $COVERAGE_FILE --output-directory $UT_DIR_TO_CHECK/lcov -# CLEAN AFTER USE -lcov --directory $UT_DIR_TO_CHECK --zerocounters 2>&1 | tee -a $LOG_FILE - -LINE_PERCENTAGE=`grep "lines......:" $LOG_FILE` -PERC_PER_LINE=${LINE_PERCENTAGE:14:3} - -if [ "$PERC_PER_LINE" -lt "$MIN_PERCENT" ] -then - echo "## Lines not enough covered ($PERC_PER_LINE) in $UT_DIR_TO_CHECK" 2>&1 | tee -a $LOG_FILE - exit 1 -else - FONC_PERCENTAGE=`grep "functions..:" $LOG_FILE` - PERC_PER_FUNC=${FONC_PERCENTAGE:14:3} - - if [ "$PERC_PER_FUNC" -lt "$MIN_PERCENT" ] - then - echo "## Functions not enough covered ($PERC_PER_FUNC) in $UT_DIR_TO_CHECK" 2>&1 | tee -a $LOG_FILE - exit 1 - fi -fi - -echo "Acceptable coverage values (lines:$PERC_PER_LINE% - functions:$PERC_PER_FUNC%) in $UT_DIR_TO_CHECK" 2>&1 | tee -a $LOG_FILE -exit 0 diff --git a/scripts/cpplint.py b/scripts/cpplint.py index 217b7136..0e186e23 100644 --- a/scripts/cpplint.py +++ b/scripts/cpplint.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright (c) 2009 Google Inc. All rights reserved. # @@ -175,71 +175,77 @@ Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...] # If you add a new error message with a new category, add it to the list # here! cpplint_unittest.py should tell you if you forget to do this. _ERROR_CATEGORIES = [ - 'build/class', - 'build/c++11', - 'build/deprecated', - 'build/endif_comment', - 'build/explicit_make_pair', - 'build/forward_decl', - 'build/header_guard', - 'build/include', - 'build/include_alpha', - 'build/include_order', - 'build/include_what_you_use', - 'build/namespaces', - 'build/printf_format', - 'build/storage_class', - 'legal/copyright', - 'readability/alt_tokens', - 'readability/braces', - 'readability/casting', - 'readability/check', - 'readability/constructors', - 'readability/fn_size', - 'readability/function', - 'readability/inheritance', - 'readability/multiline_comment', - 'readability/multiline_string', - 'readability/namespace', - 'readability/nolint', - 'readability/nul', - 'readability/streams', - 'readability/todo', - 'readability/utf8', - 'runtime/arrays', - 'runtime/casting', - 'runtime/explicit', - 'runtime/int', - 'runtime/init', - 'runtime/invalid_increment', - 'runtime/member_string_references', - 'runtime/memset', - 'runtime/indentation_namespace', - 'runtime/operator', - 'runtime/printf', - 'runtime/printf_format', - 'runtime/references', - 'runtime/string', - 'runtime/threadsafe_fn', - 'runtime/vlog', - 'whitespace/blank_line', - 'whitespace/braces', - 'whitespace/comma', - 'whitespace/comments', - 'whitespace/empty_conditional_body', - 'whitespace/empty_loop_body', - 'whitespace/end_of_line', - 'whitespace/ending_newline', - 'whitespace/forcolon', - 'whitespace/indent', - 'whitespace/line_length', - 'whitespace/newline', - 'whitespace/operators', - 'whitespace/parens', - 'whitespace/semicolon', - 'whitespace/tab', - 'whitespace/todo' - ] + 'build/class', + 'build/c++11', + 'build/deprecated', + 'build/endif_comment', + 'build/explicit_make_pair', + 'build/forward_decl', + 'build/header_guard', + 'build/include', + 'build/include_alpha', + 'build/include_order', + 'build/include_what_you_use', + 'build/namespaces', + 'build/printf_format', + 'build/storage_class', + 'legal/copyright', + 'readability/alt_tokens', + 'readability/braces', + 'readability/casting', + 'readability/check', + 'readability/constructors', + 'readability/fn_size', + 'readability/function', + 'readability/inheritance', + 'readability/multiline_comment', + 'readability/multiline_string', + 'readability/namespace', + 'readability/nolint', + 'readability/nul', + 'readability/strings', + 'readability/todo', + 'readability/utf8', + 'runtime/arrays', + 'runtime/casting', + 'runtime/explicit', + 'runtime/int', + 'runtime/init', + 'runtime/invalid_increment', + 'runtime/member_string_references', + 'runtime/memset', + 'runtime/indentation_namespace', + 'runtime/operator', + 'runtime/printf', + 'runtime/printf_format', + 'runtime/references', + 'runtime/string', + 'runtime/threadsafe_fn', + 'runtime/vlog', + 'whitespace/blank_line', + 'whitespace/braces', + 'whitespace/comma', + 'whitespace/comments', + 'whitespace/empty_conditional_body', + 'whitespace/empty_loop_body', + 'whitespace/end_of_line', + 'whitespace/ending_newline', + 'whitespace/forcolon', + 'whitespace/indent', + 'whitespace/line_length', + 'whitespace/newline', + 'whitespace/operators', + 'whitespace/parens', + 'whitespace/semicolon', + 'whitespace/tab', + 'whitespace/todo', + ] + +# These error categories are no longer enforced by cpplint, but for backwards- +# compatibility they may still appear in NOLINT comments. +_LEGACY_ERROR_CATEGORIES = [ + 'readability/streams', + ] # The default state of the category filter. This is overridden by the --filter= # flag. By default all errors are on, so only add here categories that should be @@ -522,7 +528,7 @@ def ParseNolintSuppressions(filename, raw_line, linenum, error): category = category[1:-1] if category in _ERROR_CATEGORIES: _error_suppressions.setdefault(category, set()).add(suppressed_line) - else: + elif category not in _LEGACY_ERROR_CATEGORIES: error(filename, linenum, 'readability/nolint', 5, 'Unknown NOLINT error category: %s' % category) @@ -690,7 +696,7 @@ class _IncludeState(object): # If previous line was a blank line, assume that the headers are # intentionally sorted the way they are. if (self._last_header > header_path and - not Match(r'^\s*$', clean_lines.elided[linenum - 1])): + Match(r'^\s*#\s*include\b', clean_lines.elided[linenum - 1])): return False return True @@ -1246,7 +1252,7 @@ def RemoveMultiLineCommentsFromRange(lines, begin, end): # Having // dummy comments makes the lines non-empty, so we will not get # unnecessary blank line warnings later in the code. for i in range(begin, end): - lines[i] = '// dummy' + lines[i] = '/**/' def RemoveMultiLineComments(filename, lines, error): @@ -1282,12 +1288,14 @@ def CleanseComments(line): class CleansedLines(object): - """Holds 3 copies of all lines with different preprocessing applied to them. + """Holds 4 copies of all lines with different preprocessing applied to them. - 1) elided member contains lines without strings and comments, - 2) lines member contains lines without comments, and + 1) elided member contains lines without strings and comments. + 2) lines member contains lines without comments. 3) raw_lines member contains all the lines without processing. - All these three members are of <type 'list'>, and of the same length. + 4) lines_without_raw_strings member is same as raw_lines, but with C++11 raw + strings removed. + All these members are of <type 'list'>, and of the same length. """ def __init__(self, lines): @@ -1656,15 +1664,17 @@ def GetHeaderGuardCPPVariable(filename): # flymake. filename = re.sub(r'_flymake\.h$', '.h', filename) filename = re.sub(r'/\.flymake/([^/]*)$', r'/\1', filename) - + # Replace 'c++' with 'cpp'. + filename = filename.replace('C++', 'cpp').replace('c++', 'cpp') + fileinfo = FileInfo(filename) file_path_from_root = fileinfo.RepositoryName() if _root: file_path_from_root = re.sub('^' + _root + os.sep, '', file_path_from_root) - return re.sub(r'[-./\s]', '_', file_path_from_root).upper() + '_' + return re.sub(r'[^a-zA-Z0-9]', '_', file_path_from_root).upper() + '_' -def CheckForHeaderGuard(filename, lines, error): +def CheckForHeaderGuard(filename, clean_lines, error): """Checks that the file contains a header guard. Logs an error if no #ifndef header guard is present. For other @@ -1672,7 +1682,7 @@ def CheckForHeaderGuard(filename, lines, error): Args: filename: The name of the C++ header file. - lines: An array of strings, each representing a line of the file. + clean_lines: A CleansedLines instance containing the file. error: The function to call with any errors found. """ @@ -1682,18 +1692,19 @@ def CheckForHeaderGuard(filename, lines, error): # Because this is silencing a warning for a nonexistent line, we # only support the very specific NOLINT(build/header_guard) syntax, # and not the general NOLINT or NOLINT(*) syntax. - for i in lines: + raw_lines = clean_lines.lines_without_raw_strings + for i in raw_lines: if Search(r'//\s*NOLINT\(build/header_guard\)', i): return cppvar = GetHeaderGuardCPPVariable(filename) - ifndef = None + ifndef = '' ifndef_linenum = 0 - define = None - endif = None + define = '' + endif = '' endif_linenum = 0 - for linenum, line in enumerate(lines): + for linenum, line in enumerate(raw_lines): linesplit = line.split() if len(linesplit) >= 2: # find the first occurrence of #ifndef and #define, save arg @@ -1708,18 +1719,12 @@ def CheckForHeaderGuard(filename, lines, error): endif = line endif_linenum = linenum - if not ifndef: + if not ifndef or not define or ifndef != define: error(filename, 0, 'build/header_guard', 5, 'No #ifndef header guard found, suggested CPP variable is: %s' % cppvar) return - if not define: - error(filename, 0, 'build/header_guard', 5, - 'No #define header guard found, suggested CPP variable is: %s' % - cppvar) - return - # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__ # for backward compatibility. if ifndef != cppvar: @@ -1727,26 +1732,69 @@ def CheckForHeaderGuard(filename, lines, error): if ifndef != cppvar + '_': error_level = 5 - ParseNolintSuppressions(filename, lines[ifndef_linenum], ifndef_linenum, + ParseNolintSuppressions(filename, raw_lines[ifndef_linenum], ifndef_linenum, error) error(filename, ifndef_linenum, 'build/header_guard', error_level, '#ifndef header guard has wrong style, please use: %s' % cppvar) - if define != ifndef: - error(filename, 0, 'build/header_guard', 5, - '#ifndef and #define don\'t match, suggested CPP variable is: %s' % - cppvar) + # Check for "//" comments on endif line. + ParseNolintSuppressions(filename, raw_lines[endif_linenum], endif_linenum, + error) + match = Match(r'#endif\s*//\s*' + cppvar + r'(_)?\b', endif) + if match: + if match.group(1) == '_': + # Issue low severity warning for deprecated double trailing underscore + error(filename, endif_linenum, 'build/header_guard', 0, + '#endif line should be "#endif // %s"' % cppvar) return - if endif != ('#endif // %s' % cppvar): - error_level = 0 - if endif != ('#endif // %s' % (cppvar + '_')): - error_level = 5 + # Didn't find the corresponding "//" comment. If this file does not + # contain any "//" comments at all, it could be that the compiler + # only wants "/**/" comments, look for those instead. + no_single_line_comments = True + for i in xrange(1, len(raw_lines) - 1): + line = raw_lines[i] + if Match(r'^(?:(?:\'(?:\.|[^\'])*\')|(?:"(?:\.|[^"])*")|[^\'"])*//', line): + no_single_line_comments = False + break + + if no_single_line_comments: + match = Match(r'#endif\s*/\*\s*' + cppvar + r'(_)?\s*\*/', endif) + if match: + if match.group(1) == '_': + # Low severity warning for double trailing underscore + error(filename, endif_linenum, 'build/header_guard', 0, + '#endif line should be "#endif /* %s */"' % cppvar) + return + + # Didn't find anything + error(filename, endif_linenum, 'build/header_guard', 5, + '#endif line should be "#endif // %s"' % cppvar) - ParseNolintSuppressions(filename, lines[endif_linenum], endif_linenum, - error) - error(filename, endif_linenum, 'build/header_guard', error_level, - '#endif line should be "#endif // %s"' % cppvar) + +def CheckHeaderFileIncluded(filename, include_state, error): + """Logs an error if a .cc file does not include its header.""" + + # Do not check test files + if filename.endswith('_test.cc') or filename.endswith('_unittest.cc'): + return + + fileinfo = FileInfo(filename) + headerfile = filename[0:len(filename) - 2] + 'h' + if not os.path.exists(headerfile): + return + headername = FileInfo(headerfile).RepositoryName() + first_include = 0 + for section_list in include_state.include_list: + for f in section_list: + if headername in f[0] or f[0] in headername: + return + if not first_include: + first_include = f[1] + + error(filename, first_include, 'build/include', 5, + '%s should include its header file %s' % (fileinfo.RepositoryName(), + headername)) def CheckForBadCharacters(filename, lines, error): @@ -2042,6 +2090,23 @@ class _ClassInfo(_BlockInfo): self.is_derived = True def CheckEnd(self, filename, clean_lines, linenum, error): + # If there is a DISALLOW macro, it should appear near the end of + # the class. + seen_last_thing_in_class = False + for i in xrange(linenum - 1, self.starting_linenum, -1): + match = Search( + r'\b(DISALLOW_COPY_AND_ASSIGN|DISALLOW_IMPLICIT_CONSTRUCTORS)\(' + + self.name + r'\)', + clean_lines.elided[i]) + if match: + if seen_last_thing_in_class: + error(filename, i, 'readability/constructors', 3, + match.group(1) + ' should be the last thing in the class') + break + + if not Match(r'^\s*$', clean_lines.elided[i]): + seen_last_thing_in_class = True + # Check that closing brace is aligned with beginning of the class. # Only do this if the closing brace is indented by only whitespaces. # This means we will not check single-line class definitions. @@ -2722,7 +2787,8 @@ def CheckSpacingForFunctionCall(filename, clean_lines, linenum, error): 'Extra space after (') if (Search(r'\w\s+\(', fncall) and not Search(r'#\s*define|typedef|using\s+\w+\s*=', fncall) and - not Search(r'\w\s+\((\w+::)*\*\w+\)\(', fncall)): + not Search(r'\w\s+\((\w+::)*\*\w+\)\(', fncall) and + not Search(r'\bcase\s+\(', fncall)): # TODO(unknown): Space after an operator function seem to be a common # error, silence those for now by restricting them to highest verbosity. if Search(r'\boperator_*\b', line): @@ -2892,11 +2958,14 @@ def CheckComment(line, filename, linenum, next_line_start, error): 'TODO(my_username) should be followed by a space') # If the comment contains an alphanumeric character, there - # should be a space somewhere between it and the //. - if Match(r'//[^ ]*\w', comment): + # should be a space somewhere between it and the // unless + # it's a /// or //! Doxygen comment. + if (Match(r'//[^ ]*\w', comment) and + not Match(r'(///|//\!)(\s+|$)', comment)): error(filename, linenum, 'whitespace/comments', 4, 'Should have a space between // and comment') + def CheckAccess(filename, clean_lines, linenum, nesting_state, error): """Checks for improper use of DISALLOW* macros. @@ -3083,7 +3152,12 @@ def CheckOperatorSpacing(filename, clean_lines, linenum, error): # Otherwise not. Note we only check for non-spaces on *both* sides; # sometimes people put non-spaces on one side when aligning ='s among # many lines (not that this is behavior that I approve of...) - if Search(r'[\w.]=[\w.]', line) and not Search(r'\b(if|while) ', line): + if ((Search(r'[\w.]=', line) or + Search(r'=[\w.]', line)) + and not Search(r'\b(if|while|for) ', line) + # Operators taken from [lex.operators] in C++11 standard. + and not Search(r'(>=|<=|==|!=|&=|\^=|\|=|\+=|\*=|\/=|\%=)', line) + and not Search(r'operator=', line)): error(filename, linenum, 'whitespace/operators', 4, 'Missing spaces around =') @@ -3135,9 +3209,8 @@ def CheckOperatorSpacing(filename, clean_lines, linenum, error): # # We also allow operators following an opening parenthesis, since # those tend to be macros that deal with operators. - match = Search(r'(operator|\S)(?:L|UL|ULL|l|ul|ull)?<<([^\s,=])', line) - if (match and match.group(1) != '(' and - not (match.group(1).isdigit() and match.group(2).isdigit()) and + match = Search(r'(operator|[^\s(<])(?:L|UL|ULL|l|ul|ull)?<<([^\s,=<])', line) + if (match and not (match.group(1).isdigit() and match.group(2).isdigit()) and not (match.group(1) == 'operator' and match.group(2) == ';')): error(filename, linenum, 'whitespace/operators', 3, 'Missing spaces around <<') @@ -3255,7 +3328,7 @@ def CheckBracesSpacing(filename, clean_lines, linenum, error): # an initializer list, for instance), you should have spaces before your # braces. And since you should never have braces at the beginning of a line, # this is an easy test. - match = Match(r'^(.*[^ ({]){', line) + match = Match(r'^(.*[^ ({>]){', line) if match: # Try a bit harder to check for brace initialization. This # happens in one of the following forms: @@ -3355,13 +3428,14 @@ def IsTemplateParameterList(clean_lines, linenum, column): return False -def IsRValueType(clean_lines, nesting_state, linenum, column): +def IsRValueType(typenames, clean_lines, nesting_state, linenum, column): """Check if the token ending on (linenum, column) is a type. Assumes that text to the right of the column is "&&" or a function name. Args: + typenames: set of type names from template-argument-list. clean_lines: A CleansedLines instance containing the file. nesting_state: A NestingState instance which maintains information about the current stack of nested blocks being parsed. @@ -3385,7 +3459,7 @@ def IsRValueType(clean_lines, nesting_state, linenum, column): if Match(r'&&\s*(?:[>,]|\.\.\.)', suffix): return True - # Check for simple type and end of templates: + # Check for known types and end of templates: # int&& variable # vector<int>&& variable # @@ -3393,9 +3467,10 @@ def IsRValueType(clean_lines, nesting_state, linenum, column): # recognize pointer and reference types: # int* Function() # int& Function() - if match.group(2) in ['char', 'char16_t', 'char32_t', 'wchar_t', 'bool', - 'short', 'int', 'long', 'signed', 'unsigned', - 'float', 'double', 'void', 'auto', '>', '*', '&']: + if (match.group(2) in typenames or + match.group(2) in ['char', 'char16_t', 'char32_t', 'wchar_t', 'bool', + 'short', 'int', 'long', 'signed', 'unsigned', + 'float', 'double', 'void', 'auto', '>', '*', '&']): return True # If we see a close parenthesis, look for decltype on the other side. @@ -3528,7 +3603,7 @@ def IsRValueType(clean_lines, nesting_state, linenum, column): # Something else. Check that tokens to the left look like # return_type function_name - match_func = Match(r'^(.*)\s+\w(?:\w|::)*(?:<[^<>]*>)?\s*$', + match_func = Match(r'^(.*\S.*)\s+\w(?:\w|::)*(?:<[^<>]*>)?\s*$', match_symbol.group(1)) if match_func: # Check for constructors, which don't have return types. @@ -3538,7 +3613,7 @@ def IsRValueType(clean_lines, nesting_state, linenum, column): if (implicit_constructor and implicit_constructor.group(1) == implicit_constructor.group(2)): return True - return IsRValueType(clean_lines, nesting_state, linenum, + return IsRValueType(typenames, clean_lines, nesting_state, linenum, len(match_func.group(1))) # Nothing before the function name. If this is inside a block scope, @@ -3576,12 +3651,13 @@ def IsDeletedOrDefault(clean_lines, linenum): return Match(r'\s*=\s*(?:delete|default)\b', close_line[close_paren:]) -def IsRValueAllowed(clean_lines, linenum): +def IsRValueAllowed(clean_lines, linenum, typenames): """Check if RValue reference is allowed on a particular line. Args: clean_lines: A CleansedLines instance containing the file. linenum: The number of the line to check. + typenames: set of type names from template-argument-list. Returns: True if line is within the region where RValue references are allowed. """ @@ -3602,7 +3678,7 @@ def IsRValueAllowed(clean_lines, linenum): return IsDeletedOrDefault(clean_lines, linenum) # Allow constructors - match = Match(r'\s*([\w<>]+)\s*::\s*([\w<>]+)\s*\(', line) + match = Match(r'\s*(?:[\w<>]+::)*([\w<>]+)\s*::\s*([\w<>]+)\s*\(', line) if match and match.group(1) == match.group(2): return IsDeletedOrDefault(clean_lines, linenum) if Search(r'\b(?:explicit|inline)\s+[\w<>]+\s*\(', line): @@ -3615,7 +3691,86 @@ def IsRValueAllowed(clean_lines, linenum): if Match(r'^\s*$', previous_line) or Search(r'[{}:;]\s*$', previous_line): return IsDeletedOrDefault(clean_lines, linenum) - return False + # Reject types not mentioned in template-argument-list + while line: + match = Match(r'^.*?(\w+)\s*&&(.*)$', line) + if not match: + break + if match.group(1) not in typenames: + return False + line = match.group(2) + + # All RValue types that were in template-argument-list should have + # been removed by now. Those were allowed, assuming that they will + # be forwarded. + # + # If there are no remaining RValue types left (i.e. types that were + # not found in template-argument-list), flag those as not allowed. + return line.find('&&') < 0 + + +def GetTemplateArgs(clean_lines, linenum): + """Find list of template arguments associated with this function declaration. + + Args: + clean_lines: A CleansedLines instance containing the file. + linenum: Line number containing the start of the function declaration, + usually one line after the end of the template-argument-list. + Returns: + Set of type names, or empty set if this does not appear to have + any template parameters. + """ + # Find start of function + func_line = linenum + while func_line > 0: + line = clean_lines.elided[func_line] + if Match(r'^\s*$', line): + return set() + if line.find('(') >= 0: + break + func_line -= 1 + if func_line == 0: + return set() + + # Collapse template-argument-list into a single string + argument_list = '' + match = Match(r'^(\s*template\s*)<', clean_lines.elided[func_line]) + if match: + # template-argument-list on the same line as function name + start_col = len(match.group(1)) + _, end_line, end_col = CloseExpression(clean_lines, func_line, start_col) + if end_col > -1 and end_line == func_line: + start_col += 1 # Skip the opening bracket + argument_list = clean_lines.elided[func_line][start_col:end_col] + + elif func_line > 1: + # template-argument-list one line before function name + match = Match(r'^(.*)>\s*$', clean_lines.elided[func_line - 1]) + if match: + end_col = len(match.group(1)) + _, start_line, start_col = ReverseCloseExpression( + clean_lines, func_line - 1, end_col) + if start_col > -1: + start_col += 1 # Skip the opening bracket + while start_line < func_line - 1: + argument_list += clean_lines.elided[start_line][start_col:] + start_col = 0 + start_line += 1 + argument_list += clean_lines.elided[func_line - 1][start_col:end_col] + + if not argument_list: + return set() + + # Extract type names + typenames = set() + while True: + match = Match(r'^[,\s]*(?:typename|class)(?:\.\.\.)?\s+(\w+)(.*)$', + argument_list) + if not match: + break + typenames.add(match.group(1)) + argument_list = match.group(2) + return typenames def CheckRValueReference(filename, clean_lines, linenum, nesting_state, error): @@ -3643,9 +3798,10 @@ def CheckRValueReference(filename, clean_lines, linenum, nesting_state, error): # Either poorly formed && or an rvalue reference, check the context # to get a more accurate error message. Mostly we want to determine # if what's to the left of "&&" is a type or not. + typenames = GetTemplateArgs(clean_lines, linenum) and_pos = len(match.group(1)) - if IsRValueType(clean_lines, nesting_state, linenum, and_pos): - if not IsRValueAllowed(clean_lines, linenum): + if IsRValueType(typenames, clean_lines, nesting_state, linenum, and_pos): + if not IsRValueAllowed(clean_lines, linenum, typenames): error(filename, linenum, 'build/c++11', 3, 'RValue references are an unapproved C++ feature.') else: @@ -3926,8 +4082,10 @@ def CheckTrailingSemicolon(filename, clean_lines, linenum, error): # semicolons, while the downside for getting the blacklist wrong # would result in compile errors. # - # In addition to macros, we also don't want to warn on compound - # literals and lambdas. + # In addition to macros, we also don't want to warn on + # - Compound literals + # - Lambdas + # - alignas specifier with anonymous structs: closing_brace_pos = match.group(1).rfind(')') opening_parenthesis = ReverseCloseExpression( clean_lines, linenum, closing_brace_pos) @@ -3941,6 +4099,7 @@ def CheckTrailingSemicolon(filename, clean_lines, linenum, error): 'EXCLUSIVE_LOCKS_REQUIRED', 'SHARED_LOCKS_REQUIRED', 'LOCKS_EXCLUDED', 'INTERFACE_DEF')) or (func and not Search(r'\boperator\s*\[\s*\]', func.group(1))) or + Search(r'\b(?:struct|union)\s+alignas\s*$', line_prefix) or Search(r'\s+=\s*$', line_prefix)): match = None if (match and @@ -4484,6 +4643,10 @@ def CheckIncludeLine(filename, clean_lines, linenum, include_state, error): error(filename, linenum, 'build/include', 4, '"%s" already included at %s:%s' % (include, filename, duplicate_line)) + elif (include.endswith('.cc') and + os.path.dirname(fileinfo.RepositoryName()) != os.path.dirname(include)): + error(filename, linenum, 'build/include', 4, + 'Do not include .cc files from other packages') elif not _THIRD_PARTY_HEADERS_PATTERN.match(include): include_state.include_list[-1].append((include, linenum)) @@ -4511,20 +4674,6 @@ def CheckIncludeLine(filename, clean_lines, linenum, include_state, error): 'Include "%s" not in alphabetical order' % include) include_state.SetLastHeader(canonical_include) - # Look for any of the stream classes that are part of standard C++. - match = _RE_PATTERN_INCLUDE.match(line) - if match: - include = match.group(2) - if Match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include): - # Many unit tests use cout, so we exempt them. - if not _IsTestFilename(filename): - # Suggest a different header for ostream - if include == 'ostream': - error(filename, linenum, 'readability/streams', 3, - 'For logging, include "base/logging.h" instead of <ostream>.') - else: - error(filename, linenum, 'readability/streams', 3, - 'Streams are highly discouraged.') def _GetTextInside(text, start_pattern): @@ -4755,25 +4904,6 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension, 'Do not use variable-length arrays. Use an appropriately named ' "('k' followed by CamelCase) compile-time constant for the size.") - # If DISALLOW_COPY_AND_ASSIGN DISALLOW_IMPLICIT_CONSTRUCTORS is present, - # then it should be the last thing in the class declaration. - match = Match( - (r'\s*' - r'(DISALLOW_(COPY_AND_ASSIGN|IMPLICIT_CONSTRUCTORS))' - r'\(.*\);$'), - line) - if match and linenum + 1 < clean_lines.NumLines(): - next_line = clean_lines.elided[linenum + 1] - # We allow some, but not all, declarations of variables to be present - # in the statement that defines the class. The [\w\*,\s]* fragment of - # the regular expression below allows users to declare instances of - # the class or pointers to instances, but not less common types such - # as function pointers or arrays. It's a tradeoff between allowing - # reasonable code and avoiding trying to parse more C++ using regexps. - if not Search(r'^\s*}[\w\*,\s]*;', next_line): - error(filename, linenum, 'readability/constructors', 3, - match.group(1) + ' should be the last thing in the class') - # Check for use of unnamed namespaces in header files. Registration # macros are typically OK, so we allow use of "namespace {" on lines # that end with backslashes. @@ -4889,6 +5019,22 @@ def IsDerivedFunction(clean_lines, linenum): return False +def IsOutOfLineMethodDefinition(clean_lines, linenum): + """Check if current line contains an out-of-line method definition. + + Args: + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + Returns: + True if current line contains an out-of-line method definition. + """ + # Scan back a few lines for start of current function + for i in xrange(linenum, max(-1, linenum - 10), -1): + if Match(r'^([^()]*\w+)\(', clean_lines.elided[i]): + return Match(r'^[^()]*\w+::\w+\(', clean_lines.elided[i]) is not None + return False + + def IsInitializerList(clean_lines, linenum): """Check if current line is inside constructor initializer list. @@ -4957,6 +5103,11 @@ def CheckForNonConstReference(filename, clean_lines, linenum, if IsDerivedFunction(clean_lines, linenum): return + # Don't warn on out-of-line method definitions, as we would warn on the + # in-line declaration, if it isn't marked with 'override'. + if IsOutOfLineMethodDefinition(clean_lines, linenum): + return + # Long type names may be broken across multiple lines, usually in one # of these forms: # LongType @@ -5152,9 +5303,9 @@ def CheckCasts(filename, clean_lines, linenum, error): # This is not a cast: # reference_type&(int* function_param); match = Search( - r'(?:[^\w]&\(([^)]+)\)[\w(])|' + r'(?:[^\w]&\(([^)*][^)]*)\)[\w(])|' r'(?:[^\w]&(static|dynamic|down|reinterpret)_cast\b)', line) - if match and match.group(1) != '*': + if match: # Try a better error message when the & is bound to something # dereferenced by the casted pointer, as opposed to the casted # pointer itself. @@ -5235,6 +5386,7 @@ def CheckCStyleCast(filename, clean_lines, linenum, cast_type, pattern, error): # ExceptionMember(int) throw (...); # ExceptionMember(int) throw (...) { # PureVirtual(int) = 0; + # [](int) -> bool { # # These are functions of some sort, where the compiler would be fine # if they had named parameters, but people often omit those @@ -5246,7 +5398,7 @@ def CheckCStyleCast(filename, clean_lines, linenum, cast_type, pattern, error): # <TemplateArgument(int)>; # <(FunctionPointerTemplateArgument)(int)>; remainder = line[match.end(0):] - if Match(r'^\s*(?:;|const\b|throw\b|final\b|override\b|[=>{),])', + if Match(r'^\s*(?:;|const\b|throw\b|final\b|override\b|[=>{),]|->)', remainder): # Looks like an unnamed parameter. @@ -5335,6 +5487,7 @@ _HEADERS_CONTAINING_TEMPLATES = ( ('<set>', ('set', 'multiset',)), ('<stack>', ('stack',)), ('<string>', ('char_traits', 'basic_string',)), + ('<tuple>', ('tuple',)), ('<utility>', ('pair',)), ('<vector>', ('vector',)), @@ -5602,9 +5755,21 @@ def CheckRedundantVirtual(filename, clean_lines, linenum, error): """ # Look for "virtual" on current line. line = clean_lines.elided[linenum] - virtual = Match(r'^(.*\bvirtual\b)', line) + virtual = Match(r'^(.*)(\bvirtual\b)(.*)$', line) if not virtual: return + # Ignore "virtual" keywords that are near access-specifiers. These + # are only used in class base-specifier and do not apply to member + # functions. + if (Search(r'\b(public|protected|private)\s+$', virtual.group(1)) or + Match(r'^\s+(public|protected|private)\b', virtual.group(3))): + return + + # Ignore the "virtual" keyword from virtual base classes. Usually + # there is a column on the same line in these cases (virtual base + # classes are rare in google3 because multiple inheritance is rare). + if Match(r'^.*[^:]:[^:].*$', line): return + # Look for the next opening parenthesis. This is the start of the # parameter list (possibly on the next line shortly after virtual). # TODO(unknown): doesn't work if there are virtual functions with @@ -5612,7 +5777,7 @@ def CheckRedundantVirtual(filename, clean_lines, linenum, error): # that this is rare. end_col = -1 end_line = -1 - start_col = len(virtual.group(1)) + start_col = len(virtual.group(2)) for start_line in xrange(linenum, min(linenum + 3, clean_lines.NumLines())): line = clean_lines.elided[start_line][start_col:] parameter_list = Match(r'^([^(]*)\(', line) @@ -5652,9 +5817,21 @@ def CheckRedundantOverrideOrFinal(filename, clean_lines, linenum, error): linenum: The number of the line to check. error: The function to call with any errors found. """ - # Check that at most one of "override" or "final" is present, not both + # Look for closing parenthesis nearby. We need one to confirm where + # the declarator ends and where the virt-specifier starts to avoid + # false positives. line = clean_lines.elided[linenum] - if Search(r'\boverride\b', line) and Search(r'\bfinal\b', line): + declarator_end = line.rfind(')') + if declarator_end >= 0: + fragment = line[declarator_end:] + else: + if linenum > 1 and clean_lines.elided[linenum - 1].rfind(')') >= 0: + fragment = line + else: + return + + # Check that at most one of "override" or "final" is present, not both + if Search(r'\boverride\b', fragment) and Search(r'\bfinal\b', fragment): error(filename, linenum, 'readability/inheritance', 4, ('"override" is redundant since function is ' 'already declared as "final"')) @@ -5809,9 +5986,6 @@ def FlagCxx11Features(filename, clean_lines, linenum, error): # type_traits 'alignment_of', 'aligned_union', - - # utility - 'forward', ): if Search(r'\bstd::%s\b' % top_name, line): error(filename, linenum, 'build/c++11', 5, @@ -5846,11 +6020,12 @@ def ProcessFileData(filename, file_extension, lines, error, CheckForCopyright(filename, lines, error) - if file_extension == 'h': - CheckForHeaderGuard(filename, lines, error) - RemoveMultiLineComments(filename, lines, error) clean_lines = CleansedLines(lines) + + if file_extension == 'h': + CheckForHeaderGuard(filename, clean_lines, error) + for line in xrange(clean_lines.NumLines()): ProcessLine(filename, file_extension, clean_lines, line, include_state, function_state, nesting_state, error, @@ -5859,6 +6034,10 @@ def ProcessFileData(filename, file_extension, lines, error, nesting_state.CheckCompletedBlocks(filename, error) CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error) + + # Check that the .cc file has included its header if it exists. + if file_extension == 'cc': + CheckHeaderFileIncluded(filename, include_state, error) # We check here rather than inside ProcessLine so that we see raw # lines rather than "cleaned" lines. @@ -6136,8 +6315,9 @@ def main(): for filename in filenames: ProcessFile(filename, _cpplint_state.verbose_level) _cpplint_state.PrintErrorCounts() - print("erreur=", _cpplint_state.error_count) - sys.exit(_cpplint_state.error_count) + # VR fix - otherwise all cpplint are errors from script launch + # sys.exit(_cpplint_state.error_count > 0) + sys.exit(0) if __name__ == '__main__': diff --git a/scripts/cpplint_to_cppcheckxml.py b/scripts/cpplint_to_cppcheckxml.py new file mode 100755 index 00000000..7a3813c7 --- /dev/null +++ b/scripts/cpplint_to_cppcheckxml.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python + +# Convert output from Google's cpplint.py to the cppcheck XML format for +# consumption by the Jenkins cppcheck plugin. + +# Reads from stdin and writes to stderr (to mimic cppcheck) + + +import sys +import re +import cgi + +def cpplint_score_to_cppcheck_severity(score): + # I'm making this up + if score == 1: + return 'style' + elif score == 2: + return 'style' + elif score == 3: + return 'warning' + elif score == 4: + return 'warning' + elif score == 5: + return 'error' + + +def parse(): + # TODO: do this properly, using the xml module. + # Write header + sys.stderr.write('''<?xml version="1.0" encoding="UTF-8"?>\n''') + # VR : sys.stderr.write('''<results>\n''') + # Add from VR + [ + sys.stderr.write('''<results version="2">\n''') + sys.stderr.write(''' <cppcheck version="1.63"/>\n''') + sys.stderr.write(''' <errors>\n''') + # -] + + # Do line-by-line conversion + r = re.compile('([^:]*):([0-9]*): ([^\[]*)\[([^\]]*)\] \[([0-9]*)\].*') + + for l in sys.stdin.readlines(): + m = r.match(l.strip()) + if not m: + continue + g = m.groups() + if len(g) != 5: + continue + fname, lineno, msg, label, score = g + severity = cpplint_score_to_cppcheck_severity(int(score)) + # VR : sys.stderr.write('''<error file="%s" line="%s" id="%s" severity="%s" msg="%s"/>\n'''%(fname, lineno, label, severity, msg)) + # Add from VR + [ + sys.stderr.write(''' <error id="%s" severity="%s" msg="%s">\n'''%(label, severity, cgi.escape(msg,quote=True))) + sys.stderr.write(''' <location file="%s" line="%s"/>\n'''%(fname, lineno)) + sys.stderr.write(''' </error>\n''') + # -] + + # Write footer + # Add from VR + [ + sys.stderr.write(''' </errors>\n''') + # -] + sys.stderr.write('''</results>\n''') + + +if __name__ == '__main__': + parse() + diff --git a/src/Alpha_shapes/test/Alpha_shapes_unit_test.cpp b/src/Alpha_shapes/test/Alpha_shapes_unit_test.cpp index a90704b6..b4c32321 100644 --- a/src/Alpha_shapes/test/Alpha_shapes_unit_test.cpp +++ b/src/Alpha_shapes/test/Alpha_shapes_unit_test.cpp @@ -20,7 +20,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#define BOOST_TEST_MODULE alpha_shapes +#define BOOST_TEST_MODULE alpha_shapes test #include <boost/test/included/unit_test.hpp> #include <boost/system/error_code.hpp> #include <boost/chrono/thread_clock.hpp> diff --git a/src/Alpha_shapes/test/CMakeLists.txt b/src/Alpha_shapes/test/CMakeLists.txt index a48c1a8f..7d61a3dd 100644 --- a/src/Alpha_shapes/test/CMakeLists.txt +++ b/src/Alpha_shapes/test/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 2.6) -project(GUDHIAlphaShapesTest) +project(GUDHIAlphaShapesUT) # need CGAL 4.6 # cmake -DCGAL_DIR=~/workspace/CGAL-4.6-beta1 ../../.. @@ -15,10 +15,27 @@ if(CGAL_FOUND) include( ${EIGEN3_USE_FILE} ) include_directories (BEFORE "../../include") + if (GCOVR_PATH) + # for gcovr to make coverage reports - Corbera Jenkins plugin + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fprofile-arcs -ftest-coverage") + endif() + if (GPROF_PATH) + # for gprof to make coverage reports - Jenkins + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pg") + endif() + add_definitions(-DDEBUG_TRACES) - add_executable ( AlphaShapesUnitTest Alpha_shapes_unit_test.cpp ) - target_link_libraries(AlphaShapesUnitTest ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) - add_test(AlphaShapesUnitTest ${CMAKE_CURRENT_BINARY_DIR}/AlphaShapesUnitTest) + add_executable ( AlphaShapesUT Alpha_shapes_unit_test.cpp ) + target_link_libraries(AlphaShapesUT ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) + add_test(NAME AlphaShapesUT + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/AlphaShapesUT + # XML format for Jenkins xUnit plugin + --log_format=XML --log_sink=${CMAKE_SOURCE_DIR}/AlphaShapesUT.xml --log_level=test_suite --report_level=no) + else() message(WARNING "Eigen3 not found. Version 3.1.0 is required for Alpha shapes feature.") @@ -28,4 +45,3 @@ if(CGAL_FOUND) endif () endif() -cpplint_add_tests("${CMAKE_SOURCE_DIR}/src/Alpha_shapes/include/gudhi") diff --git a/src/Alpha_shapes/test/README b/src/Alpha_shapes/test/README index 244a2b84..cddd46ca 100644 --- a/src/Alpha_shapes/test/README +++ b/src/Alpha_shapes/test/README @@ -1,12 +1,14 @@ To compile: *********** +cd /path-to-gudhi/ cmake . +cd /path-to-test/ make To launch with details: *********************** -./AlphaShapesUnitTest --report_level=detailed --log_level=all +./AlphaShapesUT --report_level=detailed --log_level=all ==> echo $? returns 0 in case of success (non-zero otherwise) diff --git a/src/Bottleneck/test/CMakeLists.txt b/src/Bottleneck/test/CMakeLists.txt index 7044372e..3dfd80cd 100644 --- a/src/Bottleneck/test/CMakeLists.txt +++ b/src/Bottleneck/test/CMakeLists.txt @@ -1,21 +1,25 @@ cmake_minimum_required(VERSION 2.6) -project(GUDHIBottleneckUnitTest) +project(GUDHIBottleneckUT) -if(NOT MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} --coverage") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} --coverage") +if (GCOVR_PATH) + # for gcovr to make coverage reports - Corbera Jenkins plugin + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fprofile-arcs -ftest-coverage") +endif() +if (GPROF_PATH) + # for gprof to make coverage reports - Jenkins + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pg") endif() -add_executable ( BottleneckUnitTest bottleneck_unit_test.cpp ) -target_link_libraries(BottleneckUnitTest ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) +add_executable ( BottleneckUT bottleneck_unit_test.cpp ) +target_link_libraries(BottleneckUT ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) # Unitary tests -add_test(BottleneckUnitTest ${CMAKE_CURRENT_BINARY_DIR}/BottleneckUnitTest) - -if (LCOV_PATH) - # Lcov code coverage of unitary test - add_test(src/Bottleneck/lcov/coverage.log ${CMAKE_SOURCE_DIR}/scripts/check_code_coverage.sh ${CMAKE_SOURCE_DIR}/src/Bottleneck) -endif() +add_test(NAME BottleneckUT + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/BottleneckUT + # XML format for Jenkins xUnit plugin + --log_format=XML --log_sink=${CMAKE_SOURCE_DIR}/BottleneckUT.xml --log_level=test_suite --report_level=no) -cpplint_add_tests("${CMAKE_SOURCE_DIR}/src/Bottleneck/include/gudhi") diff --git a/src/Persistent_cohomology/test/CMakeLists.txt b/src/Persistent_cohomology/test/CMakeLists.txt index 9dc19251..ed63a6ac 100644 --- a/src/Persistent_cohomology/test/CMakeLists.txt +++ b/src/Persistent_cohomology/test/CMakeLists.txt @@ -1,29 +1,39 @@ cmake_minimum_required(VERSION 2.6) -project(GUDHITestSimplexTree) +project(GUDHIPersistentCohomologyUT) -if(NOT MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} --coverage") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} --coverage") +if (GCOVR_PATH) + # for gcovr to make coverage reports - Corbera Jenkins plugin + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fprofile-arcs -ftest-coverage") +endif() +if (GPROF_PATH) + # for gprof to make coverage reports - Jenkins + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pg") endif() -add_executable ( persistent_cohomology_unit_test persistent_cohomology_unit_test.cpp ) -target_link_libraries(persistent_cohomology_unit_test ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) +add_executable ( PersistentCohomologyUT persistent_cohomology_unit_test.cpp ) +target_link_libraries(PersistentCohomologyUT ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) # Unitary tests -add_test(persistent_cohomology_unit_test ${CMAKE_CURRENT_BINARY_DIR}/persistent_cohomology_unit_test ${CMAKE_SOURCE_DIR}/src/Persistent_cohomology/test/simplex_tree_file_for_unit_test.txt) +add_test(NAME PersistentCohomologyUT + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/PersistentCohomologyUT + ${CMAKE_SOURCE_DIR}/src/Persistent_cohomology/test/simplex_tree_file_for_unit_test.txt + # XML format for Jenkins xUnit plugin + --log_format=XML --log_sink=${CMAKE_SOURCE_DIR}/PersistentCohomologyUT.xml --log_level=test_suite --report_level=no) if(GMPXX_FOUND AND GMP_FOUND) - add_executable ( persistent_cohomology_unit_test_multi_field persistent_cohomology_unit_test_multi_field.cpp ) - target_link_libraries(persistent_cohomology_unit_test_multi_field ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES}) + add_executable ( PersistentCohomologyMultiFieldUT persistent_cohomology_unit_test_multi_field.cpp ) + target_link_libraries(PersistentCohomologyMultiFieldUT ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES}) - # Unitary tests - add_test(persistent_cohomology_unit_test_multi_field ${CMAKE_CURRENT_BINARY_DIR}/persistent_cohomology_unit_test_multi_field ${CMAKE_SOURCE_DIR}/src/Persistent_cohomology/test/simplex_tree_file_for_multi_field_unit_test.txt) -endif() + # Unitary tests + add_test(NAME PersistentCohomologyMultiFieldUT + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/PersistentCohomologyMultiFieldUT + ${CMAKE_SOURCE_DIR}/src/Persistent_cohomology/test/simplex_tree_file_for_multi_field_unit_test.txt + # XML format for Jenkins xUnit plugin + --log_format=XML --log_sink=${CMAKE_SOURCE_DIR}/PersistentCohomologyMultiFieldUT.xml --log_level=test_suite --report_level=no) -if (LCOV_PATH) - # Lcov code coverage of unitary test - add_test(src/Persistent_cohomology/lcov/coverage.log ${CMAKE_SOURCE_DIR}/scripts/check_code_coverage.sh ${CMAKE_SOURCE_DIR}/src/Persistent_cohomology) endif() -cpplint_add_tests("${CMAKE_SOURCE_DIR}/src/Persistent_cohomology/include/gudhi") diff --git a/src/Persistent_cohomology/test/README b/src/Persistent_cohomology/test/README index ddceac63..6c64b5fe 100644 --- a/src/Persistent_cohomology/test/README +++ b/src/Persistent_cohomology/test/README @@ -1,7 +1,9 @@ To compile: *********** +cd /path-to-gudhi/ cmake . +cd /path-to-test/ make To launch with details: @@ -9,13 +11,13 @@ To launch with details: SINGLE FIELD ------------ -./persistent_cohomology_unit_test simplex_tree_file_for_unit_test.txt --report_level=detailed --log_level=all +./PersistentCohomologyUT simplex_tree_file_for_unit_test.txt --report_level=detailed --log_level=all ==> echo $? returns 0 in case of success (non-zero otherwise) MULTI FIELD ----------- -./persistent_cohomology_unit_test_multi_field simplex_tree_file_for_multi_field_unit_test.txt --report_level=detailed --log_level=all +./PersistentCohomologyMultiFieldUT simplex_tree_file_for_multi_field_unit_test.txt --report_level=detailed --log_level=all ==> echo $? returns 0 in case of success (non-zero otherwise) diff --git a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp index 1e7a74a7..55bc7066 100644 --- a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp +++ b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp @@ -1,4 +1,4 @@ -#define BOOST_TEST_MODULE const_string test +#define BOOST_TEST_MODULE persistent_cohomology test #include <boost/test/included/unit_test.hpp> #include <boost/system/error_code.hpp> #include <boost/chrono/thread_clock.hpp> @@ -22,8 +22,7 @@ using namespace boost::unit_test; typedef Simplex_tree<> typeST; std::string test_rips_persistence(int coefficient, int min_persistence) { - // Check file name is given as parameter from CMakeLists.txt - BOOST_CHECK(framework::master_test_suite().argc >= 2); + // file name is given as parameter from CMakeLists.txt const std::string inputFile(framework::master_test_suite().argv[1]); std::ifstream simplex_tree_stream; diff --git a/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp b/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp index e88add3a..8802005c 100644 --- a/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp +++ b/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp @@ -1,4 +1,4 @@ -#define BOOST_TEST_MODULE const_string test +#define BOOST_TEST_MODULE persistent_cohomology_multi_field test #include <boost/test/included/unit_test.hpp> #include <boost/system/error_code.hpp> #include <boost/chrono/thread_clock.hpp> @@ -23,8 +23,7 @@ using namespace boost::unit_test; typedef Simplex_tree<> typeST; std::string test_rips_persistence(int min_coefficient, int max_coefficient, int min_persistence) { - // Check file name is given as parameter from CMakeLists.txt - BOOST_CHECK(framework::master_test_suite().argc >= 2); + // file name is given as parameter from CMakeLists.txt const std::string inputFile(framework::master_test_suite().argv[1]); std::ifstream simplex_tree_stream; diff --git a/src/Simplex_tree/test/CMakeLists.txt b/src/Simplex_tree/test/CMakeLists.txt index 02ef9d8b..b6a1c0b6 100644 --- a/src/Simplex_tree/test/CMakeLists.txt +++ b/src/Simplex_tree/test/CMakeLists.txt @@ -1,21 +1,25 @@ cmake_minimum_required(VERSION 2.6) -project(GUDHITestSimplexTree) +project(GUDHISimplexTreeUT) -if(NOT MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} --coverage") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} --coverage") +if (GCOVR_PATH) + # for gcovr to make coverage reports - Corbera Jenkins plugin + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fprofile-arcs -ftest-coverage") +endif() +if (GPROF_PATH) + # for gprof to make coverage reports - Jenkins + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pg") endif() -add_executable ( simplex_tree_unit_test simplex_tree_unit_test.cpp ) -target_link_libraries(simplex_tree_unit_test ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) +add_executable ( SimplexTreeUT simplex_tree_unit_test.cpp ) +target_link_libraries(SimplexTreeUT ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) # Unitary tests -add_test(simplex_tree_unit_test ${CMAKE_CURRENT_BINARY_DIR}/simplex_tree_unit_test) - -if (LCOV_PATH) - # Lcov code coverage of unitary test - add_test(src/Simplex_tree/lcov/coverage.log ${CMAKE_SOURCE_DIR}/scripts/check_code_coverage.sh ${CMAKE_SOURCE_DIR}/src/Simplex_tree) -endif() +add_test(NAME SimplexTreeUT + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/SimplexTreeUT + # XML format for Jenkins xUnit plugin + --log_format=XML --log_sink=${CMAKE_SOURCE_DIR}/SimplexTreeUT.xml --log_level=test_suite --report_level=no) -cpplint_add_tests("${CMAKE_SOURCE_DIR}/src/Simplex_tree/include/gudhi") diff --git a/src/Simplex_tree/test/README b/src/Simplex_tree/test/README index 620bcd5f..21c3d871 100644 --- a/src/Simplex_tree/test/README +++ b/src/Simplex_tree/test/README @@ -1,12 +1,14 @@ To compile: *********** +cd /path-to-gudhi/ cmake . +cd /path-to-test/ make To launch with details: *********************** -./simplex_tree_unit_test --report_level=detailed --log_level=all +./SimplexTreeUT --report_level=detailed --log_level=all ==> echo $? returns 0 in case of success (non-zero otherwise) diff --git a/src/Simplex_tree/test/simplex_tree_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_unit_test.cpp index c0cfced1..6b0a1f3d 100644 --- a/src/Simplex_tree/test/simplex_tree_unit_test.cpp +++ b/src/Simplex_tree/test/simplex_tree_unit_test.cpp @@ -1,4 +1,4 @@ -#define BOOST_TEST_MODULE const_string test +#define BOOST_TEST_MODULE simplex_tree test #include <boost/test/included/unit_test.hpp> #include <boost/system/error_code.hpp> #include <boost/chrono/thread_clock.hpp> diff --git a/src/Skeleton_blocker/test/CMakeLists.txt b/src/Skeleton_blocker/test/CMakeLists.txt index c69bfec7..e62600a2 100644 --- a/src/Skeleton_blocker/test/CMakeLists.txt +++ b/src/Skeleton_blocker/test/CMakeLists.txt @@ -1,12 +1,17 @@ cmake_minimum_required(VERSION 2.6) project(GUDHIskbl) -if(NOT MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") - - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} --coverage") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} --coverage") +if (GCOVR_PATH) + # for gcovr to make coverage reports - Corbera Jenkins plugin + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fprofile-arcs -ftest-coverage") +endif() +if (GPROF_PATH) + # for gprof to make coverage reports - Jenkins + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pg") endif() add_executable(TestSkeletonBlockerComplex TestSkeletonBlockerComplex.cpp) @@ -17,10 +22,3 @@ add_test(TestSkeletonBlockerComplex ${CMAKE_CURRENT_BINARY_DIR}/TestSkeletonBloc add_test(TestSimplifiable ${CMAKE_CURRENT_BINARY_DIR}/TestSimplifiable) add_test(TestGeometricComplex ${CMAKE_CURRENT_BINARY_DIR}/TestGeometricComplex) - -if (LCOV_PATH) - # Lcov code coverage of unitary test - add_test(src/Skeleton_blocker/lcov/coverage.log ${CMAKE_SOURCE_DIR}/scripts/check_code_coverage.sh ${CMAKE_SOURCE_DIR}/src/Skeleton_blocker) -endif() - -cpplint_add_tests("${CMAKE_SOURCE_DIR}/src/Skeleton_blocker/include/gudhi") |