Tutorial – Getting started with TypeScript and Cocos2d-x JS – Part 2 – TSlint & Mocha

Tutorial – Getting started with TypeScript and Cocos2d-x JS – Part 2 – TSlint & Mocha

Back in part 1 of this tutorial , we set up a simple hello world project for TypeScript development. We briefly discussed the use of namespaces and triple slash directives as a way to avoid dependencies on external module loading.

The aim is to ensure compatibility with Cocos2d-x JSB by avoiding use of external modules due to require being a reserved word.  There is another way around this, you can use webpack, which will replace all require calls with __webpack_require__ in its output.

I think largely the choice between using namespaces and external modules is up to you, and will be based upon your projects unique requirements. The advice I have seen floating around is to pick one or the other.

Benefits I found in using the namespace approach:

  • When porting my Javascript project to TypeScript, the existing Javascript IIFE namespace patterns exhibited a one to one correspondence with their TypeScript equivalents, as a result the porting process was a breeze.
  • There are many existing  JavaScript  IIFE namespace  libraries that are just as easily ported to TypeScript namespaces.
  • Namespaces are a  simple and familiar concept to many developers
  • Namespaces can be split across multiple files
  • Namespaces are not broken, they work, just ensure you understand their limitations

Arguments for using external modules might include:

  • your projects unique build and code organisation requirements
  • projects that share code between client and server in a node environment
  • development of node packages
  • large scale web applications
  • projects that likely to have a high level of dependencies on other node packages
  • increased flexibility in code management and tooling
  • future proofing code that may in future fall into any of the above arguments

Some useful links for discussion on these topics:

https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Namespaces.md

http://stackoverflow.com/questions/30357634/how-do-i-use-namespaces-with-typescript-external-modules

http://blog.theburge.co/web/2016/02/21/bundling-typescript.html

 

Let us continue..

TSLint

We want to add tslint to our project to provide static analysis checks for our TypeScript.

Navigate to your project root folder. (use the project you created in part 1 of this tutorial or use the typescript-cocos2dx-hello-world project from the Git Repository)

Open up the command line and execute the following commands:

npm install –save-dev tslint
npm install –save-dev gulp-tslint

Open gulpfile.js and add the following code (changes have been highlighted):

var gulp = require("gulp");
var ts = require("gulp-typescript");
var tsProject = ts.createProject("tsconfig.json");

var gulpTslint = require("gulp-tslint");
var tslint = require("tslint");
 

gulp.task('lint', function() {
var program = tslint.Linter.createProgram("./tsconfig.json");
 
gulp.src('tssrc/**/*.ts', { base: '.' })
  .pipe(gulpTslint({ program })).pipe(gulpTslint.report());
});

gulp.task("default", function () {
    return tsProject.src()
        .pipe(tsProject())
        .js.pipe(gulp.dest("tsdist"));
});

Create a file named tslint.json and add the following json:

{
  "rules": {
    "class-name": true,
    "comment-format": [true, "check-space"],
    "curly": true,
    "eofline": true,
    "forin": true,
    "indent": [true, "spaces"],
    "label-position": true,
    "max-line-length": [true, 140],
    "member-access": true,
    "member-ordering": [true,
      "public-before-private",
      "static-before-instance",
      "variables-before-functions"
    ],
    "no-arg": true,
    "no-bitwise": true,
    "no-console": [true,
      "debug",
      "info",
      "time",
      "timeEnd",
      "trace"
    ],
    "no-construct": true,
    "no-debugger": true,
    "no-duplicate-variable": true,
    "no-empty": true,
    "no-eval": true,
    "no-inferrable-types": true,
    "no-shadowed-variable": false,
    "no-string-literal": true,
    "no-switch-case-fall-through": true,
    "no-trailing-whitespace": true,
    "no-unused-expression": true,
    "no-use-before-declare": true,
    "no-var-keyword": true,
    "object-literal-sort-keys": true,
    "no-for-in-array": true,
    "one-line": [true,
      "check-open-brace",
      "check-catch",
      "check-else",
      "check-finally",
      "check-whitespace"
    ],
    "quotemark": [true, "double", "avoid-escape"],
    "radix": true,
    "semicolon": true,
    "trailing-comma": [false, {
      "singleline": "never",
      "multiline": "always"
    }],
    "triple-equals": [true, "allow-null-check"],
    "typedef-whitespace": [true, {
      "call-signature": "nospace",
      "index-signature": "nospace",
      "parameter": "nospace",
      "property-declaration": "nospace",
      "variable-declaration": "nospace"
    }],
    "variable-name": false,
    "whitespace": [true,
      "check-branch",
      "check-decl",
      "check-operator",
      "check-separator",
      "check-type"
    ]
  }
}

Execute the following commands to verify that everything works:

gulp lint

gulp

node tsdist/main.js

Note: The linter can be quite strict about trailing white space. You can fix this by editing the file to add a trailing newline to the EOF and/or remove trailing whitespace from offending lines. Please refer to this post.

You now have tslint analysis set up. You will find the completed  typescript-cocos2dx-tslint project on the Git Repository).

To take this further you can also integrate your gulp tasks with Visual Studio Code. This will allow you to output lint reports in the problems panel.

I will do another article about Visual Studio Code integration at a later date.  In the meantime please see this page for further reading.

Mocha for TDD

Ok so we now have a base Hello World project with tslint and gulp ready for our TypeScript adventures.

Let us set up Mocha for TDD…

Navigate to your project root folder (use the project you created earlier or use the typescript-cocos2dx-tslint project from the Git Repository).

Open up the command line and execute the following commands:

npm install typings –global

typings install dt~mocha –global –save
npm install –save-dev gulp-mocha

Note: we have also installed the typings cli and added mocha typing’s to our project. This will allow us to reference mocha types in our unit tests. you should notice a new file named typings.json within your root folder. A folder named typings should also be present.

Note: you can add the typings folder to .gitignore, as all of the projects typing’s dependencies should be referenced within typings.json and can be resolved by navigating to your projects root folder and executing the following command:

typings install

Moving on…

Open up gulpfile.js and insert the following code (changes have been highlighted)

var gulp = require("gulp");
var ts = require("gulp-typescript");
var tsProject = ts.createProject("tsconfig.json");

var tsTestProject = ts.createProject("tsconfig.test.json");
const mocha = require('gulp-mocha');

var gulpTslint = require("gulp-tslint");
var tslint = require("tslint");
 
gulp.task('lint', function() {
var program = tslint.Linter.createProgram("./tsconfig.json");
 
gulp.src('tssrc/**/*.ts', { base: '.' })
  .pipe(gulpTslint({ program })).pipe(gulpTslint.report());
});


gulp.task('test', function () {

    return gulp.src('./tstest/*.spec.ts',
        {
            base: '.'
        })
        /*transpile*/
        .pipe(tsTestProject())
        /*flush to disk*/
        .pipe(gulp.dest('tsdist'))
        /*execute tests*/
        .pipe(mocha())
        .on("error", function(err) {
            console.log(err)
        });
});

gulp.task("default", function () {
    return tsProject.src()
        .pipe(tsProject())
        .js.pipe(gulp.dest("tsdist"));
});

You will notice that there is a reference to an alternative tsconfig file named tsconfig.test.json. We have added this tsconfig file so that our default build task can be built independently from our tests. This file references both the tstest directories and the tssrc directories and is used as part of our mocha test gulp task.

Navigate to your project root:

Create a file named tsconfig.test.json

Insert the following JSON:

{
    "files": [
        "tssrc/**/*.ts",
        "tstest/**/*spec.ts"
    ],
    "compilerOptions": {
        "noImplicitAny": true,
        "target": "es5",
        "module": "none",
        "outFile":"main.js"
    }

}

Our gulp task should now be ready.

Time to add some tests..

Adding Tests

Navigate to your project root:

Create a folder named tstest

Create a file named greet.spec.ts  within the tstest folder you have just created and insert the following code:

 /// <reference path="../typings/globals/mocha/index.d.ts" />
  /// <reference path="../tssrc/greet.ts" />

import sayHello = typescriptbase.sayHello;

describe('SayHello', () => {



    beforeEach(() => {
  
    });

    describe('sayHello', () => {

        it('should return concatinated string', () => {
            console.log(sayHello("TypeScript"));
        });
    });
});

Navigate  to your projects root directory and execute the following command:

gulp test

You should be presented with the results of your test and are now ready for TDD.

Ill see you in part 3 of this tutorial where we start to integrate with a Cocos2d-x JS project.

You will find the completed  typescript-cocos2dx-mocha project on the Git Repository).

 

Command Line Quick Reference

#when run from a project directory will execute the tasks specified within gulpfile.js
gulp

#initialises a folder into an npm package
npm init

#resolves all --save-dev dependencies for a package/project into the node_modules folder
npm install

#installs typescript globally into npm
npm install -g typescript

#installs gulp command line utility
npm install -g gulp-cli

#the --save-dev switch instructs npm to install gulp, typescript and gulp-typescript as dependencies for your project
npm install --save-dev typescript gulp gulp-typescript

#installs gulp-tslint lint as a dependency for your project
npm install --save-dev gulp-tslint

#installs tslint as a dependency for your project
npm install --save-dev tslint

#instructs node runime to run the main.js file
node tsdist/main.js

#installs typings cli
npm install typings --global

#installs typings for mocha
typings install dt~mocha --global --save

#installs mocha for gulp
npm install --save-dev gulp-mocha

 

References:

https://www.npmjs.com/package/gulp-tslint

https://www.npmjs.com/package/typings

https://github.com/typings/typings

https://github.com/sindresorhus/gulp-mocha

http://stackoverflow.com/questions/43164533/gulp-mocha-typescript-unit-test

https://marketplace.visualstudio.com/items?itemName=eg2.tslint

https://github.com/DanWahlin/AngularIn20TypeScript/blob/master/gulpfile.js

https://github.com/panuhorsmalahti/gulp-tslint/blob/master/tslint.json

https://github.com/panuhorsmalahti/gulp-tslint

https://github.com/palantir/tslint/issues/481

 

 

2 Replies to “Tutorial – Getting started with TypeScript and Cocos2d-x JS – Part 2 – TSlint & Mocha”

Leave a Reply

Your email address will not be published. Required fields are marked *