Skip to content

Commit 6ad8d20

Browse files
committed
Report the path/url of the file that the spec/suite was defined in
Fixes #1884
1 parent bc3a495 commit 6ad8d20

File tree

7 files changed

+216
-105
lines changed

7 files changed

+216
-105
lines changed

lib/jasmine-core/jasmine.js

Lines changed: 61 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2008-2022 Pivotal Labs
2+
Copyright (c) 2008-2023 Pivotal Labs
33
44
Permission is hereby granted, free of charge, to any person obtaining
55
a copy of this software and associated documentation files (the
@@ -741,6 +741,7 @@ getJasmineRequireObj().Spec = function(j$) {
741741
this.asyncExpectationFactory = attrs.asyncExpectationFactory;
742742
this.resultCallback = attrs.resultCallback || function() {};
743743
this.id = attrs.id;
744+
this.filename = attrs.filename;
744745
this.description = attrs.description || '';
745746
this.queueableFn = attrs.queueableFn;
746747
this.beforeAndAfterFns =
@@ -774,35 +775,7 @@ getJasmineRequireObj().Spec = function(j$) {
774775
this.exclude();
775776
}
776777

777-
/**
778-
* @typedef SpecResult
779-
* @property {String} id - The unique id of this spec.
780-
* @property {String} description - The description passed to the {@link it} that created this spec.
781-
* @property {String} fullName - The full description including all ancestors of this spec.
782-
* @property {Expectation[]} failedExpectations - The list of expectations that failed during execution of this spec.
783-
* @property {Expectation[]} passedExpectations - The list of expectations that passed during execution of this spec.
784-
* @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred during execution this spec.
785-
* @property {String} pendingReason - If the spec is {@link pending}, this will be the reason.
786-
* @property {String} status - Once the spec has completed, this string represents the pass/fail status of this spec.
787-
* @property {number} duration - The time in ms used by the spec execution, including any before/afterEach.
788-
* @property {Object} properties - User-supplied properties, if any, that were set using {@link Env#setSpecProperty}
789-
* @property {DebugLogEntry[]|null} debugLogs - Messages, if any, that were logged using {@link jasmine.debugLog} during a failing spec.
790-
* @since 2.0.0
791-
*/
792-
this.result = {
793-
id: this.id,
794-
description: this.description,
795-
fullName: this.getFullName(),
796-
failedExpectations: [],
797-
passedExpectations: [],
798-
deprecationWarnings: [],
799-
pendingReason: '',
800-
duration: null,
801-
properties: null,
802-
debugLogs: null
803-
};
804-
805-
this.reportedDone = false;
778+
this.reset();
806779
}
807780

808781
Spec.prototype.addExpectationResult = function(passed, data, isError) {
@@ -912,14 +885,31 @@ getJasmineRequireObj().Spec = function(j$) {
912885
};
913886

914887
Spec.prototype.reset = function() {
888+
/**
889+
* @typedef SpecResult
890+
* @property {String} id - The unique id of this spec.
891+
* @property {String} description - The description passed to the {@link it} that created this spec.
892+
* @property {String} fullName - The full description including all ancestors of this spec.
893+
* @property {String} filename - The name of the file the spec was defined in.
894+
* @property {Expectation[]} failedExpectations - The list of expectations that failed during execution of this spec.
895+
* @property {Expectation[]} passedExpectations - The list of expectations that passed during execution of this spec.
896+
* @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred during execution this spec.
897+
* @property {String} pendingReason - If the spec is {@link pending}, this will be the reason.
898+
* @property {String} status - Once the spec has completed, this string represents the pass/fail status of this spec.
899+
* @property {number} duration - The time in ms used by the spec execution, including any before/afterEach.
900+
* @property {Object} properties - User-supplied properties, if any, that were set using {@link Env#setSpecProperty}
901+
* @property {DebugLogEntry[]|null} debugLogs - Messages, if any, that were logged using {@link jasmine.debugLog} during a failing spec.
902+
* @since 2.0.0
903+
*/
915904
this.result = {
916905
id: this.id,
917906
description: this.description,
918907
fullName: this.getFullName(),
908+
filename: this.filename,
919909
failedExpectations: [],
920910
passedExpectations: [],
921911
deprecationWarnings: [],
922-
pendingReason: this.excludeMessage,
912+
pendingReason: this.excludeMessage || '',
923913
duration: null,
924914
properties: null,
925915
debugLogs: null
@@ -1816,17 +1806,23 @@ getJasmineRequireObj().Env = function(j$) {
18161806

18171807
this.describe = function(description, definitionFn) {
18181808
ensureIsNotNested('describe');
1819-
return suiteBuilder.describe(description, definitionFn).metadata;
1809+
const filename = callerCallerFilename();
1810+
return suiteBuilder.describe(description, definitionFn, filename)
1811+
.metadata;
18201812
};
18211813

18221814
this.xdescribe = function(description, definitionFn) {
18231815
ensureIsNotNested('xdescribe');
1824-
return suiteBuilder.xdescribe(description, definitionFn).metadata;
1816+
const filename = callerCallerFilename();
1817+
return suiteBuilder.xdescribe(description, definitionFn, filename)
1818+
.metadata;
18251819
};
18261820

18271821
this.fdescribe = function(description, definitionFn) {
18281822
ensureIsNotNested('fdescribe');
1829-
return suiteBuilder.fdescribe(description, definitionFn).metadata;
1823+
const filename = callerCallerFilename();
1824+
return suiteBuilder.fdescribe(description, definitionFn, filename)
1825+
.metadata;
18301826
};
18311827

18321828
function specResultCallback(spec, result, next) {
@@ -1853,17 +1849,20 @@ getJasmineRequireObj().Env = function(j$) {
18531849

18541850
this.it = function(description, fn, timeout) {
18551851
ensureIsNotNested('it');
1856-
return suiteBuilder.it(description, fn, timeout).metadata;
1852+
const filename = callerCallerFilename();
1853+
return suiteBuilder.it(description, fn, timeout, filename).metadata;
18571854
};
18581855

18591856
this.xit = function(description, fn, timeout) {
18601857
ensureIsNotNested('xit');
1861-
return suiteBuilder.xit(description, fn, timeout).metadata;
1858+
const filename = callerCallerFilename();
1859+
return suiteBuilder.xit(description, fn, timeout, filename).metadata;
18621860
};
18631861

18641862
this.fit = function(description, fn, timeout) {
18651863
ensureIsNotNested('fit');
1866-
return suiteBuilder.fit(description, fn, timeout).metadata;
1864+
const filename = callerCallerFilename();
1865+
return suiteBuilder.fit(description, fn, timeout, filename).metadata;
18671866
};
18681867

18691868
/**
@@ -2003,6 +2002,10 @@ getJasmineRequireObj().Env = function(j$) {
20032002
};
20042003
}
20052004

2005+
function callerCallerFilename() {
2006+
return new j$.StackTrace(new Error()).frames[3].file;
2007+
}
2008+
20062009
return Env;
20072010
};
20082011

@@ -9530,6 +9533,7 @@ getJasmineRequireObj().Suite = function(j$) {
95309533
this.id = attrs.id;
95319534
this.parentSuite = attrs.parentSuite;
95329535
this.description = attrs.description;
9536+
this.filename = attrs.filename;
95339537
this.expectationFactory = attrs.expectationFactory;
95349538
this.asyncExpectationFactory = attrs.asyncExpectationFactory;
95359539
this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;
@@ -9635,6 +9639,7 @@ getJasmineRequireObj().Suite = function(j$) {
96359639
* @property {String} id - The unique id of this suite.
96369640
* @property {String} description - The description text passed to the {@link describe} that made this suite.
96379641
* @property {String} fullName - The full description including all ancestors of this suite.
9642+
* @property {String} filename - The name of the file the suite was defined in.
96389643
* @property {Expectation[]} failedExpectations - The list of expectations that failed in an {@link afterAll} for this suite.
96399644
* @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred on this suite.
96409645
* @property {String} status - Once the suite has completed, this string represents the pass/fail status of this suite.
@@ -9646,6 +9651,7 @@ getJasmineRequireObj().Suite = function(j$) {
96469651
id: this.id,
96479652
description: this.description,
96489653
fullName: this.getFullName(),
9654+
filename: this.filename,
96499655
failedExpectations: [],
96509656
deprecationWarnings: [],
96519657
duration: null,
@@ -9873,9 +9879,9 @@ getJasmineRequireObj().SuiteBuilder = function(j$) {
98739879
this.focusedRunables = [];
98749880
}
98759881

9876-
describe(description, definitionFn) {
9882+
describe(description, definitionFn, filename) {
98779883
ensureIsFunction(definitionFn, 'describe');
9878-
const suite = this.suiteFactory_(description);
9884+
const suite = this.suiteFactory_(description, filename);
98799885
if (definitionFn.length > 0) {
98809886
throw new Error('describe does not expect any arguments');
98819887
}
@@ -9886,9 +9892,9 @@ getJasmineRequireObj().SuiteBuilder = function(j$) {
98869892
return suite;
98879893
}
98889894

9889-
fdescribe(description, definitionFn) {
9895+
fdescribe(description, definitionFn, filename) {
98909896
ensureIsFunction(definitionFn, 'fdescribe');
9891-
const suite = this.suiteFactory_(description);
9897+
const suite = this.suiteFactory_(description, filename);
98929898
suite.isFocused = true;
98939899

98949900
this.focusedRunables.push(suite.id);
@@ -9898,45 +9904,45 @@ getJasmineRequireObj().SuiteBuilder = function(j$) {
98989904
return suite;
98999905
}
99009906

9901-
xdescribe(description, definitionFn) {
9907+
xdescribe(description, definitionFn, filename) {
99029908
ensureIsFunction(definitionFn, 'xdescribe');
9903-
const suite = this.suiteFactory_(description);
9909+
const suite = this.suiteFactory_(description, filename);
99049910
suite.exclude();
99059911
this.addSpecsToSuite_(suite, definitionFn);
99069912

99079913
return suite;
99089914
}
99099915

9910-
it(description, fn, timeout) {
9916+
it(description, fn, timeout, filename) {
99119917
// it() sometimes doesn't have a fn argument, so only check the type if
99129918
// it's given.
99139919
if (arguments.length > 1 && typeof fn !== 'undefined') {
99149920
ensureIsFunctionOrAsync(fn, 'it');
99159921
}
99169922

9917-
return this.it_(description, fn, timeout);
9923+
return this.it_(description, fn, timeout, filename);
99189924
}
99199925

9920-
xit(description, fn, timeout) {
9926+
xit(description, fn, timeout, filename) {
99219927
// xit(), like it(), doesn't always have a fn argument, so only check the
99229928
// type when needed.
99239929
if (arguments.length > 1 && typeof fn !== 'undefined') {
99249930
ensureIsFunctionOrAsync(fn, 'xit');
99259931
}
9926-
const spec = this.it_(description, fn, timeout);
9932+
const spec = this.it_(description, fn, timeout, filename);
99279933
spec.exclude('Temporarily disabled with xit');
99289934
return spec;
99299935
}
99309936

9931-
fit(description, fn, timeout) {
9937+
fit(description, fn, timeout, filename) {
99329938
// Unlike it and xit, the function is required because it doesn't make
99339939
// sense to focus on nothing.
99349940
ensureIsFunctionOrAsync(fn, 'fit');
99359941

99369942
if (timeout) {
99379943
j$.util.validateTimeout(timeout);
99389944
}
9939-
const spec = this.specFactory_(description, fn, timeout);
9945+
const spec = this.specFactory_(description, fn, timeout, filename);
99409946
this.currentDeclarationSuite_.addChild(spec);
99419947
this.focusedRunables.push(spec.id);
99429948
this.unfocusAncestor_();
@@ -9996,12 +10002,12 @@ getJasmineRequireObj().SuiteBuilder = function(j$) {
999610002
});
999710003
}
999810004

9999-
it_(description, fn, timeout) {
10005+
it_(description, fn, timeout, filename) {
1000010006
if (timeout) {
1000110007
j$.util.validateTimeout(timeout);
1000210008
}
1000310009

10004-
const spec = this.specFactory_(description, fn, timeout);
10010+
const spec = this.specFactory_(description, fn, timeout, filename);
1000510011
if (this.currentDeclarationSuite_.markedExcluding) {
1000610012
spec.exclude();
1000710013
}
@@ -10010,11 +10016,12 @@ getJasmineRequireObj().SuiteBuilder = function(j$) {
1001010016
return spec;
1001110017
}
1001210018

10013-
suiteFactory_(description) {
10019+
suiteFactory_(description, filename) {
1001410020
const config = this.env_.configuration();
1001510021
return new j$.Suite({
1001610022
id: 'suite' + this.nextSuiteId_++,
1001710023
description,
10024+
filename,
1001810025
parentSuite: this.currentDeclarationSuite_,
1001910026
timer: new j$.Timer(),
1002010027
expectationFactory: this.expectationFactory_,
@@ -10047,12 +10054,13 @@ getJasmineRequireObj().SuiteBuilder = function(j$) {
1004710054
this.currentDeclarationSuite_ = parentSuite;
1004810055
}
1004910056

10050-
specFactory_(description, fn, timeout) {
10057+
specFactory_(description, fn, timeout, filename) {
1005110058
this.totalSpecsDefined++;
1005210059
const config = this.env_.configuration();
1005310060
const suite = this.currentDeclarationSuite_;
1005410061
const spec = new j$.Spec({
1005510062
id: 'spec' + this.nextSpecId_++,
10063+
filename,
1005610064
beforeAndAfterFns: beforeAndAfterFns(suite),
1005710065
expectationFactory: this.expectationFactory_,
1005810066
asyncExpectationFactory: this.specAsyncExpectationFactory_,

spec/core/SpecSpec.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ describe('Spec', function() {
195195
onStart: startCallback,
196196
resultCallback: resultCallback,
197197
description: 'with a spec',
198+
filename: 'someSpecFile.js',
198199
getSpecName: function() {
199200
return 'a suite with a spec';
200201
},
@@ -219,6 +220,7 @@ describe('Spec', function() {
219220
status: 'pending',
220221
description: 'with a spec',
221222
fullName: 'a suite with a spec',
223+
filename: 'someSpecFile.js',
222224
failedExpectations: [],
223225
passedExpectations: [],
224226
deprecationWarnings: [],

0 commit comments

Comments
 (0)