prop/test/microwaveprop/weather/hrrr_native_profile_test.exs
Graham McIntire 079346a1b9
Some checks failed
Build and Push / Build and Push Docker Image (push) Failing after 4m38s
fix: resolve all 281 credo issues across source and test files
- 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>
2026-07-29 09:04:21 -05:00

111 lines
3.6 KiB
Elixir
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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