11@testsnippet deps_export_atp begin
2- using EzXML
2+ using EzXML
33end
44
55# TODO : test if serialization works properly if uncertain types are used (Measurements)
66
7- @testitem " ImportExport(export_data::atp): export LineCableSystem -> LCC data" setup = [defaults, cable_system_export, deps_export_atp] begin
8-
9-
10- # 1. ARRANGE & ACT: Run the export in a temporary directory
11- mktempdir (joinpath (@__DIR__ )) do tmpdir
12- output_file = joinpath (tmpdir, " atp_export_test.xml" )
13- result_path = export_data (:atp , cable_system, earth_props, file_name= output_file)
14- expected_file = joinpath (dirname (output_file), " $(cable_system. system_id) _$(basename (output_file)) " )
15-
16- # 2. ASSERT: Basic file checks (exporter prefixes basename with system_id)
17- @test result_path == expected_file
18- @test isfile (expected_file)
19- @test filesize (expected_file) > 500
20-
21- # 3. ASSERT: General XML structure and LCC data
22- @info " Performing high-level XML structure checks..."
23- doc = readxml (expected_file)
24- root_node = root (doc)
25-
26- @test nodename (root_node) == " project"
27- @test root_node[" Application" ] == " ATPDraw"
28-
29- # Find the main LCC component content node
30- comp_content_node = findfirst (" /project/objects/comp/comp_content" , root_node)
31- @test ! isnothing (comp_content_node)
32-
33- # Verify general parameters like Length, Freq, and Ground Resistivity
34- @info " Verifying general LCC data (Length, Freq, Grnd resis)..."
35- @test parse (Float64, findfirst (" data[@Name='Length']" , comp_content_node)[" Value" ]) ≈ cable_system. line_length
36- @test parse (Float64, findfirst (" data[@Name='Freq']" , comp_content_node)[" Value" ]) ≈ problem_atp. frequencies[1 ]
37- @test parse (Float64, findfirst (" data[@Name='Grnd resis']" , comp_content_node)[" Value" ]) ≈ problem_atp. earth_props. layers[end ]. base_rho_g
38-
39- # 4. ASSERT: Detailed validation of ALL cables and conductors
40- @info " Verifying all cables and their conductors..."
41- lcc_node = findfirst (" /project/objects/comp/LCC" , root_node)
42- cable_header = findfirst (" cable_header" , lcc_node)
43- cable_nodes = findall (" cable" , cable_header)
44-
45- @test length (cable_nodes) == num_phases
46-
47- # Loop through each cable exported in the XML and compare it to the source
48- for (i, cable_node) in enumerate (cable_nodes)
49- @info " -> Checking Cable #$i ..."
50- source_cable = cable_system. cables[i]
51-
52- # Verify position of EACH cable
53- @test parse (Float64, cable_node[" PosX" ]) ≈ source_cable. horz
54- @test parse (Float64, cable_node[" PosY" ]) ≈ source_cable. vert
55-
56- # Verify the number of conductor components inside this cable
57- num_components = length (source_cable. design_data. components)
58- @test parse (Int, cable_node[" NumCond" ]) == num_components
59-
60- conductor_nodes = findall (" conductor" , cable_node)
61- @test length (conductor_nodes) == num_components
62-
63- # Loop through each conductor component within the cable
64- for (j, conductor_node) in enumerate (conductor_nodes)
65- source_component = source_cable. design_data. components[j]
66- cond_group = source_component. conductor_group
67- cond_props = source_component. conductor_props
68- ins_group = source_component. insulator_group
69- ins_props = source_component. insulator_props
70-
71- expected_radius_in = cond_group. radius_in
72- expected_radius_ext = cond_group. radius_ext
73- expected_rho = cond_props. rho
74- expected_muC = cond_props. mu_r
75- expected_epsI = ins_props. eps_r
76- expected_muI = ins_props. mu_r
77- expected_Cext = ins_group. shunt_capacitance
78- expected_Gext = ins_group. shunt_conductance
79-
80- # Assert that every attribute matches the expected value
81- @test parse (Float64, conductor_node[" Rin" ]) ≈ expected_radius_in
82- @test parse (Float64, conductor_node[" Rout" ]) ≈ expected_radius_ext
83- @test parse (Float64, conductor_node[" rho" ]) ≈ expected_rho
84- @test parse (Float64, conductor_node[" muC" ]) ≈ expected_muC
85- @test parse (Float64, conductor_node[" muI" ]) ≈ expected_muI
86- @test parse (Float64, conductor_node[" epsI" ]) ≈ expected_epsI
87- @test parse (Float64, conductor_node[" Cext" ]) ≈ expected_Cext
88- @test parse (Float64, conductor_node[" Gext" ]) ≈ expected_Gext
89- end
90- end
91- @info " All detailed checks passed!"
92- end
7+ @testitem " ImportExport(export_data::atp): export LineCableSystem -> LCC data" setup =
8+ [defaults, cable_system_export, deps_export_atp] begin
9+
10+
11+ # 1. ARRANGE & ACT: Run the export in a temporary directory
12+ mktempdir (joinpath (@__DIR__ )) do tmpdir
13+ output_file = joinpath (tmpdir, " atp_export_test.xml" )
14+ result_path = export_data (:atp , cable_system, earth_props, file_name = output_file)
15+ expected_file = joinpath (
16+ dirname (output_file),
17+ " $(cable_system. system_id) _$(basename (output_file)) " ,
18+ )
19+
20+ # 2. ASSERT: Basic file checks (exporter prefixes basename with system_id)
21+ @test result_path == expected_file
22+ @test isfile (expected_file)
23+ @test filesize (expected_file) > 500
24+
25+ # 3. ASSERT: General XML structure and LCC data
26+ @info " Performing high-level XML structure checks..."
27+ doc = readxml (expected_file)
28+ root_node = root (doc)
29+
30+ @test nodename (root_node) == " project"
31+ @test root_node[" Application" ] == " ATPDraw"
32+
33+ # Find the main LCC component content node
34+ comp_content_node = findfirst (" /project/objects/comp/comp_content" , root_node)
35+ @test ! isnothing (comp_content_node)
36+
37+ # Verify general parameters like Length, Freq, and Ground Resistivity
38+ @info " Verifying general LCC data (Length, Freq, Grnd resis)..."
39+ @test parse (
40+ Float64,
41+ findfirst (" data[@Name='Length']" , comp_content_node)[" Value" ],
42+ ) ≈ cable_system. line_length
43+ @test parse (Float64, findfirst (" data[@Name='Freq']" , comp_content_node)[" Value" ]) ≈
44+ problem_atp. frequencies[1 ]
45+ @test parse (
46+ Float64,
47+ findfirst (" data[@Name='Grnd resis']" , comp_content_node)[" Value" ],
48+ ) ≈ problem_atp. earth_props. layers[end ]. base_rho_g
49+
50+ # 4. ASSERT: Detailed validation of ALL cables and conductors
51+ @info " Verifying all cables and their conductors..."
52+ lcc_node = findfirst (" /project/objects/comp/LCC" , root_node)
53+ cable_header = findfirst (" cable_header" , lcc_node)
54+ cable_nodes = findall (" cable" , cable_header)
55+
56+ @test length (cable_nodes) == num_phases
57+
58+ # Loop through each cable exported in the XML and compare it to the source
59+ for (i, cable_node) in enumerate (cable_nodes)
60+ @info " -> Checking Cable #$i ..."
61+ source_cable = cable_system. cables[i]
62+
63+ # Verify position of EACH cable
64+ @test parse (Float64, cable_node[" PosX" ]) ≈ source_cable. horz
65+ @test parse (Float64, cable_node[" PosY" ]) ≈ source_cable. vert
66+
67+ # Verify the number of conductor components inside this cable
68+ num_components = length (source_cable. design_data. components)
69+ @test parse (Int, cable_node[" NumCond" ]) == num_components
70+
71+ conductor_nodes = findall (" conductor" , cable_node)
72+ @test length (conductor_nodes) == num_components
73+
74+ # Loop through each conductor component within the cable
75+ for (j, conductor_node) in enumerate (conductor_nodes)
76+ source_component = source_cable. design_data. components[j]
77+ cond_group = source_component. conductor_group
78+ cond_props = source_component. conductor_props
79+ ins_group = source_component. insulator_group
80+ ins_props = source_component. insulator_props
81+
82+ expected_radius_in = cond_group. radius_in
83+ expected_radius_ext = cond_group. radius_ext
84+ expected_rho = cond_props. rho
85+ expected_muC = cond_props. mu_r
86+ expected_epsI = ins_props. eps_r
87+ expected_muI = ins_props. mu_r
88+ expected_Cext = ins_group. shunt_capacitance
89+ expected_Gext = ins_group. shunt_conductance
90+
91+ # Assert that every attribute matches the expected value
92+ @test parse (Float64, conductor_node[" Rin" ]) ≈ expected_radius_in
93+ @test parse (Float64, conductor_node[" Rout" ]) ≈ expected_radius_ext
94+ @test parse (Float64, conductor_node[" rho" ]) ≈ expected_rho
95+ @test parse (Float64, conductor_node[" muC" ]) ≈ expected_muC
96+ @test parse (Float64, conductor_node[" muI" ]) ≈ expected_muI
97+ @test parse (Float64, conductor_node[" epsI" ]) ≈ expected_epsI
98+ @test parse (Float64, conductor_node[" Cext" ]) ≈ expected_Cext
99+ @test parse (Float64, conductor_node[" Gext" ]) ≈ expected_Gext
100+ end
101+ end
102+ @info " All detailed checks passed!"
103+ end
93104end
94105
95106
96107
97108
98- @testitem " ImportExport(export_data::atp): export LineParameters -> ZY matrices" setup = [defaults, cable_system_export, deps_export_atp] begin
109+ @testitem " ImportExport(export_data::atp): export LineParameters -> ZY matrices" setup =
110+ [defaults, cable_system_export, deps_export_atp] begin
99111
100112
101113
102- # 1. RUN THE TEST IN A TEMPORARY DIRECTORY
103- mktempdir (joinpath (@__DIR__ )) do tmpdir
104- output_file = joinpath (tmpdir, " atp_export_test.xml" )
105- @info " Exporting ATP XML file to: $output_file "
106- Z_matrix = randn (ComplexF64, num_phases, num_phases, length (freqs))
107- Y_matrix = randn (ComplexF64, num_phases, num_phases, length (freqs))
108- line_params = LineParameters (Z_matrix, Y_matrix)
114+ # 1. RUN THE TEST IN A TEMPORARY DIRECTORY
115+ mktempdir (joinpath (@__DIR__ )) do tmpdir
116+ output_file = joinpath (tmpdir, " atp_export_test.xml" )
117+ @info " Exporting ATP XML file to: $output_file "
118+ Z_matrix = randn (ComplexF64, num_phases, num_phases, length (freqs))
119+ Y_matrix = randn (ComplexF64, num_phases, num_phases, length (freqs))
120+ line_params = LineParameters (Z_matrix, Y_matrix, freqs )
109121
110- # Call the function we want to test (use the LineParameters overload and pass freqs)
111- result_path = export_data (:atp , line_params, freqs; file_name= output_file, cable_system= cable_system)
112- expected_file = joinpath (dirname (output_file), " $(cable_system. system_id) _$(basename (output_file)) " )
122+ # Call the function we want to test (use the LineParameters overload and pass freqs)
123+ result_path = export_data (
124+ :atp ,
125+ line_params;
126+ file_name = output_file,
127+ cable_system = cable_system,
128+ )
129+ expected_file = joinpath (
130+ dirname (output_file),
131+ " $(cable_system. system_id) _$(basename (output_file)) " ,
132+ )
113133
114- # 2. BASIC FILE CHECKS
115- @test result_path == expected_file
116- @test isfile (expected_file)
117- @test filesize (expected_file) > 100
134+ # 2. BASIC FILE CHECKS
135+ @test result_path == expected_file
136+ @test isfile (expected_file)
137+ @test filesize (expected_file) > 100
118138
119- xml_content = read (expected_file, String)
120- @test occursin (" <ZY" , xml_content)
121- @test occursin (" </ZY>" , xml_content)
139+ xml_content = read (expected_file, String)
140+ @test occursin (" <ZY" , xml_content)
141+ @test occursin (" </ZY>" , xml_content)
122142
123- # 3. XML STRUCTURE AND DATA VALIDATION
124- @info " Performing XML structure checks via XPath..."
125- xml_doc = readxml (expected_file)
126- root_node = root (xml_doc)
143+ # 3. XML STRUCTURE AND DATA VALIDATION
144+ @info " Performing XML structure checks via XPath..."
145+ xml_doc = readxml (expected_file)
146+ root_node = root (xml_doc)
127147
128- @test nodename (root_node) == " ZY"
129- @test parse (Int, root_node[" NumPhases" ]) == num_phases
148+ @test nodename (root_node) == " ZY"
149+ @test parse (Int, root_node[" NumPhases" ]) == num_phases
130150
131- # Search the whole document for Z blocks (safer) and assert presence before indexing
132- z_blocks = findall (" //Z" , xml_doc)
133- @test ! isempty (z_blocks)
134- @test length (z_blocks) == length (freqs)
151+ # Search the whole document for Z blocks (safer) and assert presence before indexing
152+ z_blocks = findall (" //Z" , xml_doc)
153+ @test ! isempty (z_blocks)
154+ @test length (z_blocks) == length (freqs)
135155
136- # 4. DETAILED DATA VERIFICATION (for the first frequency)
137- @info " Verifying numerical data for first frequency..."
138- first_z_block = z_blocks[1 ]
139- @test parse (Float64, first_z_block[" Freq" ]) ≈ freqs[1 ]
156+ # 4. DETAILED DATA VERIFICATION (for the first frequency)
157+ @info " Verifying numerical data for first frequency..."
158+ first_z_block = z_blocks[1 ]
159+ @test parse (Float64, first_z_block[" Freq" ]) ≈ freqs[1 ]
140160
141- z_matrix_rows = split (strip (nodecontent (first_z_block)), ' \n ' )
142- @test length (z_matrix_rows) == num_phases
161+ z_matrix_rows = split (strip (nodecontent (first_z_block)), ' \n ' )
162+ @test length (z_matrix_rows) == num_phases
143163
144- first_row_elements = split (z_matrix_rows[1 ], ' ,' )
145- @test length (first_row_elements) == num_phases
146- number_pattern = r" (-?[\d\. ]+E[+-]\d +)"
147- complex_pattern = Regex (" $(number_pattern. pattern) ([+-][\\ d\\ .]+E[+-]\\ d+)i" )
164+ first_row_elements = split (z_matrix_rows[1 ], ' ,' )
165+ @test length (first_row_elements) == num_phases
166+ number_pattern = r" (-?[\d\. ]+E[+-]\d +)"
167+ complex_pattern = Regex (" $(number_pattern. pattern) ([+-][\\ d\\ .]+E[+-]\\ d+)i" )
148168
149- match_result = match (complex_pattern, first_row_elements[1 ])
169+ match_result = match (complex_pattern, first_row_elements[1 ])
150170
151- if ! isnothing (match_result)
152- # The captures are now guaranteed to be valid Float64 strings
153- real_part = parse (Float64, match_result. captures[1 ])
154- imag_part = parse (Float64, match_result. captures[2 ])
155- parsed_z11 = complex (real_part, imag_part)
171+ if ! isnothing (match_result)
172+ # The captures are now guaranteed to be valid Float64 strings
173+ real_part = parse (Float64, match_result. captures[1 ])
174+ imag_part = parse (Float64, match_result. captures[2 ])
175+ parsed_z11 = complex (real_part, imag_part)
156176
157- expected_z11 = Z_matrix[1 , 1 , 1 ]
158- @test parsed_z11 ≈ expected_z11 rtol = 1e-12
159- end
160- end
161- end
177+ expected_z11 = Z_matrix[1 , 1 , 1 ]
178+ @test parsed_z11 ≈ expected_z11 rtol = 1e-12
179+ end
180+ end
181+ end
0 commit comments