Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: watch mode for patterns test #298

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

Ashu999
Copy link

@Ashu999 Ashu999 commented May 1, 2024

Fixes: #51
/claim #51

WIP: tests are left

Summary by CodeRabbit

  • New Features

    • Introduced watch mode for pattern testing, enabling real-time file modification monitoring and automatic test reruns.
  • Enhancements

    • Added new dependencies like notify and notify-debouncer-mini to enhance functionality.
    • Simplified and streamlined dependency lists for remote_workflows and workflow_server for better maintenance.
  • Improvements

    • Enhanced pattern testing by adding additional arguments and improving the structure.
    • Added the Clone trait to various structs for improved data handling.
  • Bug Fixes

    • Improved the handling of file modifications during watch mode to ensure accurate test results.

@Ashu999 Ashu999 changed the title feature: watch mode for patterns test feat: watch mode for patterns test May 2, 2024
@Ashu999 Ashu999 marked this pull request as ready for review May 20, 2024 19:21
@Ashu999 Ashu999 requested a review from a team as a code owner May 20, 2024 19:21
Copy link
Contributor

coderabbitai bot commented May 20, 2024

Walkthrough

Walkthrough

The recent changes introduce a watch mode for the grit patterns test command, enabling automatic re-running of tests when files change. This enhancement includes adding dependencies, adjusting functions to support watch mode, and updating relevant structs to facilitate efficient and automated pattern testing within the CLI tool.

Changes

Files/Groups Change Summary
Cargo.toml, commands/patterns.rs Added dependencies notify and notify-debouncer-mini, simplified dependency lists, introduced watch field in PatternsTestArgs.
commands/mod.rs, commands/plumbing.rs Modified function calls to support watch mode by adding arguments like watch: false in relevant functions.
commands/patterns_test.rs, flags.rs Implemented functionality for watch mode in pattern testing, updated struct traits, and added Clone trait to a struct.
pattern_compiler/compiler.rs Made specific structs and functions public to enhance accessibility and functionality within the pattern compiler module.

Assessment against linked issues

Objective (Issue #51) Addressed Explanation
Watch mode should watch for file changes to any patterns in the .grit directory and automatically re-run those tests
If a file changes, only the affected patterns should be re-run
Account for pattern dependencies
Include at least 2 tests, including one integration test of the final binary The summary does not mention the addition of tests. Manual verification needed.

Tip

New Features and Improvements

Review Settings

Introduced new personality profiles for code reviews. Users can now select between "Chill" and "Assertive" review tones to tailor feedback styles according to their preferences. The "Assertive" profile posts more comments and nitpicks the code more aggressively, while the "Chill" profile is more relaxed and posts fewer comments.

AST-based Instructions

CodeRabbit offers customizing reviews based on the Abstract Syntax Tree (AST) pattern matching. Read more about AST-based instructions in the documentation.

Community-driven AST-based Rules

We are kicking off a community-driven initiative to create and share AST-based rules. Users can now contribute their AST-based rules to detect security vulnerabilities, code smells, and anti-patterns. Please see the ast-grep-essentials repository for more information.

New Static Analysis Tools

We are continually expanding our support for static analysis tools. We have added support for biome, hadolint, and ast-grep. Update the settings in your .coderabbit.yaml file or head over to the settings page to enable or disable the tools you want to use.

Tone Settings

Users can now customize CodeRabbit to review code in the style of their favorite characters or personalities. Here are some of our favorite examples:

  • Mr. T: "You must talk like Mr. T in all your code reviews. I pity the fool who doesn't!"
  • Pirate: "Arr, matey! Ye must talk like a pirate in all yer code reviews. Yarrr!"
  • Snarky: "You must be snarky in all your code reviews. Snark, snark, snark!"

Revamped Settings Page

We have redesigned the settings page for a more intuitive layout, enabling users to find and adjust settings quickly. This change was long overdue; it not only improves the user experience but also allows our development team to add more settings in the future with ease. Going forward, the changes to .coderabbit.yaml will be reflected in the settings page, and vice versa.

Miscellaneous

  • Turn off free summarization: You can switch off free summarization of PRs opened by users not on a paid plan using the enable_free_tier setting.
  • Knowledge-base scope: You can now set the scope of the knowledge base to either the repository (local) or the organization (global) level using the knowledge_base setting. In addition, you can specify Jira project keys and Linear team keys to limit the knowledge base scope for those integrations.
  • High-level summary placement: You can now customize the location of the high-level summary in the PR description using the high_level_summary_placeholder setting (default @coderabbitai summary).
  • Revamped request changes workflow: You can now configure CodeRabbit to auto-approve or request changes on PRs based on the review feedback using the request_changes_workflow setting.

Recent Review Details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits Files that changed from the base of the PR and between d51ba5e and 44fcd31.
Files selected for processing (2)
  • crates/cli/src/commands/patterns_test.rs (5 hunks)
  • crates/core/src/pattern_compiler/compiler.rs (1 hunks)
Additional comments not posted (1)
crates/core/src/pattern_compiler/compiler.rs (1)

570-664: The new get_dependents_of_target_patterns function is a significant addition. It appears to correctly identify dependent patterns based on the provided target patterns. However, ensure that this function is thoroughly tested, particularly for its ability to handle nested dependencies and multiple file scenarios.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Comment on lines 308 to 354
fn enable_watch_mode(cmd_arg: PatternsTestArgs, cmd_flags: GlobalFormatFlags) -> () {
let path = Path::new(".grit");
// setup debouncer
let (tx, rx) = std::sync::mpsc::channel();
// notify backend configuration
let backend_config = notify::Config::default().with_poll_interval(Duration::from_millis(10));
// debouncer configuration
let debouncer_config = Config::default()
.with_timeout(Duration::from_millis(10))
.with_notify_config(backend_config);
// select backend via fish operator, here PollWatcher backend
let mut debouncer = new_debouncer_opt::<_, notify::PollWatcher>(debouncer_config, tx).unwrap();

debouncer
.watcher()
.watch(path, RecursiveMode::Recursive)
.unwrap();
log::info!("\n[Watch Mode] enabled on path: {}", path.display());

// event pocessing
for result in rx {
match result {
Ok(event) => {
let modified_file_path = event.get(0).unwrap().path.clone();
log::info!("\n[Watch Mode] File modified: {:?}", modified_file_path);

let mut arg = cmd_arg.clone();
let flags = cmd_flags.clone();
arg.watch = false; //avoid creating infinite watchers
tokio::task::spawn(async move {
let affected_patterns_names =
get_affected_patterns(modified_file_path).await.unwrap();

info!(
"[Watch Mode] Patterns changed/affected : {:?}\n[Watch Mode] Re-running test for changed/affected patterns...\n",
affected_patterns_names
);

let _ = run_patterns_test(arg, flags, Some(affected_patterns_names)).await;
});
}
Err(error) => {
log::error!("Error {error:?}")
}
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation of watch mode in enable_watch_mode function is well-structured. However, consider adding error handling for the unwrap calls to prevent potential panics in production.

- let mut debouncer = new_debouncer_opt::<_, notify::PollWatcher>(debouncer_config, tx).unwrap();
+ let mut debouncer = new_debouncer_opt::<_, notify::PollWatcher>(debouncer_config, tx)
+     .expect("Failed to create debouncer");

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
fn enable_watch_mode(cmd_arg: PatternsTestArgs, cmd_flags: GlobalFormatFlags) -> () {
let path = Path::new(".grit");
// setup debouncer
let (tx, rx) = std::sync::mpsc::channel();
// notify backend configuration
let backend_config = notify::Config::default().with_poll_interval(Duration::from_millis(10));
// debouncer configuration
let debouncer_config = Config::default()
.with_timeout(Duration::from_millis(10))
.with_notify_config(backend_config);
// select backend via fish operator, here PollWatcher backend
let mut debouncer = new_debouncer_opt::<_, notify::PollWatcher>(debouncer_config, tx).unwrap();
debouncer
.watcher()
.watch(path, RecursiveMode::Recursive)
.unwrap();
log::info!("\n[Watch Mode] enabled on path: {}", path.display());
// event pocessing
for result in rx {
match result {
Ok(event) => {
let modified_file_path = event.get(0).unwrap().path.clone();
log::info!("\n[Watch Mode] File modified: {:?}", modified_file_path);
let mut arg = cmd_arg.clone();
let flags = cmd_flags.clone();
arg.watch = false; //avoid creating infinite watchers
tokio::task::spawn(async move {
let affected_patterns_names =
get_affected_patterns(modified_file_path).await.unwrap();
info!(
"[Watch Mode] Patterns changed/affected : {:?}\n[Watch Mode] Re-running test for changed/affected patterns...\n",
affected_patterns_names
);
let _ = run_patterns_test(arg, flags, Some(affected_patterns_names)).await;
});
}
Err(error) => {
log::error!("Error {error:?}")
}
}
}
}
fn enable_watch_mode(cmd_arg: PatternsTestArgs, cmd_flags: GlobalFormatFlags) -> () {
let path = Path::new(".grit");
// setup debouncer
let (tx, rx) = std::sync::mpsc::channel();
// notify backend configuration
let backend_config = notify::Config::default().with_poll_interval(Duration::from_millis(10));
// debouncer configuration
let debouncer_config = Config::default()
.with_timeout(Duration::from_millis(10))
.with_notify_config(backend_config);
// select backend via fish operator, here PollWatcher backend
let mut debouncer = new_debouncer_opt::<_, notify::PollWatcher>(debouncer_config, tx)
.expect("Failed to create debouncer");
debouncer
.watcher()
.watch(path, RecursiveMode::Recursive)
.unwrap();
log::info!("\n[Watch Mode] enabled on path: {}", path.display());
// event pocessing
for result in rx {
match result {
Ok(event) => {
let modified_file_path = event.get(0).unwrap().path.clone();
log::info!("\n[Watch Mode] File modified: {:?}", modified_file_path);
let mut arg = cmd_arg.clone();
let flags = cmd_flags.clone();
arg.watch = false; //avoid creating infinite watchers
tokio::task::spawn(async move {
let affected_patterns_names =
get_affected_patterns(modified_file_path).await.unwrap();
info!(
"[Watch Mode] Patterns changed/affected : {:?}\n[Watch Mode] Re-running test for changed/affected patterns...\n",
affected_patterns_names
);
let _ = run_patterns_test(arg, flags, Some(affected_patterns_names)).await;
});
}
Err(error) => {
log::error!("Error {error:?}")
}
}
}
}

Comment on lines 356 to 411
async fn get_affected_patterns(modified_file_path: PathBuf) -> Result<Vec<String>> {
let modified_file_path_string = modified_file_path.into_os_string().into_string().unwrap();

let (patterns, _) = resolve_from_cwd(&Source::Local).await?;
let affected_patterns = collect_testable_patterns(patterns.clone())
.into_iter()
.filter(|p| {
p.config.path.is_some() && p.config.path.as_ref().unwrap() == &modified_file_path_string
})
.collect::<Vec<_>>();

let mut affected_patterns_names = <Vec<String>>::new();
for affected_pattern in &affected_patterns {
affected_patterns_names.push(affected_pattern.local_name.clone().unwrap());
}
let mut affected_patterns_dependents_names = <Vec<String>>::new();

let grit_files = get_grit_files_from_cwd().await?;
let current_dir = std::env::current_dir()?;
let resolver = GritModuleResolver::new(current_dir.to_str().unwrap());

for p in patterns {
let body = format!("{}()", p.local_name);
let lang = PatternLanguage::get_language(&p.body);
let grit_files = grit_files.get_language_directory_or_default(lang)?;
let rich_pattern = resolver
.make_pattern(&body, Some(p.local_name.to_string()))
.unwrap();
let src = rich_pattern.body;
let mut parser = MarzanoGritParser::new()?;
let src_tree = parser.parse_file(&src, Some(Path::new(DEFAULT_FILE_NAME)))?;
let root = src_tree.root_node();
let is_multifile = is_multifile(&root, &grit_files, &mut parser)?;

let dependents = get_dependents_of_affected_patterns(
&grit_files,
&src,
&mut parser,
!is_multifile,
&affected_patterns_names,
)?;

for d in dependents {
if !affected_patterns_dependents_names.contains(&d) {
affected_patterns_dependents_names.push(d);
}
}
}

for depen in affected_patterns_dependents_names {
if !affected_patterns_names.contains(&depen) {
affected_patterns_names.push(depen);
}
}
Ok(affected_patterns_names)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tip

Codebase Verification

The search results indicate that there are numerous test functions across the codebase, but none specifically target the get_affected_patterns function. This suggests that there might not be direct unit tests for this function.

To ensure comprehensive testing of the get_affected_patterns function, it is crucial to add or verify the existence of tests that cover various scenarios, especially complex dependency scenarios.

  • Action Required: Add unit tests for the get_affected_patterns function to ensure it correctly handles complex dependency scenarios.
Analysis chain

The get_affected_patterns function effectively identifies patterns affected by file modifications. Ensure comprehensive testing to validate that it correctly handles complex dependency scenarios.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify that `get_affected_patterns` correctly identifies affected patterns and their dependents.

# Test: Run unit tests for `get_affected_patterns`.
cat tests/patterns_test.rs | grep "test_get_affected_patterns"

Length of output: 117



Script:

#!/bin/bash
# Locate the definition of the `get_affected_patterns` function
ast-grep --lang rust --pattern 'async fn get_affected_patterns($_) -> $_ { $$$ }'

# Locate test functions related to `get_affected_patterns`
rg 'get_affected_patterns' --type rust

Length of output: 5187



Script:

#!/bin/bash
# Search for test functions in the `crates/cli/src/commands/patterns_test.rs` file
rg '#\[test\]' crates/cli/src/commands/patterns_test.rs -A 2

Length of output: 62



Script:

#!/bin/bash
# Search for test functions across the entire codebase
rg '#\[test\]' -A 2 --type rust

Length of output: 138229

Copy link
Contributor

@morgante morgante left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the start, but this should be doable in a cleaner way with less code.

Ok(())
}

pub(crate) async fn run_patterns_test(
arg: PatternsTestArgs,
flags: GlobalFormatFlags,
watch_mode_args: Option<Vec<String>>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't feel like the right interface.

I think you should probably extract the core / repeated logic into a test_patterns function. Then the filtering of which patterns to run is kind of the same whether it's based on watch or exclude or something else.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking of using arg.filter here, but it only takes single string as input and uses regex.
If it's ok with you, I can modify the behavior of filter to support multiple arguments, not use regex and filter based on exact pattern name instead. This is how I have seen most of the testing tools work, when targeting a specific test(s).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to change the interface. No the point is you should have an inner function with a signature like test_patterns(..., targeted_patterns: Vec<String>). The outer / top functions (like arg.filter) chooses which patterns to run, then invokes the inner function to do the actual execution. The same function can also be used for the watch inner, since the core of what it does is just identifying the correct subset of patterns to run.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I understood the point (from 1st comment) about keeping the filtration logic together, since they share similar purpose and variables. I can take some common filtration logic from get_marzano_pattern_test_results as well.

regarding the test execution, it happens inside get_marzano_pattern_test_results, are you suggesting to modify it into a new function test_patterns and make it an inner function?

}

fn enable_watch_mode(cmd_arg: PatternsTestArgs, cmd_flags: GlobalFormatFlags) -> () {
let path = Path::new(".grit");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want to watch all of .grit (including .gritmodules). Also this should probably not be created new, but instead should be passed in based on the original patterns retrieved.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

notify crate currently does not support ignoring the directories inside tracked directory(notify-rs/notify#598). I have added a temporary fix to avoid re-running the tests in case any of these files are modified.

Copy link
Author

@Ashu999 Ashu999 May 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be passed in based on the original patterns retrieved

let's say a new pattern is added to a file, we will not know that unless we re-read the patterns from file. right?

Comment on lines 359 to 360
let (patterns, _) = resolve_from_cwd(&Source::Local).await?;
let affected_patterns = collect_testable_patterns(patterns.clone())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebuilding this from scratch every time is inefficient. We should instead just be looking at the existing retrieve patterns that were first found in the original top level command, then filtering those down to the ones related to the modified file.

Copy link
Author

@Ashu999 Ashu999 May 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in: #298 (comment), also code is now refactored (moved filter logic inside run_patterns_test()) to read patterns, testable only once per modification trigger.

}
Ok(affected_patterns_names)
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reparsing shouldn't be necessary. If we need additional metadata as the patterns are built in the first place, collect that in the compiler.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you explain this a little more, how to collect the required data in in the compiler? does it happen inside filter_libs() in compiler.rs?

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Outside diff range and nitpick comments (1)
crates/cli/src/commands/patterns_test.rs (1)

Line range hint 258-304: The implementation of the run_patterns_test function with the new watch_mode_arg parameter is well-structured. However, consider handling the case where the watch_mode_arg is None more explicitly to avoid potential confusion about the function's behavior in non-watch mode.

if let Some(watch_mode_arg) = watch_mode_arg {
    // Existing watch mode logic here
} else {
    // Logic for non-watch mode
}

Comment on lines +307 to +359
fn enable_watch_mode(cmd_arg: PatternsTestArgs, cmd_flags: GlobalFormatFlags) {
let path = Path::new(".grit");
let ignore_path = [".grit/.gritmodules", ".gitignore", ".grit/*.log"];
// setup debouncer
let (tx, rx) = std::sync::mpsc::channel();
// notify backend configuration
let backend_config = notify::Config::default().with_poll_interval(Duration::from_millis(10));
// debouncer configuration
let debouncer_config = Config::default()
.with_timeout(Duration::from_millis(10))
.with_notify_config(backend_config);
// select backend via fish operator, here PollWatcher backend
let mut debouncer = new_debouncer_opt::<_, notify::PollWatcher>(debouncer_config, tx).unwrap();

debouncer
.watcher()
.watch(path, RecursiveMode::Recursive)
.unwrap();
log::info!("\n[Watch Mode] enabled on path: {}", path.display());

// event pocessing
for result in rx {
match result {
Ok(event) => 'event_block: {
let modified_file_path = event
.get(0)
.unwrap()
.path
.clone()
.into_os_string()
.into_string()
.unwrap();
//temorary fix, until notify crate adds support for ignoring paths
for path in &ignore_path {
if modified_file_path.contains(path) {
break 'event_block;
}
}
log::info!("\n[Watch Mode] File modified: {:?}", modified_file_path);

let mut arg = cmd_arg.clone();
let flags = cmd_flags.clone();
arg.watch = false; //avoid creating infinite watchers
tokio::task::spawn(async move {
let _ = run_patterns_test(arg, flags, Some(modified_file_path)).await;
});
}
Err(error) => {
log::error!("Error {error:?}")
}
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The enable_watch_mode function effectively sets up file watching and event handling. However, the use of .unwrap() could lead to panics in production if errors occur. Replace .unwrap() with more robust error handling.

let mut debouncer = new_debouncer_opt::<_, notify::PollWatcher>(debouncer_config, tx)
    .expect("Failed to create debouncer");

Comment on lines +361 to +416
fn get_affected_patterns(
modified_file_path: String,
patterns: Vec<ResolvedGritDefinition>,
libs: &PatternsDirectory,
testable_patterns: &Vec<GritPatternTestInfo>,
) -> Result<Vec<String>> {
let affected_patterns = testable_patterns
.iter()
.filter(|p| {
p.config.path.is_some() && p.config.path.as_ref().unwrap() == &modified_file_path
})
.collect::<Vec<_>>();

let mut affected_patterns_names = <Vec<String>>::new();
for affected_pattern in &affected_patterns {
affected_patterns_names.push(affected_pattern.local_name.clone().unwrap());
}
let mut affected_patterns_dependents_names = <Vec<String>>::new();

let current_dir = std::env::current_dir()?;
let resolver = GritModuleResolver::new(current_dir.to_str().unwrap());

for p in patterns {
let body = format!("{}()", p.local_name);
let lang = PatternLanguage::get_language(&p.body);
let libs = libs.get_language_directory_or_default(lang)?;
let rich_pattern = resolver
.make_pattern(&body, Some(p.local_name.to_string()))
.unwrap();
let src = rich_pattern.body;
let mut parser = MarzanoGritParser::new()?;
let src_tree = parser.parse_file(&src, Some(Path::new(DEFAULT_FILE_NAME)))?;
let root = src_tree.root_node();
let is_multifile = is_multifile(&root, &libs, &mut parser)?;

let dependents = get_dependents_of_target_patterns(
&libs,
&src,
&mut parser,
!is_multifile,
&affected_patterns_names,
)?;

for d in dependents {
if !affected_patterns_dependents_names.contains(&d) {
affected_patterns_dependents_names.push(d);
}
}
}

for depen in affected_patterns_dependents_names {
if !affected_patterns_names.contains(&depen) {
affected_patterns_names.push(depen);
}
}
Ok(affected_patterns_names)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tip

Codebase Verification

The search results indicate that there are numerous test functions across the codebase, but none of them seem to be directly related to the get_affected_patterns function. Additionally, the only occurrence of get_affected_patterns is in the crates/cli/src/commands/patterns_test.rs file, which does not contain any test functions.

Given this information, it appears that the get_affected_patterns function is not currently covered by unit tests. This is a significant oversight, especially considering the function's importance in determining affected patterns based on file changes.

To address this, I recommend adding unit tests for the get_affected_patterns function to ensure it handles complex dependency scenarios correctly.

  • Add unit tests for the get_affected_patterns function in crates/cli/src/commands/patterns_test.rs.
Analysis chain

The get_affected_patterns function is crucial for determining which patterns are affected by file changes. Ensure that this function is covered by unit tests, especially to handle complex dependency scenarios.


The previous attempts to locate unit tests for the get_affected_patterns function did not yield any results. To ensure thorough verification, we should search for all test functions in the crates/cli/src/commands/patterns_test.rs file and manually inspect if any of them test the get_affected_patterns function.


The previous attempts to locate test functions in crates/cli/src/commands/patterns_test.rs did not yield any results. This suggests that there might not be any test functions in that file, or they might be named differently.

To ensure thorough verification, we should search for all test functions across the entire codebase and check if any of them test the get_affected_patterns function.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify that `get_affected_patterns` correctly identifies affected patterns and their dependents.

# Test: Run unit tests for `get_affected_patterns`.
cat tests/patterns_test.rs | grep "test_get_affected_patterns"

Length of output: 117



Script:

#!/bin/bash
# Locate the definition of the `get_affected_patterns` function
ast-grep --lang rust --pattern 'fn get_affected_patterns($_, $_, $_, $_) -> $_ { $$$ }'

# Search for test functions that might be testing `get_affected_patterns`
rg 'get_affected_patterns' --type rust

Length of output: 5042



Script:

#!/bin/bash
# Search for test functions in `crates/cli/src/commands/patterns_test.rs` and check if they call `get_affected_patterns`
rg -A 5 'fn test_' crates/cli/src/commands/patterns_test.rs | grep -B 5 'get_affected_patterns'

Length of output: 95



Script:

#!/bin/bash
# List all test functions in `crates/cli/src/commands/patterns_test.rs`
rg 'fn test_' crates/cli/src/commands/patterns_test.rs

Length of output: 56



Script:

#!/bin/bash
# List all test functions across the entire codebase
rg 'fn test_' --type rust

# Search for calls to `get_affected_patterns` across the entire codebase
rg 'get_affected_patterns' --type rust

Length of output: 11294

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Watch mode for grit patterns test
2 participants