Errata

Testable JavaScript

Errata for Testable JavaScript

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

Color key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted By Date submitted Date corrected
ePub
Page Loc 43
Second paragraph

...will keep you in that lower-right sweet spot in the matric.

The lower-right corner is loose and complex. I would have expected the lower-left to be the goal.

Note from the Author or Editor:
yes! Lower left!

David Wire  May 27, 2013  Dec 05, 2014
PDF
Page 14
1st paragraph

The link in this sentence:

The more code you have, the [greater the chance it will have bugs in it].

Points at this address:

http://bit.ly/XUdmPf

But a visit to that address goes to http://www.enerjy.com/techpaper-2008-01-02.pdf

THAT page is not loading. I realize this probably falls under the category of "Not Your Responsibility/Problem" but it does harm the value of the link in that sentence. You went to the trouble of trying to point at that link, so either issue an update that removes that link, or adjust the Bit.ly link to point at a cached copy of that link on Google.

I found this on Google:

http://webcache.googleusercontent.com/search?q=cache:opegFTu7AfkJ:enerjy.com/techpaper-2008-01-02.pdf+&cd=1&hl=en&ct=clnk&gl=us

BTW, thanks for the book so far -- it's illuminating!

Note from the Author or Editor:
please change the link to point to:

http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.130.7149&rep=rep1&type=pdf

instead

Justin Goltermann  Jan 03, 2014  Dec 05, 2014
Printed
Page 16

p.14: "In this world, commands are setters and queries are getters."

So a setter is a command, makes sense.

p.16: "Here, we split up the setting of the values (query, a return value)
....".

So now a setter is a query? Even more confusing since the setter returns the new value, which is comfortable but makes the interface semantics harder to understand. In any case: I would assume we treat this as a command that nearby returns the new value. Right?

Note from the Author or Editor:
You are correct this example is confusing from a straight command/query separation viewpoint - later iterations of this code try to resolve some of this ambiguity but even the final end result is a compromise (as the text indicates) as strict command/query separation is almost impossible to achieve in practice.

Anonymous  Oct 01, 2013  Dec 05, 2014
Printed
Page 17
3rd paragraph - configure function example

it seems that the "config" hash is not defined in the configure
function as it was in prior pages. (also not define as a global)

Note from the Author or Editor:
yes! it needs to be defined within that configure function!
var config = {};
page 17

yoni felberg  Mar 11, 2013  Dec 05, 2014
PDF
Page 23
last line

JSUnit should be JSLint.

Note from the Author or Editor:
Yes! Should be JSHint.

Anonymous  Aug 09, 2013  Dec 05, 2014
Printed
Page 29
1st paragraph of Fan-Out

Grammatical error in the following:

They postulated that 50% to 75% of the cost of software is due to maintenance, and they wanted to measure, as early as the design phase as possible, ...

A simple fix could be:

... as early in the design phase as possible, ...

Note from the Author or Editor:
Agreed wording is wrong. That second 'as' should indeed be 'in':

They postulated that 50% to 75% of the cost of software is due to maintenance, and they wanted to measure, as early in the design phase as possible

Javier Castro  Sep 22, 2015 
PDF
Page 43
First code block

Whether "dinner = chef.cook(ingredients);" should be "dinner = chef.cook(food);", or "food = new Ingredients()" should be "ingredients = new Ingredients()".

Note from the Author or Editor:
, food = new Ingredients()

should be:

, ingredients = new Ingredients()

Oliver Schmidt  Dec 16, 2013  Dec 05, 2014
ePub
Page 45
3rd paragraph

(Referring to page 45 in iBooks on iPad 3 with smallest font size, portrait orientation, and "Book" theme. Sorry�I can't find any way to get a universal location reference in iBooks.)

「�switch statements, but you are not using those as they are not one of the "good parts," right?」

Actually, Doug Crockford did not say `switch` statements themselves are one of the "bad parts". He only said not to deliberately fall through from one case to another. A `switch` statement with a `break` for each block is perfectly acceptable, and accordingly, JSLint does not complain about them.

I took away the same "switch = bad" lesson from my first reading of The Good Parts, but when I went back later to double check, I found out that wasn't actually what Crockford said.

Note from the Author or Editor:
you are correct - I also don't like them for the increased complexity they cause but you are correct about my misreading of Crockford - thanks!

Jason Sims  Sep 07, 2013  Dec 05, 2014
Printed
Page 71
Test Case

How can you call the addUser() function? Isn't it outside of scope in the test code?

Would you need to use the eventHub mock to get a reference to the function when eventHub.on('CREATE_USER', addUser) is called in the DB function or what am I missing?

Note from the Author or Editor:
Ok code on page 69 needs to be changed to:

// Some handle to a datastore
function DB(eventHub, dbHandle) {
// Add user function
eventHub.on('CREATE_USER', createAddUserHandler(eventHub, dbHandle));
}

function createAddUserHandler(eventHub, dbHandle) {
return function addUser(user) {
var result = dbHandle.addRow('user', user);
eventHub.fire('USER_CREATED', {
success: result.success
, message: result.message
, user: user
});
}
}

code on page 70 should be changed to:

YUI().use('test', function(Y) {
var eventHub = Y.Mock()
, addUserTests = new Y.Test.Case({
name: 'add user'
, testAddOne: function() {
var user = { user_id: 'mark' }
, dbHandle = { // DB stub
addRow: function(user) {
return { user: user
, success: true
, message: 'ok' };
}
}
, addUser = createAddUserHandler(eventHub, dbHandle)
;

Y.Mock.expect(
eventHub
, 'fire'
, [
'USER_CREATED'
, { success: true, message: 'ok', user: user }
]
);
DB(eventHub, dbHandle); // Inject test versions
addUser(user);
Y.Mock.verify(eventHub);
}
});

eventHub.on = function(event, func) {};
eventHub.fire = function(event, data) {};
Y.Test.Runner.add(addUserTests);
Y.Test.Runner.run();
});

Seth S  Jan 15, 2014  Dec 05, 2014
PDF
Page 79
4th code example

EventHub does not seem to have emit(). Is it fire() instead?

Note from the Author or Editor:
Yes for the YUI client (which this example shows) it should be fire.

Anonymous  Aug 10, 2013  Dec 05, 2014
PDF, ePub
Page 88
Last line on the page

There is a link provided to a paper for further reading which reads: "for more details on this, read this paper".

The link, which points to:

http://www.enerjy.com/techpaper-2008-01-02.pdf

is currently broken and has been for several days (DNS record for the referenced website does not exist anymore, but whois is ok). Furthermore, no other proper reference is provided (no title, author name(s)...) which would let one find the referenced document by other means.

Maybe I am old fashionned but a good old bibliography still has some advantages over embedded links (and in fact I cannot see any reason why we could not have both, espacially in electronic editions).

Note from the Author or Editor:
The paper can now be reached here:

https://github.com/zzo/TestableJS/blob/master/ch1/enerjy.pdf?raw=true

Anonymous  Jul 17, 2014  Dec 05, 2014
Printed
Page 92
bottom

Y.ArrayAssert.contains(item, "Item not pushed into cart!");

What is Y.ArrayAssert?
Where is the array?

Note from the Author or Editor:
Yes that should not be 'item'! That should be testing that the shopping cart itself contains the added item. It should be 'shoppingCart.cart' as in the subsequent 'testAddNok' method!

Anonymous  Oct 02, 2013  Dec 05, 2014
PDF
Page 108
first and last code blocks

Errant indentation issues in both blocks leads to confusion.

First block has an extra 4 spaces in all lines except the last line, and the indent style is 2 spaces (it's 4 spaces elsewhere).

Last block has an extra 4 spaces in lines 3-4 (assuming 4 spaces to be the standard ident here.)

Note from the Author or Editor:
I see on pg109 the describe block is indented 4 spaces too far - should be:

var mySum = require('./mySumFS');
describe("Sum suite File", function() {
it("Adds Integers!", function() {
expect(mySum.sum("numbers")).toEqual(12);
});
});

The 'describe' block should be even with the 'var' statement.

the rest looks ok to me?

Anonymous  May 02, 2013  Dec 05, 2014
PDF
Page 109
second code block

The closing }); for the describe block is missing.

Note from the Author or Editor:
yes! missing in the book - the original idea was to leave it open because there is another test ('it block) below that is part of the describe but it makes more sense to just close the describe block off here and the 'it' block below as it own separate block.
So on bottom 109-top 110 needs
});
at the end of the code block

Anonymous  May 02, 2013  Dec 05, 2014
PDF
Page 111
second code block

extra right paren in lines 5 and 10

Note from the Author or Editor:
yes! there are extra parens there (page 112):

var sum = mySum.sum(mySum.getByParam, [6,6]));

and

var sum = mySum.sum(mySum.getByFile, ["strings"]));

Anonymous  May 02, 2013  Dec 05, 2014
Printed
Page 112
end of second full paragraph

"...allow the test code to either return called values..."

should probably be:

"...allow the test code to either return canned values..."

Note from the Author or Editor:
exactly what this errata says - 'called' should be replaced with 'canned'

Seth S  Jan 15, 2014  Dec 05, 2014
PDF
Page 120
Paragraph after 3rd code block

[...] which will hold the counts for line and function coverage AND well as some other bookkeeping."

should be

[...] which will hold the counts for line and function coverage AS well as some other bookkeeping."

Oliver Schmidt  Jan 09, 2014  Dec 05, 2014
PDF
Page 124
code example at the bottom

Should "FILES_FOR_COVERAGE[keep]" be "COVERAGE_ME[file]" in order to be consistent with the code in p.123?

Note from the Author or Editor:
yes that line should be:
COVERAGE_ME[file] = 1;

Anonymous  Jun 11, 2013  Dec 05, 2014
Printed
Page 151
code example and the following paragraph

Function proxy.selHAR() is nonexistent. Is it cbHAR() instead?

Note from the Author or Editor:
Yes - should be cbHAR

Anonymous  Jun 14, 2013  Dec 05, 2014