diff --git a/lib/jasmine-core/boot1.js b/lib/jasmine-core/boot1.js index b91a1a75..4f19bd7f 100644 --- a/lib/jasmine-core/boot1.js +++ b/lib/jasmine-core/boot1.js @@ -40,12 +40,20 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. (function() { const env = jasmine.getEnv(); + /** + * ## Runner Parameters + * + * More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface. + */ + const queryString = new jasmine.QueryString({ getWindowLocation: function() { return window.location; } }); + const filterSpecs = !!queryString.getParam('spec'); + const config = { stopOnSpecFailure: queryString.getParam('stopOnSpecFailure'), stopSpecOnExpectationFailure: queryString.getParam( @@ -87,7 +95,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. return document.createTextNode.apply(document, arguments); }, timer: new jasmine.Timer(), - queryString + filterSpecs: filterSpecs }); /** @@ -99,9 +107,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /** * Filter which specs will be run by matching the start of the full name against the `spec` query param. */ - const specFilter = new jasmine.HtmlExactSpecFilter({ queryString }); + const specFilter = new jasmine.HtmlSpecFilter({ + filterString: function() { + return queryString.getParam('spec'); + } + }); + config.specFilter = function(spec) { - return specFilter.matches(spec); + return specFilter.matches(spec.getFullName()); }; env.configure(config); diff --git a/lib/jasmine-core/jasmine-html.js b/lib/jasmine-core/jasmine-html.js index 1a45ff0d..cbbf328c 100644 --- a/lib/jasmine-core/jasmine-html.js +++ b/lib/jasmine-core/jasmine-html.js @@ -30,7 +30,6 @@ jasmineRequire.html = function(j$) { j$.HtmlReporter = jasmineRequire.HtmlReporter(j$); j$.QueryString = jasmineRequire.QueryString(); j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter(); - j$.HtmlExactSpecFilter = jasmineRequire.HtmlExactSpecFilter(); }; jasmineRequire.HtmlReporter = function(j$) { @@ -42,13 +41,11 @@ jasmineRequire.HtmlReporter = function(j$) { this.specsExecuted = 0; this.failureCount = 0; this.pendingSpecCount = 0; - this.suitesById = []; } ResultsStateBuilder.prototype.suiteStarted = function(result) { this.currentParent.addChild(result, 'suite'); this.currentParent = this.currentParent.last(); - this.suitesById[result.id] = this.currentParent; }; ResultsStateBuilder.prototype.suiteDone = function(result) { @@ -101,14 +98,10 @@ jasmineRequire.HtmlReporter = function(j$) { const getContainer = options.getContainer; const createElement = options.createElement; const createTextNode = options.createTextNode; - // TODO: in the next major release, replace navigateWithNewParam and - // addToExistingQueryString with direct usage of options.queryString const navigateWithNewParam = options.navigateWithNewParam || function() {}; const addToExistingQueryString = options.addToExistingQueryString || defaultQueryString; - const filterSpecs = options.queryString - ? !!options.queryString.getParam('spec') - : options.filterSpecs; // For compatibility with pre-5.11 boot files + const filterSpecs = options.filterSpecs; let htmlReporterMain; let symbols; const deprecationWarnings = []; @@ -737,6 +730,21 @@ jasmineRequire.HtmlReporter = function(j$) { return wrapper; } + function suiteHref(suite) { + const els = []; + + while (suite && suite.parent) { + els.unshift(suite.result.description); + suite = suite.parent; + } + + // include window.location.pathname to fix issue with karma-jasmine-html-reporter in angular: see https://github.com/jasmine/jasmine/issues/1906 + return ( + (window.location.pathname || '') + + addToExistingQueryString('spec', els.join(' ')) + ); + } + function addDeprecationWarnings(result, runnableType) { if (result && result.deprecationWarnings) { for (let i = 0; i < result.deprecationWarnings.length; i++) { @@ -834,33 +842,11 @@ jasmineRequire.HtmlReporter = function(j$) { return '' + count + ' ' + word; } - function suitePath(suite) { - const els = []; - - while (suite && suite.parent) { - els.unshift(suite.result.description); - suite = suite.parent; - } - - return els; - } - - function suiteHref(suite) { - return pathHref(suitePath(suite)); - } - function specHref(result) { - const suite = stateBuilder.suitesById[result.parentSuiteId]; - const path = suitePath(suite); - path.push(result.description); - return pathHref(path); - } - - function pathHref(path) { // include window.location.pathname to fix issue with karma-jasmine-html-reporter in angular: see https://github.com/jasmine/jasmine/issues/1906 return ( (window.location.pathname || '') + - addToExistingQueryString('spec', JSON.stringify(path)) + addToExistingQueryString('spec', result.fullName) ); } @@ -911,27 +897,11 @@ jasmineRequire.HtmlReporter = function(j$) { jasmineRequire.HtmlSpecFilter = function() { 'use strict'; - /** - * @name HtmlSpecFilter - * @classdesc Legacy HTML spec filter, for backward compatibility - * with boot files that predate {@link HtmlExactSpecFilter}. - * @param options Object with a filterString method - * @constructor - * @deprecated - * @since 1.2.0 - */ - // Legacy HTML spec filter, preserved for backward compatibility with - // boot files that predate HtmlExactSpecFilterV2 function HtmlSpecFilter(options) { - let filterString = (options && options.filterString()) || ''; - - if (filterString.startsWith('[')) { - // Convert an HtmlExactSpecFilterV2 string into something we can use - filterString = JSON.parse(filterString).join(' '); - } - - filterString = filterString.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); - + const filterString = + options && + options.filterString() && + options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); const filterPattern = new RegExp(filterString); /** @@ -1060,58 +1030,3 @@ jasmineRequire.QueryString = function() { return QueryString; }; - -jasmineRequire.HtmlExactSpecFilter = function() { - 'use strict'; - - /** - * Spec filter for use with {@link HtmlReporter} - * - * See lib/jasmine-core/boot1.js for usage. - * @since 5.11.0 - */ - class HtmlExactSpecFilter { - #getFilterString; - - /** - * Create a filter instance. - * @param options Object with a queryString property, which should be an - * instance of {@link QueryString}. - */ - constructor(options) { - this.#getFilterString = function() { - return options.queryString.getParam('spec'); - }; - } - - /** - * Determines whether the specified spec should be executed. - * @param {Spec} spec - * @returns {boolean} - */ - matches(spec) { - const filterString = this.#getFilterString(); - - if (!filterString) { - return true; - } - - const filterPath = JSON.parse(this.#getFilterString()); - const specPath = spec.getPath(); - - if (filterPath.length > specPath.length) { - return false; - } - - for (let i = 0; i < filterPath.length; i++) { - if (specPath[i] !== filterPath[i]) { - return false; - } - } - - return true; - } - } - - return HtmlExactSpecFilter; -}; diff --git a/spec/core/jasmineNamespaceSpec.js b/spec/core/jasmineNamespaceSpec.js index 95c7c0ed..acde7106 100644 --- a/spec/core/jasmineNamespaceSpec.js +++ b/spec/core/jasmineNamespaceSpec.js @@ -54,7 +54,6 @@ describe('The jasmine namespace', function() { // jasmine-html.js result.add('HtmlReporter'); result.add('HtmlSpecFilter'); - result.add('HtmlExactSpecFilter'); result.add('QueryString'); } diff --git a/spec/html/HtmlExactSpecFilterSpec.js b/spec/html/HtmlExactSpecFilterSpec.js deleted file mode 100644 index ada0c49e..00000000 --- a/spec/html/HtmlExactSpecFilterSpec.js +++ /dev/null @@ -1,63 +0,0 @@ -describe('HtmlExactSpecFilter', function() { - it('matches everything when no string is provided', function() { - const specFilter = new jasmineUnderTest.HtmlExactSpecFilter({ - queryString: { - getParam(name) { - return ''; - } - } - }); - - expect(specFilter.matches({})).toBeTrue(); - }); - - it('matches a spec with the exact same path', function() { - const specFilter = new jasmineUnderTest.HtmlExactSpecFilter({ - queryString: { - getParam(name) { - if (name === 'spec') { - return '["a","b","c"]'; - } - } - } - }); - - expect(specFilter.matches(stubSpec(['a', 'b', 'c']))).toBeTrue(); - }); - - it('matches a spec whose path has the filter path as a prefix', function() { - const specFilter = new jasmineUnderTest.HtmlExactSpecFilter({ - queryString: { - getParam(name) { - if (name === 'spec') { - return '["a","b"]'; - } - } - } - }); - - expect(specFilter.matches(stubSpec(['a', 'b', 'c']))).toBeTrue(); - }); - - it('does not match a spec with a different path', function() { - const specFilter = new jasmineUnderTest.HtmlExactSpecFilter({ - queryString: { - getParam(name) { - if (name === 'spec') { - return '["a","b","c"]'; - } - } - } - }); - - expect(specFilter.matches(stubSpec(['a', 'd', 'c']))).toBeFalse(); - }); - - function stubSpec(path) { - return { - getPath() { - return path; - } - }; - } -}); diff --git a/spec/html/HtmlReporterSpec.js b/spec/html/HtmlReporterSpec.js index 9a682cb7..54c09bd1 100644 --- a/spec/html/HtmlReporterSpec.js +++ b/spec/html/HtmlReporterSpec.js @@ -528,7 +528,6 @@ describe('HtmlReporter', function() { let specResult = { id: 123, - parentSuiteId: 1, description: 'with a spec', fullName: 'A Suite with a spec', status: 'passed', @@ -606,9 +605,7 @@ describe('HtmlReporter', function() { const suiteDetail = outerSuite.childNodes[0]; const suiteLink = suiteDetail.childNodes[0]; expect(suiteLink.innerHTML).toEqual('A Suite'); - expect(suiteLink.getAttribute('href')).toEqual( - '/?foo=bar&spec=["A Suite"]' - ); + expect(suiteLink.getAttribute('href')).toEqual('/?foo=bar&spec=A Suite'); const specs = outerSuite.childNodes[1]; const spec = specs.childNodes[0]; @@ -618,7 +615,7 @@ describe('HtmlReporter', function() { const specLink = spec.childNodes[0]; expect(specLink.innerHTML).toEqual('with a spec'); expect(specLink.getAttribute('href')).toEqual( - '/?foo=bar&spec=["A Suite","with a spec"]' + '/?foo=bar&spec=A Suite with a spec' ); const specDuration = spec.childNodes[1]; @@ -1368,11 +1365,6 @@ describe('HtmlReporter', function() { }, createTextNode: function() { return document.createTextNode.apply(document, arguments); - }, - queryString: { - getParam(name) { - return ''; - } } }; specStatus = { @@ -1387,12 +1379,7 @@ describe('HtmlReporter', function() { describe('when the specs are not filtered', function() { beforeEach(function() { - reporterConfig.queryString.getParam = function(name) { - if (name !== 'spec') { - throw new Error('Unexpected query param ' + name); - } - return ''; - }; + reporterConfig.filterSpecs = false; reporter = new jasmineUnderTest.HtmlReporter(reporterConfig); reporter.initialize(); reporter.jasmineStarted({ totalSpecsDefined: 1 }); @@ -1410,12 +1397,7 @@ describe('HtmlReporter', function() { describe('when the specs are filtered', function() { beforeEach(function() { - reporterConfig.queryString.getParam = function(name) { - if (name !== 'spec') { - throw new Error('Unexpected query param ' + name); - } - return 'not the empty string'; - }; + reporterConfig.filterSpecs = true; reporter = new jasmineUnderTest.HtmlReporter(reporterConfig); reporter.initialize(); reporter.jasmineStarted({ totalSpecsDefined: 1 }); @@ -1559,7 +1541,6 @@ describe('HtmlReporter', function() { const failingSpecResult = { id: 124, - parentSuiteId: 2, status: 'failed', description: 'a failing spec', fullName: 'a suite inner suite a failing spec', @@ -1683,18 +1664,16 @@ describe('HtmlReporter', function() { expect(links.length).toEqual(3); expect(links[0].textContent).toEqual('A suite'); - expect(links[0].getAttribute('href')).toEqual( - '/?foo=bar&spec=["A suite"]' - ); + expect(links[0].getAttribute('href')).toMatch(/\?foo=bar&spec=A suite/); expect(links[1].textContent).toEqual('inner suite'); - expect(links[1].getAttribute('href')).toEqual( - '/?foo=bar&spec=["A suite","inner suite"]' + expect(links[1].getAttribute('href')).toMatch( + /\?foo=bar&spec=A suite inner suite/ ); expect(links[2].textContent).toEqual('a failing spec'); - expect(links[2].getAttribute('href')).toEqual( - '/?foo=bar&spec=["A suite","inner suite","a failing spec"]' + expect(links[2].getAttribute('href')).toMatch( + /\?foo=bar&spec=a suite inner suite a failing spec/ ); }); diff --git a/spec/html/HtmlSpecFilterSpec.js b/spec/html/HtmlSpecFilterSpec.js index ccfdc11d..8fa9a05d 100644 --- a/spec/html/HtmlSpecFilterSpec.js +++ b/spec/html/HtmlSpecFilterSpec.js @@ -1,4 +1,4 @@ -describe('HtmlSpecFilter', function() { +describe('jasmineUnderTest.HtmlSpecFilter', function() { it('should match when no string is provided', function() { const specFilter = new jasmineUnderTest.HtmlSpecFilter(); @@ -16,17 +16,4 @@ describe('HtmlSpecFilter', function() { expect(specFilter.matches('foo')).toBe(true); expect(specFilter.matches('bar')).toBe(false); }); - - it('copes with HtmlExactSpecFilterV2 filter strings', function() { - const specFilter = new jasmineUnderTest.HtmlSpecFilter({ - filterString: function() { - return '["foo","bar"]'; - } - }); - - expect(specFilter.matches('foo bar')).toBe(true); - expect(specFilter.matches('baz foo bar qux')).toBe(true); - expect(specFilter.matches('foo')).toBe(false); - expect(specFilter.matches('bar')).toBe(false); - }); }); diff --git a/src/boot/boot1.js b/src/boot/boot1.js index 7f22a55d..e4d8b356 100644 --- a/src/boot/boot1.js +++ b/src/boot/boot1.js @@ -16,12 +16,20 @@ (function() { const env = jasmine.getEnv(); + /** + * ## Runner Parameters + * + * More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface. + */ + const queryString = new jasmine.QueryString({ getWindowLocation: function() { return window.location; } }); + const filterSpecs = !!queryString.getParam('spec'); + const config = { stopOnSpecFailure: queryString.getParam('stopOnSpecFailure'), stopSpecOnExpectationFailure: queryString.getParam( @@ -63,7 +71,7 @@ return document.createTextNode.apply(document, arguments); }, timer: new jasmine.Timer(), - queryString + filterSpecs: filterSpecs }); /** @@ -75,9 +83,14 @@ /** * Filter which specs will be run by matching the start of the full name against the `spec` query param. */ - const specFilter = new jasmine.HtmlExactSpecFilter({ queryString }); + const specFilter = new jasmine.HtmlSpecFilter({ + filterString: function() { + return queryString.getParam('spec'); + } + }); + config.specFilter = function(spec) { - return specFilter.matches(spec); + return specFilter.matches(spec.getFullName()); }; env.configure(config); diff --git a/src/html/HtmlExactSpecFilter.js b/src/html/HtmlExactSpecFilter.js deleted file mode 100644 index 6a18d83a..00000000 --- a/src/html/HtmlExactSpecFilter.js +++ /dev/null @@ -1,54 +0,0 @@ -jasmineRequire.HtmlExactSpecFilter = function() { - 'use strict'; - - /** - * Spec filter for use with {@link HtmlReporter} - * - * See lib/jasmine-core/boot1.js for usage. - * @since 5.11.0 - */ - class HtmlExactSpecFilter { - #getFilterString; - - /** - * Create a filter instance. - * @param options Object with a queryString property, which should be an - * instance of {@link QueryString}. - */ - constructor(options) { - this.#getFilterString = function() { - return options.queryString.getParam('spec'); - }; - } - - /** - * Determines whether the specified spec should be executed. - * @param {Spec} spec - * @returns {boolean} - */ - matches(spec) { - const filterString = this.#getFilterString(); - - if (!filterString) { - return true; - } - - const filterPath = JSON.parse(this.#getFilterString()); - const specPath = spec.getPath(); - - if (filterPath.length > specPath.length) { - return false; - } - - for (let i = 0; i < filterPath.length; i++) { - if (specPath[i] !== filterPath[i]) { - return false; - } - } - - return true; - } - } - - return HtmlExactSpecFilter; -}; diff --git a/src/html/HtmlReporter.js b/src/html/HtmlReporter.js index b063fa5d..bb3e8948 100644 --- a/src/html/HtmlReporter.js +++ b/src/html/HtmlReporter.js @@ -7,13 +7,11 @@ jasmineRequire.HtmlReporter = function(j$) { this.specsExecuted = 0; this.failureCount = 0; this.pendingSpecCount = 0; - this.suitesById = []; } ResultsStateBuilder.prototype.suiteStarted = function(result) { this.currentParent.addChild(result, 'suite'); this.currentParent = this.currentParent.last(); - this.suitesById[result.id] = this.currentParent; }; ResultsStateBuilder.prototype.suiteDone = function(result) { @@ -66,14 +64,10 @@ jasmineRequire.HtmlReporter = function(j$) { const getContainer = options.getContainer; const createElement = options.createElement; const createTextNode = options.createTextNode; - // TODO: in the next major release, replace navigateWithNewParam and - // addToExistingQueryString with direct usage of options.queryString const navigateWithNewParam = options.navigateWithNewParam || function() {}; const addToExistingQueryString = options.addToExistingQueryString || defaultQueryString; - const filterSpecs = options.queryString - ? !!options.queryString.getParam('spec') - : options.filterSpecs; // For compatibility with pre-5.11 boot files + const filterSpecs = options.filterSpecs; let htmlReporterMain; let symbols; const deprecationWarnings = []; @@ -702,6 +696,21 @@ jasmineRequire.HtmlReporter = function(j$) { return wrapper; } + function suiteHref(suite) { + const els = []; + + while (suite && suite.parent) { + els.unshift(suite.result.description); + suite = suite.parent; + } + + // include window.location.pathname to fix issue with karma-jasmine-html-reporter in angular: see https://github.com/jasmine/jasmine/issues/1906 + return ( + (window.location.pathname || '') + + addToExistingQueryString('spec', els.join(' ')) + ); + } + function addDeprecationWarnings(result, runnableType) { if (result && result.deprecationWarnings) { for (let i = 0; i < result.deprecationWarnings.length; i++) { @@ -799,33 +808,11 @@ jasmineRequire.HtmlReporter = function(j$) { return '' + count + ' ' + word; } - function suitePath(suite) { - const els = []; - - while (suite && suite.parent) { - els.unshift(suite.result.description); - suite = suite.parent; - } - - return els; - } - - function suiteHref(suite) { - return pathHref(suitePath(suite)); - } - function specHref(result) { - const suite = stateBuilder.suitesById[result.parentSuiteId]; - const path = suitePath(suite); - path.push(result.description); - return pathHref(path); - } - - function pathHref(path) { // include window.location.pathname to fix issue with karma-jasmine-html-reporter in angular: see https://github.com/jasmine/jasmine/issues/1906 return ( (window.location.pathname || '') + - addToExistingQueryString('spec', JSON.stringify(path)) + addToExistingQueryString('spec', result.fullName) ); } diff --git a/src/html/HtmlSpecFilter.js b/src/html/HtmlSpecFilter.js index 9217eee9..a9058873 100644 --- a/src/html/HtmlSpecFilter.js +++ b/src/html/HtmlSpecFilter.js @@ -1,27 +1,11 @@ jasmineRequire.HtmlSpecFilter = function() { 'use strict'; - /** - * @name HtmlSpecFilter - * @classdesc Legacy HTML spec filter, for backward compatibility - * with boot files that predate {@link HtmlExactSpecFilter}. - * @param options Object with a filterString method - * @constructor - * @deprecated - * @since 1.2.0 - */ - // Legacy HTML spec filter, preserved for backward compatibility with - // boot files that predate HtmlExactSpecFilterV2 function HtmlSpecFilter(options) { - let filterString = (options && options.filterString()) || ''; - - if (filterString.startsWith('[')) { - // Convert an HtmlExactSpecFilterV2 string into something we can use - filterString = JSON.parse(filterString).join(' '); - } - - filterString = filterString.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); - + const filterString = + options && + options.filterString() && + options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); const filterPattern = new RegExp(filterString); /** diff --git a/src/html/requireHtml.js b/src/html/requireHtml.js index dd3b5a47..f303f019 100644 --- a/src/html/requireHtml.js +++ b/src/html/requireHtml.js @@ -6,5 +6,4 @@ jasmineRequire.html = function(j$) { j$.HtmlReporter = jasmineRequire.HtmlReporter(j$); j$.QueryString = jasmineRequire.QueryString(); j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter(); - j$.HtmlExactSpecFilter = jasmineRequire.HtmlExactSpecFilter(); };