use crate::location::Location;
use crate::error::AstroError;
#[test]
fn test_decimal_degrees_basic() {
let loc = Location::parse("40.7128", "-74.0060", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 1e-6);
assert!((loc.longitude_deg + 74.0060).abs() < 1e-6);
let loc = Location::parse("+40.7128", "-74.0060", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 1e-6);
}
#[test]
fn test_decimal_degrees_with_compass() {
let loc = Location::parse("40.7128N", "74.0060W", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 1e-6);
assert!((loc.longitude_deg + 74.0060).abs() < 1e-6);
let loc = Location::parse("N40.7128", "W74.0060", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 1e-6);
assert!((loc.longitude_deg + 74.0060).abs() < 1e-6);
let loc = Location::parse("40.7128 N", "74.0060 W", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 1e-6);
let loc = Location::parse("40.7128 North", "74.0060 West", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 1e-6);
let loc = Location::parse("40.7128 north", "74.0060 WEST", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 1e-6);
}
#[test]
fn test_dms_basic() {
let loc = Location::parse("40 42 46", "-74 0 21.6", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 1e-4);
assert!((loc.longitude_deg + 74.006).abs() < 1e-4);
let loc = Location::parse("40:42:46", "-74:0:21.6", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 1e-4);
let loc = Location::parse("40-42-46", "-74-0-21.6", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 1e-4);
}
#[test]
fn test_dms_with_symbols() {
let loc = Location::parse("40°42'46\"", "-74°0'21.6\"", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 1e-3);
let loc = Location::parse("40°42′46″", "-74°0′21.6″", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 1e-3);
let loc = Location::parse("40d42m46s", "-74d0m21.6s", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 1e-3);
let loc = Location::parse("40 degrees 42 minutes 46 seconds", "-74 deg 0 min 21.6 sec", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 1e-3);
let loc = Location::parse("40°42'46\"N", "74°0'21.6\"W", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 1e-3);
assert!((loc.longitude_deg + 74.006).abs() < 1e-3);
}
#[test]
fn test_hms_for_longitude() {
let loc = Location::parse("51.5074 N", "0h 7m 39.84s W", 0.0).unwrap();
assert!((loc.latitude_deg - 51.5074).abs() < 1e-6);
assert!((loc.longitude_deg + 1.9166).abs() < 1e-3);
let loc = Location::parse("51.5074", "0h7m39.84s", 0.0).unwrap();
assert!((loc.longitude_deg - 7.664).abs() < 1e-3);
let loc = Location::parse("40.7128", "4 hours 56 minutes 27 seconds W", 0.0).unwrap();
assert!((loc.longitude_deg + 74.1125).abs() < 1e-3);
let loc = Location::parse("0.0", "12h:30m:00s", 0.0).unwrap();
assert!((loc.longitude_deg - 180.0).abs() < 1e-6);
}
#[test]
fn test_degrees_decimal_minutes() {
let loc = Location::parse("40 42.767", "-74 0.36", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 0.01); assert!((loc.longitude_deg + 74.006).abs() < 1e-3);
let loc = Location::parse("40° 42.767'", "-74° 0.36'", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 0.01);
let loc = Location::parse("40d 42.767m", "-74d 0.36m", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 0.01);
}
#[test]
fn test_compact_formats() {
let loc = Location::parse("404246N", "0740022W", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 1e-3);
assert!((loc.longitude_deg + 74.0061).abs() < 1e-3);
let loc = Location::parse("4042.767N", "07400.360W", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 1e-4);
assert!((loc.longitude_deg + 74.006).abs() < 1e-4);
}
#[test]
fn test_edge_cases() {
let loc = Location::parse("-00 30 00", "000 00 00", 0.0).unwrap();
assert!((loc.latitude_deg + 0.5).abs() < 1e-6);
assert!(loc.longitude_deg.abs() < 1e-6);
let loc = Location::parse("33.8688 S", "151.2093 E", 0.0).unwrap();
assert!((loc.latitude_deg + 33.8688).abs() < 1e-6);
assert!((loc.longitude_deg - 151.2093).abs() < 1e-6);
let loc = Location::parse("40 42 46.08", "-74 0 21.6", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 1e-5);
}
#[test]
fn test_mixed_formats() {
let loc = Location::parse("40d 42' 46\"", "-74:00:21.6", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 1e-4);
let loc = Location::parse(" 40 42 46 ", " -74 0 21.6 ", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 1e-4);
}
#[test]
fn test_parsing_error_cases() {
match Location::parse("40.7128 E", "74.0060 W", 0.0) {
Err(AstroError::InvalidDmsFormat { .. }) => {},
_ => panic!("Expected InvalidDmsFormat error"),
}
match Location::parse("40.7128 N", "74.0060 N", 0.0) {
Err(AstroError::InvalidDmsFormat { .. }) => {},
_ => panic!("Expected InvalidDmsFormat error"),
}
match Location::parse("91.0", "0.0", 0.0) {
Err(AstroError::InvalidCoordinate { .. }) => {},
_ => panic!("Expected InvalidCoordinate error"),
}
match Location::parse("0.0", "181.0", 0.0) {
Err(AstroError::InvalidCoordinate { .. }) => {},
_ => panic!("Expected InvalidCoordinate error"),
}
match Location::parse("not a coordinate", "also bad", 0.0) {
Err(AstroError::InvalidDmsFormat { .. }) => {},
_ => panic!("Expected InvalidDmsFormat error"),
}
}
#[test]
fn test_coverage_boosters() {
match Location::from_dms("40 42 bad", "0 0 0", 0.0) {
Err(AstroError::InvalidDmsFormat { .. }) => {},
_ => panic!("Expected InvalidDmsFormat error"),
}
match Location::parse("0.0", "completely invalid longitude format xyz", 0.0) {
Err(AstroError::InvalidDmsFormat { expected, .. }) => {
assert!(expected.contains("74.0060W") && expected.contains("4h56m27s"));
},
_ => panic!("Expected InvalidDmsFormat error with longitude examples"),
}
let loc = Location::parse("40.7", "74W", 10.0).unwrap();
assert!((loc.longitude_deg + 74.0).abs() < 1e-6);
let loc = Location::parse("40 42.767", "0", 0.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 0.01);
let loc = Location::parse("-30 15.5", "0", 0.0).unwrap();
assert!((loc.latitude_deg + 30.0183).abs() < 0.01);
}
#[test]
fn test_parsing_backwards_compatibility() {
let loc = Location::from_dms("+39 00 01.7", "-92 18 03.2", 250.0).unwrap();
assert!((loc.latitude_deg - 39.0004722).abs() < 1e-6);
assert!((loc.longitude_deg + 92.3008888).abs() < 1e-6);
}
#[test]
fn test_real_world_examples() {
let loc = Location::parse("40°42'46\"N", "74°0'21\"W", 10.0).unwrap();
assert!((loc.latitude_deg - 40.7128).abs() < 1e-3);
let loc = Location::parse("51°30'26\"N", "0°7'39\"W", 11.0).unwrap();
assert!((loc.latitude_deg - 51.5072).abs() < 1e-3);
let loc = Location::parse("33°52'08\"S", "151°12'30\"E", 100.0).unwrap();
assert!((loc.latitude_deg + 33.8689).abs() < 1e-3);
assert!((loc.longitude_deg - 151.2083).abs() < 1e-3);
let loc = Location::parse("35.6762 N", "139.6503 E", 40.0).unwrap();
assert!((loc.latitude_deg - 35.6762).abs() < 1e-6);
let loc = Location::parse("51°28'38\"N", "0°0'0\"", 46.0).unwrap();
assert!((loc.latitude_deg - 51.4772).abs() < 1e-3);
assert!(loc.longitude_deg.abs() < 1e-6);
}