From 71bfbad7acce4141aa95867b84425fc853d2de23 Mon Sep 17 00:00:00 2001 From: owjs3901 Date: Fri, 23 Oct 2026 23:54:23 +0900 Subject: [PATCH] test(extractor): preserve absence proof without supplied scoping Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- libs/extractor/src/style_values/absence.rs | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/libs/extractor/src/style_values/absence.rs b/libs/extractor/src/style_values/absence.rs index 10cef0a84..aa6b0b2d1 100644 --- a/libs/extractor/src/style_values/absence.rs +++ b/libs/extractor/src/style_values/absence.rs @@ -82,6 +82,33 @@ mod tests { use oxc_span::SourceType; use rstest::rstest; + #[rstest] + #[case("undefined;", true)] + #[case("let undefined = runtime; undefined;", false)] + fn absence_survives_cleared_ids_when_scoping_is_not_supplied( + #[case] source: &str, + #[case] absent: bool, + ) { + // Given authored references without a caller-supplied semantic analysis. + let arena = Allocator::default(); + let parsed = Parser::new(&arena, source, SourceType::tsx()).parse(); + let mut values = StyleValues::default(); + values.record_absence(&parsed.program); + let Statement::ExpressionStatement(statement) = + &parsed.program.body[parsed.program.body.len() - 1] + else { + panic!("expected expression"); + }; + let Expression::Identifier(identifier) = &statement.expression else { + panic!("expected identifier"); + }; + identifier.reference_id.set(None); + // When extraction consults the authored-span proof after IDs are cleared. + let result = values.is_unbound_undefined(&statement.expression); + // Then only the unbound global is absent, never a shadowing binding. + assert_eq!(result, absent); + } + #[rstest] #[case("undefined;", true)] #[case("let undefined = runtime; undefined;", false)]