PageRenderTime 35ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/regression.rs

https://github.com/BurntSushi/ripgrep
Rust | 866 lines | 617 code | 142 blank | 107 comment | 2 complexity | 2d2e71261e438c04ecc07622bbaa72a6 MD5 | raw file
Possible License(s): MIT, Unlicense
  1. use crate::hay::SHERLOCK;
  2. use crate::util::{sort_lines, Dir, TestCommand};
  3. // See: https://github.com/BurntSushi/ripgrep/issues/16
  4. rgtest!(r16, |dir: Dir, mut cmd: TestCommand| {
  5. dir.create_dir(".git");
  6. dir.create(".gitignore", "ghi/");
  7. dir.create_dir("ghi");
  8. dir.create_dir("def/ghi");
  9. dir.create("ghi/toplevel.txt", "xyz");
  10. dir.create("def/ghi/subdir.txt", "xyz");
  11. cmd.arg("xyz").assert_err();
  12. });
  13. // See: https://github.com/BurntSushi/ripgrep/issues/25
  14. rgtest!(r25, |dir: Dir, mut cmd: TestCommand| {
  15. dir.create_dir(".git");
  16. dir.create(".gitignore", "/llvm/");
  17. dir.create_dir("src/llvm");
  18. dir.create("src/llvm/foo", "test");
  19. cmd.arg("test");
  20. eqnice!("src/llvm/foo:test\n", cmd.stdout());
  21. cmd.current_dir(dir.path().join("src"));
  22. eqnice!("llvm/foo:test\n", cmd.stdout());
  23. });
  24. // See: https://github.com/BurntSushi/ripgrep/issues/30
  25. rgtest!(r30, |dir: Dir, mut cmd: TestCommand| {
  26. dir.create(".gitignore", "vendor/**\n!vendor/manifest");
  27. dir.create_dir("vendor");
  28. dir.create("vendor/manifest", "test");
  29. eqnice!("vendor/manifest:test\n", cmd.arg("test").stdout());
  30. });
  31. // See: https://github.com/BurntSushi/ripgrep/issues/49
  32. rgtest!(r49, |dir: Dir, mut cmd: TestCommand| {
  33. dir.create(".gitignore", "foo/bar");
  34. dir.create_dir("test/foo/bar");
  35. dir.create("test/foo/bar/baz", "test");
  36. cmd.arg("xyz").assert_err();
  37. });
  38. // See: https://github.com/BurntSushi/ripgrep/issues/50
  39. rgtest!(r50, |dir: Dir, mut cmd: TestCommand| {
  40. dir.create(".gitignore", "XXX/YYY/");
  41. dir.create_dir("abc/def/XXX/YYY");
  42. dir.create_dir("ghi/XXX/YYY");
  43. dir.create("abc/def/XXX/YYY/bar", "test");
  44. dir.create("ghi/XXX/YYY/bar", "test");
  45. cmd.arg("xyz").assert_err();
  46. });
  47. // See: https://github.com/BurntSushi/ripgrep/issues/64
  48. rgtest!(r64, |dir: Dir, mut cmd: TestCommand| {
  49. dir.create_dir("dir");
  50. dir.create_dir("foo");
  51. dir.create("dir/abc", "");
  52. dir.create("foo/abc", "");
  53. eqnice!("foo/abc\n", cmd.arg("--files").arg("foo").stdout());
  54. });
  55. // See: https://github.com/BurntSushi/ripgrep/issues/65
  56. rgtest!(r65, |dir: Dir, mut cmd: TestCommand| {
  57. dir.create_dir(".git");
  58. dir.create(".gitignore", "a/");
  59. dir.create_dir("a");
  60. dir.create("a/foo", "xyz");
  61. dir.create("a/bar", "xyz");
  62. cmd.arg("xyz").assert_err();
  63. });
  64. // See: https://github.com/BurntSushi/ripgrep/issues/67
  65. rgtest!(r67, |dir: Dir, mut cmd: TestCommand| {
  66. dir.create_dir(".git");
  67. dir.create(".gitignore", "/*\n!/dir");
  68. dir.create_dir("dir");
  69. dir.create_dir("foo");
  70. dir.create("foo/bar", "test");
  71. dir.create("dir/bar", "test");
  72. eqnice!("dir/bar:test\n", cmd.arg("test").stdout());
  73. });
  74. // See: https://github.com/BurntSushi/ripgrep/issues/87
  75. rgtest!(r87, |dir: Dir, mut cmd: TestCommand| {
  76. dir.create_dir(".git");
  77. dir.create(".gitignore", "foo\n**no-vcs**");
  78. dir.create("foo", "test");
  79. cmd.arg("test").assert_err();
  80. });
  81. // See: https://github.com/BurntSushi/ripgrep/issues/90
  82. rgtest!(r90, |dir: Dir, mut cmd: TestCommand| {
  83. dir.create_dir(".git");
  84. dir.create(".gitignore", "!.foo");
  85. dir.create(".foo", "test");
  86. eqnice!(".foo:test\n", cmd.arg("test").stdout());
  87. });
  88. // See: https://github.com/BurntSushi/ripgrep/issues/93
  89. rgtest!(r93, |dir: Dir, mut cmd: TestCommand| {
  90. dir.create("foo", "192.168.1.1");
  91. eqnice!("foo:192.168.1.1\n", cmd.arg(r"(\d{1,3}\.){3}\d{1,3}").stdout());
  92. });
  93. // See: https://github.com/BurntSushi/ripgrep/issues/99
  94. rgtest!(r99, |dir: Dir, mut cmd: TestCommand| {
  95. dir.create("foo1", "test");
  96. dir.create("foo2", "zzz");
  97. dir.create("bar", "test");
  98. eqnice!(
  99. sort_lines("bar\ntest\n\nfoo1\ntest\n"),
  100. sort_lines(&cmd.arg("-j1").arg("--heading").arg("test").stdout())
  101. );
  102. });
  103. // See: https://github.com/BurntSushi/ripgrep/issues/105
  104. rgtest!(r105_part1, |dir: Dir, mut cmd: TestCommand| {
  105. dir.create("foo", "zztest");
  106. eqnice!("foo:1:3:zztest\n", cmd.arg("--vimgrep").arg("test").stdout());
  107. });
  108. // See: https://github.com/BurntSushi/ripgrep/issues/105
  109. rgtest!(r105_part2, |dir: Dir, mut cmd: TestCommand| {
  110. dir.create("foo", "zztest");
  111. eqnice!("foo:1:3:zztest\n", cmd.arg("--column").arg("test").stdout());
  112. });
  113. // See: https://github.com/BurntSushi/ripgrep/issues/127
  114. rgtest!(r127, |dir: Dir, mut cmd: TestCommand| {
  115. // Set up a directory hierarchy like this:
  116. //
  117. // .gitignore
  118. // foo/
  119. // sherlock
  120. // watson
  121. //
  122. // Where `.gitignore` contains `foo/sherlock`.
  123. //
  124. // ripgrep should ignore 'foo/sherlock' giving us results only from
  125. // 'foo/watson' but on Windows ripgrep will include both 'foo/sherlock' and
  126. // 'foo/watson' in the search results.
  127. dir.create_dir(".git");
  128. dir.create(".gitignore", "foo/sherlock\n");
  129. dir.create_dir("foo");
  130. dir.create("foo/sherlock", SHERLOCK);
  131. dir.create("foo/watson", SHERLOCK);
  132. let expected = "\
  133. foo/watson:For the Doctor Watsons of this world, as opposed to the Sherlock
  134. foo/watson:be, to a very large extent, the result of luck. Sherlock Holmes
  135. ";
  136. assert_eq!(expected, cmd.arg("Sherlock").stdout());
  137. });
  138. // See: https://github.com/BurntSushi/ripgrep/issues/128
  139. rgtest!(r128, |dir: Dir, mut cmd: TestCommand| {
  140. dir.create_bytes("foo", b"01234567\x0b\n\x0b\n\x0b\n\x0b\nx");
  141. eqnice!("foo:5:x\n", cmd.arg("-n").arg("x").stdout());
  142. });
  143. // See: https://github.com/BurntSushi/ripgrep/issues/131
  144. //
  145. // TODO(burntsushi): Darwin doesn't like this test for some reason. Probably
  146. // due to the weird file path.
  147. #[cfg(not(target_os = "macos"))]
  148. rgtest!(r131, |dir: Dir, mut cmd: TestCommand| {
  149. dir.create_dir(".git");
  150. dir.create(".gitignore", "TopÑapa");
  151. dir.create("TopÑapa", "test");
  152. cmd.arg("test").assert_err();
  153. });
  154. // See: https://github.com/BurntSushi/ripgrep/issues/137
  155. //
  156. // TODO(burntsushi): Figure out how to make this test work on Windows. Right
  157. // now it gives "access denied" errors when trying to create a file symlink.
  158. // For now, disable test on Windows.
  159. #[cfg(not(windows))]
  160. rgtest!(r137, |dir: Dir, mut cmd: TestCommand| {
  161. dir.create("sherlock", SHERLOCK);
  162. dir.link_file("sherlock", "sym1");
  163. dir.link_file("sherlock", "sym2");
  164. let expected = "\
  165. ./sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
  166. ./sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
  167. sym1:For the Doctor Watsons of this world, as opposed to the Sherlock
  168. sym1:be, to a very large extent, the result of luck. Sherlock Holmes
  169. sym2:For the Doctor Watsons of this world, as opposed to the Sherlock
  170. sym2:be, to a very large extent, the result of luck. Sherlock Holmes
  171. ";
  172. cmd.arg("-j1").arg("Sherlock").arg("./").arg("sym1").arg("sym2");
  173. eqnice!(expected, cmd.stdout());
  174. });
  175. // See: https://github.com/BurntSushi/ripgrep/issues/156
  176. rgtest!(r156, |dir: Dir, mut cmd: TestCommand| {
  177. let expected = r#"#parse('widgets/foo_bar_macros.vm')
  178. #parse ( 'widgets/mobile/foo_bar_macros.vm' )
  179. #parse ("widgets/foobarhiddenformfields.vm")
  180. #parse ( "widgets/foo_bar_legal.vm" )
  181. #include( 'widgets/foo_bar_tips.vm' )
  182. #include('widgets/mobile/foo_bar_macros.vm')
  183. #include ("widgets/mobile/foo_bar_resetpw.vm")
  184. #parse('widgets/foo-bar-macros.vm')
  185. #parse ( 'widgets/mobile/foo-bar-macros.vm' )
  186. #parse ("widgets/foo-bar-hiddenformfields.vm")
  187. #parse ( "widgets/foo-bar-legal.vm" )
  188. #include( 'widgets/foo-bar-tips.vm' )
  189. #include('widgets/mobile/foo-bar-macros.vm')
  190. #include ("widgets/mobile/foo-bar-resetpw.vm")
  191. "#;
  192. dir.create("testcase.txt", expected);
  193. cmd.arg("-N");
  194. cmd.arg(r#"#(?:parse|include)\s*\(\s*(?:"|')[./A-Za-z_-]+(?:"|')"#);
  195. cmd.arg("testcase.txt");
  196. eqnice!(expected, cmd.stdout());
  197. });
  198. // See: https://github.com/BurntSushi/ripgrep/issues/184
  199. rgtest!(r184, |dir: Dir, mut cmd: TestCommand| {
  200. dir.create(".gitignore", ".*");
  201. dir.create_dir("foo/bar");
  202. dir.create("foo/bar/baz", "test");
  203. cmd.arg("test");
  204. eqnice!("foo/bar/baz:test\n", cmd.stdout());
  205. cmd.current_dir(dir.path().join("./foo/bar"));
  206. eqnice!("baz:test\n", cmd.stdout());
  207. });
  208. // See: https://github.com/BurntSushi/ripgrep/issues/199
  209. rgtest!(r199, |dir: Dir, mut cmd: TestCommand| {
  210. dir.create("foo", "tEsT");
  211. eqnice!("foo:tEsT\n", cmd.arg("--smart-case").arg(r"\btest\b").stdout());
  212. });
  213. // See: https://github.com/BurntSushi/ripgrep/issues/206
  214. rgtest!(r206, |dir: Dir, mut cmd: TestCommand| {
  215. dir.create_dir("foo");
  216. dir.create("foo/bar.txt", "test");
  217. cmd.arg("test").arg("-g").arg("*.txt");
  218. eqnice!("foo/bar.txt:test\n", cmd.stdout());
  219. });
  220. // See: https://github.com/BurntSushi/ripgrep/issues/210
  221. #[cfg(unix)]
  222. rgtest!(r210, |dir: Dir, mut cmd: TestCommand| {
  223. use std::ffi::OsStr;
  224. use std::os::unix::ffi::OsStrExt;
  225. let badutf8 = OsStr::from_bytes(&b"foo\xffbar"[..]);
  226. // APFS does not support creating files with invalid UTF-8 bytes.
  227. // https://github.com/BurntSushi/ripgrep/issues/559
  228. if dir.try_create(badutf8, "test").is_ok() {
  229. cmd.arg("-H").arg("test").arg(badutf8);
  230. assert_eq!(b"foo\xffbar:test\n".to_vec(), cmd.output().stdout);
  231. }
  232. });
  233. // See: https://github.com/BurntSushi/ripgrep/issues/228
  234. rgtest!(r228, |dir: Dir, mut cmd: TestCommand| {
  235. dir.create_dir("foo");
  236. cmd.arg("--ignore-file").arg("foo").arg("test").assert_err();
  237. });
  238. // See: https://github.com/BurntSushi/ripgrep/issues/229
  239. rgtest!(r229, |dir: Dir, mut cmd: TestCommand| {
  240. dir.create("foo", "economie");
  241. cmd.arg("-S").arg("[E]conomie").assert_err();
  242. });
  243. // See: https://github.com/BurntSushi/ripgrep/issues/251
  244. rgtest!(r251, |dir: Dir, mut cmd: TestCommand| {
  245. dir.create("foo", "привет\nПривет\nПрИвЕт");
  246. let expected = "foo:привет\nfoo:Привет\nfoo:ПрИвЕт\n";
  247. eqnice!(expected, cmd.arg("-i").arg("привет").stdout());
  248. });
  249. // See: https://github.com/BurntSushi/ripgrep/issues/256
  250. #[cfg(not(windows))]
  251. rgtest!(r256, |dir: Dir, mut cmd: TestCommand| {
  252. dir.create_dir("bar");
  253. dir.create("bar/baz", "test");
  254. dir.link_dir("bar", "foo");
  255. eqnice!("foo/baz:test\n", cmd.arg("test").arg("foo").stdout());
  256. });
  257. // See: https://github.com/BurntSushi/ripgrep/issues/256
  258. #[cfg(not(windows))]
  259. rgtest!(r256_j1, |dir: Dir, mut cmd: TestCommand| {
  260. dir.create_dir("bar");
  261. dir.create("bar/baz", "test");
  262. dir.link_dir("bar", "foo");
  263. eqnice!("foo/baz:test\n", cmd.arg("-j1").arg("test").arg("foo").stdout());
  264. });
  265. // See: https://github.com/BurntSushi/ripgrep/issues/270
  266. rgtest!(r270, |dir: Dir, mut cmd: TestCommand| {
  267. dir.create("foo", "-test");
  268. cmd.arg("-e").arg("-test");
  269. eqnice!("foo:-test\n", cmd.stdout());
  270. });
  271. // See: https://github.com/BurntSushi/ripgrep/issues/279
  272. rgtest!(r279, |dir: Dir, mut cmd: TestCommand| {
  273. dir.create("foo", "test");
  274. eqnice!("", cmd.arg("-q").arg("test").stdout());
  275. });
  276. // See: https://github.com/BurntSushi/ripgrep/issues/391
  277. rgtest!(r391, |dir: Dir, mut cmd: TestCommand| {
  278. dir.create_dir(".git");
  279. dir.create("lock", "");
  280. dir.create("bar.py", "");
  281. dir.create(".git/packed-refs", "");
  282. dir.create(".git/description", "");
  283. cmd.args(&[
  284. "--no-ignore",
  285. "--hidden",
  286. "--follow",
  287. "--files",
  288. "--glob",
  289. "!{.git,node_modules,plugged}/**",
  290. "--glob",
  291. "*.{js,json,php,md,styl,scss,sass,pug,html,config,py,cpp,c,go,hs}",
  292. ]);
  293. eqnice!("bar.py\n", cmd.stdout());
  294. });
  295. // See: https://github.com/BurntSushi/ripgrep/issues/405
  296. rgtest!(r405, |dir: Dir, mut cmd: TestCommand| {
  297. dir.create_dir("foo/bar");
  298. dir.create_dir("bar/foo");
  299. dir.create("foo/bar/file1.txt", "test");
  300. dir.create("bar/foo/file2.txt", "test");
  301. cmd.arg("-g").arg("!/foo/**").arg("test");
  302. eqnice!("bar/foo/file2.txt:test\n", cmd.stdout());
  303. });
  304. // See: https://github.com/BurntSushi/ripgrep/issues/428
  305. #[cfg(not(windows))]
  306. rgtest!(r428_color_context_path, |dir: Dir, mut cmd: TestCommand| {
  307. dir.create("sherlock", "foo\nbar");
  308. cmd.args(&[
  309. "-A1",
  310. "-H",
  311. "--no-heading",
  312. "-N",
  313. "--colors=match:none",
  314. "--color=always",
  315. "foo",
  316. ]);
  317. let expected = format!(
  318. "{colored_path}:foo\n{colored_path}-bar\n",
  319. colored_path =
  320. "\x1b\x5b\x30\x6d\x1b\x5b\x33\x35\x6dsherlock\x1b\x5b\x30\x6d"
  321. );
  322. eqnice!(expected, cmd.stdout());
  323. });
  324. // See: https://github.com/BurntSushi/ripgrep/issues/428
  325. rgtest!(r428_unrecognized_style, |_: Dir, mut cmd: TestCommand| {
  326. cmd.arg("--colors=match:style:").arg("Sherlock");
  327. cmd.assert_err();
  328. let output = cmd.cmd().output().unwrap();
  329. let stderr = String::from_utf8_lossy(&output.stderr);
  330. let expected = "\
  331. unrecognized style attribute ''. Choose from: nobold, bold, nointense, \
  332. intense, nounderline, underline.
  333. ";
  334. eqnice!(expected, stderr);
  335. });
  336. // See: https://github.com/BurntSushi/ripgrep/issues/451
  337. rgtest!(r451_only_matching_as_in_issue, |dir: Dir, mut cmd: TestCommand| {
  338. dir.create("digits.txt", "1 2 3\n");
  339. cmd.arg("--only-matching").arg(r"[0-9]+").arg("digits.txt");
  340. let expected = "\
  341. 1
  342. 2
  343. 3
  344. ";
  345. eqnice!(expected, cmd.stdout());
  346. });
  347. // See: https://github.com/BurntSushi/ripgrep/issues/451
  348. rgtest!(r451_only_matching, |dir: Dir, mut cmd: TestCommand| {
  349. dir.create("digits.txt", "1 2 3\n123\n");
  350. cmd.args(&["--only-matching", "--column", r"[0-9]", "digits.txt"]);
  351. let expected = "\
  352. 1:1:1
  353. 1:3:2
  354. 1:5:3
  355. 2:1:1
  356. 2:2:2
  357. 2:3:3
  358. ";
  359. eqnice!(expected, cmd.stdout());
  360. });
  361. // See: https://github.com/BurntSushi/ripgrep/issues/483
  362. rgtest!(r483_matching_no_stdout, |dir: Dir, mut cmd: TestCommand| {
  363. dir.create("file.py", "");
  364. cmd.arg("--quiet").arg("--files").arg("--glob").arg("*.py");
  365. eqnice!("", cmd.stdout());
  366. });
  367. // See: https://github.com/BurntSushi/ripgrep/issues/483
  368. rgtest!(r483_non_matching_exit_code, |dir: Dir, mut cmd: TestCommand| {
  369. dir.create("file.rs", "");
  370. cmd.arg("--quiet").arg("--files").arg("--glob").arg("*.py");
  371. cmd.assert_err();
  372. });
  373. // See: https://github.com/BurntSushi/ripgrep/issues/493
  374. rgtest!(r493, |dir: Dir, mut cmd: TestCommand| {
  375. dir.create("input.txt", "peshwaship 're seminomata");
  376. cmd.arg("-o").arg(r"\b 're \b").arg("input.txt");
  377. assert_eq!(" 're \n", cmd.stdout());
  378. });
  379. // See: https://github.com/BurntSushi/ripgrep/issues/506
  380. rgtest!(r506_word_not_parenthesized, |dir: Dir, mut cmd: TestCommand| {
  381. dir.create("wb.txt", "min minimum amin\nmax maximum amax");
  382. cmd.arg("-w").arg("-o").arg("min|max").arg("wb.txt");
  383. eqnice!("min\nmax\n", cmd.stdout());
  384. });
  385. // See: https://github.com/BurntSushi/ripgrep/issues/553
  386. rgtest!(r553_switch, |dir: Dir, mut cmd: TestCommand| {
  387. dir.create("sherlock", SHERLOCK);
  388. let expected = "\
  389. sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
  390. sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
  391. ";
  392. cmd.arg("-i").arg("sherlock");
  393. eqnice!(expected, cmd.stdout());
  394. // Repeat the `i` flag to make sure everything still works.
  395. eqnice!(expected, cmd.arg("-i").stdout());
  396. });
  397. rgtest!(r553_flag, |dir: Dir, mut cmd: TestCommand| {
  398. dir.create("sherlock", SHERLOCK);
  399. let expected = "\
  400. For the Doctor Watsons of this world, as opposed to the Sherlock
  401. Holmeses, success in the province of detective work must always
  402. --
  403. but Doctor Watson has to have it taken out for him and dusted,
  404. and exhibited clearly, with a label attached.
  405. ";
  406. cmd.arg("-C").arg("1").arg(r"world|attached").arg("sherlock");
  407. eqnice!(expected, cmd.stdout());
  408. let expected = "\
  409. For the Doctor Watsons of this world, as opposed to the Sherlock
  410. and exhibited clearly, with a label attached.
  411. ";
  412. eqnice!(expected, cmd.arg("-C").arg("0").stdout());
  413. });
  414. // See: https://github.com/BurntSushi/ripgrep/issues/568
  415. rgtest!(r568_leading_hyphen_option_args, |dir: Dir, mut cmd: TestCommand| {
  416. dir.create("file", "foo bar -baz\n");
  417. cmd.arg("-e-baz").arg("-e").arg("-baz").arg("file");
  418. eqnice!("foo bar -baz\n", cmd.stdout());
  419. let mut cmd = dir.command();
  420. cmd.arg("-rni").arg("bar").arg("file");
  421. eqnice!("foo ni -baz\n", cmd.stdout());
  422. let mut cmd = dir.command();
  423. cmd.arg("-r").arg("-n").arg("-i").arg("bar").arg("file");
  424. eqnice!("foo -n -baz\n", cmd.stdout());
  425. });
  426. // See: https://github.com/BurntSushi/ripgrep/issues/599
  427. //
  428. // This test used to check that we emitted color escape sequences even for
  429. // empty matches, but with the addition of the JSON output format, clients no
  430. // longer need to rely on escape sequences to parse matches. Therefore, we no
  431. // longer emit useless escape sequences.
  432. rgtest!(r599, |dir: Dir, mut cmd: TestCommand| {
  433. dir.create("input.txt", "\n\ntest\n");
  434. cmd.args(&[
  435. "--color",
  436. "ansi",
  437. "--colors",
  438. "path:none",
  439. "--colors",
  440. "line:none",
  441. "--colors",
  442. "match:fg:red",
  443. "--colors",
  444. "match:style:nobold",
  445. "--line-number",
  446. r"^$",
  447. "input.txt",
  448. ]);
  449. let expected = "\
  450. 1:
  451. 2:
  452. ";
  453. eqnice_repr!(expected, cmd.stdout());
  454. });
  455. // See: https://github.com/BurntSushi/ripgrep/issues/693
  456. rgtest!(r693_context_in_contextless_mode, |dir: Dir, mut cmd: TestCommand| {
  457. dir.create("foo", "xyz\n");
  458. dir.create("bar", "xyz\n");
  459. cmd.arg("-C1").arg("-c").arg("--sort-files").arg("xyz");
  460. eqnice!("bar:1\nfoo:1\n", cmd.stdout());
  461. });
  462. // See: https://github.com/BurntSushi/ripgrep/issues/807
  463. rgtest!(r807, |dir: Dir, mut cmd: TestCommand| {
  464. dir.create_dir(".git");
  465. dir.create(".gitignore", ".a/b");
  466. dir.create_dir(".a/b");
  467. dir.create_dir(".a/c");
  468. dir.create(".a/b/file", "test");
  469. dir.create(".a/c/file", "test");
  470. eqnice!(".a/c/file:test\n", cmd.arg("--hidden").arg("test").stdout());
  471. });
  472. // See: https://github.com/BurntSushi/ripgrep/issues/900
  473. rgtest!(r900, |dir: Dir, mut cmd: TestCommand| {
  474. dir.create("sherlock", SHERLOCK);
  475. dir.create("pat", "");
  476. cmd.arg("-fpat").arg("sherlock").assert_err();
  477. });
  478. // See: https://github.com/BurntSushi/ripgrep/issues/1064
  479. rgtest!(r1064, |dir: Dir, mut cmd: TestCommand| {
  480. dir.create("input", "abc");
  481. eqnice!("input:abc\n", cmd.arg("a(.*c)").stdout());
  482. });
  483. // See: https://github.com/BurntSushi/ripgrep/issues/1174
  484. rgtest!(r1098, |dir: Dir, mut cmd: TestCommand| {
  485. dir.create_dir(".git");
  486. dir.create(".gitignore", "a**b");
  487. dir.create("afoob", "test");
  488. cmd.arg("test").assert_err();
  489. });
  490. // See: https://github.com/BurntSushi/ripgrep/issues/1130
  491. rgtest!(r1130, |dir: Dir, mut cmd: TestCommand| {
  492. dir.create("foo", "test");
  493. eqnice!(
  494. "foo\n",
  495. cmd.arg("--files-with-matches").arg("test").arg("foo").stdout()
  496. );
  497. let mut cmd = dir.command();
  498. eqnice!(
  499. "foo\n",
  500. cmd.arg("--files-without-match").arg("nada").arg("foo").stdout()
  501. );
  502. });
  503. // See: https://github.com/BurntSushi/ripgrep/issues/1159
  504. rgtest!(r1159_invalid_flag, |_: Dir, mut cmd: TestCommand| {
  505. cmd.arg("--wat").assert_exit_code(2);
  506. });
  507. // See: https://github.com/BurntSushi/ripgrep/issues/1159
  508. rgtest!(r1159_exit_status, |dir: Dir, _: TestCommand| {
  509. dir.create("foo", "test");
  510. // search with a match gets 0 exit status.
  511. let mut cmd = dir.command();
  512. cmd.arg("test").assert_exit_code(0);
  513. // search with --quiet and a match gets 0 exit status.
  514. let mut cmd = dir.command();
  515. cmd.arg("-q").arg("test").assert_exit_code(0);
  516. // search with a match and an error gets 2 exit status.
  517. let mut cmd = dir.command();
  518. cmd.arg("test").arg("no-file").assert_exit_code(2);
  519. // search with a match in --quiet mode and an error gets 0 exit status.
  520. let mut cmd = dir.command();
  521. cmd.arg("-q").arg("test").arg("foo").arg("no-file").assert_exit_code(0);
  522. // search with no match gets 1 exit status.
  523. let mut cmd = dir.command();
  524. cmd.arg("nada").assert_exit_code(1);
  525. // search with --quiet and no match gets 1 exit status.
  526. let mut cmd = dir.command();
  527. cmd.arg("-q").arg("nada").assert_exit_code(1);
  528. // search with no match and an error gets 2 exit status.
  529. let mut cmd = dir.command();
  530. cmd.arg("nada").arg("no-file").assert_exit_code(2);
  531. // search with no match in --quiet mode and an error gets 2 exit status.
  532. let mut cmd = dir.command();
  533. cmd.arg("-q").arg("nada").arg("foo").arg("no-file").assert_exit_code(2);
  534. });
  535. // See: https://github.com/BurntSushi/ripgrep/issues/1163
  536. rgtest!(r1163, |dir: Dir, mut cmd: TestCommand| {
  537. dir.create("bom.txt", "\u{FEFF}test123\ntest123");
  538. eqnice!(
  539. "bom.txt:test123\nbom.txt:test123\n",
  540. cmd.arg("^test123").stdout()
  541. );
  542. });
  543. // See: https://github.com/BurntSushi/ripgrep/issues/1164
  544. rgtest!(r1164, |dir: Dir, mut cmd: TestCommand| {
  545. dir.create_dir(".git");
  546. dir.create(".gitignore", "myfile");
  547. dir.create("MYFILE", "test");
  548. cmd.arg("--ignore-file-case-insensitive").arg("test").assert_err();
  549. eqnice!(
  550. "MYFILE:test\n",
  551. cmd.arg("--no-ignore-file-case-insensitive").stdout()
  552. );
  553. });
  554. // See: https://github.com/BurntSushi/ripgrep/issues/1173
  555. rgtest!(r1173, |dir: Dir, mut cmd: TestCommand| {
  556. dir.create_dir(".git");
  557. dir.create(".gitignore", "**");
  558. dir.create("foo", "test");
  559. cmd.arg("test").assert_err();
  560. });
  561. // See: https://github.com/BurntSushi/ripgrep/issues/1174
  562. rgtest!(r1174, |dir: Dir, mut cmd: TestCommand| {
  563. dir.create_dir(".git");
  564. dir.create(".gitignore", "**/**/*");
  565. dir.create_dir("a");
  566. dir.create("a/foo", "test");
  567. cmd.arg("test").assert_err();
  568. });
  569. // See: https://github.com/BurntSushi/ripgrep/issues/1176
  570. rgtest!(r1176_literal_file, |dir: Dir, mut cmd: TestCommand| {
  571. dir.create("patterns", "foo(bar\n");
  572. dir.create("test", "foo(bar");
  573. eqnice!(
  574. "foo(bar\n",
  575. cmd.arg("-F").arg("-f").arg("patterns").arg("test").stdout()
  576. );
  577. });
  578. // See: https://github.com/BurntSushi/ripgrep/issues/1176
  579. rgtest!(r1176_line_regex, |dir: Dir, mut cmd: TestCommand| {
  580. dir.create("patterns", "foo\n");
  581. dir.create("test", "foobar\nfoo\nbarfoo\n");
  582. eqnice!(
  583. "foo\n",
  584. cmd.arg("-x").arg("-f").arg("patterns").arg("test").stdout()
  585. );
  586. });
  587. // See: https://github.com/BurntSushi/ripgrep/issues/1203
  588. rgtest!(r1203_reverse_suffix_literal, |dir: Dir, _: TestCommand| {
  589. dir.create("test", "153.230000\n");
  590. let mut cmd = dir.command();
  591. eqnice!("153.230000\n", cmd.arg(r"\d\d\d00").arg("test").stdout());
  592. let mut cmd = dir.command();
  593. eqnice!("153.230000\n", cmd.arg(r"\d\d\d000").arg("test").stdout());
  594. });
  595. // See: https://github.com/BurntSushi/ripgrep/issues/1223
  596. rgtest!(
  597. r1223_no_dir_check_for_default_path,
  598. |dir: Dir, mut cmd: TestCommand| {
  599. dir.create_dir("-");
  600. dir.create("a.json", "{}");
  601. dir.create("a.txt", "some text");
  602. eqnice!(
  603. "a.json\na.txt\n",
  604. sort_lines(&cmd.arg("a").pipe(b"a.json\na.txt"))
  605. );
  606. }
  607. );
  608. // See: https://github.com/BurntSushi/ripgrep/issues/1259
  609. rgtest!(r1259_drop_last_byte_nonl, |dir: Dir, mut cmd: TestCommand| {
  610. dir.create("patterns-nonl", "[foo]");
  611. dir.create("patterns-nl", "[foo]\n");
  612. dir.create("test", "fz");
  613. eqnice!("fz\n", cmd.arg("-f").arg("patterns-nonl").arg("test").stdout());
  614. cmd = dir.command();
  615. eqnice!("fz\n", cmd.arg("-f").arg("patterns-nl").arg("test").stdout());
  616. });
  617. // See: https://github.com/BurntSushi/ripgrep/issues/1319
  618. rgtest!(r1319, |dir: Dir, mut cmd: TestCommand| {
  619. dir.create("input", "CCAGCTACTCGGGAGGCTGAGGCTGGAGGATCGCTTGAGTCCAGGAGTTC");
  620. eqnice!(
  621. "input:CCAGCTACTCGGGAGGCTGAGGCTGGAGGATCGCTTGAGTCCAGGAGTTC\n",
  622. cmd.arg("TTGAGTCCAGGAG[ATCG]{2}C").stdout()
  623. );
  624. });
  625. // See: https://github.com/BurntSushi/ripgrep/issues/1334
  626. rgtest!(r1334_crazy_literals, |dir: Dir, mut cmd: TestCommand| {
  627. dir.create("patterns", &"1.208.0.0/12\n".repeat(40));
  628. dir.create("corpus", "1.208.0.0/12\n");
  629. eqnice!(
  630. "1.208.0.0/12\n",
  631. cmd.arg("-Ff").arg("patterns").arg("corpus").stdout()
  632. );
  633. });
  634. // See: https://github.com/BurntSushi/ripgrep/issues/1389
  635. rgtest!(r1389_bad_symlinks_no_biscuit, |dir: Dir, mut cmd: TestCommand| {
  636. dir.create_dir("mydir");
  637. dir.create("mydir/file.txt", "test");
  638. dir.link_dir("mydir", "mylink");
  639. let stdout = cmd
  640. .args(&["test", "--no-ignore", "--sort", "path", "mylink"])
  641. .stdout();
  642. eqnice!("mylink/file.txt:test\n", stdout);
  643. });
  644. // See: https://github.com/BurntSushi/ripgrep/pull/1446
  645. rgtest!(
  646. r1446_respect_excludes_in_worktree,
  647. |dir: Dir, mut cmd: TestCommand| {
  648. dir.create_dir("repo/.git/info");
  649. dir.create("repo/.git/info/exclude", "ignored");
  650. dir.create_dir("repo/.git/worktrees/repotree");
  651. dir.create("repo/.git/worktrees/repotree/commondir", "../..");
  652. dir.create_dir("repotree");
  653. dir.create("repotree/.git", "gitdir: repo/.git/worktrees/repotree");
  654. dir.create("repotree/ignored", "");
  655. dir.create("repotree/not-ignored", "");
  656. cmd.arg("--sort").arg("path").arg("--files").arg("repotree");
  657. eqnice!("repotree/not-ignored\n", cmd.stdout());
  658. }
  659. );
  660. // See: https://github.com/BurntSushi/ripgrep/issues/1537
  661. rgtest!(r1537, |dir: Dir, mut cmd: TestCommand| {
  662. dir.create("foo", "abc;de,fg");
  663. let expected = "foo:abc;de,fg\n";
  664. eqnice!(expected, cmd.arg(";(.*,){1}").stdout());
  665. });
  666. // See: https://github.com/BurntSushi/ripgrep/issues/1559
  667. rgtest!(r1559, |dir: Dir, mut cmd: TestCommand| {
  668. dir.create(
  669. "foo",
  670. "\
  671. type A struct {
  672. TaskID int `json:\"taskID\"`
  673. }
  674. type B struct {
  675. ObjectID string `json:\"objectID\"`
  676. TaskID int `json:\"taskID\"`
  677. }
  678. ",
  679. );
  680. let expected = "\
  681. foo: TaskID int `json:\"taskID\"`
  682. foo: TaskID int `json:\"taskID\"`
  683. ";
  684. eqnice!(expected, cmd.arg("TaskID +int").stdout());
  685. });
  686. // See: https://github.com/BurntSushi/ripgrep/issues/1573
  687. //
  688. // Tests that if look-ahead is used, then --count-matches is correct.
  689. rgtest!(r1573, |dir: Dir, mut cmd: TestCommand| {
  690. // Only PCRE2 supports look-ahead.
  691. if !dir.is_pcre2() {
  692. return;
  693. }
  694. dir.create_bytes("foo", b"\xFF\xFE\x00\x62");
  695. dir.create(
  696. "foo",
  697. "\
  698. def A;
  699. def B;
  700. use A;
  701. use B;
  702. ",
  703. );
  704. // Check that normal --count is correct.
  705. cmd.args(&[
  706. "--pcre2",
  707. "--multiline",
  708. "--count",
  709. r"(?s)def (\w+);(?=.*use \w+)",
  710. "foo",
  711. ]);
  712. eqnice!("2\n", cmd.stdout());
  713. // Now check --count-matches.
  714. let mut cmd = dir.command();
  715. cmd.args(&[
  716. "--pcre2",
  717. "--multiline",
  718. "--count-matches",
  719. r"(?s)def (\w+);(?=.*use \w+)",
  720. "foo",
  721. ]);
  722. eqnice!("2\n", cmd.stdout());
  723. });