diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3e1225d04b..7c91cfff57 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3075,6 +3075,7 @@ jobs: test_issue_610_smoke \ test_issue_640_navstack_textfield \ test_issue_763_reactive_textfield \ + test_issue_10155_textfield_singleline \ test_issue_764_state_at_module_init \ test_ramda_user_import \ test_take_screenshot \ diff --git a/CLAUDE.md b/CLAUDE.md index 4d44e9ee2e..5b730029d1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,7 +8,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co Perry is a native TypeScript compiler written in Rust that compiles TypeScript source code directly to native executables. It uses SWC for TypeScript parsing and LLVM for code generation. -**Current Version:** 0.5.1545 +**Current Version:** 0.5.1546 ## TypeScript Parity Status diff --git a/Cargo.lock b/Cargo.lock index e8eb29d7cf..554bbe3def 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5690,7 +5690,7 @@ checksum = "4b2094dda4d997bf73a372cb660d02e9abdb0a13cbf834ddd2b2f8847bffe2cf" [[package]] name = "perry" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "anyhow", "base64 0.22.1", @@ -5754,7 +5754,7 @@ dependencies = [ [[package]] name = "perry-api-manifest" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "perry-dispatch", "serde", @@ -5762,7 +5762,7 @@ dependencies = [ [[package]] name = "perry-audio-miniaudio" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "cc", "libc", @@ -5771,7 +5771,7 @@ dependencies = [ [[package]] name = "perry-codegen" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "aho-corasick", "anyhow", @@ -5789,7 +5789,7 @@ dependencies = [ [[package]] name = "perry-codegen-arkts" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "anyhow", "perry-hir", @@ -5797,7 +5797,7 @@ dependencies = [ [[package]] name = "perry-codegen-glance" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "anyhow", "perry-hir", @@ -5805,7 +5805,7 @@ dependencies = [ [[package]] name = "perry-codegen-js" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "anyhow", "perry-dispatch", @@ -5814,7 +5814,7 @@ dependencies = [ [[package]] name = "perry-codegen-swiftui" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "anyhow", "perry-hir", @@ -5822,7 +5822,7 @@ dependencies = [ [[package]] name = "perry-codegen-wasm" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "anyhow", "base64 0.22.1", @@ -5834,7 +5834,7 @@ dependencies = [ [[package]] name = "perry-codegen-wear-tiles" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "anyhow", "perry-hir", @@ -5842,7 +5842,7 @@ dependencies = [ [[package]] name = "perry-container-compose" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "anyhow", "async-trait", @@ -5870,14 +5870,14 @@ dependencies = [ [[package]] name = "perry-container-e2e" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "anyhow", ] [[package]] name = "perry-diagnostics" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "serde", "serde_json", @@ -5885,7 +5885,7 @@ dependencies = [ [[package]] name = "perry-dispatch" -version = "0.5.1545" +version = "0.5.1546" [[package]] name = "perry-doc-fixture-my-bindings" @@ -5896,7 +5896,7 @@ dependencies = [ [[package]] name = "perry-doc-tests" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "anyhow", "clap", @@ -5911,7 +5911,7 @@ dependencies = [ [[package]] name = "perry-ext-ads" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "block2", "objc2", @@ -5921,7 +5921,7 @@ dependencies = [ [[package]] name = "perry-ext-argon2" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "argon2", "perry-ffi", @@ -5930,7 +5930,7 @@ dependencies = [ [[package]] name = "perry-ext-axios" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "perry-ffi", "reqwest", @@ -5939,7 +5939,7 @@ dependencies = [ [[package]] name = "perry-ext-bcrypt" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "bcrypt", "perry-ffi", @@ -5947,7 +5947,7 @@ dependencies = [ [[package]] name = "perry-ext-better-sqlite3" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "perry-ffi", "rusqlite", @@ -5955,7 +5955,7 @@ dependencies = [ [[package]] name = "perry-ext-cheerio" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "perry-ffi", "scraper", @@ -5963,7 +5963,7 @@ dependencies = [ [[package]] name = "perry-ext-commander" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "perry-ffi", "perry-runtime", @@ -5971,7 +5971,7 @@ dependencies = [ [[package]] name = "perry-ext-cron" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "chrono", "cron", @@ -5981,7 +5981,7 @@ dependencies = [ [[package]] name = "perry-ext-dayjs" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "chrono", "perry-ffi", @@ -5989,7 +5989,7 @@ dependencies = [ [[package]] name = "perry-ext-decimal" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "perry-ffi", "rust_decimal", @@ -5997,7 +5997,7 @@ dependencies = [ [[package]] name = "perry-ext-dotenv" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "perry-ffi", "serde_json", @@ -6005,7 +6005,7 @@ dependencies = [ [[package]] name = "perry-ext-ethers" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "perry-ffi", "rand 0.10.2", @@ -6013,7 +6013,7 @@ dependencies = [ [[package]] name = "perry-ext-events" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "perry-ffi", "perry-runtime", @@ -6021,14 +6021,14 @@ dependencies = [ [[package]] name = "perry-ext-exponential-backoff" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "perry-ffi", ] [[package]] name = "perry-ext-fastify" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "bytes", "http-body-util", @@ -6046,7 +6046,7 @@ dependencies = [ [[package]] name = "perry-ext-fetch" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "bytes", "lazy_static", @@ -6059,7 +6059,7 @@ dependencies = [ [[package]] name = "perry-ext-http" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "base64 0.22.1", "bytes", @@ -6091,7 +6091,7 @@ dependencies = [ [[package]] name = "perry-ext-ioredis" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "lazy_static", "perry-ffi", @@ -6101,7 +6101,7 @@ dependencies = [ [[package]] name = "perry-ext-jsonwebtoken" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "base64 0.22.1", "jsonwebtoken", @@ -6112,7 +6112,7 @@ dependencies = [ [[package]] name = "perry-ext-lru-cache" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "lru", "perry-ffi", @@ -6121,7 +6121,7 @@ dependencies = [ [[package]] name = "perry-ext-moment" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "chrono", "perry-ffi", @@ -6129,7 +6129,7 @@ dependencies = [ [[package]] name = "perry-ext-mongodb" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "bson", "futures-util", @@ -6141,7 +6141,7 @@ dependencies = [ [[package]] name = "perry-ext-mysql2" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "chrono", "perry-ffi", @@ -6153,7 +6153,7 @@ dependencies = [ [[package]] name = "perry-ext-nanoid" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "nanoid", "perry-ffi", @@ -6162,7 +6162,7 @@ dependencies = [ [[package]] name = "perry-ext-net" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "bytes", "perry-ffi", @@ -6177,7 +6177,7 @@ dependencies = [ [[package]] name = "perry-ext-node-forge" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "const-oid 0.10.2", "der 0.8.1", @@ -6196,7 +6196,7 @@ dependencies = [ [[package]] name = "perry-ext-nodemailer" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "lettre", "perry-ffi", @@ -6206,7 +6206,7 @@ dependencies = [ [[package]] name = "perry-ext-parcel-watcher" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "notify", "perry-ffi", @@ -6218,7 +6218,7 @@ dependencies = [ [[package]] name = "perry-ext-pdf" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "perry-ffi", "printpdf", @@ -6226,7 +6226,7 @@ dependencies = [ [[package]] name = "perry-ext-pg" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "perry-ffi", "sqlx", @@ -6235,7 +6235,7 @@ dependencies = [ [[package]] name = "perry-ext-qs" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "perry-ffi", "perry-runtime", @@ -6244,7 +6244,7 @@ dependencies = [ [[package]] name = "perry-ext-ratelimit" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "governor", "perry-ffi", @@ -6252,7 +6252,7 @@ dependencies = [ [[package]] name = "perry-ext-sharp" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "fast_image_resize", "image", @@ -6263,7 +6263,7 @@ dependencies = [ [[package]] name = "perry-ext-streams" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "lazy_static", "perry-ffi", @@ -6272,7 +6272,7 @@ dependencies = [ [[package]] name = "perry-ext-typescript" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "anyhow", "perry-ffi", @@ -6292,7 +6292,7 @@ dependencies = [ [[package]] name = "perry-ext-undici" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "perry-ffi", "perry-runtime", @@ -6301,7 +6301,7 @@ dependencies = [ [[package]] name = "perry-ext-uuid" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "perry-ffi", "uuid", @@ -6309,7 +6309,7 @@ dependencies = [ [[package]] name = "perry-ext-validator" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "perry-ffi", "perry-validation", @@ -6318,7 +6318,7 @@ dependencies = [ [[package]] name = "perry-ext-ws" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "futures-util", "lazy_static", @@ -6331,7 +6331,7 @@ dependencies = [ [[package]] name = "perry-ext-zlib" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "brotli", "flate2", @@ -6341,7 +6341,7 @@ dependencies = [ [[package]] name = "perry-ffi" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "dashmap 6.2.1", "once_cell", @@ -6351,7 +6351,7 @@ dependencies = [ [[package]] name = "perry-hir" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "anyhow", "perry-api-manifest", @@ -6372,11 +6372,11 @@ dependencies = [ [[package]] name = "perry-native-registration" -version = "0.5.1545" +version = "0.5.1546" [[package]] name = "perry-parser" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "anyhow", "perry-diagnostics", @@ -6390,7 +6390,7 @@ dependencies = [ [[package]] name = "perry-perex" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "perex", "regex", @@ -6398,7 +6398,7 @@ dependencies = [ [[package]] name = "perry-runtime" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "ahash", "anyhow", @@ -6458,14 +6458,14 @@ dependencies = [ [[package]] name = "perry-runtime-static" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "perry-runtime", ] [[package]] name = "perry-stdlib" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "aes 0.8.4", "aes 0.9.1", @@ -6560,14 +6560,14 @@ dependencies = [ [[package]] name = "perry-stdlib-static" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "perry-stdlib", ] [[package]] name = "perry-transform" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "anyhow", "perry-hir", @@ -6576,7 +6576,7 @@ dependencies = [ [[package]] name = "perry-ui" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "perry-ffi", "perry-ui-model", @@ -6584,7 +6584,7 @@ dependencies = [ [[package]] name = "perry-ui-android" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "base64 0.22.1", "itoa", @@ -6602,7 +6602,7 @@ dependencies = [ [[package]] name = "perry-ui-geisterhand" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "rand 0.10.2", "serde", @@ -6612,7 +6612,7 @@ dependencies = [ [[package]] name = "perry-ui-gtk4" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "base64 0.22.1", "cairo-rs 0.22.9", @@ -6635,7 +6635,7 @@ dependencies = [ [[package]] name = "perry-ui-ios" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "base64 0.22.1", "block2", @@ -6652,7 +6652,7 @@ dependencies = [ [[package]] name = "perry-ui-macos" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "base64 0.22.1", "block2", @@ -6669,7 +6669,7 @@ dependencies = [ [[package]] name = "perry-ui-model" -version = "0.5.1545" +version = "0.5.1546" [[package]] name = "perry-ui-test" @@ -6680,11 +6680,11 @@ dependencies = [ [[package]] name = "perry-ui-testkit" -version = "0.5.1545" +version = "0.5.1546" [[package]] name = "perry-ui-tvos" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "base64 0.22.1", "block2", @@ -6701,7 +6701,7 @@ dependencies = [ [[package]] name = "perry-ui-visionos" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "base64 0.22.1", "block2", @@ -6718,7 +6718,7 @@ dependencies = [ [[package]] name = "perry-ui-watchos" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "block2", "libc", @@ -6732,7 +6732,7 @@ dependencies = [ [[package]] name = "perry-ui-windows" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "base64 0.22.1", "libc", @@ -6751,7 +6751,7 @@ dependencies = [ [[package]] name = "perry-ui-windows-winui" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "base64 0.22.1", "libc", @@ -6764,7 +6764,7 @@ dependencies = [ [[package]] name = "perry-updater" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "anyhow", "base64 0.22.1", @@ -6780,7 +6780,7 @@ dependencies = [ [[package]] name = "perry-validation" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "idna", "regex", @@ -6790,7 +6790,7 @@ dependencies = [ [[package]] name = "perry-wasm-host" -version = "0.5.1545" +version = "0.5.1546" dependencies = [ "wasmi", ] diff --git a/Cargo.toml b/Cargo.toml index 1a68dbf1f0..c12fd3abd3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -338,7 +338,7 @@ codegen-units = 1 codegen-units = 1 [workspace.package] -version = "0.5.1545" +version = "0.5.1546" edition = "2021" license = "MIT" repository = "https://github.com/PerryTS/perry" diff --git a/changelog.d/10157-macos-textfield-single-line.md b/changelog.d/10157-macos-textfield-single-line.md new file mode 100644 index 0000000000..901fa8c2b0 --- /dev/null +++ b/changelog.d/10157-macos-textfield-single-line.md @@ -0,0 +1,8 @@ +Fixed macOS `TextField` wrapping to multiple lines when its text was wider than +the field. `perry-ui-macos`'s `create()` built the field from +`NSTextField::textFieldWithString`, whose cell wraps and grows, and never +overrode it — so a fixed-width field grew tall instead of scrolling, unlike +every other backend. The cell is now configured for single-line editing +(`usesSingleLineMode`, `scrollable`, `wraps = false`, clipping line-break mode), +matching iOS / GTK4 / Android / Windows. Multiline input keeps its own widget, +`TextArea`. diff --git a/changelog.d/10160-self-namespace-dynamic-import.md b/changelog.d/10160-self-namespace-dynamic-import.md new file mode 100644 index 0000000000..209c2e5708 --- /dev/null +++ b/changelog.d/10160-self-namespace-dynamic-import.md @@ -0,0 +1,3 @@ +### Fixed + +- `export * as Self from "./self"` now reads as the module's own namespace object through a dynamic `import()` namespace (and its destructuring); the entry was `undefined` because the populator loaded the module's namespace global before it was stored (#10160). diff --git a/crates/perry-codegen/src/codegen/artifacts.rs b/crates/perry-codegen/src/codegen/artifacts.rs index fcfd8ec434..6d39180555 100644 --- a/crates/perry-codegen/src/codegen/artifacts.rs +++ b/crates/perry-codegen/src/codegen/artifacts.rs @@ -1356,6 +1356,23 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> { blk.ret(DOUBLE, &value); continue; } + crate::NamespaceEntryKind::NestedNamespace { source_prefix } + if source_prefix == module_prefix => + { + // #10160: `export * as Self from "./self"` reads this + // module's own namespace global at access time; the + // populator publishes the entry as a live accessor. + let wrapper = llmod.define_function( + &wrapper_name, + DOUBLE, + vec![(I64, "%this_closure".to_string())], + ); + let _ = wrapper.create_block("entry"); + let blk = wrapper.block_mut(0).unwrap(); + let value = blk.load(DOUBLE, &format!("@__perry_ns_{module_prefix}")); + blk.ret(DOUBLE, &value); + continue; + } crate::NamespaceEntryKind::ForeignVar { source_prefix, source_local, diff --git a/crates/perry-codegen/src/codegen/helpers.rs b/crates/perry-codegen/src/codegen/helpers.rs index 39e1bc74e5..aa7ff04a61 100644 --- a/crates/perry-codegen/src/codegen/helpers.rs +++ b/crates/perry-codegen/src/codegen/helpers.rs @@ -1428,10 +1428,21 @@ pub(super) fn emit_namespace_populator( let len_slot = blk.gep(I32, &lens_buf, &[(I64, &idx_str)]); blk.store(I32, &format!("{}", key_len), &len_slot); - let is_live_binding = matches!( - entry.kind, - NamespaceEntryKind::LocalVar { .. } | NamespaceEntryKind::ForeignVar { .. } + // #10160: `export * as Self from "./self"` — this module's own + // `@__perry_ns_` is only stored after `js_create_namespace` + // returns below, so loading it here would freeze `undefined` into + // the entry. Publish it as a live accessor instead; its getter + // wrapper (emitted next to the LocalVar wrappers in artifacts.rs) + // loads the global at read time. + let is_self_namespace = matches!( + &entry.kind, + NamespaceEntryKind::NestedNamespace { source_prefix } if source_prefix == module_prefix ); + let is_live_binding = is_self_namespace + || matches!( + entry.kind, + NamespaceEntryKind::LocalVar { .. } | NamespaceEntryKind::ForeignVar { .. } + ); let live_slot = blk.gep(I8, &live_buf, &[(I64, &idx_str)]); blk.store(I8, if is_live_binding { "1" } else { "0" }, &live_slot); @@ -1496,6 +1507,16 @@ pub(super) fn emit_namespace_populator( ); crate::expr::nanbox_pointer_inline(blk, &handle) } + NamespaceEntryKind::NestedNamespace { .. } if is_self_namespace => { + let wrapper = namespace_live_getter_wrapper_symbol(module_prefix, i); + let blk = ctx.block(); + let handle = blk.call( + I64, + "js_closure_alloc_singleton", + &[(PTR, &format!("@{}", wrapper))], + ); + crate::expr::nanbox_pointer_inline(blk, &handle) + } NamespaceEntryKind::NestedNamespace { source_prefix } => ctx .block() .load(DOUBLE, &format!("@__perry_ns_{}", source_prefix)), diff --git a/crates/perry-ui-macos/src/widgets/textfield.rs b/crates/perry-ui-macos/src/widgets/textfield.rs index c6ecb24828..c879ed2e5c 100644 --- a/crates/perry-ui-macos/src/widgets/textfield.rs +++ b/crates/perry-ui-macos/src/widgets/textfield.rs @@ -2,7 +2,7 @@ use crate::ffi::{js_gc_pin_user_ptr, js_string_from_bytes}; use objc2::rc::Retained; use objc2::runtime::{AnyObject, Sel}; use objc2::{define_class, msg_send, AnyThread, DefinedClass}; -use objc2_app_kit::{NSTextField, NSView}; +use objc2_app_kit::{NSLineBreakMode, NSTextField, NSView}; use objc2_foundation::{ MainThreadMarker, NSNotification, NSNotificationCenter, NSObject, NSString, }; @@ -197,6 +197,17 @@ pub fn create(placeholder_ptr: *const u8, on_change: f64) -> i64 { text_field.setEditable(true); text_field.setBezeled(true); + // Single-line, to match TextField on every other backend; TextArea is + // the multiline widget. textFieldWithString: hands back a cell that + // wraps and grows tall, so a fixed-width field must be told to keep one + // line and scroll horizontally instead. + if let Some(cell) = text_field.cell() { + cell.setUsesSingleLineMode(true); + cell.setScrollable(true); + cell.setWraps(false); + cell.setLineBreakMode(NSLineBreakMode::ByClipping); + } + let view: Retained = Retained::cast_unchecked(text_field); let handle = super::register_widget(view); diff --git a/crates/perry/tests/source_graph_export_regressions.rs b/crates/perry/tests/source_graph_export_regressions.rs index ceade525bc..12c85b80fe 100644 --- a/crates/perry/tests/source_graph_export_regressions.rs +++ b/crates/perry/tests/source_graph_export_regressions.rs @@ -954,3 +954,5 @@ fn mixed_type_and_value_specifier_import_keeps_runtime_edge() { "dependency initialized\n42\n" ); } +#[path = "source_graph_export_regressions/issue_10160.rs"] +mod issue_10160; diff --git a/crates/perry/tests/source_graph_export_regressions/issue_10160.rs b/crates/perry/tests/source_graph_export_regressions/issue_10160.rs new file mode 100644 index 0000000000..19a4fafe1c --- /dev/null +++ b/crates/perry/tests/source_graph_export_regressions/issue_10160.rs @@ -0,0 +1,77 @@ +//! `export * as Self from "./self"` must read as the module's own namespace +//! through a dynamic `import()` namespace, not as `undefined` (#10160). + +use super::{compile_and_run, write}; + +fn store(dir: &std::path::Path) { + write( + dir, + "store.ts", + "export class Service {\n\ + \x20 static use(f: (s: string) => string) { return f(\"store-ok\") }\n\ + }\n\ + export const node = \"node-layer\"\n\ + export * as InstanceStore from \"./store\"\n", + ); +} + +#[test] +fn self_namespace_reexport_is_defined_on_a_dynamic_import_namespace() { + let dir = tempfile::tempdir().unwrap(); + store(dir.path()); + write( + dir.path(), + "main.ts", + "import { InstanceStore as Static } from \"./store\"\n\ + console.log(typeof Static, typeof Static.Service, Static.Service.use((s) => s))\n\ + const mod = await import(\"./store\")\n\ + console.log(Object.keys(mod).sort().join(\",\"))\n\ + const { InstanceStore } = mod\n\ + console.log(typeof InstanceStore, typeof InstanceStore.Service, InstanceStore.Service.use((s) => s + \"!\"))\n\ + console.log(InstanceStore.InstanceStore === InstanceStore, InstanceStore.node, Static.node)\n", + ); + assert_eq!( + compile_and_run(dir.path(), "main.ts"), + "object function store-ok\n\ + InstanceStore,Service,node\n\ + object function store-ok!\n\ + true node-layer node-layer\n" + ); +} + +#[test] +fn self_namespace_reexport_is_defined_on_a_static_star_import() { + let dir = tempfile::tempdir().unwrap(); + store(dir.path()); + write( + dir.path(), + "main.ts", + "import * as ns from \"./store\"\n\ + console.log(typeof ns.InstanceStore, ns.InstanceStore.Service.use((s) => s), ns.InstanceStore.node)\n", + ); + assert_eq!( + compile_and_run(dir.path(), "main.ts"), + "object store-ok node-layer\n" + ); +} + +#[test] +fn foreign_namespace_reexport_stays_intact_on_a_dynamic_import_namespace() { + let dir = tempfile::tempdir().unwrap(); + write(dir.path(), "other.ts", "export const value = 42\n"); + write( + dir.path(), + "barrel.ts", + "export * as Other from \"./other\"\nexport * as Barrel from \"./barrel\"\n", + ); + write( + dir.path(), + "main.ts", + "const mod = await import(\"./barrel\")\n\ + console.log(typeof mod.Other, mod.Other.value, typeof mod.Barrel, mod.Barrel.Other.value)\n", + ); + assert_eq!( + compile_and_run(dir.path(), "main.ts"), + "object 42 object 42\n" + ); +} diff --git a/test-files/test_issue_10155_textfield_singleline.ts b/test-files/test_issue_10155_textfield_singleline.ts new file mode 100644 index 0000000000..dee9a83163 --- /dev/null +++ b/test-files/test_issue_10155_textfield_singleline.ts @@ -0,0 +1,20 @@ +// Smoke test for issue #10155: a fixed-width editable TextField on macOS must +// stay one line and scroll horizontally, not wrap and grow tall. +// Run the built app and confirm the long value shows on one line inside the +// 220px-wide field, matching a normal single-line NSTextField. +import { App, VStack, Text, TextField, State, stateBindTextfield, widgetSetWidth } from "perry/ui" + +const text = State("assignee = currentUser() AND statusCategory != Done AND project = SU") +const field = TextField("query...", (value: string) => text.set(value)) +stateBindTextfield(text, field) +widgetSetWidth(field, 220) + +App({ + title: "issue 10155 single-line TextField", + width: 300, + height: 160, + body: VStack(12, [ + Text("Field below must stay one line and scroll, not wrap:"), + field, + ]), +})