127 lines
3.9 KiB
Rust
127 lines
3.9 KiB
Rust
use module_runtime::{
|
|
AnalyticsGranularity, RuntimeAnalyticsDailyStatSnapshot, RuntimeTrackingScopeKind,
|
|
aggregate_runtime_tracking_daily_stats,
|
|
};
|
|
|
|
fn stat(
|
|
event_key: &str,
|
|
scope_id: &str,
|
|
day_key: i64,
|
|
count: u32,
|
|
) -> RuntimeAnalyticsDailyStatSnapshot {
|
|
RuntimeAnalyticsDailyStatSnapshot {
|
|
event_key: event_key.to_string(),
|
|
scope_kind: RuntimeTrackingScopeKind::User,
|
|
scope_id: scope_id.to_string(),
|
|
day_key,
|
|
count,
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn aggregates_daily_stats_by_iso_week_bucket() {
|
|
let buckets = aggregate_runtime_tracking_daily_stats(
|
|
vec![
|
|
stat("daily_login", "user-1", 20_517, 1), // 2026-03-05
|
|
stat("daily_login", "user-1", 20_518, 2), // 2026-03-06
|
|
stat("daily_login", "user-1", 20_524, 3), // 2026-03-12
|
|
stat("daily_login", "user-2", 20_517, 9),
|
|
],
|
|
"daily_login",
|
|
RuntimeTrackingScopeKind::User,
|
|
"user-1",
|
|
AnalyticsGranularity::Week,
|
|
);
|
|
|
|
assert_eq!(buckets.len(), 2);
|
|
assert_eq!(buckets[0].bucket_key, "202610");
|
|
assert_eq!(buckets[0].bucket_start_date_key, 20_514); // 2026-03-02
|
|
assert_eq!(buckets[0].bucket_end_date_key, 20_520); // 2026-03-08
|
|
assert_eq!(buckets[0].value, 3);
|
|
assert_eq!(buckets[1].bucket_key, "202611");
|
|
assert_eq!(buckets[1].bucket_start_date_key, 20_521); // 2026-03-09
|
|
assert_eq!(buckets[1].bucket_end_date_key, 20_527); // 2026-03-15
|
|
assert_eq!(buckets[1].value, 3);
|
|
}
|
|
|
|
#[test]
|
|
fn aggregates_daily_stats_by_month_quarter_and_year_bucket() {
|
|
let stats = vec![
|
|
stat("play", "user-1", 20_545, 2), // 2026-04-02
|
|
stat("play", "user-1", 20_573, 3), // 2026-04-30
|
|
stat("play", "user-1", 20_574, 5), // 2026-05-01
|
|
stat("play", "user-1", 20_818, 7), // 2026-12-31
|
|
];
|
|
|
|
let month = aggregate_runtime_tracking_daily_stats(
|
|
stats.clone(),
|
|
"play",
|
|
RuntimeTrackingScopeKind::User,
|
|
"user-1",
|
|
AnalyticsGranularity::Month,
|
|
);
|
|
assert_eq!(
|
|
month
|
|
.iter()
|
|
.map(|bucket| (&bucket.bucket_key, bucket.value))
|
|
.collect::<Vec<_>>(),
|
|
vec![
|
|
(&"202604".to_string(), 5),
|
|
(&"202605".to_string(), 5),
|
|
(&"202612".to_string(), 7)
|
|
]
|
|
);
|
|
assert_eq!(month[0].bucket_start_date_key, 20_544);
|
|
assert_eq!(month[0].bucket_end_date_key, 20_573);
|
|
|
|
let quarter = aggregate_runtime_tracking_daily_stats(
|
|
stats.clone(),
|
|
"play",
|
|
RuntimeTrackingScopeKind::User,
|
|
"user-1",
|
|
AnalyticsGranularity::Quarter,
|
|
);
|
|
assert_eq!(
|
|
quarter
|
|
.iter()
|
|
.map(|bucket| (&bucket.bucket_key, bucket.value))
|
|
.collect::<Vec<_>>(),
|
|
vec![(&"20262".to_string(), 10), (&"20264".to_string(), 7)]
|
|
);
|
|
|
|
let year = aggregate_runtime_tracking_daily_stats(
|
|
stats,
|
|
"play",
|
|
RuntimeTrackingScopeKind::User,
|
|
"user-1",
|
|
AnalyticsGranularity::Year,
|
|
);
|
|
assert_eq!(year.len(), 1);
|
|
assert_eq!(year[0].bucket_key, "2026");
|
|
assert_eq!(year[0].value, 17);
|
|
}
|
|
|
|
#[test]
|
|
fn day_granularity_keeps_each_day_bucket_and_filters_scope() {
|
|
let buckets = aggregate_runtime_tracking_daily_stats(
|
|
vec![
|
|
stat("daily_login", "user-1", 20_517, 1),
|
|
stat("daily_login", "user-1", 20_518, 2),
|
|
stat("daily_login", "user-2", 20_517, 9),
|
|
stat("other", "user-1", 20_517, 9),
|
|
],
|
|
"daily_login",
|
|
RuntimeTrackingScopeKind::User,
|
|
"user-1",
|
|
AnalyticsGranularity::Day,
|
|
);
|
|
|
|
assert_eq!(buckets.len(), 2);
|
|
assert_eq!(buckets[0].bucket_key, "2026-03-05");
|
|
assert_eq!(buckets[0].bucket_start_date_key, 20_517);
|
|
assert_eq!(buckets[0].bucket_end_date_key, 20_517);
|
|
assert_eq!(buckets[0].value, 1);
|
|
assert_eq!(buckets[1].bucket_key, "2026-03-06");
|
|
assert_eq!(buckets[1].value, 2);
|
|
}
|