Require explicit transition prompts
This commit is contained in:
@@ -26,3 +26,8 @@ pub const STATUS_RATE_SESSION: &str = "☑ rate antidrift session!";
|
|||||||
pub const STATUS_QUIT: &str = "antidrift shutting down";
|
pub const STATUS_QUIT: &str = "antidrift shutting down";
|
||||||
pub const STATUS_TRANSITION: &str = "↔ antidrift transition";
|
pub const STATUS_TRANSITION: &str = "↔ antidrift transition";
|
||||||
pub const SUCCESS_CONDITION_TITLE: &str = "Success Condition";
|
pub const SUCCESS_CONDITION_TITLE: &str = "Success Condition";
|
||||||
|
pub const TRANSITION_DURATION_TITLE: &str = "Transition Minutes";
|
||||||
|
pub const TRANSITION_REASON_TITLE: &str = "Transition Reason";
|
||||||
|
pub const TRANSITION_RETURN_TITLE: &str = "Return Target";
|
||||||
|
pub const PROVIDE_TRANSITION_REASON: &str = "Provide transition reason! ";
|
||||||
|
pub const PROVIDE_TRANSITION_RETURN: &str = "Provide return target! ";
|
||||||
|
|||||||
+266
-30
@@ -32,6 +32,9 @@ enum State {
|
|||||||
InputIntention,
|
InputIntention,
|
||||||
InputSuccessCondition,
|
InputSuccessCondition,
|
||||||
InputDuration,
|
InputDuration,
|
||||||
|
InputTransitionReason,
|
||||||
|
InputTransitionReturn,
|
||||||
|
InputTransitionDuration,
|
||||||
InProgress,
|
InProgress,
|
||||||
Paused,
|
Paused,
|
||||||
End,
|
End,
|
||||||
@@ -96,6 +99,9 @@ struct App {
|
|||||||
user_success_condition: String,
|
user_success_condition: String,
|
||||||
user_duration_str: String,
|
user_duration_str: String,
|
||||||
user_duration: Duration,
|
user_duration: Duration,
|
||||||
|
transition_reason: String,
|
||||||
|
transition_return_target: String,
|
||||||
|
transition_duration_str: String,
|
||||||
current_window_title: Rc<String>,
|
current_window_title: Rc<String>,
|
||||||
evidence_health: EvidenceHealth,
|
evidence_health: EvidenceHealth,
|
||||||
session_controller: SessionController,
|
session_controller: SessionController,
|
||||||
@@ -179,6 +185,9 @@ impl App {
|
|||||||
user_success_condition,
|
user_success_condition,
|
||||||
user_duration_str,
|
user_duration_str,
|
||||||
user_duration,
|
user_duration,
|
||||||
|
transition_reason: String::new(),
|
||||||
|
transition_return_target: String::new(),
|
||||||
|
transition_duration_str: "2".to_string(),
|
||||||
current_window_title: window_snapshot.title.into(),
|
current_window_title: window_snapshot.title.into(),
|
||||||
evidence_health: window_snapshot.health,
|
evidence_health: window_snapshot.health,
|
||||||
session_controller,
|
session_controller,
|
||||||
@@ -239,13 +248,40 @@ impl App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn pause(&mut self) -> Result<()> {
|
fn pause(&mut self) -> Result<()> {
|
||||||
if self.session_controller.runtime_state() == RuntimeState::Active {
|
self.transition_reason.clear();
|
||||||
self.session_controller.start_transition(
|
self.transition_return_target = self.user_intention.clone();
|
||||||
"legacy pause",
|
self.transition_duration_str = "2".to_string();
|
||||||
self.user_intention.clone(),
|
self.state = State::InputTransitionReason;
|
||||||
Duration::from_secs(60),
|
Ok(())
|
||||||
)?;
|
}
|
||||||
|
|
||||||
|
fn start_transition_if_valid(&mut self) -> Result<()> {
|
||||||
|
if self.transition_reason.trim().is_empty() {
|
||||||
|
self.state = State::InputTransitionReason;
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.transition_return_target.trim().is_empty() {
|
||||||
|
self.state = State::InputTransitionReturn;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let expected_duration = self
|
||||||
|
.transition_duration_str
|
||||||
|
.parse::<u64>()
|
||||||
|
.map(|minutes| Duration::from_secs(minutes * 60))
|
||||||
|
.unwrap_or(Duration::ZERO);
|
||||||
|
|
||||||
|
if expected_duration.is_zero() {
|
||||||
|
self.state = State::InputTransitionDuration;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
self.session_controller.start_transition(
|
||||||
|
self.transition_reason.clone(),
|
||||||
|
self.transition_return_target.clone(),
|
||||||
|
expected_duration,
|
||||||
|
)?;
|
||||||
self.state = State::Paused;
|
self.state = State::Paused;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -281,14 +317,17 @@ impl App {
|
|||||||
|
|
||||||
fn write_status(&self) {
|
fn write_status(&self) {
|
||||||
let status = match self.state {
|
let status = match self.state {
|
||||||
State::InputIntention | State::InputSuccessCondition | State::InputDuration => {
|
State::InputIntention
|
||||||
match self.session_controller.runtime_state() {
|
| State::InputSuccessCondition
|
||||||
RuntimeState::Locked => constants::STATUS_LOCKED.to_string(),
|
| State::InputDuration
|
||||||
RuntimeState::Planning => constants::STATUS_PLANNING.to_string(),
|
| State::InputTransitionReason
|
||||||
RuntimeState::Transition => constants::STATUS_TRANSITION.to_string(),
|
| State::InputTransitionReturn
|
||||||
_ => constants::STATUS_CONFIGURE.to_string(),
|
| State::InputTransitionDuration => match self.session_controller.runtime_state() {
|
||||||
}
|
RuntimeState::Locked => constants::STATUS_LOCKED.to_string(),
|
||||||
}
|
RuntimeState::Planning => constants::STATUS_PLANNING.to_string(),
|
||||||
|
RuntimeState::Transition => constants::STATUS_TRANSITION.to_string(),
|
||||||
|
_ => constants::STATUS_CONFIGURE.to_string(),
|
||||||
|
},
|
||||||
State::InProgress => format!(
|
State::InProgress => format!(
|
||||||
"🎯 {} - {}",
|
"🎯 {} - {}",
|
||||||
self.user_intention,
|
self.user_intention,
|
||||||
@@ -316,7 +355,12 @@ impl App {
|
|||||||
|
|
||||||
fn tick_50ms(&mut self) -> Result<()> {
|
fn tick_50ms(&mut self) -> Result<()> {
|
||||||
match self.state {
|
match self.state {
|
||||||
State::InputIntention | State::InputSuccessCondition | State::InputDuration => {
|
State::InputIntention
|
||||||
|
| State::InputSuccessCondition
|
||||||
|
| State::InputDuration
|
||||||
|
| State::InputTransitionReason
|
||||||
|
| State::InputTransitionReturn
|
||||||
|
| State::InputTransitionDuration => {
|
||||||
if let Ok(user_duration_mins) = self.user_duration_str.parse::<u64>() {
|
if let Ok(user_duration_mins) = self.user_duration_str.parse::<u64>() {
|
||||||
self.user_duration = Duration::from_secs(user_duration_mins * 60);
|
self.user_duration = Duration::from_secs(user_duration_mins * 60);
|
||||||
} else {
|
} else {
|
||||||
@@ -432,6 +476,15 @@ fn duration_as_str(duration: &Duration) -> String {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_transition_input_state(state: &State) -> bool {
|
||||||
|
matches!(
|
||||||
|
state,
|
||||||
|
State::InputTransitionReason
|
||||||
|
| State::InputTransitionReturn
|
||||||
|
| State::InputTransitionDuration
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn session_stats_as_vec(session_stats: &HashMap<Rc<String>, Duration>) -> Vec<SessionRating> {
|
fn session_stats_as_vec(session_stats: &HashMap<Rc<String>, Duration>) -> Vec<SessionRating> {
|
||||||
let mut stats: Vec<_> = session_stats
|
let mut stats: Vec<_> = session_stats
|
||||||
.iter()
|
.iter()
|
||||||
@@ -528,6 +581,39 @@ fn handle_events(app: &mut App) -> Result<()> {
|
|||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
|
State::InputTransitionReason => match key.code {
|
||||||
|
KeyCode::Enter => app.state = State::InputTransitionReturn,
|
||||||
|
KeyCode::Tab => app.state = State::InputTransitionReturn,
|
||||||
|
KeyCode::Backspace => {
|
||||||
|
let _ = app.transition_reason.pop();
|
||||||
|
}
|
||||||
|
KeyCode::Char(c) => {
|
||||||
|
app.transition_reason.push(c);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
State::InputTransitionReturn => match key.code {
|
||||||
|
KeyCode::Enter => app.state = State::InputTransitionDuration,
|
||||||
|
KeyCode::Tab => app.state = State::InputTransitionDuration,
|
||||||
|
KeyCode::Backspace => {
|
||||||
|
let _ = app.transition_return_target.pop();
|
||||||
|
}
|
||||||
|
KeyCode::Char(c) => {
|
||||||
|
app.transition_return_target.push(c);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
State::InputTransitionDuration => match key.code {
|
||||||
|
KeyCode::Enter => app.start_transition_if_valid()?,
|
||||||
|
KeyCode::Tab => app.state = State::InputTransitionReason,
|
||||||
|
KeyCode::Backspace => {
|
||||||
|
let _ = app.transition_duration_str.pop();
|
||||||
|
}
|
||||||
|
KeyCode::Char(c) if c.is_ascii_digit() => {
|
||||||
|
app.transition_duration_str.push(c);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
State::InProgress => match key.code {
|
State::InProgress => match key.code {
|
||||||
KeyCode::Char('q') => {
|
KeyCode::Char('q') => {
|
||||||
app.to_end()?;
|
app.to_end()?;
|
||||||
@@ -605,32 +691,54 @@ fn ui(frame: &mut Frame, app: &App) {
|
|||||||
let [layout_intention, layout_success_condition, layout_duration, layout_titles, layout_status] =
|
let [layout_intention, layout_success_condition, layout_duration, layout_titles, layout_status] =
|
||||||
layout.areas(frame.size());
|
layout.areas(frame.size());
|
||||||
|
|
||||||
let border_type_intention = if app.state == State::InputIntention {
|
let transition_input = is_transition_input_state(&app.state);
|
||||||
BorderType::Thick
|
|
||||||
|
let border_type_intention =
|
||||||
|
if app.state == State::InputIntention || app.state == State::InputTransitionReason {
|
||||||
|
BorderType::Thick
|
||||||
|
} else {
|
||||||
|
BorderType::Plain
|
||||||
|
};
|
||||||
|
let input_intention = if transition_input {
|
||||||
|
Line::from(Span::raw(&app.transition_reason))
|
||||||
} else {
|
} else {
|
||||||
BorderType::Plain
|
Line::from(Span::raw(&app.user_intention))
|
||||||
|
};
|
||||||
|
let intention_title = if transition_input {
|
||||||
|
constants::TRANSITION_REASON_TITLE
|
||||||
|
} else {
|
||||||
|
constants::INTENTION_TITLE
|
||||||
};
|
};
|
||||||
let input_intention = Line::from(Span::raw(&app.user_intention));
|
|
||||||
frame.render_widget(
|
frame.render_widget(
|
||||||
Paragraph::new(input_intention).block(
|
Paragraph::new(input_intention).block(
|
||||||
Block::bordered()
|
Block::bordered()
|
||||||
.border_type(border_type_intention)
|
.border_type(border_type_intention)
|
||||||
.title(constants::INTENTION_TITLE),
|
.title(intention_title),
|
||||||
),
|
),
|
||||||
layout_intention,
|
layout_intention,
|
||||||
);
|
);
|
||||||
|
|
||||||
let border_type_success_condition = if app.state == State::InputSuccessCondition {
|
let border_type_success_condition =
|
||||||
BorderType::Thick
|
if app.state == State::InputSuccessCondition || app.state == State::InputTransitionReturn {
|
||||||
|
BorderType::Thick
|
||||||
|
} else {
|
||||||
|
BorderType::Plain
|
||||||
|
};
|
||||||
|
let input_success_condition = if transition_input {
|
||||||
|
Line::from(Span::raw(&app.transition_return_target))
|
||||||
} else {
|
} else {
|
||||||
BorderType::Plain
|
Line::from(Span::raw(&app.user_success_condition))
|
||||||
|
};
|
||||||
|
let success_condition_title = if transition_input {
|
||||||
|
constants::TRANSITION_RETURN_TITLE
|
||||||
|
} else {
|
||||||
|
constants::SUCCESS_CONDITION_TITLE
|
||||||
};
|
};
|
||||||
let input_success_condition = Line::from(Span::raw(&app.user_success_condition));
|
|
||||||
frame.render_widget(
|
frame.render_widget(
|
||||||
Paragraph::new(input_success_condition).block(
|
Paragraph::new(input_success_condition).block(
|
||||||
Block::bordered()
|
Block::bordered()
|
||||||
.border_type(border_type_success_condition)
|
.border_type(border_type_success_condition)
|
||||||
.title(constants::SUCCESS_CONDITION_TITLE),
|
.title(success_condition_title),
|
||||||
),
|
),
|
||||||
layout_success_condition,
|
layout_success_condition,
|
||||||
);
|
);
|
||||||
@@ -640,20 +748,31 @@ fn ui(frame: &mut Frame, app: &App) {
|
|||||||
let s = duration_as_str(&app.session_remaining);
|
let s = duration_as_str(&app.session_remaining);
|
||||||
vec![Line::from(Span::raw(s))]
|
vec![Line::from(Span::raw(s))]
|
||||||
}
|
}
|
||||||
|
State::InputTransitionReason
|
||||||
|
| State::InputTransitionReturn
|
||||||
|
| State::InputTransitionDuration => {
|
||||||
|
vec![Line::from(Span::raw(&app.transition_duration_str))]
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
vec![Line::from(Span::raw(&app.user_duration_str))]
|
vec![Line::from(Span::raw(&app.user_duration_str))]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let border_type_duration = if app.state == State::InputDuration {
|
let border_type_duration =
|
||||||
BorderType::Thick
|
if app.state == State::InputDuration || app.state == State::InputTransitionDuration {
|
||||||
|
BorderType::Thick
|
||||||
|
} else {
|
||||||
|
BorderType::Plain
|
||||||
|
};
|
||||||
|
let duration_title = if transition_input {
|
||||||
|
constants::TRANSITION_DURATION_TITLE
|
||||||
} else {
|
} else {
|
||||||
BorderType::Plain
|
constants::DURATION_TITLE
|
||||||
};
|
};
|
||||||
frame.render_widget(
|
frame.render_widget(
|
||||||
Paragraph::new(input_duration).block(
|
Paragraph::new(input_duration).block(
|
||||||
Block::bordered()
|
Block::bordered()
|
||||||
.border_type(border_type_duration)
|
.border_type(border_type_duration)
|
||||||
.title(constants::DURATION_TITLE),
|
.title(duration_title),
|
||||||
),
|
),
|
||||||
layout_duration,
|
layout_duration,
|
||||||
);
|
);
|
||||||
@@ -677,7 +796,36 @@ fn ui(frame: &mut Frame, app: &App) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut spans: Vec<Span> = Vec::new();
|
let mut spans: Vec<Span> = Vec::new();
|
||||||
if app.user_intention.len() == 0 {
|
if transition_input {
|
||||||
|
if app.transition_reason.trim().is_empty() {
|
||||||
|
let span = Span::styled(
|
||||||
|
constants::PROVIDE_TRANSITION_REASON,
|
||||||
|
Style::new().fg(Color::LightRed),
|
||||||
|
);
|
||||||
|
spans.push(span);
|
||||||
|
}
|
||||||
|
|
||||||
|
if app.transition_return_target.trim().is_empty() {
|
||||||
|
let span = Span::styled(
|
||||||
|
constants::PROVIDE_TRANSITION_RETURN,
|
||||||
|
Style::new().fg(Color::LightRed),
|
||||||
|
);
|
||||||
|
spans.push(span);
|
||||||
|
}
|
||||||
|
|
||||||
|
let valid_transition_duration = app
|
||||||
|
.transition_duration_str
|
||||||
|
.parse::<u64>()
|
||||||
|
.map(|minutes| minutes > 0)
|
||||||
|
.unwrap_or(false);
|
||||||
|
if !valid_transition_duration {
|
||||||
|
let span = Span::styled(
|
||||||
|
constants::PROVIDE_VALID_DURATION,
|
||||||
|
Style::new().fg(Color::LightRed),
|
||||||
|
);
|
||||||
|
spans.push(span);
|
||||||
|
}
|
||||||
|
} else if app.user_intention.len() == 0 {
|
||||||
let span = Span::styled(
|
let span = Span::styled(
|
||||||
constants::PROVIDE_INTENTION,
|
constants::PROVIDE_INTENTION,
|
||||||
Style::new().fg(Color::LightRed),
|
Style::new().fg(Color::LightRed),
|
||||||
@@ -711,6 +859,9 @@ fn ui(frame: &mut Frame, app: &App) {
|
|||||||
spans.push(span);
|
spans.push(span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
State::InputTransitionReason
|
||||||
|
| State::InputTransitionReturn
|
||||||
|
| State::InputTransitionDuration => {}
|
||||||
State::InProgress => {
|
State::InProgress => {
|
||||||
let span = Span::styled(
|
let span = Span::styled(
|
||||||
constants::SESSION_IN_PROGRESS,
|
constants::SESSION_IN_PROGRESS,
|
||||||
@@ -843,6 +994,10 @@ mod tests {
|
|||||||
app.to_in_progress().unwrap();
|
app.to_in_progress().unwrap();
|
||||||
std::thread::sleep(Duration::from_millis(1200));
|
std::thread::sleep(Duration::from_millis(1200));
|
||||||
app.pause().unwrap();
|
app.pause().unwrap();
|
||||||
|
app.transition_reason = "stretch".to_string();
|
||||||
|
app.transition_return_target = "write tests".to_string();
|
||||||
|
app.transition_duration_str = "2".to_string();
|
||||||
|
app.start_transition_if_valid().unwrap();
|
||||||
std::thread::sleep(Duration::from_millis(2200));
|
std::thread::sleep(Duration::from_millis(2200));
|
||||||
app.resume().unwrap();
|
app.resume().unwrap();
|
||||||
}
|
}
|
||||||
@@ -871,6 +1026,10 @@ mod tests {
|
|||||||
app.to_in_progress().unwrap();
|
app.to_in_progress().unwrap();
|
||||||
std::thread::sleep(Duration::from_millis(1200));
|
std::thread::sleep(Duration::from_millis(1200));
|
||||||
app.pause().unwrap();
|
app.pause().unwrap();
|
||||||
|
app.transition_reason = "stretch".to_string();
|
||||||
|
app.transition_return_target = "write tests".to_string();
|
||||||
|
app.transition_duration_str = "2".to_string();
|
||||||
|
app.start_transition_if_valid().unwrap();
|
||||||
std::thread::sleep(Duration::from_millis(2200));
|
std::thread::sleep(Duration::from_millis(2200));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -900,6 +1059,10 @@ mod tests {
|
|||||||
app.user_duration_str = "1".to_string();
|
app.user_duration_str = "1".to_string();
|
||||||
app.to_in_progress().unwrap();
|
app.to_in_progress().unwrap();
|
||||||
app.pause().unwrap();
|
app.pause().unwrap();
|
||||||
|
app.transition_reason = "stretch".to_string();
|
||||||
|
app.transition_return_target = "write tests".to_string();
|
||||||
|
app.transition_duration_str = "2".to_string();
|
||||||
|
app.start_transition_if_valid().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut app = App::new_with_event_log_path(&path).unwrap();
|
let mut app = App::new_with_event_log_path(&path).unwrap();
|
||||||
@@ -926,4 +1089,77 @@ mod tests {
|
|||||||
|
|
||||||
let _ = fs::remove_file(path);
|
let _ = fs::remove_file(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pause_from_in_progress_opens_transition_reason_without_starting_controller_transition() {
|
||||||
|
let path = unique_event_log_path("transition-prompt");
|
||||||
|
let mut app = App::new_with_event_log_path(&path).unwrap();
|
||||||
|
|
||||||
|
app.user_intention = "write tests".to_string();
|
||||||
|
app.user_success_condition = "tests pass".to_string();
|
||||||
|
app.user_duration_str = "1".to_string();
|
||||||
|
app.to_in_progress().unwrap();
|
||||||
|
|
||||||
|
app.pause().unwrap();
|
||||||
|
|
||||||
|
assert_eq!(app.state, State::InputTransitionReason);
|
||||||
|
assert_eq!(app.session_controller.runtime_state(), RuntimeState::Active);
|
||||||
|
assert_eq!(app.transition_reason, "");
|
||||||
|
assert_eq!(app.transition_return_target, "write tests");
|
||||||
|
assert_eq!(app.transition_duration_str, "2");
|
||||||
|
|
||||||
|
let _ = fs::remove_file(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn valid_transition_inputs_enter_paused_and_start_controller_transition() {
|
||||||
|
let path = unique_event_log_path("valid-transition-inputs");
|
||||||
|
let mut app = App::new_with_event_log_path(&path).unwrap();
|
||||||
|
|
||||||
|
app.user_intention = "write tests".to_string();
|
||||||
|
app.user_success_condition = "tests pass".to_string();
|
||||||
|
app.user_duration_str = "1".to_string();
|
||||||
|
app.to_in_progress().unwrap();
|
||||||
|
app.pause().unwrap();
|
||||||
|
|
||||||
|
app.transition_reason = "stretch".to_string();
|
||||||
|
app.transition_return_target = "write tests".to_string();
|
||||||
|
app.transition_duration_str = "3".to_string();
|
||||||
|
app.start_transition_if_valid().unwrap();
|
||||||
|
|
||||||
|
assert_eq!(app.state, State::Paused);
|
||||||
|
assert_eq!(
|
||||||
|
app.session_controller.runtime_state(),
|
||||||
|
RuntimeState::Transition
|
||||||
|
);
|
||||||
|
|
||||||
|
let _ = fs::remove_file(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn missing_transition_reason_or_return_target_does_not_start_transition() {
|
||||||
|
let path = unique_event_log_path("invalid-transition-inputs");
|
||||||
|
let mut app = App::new_with_event_log_path(&path).unwrap();
|
||||||
|
|
||||||
|
app.user_intention = "write tests".to_string();
|
||||||
|
app.user_success_condition = "tests pass".to_string();
|
||||||
|
app.user_duration_str = "1".to_string();
|
||||||
|
app.to_in_progress().unwrap();
|
||||||
|
app.pause().unwrap();
|
||||||
|
|
||||||
|
app.transition_reason = "".to_string();
|
||||||
|
app.transition_return_target = "write tests".to_string();
|
||||||
|
app.transition_duration_str = "3".to_string();
|
||||||
|
app.start_transition_if_valid().unwrap();
|
||||||
|
assert_eq!(app.state, State::InputTransitionReason);
|
||||||
|
assert_eq!(app.session_controller.runtime_state(), RuntimeState::Active);
|
||||||
|
|
||||||
|
app.transition_reason = "stretch".to_string();
|
||||||
|
app.transition_return_target = "".to_string();
|
||||||
|
app.start_transition_if_valid().unwrap();
|
||||||
|
assert_eq!(app.state, State::InputTransitionReturn);
|
||||||
|
assert_eq!(app.session_controller.runtime_state(), RuntimeState::Active);
|
||||||
|
|
||||||
|
let _ = fs::remove_file(path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user