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 the 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 are 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 the 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

tslint is a static analysis tool that will report upon readability, maintainability, and functionality errors with our TypeScript code.

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 the 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 set-up and ready for our TypeScript adventures.

Let us now 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 within 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 within our unit tests. you should also notice a new file named typings.json within your root folder. An additional folder named typings should also be present.

Note: you can add the typings folder to your .gitignore file, 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.

I’ll 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 *