100% found this document useful (1 vote)
6 views

Instant Access to (Ebook) Jasmine JavaScript Testing, 2nd Edition: Test your JavaScript applications efficiently using Jasmine and React.js by Paulo Ragonha ISBN 9781785282041, 1785282042 ebook Full Chapters

The document promotes the ebook 'Jasmine JavaScript Testing, 2nd Edition' by Paulo Ragonha, which focuses on efficiently testing JavaScript applications using Jasmine and React.js. It provides links to download the ebook and other related resources, as well as a brief overview of the book's content, including best practices for JavaScript development and test-driven development concepts. The document also includes information about the author and various reviewers involved in the book's creation.

Uploaded by

zxuanoiga
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
6 views

Instant Access to (Ebook) Jasmine JavaScript Testing, 2nd Edition: Test your JavaScript applications efficiently using Jasmine and React.js by Paulo Ragonha ISBN 9781785282041, 1785282042 ebook Full Chapters

The document promotes the ebook 'Jasmine JavaScript Testing, 2nd Edition' by Paulo Ragonha, which focuses on efficiently testing JavaScript applications using Jasmine and React.js. It provides links to download the ebook and other related resources, as well as a brief overview of the book's content, including best practices for JavaScript development and test-driven development concepts. The document also includes information about the author and various reviewers involved in the book's creation.

Uploaded by

zxuanoiga
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 56

Visit https://ebooknice.

com to download the full version and


explore more ebooks

(Ebook) Jasmine JavaScript Testing, 2nd Edition:


Test your JavaScript applications efficiently using
Jasmine and React.js by Paulo Ragonha ISBN
9781785282041, 1785282042
_____ Click the link below to download _____
https://ebooknice.com/product/jasmine-javascript-
testing-2nd-edition-test-your-javascript-applications-
efficiently-using-jasmine-and-react-js-5470406

Explore and download more ebooks at ebooknice.com


Here are some recommended products that might interest you.
You can download now and explore!

(Ebook) Jasmine JavaScript Testing, 2nd Edition_ Test your


JavaScript applications efficiently using Jasmine and
React.js by kan
https://ebooknice.com/product/jasmine-javascript-testing-2nd-edition-
test-your-javascript-applications-efficiently-using-jasmine-and-react-
js-50195432
ebooknice.com

(Ebook) Jasmine JavaScript Testing: Leverage the power of


unit testing to create bigger and better JavaScript
applications by Paulo Ragonha ISBN 9781782167204,
178216720X
https://ebooknice.com/product/jasmine-javascript-testing-leverage-the-
power-of-unit-testing-to-create-bigger-and-better-javascript-
applications-5498694
ebooknice.com

(Ebook) Biota Grow 2C gather 2C cook by Loucas, Jason;


Viles, James ISBN 9781459699816, 9781743365571,
9781925268492, 1459699815, 1743365578, 1925268497
https://ebooknice.com/product/biota-grow-2c-gather-2c-cook-6661374

ebooknice.com

(Ebook) Test-Driven Development with Python. Obey the


Testing Goat. Using Django, Selenium, and JavaScript by
Harry J. W. Percival ISBN 9781491958674, 9781491958704,
1491958677, 1491958707
https://ebooknice.com/product/test-driven-development-with-python-
obey-the-testing-goat-using-django-selenium-and-javascript-6712714

ebooknice.com
(Ebook) React.js Book: Learning React JavaScript Library
From Scratch by Greg Sidelnikov

https://ebooknice.com/product/react-js-book-learning-react-javascript-
library-from-scratch-7159540

ebooknice.com

(Ebook) The Road to React: The React.js in JavaScript Book


(2024 Edition) by Robin Wieruch ISBN 9798484786787,
8484786781
https://ebooknice.com/product/the-road-to-react-the-react-js-in-
javascript-book-2024-edition-56815214

ebooknice.com

(Ebook) Python Testing Cookbook: Easy solutions to test


your Python projects using test-driven development and
Selenium, 2nd Edition by Greg L. Turnquist & Bhaskar N.
Das ISBN 9781787122529, 1787122522
https://ebooknice.com/product/python-testing-cookbook-easy-solutions-
to-test-your-python-projects-using-test-driven-development-and-
selenium-2nd-edition-10806786
ebooknice.com

(Ebook) Functional Programming in JavaScript: How to


improve your JavaScript programs using functional
techniques by Luis Atencio ISBN 9781617292828, 1617292826
https://ebooknice.com/product/functional-programming-in-javascript-
how-to-improve-your-javascript-programs-using-functional-
techniques-5751626
ebooknice.com

(Ebook) Functional Programming in JavaScript: How to


improve your JavaScript programs using functional
techniques by Luis Atencio ISBN 9781617292828, 1617292826
https://ebooknice.com/product/functional-programming-in-javascript-
how-to-improve-your-javascript-programs-using-functional-
techniques-55892992
ebooknice.com
Jasmine JavaScript Testing 2nd Edition Test your
JavaScript applications efficiently using Jasmine and
React js Paulo Ragonha Digital Instant Download
Author(s): Paulo Ragonha
ISBN(s): 9781785282041, 1785282042
File Details: PDF, 1.55 MB
Year: 2015
Language: english
[1]

www.it-ebooks.info
Jasmine JavaScript Testing
Second Edition

Test your JavaScript applications efficiently


using Jasmine and React.js

Paulo Ragonha

BIRMINGHAM - MUMBAI

www.it-ebooks.info
Jasmine JavaScript Testing
Second Edition

Copyright © 2015 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval
system, or transmitted in any form or by any means, without the prior written
permission of the publisher, except in the case of brief quotations embedded in
critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy
of the information presented. However, the information contained in this book is
sold without warranty, either express or implied. Neither the author, nor Packt
Publishing, and its dealers and distributors will be held liable for any damages
caused or alleged to be caused directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the
companies and products mentioned in this book by the appropriate use of capitals.
However, Packt Publishing cannot guarantee the accuracy of this information.

First published: August 2013


Second edition: April 2015

Production reference: 1210415

Published by Packt Publishing Ltd.


Livery Place
35 Livery Street
Birmingham B3 2PB, UK.

ISBN 978-1-78528-204-1

www.packtpub.com

www.it-ebooks.info
Credits

Author Project Coordinator


Paulo Ragonha Suzanne Coutinho

Reviewers Proofreaders
Hany A. Elemary Paul Hindle
Ryzhikov Maksim Linda Morris
Veer Shubhranshu Shrivastav
Sergey Simonchik Indexer
Tejal Soni

Commissioning Editor
Amarabha Banerjee Production Coordinator
Aparna Bhagat

Acquisition Editor
Larissa Pinto Cover Work
Aparna Bhagat

Content Development Editor


Manasi Pandire

Technical Editor
Anushree Arun Tendulkar

Copy Editor
Sarang Chari

www.it-ebooks.info
About the Author

Paulo Ragonha is a software engineer with over 7 years of professional experience.


An advocate of the open Web, he is inspired and driven to build compelling
experiences on top of this ubiquitous platform.

He loves to hack, so you will often see him wandering around in conferences or
attending hackathons. His most recent professional experiences ranged from DevOps
(with Chef and Docker) to moving up the stack with Node.js, Ruby, and Python and
all the way toward building single-page applications (mostly with Backbone.js and
"ad hoc" solutions).

Passionate about automation, he sees testing as a liberating tool to enjoy the craft of
writing code even more. Back in 2013, he wrote the first edition of the book Jasmine
JavaScript Testing, Packt Publishing.

Paulo has an amazing wife, who he loves very much. He lives in beautiful
Florianópolis, a coastal city in the south of Brazil. He is a casual speaker, a biker,
a runner, and a hobbyist photographer.

www.it-ebooks.info
About the Reviewers

Hany A. Elemary is a software engineer / technical team lead at OCLC in


Columbus, Ohio, currently working on the next generation of mobile/web apps
(http://www.worldcat.org and WorldCat for local institutions). He has been blessed
with diverse experience while working for multiple companies (from small software
shops to large corporations) and seeing different releasable software strategies. He
has a clear focus and passion for mobile/web UI design, interactions, usability, and
accessibility. When there is time, he enjoys playing his acoustic guitar, AnnaMaria.

Special thanks to my close friends and family for always pushing me


to be better in every aspect of life.

Ryzhikov Maksim is a 27-year-old software developer from Saint Petersburg,


Russia.

He develops complex web applications. He graduated from the physics faculty at


Saint Petersburg State University. His journey into the world of software development
started not so long ago—5 years ago.

His brother invited him to join the team that developed programs for American
hospitals, as an HTML developer.

Ryzhikov started with developing a simple, static site for hospitals and then studied
JavaScript, Ruby, and SQL and worked as a full-stack developer. In 5 years of work
in the area of IT, he has worked in various projects and teams. He developed medical
systems, dating sites, web mail (Yandex.Mail), and now he helps develop tools for
developers at JetBrains.

www.it-ebooks.info
Veer Shubhranshu Shrivastav is an Indian software developer working
with Tata Consultancy Services since 2013 and is a former research intern at IIIT-
Delhi. He has worked on different technologies, such as PHP, Moodle, jQuery,
AngularJS, RequireJS, Android, Jasmine, Ionic, and so on, and also takes an interest
in cryptography, network security, and database technologies. He has worked with
various Indian IT start-ups, helping them as a software architect.

With his interest in the open source community, he developed a Pro*C library
named CODBC, which is available at http://codbc.com. The library enables
an object-oriented approach to connect C++ and Oracle Database.

Sergey Simonchik is a software developer living and working in Saint Petersburg,


Russia. He is lucky because he has a wonderful wife and a kind cat. Sergey develops
the WebStorm IDE at JetBrains. He is working on improving JavaScript unit testing
support and other IDE features.

www.it-ebooks.info
www.PacktPub.com
Support files, eBooks, discount offers,
and more
For support files and downloads related to your book, please visit www.PacktPub.com.

Did you know that Packt offers eBook versions of every book published, with PDF and
ePub files available? You can upgrade to the eBook version at www.PacktPub.com and
as a print book customer, you are entitled to a discount on the eBook copy. Get in touch
with us at [email protected] for more details.

At www.PacktPub.com, you can also read a collection of free technical articles, sign up
for a range of free newsletters and receive exclusive discounts and offers on Packt books
and eBooks.
TM

https://www2.packtpub.com/books/subscription/packtlib

Do you need instant solutions to your IT questions? PacktLib is Packt's online digital
book library. Here, you can search, access, and read Packt's entire library of books.

Why subscribe?
• Fully searchable across every book published by Packt
• Copy and paste, print, and bookmark content
• On demand and accessible via a web browser

Free access for Packt account holders


If you have an account with Packt at www.PacktPub.com, you can use this to access
PacktLib today and view 9 entirely free books. Simply use your login credentials for
immediate access.

www.it-ebooks.info
www.it-ebooks.info
Table of Contents
Preface v
Chapter 1: Getting Started with Jasmine 1
JavaScript – the bad parts 1
Jasmine and behavior-driven development 3
Downloading Jasmine 4
Summary 6
Chapter 2: Your First Spec 7
The Investment Tracker application 7
Jasmine basics and thinking in BDD 8
Setup and teardown 14
Nested describes 18
Setup and teardown 19
Coding a spec with shared behavior 19
Understanding matchers 20
Custom matchers 21
Built-in matchers 26
Summary 32
Chapter 3: Testing Frontend Code 33
Thinking in terms of components (Views) 34
The module pattern 35
Using HTML fixtures 36
Basic View coding rules 40
The View should encapsulate a DOM element 41
Integrating Views with observers 43
Testing Views with jQuery matchers 48
The toBeMatchedBy jQuery matcher 49
The toContainHtml jQuery matcher 50
The toContainElement jQuery matcher 50

[i]

www.it-ebooks.info
Table of Contents

The toHaveValue jQuery matcher 50


The toHaveAttr jQuery matcher 50
The toBeFocused jQuery matcher 51
The toBeDisabled jQuery matcher 51
More matchers 51
Summary 51
Chapter 4: Asynchronous Testing – AJAX 53
Acceptance criterion 53
Setting up the scenario 55
Installing Node.js 55
Coding the server 55
Running the server 56
Writing the spec 57
Asynchronous setups and teardowns 57
Asynchronous specs 58
Timeout 59
Summary 60
Chapter 5: Jasmine Spies 61
The "bare" spy 61
Spying on an object's functions 62
Testing DOM events 63
Summary 64
Chapter 6: Light Speed Unit Testing 65
Jasmine stubs 65
Jasmine Ajax 67
Installing the plugin 67
A fake XMLHttpRequest 67
Summary 69
Chapter 7: Testing React Applications 71
Project setup 72
Our first React component 72
The Virtual DOM 75
JSX 76
Using JSX with Jasmine 78
Component attributes (props) 80
Component events 82
Component state 85
Component life cycle 89
Composing components 91
Summary 92
[ ii ]

www.it-ebooks.info
Table of Contents

Chapter 8: Build Automation 93


Module bundler – webpack 94
Module definition 94
Webpack project setup 95
Managing dependencies with NPM 96
Webpack configuration 97
The spec runner 99
Testing a module 100
Test runner: Karma 100
Quick feedback loop 102
Watch and run the tests 102
Watch and update the browser 103
Optimizing for production 103
Static code analysis: JSHint 105
Continuous integration – Travis-CI 107
Adding a project to Travis-CI 107
Project setup 108
Summary 108
Index 109

[ iii ]

www.it-ebooks.info
www.it-ebooks.info
Preface
This book is about being a better JavaScript developer. So, throughout the chapters,
you will not only learn about writing tests in the Jasmine 'idiom', but also about
the best practices in writing software in the JavaScript language. It is about
acknowledging JavaScript as a real platform for application development and
leveraging all its potential. It is also about tooling and automation and how to make
your life easier and more productive.

Most importantly, this book is about craftsmanship of not only working software,
but also well-crafted software.

Jasmine JavaScript Testing, Second Edition is a practical guide to writing and


automating JavaScript testing for web applications. It uses technologies such as
Jasmine, Node.js, and webpack.

Over the course of the chapters, the concept of test-driven development is explained
through the development of a simple stock market Investment Tracker application. It
starts with the basics of testing through the development of the base domain classes
(such as stock and investment), passes through the concepts of maintainable browser
code, and concludes with a full refactoring to a React.js application build on ECMA
Script 6 modules and automated build.

What this book covers


Chapter 1, Getting Started with Jasmine, covers the motivations behind testing a
JavaScript application. It presents the concept of BDD and how it helps you to write
better tests. It also demonstrates how easy it is to download Jasmine and start coding
your first tests.

[v]

www.it-ebooks.info
Preface

Chapter 2, Your First Spec, helps you learn the thought process behind thinking
in terms of test-driven development. You will code your very first JavaScript
functionality driven by tests. You will also learn the basic functions of Jasmine
and how to structure your tests. Also demonstrated, is how Jasmine matchers work
and how you can create one of your own to improve your tests' code readability.

Chapter 3, Testing Frontend Code, covers some patterns in writing maintainable


browser code. You will learn about thinking in terms of components and how to use
the module pattern to better organize your source files. You will also be presented
with the concept of HTML fixtures and how you can use it to test your JavaScript
code without requiring your servers to render an HTML. You will also learn about
a Jasmine plugin called jasmine-jquery and how it can help you write better tests
with jQuery.

Chapter 4, Asynchronous Testing – AJAX, talks about the challenges in testing AJAX
requests and how you can use Jasmine to test any asynchronous code. You will learn
about Node.js and how to create a very simple HTTP server to use as a fixture to
your tests.

Chapter 5, Jasmine Spies, presents the concept of test doubles and how to use spies to
do behavior checking.

Chapter 6, Light Speed Unit Testing, helps you to learn about the issues with AJAX
testing and how you can make your tests run faster using stubs or fakes.

Chapter 7, Testing React Applications, introduces you to React, a library to build user
interfaces, and covers how you can use it to improve the concepts presented in
Chapter 3, Testing Frontend Code, to create richer and more maintainable applications,
of course, driven by tests.

Chapter 8, Build Automation, presents you with the power of automation. It introduces
you to webpack, a bundling tool for frontend assets. You will start to think in terms
of modules and their dependencies, and you will learn how to code your tests as
modules. You will also learn about packing and minifying the code to production
and how to automate this process. Finally, you are going to learn about running your
tests from a command line and how this can be used in a continuous integration
environment with Travis.ci.

[ vi ]

www.it-ebooks.info
Preface

What you need for this book


Besides a browser and a text editor, the only requirement to run some of the
examples, is Node.js 0.10.x.

Who this book is for


This book is a must-have material for web developers new to the concept of unit
testing. It's assumed that you have a basic knowledge of JavaScript and HTML.

Conventions
In this book, you will find a number of text styles that distinguish between different
kinds of information. Here are some examples of these styles and an explanation of
their meaning.

Code words in text, database table names, folder names, filenames, file extensions,
pathnames, dummy URLs, user input, and Twitter handles are shown as follows:
"We can include other contexts through the use of the include directive."

A block of code is set as follows:


describe("Investment", function() {
it("should be of a stock", function() {
expect(investment.stock).toBe(stock);
});
});

When we wish to draw your attention to a particular part of a code block, the relevant
lines or items are set in bold:
describe("Investment", function() {
it("should be of a stock", function() {
expect(investment.stock).toBe(stock);
});
});

Any command-line input or output is written as follows:


# npm install --save-dev webpack

New terms and important words are shown in bold. Words that you see on
the screen, for example, in menus or dialog boxes, appear in the text like this:
"Clicking the Next button moves you to the next screen."

[ vii ]

www.it-ebooks.info
Preface

Warnings or important notes appear in a box like this.

Tips and tricks appear like this.

Reader feedback
Feedback from our readers is always welcome. Let us know what you think about
this book—what you liked or disliked. Reader feedback is important for us as it helps
us develop titles that you will really get the most out of.

To send us general feedback, simply e-mail [email protected], and mention


the book's title in the subject of your message.

If there is a topic that you have expertise in and you are interested in either writing
or contributing to a book, see our author guide at www.packtpub.com/authors.

Customer support
Now that you are the proud owner of a Packt book, we have a number of things to
help you to get the most from your purchase.

Downloading the example code


You can download the example code files from your account at http://www.
packtpub.com for all the Packt Publishing books you have purchased. If you
purchased this book elsewhere, you can visit http://www.packtpub.com/support
and register to have the files e-mailed directly to you.

[ viii ]

www.it-ebooks.info
Preface

Errata
Although we have taken every care to ensure the accuracy of our content, mistakes
do happen. If you find a mistake in one of our books—maybe a mistake in the text or
the code—we would be grateful if you could report this to us. By doing so, you can
save other readers from frustration and help us improve subsequent versions of this
book. If you find any errata, please report them by visiting http://www.packtpub.
com/submit-errata, selecting your book, clicking on the Errata Submission Form
link, and entering the details of your errata. Once your errata are verified, your
submission will be accepted and the errata will be uploaded to our website or added
to any list of existing errata under the Errata section of that title.

To view the previously submitted errata, go to https://www.packtpub.com/books/


content/support and enter the name of the book in the search field. The required
information will appear under the Errata section.

Piracy
Piracy of copyrighted material on the Internet is an ongoing problem across all
media. At Packt, we take the protection of our copyright and licenses very seriously.
If you come across any illegal copies of our works in any form on the Internet, please
provide us with the location address or website name immediately so that we can
pursue a remedy.

Please contact us at [email protected] with a link to the suspected


pirated material.

We appreciate your help in protecting our authors and our ability to bring you
valuable content.

Questions
If you have a problem with any aspect of this book, you can contact us at
[email protected], and we will do our best to address the problem.

[ ix ]

www.it-ebooks.info
www.it-ebooks.info
Getting Started with Jasmine
It is an exciting time to be a JavaScript developer; technologies have matured,
web browsers are more standardized, and there are new things to play with every
day. JavaScript has become an established language, and the Web is the true
open platform of today. We've seen the rise of single-page web applications, the
proliferation of Model View Controller (MVC) frameworks, such as Backbone.js
and AngularJS, the use of JavaScript on the server with Node.js, and even mobile
applications created entirely with HTML, JavaScript, and CSS using technologies
such as PhoneGap.

From its humble beginnings with handling HTML forms, to the massive applications
of today, the JavaScript language has come very far, and with it, a number of tools
have matured to ensure that you can have the same level of quality with it that you
have with any other language.

This book is about the tools that keep you in control of your JavaScript development.

JavaScript – the bad parts


There are many complications when dealing with client JavaScript code; the obvious
one, is that you cannot control the client's runtime. While on the server, you can
run a specific version of your Node.js server, you can't oblige your clients to run the
latest version of Chrome or Firefox.

The JavaScript language is defined by the ECMAScript specification; therefore, each


browser can have its own implementation of a runtime, which means there could be
small differences or bugs between them.

[1]

www.it-ebooks.info
Getting Started with Jasmine

Besides that, you have issues with the language itself. Brendan Eich developed
JavaScript in just 10 days, under a lot of management pressure at Netscape. Although
it got itself right in its simplicity, first-class functions, and object prototypes, it also
introduced some problems with the attempt to make the language malleable and
allow it to evolve.

Every JavaScript object is mutable; this means that there is nothing you can do to
prevent a module from overwriting pieces of other modules. The following code
illustrates how simple it is to overwrite the global console.log function:
console.log('test');
>> 'test'
console.log = 'break';
console.log('test');
>> TypeError: Property 'log' of object #<Console> is not a function

This was a conscious decision on the language design; it allows developers to tinker
and add missing functionality to the language. But given such power, it is relatively
easy to make a mistake.

Version 5 of the ECMA specification introduced the Object.seal function, which


prevents further changes on any object once called. But its current support is not
widespread; Internet Explorer, for example, only implemented it on its version 9.

Another problem, is with how JavaScript deals with type. In other languages, an
expression like '1' + 1 would probably raise an error; in JavaScript, due to some
non-intuitive type coercion rules, the aforementioned code results in '11'. But the
main problem is in its inconsistency; on multiplication, a string is converted into a
number, so '3' * 4, is actually 12.

This can lead to some hard-to-find problems on big expressions. Suppose you have
some data coming from a server, and although you are expecting numbers, one value
came as a string:
var a = 1, b = '2', c = 3, d = 4;
var result = a + b + c * d;

The resulting value of the preceding example is '1212', a string.

These are just two common problems faced by developers. Throughout the book,
you are going to apply best practices and write tests to guarantee that you don't fall
into these, and other, pitfalls.

[2]

www.it-ebooks.info
Chapter 1

Jasmine and behavior-driven


development
Jasmine is a little behavior-driven development (BDD) test framework created by
the developers at Pivotal Labs, to allow you to write automated JavaScript unit tests.

But before we can go any further, first we need to get some fundamentals right,
starting with what a test unit is.

A test unit is a piece of code that tests a functionality unit of the application code. But
sometimes, it can be tricky to understand what a functionality unit can be, so for that
reason, Dan North came up with a solution in the form of BDD, which is a rethink of
test-driven development (TDD).

In traditional unit testing practice, the developer is left with loose guidelines on how
to start the process of testing, what to test, how big a test should be, or even how to
call a test.

To fix these problems, Dan took the concept of user stories from the standard agile
construct, as a model on how to write tests.

For example, a music player application could have an acceptance criterion such as:

Given a player, when the song has been paused, then it should indicate that the
song is currently paused.

As shown in the following list, this acceptance criterion is written following an


underlying pattern:

• Given: This provides an initial context


• When: This defines the event that occurs
• Then: This ensures an outcome

In Jasmine, this translates into a very expressive language that allows tests to be
written in a way that reflects actual business values. The preceding acceptance
criterion written as a Jasmine test unit would be as follows:
describe("Player", function() {
describe("when song has been paused", function() {
it("should indicate that the song is paused", function() {

});
});
});

[3]

www.it-ebooks.info
Getting Started with Jasmine

You can see how the criterion translates well into the Jasmine syntax. In the next
chapter, we will get into the details of how these functions work.

With Jasmine, as with other BDD frameworks, each acceptance criterion directly
translates to a test unit. For that reason, each test unit is usually called a spec, short
for specification. During the course of this book, we will be using this terminology.

Downloading Jasmine
Getting started with Jasmine is actually pretty simple.

Open the Jasmine website at http://jasmine.github.io/2.1/introduction.


html#section-Downloads and download the Standalone Release (version 2.1.3 is
going to be used in the book).

While at the Jasmine website, you might notice that it is actually a live page
executing the specs contained in it. This is made possible by the simplicity of the
Jasmine framework, allowing it to be executed in the most diverse environments.

After you've downloaded the distribution and uncompressed it, you can open the
SpecRunner.html file on your browser. It will show the results of a sample test
suite (including the acceptance criterion we showed you earlier):

This shows the SpecRunner.html file opened on the browser

This SpecRunner.html file is a Jasmine browser spec runner. It is a simple HTML file
that references the Jasmine code, the source files, and the test files. For convention
purposes, we are going to refer to this file simply as runner.

[4]

www.it-ebooks.info
Chapter 1

You can see how simple it is by opening it on a text editor. It is a small HTML file
that references the Jasmine source:
<script src="lib/jasmine-2.1.3/jasmine.js"></script>
<script src="lib/jasmine-2.1.3/jasmine-html.js"></script>
<script src="lib/jasmine-2.1.3/boot.js"></script>

The runner references the source files:


<script type="text/javascript" src="src/Player.js"></script>
<script type="text/javascript" src="src/Song.js"></script>

The runner references a special SpecHelper.js file that contains code shared
between specs:
<script type="text/javascript" src="spec/SpecHelper.js"></script>

The runner also references the spec files:


<script type="text/javascript" src="spec/PlayerSpec.js"></script>

Downloading the example code


You can download the example code files for all Packt books you have
purchased from your account at http://www.packtpub.com. If you
purchased this book elsewhere, you can visit http://www.packtpub.
com/support and register to have the files e-mailed directly to you.

The Jasmine framework is set up inside the lib/jasmine-2.1.3/boot.js file, and


although it's an extensive file, most of its content is in documentation on how the
setup actually happens. It is recommended that you open it in a text editor and study
its content.

Although, for now, we are running the specs in the browser, in Chapter 8, Build
Automation, we are going to make the same specs and code run on a headless
browser, such as PhantomJS, and have the results written on the console.

A headless browser is a browser environment without its graphical user interface.


It can either be an actual browser environment, such as PhantomJS, which uses the
WebKit rendering engine, or a simulated browser environment, such as Envjs.

And although not covered in this book, Jasmine can also be used to test server-side
JavaScript code written for environments such as Node.js.

This Jasmine flexibility is amazing, because you can use the same tool to test all sorts
of JavaScript code.

[5]

www.it-ebooks.info
Getting Started with Jasmine

Summary
In this chapter, you saw some of the motivations behind testing a JavaScript
application. I showed you some common pitfalls of the JavaScript language
and how BDD and Jasmine both help you to write better tests.

You have also seen how easy it is to download and get started with Jasmine.

In the next chapter, you are going to learn how to think in BDD and code your
very first spec.

[6]

www.it-ebooks.info
Your First Spec
This chapter is about the basics, and we are going to guide you through how to write
your first spec, think in test-first terms for development, and also show you all the
available global Jasmine functions. By the end of the chapter, you should know how
Jasmine works and be ready to start doing your first tests by yourself.

The Investment Tracker application


To get you started, we need an example scenario: consider that you are developing
an application to track investments in the stock market.

The following screenshot of the form illustrates how a user might create a new
investment on this application:

This is a form to add investments

This form will allow the input of three values that define an investment:

• First, we will input Symbol, which represents which company (stock) the
user is investing in
• Then, we will input how many Shares the user has bought (or invested in)
• Finally, we will input how much the user has paid for each share
(Share price)

[7]

www.it-ebooks.info
Your First Spec

If you are unfamiliar with how the stock market works, imagine you are shopping
for groceries. To make a purchase, you must specify what you are buying, how many
items you are buying, and how much you are going to pay. These concepts translate
to an investment as:

• A stock, which is defined by a symbol, such as PETO, can be understood to be


a grocery type
• The number of shares is the quantity of items you have purchased
• The share price is the unit price of each item

Once the user has added an investment, it must be listed along with their other
investments, as shown in the following screenshot:

This is a form and list of investments

The idea is to display how well their investments are going. Since the prices of the
stocks fluctuate over time, the difference between the price the user has paid and
the current price indicates whether it is a good (profit) or a bad (loss) investment.

In the preceding screenshot, we can see that the user has two investments:

• One is in the AOUE stock, which is scoring a profit of 101.80%


• Another is in the PETO stock, which is scoring a loss of -42.34%

This is a very simple application, and we will get a deeper understanding of its
functionality as we go on with its development.

Jasmine basics and thinking in BDD


Based on the application presented previously, we can start writing acceptance
criteria that define investment:

• Given an investment, it should be of a stock


• Given an investment, it should have the invested shares' quantity

[8]

www.it-ebooks.info
Chapter 2

• Given an investment, it should have the share price paid


• Given an investment, it should have a cost

Using the standalone distribution downloaded in the previous chapter, the first
thing we need to do is create a new spec file. This file can be created anywhere,
but it is a good idea to stick to a convention, and Jasmine already has a good one:
specs should be in the /spec folder. Create an InvestmentSpec.js file and add
the following lines:
describe("Investment", function() {

});

The describe function is a global Jasmine function used to define test contexts.
When used as the first call in a spec, it creates a new test suite (a collection of test
cases). It accepts two parameters, which are as follows:

• The name of the test suite—in this case, Investment


• A function that will contain all its specs

Then, to translate the first acceptance criterion (given an investment, it should be of


a stock) into a Jasmine spec (or test case), we are going to use another global Jasmine
function called it:
describe("Investment", function() {
it("should be of a stock", function() {

});
});

It also accepts two parameters, which are as follows:

• The title of the spec—in this case, should be of a stock


• A function that will contain the spec code

To run this spec, add it to the runner, as follows:


<!-- include spec files here... -->
<script type="text/javascript" src="spec/InvestmentSpec.js"></script>

[9]

www.it-ebooks.info
Your First Spec

Execute the spec by opening the runner on the browser. The following output
can be seen:

This is the first spec's passing result on the browser

It might sound strange to have an empty spec passing, but in Jasmine, as with other
test frameworks, a failed assertion is required to make the spec fail.

An assertion (or expectation) is a comparison between two values that must result
in a boolean value. The assertion is only considered a success if the result of the
comparison is true.

In Jasmine, assertions are written using the global Jasmine function expect, along
with a matcher that indicates what comparison must be made with the values.

Regarding the current spec (it is expected that the investment is of a stock), in
Jasmine this translates to the following code:
describe("Investment", function() {
it("should be of a stock", function() {
expect(investment.stock).toBe(stock);
});
});

Add the preceding highlighted code to the InvestmentSpec.js file. The expect
function takes only one parameter, which defines the actual value, or in other words,
what is going to be tested—investment.stock—and expects the chaining call to a
matcher function, which in this case is toBe. That defines the expected value, stock,
and the comparison method to be performed (to be the same).

Behind the scenes, Jasmine makes a comparison to check whether the actual value
(investment.stock) and expected value (stock) are the same, and if they are not,
the test fails.

[ 10 ]

www.it-ebooks.info
Chapter 2

With the assertion written, the spec that previously passed has now failed, as shown
in the following screenshot:

This shows the first spec's failure results

This spec failed because, as the error message states, investment is not defined.

The idea here is to do only what the error is indicating us to do, so although you
might feel the urge to write something else, for now let's just create this investment
variable with an Investment instance in the InvestmentSpec.js file, as follows:
describe("Investment", function() {
it("should be of a stock", function() {
var investment = new Investment();
expect(investment.stock).toBe(stock);
});
});

Don't worry that the Investment() function doesn't exist yet; the spec is about to
ask for it on the next run, as follows:

Here the spec asks for an Investment class

You can see that the error has changed to Investment is not defined. It now asks
for the Investment function. So, create a new Investment.js file in the src folder
and add it to the runner, as shown in the following code:
<!-- include source files here... -->
<script type="text/javascript" src="src/Investment.js"></script>

[ 11 ]

www.it-ebooks.info
Your First Spec

To define Investment, write the following constructor function in the Investment.


js file inside the src folder:

function Investment () {};

This makes the error change. It now complains about the missing stock variable, as
shown in the following screenshot:

This shows a missing stock error

One more time, we feed the code it is asking for into the InvestmentSpec.js file,
as shown in the following code:
describe("Investment", function() {
it("should be of a stock", function() {
var stock = new Stock();
var investment = new Investment();
expect(investment.stock).toBe(stock);
});
});

The error changes again; this time it is about the missing Stock function:

Here the spec asks for a Stock class

Create a new file in the src folder, name it Stock.js, and add it to the runner. Since
the Stock function is going to be a dependency of Investment, we should add it just
before Investment.js:
<!-- include source files here... -->
<script type="text/javascript" src="src/Stock.js"></script>
<script type="text/javascript" src="src/Investment.js"></script>

[ 12 ]

www.it-ebooks.info
Chapter 2

Write the Stock constructor function to the Stock.js file:


function Stock () {};

Finally, the error is about the expectation, as shown in the following screenshot:

The expectation is undefined to be Stock

To fix this and complete this exercise, open the Investment.js file inside the src
folder, and add the reference to the stock parameter:
function Investment (stock) {
this.stock = stock;
};

In the spec file, pass stock as a parameter to the Investment function:


describe("Investment", function() {
it("should be of a stock", function() {
var stock = new Stock();
var investment = new Investment(stock);
expect(investment.stock).toBe(stock);
});
});

Finally, you will have a passing spec:

This shows an Investment spec that passes

This exercise was meticulously conducted to show how a developer works by


feeding the spec with what it wants when doing test-first development.

The drive to write code must come from a spec that has failed. You
must not write code unless its purpose is to fix a failed spec.

[ 13 ]

www.it-ebooks.info
Your First Spec

Setup and teardown


There are three more acceptance criteria to be implemented. The next in the list is
as follows:

"Given an investment, it should have the invested shares' quantity."

Writing it should be as simple as the previous spec was. In the InvestmentSpec.js


file inside the spec folder, you can translate this new criterion into a new spec called
should have the invested shares' quantity, as follows:

describe("Investment", function() {
it("should be of a stock", function() {
var stock = new Stock();
var investment = new Investment({
stock: stock,
shares: 100
});
expect(investment.stock).toBe(stock);
});

it("should have the invested shares' quantity", function() {


var stock = new Stock();
var investment = new Investment({
stock: stock,
shares: 100
});
expect(investment.shares).toEqual(100);
});
});

You can see that apart from having written the new spec, we have also changed the
call to the Investment constructor to support the new shares parameter.

To do so, we used an object as a single parameter in the constructor to simulate


named parameters, a feature JavaScript doesn't have natively.

Implementing this in the Investment function is pretty simple—instead of having


multiple parameters on the function declaration, it has only one, which is expected
to be an object. Then, the function probes each of its expected parameters from this
object, making the proper assignments, as shown here:
function Investment (params) {
this.stock = params.stock;
};

[ 14 ]

www.it-ebooks.info
Chapter 2

The code is now refactored. We can run the tests to see that only the new spec fails,
as shown here:

This shows the failing shares spec

To fix this, change the Investment constructor to make the assignment to the shares
property, as follows:
function Investment (params) {
this.stock = params.stock;
this.shares = params.shares;
};

Finally, everything on your screen is green:

This shows the passing shares spec

But as you can see, the following code, which instantiates Stock and Investment, is
duplicated on both specs:
var stock = new Stock();
var investment = new Investment({
stock: stock,
shares: 100
});

To eliminate this duplication, Jasmine provides another global function called


beforeEach that, as the name states, is executed once before each spec. So, for
these two specs, it will run twice—once before each spec.

[ 15 ]

www.it-ebooks.info
Your First Spec

Refactor the previous specs by extracting the setup code using the beforeEach
function:
describe("Investment", function() {
var stock, investment;

beforeEach(function() {
stock = new Stock();
investment = new Investment({
stock: stock,
shares: 100
});
});

it("should be of a stock", function() {


expect(investment.stock).toBe(stock);
});

it("should have the invested shares quantity", function() {


expect(investment.shares).toEqual(100);
});
});

This looks much cleaner; we not only removed the code duplication, but also
simplified the specs. They became much easier to read and maintain since their
only responsibility now is to fulfill the expectation.

There is also a teardown function (afterEach) that sets the code to be executed after
each spec. It is very useful in situations where a cleanup is required after each spec.
We will see an example of its application in Chapter 6, Light Speed Unit Testing.

To finish the specification of Investment, add the remaining two specs to the
InvestmentSpec.js file, inside the spec folder:

describe("Investment", function() {
var stock;
var investment;

beforeEach(function() {
stock = new Stock();
investment = new Investment({
stock: stock,
shares: 100,
sharePrice: 20

[ 16 ]

www.it-ebooks.info
Chapter 2

});
});

//... other specs

it("should have the share paid price", function() {


expect(investment.sharePrice).toEqual(20);
});

it("should have a cost", function() {


expect(investment.cost).toEqual(2000);
});
});

Run the specs to see them fail, as shown in the following screenshot:

This shows the failing cost and price specs

Add the following code to fix them in the Investment.js file inside the src folder:
function Investment (params) {
this.stock = params.stock;
this.shares = params.shares;
this.sharePrice = params.sharePrice;
this.cost = this.shares * this.sharePrice;
};

[ 17 ]

www.it-ebooks.info
Your First Spec

Run the specs for the last time to see them pass:

This shows all four Investment specs passing

It is important to always see a spec fail before writing the code to fix it;
otherwise, how would you know that you really need to fix it? Imagine
this as a way to test the test.

Nested describes
Nested describes are useful when you want to describe similar behavior between
specs. Suppose we want the following two new acceptance criteria:

• Given an investment, when its stock share price valorizes, it should have
a positive return on investment (ROI)
• Given an investment, when its stock share price valorizes, it should be
a good investment

Both these criteria share the same behavior when the investment's stock share
price valorizes.

To translate this into Jasmine, you can nest a call to the describe function inside the
existing one in the InvestmentSpec.js file (I removed the rest of the code for the
purpose of demonstration; it is still there):
describe("Investment", function()
describe("when its stock share price valorizes", function() {

});
});

It should behave just like the outer one, so you can add specs (it) and use the setup
and teardown functions (beforeEach, afterEach).

[ 18 ]

www.it-ebooks.info
Chapter 2

Setup and teardown


When using the setup and teardown functions, Jasmine respects the outer setup and
teardown functions as well, so that they are run as expected. For each spec (it), the
following actions are performed:

• Jasmine runs all setup functions (beforeEach) from the outside in


• Jasmine runs a spec code (it)
• Jasmine runs all the teardown functions (afterEach) from the inside out

So, we can add a setup function to this new describe function that changes the
share price of the stock, so that it's greater than the share price of the investment:
describe("Investment", function() {
var stock;
var investment;

beforeEach(function() {
stock = new Stock();
investment = new Investment({
stock: stock,
shares: 100,
sharePrice: 20
});
});

describe("when its stock share price valorizes", function() {


beforeEach(function() {
stock.sharePrice = 40;
});
});
});

Coding a spec with shared behavior


Now that we have the shared behavior implemented, we can start coding the
acceptance criteria described earlier. Each is, just as before, a call to the global
Jasmine function it:
describe("Investment", function() {
describe("when its stock share price valorizes", function() {
beforeEach(function() {
stock.sharePrice = 40;
});

[ 19 ]

www.it-ebooks.info
Your First Spec

it("should have a positive return of investment", function() {


expect(investment.roi()).toEqual(1);
});

it("should be a good investment", function() {


expect(investment.isGood()).toEqual(true);
});
});
});

After adding the missing functions to Investment in the Investment.js file:


Investment.prototype.roi = function() {
return (this.stock.sharePrice - this.sharePrice) / this.sharePrice;
};

Investment.prototype.isGood = function() {
return this.roi() > 0;
};

You can run the specs and see that they pass:

This shows the nested describe specs pass

Understanding matchers
By now, you've already seen plenty of usage examples for matchers and probably
can feel how they work.

You have seen how to use the toBe and toEqual matchers. These are the two
base built-in matchers available in Jasmine, but we can extend Jasmine by writing
matchers of our own.

So, to really understand how Jasmine matchers work, we need to create one ourselves.

[ 20 ]

www.it-ebooks.info
Chapter 2

Custom matchers
Consider this expectation from the previous section:
expect(investment.isGood()).toEqual(true);

Although it works, it is not very expressive. Imagine if we could instead rewrite it as:
expect(investment).toBeAGoodInvestment();

This creates a much better relation with the acceptance criterion:

So, here "should be a good investment" becomes "expect investment to be a


good investment".

Implementing it is quite simple. You do so by calling the jasmine.addMatchers


function—ideally inside a setup step (beforeEach).

Although you can put this new matcher definition inside the InvestmentSpec.js
file, Jasmine already has a default place to add custom matchers, the SpecHelper.js
file, inside the spec folder. If you are using Standalone Distribution, it already comes
with a sample custom matcher; delete it and let's start from scratch.

The addMatchers function accepts a single parameter—an object where each


attribute corresponds to a new matcher. So, to add the following new matcher,
change the contents of the SpecHelper.js file to the following:
beforeEach(function() {
jasmine.addMatchers({
toBeAGoodInvestment: function() {}
});
});

The function being defined here is not the matcher itself but a factory function
to build the matcher. Its purpose, once called is to return an object containing a
compare function, as follows:
jasmine.addMatchers({
toBeAGoodInvestment: function () {
return {
compare: function (actual, expected) {
// matcher definition
}
};
}
});

[ 21 ]

www.it-ebooks.info
Exploring the Variety of Random
Documents with Different Content
PLEASE READ THIS BEFORE YOU DISTRIBUTE OR USE THIS WORK

To protect the Project Gutenberg™ mission of promoting the free


distribution of electronic works, by using or distributing this work (or
any other work associated in any way with the phrase “Project
Gutenberg”), you agree to comply with all the terms of the Full
Project Gutenberg™ License available with this file or online at
www.gutenberg.org/license.

Section 1. General Terms of Use and


Redistributing Project Gutenberg™
electronic works
1.A. By reading or using any part of this Project Gutenberg™
electronic work, you indicate that you have read, understand, agree
to and accept all the terms of this license and intellectual property
(trademark/copyright) agreement. If you do not agree to abide by all
the terms of this agreement, you must cease using and return or
destroy all copies of Project Gutenberg™ electronic works in your
possession. If you paid a fee for obtaining a copy of or access to a
Project Gutenberg™ electronic work and you do not agree to be
bound by the terms of this agreement, you may obtain a refund from
the person or entity to whom you paid the fee as set forth in
paragraph 1.E.8.

1.B. “Project Gutenberg” is a registered trademark. It may only be


used on or associated in any way with an electronic work by people
who agree to be bound by the terms of this agreement. There are a
few things that you can do with most Project Gutenberg™ electronic
works even without complying with the full terms of this agreement.
See paragraph 1.C below. There are a lot of things you can do with
Project Gutenberg™ electronic works if you follow the terms of this
agreement and help preserve free future access to Project
Gutenberg™ electronic works. See paragraph 1.E below.
1.C. The Project Gutenberg Literary Archive Foundation (“the
Foundation” or PGLAF), owns a compilation copyright in the
collection of Project Gutenberg™ electronic works. Nearly all the
individual works in the collection are in the public domain in the
United States. If an individual work is unprotected by copyright law in
the United States and you are located in the United States, we do
not claim a right to prevent you from copying, distributing,
performing, displaying or creating derivative works based on the
work as long as all references to Project Gutenberg are removed. Of
course, we hope that you will support the Project Gutenberg™
mission of promoting free access to electronic works by freely
sharing Project Gutenberg™ works in compliance with the terms of
this agreement for keeping the Project Gutenberg™ name
associated with the work. You can easily comply with the terms of
this agreement by keeping this work in the same format with its
attached full Project Gutenberg™ License when you share it without
charge with others.

1.D. The copyright laws of the place where you are located also
govern what you can do with this work. Copyright laws in most
countries are in a constant state of change. If you are outside the
United States, check the laws of your country in addition to the terms
of this agreement before downloading, copying, displaying,
performing, distributing or creating derivative works based on this
work or any other Project Gutenberg™ work. The Foundation makes
no representations concerning the copyright status of any work in
any country other than the United States.

1.E. Unless you have removed all references to Project Gutenberg:

1.E.1. The following sentence, with active links to, or other


immediate access to, the full Project Gutenberg™ License must
appear prominently whenever any copy of a Project Gutenberg™
work (any work on which the phrase “Project Gutenberg” appears, or
with which the phrase “Project Gutenberg” is associated) is
accessed, displayed, performed, viewed, copied or distributed:
This eBook is for the use of anyone anywhere in the United
States and most other parts of the world at no cost and with
almost no restrictions whatsoever. You may copy it, give it away
or re-use it under the terms of the Project Gutenberg License
included with this eBook or online at www.gutenberg.org. If you
are not located in the United States, you will have to check the
laws of the country where you are located before using this
eBook.

1.E.2. If an individual Project Gutenberg™ electronic work is derived


from texts not protected by U.S. copyright law (does not contain a
notice indicating that it is posted with permission of the copyright
holder), the work can be copied and distributed to anyone in the
United States without paying any fees or charges. If you are
redistributing or providing access to a work with the phrase “Project
Gutenberg” associated with or appearing on the work, you must
comply either with the requirements of paragraphs 1.E.1 through
1.E.7 or obtain permission for the use of the work and the Project
Gutenberg™ trademark as set forth in paragraphs 1.E.8 or 1.E.9.

1.E.3. If an individual Project Gutenberg™ electronic work is posted


with the permission of the copyright holder, your use and distribution
must comply with both paragraphs 1.E.1 through 1.E.7 and any
additional terms imposed by the copyright holder. Additional terms
will be linked to the Project Gutenberg™ License for all works posted
with the permission of the copyright holder found at the beginning of
this work.

1.E.4. Do not unlink or detach or remove the full Project


Gutenberg™ License terms from this work, or any files containing a
part of this work or any other work associated with Project
Gutenberg™.

1.E.5. Do not copy, display, perform, distribute or redistribute this


electronic work, or any part of this electronic work, without
prominently displaying the sentence set forth in paragraph 1.E.1 with
active links or immediate access to the full terms of the Project
Gutenberg™ License.
1.E.6. You may convert to and distribute this work in any binary,
compressed, marked up, nonproprietary or proprietary form,
including any word processing or hypertext form. However, if you
provide access to or distribute copies of a Project Gutenberg™ work
in a format other than “Plain Vanilla ASCII” or other format used in
the official version posted on the official Project Gutenberg™ website
(www.gutenberg.org), you must, at no additional cost, fee or expense
to the user, provide a copy, a means of exporting a copy, or a means
of obtaining a copy upon request, of the work in its original “Plain
Vanilla ASCII” or other form. Any alternate format must include the
full Project Gutenberg™ License as specified in paragraph 1.E.1.

1.E.7. Do not charge a fee for access to, viewing, displaying,


performing, copying or distributing any Project Gutenberg™ works
unless you comply with paragraph 1.E.8 or 1.E.9.

1.E.8. You may charge a reasonable fee for copies of or providing


access to or distributing Project Gutenberg™ electronic works
provided that:

• You pay a royalty fee of 20% of the gross profits you derive from
the use of Project Gutenberg™ works calculated using the
method you already use to calculate your applicable taxes. The
fee is owed to the owner of the Project Gutenberg™ trademark,
but he has agreed to donate royalties under this paragraph to
the Project Gutenberg Literary Archive Foundation. Royalty
payments must be paid within 60 days following each date on
which you prepare (or are legally required to prepare) your
periodic tax returns. Royalty payments should be clearly marked
as such and sent to the Project Gutenberg Literary Archive
Foundation at the address specified in Section 4, “Information
about donations to the Project Gutenberg Literary Archive
Foundation.”

• You provide a full refund of any money paid by a user who


notifies you in writing (or by e-mail) within 30 days of receipt that
s/he does not agree to the terms of the full Project Gutenberg™
License. You must require such a user to return or destroy all
copies of the works possessed in a physical medium and
discontinue all use of and all access to other copies of Project
Gutenberg™ works.

• You provide, in accordance with paragraph 1.F.3, a full refund of


any money paid for a work or a replacement copy, if a defect in
the electronic work is discovered and reported to you within 90
days of receipt of the work.

• You comply with all other terms of this agreement for free
distribution of Project Gutenberg™ works.

1.E.9. If you wish to charge a fee or distribute a Project Gutenberg™


electronic work or group of works on different terms than are set
forth in this agreement, you must obtain permission in writing from
the Project Gutenberg Literary Archive Foundation, the manager of
the Project Gutenberg™ trademark. Contact the Foundation as set
forth in Section 3 below.

1.F.

1.F.1. Project Gutenberg volunteers and employees expend


considerable effort to identify, do copyright research on, transcribe
and proofread works not protected by U.S. copyright law in creating
the Project Gutenberg™ collection. Despite these efforts, Project
Gutenberg™ electronic works, and the medium on which they may
be stored, may contain “Defects,” such as, but not limited to,
incomplete, inaccurate or corrupt data, transcription errors, a
copyright or other intellectual property infringement, a defective or
damaged disk or other medium, a computer virus, or computer
codes that damage or cannot be read by your equipment.

1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except


for the “Right of Replacement or Refund” described in paragraph
1.F.3, the Project Gutenberg Literary Archive Foundation, the owner
of the Project Gutenberg™ trademark, and any other party
distributing a Project Gutenberg™ electronic work under this
agreement, disclaim all liability to you for damages, costs and
expenses, including legal fees. YOU AGREE THAT YOU HAVE NO
REMEDIES FOR NEGLIGENCE, STRICT LIABILITY, BREACH OF
WARRANTY OR BREACH OF CONTRACT EXCEPT THOSE
PROVIDED IN PARAGRAPH 1.F.3. YOU AGREE THAT THE
FOUNDATION, THE TRADEMARK OWNER, AND ANY
DISTRIBUTOR UNDER THIS AGREEMENT WILL NOT BE LIABLE
TO YOU FOR ACTUAL, DIRECT, INDIRECT, CONSEQUENTIAL,
PUNITIVE OR INCIDENTAL DAMAGES EVEN IF YOU GIVE
NOTICE OF THE POSSIBILITY OF SUCH DAMAGE.

1.F.3. LIMITED RIGHT OF REPLACEMENT OR REFUND - If you


discover a defect in this electronic work within 90 days of receiving it,
you can receive a refund of the money (if any) you paid for it by
sending a written explanation to the person you received the work
from. If you received the work on a physical medium, you must
return the medium with your written explanation. The person or entity
that provided you with the defective work may elect to provide a
replacement copy in lieu of a refund. If you received the work
electronically, the person or entity providing it to you may choose to
give you a second opportunity to receive the work electronically in
lieu of a refund. If the second copy is also defective, you may
demand a refund in writing without further opportunities to fix the
problem.

1.F.4. Except for the limited right of replacement or refund set forth in
paragraph 1.F.3, this work is provided to you ‘AS-IS’, WITH NO
OTHER WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR ANY PURPOSE.

1.F.5. Some states do not allow disclaimers of certain implied


warranties or the exclusion or limitation of certain types of damages.
If any disclaimer or limitation set forth in this agreement violates the
law of the state applicable to this agreement, the agreement shall be
interpreted to make the maximum disclaimer or limitation permitted
by the applicable state law. The invalidity or unenforceability of any
provision of this agreement shall not void the remaining provisions.
1.F.6. INDEMNITY - You agree to indemnify and hold the
Foundation, the trademark owner, any agent or employee of the
Foundation, anyone providing copies of Project Gutenberg™
electronic works in accordance with this agreement, and any
volunteers associated with the production, promotion and distribution
of Project Gutenberg™ electronic works, harmless from all liability,
costs and expenses, including legal fees, that arise directly or
indirectly from any of the following which you do or cause to occur:
(a) distribution of this or any Project Gutenberg™ work, (b)
alteration, modification, or additions or deletions to any Project
Gutenberg™ work, and (c) any Defect you cause.

Section 2. Information about the Mission of


Project Gutenberg™
Project Gutenberg™ is synonymous with the free distribution of
electronic works in formats readable by the widest variety of
computers including obsolete, old, middle-aged and new computers.
It exists because of the efforts of hundreds of volunteers and
donations from people in all walks of life.

Volunteers and financial support to provide volunteers with the


assistance they need are critical to reaching Project Gutenberg™’s
goals and ensuring that the Project Gutenberg™ collection will
remain freely available for generations to come. In 2001, the Project
Gutenberg Literary Archive Foundation was created to provide a
secure and permanent future for Project Gutenberg™ and future
generations. To learn more about the Project Gutenberg Literary
Archive Foundation and how your efforts and donations can help,
see Sections 3 and 4 and the Foundation information page at
www.gutenberg.org.

Section 3. Information about the Project


Gutenberg Literary Archive Foundation
The Project Gutenberg Literary Archive Foundation is a non-profit
501(c)(3) educational corporation organized under the laws of the
state of Mississippi and granted tax exempt status by the Internal
Revenue Service. The Foundation’s EIN or federal tax identification
number is 64-6221541. Contributions to the Project Gutenberg
Literary Archive Foundation are tax deductible to the full extent
permitted by U.S. federal laws and your state’s laws.

The Foundation’s business office is located at 809 North 1500 West,


Salt Lake City, UT 84116, (801) 596-1887. Email contact links and up
to date contact information can be found at the Foundation’s website
and official page at www.gutenberg.org/contact

Section 4. Information about Donations to


the Project Gutenberg Literary Archive
Foundation
Project Gutenberg™ depends upon and cannot survive without
widespread public support and donations to carry out its mission of
increasing the number of public domain and licensed works that can
be freely distributed in machine-readable form accessible by the
widest array of equipment including outdated equipment. Many small
donations ($1 to $5,000) are particularly important to maintaining tax
exempt status with the IRS.

The Foundation is committed to complying with the laws regulating


charities and charitable donations in all 50 states of the United
States. Compliance requirements are not uniform and it takes a
considerable effort, much paperwork and many fees to meet and
keep up with these requirements. We do not solicit donations in
locations where we have not received written confirmation of
compliance. To SEND DONATIONS or determine the status of
compliance for any particular state visit www.gutenberg.org/donate.

While we cannot and do not solicit contributions from states where


we have not met the solicitation requirements, we know of no
prohibition against accepting unsolicited donations from donors in
such states who approach us with offers to donate.

International donations are gratefully accepted, but we cannot make


any statements concerning tax treatment of donations received from
outside the United States. U.S. laws alone swamp our small staff.

Please check the Project Gutenberg web pages for current donation
methods and addresses. Donations are accepted in a number of
other ways including checks, online payments and credit card
donations. To donate, please visit: www.gutenberg.org/donate.

Section 5. General Information About Project


Gutenberg™ electronic works
Professor Michael S. Hart was the originator of the Project
Gutenberg™ concept of a library of electronic works that could be
freely shared with anyone. For forty years, he produced and
distributed Project Gutenberg™ eBooks with only a loose network of
volunteer support.

Project Gutenberg™ eBooks are often created from several printed


editions, all of which are confirmed as not protected by copyright in
the U.S. unless a copyright notice is included. Thus, we do not
necessarily keep eBooks in compliance with any particular paper
edition.

Most people start at our website which has the main PG search
facility: www.gutenberg.org.

This website includes information about Project Gutenberg™,


including how to make donations to the Project Gutenberg Literary
Archive Foundation, how to help produce our new eBooks, and how
to subscribe to our email newsletter to hear about new eBooks.
Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade

Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.

Let us accompany you on the journey of exploring knowledge and


personal growth!

ebooknice.com

You might also like