Skip to content
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 162 additions & 0 deletions tests/reverse.apln
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
:Namespace reverse
Assert←#.unittest.Assert
isDyalogClassic←#.utils.isClassic

⍝ The current model does not depend on ⌽
⍝ Handles scalars by returning ⍵
⍝ Will be using rank operator to target the last axis.
⍝ The guards are required here to return the scalar unchanged.
⍝ I am not completely sure so do correct me if i am wrong but for a rank-0 scalar, r = 0, and ⍤1 would try to select 1-cells from an array of rank 0. Since,
⍝ There are no 1-cells to select, `RandomScalar` will fail.
⍝ Here: https://docs.dyalog.com/20.0/language-reference-guide/primitive-operators/rank/
⍝ Although, i am still not sure if this is the best model function that can be used here
modelReverse←{
0=≢⍴⍵:⍵
n←(≢⍴⍵)⊃⍴⍵
({⍵[(n+1)-⍳n]}⍤1)⍵
}

∇ r←testDesc
r←'for ',case

∇ {r}←test_reverse;bool;i1;i2;i3;dbl;Hdbl;fl;Hfl;cmplx;Hcmplx;char0;char1;char2;char3;case;data;desc;scalar;empty;matrix;array3d;empty2d;empty3d;largeData;hashedData;RunVariations;data_rand_i1;data_rand_i2;data_rand_i4;data_rand_char1;data_rand_char2;quadparams
r←⍬

⍝ Monadic reverse has no implicit system variable dependencies so no need for the loops
⍝ quadparams are set to defaults as required by RunVariations
quadparams←(#.utils.ct_default) (#.utils.dct_default) (#.utils.fr_dbl) 1 (#.utils.div_0)

RunVariations←modelReverse #.testfns._RunVariationsWithModel_ ⌽

data_rand_i1←1000 #.random.Ints 8
data_rand_i2←1000 #.random.Ints 16
data_rand_i4←1000 #.random.Ints 32

:If ~isDyalogClassic
data_rand_char1←1000 #.random.Chars 8
data_rand_char2←1000 #.random.Chars 16
:EndIf

bool←0 1
i1←{⍵,-⍵}⍳120
i2←{⍵,-⍵}10000+⍳1000
i3←{⍵,-⍵}100000+⍳100

char0←⎕AV
:If ~isDyalogClassic
char1←⎕UCS⍳255
char2←⎕UCS(1000+⍳100)
char3←⎕UCS(100000+⍳100)
:EndIf

dbl←{⍵,-⍵}1000.5+⍳100
Hdbl←{⍵,-⍵}100000000000000+(2×⍳50)

⍝ Decimal floating point data requires ⎕FR←1287
⎕FR←#.utils.fr_decf
fl←{⍵,-⍵}1000.5+⍳100
Hfl←{⍵,-⍵}200000000000000000000000000000+(10000000000000000×⍳10)
⎕FR←#.utils.fr_dbl

cmplx←{⍵,-⍵}(0J1×⍳100)+⌽⍳100
Hcmplx←{⍵,-⍵}(100000000000000J100000000000000×⍳20)

:For case :In 'bool' 'i1' 'i2' 'i3' 'dbl' 'Hdbl' 'fl' 'Hfl' 'cmplx' 'Hcmplx'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why we are not looping the tests over ⎕IO?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⎕IO should be covered in RunVariations but i can loop for explicit tests.

data←⍎case
desc←testDesc
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All, the data we have here is of the same datatype in the array. Is there a reason cross datatype tests were skipped?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cross-datatype numeric tests (e.g., i1,dbl) were skipped because APL type coercion automatically promotes mixed numeric arrays to a homogeneous array of the wider type before reverse operates on them. Per the APL Wiki on Arrays (https://aplwiki.com/wiki/Array)

"When a numeric array is formed from numbers with different types, all numbers are converted to a common type in order to be represented as a flat array."

For mixed numeric/character arrays: per Dyalog 20.0 documentation (https://docs.dyalog.com/20.0/programming-reference-guide/introduction/arrays/display-of-arrays/), these become "mixed arrays" which are displayed alongside "simple numeric" arrays but contain both types. I can add those specifically as provided.

If there's a specific cross-datatype scenario you think would expose different behavior in reverse that current tests miss, i can add accordingly.


⍝ RunVariations: normal, scalar, empty, multiple shapes, shape with 0, model comparison, random data
r,←'T1'desc quadparams RunVariations,⊂data

desc←'Double reverse for ',case
r,←'T2'desc Assert data≡⌽⌽data

desc←'Datatype preserved for ',case
r,←'T3'desc Assert (⎕DR data)≡⎕DR ⌽data

⍝ Large array stress test
desc←'Large array (10000) for ',case
largeData←10000⍴data
r,←'T4'desc Assert largeData≡⌽⌽largeData

⍝ Hash collision handling test
:If 9=⎕NC'#.utils.hashArray'
hashedData←#.utils.hashArray data
desc←'Hashed array reverse for ',case
r,←'T5'desc Assert hashedData≡⌽⌽hashedData
:EndIf
:EndFor

:For case :In 'char0' 'char1' 'char2' 'char3'
:If (isDyalogClassic)∧(case≢'char0')
:Continue
:EndIf
data←⍎case
desc←testDesc

r,←'TC1'desc quadparams RunVariations,⊂data

desc←'Char datatype preserved for ',case
r,←'TC2'desc Assert (⎕DR data)≡⎕DR ⌽data
:EndFor

:For case :In 'data_rand_i1' 'data_rand_i2' 'data_rand_i4'
data←⍎case
desc←testDesc
r,←'TRand1'desc quadparams RunVariations,⊂data
:EndFor

:If ~isDyalogClassic
:For case :In 'data_rand_char1' 'data_rand_char2'
data←⍎case
desc←testDesc
r,←'TRandC1'desc quadparams RunVariations,⊂data
:EndFor
:EndIf

⍝ Scalar edge case: rank 0 arrays
scalar←42
desc←'Scalar unchanged'
r,←'TE1'desc Assert scalar≡⌽scalar

⍝ Empty vector
empty←⍬
desc←'Empty vector'
r,←'TE2'desc Assert empty≡⌽empty

⍝ Empty arrays with non-zero trailing dimensions
empty2d←0 5⍴⍬
desc←'Empty 2D array'
r,←'TEmpty1'desc Assert empty2d≡⌽empty2d
r,←'TEmpty2'desc Assert (⍴empty2d)≡⍴⌽empty2d

empty3d←0 0 5⍴⍬
desc←'Empty 3D array'
r,←'TEmpty3'desc Assert empty3d≡⌽empty3d

⍝ Multi-dimensional arrays: reverse along first axis
matrix←3 4⍴⍳12
desc←'Matrix reverse'
r,←'TE3'desc Assert matrix≡⌽⌽matrix
r,←'TE4'desc Assert (⍴matrix)≡⍴⌽matrix

array3d←2 3 4⍴⍳24
desc←'3D array reverse'
r,←'T3D1'desc Assert array3d≡⌽⌽array3d
r,←'T3D2'desc Assert (⍴array3d)≡⍴⌽array3d

array3d←4 5 6⍴⍳120
desc←'3D array (4x5x6) reverse'
r,←'T3D3'desc Assert array3d≡⌽⌽array3d

⍝ Namespace arrays
desc←'Namespace reverse'
r,←'Tns1'desc Assert ((# ⎕SE))≡⌽⌽(# ⎕SE)
r,←'Tns2'desc Assert (modelReverse(# ⎕SE))≡⌽(# ⎕SE)

desc←'Single namespace'
r,←'Tns3'desc Assert (,#)≡⌽,#
:EndNamespace