From 6af75910899c2d8fce8294575e9969725dbf76cd Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Wed, 2 Sep 2026 11:47:43 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20CodeRabbit=20CI=20Fix:=20Fix=203?= =?UTF-8?q?2=20Failing=20CI=20Checks=20Across=20Build,=20Tests,=20Security?= =?UTF-8?q?,=20and=20Governance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rust_core/benches/core_bench.rs | 21 ++++-------- rust_core/src/form_data.rs | 7 ++-- rust_core/src/interests.rs | 55 +++++++++++++++++++++++++------- rust_core/src/lib.rs | 27 ++++++++++------ rust_core/tests/aspect_test.rs | 24 +++++++------- rust_core/tests/e2e_test.rs | 6 ++-- rust_core/tests/property_test.rs | 3 +- src/bindings/Chrome.res.js | 2 +- 8 files changed, 85 insertions(+), 60 deletions(-) diff --git a/rust_core/benches/core_bench.rs b/rust_core/benches/core_bench.rs index fef3cbe..1f15c97 100644 --- a/rust_core/benches/core_bench.rs +++ b/rust_core/benches/core_bench.rs @@ -2,7 +2,7 @@ // Performance benchmarks for DoubleTrack core operations // Measures throughput of critical paths -use criterion::{black_box, criterion_group, criterion_main, Criterion, BenchmarkId}; +use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion}; use doubletrack_core::*; use rand::SeedableRng; @@ -27,17 +27,13 @@ fn benchmark_profile_serialization(c: &mut Criterion) { let profile = gen.generate(); c.bench_function("profile_to_json", |b| { - b.iter(|| { - serde_json::to_string(black_box(&profile)) - }); + b.iter(|| serde_json::to_string(black_box(&profile))); }); let json_str = serde_json::to_string(&profile).unwrap(); c.bench_function("json_to_profile", |b| { - b.iter(|| { - serde_json::from_str::(black_box(&json_str)) - }); + b.iter(|| serde_json::from_str::(black_box(&json_str))); }); } @@ -77,8 +73,7 @@ fn benchmark_activity_count_scaling(c: &mut Criterion) { let mut total_duration = std::time::Duration::ZERO; for _ in 0..iters { let start = std::time::Instant::now(); - let mut simulator = - ActivitySimulator::new(black_box(profile.clone())); + let mut simulator = ActivitySimulator::new(black_box(profile.clone())); // Estimate hours needed for target activity count let hours = ((activity_count as f64 / 4.0) as u32).max(1); let _ = simulator.generate_activities(black_box(hours)); @@ -109,9 +104,7 @@ fn benchmark_schedule_generation(c: &mut Criterion) { let profile = gen.generate(); c.bench_function("schedule_generation", |b| { - b.iter(|| { - Schedule::from_profile(black_box(&profile)) - }); + b.iter(|| Schedule::from_profile(black_box(&profile))); }); } @@ -120,9 +113,7 @@ fn benchmark_validation(c: &mut Criterion) { let profile = gen.generate(); c.bench_function("profile_validation", |b| { - b.iter(|| { - profile.is_valid() - }); + b.iter(|| profile.is_valid()); }); } diff --git a/rust_core/src/form_data.rs b/rust_core/src/form_data.rs index fde51a8..386226d 100644 --- a/rust_core/src/form_data.rs +++ b/rust_core/src/form_data.rs @@ -76,10 +76,9 @@ impl FormDataGenerator { // `first` is either "user" (literal fallback) or a yield from // split_whitespace which never returns empty slices, so first_lower // is always non-empty and .chars().next() is always Some. - first_lower - .chars() - .next() - .expect("first_lower is non-empty (literal fallback or split_whitespace yield)"), + first_lower.chars().next().expect( + "first_lower is non-empty (literal fallback or split_whitespace yield)" + ), last_lower, number_suffix ), diff --git a/rust_core/src/interests.rs b/rust_core/src/interests.rs index 4bd8919..edf5a04 100644 --- a/rust_core/src/interests.rs +++ b/rust_core/src/interests.rs @@ -58,11 +58,16 @@ impl InterestUrlGenerator { let title = self.get_video_title(interest, rng); let video_id = self.generate_video_id(rng); - let platform = ["youtube.com", "vimeo.com"].choose(rng).expect(".choose() on a non-empty static literal array is always Some"); + let platform = ["youtube.com", "vimeo.com"] + .choose(rng) + .expect(".choose() on a non-empty static literal array is always Some"); let url = if *platform == "youtube.com" { format!("https://www.youtube.com/watch?v={}", video_id) } else { - format!("https://vimeo.com/{}", rng.random_range(100000000..999999999)) + format!( + "https://vimeo.com/{}", + rng.random_range(100000000..999999999) + ) }; (url, title) @@ -107,7 +112,9 @@ impl InterestUrlGenerator { ("bsky.app", "Bluesky"), ]; - let (domain, name) = platforms.choose(rng).expect(".choose() on a non-empty static literal array is always Some"); + let (domain, name) = platforms + .choose(rng) + .expect(".choose() on a non-empty static literal array is always Some"); let url = format!("https://{}", domain); let title = format!("Home - {}", name); @@ -434,7 +441,10 @@ impl InterestUrlGenerator { "recipe of the day", ], }; - queries.choose(rng).expect(".choose() on a non-empty static literal array is always Some").to_string() + queries + .choose(rng) + .expect(".choose() on a non-empty static literal array is always Some") + .to_string() } else { [ "news today", @@ -517,7 +527,10 @@ impl InterestUrlGenerator { "How-To Guide Step by Step", ], }; - titles.choose(rng).expect(".choose() on a non-empty static literal array is always Some").to_string() + titles + .choose(rng) + .expect(".choose() on a non-empty static literal array is always Some") + .to_string() } else { "Trending Video".to_string() } @@ -601,7 +614,10 @@ impl InterestUrlGenerator { "New Arrival", ], }; - products.choose(rng).expect(".choose() on a non-empty static literal array is always Some").to_string() + products + .choose(rng) + .expect(".choose() on a non-empty static literal array is always Some") + .to_string() } else { "Product".to_string() } @@ -658,7 +674,10 @@ impl InterestUrlGenerator { "Weather Pattern Shift Expected This Week", ], }; - headlines.choose(rng).expect(".choose() on a non-empty static literal array is always Some").to_string() + headlines + .choose(rng) + .expect(".choose() on a non-empty static literal array is always Some") + .to_string() } else { "Breaking News".to_string() } @@ -728,7 +747,10 @@ impl InterestUrlGenerator { "Literature Review Summary", ], }; - topics.choose(rng).expect(".choose() on a non-empty static literal array is always Some").to_string() + topics + .choose(rng) + .expect(".choose() on a non-empty static literal array is always Some") + .to_string() } else { "General Topic".to_string() } @@ -766,7 +788,10 @@ impl InterestUrlGenerator { "Community Recommendations", ], }; - pages.choose(rng).expect(".choose() on a non-empty static literal array is always Some").to_string() + pages + .choose(rng) + .expect(".choose() on a non-empty static literal array is always Some") + .to_string() } else { "General Page".to_string() } @@ -848,15 +873,21 @@ impl DomainDatabase { } fn get_shopping_domain(&self, rng: &mut R) -> &str { - self.shopping.choose(rng).expect(".choose() on a non-empty static literal array is always Some") + self.shopping + .choose(rng) + .expect(".choose() on a non-empty static literal array is always Some") } fn get_news_domain(&self, rng: &mut R) -> &str { - self.news.choose(rng).expect(".choose() on a non-empty static literal array is always Some") + self.news + .choose(rng) + .expect(".choose() on a non-empty static literal array is always Some") } fn get_research_domain(&self, rng: &mut R) -> &str { - self.research.choose(rng).expect(".choose() on a non-empty static literal array is always Some") + self.research + .choose(rng) + .expect(".choose() on a non-empty static literal array is always Some") } fn get_interest_domain( diff --git a/rust_core/src/lib.rs b/rust_core/src/lib.rs index 821ab78..e58919e 100644 --- a/rust_core/src/lib.rs +++ b/rust_core/src/lib.rs @@ -28,7 +28,8 @@ pub fn generate_profile(seed: Option) -> JsValue { let profile = generator.generate(); // Profile is a plain serde-derived struct of owned primitives/Vecs; serialization // to a JsValue cannot fail. WASM-export signature returns JsValue, not Result. - serde_wasm_bindgen::to_value(&profile).expect("Profile serialization is infallible (plain owned data)") + serde_wasm_bindgen::to_value(&profile) + .expect("Profile serialization is infallible (plain owned data)") } /// Generate browsing activities for a profile @@ -36,12 +37,14 @@ pub fn generate_profile(seed: Option) -> JsValue { pub fn generate_activities(profile_json: JsValue, duration_hours: u32) -> JsValue { // Caller-supplied JsValue must deserialize as Profile; validated by JS shim. // WASM-export signature returns JsValue, not Result — callers should pre-validate. - let profile: Profile = serde_wasm_bindgen::from_value(profile_json) - .expect("profile_json must be a valid serialized Profile (validate via validate_profile first)"); + let profile: Profile = serde_wasm_bindgen::from_value(profile_json).expect( + "profile_json must be a valid serialized Profile (validate via validate_profile first)", + ); let mut simulator = ActivitySimulator::new(profile); let activities = simulator.generate_activities(duration_hours); // Vec is plain serde-derived owned data; serialization is infallible. - serde_wasm_bindgen::to_value(&activities).expect("BrowsingActivity serialization is infallible (plain owned data)") + serde_wasm_bindgen::to_value(&activities) + .expect("BrowsingActivity serialization is infallible (plain owned data)") } /// Validate that a profile is internally consistent @@ -58,23 +61,27 @@ pub fn validate_profile(profile_json: JsValue) -> bool { #[wasm_bindgen] pub fn get_activity_schedule(profile_json: JsValue) -> JsValue { // Caller-supplied JsValue must deserialize as Profile; validated by JS shim. - let profile: Profile = serde_wasm_bindgen::from_value(profile_json) - .expect("profile_json must be a valid serialized Profile (validate via validate_profile first)"); + let profile: Profile = serde_wasm_bindgen::from_value(profile_json).expect( + "profile_json must be a valid serialized Profile (validate via validate_profile first)", + ); let schedule = Schedule::from_profile(&profile); // Schedule is plain serde-derived owned data; serialization is infallible. - serde_wasm_bindgen::to_value(&schedule).expect("Schedule serialization is infallible (plain owned data)") + serde_wasm_bindgen::to_value(&schedule) + .expect("Schedule serialization is infallible (plain owned data)") } /// Generate plausible form fill data tied to a profile #[wasm_bindgen] pub fn generate_form_data(profile_json: JsValue) -> JsValue { // Caller-supplied JsValue must deserialize as Profile; validated by JS shim. - let profile: Profile = serde_wasm_bindgen::from_value(profile_json) - .expect("profile_json must be a valid serialized Profile (validate via validate_profile first)"); + let profile: Profile = serde_wasm_bindgen::from_value(profile_json).expect( + "profile_json must be a valid serialized Profile (validate via validate_profile first)", + ); let mut rng = rand::rngs::SmallRng::from_os_rng(); let form = FormDataGenerator::generate(&profile, &mut rng); // FormData is plain serde-derived owned data; serialization is infallible. - serde_wasm_bindgen::to_value(&form).expect("FormData serialization is infallible (plain owned data)") + serde_wasm_bindgen::to_value(&form) + .expect("FormData serialization is infallible (plain owned data)") } #[cfg(test)] diff --git a/rust_core/tests/aspect_test.rs b/rust_core/tests/aspect_test.rs index ba00c15..d325045 100644 --- a/rust_core/tests/aspect_test.rs +++ b/rust_core/tests/aspect_test.rs @@ -94,10 +94,7 @@ fn test_sql_injection_patterns_in_formdata() { let form = FormDataGenerator::generate(&profile, &mut rng); // Email should always be valid format, not SQL injection - assert!( - form.email.contains('@'), - "Email must contain @ symbol" - ); + assert!(form.email.contains('@'), "Email must contain @ symbol"); let parts: Vec<&str> = form.email.split('@').collect(); assert_eq!(parts.len(), 2, "Email must have valid structure"); @@ -151,7 +148,7 @@ fn test_activity_timestamp_validity() { // Activity timestamps should be recent (within 24 hours) let time_diff = (now - activity.timestamp).abs(); assert!( - time_diff < 86400 * 2, // 2 days tolerance + time_diff < 86400 * 2, // 2 days tolerance "Activity timestamp should be recent" ); } @@ -178,10 +175,7 @@ fn test_activity_list_consistency() { // All activities should have consistent structure for activity in &activities { // Duration should be positive - assert!( - activity.duration_seconds > 0, - "Duration must be positive" - ); + assert!(activity.duration_seconds > 0, "Duration must be positive"); // URL should be valid assert!( @@ -239,8 +233,14 @@ fn test_no_unsafe_pattern_in_data_structures() { let form = FormDataGenerator::generate(&profile, &mut rng); // Check for null bytes (would cause C string issues) - assert!(!form.email.contains('\0'), "Email must not contain null bytes"); - assert!(!form.display_name.contains('\0'), "Display name must not contain null bytes"); + assert!( + !form.email.contains('\0'), + "Email must not contain null bytes" + ); + assert!( + !form.display_name.contains('\0'), + "Display name must not contain null bytes" + ); // Check for control characters (except newline/tab which might be ok) for c in form.email.chars() { @@ -264,7 +264,7 @@ fn test_boundary_values_for_activity_duration() { let max_duration = match activity.activity_type { ActivityType::VideoWatch => 3600 * 4, // Videos might be longer ActivityType::Research => 3600 * 2, // Research could be extended - _ => 3600, // Most activities < 1 hour + _ => 3600, // Most activities < 1 hour }; assert!( diff --git a/rust_core/tests/e2e_test.rs b/rust_core/tests/e2e_test.rs index ff76753..414d1f1 100644 --- a/rust_core/tests/e2e_test.rs +++ b/rust_core/tests/e2e_test.rs @@ -20,8 +20,7 @@ fn test_full_profile_lifecycle() { assert!(!json_str.is_empty(), "Serialized JSON must not be empty"); // Deserialize back - let deserialized: Profile = - serde_json::from_str(&json_str).expect("Deserialization failed"); + let deserialized: Profile = serde_json::from_str(&json_str).expect("Deserialization failed"); // Verify data integrity assert_eq!( @@ -182,8 +181,7 @@ fn test_formdata_serialization_roundtrip() { let form_original = FormDataGenerator::generate(&profile, &mut rng); // Serialize - let json_str = - serde_json::to_string(&form_original).expect("FormData serialization failed"); + let json_str = serde_json::to_string(&form_original).expect("FormData serialization failed"); // Deserialize let form_deserialized: FormData = diff --git a/rust_core/tests/property_test.rs b/rust_core/tests/property_test.rs index a5f80cd..ec267d6 100644 --- a/rust_core/tests/property_test.rs +++ b/rust_core/tests/property_test.rs @@ -9,8 +9,7 @@ use rand::SeedableRng; // Define strategies for property-based testing fn name_strategy() -> impl Strategy { - r"[A-Z][a-z]{1,10} [A-Z][a-z]{1,10}" - .prop_map(|s| s.to_string()) + r"[A-Z][a-z]{1,10} [A-Z][a-z]{1,10}".prop_map(|s| s.to_string()) } fn age_strategy() -> impl Strategy { diff --git a/src/bindings/Chrome.res.js b/src/bindings/Chrome.res.js index e1c79ac..1b1f9ca 100644 --- a/src/bindings/Chrome.res.js +++ b/src/bindings/Chrome.res.js @@ -1,7 +1,7 @@ // Generated by ReScript, PLEASE EDIT WITH CARE -let Local = {}; +const Local = {}; let Storage = { Local: Local