test_that("natural language claims are classified without requiring a reference row", { p <- classify_stat_claim("Iran's unemployment rate was 8.1 percent in 2025.") expect_s3_class(p, "stat_claim_profile") expect_equal(p$domain, "labour") expect_equal(p$indicator, "unemployment rate") expect_equal(p$geo_code, "IRN") expect_equal(p$time, "2025") expect_equal(p$value, 8.1) expect_equal(p$unit, "percent") }) test_that("Persian digits, geography, indicator and units are classified", { p <- classify_stat_claim("نرخ بیکاری ایران در سال ۲۰۲۵ برابر با ۸٫۱ درصد بود.") expect_equal(p$domain, "labour") expect_equal(p$indicator, "unemployment rate") expect_equal(p$geo_code, "IRN") expect_equal(p$time, "2025") expect_equal(p$value, 8.1) expect_equal(p$unit, "percent") }) test_that("latest intent is retained instead of inventing a year", { p <- classify_stat_claim("According to WHO, Iran's latest life expectancy is 77.3 years.") expect_equal(p$domain, "health") expect_equal(p$indicator, "life expectancy at birth") expect_equal(p$geo_code, "IRN") expect_equal(p$time_mode, "latest") expect_true(is.na(p$time)) expect_equal(p$source_id, "who") expect_equal(p$unit, "years") }) test_that("omitted year defaults to the latest available time and records that the choice was inferred", { p <- classify_stat_claim("Iran's population was 91 million.") expect_equal(p$indicator, "total population") expect_equal(p$geo_code, "IRN") expect_equal(p$time_mode, "latest") expect_true(is.na(p$time)) expect_true(isTRUE(p$time_inferred)) }) test_that("verification with no year selects the latest matching official observation", { official <- data.frame( value = c(90000000, 91000000), indicator = c("total population", "total population"), country = c("Iran", "Iran"), year = c(2023, 2025), unit = c("persons", "persons"), source = c("Example NSO", "Example NSO"), stringsAsFactors = FALSE ) x <- verify_claim("Iran's population was 91 million.", evidence = official) expect_equal(x$status, "SUPPORTED") expect_equal(x$reference$time, "2025") expect_true(isTRUE(x$claim$time_inferred)) expect_match(x$message, "No reference year was specified") }) test_that("implicit latest is resolved within the matching indicator context", { official <- data.frame( value = c(91000000, 30000000), indicator = c("total population", "labour force total"), country = c("Iran", "Iran"), year = c(2025, 2026), unit = c("persons", "persons"), source = c("Example NSO", "Example NSO"), stringsAsFactors = FALSE ) x <- verify_claim("Iran's population was 91 million.", evidence = official) expect_equal(x$status, "SUPPORTED") expect_equal(x$reference$indicator, "total population") expect_equal(x$reference$time, "2025") }) test_that("magnitudes are normalized for population-style claims", { p <- classify_stat_claim("Iran's population reached 91 million in 2025.") expect_equal(p$indicator, "total population") expect_equal(p$value, 91000000) expect_equal(p$value_scale, 1e6) expect_equal(p$unit, "persons") }) test_that("offline evidence verification distinguishes supported and mismatch", { official <- data.frame( value = c(7.8, 8.2), indicator = c("unemployment rate", "unemployment rate"), country = c("Iran", "Iran"), year = c(2025, 2024), unit = c("percent", "percent"), source = c("Example NSO", "Example NSO"), stringsAsFactors = FALSE ) a <- verify_claim("Iran's unemployment rate was 7.8 percent in 2025.", evidence = official) b <- verify_claim("Iran's unemployment rate was 8.1 percent in 2025.", evidence = official) expect_s3_class(a, "stat_claim_verification") expect_equal(a$status, "SUPPORTED") expect_equal(a$reference$time, "2025") expect_equal(b$status, "MISMATCH") expect_equal(b$reference$value, 7.8) }) test_that("latest verification selects the most recent matching official row", { official <- data.frame( value = c(76.2, 76.8), indicator = c("life expectancy at birth", "life expectancy at birth"), country = c("Iran", "Iran"), year = c(2023, 2024), unit = c("years", "years"), source = c("Example health authority", "Example health authority"), stringsAsFactors = FALSE ) x <- verify_claim("Iran's latest life expectancy was 76.8 years.", evidence = official) expect_equal(x$status, "SUPPORTED") expect_equal(x$reference$time, "2024") }) test_that("provider suggestions are domain-aware", { p <- classify_stat_claim("Iran's life expectancy was 77 years in 2025.") plan <- suggest_stat_providers(p) expect_equal(plan$id[1], "who") expect_true("worldbank" %in% plan$id) }) test_that("age ranges and rate denominators are not mistaken for claim values", { p <- classify_stat_claim("Youth unemployment among people aged 15-24 was 20.5 percent in Iran in 2025.") expect_equal(p$value, 20.5) expect_equal(p$dimensions$age_group, "15-24") q <- classify_stat_claim("Maternal mortality in Iran was 18 per 100,000 live births in 2023.") expect_equal(q$value, 18) expect_equal(q$unit, "per 100,000") }) test_that("requested sex dimension is preferred over aggregate or other-sex rows", { official <- data.frame( value = c(77.0, 78.4, 75.6), indicator = rep("life expectancy at birth", 3), country = rep("Iran", 3), year = rep(2024, 3), unit = rep("years", 3), source = rep("Example health authority", 3), sex = c("Both sexes", "Female", "Male"), stringsAsFactors = FALSE ) x <- verify_claim("Female life expectancy in Iran was 78.4 years in 2024.", evidence = official) expect_equal(x$status, "SUPPORTED") expect_equal(x$reference$value, 78.4) }) test_that("WHO acronym detection does not confuse ordinary word who", { p <- classify_stat_claim("People who were unemployed in Iran represented 8.1 percent in 2025.") expect_true(is.na(p$source_id)) q <- classify_stat_claim("According to WHO, Iran's life expectancy was 77 years in 2024.") expect_equal(q$source_id, "who") }) test_that("an explicitly named unsupported auto-source is not silently replaced", { x <- verify_claim("According to IMF, Iran's inflation rate was 30 percent in 2025.") expect_equal(x$status, "NOT_FOUND") expect_match(x$message, "IMF") }) test_that("matching number with contradictory known unit is not accepted as evidence", { official <- data.frame( value = 10, indicator = "unemployment rate", country = "Iran", year = 2025, unit = "persons", source = "Example NSO", stringsAsFactors = FALSE ) x <- verify_claim("Iran's unemployment rate was 10 percent in 2025.", evidence = official) expect_true(x$status %in% c("NOT_FOUND", "AMBIGUOUS")) }) test_that("automatic provider routing does not require a named source", { p <- classify_stat_claim("Life expectancy in Iran was 77 years in 2023.") route <- .sf_resolve_provider_request(p, "auto", require_named_source = TRUE) expect_equal(route$mode, "auto") expect_true("who" %in% route$ids) expect_true("worldbank" %in% route$ids) }) test_that("a named supported source is respected by automatic routing", { p <- classify_stat_claim("According to WHO, life expectancy in Iran was 77 years in 2023.") route <- .sf_resolve_provider_request(p, "auto", require_named_source = TRUE) expect_equal(route$mode, "named") expect_equal(route$ids, "who") }) test_that("all routing exposes every full automatic-verification provider", { p <- classify_stat_claim("Life expectancy in Iran was 77 years in 2023.") route <- .sf_resolve_provider_request(p, "all", require_named_source = TRUE) expect_equal(route$mode, "all") expect_true(all(c("worldbank", "who", "unsd_sdg", "eurostat") %in% route$ids)) }) test_that("explicit routing cannot silently contradict a named source", { x <- verify_claim( "According to WHO, life expectancy in Iran was 77 years in 2023.", providers = "worldbank" ) expect_equal(x$status, "NOT_FOUND") expect_equal(x$provider_mode, "explicit") expect_match(x$message, "exclude that source") }) test_that("offline evidence records its source-selection mode", { official <- data.frame( value = 77, indicator = "life expectancy at birth", country = "Iran", year = 2023, unit = "years", source = "Example health authority", stringsAsFactors = FALSE ) x <- verify_claim("Life expectancy in Iran was 77 years in 2023.", evidence = official) expect_equal(x$status, "SUPPORTED") expect_equal(x$provider_mode, "evidence") expect_equal(x$reference$source, "Example health authority") })