// *********************************************************************** // Copyright (c) 2008 Charlie Poole // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // *********************************************************************** #define PORTABLE #define TIZEN #define NUNIT_FRAMEWORK #define NUNITLITE #define NET_4_5 #define PARALLEL #if !PORTABLE using System; using System.IO; using NUnit.Framework.Internal; namespace NUnit.Framework.Constraints { #region PathConstraint /// /// PathConstraint serves as the abstract base of constraints /// that operate on paths and provides several helper methods. /// public abstract class PathConstraint : StringConstraint { private const char WindowsDirectorySeparatorChar = '\\'; private const char NonWindowsDirectorySeparatorChar = '/'; private static readonly char[] DirectorySeparatorChars = new char[] { WindowsDirectorySeparatorChar, NonWindowsDirectorySeparatorChar }; /// /// Construct a PathConstraint for a give expected path /// /// The expected path protected PathConstraint(string expected) : base(expected) { this.expected = expected; this.caseInsensitive = Path.DirectorySeparatorChar == WindowsDirectorySeparatorChar; } /// /// Modifies the current instance to be case-sensitive /// and returns it. /// public PathConstraint RespectCase { get { caseInsensitive = false; return this; } } /// /// Returns the string representation of this constraint /// protected override string GetStringRepresentation() { return string.Format("<{0} \"{1}\" {2}>", DisplayName.ToLower(), expected, caseInsensitive ? "ignorecase" : "respectcase"); } #region Helper Methods /// /// Canonicalize the provided path /// /// /// The path in standardized form protected string Canonicalize(string path) { if (Path.DirectorySeparatorChar != Path.AltDirectorySeparatorChar) path = path.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); string leadingSeparators = ""; foreach (char c in path) { if (c == WindowsDirectorySeparatorChar || c == NonWindowsDirectorySeparatorChar) { leadingSeparators += Path.DirectorySeparatorChar; } else break; } #if !NETCF string[] parts = path.Split(DirectorySeparatorChars, StringSplitOptions.RemoveEmptyEntries); #else string[] parts = path.Split(DirectorySeparatorChars); #endif int count = 0; bool shifting = false; foreach (string part in parts) { switch (part) { case ".": case "": shifting = true; break; case "..": shifting = true; if (count > 0) --count; break; default: if (shifting) parts[count] = part; ++count; break; } } return leadingSeparators + String.Join(Path.DirectorySeparatorChar.ToString(), parts, 0, count); } /// /// Test whether one path in canonical form is a subpath of another path /// /// The first path - supposed to be the parent path /// The second path - supposed to be the child path /// protected bool IsSubPath(string path1, string path2) { int length1 = path1.Length; int length2 = path2.Length; // if path1 is longer or equal, then path2 can't be a subpath if (length1 >= length2) return false; // path 2 is longer than path 1: see if initial parts match if (!StringUtil.StringsEqual(path1, path2.Substring(0, length1), caseInsensitive)) return false; // must match through or up to a directory separator boundary return path2[length1 - 1] == Path.DirectorySeparatorChar || path2[length1] == Path.DirectorySeparatorChar; } #endregion } #endregion } #endif