mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-10-16 13:31:18 +00:00
Added stringByAppendingPathComponent: and stringByAppendingPathExtension: to CPString. Also, changed CPString path behaviour to correspond to Cocoa behaviour.
This commit is contained in:
1 parent
c437537749
commit
c35ccde682
2 files changed
+193
-18
No files matched your search
+106
-14
@@ -706,14 +706,67 @@ var CPStringRegexSpecialCharacters = [
|
||||
Returns an the path components of this string. This
|
||||
method assumes that the string's content is a '/'
|
||||
separated file system path.
|
||||
Multiple '/' separators between components are truncated to a single one.
|
||||
*/
|
||||
- (CPArray)pathComponents
|
||||
{
|
||||
if (length === 0) return [""];
|
||||
if (self === "/") return ["/"];
|
||||
var result = split('/');
|
||||
if (result[0] === "")
|
||||
result[0] = "/";
|
||||
if (result[result.length - 1] === "")
|
||||
result.pop();
|
||||
var index = result.length - 1;
|
||||
if (index > 0)
|
||||
{
|
||||
if (result[index] === "")
|
||||
result[index] = "/";
|
||||
while (index--)
|
||||
{
|
||||
while (result[index] === "")
|
||||
{
|
||||
result.splice(index--, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a string built from the strings in a given array by
|
||||
concatenating them with a path separator between each pair.
|
||||
This method assumes that the string's content is a '/'
|
||||
separated file system path.
|
||||
Multiple '/' separators between components are truncated to a single one.
|
||||
*/
|
||||
+ (CPString)pathWithComponents:(CPArray)components
|
||||
{
|
||||
var size = components.length,
|
||||
result = "",
|
||||
i = -1,
|
||||
firstRound = true,
|
||||
firstIsSlash = false;
|
||||
|
||||
while (++i < size)
|
||||
{
|
||||
var component = components[i],
|
||||
lenMinusOne = component.length - 1;
|
||||
if (lenMinusOne >= 0 && (component !== "/" || firstRound)) // Skip "" and "/" (not first time)
|
||||
{
|
||||
if (lenMinusOne > 0 && component.indexOf("/",lenMinusOne) === lenMinusOne) // Ends with "/"
|
||||
component = component.substring(0, lenMinusOne);
|
||||
if (firstRound)
|
||||
{
|
||||
if (component === "/")
|
||||
firstIsSlash = true;
|
||||
firstRound = false;
|
||||
}
|
||||
else if (!firstIsSlash)
|
||||
result += "/";
|
||||
else
|
||||
firstIsSlash = false;
|
||||
result += component;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -737,33 +790,72 @@ var CPStringRegexSpecialCharacters = [
|
||||
*/
|
||||
- (CPString)lastPathComponent
|
||||
{
|
||||
var components = [self pathComponents];
|
||||
return components[components.length - 1];
|
||||
var components = [self pathComponents],
|
||||
lastIndex = components.length - 1,
|
||||
lastComponent = components[lastIndex];
|
||||
return lastIndex > 0 && lastComponent === "/" ? components[lastIndex - 1] : lastComponent;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a new string made by appending to the receiver a given string
|
||||
This method assumes that the string's content is a '/'
|
||||
separated file system path.
|
||||
Multiple '/' separators between components are truncated to a single one.
|
||||
*/
|
||||
- (CPString)stringByAppendingPathComponent:(CPString)aString
|
||||
{
|
||||
var components = [self pathComponents],
|
||||
addComponents = aString && aString !== "/" ? [aString pathComponents] : [];
|
||||
return [CPString pathWithComponents:components.concat(addComponents)];
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a new string made by appending to the receiver an extension separator followed by a given extension
|
||||
This method assumes that the extension separator is a '.'
|
||||
Extension can't include a '/' character, receiver can't be empty or be just a '/'. If so the
|
||||
result will be the receiver itself.
|
||||
Multiple '/' separators between components are truncated to a single one.
|
||||
*/
|
||||
- (CPString)stringByAppendingPathExtension:(CPString)ext
|
||||
{
|
||||
if (ext.indexOf('/') >= 0 || length === 0 || self === "/") // Can't handle these
|
||||
return self;
|
||||
var components = [self pathComponents],
|
||||
last = components.length - 1;
|
||||
|
||||
if (last > 0 && components[last] === "/")
|
||||
components.splice(last--, 1);
|
||||
|
||||
components[last] = components[last] + "." + ext;
|
||||
|
||||
return [CPString pathWithComponents:components];
|
||||
}
|
||||
|
||||
/*!
|
||||
Deletes the last path component of a string.
|
||||
This method assumes that the string's content is a '/'
|
||||
separated file system path.
|
||||
Multiple '/' separators between components are truncated to a single one.
|
||||
*/
|
||||
- (CPString)stringByDeletingLastPathComponent
|
||||
{
|
||||
var path = self,
|
||||
start = length - 1;
|
||||
if (length === 0) return "";
|
||||
if (self === "/") return "/";
|
||||
var components = [self pathComponents],
|
||||
last = components.length - 1;
|
||||
|
||||
while (path.charAt(start) === '/')
|
||||
start--;
|
||||
if (components[last] === "/")
|
||||
last--;
|
||||
components.splice(last, components.length - last);
|
||||
|
||||
path = path.substr(0, path.lastIndexOf('/', start));
|
||||
|
||||
if (path === "" && charAt(0) === '/')
|
||||
return '/';
|
||||
|
||||
return path;
|
||||
return [CPString pathWithComponents:components];
|
||||
}
|
||||
|
||||
/*!
|
||||
Deletes the extension of a string.
|
||||
This method assumes that the string's content is a '/'
|
||||
separated file system path.
|
||||
Multiple '/' separators between components are truncated to a single one.
|
||||
*/
|
||||
- (CPString)stringByDeletingPathExtension
|
||||
{
|
||||
|
||||
@@ -225,6 +225,52 @@
|
||||
[self assert:"ffffff" equals:[CPString stringWithHash:16777215]];
|
||||
}
|
||||
|
||||
- (void)testStringByAppendingPathComponent
|
||||
{
|
||||
var testStrings = [
|
||||
["/tmp/", "scratch.tiff", "/tmp/scratch.tiff"],
|
||||
["/tmp///", "scratch.tiff", "/tmp/scratch.tiff"],
|
||||
["/tmp///", "///scratch.tiff", "/tmp/scratch.tiff"],
|
||||
["/tmp", "scratch.tiff", "/tmp/scratch.tiff"],
|
||||
["/tmp///", "scratch.tiff", "/tmp/scratch.tiff"],
|
||||
["/tmp///", "///scratch.tiff", "/tmp/scratch.tiff"],
|
||||
["/", "scratch.tiff", "/scratch.tiff"],
|
||||
["", "scratch.tiff", "scratch.tiff"],
|
||||
["", "", ""],
|
||||
["", "/", ""],
|
||||
["/", "/", "/"],
|
||||
["/tmp", nil, "/tmp"],
|
||||
["/tmp", "/", "/tmp"],
|
||||
["/tmp/", "", "/tmp"]
|
||||
];
|
||||
|
||||
for (var i = 0; i < testStrings.length; i++)
|
||||
{
|
||||
var result = [testStrings[i][0] stringByAppendingPathComponent:testStrings[i][1]];
|
||||
|
||||
[self assertTrue:result === testStrings[i][2] message:"Value <" + testStrings[i][0] + "> Adding <" + testStrings[i][1] + "> Expected <" + testStrings[i][2] + "> was <" + result + ">"];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testStringByAppendingPathExtension
|
||||
{
|
||||
var testStrings = [
|
||||
["/tmp/scratch.old", "tiff", "/tmp/scratch.old.tiff"],
|
||||
["/tmp/scratch.", "tiff", "/tmp/scratch..tiff"],
|
||||
["/tmp///", "tiff", "/tmp.tiff"],
|
||||
["scratch", "tiff", "scratch.tiff"],
|
||||
["/", "tiff", "/"],
|
||||
["", "tiff", ""]
|
||||
];
|
||||
|
||||
for (var i = 0; i < testStrings.length; i++)
|
||||
{
|
||||
var result = [testStrings[i][0] stringByAppendingPathExtension:testStrings[i][1]];
|
||||
|
||||
[self assertTrue:result === testStrings[i][2] message:"Value <" + testStrings[i][0] + "> Adding <" + testStrings[i][1] + "> Expected <" + testStrings[i][2] + "> was <" + result + ">"];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testStringByDeletingLastPathComponent
|
||||
{
|
||||
var testStrings = [
|
||||
@@ -235,22 +281,58 @@
|
||||
["/", "/"],
|
||||
["scratch.tiff", ""],
|
||||
["a/b/c/d//////", "a/b/c"],
|
||||
["a/b/////////c/d//////", "a/b/c"],
|
||||
["a/b/././././c/d/./././", "a/b/././././c/d/./."],
|
||||
[@"a/b/././././d////", "a/b/./././."],
|
||||
[@"~/a", "~"],
|
||||
[@"~/a/", "~"],
|
||||
[@"../../", ".."]
|
||||
[@"../../", ".."],
|
||||
[@"", ""]
|
||||
];
|
||||
|
||||
for (var i = 0; i < testStrings.length; i++)
|
||||
[self assert:[testStrings[i][0] stringByDeletingLastPathComponent] equals:testStrings[i][1]];
|
||||
{
|
||||
var result = [testStrings[i][0] stringByDeletingLastPathComponent];
|
||||
|
||||
[self assertTrue:result === testStrings[i][1] message:"Value <" + testStrings[i][0] + "> Expected <" + testStrings[i][1] + "> was <" + result + ">"];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testPathWithComponents
|
||||
{
|
||||
var testStrings = [
|
||||
[["tmp", "scratch"], "tmp/scratch"],
|
||||
[["/", "tmp", "scratch"], "/tmp/scratch"],
|
||||
[["/", "tmp", "/", "scratch"], "/tmp/scratch"],
|
||||
[["/", "tmp", "scratch", "/"], "/tmp/scratch"],
|
||||
[["/", "tmp", "scratch", ""], "/tmp/scratch"],
|
||||
[["", "/tmp", "scratch", ""], "/tmp/scratch"],
|
||||
[["", "tmp", "scratch", ""], "tmp/scratch"],
|
||||
[["/"], "/"],
|
||||
[["/", "/", "/"], "/"],
|
||||
[["", "", ""], ""],
|
||||
[[""], ""]
|
||||
];
|
||||
|
||||
for (var i = 0; i < testStrings.length; i++)
|
||||
{
|
||||
var result = [CPString pathWithComponents:testStrings[i][0]];
|
||||
|
||||
[self assertTrue:result === testStrings[i][1] message:"Value <" + testStrings[i][0] + "> Expected [" + testStrings[i][1] + "] was [" + result + "]"];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testPathComponents
|
||||
{
|
||||
var testStrings = [
|
||||
["tmp/scratch", ["tmp", "scratch"]],
|
||||
["/tmp/scratch", ["/", "tmp", "scratch"]]
|
||||
["/tmp/scratch", ["/", "tmp", "scratch"]],
|
||||
["/tmp/scratch/", ["/", "tmp", "scratch", "/"]],
|
||||
["/tmp/", ["/", "tmp", "/"]],
|
||||
["/////tmp/////scratch///", ["/", "tmp", "scratch", "/"]],
|
||||
["scratch.tiff", ["scratch.tiff"]],
|
||||
["/", ["/"]],
|
||||
["", [""]]
|
||||
];
|
||||
|
||||
for (var i = 0; i < testStrings.length; i++)
|
||||
@@ -268,7 +350,8 @@
|
||||
["/tmp/scratch", "scratch"],
|
||||
["/tmp/", "tmp"],
|
||||
["scratch", "scratch"],
|
||||
["/", "/"]
|
||||
["/", "/"],
|
||||
["", ""]
|
||||
];
|
||||
|
||||
for (var i = 0; i < testStrings.length; i++)
|
||||
|
||||
Reference in new issue
Block a user