From 0bf9aff1954358cf643b3e666bf7000597c67d94 Mon Sep 17 00:00:00 2001 From: Steve Gravrock Date: Sun, 7 Sep 2025 15:53:24 -0700 Subject: [PATCH] Extract configuration out of Env --- lib/jasmine-core/jasmine.js | 354 ++++++++++++++++++--------------- spec/core/ConfigurationSpec.js | 134 +++++++++++++ src/core/Configuration.js | 186 +++++++++++++++++ src/core/Env.js | 166 +--------------- src/core/requireCore.js | 1 + 5 files changed, 519 insertions(+), 322 deletions(-) create mode 100644 spec/core/ConfigurationSpec.js create mode 100644 src/core/Configuration.js diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index fa71ba7e..153f00d0 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -67,6 +67,7 @@ var getJasmineRequireObj = (function(jasmineGlobal) { j$.Clock = jRequire.Clock(); j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(j$); j$.Deprecator = jRequire.Deprecator(j$); + j$.Configuration = jRequire.Configuration(j$); j$.Env = jRequire.Env(j$); j$.StackTrace = jRequire.StackTrace(j$); j$.ExceptionFormatter = jRequire.ExceptionFormatter(j$); @@ -1189,132 +1190,7 @@ getJasmineRequireObj().Env = function(j$) { let runner; let parallelLoadingState = null; // 'specs', 'helpers', or null for non-parallel - /** - * This represents the available options to configure Jasmine. - * Options that are not provided will use their default values. - * @see Env#configure - * @interface Configuration - * @since 3.3.0 - */ - const config = { - /** - * Whether to randomize spec execution order - * @name Configuration#random - * @since 3.3.0 - * @type Boolean - * @default true - */ - random: true, - /** - * Seed to use as the basis of randomization. - * Null causes the seed to be determined randomly at the start of execution. - * @name Configuration#seed - * @since 3.3.0 - * @type (number|string) - * @default null - */ - seed: null, - /** - * Whether to stop execution of the suite after the first spec failure - * - *

In parallel mode, `stopOnSpecFailure` works on a "best effort" - * basis. Jasmine will stop execution as soon as practical after a failure - * but it might not be immediate.

- * @name Configuration#stopOnSpecFailure - * @since 3.9.0 - * @type Boolean - * @default false - */ - stopOnSpecFailure: false, - /** - * Whether to fail the spec if it ran no expectations. By default - * a spec that ran no expectations is reported as passed. Setting this - * to true will report such spec as a failure. - * @name Configuration#failSpecWithNoExpectations - * @since 3.5.0 - * @type Boolean - * @default false - */ - failSpecWithNoExpectations: false, - /** - * Whether to cause specs to only have one expectation failure. - * @name Configuration#stopSpecOnExpectationFailure - * @since 3.3.0 - * @type Boolean - * @default false - */ - stopSpecOnExpectationFailure: false, - /** - * A function that takes a spec and returns true if it should be executed - * or false if it should be skipped. - * @callback SpecFilter - * @param {Spec} spec - The spec that the filter is being applied to. - * @return boolean - */ - /** - * Function to use to filter specs - * @name Configuration#specFilter - * @since 3.3.0 - * @type SpecFilter - * @default A function that always returns true. - */ - specFilter: function() { - return true; - }, - /** - * Whether reporters should hide disabled specs from their output. - * Currently only supported by Jasmine's HTMLReporter - * @name Configuration#hideDisabled - * @since 3.3.0 - * @type Boolean - * @default false - */ - hideDisabled: false, - /** - * Clean closures when a suite is done running (done by clearing the stored function reference). - * This prevents memory leaks, but you won't be able to run jasmine multiple times. - * @name Configuration#autoCleanClosures - * @since 3.10.0 - * @type boolean - * @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 to issue warnings for certain deprecated functionality - * every time it's used. If not set or set to false, deprecation warnings - * for methods that tend to be called frequently will be issued only once - * or otherwise throttled to prevent the suite output from being flooded - * with warnings. - * @name Configuration#verboseDeprecations - * @since 3.6.0 - * @type Boolean - * @default false - */ - verboseDeprecations: false, - - /** - * Whether to detect late promise rejection handling during spec - * execution. If this option is enabled, a promise rejection that triggers - * the JavaScript runtime's unhandled rejection event will not be treated - * as an error as long as it's handled before the spec finishes. - * - * This option is off by default because it imposes a performance penalty. - * @name Configuration#detectLateRejectionHandling - * @since 5.10.0 - * @type Boolean - * @default false - */ - detectLateRejectionHandling: false - }; + const config = new j$.Configuration(); if (!envOptions.suppressLoadErrors) { installGlobalErrors(); @@ -1337,42 +1213,15 @@ getJasmineRequireObj().Env = function(j$) { * @argument {Configuration} configuration * @function */ - this.configure = function(configuration) { + this.configure = function(changes) { if (parallelLoadingState) { throw new Error( 'Jasmine cannot be configured via Env in parallel mode' ); } - const booleanProps = [ - 'random', - 'failSpecWithNoExpectations', - 'hideDisabled', - 'stopOnSpecFailure', - 'stopSpecOnExpectationFailure', - 'autoCleanClosures', - 'forbidDuplicateNames', - 'detectLateRejectionHandling' - ]; - - booleanProps.forEach(function(prop) { - if (typeof configuration[prop] !== 'undefined') { - config[prop] = !!configuration[prop]; - } - }); - - if (configuration.specFilter) { - config.specFilter = configuration.specFilter; - } - - if (typeof configuration.seed !== 'undefined') { - config.seed = configuration.seed; - } - - if (configuration.hasOwnProperty('verboseDeprecations')) { - config.verboseDeprecations = configuration.verboseDeprecations; - deprecator.verboseDeprecations(config.verboseDeprecations); - } + config.update(changes); + deprecator.verboseDeprecations(config.verboseDeprecations); }; /** @@ -1383,11 +1232,7 @@ getJasmineRequireObj().Env = function(j$) { * @returns {Configuration} */ this.configuration = function() { - const result = {}; - for (const property in config) { - result[property] = config[property]; - } - return result; + return config.copy(); }; this.setDefaultSpyStrategy = function(defaultStrategyFn) { @@ -3419,6 +3264,193 @@ getJasmineRequireObj().CompleteOnFirstErrorSkipPolicy = function(j$) { return CompleteOnFirstErrorSkipPolicy; }; +getJasmineRequireObj().Configuration = function(j$) { + /** + * This represents the available options to configure Jasmine. + * Options that are not provided will use their default values. + * @see Env#configure + * @interface Configuration + * @since 3.3.0 + */ + const defaultConfig = { + /** + * Whether to randomize spec execution order + * @name Configuration#random + * @since 3.3.0 + * @type Boolean + * @default true + */ + random: true, + /** + * Seed to use as the basis of randomization. + * Null causes the seed to be determined randomly at the start of execution. + * @name Configuration#seed + * @since 3.3.0 + * @type (number|string) + * @default null + */ + seed: null, + /** + * Whether to stop execution of the suite after the first spec failure + * + *

In parallel mode, `stopOnSpecFailure` works on a "best effort" + * basis. Jasmine will stop execution as soon as practical after a failure + * but it might not be immediate.

+ * @name Configuration#stopOnSpecFailure + * @since 3.9.0 + * @type Boolean + * @default false + */ + stopOnSpecFailure: false, + /** + * Whether to fail the spec if it ran no expectations. By default + * a spec that ran no expectations is reported as passed. Setting this + * to true will report such spec as a failure. + * @name Configuration#failSpecWithNoExpectations + * @since 3.5.0 + * @type Boolean + * @default false + */ + failSpecWithNoExpectations: false, + /** + * Whether to cause specs to only have one expectation failure. + * @name Configuration#stopSpecOnExpectationFailure + * @since 3.3.0 + * @type Boolean + * @default false + */ + stopSpecOnExpectationFailure: false, + /** + * A function that takes a spec and returns true if it should be executed + * or false if it should be skipped. + * @callback SpecFilter + * @param {Spec} spec - The spec that the filter is being applied to. + * @return boolean + */ + /** + * Function to use to filter specs + * @name Configuration#specFilter + * @since 3.3.0 + * @type SpecFilter + * @default A function that always returns true. + */ + specFilter: function() { + return true; + }, + /** + * Whether reporters should hide disabled specs from their output. + * Currently only supported by Jasmine's HTMLReporter + * @name Configuration#hideDisabled + * @since 3.3.0 + * @type Boolean + * @default false + */ + hideDisabled: false, + /** + * Clean closures when a suite is done running (done by clearing the stored function reference). + * This prevents memory leaks, but you won't be able to run jasmine multiple times. + * @name Configuration#autoCleanClosures + * @since 3.10.0 + * @type boolean + * @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 to issue warnings for certain deprecated functionality + * every time it's used. If not set or set to false, deprecation warnings + * for methods that tend to be called frequently will be issued only once + * or otherwise throttled to prevent the suite output from being flooded + * with warnings. + * @name Configuration#verboseDeprecations + * @since 3.6.0 + * @type Boolean + * @default false + */ + verboseDeprecations: false, + + /** + * Whether to detect late promise rejection handling during spec + * execution. If this option is enabled, a promise rejection that triggers + * the JavaScript runtime's unhandled rejection event will not be treated + * as an error as long as it's handled before the spec finishes. + * + * This option is off by default because it imposes a performance penalty. + * @name Configuration#detectLateRejectionHandling + * @since 5.10.0 + * @type Boolean + * @default false + */ + detectLateRejectionHandling: false + }; + Object.freeze(defaultConfig); + + class Configuration { + #values; + + constructor() { + this.#values = { ...defaultConfig }; + + for (const k of Object.keys(defaultConfig)) { + Object.defineProperty(this, k, { + enumerable: true, + get() { + return this.#values[k]; + } + }); + } + } + + copy() { + return { ...this.#values }; + } + + update(changes) { + const booleanProps = [ + 'random', + 'failSpecWithNoExpectations', + 'hideDisabled', + 'stopOnSpecFailure', + 'stopSpecOnExpectationFailure', + 'autoCleanClosures', + 'forbidDuplicateNames', + 'detectLateRejectionHandling' + ]; + + for (const k of booleanProps) { + if (typeof changes[k] !== 'undefined') { + this.#values[k] = changes[k]; + } + } + + if (changes.specFilter) { + this.#values.specFilter = changes.specFilter; + } + + // 0 and null are valid values, so a truthiness check wouldn't work + if (typeof changes.seed !== 'undefined') { + this.#values.seed = changes.seed; + } + + // TODO: in the next major release, make verboseDeprecations work like + // other boolean properties. + if (changes.hasOwnProperty('verboseDeprecations')) { + this.#values.verboseDeprecations = changes.verboseDeprecations; + } + } + } + + return Configuration; +}; + getJasmineRequireObj().CurrentRunableTracker = function() { class CurrentRunableTracker { #currentSpec; diff --git a/spec/core/ConfigurationSpec.js b/spec/core/ConfigurationSpec.js new file mode 100644 index 00000000..bc548380 --- /dev/null +++ b/spec/core/ConfigurationSpec.js @@ -0,0 +1,134 @@ +describe('Configuration', function() { + const standardBooleanKeys = [ + 'random', + 'stopOnSpecFailure', + 'stopSpecOnExpectationFailure', + 'failSpecWithNoExpectations', + 'hideDisabled', + 'autoCleanClosures', + 'forbidDuplicateNames', + 'detectLateRejectionHandling' + ]; + const allKeys = [ + ...standardBooleanKeys, + 'seed', + 'specFilter', + 'verboseDeprecations' + ]; + Object.freeze(standardBooleanKeys); + Object.freeze(allKeys); + + it('provides defaults', function() { + const subject = new jasmineUnderTest.Configuration(); + expect(subject.random).toEqual(true); + expect(subject.seed).toBeNull(); + expect(subject.stopOnSpecFailure).toEqual(false); + expect(subject.stopSpecOnExpectationFailure).toEqual(false); + expect(subject.failSpecWithNoExpectations).toEqual(false); + expect(subject.specFilter).toEqual(jasmine.any(Function)); + expect(subject.specFilter()).toEqual(true); + expect(subject.hideDisabled).toEqual(false); + expect(subject.autoCleanClosures).toEqual(true); + expect(subject.forbidDuplicateNames).toEqual(false); + expect(subject.verboseDeprecations).toEqual(false); + expect(subject.detectLateRejectionHandling).toEqual(false); + }); + + describe('copy()', function() { + it('returns a copy of the configuration as a plain old JS object', function() { + const subject = new jasmineUnderTest.Configuration(); + + const copy = subject.copy(); + + expect(copy.constructor.name).toEqual('Object'); + + expect(new Set(Object.keys(copy))).toEqual(new Set(allKeys)); + for (const k of allKeys) { + expect(copy[k]).toEqual(subject[k]); + } + }); + }); + + describe('update()', function() { + it('does not update properties that are absent from the parameter', function() { + const subject = new jasmineUnderTest.Configuration(); + const originalValues = subject.copy(); + + subject.update({}); + expect(subject.copy()).toEqual(originalValues); + }); + + function booleanPropertyBehavior(key) { + it('does not update the property if the specified value is undefined', function() { + const subject = new jasmineUnderTest.Configuration(); + const orig = subject[key]; + + subject.update({ [key]: undefined }); + + expect(subject[key]).toEqual(orig); + }); + + it('updates the property if the specified value is not undefined', function() { + const subject = new jasmineUnderTest.Configuration(); + const orig = subject[key]; + + subject.update({ [key]: !orig }); + expect(subject[key]).toEqual(!orig); + + subject.update({ [key]: orig }); + expect(subject[key]).toEqual(orig); + }); + } + + for (const k of standardBooleanKeys) { + describe(k, function() { + booleanPropertyBehavior(k); + }); + } + + // TODO: in the next major release, treat verboseDeprecations like other booleans + it('sets verboseDeprecations when present', function() { + const subject = new jasmineUnderTest.Configuration(); + const orig = subject.verboseDeprecations; + + subject.update({ verboseDeprecations: !orig }); + expect(subject.verboseDeprecations).toEqual(!orig); + + subject.update({ verboseDeprecations: orig }); + expect(subject.verboseDeprecations).toEqual(orig); + + // For backwards compatibility, explicitly setting to undefined should + // work. Undefined isn't officially valid but gets treated like false. + subject.update({ verboseDeprecations: undefined }); + expect(subject.verboseDeprecations).toBeUndefined(); + }); + + it('sets specFilter when truthy', function() { + const subject = new jasmineUnderTest.Configuration(); + const orig = subject.specFilter; + + subject.update({ specFilter: undefined }); + expect(subject.specFilter).toBe(orig); + + subject.update({ specFilter: false }); + expect(subject.specFilter).toBe(orig); + + function newSpecFilter() {} + subject.update({ specFilter: newSpecFilter }); + expect(subject.specFilter).toBe(newSpecFilter); + }); + + it('sets seed when not undefined', function() { + const subject = new jasmineUnderTest.Configuration(); + + subject.update({ seed: undefined }); + expect(subject.seed).toBeNull(); + + subject.update({ seed: 1234 }); + expect(subject.seed).toEqual(1234); + + subject.update({ seed: null }); + expect(subject.seed).toBeNull(); + }); + }); +}); diff --git a/src/core/Configuration.js b/src/core/Configuration.js new file mode 100644 index 00000000..4d32d5ce --- /dev/null +++ b/src/core/Configuration.js @@ -0,0 +1,186 @@ +getJasmineRequireObj().Configuration = function(j$) { + /** + * This represents the available options to configure Jasmine. + * Options that are not provided will use their default values. + * @see Env#configure + * @interface Configuration + * @since 3.3.0 + */ + const defaultConfig = { + /** + * Whether to randomize spec execution order + * @name Configuration#random + * @since 3.3.0 + * @type Boolean + * @default true + */ + random: true, + /** + * Seed to use as the basis of randomization. + * Null causes the seed to be determined randomly at the start of execution. + * @name Configuration#seed + * @since 3.3.0 + * @type (number|string) + * @default null + */ + seed: null, + /** + * Whether to stop execution of the suite after the first spec failure + * + *

In parallel mode, `stopOnSpecFailure` works on a "best effort" + * basis. Jasmine will stop execution as soon as practical after a failure + * but it might not be immediate.

+ * @name Configuration#stopOnSpecFailure + * @since 3.9.0 + * @type Boolean + * @default false + */ + stopOnSpecFailure: false, + /** + * Whether to fail the spec if it ran no expectations. By default + * a spec that ran no expectations is reported as passed. Setting this + * to true will report such spec as a failure. + * @name Configuration#failSpecWithNoExpectations + * @since 3.5.0 + * @type Boolean + * @default false + */ + failSpecWithNoExpectations: false, + /** + * Whether to cause specs to only have one expectation failure. + * @name Configuration#stopSpecOnExpectationFailure + * @since 3.3.0 + * @type Boolean + * @default false + */ + stopSpecOnExpectationFailure: false, + /** + * A function that takes a spec and returns true if it should be executed + * or false if it should be skipped. + * @callback SpecFilter + * @param {Spec} spec - The spec that the filter is being applied to. + * @return boolean + */ + /** + * Function to use to filter specs + * @name Configuration#specFilter + * @since 3.3.0 + * @type SpecFilter + * @default A function that always returns true. + */ + specFilter: function() { + return true; + }, + /** + * Whether reporters should hide disabled specs from their output. + * Currently only supported by Jasmine's HTMLReporter + * @name Configuration#hideDisabled + * @since 3.3.0 + * @type Boolean + * @default false + */ + hideDisabled: false, + /** + * Clean closures when a suite is done running (done by clearing the stored function reference). + * This prevents memory leaks, but you won't be able to run jasmine multiple times. + * @name Configuration#autoCleanClosures + * @since 3.10.0 + * @type boolean + * @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 to issue warnings for certain deprecated functionality + * every time it's used. If not set or set to false, deprecation warnings + * for methods that tend to be called frequently will be issued only once + * or otherwise throttled to prevent the suite output from being flooded + * with warnings. + * @name Configuration#verboseDeprecations + * @since 3.6.0 + * @type Boolean + * @default false + */ + verboseDeprecations: false, + + /** + * Whether to detect late promise rejection handling during spec + * execution. If this option is enabled, a promise rejection that triggers + * the JavaScript runtime's unhandled rejection event will not be treated + * as an error as long as it's handled before the spec finishes. + * + * This option is off by default because it imposes a performance penalty. + * @name Configuration#detectLateRejectionHandling + * @since 5.10.0 + * @type Boolean + * @default false + */ + detectLateRejectionHandling: false + }; + Object.freeze(defaultConfig); + + class Configuration { + #values; + + constructor() { + this.#values = { ...defaultConfig }; + + for (const k of Object.keys(defaultConfig)) { + Object.defineProperty(this, k, { + enumerable: true, + get() { + return this.#values[k]; + } + }); + } + } + + copy() { + return { ...this.#values }; + } + + update(changes) { + const booleanProps = [ + 'random', + 'failSpecWithNoExpectations', + 'hideDisabled', + 'stopOnSpecFailure', + 'stopSpecOnExpectationFailure', + 'autoCleanClosures', + 'forbidDuplicateNames', + 'detectLateRejectionHandling' + ]; + + for (const k of booleanProps) { + if (typeof changes[k] !== 'undefined') { + this.#values[k] = changes[k]; + } + } + + if (changes.specFilter) { + this.#values.specFilter = changes.specFilter; + } + + // 0 and null are valid values, so a truthiness check wouldn't work + if (typeof changes.seed !== 'undefined') { + this.#values.seed = changes.seed; + } + + // TODO: in the next major release, make verboseDeprecations work like + // other boolean properties. + if (changes.hasOwnProperty('verboseDeprecations')) { + this.#values.verboseDeprecations = changes.verboseDeprecations; + } + } + } + + return Configuration; +}; diff --git a/src/core/Env.js b/src/core/Env.js index c297e843..701b4586 100644 --- a/src/core/Env.js +++ b/src/core/Env.js @@ -63,132 +63,7 @@ getJasmineRequireObj().Env = function(j$) { let runner; let parallelLoadingState = null; // 'specs', 'helpers', or null for non-parallel - /** - * This represents the available options to configure Jasmine. - * Options that are not provided will use their default values. - * @see Env#configure - * @interface Configuration - * @since 3.3.0 - */ - const config = { - /** - * Whether to randomize spec execution order - * @name Configuration#random - * @since 3.3.0 - * @type Boolean - * @default true - */ - random: true, - /** - * Seed to use as the basis of randomization. - * Null causes the seed to be determined randomly at the start of execution. - * @name Configuration#seed - * @since 3.3.0 - * @type (number|string) - * @default null - */ - seed: null, - /** - * Whether to stop execution of the suite after the first spec failure - * - *

In parallel mode, `stopOnSpecFailure` works on a "best effort" - * basis. Jasmine will stop execution as soon as practical after a failure - * but it might not be immediate.

- * @name Configuration#stopOnSpecFailure - * @since 3.9.0 - * @type Boolean - * @default false - */ - stopOnSpecFailure: false, - /** - * Whether to fail the spec if it ran no expectations. By default - * a spec that ran no expectations is reported as passed. Setting this - * to true will report such spec as a failure. - * @name Configuration#failSpecWithNoExpectations - * @since 3.5.0 - * @type Boolean - * @default false - */ - failSpecWithNoExpectations: false, - /** - * Whether to cause specs to only have one expectation failure. - * @name Configuration#stopSpecOnExpectationFailure - * @since 3.3.0 - * @type Boolean - * @default false - */ - stopSpecOnExpectationFailure: false, - /** - * A function that takes a spec and returns true if it should be executed - * or false if it should be skipped. - * @callback SpecFilter - * @param {Spec} spec - The spec that the filter is being applied to. - * @return boolean - */ - /** - * Function to use to filter specs - * @name Configuration#specFilter - * @since 3.3.0 - * @type SpecFilter - * @default A function that always returns true. - */ - specFilter: function() { - return true; - }, - /** - * Whether reporters should hide disabled specs from their output. - * Currently only supported by Jasmine's HTMLReporter - * @name Configuration#hideDisabled - * @since 3.3.0 - * @type Boolean - * @default false - */ - hideDisabled: false, - /** - * Clean closures when a suite is done running (done by clearing the stored function reference). - * This prevents memory leaks, but you won't be able to run jasmine multiple times. - * @name Configuration#autoCleanClosures - * @since 3.10.0 - * @type boolean - * @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 to issue warnings for certain deprecated functionality - * every time it's used. If not set or set to false, deprecation warnings - * for methods that tend to be called frequently will be issued only once - * or otherwise throttled to prevent the suite output from being flooded - * with warnings. - * @name Configuration#verboseDeprecations - * @since 3.6.0 - * @type Boolean - * @default false - */ - verboseDeprecations: false, - - /** - * Whether to detect late promise rejection handling during spec - * execution. If this option is enabled, a promise rejection that triggers - * the JavaScript runtime's unhandled rejection event will not be treated - * as an error as long as it's handled before the spec finishes. - * - * This option is off by default because it imposes a performance penalty. - * @name Configuration#detectLateRejectionHandling - * @since 5.10.0 - * @type Boolean - * @default false - */ - detectLateRejectionHandling: false - }; + const config = new j$.Configuration(); if (!envOptions.suppressLoadErrors) { installGlobalErrors(); @@ -211,42 +86,15 @@ getJasmineRequireObj().Env = function(j$) { * @argument {Configuration} configuration * @function */ - this.configure = function(configuration) { + this.configure = function(changes) { if (parallelLoadingState) { throw new Error( 'Jasmine cannot be configured via Env in parallel mode' ); } - const booleanProps = [ - 'random', - 'failSpecWithNoExpectations', - 'hideDisabled', - 'stopOnSpecFailure', - 'stopSpecOnExpectationFailure', - 'autoCleanClosures', - 'forbidDuplicateNames', - 'detectLateRejectionHandling' - ]; - - booleanProps.forEach(function(prop) { - if (typeof configuration[prop] !== 'undefined') { - config[prop] = !!configuration[prop]; - } - }); - - if (configuration.specFilter) { - config.specFilter = configuration.specFilter; - } - - if (typeof configuration.seed !== 'undefined') { - config.seed = configuration.seed; - } - - if (configuration.hasOwnProperty('verboseDeprecations')) { - config.verboseDeprecations = configuration.verboseDeprecations; - deprecator.verboseDeprecations(config.verboseDeprecations); - } + config.update(changes); + deprecator.verboseDeprecations(config.verboseDeprecations); }; /** @@ -257,11 +105,7 @@ getJasmineRequireObj().Env = function(j$) { * @returns {Configuration} */ this.configuration = function() { - const result = {}; - for (const property in config) { - result[property] = config[property]; - } - return result; + return config.copy(); }; this.setDefaultSpyStrategy = function(defaultStrategyFn) { diff --git a/src/core/requireCore.js b/src/core/requireCore.js index df334bb2..669bd244 100644 --- a/src/core/requireCore.js +++ b/src/core/requireCore.js @@ -43,6 +43,7 @@ var getJasmineRequireObj = (function(jasmineGlobal) { j$.Clock = jRequire.Clock(); j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(j$); j$.Deprecator = jRequire.Deprecator(j$); + j$.Configuration = jRequire.Configuration(j$); j$.Env = jRequire.Env(j$); j$.StackTrace = jRequire.StackTrace(j$); j$.ExceptionFormatter = jRequire.ExceptionFormatter(j$);