Merge branch '3.99' into 4.0
This commit is contained in:
@@ -308,7 +308,8 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
addDeprecationWarnings(doneResult);
|
||||
|
||||
for (i = 0; i < deprecationWarnings.length; i++) {
|
||||
var context;
|
||||
var children = [],
|
||||
context;
|
||||
|
||||
switch (deprecationWarnings[i].runnableType) {
|
||||
case 'spec':
|
||||
@@ -321,13 +322,23 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
context = '';
|
||||
}
|
||||
|
||||
deprecationWarnings[i].message.split('\n').forEach(function(line) {
|
||||
children.push(line);
|
||||
children.push(createDom('br'));
|
||||
});
|
||||
|
||||
children[0] = 'DEPRECATION: ' + children[0];
|
||||
children.push(context);
|
||||
|
||||
if (deprecationWarnings[i].stack) {
|
||||
children.push(createExpander(deprecationWarnings[i].stack));
|
||||
}
|
||||
|
||||
alert.appendChild(
|
||||
createDom(
|
||||
'span',
|
||||
{ className: 'jasmine-bar jasmine-warning' },
|
||||
'DEPRECATION: ' + deprecationWarnings[i].message,
|
||||
createDom('br'),
|
||||
context
|
||||
children
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -642,17 +653,44 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
if (result && result.deprecationWarnings) {
|
||||
for (var i = 0; i < result.deprecationWarnings.length; i++) {
|
||||
var warning = result.deprecationWarnings[i].message;
|
||||
if (!j$.util.arrayContains(warning)) {
|
||||
deprecationWarnings.push({
|
||||
message: warning,
|
||||
runnableName: result.fullName,
|
||||
runnableType: runnableType
|
||||
});
|
||||
}
|
||||
deprecationWarnings.push({
|
||||
message: warning,
|
||||
stack: result.deprecationWarnings[i].stack,
|
||||
runnableName: result.fullName,
|
||||
runnableType: runnableType
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createExpander(stackTrace) {
|
||||
var expandLink = createDom('a', { href: '#' }, 'Show stack trace');
|
||||
var root = createDom(
|
||||
'div',
|
||||
{ className: 'jasmine-expander' },
|
||||
expandLink,
|
||||
createDom(
|
||||
'div',
|
||||
{ className: 'jasmine-expander-contents jasmine-stack-trace' },
|
||||
stackTrace
|
||||
)
|
||||
);
|
||||
|
||||
expandLink.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (root.classList.contains('jasmine-expanded')) {
|
||||
root.classList.remove('jasmine-expanded');
|
||||
expandLink.textContent = 'Show stack trace';
|
||||
} else {
|
||||
root.classList.add('jasmine-expanded');
|
||||
expandLink.textContent = 'Hide stack trace';
|
||||
}
|
||||
});
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
function find(selector) {
|
||||
return getContainer().querySelector('.jasmine_html-reporter ' + selector);
|
||||
}
|
||||
@@ -666,11 +704,23 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
}
|
||||
}
|
||||
|
||||
function createDom(type, attrs, childrenVarArgs) {
|
||||
var el = createElement(type);
|
||||
function createDom(type, attrs, childrenArrayOrVarArgs) {
|
||||
var el = createElement(type),
|
||||
children,
|
||||
i;
|
||||
|
||||
for (var i = 2; i < arguments.length; i++) {
|
||||
var child = arguments[i];
|
||||
if (j$.isArray_(childrenArrayOrVarArgs)) {
|
||||
children = childrenArrayOrVarArgs;
|
||||
} else {
|
||||
children = [];
|
||||
|
||||
for (i = 2; i < arguments.length; i++) {
|
||||
children.push(arguments[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
|
||||
if (typeof child === 'string') {
|
||||
el.appendChild(createTextNode(child));
|
||||
|
||||
@@ -165,6 +165,8 @@ body {
|
||||
background-color: #bababa;
|
||||
}
|
||||
.jasmine_html-reporter .jasmine-bar.jasmine-warning {
|
||||
margin-top: 14px;
|
||||
margin-bottom: 14px;
|
||||
background-color: #ba9d37;
|
||||
color: #333;
|
||||
}
|
||||
@@ -268,4 +270,21 @@ body {
|
||||
border: 1px solid #ddd;
|
||||
background: white;
|
||||
white-space: pre;
|
||||
}
|
||||
.jasmine_html-reporter .jasmine-expander a {
|
||||
display: block;
|
||||
margin-left: 14px;
|
||||
color: blue;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.jasmine_html-reporter .jasmine-expander-contents {
|
||||
display: none;
|
||||
}
|
||||
.jasmine_html-reporter .jasmine-expanded {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.jasmine_html-reporter .jasmine-expanded .jasmine-expander-contents {
|
||||
display: block;
|
||||
margin-left: 14px;
|
||||
padding: 5px;
|
||||
}
|
||||
@@ -64,7 +64,10 @@ var getJasmineRequireObj = (function(jasmineGlobal) {
|
||||
j$.getClearStack = jRequire.clearStack(j$);
|
||||
j$.Clock = jRequire.Clock();
|
||||
j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(j$);
|
||||
j$.Deprecator = jRequire.Deprecator(j$);
|
||||
j$.Env = jRequire.Env(j$);
|
||||
j$.deprecatingSuiteProxy = jRequire.deprecatingSuiteProxy(j$);
|
||||
j$.deprecatingSpecProxy = jRequire.deprecatingSpecProxy(j$);
|
||||
j$.StackTrace = jRequire.StackTrace(j$);
|
||||
j$.ExceptionFormatter = jRequire.ExceptionFormatter(j$);
|
||||
j$.ExpectationFilterChain = jRequire.ExpectationFilterChain();
|
||||
@@ -1001,7 +1004,6 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
var currentlyExecutingSuites = [];
|
||||
var currentDeclarationSuite = null;
|
||||
var hasFailures = false;
|
||||
var deprecationsToSuppress = [];
|
||||
|
||||
/**
|
||||
* This represents the available options to configure Jasmine.
|
||||
@@ -1197,6 +1199,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
|
||||
if (configuration.hasOwnProperty('verboseDeprecations')) {
|
||||
config.verboseDeprecations = configuration.verboseDeprecations;
|
||||
deprecator.verboseDeprecations(config.verboseDeprecations);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1451,48 +1454,31 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return buildExpectationResult(attrs);
|
||||
};
|
||||
|
||||
this.deprecated = function(deprecation) {
|
||||
/**
|
||||
* Causes a deprecation warning to be logged to the console and reported to
|
||||
* reporters.
|
||||
*
|
||||
* The optional second parameter is an object that can have either of the
|
||||
* following properties:
|
||||
*
|
||||
* omitStackTrace: Whether to omit the stack trace. Optional. Defaults to
|
||||
* false. This option is ignored if the deprecation is an Error. Set this
|
||||
* when the stack trace will not contain anything that helps the user find
|
||||
* the source of the deprecation.
|
||||
*
|
||||
* ignoreRunnable: Whether to log the deprecation on the root suite, ignoring
|
||||
* the spec or suite that's running when it happens. Optional. Defaults to
|
||||
* false.
|
||||
*
|
||||
* @name Env#deprecated
|
||||
* @since 2.99
|
||||
* @function
|
||||
* @param {String|Error} deprecation The deprecation message
|
||||
* @param {Object} [options] Optional extra options, as described above
|
||||
*/
|
||||
this.deprecated = function(deprecation, options) {
|
||||
var runnable = currentRunnable() || topSuite;
|
||||
var context;
|
||||
|
||||
if (runnable === topSuite) {
|
||||
context = '';
|
||||
} else if (runnable === currentSuite()) {
|
||||
context = ' (in suite: ' + runnable.getFullName() + ')';
|
||||
} else {
|
||||
context = ' (in spec: ' + runnable.getFullName() + ')';
|
||||
}
|
||||
|
||||
runnable.addDeprecationWarning(deprecation);
|
||||
if (
|
||||
typeof console !== 'undefined' &&
|
||||
typeof console.error === 'function'
|
||||
) {
|
||||
console.error('DEPRECATION: ' + deprecation + context);
|
||||
}
|
||||
};
|
||||
|
||||
this.deprecatedOnceWithStack = function(deprecation) {
|
||||
var formatter = new j$.ExceptionFormatter(),
|
||||
stackTrace = formatter
|
||||
.stack(j$.util.errorWithStack())
|
||||
.replace(/^Error\n/m, '');
|
||||
|
||||
if (config.verboseDeprecations) {
|
||||
this.deprecated(deprecation + '\n' + stackTrace);
|
||||
} else {
|
||||
if (deprecationsToSuppress.indexOf(deprecation) === -1) {
|
||||
this.deprecated(
|
||||
deprecation +
|
||||
'\n' +
|
||||
'Note: This message will be shown only once. ' +
|
||||
'Set config.verboseDeprecations to true to see every occurrence.\n' +
|
||||
stackTrace
|
||||
);
|
||||
}
|
||||
|
||||
deprecationsToSuppress.push(deprecation);
|
||||
}
|
||||
deprecator.addDeprecationWarning(runnable, deprecation, options);
|
||||
};
|
||||
|
||||
var queueRunnerFactory = function(options, args) {
|
||||
@@ -1528,6 +1514,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
asyncExpectationFactory: suiteAsyncExpectationFactory,
|
||||
expectationResultFactory: expectationResultFactory
|
||||
});
|
||||
var deprecator = new j$.Deprecator(topSuite);
|
||||
defaultResourcesForRunnable(topSuite.id);
|
||||
currentDeclarationSuite = topSuite;
|
||||
|
||||
@@ -1539,7 +1526,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
* @return {Suite} the root suite
|
||||
*/
|
||||
this.topSuite = function() {
|
||||
return topSuite;
|
||||
return j$.deprecatingSuiteProxy(topSuite, null, this);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -3367,6 +3354,267 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
||||
return DelayedFunctionScheduler;
|
||||
};
|
||||
|
||||
/* eslint-disable compat/compat */
|
||||
// TODO: Remove this in the next major release.
|
||||
getJasmineRequireObj().deprecatingSpecProxy = function(j$) {
|
||||
function isMember(target, prop) {
|
||||
return (
|
||||
Object.keys(target).indexOf(prop) !== -1 ||
|
||||
Object.keys(j$.Spec.prototype).indexOf(prop) !== -1
|
||||
);
|
||||
}
|
||||
|
||||
function isAllowedMember(prop) {
|
||||
return prop === 'description' || prop === 'getFullName';
|
||||
}
|
||||
|
||||
function msg(member) {
|
||||
var memberName = member.toString().replace(/^Symbol\((.+)\)$/, '$1');
|
||||
return (
|
||||
'Access to private Spec members (in this case `' +
|
||||
memberName +
|
||||
'`) via Env#topSuite is not supported and will break in ' +
|
||||
'a future release. See <https://jasmine.github.io/api/edge/Spec.html> ' +
|
||||
'for correct usage.'
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
new Proxy({}, {});
|
||||
} catch (e) {
|
||||
// Environment does not support Poxy.
|
||||
return function(spec) {
|
||||
return spec;
|
||||
};
|
||||
}
|
||||
|
||||
function DeprecatingSpecProxyHandler(env) {
|
||||
this._env = env;
|
||||
}
|
||||
|
||||
DeprecatingSpecProxyHandler.prototype.get = function(target, prop, receiver) {
|
||||
this._maybeDeprecate(target, prop);
|
||||
|
||||
if (prop === 'getFullName') {
|
||||
// getFullName calls a private method. Re-bind 'this' to avoid a bogus
|
||||
// deprecation warning.
|
||||
return target.getFullName.bind(target);
|
||||
} else {
|
||||
return target[prop];
|
||||
}
|
||||
};
|
||||
|
||||
DeprecatingSpecProxyHandler.prototype.set = function(target, prop, value) {
|
||||
this._maybeDeprecate(target, prop);
|
||||
return (target[prop] = value);
|
||||
};
|
||||
|
||||
DeprecatingSpecProxyHandler.prototype._maybeDeprecate = function(
|
||||
target,
|
||||
prop
|
||||
) {
|
||||
if (isMember(target, prop) && !isAllowedMember(prop)) {
|
||||
this._env.deprecated(msg(prop));
|
||||
}
|
||||
};
|
||||
|
||||
function deprecatingSpecProxy(spec, env) {
|
||||
return new Proxy(spec, new DeprecatingSpecProxyHandler(env));
|
||||
}
|
||||
|
||||
return deprecatingSpecProxy;
|
||||
};
|
||||
|
||||
/* eslint-disable compat/compat */
|
||||
// TODO: Remove this in the next major release.
|
||||
getJasmineRequireObj().deprecatingSuiteProxy = function(j$) {
|
||||
var allowedMembers = [
|
||||
'children',
|
||||
'description',
|
||||
'parentSuite',
|
||||
'getFullName'
|
||||
];
|
||||
|
||||
function isMember(target, prop) {
|
||||
return (
|
||||
Object.keys(target).indexOf(prop) !== -1 ||
|
||||
Object.keys(j$.Suite.prototype).indexOf(prop) !== -1
|
||||
);
|
||||
}
|
||||
|
||||
function isAllowedMember(prop) {
|
||||
return allowedMembers.indexOf(prop) !== -1;
|
||||
}
|
||||
|
||||
function msg(member) {
|
||||
var memberName = member.toString().replace(/^Symbol\((.+)\)$/, '$1');
|
||||
return (
|
||||
'Access to private Suite members (in this case `' +
|
||||
memberName +
|
||||
'`) via Env#topSuite is not supported and will break in ' +
|
||||
'a future release. See <https://jasmine.github.io/api/edge/Suite.html> ' +
|
||||
'for correct usage.'
|
||||
);
|
||||
}
|
||||
try {
|
||||
new Proxy({}, {});
|
||||
} catch (e) {
|
||||
// Environment does not support Poxy.
|
||||
return function(suite) {
|
||||
return suite;
|
||||
};
|
||||
}
|
||||
|
||||
function DeprecatingSuiteProxyHandler(parentSuite, env) {
|
||||
this._parentSuite = parentSuite;
|
||||
this._env = env;
|
||||
}
|
||||
|
||||
DeprecatingSuiteProxyHandler.prototype.get = function(
|
||||
target,
|
||||
prop,
|
||||
receiver
|
||||
) {
|
||||
if (prop === 'children') {
|
||||
if (!this._children) {
|
||||
this._children = target.children.map(
|
||||
this._proxyForChild.bind(this, receiver)
|
||||
);
|
||||
}
|
||||
|
||||
return this._children;
|
||||
} else if (prop === 'parentSuite') {
|
||||
return this._parentSuite;
|
||||
} else {
|
||||
this._maybeDeprecate(target, prop);
|
||||
return target[prop];
|
||||
}
|
||||
};
|
||||
|
||||
DeprecatingSuiteProxyHandler.prototype.set = function(target, prop, value) {
|
||||
debugger;
|
||||
this._maybeDeprecate(target, prop);
|
||||
return (target[prop] = value);
|
||||
};
|
||||
|
||||
DeprecatingSuiteProxyHandler.prototype._maybeDeprecate = function(
|
||||
target,
|
||||
prop
|
||||
) {
|
||||
if (isMember(target, prop) && !isAllowedMember(prop)) {
|
||||
this._env.deprecated(msg(prop));
|
||||
}
|
||||
};
|
||||
|
||||
DeprecatingSuiteProxyHandler.prototype._proxyForChild = function(
|
||||
ownProxy,
|
||||
child
|
||||
) {
|
||||
if (child.children) {
|
||||
return deprecatingSuiteProxy(child, ownProxy, this._env);
|
||||
} else {
|
||||
return j$.deprecatingSpecProxy(child, this._env);
|
||||
}
|
||||
};
|
||||
|
||||
function deprecatingSuiteProxy(suite, parentSuite, env) {
|
||||
return new Proxy(suite, new DeprecatingSuiteProxyHandler(parentSuite, env));
|
||||
}
|
||||
|
||||
return deprecatingSuiteProxy;
|
||||
};
|
||||
|
||||
getJasmineRequireObj().Deprecator = function(j$) {
|
||||
function Deprecator(topSuite) {
|
||||
this.topSuite_ = topSuite;
|
||||
this.verbose_ = false;
|
||||
this.toSuppress_ = [];
|
||||
}
|
||||
|
||||
var verboseNote =
|
||||
'Note: This message will be shown only once. ' +
|
||||
'Set config.verboseDeprecations to true to see every occurrence.';
|
||||
|
||||
Deprecator.prototype.verboseDeprecations = function(enabled) {
|
||||
this.verbose_ = enabled;
|
||||
};
|
||||
|
||||
// runnable is a spec or a suite.
|
||||
// deprecation is a string or an Error.
|
||||
// See Env#deprecated for a description of the options argument.
|
||||
Deprecator.prototype.addDeprecationWarning = function(
|
||||
runnable,
|
||||
deprecation,
|
||||
options
|
||||
) {
|
||||
options = options || {};
|
||||
|
||||
if (!this.verbose_ && !j$.isError_(deprecation)) {
|
||||
if (this.toSuppress_.indexOf(deprecation) !== -1) {
|
||||
return;
|
||||
}
|
||||
this.toSuppress_.push(deprecation);
|
||||
}
|
||||
|
||||
this.log_(runnable, deprecation, options);
|
||||
this.report_(runnable, deprecation, options);
|
||||
};
|
||||
|
||||
Deprecator.prototype.log_ = function(runnable, deprecation, options) {
|
||||
var context;
|
||||
|
||||
if (j$.isError_(deprecation)) {
|
||||
console.error(deprecation);
|
||||
return;
|
||||
}
|
||||
|
||||
if (runnable === this.topSuite_ || options.ignoreRunnable) {
|
||||
context = '';
|
||||
} else if (runnable.children) {
|
||||
context = ' (in suite: ' + runnable.getFullName() + ')';
|
||||
} else {
|
||||
context = ' (in spec: ' + runnable.getFullName() + ')';
|
||||
}
|
||||
|
||||
if (!options.omitStackTrace) {
|
||||
context += '\n' + this.stackTrace_();
|
||||
}
|
||||
|
||||
if (!this.verbose_) {
|
||||
context += '\n' + verboseNote;
|
||||
}
|
||||
|
||||
console.error('DEPRECATION: ' + deprecation + context);
|
||||
};
|
||||
|
||||
Deprecator.prototype.stackTrace_ = function() {
|
||||
var formatter = new j$.ExceptionFormatter();
|
||||
return formatter.stack(j$.util.errorWithStack()).replace(/^Error\n/m, '');
|
||||
};
|
||||
|
||||
Deprecator.prototype.report_ = function(runnable, deprecation, options) {
|
||||
if (options.ignoreRunnable) {
|
||||
runnable = this.topSuite_;
|
||||
}
|
||||
|
||||
if (j$.isError_(deprecation)) {
|
||||
runnable.addDeprecationWarning(deprecation);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.verbose_) {
|
||||
deprecation += '\n' + verboseNote;
|
||||
}
|
||||
|
||||
runnable.addDeprecationWarning({
|
||||
message: deprecation,
|
||||
omitStackTrace: options.omitStackTrace || false
|
||||
});
|
||||
};
|
||||
|
||||
return Deprecator;
|
||||
};
|
||||
|
||||
getJasmineRequireObj().errors = function() {
|
||||
function ExpectationFailed() {}
|
||||
|
||||
@@ -3779,7 +4027,7 @@ getJasmineRequireObj().buildExpectationResult = function(j$) {
|
||||
var result = {
|
||||
matcherName: options.matcherName,
|
||||
message: message(),
|
||||
stack: stack(),
|
||||
stack: options.omitStackTrace ? '' : stack(),
|
||||
passed: options.passed
|
||||
};
|
||||
|
||||
@@ -7466,8 +7714,12 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
};
|
||||
|
||||
QueueRunner.prototype.diagnoseConflictingAsync_ = function(fn, retval) {
|
||||
var msg;
|
||||
|
||||
if (retval && j$.isFunction_(retval.then)) {
|
||||
// Issue a warning that matches the user's code
|
||||
// Issue a warning that matches the user's code.
|
||||
// Omit the stack trace because there's almost certainly no user code
|
||||
// on the stack at this point.
|
||||
if (j$.isAsyncFunction_(fn)) {
|
||||
this.onException(
|
||||
'An asynchronous before/it/after ' +
|
||||
@@ -7483,6 +7735,8 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
'function to not return a promise.'
|
||||
);
|
||||
}
|
||||
|
||||
this.deprecated(msg, { omitStackTrace: true });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
329
spec/core/DeprecatorSpec.js
Normal file
329
spec/core/DeprecatorSpec.js
Normal file
@@ -0,0 +1,329 @@
|
||||
/* eslint no-console: 0 */
|
||||
describe('Deprecator', function() {
|
||||
describe('#deprecate', function() {
|
||||
beforeEach(function() {
|
||||
spyOn(console, 'error');
|
||||
});
|
||||
|
||||
it('logs the mesage without context when the runnable is the top suite', function() {
|
||||
var runnable = { addDeprecationWarning: function() {} };
|
||||
var deprecator = new jasmineUnderTest.Deprecator(runnable);
|
||||
deprecator.verboseDeprecations(true);
|
||||
|
||||
deprecator.addDeprecationWarning(runnable, 'the message', {
|
||||
omitStackTrace: true
|
||||
});
|
||||
|
||||
expect(console.error).toHaveBeenCalledWith('DEPRECATION: the message');
|
||||
});
|
||||
|
||||
it('logs the message in a descendant suite', function() {
|
||||
var runnable = {
|
||||
addDeprecationWarning: function() {},
|
||||
getFullName: function() {
|
||||
return 'the suite';
|
||||
},
|
||||
children: []
|
||||
};
|
||||
var deprecator = new jasmineUnderTest.Deprecator({});
|
||||
deprecator.verboseDeprecations(true);
|
||||
|
||||
deprecator.addDeprecationWarning(runnable, 'the message', {
|
||||
omitStackTrace: true
|
||||
});
|
||||
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
'DEPRECATION: the message (in suite: the suite)'
|
||||
);
|
||||
});
|
||||
|
||||
it('logs and reports the message in a spec', function() {
|
||||
var runnable = {
|
||||
addDeprecationWarning: function() {},
|
||||
getFullName: function() {
|
||||
return 'the spec';
|
||||
}
|
||||
};
|
||||
var deprecator = new jasmineUnderTest.Deprecator({});
|
||||
deprecator.verboseDeprecations(true);
|
||||
|
||||
deprecator.addDeprecationWarning(runnable, 'the message', {
|
||||
omitStackTrace: true
|
||||
});
|
||||
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
'DEPRECATION: the message (in spec: the spec)'
|
||||
);
|
||||
});
|
||||
|
||||
it('logs and reports the message without runnable info when ignoreRunnable is true', function() {
|
||||
var topSuite = jasmine.createSpyObj('topSuite', [
|
||||
'addDeprecationWarning',
|
||||
'getFullName'
|
||||
]);
|
||||
var deprecator = new jasmineUnderTest.Deprecator(topSuite);
|
||||
var runnable = jasmine.createSpyObj('spec', [
|
||||
'addDeprecationWarning',
|
||||
'getFullName'
|
||||
]);
|
||||
runnable.getFullName.and.returnValue('a spec');
|
||||
|
||||
deprecator.addDeprecationWarning(runnable, 'the message', {
|
||||
ignoreRunnable: true
|
||||
});
|
||||
|
||||
expect(topSuite.addDeprecationWarning).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
);
|
||||
expect(runnable.addDeprecationWarning).not.toHaveBeenCalled();
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(/the message/)
|
||||
);
|
||||
expect(console.error).not.toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(/a spec/)
|
||||
);
|
||||
});
|
||||
|
||||
describe('with no options', function() {
|
||||
it('includes the stack trace', function() {
|
||||
testStackTrace(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
it('omits the stack trace when omitStackTrace is true', function() {
|
||||
testNoStackTrace({ omitStackTrace: true });
|
||||
});
|
||||
|
||||
it('includes the stack trace when omitStackTrace is false', function() {
|
||||
testStackTrace({ omitStackTrace: false });
|
||||
});
|
||||
|
||||
it('includes the stack trace when omitStackTrace is undefined', function() {
|
||||
testStackTrace({ includeStackTrace: undefined });
|
||||
});
|
||||
|
||||
it('emits the deprecation only once when verboseDeprecations is not set', function() {
|
||||
var deprecator = new jasmineUnderTest.Deprecator({});
|
||||
var runnable1 = jasmine.createSpyObj('runnable1', [
|
||||
'addDeprecationWarning',
|
||||
'getFullName'
|
||||
]);
|
||||
var runnable2 = jasmine.createSpyObj('runnable2', [
|
||||
'addDeprecationWarning',
|
||||
'getFullName'
|
||||
]);
|
||||
|
||||
deprecator.addDeprecationWarning(runnable1, 'the message');
|
||||
deprecator.addDeprecationWarning(runnable1, 'the message');
|
||||
deprecator.addDeprecationWarning(runnable2, 'the message');
|
||||
|
||||
expect(runnable1.addDeprecationWarning).toHaveBeenCalledTimes(1);
|
||||
expect(runnable2.addDeprecationWarning).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('emits the deprecation only once when verboseDeprecations is false', function() {
|
||||
var deprecator = new jasmineUnderTest.Deprecator({});
|
||||
var runnable1 = jasmine.createSpyObj('runnable1', [
|
||||
'addDeprecationWarning',
|
||||
'getFullName'
|
||||
]);
|
||||
var runnable2 = jasmine.createSpyObj('runnable2', [
|
||||
'addDeprecationWarning',
|
||||
'getFullName'
|
||||
]);
|
||||
|
||||
deprecator.verboseDeprecations(false);
|
||||
deprecator.addDeprecationWarning(runnable1, 'the message');
|
||||
deprecator.addDeprecationWarning(runnable1, 'the message');
|
||||
deprecator.addDeprecationWarning(runnable2, 'the message');
|
||||
|
||||
expect(runnable1.addDeprecationWarning).toHaveBeenCalledTimes(1);
|
||||
expect(runnable2.addDeprecationWarning).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('emits the deprecation for each call when verboseDeprecations is true', function() {
|
||||
var deprecator = new jasmineUnderTest.Deprecator({});
|
||||
var runnable1 = jasmine.createSpyObj('runnable1', [
|
||||
'addDeprecationWarning',
|
||||
'getFullName'
|
||||
]);
|
||||
var runnable2 = jasmine.createSpyObj('runnable2', [
|
||||
'addDeprecationWarning',
|
||||
'getFullName'
|
||||
]);
|
||||
|
||||
deprecator.verboseDeprecations(true);
|
||||
deprecator.addDeprecationWarning(runnable1, 'the message');
|
||||
deprecator.addDeprecationWarning(runnable1, 'the message');
|
||||
deprecator.addDeprecationWarning(runnable2, 'the message');
|
||||
|
||||
expect(runnable1.addDeprecationWarning).toHaveBeenCalledTimes(2);
|
||||
expect(runnable2.addDeprecationWarning).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('includes a note about verboseDeprecations', function() {
|
||||
var deprecator = new jasmineUnderTest.Deprecator({});
|
||||
var runnable = jasmine.createSpyObj('runnable', [
|
||||
'addDeprecationWarning',
|
||||
'getFullName'
|
||||
]);
|
||||
|
||||
deprecator.addDeprecationWarning(runnable, 'the message');
|
||||
|
||||
expect(runnable.addDeprecationWarning).toHaveBeenCalledTimes(1);
|
||||
expect(
|
||||
runnable.addDeprecationWarning.calls.argsFor(0)[0].message
|
||||
).toContain(verboseDeprecationsNote());
|
||||
expect(console.error).toHaveBeenCalledTimes(1);
|
||||
expect(console.error.calls.argsFor(0)[0]).toContain(
|
||||
verboseDeprecationsNote()
|
||||
);
|
||||
});
|
||||
|
||||
it('omits the note about verboseDeprecations when verboseDeprecations is true', function() {
|
||||
var deprecator = new jasmineUnderTest.Deprecator({});
|
||||
var runnable = jasmine.createSpyObj('runnable', [
|
||||
'addDeprecationWarning',
|
||||
'getFullName'
|
||||
]);
|
||||
|
||||
deprecator.verboseDeprecations(true);
|
||||
deprecator.addDeprecationWarning(runnable, 'the message');
|
||||
|
||||
expect(runnable.addDeprecationWarning).toHaveBeenCalledTimes(1);
|
||||
expect(
|
||||
runnable.addDeprecationWarning.calls.argsFor(0)[0].message
|
||||
).not.toContain(verboseDeprecationsNote());
|
||||
expect(console.error).toHaveBeenCalledTimes(1);
|
||||
expect(console.error.calls.argsFor(0)[0]).not.toContain(
|
||||
verboseDeprecationsNote()
|
||||
);
|
||||
});
|
||||
|
||||
describe('When the deprecation is an Error', function() {
|
||||
// This form is used by external systems like atom-jasmine3-test-runner
|
||||
// to report their own deprecations through Jasmine. See
|
||||
// <https://github.com/jasmine/jasmine/pull/1498>.
|
||||
it('passes the error through unchanged', function() {
|
||||
var deprecator = new jasmineUnderTest.Deprecator({});
|
||||
var runnable = jasmine.createSpyObj('runnable', [
|
||||
'addDeprecationWarning',
|
||||
'getFullName'
|
||||
]);
|
||||
var exceptionFormatter = new jasmineUnderTest.ExceptionFormatter();
|
||||
var deprecation, originalStack;
|
||||
|
||||
try {
|
||||
throw new Error('the deprecation');
|
||||
} catch (err) {
|
||||
deprecation = err;
|
||||
originalStack = err.stack;
|
||||
}
|
||||
|
||||
deprecator.addDeprecationWarning(runnable, deprecation);
|
||||
|
||||
expect(runnable.addDeprecationWarning).toHaveBeenCalledTimes(1);
|
||||
expect(
|
||||
runnable.addDeprecationWarning.calls.argsFor(0)[0].message
|
||||
).toEqual('the deprecation');
|
||||
expect(runnable.addDeprecationWarning.calls.argsFor(0)[0].stack).toBe(
|
||||
originalStack
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledTimes(1);
|
||||
expect(console.error.calls.argsFor(0)[0].message).toEqual(
|
||||
'the deprecation'
|
||||
);
|
||||
expect(console.error.calls.argsFor(0)[0].stack).toEqual(originalStack);
|
||||
});
|
||||
|
||||
it('reports the deprecation every time, regardless of config.verboseDeprecations', function() {
|
||||
var deprecator = new jasmineUnderTest.Deprecator({});
|
||||
var runnable = jasmine.createSpyObj('runnable', [
|
||||
'addDeprecationWarning',
|
||||
'getFullName'
|
||||
]);
|
||||
var deprecation;
|
||||
|
||||
try {
|
||||
throw new Error('the deprecation');
|
||||
} catch (err) {
|
||||
deprecation = err;
|
||||
}
|
||||
|
||||
deprecator.addDeprecationWarning(runnable, deprecation);
|
||||
deprecator.addDeprecationWarning(runnable, deprecation);
|
||||
|
||||
expect(runnable.addDeprecationWarning).toHaveBeenCalledTimes(2);
|
||||
expect(console.error).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('omits the note about verboseDeprecations', function() {
|
||||
var deprecator = new jasmineUnderTest.Deprecator({});
|
||||
var runnable = jasmine.createSpyObj('runnable', [
|
||||
'addDeprecationWarning',
|
||||
'getFullName'
|
||||
]);
|
||||
var deprecation;
|
||||
|
||||
try {
|
||||
throw new Error('the deprecation');
|
||||
} catch (err) {
|
||||
deprecation = err;
|
||||
}
|
||||
|
||||
deprecator.addDeprecationWarning(runnable, deprecation);
|
||||
|
||||
expect(runnable.addDeprecationWarning).toHaveBeenCalledTimes(1);
|
||||
expect(
|
||||
runnable.addDeprecationWarning.calls.argsFor(0)[0].message
|
||||
).not.toContain(verboseDeprecationsNote());
|
||||
expect(console.error).toHaveBeenCalledTimes(1);
|
||||
expect(console.error.calls.argsFor(0)[0]).not.toContain(
|
||||
verboseDeprecationsNote()
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
function verboseDeprecationsNote() {
|
||||
return (
|
||||
'Note: This message will be shown only once. Set ' +
|
||||
'config.verboseDeprecations to true to see every occurrence.'
|
||||
);
|
||||
}
|
||||
|
||||
function testStackTrace(options) {
|
||||
var deprecator = new jasmineUnderTest.Deprecator({});
|
||||
var runnable = jasmine.createSpyObj('runnable', [
|
||||
'addDeprecationWarning',
|
||||
'getFullName'
|
||||
]);
|
||||
|
||||
deprecator.addDeprecationWarning(runnable, 'the message', options);
|
||||
|
||||
expect(runnable.addDeprecationWarning).toHaveBeenCalledWith({
|
||||
message: jasmine.stringMatching(/^the message/),
|
||||
omitStackTrace: false
|
||||
});
|
||||
expect(console.error).toHaveBeenCalledTimes(1);
|
||||
expect(console.error.calls.argsFor(0)[0]).toContain('the message');
|
||||
expect(console.error.calls.argsFor(0)[0]).toContain('DeprecatorSpec.js');
|
||||
}
|
||||
|
||||
function testNoStackTrace(options) {
|
||||
var deprecator = new jasmineUnderTest.Deprecator({});
|
||||
var runnable = jasmine.createSpyObj('runnable', [
|
||||
'addDeprecationWarning',
|
||||
'getFullName'
|
||||
]);
|
||||
|
||||
deprecator.addDeprecationWarning(runnable, 'the message', options);
|
||||
|
||||
expect(runnable.addDeprecationWarning).toHaveBeenCalledWith({
|
||||
message: jasmine.stringMatching(/^the message/),
|
||||
omitStackTrace: true
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -26,9 +26,141 @@ describe('Env', function() {
|
||||
});
|
||||
|
||||
describe('#topSuite', function() {
|
||||
it('returns the Jasmine top suite for users to traverse the spec tree', function() {
|
||||
var suite = env.topSuite();
|
||||
it('returns an object that describes the tree of suites and specs', function() {
|
||||
var suite;
|
||||
spyOn(env, 'deprecated');
|
||||
|
||||
env.it('a top level spec');
|
||||
env.describe('a suite', function() {
|
||||
env.it('a spec');
|
||||
env.describe('a nested suite', function() {
|
||||
env.it('a nested spec');
|
||||
});
|
||||
});
|
||||
|
||||
suite = env.topSuite();
|
||||
expect(suite.description).toEqual('Jasmine__TopLevel__Suite');
|
||||
expect(suite.getFullName()).toEqual('');
|
||||
expect(suite.children.length).toEqual(2);
|
||||
|
||||
expect(suite.children[0].description).toEqual('a top level spec');
|
||||
expect(suite.children[0].getFullName()).toEqual('a top level spec');
|
||||
expect(suite.children[0].children).toBeFalsy();
|
||||
|
||||
expect(suite.children[1].description).toEqual('a suite');
|
||||
expect(suite.children[1].getFullName()).toEqual('a suite');
|
||||
expect(suite.children[1].parentSuite).toBe(suite);
|
||||
expect(suite.children[1].children.length).toEqual(2);
|
||||
|
||||
expect(suite.children[1].children[0].description).toEqual('a spec');
|
||||
expect(suite.children[1].children[0].getFullName()).toEqual(
|
||||
'a suite a spec'
|
||||
);
|
||||
expect(suite.children[1].children[0].children).toBeFalsy();
|
||||
|
||||
expect(suite.children[1].children[1].description).toEqual(
|
||||
'a nested suite'
|
||||
);
|
||||
expect(suite.children[1].children[1].getFullName()).toEqual(
|
||||
'a suite a nested suite'
|
||||
);
|
||||
expect(suite.children[1].children[1].parentSuite).toBe(suite.children[1]);
|
||||
expect(suite.children[1].children[1].children.length).toEqual(1);
|
||||
|
||||
expect(suite.children[1].children[1].children[0].description).toEqual(
|
||||
'a nested spec'
|
||||
);
|
||||
expect(suite.children[1].children[1].children[0].getFullName()).toEqual(
|
||||
'a suite a nested suite a nested spec'
|
||||
);
|
||||
expect(suite.children[1].children[1].children[0].children).toBeFalsy();
|
||||
});
|
||||
|
||||
it('does not deprecate access to public Suite and Spec members', function() {
|
||||
jasmine.getEnv().requireProxy();
|
||||
var suite;
|
||||
spyOn(env, 'deprecated');
|
||||
|
||||
env.it('a top level spec');
|
||||
env.describe('a suite', function() {
|
||||
env.it('a spec');
|
||||
});
|
||||
|
||||
suite = env.topSuite();
|
||||
suite.description;
|
||||
suite.getFullName();
|
||||
suite.children;
|
||||
suite.parentSuite;
|
||||
suite.children[0].description;
|
||||
suite.children[0].getFullName();
|
||||
suite.children[0].children;
|
||||
|
||||
suite.children[1].description;
|
||||
suite.children[1].getFullName();
|
||||
suite.children[1].parentSuite;
|
||||
suite.children[1].children;
|
||||
|
||||
expect(env.deprecated).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('deprecates access to internal Suite and Spec members', function() {
|
||||
jasmine.getEnv().requireProxy();
|
||||
var topSuite, expectationFactory, spec;
|
||||
|
||||
env.it('a top level spec');
|
||||
spyOn(env, 'deprecated');
|
||||
topSuite = env.topSuite();
|
||||
|
||||
topSuite.expectationFactory;
|
||||
expect(env.deprecated).toHaveBeenCalledWith(
|
||||
'Access to private Suite ' +
|
||||
'members (in this case `expectationFactory`) via Env#topSuite is ' +
|
||||
'not supported and will break in a future release. See ' +
|
||||
'<https://jasmine.github.io/api/edge/Suite.html> for correct usage.'
|
||||
);
|
||||
env.deprecated.calls.reset();
|
||||
|
||||
topSuite.expectationFactory = expectationFactory;
|
||||
expect(env.deprecated).toHaveBeenCalledWith(
|
||||
'Access to private Suite ' +
|
||||
'members (in this case `expectationFactory`) via Env#topSuite is ' +
|
||||
'not supported and will break in a future release. See ' +
|
||||
'<https://jasmine.github.io/api/edge/Suite.html> for correct usage.'
|
||||
);
|
||||
|
||||
topSuite.status();
|
||||
expect(env.deprecated).toHaveBeenCalledWith(
|
||||
'Access to private Suite ' +
|
||||
'members (in this case `status`) via Env#topSuite is ' +
|
||||
'not supported and will break in a future release. See ' +
|
||||
'<https://jasmine.github.io/api/edge/Suite.html> for correct usage.'
|
||||
);
|
||||
|
||||
spec = topSuite.children[0];
|
||||
spec.pend();
|
||||
expect(env.deprecated).toHaveBeenCalledWith(
|
||||
'Access to private Spec ' +
|
||||
'members (in this case `pend`) via Env#topSuite ' +
|
||||
'is not supported and will break in a future release. See ' +
|
||||
'<https://jasmine.github.io/api/edge/Spec.html> for correct usage.'
|
||||
);
|
||||
|
||||
expectationFactory = spec.expectationFactory;
|
||||
expect(env.deprecated).toHaveBeenCalledWith(
|
||||
'Access to private Spec ' +
|
||||
'members (in this case `expectationFactory`) via Env#topSuite ' +
|
||||
'is not supported and will break in a future release. See ' +
|
||||
'<https://jasmine.github.io/api/edge/Spec.html> for correct usage.'
|
||||
);
|
||||
env.deprecated.calls.reset();
|
||||
|
||||
spec.expectationFactory = expectationFactory;
|
||||
expect(env.deprecated).toHaveBeenCalledWith(
|
||||
'Access to private Spec ' +
|
||||
'members (in this case `expectationFactory`) via Env#topSuite ' +
|
||||
'is not supported and will break in a future release. See ' +
|
||||
'<https://jasmine.github.io/api/edge/Spec.html> for correct usage.'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -289,60 +421,6 @@ describe('Env', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#deprecatedOnceWithStack', function() {
|
||||
it('includes a stack trace', function() {
|
||||
spyOn(env, 'deprecated');
|
||||
|
||||
env.deprecatedOnceWithStack('msg');
|
||||
|
||||
expect(env.deprecated).toHaveBeenCalled();
|
||||
var msg = env.deprecated.calls.argsFor(0)[0];
|
||||
expect(msg).toContain('msg');
|
||||
expect(msg).toContain('EnvSpec.js');
|
||||
expect(msg).not.toContain('Error');
|
||||
});
|
||||
|
||||
describe('When verboseDeprecations is true', function() {
|
||||
it('calls #deprecated every time', function() {
|
||||
env.configure({ verboseDeprecations: true });
|
||||
spyOn(env, 'deprecated');
|
||||
|
||||
env.deprecatedOnceWithStack('msg');
|
||||
env.deprecatedOnceWithStack('msg');
|
||||
expect(env.deprecated).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(/msg/)
|
||||
);
|
||||
expect(env.deprecated).toHaveBeenCalledTimes(2);
|
||||
expect(env.deprecated).not.toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(/only once/)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('When verboseDeprecations is false', function() {
|
||||
it('calls #deprecated once per unique message', function() {
|
||||
env.configure({ verboseDeprecations: false });
|
||||
spyOn(env, 'deprecated');
|
||||
|
||||
env.deprecatedOnceWithStack('foo');
|
||||
env.deprecatedOnceWithStack('bar');
|
||||
env.deprecatedOnceWithStack('foo');
|
||||
|
||||
expect(env.deprecated).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(
|
||||
/foo\nNote: This message will be shown only once. Set config.verboseDeprecations to true to see every occurrence/m
|
||||
)
|
||||
);
|
||||
expect(env.deprecated).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(
|
||||
/bar\nNote: This message will be shown only once. Set config.verboseDeprecations to true to see every occurrence/m
|
||||
)
|
||||
);
|
||||
expect(env.deprecated).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when not constructed with suppressLoadErrors: true', function() {
|
||||
it('installs a global error handler on construction', function() {
|
||||
var globalErrors = jasmine.createSpyObj('globalErrors', [
|
||||
|
||||
322
spec/core/integration/DeprecationSpec.js
Normal file
322
spec/core/integration/DeprecationSpec.js
Normal file
@@ -0,0 +1,322 @@
|
||||
/* eslint no-console: 0 */
|
||||
describe('Deprecation (integration)', function() {
|
||||
var env;
|
||||
|
||||
beforeEach(function() {
|
||||
env = new jasmineUnderTest.Env();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
env.cleanup_();
|
||||
});
|
||||
|
||||
it('reports a deprecation on the top suite', function(done) {
|
||||
var reporter = jasmine.createSpyObj('reporter', ['jasmineDone']);
|
||||
env.addReporter(reporter);
|
||||
spyOn(console, 'error');
|
||||
|
||||
env.beforeAll(function() {
|
||||
env.deprecated('the message');
|
||||
});
|
||||
env.it('a spec', function() {});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(reporter.jasmineDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(/^DEPRECATION: the message/)
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('reports a deprecation on a descendent suite', function(done) {
|
||||
var reporter = jasmine.createSpyObj('reporter', ['suiteDone']);
|
||||
env.addReporter(reporter);
|
||||
spyOn(console, 'error');
|
||||
|
||||
env.describe('a suite', function() {
|
||||
env.beforeAll(function() {
|
||||
env.deprecated('the message');
|
||||
});
|
||||
env.it('a spec', function() {});
|
||||
});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(reporter.suiteDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(
|
||||
/^DEPRECATION: the message \(in suite: a suite\)/
|
||||
)
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('reports a deprecation on a spec', function(done) {
|
||||
var reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
spyOn(console, 'error');
|
||||
|
||||
env.describe('a suite', function() {
|
||||
env.it('a spec', function() {
|
||||
env.deprecated('the message');
|
||||
});
|
||||
});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(
|
||||
/^DEPRECATION: the message \(in spec: a suite a spec\)/
|
||||
)
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('omits the suite or spec context when ignoreRunnable is true', function(done) {
|
||||
var reporter = jasmine.createSpyObj('reporter', ['jasmineDone']);
|
||||
env.addReporter(reporter);
|
||||
spyOn(console, 'error');
|
||||
|
||||
env.it('a spec', function() {
|
||||
env.deprecated('the message', { ignoreRunnable: true });
|
||||
});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(reporter.jasmineDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(/the message/)
|
||||
);
|
||||
expect(console.error).not.toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(/a spec/)
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('includes the stack trace', function(done) {
|
||||
var reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
spyOn(console, 'error');
|
||||
|
||||
env.describe('a suite', function() {
|
||||
env.it('a spec', function() {
|
||||
env.deprecated('the message');
|
||||
});
|
||||
});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
stack: jasmine.stringMatching(/DeprecationSpec.js/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalled();
|
||||
expect(console.error.calls.argsFor(0)[0].replace(/\n/g, 'NL')).toMatch(
|
||||
/^DEPRECATION: the message \(in spec: a suite a spec\)NL.*DeprecationSpec.js/
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('excludes the stack trace when omitStackTrace is true', function(done) {
|
||||
var reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
spyOn(console, 'error');
|
||||
|
||||
env.describe('a suite', function() {
|
||||
env.it('a spec', function() {
|
||||
env.deprecated('the message', { omitStackTrace: true });
|
||||
});
|
||||
});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
stack: jasmine.falsy()
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalled();
|
||||
expect(console.error).not.toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(/DeprecationSpec.js/)
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('emits a given deprecation only once', function(done) {
|
||||
var reporter = jasmine.createSpyObj('reporter', ['specDone', 'suiteDone']);
|
||||
env.addReporter(reporter);
|
||||
spyOn(console, 'error');
|
||||
|
||||
env.describe('a suite', function() {
|
||||
env.beforeAll(function() {
|
||||
env.deprecated('the message');
|
||||
env.deprecated('the message');
|
||||
});
|
||||
|
||||
env.it('a spec', function() {
|
||||
env.deprecated('the message');
|
||||
env.deprecated('a different message');
|
||||
});
|
||||
});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(reporter.suiteDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
// only one
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
// only the other one
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^a different message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledTimes(2);
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(
|
||||
/^DEPRECATION: the message \(in suite: a suite\)/
|
||||
)
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(
|
||||
/^DEPRECATION: a different message \(in spec: a suite a spec\)/
|
||||
)
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('emits a given deprecation each time when config.verboseDeprecations is true', function(done) {
|
||||
var reporter = jasmine.createSpyObj('reporter', ['specDone', 'suiteDone']);
|
||||
env.addReporter(reporter);
|
||||
spyOn(console, 'error');
|
||||
|
||||
env.configure({ verboseDeprecations: true });
|
||||
|
||||
env.describe('a suite', function() {
|
||||
env.beforeAll(function() {
|
||||
env.deprecated('the message');
|
||||
env.deprecated('the message');
|
||||
});
|
||||
|
||||
env.it('a spec', function() {
|
||||
env.deprecated('the message');
|
||||
});
|
||||
});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(reporter.suiteDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
}),
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledTimes(3);
|
||||
expect(console.error.calls.argsFor(0)[0]).toMatch(
|
||||
/^DEPRECATION: the message \(in suite: a suite\)/
|
||||
);
|
||||
expect(console.error.calls.argsFor(1)[0]).toMatch(
|
||||
/^DEPRECATION: the message \(in suite: a suite\)/
|
||||
);
|
||||
expect(console.error.calls.argsFor(2)[0]).toMatch(
|
||||
/^DEPRECATION: the message \(in spec: a suite a spec\)/
|
||||
);
|
||||
expect(console.error.calls.argsFor(2)[0]).toMatch(
|
||||
/^DEPRECATION: the message \(in spec: a suite a spec\)/
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('handles deprecations that occur before execute() is called', function(done) {
|
||||
var reporter = jasmine.createSpyObj('reporter', ['jasmineDone']);
|
||||
env.addReporter(reporter);
|
||||
spyOn(console, 'error');
|
||||
|
||||
env.deprecated('the message');
|
||||
env.it('a spec', function() {});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(reporter.jasmineDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(/^DEPRECATION: the message/)
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -2627,70 +2627,6 @@ describe('Env integration', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should report deprecation warnings on the correct specs and suites', function(done) {
|
||||
var reporter = jasmine.createSpyObj('reporter', [
|
||||
'jasmineDone',
|
||||
'suiteDone',
|
||||
'specDone'
|
||||
]);
|
||||
|
||||
// prevent deprecation from being displayed, as well as letting us observe calls
|
||||
spyOn(console, 'error');
|
||||
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.deprecated('top level deprecation');
|
||||
|
||||
env.describe('suite', function() {
|
||||
env.beforeAll(function() {
|
||||
env.deprecated('suite level deprecation');
|
||||
});
|
||||
|
||||
env.it('spec', function() {
|
||||
env.deprecated('spec level deprecation');
|
||||
});
|
||||
});
|
||||
|
||||
env.execute(null, function() {
|
||||
var result = reporter.jasmineDone.calls.argsFor(0)[0];
|
||||
expect(result.deprecationWarnings).toEqual([
|
||||
jasmine.objectContaining({ message: 'top level deprecation' })
|
||||
]);
|
||||
/* eslint-disable-next-line no-console */
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
'DEPRECATION: top level deprecation'
|
||||
);
|
||||
|
||||
expect(reporter.suiteDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
fullName: 'suite',
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({ message: 'suite level deprecation' })
|
||||
]
|
||||
})
|
||||
);
|
||||
/* eslint-disable-next-line no-console */
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
'DEPRECATION: suite level deprecation (in suite: suite)'
|
||||
);
|
||||
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
fullName: 'suite spec',
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({ message: 'spec level deprecation' })
|
||||
]
|
||||
})
|
||||
);
|
||||
/* eslint-disable-next-line no-console */
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
'DEPRECATION: spec level deprecation (in spec: suite spec)'
|
||||
);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should report deprecation stack with an error object', function(done) {
|
||||
var exceptionFormatter = new jasmineUnderTest.ExceptionFormatter(),
|
||||
reporter = jasmine.createSpyObj('reporter', [
|
||||
|
||||
17
spec/helpers/checkForProxy.js
Normal file
17
spec/helpers/checkForProxy.js
Normal file
@@ -0,0 +1,17 @@
|
||||
/* eslint-disable compat/compat */
|
||||
(function(env) {
|
||||
function hasProxyConstructor() {
|
||||
try {
|
||||
new Proxy({}, {});
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
env.requireProxy = function() {
|
||||
if (!hasProxyConstructor()) {
|
||||
env.pending('Environment does not support Proxy');
|
||||
}
|
||||
};
|
||||
})(jasmine.getEnv());
|
||||
@@ -303,6 +303,128 @@ describe('HtmlReporter', function() {
|
||||
expect(alertBars[3].innerHTML).toMatch(/global deprecation/);
|
||||
expect(alertBars[3].innerHTML).not.toMatch(/in /);
|
||||
});
|
||||
|
||||
it('displays expandable stack traces', function() {
|
||||
var container = document.createElement('div'),
|
||||
getContainer = function() {
|
||||
return container;
|
||||
},
|
||||
reporter = new jasmineUnderTest.HtmlReporter({
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
createElement: function() {
|
||||
return document.createElement.apply(document, arguments);
|
||||
},
|
||||
createTextNode: function() {
|
||||
return document.createTextNode.apply(document, arguments);
|
||||
}
|
||||
}),
|
||||
expander,
|
||||
expanderLink,
|
||||
expanderContents;
|
||||
|
||||
reporter.initialize();
|
||||
|
||||
reporter.jasmineStarted({});
|
||||
reporter.jasmineDone({
|
||||
deprecationWarnings: [
|
||||
{
|
||||
message: 'a deprecation',
|
||||
stack: 'a stack trace'
|
||||
}
|
||||
],
|
||||
failedExpectations: []
|
||||
});
|
||||
|
||||
expander = container.querySelector(
|
||||
'.jasmine-alert .jasmine-bar .jasmine-expander'
|
||||
);
|
||||
expanderContents = expander.querySelector('.jasmine-expander-contents');
|
||||
expect(expanderContents.textContent).toMatch(/a stack trace/);
|
||||
|
||||
expanderLink = expander.querySelector('a');
|
||||
expect(expander).not.toHaveClass('jasmine-expanded');
|
||||
expect(expanderLink.textContent).toMatch(/Show stack trace/);
|
||||
|
||||
expanderLink.click();
|
||||
expect(expander).toHaveClass('jasmine-expanded');
|
||||
expect(expanderLink.textContent).toMatch(/Hide stack trace/);
|
||||
expanderLink.click();
|
||||
|
||||
expect(expander).not.toHaveClass('jasmine-expanded');
|
||||
expect(expanderLink.textContent).toMatch(/Show stack trace/);
|
||||
});
|
||||
|
||||
it('omits the expander when there is no stack trace', function() {
|
||||
var container = document.createElement('div'),
|
||||
getContainer = function() {
|
||||
return container;
|
||||
},
|
||||
reporter = new jasmineUnderTest.HtmlReporter({
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
createElement: function() {
|
||||
return document.createElement.apply(document, arguments);
|
||||
},
|
||||
createTextNode: function() {
|
||||
return document.createTextNode.apply(document, arguments);
|
||||
}
|
||||
}),
|
||||
warningBar;
|
||||
|
||||
reporter.initialize();
|
||||
|
||||
reporter.jasmineStarted({});
|
||||
reporter.jasmineDone({
|
||||
deprecationWarnings: [
|
||||
{
|
||||
message: 'a deprecation',
|
||||
stack: ''
|
||||
}
|
||||
],
|
||||
failedExpectations: []
|
||||
});
|
||||
|
||||
warningBar = container.querySelector('.jasmine-warning');
|
||||
expect(warningBar.querySelector('.jasmine-expander')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('nicely formats the verboseDeprecations note', function() {
|
||||
var container = document.createElement('div'),
|
||||
getContainer = function() {
|
||||
return container;
|
||||
},
|
||||
reporter = new jasmineUnderTest.HtmlReporter({
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
createElement: function() {
|
||||
return document.createElement.apply(document, arguments);
|
||||
},
|
||||
createTextNode: function() {
|
||||
return document.createTextNode.apply(document, arguments);
|
||||
}
|
||||
}),
|
||||
alertBar;
|
||||
|
||||
reporter.initialize();
|
||||
|
||||
reporter.jasmineStarted({});
|
||||
reporter.jasmineDone({
|
||||
deprecationWarnings: [
|
||||
{
|
||||
message:
|
||||
'a deprecation\nNote: This message will be shown only once. Set config.verboseDeprecations to true to see every occurrence.'
|
||||
}
|
||||
],
|
||||
failedExpectations: []
|
||||
});
|
||||
|
||||
alertBar = container.querySelector('.jasmine-warning');
|
||||
|
||||
expect(alertBar.innerHTML).toMatch(
|
||||
/a deprecation<br>Note: This message will be shown only once/
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when Jasmine is done', function() {
|
||||
|
||||
@@ -21,6 +21,7 @@ module.exports = {
|
||||
'helpers/generator.js',
|
||||
'helpers/BrowserFlags.js',
|
||||
'helpers/checkForMap.js',
|
||||
'helpers/checkForProxy.js',
|
||||
'helpers/checkForSet.js',
|
||||
'helpers/checkForSymbol.js',
|
||||
'helpers/checkForUrl.js',
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"helpers/asyncAwait.js",
|
||||
"helpers/generator.js",
|
||||
"helpers/checkForMap.js",
|
||||
"helpers/checkForProxy.js",
|
||||
"helpers/checkForSet.js",
|
||||
"helpers/checkForSymbol.js",
|
||||
"helpers/checkForUrl.js",
|
||||
|
||||
90
src/core/Deprecator.js
Normal file
90
src/core/Deprecator.js
Normal file
@@ -0,0 +1,90 @@
|
||||
getJasmineRequireObj().Deprecator = function(j$) {
|
||||
function Deprecator(topSuite) {
|
||||
this.topSuite_ = topSuite;
|
||||
this.verbose_ = false;
|
||||
this.toSuppress_ = [];
|
||||
}
|
||||
|
||||
var verboseNote =
|
||||
'Note: This message will be shown only once. ' +
|
||||
'Set config.verboseDeprecations to true to see every occurrence.';
|
||||
|
||||
Deprecator.prototype.verboseDeprecations = function(enabled) {
|
||||
this.verbose_ = enabled;
|
||||
};
|
||||
|
||||
// runnable is a spec or a suite.
|
||||
// deprecation is a string or an Error.
|
||||
// See Env#deprecated for a description of the options argument.
|
||||
Deprecator.prototype.addDeprecationWarning = function(
|
||||
runnable,
|
||||
deprecation,
|
||||
options
|
||||
) {
|
||||
options = options || {};
|
||||
|
||||
if (!this.verbose_ && !j$.isError_(deprecation)) {
|
||||
if (this.toSuppress_.indexOf(deprecation) !== -1) {
|
||||
return;
|
||||
}
|
||||
this.toSuppress_.push(deprecation);
|
||||
}
|
||||
|
||||
this.log_(runnable, deprecation, options);
|
||||
this.report_(runnable, deprecation, options);
|
||||
};
|
||||
|
||||
Deprecator.prototype.log_ = function(runnable, deprecation, options) {
|
||||
var context;
|
||||
|
||||
if (j$.isError_(deprecation)) {
|
||||
console.error(deprecation);
|
||||
return;
|
||||
}
|
||||
|
||||
if (runnable === this.topSuite_ || options.ignoreRunnable) {
|
||||
context = '';
|
||||
} else if (runnable.children) {
|
||||
context = ' (in suite: ' + runnable.getFullName() + ')';
|
||||
} else {
|
||||
context = ' (in spec: ' + runnable.getFullName() + ')';
|
||||
}
|
||||
|
||||
if (!options.omitStackTrace) {
|
||||
context += '\n' + this.stackTrace_();
|
||||
}
|
||||
|
||||
if (!this.verbose_) {
|
||||
context += '\n' + verboseNote;
|
||||
}
|
||||
|
||||
console.error('DEPRECATION: ' + deprecation + context);
|
||||
};
|
||||
|
||||
Deprecator.prototype.stackTrace_ = function() {
|
||||
var formatter = new j$.ExceptionFormatter();
|
||||
return formatter.stack(j$.util.errorWithStack()).replace(/^Error\n/m, '');
|
||||
};
|
||||
|
||||
Deprecator.prototype.report_ = function(runnable, deprecation, options) {
|
||||
if (options.ignoreRunnable) {
|
||||
runnable = this.topSuite_;
|
||||
}
|
||||
|
||||
if (j$.isError_(deprecation)) {
|
||||
runnable.addDeprecationWarning(deprecation);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.verbose_) {
|
||||
deprecation += '\n' + verboseNote;
|
||||
}
|
||||
|
||||
runnable.addDeprecationWarning({
|
||||
message: deprecation,
|
||||
omitStackTrace: options.omitStackTrace || false
|
||||
});
|
||||
};
|
||||
|
||||
return Deprecator;
|
||||
};
|
||||
@@ -32,7 +32,6 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
var currentlyExecutingSuites = [];
|
||||
var currentDeclarationSuite = null;
|
||||
var hasFailures = false;
|
||||
var deprecationsToSuppress = [];
|
||||
|
||||
/**
|
||||
* This represents the available options to configure Jasmine.
|
||||
@@ -228,6 +227,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
|
||||
if (configuration.hasOwnProperty('verboseDeprecations')) {
|
||||
config.verboseDeprecations = configuration.verboseDeprecations;
|
||||
deprecator.verboseDeprecations(config.verboseDeprecations);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -482,48 +482,31 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return buildExpectationResult(attrs);
|
||||
};
|
||||
|
||||
this.deprecated = function(deprecation) {
|
||||
/**
|
||||
* Causes a deprecation warning to be logged to the console and reported to
|
||||
* reporters.
|
||||
*
|
||||
* The optional second parameter is an object that can have either of the
|
||||
* following properties:
|
||||
*
|
||||
* omitStackTrace: Whether to omit the stack trace. Optional. Defaults to
|
||||
* false. This option is ignored if the deprecation is an Error. Set this
|
||||
* when the stack trace will not contain anything that helps the user find
|
||||
* the source of the deprecation.
|
||||
*
|
||||
* ignoreRunnable: Whether to log the deprecation on the root suite, ignoring
|
||||
* the spec or suite that's running when it happens. Optional. Defaults to
|
||||
* false.
|
||||
*
|
||||
* @name Env#deprecated
|
||||
* @since 2.99
|
||||
* @function
|
||||
* @param {String|Error} deprecation The deprecation message
|
||||
* @param {Object} [options] Optional extra options, as described above
|
||||
*/
|
||||
this.deprecated = function(deprecation, options) {
|
||||
var runnable = currentRunnable() || topSuite;
|
||||
var context;
|
||||
|
||||
if (runnable === topSuite) {
|
||||
context = '';
|
||||
} else if (runnable === currentSuite()) {
|
||||
context = ' (in suite: ' + runnable.getFullName() + ')';
|
||||
} else {
|
||||
context = ' (in spec: ' + runnable.getFullName() + ')';
|
||||
}
|
||||
|
||||
runnable.addDeprecationWarning(deprecation);
|
||||
if (
|
||||
typeof console !== 'undefined' &&
|
||||
typeof console.error === 'function'
|
||||
) {
|
||||
console.error('DEPRECATION: ' + deprecation + context);
|
||||
}
|
||||
};
|
||||
|
||||
this.deprecatedOnceWithStack = function(deprecation) {
|
||||
var formatter = new j$.ExceptionFormatter(),
|
||||
stackTrace = formatter
|
||||
.stack(j$.util.errorWithStack())
|
||||
.replace(/^Error\n/m, '');
|
||||
|
||||
if (config.verboseDeprecations) {
|
||||
this.deprecated(deprecation + '\n' + stackTrace);
|
||||
} else {
|
||||
if (deprecationsToSuppress.indexOf(deprecation) === -1) {
|
||||
this.deprecated(
|
||||
deprecation +
|
||||
'\n' +
|
||||
'Note: This message will be shown only once. ' +
|
||||
'Set config.verboseDeprecations to true to see every occurrence.\n' +
|
||||
stackTrace
|
||||
);
|
||||
}
|
||||
|
||||
deprecationsToSuppress.push(deprecation);
|
||||
}
|
||||
deprecator.addDeprecationWarning(runnable, deprecation, options);
|
||||
};
|
||||
|
||||
var queueRunnerFactory = function(options, args) {
|
||||
@@ -559,6 +542,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
asyncExpectationFactory: suiteAsyncExpectationFactory,
|
||||
expectationResultFactory: expectationResultFactory
|
||||
});
|
||||
var deprecator = new j$.Deprecator(topSuite);
|
||||
defaultResourcesForRunnable(topSuite.id);
|
||||
currentDeclarationSuite = topSuite;
|
||||
|
||||
@@ -570,7 +554,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
* @return {Suite} the root suite
|
||||
*/
|
||||
this.topSuite = function() {
|
||||
return topSuite;
|
||||
return j$.deprecatingSuiteProxy(topSuite, null, this);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,7 +16,7 @@ getJasmineRequireObj().buildExpectationResult = function(j$) {
|
||||
var result = {
|
||||
matcherName: options.matcherName,
|
||||
message: message(),
|
||||
stack: stack(),
|
||||
stack: options.omitStackTrace ? '' : stack(),
|
||||
passed: options.passed
|
||||
};
|
||||
|
||||
|
||||
@@ -215,8 +215,12 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
};
|
||||
|
||||
QueueRunner.prototype.diagnoseConflictingAsync_ = function(fn, retval) {
|
||||
var msg;
|
||||
|
||||
if (retval && j$.isFunction_(retval.then)) {
|
||||
// Issue a warning that matches the user's code
|
||||
// Issue a warning that matches the user's code.
|
||||
// Omit the stack trace because there's almost certainly no user code
|
||||
// on the stack at this point.
|
||||
if (j$.isAsyncFunction_(fn)) {
|
||||
this.onException(
|
||||
'An asynchronous before/it/after ' +
|
||||
@@ -232,6 +236,8 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
'function to not return a promise.'
|
||||
);
|
||||
}
|
||||
|
||||
this.deprecated(msg, { omitStackTrace: true });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
70
src/core/deprecatingSpecProxy.js
Normal file
70
src/core/deprecatingSpecProxy.js
Normal file
@@ -0,0 +1,70 @@
|
||||
/* eslint-disable compat/compat */
|
||||
// TODO: Remove this in the next major release.
|
||||
getJasmineRequireObj().deprecatingSpecProxy = function(j$) {
|
||||
function isMember(target, prop) {
|
||||
return (
|
||||
Object.keys(target).indexOf(prop) !== -1 ||
|
||||
Object.keys(j$.Spec.prototype).indexOf(prop) !== -1
|
||||
);
|
||||
}
|
||||
|
||||
function isAllowedMember(prop) {
|
||||
return prop === 'description' || prop === 'getFullName';
|
||||
}
|
||||
|
||||
function msg(member) {
|
||||
var memberName = member.toString().replace(/^Symbol\((.+)\)$/, '$1');
|
||||
return (
|
||||
'Access to private Spec members (in this case `' +
|
||||
memberName +
|
||||
'`) via Env#topSuite is not supported and will break in ' +
|
||||
'a future release. See <https://jasmine.github.io/api/edge/Spec.html> ' +
|
||||
'for correct usage.'
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
new Proxy({}, {});
|
||||
} catch (e) {
|
||||
// Environment does not support Poxy.
|
||||
return function(spec) {
|
||||
return spec;
|
||||
};
|
||||
}
|
||||
|
||||
function DeprecatingSpecProxyHandler(env) {
|
||||
this._env = env;
|
||||
}
|
||||
|
||||
DeprecatingSpecProxyHandler.prototype.get = function(target, prop, receiver) {
|
||||
this._maybeDeprecate(target, prop);
|
||||
|
||||
if (prop === 'getFullName') {
|
||||
// getFullName calls a private method. Re-bind 'this' to avoid a bogus
|
||||
// deprecation warning.
|
||||
return target.getFullName.bind(target);
|
||||
} else {
|
||||
return target[prop];
|
||||
}
|
||||
};
|
||||
|
||||
DeprecatingSpecProxyHandler.prototype.set = function(target, prop, value) {
|
||||
this._maybeDeprecate(target, prop);
|
||||
return (target[prop] = value);
|
||||
};
|
||||
|
||||
DeprecatingSpecProxyHandler.prototype._maybeDeprecate = function(
|
||||
target,
|
||||
prop
|
||||
) {
|
||||
if (isMember(target, prop) && !isAllowedMember(prop)) {
|
||||
this._env.deprecated(msg(prop));
|
||||
}
|
||||
};
|
||||
|
||||
function deprecatingSpecProxy(spec, env) {
|
||||
return new Proxy(spec, new DeprecatingSpecProxyHandler(env));
|
||||
}
|
||||
|
||||
return deprecatingSpecProxy;
|
||||
};
|
||||
98
src/core/deprecatingSuiteProxy.js
Normal file
98
src/core/deprecatingSuiteProxy.js
Normal file
@@ -0,0 +1,98 @@
|
||||
/* eslint-disable compat/compat */
|
||||
// TODO: Remove this in the next major release.
|
||||
getJasmineRequireObj().deprecatingSuiteProxy = function(j$) {
|
||||
var allowedMembers = [
|
||||
'children',
|
||||
'description',
|
||||
'parentSuite',
|
||||
'getFullName'
|
||||
];
|
||||
|
||||
function isMember(target, prop) {
|
||||
return (
|
||||
Object.keys(target).indexOf(prop) !== -1 ||
|
||||
Object.keys(j$.Suite.prototype).indexOf(prop) !== -1
|
||||
);
|
||||
}
|
||||
|
||||
function isAllowedMember(prop) {
|
||||
return allowedMembers.indexOf(prop) !== -1;
|
||||
}
|
||||
|
||||
function msg(member) {
|
||||
var memberName = member.toString().replace(/^Symbol\((.+)\)$/, '$1');
|
||||
return (
|
||||
'Access to private Suite members (in this case `' +
|
||||
memberName +
|
||||
'`) via Env#topSuite is not supported and will break in ' +
|
||||
'a future release. See <https://jasmine.github.io/api/edge/Suite.html> ' +
|
||||
'for correct usage.'
|
||||
);
|
||||
}
|
||||
try {
|
||||
new Proxy({}, {});
|
||||
} catch (e) {
|
||||
// Environment does not support Poxy.
|
||||
return function(suite) {
|
||||
return suite;
|
||||
};
|
||||
}
|
||||
|
||||
function DeprecatingSuiteProxyHandler(parentSuite, env) {
|
||||
this._parentSuite = parentSuite;
|
||||
this._env = env;
|
||||
}
|
||||
|
||||
DeprecatingSuiteProxyHandler.prototype.get = function(
|
||||
target,
|
||||
prop,
|
||||
receiver
|
||||
) {
|
||||
if (prop === 'children') {
|
||||
if (!this._children) {
|
||||
this._children = target.children.map(
|
||||
this._proxyForChild.bind(this, receiver)
|
||||
);
|
||||
}
|
||||
|
||||
return this._children;
|
||||
} else if (prop === 'parentSuite') {
|
||||
return this._parentSuite;
|
||||
} else {
|
||||
this._maybeDeprecate(target, prop);
|
||||
return target[prop];
|
||||
}
|
||||
};
|
||||
|
||||
DeprecatingSuiteProxyHandler.prototype.set = function(target, prop, value) {
|
||||
debugger;
|
||||
this._maybeDeprecate(target, prop);
|
||||
return (target[prop] = value);
|
||||
};
|
||||
|
||||
DeprecatingSuiteProxyHandler.prototype._maybeDeprecate = function(
|
||||
target,
|
||||
prop
|
||||
) {
|
||||
if (isMember(target, prop) && !isAllowedMember(prop)) {
|
||||
this._env.deprecated(msg(prop));
|
||||
}
|
||||
};
|
||||
|
||||
DeprecatingSuiteProxyHandler.prototype._proxyForChild = function(
|
||||
ownProxy,
|
||||
child
|
||||
) {
|
||||
if (child.children) {
|
||||
return deprecatingSuiteProxy(child, ownProxy, this._env);
|
||||
} else {
|
||||
return j$.deprecatingSpecProxy(child, this._env);
|
||||
}
|
||||
};
|
||||
|
||||
function deprecatingSuiteProxy(suite, parentSuite, env) {
|
||||
return new Proxy(suite, new DeprecatingSuiteProxyHandler(parentSuite, env));
|
||||
}
|
||||
|
||||
return deprecatingSuiteProxy;
|
||||
};
|
||||
@@ -42,7 +42,10 @@ var getJasmineRequireObj = (function(jasmineGlobal) {
|
||||
j$.getClearStack = jRequire.clearStack(j$);
|
||||
j$.Clock = jRequire.Clock();
|
||||
j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(j$);
|
||||
j$.Deprecator = jRequire.Deprecator(j$);
|
||||
j$.Env = jRequire.Env(j$);
|
||||
j$.deprecatingSuiteProxy = jRequire.deprecatingSuiteProxy(j$);
|
||||
j$.deprecatingSpecProxy = jRequire.deprecatingSpecProxy(j$);
|
||||
j$.StackTrace = jRequire.StackTrace(j$);
|
||||
j$.ExceptionFormatter = jRequire.ExceptionFormatter(j$);
|
||||
j$.ExpectationFilterChain = jRequire.ExpectationFilterChain();
|
||||
|
||||
@@ -277,7 +277,8 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
addDeprecationWarnings(doneResult);
|
||||
|
||||
for (i = 0; i < deprecationWarnings.length; i++) {
|
||||
var context;
|
||||
var children = [],
|
||||
context;
|
||||
|
||||
switch (deprecationWarnings[i].runnableType) {
|
||||
case 'spec':
|
||||
@@ -290,13 +291,23 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
context = '';
|
||||
}
|
||||
|
||||
deprecationWarnings[i].message.split('\n').forEach(function(line) {
|
||||
children.push(line);
|
||||
children.push(createDom('br'));
|
||||
});
|
||||
|
||||
children[0] = 'DEPRECATION: ' + children[0];
|
||||
children.push(context);
|
||||
|
||||
if (deprecationWarnings[i].stack) {
|
||||
children.push(createExpander(deprecationWarnings[i].stack));
|
||||
}
|
||||
|
||||
alert.appendChild(
|
||||
createDom(
|
||||
'span',
|
||||
{ className: 'jasmine-bar jasmine-warning' },
|
||||
'DEPRECATION: ' + deprecationWarnings[i].message,
|
||||
createDom('br'),
|
||||
context
|
||||
children
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -611,17 +622,44 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
if (result && result.deprecationWarnings) {
|
||||
for (var i = 0; i < result.deprecationWarnings.length; i++) {
|
||||
var warning = result.deprecationWarnings[i].message;
|
||||
if (!j$.util.arrayContains(warning)) {
|
||||
deprecationWarnings.push({
|
||||
message: warning,
|
||||
runnableName: result.fullName,
|
||||
runnableType: runnableType
|
||||
});
|
||||
}
|
||||
deprecationWarnings.push({
|
||||
message: warning,
|
||||
stack: result.deprecationWarnings[i].stack,
|
||||
runnableName: result.fullName,
|
||||
runnableType: runnableType
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createExpander(stackTrace) {
|
||||
var expandLink = createDom('a', { href: '#' }, 'Show stack trace');
|
||||
var root = createDom(
|
||||
'div',
|
||||
{ className: 'jasmine-expander' },
|
||||
expandLink,
|
||||
createDom(
|
||||
'div',
|
||||
{ className: 'jasmine-expander-contents jasmine-stack-trace' },
|
||||
stackTrace
|
||||
)
|
||||
);
|
||||
|
||||
expandLink.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (root.classList.contains('jasmine-expanded')) {
|
||||
root.classList.remove('jasmine-expanded');
|
||||
expandLink.textContent = 'Show stack trace';
|
||||
} else {
|
||||
root.classList.add('jasmine-expanded');
|
||||
expandLink.textContent = 'Hide stack trace';
|
||||
}
|
||||
});
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
function find(selector) {
|
||||
return getContainer().querySelector('.jasmine_html-reporter ' + selector);
|
||||
}
|
||||
@@ -635,11 +673,23 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
}
|
||||
}
|
||||
|
||||
function createDom(type, attrs, childrenVarArgs) {
|
||||
var el = createElement(type);
|
||||
function createDom(type, attrs, childrenArrayOrVarArgs) {
|
||||
var el = createElement(type),
|
||||
children,
|
||||
i;
|
||||
|
||||
for (var i = 2; i < arguments.length; i++) {
|
||||
var child = arguments[i];
|
||||
if (j$.isArray_(childrenArrayOrVarArgs)) {
|
||||
children = childrenArrayOrVarArgs;
|
||||
} else {
|
||||
children = [];
|
||||
|
||||
for (i = 2; i < arguments.length; i++) {
|
||||
children.push(arguments[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
|
||||
if (typeof child === 'string') {
|
||||
el.appendChild(createTextNode(child));
|
||||
|
||||
@@ -231,6 +231,8 @@ body {
|
||||
}
|
||||
|
||||
&.jasmine-warning {
|
||||
margin-top: $margin-unit;
|
||||
margin-bottom: $margin-unit;
|
||||
background-color: $pending-color;
|
||||
color: $text-color;
|
||||
}
|
||||
@@ -386,4 +388,27 @@ body {
|
||||
background: white;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.jasmine-expander {
|
||||
a {
|
||||
display: block;
|
||||
margin-left: $margin-unit;
|
||||
color: blue;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.jasmine-expander-contents {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.jasmine-expanded {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.jasmine-expanded .jasmine-expander-contents {
|
||||
display: block;
|
||||
margin-left: $margin-unit;
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user