property_test.rs

 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}