You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AttributesMatcherTest.java 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. /*
  2. * Copyright (C) 2010, Red Hat Inc.
  3. * and other copyright owners as documented in the project's IP log.
  4. *
  5. * This program and the accompanying materials are made available
  6. * under the terms of the Eclipse Distribution License v1.0 which
  7. * accompanies this distribution, is reproduced below, and is
  8. * available at http://www.eclipse.org/org/documents/edl-v10.php
  9. *
  10. * All rights reserved.
  11. *
  12. * Redistribution and use in source and binary forms, with or
  13. * without modification, are permitted provided that the following
  14. * conditions are met:
  15. *
  16. * - Redistributions of source code must retain the above copyright
  17. * notice, this list of conditions and the following disclaimer.
  18. *
  19. * - Redistributions in binary form must reproduce the above
  20. * copyright notice, this list of conditions and the following
  21. * disclaimer in the documentation and/or other materials provided
  22. * with the distribution.
  23. *
  24. * - Neither the name of the Eclipse Foundation, Inc. nor the
  25. * names of its contributors may be used to endorse or promote
  26. * products derived from this software without specific prior
  27. * written permission.
  28. *
  29. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  30. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  31. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  32. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  33. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  34. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  35. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  36. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  37. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  38. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  40. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  41. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42. */
  43. package org.eclipse.jgit.attributes;
  44. import static org.junit.Assert.assertEquals;
  45. import static org.junit.Assert.assertFalse;
  46. import static org.junit.Assert.assertNotNull;
  47. import static org.junit.Assert.assertTrue;
  48. import org.junit.Test;
  49. /**
  50. * Tests git attributes pattern matches
  51. */
  52. public class AttributesMatcherTest {
  53. @Test
  54. public void testBasic() {
  55. String pattern = "/test.stp";
  56. assertMatched(pattern, "/test.stp");
  57. pattern = "#/test.stp";
  58. assertNotMatched(pattern, "/test.stp");
  59. }
  60. @Test
  61. public void testFileNameWildcards() {
  62. //Test basic * and ? for any pattern + any character
  63. String pattern = "*.st?";
  64. assertMatched(pattern, "/test.stp");
  65. assertMatched(pattern, "/anothertest.stg");
  66. assertMatched(pattern, "/anothertest.st0");
  67. assertNotMatched(pattern, "/anothertest.sta1");
  68. //Check that asterisk does not expand to "/"
  69. assertNotMatched(pattern, "/another/test.sta1");
  70. //Same as above, with a leading slash to ensure that doesn't cause problems
  71. pattern = "/*.st?";
  72. assertMatched(pattern, "/test.stp");
  73. assertMatched(pattern, "/anothertest.stg");
  74. assertMatched(pattern, "/anothertest.st0");
  75. assertNotMatched(pattern, "/anothertest.sta1");
  76. //Check that asterisk does not expand to "/"
  77. assertNotMatched(pattern, "/another/test.sta1");
  78. //Test for numbers
  79. pattern = "*.sta[0-5]";
  80. assertMatched(pattern, "/test.sta5");
  81. assertMatched(pattern, "/test.sta4");
  82. assertMatched(pattern, "/test.sta3");
  83. assertMatched(pattern, "/test.sta2");
  84. assertMatched(pattern, "/test.sta1");
  85. assertMatched(pattern, "/test.sta0");
  86. assertMatched(pattern, "/anothertest.sta2");
  87. assertNotMatched(pattern, "test.stag");
  88. assertNotMatched(pattern, "test.sta6");
  89. //Test for letters
  90. pattern = "/[tv]est.sta[a-d]";
  91. assertMatched(pattern, "/test.staa");
  92. assertMatched(pattern, "/test.stab");
  93. assertMatched(pattern, "/test.stac");
  94. assertMatched(pattern, "/test.stad");
  95. assertMatched(pattern, "/vest.stac");
  96. assertNotMatched(pattern, "test.stae");
  97. assertNotMatched(pattern, "test.sta9");
  98. //Test child directory/file is matched
  99. pattern = "/src/ne?";
  100. assertMatched(pattern, "/src/new/");
  101. assertMatched(pattern, "/src/new");
  102. assertMatched(pattern, "/src/new/a.c");
  103. assertMatched(pattern, "/src/new/a/a.c");
  104. assertNotMatched(pattern, "/src/new.c");
  105. //Test name-only fnmatcher matches
  106. pattern = "ne?";
  107. assertMatched(pattern, "/src/new/");
  108. assertMatched(pattern, "/src/new");
  109. assertMatched(pattern, "/src/new/a.c");
  110. assertMatched(pattern, "/src/new/a/a.c");
  111. assertMatched(pattern, "/neb");
  112. assertNotMatched(pattern, "/src/new.c");
  113. }
  114. @Test
  115. public void testTargetWithoutLeadingSlash() {
  116. //Test basic * and ? for any pattern + any character
  117. String pattern = "/*.st?";
  118. assertMatched(pattern, "test.stp");
  119. assertMatched(pattern, "anothertest.stg");
  120. assertMatched(pattern, "anothertest.st0");
  121. assertNotMatched(pattern, "anothertest.sta1");
  122. //Check that asterisk does not expand to ""
  123. assertNotMatched(pattern, "another/test.sta1");
  124. //Same as above, with a leading slash to ensure that doesn't cause problems
  125. pattern = "/*.st?";
  126. assertMatched(pattern, "test.stp");
  127. assertMatched(pattern, "anothertest.stg");
  128. assertMatched(pattern, "anothertest.st0");
  129. assertNotMatched(pattern, "anothertest.sta1");
  130. //Check that asterisk does not expand to ""
  131. assertNotMatched(pattern, "another/test.sta1");
  132. //Test for numbers
  133. pattern = "/*.sta[0-5]";
  134. assertMatched(pattern, "test.sta5");
  135. assertMatched(pattern, "test.sta4");
  136. assertMatched(pattern, "test.sta3");
  137. assertMatched(pattern, "test.sta2");
  138. assertMatched(pattern, "test.sta1");
  139. assertMatched(pattern, "test.sta0");
  140. assertMatched(pattern, "anothertest.sta2");
  141. assertNotMatched(pattern, "test.stag");
  142. assertNotMatched(pattern, "test.sta6");
  143. //Test for letters
  144. pattern = "/[tv]est.sta[a-d]";
  145. assertMatched(pattern, "test.staa");
  146. assertMatched(pattern, "test.stab");
  147. assertMatched(pattern, "test.stac");
  148. assertMatched(pattern, "test.stad");
  149. assertMatched(pattern, "vest.stac");
  150. assertNotMatched(pattern, "test.stae");
  151. assertNotMatched(pattern, "test.sta9");
  152. //Test child directory/file is matched
  153. pattern = "/src/ne?";
  154. assertMatched(pattern, "src/new/");
  155. assertMatched(pattern, "src/new");
  156. assertMatched(pattern, "src/new/a.c");
  157. assertMatched(pattern, "src/new/a/a.c");
  158. assertNotMatched(pattern, "src/new.c");
  159. //Test name-only fnmatcher matches
  160. pattern = "ne?";
  161. assertMatched(pattern, "src/new/");
  162. assertMatched(pattern, "src/new");
  163. assertMatched(pattern, "src/new/a.c");
  164. assertMatched(pattern, "src/new/a/a.c");
  165. assertMatched(pattern, "neb");
  166. assertNotMatched(pattern, "src/new.c");
  167. }
  168. @Test
  169. public void testParentDirectoryGitAttributes() {
  170. //Contains git attribute patterns such as might be seen in a parent directory
  171. //Test for wildcards
  172. String pattern = "/*/*.c";
  173. assertMatched(pattern, "/file/a.c");
  174. assertMatched(pattern, "/src/a.c");
  175. assertNotMatched(pattern, "/src/new/a.c");
  176. //Test child directory/file is matched
  177. pattern = "/src/new";
  178. assertMatched(pattern, "/src/new/");
  179. assertMatched(pattern, "/src/new");
  180. assertMatched(pattern, "/src/new/a.c");
  181. assertMatched(pattern, "/src/new/a/a.c");
  182. assertNotMatched(pattern, "/src/new.c");
  183. //Test child directory is matched, slash after name
  184. pattern = "/src/new/";
  185. assertMatched(pattern, "/src/new/");
  186. assertMatched(pattern, "/src/new/a.c");
  187. assertMatched(pattern, "/src/new/a/a.c");
  188. assertNotMatched(pattern, "/src/new");
  189. assertNotMatched(pattern, "/src/new.c");
  190. //Test directory is matched by name only
  191. pattern = "b1";
  192. assertMatched(pattern, "/src/new/a/b1/a.c");
  193. assertNotMatched(pattern, "/src/new/a/b2/file.c");
  194. assertNotMatched(pattern, "/src/new/a/bb1/file.c");
  195. assertNotMatched(pattern, "/src/new/a/file.c");
  196. }
  197. @Test
  198. public void testTrailingSlash() {
  199. String pattern = "/src/";
  200. assertMatched(pattern, "/src/");
  201. assertMatched(pattern, "/src/new");
  202. assertMatched(pattern, "/src/new/a.c");
  203. assertMatched(pattern, "/src/a.c");
  204. assertNotMatched(pattern, "/src");
  205. assertNotMatched(pattern, "/srcA/");
  206. }
  207. @Test
  208. public void testNameOnlyMatches() {
  209. /*
  210. * Name-only matches do not contain any path separators
  211. */
  212. //Test matches for file extension
  213. String pattern = "*.stp";
  214. assertMatched(pattern, "/test.stp");
  215. assertMatched(pattern, "/src/test.stp");
  216. assertNotMatched(pattern, "/test.stp1");
  217. assertNotMatched(pattern, "/test.astp");
  218. //Test matches for name-only, applies to file name or folder name
  219. pattern = "src";
  220. assertMatched(pattern, "/src");
  221. assertMatched(pattern, "/src/");
  222. assertMatched(pattern, "/src/a.c");
  223. assertMatched(pattern, "/src/new/a.c");
  224. assertMatched(pattern, "/new/src/a.c");
  225. assertMatched(pattern, "/file/src");
  226. //Test matches for name-only, applies only to folder names
  227. pattern = "src/";
  228. assertMatched(pattern, "/src/");
  229. assertMatched(pattern, "/src/a.c");
  230. assertMatched(pattern, "/src/new/a.c");
  231. assertMatched(pattern, "/new/src/a.c");
  232. assertNotMatched(pattern, "/src");
  233. assertNotMatched(pattern, "/file/src");
  234. //Test matches for name-only, applies to file name or folder name
  235. //With a small wildcard
  236. pattern = "?rc";
  237. assertMatched(pattern, "/src/a.c");
  238. assertMatched(pattern, "/src/new/a.c");
  239. assertMatched(pattern, "/new/src/a.c");
  240. assertMatched(pattern, "/file/src");
  241. assertMatched(pattern, "/src/");
  242. //Test matches for name-only, applies to file name or folder name
  243. //With a small wildcard
  244. pattern = "?r[a-c]";
  245. assertMatched(pattern, "/src/a.c");
  246. assertMatched(pattern, "/src/new/a.c");
  247. assertMatched(pattern, "/new/src/a.c");
  248. assertMatched(pattern, "/file/src");
  249. assertMatched(pattern, "/src/");
  250. assertMatched(pattern, "/srb/a.c");
  251. assertMatched(pattern, "/grb/new/a.c");
  252. assertMatched(pattern, "/new/crb/a.c");
  253. assertMatched(pattern, "/file/3rb");
  254. assertMatched(pattern, "/xrb/");
  255. assertMatched(pattern, "/3ra/a.c");
  256. assertMatched(pattern, "/5ra/new/a.c");
  257. assertMatched(pattern, "/new/1ra/a.c");
  258. assertMatched(pattern, "/file/dra");
  259. assertMatched(pattern, "/era/");
  260. assertNotMatched(pattern, "/crg");
  261. assertNotMatched(pattern, "/cr3");
  262. }
  263. @Test
  264. public void testGetters() {
  265. AttributesRule r = new AttributesRule("/pattern/", "");
  266. assertFalse(r.isNameOnly());
  267. assertTrue(r.isDirOnly());
  268. assertNotNull(r.getAttributes());
  269. assertTrue(r.getAttributes().isEmpty());
  270. assertEquals(r.getPattern(), "/pattern");
  271. r = new AttributesRule("/patter?/", "");
  272. assertFalse(r.isNameOnly());
  273. assertTrue(r.isDirOnly());
  274. assertNotNull(r.getAttributes());
  275. assertTrue(r.getAttributes().isEmpty());
  276. assertEquals(r.getPattern(), "/patter?");
  277. r = new AttributesRule("patt*", "");
  278. assertTrue(r.isNameOnly());
  279. assertFalse(r.isDirOnly());
  280. assertNotNull(r.getAttributes());
  281. assertTrue(r.getAttributes().isEmpty());
  282. assertEquals(r.getPattern(), "patt*");
  283. r = new AttributesRule("pattern", "attribute1");
  284. assertTrue(r.isNameOnly());
  285. assertFalse(r.isDirOnly());
  286. assertNotNull(r.getAttributes());
  287. assertFalse(r.getAttributes().isEmpty());
  288. assertEquals(r.getAttributes().size(), 1);
  289. assertEquals(r.getPattern(), "pattern");
  290. r = new AttributesRule("pattern", "attribute1 -attribute2");
  291. assertTrue(r.isNameOnly());
  292. assertFalse(r.isDirOnly());
  293. assertNotNull(r.getAttributes());
  294. assertEquals(r.getAttributes().size(), 2);
  295. assertEquals(r.getPattern(), "pattern");
  296. r = new AttributesRule("pattern", "attribute1 \t-attribute2 \t");
  297. assertTrue(r.isNameOnly());
  298. assertFalse(r.isDirOnly());
  299. assertNotNull(r.getAttributes());
  300. assertEquals(r.getAttributes().size(), 2);
  301. assertEquals(r.getPattern(), "pattern");
  302. r = new AttributesRule("pattern", "attribute1\t-attribute2\t");
  303. assertTrue(r.isNameOnly());
  304. assertFalse(r.isDirOnly());
  305. assertNotNull(r.getAttributes());
  306. assertEquals(r.getAttributes().size(), 2);
  307. assertEquals(r.getPattern(), "pattern");
  308. r = new AttributesRule("pattern", "attribute1\t -attribute2\t ");
  309. assertTrue(r.isNameOnly());
  310. assertFalse(r.isDirOnly());
  311. assertNotNull(r.getAttributes());
  312. assertEquals(r.getAttributes().size(), 2);
  313. assertEquals(r.getPattern(), "pattern");
  314. r = new AttributesRule("pattern",
  315. "attribute1 -attribute2 attribute3=value ");
  316. assertTrue(r.isNameOnly());
  317. assertFalse(r.isDirOnly());
  318. assertNotNull(r.getAttributes());
  319. assertEquals(r.getAttributes().size(), 3);
  320. assertEquals(r.getPattern(), "pattern");
  321. assertEquals(r.getAttributes().get(0).toString(), "attribute1");
  322. assertEquals(r.getAttributes().get(1).toString(), "-attribute2");
  323. assertEquals(r.getAttributes().get(2).toString(), "attribute3=value");
  324. }
  325. /**
  326. * Check for a match. If target ends with "/", match will assume that the
  327. * target is meant to be a directory.
  328. *
  329. * @param pattern
  330. * Pattern as it would appear in a .gitattributes file
  331. * @param target
  332. * Target file path relative to repository's GIT_DIR
  333. */
  334. public void assertMatched(String pattern, String target) {
  335. boolean value = match(pattern, target);
  336. assertTrue("Expected a match for: " + pattern + " with: " + target,
  337. value);
  338. }
  339. /**
  340. * Check for a match. If target ends with "/", match will assume that the
  341. * target is meant to be a directory.
  342. *
  343. * @param pattern
  344. * Pattern as it would appear in a .gitattributes file
  345. * @param target
  346. * Target file path relative to repository's GIT_DIR
  347. */
  348. public void assertNotMatched(String pattern, String target) {
  349. boolean value = match(pattern, target);
  350. assertFalse("Expected no match for: " + pattern + " with: " + target,
  351. value);
  352. }
  353. /**
  354. * Check for a match. If target ends with "/", match will assume that the
  355. * target is meant to be a directory.
  356. *
  357. * @param pattern
  358. * Pattern as it would appear in a .gitattributes file
  359. * @param target
  360. * Target file path relative to repository's GIT_DIR
  361. * @return Result of {@link AttributesRule#isMatch(String, boolean)}
  362. */
  363. private static boolean match(String pattern, String target) {
  364. AttributesRule r = new AttributesRule(pattern, "");
  365. //If speed of this test is ever an issue, we can use a presetRule field
  366. //to avoid recompiling a pattern each time.
  367. return r.isMatch(target, target.endsWith("/"));
  368. }
  369. }