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