What is “assert” in JavaScript? - javascript

What does assert mean in JavaScript?
I’ve seen something like:
assert(function1() && function2() && function3(), "some text");
And would like to know what the method assert() does.

There is no standard assert in JavaScript itself. Perhaps you're using some library that provides one; for instance, if you're using Node.js, perhaps you're using the assertion module. (Browsers and other environments that offer a console implementing the Console API provide console.assert.)
The usual meaning of an assert function is to throw an error if the expression passed into the function is false; this is part of the general concept of assertion checking. Usually assertions (as they're called) are used only in "testing" or "debug" builds and stripped out of production code.
Suppose you had a function that was supposed to always accept a string. You'd want to know if someone called that function with something that wasn't a string (without having a type checking layer like TypeScript or Flow). So you might do:
assert(typeof argumentName === "string");
...where assert would throw an error if the condition were false.
A very simple version would look like this:
function assert(condition, message) {
if (!condition) {
throw message || "Assertion failed";
}
}
Better yet, make use of the Error object, which has the advantage of collecting a stack trace and such:
function assert(condition, message) {
if (!condition) {
throw new Error(message || "Assertion failed");
}
}

If using a modern browser or nodejs, you can use console.assert(expression, object).
For more information:
Chrome API Reference
Firefox Web Console
Firebug Console API
IE Console API
Opera Dragonfly
Nodejs Console API

The other answers are good: there isn't an assert function built into ECMAScript5 (e.g. JavaScript that works basically everywhere) but some browsers give it to you or have add-ons that provide that functionality. While it's probably best to use a well-established / popular / maintained library for this, for academic purposes a "poor man's assert" function might look something like this:
const assert = function(condition, message) {
if (!condition)
throw Error('Assert failed: ' + (message || ''));
};
assert(1 === 1); // Executes without problem
assert(false, 'Expected true');
// Yields 'Error: Assert failed: Expected true' in console

assert() is not a native javascript function. It is a custom function someone made. You will have to look for it on your page or in your files and post it for anybody to help determine what it's doing.

check this:http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-quick-and-easy-javascript-testing-with-assert/
it is for testing JavaScript. Amazingly, at barely five or six lines, this code provides a great level of power and control over your code, when testing.
The assert function accepts two parameters:
outcome: A boolean, which references whether your test passed or failed
description: A short description of your test.
The assert function then simply creates a list item, applies a class of either “pass” or “fail,” dependent upon whether your test returned true or false, and then appends the description to the list item. Finally, that block of coded is added to the page. It’s crazy simple, but works perfectly.

If the assertion is false, the message is displayed. Specifically, if the first argument is false, the second argument (the string message) will be be logged in the developer tools console. If the first argument is true, basically nothing happens. A simple example – I’m using Google Developer Tools:
var isTrue = true;
var isFalse = false;
console.assert(isTrue, 'Equals true so will NOT log to the console.');
console.assert(isFalse, 'Equals false so WILL log to the console.');

It probably came with a testing library that some of your code is using. Here's an example of one (chances are it's not the same library as your code is using, but it shows the general idea):
http://chaijs.com/guide/styles/#assert

Word or function "assert" is mostly used in testing parts of application.
Assert functions are a short way of instructing the program to check the condition (also called "assertion") and if the condition is not True, it will throw error.
So let's see how it would look like in "normal code"
if (typeof "string" === "array") {
throw Error('Error: "string" !== "array"');
}
With assert you can simply write:
assert(typeof "string" === "array")
In Javascript, there's no native assert function, so you have to use one from some library.
For simple introduction, you can check this article:
http://fredkschott.com/post/2014/05/nodejs-testing-essentials/
I hope it helps.

Assertion throws error message if first attribute is false, and the second attribute is the message to be thrown.
console.assert(condition,message);
There are many comments saying assertion does not exist in JavaScript but console.assert() is the assert function in JavaScript
The idea of assertion is to find why/where the bug occurs.
console.assert(document.getElementById("title"), "You have no element with ID 'title'");
console.assert(document.getElementById("image"), "You have no element with ID 'image'");
Here depending on the message you can find what the bug is.
These error messages will be displayed to console in red color as if we called console.error();
You can use assertions to test your functions eg:
console.assert(myAddFunction(5,8)===(5+8),"Failed on 5 and 8");
Note the condition can be anything like != < > etc
This is commonly used to test if the newly created function works as expected by providing some test cases and is not meant for production.
To see more functions in console execute console.log(console);

In addition to other options like console.assert or rolling your own, you can use invariant. It has a couple of unique features:
It supports formatted error messages (using a %s specifier).
In production environments (as determined by the Node.js or Webpack environment), the error message is optional, allowing for (slightly) smaller .js.

Java has a assert statement, the JVM disables assertion validation by default. They must be explicitly enabled using command line argument -enableassertions (or its shorthand -ea),
while JavaScript supports console.assert(), it's just a logging method and won't interrupt current procedure if assertion failed.
To bring things together and satisfy various needs, here is a tiny js assertion lib.
globalThis.assert = (()=> {
class AssertionError extends Error {
constructor(message) {
super(message);
this.name = 'AssertionError';
}
}
let config = {
async: true,
silent: false
};
function assert(condition, message = undefined) {
if (!condition) {
if (config.silent) {
//NOOP
} else if (config.async) {
console.assert(condition, message || 'assert');
} else {
throw new AssertionError(message || 'assertion failed');
}
}
}
assert.config = config;
return assert;
})();
/* global assert */
Object.assign(assert.config, {
// silent: true, // to disable assertion validation
async: false, // to validate assertion synchronously (will interrupt if assertion failed, like Java's)
});
let items = [
{id: 1},
{id: 2},
{id: 3}
];
function deleteItem(item) {
let index = items.findIndex((e)=> e.id === item.id);
assert(index > -1, `index should be >=0, the item(id=${item.id}) to be deleted doesn't exist, or was already deleted`);
items.splice(index, 1);
}
console.log('begin');
deleteItem({id: 1});
deleteItem({id: 1});
console.log('end');

Node.js has an assert function you can import:
const assert = require('assert')
It works as one would expect, in that assert(false) throws an error, and assert(false, message) throws an error with a message.
The other answers have already pointed out that JS itself has no native assert function, and that remains true as of this writing (April 2021).

Previous answers can be improved in terms of performances and compatibility.
Check once if the Error object exists, if not declare it :
if (typeof Error === "undefined") {
Error = function(message) {
this.message = message;
};
Error.prototype.message = "";
}
Then, each assertion will check the condition, and always throw an Error object
function assert(condition, message) {
if (!condition) throw new Error(message || "Assertion failed");
}
Keep in mind that the console will not display the real error line number, but the line of the assert function, which is not useful for debugging.

If you use webpack, you can just use the node.js assertion library. Although they claim that it's "not intended to be a general purpose assertion library", it seems to be more than OK for ad hoc assertions, and it seems no competitor exists in the Node space anyway (Chai is designed for unit testing).
const assert = require('assert');
...
assert(jqXHR.status == 201, "create response should be 201");
You need to use webpack or browserify to be able to use this, so obviously this is only useful if those are already in your workflow.

As mentioned by T.J., There is no assert in JavaScript.
However, there is a node module named assert, which is used mostly for testing. so, you might see code like:
const assert = require('assert');
assert(5 > 7);

assert() is the assert function in JavaScript. The main idea of assertion is to find why/where the bug occurs.

Chrome devtools support console.assert
You can open devtools and create a snippet in devtools-source-navigator-Snippets. And code some code... and run the snippet...

Related

How to apply expect over softAssertAll or show explicity in the test result that the softAssertAll passed (Error: Expected Object to be a function)

I'm using 'soft-assert' library (soft-assert library) to apply assertion on my test steps without stopping the test if any of them fail.
According to the documentation, all soft-assert is verified at the end of the test by using softAssertAll() command. And this works very well. However, if nothing fails, I don't see any explicit message in my test result as when I use expect command.
So, I'm trying to apply expect over the softAssertAll() command, as it's seen below, but I'm getting the error message:
"expected { Object (userInvocationStack, specWindow, ...) } to be a function"
What I'm trying to do:
expect(cy.softAssertAll()).not.throw(Error)
Does anyone know how can I do this or solve the error in the image below?
Thanks in advance.
See the Chai example for throw
var badFn = function () { throw new TypeError('Illegal salmon!'); };
expect(badFn).to.throw();
Note you pass in the function name without invoking it. I think this allows chai to wrap the function invocation in a try-catch and gracefully report the failure.
You can't do the same with a Cypress custom command as it will not raise errors in the same way as badFn above. Internally it swallows any error and sets the state of the test to "failed".
You could reasonably expect this to work
expect(jsonAssertion.softAssertAll).not.throw()
however there's an internal error in jsonAssertion that seems to be related to the this reference inside it's class.
TypeError: Cannot read properties of undefined (reading '_softThrowJsonDiffArray')
To fix, use an arrow function
const testSoftAssertAll = () => jsonAssertion.softAssertAll();
expect(testSoftAssertAll).not.throw()
or shorter
expect(() => jsonAssertion.softAssertAll()).not.throw()
Check the diff array
This is cleaner and clearer
// expect all soft-assert to be passing
expect(jsonAssertion.jsonDiffArray).to.eq(undefined)
// expect first soft-assert to fail with a certain message
expect(jsonAssertion.jsonDiffArray[0].error.message).to.contain('Illegal salmon')

JavaScript Throw Error - No error thrown? Mocha testing issue

I am working on a JavaScript project and am struggling to pass the final unit test, which essentially checks if my function throws an error if the given input is invalid. For some background, it is a function which deals with user permissions, and can check if certain permissions can be granted or denied, given certain prerequisites.
I can pass all the tests with regards to the output of the functions, but am having trouble with error handling. I am being told that I am not throwing an error, despite checking myself multiple times that an error is indeed being thrown. I'll attach images to illustrate the issue as best as possible.
First, the error object which I am trying to throw is defined below:
function InvalidBasePermissionsError() {
this.name = 'InvalidBasePermissionsError';
this.message = "Invalid Base Permissions";
this.stack = Error().stack;
}
InvalidBasePermissionsError.prototype = Object.create(Error.prototype);
My function which is failing the error-throwing test is as follows:
PermissionDependencyResolver.prototype.canDeny = function (existing, permToDeny) {
try {
if (!pdr.checkValid(existing)) {
throw new InvalidBasePermissionsError;
}
else {
var tempArr = existing
var required = [];
for (var i = 0; i < tempArr.length; i++) {
var current_dependency = this.adjList[existing[i]];
required.push.apply(required, current_dependency)
};
if (required.includes(permToDeny)) {
return false;
} else {
return true;
}
}
}
catch (e) {
console.log(e.message)
}
};
The strange thing is that when I console log the function as follows:
pdr.canDeny(['create', "delete"], 'audit')
I get the correct string "Invalid Base Permissions" printed to the console, see image1. What is even more strange is that when I run the tests, I can see this same error message being logged directly above the "failed test" message, which seems contradictory, see image 2. Is it possible that Mocha (the test framework) isn't picking up on my error handling; or have I made a mistake in my function and am not throwing the error appropriately?
The tests in question are as follows:
it('throws an exception when validating permissions if existing permissions are invalid', function(){
pdr = new PermissionDependencyResolver(complexPermissionDependencies)
expect(function () { pdr.canGrant(['edit', 'create'], 'alter_tags') }).toThrowError("Invalid Base Permissions")
expect(function () { pdr.canGrant(['view', 'delete'], 'alter_tags') }).toThrowError("Invalid Base Permissions")
expect(function () { pdr.canDeny(['create', 'delete'], 'audit') }).toThrowError("Invalid Base Permissions")
})
Is it possible that Mocha (the test framework) isn't picking up on my error handling; or have I made a mistake in my function and am not throwing the error appropriately?
Again, when I manually console log each of the cases being tested, they all throw the error message "Invalid Base Permissions" as expected. For some reason, however, the tests are telling me that nothing is being thrown.
Any ideas as to what might be causing this would be a massive help, as I'm at a loss as to what the source of the error is. Is it Mocha, JS, my try/catch syntax or some other issue. Any help is really appreciated.
Thanks!
Managed to find an answer after extensive digging around, will post in case anybody else has similar issues in future. Correct answer here: http://www.itjavascript.com/why-won-39-t-mocha-recognise-my-error-ask-question/
Basically, I was handling the error before it reached the test, so removing the try/catch statements solved the problem. Silly in hindsight but apparently you need to be very explicit with Mocha. Hopefully this'll prove useful for somebody in the future!

expect() with no actual expectations

The Problem:
Recently, while reviewing our existing test codebase, I've noticed a dangerous kind of typo/mistake when expect() was used without the "matching" part:
expect(page.filters.fromDateLabel.getText(), "After");
I'm pretty sure toEqual() was meant to be used here:
expect(page.filters.fromDateLabel.getText()).toEqual("After");
The problem with this is that jasmine would not fail the expectation in this case (well, obviously because nothing was actually expected). And this gets us to a more serious problem - nothing was actually tested in a test case - it was passing with no expectations made. We were getting a false sense of what was tested.
The Question:
I want to catch these mistakes as fast as possible. How do you think I should handle the problem?
Thoughts:
somehow fail a test case if there was no expectations made in it (not sure if jasmine has anything like this built-in)
"patch" the expect() and issue a warning/raise an error if nothing was called on the "expect" part
use static code analysis - define a custom eslint rule
The custom ESLint rule provided in the answer is now a part of eslint-plugin-jasmine 1.6.0:
valid-expect
Old Answer:
Here is a custom ESLint rule I've ended up with:
module.exports = function (context) {
return {
// checking "expect()" arguments
CallExpression: function (node) {
if (node.callee.name === 'expect') {
if (node.arguments.length > 1) {
context.report(node, 'More than one argument passed to expect()')
} else if (node.arguments.length === 0) {
context.report(node, 'No arguments passed to expect()')
}
}
},
// nothing called on "expect()"
'CallExpression:exit': function (node) {
if (node.callee.name === 'expect' && node.parent.type === 'ExpressionStatement') {
context.report(node, 'Nothing called on expect()')
}
}
}
}
It checks for 3 things:
more than 1 argument passed to expect()
no arguments are passed to expect()
there was nothing called on expect()
Here are the sample invalid expect() usages it currently catches:
expect(page.filters.fromDateLabel.getText(), "After");
expect("After");
expect();
As for the option #1, there is actually a quite related and useful ESLint rule being already implemented and open-sourced by [eslint-plugin-jasmine]:
Enforce expectation (missing-expect)
I tend to think that the static analysis route is best, but if you’re looking for a quick and dirty way, here’s some code that grabs the expectations returned by all calls to expect and creates a proxy that tracks whether any of the expectation’s properties were ever used:
var unusedExpectations = new Set();
var originalExpect = window.expect; // Should be empty after every spec
var expect = function() {
var rawExpectation = originalExpect.apply(this, arguments);
unusedExpectations.add(rawExpectation); // Assume unused until used
// Traverse expectation and its prototypes, copying all properties to
// our proxy object. (Note that this becomes much simpler if you have
// ES6 Proxy in your environment.)
var proxy = {}
for(var proto = rawExpectation; proto; proto = proto.__proto__) {
Object.getOwnPropertyNames(proto).forEach(function(prop) {
if(Object.getOwnPropertyDescriptor(proxy, prop))
return;
Object.defineProperty(
proxy, prop, {
get: function() {
// Aha! Somebody used this expectation for _something_.
unusedExpectations.delete(rawExpectation);
return rawExpectation[prop];
}
}
);
});
}
return proxy;
}
Put that in a place where it hides Jasmine’s expect from your specs, and then:
beforeEach(function() {
unusedExpectations.clear();
});
afterEach(function() {
expect(unusedExpectations.size).toEqual(0);
});
Caveats:
Kind of evil.
Will not catch expect(foo).toBeFalsy; (missing parens).
Counts the use of any property, so won’t catch expect(foo).toString().
Still, it works!
One could add code to inspect the stack trace and extract the location of the offending expect(), but I imagine flagging which spec has an unused expect() is sufficient.

Javascript throw vs. return error object vs. callback

I'm writing an assembler and simulator for a toy assembly language that I have my CS students use in class. I'm writing it in javascript with the idea that I could then build a simple UI in the browser which would show students how each instruction changes the state of the machine and such.
One question that I'm grappling with is the best way to return error information from the assembler when invalid assembly code is passed. The assembler has an extremely simple API at the moment:
var assembler = ... // Get the assembler object
var valid_source = "0 mov r1 r2\n1 halt";
var valid_binary = assembler.assemble(valid_source); // String containing 0's and 1's
var invalid_source = "foo bar baz!";
var invalid_binary = assembler.assemble(invalid_source); // What should happen here?
I have a few thoughts about how this might work:
Construct and throw a new javascript Error object. This seems like overkill (and ultimately maybe not even helpful since the user wouldn't care about the javascript stacktrace, etc).
Return a string or object containing error information. Then the user of the assembler gets to make the choice about what to do with errors (if anything).
Change the assembler API to use a callback instead:
assembler.assemble(source, function(binary, error) {
if (error) {
// Handle the error
}
// Otherwise, do stuff with the binary
});
Something else entirely?
Any ideas, thoughts, or feedback would be much appreciated.
I think your three options would work fine. Now from my perspective:
I would keep away from the third option because it gives the feeling it is an async function when it is not.
I would go for option 1 or 2. The first one is a little overkill but I think it is the most realistic approach to what compilers do. Exit with no zero code. But then you would need to add a try/catch block to handle the error.
So the next option is to return an error object. Seems the best option for me.
I recommend you to return an Error object. It is as simple as:
return new Error('Parsing error');
// Or with an error name
var error = new Error('Parsing error');
error.name = 'PARSING_ERROR';
return error;
One advantage to use the error object is that it gives you the stack trace and other handy stuff. More info here.
Also, to check if there was any error just need to check the variable type:
if (typeof valid_binary === 'string') { /* no error */ }
// Or
if (typeof valid_binary === 'object') { /* error */ }
Good luck!

How can I override/extend ReferenceError in Chrome's JavaScript?

To make debugging easier, I'm capturing all of the console logs in Chrome so that users who submit a feedback entry will also submit all of the logs to our server. When someone encounters a problem in production, I can first and foremost get them back to work so that I can then sit down and more thoroughly go through all of the logs to determine the root cause of whatever issue the user encountered in production.
The technique I use to capture the logs involves overriding console.log so that all text entered in the first argument gets stored in an array while simultaneously invoking the legacy function so that I can still see the logs in the console too.
The problem is when there's the occasional uncaught exception. These aren't included in the uploaded logs, so it's not always clear what caused the problem. So I tried overriding ReferenceError by writing a JavaScript function that takes a function as an argument, then returns a new function that does stuff with it, like storing data in a variable, and then invoking the legacy function as the last step:
function overrideException(legacyFn) {
/** arguments for original fn **/
return function() {
var args = [];
args[0] = arguments[0];
// pass in as arguments to original function and store result to
// prove we overrode the ReferenceError
output = ">> " + legacyFn.apply(this, args).stack;
return legacyFn.apply(this, arguments);
}
}
To test the overrideException function, I ran the following code on the console:
ReferenceError = overrideException(ReferenceError);
Afterwards, I tested the returned function, the new ReferenceError, by manually throwing a ReferenceError:
throw new ReferenceError("YES!! IT WORKS! HAHAHA!");
The resulting output on the console is:
ReferenceError: YES!! IT WORKS! HAHAHA!
And checking the global variable output from the overrideException function shows that it did indeed run:
output
">> ReferenceError: YES!! IT WORKS! HAHAHA!
at ReferenceError (<anonymous>)
at new <anonymous> (<anonymous>:18:35)
at <anonymous>:2:7
at Object.InjectedScript._evaluateOn (<anonymous>:562:39)
at Object.InjectedScript._evaluateAndWrap (<anonymous>:521:52)
at Object.InjectedScript.evaluate (<anonymous>:440:21)"
Now, here's where things start to fall apart. In our code, we're not going to know when an uncaught exception occurs, so I tested it by attempting to run a function that doesn't exist:
ttt();
Which results in:
ReferenceError: ttt is not defined
However, unlike the case where we explicitly throw an error, in this case, the function doesn't fire, and we're left with only the legacy functionality. The contents of the variable output is the same as in the first test.
So the question seems to be this: How do we override the ReferenceError functionality that the JavaScript engine uses to throw errors so that it's the same one we use when we throw a ReferenceError?
Keep in mind that my problem is limited only to Chrome at this time; I'm building a Chrome Packaged app.
I have done quite a bit of research for the same reason: I wanted to log errors and report them.
"Overriding" a native type (whether ReferenceError, String, or Array) is not possible.
Chrome binds these before any Javascript is run, so redefining window.ReferenceError has no effect.
You can extend ReferenceError with something like ReferenceError.prototype.extension = function() { return 0; }, or even override toString (for consistency, try it on the page, not the Dev Tools).
That doesn't help you much.
But not to worry....
(1) Use window.onerror to get file name, 1-indexed line number, and 0-indexed position of uncaught errors, as well as the error itself.
var errorData = [];
onerror = function(message, file, line, position, error) {
errorData.push({message:message, file:file, line:line, position:position, error:error});
};
See the fiddle for an example. Since the OP was Chrome-specific, this has only been tested to work in Chrome.
(2) Because of improvements to (1), this is no longer necessary, but I leave this second technique here for completeness, and since onerror is not guaranteed to work for all errors on all browsers. You will also sometimes see the following:
var errors = [];
function protectedFunction(f) {
return function() {
try {
f.apply(this, arguments);
} catch(e) {
errors.push(e);
throw e;
}
};
}
setTimeout = protectedFunction(setTimeout);
setInterval = protectedFunction(setInterval);
etc...
FYI, all this is very similar to what has been done in the Google Closure Compiler library, in goog.debug, created during Gmail development with the intent of doing exactly this. Of particular interest is goog.debug.ErrorHandler and goog.debug.ErrorReporter.

Categories