Skip to content

Commit 4c43630

Browse files
refactor(tests): updated export_data tests
1 parent 3fa2c01 commit 4c43630

1 file changed

Lines changed: 156 additions & 136 deletions

File tree

Lines changed: 156 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,161 +1,181 @@
11
@testsnippet deps_export_atp begin
2-
using EzXML
2+
using EzXML
33
end
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
93104
end
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

Comments
 (0)