Skip to content

Commit 3a52c44

Browse files
author
Gregg Van Hove
committed
Merge branch 'aeisenberg-spy-all'
- Merges jasmine#1581 from @aeisenberg - Fixes jasmine#1421
2 parents 110c092 + f62eb3b commit 3a52c44

File tree

4 files changed

+149
-0
lines changed

4 files changed

+149
-0
lines changed

lib/jasmine-core/jasmine.js

+29
Original file line numberDiff line numberDiff line change
@@ -5480,6 +5480,18 @@ getJasmineRequireObj().interface = function(jasmine, env) {
54805480
return env.spyOnProperty(obj, methodName, accessType);
54815481
},
54825482

5483+
/**
5484+
* Installs spies on all writable and configurable properties of an object.
5485+
* @name spyOnProperty
5486+
* @function
5487+
* @global
5488+
* @param {Object} obj - The object upon which to install the {@link Spy}s
5489+
* @returns {Object} the spied object
5490+
*/
5491+
spyOnAllFunctions: function(obj) {
5492+
return env.spyOnAllFunctions(obj);
5493+
},
5494+
54835495
jsApiReporter: new jasmine.JsApiReporter({
54845496
timer: new jasmine.Timer()
54855497
}),
@@ -5898,6 +5910,23 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
58985910
return spy;
58995911
};
59005912

5913+
this.spyOnAllFunctions = function(obj) {
5914+
if (j$.util.isUndefined(obj)) {
5915+
throw new Error('spyOnAllFunctions could not find an object to spy upon');
5916+
}
5917+
5918+
for (var prop in obj) {
5919+
if (Object.prototype.hasOwnProperty.call(obj, prop) && obj[prop] instanceof Function) {
5920+
var descriptor = Object.getOwnPropertyDescriptor(obj, prop);
5921+
if ((descriptor.writable || descriptor.set) && descriptor.configurable) {
5922+
this.spyOn(obj, prop);
5923+
}
5924+
}
5925+
}
5926+
5927+
return obj;
5928+
};
5929+
59015930
this.clearSpies = function() {
59025931
var spies = currentSpies();
59035932
for (var i = spies.length - 1; i >= 0; i--) {

spec/core/SpyRegistrySpec.js

+91
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,97 @@ describe("SpyRegistry", function() {
214214
});
215215
});
216216

217+
describe("#spyOnAllFunctions", function() {
218+
it("checks for the existence of the object", function() {
219+
var spyRegistry = new jasmineUnderTest.SpyRegistry();
220+
expect(function() {
221+
spyRegistry.spyOnAllFunctions(void 0);
222+
}).toThrowError(/spyOnAllFunctions could not find an object to spy upon/);
223+
});
224+
225+
it("overrides all writable and configurable functions of the object", function() {
226+
var spyRegistry = new jasmineUnderTest.SpyRegistry({createSpy: function() {
227+
return 'I am a spy';
228+
}});
229+
var createNoop = function() { return function() { /**/}; };
230+
var noop1 = createNoop();
231+
var noop2 = createNoop();
232+
var noop3 = createNoop();
233+
var noop4 = createNoop();
234+
var noop5 = createNoop();
235+
236+
var parent = {
237+
notSpied1: noop1
238+
};
239+
var subject = Object.create(parent);
240+
Object.defineProperty(subject, 'spied1', {
241+
value: noop1,
242+
writable: true,
243+
configurable: true,
244+
enumerable: true
245+
});
246+
Object.defineProperty(subject, 'spied2', {
247+
value: noop2,
248+
writable: true,
249+
configurable: true,
250+
enumerable: true
251+
});
252+
var _spied3 = noop3;
253+
Object.defineProperty(subject, 'spied3', {
254+
configurable: true,
255+
set: function (val) {
256+
_spied3 = val;
257+
},
258+
get: function() {
259+
return _spied3;
260+
},
261+
enumerable: true
262+
});
263+
subject.spied4 = noop4;
264+
Object.defineProperty(subject, 'notSpied2', {
265+
value: noop2,
266+
writable: false,
267+
configurable: true,
268+
enumerable: true
269+
});
270+
Object.defineProperty(subject, 'notSpied3', {
271+
value: noop3,
272+
writable: true,
273+
configurable: false,
274+
enumerable: true
275+
});
276+
Object.defineProperty(subject, 'notSpied4', {
277+
configurable: false,
278+
set: function(val) { /**/ },
279+
get: function() {
280+
return noop4;
281+
},
282+
enumerable: true
283+
});
284+
Object.defineProperty(subject, 'notSpied5', {
285+
value: noop5,
286+
writable: true,
287+
configurable: true,
288+
enumerable: false
289+
});
290+
subject.notSpied6 = 6;
291+
292+
var spiedObject = spyRegistry.spyOnAllFunctions(subject);
293+
294+
expect(subject.notSpied1).toBe(noop1);
295+
expect(subject.notSpied2).toBe(noop2);
296+
expect(subject.notSpied3).toBe(noop3);
297+
expect(subject.notSpied4).toBe(noop4);
298+
expect(subject.notSpied5).toBe(noop5);
299+
expect(subject.notSpied6).toBe(6);
300+
expect(subject.spied1).toBe('I am a spy');
301+
expect(subject.spied2).toBe('I am a spy');
302+
expect(subject.spied3).toBe('I am a spy');
303+
expect(subject.spied4).toBe('I am a spy');
304+
expect(spiedObject).toBe(subject);
305+
});
306+
});
307+
217308
describe("#clearSpies", function() {
218309
it("restores the original functions on the spied-upon objects", function() {
219310
var spies = [],

src/core/SpyRegistry.js

+17
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,23 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
120120
return spy;
121121
};
122122

123+
this.spyOnAllFunctions = function(obj) {
124+
if (j$.util.isUndefined(obj)) {
125+
throw new Error('spyOnAllFunctions could not find an object to spy upon');
126+
}
127+
128+
for (var prop in obj) {
129+
if (Object.prototype.hasOwnProperty.call(obj, prop) && obj[prop] instanceof Function) {
130+
var descriptor = Object.getOwnPropertyDescriptor(obj, prop);
131+
if ((descriptor.writable || descriptor.set) && descriptor.configurable) {
132+
this.spyOn(obj, prop);
133+
}
134+
}
135+
}
136+
137+
return obj;
138+
};
139+
123140
this.clearSpies = function() {
124141
var spies = currentSpies();
125142
for (var i = spies.length - 1; i >= 0; i--) {

src/core/requireInterface.js

+12
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,18 @@ getJasmineRequireObj().interface = function(jasmine, env) {
235235
return env.spyOnProperty(obj, methodName, accessType);
236236
},
237237

238+
/**
239+
* Installs spies on all writable and configurable properties of an object.
240+
* @name spyOnProperty
241+
* @function
242+
* @global
243+
* @param {Object} obj - The object upon which to install the {@link Spy}s
244+
* @returns {Object} the spied object
245+
*/
246+
spyOnAllFunctions: function(obj) {
247+
return env.spyOnAllFunctions(obj);
248+
},
249+
238250
jsApiReporter: new jasmine.JsApiReporter({
239251
timer: new jasmine.Timer()
240252
}),

0 commit comments

Comments
 (0)