mock.js 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. var path = require('path');
  2. var test = require('tape');
  3. var resolve = require('../');
  4. test('mock', function (t) {
  5. t.plan(8);
  6. var files = {};
  7. files[path.resolve('/foo/bar/baz.js')] = 'beep';
  8. var dirs = {};
  9. dirs[path.resolve('/foo/bar')] = true;
  10. function opts(basedir) {
  11. return {
  12. basedir: path.resolve(basedir),
  13. isFile: function (file, cb) {
  14. cb(null, Object.prototype.hasOwnProperty.call(files, path.resolve(file)));
  15. },
  16. isDirectory: function (dir, cb) {
  17. cb(null, !!dirs[path.resolve(dir)]);
  18. },
  19. readFile: function (file, cb) {
  20. cb(null, files[path.resolve(file)]);
  21. },
  22. realpath: function (file, cb) {
  23. cb(null, file);
  24. }
  25. };
  26. }
  27. resolve('./baz', opts('/foo/bar'), function (err, res, pkg) {
  28. if (err) return t.fail(err);
  29. t.equal(res, path.resolve('/foo/bar/baz.js'));
  30. t.equal(pkg, undefined);
  31. });
  32. resolve('./baz.js', opts('/foo/bar'), function (err, res, pkg) {
  33. if (err) return t.fail(err);
  34. t.equal(res, path.resolve('/foo/bar/baz.js'));
  35. t.equal(pkg, undefined);
  36. });
  37. resolve('baz', opts('/foo/bar'), function (err, res) {
  38. t.equal(err.message, "Cannot find module 'baz' from '" + path.resolve('/foo/bar') + "'");
  39. t.equal(err.code, 'MODULE_NOT_FOUND');
  40. });
  41. resolve('../baz', opts('/foo/bar'), function (err, res) {
  42. t.equal(err.message, "Cannot find module '../baz' from '" + path.resolve('/foo/bar') + "'");
  43. t.equal(err.code, 'MODULE_NOT_FOUND');
  44. });
  45. });
  46. test('mock from package', function (t) {
  47. t.plan(8);
  48. var files = {};
  49. files[path.resolve('/foo/bar/baz.js')] = 'beep';
  50. var dirs = {};
  51. dirs[path.resolve('/foo/bar')] = true;
  52. function opts(basedir) {
  53. return {
  54. basedir: path.resolve(basedir),
  55. isFile: function (file, cb) {
  56. cb(null, Object.prototype.hasOwnProperty.call(files, file));
  57. },
  58. isDirectory: function (dir, cb) {
  59. cb(null, !!dirs[path.resolve(dir)]);
  60. },
  61. 'package': { main: 'bar' },
  62. readFile: function (file, cb) {
  63. cb(null, files[file]);
  64. },
  65. realpath: function (file, cb) {
  66. cb(null, file);
  67. }
  68. };
  69. }
  70. resolve('./baz', opts('/foo/bar'), function (err, res, pkg) {
  71. if (err) return t.fail(err);
  72. t.equal(res, path.resolve('/foo/bar/baz.js'));
  73. t.equal(pkg && pkg.main, 'bar');
  74. });
  75. resolve('./baz.js', opts('/foo/bar'), function (err, res, pkg) {
  76. if (err) return t.fail(err);
  77. t.equal(res, path.resolve('/foo/bar/baz.js'));
  78. t.equal(pkg && pkg.main, 'bar');
  79. });
  80. resolve('baz', opts('/foo/bar'), function (err, res) {
  81. t.equal(err.message, "Cannot find module 'baz' from '" + path.resolve('/foo/bar') + "'");
  82. t.equal(err.code, 'MODULE_NOT_FOUND');
  83. });
  84. resolve('../baz', opts('/foo/bar'), function (err, res) {
  85. t.equal(err.message, "Cannot find module '../baz' from '" + path.resolve('/foo/bar') + "'");
  86. t.equal(err.code, 'MODULE_NOT_FOUND');
  87. });
  88. });
  89. test('mock package', function (t) {
  90. t.plan(2);
  91. var files = {};
  92. files[path.resolve('/foo/node_modules/bar/baz.js')] = 'beep';
  93. files[path.resolve('/foo/node_modules/bar/package.json')] = JSON.stringify({
  94. main: './baz.js'
  95. });
  96. var dirs = {};
  97. dirs[path.resolve('/foo')] = true;
  98. dirs[path.resolve('/foo/node_modules')] = true;
  99. function opts(basedir) {
  100. return {
  101. basedir: path.resolve(basedir),
  102. isFile: function (file, cb) {
  103. cb(null, Object.prototype.hasOwnProperty.call(files, path.resolve(file)));
  104. },
  105. isDirectory: function (dir, cb) {
  106. cb(null, !!dirs[path.resolve(dir)]);
  107. },
  108. readFile: function (file, cb) {
  109. cb(null, files[path.resolve(file)]);
  110. },
  111. realpath: function (file, cb) {
  112. cb(null, file);
  113. }
  114. };
  115. }
  116. resolve('bar', opts('/foo'), function (err, res, pkg) {
  117. if (err) return t.fail(err);
  118. t.equal(res, path.resolve('/foo/node_modules/bar/baz.js'));
  119. t.equal(pkg && pkg.main, './baz.js');
  120. });
  121. });
  122. test('mock package from package', function (t) {
  123. t.plan(2);
  124. var files = {};
  125. files[path.resolve('/foo/node_modules/bar/baz.js')] = 'beep';
  126. files[path.resolve('/foo/node_modules/bar/package.json')] = JSON.stringify({
  127. main: './baz.js'
  128. });
  129. var dirs = {};
  130. dirs[path.resolve('/foo')] = true;
  131. dirs[path.resolve('/foo/node_modules')] = true;
  132. function opts(basedir) {
  133. return {
  134. basedir: path.resolve(basedir),
  135. isFile: function (file, cb) {
  136. cb(null, Object.prototype.hasOwnProperty.call(files, path.resolve(file)));
  137. },
  138. isDirectory: function (dir, cb) {
  139. cb(null, !!dirs[path.resolve(dir)]);
  140. },
  141. 'package': { main: 'bar' },
  142. readFile: function (file, cb) {
  143. cb(null, files[path.resolve(file)]);
  144. },
  145. realpath: function (file, cb) {
  146. cb(null, file);
  147. }
  148. };
  149. }
  150. resolve('bar', opts('/foo'), function (err, res, pkg) {
  151. if (err) return t.fail(err);
  152. t.equal(res, path.resolve('/foo/node_modules/bar/baz.js'));
  153. t.equal(pkg && pkg.main, './baz.js');
  154. });
  155. });
  156. test('symlinked', function (t) {
  157. t.plan(4);
  158. var files = {};
  159. files[path.resolve('/foo/bar/baz.js')] = 'beep';
  160. files[path.resolve('/foo/bar/symlinked/baz.js')] = 'beep';
  161. var dirs = {};
  162. dirs[path.resolve('/foo/bar')] = true;
  163. dirs[path.resolve('/foo/bar/symlinked')] = true;
  164. function opts(basedir) {
  165. return {
  166. preserveSymlinks: false,
  167. basedir: path.resolve(basedir),
  168. isFile: function (file, cb) {
  169. cb(null, Object.prototype.hasOwnProperty.call(files, path.resolve(file)));
  170. },
  171. isDirectory: function (dir, cb) {
  172. cb(null, !!dirs[path.resolve(dir)]);
  173. },
  174. readFile: function (file, cb) {
  175. cb(null, files[path.resolve(file)]);
  176. },
  177. realpath: function (file, cb) {
  178. var resolved = path.resolve(file);
  179. if (resolved.indexOf('symlinked') >= 0) {
  180. cb(null, resolved);
  181. return;
  182. }
  183. var ext = path.extname(resolved);
  184. if (ext) {
  185. var dir = path.dirname(resolved);
  186. var base = path.basename(resolved);
  187. cb(null, path.join(dir, 'symlinked', base));
  188. } else {
  189. cb(null, path.join(resolved, 'symlinked'));
  190. }
  191. }
  192. };
  193. }
  194. resolve('./baz', opts('/foo/bar'), function (err, res, pkg) {
  195. if (err) return t.fail(err);
  196. t.equal(res, path.resolve('/foo/bar/symlinked/baz.js'));
  197. t.equal(pkg, undefined);
  198. });
  199. resolve('./baz.js', opts('/foo/bar'), function (err, res, pkg) {
  200. if (err) return t.fail(err);
  201. t.equal(res, path.resolve('/foo/bar/symlinked/baz.js'));
  202. t.equal(pkg, undefined);
  203. });
  204. });
  205. test('readPackage', function (t) {
  206. t.plan(3);
  207. var files = {};
  208. files[path.resolve('/foo/node_modules/bar/something-else.js')] = 'beep';
  209. files[path.resolve('/foo/node_modules/bar/package.json')] = JSON.stringify({
  210. main: './baz.js'
  211. });
  212. files[path.resolve('/foo/node_modules/bar/baz.js')] = 'boop';
  213. var dirs = {};
  214. dirs[path.resolve('/foo')] = true;
  215. dirs[path.resolve('/foo/node_modules')] = true;
  216. function opts(basedir) {
  217. return {
  218. basedir: path.resolve(basedir),
  219. isFile: function (file, cb) {
  220. cb(null, Object.prototype.hasOwnProperty.call(files, path.resolve(file)));
  221. },
  222. isDirectory: function (dir, cb) {
  223. cb(null, !!dirs[path.resolve(dir)]);
  224. },
  225. 'package': { main: 'bar' },
  226. readFile: function (file, cb) {
  227. cb(null, files[path.resolve(file)]);
  228. },
  229. realpath: function (file, cb) {
  230. cb(null, file);
  231. }
  232. };
  233. }
  234. t.test('with readFile', function (st) {
  235. st.plan(3);
  236. resolve('bar', opts('/foo'), function (err, res, pkg) {
  237. st.error(err);
  238. st.equal(res, path.resolve('/foo/node_modules/bar/baz.js'));
  239. st.equal(pkg && pkg.main, './baz.js');
  240. });
  241. });
  242. var readPackage = function (readFile, file, cb) {
  243. var barPackage = path.join('bar', 'package.json');
  244. if (file.slice(-barPackage.length) === barPackage) {
  245. cb(null, { main: './something-else.js' });
  246. } else {
  247. cb(null, JSON.parse(files[path.resolve(file)]));
  248. }
  249. };
  250. t.test('with readPackage', function (st) {
  251. st.plan(3);
  252. var options = opts('/foo');
  253. delete options.readFile;
  254. options.readPackage = readPackage;
  255. resolve('bar', options, function (err, res, pkg) {
  256. st.error(err);
  257. st.equal(res, path.resolve('/foo/node_modules/bar/something-else.js'));
  258. st.equal(pkg && pkg.main, './something-else.js');
  259. });
  260. });
  261. t.test('with readFile and readPackage', function (st) {
  262. st.plan(1);
  263. var options = opts('/foo');
  264. options.readPackage = readPackage;
  265. resolve('bar', options, function (err) {
  266. st.throws(function () { throw err; }, TypeError, 'errors when both readFile and readPackage are provided');
  267. });
  268. });
  269. });