problem trying to get tsUnit to work [solved]

Oct 5, 2015 at 3:24 PM
I am trying to make tsUnit work with our classes in our own namespace MyCompany, but can't seem to find a way to make it work... The following is a minimal code example that reproduces the problem I'm having:

In file ParameterTests.ts we have:
/// <reference path="references.ts" />

import * as tsUnit from "./Scripts/tsUnit/tsUnit"

namespace MyCompany
{
    export class ParameterTests extends tsUnit.TestClass
    {
        someSimpleTest()
        {
            this.areIdentical(3, this.addTwoNumbers(1, 2));
            this.areIdentical(2, this.addTwoNumbers(1, 2));
            console.log("Inside someSimpleTest");
        }

        private addTwoNumbers(num1: number, num2: number): number
        {
            return num1 + num2;
        }
    }
}
and then in the application file app.ts we have:
/// <reference path="references.ts" />

import * as tsUnit from "./Scripts/tsUnit/tsUnit"

window.onload = () => 
{
    var pt = new MyCompany.ParameterTests();
    pt.someSimpleTest();
}
and the references.ts file contains this:
/// <reference path="ParameterTests.ts" />
The problem is that the line
    var pt = new MyCompany.ParameterTests();
gives an error (Property 'ParameterTests' does not exist on type 'typeof MyCompany').

I have other classes in our MyCompany namespace (also referenced from my central references.ts file) that don't extend TestClass, and I can use them without problems in window.onload. So, I guess I'm missing something here w.r.p. the fact that tsUnit is being imported as a module.
In VS2013, I also had to enable AMD as module system (it was on None before) because of an error when trying to build the project after adding tsUnit:
"Scripts\tsUnit\tsUnit.ts(3,14): error TS1148: Build: Cannot compile modules unless the '--module' flag is provided."
Anyone any idea/hint what I might be doing wrong here? Thanks!
Coordinator
Oct 5, 2015 at 4:29 PM
Edited Oct 5, 2015 at 4:30 PM
I'm guessing you are using v2.0 of tsUnit - the latest version is fully committed to the module route (supporting AMD or CommonJS modules).

To use this in a non-module project, please stick with version 1.x which has the same features but is enclosed within an "internal module". There will be a branch of this 1.x version to update it to namespace rather than an internal module.

Alternatively, use the module flag with either AMD, CommonJS, or UMD and load the tsUnit module on the fly. If you are using browser-based tests, you can use AMD or UMD with RequireJS - the examples on GitHub use this method.

https://github.com/Steve-Fenton/tsUnit/tree/master/tsUnit.Examples
Oct 7, 2015 at 12:51 PM
Edited Oct 7, 2015 at 12:52 PM
Thanks for your fast response Sohnee!

I tried tweaking a few things based on your comments (in particular the use of AMD), but I'm still not getting it to work.
I created a very minimal example project for VS2013 (latest updates of VS2013 + latest TypeScript), and put it in a public git repository on Bitbucket:
https://bitbucket.org/KoenT_IM/tsunittestproject
AMD is now enabled, and my own code builds without problems, but as soon as I add tsUnit, I'm getting all kinds of errors, and some of my classes suddenly become unknown.

I'd love to get tsUnit to work with this minimal example. From there I'll manage to start using it in our full codebase.

So, if you could spare a moment to check this and tell me what's wrong, I'd highly appreciate it. I think it's a small setup issue I need to get right.

Also, as suggested, I also tested the code from the tsUnit github repository, and had a few problems there too:
  • First I tried running the tsUnit.Examples project in VS2013, but got these build errors:
Error 502 Build: Cannot compile modules unless the '--module' flag is provided. ...\tsUnit\tsUnit.Examples\Scripts\tsUnit\tsUnit.ts 3 14 tsUnit.Examples
Error 664 Cannot compile modules unless the '--module' flag is provided. ...\tsUnit\tsUnit.Examples\Scripts\tsUnit\tsUnit.ts 3 14 tsUnit.Examples
  • Then, I tried running the tsUnit project, which built fine, but upon running I got this error:
HTTP Error 403.14 - Forbidden
The Web server is configured to not list the contents of this directory.

Most likely causes:
• A default document is not configured for the requested URL, and directory browsing is not enabled on the server.

I guess this was just because the HTML file is named tsUnit.htm and the IIS isn't setup to start with that page.
I entered http://localhost:3696/tsUnit.htm as URL and that went fine and showed the right test results page as expected.
However, trying to use tsUnit with my minimal test project doesn't seem to work.
Coordinator
Oct 7, 2015 at 1:38 PM
I have a working version of your project... I can't add attachments here so you can grab the zip file from: https://www.stevefenton.co.uk/?attachment_id=1474

Let me know when you have it and I'll delete the download.

The changes can be summarised as...
  • Remove namespaces, as the file itself becomes a module and provides scope for its contents (i.e. nothing will be added to the global scope).
  • Remove references.ts as the dependencies will be dynamically loaded based on your import statements.
  • Add imports in each file to replace the references.ts file (and provide an example of how to alias a class so you don't need to use the full path).
  • Pull in RequireJS using NuGet as this will manage module loading at runtime.
  • Change the HTML file to have a single script tag to load RequireJS and tell it to start with the app.ts file (in all cases, we don't add the file extension)
Oct 7, 2015 at 4:31 PM
Hi Steve (it hadn't occurred to me that you're actually also the author of the book on TypeScript I bought ;-)),

thanks very much taking the time, and for both the changes and the explanation. Highly appreciated!

I downloaded the zip file and built and ran the project in VS2013.
It builds and runs. There was one warning in the "JavaScript Language Service" output: "Referenced file '~/Scripts/_references.js' not found.", but I think that's because there is one /// <reference="references.ts" /> left in the app.ts file.

However, I don't see any test results in the window, nor in the console (I'm testing in IE11 latest version, but also tried in Chrome).
I tried with removing that left-over /// <reference="references.ts" /> in app.ts.
And if I put a breakpoint in the window.onload function, it's not being hit (running in Debug release).

Any idea, what else could be going wrong?

Require.js was pulled in fine by NuGet, and I can see that the JavaScript code is being loaded:
'iexplore.exe' (Script): Loaded 'Script Code (Windows Internet Explorer)'.
'iexplore.exe' (Script): Loaded 'http://localhost:63671/app.js'.
'iexplore.exe' (Script): Loaded 'http://localhost:63671/MyClassTests.js'.
'iexplore.exe' (Script): Loaded 'http://localhost:63671/MyClass.js'.
'iexplore.exe' (Script): Loaded 'http://localhost:63671/tsUnit.js'.

I'm using VS2013 on Win7. I suppose that should be fine? Or do I need to use VS2015?
Just trying to think of possible differences with your setup, as it seems to work fine for you and not here...
Oct 9, 2015 at 2:12 PM
Edited Oct 9, 2015 at 3:29 PM
I found what the problem was:
As I could not make the debugger hit a breakpoint in the window.onload function, I tried adding a console.log in there, and that doesn't show anything in the console either. So I moved the code out of that function and now have this:
import * as tsUnit from 'tsUnit';
import * as MyClassTests from 'MyClassTests';

window.onload = () =>
{
    console.log("in window.onload");
};

var test = new tsUnit.Test(MyClassTests);
var result = test.run().showResults('results');
console.log(result.getTapResults());
And now I see the unit test results.
So, thanks again and I'll be able to take it from here!

I'm still wondering however why the window.onload is never triggered (no breakpoints being hit, and console log message doesn't appear)...

PS:
If anyone knows how to do it with namespaces, I'd be glad to learn that as well.
I've moved my test repository here: https://bitbucket.org/KoenT_IM/typescripttests
Namespaces feel more familiar to me, and from what I read, it looks like it was added more recently, so I assume that it is the "new" way of doing organizing your classes/code?
Coordinator
Oct 9, 2015 at 6:39 PM
Hello,

If you have your <script src=”require.js” data-main=”app”></script> at the end of your document (just before the </body> tag), it is actually better not to use window.onload. This is because your scripts are loaded asynchronously, so there is a reasonable chance they will load after the onload event fires. Because of the way scripts are loaded, you can avoid the window.onload listener altogether and just write the console.log statement without wrapping it.

Hope this helps,

Steve
Oct 12, 2015 at 8:50 AM
OK, thanks.
I'll assume then that as soon as the code in my main app.ts/js starts to be executed, all other modules will have been loaded at that point.
It is strange still that the window.onload never gets hit at all anymore now (not before the not-wrapped code starts, and not after that).
Hopefully this won't cause trouble once I start adding GUI stuff to my app (looking into React for that).
Koen