Separate walk_with_properties tests from parser tests
This commit is contained in:
parent
6ca1047bb0
commit
f263a4fbe3
5 changed files with 145 additions and 200 deletions
|
|
@ -95,7 +95,7 @@ fn run() -> error::Result<()> {
|
|||
state_ids_to_log,
|
||||
)?;
|
||||
}
|
||||
properties::generate_property_sheets(¤t_dir)?;
|
||||
properties::generate_property_sheets_in_directory(¤t_dir)?;
|
||||
} else if let Some(matches) = matches.subcommand_matches("test") {
|
||||
let debug = matches.is_present("debug");
|
||||
let debug_graph = matches.is_present("debug-graph");
|
||||
|
|
|
|||
|
|
@ -421,7 +421,7 @@ impl fmt::Debug for Selector {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn generate_property_sheets(repo_path: &Path) -> Result<()> {
|
||||
pub fn generate_property_sheets_in_directory(repo_path: &Path) -> Result<()> {
|
||||
let src_dir_path = repo_path.join("src");
|
||||
let properties_dir_path = repo_path.join("properties");
|
||||
|
||||
|
|
@ -443,6 +443,11 @@ pub fn generate_property_sheets(repo_path: &Path) -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn generate_property_sheet_string(path: impl AsRef<Path>, css: &str) -> Result<String> {
|
||||
let sheet = generate_property_sheet(path, css)?;
|
||||
Ok(serde_json::to_string(&sheet)?)
|
||||
}
|
||||
|
||||
fn generate_property_sheet(path: impl AsRef<Path>, css: &str) -> Result<PropertySheetJSON> {
|
||||
let rules = parse_property_sheet(path.as_ref(), &css)?;
|
||||
Ok(Builder::new(rules).build())
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
mod corpus_test;
|
||||
mod helpers;
|
||||
mod parser_api_test;
|
||||
mod parser_test;
|
||||
mod properties_test;
|
||||
mod tree_test;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
use super::helpers::fixtures::get_language;
|
||||
use serde_derive::Deserialize;
|
||||
use std::thread;
|
||||
use tree_sitter::{InputEdit, Language, LogType, Parser, Point, PropertySheet};
|
||||
use tree_sitter::{InputEdit, Language, LogType, Parser, Point};
|
||||
|
||||
#[test]
|
||||
fn test_basic_parsing() {
|
||||
|
|
@ -93,200 +92,6 @@ fn test_tree_cursor() {
|
|||
assert_eq!(cursor.node().is_named(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tree_property_matching() {
|
||||
let mut parser = Parser::new();
|
||||
parser.set_language(rust()).unwrap();
|
||||
let source_code = "fn f1() { f2(); }";
|
||||
let tree = parser.parse_str(source_code, None).unwrap();
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq)]
|
||||
struct Properties {
|
||||
reference: Option<String>,
|
||||
define: Option<String>,
|
||||
}
|
||||
|
||||
let empty_properties = Properties {
|
||||
reference: None,
|
||||
define: None,
|
||||
};
|
||||
|
||||
let property_sheet = PropertySheet::<Properties>::new(
|
||||
rust(),
|
||||
r##"
|
||||
{
|
||||
"states": [
|
||||
{
|
||||
"transitions": [
|
||||
{"type": "call_expression", "named": true, "state_id": 1},
|
||||
{"type": "function_item", "named": true, "state_id": 2}
|
||||
],
|
||||
"default_next_state_id": 0,
|
||||
"property_set_id": 0
|
||||
},
|
||||
{
|
||||
"transitions": [
|
||||
{"type": "identifier", "named": true, "state_id": 3}
|
||||
],
|
||||
"default_next_state_id": 0,
|
||||
"property_set_id": 0
|
||||
},
|
||||
{
|
||||
"transitions": [
|
||||
{"type": "identifier", "named": true, "state_id": 4}
|
||||
],
|
||||
"default_next_state_id": 0,
|
||||
"property_set_id": 0
|
||||
},
|
||||
{
|
||||
"transitions": [],
|
||||
"default_next_state_id": 0,
|
||||
"property_set_id": 1
|
||||
},
|
||||
{
|
||||
"transitions": [],
|
||||
"default_next_state_id": 0,
|
||||
"property_set_id": 2
|
||||
}
|
||||
],
|
||||
"property_sets": [
|
||||
{},
|
||||
{"reference": "function"},
|
||||
{"define": "function"}
|
||||
]
|
||||
}
|
||||
"##,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut cursor = tree.walk_with_properties(&property_sheet, source_code);
|
||||
assert_eq!(cursor.node().kind(), "source_file");
|
||||
assert_eq!(*cursor.node_properties(), empty_properties);
|
||||
|
||||
assert!(cursor.goto_first_child());
|
||||
assert_eq!(cursor.node().kind(), "function_item");
|
||||
assert_eq!(*cursor.node_properties(), empty_properties);
|
||||
|
||||
assert!(cursor.goto_first_child());
|
||||
assert_eq!(cursor.node().kind(), "fn");
|
||||
assert_eq!(*cursor.node_properties(), empty_properties);
|
||||
assert!(!cursor.goto_first_child());
|
||||
|
||||
assert!(cursor.goto_next_sibling());
|
||||
assert_eq!(cursor.node().kind(), "identifier");
|
||||
assert_eq!(cursor.node_properties().define, Some("function".to_owned()));
|
||||
assert!(!cursor.goto_first_child());
|
||||
|
||||
assert!(cursor.goto_next_sibling());
|
||||
assert_eq!(cursor.node().kind(), "parameters");
|
||||
assert_eq!(*cursor.node_properties(), empty_properties);
|
||||
|
||||
assert!(cursor.goto_first_child());
|
||||
assert_eq!(cursor.node().kind(), "(");
|
||||
assert!(cursor.goto_next_sibling());
|
||||
assert_eq!(cursor.node().kind(), ")");
|
||||
assert_eq!(*cursor.node_properties(), empty_properties);
|
||||
|
||||
assert!(cursor.goto_parent());
|
||||
assert!(cursor.goto_next_sibling());
|
||||
assert_eq!(cursor.node().kind(), "block");
|
||||
assert_eq!(*cursor.node_properties(), empty_properties);
|
||||
|
||||
assert!(cursor.goto_first_child());
|
||||
assert!(cursor.goto_next_sibling());
|
||||
assert_eq!(cursor.node().kind(), "call_expression");
|
||||
assert_eq!(*cursor.node_properties(), empty_properties);
|
||||
|
||||
assert!(cursor.goto_first_child());
|
||||
assert_eq!(cursor.node().kind(), "identifier");
|
||||
assert_eq!(
|
||||
cursor.node_properties().reference,
|
||||
Some("function".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tree_property_matching_with_regexes() {
|
||||
let mut parser = Parser::new();
|
||||
parser.set_language(rust()).unwrap();
|
||||
let source_code = "fn f1() { None(a()) }";
|
||||
let tree = parser.parse_str(source_code, None).unwrap();
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq)]
|
||||
struct Properties {
|
||||
scope: Option<String>,
|
||||
}
|
||||
|
||||
let empty_properties = Properties { scope: None };
|
||||
|
||||
let property_sheet = PropertySheet::<Properties>::new(
|
||||
rust(),
|
||||
r##"
|
||||
{
|
||||
"states": [
|
||||
{
|
||||
"id": 0,
|
||||
"transitions": [
|
||||
{"type": "call_expression", "named": true, "state_id": 1}
|
||||
],
|
||||
"default_next_state_id": 0,
|
||||
"property_set_id": 0
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"transitions": [
|
||||
{"type": "identifier", "named": true, "text": "^[A-Z]", "state_id": 2},
|
||||
{"type": "identifier", "named": true, "state_id": 3}
|
||||
],
|
||||
"default_next_state_id": 0,
|
||||
"property_set_id": 0
|
||||
},
|
||||
{
|
||||
"transitions": [],
|
||||
"default_next_state_id": 0,
|
||||
"property_set_id": 1
|
||||
},
|
||||
{
|
||||
"transitions": [],
|
||||
"default_next_state_id": 0,
|
||||
"property_set_id": 2
|
||||
}
|
||||
],
|
||||
"property_sets": [
|
||||
{},
|
||||
{"scope": "constructor"},
|
||||
{"scope": "function"}
|
||||
]
|
||||
}
|
||||
"##,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut cursor = tree.walk_with_properties(&property_sheet, source_code);
|
||||
assert_eq!(cursor.node().kind(), "source_file");
|
||||
assert_eq!(*cursor.node_properties(), empty_properties);
|
||||
|
||||
cursor.goto_first_child();
|
||||
assert!(cursor.goto_first_child());
|
||||
assert!(cursor.goto_next_sibling());
|
||||
assert!(cursor.goto_next_sibling());
|
||||
assert!(cursor.goto_next_sibling());
|
||||
assert_eq!(cursor.node().kind(), "block");
|
||||
assert_eq!(*cursor.node_properties(), empty_properties);
|
||||
|
||||
assert!(cursor.goto_first_child());
|
||||
assert!(cursor.goto_next_sibling());
|
||||
assert_eq!(cursor.node().kind(), "call_expression");
|
||||
assert_eq!(*cursor.node_properties(), empty_properties);
|
||||
|
||||
assert!(cursor.goto_first_child());
|
||||
assert_eq!(cursor.node().kind(), "identifier");
|
||||
assert_eq!(
|
||||
cursor.node_properties().scope,
|
||||
Some("constructor".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_custom_utf8_input() {
|
||||
let mut parser = Parser::new();
|
||||
|
|
@ -454,7 +259,7 @@ fn test_editing() {
|
|||
fn test_parallel_parsing() {
|
||||
// Parse this source file so that each thread has a non-trivial amount of
|
||||
// work to do.
|
||||
let this_file_source = include_str!("parser_api_test.rs");
|
||||
let this_file_source = include_str!("parser_test.rs");
|
||||
|
||||
let mut parser = Parser::new();
|
||||
parser.set_language(rust()).unwrap();
|
||||
134
cli/src/tests/properties_test.rs
Normal file
134
cli/src/tests/properties_test.rs
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
use super::helpers::fixtures::get_language;
|
||||
use crate::properties;
|
||||
use serde_derive::Deserialize;
|
||||
use tree_sitter::{Parser, PropertySheet};
|
||||
|
||||
#[derive(Debug, Default, Deserialize, PartialEq, Eq)]
|
||||
struct Properties {
|
||||
a: Option<String>,
|
||||
b: Option<String>,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_walk_with_properties_with_nth_child() {
|
||||
let language = get_language("javascript");
|
||||
let property_sheet = PropertySheet::<Properties>::new(
|
||||
language,
|
||||
&properties::generate_property_sheet_string(
|
||||
"/some/path.css",
|
||||
"
|
||||
binary_expression > identifier:nth-child(2) {
|
||||
a: x;
|
||||
}
|
||||
|
||||
binary_expression > identifier {
|
||||
a: y;
|
||||
}
|
||||
|
||||
identifier {
|
||||
a: z;
|
||||
}
|
||||
",
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let source_code = "a = b || c;";
|
||||
|
||||
let mut parser = Parser::new();
|
||||
parser.set_language(language).unwrap();
|
||||
let tree = parser.parse_str(source_code, None).unwrap();
|
||||
|
||||
let mut cursor = tree.walk_with_properties(&property_sheet, source_code);
|
||||
assert_eq!(cursor.node().kind(), "program");
|
||||
assert!(cursor.goto_first_child());
|
||||
assert_eq!(cursor.node().kind(), "expression_statement");
|
||||
assert!(cursor.goto_first_child());
|
||||
assert_eq!(cursor.node().kind(), "assignment_expression");
|
||||
|
||||
assert!(cursor.goto_first_child());
|
||||
assert_eq!(cursor.node().kind(), "identifier");
|
||||
assert_eq!(*cursor.node_properties(), Properties { a: Some("z".to_string()), b: None });
|
||||
|
||||
assert!(cursor.goto_next_sibling());
|
||||
assert_eq!(cursor.node().kind(), "=");
|
||||
assert!(cursor.goto_next_sibling());
|
||||
assert_eq!(cursor.node().kind(), "binary_expression");
|
||||
|
||||
assert!(cursor.goto_first_child());
|
||||
assert_eq!(cursor.node().kind(), "identifier");
|
||||
assert_eq!(*cursor.node_properties(), Properties { a: Some("y".to_string()), b: None });
|
||||
|
||||
assert!(cursor.goto_next_sibling());
|
||||
assert_eq!(cursor.node().kind(), "||");
|
||||
assert!(cursor.goto_next_sibling());
|
||||
assert_eq!(cursor.node().kind(), "identifier");
|
||||
assert_eq!(*cursor.node_properties(), Properties { a: Some("x".to_string()), b: None });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_walk_with_properties_with_regexes() {
|
||||
let language = get_language("javascript");
|
||||
let property_sheet = PropertySheet::<Properties>::new(
|
||||
language,
|
||||
&properties::generate_property_sheet_string(
|
||||
"/some/path.css",
|
||||
"
|
||||
identifier {
|
||||
&[text='^[A-Z]'] {
|
||||
a: y;
|
||||
}
|
||||
|
||||
&[text='^[A-Z_]+$'] {
|
||||
a: z;
|
||||
}
|
||||
|
||||
a: x;
|
||||
}
|
||||
",
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let source_code = "const ABC = Def(ghi);";
|
||||
|
||||
let mut parser = Parser::new();
|
||||
parser.set_language(language).unwrap();
|
||||
let tree = parser.parse_str(source_code, None).unwrap();
|
||||
|
||||
let mut cursor = tree.walk_with_properties(&property_sheet, source_code);
|
||||
assert_eq!(cursor.node().kind(), "program");
|
||||
assert!(cursor.goto_first_child());
|
||||
assert_eq!(cursor.node().kind(), "lexical_declaration");
|
||||
assert!(cursor.goto_first_child());
|
||||
assert_eq!(cursor.node().kind(), "const");
|
||||
assert!(cursor.goto_next_sibling());
|
||||
assert_eq!(cursor.node().kind(), "variable_declarator");
|
||||
|
||||
// The later selector with a text regex overrides the earlier one.
|
||||
assert!(cursor.goto_first_child());
|
||||
assert_eq!(cursor.node().kind(), "identifier");
|
||||
assert_eq!(*cursor.node_properties(), Properties { a: Some("z".to_string()), b: None });
|
||||
|
||||
assert!(cursor.goto_next_sibling());
|
||||
assert_eq!(cursor.node().kind(), "=");
|
||||
assert!(cursor.goto_next_sibling());
|
||||
assert_eq!(cursor.node().kind(), "call_expression");
|
||||
|
||||
// The selectors with text regexes override the selector without one.
|
||||
assert!(cursor.goto_first_child());
|
||||
assert_eq!(cursor.node().kind(), "identifier");
|
||||
assert_eq!(*cursor.node_properties(), Properties { a: Some("y".to_string()), b: None });
|
||||
|
||||
assert!(cursor.goto_next_sibling());
|
||||
assert_eq!(cursor.node().kind(), "arguments");
|
||||
assert!(cursor.goto_first_child());
|
||||
assert_eq!(cursor.node().kind(), "(");
|
||||
|
||||
// This node doesn't match either of the regexes.
|
||||
assert!(cursor.goto_next_sibling());
|
||||
assert_eq!(cursor.node().kind(), "identifier");
|
||||
assert_eq!(*cursor.node_properties(), Properties { a: Some("x".to_string()), b: None });
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue