Change the behavior of path.extname
authorAapo Laitinen <aapo.laitinen@iki.fi>
Sun, 23 May 2010 18:28:23 +0000 (21:28 +0300)
committerRyan Dahl <ry@tinyclouds.org>
Mon, 24 May 2010 16:56:28 +0000 (09:56 -0700)
Make path.extname return an empty string also if:
- The last dot is not in the last path component
- The last dot starts the last path component

doc/api.markdown
lib/path.js
test/simple/test-path.js

index da0ee84..6100fd9 100644 (file)
@@ -2611,8 +2611,9 @@ Return the last portion of a path.  Similar to the Unix `basename` command.  Exa
 
 ### path.extname(p)
 
-Return the extension of the path.  Everything after the last '.', if there
-is no '.' then it returns an empty string.  Examples:
+Return the extension of the path.  Everything after the last '.' in the last portion
+of the path.  If there is no '.' in the last portion of the path or the only '.' is
+the first character, then it returns an empty string.  Examples:
 
     path.extname('index.html')
     // returns 
index ce21469..74a998a 100644 (file)
@@ -66,8 +66,12 @@ exports.basename = function (path, ext) {
 };
 
 exports.extname = function (path) {
-  var index = path.lastIndexOf('.');
-  return index < 0 ? '' : path.substring(index);
+  var dot = path.lastIndexOf('.'),
+      slash = path.lastIndexOf('/');
+  // The last dot must be in the last path component, and it (the last dot) must
+  // not start the last path component (i.e. be a dot that signifies a hidden
+  // file in UNIX).
+  return dot <= slash + 1 ? '' : path.substring(dot);
 };
 
 exports.exists = function (path, callback) {
index e64ab7c..25cdaa4 100644 (file)
@@ -12,6 +12,27 @@ assert.equal(path.dirname("/a"), "/");
 assert.equal(path.dirname("/"), "/");
 path.exists(f, function (y) { assert.equal(y, true) });
 
+assert.equal(path.extname(""), "");
+assert.equal(path.extname("/path/to/file"), "");
+assert.equal(path.extname("/path/to/file.ext"), ".ext");
+assert.equal(path.extname("/path.to/file.ext"), ".ext");
+assert.equal(path.extname("/path.to/file"), "");
+assert.equal(path.extname("/path.to/.file"), "");
+assert.equal(path.extname("/path.to/.file.ext"), ".ext");
+assert.equal(path.extname("/path/to/f.ext"), ".ext");
+assert.equal(path.extname("/path/to/..ext"), ".ext");
+assert.equal(path.extname("file"), "");
+assert.equal(path.extname("file.ext"), ".ext");
+assert.equal(path.extname(".file"), "");
+assert.equal(path.extname(".file.ext"), ".ext");
+assert.equal(path.extname("/file"), "");
+assert.equal(path.extname("/file.ext"), ".ext");
+assert.equal(path.extname("/.file"), "");
+assert.equal(path.extname("/.file.ext"), ".ext");
+assert.equal(path.extname(".path/file.ext"), ".ext");
+assert.equal(path.extname("file.ext.ext"), ".ext");
+assert.equal(path.extname("file."), ".");
+
 assert.equal(path.join(".", "fixtures/b", "..", "/b/c.js"), "fixtures/b/c.js");
 
 assert.equal(path.normalize("./fixtures///b/../b/c.js"), "fixtures/b/c.js");