Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions crates/wright-analyzer/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,6 @@ mod tests {
let _ = ErrorInfo::new("unknown-enum member", "message");
}

#[test]
#[should_panic(expected = "violates the code grammar")]
fn error_info_new_rejects_an_uppercase_code() {
let _ = ErrorInfo::new("Unknown-Value", "message");
}

#[test]
fn error_info_carried_keeps_foreign_vocabulary() {
for code in [
Expand Down
48 changes: 0 additions & 48 deletions crates/wright-analyzer/tests/workshop_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,34 +101,6 @@ fn span_text(source: &str, span: &Value) -> String {
.collect()
}

#[test]
fn workshop_input_runs_all_semantic_queries() {
let service = workshop_service("synthetic/control-flow");
let rule = id_for(
&service,
serde_json::json!({"op": "listRules"}),
"bounded while",
);
let symbol = id_for(&service, serde_json::json!({"op": "listSymbols"}), "index");
let requests = [
serde_json::json!({"op": "program"}),
serde_json::json!({"op": "listRules"}),
serde_json::json!({"op": "getRule", "rule": rule}),
serde_json::json!({"op": "findReferences", "symbol": symbol}),
serde_json::json!({"op": "getUsage", "symbol": symbol}),
serde_json::json!({"op": "getCfg", "rule": rule}),
serde_json::json!({"op": "getFindings"}),
];
for request in requests {
query(&service, request);
}

let program_response: Value =
serde_json::from_str(&service.handle_json(r#"{"op":"program"}"#)).unwrap();
assert_eq!(program_response["result"]["origin"]["kind"], "workshop");
assert_eq!(program_response["result"]["origin"]["locale"], "en-us");
}

#[test]
fn player_event_queries_keep_catalog_event_ids() {
let mut program = Program::new();
Expand All @@ -145,26 +117,6 @@ fn player_event_queries_keep_catalog_event_ids() {
assert_eq!(rule["event"], "playerDealtDamage");
}

#[test]
fn workshop_input_analysis_findings_are_available() {
let service = workshop_service("synthetic/control-flow");
let response: Value =
serde_json::from_str(&service.handle_json(r#"{"op":"getFindings"}"#)).unwrap();
let findings = response["result"].as_array().unwrap();
assert!(
findings
.iter()
.any(|finding| finding["code"] == "min-wait-loop"),
"the Workshop-origin bounded-while is a hot loop"
);
for finding in findings {
assert!(
finding["span"].is_object(),
"findings must carry Workshop source spans: {finding}"
);
}
}

#[test]
fn workshop_analysis_preserves_lint_semantics() {
let source = r#"
Expand Down
19 changes: 0 additions & 19 deletions crates/wright-cli/src/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,23 +447,4 @@ mod tests {
assert_eq!(filename_for(ShellArg::Fish), "wright.fish");
assert_eq!(filename_for(ShellArg::PowerShell), "_wright.ps1");
}

#[test]
fn generate_script_produces_non_empty_content_for_all_shells() {
for shell in [
ShellArg::Bash,
ShellArg::Zsh,
ShellArg::Fish,
ShellArg::PowerShell,
] {
let script = generate_script(shell);
assert!(!script.is_empty(), "{:?} script must not be empty", shell);
let text = String::from_utf8_lossy(&script);
assert!(
text.contains("wright"),
"{:?} script contains wright",
shell
);
}
}
}
135 changes: 21 additions & 114 deletions crates/wright-cli/src/present.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use std::io::{IsTerminal, Write};
use std::path::Path;
#[cfg(test)]
use std::sync::atomic::AtomicUsize;
use std::sync::{
Arc, Mutex,
atomic::{AtomicBool, Ordering},
Expand Down Expand Up @@ -60,8 +58,6 @@ pub(crate) struct Activity {
visible: Arc<AtomicBool>,
status: Arc<Mutex<Option<ProgressEvent>>>,
output: Arc<Mutex<()>>,
#[cfg(test)]
frame: Arc<AtomicUsize>,
handle: Option<thread::JoinHandle<()>>,
}

Expand All @@ -72,8 +68,6 @@ impl Activity {
visible: Arc::new(AtomicBool::new(false)),
status: Arc::new(Mutex::new(None)),
output: Arc::new(Mutex::new(())),
#[cfg(test)]
frame: Arc::new(AtomicUsize::new(0)),
handle: None,
}
}
Expand All @@ -83,24 +77,18 @@ impl Activity {
let visible = Arc::new(AtomicBool::new(false));
let status = Arc::new(Mutex::new(None));
let output = Arc::new(Mutex::new(()));
#[cfg(test)]
let frame = Arc::new(AtomicUsize::new(0));
write_activity_line(&output, &done, None, None);
visible.store(true, Ordering::Release);
let t_done = Arc::clone(&done);
let t_status = Arc::clone(&status);
let t_output = Arc::clone(&output);
#[cfg(test)]
let t_frame = Arc::clone(&frame);
let handle = thread::spawn(move || {
thread::sleep(Duration::from_millis(60));
let mut f = 0;
while !t_done.load(Ordering::Acquire) {
let event = *t_status.lock().expect("lock");
write_activity_line(&t_output, &t_done, event, Some(SPINNER[f]));
f = (f + 1) % SPINNER.len();
#[cfg(test)]
t_frame.store(f, Ordering::Release);
thread::sleep(Duration::from_millis(80));
}
});
Expand All @@ -109,8 +97,6 @@ impl Activity {
visible,
status,
output,
#[cfg(test)]
frame,
handle: Some(handle),
}
}
Expand Down Expand Up @@ -1360,47 +1346,6 @@ mod tests {
assert!(dumb.activity().handle.is_none());
}

#[test]
fn activity_is_visible_immediately_and_accepts_phase_updates() {
let terminal = Presentation::resolve(
OutputFormat::Text,
RendererArg::Terminal,
ColorArg::Never,
environment(),
);
let activity = terminal.activity();
assert!(activity.visible.load(Ordering::Acquire));
assert_eq!(*activity.status.lock().unwrap(), None);
activity.on_progress(ProgressEvent::with_count(
ProgressPhase::Linting,
12,
ProgressUnit::Rules,
));
assert_eq!(
*activity.status.lock().unwrap(),
Some(ProgressEvent::with_count(
ProgressPhase::Linting,
12,
ProgressUnit::Rules,
))
);
thread::sleep(Duration::from_millis(150));
assert!(activity.frame.load(Ordering::Acquire) > 0);
}

#[test]
fn activity_cleanup_clears_the_line_and_terminates_it() {
let mut output = Vec::new();
clear_activity_line(&mut output);
assert_eq!(output, b"\r\x1b[2K\r\n");
}

#[test]
fn metadata_is_dimmed_only_for_terminal_color_output() {
assert_eq!(dim("2 symbols", false), "2 symbols");
assert_eq!(dim("2 symbols", true), "\x1b[2m2 symbols\x1b[0m");
}

#[test]
fn workflow_command_escaping_is_split_by_context() {
assert_eq!(escape_workflow_property("a,b:c%\n"), "a%2Cb%3Ac%25%0A");
Expand Down Expand Up @@ -1457,40 +1402,27 @@ mod tests {
}

#[test]
fn summary_info_only_is_pass() {
let envelope = summary_envelope(
true,
vec![diagnostic(Severity::Info)],
serde_json::json!([
{"severity": "info"},
{"severity": "notice"}
]),
);
assert_eq!(summary_status(&envelope), "PASS");
}

#[test]
fn summary_warning_over_info_is_warn() {
let envelope = summary_envelope(
true,
vec![diagnostic(Severity::Warning)],
serde_json::json!([{"severity": "info"}]),
);
assert_eq!(summary_status(&envelope), "WARN");
}

#[test]
fn summary_error_over_warning_is_error() {
let envelope = summary_envelope(
true,
vec![diagnostic(Severity::Error)],
serde_json::json!([
{"severity": "warning"},
{"severity": "error"},
{"severity": "info"}
]),
);
assert_eq!(summary_status(&envelope), "ERROR");
fn summary_status_is_the_highest_severity_and_info_passes() {
for (diagnostic_severity, findings, expected) in [
(
Severity::Info,
serde_json::json!([{"severity": "info"}, {"severity": "notice"}]),
"PASS",
),
(
Severity::Warning,
serde_json::json!([{"severity": "info"}]),
"WARN",
),
(
Severity::Error,
serde_json::json!([{"severity": "warning"}, {"severity": "error"}]),
"ERROR",
),
] {
let envelope = summary_envelope(true, vec![diagnostic(diagnostic_severity)], findings);
assert_eq!(summary_status(&envelope), expected);
}
}

#[test]
Expand Down Expand Up @@ -1519,15 +1451,6 @@ mod tests {
assert_eq!(summary_status(&envelope), "FAIL");
}

#[test]
fn gate_counts_info_severity_for_fail_on_info() {
let mut envelope =
summary_envelope(true, Vec::new(), serde_json::json!([{"severity": "info"}]));
gate(&mut envelope, Severity::Info);
assert_eq!(envelope.exit, 1);
assert_eq!(summary_status(&envelope), "FAIL");
}

#[test]
fn gate_judges_the_full_set_not_the_selected_remainder() {
let mut envelope = check_envelope(
Expand Down Expand Up @@ -1585,15 +1508,6 @@ mod tests {
assert_eq!(summary_status(&envelope), "WARN");
}

#[test]
fn gate_leaves_a_clean_result_passing() {
let mut envelope = summary_envelope(true, Vec::new(), serde_json::json!([]));
gate(&mut envelope, Severity::Info);
assert!(!envelope.gated);
assert_eq!(envelope.exit, 0);
assert_eq!(summary_status(&envelope), "PASS");
}

#[test]
fn gate_reads_the_essential_projection_severity() {
let mut envelope = Envelope {
Expand Down Expand Up @@ -1693,13 +1607,6 @@ mod tests {
assert_eq!(result.metadata().unwrap(), "7 finding(s) across 2 rule(s)");
}

#[test]
fn severity_rank_orders_errors_first() {
assert_eq!(severity_rank(Severity::Error), 0);
assert_eq!(severity_rank(Severity::Warning), 1);
assert_eq!(severity_rank(Severity::Info), 2);
}

#[test]
fn finding_location_resolves_reported_paths_against_the_source_base() {
let root = std::env::temp_dir().join(format!("wright-finding-{}", std::process::id()));
Expand Down
27 changes: 0 additions & 27 deletions crates/wright-cli/tests/address_grammar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,33 +480,6 @@ fn unmatched_files_refuse_on_cli_and_serve() {
let _ = std::fs::remove_dir_all(Path::new(clean).parent().unwrap());
}

#[test]
fn name_addresses_ignore_snapshot() {
let path = temp_file("snapshot.ws", DUP_CALLERS);

let responses = serve(
&path,
&[
json!({"op":"cfg","rule":"tick#1","snapshot":999}).to_string(),
json!({"op":"cfg","rule":0,"snapshot":999}).to_string(),
json!({"op":"costEstimate","rule":"tick#1","snapshot":999}).to_string(),
],
);
assert!(
responses[0].get("error").is_none() && responses[0]["result"].is_object(),
"a name address ignores snapshot: {}",
responses[0]
);
assert_eq!(responses[1]["error"]["code"], "stale-id");
assert!(
responses[2].get("error").is_none() && responses[2]["result"].is_object(),
"costEstimate's name filter ignores snapshot: {}",
responses[2]
);

let _ = std::fs::remove_dir_all(path.parent().unwrap());
}

#[test]
fn cost_estimate_rule_uses_the_same_grammar() {
let path = temp_file("cost.ws", DUP_CALLERS);
Expand Down
Loading
Loading