globule_test.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. 'use strict';
  2. var path = require('path');
  3. var globule = require('../lib/globule.js');
  4. /*
  5. ======== A Handy Little Nodeunit Reference ========
  6. https://github.com/caolan/nodeunit
  7. Test methods:
  8. test.expect(numAssertions)
  9. test.done()
  10. Test assertions:
  11. test.ok(value, [message])
  12. test.equal(actual, expected, [message])
  13. test.notEqual(actual, expected, [message])
  14. test.deepEqual(actual, expected, [message])
  15. test.notDeepEqual(actual, expected, [message])
  16. test.strictEqual(actual, expected, [message])
  17. test.notStrictEqual(actual, expected, [message])
  18. test.throws(block, [error], [message])
  19. test.doesNotThrow(block, [error], [message])
  20. test.ifError(value)
  21. */
  22. exports['match'] = {
  23. 'empty set': function(test) {
  24. test.expect(6);
  25. // Should return empty set if a required argument is missing or an empty set.
  26. test.deepEqual(globule.match(null, 'foo.js'), [], 'should return empty set.');
  27. test.deepEqual(globule.match('*.js', null), [], 'should return empty set.');
  28. test.deepEqual(globule.match([], 'foo.js'), [], 'should return empty set.');
  29. test.deepEqual(globule.match('*.js', []), [], 'should return empty set.');
  30. test.deepEqual(globule.match(null, ['foo.js']), [], 'should return empty set.');
  31. test.deepEqual(globule.match(['*.js'], null), [], 'should return empty set.');
  32. test.done();
  33. },
  34. 'basic matching': function(test) {
  35. test.expect(6);
  36. test.deepEqual(globule.match('*.js', 'foo.js'), ['foo.js'], 'should match correctly.');
  37. test.deepEqual(globule.match('*.js', ['foo.js']), ['foo.js'], 'should match correctly.');
  38. test.deepEqual(globule.match('*.js', ['foo.js', 'bar.css']), ['foo.js'], 'should match correctly.');
  39. test.deepEqual(globule.match(['*.js', '*.css'], 'foo.js'), ['foo.js'], 'should match correctly.');
  40. test.deepEqual(globule.match(['*.js', '*.css'], ['foo.js']), ['foo.js'], 'should match correctly.');
  41. test.deepEqual(globule.match(['*.js', '*.css'], ['foo.js', 'bar.css']), ['foo.js', 'bar.css'], 'should match correctly.');
  42. test.done();
  43. },
  44. 'no matches': function(test) {
  45. test.expect(2);
  46. test.deepEqual(globule.match('*.js', 'foo.css'), [], 'should fail to match.');
  47. test.deepEqual(globule.match('*.js', ['foo.css', 'bar.css']), [], 'should fail to match.');
  48. test.done();
  49. },
  50. 'unique': function(test) {
  51. test.expect(2);
  52. test.deepEqual(globule.match('*.js', ['foo.js', 'foo.js']), ['foo.js'], 'should return a uniqued set.');
  53. test.deepEqual(globule.match(['*.js', '*.*'], ['foo.js', 'foo.js']), ['foo.js'], 'should return a uniqued set.');
  54. test.done();
  55. },
  56. 'flatten': function(test) {
  57. test.expect(1);
  58. test.deepEqual(globule.match([['*.js', '*.css'], ['*.*', '*.js']], ['foo.js', 'bar.css']),
  59. ['foo.js', 'bar.css'],
  60. 'should process nested pattern arrays correctly.');
  61. test.done();
  62. },
  63. 'exclusion': function(test) {
  64. test.expect(5);
  65. test.deepEqual(globule.match(['!*.js'], ['foo.js', 'bar.js']), [], 'solitary exclusion should match nothing');
  66. test.deepEqual(globule.match(['*.js', '!*.js'], ['foo.js', 'bar.js']), [], 'exclusion should cancel match');
  67. test.deepEqual(globule.match(['*.js', '!f*.js'], ['foo.js', 'bar.js', 'baz.js']),
  68. ['bar.js', 'baz.js'],
  69. 'partial exclusion should partially cancel match');
  70. test.deepEqual(globule.match(['*.js', '!*.js', 'b*.js'], ['foo.js', 'bar.js', 'baz.js']),
  71. ['bar.js', 'baz.js'],
  72. 'inclusion / exclusion order matters');
  73. test.deepEqual(globule.match(['*.js', '!f*.js', '*.js'], ['foo.js', 'bar.js', 'baz.js']),
  74. ['bar.js', 'baz.js', 'foo.js'],
  75. 'inclusion / exclusion order matters');
  76. test.done();
  77. },
  78. 'options.matchBase': function(test) {
  79. test.expect(2);
  80. test.deepEqual(globule.match('*.js', ['foo.js', 'bar', 'baz/xyz.js'], {matchBase: true}),
  81. ['foo.js', 'baz/xyz.js'],
  82. 'should matchBase (minimatch) when specified.');
  83. test.deepEqual(globule.match('*.js', ['foo.js', 'bar', 'baz/xyz.js']),
  84. ['foo.js'],
  85. 'should not matchBase (minimatch) by default.');
  86. test.done();
  87. },
  88. };
  89. exports['isMatch'] = {
  90. 'basic matching': function(test) {
  91. test.expect(6);
  92. test.ok(globule.isMatch('*.js', 'foo.js'), 'should match correctly.');
  93. test.ok(globule.isMatch('*.js', ['foo.js']), 'should match correctly.');
  94. test.ok(globule.isMatch('*.js', ['foo.js', 'bar.css']), 'should match correctly.');
  95. test.ok(globule.isMatch(['*.js', '*.css'], 'foo.js'), 'should match correctly.');
  96. test.ok(globule.isMatch(['*.js', '*.css'], ['foo.js']), 'should match correctly.');
  97. test.ok(globule.isMatch(['*.js', '*.css'], ['foo.js', 'bar.css']), 'should match correctly.');
  98. test.done();
  99. },
  100. 'no matches': function(test) {
  101. test.expect(6);
  102. test.ok(!globule.isMatch('*.js', 'foo.css'), 'should fail to match.');
  103. test.ok(!globule.isMatch('*.js', ['foo.css', 'bar.css']), 'should fail to match.');
  104. test.ok(!globule.isMatch(null, 'foo.css'), 'should fail to match.');
  105. test.ok(!globule.isMatch('*.js', null), 'should fail to match.');
  106. test.ok(!globule.isMatch([], 'foo.css'), 'should fail to match.');
  107. test.ok(!globule.isMatch('*.js', []), 'should fail to match.');
  108. test.done();
  109. },
  110. 'options.matchBase': function(test) {
  111. test.expect(2);
  112. test.ok(globule.isMatch('*.js', ['baz/xyz.js'], {matchBase: true}), 'should matchBase (minimatch) when specified.');
  113. test.ok(!globule.isMatch('*.js', ['baz/xyz.js']), 'should not matchBase (minimatch) by default.');
  114. test.done();
  115. },
  116. };
  117. exports['find'] = {
  118. setUp: function(done) {
  119. this.cwd = process.cwd();
  120. process.chdir('test/fixtures/expand');
  121. done();
  122. },
  123. tearDown: function(done) {
  124. process.chdir(this.cwd);
  125. done();
  126. },
  127. 'basic matching': function(test) {
  128. test.expect(5);
  129. test.deepEqual(globule.find('**/*.js'), ['js/bar.js', 'js/foo.js'], 'single pattern argument should match.');
  130. test.deepEqual(globule.find('**/*.js', '**/*.css'),
  131. ['js/bar.js', 'js/foo.js', 'css/baz.css', 'css/qux.css'],
  132. 'multiple pattern arguments should match.');
  133. test.deepEqual(globule.find(['**/*.js', '**/*.css']),
  134. ['js/bar.js', 'js/foo.js', 'css/baz.css', 'css/qux.css'],
  135. 'array of patterns should match.');
  136. test.deepEqual(globule.find([['**/*.js'], [['**/*.css', 'js/*.js']]]),
  137. ['js/bar.js', 'js/foo.js', 'css/baz.css', 'css/qux.css'],
  138. 'array of arrays of patterns should be flattened.');
  139. test.deepEqual(globule.find('*.xyz'), [], 'bad pattern should fail to match.');
  140. test.done();
  141. },
  142. 'unique': function(test) {
  143. test.expect(4);
  144. test.deepEqual(globule.find('**/*.js', 'js/*.js'),
  145. ['js/bar.js', 'js/foo.js'],
  146. 'file list should be uniqed.');
  147. test.deepEqual(globule.find('**/*.js', '**/*.css', 'js/*.js'), ['js/bar.js', 'js/foo.js',
  148. 'css/baz.css', 'css/qux.css'],
  149. 'file list should be uniqed.');
  150. test.deepEqual(globule.find('js', 'js/'),
  151. ['js', 'js/'],
  152. 'mixed non-ending-/ and ending-/ dirs will not be uniqed by default.');
  153. test.deepEqual(globule.find('js', 'js/', {mark: true}),
  154. ['js/'],
  155. 'mixed non-ending-/ and ending-/ dirs will be uniqed when "mark" is specified.');
  156. test.done();
  157. },
  158. 'file order': function(test) {
  159. test.expect(5);
  160. var actual = globule.find('**/*.{js,css}');
  161. var expected = ['css/baz.css', 'css/qux.css', 'js/bar.js', 'js/foo.js'];
  162. test.deepEqual(actual, expected, 'should select 4 files in this order, by default.');
  163. actual = globule.find('js/foo.js', 'js/bar.js', '**/*.{js,css}');
  164. expected = ['js/foo.js', 'js/bar.js', 'css/baz.css', 'css/qux.css'];
  165. test.deepEqual(actual, expected, 'specifically-specified-up-front file order should be maintained.');
  166. actual = globule.find('js/bar.js', 'js/foo.js', '**/*.{js,css}');
  167. expected = ['js/bar.js', 'js/foo.js', 'css/baz.css', 'css/qux.css'];
  168. test.deepEqual(actual, expected, 'specifically-specified-up-front file order should be maintained.');
  169. actual = globule.find('**/*.{js,css}', '!css/qux.css', 'css/qux.css');
  170. expected = ['css/baz.css', 'js/bar.js', 'js/foo.js', 'css/qux.css'];
  171. test.deepEqual(actual, expected, 'if a file is excluded and then re-added, it should be added at the end.');
  172. actual = globule.find('js/foo.js', '**/*.{js,css}', '!css/qux.css', 'css/qux.css');
  173. expected = ['js/foo.js', 'css/baz.css', 'js/bar.js', 'css/qux.css'];
  174. test.deepEqual(actual, expected, 'should be able to combine specified-up-front and excluded/added-at-end.');
  175. test.done();
  176. },
  177. 'exclusion': function(test) {
  178. test.expect(8);
  179. test.deepEqual(globule.find(['!js/*.js']), [], 'solitary exclusion should match nothing');
  180. test.deepEqual(globule.find(['js/bar.js','!js/bar.js']), [], 'exclusion should negate match');
  181. test.deepEqual(globule.find(['**/*.js', '!js/foo.js']),
  182. ['js/bar.js'],
  183. 'should omit single file from matched set');
  184. test.deepEqual(globule.find(['!js/foo.js', '**/*.js']),
  185. ['js/bar.js', 'js/foo.js'],
  186. 'inclusion / exclusion order matters');
  187. test.deepEqual(globule.find(['**/*.js', '**/*.css', '!js/bar.js', '!css/baz.css']),
  188. ['js/foo.js','css/qux.css'],
  189. 'multiple exclusions should be removed from the set');
  190. test.deepEqual(globule.find(['**/*.js', '**/*.css', '!**/*.css']),
  191. ['js/bar.js', 'js/foo.js'],
  192. 'excluded wildcards should be removed from the matched set');
  193. test.deepEqual(globule.find(['js/bar.js', 'js/foo.js', 'css/baz.css', 'css/qux.css', '!**/b*.*']),
  194. ['js/foo.js', 'css/qux.css'],
  195. 'different pattern for exclusion should still work');
  196. test.deepEqual(globule.find(['js/bar.js', '!**/b*.*', 'js/foo.js', 'css/baz.css', 'css/qux.css']),
  197. ['js/foo.js', 'css/baz.css', 'css/qux.css'],
  198. 'inclusion / exclusion order matters');
  199. test.done();
  200. },
  201. 'options.mark': function(test) {
  202. test.expect(4);
  203. test.deepEqual(globule.find('**d*/**'), [
  204. 'deep',
  205. 'deep/deep.txt',
  206. 'deep/deeper',
  207. 'deep/deeper/deeper.txt',
  208. 'deep/deeper/deepest',
  209. 'deep/deeper/deepest/deepest.txt'], 'should match files and directories.');
  210. test.deepEqual(globule.find('**d*/**/'), [
  211. 'deep/',
  212. 'deep/deeper/',
  213. 'deep/deeper/deepest/'], 'trailing / in pattern should match directories only, matches end in /.');
  214. test.deepEqual(globule.find('**d*/**', {mark: true}), [
  215. 'deep/',
  216. 'deep/deep.txt',
  217. 'deep/deeper/',
  218. 'deep/deeper/deeper.txt',
  219. 'deep/deeper/deepest/',
  220. 'deep/deeper/deepest/deepest.txt'], 'the minimatch "mark" option ensures directories end in /.');
  221. test.deepEqual(globule.find('**d*/**/', {mark: true}), [
  222. 'deep/',
  223. 'deep/deeper/',
  224. 'deep/deeper/deepest/'], 'the minimatch "mark" option should not remove trailing / from matched paths.');
  225. test.done();
  226. },
  227. 'options.filter': function(test) {
  228. test.expect(5);
  229. test.deepEqual(globule.find('**d*/**', {filter: 'isFile'}), [
  230. 'deep/deep.txt',
  231. 'deep/deeper/deeper.txt',
  232. 'deep/deeper/deepest/deepest.txt'
  233. ], 'should match files only.');
  234. test.deepEqual(globule.find('**d*/**', {filter: 'isDirectory'}), [
  235. 'deep',
  236. 'deep/deeper',
  237. 'deep/deeper/deepest'
  238. ], 'should match directories only.');
  239. test.deepEqual(globule.find('**', {
  240. arbitraryProp: /deepest/,
  241. filter: function(filepath, options) {
  242. return options.arbitraryProp.test(filepath);
  243. }
  244. }), [
  245. 'deep/deeper/deepest',
  246. 'deep/deeper/deepest/deepest.txt',
  247. ], 'should filter arbitrarily.');
  248. test.deepEqual(globule.find('js', 'css', {filter: 'isFile'}), [], 'should fail to match.');
  249. test.deepEqual(globule.find('**/*.js', {filter: 'isDirectory'}), [], 'should fail to match.');
  250. test.done();
  251. },
  252. 'options.matchBase': function(test) {
  253. test.expect(3);
  254. test.deepEqual(globule.find('*.js'), [], 'should not matchBase (minimatch) by default.');
  255. test.deepEqual(globule.find('*.js', {matchBase: true}),
  256. ['js/bar.js', 'js/foo.js'],
  257. 'matchBase option should be passed through to minimatch.');
  258. test.deepEqual(globule.find('*.js', '*.css', {matchBase: true}),
  259. ['js/bar.js', 'js/foo.js', 'css/baz.css', 'css/qux.css'],
  260. 'matchBase option should be passed through to minimatch.');
  261. test.done();
  262. },
  263. 'options.srcBase': function(test) {
  264. test.expect(5);
  265. test.deepEqual(globule.find(['**/deep*.txt'], {srcBase: 'deep'}),
  266. ['deep.txt', 'deeper/deeper.txt', 'deeper/deepest/deepest.txt'],
  267. 'should find paths matching pattern relative to srcBase.');
  268. test.deepEqual(globule.find(['**/deep*.txt'], {cwd: 'deep'}),
  269. ['deep.txt', 'deeper/deeper.txt', 'deeper/deepest/deepest.txt'],
  270. 'cwd and srcBase should do the same thing.');
  271. test.deepEqual(globule.find(['**/deep*'], {srcBase: 'deep', filter: 'isFile'}),
  272. ['deep.txt', 'deeper/deeper.txt', 'deeper/deepest/deepest.txt'],
  273. 'srcBase should not prevent filtering.');
  274. test.deepEqual(globule.find(['**/deep*'], {srcBase: 'deep', filter: 'isDirectory'}),
  275. ['deeper', 'deeper/deepest'],
  276. 'srcBase should not prevent filtering.');
  277. test.deepEqual(globule.find(['**/deep*.txt', '!**/deeper**'], {srcBase: 'deep'}),
  278. ['deep.txt', 'deeper/deepest/deepest.txt'],
  279. 'srcBase should not prevent exclusions.');
  280. test.done();
  281. },
  282. 'options.prefixBase': function(test) {
  283. test.expect(2);
  284. test.deepEqual(globule.find(['**/deep*.txt'], {srcBase: 'deep', prefixBase: false}),
  285. ['deep.txt', 'deeper/deeper.txt', 'deeper/deepest/deepest.txt'],
  286. 'should not prefix srcBase to returned paths.');
  287. test.deepEqual(globule.find(['**/deep*.txt'], {srcBase: 'deep', prefixBase: true}),
  288. ['deep/deep.txt', 'deep/deeper/deeper.txt', 'deep/deeper/deepest/deepest.txt'],
  289. 'should prefix srcBase to returned paths.');
  290. test.done();
  291. },
  292. 'options.nonull': function(test) {
  293. test.expect(3);
  294. test.deepEqual(globule.find(['*omg*'], {nonull: true}),
  295. ['*omg*'],
  296. 'non-matching patterns should be returned in result set.');
  297. test.deepEqual(globule.find(['js/a*', 'js/b*', 'js/c*'], {nonull: true}),
  298. ['js/a*', 'js/bar.js', 'js/c*'],
  299. 'non-matching patterns should be returned in result set.');
  300. test.deepEqual(globule.find(['js/foo.js', 'js/bar.js', 'js/nonexistent.js'], {nonull: true}),
  301. ['js/foo.js', 'js/bar.js', 'js/nonexistent.js'],
  302. 'non-matching filenames should be returned in result set.');
  303. test.done();
  304. },
  305. };
  306. exports['mapping'] = {
  307. 'basic mapping': function(test) {
  308. test.expect(1);
  309. var actual = globule.mapping(['a.txt', 'b.txt', 'c.txt']);
  310. var expected = [
  311. {dest: 'a.txt', src: ['a.txt']},
  312. {dest: 'b.txt', src: ['b.txt']},
  313. {dest: 'c.txt', src: ['c.txt']},
  314. ];
  315. test.deepEqual(actual, expected, 'default options should create same-to-same src-dest mappings.');
  316. test.done();
  317. },
  318. 'options.srcBase': function(test) {
  319. test.expect(2);
  320. var actual, expected;
  321. actual = globule.mapping(['a.txt', 'bar/b.txt', 'bar/baz/c.txt'], {srcBase: 'foo'});
  322. expected = [
  323. {dest: 'a.txt', src: ['foo/a.txt']},
  324. {dest: 'bar/b.txt', src: ['foo/bar/b.txt']},
  325. {dest: 'bar/baz/c.txt', src: ['foo/bar/baz/c.txt']},
  326. ];
  327. test.deepEqual(actual, expected, 'srcBase should be prefixed to src paths (no trailing /).');
  328. actual = globule.mapping(['a.txt', 'bar/b.txt', 'bar/baz/c.txt'], {srcBase: 'foo/'});
  329. test.deepEqual(actual, expected, 'srcBase should be prefixed to src paths (trailing /).');
  330. test.done();
  331. },
  332. 'options.destBase': function(test) {
  333. test.expect(2);
  334. var actual, expected;
  335. actual = globule.mapping(['a.txt', 'bar/b.txt', 'bar/baz/c.txt'], {destBase: 'dest'});
  336. expected = [
  337. {dest: 'dest/a.txt', src: ['a.txt']},
  338. {dest: 'dest/bar/b.txt', src: ['bar/b.txt']},
  339. {dest: 'dest/bar/baz/c.txt', src: ['bar/baz/c.txt']},
  340. ];
  341. test.deepEqual(actual, expected, 'destBase should be prefixed to dest paths (no trailing /).');
  342. actual = globule.mapping(['a.txt', 'bar/b.txt', 'bar/baz/c.txt'], {destBase: 'dest/'});
  343. test.deepEqual(actual, expected, 'destBase should be prefixed to dest paths (trailing /).');
  344. test.done();
  345. },
  346. 'options.flatten': function(test) {
  347. test.expect(1);
  348. var actual, expected;
  349. actual = globule.mapping(['a.txt', 'bar/b.txt', 'bar/baz/c.txt'], {flatten: true});
  350. expected = [
  351. {dest: 'a.txt', src: ['a.txt']},
  352. {dest: 'b.txt', src: ['bar/b.txt']},
  353. {dest: 'c.txt', src: ['bar/baz/c.txt']},
  354. ];
  355. test.deepEqual(actual, expected, 'flatten should remove all src path parts from dest.');
  356. test.done();
  357. },
  358. 'options.flatten + options.destBase': function(test) {
  359. test.expect(1);
  360. var actual, expected;
  361. actual = globule.mapping(['a.txt', 'bar/b.txt', 'bar/baz/c.txt'], {destBase: 'dest', flatten: true});
  362. expected = [
  363. {dest: 'dest/a.txt', src: ['a.txt']},
  364. {dest: 'dest/b.txt', src: ['bar/b.txt']},
  365. {dest: 'dest/c.txt', src: ['bar/baz/c.txt']},
  366. ];
  367. test.deepEqual(actual, expected, 'flatten and destBase should work together.');
  368. test.done();
  369. },
  370. 'options.ext': function(test) {
  371. test.expect(1);
  372. var actual, expected;
  373. actual = globule.mapping(['x/a.js', 'x.y/b.min.js', 'x.y/z.z/c'], {ext: '.foo'});
  374. expected = [
  375. {dest: 'x/a.foo', src: ['x/a.js']},
  376. {dest: 'x.y/b.foo', src: ['x.y/b.min.js']},
  377. {dest: 'x.y/z.z/c.foo', src: ['x.y/z.z/c']},
  378. ];
  379. test.deepEqual(actual, expected, 'by default, ext should replace everything after the first dot in the filename.');
  380. test.done();
  381. },
  382. 'options.extDot': function(test) {
  383. test.expect(2);
  384. var actual, expected;
  385. actual = globule.mapping(['x/a.js', 'x.y/b.bbb.min.js', 'x.y/z.z/c'], {ext: '.foo', extDot: 'first'});
  386. expected = [
  387. {dest: 'x/a.foo', src: ['x/a.js']},
  388. {dest: 'x.y/b.foo', src: ['x.y/b.bbb.min.js']},
  389. {dest: 'x.y/z.z/c.foo', src: ['x.y/z.z/c']},
  390. ];
  391. test.deepEqual(actual, expected, 'extDot of "first" should replace everything after the first dot in the filename.');
  392. actual = globule.mapping(['x/a.js', 'x.y/b.bbb.min.js', 'x.y/z.z/c'], {ext: '.foo', extDot: 'last'});
  393. expected = [
  394. {dest: 'x/a.foo', src: ['x/a.js']},
  395. {dest: 'x.y/b.bbb.min.foo', src: ['x.y/b.bbb.min.js']},
  396. {dest: 'x.y/z.z/c.foo', src: ['x.y/z.z/c']},
  397. ];
  398. test.deepEqual(actual, expected, 'extDot of "last" should replace everything after the last dot in the filename.');
  399. test.done();
  400. },
  401. 'options.rename': function(test) {
  402. test.expect(1);
  403. var actual, expected;
  404. actual = globule.mapping(['a.txt', 'bar/b.txt', 'bar/baz/c.txt'], {
  405. arbitraryProp: 'FOO',
  406. rename: function(dest, options) {
  407. return path.join(options.arbitraryProp, dest.toUpperCase());
  408. }
  409. });
  410. expected = [
  411. {dest: 'FOO/A.TXT', src: ['a.txt']},
  412. {dest: 'FOO/BAR/B.TXT', src: ['bar/b.txt']},
  413. {dest: 'FOO/BAR/BAZ/C.TXT', src: ['bar/baz/c.txt']},
  414. ];
  415. test.deepEqual(actual, expected, 'allow arbitrary renaming of files.');
  416. test.done();
  417. },
  418. };
  419. exports['findMapping'] = {
  420. setUp: function(done) {
  421. this.cwd = process.cwd();
  422. process.chdir('test/fixtures');
  423. done();
  424. },
  425. tearDown: function(done) {
  426. process.chdir(this.cwd);
  427. done();
  428. },
  429. 'basic matching': function(test) {
  430. test.expect(2);
  431. var actual = globule.findMapping(['expand/**/*.txt']);
  432. var expected = [
  433. {dest: 'expand/deep/deep.txt', src: ['expand/deep/deep.txt']},
  434. {dest: 'expand/deep/deeper/deeper.txt', src: ['expand/deep/deeper/deeper.txt']},
  435. {dest: 'expand/deep/deeper/deepest/deepest.txt', src: ['expand/deep/deeper/deepest/deepest.txt']},
  436. ];
  437. test.deepEqual(actual, expected, 'default options');
  438. expected = globule.mapping(globule.find(['expand/**/*.txt']));
  439. test.deepEqual(actual, expected, 'this is what it\'s doing under the hood, anwyays.');
  440. test.done();
  441. },
  442. 'options.srcBase': function(test) {
  443. test.expect(1);
  444. var actual = globule.findMapping(['**/*.txt'], {destBase: 'dest', srcBase: 'expand/deep'});
  445. var expected = [
  446. {dest: 'dest/deep.txt', src: ['expand/deep/deep.txt']},
  447. {dest: 'dest/deeper/deeper.txt', src: ['expand/deep/deeper/deeper.txt']},
  448. {dest: 'dest/deeper/deepest/deepest.txt', src: ['expand/deep/deeper/deepest/deepest.txt']},
  449. ];
  450. test.deepEqual(actual, expected, 'srcBase should be stripped from front of destPath, pre-destBase+destPath join');
  451. test.done();
  452. },
  453. };