diff --git a/lib/jasmine-core/jasmine-html.js b/lib/jasmine-core/jasmine-html.js
index f2a05183..29d021ce 100644
--- a/lib/jasmine-core/jasmine-html.js
+++ b/lib/jasmine-core/jasmine-html.js
@@ -81,7 +81,6 @@ jasmineRequire.HtmlReporter = function(j$) {
addToExistingQueryString =
options.addToExistingQueryString || defaultQueryString,
filterSpecs = options.filterSpecs,
- timer = options.timer || j$.noopTimer,
htmlReporterMain,
symbols,
deprecationWarnings = [];
@@ -115,7 +114,6 @@ jasmineRequire.HtmlReporter = function(j$) {
var totalSpecsDefined;
this.jasmineStarted = function(options) {
totalSpecsDefined = options.totalSpecsDefined || 0;
- timer.start();
};
var summary = createDom('div', { className: 'jasmine-summary' });
@@ -194,7 +192,7 @@ jasmineRequire.HtmlReporter = function(j$) {
createDom(
'span',
{ className: 'jasmine-duration' },
- 'finished in ' + timer.elapsed() / 1000 + 's'
+ 'finished in ' + doneResult.totalTime / 1000 + 's'
)
);
diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js
index 03666af2..2f48e945 100644
--- a/lib/jasmine-core/jasmine.js
+++ b/lib/jasmine-core/jasmine.js
@@ -1643,8 +1643,8 @@ getJasmineRequireObj().Env = function(j$) {
return spyFactory.createSpy(name, originalFn);
};
- this.createSpyObj = function(baseName, methodNames) {
- return spyFactory.createSpyObj(baseName, methodNames);
+ this.createSpyObj = function(baseName, methodNames, propertyNames) {
+ return spyFactory.createSpyObj(baseName, methodNames, propertyNames);
};
var ensureIsFunction = function(fn, caller) {
@@ -6577,10 +6577,11 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @function
* @param {String} [baseName] - Base name for the spies in the object.
* @param {String[]|Object} methodNames - Array of method names to create spies for, or Object whose keys will be method names and values the {@link Spy#and#returnValue|returnValue}.
+ * @param {String[]|Object} [propertyNames] - Array of property names to create spies for, or Object whose keys will be propertynames and values the {@link Spy#and#returnValue|returnValue}.
* @return {Object}
*/
- jasmine.createSpyObj = function(baseName, methodNames) {
- return env.createSpyObj(baseName, methodNames);
+ jasmine.createSpyObj = function(baseName, methodNames, propertyNames) {
+ return env.createSpyObj(baseName, methodNames, propertyNames);
};
/**
@@ -6811,34 +6812,43 @@ getJasmineRequireObj().SpyFactory = function(j$) {
return j$.Spy(name, originalFn, getCustomStrategies(), getPromise);
};
- this.createSpyObj = function(baseName, methodNames) {
+ this.createSpyObj = function(baseName, methodNames, propertyNames) {
var baseNameIsCollection =
j$.isObject_(baseName) || j$.isArray_(baseName);
- if (baseNameIsCollection && j$.util.isUndefined(methodNames)) {
+ if (baseNameIsCollection) {
+ propertyNames = methodNames;
methodNames = baseName;
baseName = 'unknown';
}
var obj = {};
- var spiesWereSet = false;
+ var spy, descriptor;
- if (j$.isArray_(methodNames)) {
- for (var i = 0; i < methodNames.length; i++) {
- obj[methodNames[i]] = self.createSpy(baseName + '.' + methodNames[i]);
- spiesWereSet = true;
- }
- } else if (j$.isObject_(methodNames)) {
- for (var key in methodNames) {
- if (methodNames.hasOwnProperty(key)) {
- obj[key] = self.createSpy(baseName + '.' + key);
- obj[key].and.returnValue(methodNames[key]);
- spiesWereSet = true;
- }
+ var methods = normalizeKeyValues(methodNames);
+ for (var i = 0; i < methods.length; i++) {
+ spy = obj[methods[i][0]] = self.createSpy(
+ baseName + '.' + methods[i][0]
+ );
+ if (methods[i].length > 1) {
+ spy.and.returnValue(methods[i][1]);
}
}
- if (!spiesWereSet) {
+ var properties = normalizeKeyValues(propertyNames);
+ for (var i = 0; i < properties.length; i++) {
+ descriptor = {
+ get: self.createSpy(baseName + '.' + properties[i][0] + '.get'),
+ set: self.createSpy(baseName + '.' + properties[i][0] + '.set')
+ };
+ if (properties[i].length > 1) {
+ descriptor.get.and.returnValue(properties[i][1]);
+ descriptor.set.and.returnValue(properties[i][1]);
+ }
+ Object.defineProperty(obj, properties[i][0], descriptor);
+ }
+
+ if (methods.length === 0 && properties.length === 0) {
throw 'createSpyObj requires a non-empty array or object of method names to create spies for';
}
@@ -6846,6 +6856,22 @@ getJasmineRequireObj().SpyFactory = function(j$) {
};
}
+ function normalizeKeyValues(object) {
+ var result = [];
+ if (j$.isArray_(object)) {
+ for (var i = 0; i < object.length; i++) {
+ result.push([object[i]]);
+ }
+ } else if (j$.isObject_(object)) {
+ for (var key in object) {
+ if (object.hasOwnProperty(key)) {
+ result.push([key, object[key]]);
+ }
+ }
+ }
+ return result;
+ }
+
return SpyFactory;
};
diff --git a/spec/core/SpySpec.js b/spec/core/SpySpec.js
index f2eea200..b1165dd3 100644
--- a/spec/core/SpySpec.js
+++ b/spec/core/SpySpec.js
@@ -174,6 +174,49 @@ describe('Spies', function() {
'createSpyObj requires a non-empty array or object of method names to create spies for'
);
});
+
+ it('creates an object with spy properties if a second list is passed', function() {
+ var spyObj = env.createSpyObj('base', ['method1'], ['prop1']);
+
+ expect(spyObj).toEqual({
+ method1: jasmine.any(Function)
+ });
+
+ var descriptor = Object.getOwnPropertyDescriptor(spyObj, 'prop1');
+ expect(descriptor.get.and.identity).toEqual('base.prop1.get');
+ expect(descriptor.set.and.identity).toEqual('base.prop1.set');
+
+ expect(spyObj.prop1).toBeUndefined();
+ });
+
+ it('creates an object with property names and return values if second object is passed', function() {
+ var spyObj = env.createSpyObj('base', ['method1'], {
+ prop1: 'foo',
+ prop2: 37
+ });
+
+ expect(spyObj).toEqual({
+ method1: jasmine.any(Function)
+ });
+
+ expect(spyObj.prop1).toEqual('foo');
+ expect(spyObj.prop2).toEqual(37);
+ spyObj.prop2 = 4;
+ expect(spyObj.prop2).toEqual(37);
+ expect(
+ Object.getOwnPropertyDescriptor(spyObj, 'prop2').set.calls.count()
+ ).toBe(1);
+ });
+
+ it('allows base name to be ommitted when assigning methods and properties', function() {
+ var spyObj = env.createSpyObj({ m: 3 }, { p: 4 });
+
+ expect(spyObj.m()).toEqual(3);
+ expect(spyObj.p).toEqual(4);
+ expect(
+ Object.getOwnPropertyDescriptor(spyObj, 'p').get.and.identity
+ ).toEqual('unknown.p.get');
+ });
});
it('can use different strategies for different arguments', function() {
diff --git a/src/core/Env.js b/src/core/Env.js
index d3e9e257..43e4a8e7 100644
--- a/src/core/Env.js
+++ b/src/core/Env.js
@@ -788,8 +788,8 @@ getJasmineRequireObj().Env = function(j$) {
return spyFactory.createSpy(name, originalFn);
};
- this.createSpyObj = function(baseName, methodNames) {
- return spyFactory.createSpyObj(baseName, methodNames);
+ this.createSpyObj = function(baseName, methodNames, propertyNames) {
+ return spyFactory.createSpyObj(baseName, methodNames, propertyNames);
};
var ensureIsFunction = function(fn, caller) {
diff --git a/src/core/SpyFactory.js b/src/core/SpyFactory.js
index a622a8a3..d9cdc228 100644
--- a/src/core/SpyFactory.js
+++ b/src/core/SpyFactory.js
@@ -6,34 +6,43 @@ getJasmineRequireObj().SpyFactory = function(j$) {
return j$.Spy(name, originalFn, getCustomStrategies(), getPromise);
};
- this.createSpyObj = function(baseName, methodNames) {
+ this.createSpyObj = function(baseName, methodNames, propertyNames) {
var baseNameIsCollection =
j$.isObject_(baseName) || j$.isArray_(baseName);
- if (baseNameIsCollection && j$.util.isUndefined(methodNames)) {
+ if (baseNameIsCollection) {
+ propertyNames = methodNames;
methodNames = baseName;
baseName = 'unknown';
}
var obj = {};
- var spiesWereSet = false;
+ var spy, descriptor;
- if (j$.isArray_(methodNames)) {
- for (var i = 0; i < methodNames.length; i++) {
- obj[methodNames[i]] = self.createSpy(baseName + '.' + methodNames[i]);
- spiesWereSet = true;
- }
- } else if (j$.isObject_(methodNames)) {
- for (var key in methodNames) {
- if (methodNames.hasOwnProperty(key)) {
- obj[key] = self.createSpy(baseName + '.' + key);
- obj[key].and.returnValue(methodNames[key]);
- spiesWereSet = true;
- }
+ var methods = normalizeKeyValues(methodNames);
+ for (var i = 0; i < methods.length; i++) {
+ spy = obj[methods[i][0]] = self.createSpy(
+ baseName + '.' + methods[i][0]
+ );
+ if (methods[i].length > 1) {
+ spy.and.returnValue(methods[i][1]);
}
}
- if (!spiesWereSet) {
+ var properties = normalizeKeyValues(propertyNames);
+ for (var i = 0; i < properties.length; i++) {
+ descriptor = {
+ get: self.createSpy(baseName + '.' + properties[i][0] + '.get'),
+ set: self.createSpy(baseName + '.' + properties[i][0] + '.set')
+ };
+ if (properties[i].length > 1) {
+ descriptor.get.and.returnValue(properties[i][1]);
+ descriptor.set.and.returnValue(properties[i][1]);
+ }
+ Object.defineProperty(obj, properties[i][0], descriptor);
+ }
+
+ if (methods.length === 0 && properties.length === 0) {
throw 'createSpyObj requires a non-empty array or object of method names to create spies for';
}
@@ -41,5 +50,21 @@ getJasmineRequireObj().SpyFactory = function(j$) {
};
}
+ function normalizeKeyValues(object) {
+ var result = [];
+ if (j$.isArray_(object)) {
+ for (var i = 0; i < object.length; i++) {
+ result.push([object[i]]);
+ }
+ } else if (j$.isObject_(object)) {
+ for (var key in object) {
+ if (object.hasOwnProperty(key)) {
+ result.push([key, object[key]]);
+ }
+ }
+ }
+ return result;
+ }
+
return SpyFactory;
};
diff --git a/src/core/requireInterface.js b/src/core/requireInterface.js
index 2abe12d2..cba23c3d 100644
--- a/src/core/requireInterface.js
+++ b/src/core/requireInterface.js
@@ -333,10 +333,11 @@ getJasmineRequireObj().interface = function(jasmine, env) {
* @function
* @param {String} [baseName] - Base name for the spies in the object.
* @param {String[]|Object} methodNames - Array of method names to create spies for, or Object whose keys will be method names and values the {@link Spy#and#returnValue|returnValue}.
+ * @param {String[]|Object} [propertyNames] - Array of property names to create spies for, or Object whose keys will be propertynames and values the {@link Spy#and#returnValue|returnValue}.
* @return {Object}
*/
- jasmine.createSpyObj = function(baseName, methodNames) {
- return env.createSpyObj(baseName, methodNames);
+ jasmine.createSpyObj = function(baseName, methodNames, propertyNames) {
+ return env.createSpyObj(baseName, methodNames, propertyNames);
};
/**