Skip to content

Commit 5a38791

Browse files
test(tutorials): add tutorial integration tests
1 parent 646f289 commit 5a38791

3 files changed

Lines changed: 561 additions & 0 deletions

File tree

test/test_tutorial1.jl

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
using Test
2+
using DataFrames
3+
using LineCableModels
4+
5+
# Helpers
6+
function material_approx_equal(m::Material, rho, eps_r, mu_r, T0, alpha; atol=1e-12, rtol=1e-8)
7+
return isapprox(m.rho, rho; atol=atol, rtol=rtol) &&
8+
isapprox(m.eps_r, eps_r; atol=atol, rtol=rtol) &&
9+
isapprox(m.mu_r, mu_r; atol=atol, rtol=rtol) &&
10+
isapprox(m.T0, T0; atol=atol, rtol=rtol) &&
11+
isapprox(m.alpha, alpha; atol=atol, rtol=rtol)
12+
end
13+
14+
@testset "examples/tutorial1.jl tests" begin
15+
16+
@testset "initialize and inspect" begin
17+
materials = MaterialsLibrary() # default initialization as in the tutorial
18+
@test materials !== nothing
19+
20+
# DataFrame conversion
21+
df = DataFrame(materials)
22+
@test isa(df, DataFrame)
23+
@test nrow(df) >= 0 # should be defined (>=0); more specific tests below
24+
25+
# Check expected columns if present
26+
expected = ["name", "rho", "eps_r", "mu_r", "T0", "alpha"]
27+
@test all(x -> x in string.(names(df)), expected)
28+
end
29+
30+
@testset "add materials from tutorial" begin
31+
materials = MaterialsLibrary(add_defaults=false) # start clean for deterministic tests
32+
33+
# Define tutorial materials (subset representative of file)
34+
copper_corrected = Material(1.835e-8, 1.0, 0.999994, 20.0, 0.00393)
35+
aluminum_corrected = Material(3.03e-8, 1.0, 0.999994, 20.0, 0.00403)
36+
epr = Material(1e15, 3.0, 1.0, 20.0, 0.005)
37+
pvc = Material(1e15, 8.0, 1.0, 20.0, 0.1)
38+
39+
add!(materials, "copper_corrected", copper_corrected)
40+
add!(materials, "aluminum_corrected", aluminum_corrected)
41+
add!(materials, "epr", epr)
42+
add!(materials, "pvc", pvc)
43+
44+
# Verify that keys exist
45+
for name in ("copper_corrected", "aluminum_corrected", "epr", "pvc")
46+
@test haskey(materials, name)
47+
end
48+
49+
# DataFrame contains the names
50+
df = DataFrame(materials)
51+
@test "copper_corrected" in df.name
52+
@test "epr" in df.name
53+
end
54+
55+
@testset "remove duplicate" begin
56+
materials = MaterialsLibrary(add_defaults=false)
57+
epr = Material(1e15, 3.0, 1.0, 20.0, 0.005)
58+
add!(materials, "epr", epr)
59+
60+
# Add duplicate and then remove it
61+
add!(materials, "epr_dupe", epr)
62+
@test haskey(materials, "epr_dupe")
63+
delete!(materials, "epr_dupe")
64+
@test !haskey(materials, "epr_dupe")
65+
end
66+
67+
@testset "save and load round-trip (temp file)" begin
68+
materials = MaterialsLibrary(add_defaults=false)
69+
70+
# Add a small set of materials
71+
copper_corrected = Material(1.835e-8, 1.0, 0.999994, 20.0, 0.00393)
72+
epr = Material(1e15, 3.0, 1.0, 20.0, 0.005)
73+
add!(materials, "copper_corrected", copper_corrected)
74+
add!(materials, "epr", epr)
75+
76+
tmpfile = tempname() * ".json"
77+
try
78+
# Save to temporary file
79+
save(materials, file_name=tmpfile)
80+
@test isfile(tmpfile)
81+
82+
# Load into a fresh library
83+
loaded = MaterialsLibrary(add_defaults=false)
84+
load!(loaded, file_name=tmpfile)
85+
86+
# Keys present after load
87+
@test haskey(loaded, "copper_corrected")
88+
@test haskey(loaded, "epr")
89+
90+
# Retrieve and compare properties
91+
copper_loaded = get(loaded, "copper_corrected")
92+
@test isa(copper_loaded, Material)
93+
@test material_approx_equal(copper_loaded, 1.835e-8, 1.0, 0.999994, 20.0, 0.00393)
94+
95+
epr_loaded = get(loaded, "epr")
96+
@test isa(epr_loaded, Material)
97+
@test material_approx_equal(epr_loaded, 1e15, 3.0, 1.0, 20.0, 0.005)
98+
99+
finally
100+
isfile(tmpfile) && rm(tmpfile)
101+
end
102+
end
103+
104+
@testset "error handling" begin
105+
# Fresh empty library (no defaults) for deterministic error behavior
106+
empty_lib = MaterialsLibrary(add_defaults=false)
107+
108+
# get on non-existent key should throw KeyError (match tutorial usage expectation)
109+
@test_throws KeyError get(empty_lib, "non_existent_material")
110+
111+
# delete! on non-existent key should throw KeyError
112+
@test_throws KeyError delete!(empty_lib, "non_existent_material")
113+
114+
# load! from a non-existent file should throw an I/O-related error (SystemError / IOError)
115+
bad_file_lib = MaterialsLibrary(add_defaults=false)
116+
@test_throws Exception load!(bad_file_lib, file_name="this_file_should_not_exist_hopefully_0123456789.json")
117+
end
118+
119+
@testset "integration-like workflow (safe, uses temp files)" begin
120+
# Recreate the main tutorial workflow but using temporary save path
121+
materials = MaterialsLibrary(add_defaults=false)
122+
123+
# Add the full tutorial list used in examples (representative)
124+
add!(materials, "copper_corrected", Material(1.835e-8, 1.0, 0.999994, 20.0, 0.00393))
125+
add!(materials, "aluminum_corrected", Material(3.03e-8, 1.0, 0.999994, 20.0, 0.00403))
126+
add!(materials, "lead", Material(21.4e-8, 1.0, 0.999983, 20.0, 0.00400))
127+
add!(materials, "steel", Material(13.8e-8, 1.0, 300.0, 20.0, 0.00450))
128+
add!(materials, "bronze", Material(3.5e-8, 1.0, 1.0, 20.0, 0.00300))
129+
add!(materials, "stainless_steel", Material(70.0e-8, 1.0, 500.0, 20.0, 0.0))
130+
add!(materials, "epr", Material(1e15, 3.0, 1.0, 20.0, 0.005))
131+
add!(materials, "pvc", Material(1e15, 8.0, 1.0, 20.0, 0.1))
132+
add!(materials, "laminated_paper", Material(1e15, 2.8, 1.0, 20.0, 0.0))
133+
add!(materials, "carbon_pe", Material(0.06, 1e3, 1.0, 20.0, 0.0))
134+
add!(materials, "conductive_paper", Material(18.5, 8.6, 1.0, 20.0, 0.0))
135+
136+
# Duplicate add and delete
137+
add!(materials, "epr_dupe", get(materials, "epr"))
138+
@test haskey(materials, "epr_dupe")
139+
delete!(materials, "epr_dupe")
140+
@test !haskey(materials, "epr_dupe")
141+
142+
tmpfile = tempname() * ".json"
143+
try
144+
save(materials, file_name=tmpfile)
145+
@test isfile(tmpfile)
146+
147+
reloaded = MaterialsLibrary(add_defaults=false)
148+
load!(reloaded, file_name=tmpfile)
149+
150+
# verify a representative sample of materials exists after reload
151+
for name in ("copper_corrected", "pvc", "stainless_steel")
152+
@test haskey(reloaded, name)
153+
end
154+
155+
# Verify copper properties after reload
156+
copper = get(reloaded, "copper_corrected")
157+
@test material_approx_equal(copper, 1.835e-8, 1.0, 0.999994, 20.0, 0.00393)
158+
159+
finally
160+
isfile(tmpfile) && rm(tmpfile)
161+
end
162+
end
163+
164+
end

0 commit comments

Comments
 (0)