// NAnt - A .NET build tool // Copyright (C) 2001-2002 Gerry Shaw // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // Gerry Shaw (gerry_shaw@yahoo.com) using System; using System.Globalization; using System.IO; using NUnit.Framework; using NAnt.Core; using Tests.NAnt.Core.Util; namespace Tests.NAnt.Core { [TestFixture] public class DirectoryScannerTest : BuildTestBase { #region Private Instance Fields private string _folder1; private string _folder2; private string _folder3; private DirectoryScanner _scanner; #endregion Private Instance Fields #region Public Instance Methods /// Test ? wildcard and / seperator. /// /// Matches all the files in the folder2 directory that being with Foo /// and one extra character and end with .txt. /// [Test] public void Test_WildcardMatching1() { string[] includedFileNames = new string[] { Path.Combine(_folder2, "Foo.txt"), Path.Combine(_folder2, "Foo1.txt"), Path.Combine(_folder2, "Foo2.txt"), }; string[] excludedFileNames = new string[] { Path.Combine(_folder2, "Foo3"), Path.Combine(_folder2, "Foo4.bar"), Path.Combine(_folder1, "Foo5.txt"), Path.Combine(_folder3, "Foo6.txt") }; _scanner.Includes.Add("folder2/Foo?.txt"); CheckScan(includedFileNames, excludedFileNames); } /// Test * wildcard. /// /// Matches all the files in base directory that end with .txt. /// [Test] public void Test_WildcardMatching2() { string[] includedFileNames = new string[] { Path.Combine(TempDirName, "Foo1.txt"), Path.Combine(TempDirName, "Foo2.txt"), }; string[] excludedFileNames = new string[] { Path.Combine(TempDirName, "Foo.bar"), Path.Combine(_folder2, "Foo3.txt"), Path.Combine(_folder3, "Foo4.txt") }; _scanner.Includes.Add(@"*.txt"); CheckScan(includedFileNames, excludedFileNames); } /// /// Test * wildcard with basedirectory ending with directory separator /// character. /// [Test] public void Test_WildcardMatching3() { string[] includedFileNames = new string[] { Path.Combine(TempDirName, "Foo1.txt"), Path.Combine(TempDirName, "Foo2.txt"), }; string[] excludedFileNames = new string[] { Path.Combine(TempDirName, "Foo.bar"), Path.Combine(_folder2, "Foo3.txt"), Path.Combine(_folder3, "Foo4.txt") }; // ensure base directory ends with directory separator character if (!_scanner.BaseDirectory.FullName.EndsWith(Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture))) { _scanner.BaseDirectory = new DirectoryInfo(_scanner.BaseDirectory.FullName + Path.DirectorySeparatorChar); } _scanner.Includes.Add(@"Foo*.txt"); CheckScan(includedFileNames, excludedFileNames); } /// /// Test * wildcard with basedirectory ending with slash /// character. /// /// /// Matches all the files in base directory that end with .txt. /// [Test] public void Test_WildcardMatching4() { string[] includedFileNames = new string[] { Path.Combine(TempDirName, "Foo1.txt"), Path.Combine(TempDirName, "Foo2.txt"), }; string[] excludedFileNames = new string[] { Path.Combine(TempDirName, "Foo.bar"), Path.Combine(_folder2, "Foo3.txt"), Path.Combine(_folder3, "Foo4.txt") }; // ensure base directory ends with slash if (!_scanner.BaseDirectory.FullName.EndsWith("/") && !_scanner.BaseDirectory.FullName.EndsWith(Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture))) { _scanner.BaseDirectory = new DirectoryInfo(_scanner.BaseDirectory.FullName + "/"); } _scanner.Includes.Add(@"Foo*.txt"); CheckScan(includedFileNames, excludedFileNames); } /// /// Test wildcard matching base directory. /// [Test] public void Test_WildcardMatching_BaseDirectory1() { string[] includedFileNames = new string[] { Path.Combine(_folder2, "Foo2.txt") }; string[] excludedFileNames = new string[] { Path.Combine(_folder2, "Foo1.txt") }; string[] includedDirs = new string[] { _folder3 }; string[] excludedDirs = new string[] { TempDirName, _folder2 }; // the folder2 directory should NOT be matched _scanner.Includes.Add("folder2/**/*"); _scanner.Excludes.Add("folder2/**/Foo1.txt"); // the folder2 directory should not be included in the DirectoryNames // collection CheckScan(includedFileNames, excludedFileNames, includedDirs, excludedDirs); } /// /// Test wildcard matching base directory. /// [Test] public void Test_WildcardMatching_BaseDirectory2() { string[] includedFileNames = new string[] { Path.Combine(_folder2, "Foo2.txt") }; string[] excludedFileNames = new string[] { Path.Combine(_folder2, "Foo1.txt") }; string[] includedDirs = new string[] { _folder2, _folder3 }; string[] excludedDirs = new string[] { TempDirName, }; // the folder2 directory should now be matched _scanner.Includes.Add("folder2/**"); _scanner.Excludes.Add("folder2/**/Foo1.txt"); // the folder2 directory should be included in the DirectoryNames // collection CheckScan(includedFileNames, excludedFileNames, includedDirs, excludedDirs); } /// /// Test wildcard matching base directory. /// [Test] public void Test_WildcardMatching_BaseDirectory3() { string tempDirBin = Path.Combine(TempDirName, "bin"); string folder1Bin = Path.Combine(_folder1, "bin"); string folder2Bin = Path.Combine(_folder2, "bin"); string folder3Bin = Path.Combine(_folder3, "bin"); string folder2BinTest = Path.Combine(folder2Bin, "test"); string[] includedFileNames = new string[] { Path.Combine(tempDirBin, "Foo2.txt"), Path.Combine(folder1Bin, "Foo.whatever"), Path.Combine(folder2BinTest, "whatever.txt"), // exclude only deals with Foo1.txt in bin directories itself Path.Combine(folder2BinTest, "Foo1.txt") }; string[] excludedFileNames = new string[] { Path.Combine(tempDirBin, "Foo1.txt"), Path.Combine(folder1Bin, "Foo1.txt"), Path.Combine(TempDirName, "whatever.txt"), Path.Combine(_folder1, "Foo.whatever.txt") }; string[] includedDirs = new string[] { tempDirBin, folder2Bin, folder3Bin, folder2BinTest }; string[] excludedDirs = new string[] { TempDirName, _folder1, _folder2, _folder3, }; // all bin directories (and their files and subdirectories) should // now be matched _scanner.Includes.Add("**/bin/**"); // exclude all Foo1.txt files that are in bin directories _scanner.Excludes.Add("**/bin/Foo1.txt"); CheckScan(includedFileNames, excludedFileNames, includedDirs, excludedDirs); } /// Tests without wildcards. /// /// Try to match the files without wildcards. /// [Test] public void Test_NoWildcardMatching1() { string[] includedFileNames = new string[] { Path.Combine(TempDirName, "Foo1.txt"), Path.Combine(_folder2, "Foo3.txt"), Path.Combine(_folder2, "Foo2.txt"), }; string[] excludedFileNames = new string[] { Path.Combine(TempDirName, "Foo.bar"), Path.Combine(_folder3, "Foo4.txt") }; _scanner.Includes.Add(@"Foo1.txt"); _scanner.Includes.Add(@"folder2/Foo2.txt"); _scanner.Includes.Add(@"folder2\Foo3.txt"); CheckScan(includedFileNames, excludedFileNames); } /// Tests without wildcards. /// /// Try to match the files without wildcards. Include a file with one slash and exclude it with the other. /// [Test] public void Test_NoWildcardMatching2() { string[] includedFileNames = new string[] { Path.Combine(TempDirName, "Foo1.txt"), Path.Combine(_folder2, "Foo3.txt"), }; string[] excludedFileNames = new string[] { Path.Combine(TempDirName, "Foo.bar"), Path.Combine(_folder2, "Foo2.txt"), Path.Combine(_folder3, "Foo4.txt") }; _scanner.Includes.Add(@"Foo1.txt"); _scanner.Includes.Add(@"folder2/Foo2.txt"); _scanner.Excludes.Add(@"folder2\Foo2.txt"); _scanner.Includes.Add(@"folder2\Foo4.txt"); _scanner.Excludes.Add(@"folder2/Foo4.txt"); _scanner.Includes.Add(@"folder2\Foo3.txt"); CheckScan(includedFileNames, excludedFileNames); } /// Tests parent directory patterns. /// /// Tests for inclusion of files in the parent directory. /// [Test] public void Test_ParentDirectory1() { string[] includedFileNames = new string[] { Path.Combine(TempDirName, "Foo1.txt"), Path.Combine(_folder2, "Foo2.txt"), Path.Combine(_folder2, "Foo3.txt"), }; string[] excludedFileNames = new string[] { Path.Combine(TempDirName, "Foo.bar"), Path.Combine(_folder3, "Foo4.txt") }; _scanner.BaseDirectory = new DirectoryInfo(_folder2); _scanner.Includes.Add(@"../Foo1.txt"); _scanner.Includes.Add(@"Foo2.txt"); _scanner.Includes.Add(@"../folder2\Foo3.txt"); CheckScan(includedFileNames, excludedFileNames); } /// Tests parent directory patterns. /// /// Tests for inclusion of files in the parent directory. /// [Test] public void Test_ParentDirectory2() { string[] includedFileNames = new string[] { Path.Combine(TempDirName, "Foo1.txt"), Path.Combine(_folder2, "Foo2.txt"), Path.Combine(_folder2, "Foo3.txt"), }; string[] excludedFileNames = new string[] { Path.Combine(TempDirName, "Foo.bar"), Path.Combine(_folder3, "Foo4.txt") }; _scanner.BaseDirectory = new DirectoryInfo(_folder2); _scanner.Includes.Add(@"../**.txt"); _scanner.Excludes.Add(@"**/Foo4.txt"); CheckScan(includedFileNames, excludedFileNames); } /// Test ** wildcard. /// /// Matches everything in the base directory and sub directories. /// [Test] public void Test_RecursiveWildcardMatching1() { string[] includedFileNames = new string[] { Path.Combine(TempDirName, "Foo1.txt"), Path.Combine(TempDirName, "Foo2.bar"), Path.Combine(_folder2, "Foo3.Foo"), Path.Combine(_folder3, "Foo4.me") }; string[] excludedFileNames = new string[] { }; _scanner.Includes.Add(@"**"); CheckScan(includedFileNames, excludedFileNames); } /// Test ** wildcard. /// /// Matches everything in the base directory and sub directories that /// ends with .txt. /// [Test] public void Test_RecursiveWildcardMatching2() { string[] includedFileNames = new string[] { Path.Combine(TempDirName, "Foo1.txt"), Path.Combine(TempDirName, "Foo2.txt"), Path.Combine(_folder2, "Foo3.txt"), Path.Combine(_folder3, "Foo4.txt") }; string[] excludedFileNames = new string[] { Path.Combine(TempDirName, "Foo2.bar"), Path.Combine(_folder2, "Foo3.bar"), Path.Combine(_folder3, "Foo4.bar") }; _scanner.Includes.Add(@"**\*.txt"); CheckScan(includedFileNames, excludedFileNames); } /// Test ** wildcard. /// /// Matches all files/dirs that start with "XYZ" and where there is a /// parent directory called 'folder3' (e.g. "abc\folder3\def\ghi\XYZ123"). /// [Test] public void Test_RecursiveWildcardMatching3() { string[] includedFileNames = new string[] { Path.Combine(_folder3, "XYZ.txt"), Path.Combine(_folder3, "XYZ.bak"), Path.Combine(_folder3, "XYZzzz.txt"), }; string[] excludedFileNames = new string[] { Path.Combine(TempDirName, "Foo2.bar"), Path.Combine(_folder2, "Foo3.bar"), Path.Combine(_folder3, "Foo4.bar") }; _scanner.Includes.Add(@"**\folder3\**\XYZ*"); CheckScan(includedFileNames, excludedFileNames); } /// Test specifying a folder both recursively and non-recursively. /// /// Matches all files/dirs that start with "XYZ" and where there is a /// parent directory called 'folder3' (e.g. "abc\folder3\def\ghi\XYZ123"). /// [Test] public void Test_RecursiveWildcardMatching4() { string[] includedFileNames = new string[] { Path.Combine(_folder3, "XYZ.txt"), Path.Combine(_folder3, "XYZ.bak"), Path.Combine(_folder3, "XYZzzz.txt"), }; string[] excludedFileNames = new string[] { Path.Combine(TempDirName, "Foo2.bar"), Path.Combine(_folder2, "Foo3.bar"), Path.Combine(_folder3, "Foo4.bar") }; _scanner.Includes.Add(@"folder3/XYZ*"); _scanner.Includes.Add(@"**\folder3\**\XYZ*"); CheckScan(includedFileNames, excludedFileNames); } /// Test excluding files. /// /// Matches all XYZ* files, but then excludes them. /// [Test] public void Test_Excludes1() { string[] includedFileNames = new string[] { }; string[] excludedFileNames = new string[] { Path.Combine(TempDirName, "Foo2.bar"), Path.Combine(_folder2, "Foo3.bar"), Path.Combine(_folder3, "Foo4.bar"), Path.Combine(_folder3, "XYZ.txt"), Path.Combine(_folder3, "XYZ.bak"), Path.Combine(_folder3, "XYZzzz.txt"), }; _scanner.Includes.Add(@"folder3/XYZ*"); _scanner.Excludes.Add(@"**\XYZ*"); CheckScan(includedFileNames, excludedFileNames); } /// Test excluding files. /// /// Matches all files, then excludes XYZ*. /// [Test] public void Test_Excludes2() { string[] includedFileNames = new string[] { Path.Combine(TempDirName, "Foo2.bar"), Path.Combine(_folder2, "Foo3.bar"), Path.Combine(_folder3, "Foo4.bar") }; string[] excludedFileNames = new string[] { Path.Combine(_folder3, "XYZ.txt"), Path.Combine(_folder3, "XYZ.bak"), Path.Combine(_folder3, "XYZzzz.txt"), }; _scanner.Includes.Add(@"**"); _scanner.Excludes.Add(@"**\XYZ*"); CheckScan(includedFileNames, excludedFileNames); } /// Test excluding files. /// /// Matches all files from the temp directory, then excludes XYZ*. See if adding a recursive exclude to a /// non-recursive include break things. /// [Test] public void Test_Excludes3() { string[] includedFileNames = new string[] { Path.Combine(TempDirName, "Foo2.bar") }; string[] excludedFileNames = new string[] { Path.Combine(_folder2, "Foo3.bar"), Path.Combine(_folder3, "Foo4.bar"), Path.Combine(_folder3, "XYZ.txt"), Path.Combine(_folder3, "XYZ.bak"), Path.Combine(_folder3, "XYZzzz.txt") }; _scanner.Includes.Add(@"*"); _scanner.Excludes.Add(@"**\XYZ*"); CheckScan(includedFileNames, excludedFileNames); } /// Test excluding files. /// /// Matches all files from the temp directory, then excludes XYZzzz.txt. See if adding an exact exclude to a /// recursive include break things. /// [Test] public void Test_Excludes4() { string[] includedFileNames = new string[] { Path.Combine(TempDirName, "Foo2.bar"), Path.Combine(_folder2, "Foo3.bar"), Path.Combine(_folder3, "Foo4.bar"), Path.Combine(_folder3, "XYZ.txt"), Path.Combine(_folder3, "XYZ.bak") }; string[] excludedFileNames = new string[] { Path.Combine(_folder3, "XYZzzz.txt") }; _scanner.Includes.Add(@"**"); _scanner.Excludes.Add(@"folder2\folder3\XYZzzz.txt"); CheckScan(includedFileNames, excludedFileNames); } /// Test excluding files. /// /// Matches all files from the temp directory, then excludes XYZzzz.txt. See if adding an exact exclude to a /// recursive include break things. /// [Test] public void Test_Dont_Match_Basedir() { string[] includedFileNames = new string[] { Path.Combine(_folder2, "Foo3.bar"), Path.Combine(_folder3, "Foo4.bar"), Path.Combine(_folder3, "XYZ.txt"), Path.Combine(_folder3, "XYZ.bak") }; string[] excludedFileNames = new string[] { Path.Combine(TempDirName, "Foo2.bar"), Path.Combine(_folder3, "XYZzzz.txt") }; _scanner.Includes.Add(@"folder2/**/*"); _scanner.Excludes.Add(@"folder2/**/XYZzzz.txt"); CheckScan(includedFileNames, excludedFileNames); } /// /// Test for bug #1195736. /// [Test] public void Test_Dont_Match_BaseDir_2() { string baseDir = CreateTempDir("NAnt.Tests.DirectoryScannerBaseDirTest"); TempFile.Create(Path.Combine(baseDir, "filea.txt")); TempFile.Create(Path.Combine(baseDir, "fileb.txt")); _scanner = new DirectoryScanner(); _scanner.BaseDirectory = new DirectoryInfo(baseDir + Path.DirectorySeparatorChar); _scanner.Includes.Add(@"filea.txt"); _scanner.Includes.Add(Path.Combine(baseDir, "fileb.txt")); _scanner.Scan(); Assert.AreEqual(2, _scanner.FileNames.Count); } #endregion Public Instance Methods #region Protected Instance Methods [SetUp] protected override void SetUp() { base.SetUp(); _folder1 = Path.Combine(TempDirName, "folder1"); _folder2 = Path.Combine(TempDirName, "folder2"); _folder3 = Path.Combine(_folder2, "folder3"); Directory.CreateDirectory(_folder1); Directory.CreateDirectory(_folder2); Directory.CreateDirectory(_folder3); _scanner = new DirectoryScanner(); _scanner.BaseDirectory = TempDirectory; } #endregion Protected Instance Methods #region Private Instance Methods /// /// Helper function for running scan tests. /// private void CheckScan(string[] includedFileNames, string[] excludedFileNames) { // create all the files foreach (string fileName in includedFileNames) { TempFile.Create(fileName); } foreach (string fileName in excludedFileNames) { TempFile.Create(fileName); } // Run the scan, _scanner.Includes and _scanner.Excludes need to have // been set up before calling this method. _scanner.Scan(); // Make sure only the included file names were picked up in the scan // and none of the excluded. foreach (string fileName in includedFileNames) { Assert.IsTrue(_scanner.FileNames.IndexOf(fileName) != -1, fileName + " not included."); } foreach (string fileName in excludedFileNames) { Assert.IsTrue(_scanner.FileNames.IndexOf(fileName) == -1, fileName + " included."); } } /// /// Helper function for running scan tests. /// private void CheckScan(string[] includedFiles, string[] excludedFiles, string[] includedDirs, string[] excludedDirs) { // create all the directories foreach (string dir in includedDirs) { if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } } foreach (string dir in excludedDirs) { if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } } CheckScan(includedFiles, excludedFiles); foreach (string dir in includedDirs) { Assert.IsTrue(_scanner.DirectoryNames.IndexOf(dir) != -1, dir + " not included."); } foreach (string dir in excludedDirs) { Assert.IsTrue(_scanner.DirectoryNames.IndexOf(dir) == -1, dir + " included."); } } #endregion Private Instance Methods } }