mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
Merge c4fe9b6b4b
into 3890e12c9e
This commit is contained in:
commit
d5de0a5ebb
2 changed files with 65 additions and 4 deletions
|
@ -184,17 +184,34 @@ impl CardQueues {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return the current due counts. If there are no due cards, the learning
|
||||
/// cutoff is updated to the current time first, and any newly-due learning
|
||||
/// cards are added to the counts.
|
||||
/// Return the current due counts. If there are no due cards or if learning
|
||||
/// cards have become due since the last cutoff update, the learning cutoff
|
||||
/// is updated to the current time first, and any newly-due learning cards
|
||||
/// are added to the counts.
|
||||
pub(crate) fn counts(&mut self) -> Counts {
|
||||
if self.counts.all_zero() {
|
||||
if self.counts.all_zero() || self.has_newly_due_learning_cards() {
|
||||
// we discard the returned undo information in this case
|
||||
self.update_learning_cutoff_and_count();
|
||||
}
|
||||
self.counts
|
||||
}
|
||||
|
||||
/// Check if any learning cards have become due since the last cutoff
|
||||
/// update.
|
||||
fn has_newly_due_learning_cards(&self) -> bool {
|
||||
let current_cutoff = self.current_learning_cutoff;
|
||||
let now = TimestampSecs::now();
|
||||
|
||||
if now <= current_cutoff {
|
||||
return false;
|
||||
}
|
||||
|
||||
let new_ahead_cutoff = now.adding_secs(self.learn_ahead_secs);
|
||||
self.intraday_learning
|
||||
.iter()
|
||||
.any(|e| e.due > current_cutoff && e.due <= new_ahead_cutoff)
|
||||
}
|
||||
|
||||
fn is_stale(&self, current_day: u32) -> bool {
|
||||
self.current_day != current_day
|
||||
}
|
||||
|
|
|
@ -290,4 +290,48 @@ mod test {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn learning_cards_become_due_after_counts_cached() -> Result<()> {
|
||||
use crate::scheduler::queue::learning::LearningQueueEntry;
|
||||
|
||||
let mut col = Collection::new();
|
||||
if col.timing_today()?.near_cutoff() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Add a note with learning cards
|
||||
add_note(&mut col, true)?;
|
||||
|
||||
// Answer to put a card into learning state
|
||||
col.answer_again();
|
||||
assert_eq!(col.counts(), [1, 1, 0]);
|
||||
|
||||
// Get the current queues to cache the counts
|
||||
let queues = col.get_queues()?;
|
||||
let old_cutoff = queues.current_learning_cutoff;
|
||||
|
||||
// Manually add a learning card that would be due now but wasn't
|
||||
// when the cutoff was set (simulating time passing)
|
||||
let now = crate::timestamp::TimestampSecs::now();
|
||||
let new_entry = LearningQueueEntry {
|
||||
due: now, // due right now
|
||||
id: CardId(999), // fake ID
|
||||
mtime: now,
|
||||
};
|
||||
|
||||
// Insert the entry directly into the queue to simulate the bug scenario
|
||||
let queues = col.state.card_queues.as_mut().unwrap();
|
||||
queues.intraday_learning.push_back(new_entry);
|
||||
|
||||
// The old logic would not detect this newly due card because
|
||||
// counts() only checked all_zero(), but our fix should detect it
|
||||
let _updated_counts = queues.counts();
|
||||
|
||||
// The important thing is that update_learning_cutoff_and_count was called,
|
||||
// which our fix should trigger. This updates the cutoff to the current time.
|
||||
assert!(queues.current_learning_cutoff >= old_cutoff);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue