Optionally enforce uniqueness of spec and suite names

This is off by default for backwards compatibility but can be enabled
by setting the forbidDuplicateNames env config property to true.

Fixes #1633.
This commit is contained in:
Steve Gravrock
2024-11-10 09:32:43 -08:00
parent 744e765d6f
commit d5e7bc9fd6
7 changed files with 233 additions and 2 deletions

View File

@@ -138,6 +138,15 @@ getJasmineRequireObj().Env = function(j$) {
* @default true
*/
autoCleanClosures: true,
/**
* Whether to forbid duplicate spec or suite names. If set to true, using
* the same name multiple times in the same immediate parent suite is an
* error.
* @name Configuration#forbidDuplicateNames
* @type boolean
* @default false
*/
forbidDuplicateNames: false,
/**
* Whether or not to issue warnings for certain deprecated functionality
* every time it's used. If not set or set to false, deprecation warnings
@@ -186,7 +195,8 @@ getJasmineRequireObj().Env = function(j$) {
'hideDisabled',
'stopOnSpecFailure',
'stopSpecOnExpectationFailure',
'autoCleanClosures'
'autoCleanClosures',
'forbidDuplicateNames'
];
booleanProps.forEach(function(prop) {

View File

@@ -251,6 +251,16 @@ getJasmineRequireObj().Suite = function(j$) {
);
};
Suite.prototype.hasChildWithDescription = function(description) {
for (const child of this.children) {
if (child.description === description) {
return true;
}
}
return false;
};
Object.defineProperty(Suite.prototype, 'metadata', {
get: function() {
if (!this.metadata_) {

View File

@@ -161,6 +161,8 @@ getJasmineRequireObj().SuiteBuilder = function(j$) {
j$.util.validateTimeout(timeout);
}
this.checkDuplicate_(description, 'spec');
const spec = this.specFactory_(description, fn, timeout, filename);
if (this.currentDeclarationSuite_.markedExcluding) {
spec.exclude();
@@ -170,7 +172,27 @@ getJasmineRequireObj().SuiteBuilder = function(j$) {
return spec;
}
checkDuplicate_(description, type) {
if (!this.env_.configuration().forbidDuplicateNames) {
return;
}
if (this.currentDeclarationSuite_.hasChildWithDescription(description)) {
const parentDesc =
this.currentDeclarationSuite_ === this.topSuite
? 'top suite'
: `"${this.currentDeclarationSuite_.getFullName()}"`;
throw new Error(
`Duplicate ${type} name "${description}" found in ${parentDesc}`
);
}
}
suiteFactory_(description, filename) {
if (this.topSuite) {
this.checkDuplicate_(description, 'suite');
}
const config = this.env_.configuration();
const parentSuite = this.currentDeclarationSuite_;
const reportedParentSuiteId =