mirror of
https://github.com/0xrsydn/idx-cli.git
synced 2026-08-07 01:33:52 +00:00
test: autoresgressive simple
This commit is contained in:
parent
7ea79d24e6
commit
0fd6c666a6
1 changed files with 216 additions and 5 deletions
221
tests/cli.rs
221
tests/cli.rs
|
|
@ -175,7 +175,27 @@ fn msn_profile_with_mock_fixture_table_contains_expected_fields() {
|
||||||
.assert()
|
.assert()
|
||||||
.success()
|
.success()
|
||||||
.stdout(predicate::str::contains("Symbol"))
|
.stdout(predicate::str::contains("Symbol"))
|
||||||
.stdout(predicate::str::contains("Bank Central Asia Tbk PT"));
|
.stdout(predicate::str::contains("PT Bank Central Asia Tbk"))
|
||||||
|
.stdout(predicate::str::contains("Financials"))
|
||||||
|
.stdout(predicate::str::contains("https://www.bca.co.id/"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn msn_profile_with_mock_fixture_json_prefers_company_and_localized_fields() {
|
||||||
|
test_bin("msn-profile-json")
|
||||||
|
.env("IDX_PROVIDER", "msn")
|
||||||
|
.env("IDX_USE_MOCK_PROVIDER", "1")
|
||||||
|
.args(["-o", "json", "stocks", "profile", "BBCA"])
|
||||||
|
.assert()
|
||||||
|
.success()
|
||||||
|
.stdout(predicate::str::contains(
|
||||||
|
"\"long_name\": \"PT Bank Central Asia Tbk\"",
|
||||||
|
))
|
||||||
|
.stdout(predicate::str::contains(
|
||||||
|
"\"industry\": \"Banking Services\"",
|
||||||
|
))
|
||||||
|
.stdout(predicate::str::contains("\"country\": \"Indonesia\""))
|
||||||
|
.stdout(predicate::str::contains("Indonesia-based commercial bank"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -186,11 +206,28 @@ fn msn_financials_with_mock_fixture_table_contains_sections() {
|
||||||
.args(["stocks", "financials", "BBCA"])
|
.args(["stocks", "financials", "BBCA"])
|
||||||
.assert()
|
.assert()
|
||||||
.success()
|
.success()
|
||||||
.stdout(predicate::str::contains("Income Statement"))
|
.stdout(predicate::str::contains("Income Statement (2025-12-31)"))
|
||||||
.stdout(predicate::str::contains("netIncome"))
|
.stdout(predicate::str::contains("Net Income"))
|
||||||
|
.stdout(predicate::str::contains("Operating Cash Flow"))
|
||||||
.stdout(predicate::str::contains("Cash Flow"));
|
.stdout(predicate::str::contains("Cash Flow"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn msn_earnings_with_mock_fixture_table_is_sectioned_and_formatted() {
|
||||||
|
test_bin("msn-earnings-table")
|
||||||
|
.env("IDX_PROVIDER", "msn")
|
||||||
|
.env("IDX_USE_MOCK_PROVIDER", "1")
|
||||||
|
.args(["stocks", "earnings", "BBCA"])
|
||||||
|
.assert()
|
||||||
|
.success()
|
||||||
|
.stdout(predicate::str::contains("Earnings History"))
|
||||||
|
.stdout(predicate::str::contains("Earnings Forecast"))
|
||||||
|
.stdout(predicate::str::contains("FY2025"))
|
||||||
|
.stdout(predicate::str::contains("Q1 2026"))
|
||||||
|
.stdout(predicate::str::contains("110,000,000,000"))
|
||||||
|
.stdout(predicate::str::contains("2026-03-15"));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn msn_earnings_with_mock_fixture_json_contains_forecast_and_history() {
|
fn msn_earnings_with_mock_fixture_json_contains_forecast_and_history() {
|
||||||
test_bin("msn-earnings-json")
|
test_bin("msn-earnings-json")
|
||||||
|
|
@ -217,6 +254,20 @@ fn msn_sentiment_with_mock_fixture_table_contains_ranges() {
|
||||||
.stdout(predicate::str::contains("BULLISH"));
|
.stdout(predicate::str::contains("BULLISH"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn msn_sentiment_with_mock_fixture_json_contains_symbol_and_counts() {
|
||||||
|
test_bin("msn-sentiment-json")
|
||||||
|
.env("IDX_PROVIDER", "msn")
|
||||||
|
.env("IDX_USE_MOCK_PROVIDER", "1")
|
||||||
|
.args(["-o", "json", "stocks", "sentiment", "BBCA"])
|
||||||
|
.assert()
|
||||||
|
.success()
|
||||||
|
.stdout(predicate::str::contains("\"symbol\": \"BBCA.JK\""))
|
||||||
|
.stdout(predicate::str::contains("\"time_range\": \"1D\""))
|
||||||
|
.stdout(predicate::str::contains("\"bullish\": 10"))
|
||||||
|
.stdout(predicate::str::contains("\"neutral\": 3"));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn msn_insights_with_mock_fixture_table_contains_highlights_and_risks() {
|
fn msn_insights_with_mock_fixture_table_contains_highlights_and_risks() {
|
||||||
test_bin("msn-insights-table")
|
test_bin("msn-insights-table")
|
||||||
|
|
@ -225,11 +276,35 @@ fn msn_insights_with_mock_fixture_table_contains_highlights_and_risks() {
|
||||||
.args(["stocks", "insights", "BBCA"])
|
.args(["stocks", "insights", "BBCA"])
|
||||||
.assert()
|
.assert()
|
||||||
.success()
|
.success()
|
||||||
|
.stdout(predicate::str::contains("Mixed analyst signals"))
|
||||||
|
.stdout(predicate::str::contains(
|
||||||
|
"Last updated: 2026-03-26T04:14:57.9197955Z",
|
||||||
|
))
|
||||||
.stdout(predicate::str::contains("Highlights:"))
|
.stdout(predicate::str::contains("Highlights:"))
|
||||||
.stdout(predicate::str::contains(
|
.stdout(predicate::str::contains(
|
||||||
"Shares trade near historical averages.",
|
"Analyst price target: Analysts forecast more than 20% upside",
|
||||||
))
|
))
|
||||||
.stdout(predicate::str::contains("Risks:"));
|
.stdout(predicate::str::contains("Risks:"))
|
||||||
|
.stdout(predicate::str::contains(
|
||||||
|
"Quarterly Revenue YoY Growth: Revenue grew worse than peers",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn msn_insights_with_mock_fixture_json_contains_summary_and_last_updated() {
|
||||||
|
test_bin("msn-insights-json")
|
||||||
|
.env("IDX_PROVIDER", "msn")
|
||||||
|
.env("IDX_USE_MOCK_PROVIDER", "1")
|
||||||
|
.args(["-o", "json", "stocks", "insights", "BBCA"])
|
||||||
|
.assert()
|
||||||
|
.success()
|
||||||
|
.stdout(predicate::str::contains(
|
||||||
|
"\"summary\": \"Mixed analyst signals",
|
||||||
|
))
|
||||||
|
.stdout(predicate::str::contains(
|
||||||
|
"\"last_updated\": \"2026-03-26T04:14:57.9197955Z\"",
|
||||||
|
))
|
||||||
|
.stdout(predicate::str::contains("Revenue grew worse than peers"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -244,6 +319,24 @@ fn msn_news_with_mock_fixture_table_contains_provider_and_title() {
|
||||||
.stdout(predicate::str::contains("Contoso News"));
|
.stdout(predicate::str::contains("Contoso News"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn msn_news_with_mock_fixture_json_contains_provider_and_timestamp() {
|
||||||
|
test_bin("msn-news-json")
|
||||||
|
.env("IDX_PROVIDER", "msn")
|
||||||
|
.env("IDX_USE_MOCK_PROVIDER", "1")
|
||||||
|
.args(["-o", "json", "stocks", "news", "BBCA", "--limit", "5"])
|
||||||
|
.assert()
|
||||||
|
.success()
|
||||||
|
.stdout(predicate::str::contains("\"id\": \"news-1\""))
|
||||||
|
.stdout(predicate::str::contains(
|
||||||
|
"\"title\": \"BCA reports steady growth\"",
|
||||||
|
))
|
||||||
|
.stdout(predicate::str::contains("\"provider\": \"Contoso News\""))
|
||||||
|
.stdout(predicate::str::contains(
|
||||||
|
"\"published_at\": \"2026-03-20T10:00:00Z\"",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn msn_screen_with_mock_fixture_table_contains_quotes() {
|
fn msn_screen_with_mock_fixture_table_contains_quotes() {
|
||||||
test_bin("msn-screen-table")
|
test_bin("msn-screen-table")
|
||||||
|
|
@ -264,6 +357,29 @@ fn msn_screen_with_mock_fixture_table_contains_quotes() {
|
||||||
.stdout(predicate::str::contains("BBRI.JK"));
|
.stdout(predicate::str::contains("BBRI.JK"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn msn_screen_with_mock_fixture_json_contains_normalized_symbols_and_ranges() {
|
||||||
|
test_bin("msn-screen-json")
|
||||||
|
.env("IDX_PROVIDER", "msn")
|
||||||
|
.env("IDX_USE_MOCK_PROVIDER", "1")
|
||||||
|
.args([
|
||||||
|
"-o",
|
||||||
|
"json",
|
||||||
|
"stocks",
|
||||||
|
"screen",
|
||||||
|
"--filter",
|
||||||
|
"top-performers",
|
||||||
|
"--limit",
|
||||||
|
"10",
|
||||||
|
])
|
||||||
|
.assert()
|
||||||
|
.success()
|
||||||
|
.stdout(predicate::str::contains("\"symbol\": \"BBCA.JK\""))
|
||||||
|
.stdout(predicate::str::contains("\"symbol\": \"BBRI.JK\""))
|
||||||
|
.stdout(predicate::str::contains("\"change\": 117"))
|
||||||
|
.stdout(predicate::str::contains("\"range_signal\": \"upper\""));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn growth_with_mock_provider_table_contains_expected_rows() {
|
fn growth_with_mock_provider_table_contains_expected_rows() {
|
||||||
test_bin("growth-table")
|
test_bin("growth-table")
|
||||||
|
|
@ -545,3 +661,98 @@ fn invalid_provider_env_returns_non_zero() {
|
||||||
.failure()
|
.failure()
|
||||||
.stderr(predicate::str::contains("invalid provider"));
|
.stderr(predicate::str::contains("invalid provider"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn invalid_provider_env_honors_json_output() {
|
||||||
|
test_bin("invalid-provider-json")
|
||||||
|
.env("IDX_PROVIDER", "bogus")
|
||||||
|
.args(["-o", "json", "version"])
|
||||||
|
.assert()
|
||||||
|
.failure()
|
||||||
|
.stderr(predicate::str::contains("\"error\": true"))
|
||||||
|
.stderr(predicate::str::contains("invalid provider"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn offline_and_no_cache_flags_are_rejected() {
|
||||||
|
test_bin("offline-no-cache")
|
||||||
|
.args(["--offline", "--no-cache", "stocks", "quote", "BBCA"])
|
||||||
|
.assert()
|
||||||
|
.failure()
|
||||||
|
.stderr(predicate::str::contains(
|
||||||
|
"cannot combine --offline with --no-cache",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn msn_profile_supports_offline_cache_reads() {
|
||||||
|
let root = test_env_dir("msn-profile-offline");
|
||||||
|
let cache_home = root.join("cache");
|
||||||
|
|
||||||
|
bin_with_root(&root)
|
||||||
|
.env("XDG_CACHE_HOME", &cache_home)
|
||||||
|
.env("IDX_PROVIDER", "msn")
|
||||||
|
.env("IDX_USE_MOCK_PROVIDER", "1")
|
||||||
|
.args(["stocks", "profile", "BBCA"])
|
||||||
|
.assert()
|
||||||
|
.success();
|
||||||
|
|
||||||
|
bin_with_root(&root)
|
||||||
|
.env("XDG_CACHE_HOME", &cache_home)
|
||||||
|
.env("IDX_PROVIDER", "msn")
|
||||||
|
.env("IDX_USE_MOCK_PROVIDER", "1")
|
||||||
|
.args(["--offline", "stocks", "profile", "BBCA"])
|
||||||
|
.assert()
|
||||||
|
.success()
|
||||||
|
.stdout(predicate::str::contains("PT Bank Central Asia Tbk"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn msn_profile_serves_stale_cache_on_provider_failure_with_warning() {
|
||||||
|
let root = test_env_dir("msn-profile-stale");
|
||||||
|
let cache_home = root.join("cache");
|
||||||
|
|
||||||
|
bin_with_root(&root)
|
||||||
|
.env("XDG_CACHE_HOME", &cache_home)
|
||||||
|
.env("IDX_PROVIDER", "msn")
|
||||||
|
.env("IDX_USE_MOCK_PROVIDER", "1")
|
||||||
|
.env("IDX_CACHE_FUNDAMENTAL_TTL", "0")
|
||||||
|
.args(["stocks", "profile", "BBCA"])
|
||||||
|
.assert()
|
||||||
|
.success();
|
||||||
|
|
||||||
|
bin_with_root(&root)
|
||||||
|
.env("XDG_CACHE_HOME", &cache_home)
|
||||||
|
.env("IDX_PROVIDER", "msn")
|
||||||
|
.env("IDX_USE_MOCK_PROVIDER", "1")
|
||||||
|
.env("IDX_CACHE_FUNDAMENTAL_TTL", "0")
|
||||||
|
.env("IDX_MOCK_ERROR", "1")
|
||||||
|
.args(["stocks", "profile", "BBCA"])
|
||||||
|
.assert()
|
||||||
|
.success()
|
||||||
|
.stderr(predicate::str::contains("warning: network failed"))
|
||||||
|
.stdout(predicate::str::contains("PT Bank Central Asia Tbk"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn msn_screen_rejects_invalid_filter() {
|
||||||
|
test_bin("msn-screen-invalid-filter")
|
||||||
|
.env("IDX_PROVIDER", "msn")
|
||||||
|
.env("IDX_USE_MOCK_PROVIDER", "1")
|
||||||
|
.args(["stocks", "screen", "--filter", "bogus"])
|
||||||
|
.assert()
|
||||||
|
.failure()
|
||||||
|
.stderr(predicate::str::contains("invalid screener filter"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn msn_screen_rejects_invalid_region_in_json_mode() {
|
||||||
|
test_bin("msn-screen-invalid-region-json")
|
||||||
|
.env("IDX_PROVIDER", "msn")
|
||||||
|
.env("IDX_USE_MOCK_PROVIDER", "1")
|
||||||
|
.args(["-o", "json", "stocks", "screen", "--region", "eu"])
|
||||||
|
.assert()
|
||||||
|
.failure()
|
||||||
|
.stderr(predicate::str::contains("\"error\": true"))
|
||||||
|
.stderr(predicate::str::contains("invalid screener region"));
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue