2022-09-06 23:11:39 +02:00
# python -m pytest test-other.py
import os
2023-11-16 13:44:50 +01:00
import sys
2022-09-06 23:11:39 +02:00
import pytest
2023-11-06 19:06:22 +01:00
from testutils import cppcheck , assert_cppcheck
2022-09-06 23:11:39 +02:00
2023-08-23 11:20:20 +02:00
2022-09-06 23:11:39 +02:00
def __test_missing_include ( tmpdir , use_j ) :
test_file = os . path . join ( tmpdir , ' test.c ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
#include "test.h"
""" )
2023-03-04 09:02:35 +01:00
args = [ ' --enable=missingInclude ' , ' --template= {file} : {line} : {column} : {severity} : { inconclusive:inconclusive:} {message} [ {id} ] ' , test_file ]
2022-09-06 23:11:39 +02:00
if use_j :
2023-03-04 09:02:35 +01:00
args . insert ( 0 , ' -j2 ' )
2022-09-06 23:11:39 +02:00
2023-03-04 09:02:35 +01:00
_ , _ , stderr = cppcheck ( args )
assert stderr == ' {} :2:0: information: Include file: " test.h " not found. [missingInclude] \n ' . format ( test_file )
2022-09-06 23:11:39 +02:00
2023-08-23 11:20:20 +02:00
2022-09-06 23:11:39 +02:00
def test_missing_include ( tmpdir ) :
__test_missing_include ( tmpdir , False )
2023-08-23 11:20:20 +02:00
2022-09-06 23:11:39 +02:00
def test_missing_include_j ( tmpdir ) : #11283
__test_missing_include ( tmpdir , True )
2023-08-23 11:20:20 +02:00
2022-09-06 23:11:39 +02:00
def __test_missing_include_check_config ( tmpdir , use_j ) :
test_file = os . path . join ( tmpdir , ' test.c ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
#include "test.h"
""" )
# TODO: -rp is not working requiring the full path in the assert
args = ' --check-config -rp= {} {} ' . format ( tmpdir , test_file )
if use_j :
args = ' -j2 ' + args
_ , _ , stderr = cppcheck ( args . split ( ) )
2023-03-04 09:02:35 +01:00
assert stderr == ' ' # --check-config no longer reports the missing includes
2022-09-06 23:11:39 +02:00
2023-08-23 11:20:20 +02:00
2022-09-06 23:11:39 +02:00
def test_missing_include_check_config ( tmpdir ) :
__test_missing_include_check_config ( tmpdir , False )
2023-08-23 11:20:20 +02:00
2022-09-06 23:11:39 +02:00
def test_missing_include_check_config_j ( tmpdir ) :
2023-04-21 10:14:34 +02:00
__test_missing_include_check_config ( tmpdir , True )
2023-08-23 11:20:20 +02:00
2023-04-21 10:14:34 +02:00
def test_missing_include_inline_suppr ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.c ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
/ / cppcheck - suppress missingInclude
#include "missing.h"
/ / cppcheck - suppress missingIncludeSystem
#include <missing2.h>
""" )
args = [ ' --enable=missingInclude ' , ' --inline-suppr ' , test_file ]
_ , _ , stderr = cppcheck ( args )
2023-08-07 19:48:11 +02:00
assert stderr == ' '
2023-08-23 11:20:20 +02:00
2023-11-16 17:25:49 +01:00
def test_preprocessor_error ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' 10866.c ' )
with open ( test_file , ' wt ' ) as f :
f . write ( ' #error test \n x=1; \n ' )
exitcode , _ , stderr = cppcheck ( [ ' --error-exitcode=1 ' , test_file ] )
assert ' preprocessorErrorDirective ' in stderr
assert exitcode != 0
2023-08-07 19:48:11 +02:00
def test_invalid_library ( tmpdir ) :
2023-09-11 11:08:23 +02:00
args = [ ' --library=none ' , ' --library=posix ' , ' --library=none2 ' , ' file.c ' ]
2023-08-07 19:48:11 +02:00
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 1
assert ( stdout == " cppcheck: Failed to load library configuration file ' none ' . File not found \n "
" cppcheck: Failed to load library configuration file ' none2 ' . File not found \n " )
assert stderr == " "
2023-08-21 12:17:08 +02:00
def test_message_j ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.c ' )
with open ( test_file , ' wt ' ) as f :
f . write ( " " )
2023-09-11 11:08:23 +02:00
args = [ ' -j2 ' , test_file ]
2023-08-21 12:17:08 +02:00
_ , stdout , _ = cppcheck ( args )
assert stdout == " Checking {} ... \n " . format ( test_file ) # we were adding stray \0 characters at the end
2023-08-23 11:20:20 +02:00
# TODO: test missing std.cfg
def test_progress ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.c ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
int main ( int argc )
{
}
""" )
2023-09-11 11:08:23 +02:00
args = [ ' --report-progress=0 ' , ' --enable=all ' , ' --inconclusive ' , test_file ]
2023-08-23 11:20:20 +02:00
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
pos = stdout . find ( ' \n ' )
assert ( pos != - 1 )
pos + = 1
assert stdout [ : pos ] == " Checking {} ... \n " . format ( test_file )
assert ( stdout [ pos : ] ==
" progress: Tokenize (typedef) 0 % \n "
" progress: Tokenize (typedef) 12 % \n "
" progress: Tokenize (typedef) 25 % \n "
" progress: Tokenize (typedef) 37 % \n "
" progress: Tokenize (typedef) 50 % \n "
" progress: Tokenize (typedef) 62 % \n "
" progress: Tokenize (typedef) 75 % \n "
" progress: Tokenize (typedef) 87 % \n "
" progress: SymbolDatabase 0 % \n "
" progress: SymbolDatabase 12 % \n "
" progress: SymbolDatabase 87 % \n "
)
assert stderr == " "
def test_progress_j ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.c ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
int main ( int argc )
{
}
""" )
2023-09-11 11:08:23 +02:00
args = [ ' --report-progress=0 ' , ' --enable=all ' , ' --inconclusive ' , ' -j2 ' , ' --disable=unusedFunction ' , test_file ]
2023-08-23 11:20:20 +02:00
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
assert stdout == " Checking {} ... \n " . format ( test_file )
assert stderr == " "
2023-08-30 19:35:43 +02:00
2023-08-31 16:46:20 +02:00
@pytest.mark.timeout ( 10 )
def test_slow_array_many_floats ( tmpdir ) :
# 11649
# cppcheck valueflow takes a long time when an array has many floats
filename = os . path . join ( tmpdir , ' hang.c ' )
with open ( filename , ' wt ' ) as f :
f . write ( " const float f[] = { \n " )
for i in range ( 20000 ) :
f . write ( ' 13.6f, \n ' )
f . write ( " }; \n " )
cppcheck ( [ filename ] ) # should not take more than ~1 second
2023-08-30 19:35:43 +02:00
@pytest.mark.timeout ( 10 )
def test_slow_array_many_strings ( tmpdir ) :
# 11901
# cppcheck valueflow takes a long time when analyzing a file with many strings
filename = os . path . join ( tmpdir , ' hang.c ' )
with open ( filename , ' wt ' ) as f :
f . write ( " const char *strings[] = { \n " )
for i in range ( 20000 ) :
f . write ( ' " abc " , \n ' )
f . write ( " }; \n " )
cppcheck ( [ filename ] ) # should not take more than ~1 second
2023-08-31 13:33:29 +02:00
2023-09-14 09:41:39 +02:00
@pytest.mark.timeout ( 10 )
def test_slow_long_line ( tmpdir ) :
# simplecpp #314
filename = os . path . join ( tmpdir , ' hang.c ' )
with open ( filename , ' wt ' ) as f :
f . write ( " #define A() static const int a[] = { \\ \n " )
for i in range ( 5000 ) :
f . write ( " -123, 456, -789, \\ \n " )
f . write ( " }; \n " )
cppcheck ( [ filename ] ) # should not take more than ~1 second
2023-08-31 13:33:29 +02:00
def test_execute_addon_failure ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
void f ( ) ;
""" )
args = [ ' --addon=naming ' , test_file ]
# provide empty PATH environment variable so python is not found and execution of addon fails
env = { ' PATH ' : ' ' }
_ , _ , stderr = cppcheck ( args , env )
assert stderr == ' {} :0:0: error: Bailing out from analysis: Checking file failed: Failed to auto detect python [internalError] \n \n ^ \n ' . format ( test_file )
def test_execute_addon_failure_2 ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
void f ( ) ;
""" )
# specify non-existent python executbale so execution of addon fails
args = [ ' --addon=naming ' , ' --addon-python=python5.x ' , test_file ]
_ , _ , stderr = cppcheck ( args )
2023-09-20 10:40:57 +02:00
ec = 1 if os . name == ' nt ' else 127
assert stderr == " {} :0:0: error: Bailing out from analysis: Checking file failed: Failed to execute addon ' naming ' - exitcode is {} [internalError] \n \n ^ \n " . format ( test_file , ec )
2023-08-31 13:33:29 +02:00
2023-11-04 17:07:30 +01:00
def test_execute_addon_file0 ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.c ' )
with open ( test_file , ' wt ' ) as f :
f . write ( ' void foo() {} \n ' )
args = [ ' --xml ' , ' --addon=misra ' , ' --enable=style ' , test_file ]
_ , _ , stderr = cppcheck ( args )
assert ' misra-c2012-8.2 ' in stderr
assert ' .dump ' not in stderr
2023-08-31 13:33:29 +02:00
# TODO: find a test case which always fails
@pytest.mark.skip
def test_internal_error ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
#include <cstdio>
void f ( ) {
double gc = 3333.3333 ;
char stat [ 80 ] ;
sprintf ( stat , " ' %2.1f ' " , gc ) ;
}
""" )
args = [ test_file ]
_ , _ , stderr = cppcheck ( args )
2023-09-14 09:41:39 +02:00
assert stderr == ' {} :0:0: error: Bailing from out analysis: Checking file failed: converting \' 1f \' to integer failed - not an integer [internalError] \n \n ^ \n ' . format ( test_file )
2023-09-20 10:40:57 +02:00
def test_addon_misra ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
typedef int MISRA_5_6_VIOLATION ;
""" )
args = [ ' --addon=misra ' , ' --enable=all ' , test_file ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file )
]
assert stderr == ' {} :2:1: style: misra violation (use --rule-texts=<file> to get proper output) [misra-c2012-2.3] \n typedef int MISRA_5_6_VIOLATION; \n ^ \n ' . format ( test_file )
def test_addon_y2038 ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
# TODO: trigger warning
with open ( test_file , ' wt ' ) as f :
f . write ( """
2023-09-25 13:39:17 +02:00
extern void f ( )
{
time_t t = std : : time ( nullptr ) ;
( void ) t ;
}
2023-09-20 10:40:57 +02:00
""" )
2023-09-25 13:39:17 +02:00
args = [ ' --addon=y2038 ' , ' --enable=all ' , ' --template= {file} : {line} : {column} : {severity} : { inconclusive:inconclusive:} {message} [ {id} ] ' , test_file ]
2023-09-20 10:40:57 +02:00
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file )
]
2023-09-25 13:39:17 +02:00
assert stderr == ' {} :4:21: warning: time is Y2038-unsafe [y2038-unsafe-call] \n ' . format ( test_file )
2023-09-20 10:40:57 +02:00
def test_addon_threadsafety ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
2023-09-25 13:39:17 +02:00
extern const char * f ( )
{
return strerror ( 1 ) ;
}
2023-09-20 10:40:57 +02:00
""" )
2023-09-25 13:39:17 +02:00
args = [ ' --addon=threadsafety ' , ' --enable=all ' , ' --template= {file} : {line} : {column} : {severity} : { inconclusive:inconclusive:} {message} [ {id} ] ' , test_file ]
2023-09-20 10:40:57 +02:00
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file )
]
2023-09-25 13:39:17 +02:00
assert stderr == ' {} :4:12: warning: strerror is MT-unsafe [threadsafety-unsafe-call] \n ' . format ( test_file )
2023-09-20 10:40:57 +02:00
def test_addon_naming ( tmpdir ) :
2023-09-25 13:39:17 +02:00
# the addon does nothing without a config
addon_file = os . path . join ( tmpdir , ' naming1.json ' )
with open ( addon_file , ' wt ' ) as f :
f . write ( """
{
" script " : " addons/naming.py " ,
" args " : [
" --var=[_a-z].* "
]
}
""" )
2023-09-20 10:40:57 +02:00
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
2023-09-25 13:39:17 +02:00
int Var ;
2023-09-20 10:40:57 +02:00
""" )
2023-09-25 13:39:17 +02:00
args = [ ' --addon= {} ' . format ( addon_file ) , ' --enable=all ' , ' --template= {file} : {line} : {column} : {severity} : { inconclusive:inconclusive:} {message} [ {id} ] ' , test_file ]
2023-09-20 10:40:57 +02:00
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file )
]
2023-09-25 13:39:17 +02:00
assert stderr == ' {} :2:1: style: Variable Var violates naming convention [naming-varname] \n ' . format ( test_file )
2023-09-20 10:40:57 +02:00
2023-09-25 13:39:17 +02:00
# the namingng addon only works standalone and not in CLI mode - see #12005
@pytest.mark.skip
2023-09-20 10:40:57 +02:00
def test_addon_namingng ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
# TODO: trigger warning
with open ( test_file , ' wt ' ) as f :
f . write ( """
typedef int MISRA_5_6_VIOLATION ;
""" )
2023-09-25 13:39:17 +02:00
args = [ ' --addon=namingng ' , ' --enable=all ' , test_file ]
2023-09-20 10:40:57 +02:00
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file )
]
assert stderr == ' '
2023-09-25 13:39:17 +02:00
def test_addon_findcasts ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
extern void f ( char c )
{
int i = ( int ) c ;
( void ) i ;
}
""" )
args = [ ' --addon=findcasts ' , ' --enable=all ' , ' --template= {file} : {line} : {column} : {severity} : { inconclusive:inconclusive:} {message} [ {id} ] ' , test_file ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file )
]
assert stderr == ' {} :4:21: information: found a cast [findcasts-cast] \n ' . format ( test_file )
def test_addon_misc ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
extern void f ( )
{
char char * [ ] = { " a " " b " }
}
""" )
args = [ ' --addon=misc ' , ' --enable=all ' , ' --template= {file} : {line} : {column} : {severity} : { inconclusive:inconclusive:} {message} [ {id} ] ' , test_file ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file )
]
assert stderr == ' {} :4:26: style: String concatenation in array initialization, missing comma? [misc-stringConcatInArrayInit] \n ' . format ( test_file )
2023-09-20 10:40:57 +02:00
def test_invalid_addon_json ( tmpdir ) :
addon_file = os . path . join ( tmpdir , ' addon1.json ' )
with open ( addon_file , ' wt ' ) as f :
f . write ( """
""" )
test_file = os . path . join ( tmpdir , ' file.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
typedef int MISRA_5_6_VIOLATION ;
""" )
args = [ ' --addon= {} ' . format ( addon_file ) , ' --enable=all ' , test_file ]
exitcode , stdout , stderr = cppcheck ( args )
2023-10-08 21:28:57 +02:00
assert exitcode == 1
2023-09-20 10:40:57 +02:00
lines = stdout . splitlines ( )
assert lines == [
' Loading {} failed. syntax error at line 2 near: ' . format ( addon_file )
]
assert stderr == ' '
def test_invalid_addon_py ( tmpdir ) :
addon_file = os . path . join ( tmpdir , ' addon1.py ' )
with open ( addon_file , ' wt ' ) as f :
f . write ( """
raise Exception ( )
""" )
test_file = os . path . join ( tmpdir , ' file.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
typedef int MISRA_5_6_VIOLATION ;
""" )
args = [ ' --addon= {} ' . format ( addon_file ) , ' --enable=all ' , test_file ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0 # TODO: needs to be 1
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file )
]
assert stderr == " {} :0:0: error: Bailing out from analysis: Checking file failed: Failed to execute addon ' addon1 ' - exitcode is 1 [internalError] \n \n ^ \n " . format ( test_file )
def test_invalid_addon_py_verbose ( tmpdir ) :
addon_file = os . path . join ( tmpdir , ' addon1.py ' )
with open ( addon_file , ' wt ' ) as f :
f . write ( """
raise Exception ( )
""" )
test_file = os . path . join ( tmpdir , ' file.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
typedef int MISRA_5_6_VIOLATION ;
""" )
args = [ ' --addon= {} ' . format ( addon_file ) , ' --enable=all ' , ' --verbose ' , test_file ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0 # TODO: needs to be 1
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file ) ,
' Defines: ' ,
' Undefines: ' ,
' Includes: ' ,
' Platform:native '
]
"""
/ tmp / pytest - of - user / pytest - 11 / test_invalid_addon_py_20 / file . cpp : 0 : 0 : error : Bailing out from analysis : Checking file failed : Failed to execute addon ' addon1 ' - exitcode is 1 : python3 / home / user / CLionProjects / cppcheck / addons / runaddon . py / tmp / pytest - of - user / pytest - 11 / test_invalid_addon_py_20 / addon1 . py - - cli / tmp / pytest - of - user / pytest - 11 / test_invalid_addon_py_20 / file . cpp .24762 . dump
Output :
Traceback ( most recent call last ) :
File " /home/user/CLionProjects/cppcheck/addons/runaddon.py " , line 8 , in < module >
runpy . run_path ( addon , run_name = ' __main__ ' )
File " <frozen runpy> " , line 291 , in run_path
File " <frozen runpy> " , line 98 , in _run_module_code
File " <frozen runpy> " , line 88 , in _run_code
File " /tmp/pytest-of-user/pytest-11/test_invalid_addon_py_20/addon1.py " , line 2 , in < module >
raise Exception ( )
Exceptio [ internalError ]
"""
# /tmp/pytest-of-user/pytest-10/test_invalid_addon_py_20/file.cpp:0:0: error: Bailing out from analysis: Checking file failed: Failed to execute addon 'addon1' - exitcode is 256.: python3 /home/user/CLionProjects/cppcheck/addons/runaddon.py /tmp/pytest-of-user/pytest-10/test_invalid_addon_py_20/addon1.py --cli /tmp/pytest-of-user/pytest-10/test_invalid_addon_py_20/file.cpp.24637.dump
assert stderr . startswith ( " {} :0:0: error: Bailing out from analysis: Checking file failed: Failed to execute addon ' addon1 ' - exitcode is 1: " . format ( test_file ) )
assert stderr . count ( ' Output: \n Traceback ' )
assert stderr . endswith ( ' raise Exception() \n Exception [internalError] \n \n ^ \n ' )
def test_addon_result ( tmpdir ) :
addon_file = os . path . join ( tmpdir , ' addon1.py ' )
with open ( addon_file , ' wt ' ) as f :
f . write ( """
print ( " Checking ... " )
print ( " " )
print ( ' { " file " : " test.cpp " , " linenr " : 1, " column " : 1, " severity " : " style " , " message " : " msg " , " addon " : " addon1 " , " errorId " : " id " , " extra " : " " } ' )
print ( ' { " loc " : [ { " file " : " test.cpp " , " linenr " : 1, " column " : 1, " info " : " " }], " severity " : " style " , " message " : " msg " , " addon " : " addon1 " , " errorId " : " id " , " extra " : " " } ' )
""" )
test_file = os . path . join ( tmpdir , ' file.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
typedef int MISRA_5_6_VIOLATION ;
""" )
args = [ ' --addon= {} ' . format ( addon_file ) , ' --enable=all ' , test_file ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0 # TODO: needs to be 1
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file )
]
assert stderr == ' test.cpp:1:1: style: msg [addon1-id] \n \n ^ \n '
2023-09-20 14:45:44 +02:00
# #11483
def test_unused_function_include ( tmpdir ) :
test_cpp_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_cpp_file , ' wt ' ) as f :
f . write ( """
#include "test.h"
""" )
test_h_file = os . path . join ( tmpdir , ' test.h ' )
with open ( test_h_file , ' wt ' ) as f :
f . write ( """
class A {
public :
void f ( ) { }
/ / cppcheck - suppress unusedFunction
void f2 ( ) { }
} ;
""" )
args = [ ' --enable=unusedFunction ' , ' --inline-suppr ' , ' --template= {file} : {line} : {column} : {severity} : { inconclusive:inconclusive:} {message} [ {id} ] ' , test_cpp_file ]
_ , _ , stderr = cppcheck ( args )
assert stderr == " {} :4:0: style: The function ' f ' is never used. [unusedFunction] \n " . format ( test_h_file )
2023-10-05 19:04:06 +02:00
# TODO: test with -j and all other types
def test_showtime_top5_file ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
int main ( int argc )
{
}
""" )
args = [ ' --showtime=top5_file ' , ' --quiet ' , test_file ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0 # TODO: needs to be 1
lines = stdout . splitlines ( )
assert len ( lines ) == 7
assert lines [ 0 ] == ' '
for i in range ( 1 , 5 ) :
assert lines [ i ] . endswith ( ' - 1 result(s)) ' )
assert lines [ 6 ] . startswith ( ' Overall time: ' )
assert stderr == ' '
2023-10-08 21:28:57 +02:00
def test_missing_addon ( tmpdir ) :
args = [ ' --addon=misra3 ' , ' --addon=misra ' , ' --addon=misra2 ' , ' file.c ' ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 1
lines = stdout . splitlines ( )
lines . sort ( )
assert lines == [
' Did not find addon misra2.py ' ,
' Did not find addon misra3.py '
]
assert stderr == " "
2023-11-06 19:06:22 +01:00
def test_file_filter ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) as f :
pass
args = [ ' --file-filter=*.cpp ' , test_file ]
out_lines = [
' Checking {} ... ' . format ( test_file )
]
assert_cppcheck ( args , ec_exp = 0 , err_exp = [ ] , out_exp = out_lines )
def test_file_filter_2 ( tmpdir ) :
test_file_1 = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file_1 , ' wt ' ) as f :
pass
test_file_2 = os . path . join ( tmpdir , ' test.c ' )
with open ( test_file_2 , ' wt ' ) as f :
pass
args = [ ' --file-filter=*.cpp ' , test_file_1 , test_file_2 ]
out_lines = [
' Checking {} ... ' . format ( test_file_1 )
]
assert_cppcheck ( args , ec_exp = 0 , err_exp = [ ] , out_exp = out_lines )
def test_file_filter_3 ( tmpdir ) :
test_file_1 = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file_1 , ' wt ' ) as f :
pass
test_file_2 = os . path . join ( tmpdir , ' test.c ' )
with open ( test_file_2 , ' wt ' ) as f :
pass
args = [ ' --file-filter=*.c ' , test_file_1 , test_file_2 ]
out_lines = [
' Checking {} ... ' . format ( test_file_2 )
]
assert_cppcheck ( args , ec_exp = 0 , err_exp = [ ] , out_exp = out_lines )
def test_file_filter_no_match ( tmpdir ) :
args = [ ' --file-filter=*.c ' , ' test.cpp ' ]
out_lines = [
' cppcheck: error: could not find any files matching the filter. '
]
assert_cppcheck ( args , ec_exp = 1 , err_exp = [ ] , out_exp = out_lines )
2023-11-07 21:21:24 +01:00
def test_file_order ( tmpdir ) :
test_file_a = os . path . join ( tmpdir , ' a.c ' )
with open ( test_file_a , ' wt ' ) :
pass
test_file_b = os . path . join ( tmpdir , ' b.c ' )
with open ( test_file_b , ' wt ' ) :
pass
test_file_c = os . path . join ( tmpdir , ' c.c ' )
with open ( test_file_c , ' wt ' ) :
pass
test_file_d = os . path . join ( tmpdir , ' d.c ' )
with open ( test_file_d , ' wt ' ) :
pass
args = [ test_file_c , test_file_d , test_file_b , test_file_a ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file_c ) ,
' 1/4 files checked 0 % d one ' ,
' Checking {} ... ' . format ( test_file_d ) ,
' 2/4 files checked 0 % d one ' ,
' Checking {} ... ' . format ( test_file_b ) ,
' 3/4 files checked 0 % d one ' ,
' Checking {} ... ' . format ( test_file_a ) ,
' 4/4 files checked 0 % d one '
]
assert stderr == ' '
2023-11-09 10:17:30 +01:00
def test_markup ( tmpdir ) :
test_file_1 = os . path . join ( tmpdir , ' test_1.qml ' )
with open ( test_file_1 , ' wt ' ) as f :
pass
test_file_2 = os . path . join ( tmpdir , ' test_2.cpp ' )
with open ( test_file_2 , ' wt ' ) as f :
pass
test_file_3 = os . path . join ( tmpdir , ' test_3.qml ' )
with open ( test_file_3 , ' wt ' ) as f :
pass
test_file_4 = os . path . join ( tmpdir , ' test_4.cpp ' )
with open ( test_file_4 , ' wt ' ) as f :
pass
args = [ ' --library=qt ' , test_file_1 , test_file_2 , test_file_3 , test_file_4 ]
out_lines = [
' Checking {} ... ' . format ( test_file_2 ) ,
' 1/4 files checked 0 % d one ' ,
' Checking {} ... ' . format ( test_file_4 ) ,
' 2/4 files checked 0 % d one ' ,
' Checking {} ... ' . format ( test_file_1 ) ,
' 3/4 files checked 0 % d one ' ,
' Checking {} ... ' . format ( test_file_3 ) ,
' 4/4 files checked 0 % d one '
]
assert_cppcheck ( args , ec_exp = 0 , err_exp = [ ] , out_exp = out_lines )
def test_markup_j ( tmpdir ) :
test_file_1 = os . path . join ( tmpdir , ' test_1.qml ' )
with open ( test_file_1 , ' wt ' ) as f :
pass
test_file_2 = os . path . join ( tmpdir , ' test_2.cpp ' )
with open ( test_file_2 , ' wt ' ) as f :
pass
test_file_3 = os . path . join ( tmpdir , ' test_3.qml ' )
with open ( test_file_3 , ' wt ' ) as f :
pass
test_file_4 = os . path . join ( tmpdir , ' test_4.cpp ' )
with open ( test_file_4 , ' wt ' ) as f :
pass
args = [ ' --library=qt ' , test_file_1 , test_file_2 , test_file_3 , test_file_4 ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
lines = stdout . splitlines ( )
for i in range ( 1 , 5 ) :
lines . remove ( ' {} /4 files checked 0 % d one ' . format ( i ) )
assert lines == [
' Checking {} ... ' . format ( test_file_2 ) ,
' Checking {} ... ' . format ( test_file_4 ) ,
' Checking {} ... ' . format ( test_file_1 ) ,
' Checking {} ... ' . format ( test_file_3 )
]
assert stderr == ' '
2023-11-16 13:44:50 +01:00
def test_valueflow_debug ( tmpdir ) :
test_file_cpp = os . path . join ( tmpdir , ' test_1.cpp ' )
with open ( test_file_cpp , ' wt ' ) as f :
f . write ( """
#include "test.h"
void f ( )
{
int i = 0 ;
}
"""
)
test_file_h = os . path . join ( tmpdir , ' test.h ' )
with open ( test_file_h , ' wt ' ) as f :
f . write ( """
#include "test2.h"
inline void f1 ( )
{
int i = 0 ;
}
"""
)
pass
test_file_h_2 = os . path . join ( tmpdir , ' test2.h ' )
with open ( test_file_h_2 , ' wt ' ) as f :
f . write ( """
inline void f2 ( )
{
int i = 0 ;
}
"""
)
args = [ ' --debug ' , test_file_cpp ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
if sys . platform == " win32 " :
stdout = stdout . replace ( ' / ' , ' \\ ' )
assert stdout == ''' Checking {} ...
##file {}
2 : void f2 ( )
3 : { {
4 : int i @var1 ; i @var1 = @expr1073741828 0 ;
5 : } }
##file {}
1 :
2 :
3 : void f1 ( )
4 : { {
5 : int i @var2 ; i @var2 = @expr1073741829 0 ;
6 : } }
##file {}
1 :
2 :
3 :
4 : void f ( )
5 : { {
6 : int i @var3 ; i @var3 = @expr1073741830 0 ;
7 : } }
##Value flow
File { }
Line 4
= always 0
0 always 0
File { }
Line 5
= always 0
0 always 0
File { }
Line 6
= always 0
0 always 0
''' .format(test_file_cpp, test_file_h_2, test_file_h, test_file_cpp, test_file_h_2, test_file_h, test_file_cpp)
assert stderr == ' '