/typescript-tdd-exercises

A seed project to help learn TDD

Primary LanguageTypeScript

Overview Build Status

This project contains a set of exercises to help teach TDD. It will auto-compile your TypeScript code, run your tests and, enforce a minimum code coverage percentage (95%).

Installing and running

Clone this project. You'll need to install npm and change your current working directory to this folder.

Install all dependencies:

$ npm install

DO NOT use sudo in this step or you will have problems!

Setting up TypeScript watchers (compiles your code)

For these exercises, we will use Grunt to manage the build process.

Test that npm watch is working correctly:

$ npm run watch

You should see it "waiting..." If so, CTRL + C to break out and then run the tests manually:

$ npm test

If you see the following, your setup process is complete:

expected output

To get notifications working, you may need to install the following:

  1. Install Growl
  2. Run sudo gem install terminal-notifier

Seeing Code Coverage

You can see code coverage analysis in two ways:

  1. Make a change while grunt watch is on and read the console
  2. Run grunt test and read the console

Then visit the lcov report page (file will be missing if a coverage analysis has not been run)

Under the Hood

You can find all of the grunt configurations in the grunt folder. Here's what Grunt is doing:

  1. Compiled TypeScript output (JavaScript) goes to the out folder while preserving the original file/folder structure.
  2. All of the .js files are then copied (concatenated) to out/test.js and out/coverage.js file. The source maps are preserved.
  3. All out/src/**/*.js files are "instrumented" by Istanbul for code coverage analysis. The results are stored in out/instrument.
  4. Code coverage involves running all tests against this instrumented folder. The instrumented files are merged with test files and placed in out/coverage.js. The file is executed.
  5. Coverage results are captured in coverage/.
  6. Coverage thresholds are configured in grunt/coverage.js and the data is pulled from coverage/reports/coverage.json.
  7. If any grunt process fails (e.g., a test or a coverage threshold) an error is shown and the rest of the jobs stop.
  8. npm run watch watches for code changes that trigger the above steps automatically as necessary. It is meant to be noisy if you are not writing passing tests.

Exercises

  1. Exercise 1
  2. Exercise 2
  3. Exercise 3
  4. Exercise 4

Review the example project if you have questions about TypeScript.

Notes

TypeScript

/// <reference path="../../references.ts" />

Structure

  • Executed JS is not kept as separate files. This is to avoid the complexity of using Node's require syntax in a TypeScript environment (although entirely doable).
  • You can find example files at src/example/ and test/example/.
  • You can find instructions for individual exercises in the src/ folder.
  • TypeScript declarations are found in tsd.d.ts, and are managed using tsd. They are like .h files in other languages. If you end up using external libraries such as Underscore.js, you may want to install dependencies using tsd install [name] --save (more on this here: https://github.com/DefinitelyTyped/tsd)
  • Folders you may want to mark as excluded from your IDE's code index: out/, node_modules/, and coverage/.

Resources

  • This setup process borrows from the Typescript Starter repo
  • You need to install npm (node comes with it). This is because TypeScript compiles to JavaScript and without Node, you would need to run your code in a browser. Running sample snippets in a browser adds unnecessary complexity as compared to running Node scripts.
  • Testing is done using two libraries. One is Mocha, a framework for writing assertions (the assert variable). The other is Sinon, a stubbing and mocking library (the sinon and sandbox variables). See examples of this in Driver tests.
  • As a convenience, all test modules have a sandbox variable that you can use to make stubs. It will clean up your mocks and stubs after each test run. You can mostly ignore this, but if you are curious why this was setup, you can find more about it here.

Troubleshooting

If you are getting problems installing the npm packages, try fixing the directory permissions. Go to the working directory for the project:

sudo chown -R $USER ~/.npm # <== your user's npm cache folder
sudo chown -R $USER /usr/local/lib/node_modules # <== your global npm folder
sudo rm -Rf node_modules
npm install