Skip to content

Commit 0bf2a20

Browse files
Merge pull request #13 from browserify/tests
Port tests from node core
2 parents 4c66781 + 4df8c2a commit 0bf2a20

14 files changed

+1022
-63
lines changed

.travis.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
language: node_js
2+
sudo: false
3+
node_js:
4+
- "10"
5+
- "9"
6+
- "8"
7+
- "6"
8+
- "4"
9+
- "iojs"
10+
- "0.12"
11+
- "0.10"
12+
- "0.8"
13+
before_install:
14+
# Old npm certs are untrusted https://github.com/npm/npm/issues/20191
15+
- 'if [ "${TRAVIS_NODE_VERSION}" = "0.6" ] || [ "${TRAVIS_NODE_VERSION}" = "0.8" ]; then export NPM_CONFIG_STRICT_SSL=false; fi'
16+
- 'nvm install-latest-npm'

index.js

Lines changed: 97 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -38,45 +38,56 @@ function normalizeStringPosix(path, allowAboveRoot) {
3838
var dots = 0;
3939
var code;
4040
for (var i = 0; i <= path.length; ++i) {
41-
if (i < path.length) code = path.charCodeAt(i);else if (code === 47 /*/*/) break;else code = 47 /*/*/;
41+
if (i < path.length)
42+
code = path.charCodeAt(i);
43+
else if (code === 47 /*/*/)
44+
break;
45+
else
46+
code = 47 /*/*/;
4247
if (code === 47 /*/*/) {
43-
if (lastSlash === i - 1 || dots === 1) {
44-
// NOOP
45-
} else if (lastSlash !== i - 1 && dots === 2) {
46-
if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 /*.*/ || res.charCodeAt(res.length - 2) !== 46 /*.*/) {
47-
if (res.length > 2) {
48-
var lastSlashIndex = res.lastIndexOf('/');
49-
if (lastSlashIndex !== res.length - 1) {
50-
if (lastSlashIndex === -1) {
51-
res = '';
52-
lastSegmentLength = 0;
53-
} else {
54-
res = res.slice(0, lastSlashIndex);
55-
lastSegmentLength = res.length - 1 - res.lastIndexOf('/');
56-
}
57-
lastSlash = i;
58-
dots = 0;
59-
continue;
60-
}
61-
} else if (res.length === 2 || res.length === 1) {
48+
if (lastSlash === i - 1 || dots === 1) {
49+
// NOOP
50+
} else if (lastSlash !== i - 1 && dots === 2) {
51+
if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 /*.*/ || res.charCodeAt(res.length - 2) !== 46 /*.*/) {
52+
if (res.length > 2) {
53+
var lastSlashIndex = res.lastIndexOf('/');
54+
if (lastSlashIndex !== res.length - 1) {
55+
if (lastSlashIndex === -1) {
6256
res = '';
6357
lastSegmentLength = 0;
64-
lastSlash = i;
65-
dots = 0;
66-
continue;
58+
} else {
59+
res = res.slice(0, lastSlashIndex);
60+
lastSegmentLength = res.length - 1 - res.lastIndexOf('/');
6761
}
62+
lastSlash = i;
63+
dots = 0;
64+
continue;
6865
}
69-
if (allowAboveRoot) {
70-
if (res.length > 0) res += '/..';else res = '..';
71-
lastSegmentLength = 2;
66+
} else if (res.length === 2 || res.length === 1) {
67+
res = '';
68+
lastSegmentLength = 0;
69+
lastSlash = i;
70+
dots = 0;
71+
continue;
7272
}
73-
} else {
74-
if (res.length > 0) res += '/' + path.slice(lastSlash + 1, i);else res = path.slice(lastSlash + 1, i);
75-
lastSegmentLength = i - lastSlash - 1;
7673
}
77-
lastSlash = i;
78-
dots = 0;
79-
} else if (code === 46 /*.*/ && dots !== -1) {
74+
if (allowAboveRoot) {
75+
if (res.length > 0)
76+
res += '/..';
77+
else
78+
res = '..';
79+
lastSegmentLength = 2;
80+
}
81+
} else {
82+
if (res.length > 0)
83+
res += '/' + path.slice(lastSlash + 1, i);
84+
else
85+
res = path.slice(lastSlash + 1, i);
86+
lastSegmentLength = i - lastSlash - 1;
87+
}
88+
lastSlash = i;
89+
dots = 0;
90+
} else if (code === 46 /*.*/ && dots !== -1) {
8091
++dots;
8192
} else {
8293
dots = -1;
@@ -106,8 +117,11 @@ var posix = {
106117

107118
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
108119
var path;
109-
if (i >= 0) path = arguments[i];else {
110-
if (cwd === undefined) cwd = process.cwd();
120+
if (i >= 0)
121+
path = arguments[i];
122+
else {
123+
if (cwd === undefined)
124+
cwd = process.cwd();
111125
path = cwd;
112126
}
113127

@@ -129,7 +143,10 @@ var posix = {
129143
resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute);
130144

131145
if (resolvedAbsolute) {
132-
if (resolvedPath.length > 0) return '/' + resolvedPath;else return '/';
146+
if (resolvedPath.length > 0)
147+
return '/' + resolvedPath;
148+
else
149+
return '/';
133150
} else if (resolvedPath.length > 0) {
134151
return resolvedPath;
135152
} else {
@@ -161,16 +178,21 @@ var posix = {
161178
},
162179

163180
join: function join() {
164-
if (arguments.length === 0) return '.';
181+
if (arguments.length === 0)
182+
return '.';
165183
var joined;
166184
for (var i = 0; i < arguments.length; ++i) {
167185
var arg = arguments[i];
168186
assertPath(arg);
169187
if (arg.length > 0) {
170-
if (joined === undefined) joined = arg;else joined += '/' + arg;
188+
if (joined === undefined)
189+
joined = arg;
190+
else
191+
joined += '/' + arg;
171192
}
172193
}
173-
if (joined === undefined) return '.';
194+
if (joined === undefined)
195+
return '.';
174196
return posix.normalize(joined);
175197
},
176198

@@ -188,15 +210,17 @@ var posix = {
188210
// Trim any leading backslashes
189211
var fromStart = 1;
190212
for (; fromStart < from.length; ++fromStart) {
191-
if (from.charCodeAt(fromStart) !== 47 /*/*/) break;
213+
if (from.charCodeAt(fromStart) !== 47 /*/*/)
214+
break;
192215
}
193216
var fromEnd = from.length;
194217
var fromLen = fromEnd - fromStart;
195218

196219
// Trim any leading backslashes
197220
var toStart = 1;
198221
for (; toStart < to.length; ++toStart) {
199-
if (to.charCodeAt(toStart) !== 47 /*/*/) break;
222+
if (to.charCodeAt(toStart) !== 47 /*/*/)
223+
break;
200224
}
201225
var toEnd = to.length;
202226
var toLen = toEnd - toStart;
@@ -209,20 +233,20 @@ var posix = {
209233
if (i === length) {
210234
if (toLen > length) {
211235
if (to.charCodeAt(toStart + i) === 47 /*/*/) {
212-
// We get here if `from` is the exact base path for `to`.
213-
// For example: from='/foo/bar'; to='/foo/bar/baz'
214-
return to.slice(toStart + i + 1);
215-
} else if (i === 0) {
236+
// We get here if `from` is the exact base path for `to`.
237+
// For example: from='/foo/bar'; to='/foo/bar/baz'
238+
return to.slice(toStart + i + 1);
239+
} else if (i === 0) {
216240
// We get here if `from` is the root
217241
// For example: from='/'; to='/foo'
218242
return to.slice(toStart + i);
219243
}
220244
} else if (fromLen > length) {
221245
if (from.charCodeAt(fromStart + i) === 47 /*/*/) {
222-
// We get here if `to` is the exact base path for `from`.
223-
// For example: from='/foo/bar/baz'; to='/foo/bar'
224-
lastCommonSep = i;
225-
} else if (i === 0) {
246+
// We get here if `to` is the exact base path for `from`.
247+
// For example: from='/foo/bar/baz'; to='/foo/bar'
248+
lastCommonSep = i;
249+
} else if (i === 0) {
226250
// We get here if `to` is the root.
227251
// For example: from='/foo'; to='/'
228252
lastCommonSep = 0;
@@ -232,23 +256,32 @@ var posix = {
232256
}
233257
var fromCode = from.charCodeAt(fromStart + i);
234258
var toCode = to.charCodeAt(toStart + i);
235-
if (fromCode !== toCode) break;else if (fromCode === 47 /*/*/) lastCommonSep = i;
259+
if (fromCode !== toCode)
260+
break;
261+
else if (fromCode === 47 /*/*/)
262+
lastCommonSep = i;
236263
}
237264

238265
var out = '';
239266
// Generate the relative path based on the path difference between `to`
240267
// and `from`
241268
for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {
242269
if (i === fromEnd || from.charCodeAt(i) === 47 /*/*/) {
243-
if (out.length === 0) out += '..';else out += '/..';
244-
}
270+
if (out.length === 0)
271+
out += '..';
272+
else
273+
out += '/..';
274+
}
245275
}
246276

247277
// Lastly, append the rest of the destination (`to`) path that comes after
248278
// the common path parts
249-
if (out.length > 0) return out + to.slice(toStart + lastCommonSep);else {
279+
if (out.length > 0)
280+
return out + to.slice(toStart + lastCommonSep);
281+
else {
250282
toStart += lastCommonSep;
251-
if (to.charCodeAt(toStart) === 47 /*/*/) ++toStart;
283+
if (to.charCodeAt(toStart) === 47 /*/*/)
284+
++toStart;
252285
return to.slice(toStart);
253286
}
254287
},
@@ -381,27 +414,30 @@ var posix = {
381414
}
382415
if (code === 46 /*.*/) {
383416
// If this is our first dot, mark it as the start of our extension
384-
if (startDot === -1) startDot = i;else if (preDotState !== 1) preDotState = 1;
385-
} else if (startDot !== -1) {
417+
if (startDot === -1)
418+
startDot = i;
419+
else if (preDotState !== 1)
420+
preDotState = 1;
421+
} else if (startDot !== -1) {
386422
// We saw a non-dot and non-path separator before our dot, so we should
387423
// have a good chance at having a non-empty extension
388424
preDotState = -1;
389425
}
390426
}
391427

392428
if (startDot === -1 || end === -1 ||
393-
// We saw a non-dot character immediately before the dot
394-
preDotState === 0 ||
395-
// The (right-most) trimmed path component is exactly '..'
396-
preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
429+
// We saw a non-dot character immediately before the dot
430+
preDotState === 0 ||
431+
// The (right-most) trimmed path component is exactly '..'
432+
preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
397433
return '';
398434
}
399435
return path.slice(startDot, end);
400436
},
401437

402438
format: function format(pathObject) {
403-
if (pathObject === null || typeof pathObject === 'undefined') {
404-
throw new TypeError('Parameter "pathObject" must be an object, not ' + (typeof pathObject));
439+
if (pathObject === null || typeof pathObject !== 'object') {
440+
throw new TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof pathObject);
405441
}
406442
return _format('/', pathObject);
407443
},

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
"main": "index.js",
66
"dependencies": {},
77
"devDependencies": {
8-
"tape": "~1.0.4"
8+
"tape": "^4.9.0"
99
},
1010
"scripts": {
11-
"test": "tape test/*.js"
11+
"test": "node test"
1212
},
1313
"repository": {
1414
"type": "git",

test/index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
require('./test-path');
2+
require('./test-path-basename');
3+
require('./test-path-dirname');
4+
require('./test-path-extname');
5+
require('./test-path-isabsolute');
6+
require('./test-path-join');
7+
require('./test-path-relative');
8+
require('./test-path-resolve');
9+
require('./test-path-zero-length-strings');

test/test-path-basename.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
'use strict';
2+
var tape = require('tape');
3+
var path = require('../');
4+
5+
tape('path.basename', function (t) {
6+
t.strictEqual(path.basename(__filename), 'test-path-basename.js');
7+
t.strictEqual(path.basename(__filename, '.js'), 'test-path-basename');
8+
t.strictEqual(path.basename('.js', '.js'), '');
9+
t.strictEqual(path.basename(''), '');
10+
t.strictEqual(path.basename('/dir/basename.ext'), 'basename.ext');
11+
t.strictEqual(path.basename('/basename.ext'), 'basename.ext');
12+
t.strictEqual(path.basename('basename.ext'), 'basename.ext');
13+
t.strictEqual(path.basename('basename.ext/'), 'basename.ext');
14+
t.strictEqual(path.basename('basename.ext//'), 'basename.ext');
15+
t.strictEqual(path.basename('aaa/bbb', '/bbb'), 'bbb');
16+
t.strictEqual(path.basename('aaa/bbb', 'a/bbb'), 'bbb');
17+
t.strictEqual(path.basename('aaa/bbb', 'bbb'), 'bbb');
18+
t.strictEqual(path.basename('aaa/bbb//', 'bbb'), 'bbb');
19+
t.strictEqual(path.basename('aaa/bbb', 'bb'), 'b');
20+
t.strictEqual(path.basename('aaa/bbb', 'b'), 'bb');
21+
t.strictEqual(path.basename('/aaa/bbb', '/bbb'), 'bbb');
22+
t.strictEqual(path.basename('/aaa/bbb', 'a/bbb'), 'bbb');
23+
t.strictEqual(path.basename('/aaa/bbb', 'bbb'), 'bbb');
24+
t.strictEqual(path.basename('/aaa/bbb//', 'bbb'), 'bbb');
25+
t.strictEqual(path.basename('/aaa/bbb', 'bb'), 'b');
26+
t.strictEqual(path.basename('/aaa/bbb', 'b'), 'bb');
27+
t.strictEqual(path.basename('/aaa/bbb'), 'bbb');
28+
t.strictEqual(path.basename('/aaa/'), 'aaa');
29+
t.strictEqual(path.basename('/aaa/b'), 'b');
30+
t.strictEqual(path.basename('/a/b'), 'b');
31+
t.strictEqual(path.basename('//a'), 'a');
32+
t.end();
33+
})
34+
35+
tape('path.win32.basename', { skip: true }, function (t) {
36+
// On Windows a backslash acts as a path separator.
37+
t.strictEqual(path.win32.basename('\\dir\\basename.ext'), 'basename.ext');
38+
t.strictEqual(path.win32.basename('\\basename.ext'), 'basename.ext');
39+
t.strictEqual(path.win32.basename('basename.ext'), 'basename.ext');
40+
t.strictEqual(path.win32.basename('basename.ext\\'), 'basename.ext');
41+
t.strictEqual(path.win32.basename('basename.ext\\\\'), 'basename.ext');
42+
t.strictEqual(path.win32.basename('foo'), 'foo');
43+
t.strictEqual(path.win32.basename('aaa\\bbb', '\\bbb'), 'bbb');
44+
t.strictEqual(path.win32.basename('aaa\\bbb', 'a\\bbb'), 'bbb');
45+
t.strictEqual(path.win32.basename('aaa\\bbb', 'bbb'), 'bbb');
46+
t.strictEqual(path.win32.basename('aaa\\bbb\\\\\\\\', 'bbb'), 'bbb');
47+
t.strictEqual(path.win32.basename('aaa\\bbb', 'bb'), 'b');
48+
t.strictEqual(path.win32.basename('aaa\\bbb', 'b'), 'bb');
49+
t.strictEqual(path.win32.basename('C:'), '');
50+
t.strictEqual(path.win32.basename('C:.'), '.');
51+
t.strictEqual(path.win32.basename('C:\\'), '');
52+
t.strictEqual(path.win32.basename('C:\\dir\\base.ext'), 'base.ext');
53+
t.strictEqual(path.win32.basename('C:\\basename.ext'), 'basename.ext');
54+
t.strictEqual(path.win32.basename('C:basename.ext'), 'basename.ext');
55+
t.strictEqual(path.win32.basename('C:basename.ext\\'), 'basename.ext');
56+
t.strictEqual(path.win32.basename('C:basename.ext\\\\'), 'basename.ext');
57+
t.strictEqual(path.win32.basename('C:foo'), 'foo');
58+
t.strictEqual(path.win32.basename('file:stream'), 'file:stream');
59+
t.end();
60+
});
61+
62+
tape('On unix a backslash is just treated as any other character.', function (t) {
63+
t.strictEqual(path.posix.basename('\\dir\\basename.ext'),
64+
'\\dir\\basename.ext');
65+
t.strictEqual(path.posix.basename('\\basename.ext'), '\\basename.ext');
66+
t.strictEqual(path.posix.basename('basename.ext'), 'basename.ext');
67+
t.strictEqual(path.posix.basename('basename.ext\\'), 'basename.ext\\');
68+
t.strictEqual(path.posix.basename('basename.ext\\\\'), 'basename.ext\\\\');
69+
t.strictEqual(path.posix.basename('foo'), 'foo');
70+
t.end();
71+
});
72+
73+
tape('POSIX filenames may include control characters', function (t) {
74+
// c.f. http://www.dwheeler.com/essays/fixing-unix-linux-filenames.html
75+
var controlCharFilename = "Icon" + (String.fromCharCode(13));
76+
t.strictEqual(path.posix.basename(("/a/b/" + controlCharFilename)),
77+
controlCharFilename);
78+
t.end();
79+
});

0 commit comments

Comments
 (0)