diffr_plugin_test_bodies/
lib.rs1use diffr_plugin_sdk::{
3 anyhow, docstring_of, export, has_tag, is_fold, line_count, walk, Draft, FileEntry, Move,
4 Pairing, Plugin, Source,
5};
6use serde::Deserialize;
7use std::collections::BTreeMap;
8
9const PLUGIN: &str = "test-bodies";
12const TEST: &str = "test-bodies:test";
13const MODULE: &str = "test-bodies:module";
14
15#[derive(Deserialize)]
16#[serde(deny_unknown_fields)]
17pub struct Options {
18 min_lines: usize,
19}
20
21pub struct TestBodies {
28 options: Options,
29}
30
31impl Plugin for TestBodies {
32 type Options = Options;
33
34 fn new(options: Options) -> anyhow::Result<Self> {
35 Ok(Self { options })
36 }
37
38 fn queries(&self) -> anyhow::Result<Vec<diffr_plugin_sdk::QuerySource>> {
39 Ok(vec![
40 diffr_plugin_sdk::QuerySource {
41 language: "rust".into(),
42 name: "builtin:test-bodies/queries/rust.scm".into(),
43 text: include_str!("../queries/rust.scm").into(),
44 },
45 diffr_plugin_sdk::QuerySource {
46 language: "python".into(),
47 name: "builtin:test-bodies/queries/python.scm".into(),
48 text: include_str!("../queries/python.scm").into(),
49 },
50 diffr_plugin_sdk::QuerySource {
51 language: "go".into(),
52 name: "builtin:test-bodies/queries/go.scm".into(),
53 text: include_str!("../queries/go.scm").into(),
54 },
55 diffr_plugin_sdk::QuerySource {
56 language: "javascript".into(),
57 name: "builtin:test-bodies/queries/javascript.scm".into(),
58 text: include_str!("../queries/javascript.scm").into(),
59 },
60 diffr_plugin_sdk::QuerySource {
61 language: "javascriptjsx".into(),
62 name: "builtin:test-bodies/queries/javascript.scm".into(),
63 text: include_str!("../queries/javascript.scm").into(),
64 },
65 diffr_plugin_sdk::QuerySource {
66 language: "typescript".into(),
67 name: "builtin:test-bodies/queries/javascript.scm".into(),
68 text: include_str!("../queries/javascript.scm").into(),
69 },
70 diffr_plugin_sdk::QuerySource {
71 language: "typescripttsx".into(),
72 name: "builtin:test-bodies/queries/javascript.scm".into(),
73 text: include_str!("../queries/javascript.scm").into(),
74 },
75 ])
76 }
77
78 fn classify(&self, _file: &FileEntry) -> anyhow::Result<Vec<String>> {
79 Ok(Vec::new())
80 }
81
82 fn mutate(&self, _file: &FileEntry, sides: &Pairing<Source>) -> anyhow::Result<Vec<Move>> {
83 let options = &self.options;
84 let mut labels: BTreeMap<u32, (String, Option<u32>)> = BTreeMap::new();
88 for source in sides.sides() {
89 walk(&source.regions, &mut |region| {
90 if !is_fold(region) || line_count(region) < options.min_lines {
91 return;
92 }
93 if has_tag(region, MODULE) {
94 labels.insert(
95 region.id,
96 (
97 if region.visibility.label.is_empty() {
98 "test module".to_owned()
99 } else {
100 region.visibility.label.clone()
101 },
102 None,
103 ),
104 );
105 } else if has_tag(region, TEST) {
106 labels.entry(region.id).or_insert((
107 if region.visibility.label.is_empty() {
108 "test body".to_owned()
109 } else {
110 region.visibility.label.clone()
111 },
112 docstring_of(source, region, PLUGIN),
113 ));
114 }
115 });
116 }
117 let mut draft = Draft::new(sides);
118 for (id, (label, docstring)) in labels {
119 draft.collapse(id, label.to_owned())?;
120 if let Some(docstring) = docstring {
121 draft.link(&[id, docstring])?;
122 }
123 }
124 Ok(draft.into_moves())
125 }
126}
127
128export!("test-bodies", TestBodies);