Thursday, March 17, 2016

Typescript tips & testing with Mochai & Chai

I describe how to setup a testing environment for Typescript with Mocha and Chai, using Atom as my editor and node.js for the Typescript transpiler/compiler.

This article uses Windows 7, but most of it applies to Linux and OSX as well.

To setup a test environment for testing Typescript code with Mocha and Chai, I installed:
- node.js https://nodejs.org/
- the Typescript transpiler package inside node https://www.npmjs.com/package/typescript

I use nodejs v4.1.0 but the Typescript transpiler is probably fine with other previous versions.

To install or update the typescript package on node:
> npm install -g typescript
C:\Users\User\AppData\Roaming\npm\tsc -> C:\Users\User\AppData\Roaming\npm\node_modules\typescript\bin\tsc
C:\Users\User\AppData\Roaming\npm\tsserver -> C:\Users\User\AppData\Roaming\npm\node_modules\typescript\bin\tsserver
typescript@1.8.9 C:\Users\User\AppData\Roaming\npm\node_modules\typescript

To know the latest version of Typescript compiler package available on node:

> npm view typescript version
1.8.9

You can check the versions installed with the terminal commands:

for node:
> node -v
v4.1.0

to view the node packages installed globally installed on your node.js:

> npm list --depth=0
C:\Users\User\AppData\Roaming\npm
├── bower@1.5.2
├── elm-oracle@1.1.1
├── tsd@0.6.5
├── typescript@1.8.2
└── typings@0.7.8

for the typescript transpiler installed as the command line utility, the command is "tsc"
> where tsc.exe
C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.8\tsc.exe
> tsc -v
1.8.2

For the node tsc:
> where tsc
C:\Users\User\AppData\Roaming\npm\tsc
C:\Users\User\AppData\Roaming\npm\tsc.cmd
> tsc -v
Version 1.8.2

I also use Atom with the Typescript plugin to edit Typescript code https://atom.io/packages/atom-typescript . Be aware that the atom typescript plugin uses the latest version of the compiler directly from the development repository, see

https://github.com/TypeStrong/atom-typescript/blob/master/docs/faq.md#which-version-of-typescript-does-atom-typescript-use

"Which version of TypeScript does atom-typescript use?
It uses ntypescript which is just a build of Microsoft/Master. This means it's the latest and greatest of the TypeScript goodness. There is a possibility that in the future it will move to TypeScript nightlies but our current automation is working well."

Versions of Typescript differ greatly in features, so in doubt, use the "tsc" command to compile your code from the command line/terminal, you'll know exactly which version of typescript is used.

The compiler options are listed here:
https://github.com/Microsoft/TypeScript/wiki/Compiler-Options

The typescript compiler uses either the options you specify on the command line or a file called tsconfig.json. I recommend using that file, it makes compilation easier, specially with multiple files. The Atom plugin too uses it to compile your files when you save them in the editor or press F6.

the doc for tsconfig.json is located here:
https://github.com/Microsoft/TypeScript/wiki/tsconfig.json

The tsc compiler looks for the tsconfig.json file in the current directory and up the parent directories until it finds the tsconfig.json file.

------------------------------------------------------------------------
The tsconfig.json file for this simple test project is:

{
    "compilerOptions": {
        "removeComments": true,
        "sourceMap": true
    },
    "files": [
        "mocha.d.ts",
        "chai.d.ts",
        "test.simpletypescript.ts"
    ]
}
------------------------------------------------------------------------

The compiler options are optional, they are here just to show how to use them. The "removeComments" option removes the comments in the output js file. It is practical to reduce the size of the js file for deployment. The "sourceMap" option generates the source map to help debugging with the browser. Check the available options here

The TypeScript Language Specification is at
https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md

The version at the time of this writing is "Version 1.8 January, 2016". Decorators/annotations (for Angular2) have been added in 1.5 and other features are added with each release, so keep an eye on this document.

To keep it simple here, instead of using the "typings" node package (see the note at the end of the article), I just downloaded the definition files for mocha and chai. you can search for the d.ts files your project requires with this page http://definitelytyped.org/tsd/

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/mocha/mocha.d.ts
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/chai/chai.d.ts

I copied them in the same directory as my source file, as shown in the "files" option of the tsconfig.json file above.

For the example, I have an index.html file which sets up and run mocha, and test.simpletypescript.ts, which contains the test code using chai.

------------------------------------------------------------------------
index.html:

<html>
<head>
  <meta charset="utf-8">
  <title>Mocha Tests</title>
  <link href="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.css" rel="stylesheet" />
</head>
<body>
  <div id="mocha"></div>

  <script src="https://cdn.rawgit.com/jquery/jquery/2.1.4/dist/jquery.min.js"></script>
  <script src="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.js"></script>
  <script src="https://cdn.rawgit.com/chaijs/chai/2.3.0/chai.js"></script>

<!--
The BDD interface provides describe(), context(), it(), before(), after(), beforeEach(), and afterEach().
"context() is just an alias for describe(), and behaves the same way; it just provides a way to keep tests easier to read and organized.
-->

<!-- if not present: "test.simpletypescript.ts:6 Uncaught ReferenceError: describe is not defined" in the web console -->
  <script>mocha.setup('bdd')</script>
  <script src="test.simpletypescript.js"></script>

  <script>
    mocha.checkLeaks();
    mocha.globals(['jQuery']);
    mocha.run();
  </script>
</body>
</html>
------------------------------------------------------------------------
test.simpletypescript.ts:

var expect = chai.expect; // MUST have that line to compile

describe('Simple Mocha Test', function() : void {
  console.log("Simple Mocha Test in TS");
  it('true should be true', function() : void {
    expect(true).to.be.true;
  });

  it('1 should not be true', function() : void {
    expect(1).to.not.be.true;
  });
});
------------------------------------------------------------------------
Opening the index.html file in your browser should show:

passes: 2 failures: 0 duration: 0.19s

Simple Mocha Test
true should be true ‣
1 should not be true

Another way to deal with definition files is to "import" them in the source code like this:
------------------------------------------------------------------------
test.simpletypescript.ts:

/// <reference path="mocha.d.ts"/>
/// <reference path="chai.d.ts"/>

var expect = chai.expect; // MUST have that line to compile

describe('Simple Mocha Test', function() : void {
  console.log("Simple Mocha Test in TS");
  it('true should be true', function() : void {
    expect(true).to.be.true;
  });

  it('1 should not be true', function() : void {
    expect(1).to.not.be.true;
  });
});
------------------------------------------------------------------------
and to remove them from the tsconfig.json file:

{
    "compilerOptions": {
        "removeComments": true,
        "sourceMap": true
    },
    "files": [
        "test.simpletypescript.ts"
    ]
}


------------------------------------------------------------------------

I prefer having them in the tsconfig.json file, should I have to modify them, I do it only in the tsconfig.json file, not in every single source file. Moreover, the project dependencies are clear when the definition files are only in the tsconfig.json file.
I hope this will help to get started with Typescript testing with Mocha and Chai in the browser.

Keep typescripting.

Notes:

TSD and TYPINGS:

When working with external javascript libraries/frameworks, we need to add the *.d.ts definition files with the ambient declarations. Until recently the node "tsd" package was used to download the d.ts files. It has been deprecated in favor of the "typings" package. tsd and typings use the same definition files from DefinitelyTyped https://github.com/DefinitelyTyped/DefinitelyTyped , which holds almost all defintion files you'll ever need. If not, you can always write your own.

Deprecation notice:
https://github.com/DefinitelyTyped/tsd/issues/269
https://github.com/DefinitelyTyped/tsd
"DEPRECATED: TSD is deprecated, please use Typings and see this issue for more information."

Typings:
https://github.com/typings/typings


Typescript extension for Visual Studio:

You can also install the Typescript compiler extension for Visual Studio 2103 or 2015
http://www.typescriptlang.org/#Download

Even if you don't install Visual Studio, the Typescript compiler will be installed and you can invoke it  on the command line with "tsc". If you have the VS extension installed, you'll get a second "tesc" compiler on your system, and chances are that the VS one will be invokde instead of your node compiler. So check you Windows path and tsc version when compiling to avoid pulling your hair out. I had 3 different versions of the compiler at some point: the one used by atom, the node package and the VS one. All different versions with significant different features. To disable the Visual Studio compiler extension, remove the typescript environment variable entry in the windows PATH. That will leave the way open to the node package compiler.

Friday, January 01, 2016

Angular2 Custom Events

Angular2 beta just came out and has events based on RxJS. Events are used in Inputs and Outputs and the docs show how to emit an event but not how to subscribe to them. You might need them for inter-service communication. There might be better options for that, but nowhere to find in the docs for now, the docs are being written at the moment.

The doc for EventEmitter is here:

https://angular.io/docs/ts/latest/api/core/EventEmitter-class.html

Digging in the code for EventEmitter

https://github.com/angular/angular/blob/2.0.0-beta.0/modules/angular2/src/facade/async.ts#L68-L164

allows to write some code like this in Typescript:

First, we need to import the EventEmitter class in each .ts file that uses events:

import {EventEmitter} from 'angular2/core';  

Then we can create an event emitter, a source, that we named ticktickevent:

asyncevent: boolean = true;  
ticktickevent: EventEmitter;

The only argument to EventEmitter(async: boolean) is a boolean specifying if the event needs to be treated synchronously, in that case the onNext, onError and onComplete callbacks are called right away, or asynchronously, meaning that the callbacks are put in the timeout queue and called after the UI events are completed. Use async = true if you are executing lengthy code in the callbacks, that leaves the priority to user events and should keep the UI responsive.

EventEmitter is a generic class, replace by the type of event that you want to emit. In our case, Object is used to keep things simple, since we emit events like this: {event: 'ticktick', data: 'fun'}. It would be best to declare a Typescript interface for the event, so Typescript can check that the proper object structure is used in all the calls. You could use EventEmitter or EventEmitter if your event is only a string or a number.

Then we subscribe to the event:

ticktickevent.subscribe(onNextEvent);  
 or  
ticktickevent.subscribe(onNextEvent, onErrorEvent);  
 or  
ticktickevent.subscribe(onNextEvent, onErrorEvent, onCompletedEvent);  

depending on your needs for all the callbacks or only some, The signature of the method is:

EventEmitter.subscribe(generatorOrNext?: any, error?: any, complete?: any) : any;  

The callbacks are like this:

onNextEvent(event) {  
   console.log("onNextEvent event: %o", event);  
  }  
 onErrorEvent(error) {  
   console.log("onErrorEvent error: %o", error);  
  }  
 onCompletedEvent() { // no param  
   console.log("onCompletedEvent");  
  }  

To generate a regular (not an error) event:

ticktickevent.next({'event': 'ticktick', 'data': 'fun'});

which will call

onNextEvent(event) with event = {'event': 'ticktick', 'data': 'fun'}

To trigger an error:

ticktickevent.error({'type': 'stream error', data: '42'});

which will call

onErrorEvent(error) with error = {'type': 'stream error', 'data': '42'}

and to complete (close) the event stream:

ticktickevent.complete();  

which in turn will call

onCompletedEvent();

with no argument.

That's it, you should be able to create an event emitter, emit events and subscribe to them.
You should be able to use that in Javascript as well, just drop all type indications in the code.

Sorry for the bad formatting, I'll fix it when I get some time.

Friday, May 22, 2015

Tuples and destructuring in TypeScript

I have been interested in TypeScript for a while, AngularJS 2 has put it on the developer's map now.

A feature that I look for in any of the new languages now is tuples and destructuring. It makes it easier to return multiple values from a function and assign it to different variables and not an array. TypeScript has it too, example:

TypeScript code:

function returnTuple(a: string, b: string) {
return [b, a];
}
var n = 'World!', m = 'Hello';
var p: string, q: string;
[p, q] = returnTuple(n, m);
alert("result: " + p + " " + q);

Generated Javascript code:

function returnTuple(a, b) {
    return [b, a];
}
var n = 'World!', m = 'Hello';
var p, q;
_a = returnTuple(n, m), p = _a[0], q = _a[1];
alert("result: " + p + " " + q);
var _a;

A run shows an alert with "Hello World!"
A bit like the Go playground, Typescript has one too: http://www.typescriptlang.org/Playground so you can test and play with the code there!

Thursday, June 12, 2014

Golang tip to check if a variable is an array: get the variable value with the reflect package and then the kind of the value: see http://play.golang.org/p/eUS6I4a50e

All possible kinds: http://golang.org/pkg/reflect/#Kind

If you know something simpler, let me know...

Code:

package main

import ("fmt"
"reflect")

func isArray(a interface{}) bool {
var v reflect.Value
v = reflect.ValueOf(a)
fmt.Println("a value: %T %v", v, v)

var k reflect.Kind
k = v.Kind()
fmt.Println("a kind: %T %v", k, k)

if (k == reflect.Array) {
return true
}
return false
}

func main() {
a := [...]string{"1","2"}
//a := "fred"
if (isArray(a)) {
fmt.Println("a is an array")
} else {
fmt.Println("a is NOT an array")
}

t := reflect.TypeOf(a)
fmt.Println("a type: %T %v", t, t)

var v reflect.Value
v = reflect.ValueOf(a)
fmt.Println("a value: %T %v", v, v)

var k reflect.Kind
k = v.Kind()
fmt.Println("a kind: %T %v", k, k)

}

Run:

a value: %T %v <[2]string Value> <[2]string Value>
a kind: %T %v array array
a is an array
a type: %T %v [2]string [2]string
a value: %T %v <[2]string Value> <[2]string Value>
a kind: %T %v array array

Tuesday, May 20, 2014

BigQuery Google App Engine (GAE) Java Example


I recently wrote a technical "How-to" on "Using the BigQuery API with Java in an Eclipse Project on the Google App Engine". The application uses a service account for authentication that allows an application to run without asking the user for specific credentials. It shows how to authenticate and make some API calls to BigQuery.

Being a servlet, the code is probably portable to another servlet container like Tomcat.

The project and code are here:


Happy BigQuerying!

Saturday, December 07, 2013

Optional boolean argument for a java method:

void testOptionalArgument(boolean ... flag) {
    if (flag == null) {
        log.info("optional flag null");
    } else {
        int length = flag.length;
        log.info("optional flag: " + flag + " length: " + length);
        if (length > 0) {
            log.info("optional flag: " + flag[0]);
        }
    }
}

Calling this method in 3 different ways:

testOptionalArgument(); // optional flag: [Z@ed3c51 length: 0
testOptionalArgument(true);  // optional flag: [Z@1131359 length: 1 optional flag: true
testOptionalArgument(false); // optional flag: [Z@15b3baf length: 1 optional flag: false


Sunday, June 02, 2013

How to remove the copy/print protection in a pdf file for free

Sometimes I download a document and to my surprise, I can't copy text from it or print the document. That protection is only the copy/print text of a pdf document, not a password protection that prevents opening the document if one doesn't have this password.

Here is a quite easy way, and free, to remove this copy/print protection. I saw it mentioned several years ago on the web, but now it is drowned in the flurry of links. It's for Windows, but you can changes the paths for Linux/MacOS.

- download and install ghostscript, the open source library for pdf http://www.ghostscript.com/
- open a console and set the current directory to the one where ghostscript was installed
- run the following line after changing the path/filename for your original file (the one with the restrictions) and the path/filename for the output file

gswin32c -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile="c:\noprotection.pdf" "c:\protected.pdf"
If you want to skip a few pages (like the "How to use this form", add the "-dFirstPage" option, it will output the document starting with the page specified. There is also a last page option, see the ghostscript manual.

gswin32c -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -dFirstPage=10 -sOutputFile="c:\noprotection.pdf" "c:\protected.pdf"

Links:
http://www.ghostscript.com/download/gsdnld.html
http://www.ghostscript.com/
http://www.ghostscript.com/doc/9.07/Use.htm#PDF