1use proptest::prelude::*;
2
3use super::*;
4
5#[derive(Debug, Clone, proptest_derive::Arbitrary)]
6pub enum Direction {
7 Up,
8 Down,
9 Left,
10 Right,
11}
12
13#[derive(Debug, Clone, proptest_derive::Arbitrary)]
14pub enum TestAction {
15 #[proptest(weight = 4)]
16 Type(String),
17 Backspace {
18 #[proptest(strategy = "1usize..100")]
19 count: usize,
20 },
21 Move {
22 #[proptest(strategy = "1usize..100")]
23 count: usize,
24 direction: Direction,
25 },
26}
27
28impl Editor {
29 pub fn apply_test_action(
30 &mut self,
31 action: &TestAction,
32 window: &mut Window,
33 cx: &mut Context<Self>,
34 ) {
35 match action {
36 TestAction::Type(text) => self.insert(&text, window, cx),
37 TestAction::Backspace { count } => {
38 for _ in 0..*count {
39 self.delete(&Default::default(), window, cx);
40 }
41 }
42 TestAction::Move { count, direction } => {
43 for _ in 0..*count {
44 match direction {
45 Direction::Up => self.move_up(&Default::default(), window, cx),
46 Direction::Down => self.move_down(&Default::default(), window, cx),
47 Direction::Left => self.move_left(&Default::default(), window, cx),
48 Direction::Right => self.move_right(&Default::default(), window, cx),
49 }
50 }
51 }
52 }
53 }
54}
55
56fn test_actions() -> impl Strategy<Value = Vec<TestAction>> {
57 proptest::collection::vec(any::<TestAction>(), 1..10)
58}
59
60#[gpui::property_test(config = ProptestConfig {cases: 100, ..Default::default()})]
61fn editor_property_test(
62 cx: &mut TestAppContext,
63 #[strategy = test_actions()] actions: Vec<TestAction>,
64) {
65 init_test(cx, |_| {});
66
67 let group_interval = Duration::from_millis(1);
68
69 let buffer = cx.new(|cx| {
70 let mut buf = language::Buffer::local("123456", cx);
71 buf.set_group_interval(group_interval);
72 buf
73 });
74
75 let buffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx));
76 let editor = cx.add_window(|window, cx| build_editor(buffer.clone(), window, cx));
77
78 editor
79 .update(cx, |editor, window, cx| {
80 for action in actions {
81 editor.apply_test_action(&action, window, cx);
82 }
83 })
84 .unwrap();
85}