UNB/ CS/ David Bremner/ teaching/ cs2613/ labs/ Lab 9

-

Before the Lab

Background

Getting started

Questions

Time
5 Minutes
Activity
Group discussion / Announcments

JavaScript equality and type coercion

Time
10 Minutes
Activity
Demo

We remember from earlier Eloquent JavaScript Chapter 1, and the WAT talk by Gary Bernhardt, that type coercion is an important part of evaluating JS expressions. This is sometimes useful

> 42 + 'is a big number'

But just as often a source of errors and confusion.

> "" + 1
> x=""
> x++

One operator where type coercion can be particularly surprising is the standard equality test ==. Not only does type coercion apply:

> "" == 0
> false == 0
> "" == 0

but special rules apply to "undefined" and "null"

> false == undefined
> undefined == null
> undefined == undefined

even though they would normally be considered falsy (considered false in boolean contexts).

   > if (undefined) { console.log("truthy") } else { console.log("falsey") }

NaN is another falsy value not == to the other falsy values, not even itself:

   > NaN == undefined
   > NaN == NaN

To avoid this twisty maze of "helpful" type coercion, you can use the "strict equality" checker ===

   > "" === 0
   > false === 0
   > "" === 0
   > false === undefined
   > undefined === null
   > undefined === undefined

Javascript functions

Time
20 minutes
Activity
Individual

Reference for this section is JavaScript functions Like Racket, JavaScript has two different ways of defining functions. The first way is by assigning an anonymous function to a variable.

    (define square (lambda (x) (* x x)))
    let square = x => x*x;
    let square2 = function (x) {return x*x};

The more compact way of defining functions in both Racket and JavaScript combines the binding and creation of a function/lambda

    (define (square x) (* x x))
    function square(x) { return x*x }
const plus = (a,b) => {
    for (let i=0; i < a; i++){
        b++;
    }
    return b;
}

const mult = function (a,b) {
    sum=0;



    return sum;
}

Node test runner

Time
10 Minutes
Activity
Demo

In order to provide similar functionality to check-expect in racket, we will use the nodejs test framework.

In order to use the test runner, we need to add two lines to the beginning of our javascript files.

const test=require("node:test");
const assert=require("assert");

We'll talk more about both const and require later.

A test is considered to pass if it does not throw an exception. assert provides several functions useful for this kind of test. We will concentrate on assert.strictEqual for now, which corresponds to the === test discussed above.

Here is a complete example with one passing test and one failing one

const test=require("node:test");
const assert=require("assert");

function add1(n) {
    return n+1;
}

test('one plus one is two', (t)=>assert.strictEqual(add1(1),2));
test('one plus one is three', (t)=>assert.strictEqual(add1(1),3));

Test coverage

We will use an experimental feature of node v20 in order to make sure we have test coverage (analogous to how we set up DrRacket for visual test coverage).

Getting a coverage report

Time
15 minutes
Activity
Group activity
ℹ start of coverage report
ℹ ---------------------------------------------------------
ℹ file      | line % | branch % | funcs % | uncovered lin…
ℹ ---------------------------------------------------------
ℹ sample.js | 100.00 |   100.00 |  100.00 |
ℹ ---------------------------------------------------------
ℹ all files | 100.00 |   100.00 |  100.00 |
ℹ ---------------------------------------------------------
ℹ end of coverage report

Writing tests

Time
30 minutes
Activity
Individual

Before the next lab