Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions test/Artifacts.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
[CaseData]
git-tree-sha1 = "edcb5940e84a802a86ad4f2223214d33121ac044"
lazy = true

[[CaseData.download]]
url = "https://github.com/NREL-Sienna/PowerSystemsTestData/archive/refs/tags/4.0.2.tar.gz"
sha256 = "c844aba2ce37c1cc1bb4c496c809607f4ddb310cb76a5fdc266bf6a1345f2b51"

[rts]
git-tree-sha1 = "5098f357bad765bfefcff58f080818863ca776bd"
git-tree-sha1 = "c257b2c37b981f261fdc328b0fb9b96436a96537"
lazy = true

[[rts.download]]
url = "https://github.com/GridMod/RTS-GMLC/archive/refs/tags/v0.2.2.tar.gz"
sha256 = "f7a816f2390b96d44fa931c2790e2ec5ef81d0deb503c4c719b25ec1b585e2c2"
url = "https://github.com/GridMod/RTS-GMLC/archive/refs/tags/v0.2.3.tar.gz"
sha256 = "993429b8dc5f096e62479ca3b8551d52a53941322b452c825d12881cda915eae"
10 changes: 3 additions & 7 deletions test/Project.toml
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
[deps]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
InfrastructureSystems = "2cd47ed4-ca9b-11e9-27f2-ab636a7671f1"
LazyArtifacts = "4af54fe1-eca0-43a8-85a7-787d91b784e3"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
PowerSystemCaseBuilder = "f00506e0-b84f-492a-93c2-c0a9afc4364e"
PowerSystems = "bcd98974-b02a-5e2f-9ee0-a103f5c450dd"
PowerTableDataParser = "2b750c0e-0bff-11f1-9200-1befd75df6be"
SQLite = "0aa819cd-b072-5ff4-a722-6bc24af294d9"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"

[compat]
julia = "^1.6"
julia = "^1.10"
18 changes: 0 additions & 18 deletions test/common.jl

This file was deleted.

34 changes: 34 additions & 0 deletions test/loading_utils.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import LazyArtifacts

const RTS_SRC = joinpath(
LazyArtifacts.artifact"rts",
"RTS-GMLC-0.2.3",
"RTS_Data",
"SourceData",
)
const RTS_DESCRIPTORS = joinpath(@__DIR__, "data", "rts", "user_descriptors.yaml")

const BUS118_SRC = joinpath(
LazyArtifacts.artifact"CaseData",
"PowerSystemsTestData-4.0.2",
"118-Bus",
)
const BUS118_DESCRIPTORS = joinpath(@__DIR__, "data", "118_bus", "user_descriptors.yaml")
const BUS118_GEN_MAPPING = joinpath(@__DIR__, "data", "118_bus", "generator_mapping.yaml")
Comment on lines +3 to +17

Copilot AI Apr 20, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RTS_DESCRIPTORS, BUS118_DESCRIPTORS, and BUS118_GEN_MAPPING point at test/data/... paths, but there is no test/data directory in this PR/repo, so these tests will fail at runtime when attempting to open the YAML files. Add the missing YAML files under test/data/..., or change these constants to reference descriptor/mapping files that are guaranteed to exist (e.g., shipped in the artifacts you download, or generated in the tests via mktempdir()/tempname()).

Suggested change
const RTS_SRC = joinpath(
LazyArtifacts.artifact"rts",
"RTS-GMLC-0.2.3",
"RTS_Data",
"SourceData",
)
const RTS_DESCRIPTORS = joinpath(@__DIR__, "data", "rts", "user_descriptors.yaml")
const BUS118_SRC = joinpath(
LazyArtifacts.artifact"CaseData",
"PowerSystemsTestData-4.0.2",
"118-Bus",
)
const BUS118_DESCRIPTORS = joinpath(@__DIR__, "data", "118_bus", "user_descriptors.yaml")
const BUS118_GEN_MAPPING = joinpath(@__DIR__, "data", "118_bus", "generator_mapping.yaml")
function _write_test_yaml(filename, contents = "{}\n")
dir = mktempdir()
path = joinpath(dir, filename)
write(path, contents)
return path
end
const RTS_SRC = joinpath(
LazyArtifacts.artifact"rts",
"RTS-GMLC-0.2.3",
"RTS_Data",
"SourceData",
)
const RTS_DESCRIPTORS = _write_test_yaml("rts_user_descriptors.yaml")
const BUS118_SRC = joinpath(
LazyArtifacts.artifact"CaseData",
"PowerSystemsTestData-4.0.2",
"118-Bus",
)
const BUS118_DESCRIPTORS = _write_test_yaml("118_bus_user_descriptors.yaml")
const BUS118_GEN_MAPPING = _write_test_yaml("118_bus_generator_mapping.yaml")

Copilot uses AI. Check for mistakes.

load_rts_data() = PDP.PowerSystemTableData(RTS_SRC, 100.0, RTS_DESCRIPTORS)

# 118-Bus CSVs ship with PLEXOS-style filenames (Buses.csv / Lines.csv) but the
# parser keys off lowercase stems (bus / branch / gen). Stage them in a tmpdir.
function load_118_bus_data()
tmpdir = mktempdir()
cp(joinpath(BUS118_SRC, "Buses.csv"), joinpath(tmpdir, "bus.csv"))
cp(joinpath(BUS118_SRC, "Lines.csv"), joinpath(tmpdir, "branch.csv"))
cp(joinpath(BUS118_SRC, "gen.csv"), joinpath(tmpdir, "gen.csv"))
return PDP.PowerSystemTableData(
tmpdir,
100.0,
BUS118_DESCRIPTORS;
generator_mapping_file = BUS118_GEN_MAPPING,
)
end
3 changes: 0 additions & 3 deletions test/rts_loading_utils.jl

This file was deleted.

17 changes: 3 additions & 14 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
using Test
using Logging
using DataStructures
using Dates
using LinearAlgebra
using PowerSystems
using PowerSystemCaseBuilder
using PowerTableDataParser
import InfrastructureSystems
import DataFrames
import YAML

const IS = InfrastructureSystems
const PDP = PowerTableDataParser
const PSB = PowerSystemCaseBuilder
const PSY = PowerSystems

import Aqua
Aqua.test_unbound_args(PowerTableDataParser)
Expand All @@ -20,13 +15,7 @@ Aqua.test_ambiguities(PowerTableDataParser)
Aqua.test_stale_deps(PowerTableDataParser)
Aqua.test_deps_compat(PowerTableDataParser)

const DATA_DIR = PSB.DATA_DIR
const BAD_DATA = joinpath(DATA_DIR, "bad_data_for_tests")
const RTS_GMLC_DIR = joinpath(DATA_DIR, "RTS_GMLC")
const DESCRIPTORS = joinpath(RTS_GMLC_DIR, "user_descriptors.yaml")

include("common.jl")
include("rts_loading_utils.jl")
include("loading_utils.jl")

LOG_FILE = "table-parser-test.log"
LOG_LEVELS = Dict(
Expand Down
31 changes: 31 additions & 0 deletions test/test_common.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
@testset "get_generator_mapping" begin
# happy path — package default
mappings = PDP.get_generator_mapping(PDP.GENERATOR_MAPPING_FILE_CDM)
@test mappings isa Dict{NamedTuple, String}
@test !isempty(mappings)

# GenericBattery rename → EnergyReservoirStorage with a warning
tmp = tempname() * ".yaml"
write(
tmp,
"""
GenericBattery:
- {fuel: Battery, type: BA}
""",
)
renamed = @test_logs (:warn,) PDP.get_generator_mapping(tmp)
@test renamed[(fuel = "Battery", unit_type = "BA")] == "EnergyReservoirStorage"

# duplicate (fuel, type) across two generator entries → error
dup = tempname() * ".yaml"
write(
dup,
"""
ThermalStandard:
- {fuel: NG, type: ST}
HydroDispatch:
- {fuel: NG, type: ST}
""",
)
@test_throws ErrorException PDP.get_generator_mapping(dup)
end
120 changes: 120 additions & 0 deletions test/test_constructor_edges.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
@testset "Directory constructor edge cases" begin
# Empty directory
empty_dir = mktempdir()
@test_throws ErrorException PDP.PowerSystemTableData(
empty_dir,
100.0,
BUS118_DESCRIPTORS,
)

# Directory with only non-CSV / non-folder files
no_csv = mktempdir()
write(joinpath(no_csv, "README.md"), "nothing here")
@test_throws ErrorException PDP.PowerSystemTableData(
no_csv,
100.0,
BUS118_DESCRIPTORS,
)

# Bad generator mapping path → rethrown (parser also @errors, expected)
staging = mktempdir()
cp(joinpath(BUS118_SRC, "Buses.csv"), joinpath(staging, "bus.csv"))
cp(joinpath(BUS118_SRC, "Lines.csv"), joinpath(staging, "branch.csv"))
cp(joinpath(BUS118_SRC, "gen.csv"), joinpath(staging, "gen.csv"))
@test_logs (:error,) match_mode = :any begin
@test_throws Exception PDP.PowerSystemTableData(
staging,
100.0,
BUS118_DESCRIPTORS;
generator_mapping_file = joinpath(staging, "does_not_exist.yaml"),
)
end
end

@testset "Dict constructor: missing keys" begin
descriptors = Dict{Symbol, Vector}()
user_descriptors = Dict{Symbol, Vector}()
gen_mapping = Dict{NamedTuple, String}()

# Missing 'bus' key
@test_throws IS.DataFormatError PDP.PowerSystemTableData(
Dict{String, Any}(),
mktempdir(),
user_descriptors,
descriptors,
gen_mapping,
)

# Missing 'base_power' → warns and falls back to DEFAULT_BASE_MVA
bus_df = DataFrames.DataFrame(; bus_id = [1])
data = Dict{String, Any}("bus" => bus_df)
sys_data = @test_logs (:warn,) match_mode = :any PDP.PowerSystemTableData(
data,
mktempdir(),
user_descriptors,
descriptors,
gen_mapping,
)
@test sys_data.base_power == PDP.DEFAULT_BASE_MVA
@test haskey(sys_data.category_to_df, :BUS)
end

@testset "Timeseries metadata fallback" begin
descriptors = Dict{Symbol, Vector}()
user_descriptors = Dict{Symbol, Vector}()
gen_mapping = Dict{NamedTuple, String}()
bus_df = DataFrames.DataFrame(; bus_id = [1])
data() = Dict{String, Any}("bus" => bus_df, "base_power" => 100.0)

# .json present
d_json = mktempdir()
write(joinpath(d_json, "timeseries_pointers.json"), "{}")
sd_json = PDP.PowerSystemTableData(
data(),
d_json,
user_descriptors,
descriptors,
gen_mapping,
)
@test endswith(sd_json.timeseries_metadata_file, ".json")

# .csv present (no .json)
d_csv = mktempdir()
write(joinpath(d_csv, "timeseries_pointers.csv"), "")
sd_csv = PDP.PowerSystemTableData(
data(),
d_csv,
user_descriptors,
descriptors,
gen_mapping,
)
@test endswith(sd_csv.timeseries_metadata_file, ".csv")

# Neither present
d_none = mktempdir()
sd_none = PDP.PowerSystemTableData(
data(),
d_none,
user_descriptors,
descriptors,
gen_mapping,
)
@test sd_none.timeseries_metadata_file === nothing
end

@testset "_read_config_file: reserves rename + Symbol uppercasing" begin
tmp = tempname() * ".yaml"
write(
tmp,
"""
bus:
- {custom_name: Number, name: bus_id}
reserves:
- {custom_name: R, name: name}
""",
)
cfg = PDP._read_config_file(tmp)
@test haskey(cfg, :BUS)
@test haskey(cfg, :RESERVE)
@test !haskey(cfg, :RESERVES)
end
12 changes: 12 additions & 0 deletions test/test_enums.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@testset "get_enum_value" begin
@test PDP.get_enum_value(PDP.InputCategory, "bus") == PDP.InputCategory.BUS
# case-insensitive
@test PDP.get_enum_value(PDP.InputCategory, "BUS") == PDP.InputCategory.BUS
@test PDP.get_enum_value(PDP.InputCategory, "Branch") == PDP.InputCategory.BRANCH

# invalid enum type — anything not in PDP.ENUM_MAPPINGS
@test_throws ArgumentError PDP.get_enum_value(Int, "bus")

# invalid value within a known enum
@test_throws ArgumentError PDP.get_enum_value(PDP.InputCategory, "not_a_category")
end
Loading
Loading