Some checks failed
Build and Push / Build and Push Docker Image (push) Failing after 4m38s
- F-level (228): replace length/1 with Enum.count_until/2 or pattern matching; convert Enum.flat_map+if to Enum.filter+Enum.map; fix identity case in narr_client - W-level (46): normalize dual atom/string key access in weather_layers, beacon_measurements, surface, skewt_live, contact_live/show; add :data_provider and weather-map assigns to ignored_assigns in credo config (consumed by child components credo can't trace); remove weak is_list assertion; remove explicit assert_receive timeout - R-level (6): replace 'This module provides...' moduledocs with meaningful descriptions - Also fix 4 compile-connected xref issues by deferring BandConfig.band_options() from module attribute to runtime Co-Authored-By: Claude <noreply@anthropic.com>
111 lines
3.6 KiB
Elixir
111 lines
3.6 KiB
Elixir
defmodule Microwaveprop.Weather.HrrrNativeProfileTest do
|
||
use Microwaveprop.DataCase, async: true
|
||
|
||
alias Microwaveprop.Weather.HrrrNativeProfile
|
||
|
||
@valid_attrs %{
|
||
valid_time: ~U[2026-03-28 18:00:00Z],
|
||
run_time: ~U[2026-03-28 18:00:00Z],
|
||
lat: 32.9,
|
||
lon: -97.0,
|
||
level_count: 3,
|
||
heights_m: [10.0, 100.0, 500.0],
|
||
temp_k: [295.0, 292.0, 285.0],
|
||
spfh: [0.010, 0.008, 0.004],
|
||
pressure_pa: [101_000.0, 99_800.0, 95_000.0],
|
||
u_wind_ms: [2.0, 3.0, 4.0],
|
||
v_wind_ms: [1.0, 1.5, 2.0],
|
||
tke_m2s2: [0.5, 0.3, 0.1],
|
||
surface_temp_k: 295.0,
|
||
surface_spfh: 0.010,
|
||
surface_pressure_pa: 101_325.0
|
||
}
|
||
|
||
describe "changeset/2" do
|
||
test "accepts a full native profile" do
|
||
changeset = HrrrNativeProfile.changeset(%HrrrNativeProfile{}, @valid_attrs)
|
||
assert changeset.valid?
|
||
|
||
assert {:ok, profile} = Repo.insert(changeset)
|
||
assert profile.level_count == 3
|
||
assert profile.heights_m == [10.0, 100.0, 500.0]
|
||
end
|
||
|
||
test "requires valid_time, lat, lon" do
|
||
changeset = HrrrNativeProfile.changeset(%HrrrNativeProfile{}, %{})
|
||
refute changeset.valid?
|
||
assert "can't be blank" in errors_on(changeset).valid_time
|
||
assert "can't be blank" in errors_on(changeset).lat
|
||
assert "can't be blank" in errors_on(changeset).lon
|
||
end
|
||
|
||
test "rejects mismatched level array lengths" do
|
||
attrs = Map.put(@valid_attrs, :temp_k, [295.0, 292.0])
|
||
changeset = HrrrNativeProfile.changeset(%HrrrNativeProfile{}, attrs)
|
||
refute changeset.valid?
|
||
assert errors_on(changeset)[:temp_k]
|
||
end
|
||
|
||
test "enforces (lat, lon, valid_time) uniqueness" do
|
||
{:ok, _} = %HrrrNativeProfile{} |> HrrrNativeProfile.changeset(@valid_attrs) |> Repo.insert()
|
||
|
||
{:error, changeset} =
|
||
%HrrrNativeProfile{} |> HrrrNativeProfile.changeset(@valid_attrs) |> Repo.insert()
|
||
|
||
refute changeset.valid?
|
||
assert "has already been taken" in errors_on(changeset).lat
|
||
end
|
||
end
|
||
|
||
describe "to_skew_t_profile/1" do
|
||
test "converts native parallel arrays into skew-T map list sorted surface-first" do
|
||
profile = struct(HrrrNativeProfile, @valid_attrs)
|
||
|
||
levels = HrrrNativeProfile.to_skew_t_profile(profile)
|
||
|
||
assert Enum.count_until(levels, 4) == 3
|
||
|
||
# Ordered surface-first (descending pressure).
|
||
pressures = Enum.map(levels, & &1["pres"])
|
||
assert pressures == Enum.sort(pressures, :desc)
|
||
|
||
[surface | _] = levels
|
||
|
||
# pressure Pa → hPa
|
||
assert_in_delta surface["pres"], 1010.0, 0.01
|
||
# temperature K → °C
|
||
assert_in_delta surface["tmpc"], 295.0 - 273.15, 0.01
|
||
# geopotential height passes through
|
||
assert surface["hght"] == 10.0
|
||
|
||
# Dewpoint derived from SPFH + pressure + temperature via Magnus.
|
||
# e = q*p/(0.622 + 0.378*q)/100 = 0.010*101000/0.62578/100 ≈ 16.140 hPa
|
||
# td = 243.5*ln(e/6.112)/(17.67 − ln(e/6.112)) ≈ 14.16 °C
|
||
assert_in_delta surface["dwpc"], 14.16, 0.1
|
||
end
|
||
|
||
test "returns empty list when arrays are nil or empty" do
|
||
blank = %HrrrNativeProfile{
|
||
heights_m: nil,
|
||
temp_k: nil,
|
||
spfh: nil,
|
||
pressure_pa: nil
|
||
}
|
||
|
||
assert HrrrNativeProfile.to_skew_t_profile(blank) == []
|
||
end
|
||
|
||
test "drops levels with missing pressure or temperature" do
|
||
attrs =
|
||
@valid_attrs
|
||
|> Map.put(:temp_k, [295.0, nil, 285.0])
|
||
|> Map.put(:pressure_pa, [101_000.0, 99_800.0, nil])
|
||
|
||
profile = struct(HrrrNativeProfile, attrs)
|
||
|
||
levels = HrrrNativeProfile.to_skew_t_profile(profile)
|
||
assert Enum.count_until(levels, 2) == 1
|
||
assert hd(levels)["hght"] == 10.0
|
||
end
|
||
end
|
||
end
|