mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-10-29 17:50:22 +00:00
368 lines
11 KiB
APL
368 lines
11 KiB
APL
:NameSpace UT
|
||
|
||
sac ← 0
|
||
expect_orig ← expect ← ⎕NS⍬
|
||
exception ← ⍬
|
||
nexpect_orig ← nexpect ← ⎕NS⍬
|
||
|
||
∇ {Z}←{Conf}run Argument;PRE_test;POST_test;TEST_step;COVER_step;FromSpace
|
||
|
||
load_display_if_not_already_loaded
|
||
load_salt_scripts_into_current_namespace_if_configured
|
||
|
||
FromSpace←1⊃⎕RSI
|
||
|
||
PRE_test←{}
|
||
POST_test←{}
|
||
COVER_step←{}
|
||
:If 0≠⎕NC'Conf'
|
||
:If Conf has'cover_target'
|
||
PRE_test←{{}⎕PROFILE'start'}
|
||
POST_test←{{}⎕PROFILE'stop'}
|
||
:EndIf
|
||
:EndIf
|
||
|
||
:If is_function Argument
|
||
TEST_step←single_function_test_function
|
||
COVER_file←Argument,'_coverage.html'
|
||
|
||
:ElseIf is_list_of_functions Argument
|
||
TEST_step←list_of_functions_test_function
|
||
COVER_file←'list_coverage.html'
|
||
|
||
:ElseIf is_file Argument
|
||
TEST_step←file_test_function
|
||
COVER_file←(get_file_name Argument),'_coverage.html'
|
||
|
||
:ElseIf is_dir Argument
|
||
test_files←test_files_in_dir Argument
|
||
TEST_step←test_dir_function
|
||
Argument←test_files
|
||
:EndIf
|
||
|
||
:If 0≠⎕NC'Conf'
|
||
:If Conf has'cover_target'
|
||
COVER_step←{Conf,←⊂('cover_file'COVER_file)
|
||
generate_coverage_page Conf}
|
||
:EndIf
|
||
:EndIf
|
||
|
||
PRE_test ⍬
|
||
Z←FromSpace TEST_step Argument
|
||
POST_test ⍬
|
||
COVER_step ⍬
|
||
∇
|
||
|
||
∇ load_display_if_not_already_loaded
|
||
:If 0=⎕NC'#.DISPLAY'
|
||
'DISPLAY'#.⎕CY'display'
|
||
:EndIf
|
||
∇
|
||
|
||
∇ load_salt_scripts_into_current_namespace_if_configured
|
||
:If 0≠⎕NC'#.UT.appdir'
|
||
:If ⍬≢#.UT.appdir
|
||
⎕SE.SALT.Load #.UT.appdir,'src/*.dyalog -target=#'
|
||
⎕SE.SALT.Load #.UT.appdir,'test/*.dyalog -target=#'
|
||
:EndIf
|
||
:EndIf
|
||
∇
|
||
|
||
∇ Z←FromSpace single_function_test_function TestName
|
||
Z←run_ut FromSpace TestName
|
||
∇
|
||
|
||
∇ Z←FromSpace list_of_functions_test_function ListOfNames;t
|
||
t←⎕TS
|
||
Z←run_ut¨{FromSpace ⍵}¨ListOfNames
|
||
t←⎕TS-t
|
||
('Test execution report')print_passed_crashed_failed Z t
|
||
∇
|
||
|
||
∇ Z←FromSpace file_test_function FilePath;FileNS;Functions;TestFunctions;t
|
||
FileNS←⎕SE.SALT.Load FilePath,' -target=#'
|
||
Functions←↓FileNS.⎕NL 3
|
||
TestFunctions←(is_test¨Functions)/Functions
|
||
:If (0/⍬,⊂0/'')≡TestFunctions
|
||
⎕←'No test functions found'
|
||
Z←⍬
|
||
:Else
|
||
t←⎕TS
|
||
Z←run_ut¨{FileNS ⍵}¨TestFunctions
|
||
t←⎕TS-t
|
||
(FilePath,' tests')print_passed_crashed_failed Z t
|
||
:EndIf
|
||
∇
|
||
|
||
∇ Z←FromSpace test_dir_function Test_files
|
||
:If Test_files≡⍬/⍬,⊂''
|
||
⎕←'No test files found'
|
||
Z←⍬
|
||
:Else
|
||
Z←#.UT.run¨Test_files
|
||
:EndIf
|
||
∇
|
||
|
||
∇ Z←get_file_name Argument;separator
|
||
separator←⊃⌽(Argument∊'/\')/⍳⍴Argument
|
||
Z←¯7↓separator↓Argument
|
||
∇
|
||
|
||
∇ generate_coverage_page Conf;ProfileData;CoverResults;HTML
|
||
ProfileData←⎕PROFILE'data'
|
||
ToCover←retrieve_coverables¨(⊃'cover_target'in Conf)
|
||
:If (⍴ToCover)≡(⍴⊂1)
|
||
ToCover←⊃ToCover
|
||
:EndIf
|
||
Representations←get_representation¨ToCover
|
||
CoverResults←ProfileData∘generate_cover_result¨↓ToCover,[1.5]Representations
|
||
HTML←generate_html CoverResults
|
||
Conf write_html_to_page HTML
|
||
⎕PROFILE'clear'
|
||
∇
|
||
|
||
∇ Z←retrieve_coverables Something;nc;functions
|
||
nc←⎕NC Something
|
||
:If nc=3
|
||
Z←Something
|
||
:ElseIf nc=9
|
||
functions←strip¨↓⍎Something,'.⎕NL 3'
|
||
Z←{(Something,'.',⍵)}¨functions
|
||
:EndIf
|
||
∇
|
||
|
||
∇ Z←strip input
|
||
Z←(input≠' ')/input
|
||
∇
|
||
|
||
∇ Z←get_representation Function;nc;rep
|
||
nc←⎕NC⊂Function
|
||
:If nc=3.1
|
||
rep←↓⎕CR Function
|
||
rep[1]←⊂'∇',⊃rep[1]
|
||
rep,←⊂'∇'
|
||
rep←↑rep
|
||
:Else
|
||
rep←⎕CR Function
|
||
:EndIf
|
||
Z←rep
|
||
∇
|
||
|
||
∇ Z←ProfileData generate_cover_result(name representation);Indices;lines;functionlines;covered_lines
|
||
Indices←({name≡⍵}¨ProfileData[;1])/⍳⍴ProfileData[;1]
|
||
lines←ProfileData[Indices;2]
|
||
nc←⎕NC⊂name
|
||
:If 3.1=nc
|
||
functionlines←¯2+⍴↓representation
|
||
:Else
|
||
functionlines←⊃⍴↓representation
|
||
:EndIf
|
||
covered_lines←(⍬∘≢¨lines)/lines
|
||
Z←(nc lines functionlines covered_lines representation)
|
||
∇
|
||
|
||
∇ Z←generate_html CoverResults;Covered;Total;Percentage;CoverageText;ColorizedCode;Timestamp;Page
|
||
Covered←⊃⊃+/{⍴4⊃⍵}¨CoverResults
|
||
Total←⊃⊃+/{3⊃⍵}¨CoverResults
|
||
Percentage←100×Covered÷Total
|
||
CoverageText←'Coverage: ',Percentage,'% (',Covered,'/',Total,')'
|
||
ColorizedCode←⊃,/{colorize_code_by_coverage ⍵}¨CoverResults
|
||
Timestamp←generate_timestamp_text
|
||
Page←⍬
|
||
Page,←⊂⍬,'<html>'
|
||
Page,←⊂⍬,'<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>'
|
||
Page,←⊂⍬,'<style>pre cov {line-height:80%;}'
|
||
Page,←⊂⍬,'pre cov {color: green;}'
|
||
Page,←⊂⍬,'pre uncov {line-height:80%;}'
|
||
Page,←⊂⍬,'pre uncov {color:red;}</style>'
|
||
Page,←⊂⍬,CoverageText
|
||
Page,←⊂⍬,'<pre>'
|
||
Page,←ColorizedCode
|
||
Page,←⊂⍬,'</pre>'
|
||
Page,←Timestamp
|
||
Page,←⊂⍬,'</html>'
|
||
Z←Page
|
||
∇
|
||
|
||
∇ Z←colorize_code_by_coverage CoverResult;Colors;Ends;Code
|
||
:If 3.1=⊃CoverResult
|
||
Colors←(2+3⊃CoverResult)⍴⊂'<uncov>'
|
||
Colors[1]←⊂''
|
||
Colors[⍴Colors]←⊂''
|
||
Ends←(2+3⊃CoverResult)⍴⊂'</uncov>'
|
||
Ends[1]←⊂''
|
||
Ends[⍴Ends]←⊂''
|
||
:Else
|
||
Colors←(3⊃CoverResult)⍴⊂'<uncov>'
|
||
Ends←(3⊃CoverResult)⍴⊂'</uncov>'
|
||
:EndIf
|
||
Colors[1+4⊃CoverResult]←⊂'<cov>'
|
||
Ends[1+4⊃CoverResult]←⊂'</cov>'
|
||
Code←↓5⊃CoverResult
|
||
Z←Colors,[1.5]Code
|
||
Z←{⍺,(⎕UCS 13),⍵}/Z,Ends
|
||
∇
|
||
|
||
∇ Z←generate_timestamp_text;TS;YYMMDD;HHMMSS
|
||
TS←⎕TS
|
||
YYMMDD←⊃{⍺,'-',⍵}/3↑TS
|
||
HHMMSS←⊃{⍺,':',⍵}/3↑3↓TS
|
||
Z←'Page generated: ',YYMMDD,'|',HHMMSS
|
||
∇
|
||
|
||
∇ Conf write_html_to_page Page;tie;filename
|
||
filename←(⊃'cover_out'in Conf),(⊃'cover_file'in Conf)
|
||
:Trap 22
|
||
tie←filename ⎕NTIE 0
|
||
filename ⎕NERASE tie
|
||
filename ⎕NCREATE tie
|
||
:Else
|
||
tie←filename ⎕NCREATE 0
|
||
:EndTrap
|
||
Simple_array←⍕⊃,/Page
|
||
(⎕UCS'UTF-8'⎕UCS Simple_array)⎕NAPPEND tie
|
||
∇
|
||
|
||
∇ Z←is_function Argument
|
||
Z←'_TEST'≡¯5↑Argument
|
||
∇
|
||
|
||
∇ Z←is_list_of_functions Argument
|
||
Z←2=≡Argument
|
||
∇
|
||
|
||
∇ Z←is_file Argument
|
||
Z←'.dyalog'≡¯7↑Argument
|
||
∇
|
||
|
||
∇ Z←is_dir Argument;attr
|
||
:If 'Linux'≡5↑⊃'.'⎕WG'APLVersion'
|
||
Z←'yes'≡⊃⎕CMD'test -d ',Argument,' && echo yes || echo no'
|
||
:Else
|
||
'gfa'⎕NA'I kernel32|GetFileAttributes* <0t'
|
||
:If Z←¯1≠attr←gfa⊂Argument ⍝ If file exists
|
||
Z←⊃2 16⊤attr ⍝ Return bit 4
|
||
:EndIf
|
||
:EndIf
|
||
∇
|
||
|
||
|
||
∇ Z←test_files_in_dir Argument
|
||
:If 'Linux'≡5↑⊃'.'⎕WG'APLVersion'
|
||
Z←⎕SH'find ',Argument,' -name \*_tests.dyalog'
|
||
:Else
|
||
#.⎕CY'files'
|
||
Z←#.Files.Dir Argument,'\*_tests.dyalog'
|
||
Z←(Argument,'\')∘,¨Z
|
||
:EndIf
|
||
∇
|
||
|
||
∇ Z←run_ut ut_data;returned;crashed;pass;crash;fail;message
|
||
(returned crashed time)←execute_function ut_data
|
||
(pass crash fail)←determine_pass_crash_or_fail returned crashed
|
||
message←determine_message pass fail crashed(2⊃ut_data)returned time
|
||
print_message_to_screen message
|
||
Z←(pass crash fail)
|
||
∇
|
||
|
||
∇ Z←execute_function ut_data;function;t
|
||
reset_UT_globals
|
||
function←(⍕(⊃ut_data[1])),'.',⊃ut_data[2]
|
||
:Trap sac
|
||
:If 3.2≡⎕NC⊂function
|
||
t←⎕TS
|
||
Z←(⍎function,' ⍬')0
|
||
t←⎕TS-t
|
||
:Else
|
||
t←⎕TS
|
||
Z←(⍎function)0
|
||
t←⎕TS-t
|
||
:EndIf
|
||
|
||
:Else
|
||
Z←(↑⎕DM)1
|
||
:If exception≢⍬
|
||
expect←exception
|
||
Z[2]←0
|
||
t←⎕TS-t
|
||
:EndIf
|
||
:EndTrap
|
||
Z,←⊂t
|
||
∇
|
||
|
||
∇ reset_UT_globals
|
||
expect_orig ← expect← ⎕NS⍬
|
||
exception←⍬
|
||
nexpect_orig ← nexpect← ⎕NS⍬
|
||
∇
|
||
|
||
∇ Z←is_test FunctionName;wsIndex
|
||
wsIndex←FunctionName⍳' '
|
||
FunctionName←(wsIndex-1)↑FunctionName
|
||
Z←'_TEST'≡¯5↑FunctionName
|
||
∇
|
||
|
||
∇ Heading print_passed_crashed_failed(ArrayRes time)
|
||
⎕←'-----------------------------------------'
|
||
⎕←Heading
|
||
⎕←' ⍋ Passed: ',+/{1⊃⍵}¨ArrayRes
|
||
⎕←' ⍟ Crashed: ',+/{2⊃⍵}¨ArrayRes
|
||
⎕←' ⍒ Failed: ',+/{3⊃⍵}¨ArrayRes
|
||
⎕←' ○ Runtime: ',time[5],'m',time[6],'s',time[7],'ms'
|
||
∇
|
||
|
||
determine_pass_crash_or_fail←{
|
||
r c←⍵ ⋄ 0≠c:0 1 0 ⋄ z←(0 0 1)(1 0 0)
|
||
expect_orig≢expect:(⎕IO+expect≡r)⊃z ⋄ (⎕IO+nexpect≢r)⊃z
|
||
}
|
||
|
||
∇ Z←determine_message(pass fail crashed name returned time)
|
||
:If crashed
|
||
Z←'CRASHED: 'failure_message name returned
|
||
:ElseIf pass
|
||
Z←'Passed ',time[5],'m',time[6],'s',time[7],'ms'
|
||
:Else
|
||
Z←'FAILED: 'failure_message name returned
|
||
:EndIf
|
||
∇
|
||
|
||
∇ print_message_to_screen message
|
||
⎕←message
|
||
∇
|
||
|
||
∇ Z←term_to_text Term;Text;Rows
|
||
Text←#.DISPLAY Term
|
||
Rows←1⊃⍴Text
|
||
Z←(Rows 4⍴''),Text
|
||
∇
|
||
|
||
∇ Z←Cause failure_message(name returned);hdr;exp;expterm;got;gotterm
|
||
hdr←Cause,name
|
||
exp←'Expected'
|
||
expterm←term_to_text #.UT.expect
|
||
got←'Got'
|
||
gotterm←term_to_text returned
|
||
Z←align_and_join_message_parts hdr exp expterm got gotterm
|
||
∇
|
||
|
||
∇ Z←align_and_join_message_parts Parts;hdr;exp;expterm;got;gotterm;R1;C1;R2;C2;W
|
||
(hdr exp expterm got gotterm)←Parts
|
||
(R1 C1)←⍴expterm
|
||
(R2 C2)←⍴gotterm
|
||
W←⊃⊃⌈/C1 C2(⍴hdr)(⍴exp)(⍴got)
|
||
Z←(W↑hdr),[0.5](W↑exp)
|
||
Z←Z⍪(R1 W↑expterm)
|
||
Z←Z⍪(W↑got)
|
||
Z←Z⍪(R2 W↑gotterm)
|
||
∇
|
||
|
||
∇ Z←confparam in config
|
||
Z←1↓⊃({confparam≡⊃⍵}¨config)/config
|
||
∇
|
||
|
||
∇ Z←config has confparam
|
||
Z←∨/{confparam≡⊃⍵}¨config
|
||
∇
|
||
|
||
:EndNameSpace
|