Skip to content

Commit a89328d

Browse files
committed
Add tests for real formats and increased coverage
1 parent ac92151 commit a89328d

File tree

1 file changed

+176
-0
lines changed

1 file changed

+176
-0
lines changed

src/tests/jf_test_12.f90

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
module jf_test_12_mod
2+
3+
use json_module
4+
use, intrinsic :: iso_fortran_env , only: error_unit, output_unit, wp => real64
5+
6+
implicit none
7+
8+
character(len=*),parameter :: dir = '../files/outputs/' !! Path to write JSON file to
9+
character(len=*),parameter :: file = 'array.json' !! Filename to write
10+
11+
contains
12+
13+
subroutine test_12(error_cnt)
14+
15+
integer,intent(out) :: error_cnt !! report number of errors to caller
16+
17+
integer,parameter :: imx = 5, jmx = 3, kmx = 4 !! dimensions for raw work array of primitive type
18+
integer :: shape(3) !! shape of work array
19+
integer, allocatable :: fetched_shape(:) !! retrieved shape
20+
type(json_value), pointer :: root, meta_array !! json nodes to work with
21+
type(json_value), pointer :: tmp_json_ptr
22+
type(json_file) :: my_file
23+
real(wp) :: raw_array(imx,jmx,kmx) !! raw work array
24+
real(wp) :: array_element
25+
real(wp), allocatable :: fetched_array(:)
26+
character(kind=CK,len=:), allocatable :: description
27+
integer :: i,j,k !! loop indices
28+
integer :: array_length
29+
logical :: existed
30+
logical, allocatable :: SOS(:)
31+
32+
error_cnt = 0
33+
call json_initialize(verbose=.true.,real_format='G')
34+
call check_errors()
35+
36+
write(error_unit,'(A)') ''
37+
write(error_unit,'(A)') '================================='
38+
write(error_unit,'(A)') ' TEST 12'
39+
write(error_unit,'(A)') '================================='
40+
write(error_unit,'(A)') ''
41+
42+
! populate the raw array
43+
forall (i=1:imx,j=1:jmx,k=1:kmx) ! could use size(... , dim=...) instead of constants
44+
raw_array(i,j,k) = i + (j-1)*imx + (k-1)*imx*jmx
45+
end forall
46+
47+
call json_create_object(root,dir//file)
48+
call check_errors()
49+
50+
call json_create_object(meta_array,'array data')
51+
call check_errors()
52+
53+
shape = [size(raw_array,dim=1), size(raw_array,dim=2), size(raw_array,dim=3)]
54+
call json_add(meta_array, 'shape', shape)
55+
call check_errors()
56+
57+
call json_add(meta_array, 'total size', size(raw_array))
58+
call check_errors()
59+
60+
call json_update(meta_array, 'total size', size(raw_array), found=existed)
61+
call check_errors(existed)
62+
63+
call json_add(meta_array, CK_'description', 'test data')
64+
call check_errors()
65+
66+
! now add the array
67+
! N.B. `json_add()` only accepts 1-D arrays and scalars, so transform with `reshape`
68+
! N.B. reshape populates new array in "array element order".
69+
! C.F. "Modern Fortran Explained", by Metcalf, Cohen and Reid, p. 24.
70+
! N.B. Fortran is a column major language
71+
72+
call json_add( meta_array, 'data', reshape( raw_array, [ size(raw_array) ] ) )
73+
call check_errors()
74+
75+
! now put it all together
76+
call json_add(root,meta_array)
77+
call check_errors()
78+
79+
write(error_unit,'(A)') "Print the JSON object to stderr:"
80+
call json_print(root,error_unit)
81+
call check_errors()
82+
83+
call json_get(root,'$.array data.data(1)',array_element)
84+
call check_errors(array_element == 1.0_wp)
85+
86+
call json_get(root,'@.array data.shape',fetched_shape)
87+
call check_errors(all(fetched_shape == shape))
88+
89+
call json_update(meta_array,'description',CK_'Test Data',found=existed)
90+
call check_errors(existed)
91+
92+
call json_update(meta_array,CK_'description','Test data',found=existed)
93+
call check_errors(existed)
94+
95+
call json_get(meta_array,'description',description)
96+
call check_errors('Test data' == description)
97+
98+
call json_get(root,'array data.total size',array_length)
99+
call check_errors(array_length == imx*jmx*kmx)
100+
101+
sos = [.true., .true., .true., &
102+
.false., .false., .false., &
103+
.true., .true., .true.]
104+
call json_add(root,'SOS',sos)
105+
call check_errors()
106+
107+
call json_get(root,'SOS',sos)
108+
call check_errors()
109+
110+
call json_add(root,'vector string', [CK_'only one value'])
111+
call check_errors()
112+
113+
call json_add(root,CK_'page', ['The quick brown fox ', 'jumps over the lazy dog.'])
114+
call check_errors()
115+
116+
call json_get(root,'SOS',tmp_json_ptr)
117+
call check_errors()
118+
119+
call json_get(tmp_json_ptr,sos)
120+
call check_errors()
121+
122+
call json_get(meta_array,'shape',tmp_json_ptr)
123+
call check_errors()
124+
125+
call json_get(tmp_json_ptr,fetched_shape)
126+
call check_errors(all(fetched_shape == shape))
127+
128+
call json_get(meta_array,'data',tmp_json_ptr)
129+
call check_errors()
130+
131+
call json_get(tmp_json_ptr,fetched_array)
132+
call check_errors(all(fetched_array == reshape(raw_array,[size(raw_array)])))
133+
134+
call json_get(root,'array data.data',fetched_array)
135+
call check_errors(all(fetched_array == reshape(raw_array,[size(raw_array)])))
136+
137+
raw_array = 0
138+
call json_get(me=root,path='array data.data',array_callback=get_3D_from_array)
139+
call check_errors(all(fetched_array == reshape(raw_array,[size(raw_array)])))
140+
141+
contains
142+
subroutine check_errors(assertion)
143+
logical, optional, intent(in) :: assertion
144+
if (json_failed()) then
145+
call json_print_error_message(error_unit)
146+
error_cnt = error_cnt + 1
147+
end if
148+
if (present (assertion)) then
149+
if (.not. assertion) error_cnt = error_cnt + 1
150+
end if
151+
end subroutine
152+
153+
subroutine get_3D_from_array(element, i, count)
154+
type(json_value), pointer , intent(in) :: element
155+
integer , intent(in) :: i !index
156+
integer , intent(in) :: count !size of array
157+
158+
! let's pretend we're c programmers!
159+
call json_get( element, raw_array( &
160+
mod(i-1,imx) + 1, & ! i index
161+
mod((i-1)/imx,jmx) + 1, & ! j index
162+
mod((i-1)/imx/jmx,kmx) + 1 ) ) ! k inded
163+
end subroutine
164+
165+
end subroutine
166+
167+
end module
168+
169+
program jf_test_12
170+
use jf_test_12_mod, only: test_12
171+
implicit none
172+
integer :: n_errors
173+
n_errors = 0
174+
call test_12(n_errors)
175+
if ( n_errors /= 0) stop 1
176+
end program

0 commit comments

Comments
 (0)