From c4876d01a1b87dbea2e965cef58432eae178fdf1 Mon Sep 17 00:00:00 2001 From: Aapo Laitinen Date: Sun, 23 May 2010 21:28:23 +0300 Subject: [PATCH] Change the behavior of path.extname 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 | 5 +++-- lib/path.js | 8 ++++++-- test/simple/test-path.js | 21 +++++++++++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/doc/api.markdown b/doc/api.markdown index da0ee84e3e..6100fd928c 100644 --- a/doc/api.markdown +++ b/doc/api.markdown @@ -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 diff --git a/lib/path.js b/lib/path.js index ce21469bb3..74a998acd0 100644 --- a/lib/path.js +++ b/lib/path.js @@ -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) { diff --git a/test/simple/test-path.js b/test/simple/test-path.js index e64ab7c495..25cdaa47be 100644 --- a/test/simple/test-path.js +++ b/test/simple/test-path.js @@ -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");