From a3f0087b11d6ab5faebbb68f37e8dc1231c8f1e4 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 5 Mar 2020 13:04:49 -0800 Subject: [PATCH] Start work on tagging unit test Co-Authored-By: Patrick Thomson --- cli/src/tests/mod.rs | 1 + cli/src/tests/tags_test.rs | 56 ++++++++++++++++++++++++++++++++++++++ tags/src/lib.rs | 32 ++++++++++++++++------ 3 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 cli/src/tests/tags_test.rs diff --git a/cli/src/tests/mod.rs b/cli/src/tests/mod.rs index 0ccb0ae0..ac54db00 100644 --- a/cli/src/tests/mod.rs +++ b/cli/src/tests/mod.rs @@ -4,5 +4,6 @@ mod highlight_test; mod node_test; mod parser_test; mod query_test; +mod tags_test; mod test_highlight_test; mod tree_test; diff --git a/cli/src/tests/tags_test.rs b/cli/src/tests/tags_test.rs new file mode 100644 index 00000000..e9ad908c --- /dev/null +++ b/cli/src/tests/tags_test.rs @@ -0,0 +1,56 @@ +use super::helpers::fixtures::get_language; +use tree_sitter_tags::{TagKind, TagsConfiguration, TagsContext}; + +#[test] +fn test_tags_javascript() { + let language = get_language("python"); + let tags_config = TagsConfiguration::new( + language, + r#" + ((function_definition + name: (identifier) @name + body: (block + . (string) @doc)) @function + (set! replace @doc "(^['\s]*)|(['\s]*$)")) + + (function_definition + name: (identifier) @name) @function + (class_definition + name: (identifier) @name) @class + (call + function: (identifier) @name) @call + "#, + "", + ) + .unwrap(); + + let mut tag_context = TagsContext::new(); + let tags = tag_context.generate_tags( + &tags_config, + br#" + class Customer: + """ + Data about a customer + """ + + def age(self): + """ + Get the customer's age + """ + compute_age(self.id); + } + "#, + ); + + assert_eq!( + tags.iter().map(|t| (t.name, t.kind)).collect::>(), + &[ + ("Customer", TagKind::Class), + ("age", TagKind::Function), + ("compute_age", TagKind::Call), + ] + ); + + assert_eq!(tags[0].docs, Some("Data about a customer")); + assert_eq!(tags[1].docs, Some("Get the customer's age")); +} diff --git a/tags/src/lib.rs b/tags/src/lib.rs index 64e79020..bc4f8e9a 100644 --- a/tags/src/lib.rs +++ b/tags/src/lib.rs @@ -14,30 +14,31 @@ pub struct TagsContext { cursor: QueryCursor, } -#[derive(Serialize)] +#[derive(Debug, Serialize)] pub struct Range { pub start: i64, pub end: i64, } -#[derive(Serialize)] +#[derive(Debug, Serialize)] pub struct Loc { pub byte_range: Range, pub span: Span, } -#[derive(Serialize)] +#[derive(Debug, Serialize)] pub struct Span { pub start: Pos, pub end: Pos, } -#[derive(Serialize)] +#[derive(Debug, Serialize)] pub struct Pos { pub line: i64, pub column: i64, } +#[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum TagKind { Function, Method, @@ -46,7 +47,7 @@ pub enum TagKind { Call, } -#[derive(Serialize)] +#[derive(Debug, Serialize)] pub struct Tag<'a> { pub kind: TagKind, pub loc: Loc, @@ -88,8 +89,6 @@ impl TagsConfiguration { } } - query.pattern_count(); - query.start_byte_for_pattern(5); Ok(TagsConfiguration { language, query, @@ -107,6 +106,23 @@ impl TagsContext { } pub fn generate_tags(&mut self, config: &TagsConfiguration, source: &[u8]) -> Vec { - Vec::new() + self.parser + .set_language(config.language) + .expect("Incompatible language"); + let tree = self + .parser + .parse(source, None) + .expect("Parsing failed unexpectedly"); + let matches = self + .cursor + .matches(&config.query, tree.root_node(), |node| { + &source[node.byte_range()] + }); + matches + .map(|mat| { + for capture in mat.captures {} + unimplemented!(); + }) + .collect() } }