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