polserver/cmake/escripttest.cmake
turleypol 7627e3d353
"Preview/Initial"- Version sourcecode formatting feature (#626)
* Squash only prettify changes from escript_formating_try

* support of "format-off" / "format-on" comments to mark areas without
formatting

* fix typo

* added FormatterIdentLevel, FormatterMergeEmptyLines cfg entry
better line splits for dicts/arrays

* added several spacing options. the current setting list is now:
//LineWidth
FormatterLineWidth 80
// keep original keyword spelling
FormatterKeepKeywords 0
// number of spaces for ident
FormatterIdentLevel 2
// multiple newlines get merged to a single
FormatterMergeEmptyLines 1
// space between emtpy parenthesis eg foo() vs foo( )
FormatterEmptyParenthesisSpacing 0
// space between emtpy brackets eg struct{} vs struct{ }
FormatterEmptyBracketSpacing 0
// space after/before parenthesis in conditionals
// eg if ( true ) vs if (true)
FormatterConditionalParenthesisSpacing 1
// space after/before parenthesis
// eg foo( true ) vs foo(true)
FormatterParenthesisSpacing 1
// space after/before brackets
// eg array{ true } vs array{true}
FormatterBracketSpacing 1
// add space after delimiter comma or semi in for loops
// eg {1, 2, 3} vs {1,2,3}
FormatterDelimiterSpacing 1
// add space around assignment
// eg a := 1; vs a:=1;
FormatterAssignmentSpacing 1
// add space around comparison
// eg a == 1 vs a==1
FormatterComparisonSpacing 1
// add space around operations
// eg a + 1 vs a+1
FormatterOperatorSpacing 1
// use \r\n as newline instead of \n
FormatterWindowsLineEndings 0

* added tab support
// use tabs instead of spaces
FormatterUseTabs 0
// tab width
FormatterTabWidth 4

* extended example ecompile.cfg with formatter settings

* cleanup

* program args comma is optional...
fixed line comments in group splitting

* since tokenids are now correct no more guessing for linecomments needed

* comments use as start tokenid the whitespace token if its on the same
line

* splitted processing from linebuilding

* renamed TokenPart to FmtToken better matches the purpose.
Comments get directly stored as FmtToken
started with a context enum

* better(?) formatting for groups

* fix eof rawlines
added check that all comments/rawlines got parsed

* const correctness

* datatype adapted to antlr

* fixed warnings

* added InsertNewlineAtEOF

* add newline at the end if the original file had one
dont strip comment whitespace if its somejind of "header block"
use the defined lineending for /* */ comments

* docs

* \r\n is default on windows \n otherwise

* fixed warning

---------

Co-authored-by: Kevin Eady <8634912+KevinEady@users.noreply.github.com>
2024-02-26 21:21:44 +01:00

176 lines
6 KiB
CMake

#EScript test suite
if(NOT DEFINED testdir)
message(FATAL_ERROR "testdir not defined")
endif()
if(NOT DEFINED subtest)
message(FATAL_ERROR "subtest not defined")
endif()
if(NOT DEFINED runecl)
message(FATAL_ERROR "runecl not defined")
endif()
if(NOT DEFINED ecompile)
message(FATAL_ERROR "ecompile not defined")
endif()
# Uncomment to not delete failed formatted files (will be saved as {scriptname}.formatted.src)
# set(keepfailedformats TRUE)
function (cleanup scriptname)
foreach (ext .ecl .tst .unformatted.src .formatted.src)
if(EXISTS "${scriptname}${ext}")
if ("${ext}" STREQUAL ".formatted.src" AND DEFINED keepfailedformats)
continue()
endif()
if("${ext}" STREQUAL ".unformatted.src")
configure_file(${scriptname}${ext} ${scriptname}.src COPYONLY)
endif()
file(REMOVE "${scriptname}${ext}")
endif()
endforeach()
endfunction()
function (readfile file content content_len)
# read given file into string list
FILE(READ ${file} contents)
#keep original ;
STRING(REGEX REPLACE ";" "\\\\;" contents "${contents}")
#remove last newline
STRING(REGEX REPLACE "\n$" "" contents "${contents}")
#cmake does not really support entries add _
STRING(REGEX REPLACE "\n\n" "\n_\n" contents "${contents}")
#each newline a new list element
STRING(REGEX REPLACE "\n" ";" contents "${contents}")
list(LENGTH contents len)
set(${content} ${contents} PARENT_SCOPE)
set(${content_len} ${len} PARENT_SCOPE)
endfunction()
function (compareresult scriptname result)
execute_process(
COMMAND ${CMAKE_COMMAND} -E compare_files "${scriptname}.out" "${scriptname}.tst"
RESULT_VARIABLE test_not_successful
OUTPUT_QUIET
ERROR_QUIET
)
if (NOT ${test_not_successful})
set(${result} 1 PARENT_SCOPE)
return()
endif()
set(${result} 0 PARENT_SCOPE)
readfile("${scriptname}.out" outcontent outlen)
readfile("${scriptname}.tst" tstcontent tstlen)
if (${outlen} EQUAL ${tstlen})
math(EXPR looprange ${outlen}-1)
foreach(i RANGE ${looprange})
list(GET outcontent ${i} out)
list(GET tstcontent ${i} tst)
if (NOT ${out} STREQUAL ${tst})
math(EXPR line ${i}+1)
message("${scriptname}.src failed:")
message("Line ${line} Expected:\n${out}\nGot:\n${tst}")
cleanup(${scriptname})
set(${result} 0 PARENT_SCOPE)
message(SEND_ERROR "Line differs")
endif()
endforeach()
else()
message("\"${tstcontent}\"")
message(SEND_ERROR "Testdata length differs")
cleanup(${scriptname})
endif()
endfunction()
function (checkprocfailure output errorfile result)
# correct error msg from process?
file(READ "${errorfile}" contents)
string(FIND "${output}" "${contents}" err_found)
if(${err_found} LESS 0)
message(SEND_ERROR "Expected:\n${contents}\nGot:${output}")
set(${result} 0 PARENT_SCOPE)
else()
set(${result} 1 PARENT_SCOPE)
endif()
endfunction()
# start of test
function (testwithcompiler formatoption)
file(GLOB scripts RELATIVE ${testdir} ${testdir}/${subtest}/*)
foreach(script ${scripts})
string(FIND "${script}" ".src" out)
if(${out} LESS 0)
continue()
endif()
string(REPLACE ".src" "" scriptname "${script}")
if (EXISTS "${testdir}/${scriptname}.out" AND NOT ${formatoption} STREQUAL "")
message("${script} [formatted]")
string(REPLACE ".src" ".unformatted.src" unformattedscript "${script}")
configure_file(${testdir}/${script} ${testdir}/${unformattedscript} COPYONLY)
execute_process( COMMAND ${ecompile} ${formatoption} -q -C ecompile.cfg ${script}
RESULT_VARIABLE ecompile_format_res
OUTPUT_VARIABLE ecompile_format_out
ERROR_VARIABLE ecompile_format_out)
else()
message(${script})
endif()
if (EXISTS "${testdir}/${scriptname}.out" OR EXISTS "${testdir}/${scriptname}.err")
execute_process( COMMAND ${ecompile} -q -C ecompile.cfg ${script}
RESULT_VARIABLE ecompile_res
OUTPUT_VARIABLE ecompile_out
ERROR_VARIABLE ecompile_out)
if (EXISTS "${testdir}/${scriptname}.err")
if("${ecompile_res}" STREQUAL "0")
cleanup(${scriptname})
message(SEND_ERROR "${scriptname}.src compiled, but should not")
else()
checkprocfailure("${ecompile_out}" "${testdir}/${scriptname}.err" success)
if (NOT ${success})
cleanup(${scriptname})
message(SEND_ERROR "${scriptname}.src failed with different error")
endif()
endif()
else()
if(NOT "${ecompile_res}" STREQUAL "0")
if(NOT ${formatoption} STREQUAL "" AND DEFINED keepfailedformats)
configure_file(${testdir}/${script} ${testdir}/${scriptname}.formatted.src)
endif()
cleanup(${scriptname})
message(SEND_ERROR "${scriptname}.src did not compile")
message(${ecompile_out})
endif()
execute_process( COMMAND ${runecl} -q "${scriptname}.ecl"
OUTPUT_FILE "${scriptname}.tst"
RESULT_VARIABLE runecl_res
ERROR_VARIABLE runecl_out)
if (EXISTS "${testdir}/${scriptname}.exr")
if(NOT "${runecl_res}" STREQUAL "0")
checkprocfailure("${runecl_out}" "${testdir}/${scriptname}.exr" success)
if (NOT ${success})
cleanup(${scriptname})
message(SEND_ERROR "${scriptname}.ecl failed with different error")
endif()
else()
cleanup(${scriptname})
message(SEND_ERROR "${scriptname}.ecl should have failed")
endif()
else()
if(NOT "${runecl_res}" STREQUAL "0")
file(READ "${scriptname}.tst" contents)
message("${runecl_out} ${contents}")
cleanup(${scriptname})
message(SEND_ERROR "${scriptname}.ecl did not run")
else()
compareresult(${scriptname} success)
# no message needed compare prints
endif()
endif()
endif()
cleanup(${scriptname})
endif()
endforeach()
endfunction()
testwithcompiler("")
testwithcompiler("-Fi")