Skip to content

Commit e1b6449

Browse files
abelsiqueiraclaude
andcommitted
Add timeframe profile tests and prefer Julia MCP for testing
- Add attach_timeframe_profile! to API consistency tests (TulipaData and TulipaAsset) - Fix missing set_partition! import in TulipaAsset API test - Add Stage 4 to export test verifying timeframe profile CSV output - Add test for timeframe profiles across multiple milestone years - Mark Julia MCP as preferred test runner in CLAUDE.md Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Claude Code (claude-sonnet-4-6) <noreply@anthropic.com>
1 parent 9654764 commit e1b6449

4 files changed

Lines changed: 71 additions & 3 deletions

File tree

CLAUDE.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,9 +296,11 @@ end
296296

297297
**When testing new tests, use filtering to run only the relevant files.**
298298

299-
#### Running Tests via [Julia MCP](https://github.com/aplavin/julia-mcp)
299+
#### Running Tests via [Julia MCP](https://github.com/aplavin/julia-mcp) (Preferred)
300300

301-
When using the Julia MCP (`julia_eval`), point `env_path` at `test/` — it has its own `Project.toml` with the package registered as a path source, so no extra setup or `TestEnv` is needed. Use `@run_package_tests` directly (the CLI runner's `runtests.jl` relies on `ARGS` and won't work in a REPL):
301+
**When the Julia MCP (`julia_eval`) is available, always prefer it over the CLI runner for testing.** It keeps a warm Julia session, avoiding recompilation overhead on each run.
302+
303+
Point `env_path` at `test/` — it has its own `Project.toml` with the package registered as a path source, so no extra setup or `TestEnv` is needed. Use `@run_package_tests` directly (the CLI runner's `runtests.jl` relies on `ARGS` and won't work in a REPL):
302304

303305
```julia
304306
# Run all tests

test/test-api-consistency.jl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@
1515
@test attach_milestone_data!(tulipa, "producer1", 2030) === tulipa
1616
@test attach_both_years_data!(tulipa, "producer1", 2030, 2030) === tulipa
1717
@test attach_profile!(tulipa, "producer1", :availability, 2030, rand(24)) === tulipa
18+
@test attach_timeframe_profile!(
19+
tulipa,
20+
"producer1",
21+
:max_storage_level,
22+
2030,
23+
rand(10),
24+
) === tulipa
1825

1926
# attach_* functions (flow variants)
2027
@test attach_commission_data!(tulipa, "producer1", "consumer1", 2030) === tulipa
@@ -34,14 +41,17 @@ end
3441
attach_commission_data!,
3542
attach_milestone_data!,
3643
attach_both_years_data!,
37-
attach_profile!
44+
attach_profile!,
45+
attach_timeframe_profile!,
46+
set_partition!
3847

3948
asset = TulipaAsset("test", :producer)
4049

4150
@test attach_commission_data!(asset, 2030, capacity = 1.0) === asset
4251
@test attach_milestone_data!(asset, 2030, investable = true) === asset
4352
@test attach_both_years_data!(asset, 2030, 2030, initial_units = 1) === asset
4453
@test attach_profile!(asset, :availability, 2030, rand(24)) === asset
54+
@test attach_timeframe_profile!(asset, :max_storage_level, 2030, rand(10)) === asset
4555
@test set_partition!(asset, 2030, 3, 4) === asset
4656
@test set_partition!(asset, 2030, 4, :explicit, "12;12") === asset
4757
end

test/test-output.jl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,4 +195,23 @@ end
195195

196196
data = create_and_get_data(tulipa, TEM.schema)
197197
test_that_tables_are_equivalent(data, manual_data)
198+
199+
## Stage 4 - attach timeframe profile
200+
201+
tf_profile = collect(0.1:0.1:1.0)
202+
attach_timeframe_profile!(tulipa, "ccgt", :max_storage_level, 2030, tf_profile)
203+
204+
push!(
205+
manual_data[:assets_timeframe_profiles],
206+
("ccgt", 2030, 1, "max_storage_level", "ccgt-max_storage_level-2030-1"),
207+
)
208+
for (i, x) in enumerate(tf_profile)
209+
push!(
210+
manual_data[:profiles_timeframe],
211+
("ccgt-max_storage_level-2030-1", 2030, i, x),
212+
)
213+
end
214+
215+
data = create_and_get_data(tulipa, TEM.schema)
216+
test_that_tables_are_equivalent(data, manual_data)
198217
end

test/test-timeframe-profiles.jl

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,40 @@ end
104104
@test all(scenario1_rows.value .≈ 0.9)
105105
@test all(scenario2_rows.value .≈ 0.8)
106106
end
107+
108+
@testitem "Timeframe profiles across multiple milestone years" tags =
109+
[:unit, :fast, :schema] setup = [CommonSetup, CreateConnectionSetup, TestSchema] begin
110+
using DuckDB: DuckDB
111+
using DataFrames: DataFrame
112+
113+
tulipa = TulipaData()
114+
add_asset!(tulipa, "storage", :storage)
115+
attach_profile!(tulipa, "storage", :availability, 2030, ones(24))
116+
attach_profile!(tulipa, "storage", :availability, 2040, ones(48))
117+
attach_timeframe_profile!(tulipa, "storage", :max_storage_level, 2030, 0.9 .* ones(5))
118+
attach_timeframe_profile!(tulipa, "storage", :max_storage_level, 2040, 0.7 .* ones(8))
119+
120+
connection = create_connection(tulipa, TestSchema.schema)
121+
122+
atp_df =
123+
DuckDB.query(
124+
connection,
125+
"SELECT * FROM assets_timeframe_profiles ORDER BY milestone_year",
126+
) |> DataFrame
127+
@test size(atp_df, 1) == 2
128+
@test atp_df.milestone_year == [2030, 2040]
129+
@test all(atp_df.asset .== "storage")
130+
131+
tf_df =
132+
DuckDB.query(
133+
connection,
134+
"SELECT * FROM profiles_timeframe ORDER BY milestone_year, period",
135+
) |> DataFrame
136+
@test size(tf_df, 1) == 13 # 5 periods (2030) + 8 periods (2040)
137+
rows_2030 = filter(r -> r.milestone_year == 2030, tf_df)
138+
rows_2040 = filter(r -> r.milestone_year == 2040, tf_df)
139+
@test size(rows_2030, 1) == 5
140+
@test size(rows_2040, 1) == 8
141+
@test all(rows_2030.value .≈ 0.9)
142+
@test all(rows_2040.value .≈ 0.7)
143+
end

0 commit comments

Comments
 (0)