This reverts commit e2a7740322.
structuredClone errors in these browsers were a symptom of inavertently
including Error objects in reporter events. In newer browsers,
structuredClone can copy those objects, but it's lossy: if an instance of
an Error subclass is cloned, the result is an instance of Error.
With that fixed, Jasmine is compatible with Safari 16 and FF 102. At least
for now. And keeping them around may provide a way to detect similar bugs.
This reverts commit 6da88ec19eea2780c030dc95fcc55d059fed69e5.
Removing existing handlers turns out to be load-bearing for Jasmine's
parallel mode. ParallelWorker (in the jasmine package) installs a pair
of handlers before booting core so that it can catch late async errors
that happen after one spec file has finished executing and before the
next starts. If those aren't uninstalled, errors that get routed through
jasmine-core's normal error handling mechanism will also be reported
via ParallelWorker's handlers. It might be possible for ParallelWorker
to uninstall and install its handlers at the right time, but it's
likely that there would be gaps in between when core uninstalls its
handlers and when ParallelWorker installs. And in any case, the
old behavior of GlobalErrors was a perfect match for what ParallelWorker
needs, so let's keep it.
Safari 15:
* Lacks structuredClone, which is starting to become useful
* Has stack trace quirks that are not well understood, not properly handled
by Jasmine, and can cause problems in Jasmine's own tests
* Is not widely used
* Does not run on any OS that still receives security updates
In theory, resetting clearStack's inline call count every time late
rejection handling does a setTimeout should reduce the performance penalty
in some environments. In practice, it doesn't:
* In Chrome and FF, late rejection handling has no measurable penalty.
* In Safari, resetting the inline call count actually slows things down
considerably(!).
* In Node, clearStack doesn't use setTimeout so there is no benefit.
When run with --not-actually-all, scripts/run-all-browsers skips all
but the oldest and newest supported Firefox and Safari versions. This
provides a faster but still quite reliable mergeability check.
CI still tests against all supported browsers.
This:
* Sets the stage for getting suite and spec execution in one place
* Greatly simplifies the interaction between Runner and TreeProcessor
* Focuses TreeProcessor more on building execution trees
These are mostly adaptations of the execution tests from TreeProcessorSpec.js.
They are meant to support refactoring of the interface and responsibility
division between Runner and TreeProcessor. All these scenarios are probably
covered by nearly-end-to-end integration tests, but those are more difficult
to debug.
All current shipped versions of zone.js contain a monkey patch that fails
to pass constructor arguments on to GlobalErrors. That would crash Jasmine
if it was applied early enough to have any effect.
See <https://github.com/angular/angular/issues/63072>.
This commit attempts to ensure that the timers created by jasmine mock
clock do not conflict with the native timers. This also retains
pre-existing behavior whereby a native scheduled function cannot be
cleared if it was created prior to the mock clock being installed
(unless the mock clock is uninstalled first).
Prior to this commit, attempting to clear a native timer would result in
clearing a mocked scheduled function instead, in some scenarios where
the IDs conflicted.
fixes#2068
This helps make matcher errors and spy strategy mismatch errors easier
to understand in cases where the difference involves expecting one
function but getting a different one.
The autotick feature mistakenly does not account for the clock being a
singleton and the re-installation of the clock causes the auto ticking
exit conditions to become true again, before it has a chance to break.
This is in addition to the existing concatenated name. It's meant to
support tools like IDE integrations that want to be able to filter a
run to an exact set of suites/specs.
It doesn't look like there's a reliable way to test setTimeout throttling
prevention. The underlying behavior is too nondeterministic. This test
failed at a significant rate in browsers where throttling prevention worked,
simply due to setTimeout taking longer than expected (e.g. 130ms for the
entire test vs an expected <= 5oms). When run in Safari, where setTimeout
throttling prevention doesn't work, it would incorrectly pass if run early
enough in the test order. This is presumably because setTimeout throttling
is influenced by the setTimeout calls made by Jasmine itself prior to
running the test.
This isn't officially compatible with the oldest version of Node that
Jasmine supports, but it works. If it stops working, we can always disable
linting in CI builds on older Node versions.
temp has seen some recent maintainer activity but there haven't been
any commits since 2021 and PRs have gone un-addressed for years. It's
one of the dev dependencies that depends on very old versions of rimraf.
* fixes the throttling timeout test which incorrectly converted
from milliseconds to seconds before making an assertion expecting
milliseconds.
* reduces number of timeouts from 2000 to 100, which is still more than enough
to observe throttling (or lackthereof).
* Omits Node from the test since it does not throttle timeouts
Testing with mock clocks can often turn into a real struggle when
dealing with situations where some work in the test is truly async and
other work is captured by the mock clock. This can happen for many
reasons, but as one example:
An asynchonrous change from a task in the mocked clock may change DOM where
a resize observer then gets triggered. This browser API is truly asynchronous
and would require the user to wait real time for it to fire. If there is
follow-up work after the resize observer fires, it may be captured by the mock
clock again. This would require the tester to write something like the
following:
```
// flush the timer
jasmine.clock().tick();
// wait for resize observer
await new Promise(resolve => setTimeout(resolve));
// flush follow-up work from the resize observer callback
jasmine.clock().tick();
```
When using mock clocks, testers are always forced to write tests with intimate
knowledge of when the mock clock needs to be ticked. Oftentimes, the
purpose of using a mock clock is to speed up the execution time of the
test when there are timeouts involved. It is not often a goal to test
the exact timeout values. This can cause tests to be riddled with
`tick`. It ideal for test code to be written in a way
that is independent of whether a mock clock is installed. For example:
```
document.getElementById('submit');
// https://testing-library.com/docs/dom-testing-library/api-async/#waitfor
await waitFor(() => expect(mockAPI).toHaveBeenCalledTimes(1))
```
When mock clocks are involved, the above may not be possible if there is
some delay involved between the click and the request to the API.
Instead, developers would need to manually tick the clock beyond the
delay to trigger the API call.
This commit attempts to resolve these issues by adding a feature to the
clock which allows it to advance on its own with the passage of time,
just as clocks do without mocks installed. It also allows for some
breathing time so any unmocked micro and macrotasks are given space to
execute as well.
This feature would also address both #1725 and #1932. `asyncTick` can be
accomplished by enabling the auto tick feature and then waiting for a
promise with a timout to be resolved
(`await new Promise(resolve => setTimeout(resolve, 20))`) where
`setTimeout` is captured by the mock clock and flushed while the code is
waiting for the promise to resolve.
resolves#1725resolves#1932
All credit goes to @stephenfarrar for this.
This is particularly helpful when reporting testing-library errors, which
have messages that contain blank lines and can be hundreds or even thousands
of lines long.
Fixes#2008
wrapping setTimeout in postMessage is a trade-off between
* slowdown due to postMessage (slow on Safari)
* speedup due to no setTimeout clamping (can be severe on Safari)
This was intended as a 3.0 migration aid for browser users who had
dependencies that triggered errors at load time. However, it was never
documented and never supported by jasmine-brower-runner, karma, or any
other commonly used tool for runing Jasmine in the browser. There is
no evidence of it actually being used. It is, however, starting to
show up in machine-generated "tutorials".
The Pivotal copyright notice needs to be retained. That's the right
thing to do and the MIT license requires it. However, using it by itself
becomes more obviously incorrect with each passing year since Pivotal
ceased to exist. Moreover, Pivotal hasn't actually been the sole
copyright owner since the first external contribution was merged.
Contributors were not asked to sign a copyright assignment, so they
retain copyright to their contributions.
"Copyright (c) 2008-2019 Pivotal Labs" complies with the terms of the
license and acknowledges Pivotal's outsized role in developing Jasmine.
"Copyright (c) 2008-$YEAR The Jasmine developers" acknowledges all
authors and will remain correct in the future.
The CI status badge mostly just shows whether Saucelabas was flaky
last night. Code Triage was a nice idea but it's attracted at most
one new contributor over 5.5 years.
These are similar to `expect` and `expectAsync` except that they throw
exceptions rather than recording matcher failures as spec/suite failures.
They're intended to support using Jasmine matchers in testing-library's
`waitFor`, and also provide a way to integration-test custom matchers.
These funtions are not equivalent to `expect` and `expectAsync` and should
not be used in situations where you want a matcher failure to reliably fail
the spec. Whether that happens depends on the structure of the surrounding
code. In general, you should only use `throwUnless` when you expect
something (which could be your own code or library code like `waitFor`) to
catch the resulting exception.
Fixes#2003.
Fixes#1980.
Not updating Prettier because newer versions impose significant formatting
changes. In particular, 2.0 changes every function definition from
`function() {` to `function () {` with no way to opt out. I'm not willing
to accept that kind of churn just becuse the Prettier devs changed their
mind about what color the bikeshed should be.
We'll most likely stay on Prettier 1.17 for as long as it remains viable,
then either switch to an autoformatter that offers stability or just
remove it.
Node 16 will reach EOL no later than a few months after Jasmine 5 is
released. Experience with Node 12 and Node 14 has shown that our
dependencies, especially dev dependencies, move on from past-EOL Node
versions fairly quickly. That can make it difficult to continue supporting
them. Since long term support for past EOL Node versions is a non-goal and
many users expect that Node versions will only be dropped in major
releases, it's better to drop it in 5.0.
This is intended to support parallel execution, which is planned for a
future release of Jasmine. Because the execution of unrelated suites will
interleave when run in parallel, reporters will not be able to assume
that the most recent `suiteStarted` event identifies the parent of the
current suite/spec. By adding this feature now, we allow reporters to
support both parallel execution and at least some 4.x versions without
having to implement two different ways of finding the parent suite.
Either running these once total or running them once per process
would be the wrong choice for a significant chunk of users, so do
neither. Later we'll add a new API for exactly-once setup and teardown
in parallel mode.
Each spec file is only loaded in a single worker, so top level
before/afterEach can't behave consistently.
beforeEach/afterEach are still supported in:
* Helper files
* describe() blocks
* At the top level of spec files in non-parallel mode
* Fixed description of patch releases
* Moved -npm release docmentation to that repo
* Refer to -npm specifically rather than "binding libraries" generally,
now that we only have one of those that versions in lockstep with core.
* Generally simplifies error handling in browsers
* Makes Jasmine's own integration tests easier to debug
* Stack traces will be provided for more global errors
* ... but less error information will be provided in some browsers if the
error comes from a file:// URL (use `npx serve` or similar instead)
* Jasmine will no longer override existing onerror handlers in browsers
* Setting window.onerror will no longer override Jasmine's global error
handling (use jasmine.spyOnGlobalErrors instead)
* Avoid setTimeout in Node, because we don't need the overhead there.
* Still call setTimeout in browsers to prevent the tab from being killed.
* Use queueMicrotask in Safari, because it's dramatically faster than
MessageChannel there.
* Continue to use MessageChannel in other supported browsers becuase it's
somewhat faster than queueMicrotask there.
* Don't use setImmediate any more because there's a faster alternative in
all supported envs.
In jasmine-core's own test suite, this yields a roughly 50-70% speedup
in Node, ~20% in Edge, and 75-90%(!) in Safari.
* The `boot` function exported by the core module returns the same object
every time it's called.
* Removed node_boot.js. Use the exported `boot` function instead
* JasmineStartedInfo does not have totalSpecsDefined or order in parallel mode
* JasmineDoneInfo does not have order in parallel mode
* Added incompleteCode and numWorkers to JasmineDoneInfo
Previously, an error that occurred after Jasmine started to report the
suiteDone or specDone event for the current runable would not be reliably
reported. Now such an error is reported on the nearest ancestor suite whose
suiteDone event has not yet been reported.
.substr() is deprecated so we replace it with functions which work similarily but aren't deprecated
Signed-off-by: Tobias Speicher <rootcommander@gmail.com>
The message return on negate clause was not expected. This makes it negative to match expectation. This also add tests for the change, and renames some tests to make it more clear.
This approach makes it hard to scale and goes against DRY and debuggability vs the previous approach which followed Python parameterized testing, but this was the recommendation of the Jasmine team to keep it consistent with other tests.
Further tests here could be adding other types like Array, Map, WeakMap, Set, WeakSet...
This matcher checks all the properties of a given spy object and checks whether at least one of the spies has been called. It returns true if one or more of the spies of the spy object has been called and false otherwise.
* Moved "Before Submitting a Pull Request" to the top
* Removed discussion of the standard Github PR workflow
(Contributors who don't know how to create PRs on Github at all can find
that information elsewhere. For the rest, it's just noise.)
* Misc copy edits
This is noisier, but it maintains compatibility with reporters that assume
(quite reasonably) that all specs and suites are either filtered out or
reported.
This was already done for everything except spec cleanup fns, since the
various skip policies need to know the difference between afterEach and
afterAll.
Add support for running jasmine multiple times.
```js
const Jasmine = require('jasmine');
async function main() {
const jasmine = new Jasmine({ projectBaseDir: process.cwd() });
let specId = 'spec0';
jasmine.loadConfigFile('./spec/support/jasmine.json');
jasmine.env.configure({
specFilter(sp) {
return sp.id === specId;
},
autoCleanClosures: false
});
jasmine.exit = () => {};
await jasmine.execute();
specId = 'spec2';
await jasmine.execute();
}
main().catch((err) => {
console.error(err);
process.exitCode = 1;
});
```
With `jasmine.env.configure({ autoCleanClosures: false })` you disable Jasmine's feature to automatically clean closures (functions) during the test run. This is a requirement to be able to rerun.
When `execute` is called more than once, the `topSuite.reset` is called, which will reset the state for the next run as well as reset any child suites.
Add a function `exclude` to the `Suite` and `Spec` clases. This functions similar to `pend`, but will allow the "pending" state to persist over multiple runs. This is useful when `xit` is used.
Revert changes to jasmine.js
fix: make sure to call hooks during second run
Remove jsdoc from private apis
Fix elint issue
Add new line
Because pending() is implemented via the standard exception handling
path, we effectively got this feature for free as a result of the changes
for #1533, particularly 457a2727.
* [#178598493]
* Fixes#1579
This should allow us to more easily support complex skipping strategies
like skipping nested cleanup fns when the corresponding befores were
skipped, or skipping specs and suites when a beforeAll fails.
* #1533
This works, but until the -npm 3.10.0 is out, it creates a chicken and egg
problem where each of core 3.10.0 and -npm 3.10.0 needs to be released
after the other.
This reverts commit 1c9382c990.
This allows assertion failures and other errors that occcur after the async
error to be routed to the correct spec/suite.
Previously, Jasmine treated global errors and unhandled promise rejections
just like exceptions thrown from a synchronous spec: it recorded the error
as a spec failure and moved on. Now, global errors and uhandled rejections
are recorded as failures but the current queueable fn will continue until
it either signals completion or times out. Global errors and unhandled
rejections are different from synchronous exceptions: it's common for the
queueable fn that caused them to continue executing. Immediately moving on
often meant that the queueable fn would produce expectation failures or
other errors when a different spec or suite was running, thus causing
those failures to be routed to the wrong place.
This info is useful because if someone does not set the number to a high enough value while stepping through test code, before or after hooks may be triggered mid-test while the user is debugging which will be confusing.
All supported platforms now provide promises, so there's no longer a need
for Jasmine to be able to create them via a user-provided library. Jasmine
can still consume non-native promises but will always use the built-in
Promise object to create promises.
[#179078103]
This is mainly intended to support jasmine-browser-runner, which will load
a script that configures the env in between the two boot files (boot0.js and
boot1.js). The single-file boot.js is retained for now but will be removed
in a future release.
This reduces the risk of incorrectly passing a spec due to not correctly
detecting that an argument is an `Error` instance. Detecting Error instances
in a way that's reliable and portable across different browsers, TrustedTypes,
and frames is difficult.
[Finishes #178267587]
These might be useful for a function with a more restricted domain. But for
equals, which accepts two of literally anything, the short run was too short
to catch any problems and the long run tended to exceed the CircleCi timeout.
The isError_ check uses a heuristic that calls the Function constructor
to determine if the given value is an Error object. This results in a
runtime violation in test suites that enforce Trusted Types.
Since Trusted Types are only supported in modern browsers (currently,
Chromium-based browsers), we can use a more straightforward heuristic in
environments where Trusted Types are supported.
Fixes#1910. See that thread for more details.
Reverted because it breaks the option checkboxes in the HTML reporter, both
in the standalone distribution and in jasmine-browser-runner.
Reopens#1906.
This reverts commit 1e4f0d1545.
The deprecation warning relies on Proxy, and won't work in environments
that don't have it. Among Jasmine's supported environments, that's Safari 9,
Safari 8, and all versions of IE.
* De-duplication now happens in core, not in reporters. This ensures that
the console doesn't get flooded.
* Stack traces are opt-out, not opt-in.
* The current runnable is not reported or logged for certain deprecations
where it's irrelevant.
* HtmlReporter shows stack traces in expandable widgets.
* Env#deprecated and Env#deprecatedOnceWithStack are merged.
This was a holdover from 1.x that should have been removed in 2.0,
but was missed. Suite is meant to be private, and almost none of
its methods can be safely called by user code.
Jasmine 1.x exposed Suite objects to user code as the `this` in describe
functions. That should have been removed in 2.0 but it was missed. It
will be removed in 4.0. This change adds a deprecation warning if anything
on a describe's `this` is accessed.
The deprecation warning relies on Proxy, and won't work in environments
that don't have it. Among Jasmine's supported environments, that's Safari 9,
Safari 8, and all versions of IE. In those browsers, a describe's `this`
will still be a Suite for now, but there will be no deprecation warnings.
* Don't run them in browsers in the regular CI build
* Run them in browsers in a special nightly build
* Run them in Node in the regular CI build
* Run them when developers manually run the suite
This should allow the regular CI build to give us a more useful signal,
while keeping us from losing sight of the flaky specs.
We still support IE 10 and 11, but the Node selenium-webdriver has
serious problems with it. Until that's fixed or worked around, IE builds
won't pass. This gets us otherwise green so we can easily see if
anything else is broken.
When using the following code to simulate a node error:
spyOn(process, 'kill').and.throwError({code: 'ESRCH'})
The object passed in will be converted to a string by the Error
constructor and result in '[object Object]' which is not very useful.
This PR changes the ``throwError`` spy strategy to only convert
strings into an Error object, but any other objects which are passed
in will be thrown as is. This means the spy strategy can never emulate
throwing a bare string ``throw 'error'``, but this would be a backward
incompatible change.
This should fix CI, and can be reverted once a new version of
jasmine-browser that contains 33bd0fcb0ba990102dcd846e673d07b11041dd44
has been published.
Use setSpecProperty to attach key/value pairs to spec results that can be
picked up in specialized jasmine reporters. Example use-cases
include:
* Tagging specs with URLs or string-tokens referencing test-plan docs.
* Recording performance information for blocks of JS.
Similarly setSuiteProperty attaches key/value pairs to suite results
Previously, suite duration was always reported as 0 and spec duration
was always reported as null. Suites always used a no-op timer, and
specs set their result.duration after the result had already been sent
to reporters.
Fixes#1676.
Previously, a custom matcher library that wanted to remain compatible with
Jasmine <= 3.5.x could not know whether or not Jasmine expected it to pass
custom equality testers to MatchersUtil#contains. Passing them would produce
a deprecation warning in newer versions and not passing them would break
compatibility with older versions. Now we use matcher factory arity to
determine whether to pass custom equality testers to the factory, which
allows libraries to do something like this:
function matcherFactory(util) {
const customEqualityTesters = arguments[1];
// customEqualityTesters will be undefined in newer versions of Jasmine
// and defined in older versions that expect it to be passed back to
// MatchersUtil#equals.
}
* Include stack traces. This makes it easier to find the matcher that
needs to be updated, particularly when it comes from a library rather
than the user's own code.
* Show each deprecation only once unless `config.verboseDeprecations`
is set. Since matchers are often added in a global `beforeEach`, logging
deprecations every time can be overwhelming.
Custom object formatters allow users to customize how an object is
stringified in matcher failure messages. This can already be done by
adding a `jasmineToString` method to the objects in question. But
it's not always desirable or possible to do that, particularly when
objects of a given "type" do not inherit from a specific prototype.
For instance, suppose a web service returns a list of foos that are
deserialized from JSON, e.g.:
{ fooId: 42, /* more properties */ }
The only way to define `jasmineToString` on those is by writing code to
add it to each instance at runtime. But a custom object formatter can
recognize that the object it's looking at is a foo and format it
accordingly:
jasmine.addCustomObjectFormatter(function(obj) {
if (typeof obj.fooId !== 'number') {
return undefined;
}
return '[Foo with ID ' + obj.fooId + ']';
});
Unlike `jasmineToString`, custom object formatters are scoped to a
particular spec or suite and don't require any changes to the code
under test.
This will allow us to add support for custom object formatters, which
will be a per-runable resource like custom matchers, by injecting them
into the pretty-printer.
This makes it easier to write high quality matchers and asymmetric equality
testers, and is also a step toward supporting custom object formatters.
Previously, Jasmine passed custom object formatters as the second argument
to matcher factories and as and the second argument to asymmetric equality
testers' `asymmetricMatch` method. Matchers and asymmetric equality testers
were responsible for passing the custom object formatters to methods like
`matchersUtil#equals`:
function toEqual(util, customEqualityTesters) {
return {
compare: function(actual, expected) {
// ...
result.pass = util.equals(actual, expected, customEqualityTesters, diffBuilder);
And:
ArrayContaining.prototype.asymmetricMatch = function(other, customTesters) {
// ...
for (var i = 0; i < this.sample.length; i++) {
var item = this.sample[i];
if (!j$.matchersUtil.contains(other, item, customTesters)) {
return false;
}
}
With this change, that is no longer necessary. Matchers and asymmetric
equality testers can ignore the existence of custom equality testers and
still fully support them:
function toEqual(util) {
return {
compare: function(actual, expected) {
// ...
result.pass = util.equals(actual, expected, diffBuilder);
And:
ArrayContaining.prototype.asymmetricMatch = function(other, matchersUtil) {
// ...
for (var i = 0; i < this.sample.length; i++) {
var item = this.sample[i];
if (!matchersUtil.contains(other, item)) {
return false;
}
}
The old interfaces are still supported, for now, but will be deprecated
in a future commit and removed in the next major release after that.
In addition to making matchers and custom equality testers simpler,
this change sets the stage for adding support for custom object
formatters. Those will be architecturally similar to custom equality
testers, and by injecting a `MatchersUtil` instance everywhere we can
add them without requiring user code to pass them around as used to be
the case with custom object formatters.
* Use Windows instead of Linux so we can get current browsers from Sauce.
* Test against the version of Firefox that corresponds to ESR as well as
latest.
* Test the latest Edge rather than a specific older version.
* Test Safari 8 and 13 instead of 8, 9 and 10. What works in those versions
is likely to work in the ones in between.
Property tests can only run in Node, so they were previously in another
directory that only gets run in Node. Now they're next to the related
non-property tests and marked pending in the browser. This makes it more
likely that a developer who normally only runs tests in the browser will
notice and run them.
* See #1764 from @dubzzz
* Property tests are only run in Node, not browser.
* The Travis build sets JASMINE_LONG_PROPERTY_TESTS to enable much more
thorough (but slow) testing.
When I first saw it(), I was wondering if the name "it" is
an abbreviation of anything. After some search, I finally
realized that the name is only a pronoun. Therefore, I
think it's worthwhile to include it in the documentation.
If the tests only fail on one browser, it's usually IE. So testing
IE first gives us faster feedback in cases where we're actively
watching the Travis build.
Turns this output:
Expected $[0].foo = Object({ a: 4, b: 5 }) to equal <jasmine.objectContaining(Object({ a: 1, c: 3 }))>.
into this:
Expected $[0].foo.a = 4 to equal 1.
Expected $[0].foo.c = undefined to equal 3.
And turns this output:
Expected spy jasmineDone to have been called with:
[ ... snipped very long expected call ]
but actual calls were:
[ ... snipped very long actual call ]
Call 0:
Expected $[0] = Object({ overallStatus: 'failed', totalTime: 1, incompleteReason: undefined, order: Order({ random: true, seed: '88732', sort: Function }), failedExpectations: [ Object({ matcherName: 'toBeResolved', passed: false, message: 'Suite "a suite" ran a "toBeResolved" expectation after it finished.
Did you forget to return or await the result of expectAsync?', error: undefined, errorForStack: Error, actual: [object Promise], expected: [ ], globalErrorType: 'lateExpeztation' }) ], deprecationWarnings: [ ] }) to equal <jasmine.objectContaining(Object({ failedExpectations: [ <jasmine.objectContaining(Object({ passed: false, globalErrorType: 'lateExpectation', message: 'Suite "a suite" ran a "toBeResolved" expectation after it finished.
Did you forget to return or await the result of expectAsync?', matcherName: 'toBeResolved' }))> ] }))>.
into this:
Expected spy jasmineDone to have been called with:
[ ... snipped very long expected call ]
but actual calls were:
[ ... snipped very long actual call ]
Call 0:
Expected $[0].failedExpectations[0].globalErrorType = 'lateExpeztation' to equal 'lateExpectation'.
This makes it easier to see where each failure message begins and ends.
Before:
Some context: a
multiline
message
After:
Some context:
a
multiline
message
It's very easy to forget to `await` or `return` the promise returned
from `expectAsync`. When that happens, the expectation failure will
occur after the spec or suite's result has been reported to reporters,
and the failure will typically not be shown to the user. This change
adds a top-level suite failure in that case, similar to the way we
report unhandled exceptions or promise rejections that occur after the
runable completes. Adding the error at the top level gives us the best
chance of getting in before the set of failures we add it to is sent
to reporters.
See #1752.
PhantomJS is at end of life, and the last version of Selenium that supported
it was 3.6.0, released almost three years ago. We can't test Jasmine against
PhantomJS without pinning key pieces of the project to increasingly outdated
versions of key libraries.
If the actual value of a test was a string, this was matching against arrays
that contained the strings. This was due to the use of the contains matcher,
which against string looks for substrings, when it was intended to look for
array elements.
The first number is the error message in HTML5 browser, which does not include
the call stack. The error instance allows logging the complete call stack in
reporters.
Users would like an error if it() is acciddently moved within a before/afterEach/All function.
The it() function calls ensureIsNotNested to report such an error. But if the user has no
other it() functions in the Suite, it() and thus ensureIsNotNested() is never called.
Here we check nested Suites for children; if none are found we throw.
There are now multiple ways to do async functions, and callbacks
are probably the least common in new code, so the message should
be more general rather than referring to callbacks.
The global window error handler is used to handle errors thrown from within asynchronous functions and tests. The first parameter is the error; the fifth parameter is the full error object including the stacktrace. Searching for the first occurrence of an error instance to work with browsers, which may not comply with the HTML5 standard.
This breaks each call out onto its own line, so that it's much easier to
see where each call starts and how they differ. E.g. previously the output
would be:
Expected spy foo to have been called with [ 'bar', 'baz', 'qux' ] but actual calls were [ [ 42, 'wibble' ], [ 'bar' 'qux' ], [ 'grault '] ]
Now it's:
Expected spy foo to have been called with:
[ 'bar', 'baz', 'qux' ]
but actual calls were:
[ 42, 'wibble' ],
[ 'bar' 'qux' ],
[ 'grault '].
The PrettyPrint handler for scalars uses toString() but if that method
has been spyed on, then the stringify fails with
TypeError: Cannot read property 'length' of undefined.
By hanlding this case earlier in format() we avoid the error.
Add unit test covering this case.
Wrap spec start/complete in Timer start/elapsed.
configuration.timeSpecDuration = false will disable feature.
* Add Suite result.duration, elapsed time in ms
* Remove timeSpecDuration option.
* Respond to review, use noopTimer
With the current set up, error message is only printed out when error name is available.
There are situations where the ErrorEvent object does not have a `name` property, but the message is still relevant.
For more details see #1594
This function will spy on all writable and configurable functionss of
an object that is passed in. It can be used like this:
spyOnAllFunctions(obj);
This commit addresses https://github.com/jasmine/jasmine/issues/1421
This makes failures somewhat easier to read. We still preserve whitespace
within lines to make whitespace-only failures readable, e.g.
expect('foo bar').toEqual('foo bar'). See #296.
Adds a badge showing the number of people helping this repo on CodeTriage.
[](https://www.codetriage.com/jasmine/jasmine)
## What is CodeTriage?
CodeTriage is an Open Source app that is designed to make contributing to Open Source projects easier. It works by sending subscribers a few open issues in their inbox. If subscribers get busy, there is an algorithm that backs off issue load so they do not get overwhelmed
[Read more about the CodeTriage project](https://www.codetriage.com/what).
## Why am I getting this PR?
Your project was picked by the human, @schneems. They selected it from the projects submitted to https://www.codetriage.com and hand edited the PR. How did your project get added to [CodeTriage](https://www.codetriage.com/what)? Roughly 8 months ago, [alopezsanchez](https://github.com/alopezsanchez) added this project to CodeTriage in order to start contributing. Since then, 2 people have subscribed to help this repo.
## What does adding a badge accomplish?
Adding a badge invites people to help contribute to your project. It also lets developers know that others are invested in the longterm success and maintainability of the project.
You can see an example of a CodeTriage badge on these popular OSS READMEs:
- [](https://www.codetriage.com/rails/rails) https://github.com/rails/rails
- [](https://www.codetriage.com/crystal-lang/crystal) https://github.com/crystal-lang/crystal
## Have a question or comment?
While I am a bot, this PR was manually reviewed and monitored by a human - @schneems. My job is writing commit messages and handling PR logistics.
If you have any questions, you can reply back to this PR and they will be answered by @schneems. If you do not want a badge right now, no worries, close the PR, you will not hear from me again.
Thanks for making your project Open Source! Any feedback is greatly appreciated.
- Ensure *All's only execute if at least one child will run
- Specs will report a status of `excluded` instead of disabled
[finishes #153967580]
- #1418
Signed-off-by: Elenore Bastian <ebastian@pivotal.io>
CodeClimate's recommendations have been a mix of irrelevant and
actively harmful for some time. The latest problem is that it applies
length and complexity requirements equally to all functions whether
they act as privacy scopes, namespaces, classes or just regular old
functions.
Static analysis tools are only worthwhile if their recommendations add
enough value to offset the cost of slogging through them -- in other
words, if the signal to noise ratio is high enough. CodeClimate hasn't
carried its own weight for a long time, and it's only gotten worse with
each recent update.
- Pass file and line number to reporters when present
- Show file and line number in the HTML reporter when present
- Visually separate adjacent errors in the HTML reporter
[#24901981]
* Extracted sub-matchers for the two major existing strategies
(matching all errors, and matching by type and/or message)
* Reduced the use of mutable state
This enables some useful simplifications at the cost of making it
impossible (for now) to expect a function to throw an error with a falsy
message.
[#20622765]
CodeClimate makes recommendations that, while helpful for production
code, can be harmful for test code. In particular, following its
recommendations would lead us to aggressively de-duplicate even small
amounts of test setup code. That can create unwanted coupling, obscure
the intent of the tests, and make it harder to maintain tests as their
setup needs diverge.
Follow-up to some recent commits that fixed issues around
jasmine.anything() matching. This simply adds some extra tests that
exercise usage of Symbols with jasmine.anything() and as Map keys.
The previous Map equality code was assuming that the set of keys would
be identical between the two Maps. This change adds insertion-order
tracking for each key with its corresponding key. If one of the two keys
is an asymmetric equality obj, the keys are eq()'d, and if it succeeds,
the corresponding values are compared. Otherwise, the "main" key is
looked up directly in the other object; this is to prevent
similar-looking obj keys with different obj identities from comparing
equal.
Fixes#1432.
The original asymmetric matcher code for Any did not work with symbols
since `symbolInstance instanceof Symbol` is actually `false` (but,
`symbolInstance.constructor` is `Symbol). This simply adds an extra
clause that explicitly checks for symbol (if available) like the other
primitive types.
Also added some missing specs for other types, like Map, Set, etc.
Fixes#1431.
We want to make sure that Travis checks against the latest version of
our dependencies, and also maintain compatibility across multiple
versions of Node.
Signed-off-by: Steve Gravrock <sgravrock@pivotal.io>
The old contributing docs had a misaligned nested unordered-list, which
resulted in it creating a new list instead of being nested under its
parent.
It also seems like it would be useful to have the "revert your changes"
prose as part of the "Before Committing" section, since otherwise people
may miss it and have to amend.
The previous code was using `== null` to handle both `null` and
`undefined`, resulting in a jshint warning. The conditional is meant to
check for non-primitive values, and it happens to be the case that a
falsey value in JS is always a primitive, or `null` or `undefined`.
clearTimeout was not correctly handling the case of clearing a
timeout that is also scheduled to run at the same tick.
This fix adds a deletedKeys array that is checked whilst we are
running the scheduled functions for the current clock tick. If
a function exists in deletedKeys it will not be ran. deletedKeys
is then reset to an empty array.
Note: afterEach() functions are still run, because skipping them is
highly likely to pollute specs that run after the failure.
[Finishes #92252330]
- Fixes#577
- Fixes#807
Besides surfacing the error in the hopefully-correct place, this also
prevents the queue runners for sibling suites from interleaving, which
in turn prevents all kinds of internal state corruption.
Signed-off-by: Gregg Van Hove <gvanhove@pivotal.io>
It's possible for async code to cause an error when Jasmine
doesn't have any listeners registered internally. This causes
Jasmine to crash (Node) or log to the console (browser)
because of trying to call the nonexistent handler. This change
doesn't fix the overall problem but it does ensure that the
original error is logged rather than Jasmine's internal error.
Made installation instructions more version-agnostic (using {#.#.#} instead of what was hard-coded to 2.0.0), corrected example HTML file (../jasmine-core/... instead of ../jasmine-2.0.0/... in the paths for the core files).
It was discovered that afterAll hooks run in the same order that you add them,
while afterEach hooks were running in reverse order. This commit makes their
order consistent, and adds regression tests.
Relevant issue - https://github.com/jasmine/jasmine/issues/1311
This allows custom equality testers to affect asymmetric matches.
This avoid suprises when combining addCustomEqualityTester with
objectContaining or arrayContaining.
Closes#1138
examples:
```JavaScript
var mySpy = jasmine.createSpyObj("mySpy", { getAge: 55, getLanguage: "JavaScrizzle" });
var age = mySpy.getAge();
expect(age).toEqual(55);
expect(mySpy.getAge).toHaveBeenCalled();
```
Also does:
Add "isObject_" method to utils to make it easier for "createSpy" to support an array or object of stubs
- Since we're stating that compass is a development dependency in our
gemspec, and we use bundle to install it, we should make sure that
grunt is using the correct (bundled) version of compass.
- This is especially important since many of the older versions of compass
are buggy (see https://github.com/gruntjs/grunt-contrib-compass/issues/204)
- If the spied method is not an own property of the object being spied
upon, the method is deleted from the object on teardown instead of
being set to the original implementation.
- #737
The `Suite` constructor function does not expect or use the its only `attrs`
parameter's `queueRunner` attribute, so setting it serves no purpose and
only clutters the code and makes it more difficult to understand.
This is a fix for issue #917.
It seems that 'symbols' was originally included as a performance optimization, to avoid repeated find() calls for '.jasmine-symbol-summary'. However this find() occasionally fails during initialize if the dom has not loaded completely.
This change will not affect performance, as symbols is still cached. However it improves upon the original code in that the find happens at a stage much later than initialize.
Rephrase confusing statement:
From:
If when you run ($ grunt)...you see that JSHint runs your system is ready.
To:
Now run ($ grunt)...if you see that JSHint runs, your system is ready.
The only difference between this commit and the previous is that I have
used a difference scheme for naming Jasmine CSS classes.
Instead of appending "_jasmine-css" to all Jasmine CSS selectors, I have
now preprended "jasmine-" instead.
As described in Issue Report 844...
https://github.com/jasmine/jasmine/issues/844
...style rules in the app-being-tested may incidentally affect elements
in the Jasmine HTML Report container, as long as there is a chance that
the app-being-tested has CSS style rules for classes (or IDs) that
Jasmine uses.
This fix attempts to bring Jasmine to a state where each and every class
it uses always ends with "_jasmine-css" which should be unique enough to
ensure that CSS in the app-being-tested won't affect the Jasmine report,
because no app-being-tested is ever likely to use classes that end with
"_jasmine-css"
I'll be surpised if this commit is good enough as it is now, on the
first attempt to fix#844, because of reasons I'll explain in either
the Issue or the Pull Request.
I removed the `.showDetails` and `.summaryMenuItem` styles from the Sass
file because I believe that no HTML elements with those classes will
ever be generated by Jasmine and that they are dead code that someone
forgot to remove.
This is my first contribution to the Jasmine project and so I might be
doing something wrong, but I believe just this one change will propagate
to all the generated code when it is built, and that I should not be
altering any other code in any other place to accomplish the change I
intend.
This is related to Jasmine Issue 847:
https://github.com/jasmine/jasmine/issues/847
# Problem
To bring this lib in using Sprockets, you must do this:
```javascript
//= require jasmine/lib/jasmine-core
```
Sprockets can read `bower.json` and, if `main` is explicitly stated in the file, you can do the much more future-proof and compact:
```javascript
//= require jasmine
```
# Solution
Explicitly specify it.
# Caveats
I am not super-versed in Bower or JS packaging, so this is proposed in the vein of "this fixes my problem and seems consistent with other JS libs I've looked at", but I'm open to other solutions.
- execute beforeAll/afterAll once per suite instead of once per child
when running focused specs/suites Fixes#773
- refuse to execute an order if it would cause a suite with a beforeAll
or afterAll to be re-entered after leaving once
- report children of an xdescribe similarly to how they would be
reported if they were themselves x'd out Fixes#774
- only process the tree once instead of figuring it out again at each
level
[finishes #87545620]
Fixes#776
- If the mock clock was installed in a beforeAll, the QueueRunner would use the mock clock for its own clock. If the mock clock was ticked more than the default timeout, async specs would timeout.
[fixes#783#792]
In GJS, jasmineGlobal was not getting set to the global object; when
importing jasmine.js in GJS, "this" resolves to the jasmine.js module
object, not the global object. Solve this specifically for GJS by
assuming that `window.toString === '[object GjsGlobal]'` only in GJS; if
this is the case, assign "window" to "jasmineGlobal".
Adding a "var" to the declaration of "getJasmineRequireObj" is also
necessary, or else "getJasmineRequireObj" won't be exported in the
Jasmine module.
See #751
SpiderMonkey complains about functions not always returning a value. In
most cases that is a conscious code style choice, so it is not fixed
here.
In one case (MockDate) the interpreter thought you could have fallen off
the end of a "switch" statement, although the number of arguments
prevented that. This was fixed by changing the last case to "default".
In another case (QueueRunner) the function really did return a value
sometimes and nothing other times, although as far as I could see, it
could only ever return "undefined". The function now explicitly only
returns no value.
See #751
- This requires passing if runnables are set to the Suite. Hopefully in
the future we will change how focused runnables and *Alls interact so
this is no longer necessary.
[#732]
IE 8 doesn't have Array.prototype.indexOf so this breaks there.
Reverting until we can figure out a better way to solve across all
supported browsers.
This reverts commit 663fbd0cdb.
For some reason, when you put this spec in a describe block, it causes
specs to hang on IE8. I tried to debug this for a while, and I have no
idea what is happening.
[#79533268]
- Behaves similarly to to specResults
- Since suites were stored in an object instead of an array and the
current interface exposes this object, we now must keep track of suites
twice in the reporter. We cannot just construct the object lazily,
because then the object will not update with new suite results
like it does currently (see JsApiReporterSpec:148).
[#79533268]
- Focused runnables now walk up the tree to unfocus the first focused
ancestor. Because of the way the tree is constructed, this makes sure
that each focused runnable has no focused ancestors.
[#78289686]
Add specs to test if issue #655 is present: the handler of an interval
cannot successfully clear the same interval that generated it's
invocation.
The most direct test consist in setting an interval with a handler that
calls clearInterval over that same interval and make the clock tick for
double of it's period. If the issue is present the interval's handler
will be called twice. If the issue is not present, the first invocation
of the handler will avoid a second one (because of the clearInterval).
Another test is included in order to check if recurring scheduled
functions are rescheduled before being called. Doing this in the reverse
order is the exact cause of the issue.
Required duplicating some of the logic for constructing a suite from
describe so that we could mark a suite as focused in fdescribe, but
otherwise this prevents focused tests from being run more than once.
[#73742944]
Yo, this probably isn't the best behavior. Rspec and Ginkgo definitely
do not exhibit this behavior when you nest focused runnables inside
other focused runnables. We thought fixing it, but it seems like a
nontrivial refactoring would be necessary to clean this up.
[#73742944]
- Fix bug where beforeAlls were being mutated in Suite#execute
- When Env.execute() receives a list of runnables, beforeAlls and
afterAlls are collected as beforeEachs and afterEachs. This allows
runnables to be specified in any order, regardless of if any of them
have before/afterAlls.
- Spec constructor takes a single function that returns both before and
afters, instead of two functions. This breaks the current interface
for constructing a Spec.
[#73742528]
We found that this test was always passing and had strange interactions
with the ordering of other specs. Rewriting it to explicitly finish the
afterAll after a specified interval makes it fail correctly.
[#73742528]
This makes the specs green and appears to work for most cases. I have a
number of concerns about the implementation and would appreciate
ideas/feedback.
- Suite#addExpecationResult infers if it is coming from an afterAll fn
based on if the first child of the suite is finished. This assumes
that the first child of the suite is a spec (this appears to be true
as long as there is at least one spec in the suite)
- Suites behave like unfinished specs. Because suites will propagate
expectation failures to their children suites, the afterAll
expectation reporting appears to work for suites without specs
unless you have:
1) An otherwise empty suite with an afterAll
2) An afterAll'd suite whose first suite is empty (or whose first
suite's first suite is empty (and so on))
- Changed afterAllError to afterAllEvent, so it can accommodate both
errors and expectation failures. The reporter now receives a string
instead of the actual error object. The loss of the object doesn't
affect our reporters, but may be a nice-to-have for other reporters/
the future.
- The gap between the expectations caught in Suite and QueueRunner (who
triggers reporting via an injected callback) is an array injected into
QR by the Suite. The array is then flushed at some point (currently
after the attempt… functions). This works, but is a bit goofy.
[#73741654]
As described in issue #655, the handler of an interval cannot
successfully clear the same interval that generated it's invocation.
Solve this issue by changing the order in which interval's handlers are
called and then rescheduled to: first reschedule it and then call it.
The actual order (call first then reschedule) produces that, during the
execution of the interval's handler, the handler is not registered as
a function to run after a timeout or interval ("scheduledFunctions"),
because it was previously unregistered. Consequently, if the handler
calls clearInterval, that function wont be able to find the handler and
remove it completely.
Previously, was only printing out the stack while the html reporter
would print out the message as well as the stack. Now they should be
more consistent.
As noticed by @despairblue in #638
Fixes incorrect use of signature args
- Not currently an issue, since always called with '2', but could break unexpectedly if argSlice is used without reading the body.
jasmine_selenium_runner on master now has a fix for printing circular
objects which is needed since Jasmine has some circular objects that are
included now that we return passedExpectations (but was a bug with
failedExpectations anyways)
- Having the 'empty' state for a spec result can be considered a
breaking change to the reporter interface
- Instead, we determine if a spec has no expectations using the added
key of 'passedExpectations' in combination of the 'failedExpectations'
to determine that there a spec is 'empty'
[fixes#73741032]
If an async test has timed-out, there could still be some expectations
that are scheduled to run after the fact in which case curerntSpec will
be null. Rather than the type error that would result, we now indicate
that 'expect' was used at an unexpected time.
This also helps cases where an 'expect' is being used at a top-level,
showing an error message in the console for this case as well.
[fixes#602]
- jasmine-core can now self test with the jasmine-npm
- Add node examples files
- Add node_boot.js for node environment
- Move jasmine-core npm packaging to .npmignore
- removing src_dir and src_files from jasmine.json b/c jasmine-npm does not support requiring source files automatically.
will print out.
Currently, jasmine's pretty printer will iterate over an entire array,
formatting every element recursively. For very large arrays, this can
crash the page, or cause a 'slow script' warning.
This commit exposes a 'MAX_PRETTY_PRINT_ARRAY_LENGTH' option. If an
array larger than this is encountered, recursion will stop and the
array length will be printed instead e.g. "Array[20000000]".
The 'MAX_PRETTY_PRINT_ARRAY_LENGTH' option defaults to 100. This is
length of array will not kill your browser, but will allow you
to see big arrays, if you can stomach the output.
- Add console.error to the HtmlReporter when there is a spec without any expectation
- Change the spec's link text and color to include a warning
- Create a status for specs to label them as "empty"
- console is not accessible to IE unless you have developer tools open,
so protect against that by mocking console.
[#59424794]
- Switch from showing error stack to showing message/description since only chrome/ff support stack
- Fallback to error.description if error.message is undefined
- Made exceptionList variable name consistent between both reporters
- Add 'afterAllException' hook to reporter dispatch, we might want to make this more generic in the future
- Add afterAllException function to HtmlReporter
[#66789174]
- QueueRunner now responsible for timing out async specs instead of
Spec
- Make sure only spec functions are timeoutable and not suites (due to
the refactor)
By deferring the evaluation of these messages, we can avoid the
expensive creation of them when in the majority use case (tests are
passing) they are not needed.
These failure messages were causing performance problems with larger
objects needed to be pretty printed as discussed in #520 and brought up
by @rdy.
[fixes#65925900][fixes#520]
Updating the passing and failing colors in HTML reporter to
help red/green color blind users using the colors suggested by @dleppik
Console reporter still likely needs similar changes but there's less
options there
[#463, #509, finishes #60613086]
All timeouts and intervals set during a tick were being scheduled to run
at delay + end-of-tick, instead of delay + time-of-outer-timeout.
Scheduled run-at times were shifted because currentTime was being
incremented before executing scheduled functions.
Additionally, the execute loop was iterating over a functions-to-run
array, created from scheduledFunctions before starting. Any changes to
scheduledFunctions were being ignored during the tick, and the next tick
would ignore any functions which should have been executed in the past.
The commit is a rewrite of DelayedFunctionScheduler, preserving the
public interface. Execution of scheduled functions updates currentTime
on each iteration, and each time takes the functions with the lowest
runAtMillis from the schedule, if they aren't higher than endTime.
When an async spec throws a (sync) exception for some reason, the
exception was correctly caught and reported by Jasmine but the timeout
timer continued to run in the background.
For instance, running the (rather stupid) example below would report
the exception immediately but would also make the process loop for 5s
(and report the exception depending on the reported being used).
describe('exception', function () {
it('is caught but timer continues to run', function (done) {
throw new Error('Oh no!');
});
});
This happened because the timout timer is set in Spec while the
"try... catch" block is in the queue runner. The "callDone" function
of "timeoutable" that resets the timer was thus not called.
The commit simply introduces a "try... catch" block within the
`timeoutable` function to ensure that "callDone" gets called even
when an exception is thrown.
- Passing in a 'negativeCompare' will cause that function to be used when it is a 'not' assertion
- Otherwise, the reversal of the compare's result will be used instead
[finishes #59703824]
- Users can no longer spelunk the spec tree from topSuite
- Users no longer have access to currentSuite/currentSpec
- Other miscellaneous (arguably less useful) methods have also been tucked
away into the closure, like suiteFactory
- Specs are passing by default unless told otherwise
- Getting the result.status of a spec before the spec has run is now
undefined instead of pending
[finishes #59422744]
An update of fb3e1acb09
ES5 strict mode does not promote an undefined 'this' to the global object. The only way to get the global object in strict mode is to say 'this' while in the global scope.
- Will replace rake core_specs.
- Remove obsolete dependencies & files -- most of these were for build tasks we
are no longer using. Notably, rspec and spec_helper were deleted.
On a very large test suite (8000 specs), a significant amount
of time is spent just drawing the spec dots. Some sort of
worse-than-linear artifact that summons itself only when you
have 8000 floated elements trying to hang out together.
This performance penalty is not seen with inline-block.
In Chrome 29:
Floated dots: 16.795s
Inline-block dots: 2.774s
Setting the dots to 'display: none;' takes about the same time
as the inline-block figure, so this is probably a low enough bound
(no need for chunked rendering or who knows what).
- Update compass configuration to build jasmine.scss into lib
- Remove src/html/jasmine.css (since jasmine.scss builds directly into
lib now)
- Bump lib/jasmine-core/jasmine.css to be latest from scss
Allows a user to specify their desired timeout interval for async specs
and change it on a per spec basis (for particularly slow specs, for example).
As pointed out by @Eric-Wright in #422. [finishes #55996798]
Change the 'this' user functions are called with to be an empty object
instead of the QueueRunner so that if the user puts properties on it,
they won't conflict.
Also, changes async specs to be called with a proper 'this', as pointed
out by @Eric-Wright in #419 and #420.
[finishes #56030080]
Spec still can't work for maximumSpecCallbackDepth = 1 until further
mock clock enhancements. Fixes the specs running twice issue caused by
the previous commit.
- DRYs up the browser checking code
- Adds in Firefox as another flag
- Makes it possible to do checks like `if (env.ieVersion)` to target all
IE versions
Jasmine spies now have a 'and' property which allows the user to
change the spy's execution strategy-- such as '.and.callReturn(4)'
and a 'calls' property which allows inspection of the calls a spy
has received.
* This is a breaking change *
There is a CallTracker that keeps track of all calls and arguments
and a SpyStrategy which determines what the spy should do when it
is called.
Still not green, but getting close. Summary of Older IE discrepancies:
- Older IE doesn't have apply/call on the timing functions
- Older IE doesn't allow applying falsy arguments
- Older IE doesn't allow setting onclick to undefined values
- Older IE doesn't have text property on dom nodes
Similar to the changes in Jasmine core and console, this gets the
HTML specs of Jasmine using j$ instead of jasmine so that they use
the source files instead of the built distribution
- included what was thrown for failure messages in toThrow and toThrowError
- fixed typo from 'execption' to 'exception' in toThrowError failure messages
- clarified failure messages in toThrowError to include specific error types
[Fixes#52680709]
Since this information is desired in ConsoleReporter, HtmlReporter,
and now JsApiReporter, the executionTime is passed through in
jasmineDone from Env instead of making each reporter compute it.
Fixes#30, [Finishes #45659879]
since the passed in errorType could be a custom user function,
we instead detect if its an instanceof Error by using a Surrogate
(inspired by Backbone's use of surrogacy)
In Safari Mac 6.0.4 (and possibly other versions), a new error does
not have the stack property. Throwing the error and then catching it
ensures that the stack property has the correct value.
This fix gets the specs to run green in Safari.
- It still supports no expected, which means that something was thrown
- Expected value is now tested via equality in order to pass
Adding toThrowError:
- toThrowError() passes if an Error type was thrown
- toThrowError(String) & toThrowError(RegExp) compare Expected to the Error message
- toThrowError(Error constructor) compares Expected to the constructor of what was thrown
- toThrowError(Error constructor, String) & toThrowError(Error constructor, RegExp) compares both the Error and the message
Also, equality now handles Errors, enforcing the message as part of the equality.
Canonical Jasmine version now lives in `package.json` (Node formatted) and is copied into Jasmine source (JavaScript and Ruby)
Jasmine distribution now has MIT license and Pivotal Labs copyright at the top of each distributed file.
If ommited or null, delay for refered methods will default to 0. This
will make setTimeout and setInterval methods to behave as expected by
[HTML5 specs](http://www.w3.org/TR/html51/webappapis.html#timers):
"Let timeout [delay] be the second argument to the method, or zero if the
argument was omitted."
This commit also fixes an issue with tick() being called without arguments,
that causes the scheduler to break and stop working after this call.
* canonical version number of jasmine-core is now is package.json
* `grunt buildDistribution` builds jasmine.js, jasmine-html.js, jasmine.css and outputs them to the dist dir
* `grunt buildStandaloneDist` builds the example spec runner files and compresses them to dist/jasmine-VERSION.zip
* `grunt compass` compiles jasmine.css
* jasmine.Env handling of version is backwards compatible, but uses the version string directly (and nicely deprecated)
* Ruby/thor tasks that did the above deleted
Move from embedded "fork" of jsHint to using grunt's jsHint module.
Cleaned ALL jsHint errors.
Added jasmine.util.isUndefined as alternative to extra careful protection against undefined clobbering
- xit
- it with a null function body ( it("should be pending");
- calling pending() inside a spec
- having a spec without any expectations
Pending and Filtered specs now call Reporter interface specStarted so that reporting acts as expected.
Pending and Filtered spec names are present and styled in the HTML reporter
Using xit used to disable a spec. Disabling is now just when a spec is filtered out at run time (usually w/ the reporter).
Suites are still disabled with xdescribe and means its specs are never executed.
* New reporter interface across all reporters
* xdescribe & xit now store disabled specs
* Rewrite of HtmlReporter to support new interface and be more performant
- HTMLReporters should be rewritten to make this sort of thing easier.
- Fix HTMLReporter try/catch switch
- We can't really call resultCallback & throw, so that's been reverted
for now.
- This is necessary for the user to see spec results fill-in
progressively.
- There is a slight performance loss. 250 - 500ms seems to deliver the
same amount of loss. This is still at parity with Jasmine 1.x
- setTimeout will clear stack, prevent overflow. We run this once every
thousand specs.
- Browser users will probably want a time-based clear rather than spec
count based clear, as a thousand tests is typically quite slow. The
reporter should provide this.
- THere seems to be a performance regression. Large test suites may
throw
- Regressions: Mock Clock won't install correctly, async specs are
temporarily not supported.
- Async spec runs/waits interface is gone. Blocks are gone.
- Move most global usage into jasmine.Env constructor.
- Remove optional 'Jasmine running' from HtmlReporter -- caused
NS_FACTORY_ERROR in firefox when tested
- consequently, Runner & Suite no longer have results.
- Results come back to reporters from Spec, we should not have a need to
walk them later via suite/runner (in fact, no reporter used results on
suite/runner -- only bad tests)
- Remove/clean up tests relying on #results
- Remove integration tests that duplicate already tested behavior
- Allow users to set the pretty-printer's recursion depth
- When pretty-printing objects, don't include inherited properties.
- Change toBeCloseTo matcher to be more consistent
- Added toBeNaN matcher
- Add checkbox to test runner which toggles catching of exceptions duri
- Add config option which stops jasmine from capturing exceptions in a
Currently, jasmine's pretty printer traverses objects
to 40 levels of nesting. If an object is more deeply
nested than that, an exception is thrown. I find that
after a few levels of nesting, the output becomes
difficult to read. The process of serializing such
deep objects also sometimes crashes the browser or
causes a 'slow script' warning.
This commit exposes a 'MAX_PRETTY_PRINT_DEPTH' option.
It also causes the pretty printer to skip over
parts of an object that are nested to deeply by simply
printing out 'Object' or 'Array', rather than throwing
an exception.
When making assertions about complex objects, Jasmine's
failure message are sometimes gigantic and difficult
to read because the string representation of an object
contains all of the methods and properties in its
prototype chain. This commit causes the pretty printer
to only display on object's own properties.
`example_source_tags` and `example_spec_tags` each returned what the other
should have returned. I noticed this bug because it made the comments in
SpecRunner.html about where to include spec and source files incongruous with
the example tags that followed.
The current code makes the assumption that if window is undefined it is
being run in an environment which supports the CommonJS Modules spec.
This is not the case when Jasmine is being run in rhino or SpiderMonkey
(smjs) without EnvJS.
The fix is simply to check that exports is an object.
Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
This blocks will be run even when a preceeding block sets the abort
flag. This is so that we can support afterEach calls running when the
spec fails due to a timeout.
This stops it throwing errors in IE and other browsers. I think the newer Firefox and Chrome versions are the only browsers to not die when running it.
- Allow users to set the pretty-printer's recursion depth
- When pretty-printing objects, don't include inherited properties.
- Change toBeCloseTo matcher to be more consistent
- Added toBeNaN matcher
- Add checkbox to test runner which toggles catching of exceptions duri
- Add config option which stops jasmine from capturing exceptions in a
Currently, jasmine's pretty printer traverses objects
to 40 levels of nesting. If an object is more deeply
nested than that, an exception is thrown. I find that
after a few levels of nesting, the output becomes
difficult to read. The process of serializing such
deep objects also sometimes crashes the browser or
causes a 'slow script' warning.
This commit exposes a 'MAX_PRETTY_PRINT_DEPTH' option.
It also causes the pretty printer to skip over
parts of an object that are nested to deeply by simply
printing out 'Object' or 'Array', rather than throwing
an exception.
When making assertions about complex objects, Jasmine's
failure message are sometimes gigantic and difficult
to read because the string representation of an object
contains all of the methods and properties in its
prototype chain. This commit causes the pretty printer
to only display on object's own properties.
This stops it throwing errors in IE and other browsers. I think the newer Firefox and Chrome versions are the only browsers to not die when running it.
This blocks will be run even when a preceeding block sets the abort
flag. This is so that we can support afterEach calls running when the
spec fails due to a timeout.
* bigfix/after_waitsFor:
Test that show that afterEach and after are not being called when a waitsFor times out.
Test that afterEach is called after a failing spec.
Consolidate all waitsFor specs in the same describe block.
The current code makes the assumption that if window is undefined it is
being run in an environment which supports the CommonJS Modules spec.
This is not the case when Jasmine is being run in rhino or SpiderMonkey
(smjs) without EnvJS.
The fix is simply to check that exports is an object.
Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
`example_source_tags` and `example_spec_tags` each returned what the other
should have returned. I noticed this bug because it made the comments in
SpecRunner.html about where to include spec and source files incongruous with
the example tags that followed.
Move Browser & Node specs to test against lib/jasmine.js instead of the separate source. Yes, this makes development a little harder but it's better to test that jasmine.js was built correctly.
We welcome your contributions! Thanks for helping make Jasmine a better project
for everyone. If you want to contribute but don't know what to work on,
[issues tagged help needed](https://github.com/issues?q=is%3Aopen+is%3Aissue+org%3Ajasmine+label%3A%22help+needed%22+)
should have enough detail to get started.
## Before Submitting a Pull Request
1. Ensure all specs are green in browsers *and* node.
* Use `npm test` to test in Node.
* Use `npm run serve` to test in browsers.
2. Fix any eslint or prettier errors reported at the end of `npm test`. Prettier
errors can be automatically fixed by running `npm run cleanup`.
3. Build `jasmine.js` with `npm run build` and run all specs again. This
ensures that your changes self-test well.
5. Revert your changes to `jasmine.js` and `jasmine-html.js`. When we accept
your pull request, we will generate these files as a separate commit and
merge the entire branch into master.
We only accept green pull requests. If you see that the CI build failed, please
fix it. Feel free to ask for help if you're stuck.
## Background
### Directory Structure
*`/src` contains all of the source files
*`/src/core` - generic source files
*`/src/html` - browser-specific files
*`/src/boot` - sources for boot files (see below)
*`/spec` contains all of the tests
* mirrors the source directory
* there are some additional files
*`/lib` contains the compiled copy of Jasmine. This is used to self-test and
distributed as the `jasmine-core` Node, and Ruby packages.
### Self-testing
Jasmine tests itself. The files in `lib` are loaded first, defining the reference `jasmine`. Then the files in `src` are loaded, defining the reference `jasmineUnderTest`. So there are two copies of the code loaded under test.
The tests should always use `jasmineUnderTest` to refer to the objects and functions that are being tested. But the tests can use functions on `jasmine` as needed. _Be careful how you structure any new test code_. Copy the patterns you see in the existing code - this ensures that the code you're testing is not leaking into the `jasmine` reference and vice-versa.
### `boot0.js` and `boot1.js`
These files file does all of the setup necessary for Jasmine to work in a
browser. They load all of the code, create an `Env`, attach the global
functions, and build the reporter. It also sets up the execution of the
`Env` - for browsers this is in `window.onload`. While the default in `lib`
is appropriate for browsers, projects may wish to customize this file.
### Compatibility
Jasmine runs in both Node and a variety of browsers. See the README for the
list of currently supported environments.
## Development
All source code belongs in `src/`. The `core/` directory contains the bulk of Jasmine's functionality. This code should remain browser- and environment-agnostic. If your feature or fix cannot be, as mentioned above, please degrade gracefully. Any code that depends on a browser (specifically, it expects `window` to be the global or `document` is present) should live in `src/html/`.
### Install Dev Dependencies
Jasmine Core relies on Node.js.
To install the Node dependencies, you will need Node.js and npm.
$ npm install
...will install all of the node modules locally. Now run
$ npm test
...you should see tests run and eslint checking formatting.
### How to write new Jasmine code
Or, How to make a successful pull request
* _Do not change the public interface_. Lots of projects depend on Jasmine and
if you aren't careful you'll break them.
* _Be environment agnostic_. Some people run their specs in browsers, others in
Node. Jasmine should support them all as much as possible.
* _Be browser agnostic_ - if you must rely on browser-specific functionality,
please write it in a way that degrades gracefully.
Thanks for taking the time to report a bug. Please follow these steps first.
## Troubleshooting
Please take the time to rule out issues with your code or third party libraries before filing a bug report. If you are reporting an error, try to determine whether the error is coming from Jasmine, another library, or your own code.
Check the [FAQ](https://jasmine.github.io/pages/faq.html) and any other relevant [documentation](https://jasmine.github.io/pages/docs_home.html) to see if your issue has already been addressed.
## Special troubleshooting steps for asynchronous scenarios
If the issue has to do with testing asynchronous code, please read the [async tutorial](https://jasmine.github.io/tutorials/async) and the [async section of the FAQ](https://jasmine.github.io/pages/faq.html#async). In particular, check for the following common errors:
* Are you trying to write a synchronous test for asynchronous code?
* Does the test signal completion before the code under test finishes?
* Do expectations run before the code that they're trying to verify?
## Try the latest version of Jasmine
If at all possible, upgrade to the latest versions of `jasmine-core` and any other relevant packages (e.g. `jasmine`, `jasmine-browser-runner`). If you can't do that, please check the [release notes](https://github.com/jasmine/jasmine/tree/main/release_notes) for all newer versions to make sure that the bug hasn't already been fixed.
## Explain how to reproduce the bug
**Working steps to reproduce are required for all bug reports.** Please help us help you by creating complete but minimal instructions for reproducing the bug.
The steps to reproduce could be:
* A code snippet that reproduces the problem when run by itself in a newly generated empty `jasmine` or `jasmine-browser-runner` project, or in the standalone distribution.
* A set of steps that reproduce the problem when followed exactly as they're written in an empty directory.
* A link to a Git repository or zip/tar file containing a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). This option is required for all bugs that can only be reproduced with third-party libraries, including Angular and Karma.
Please **test your steps** by starting with an empty directory and following them exactly as they're written. Bug reports with steps to reproduce that are unclear, don't work, or include an unreasonable amount of extraneous code will likely be closed.
- type:textarea
id:steps-to-reproduce
attributes:
label:Steps to Reproduce
validations:
required:true
- type:textarea
id:expected-behavior
attributes:
label:Expected Behavior
description:What do you think should have happened?
validations:
required:true
- type:textarea
id:actual-behavior
attributes:
label:Actual Behavior
description:What happened instead?
validations:
required:true
- type:textarea
id:possible-solution
attributes:
label:Possible Solution
description:This is optional, but if you have an idea for how to fix the bug we'd like to hear it.
- type:textarea
id:context
attributes:
label:Context
description:How has this issue affected you? What are you trying to accomplish? By providing context, you can help us come up with a solution that is most useful in the real world.
- type:input
id:jasmine-core-version
attributes:
label:jasmine-core version
validations:
required:true
- type:textarea
id:other-versions
attributes:
label:Versions of other relevant packages
placeholder:|
jasmine-browser-runner 1.2.0
fancy-reporter 132.4.8
- type:input
id:browser-or-node-version
attributes:
label:Node.js and/or browser version
placeholder:E.g. "node 16.2.0" or "Safari 15"
validations:
required:true
- type:input
id:os
attributes:
label:Operating System
placeholder:E.g. "Windows 10", "MacOS 12.5", "MCC Interim Linux 0.99.p8"
value:Thanks for taking the time to propose a new feature. Although Jasmine is mostly feature complete, we're always open to hearing new ideas.
- type:textarea
id:description
attributes:
label:Feature Proposal
validations:
required:true
- type:textarea
id:context
attributes:
label:Context
description:How would this feature be useful to you? What are you trying to accomplish? By providing context, you can help us come up with a solution that is most useful in the real world.
validations:
required:true
- type:textarea
id:example
attributes:
label:Example
description:If you're proposing a new API or something similar, please show an example of how it would be used.
render:JavaScript
- type:textarea
id:other-info
attributes:
label:Other Information
description:Anything else that you think would be helpful.
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at jasmine-maintainers@googlegroups.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
1. Get the latest release from the [downloads page](http://github.com/pivotal/jasmine/downloads).
2. Open `SpecRunner.html` in your favorite browser.
For running within a Ruby environment, including automated execution with Selenium, please use
the [jasmine gem](http://github.com/pivotal/jasmine-gem).
### Which Release Should I Use?
Please use the latest version unless you have a good reason not to. Some of this documentation may not be applicable to older versions. Please see [[Release Notes]](http://wiki.github.com/pivotal/jasmine/release-notes) for change information.
Why Another JavaScript TDD/BDD Framework?
-----------
There are some great JavaScript testing frameworks out there already, so why did we write another?
None of the existing frameworks quite worked the way we wanted. Many only work from within a browser. Most don't support testing asynchronous code like event callbacks. Some have syntax that's hard for JS developers or IDEs to understand.
So we decided to start from scratch.
Enter Jasmine
------------
Jasmine is our dream JavaScript testing framework. It's heavily influenced by, and borrows the best parts of, ScrewUnit, JSSpec, [JSpec](http://github.com/visionmedia/jspec/tree/master), and of course RSpec.
Jasmine was designed with a few principles in mind. We believe that a good JavaScript testing framework:
* should not be tied to any browser, framework, platform, or host language.
* should have idiomatic and unsurprising syntax.
* should work anywhere JavaScript can run, including browsers, servers, phones, etc.
* shouldn't intrude in your application's territory (e.g. by cluttering the global namespace).
* should play well with IDEs (e.g. test code should pass static analysis).
Some of our goals while writing Jasmine:
* it should encourage good testing practices.
* it should integrate easily with continuous build systems.
* it should be simple to get started with.
The result is Jasmine, and we love test-driving our code with it. Enjoy.
How To
------
There is a simple example of how to use Jasmine in the /example directory. But here's more information.
### Specs
Each spec is, naturally, a JavaScript function. You tell Jasmine about this spec with a call to `it()` with a string and the function. The string is a description that will be helpful to you when reading a report.
it('should be a test', function () {
var foo = 0;
foo++;
});
### Expectations
Within your spec you will want to express expectations about the behavior of your application code. These are made with the `expect()` function and expectation matchers, like this:
it('should be a test', function () {
var foo = 0; // set up the world
foo++; // call your application code
expect(foo).toEqual(1); // passes because foo == 1
});
Results of the expectations are logged for later for reporting.
#### Expectation Matchers
Jasmine has several built-in matchers. Here are a few:
>`expect(x).toEqual(y);` compares objects or primitives `x` and `y` and passes if they are equivalent
>
>`expect(x).toMatch(pattern);` compares `x` to string or regular expression `pattern` and passes if they match
>
>`expect(x).toBeDefined();` passes if `x` is not `undefined`
>
>`expect(x).toBeNull();` passes if `x` is `null`
>
>`expect(x).toBeTruthy();` passes if `x` evaluates to true
>
>`expect(x).toBeFalsy();` passes if `x` evaluates to false
>
>`expect(x).toContain(y);` passes if array or string `x` contains `y`
Every matcher's criteria can be inverted by prepending `.not`:
>`expect(x).not.toEqual(y);` compares objects or primitives `x` and `y` and passes if they are *not* equivalent
#### Writing New Matchers
We've provided a small set of matchers that cover many common situations. However, we recommend that you write custom matchers when you want to assert a more specific sort of expectation. Custom matchers help to document the intent of your specs, and can help to remove code duplication in your specs.
It's extremely easy to create new matchers for your app. A matcher function receives the actual value as `this.actual`, and zero or more arguments may be passed in the function call. The function should return `true` if the actual value passes the matcher's requirements, and `false` if it does not.
Here's the definition of `toBeLessThan()`:
toBeLessThan: function(expected) {
return this.actual < expected;
};
To add the matcher to your suite, call `this.addMatchers()` from within a `before` or `it` block. Call it with an object mapping matcher name to function:
Specs are grouped in Suites. Suites are defined using the global `describe()` function:
describe('One suite', function () {
it('has a test', function () {
...
});
it('has another test', function () {
...
});
});
The Suite name is so that reporting is more descriptive.
Suites are executed in the order in which `describe()` calls are made, usually in the order in which their script files are included. Additionally, specs within a suite share a functional scope. So you may declare variables inside a describe block and they are accessible from within your specs. For example:
describe('A suite with some variables', function () {
var bar = 0
it('has a test', function () {
bar++;
expect(bar).toEqual(1);
});
it('has another test', function () {
bar++;
expect(bar).toEqual(2);
});
});
#### beforeEach
A suite can have a beforeEach declaration. It takes a function that is run before each spec. For example:
describe('some suite', function () {
var suiteWideFoo;
beforeEach(function () {
suiteWideFoo = 1;
});
it('should equal bar', function () {
expect(suiteWideFoo).toEqual(1);
});
});
A runner can also have beforeEach declarations. Runner beforeEach functions are executed before every spec in all suites, and execute BEFORE suite beforeEach functions. For example:
Similarly, there is an afterEach declaration. It takes a function that is run after each spec. For example:
describe('some suite', function () {
var suiteWideFoo;
afterEach(function () {
suiteWideFoo = 0;
});
it('should equal 1', function () {
expect(suiteWideFoo).toEqual(1);
});
it('should equal 0 after', function () {
expect(suiteWideFoo).toEqual(0);
};
});
A runner can also have an afterEach declarations. Runner afterEach functions are executed after every spec in all suites, and execute AFTER suite afterEach functions. For example:
A spec may ask Jasmine to execute some code after the spec has finished running; the code will run whether the spec finishes successfully or not. Multiple after functions may be given.
There are spy-specfic matchers that are very handy.
`expect(x).toHaveBeenCalled()` passes if `x` is a spy and was called
`expect(x).toHaveBeenCalledWith(arguments)` passes if `x` is a spy and was called with the specified arguments
`expect(x).not.toHaveBeenCalled()` passes if `x` is a spy and was not called
`expect(x).not.toHaveBeenCalledWith(arguments)` passes if `x` is a spy and was not called with the specified arguments
The old matchers `wasCalled`, `wasNotCalled`, `wasCalledWith`, and `wasNotCalledWith` have been deprecated and will be removed in a future release. Please change your specs to use `toHaveBeenCalled`, `not.toHaveBeenCalled`, `toHaveBeenCalledWith`, and `not.toHaveBeenCalledWith` respectively.
Spies can be trained to respond in a variety of ways when invoked:
`spyOn(x, 'method').andCallThrough()`: spies on AND calls the original function spied on
`spyOn(x, 'method').andReturn(arguments)`: returns passed arguments when spy is called
`spyOn(x, 'method').andThrow(exception)`: throws passed exception when spy is called
`spyOn(x, 'method').andCallFake(function)`: calls passed function when spy is called
Spies have some useful properties:
`callCount`: returns number of times spy was called
`mostRecentCall.args`: returns argument array from last call to spy.
`argsForCall[i]` returns arguments array for call `i` to spy.
Spies are automatically removed after each spec. They may be set in the beforeEach function.
### Disabling Tests & Suites
Specs may be disabled by calling `xit()` instead of `it()`. Suites may be disabled by calling `xdescribe()` instead of `describe()`. A simple find/replace in your editor of choice will allow you to run a subset of your specs.
### Asynchronous Specs
You may be thinking, "That's all very nice, but what's this about asynchronous tests?"
Well, say you need to make a call that is asynchronous - an AJAX API, event callback, or some other JavaScript library. That is, the call returns immediately, yet you want to make expectations 'at some point in the future' after some magic happens in the background.
Jasmine allows you to do this with `runs()` and `waits()` blocks.
`runs()` blocks by themselves simply run as if they were called directly. The following snippets of code should provide similar results:
it('should be a test', function () {
var foo = 0
foo++;
expect(foo).toEqual(1);
});
and
it('should be a test', function () {
runs( function () {
var foo = 0
foo++;
expect(foo).toEqual(1);
});
});
multiple `runs()` blocks in a spec will run serially. For example,
it('should be a test', function () {
runs( function () {
var foo = 0
foo++;
expect(foo).toEqual(1);
});
runs( function () {
var bar = 0
bar++;
expect(bar).toEqual(1);
});
});
`runs()` blocks share functional scope -- `this` properties will be common to all blocks, but declared `var`'s will not!
it('should be a test', function () {
runs( function () {
this.foo = 0
this.foo++;
var bar = 0;
bar++;
expect(this.foo).toEqual(1);
expect(bar).toEqual(1);
});
runs( function () {
this.foo++;
var bar = 0
bar++;
expect(foo).toEqual(2);
expect(bar).toEqual(1);
});
});
`runs()` blocks exist so you can test asynchronous processes. The function `waits()` works with `runs()` to provide a naive
timeout before the next block is run. You supply a time to wait before the next `runs()` function is executed. For example:
it('should be a test', function () {
runs(function () {
this.foo = 0;
var that = this;
setTimeout(function () {
that.foo++;
}, 250);
});
runs(function () {
this.expects(this.foo).toEqual(0);
});
waits(500);
runs(function () {
this.expects(this.foo).toEqual(1);
});
});
What's happening here?
* The first call to `runs()` sets call for 1/4 of a second in the future that increments `this.foo`.
* The second `runs()` is executed immediately and then verifies that `this.foo` was indeed initialized to zero in the previous `runs()`.
* Then we wait for half a second.
* Then the last call to `runs()` expects that `this.foo` was incremented by the `setTimeout`.
## Support
We now have a Google Group for support & discussion.
We welcome your contributions! Jasmine is currently maintained by Davis Frank ([infews](http://github.com/infews)), Rajan Agaskar ([ragaskar](http://github.com/ragaskar)), and Christian Williams ([Xian](http://github.com/Xian)). You can help us by removing all other recipients from your pull request.
## Acknowledgments
* A big shout out to the various JavaScript test framework authors, especially TJ for [JSpec](http://github.com/visionmedia/jspec/tree/master) - we played with it a bit before deciding that we really needed to roll our own.
* Thanks to Pivot [Jessica Miller](http://www.jessicamillerworks.com/) for our fancy pass/fail/pending icons
* Huge contributions have been made by [Adam Abrons](mailto:adam@pivotallabs.com), [Lee Byrd](mailto:lee@pivotallabs.com), [Erik Hanson](mailto:erik@pivotallabs.com), [Carl Jackson](mailto:carl@pivotallabs.com), and many other Pivots.
Jasmine is a Behavior Driven Development testing framework for JavaScript. It does not rely on browsers, DOM, or any JavaScript framework. Thus it's suited for websites, [Node.js](http://nodejs.org) projects, or anywhere that JavaScript can run.
Upgrading from Jasmine 4.x? Check out the [upgrade guide](https://jasmine.github.io/tutorials/upgrading_to_Jasmine_5.0).
## Contributing
Please read the [contributors' guide](https://github.com/jasmine/jasmine/blob/main/.github/CONTRIBUTING.md).
## Installation
There are several different ways to install Jasmine, depending on your
environment and how you'd like to use it. See the [Getting Started page](https://jasmine.github.io/pages/getting_started.html)
for details.
## Usage
See the [documentation site](https://jasmine.github.io/pages/docs_home.html),
particularly the [Your First Suite tutorial](https://jasmine.github.io/tutorials/your_first_suite)
for information on writing specs, and [the FAQ](https://jasmine.github.io/pages/faq.html).
## Supported environments
Jasmine tests itself across popular browsers (Safari, Chrome, Firefox, and
For evergreen browsers, each version of Jasmine is tested against the version of the browser that is available to us
at the time of release. Other browsers, as well as older & newer versions of some supported browsers, are likely to work.
However, Jasmine isn't tested against them and they aren't actively supported.
\* Supported on a best-effort basis. Support for these versions may be dropped
if it becomes impractical, and bugs affecting only these versions may not be
treated as release blockers.
To find out what environments work with a particular Jasmine release, see the [release notes](https://github.com/jasmine/jasmine/tree/main/release_notes).
## Maintainers
* [Gwendolyn Van Hove](mailto:gwen@slackersoft.net)
Follow the instructions in `CONTRIBUTING.md` during development.
### Git Rules
Please attempt to keep commits to `main` small, but cohesive. If a feature is contained in a bunch of small commits (e.g., it has several wip commits or small work), please squash them when pushing to `main`.
### Version
We attempt to stick to [Semantic Versioning](http://semver.org/). Most of the time, development should be against a new minor version - fixing bugs and adding new features that are backwards compatible.
The current version lives in the file `/package.json`. This version will be
copied to `jasmine.js` when the distribution is built. When releasing a new
version, update `package.json` with the new version and `npm run build` to
update the gem version number.
Note that Jasmine should only use the "patch" version number if the new release
contains only bug fixes.
When `jasmine-core` revs its major or minor version, the `jasmine` NPM package
should also rev to that version.
## Release
When ready to release - specs are all green and the stories are done:
1. Update the release notes in `release_notes` - use the Anchorman gem to generate the markdown file and edit accordingly. Include a list of supported environments.
1. Update the version in `package.json`
1. Run `npm run build`.
### Commit and push core changes
1. Commit release notes and version changes (jasmine.js, package.json)
2. Push
3. Tag the release and push the tag.
4. Wait for Circle CI to go green
### Build standalone distribution
1. Build the standalone distribution with `npm run buildStandaloneDist`
1. This will generate `dist/jasmine-standalone-<version>.zip`, which you will upload later (see "Finally" below).
### Release the core NPM module
1.`npm login` to save your credentials locally
2.`npm publish .` to publish what's in `package.json`
### Release the docs
Probably only need to do this when releasing a minor version, and not a patch
version. See [the README file in the docs repo](https://github.com/jasmine/jasmine.github.io/blob/master/README.md)
for instructions.
### Release the `jasmine` NPM package
See <https://github.com/jasmine/jasmine-npm/blob/main/RELEASE.md>.
### Publish the GitHub release
1. Visit the releases page and find the tag just published.
2. Paste in a link to the correct release notes for this release.
* Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.
*/
constjasmine=jasmineRequire.core(jasmineRequire),
global=jasmine.getGlobal();
global.jasmine=jasmine;
/**
* Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference.
*/
jasmineRequire.html(jasmine);
/**
* Create the Jasmine environment. This is used to run all specs in a project.
*/
constenv=jasmine.getEnv();
/**
* ## The Global Interface
*
* Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged.
* Add all of the Jasmine global/public interface to the global scope, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
* The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
* Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded.
- Support for focused specs via `fit` and `fdescribe`
- Support for `beforeAll` and `afterAll`
- Support for an explicit `fail` function, both in synchronous and asynchronous specs
- Allow custom timeout for `beforeEach`, `afterEach`, `beforeAll`, `afterAll` and `it`
- Spies now track return values
- Specs can now specify their own timeouts
- Testing in Node.js via the official Jasmine Node Module
- Spec results now have `suiteResults` method that behaves similarly to to `specResults`
- HtmlReporter shows error alerts for afterAllExceptions
## Bugs
- CI now works for IE8 (this was releated to `ConsoleReporter` below)
- Detect global object properly when getting the jasmine require obj
- Fixes Issue #[569][issue_569] - [Tracker Story #73684570](http://www.pivotaltracker.com/story/73684570)
## Deprecations
### `ConsoleReporter` as part of Jasmine core
The Console Reporter exists nearly entirely for the old manner of running Jasmine's own specs in node.js. As we are now supporting node.js officially, this reporter code no longer needs to be in this repo and instead will be in the Jasmine npm.
For now you will see a deprecation message. It will be removed entirely in Jasmine 3.0.
## Documentation
- Release Notes from previous releases now live at [Jasmine's GitHub release page][releases]. See Tracker Story #[54582902][tracker_1]
- Better instructions for releasing new documentation
-`toContain` works with array-like objects (Arguments, HTMLCollections, etc)
- Merges #[699][issue_699] from @charleshansen
- Fixed isPendingSpecException test title
- Merges #[691][issue_691] from @ertrzyiks
- Fixed an issue with example code in the npm
- Merges #[686][issue_686] from @akoptsov
- When the Jasmine clock is installed and date is mocked, `new Date() instanceof Date` should equal `true` Issue #[678][issue_678] & Issue #[679][issue_679] from @chernetsov
- Support for an explicit `fail` function, both in synchronous and asynchronous specs
- Fixes Issue #[567][issue_567], Issue #[568][issue_568], and Issue #[563][issue_563]
- Allow custom timeout for `beforeEach`, `afterEach`, `beforeAll`, `afterAll` and `it`
- Fixes Issue #[483][issue_483] - specs can now specify their own timeouts
- Spies can track return values
- Fixes Issue #[660][issue_660], Merged Issue #[669][issue_669] from @mkhanal
- Interval handlers can now clear their interval
- Fixes Issue #[655][issue_655] Merged Issue #[658][issue_658] from @tgirardi
- Updated to the latest `json2.js`
- Merges #[616][issue_616] from @apaladox2015
------
_Release Notes generated with [Anchorman](http://github.com/infews/anchorman)_
* When stop on failure is enabled, skip subsequent it() and beforeEach(). Note: afterEach() functions are still run, because skipping them is highly likely to pollute specs that run after the failure.
* Report the random seed at the beginning and end of execution. This allows reporters to provide the seed to the user even in cases where Jasmine crashes before completing.
- Merges [#1348](https://github.com/jasmine/jasmine/issues/1348) from @sgravrock
* Add ES6 map support to Jasmine
- Merges [#1340](https://github.com/jasmine/jasmine/issues/1340) from @rmehlinger
The [`introduction.js`][intro] page covers the current syntax, highlighting the changes. Here are the known interface changes that are not backwards compatible with 1.x.
* New syntax for asynchronous specs
* New syntax for spies
* New interface for reporters
* Better Equality testing
* Replaced custom matchers for ease of use
* Change to `toThrow` matcher
* Clock now remains installed when a spec finishes
* More Jasmine internal variables/functions have been moved into closures
### New syntax for asynchronous specs
Similar to [Mocha][mocha], Jasmine `before`s, `spec`s, and `after`s can take an optional `done` callback in order to force asynchronous tests. The next function, whether it's a `before`, `spec` or `after`, will wait until this function is called or until a timeout is reached.
### New syntax for spies
Spies have a slightly modified syntax. The idea came from a desire to preserve any of the properties on a spied-upon function and some better testing patterns.
### New interface for reporters
The reporter interface has been **replaced**. The callbacks are different and more consistent. The objects passed in should only provide what is needed to report results. This enforces an interface to result data so custom reporters will be less coupled to the Jasmine implementation. The Jasmine reporter API now includes a slot for a `timer` object.
### Better Equality testing
We removed the previous equality code and are now using new code for testing equality. We started with [Underscore.js][underscore]'s `isEqual`, refactored a bit and added some additional tests.
### Replaced custom matchers for ease of use
The interface for adding custom matchers has been **replaced**. It has always been possible to add custom matchers, but the API was barely documented and difficult to test. We've changed how matchers are added and tested. Jasmine adds its own matchers by the same mechanism that custom matchers use. Dogfooding FTW.
### Change to `toThrow` matcher
We've changed the behavior of the `toThrow` matcher, moving some functionality to the `toThrowError` matcher. This should allow more of the requested use cases.
### Clock now remains installed when a spec finishes
After installing the Jasmine Clock, it will stay installed until `uninstall` is called -- clearing up any ambiguity for when those timing functions will revert to using the global clock object.
## More Jasmine internal variables/functions have been moved into closures
Certain variables/functions like a function to get the next spec id have been moved into closures, making the Jasmine interface cleaner.
## Other Changes
* Massive refactoring and better testing
* Environment setup now in `boot.js`
* Development and Build moved to Grunt
* Changes to how Jasmine is loaded
* Changes to how Jasmine is tested
* Better node.js support
* Better Continuous Integration Environment at Travis
* Support matrix updated
* Removed JsDoc Pages
* Adding Code Climate for JavaScript
## Massive refactoring and better testing
This is the biggest set of changes. We've touched nearly every file and every object. We've merged objects together and factored out code. We styled the code more consistently. We've improved nearly every test.
In general, Jasmine is made of smaller, more-loosely-coupled objects, unit-tested with explicit dependencies injected. This made tests easier to read, write, and maintain. We know this has made Jasmine development easier for the core team. We expect (and hope) this makes it easier for the community to extend Jasmine and provide pull requests that make more sense the first time out.
## Environment setup now in `boot.js`
Instantiation and setup of the Jasmine environment, including building reporters, exposing the "global" functions, and executing tests has moved into its own file: `boot.js`. This should make it easier to add custom reporters, configure some objects, or just in general change how you use Jasmine from the outside.
For example, during development, Jasmine uses its own `devboot.js` to load itself twice - once from `jasmine.js` and once from the source directories.
## Development and Build moved to Grunt
We've moved away from Ruby and embraced [Node.js][node] and [Grunt.js][grunt] for the various command line tasks during development. Yes, it's a just a different set of dependencies. But it's less code for the team to maintain - it turns out that JavaScript tools are pretty good at building JavaScript projects. This will make it easier for the community to make sure contributions work in browsers and in Node.js before submitting Pull Requests. There is more detail in the [Contributor's Guide][contrib].
## Changes to how Jasmine is loaded
We did not want to add new run-time dependencies, yet we needed to be cleaner when loading Jasmine. So we wrote a custom "require" scheme that works in Node.js and in browsers. This only affects pull requests which add files - please be careful in these cases. Again, the [Contributor's Guide][contrib] should help.
## Changes to how Jasmine is tested with Jasmine
Writing a custom require system helped enforce self-testing - the built `jasmine.js` testing Jasmine from the source directories. Overall this has improved the stability of the code. When you look at Jasmine's tests, you'll see both `jasmine` and `j$` used. The former, `jasmine`, will always be used to test the code from source, which is loaded into the reference `j$`. Please adhere to this pattern when writing tests for contributions.
## Better node.js support
`Node.js` is now officially a first-class citizen. For a long time we've made sure tests were green in Node before releasing. But it is now officially part of Jasmine's CI build at [Travis][travis]. For the curious, the [`node_suite.js`][node_suite], is essentially a `boot.js` for Node. An official `npm` is coming.
## Better Continuous Integration Environment at Travis
The [CI build at Travis][travis_jasmine] now runs the core specs in a build matrix across browsers. It's far from complete on the operating system matrix, but you will see that Jasmine runs against: Firefox, Chrome, Safari 5, Safari 6, [Phantom.js][phantom], [Node.js][node], and IE versions 8, 9, and 10. Big thanks to [SauceLabs][sauce] for their support of open source projects. We will happily take pull requests for additional OS/Browser combos within the matrix.
## Support Matrix Updated
We're dropping support for IE < 8. [Jasmine 1.x][jasmine_downloads] remains for projects that need to support older browsers.
## Removed JsDoc Pages
Comments in code are lies waiting to happen. Jasmine's JsDoc comments were no exception. The comments were out of date, the generated pages were even more out of date, and frankly they were not helpful. So they're gone.
Last year saw the posting of the [`introduction.js`][intro] page to document the real, practical interface for projects to use. This page has received a lot of positive feedback so expect more pages like this one.
## Adding Code Climate for JavaScript
We are running Code Climate for Jasmine. We have some work to do here but it's helping us easily find code hotspots.
## Pull Requests and Issues
The following Pull Requests were merged:
* ObjectContaining wrong filed value error message #[394](https://github.com/pivotal/jasmine/issues/394) from albertandrejev
* Removed unnecessary parameter from `suiteFactory()` call #[397](https://github.com/pivotal/jasmine/issues/397) from valera-rozuvan
*`jasmine.Any` supports `Boolean` #[392](https://github.com/pivotal/jasmine/issues/392) from albertandrejev
* Reporters get execution time #[30](https://github.com/pivotal/jasmine/issues/30)
* Removed deprecated `jasmine.Matchers.pp` #[363](https://github.com/pivotal/jasmine/issues/363) from robinboehm
* Fix for Clock ticking to default to 0 #[340](https://github.com/pivotal/jasmine/issues/340) from Caio Cunha
* Whitespace failures should be easier to understand #[332](https://github.com/pivotal/jasmine/issues/332) from bjornblomqvist
* Fix for more markdown-y image for Build status #[329](https://github.com/pivotal/jasmine/issues/329) from sunliwen
* UTF-8 encoding fixes #[333](https://github.com/pivotal/jasmine/issues/333) from bjornblomqvist
* Replaced deprecated octal literal with hexadecimal from kris7t
* Make getGlobal() work in strict mode from metaweta
* Clears timeout timer even when async spec throws an exception from tidoust
* Timeouts scheduled within a delayed function are correctly scheduled and executed from maciej-filip-sz
### Bug Fixes
* Improved the performance of the HTML output with a CSS change #[428](https://github.com/pivotal/jasmine/issues/428) - Thanks @tjgrathwell
* Removed an accidental global pollution of `j$` as a reference to Jasmine. Thanks to Morten Maxild from the mailing list
* There is now a consistent `this` between `beforeEach`, `it` and `afterEach` for a spec
* A spy's strategy now has properties `returnValue` and `throwError` because they are better names
* Make it easy to copy the title of failing specs from the HTML output
* Don't add periods to the full name of a spec fix #[427](https://github.com/pivotal/jasmine/issues/427)
* Allow Env to take optional spec/suite ids when asked to `execute`
* [Mock clock now less intrusive, replacing global timer functions only when clock is installed](http://www.pivotaltracker.com/story/54168708)
* Restore custom failure messages for `toHaveBeenCalledWith`
* Jasmine global object has a addCustomEqualityTester and addMatchers (no longer directly on global)
* Fixed a global leak of `timer`
* Remove currentRunner from Env (users can use topSuite from Env instead)
* [Specs without expectations are now considered passing](http://www.pivotaltracker.com/story/59422744)
* Improve error message when a spec does not call the async callback within the default time interval
* Allow passing a negativeCompare in a custom matcher for more custom implementations when `.not` is called
* Update favicon to be higher resolution
* Make all async functions be subject to the timeout
There were several other pull requests that either had already been fixed, or were good starting points for the various changes above. Thank you for all of the hard work to keep Jasmine awesome.
## Other Bugs and Features
There were a few small changes and fixes that didn't fit into any of the above categories:
* HTML Reporter refactored for simplicity and performance
* Default character encoding on the HTML runner page is UTF-8
* [Escape special regex characters from the spec param](http://www.pivotaltracker.com/story/52731407)
* Favicon returns
* [Clock supports `eval`'d strings as functions](http://www.pivotaltracker.com/story/40853563)
* There should always be stack traces on failures
* Removed references to unused `jasmine.VERBOSE`
* Removed references to unused `jasmine.XmlHttpRequest`
This is a maintenance release of Jasmine with a number of new features and fixes
### Highlights
* The output of toHaveBeenCalledWith should now be more readable
This breaks each call out onto its own line, so that it's much easier to
see where each call starts and how they differ. E.g. previously the output
would be:
Expected spy foo to have been called with [ 'bar', 'baz', 'qux' ] but actual calls were [ [ 42, 'wibble' ], [ 'bar' 'qux' ], [ 'grault '] ]
Now it's:
Expected spy foo to have been called with:
[ 'bar', 'baz', 'qux' ]
but actual calls were:
[ 42, 'wibble' ],
[ 'bar' 'qux' ],
[ 'grault '].
* Add new spy strategies to resolve and reject Promises `resolveTo` and `rejectWith`
* Add the ability to have custom async matchers
### Internal notes
* Stop testing against PhantomJS
* PhantomJS is at end of life, and the last version of Selenium that supported it was 3.6.0, released almost three years ago. We can't test Jasmine against PhantomJS without pinning key pieces of the project to increasingly outdated versions of key libraries.
* Fail Jasmine's CI build if the promise returned from `jasmineBrowser.runSpecs` is rejected
* A bunch of other rejiggering of the Travis-CI builds to make them easier to work with
* Also released a new browser runner that is being used by Jasmine
* See [jasmine-browser-runner](https://github.com/jasmine/jasmine-browser)
* This is a first pass at getting this to work for other projects as well. Please try it out and let us know what isn't working for you.
* add prettier and eslint
## All Changes
* Adds new configuration option to failSpecWithNoExpectations that will report specs without expectations as failures if enabled
* Merges [#1743](https://github.com/jasmine/jasmine/issues/1743) from @dtychshenko
* Merges [#1918](https://github.com/jasmine/jasmine/pull/1918) from @eltociear
* Specify files to include in the NPM package rather than files to exclude
* Added test coverage for MatchersUtil#equals with typed arrays
* Removed checks for typed array support in the test suite
* All supported browsers have all typed arrays except for Uint8ClampedArray,
BigInt64Array, and BigUint64Array.
* Fixed test failures on IE 10
* Test matrix updates
* Added Node 16
* Added Safari 14
* Added Firefox 78 (closest match to current ESR)
* Removed Safari 10-12 to speed up CI. The newer and older versions we test
provide a good measure of safety.
* Replaced node-sass dev dependency that isn't compatible with Node 16
* Removed unused dev dependencies
* Migrated CI from Travis to Circle
* Compensate for clock jitter in specs
## Supported environments
jasmine-core 3.8.0 has been tested in the following environments.
| Environment | Supported versions |
|-------------------|--------------------|
| Node | 10, 12, 14, 16 |
| Safari | 8-14 |
| Chrome | 91 |
| Firefox | 89, 68, 78 |
| Edge | 91 |
| Internet Explorer | 10, 11 |
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.