tikhomirov@269: /* tikhomirov@612: * Copyright (c) 2011-2013 TMate Software Ltd tikhomirov@269: * tikhomirov@269: * This program is free software; you can redistribute it and/or modify tikhomirov@269: * it under the terms of the GNU General Public License as published by tikhomirov@269: * the Free Software Foundation; version 2 of the License. tikhomirov@269: * tikhomirov@269: * This program is distributed in the hope that it will be useful, tikhomirov@269: * but WITHOUT ANY WARRANTY; without even the implied warranty of tikhomirov@269: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the tikhomirov@269: * GNU General Public License for more details. tikhomirov@269: * tikhomirov@269: * For information on how to redistribute this software under tikhomirov@269: * the terms of a license other than GNU General Public License tikhomirov@269: * contact TMate Software at support@hg4j.com tikhomirov@269: */ tikhomirov@269: package org.tmatesoft.hg.test; tikhomirov@269: tikhomirov@408: import static org.tmatesoft.hg.util.Path.create; tikhomirov@408: tikhomirov@269: import java.io.BufferedReader; tikhomirov@269: import java.io.File; tikhomirov@269: import java.io.FileReader; tikhomirov@269: import java.io.StringReader; tikhomirov@269: tikhomirov@269: import org.junit.Rule; tikhomirov@269: import org.junit.Test; tikhomirov@409: import org.tmatesoft.hg.internal.WinToNixPathRewrite; tikhomirov@269: import org.tmatesoft.hg.repo.HgIgnore; tikhomirov@269: import org.tmatesoft.hg.repo.HgInternals; tikhomirov@612: import org.tmatesoft.hg.repo.HgLookup; tikhomirov@612: import org.tmatesoft.hg.repo.HgRepository; tikhomirov@612: import org.tmatesoft.hg.repo.HgRepositoryFiles; tikhomirov@269: import org.tmatesoft.hg.util.Path; tikhomirov@269: tikhomirov@269: /** tikhomirov@269: * tikhomirov@269: * @author Artem Tikhomirov tikhomirov@269: * @author TMate Software Ltd. tikhomirov@269: */ tikhomirov@269: public class TestIgnore { tikhomirov@269: tikhomirov@269: @Rule tikhomirov@269: public ErrorCollectorExt errorCollector = new ErrorCollectorExt(); tikhomirov@269: tikhomirov@269: public static void main(String[] args) throws Throwable { tikhomirov@269: TestIgnore test = new TestIgnore(); tikhomirov@269: test.testGlobWithAlternatives(); tikhomirov@269: test.testComplexFileParse(); tikhomirov@342: test.testSegmentsGlobMatch(); tikhomirov@339: test.testWildcardsDoNotMatchDirectorySeparator(); tikhomirov@269: test.errorCollector.verify(); tikhomirov@269: } tikhomirov@269: tikhomirov@269: @Test tikhomirov@269: public void testGlobWithAlternatives() throws Exception { tikhomirov@269: String content = "syntax:glob\ndoc/*.[0-9].{x,ht}ml"; tikhomirov@409: HgIgnore hgIgnore = HgInternals.newHgIgnore(new StringReader(content), null); tikhomirov@269: final Path p1 = Path.create("doc/asd.2.xml"); tikhomirov@269: final Path p2 = Path.create("doc/zxc.6.html"); tikhomirov@269: errorCollector.assertTrue(p1.toString(), hgIgnore.isIgnored(p1)); tikhomirov@269: errorCollector.assertTrue(p2.toString(), hgIgnore.isIgnored(p2)); tikhomirov@269: } tikhomirov@269: tikhomirov@269: @Test tikhomirov@269: public void testComplexFileParse() throws Exception { tikhomirov@269: BufferedReader br = new BufferedReader(new FileReader(new File(Configuration.get().getTestDataDir(), "mercurial.hgignore"))); tikhomirov@409: HgIgnore hgIgnore = HgInternals.newHgIgnore(br, null); tikhomirov@269: br.close(); tikhomirov@269: Path[] toCheck = new Path[] { tikhomirov@269: Path.create("file.so"), tikhomirov@269: Path.create("a/b/file.so"), tikhomirov@269: Path.create("#abc#"), tikhomirov@269: Path.create(".#abc"), tikhomirov@269: Path.create("locale/en/LC_MESSAGES/hg.mo"), tikhomirov@269: }; tikhomirov@409: doAssert(hgIgnore, toCheck, null); tikhomirov@269: } tikhomirov@269: tikhomirov@339: @Test tikhomirov@342: public void testSegmentsGlobMatch() throws Exception { tikhomirov@339: String s = "syntax:glob\nbin\n.*\nTEST-*.xml"; tikhomirov@409: HgIgnore hgIgnore = HgInternals.newHgIgnore(new StringReader(s), null); tikhomirov@339: Path[] toCheck = new Path[] { tikhomirov@339: Path.create("bin/org/sample/First.class"), tikhomirov@339: Path.create(".ignored-file"), tikhomirov@339: Path.create("dir/.ignored-file"), tikhomirov@339: Path.create("dir/.ignored-dir/file"), tikhomirov@339: Path.create("TEST-a.xml"), tikhomirov@339: Path.create("dir/TEST-b.xml"), tikhomirov@339: }; tikhomirov@409: doAssert(hgIgnore, toCheck, null); tikhomirov@409: // tikhomirov@343: s = "syntax:glob\n.git"; tikhomirov@409: hgIgnore = HgInternals.newHgIgnore(new StringReader(s), null); tikhomirov@343: Path p = Path.create(".git/aa"); tikhomirov@343: errorCollector.assertTrue(p.toString(), hgIgnore.isIgnored(p)); tikhomirov@343: p = Path.create("dir/.git/bb"); tikhomirov@343: errorCollector.assertTrue(p.toString(), hgIgnore.isIgnored(p)); tikhomirov@343: p = Path.create("dir/.gittt/cc"); tikhomirov@343: errorCollector.assertTrue(p.toString(), !hgIgnore.isIgnored(p)); tikhomirov@339: } tikhomirov@342: tikhomirov@342: @Test tikhomirov@342: public void testSegmentsRegexMatch() throws Exception { tikhomirov@342: // regex patterns that don't start with explicit ^ are allowed to match anywhere in the string tikhomirov@348: String s = "syntax:regexp\n/\\.git\n^abc\n"; tikhomirov@409: HgIgnore hgIgnore = HgInternals.newHgIgnore(new StringReader(s), null); tikhomirov@342: Path p = Path.create(".git/aa"); tikhomirov@342: errorCollector.assertTrue(p.toString(), !hgIgnore.isIgnored(p)); tikhomirov@342: p = Path.create("dir/.git/bb"); tikhomirov@342: errorCollector.assertTrue(p.toString(), hgIgnore.isIgnored(p)); tikhomirov@342: p = Path.create("dir/abc/aa"); tikhomirov@342: errorCollector.assertTrue(p.toString(), !hgIgnore.isIgnored(p)); tikhomirov@342: p = Path.create("abc/bb"); tikhomirov@342: errorCollector.assertTrue(p.toString(), hgIgnore.isIgnored(p)); tikhomirov@342: // Mercurial (in fact, likely pyton's regex match() function) treats tikhomirov@342: // regex patterns as having .* at the end (unless there's explicit $). tikhomirov@342: // IOW, matches to the beginning of the string, not to the whole string tikhomirov@342: p = Path.create("abcde/fg"); tikhomirov@342: errorCollector.assertTrue(p.toString(), hgIgnore.isIgnored(p)); tikhomirov@342: } tikhomirov@342: tikhomirov@339: @Test tikhomirov@339: public void testWildcardsDoNotMatchDirectorySeparator() throws Exception { tikhomirov@339: String s = "syntax:glob\na?b\nc*d"; tikhomirov@409: HgIgnore hgIgnore = HgInternals.newHgIgnore(new StringReader(s), null); tikhomirov@339: // shall not be ignored tikhomirov@339: Path[] toPass = new Path[] { tikhomirov@339: Path.create("a/b"), tikhomirov@339: Path.create("a/b/x"), tikhomirov@339: Path.create("x/a/b"), tikhomirov@339: Path.create("axyb"), tikhomirov@339: Path.create("c/d"), tikhomirov@339: Path.create("c/d/x"), tikhomirov@339: Path.create("x/c/d"), tikhomirov@339: }; tikhomirov@339: // shall be ignored tikhomirov@339: Path[] toIgnore = new Path[] { tikhomirov@339: Path.create("axb"), tikhomirov@339: Path.create("a3b"), tikhomirov@339: Path.create("a_b"), tikhomirov@339: Path.create("cd"), tikhomirov@339: Path.create("cxd"), tikhomirov@339: Path.create("cxyd"), tikhomirov@339: Path.create("x/cd"), tikhomirov@339: Path.create("x/cxyd"), tikhomirov@339: Path.create("cd/x"), tikhomirov@339: Path.create("cxyd/x"), tikhomirov@339: }; tikhomirov@409: doAssert(hgIgnore, toIgnore, toPass); tikhomirov@339: } tikhomirov@408: tikhomirov@408: @Test tikhomirov@408: public void testSyntaxPrefixAtLine() throws Exception { tikhomirov@408: String s = "glob:*.c\nregexp:.*\\.d"; tikhomirov@409: HgIgnore hgIgnore = HgInternals.newHgIgnore(new StringReader(s), null); tikhomirov@408: Path[] toPass = new Path[] { tikhomirov@408: create("a/c"), tikhomirov@408: create("a/d"), tikhomirov@408: create("a/d.a"), tikhomirov@408: create("a/d.e"), tikhomirov@408: }; tikhomirov@408: Path[] toIgnore = new Path[] { tikhomirov@408: create("a.c"), tikhomirov@408: create("a.d"), tikhomirov@408: create("src/a.c"), tikhomirov@408: create("src/a.d"), tikhomirov@408: }; tikhomirov@409: doAssert(hgIgnore, toIgnore, toPass); tikhomirov@409: } tikhomirov@409: tikhomirov@409: @Test tikhomirov@409: public void testGlobWithWindowsPathSeparators() throws Exception { tikhomirov@409: String s = "syntax:glob\n" + "bin\\*\n" + "*\\dir*\\*.a\n" + "*\\_ReSharper*\\\n"; tikhomirov@409: // explicit PathRewrite for the test to run on *nix as well tikhomirov@409: HgIgnore hgIgnore = HgInternals.newHgIgnore(new StringReader(s), new WinToNixPathRewrite()); tikhomirov@409: Path[] toPass = new Path[] { tikhomirov@409: create("bind/x"), tikhomirov@409: create("dir/x.a"), tikhomirov@409: create("dir-b/x.a"), tikhomirov@409: create("a/dir-b/x.b"), tikhomirov@409: create("_ReSharper-1/file"), tikhomirov@409: }; tikhomirov@409: Path[] toIgnore = new Path[] { tikhomirov@409: // create("bin/x"), tikhomirov@409: // create("a/bin/x"), tikhomirov@409: // create("a/dir/c.a"), tikhomirov@409: // create("b/dir-c/d.a"), tikhomirov@409: create("src/_ReSharper-1/file/x"), tikhomirov@409: }; tikhomirov@409: doAssert(hgIgnore, toIgnore, toPass); tikhomirov@409: } tikhomirov@409: tikhomirov@612: @Test tikhomirov@612: public void testRefreshOnChange() throws Exception { tikhomirov@612: File repoLoc = RepoUtils.cloneRepoToTempLocation("log-1", "test-refresh-hgignore", false); tikhomirov@612: File hgignoreFile = new File(repoLoc, HgRepositoryFiles.HgIgnore.getPath()); tikhomirov@612: RepoUtils.createFile(hgignoreFile, "bin/"); tikhomirov@612: HgRepository hgRepo = new HgLookup().detect(repoLoc); tikhomirov@612: final Path p1 = Path.create("bin/a/b/c"); tikhomirov@612: final Path p2 = Path.create("src/a/b/c"); tikhomirov@612: HgIgnore ignore = hgRepo.getIgnore(); tikhomirov@612: errorCollector.assertTrue(ignore.isIgnored(p1)); tikhomirov@612: errorCollector.assertFalse(ignore.isIgnored(p2)); tikhomirov@612: Thread.sleep(1000); // Linux granularity for modification time is 1 second tikhomirov@612: // file of the same length tikhomirov@612: RepoUtils.createFile(hgignoreFile, "src/"); tikhomirov@612: ignore = hgRepo.getIgnore(); tikhomirov@612: errorCollector.assertFalse(ignore.isIgnored(p1)); tikhomirov@612: errorCollector.assertTrue(ignore.isIgnored(p2)); tikhomirov@612: tikhomirov@612: } tikhomirov@612: tikhomirov@409: private void doAssert(HgIgnore hgIgnore, Path[] toIgnore, Path[] toPass) { tikhomirov@409: if (toIgnore == null && toPass == null) { tikhomirov@409: throw new IllegalArgumentException(); tikhomirov@408: } tikhomirov@409: if (toIgnore != null) { tikhomirov@409: for (Path p : toIgnore) { tikhomirov@409: errorCollector.assertTrue("Shall ignore " + p, hgIgnore.isIgnored(p)); tikhomirov@409: } tikhomirov@409: } tikhomirov@409: if (toPass != null) { tikhomirov@409: for (Path p : toPass) { tikhomirov@409: errorCollector.assertTrue("Shall pass " + p, !hgIgnore.isIgnored(p)); tikhomirov@409: } tikhomirov@408: } tikhomirov@408: } tikhomirov@269: }