Skip to content

Instantly share code, notes, and snippets.

@eirikb
Last active March 3, 2020 20:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eirikb/b390eb7d59d445c1de7dd1a4f4be3bc2 to your computer and use it in GitHub Desktop.
Save eirikb/b390eb7d59d445c1de7dd1a4f4be3bc2 to your computer and use it in GitHub Desktop.
const test = require('ava');
const when = require('./when');
const { sp } = require('@pnp/pnpjs');
test('when', t => {
const mySp = when(sp);
mySp.web.getList('web/Lists/A').items.filter(`Title eq 'yes'`).get.thenReturn([{ Id: 1 }]);
mySp.web.getList('web/Lists/A').items.filter(`Title eq 'no'`).get.thenReturn([{ Id: 2 }]);
mySp.web.getList('web/Lists/B').items.filter(`Title eq 'yes'`).get.thenReturn([{ Id: 3 }]);
t.plan(5);
t.deepEqual(mySp.web.getList('web/Lists/A').items.filter(`Title eq 'yes'`).get(), [{ Id: 1 }]);
t.deepEqual(mySp.web.getList('web/Lists/A').items.filter(`Title eq 'no'`).get(), [{ Id: 2 }]);
t.deepEqual(mySp.web.getList('web/Lists/B').items.filter(`Title eq 'yes'`).get(), [{ Id: 3 }]);
const item = mySp.web.getList('web/Lists/C').items.getById(137);
item.get.thenReturn({ Title: 'OK' });
item.update.thenCall(item => {
t.deepEqual({ Title: 'Yes!' }, item);
});
t.deepEqual(mySp.web.getList('web/Lists/C').items.getById(137).get(), { Title: 'OK' });
mySp.web.getList('web/Lists/C').items.getById(137).update({
Title: 'Yes!'
});
// Prints paths, helpful to see what is missing from stubbing. Note if an error occurs the path is also printed
console.log(mySp._paths);
});
module.exports = function (target) {
const stubs = {};
function when(target, path = '', hack) {
if (stubs[path]) {
return stubs[path];
}
const stub = new Proxy(target, {
get: function (o, prop) {
o = hack || o;
if (prop === '_paths') {
return Object.keys(stubs);
}
const val = o[prop];
if (typeof val === 'function') {
const subKey = `${path}-${prop}`;
if (stubs[subKey]) {
return stubs[subKey];
}
const fn = (...args) => {
if (fn.thenReturnArgs) {
return fn.thenReturnArgs;
}
if (fn.thenCallFn) {
fn.thenCallFn(...args);
}
try {
const res = val.apply(o, args);
if (res) {
if (res.catch) {
res.catch(e => {
console.log('Path failed', path, prop);
throw e;
});
}
return when(res, `${path} ${prop}(${args.join(',')})`);
}
} catch (e) {
console.log('Path failed:', path, prop);
throw e;
}
};
val.thenReturn = args => {
fn.thenReturnArgs = args;
stubs[subKey] = fn;
};
val.thenCall = fn => {
fn.thenCallFn = fn;
stubs[subKey] = fn;
};
return when(fn, `${path} ${prop}`, val);
}
if (typeof val === 'object') {
return when(o[prop], `${path} ${prop}`);
} else {
return val;
}
}
});
stubs[path] = stub;
return stub;
}
return when(target);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment