"Hello World" + JS V8 + VS2010 - javascript

I downloaded and built JS V8 for using in VS2010 in Release mode. Now I try run Hello World example:
#include "v8.h"
int _tmain(int argc, _TCHAR* argv[])
{
v8::HandleScope handle_scope;
v8::Persistent<v8::Context> context = v8::Context::New();
v8::Context::Scope context_scope(context);
v8::Handle<v8::String> source = v8::String::New("'Hello' + ', World'");
v8::Handle<v8::Script> script = v8::Script::Compile(source);
v8::Handle<v8::Value> result = script->Run();
context.Dispose();
v8::String::AsciiValue ascii (result);
printf ("%s\n", *ascii);
return 0;
}
I added Additional Dependencies:
"C:\v8\build\Release\lib\preparser_lib.lib"
"C:\v8\build\Release\lib\v8_base.lib"
When I try to compile and run the program, I encountered a linking error:
1>------ Build started: Project: V8_example, Configuration: Release Win32 ------
1>LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library
1>v8_base.lib(platform-win32.obj) : error LNK2001: unresolved external symbol __imp__inet_addr#4
...
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
When I have set "Ignore All Default Libraries: Yes(/NODEFAULTLIB)", these errors showed up:
1>------ Build started: Project: V8_example, Configuration: Release Win32 ------
1>v8_base.lib(strtod.obj) : error LNK2001: unresolved external symbol #__security_check_cookie#4
1>v8_base.lib(full-codegen-ia32.obj) : error LNK2001: unresolved external symbol #__security_check_cookie#4
...
1>c:\users\admin\documents\visual studio 2010\Projects\V8_example\Release\V8_example.exe : fatal error LNK1120: 141 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Has anyone tried to run this example or know how to fix these errors?

The error is caused by the missing symbol __imp__inet_addr#4, which is located in Ws2_32.lib.
Go to project Properties -> Linker -> Input -> Additional Dependencies. Simply add Ws2_32.lib and you're done.

I had to include the following libraries:
v8_base.lib;v8_snapshot.lib;ws2_32.lib;winmm.lib
DO NOT DEFINE /NODEFAULTLIB:LIBCMT this caused my build to fail.
If you're curious as to how I found out, I looked under the ALL.sln that is generated by GYP and checked the shell target. It's an executable that has to link with v8_base at some point, so it has the required Linker options. It was a bit difficult to find, however.

how about /NODEFAULTLIB:LIBCMT, to exclude only this single library?
also I believe you need to link v8_snapshot.lib or v8_nosnapshot.lib
or you build shared library and link to v8.lib

Related

Ignore return outside of function with babel 7

I recently updated to babel 7 and webpack 4 and am receiving this error when running our gulp build task:
gulp build
[00:26:04] Requiring external module #babel/register
[91m[BABEL] Note: The code generator has deoptimised the styling of /node_modules/lodash/lodash.js as it exceeds the max of 500KB.
[0m[91m/node_modules/#babel/core/lib/parser/index.js:95
throw err;
^
SyntaxError: /node_modules/dev-ip/lib/dev-ip.js: 'return' outside of function (41:8)
39 | var out = getIp();
40 | if (!out.length) {
> 41 | return console.log(messages.error);
| ^
42 | }
43 | console.log(getIp("cli"));
44 | }
at Parser.raise (/node_modules/#babel/parser/src/parser/location.js:41:63)
at Parser.parseReturnStatement (/node_modules/#babel/parser/src/parser/statement.js:577:12)
at Parser.parseStatementContent (/node_modules/#babel/parser/src/parser/statement.js:199:21)
at Parser.parseStatement (/node_modules/#babel/parser/src/parser/statement.js:146:17)
at Parser.parseBlockOrModuleBlockBody (/node_modules/#babel/parser/src/parser/statement.js:865:25)
at Parser.parseBlockBody (/node_modules/#babel/parser/src/parser/statement.js:841:10)
at Parser.parseBlock (/node_modules/#babel/parser/src/parser/statement.js:818:10)
at Parser.parseStatementContent (/node_modules/#babel/parser/src/parser/statement.js:223:21)
at Parser.parseStatement (/node_modules/#babel/parser/src/parser/statement.js:146:17)
at Parser.parseIfStatement (/node_modules/#babel/parser/src/parser/statement.js:570:28)
[0m[91merror Command failed with exit code 1.
This is caused by the return outside of a function in browser-syncs dev-ip dependency.
Is there a way to configure my .babelrc file to ignore this?
I've tried the following:
Installing only production dependencies, but because browser sync is imported in my gulp file it's still being compiled
Setting up workspaces with yarn, but similar issue as #1
Dynamically importing browser sync in my gulp file, I guess this is not yet supported yet?
Telling babel to ignore or exclude compiling the node_modules folder, but this doesn't seem to do anything?
Apparently babel-parser has an option allowReturnOutsideFunction: true, but I can't figure out how to set this in my .babelrc file.
Any thoughts on how to get around this?
With Babel7, you can provide all parser options (which include allowReturnOutsideFunction) via parserOpts, e.g.:
// .babelrc.js
module.exports = {
parserOpts: { allowReturnOutsideFunction: true }
};
Since I could not find a solution to this, I ended up just forking browser-sync and dev-ip.
I give you, browser-stink

Protractor Flake guidance needed to rerun failed test cases

Please correct my understanding for the below:
I've installed protractor flake
From the website we have 2 sets of
code
My assumption
I'm pretty sure the B part needs to be given in configuration.js file
of my protractor project but the A part where exactly should it be written.
As a separate file should i write it and then require them in the spec file which i'm running.I need exact steps as to achieve the above
The usage section which starts with below:
**var protractorFlake = require('protractor-flake')
// OR using es6 modules/typescript
import protractorFlake = require('protractor-flake')**
and ends with **process.exit(status)**
and the parsers section which starts with
module.exports = { till return [...failedSpecs]
As per the documentation,
Add dependency
npm i protractor-flake
# or globally for easier cli usage
npm i -g protractor-flake
Running tests
Option 1: Via the CLI:
# protractor-flake <protractor-flake-options> -- <options to be passed to protractor>
protractor-flake --parser standard --max-attempts=3 -- path/to/protractor.conf.js
Assuming that your conf.js file is in root directory.
Available command line options.
color?: string | boolean
choose color from here or set false to disable coloring
Usage : protractor-flake --parser standard --color=magenta --max-attempts=3 -- conf.js
protractorArgs?: string[]
protractorPath?: string: protractor location like this 'node_modules/.bin/protractor',
Usage : protractor-flake --parser standard --protractorPath=node_modules/.bin/protractor --max-attempts=3 -- conf.js
parser?: string: the name of one of the included parsers
Usage : protractor-flake --parser standard --color=magenta --max-attempts=3 -- conf.js
You can refer other options from here
Option 2: Programmatically
Create file in your root directory as flake and copy below snippet.
flake is a node script that uses protractor-flake to re-run failed tests. Note
that it reruns tests at the file level, so if one test fails, it will rerun all
the tests in that file.
Thanks Brian Ray to this repository
#!/usr/bin/env node
/**
*
* usage:
* `./flake conf.js [other protractor args]`
*/
const protractorFlake = require('protractor-flake');
// skip first two passed args (node and self)
let protractorArgs = process.argv.splice(2);
console.log(protractorArgs);
protractorFlake({
protractorPath: 'node_modules/.bin/protractor',
maxAttempts: 3,
parser: 'standard',
nodeBin: 'node',
protractorArgs: protractorArgs
}, (status, output) => {
process.exit(status);
});
After creating this file, for avoiding permission error's just run chmod +x ./flake
To run your test cases
./flake conf.js
If you are keeping specs in a test suite, just pass after conf.js.
./flake conf.js --suite smoke_test
Before you are running, check these Caveats

Running QUnit (TypeScript) tests with Chutzpah gives "Called start() outside of a test context while already started"

I've got a fairly simple repro with an outcome I don't understand.
Make sure you have the Chutpah Test Adapter 4.0.3 installed. Using Visual Studio 2013 take the following steps:
Create a new .NET 4.5.1 class library project;
Add the NuGet package qunit.TypeScript.DefinitelyTyped 0.1.7;
Add a TypeScript file file1.ts to the project with this content:
/// <reference path="./Scripts/typings/qunit/qunit.d.ts"/>
QUnit.test("QUnit is working", assert => assert.ok(true));
Right-click inside that file and pick "Run JS Tests" from the context menu.
I can confirm that file1.js is generated as expected.
The result is that no tests are run, the test explorer shows no tests, and the Test output shows:
Error: Error: Called start() outside of a test context while already started
at start in file:///C:/Users/username/AppData/Local/Microsoft/VisualStudio/12.0/Extensions/abcxyz/TestFiles/QUnit/qunit.js (line 287)
at startQUnit in phantomjs://webpage.evaluate() (line 12)
at onPageLoaded in phantomjs://webpage.evaluate() (line 16)
in phantomjs://webpage.evaluate() (line 18)
While Running:c:\users\username\documents\visual studio 2013\Projects\ClassLibrary3\ClassLibrary3\file1.ts
------ Test started: File: c:\users\username\documents\visual studio 2013\Projects\ClassLibrary3\ClassLibrary3\file1.ts ------
Error: Error: Called start() outside of a test context while already started
While Running:c:\users\username\documents\visual studio 2013\Projects\ClassLibrary3\ClassLibrary3\file1.ts
0 passed, 0 failed, 0 total (chutzpah).
========== Total Tests: 0 passed, 0 failed, 0 total ==========
If I choose the "Open In Browser" Chutzpah context menu item I get a regular QUnit test page, nicely formatted, showing zero tests run.
Obviously the expected result was that one test was successfully run.
What am I missing here?
D'oh! The Chutzpah + TypeScript documentation is actually pretty clear about this:
You need to tell Chutzpah how to compile your files into JavaScript using the compile setting in the chutzpah.json file.
For the scenario from the question take e.g. these steps to get it to work:
Add a chutzpah.json file to the root of your project.
Enter the following code:
{
"Compile": {
"Mode": "External",
"Extensions": [".ts"],
"ExtensionsWithNoOutput": [".d.ts"]
}
}
After this the right-click run will already improve, showing:
========== Total Tests: 1 passed, 0 failed, 1 total ==========
If this doesn't work right away close and re-open the solution.
To get the tests to show up in the Test Explorer you need to group them into modules, e.g. by adding this to file1.ts:
QUnit.module("Qu.Testing");
For more info, see the Compile Setting documentation.
Leaving this up here should others fall in the same trap I did.

Can Emstripten compile the iostream library?

I'm on Ubuntu.
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 14.04.2 LTS
Release: 14.04
Codename: trusty
I installed Emscripten.
$ sudo apt-get install emscripten
I wrote the following C++ program:
#include <iostream>
int main(){
printf("hello world\n");
}
It compiles as expected.
$ emcc -O1 -s ASM_JS=1 main.cpp
$
However, when I write a similar program using the iostream facilities:
#include <iostream>
int main(){
std::cout << "hello world" << std::endl;
}
It fails to build.
$ emcc -O1 -s ASM_JS=1 main.cpp
aborting from js compiler due to exception: unknown vector type <4 x i8> | undefined
aborting from js compiler due to exception: unknown vector type <4 x i8> | undefined
aborting from js compiler due to exception: unknown vector type <4 x i8> | undefined
Traceback (most recent call last):
File "/usr/share/emscripten/emscripten.py", line 1352, in <module>
_main(environ=os.environ)
File "/usr/share/emscripten/emscripten.py", line 1340, in _main
temp_files.run_and_clean(lambda: main(
File "/usr/share/emscripten/tools/tempfiles.py", line 39, in run_and_clean
return func()
File "/usr/share/emscripten/emscripten.py", line 1348, in <lambda>
DEBUG_CACHE=DEBUG_CACHE,
File "/usr/share/emscripten/emscripten.py", line 1235, in main
jcache=jcache, temp_files=temp_files, DEBUG=DEBUG, DEBUG_CACHE=DEBUG_CACHE)
File "/usr/share/emscripten/emscripten.py", line 292, in emscript
assert len(output) == 2, 'Did not receive forwarded data in an output - process failed? We only got: ' + output[0][-3000:]
AssertionError: Did not receive forwarded data in an output - process failed? We only got: ((HEAP32[(($1)>>2)])|0);
$3=((($2)-(12))|0);
$4=$3;
$5=((HEAP32[(($4)>>2)])|0);
$6=$this;
$_sum=((($5)+(24))|0);
$7=(($6+$_sum)|0);
$8=$7;
$9=((HEAP32[(($8)>>2)])|0);
$10=($9|0)==0;
if ($10) {
STACKTOP=sp;return (($this)|0);
}
$12=(($__s)|0);
HEAP8[($12)]=0;
$13=(($__s+4)|0);
HEAP32[(($13)>>2)]=$this;
$_sum_i=((($5)+(16))|0);
$14=(($6+$_sum_i)|0);
$15=$14;
$16=((HEAP32[(($15)>>2)])|0);
$17=($16|0)==0;
do {
if ($17) {
$_sum1_i=((($5)+(72))|0);
$19=(($6+$_sum1_i)|0);
$20=$19;
$21=((HEAP32[(($20)>>2)])|0);
$22=($21|0)==0;
if (!($22)) {
$24=((__ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE5flushEv($21))|0);
}
HEAP8[($12)]=1;
$26=((HEAP32[(($1)>>2)])|0);
$27=((($26)-(12))|0);
$28=$27;
$29=((HEAP32[(($28)>>2)])|0);
$_sum1=((($29)+(24))|0);
$30=(($6+$_sum1)|0);
$31=$30;
$32=((HEAP32[(($31)>>2)])|0);
$33=$32;
$34=$32;
$35=((HEAP32[(($34)>>2)])|0);
$36=(($35+24)|0);
$37=((HEAP32[(($36)>>2)])|0);
$38=((FUNCTION_TABLE_ii[($37)&{{{ FTM_ii }}}]($33))|0);
$39=($38|0)==-1;
if (!($39)) {
break;
}
$41=((HEAP32[(($1)>>2)])|0);
$42=((($41)-(12))|0);
$43=$42;
$44=((HEAP32[(($43)>>2)])|0);
$45=(($6+$44)|0);
$46=$45;
$_sum2=((($44)+(16))|0);
$47=(($6+$_sum2)|0);
$48=$47;
$49=((HEAP32[(($48)>>2)])|0);
$50=$49|1;
__ZNSt3__18ios_base5clearEj($46,$50);
}
} while(0);
__ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE6sentryD2Ev($__s);
STACKTOP=sp;return (($this)|0);
}
function __ZNSt3__18ios_base33__set_badbit_and_consider_rethrowEv($this){
$this=($this)|0;
var $1=0,$2=0,$3=0,$4=0,$5=0,$6=0,$7=0,label=0;
$1=(($this+16)|0);
$2=((HEAP32[(($1)>>2)])|0);
$3=$2|1;
HEAP32[(($1)>>2)]=$3;
$4=(($this+20)|0);
$5=((HEAP32[(($4)>>2)])|0);
$6=$5&1;
$7=($6|0)==0;
if ($7) {
return;
} else {
___cxa_rethrow();
}
}
function __ZNSt3__113basic_istreamIwNS_11char_traitsIwEEED0Ev($this){
$this=($this)|0;
var $1=0,$2=0,label=0;
$1=(($this+8)|0);
__ZNSt3__18ios_baseD2Ev($1);
$2=$this;
__ZdlPv($2);
return;
}
function __ZNSt3__113basic_istreamIwNS_11char_traitsIwEEED1Ev($this){
$this=($this)|0;
var $1=0,label=0;
$1=(($this+8)|0);
__ZNSt3__18ios_baseD2Ev($1);
return;
}
function __ZTv0_n12_NSt3__113basic_istreamIwNS_11char_traitsIwEEED0Ev($this){
$this=($this)|0;
var $1=0,$2=0,$3=0,$4=0,$5=0,$6=0,$7=0,$_sum=0,$8=0,$9=0,label=0;
$1=$this;
$2=$this;
$3=((HEAP32[(($2)>>2)])|0);
$4=((($3)-(12))|0);
$5=$4;
$6=((HEAP32[(($5)>>2)])|0);
$7=(($1+$6)|0);
$_sum=((($6)+(8))|0);
$8=(($1+$_sum)|0);
$9=$8;
__ZNSt3__18ios_baseD2Ev($9);
__ZdlPv($7);
return;
}
function __ZTv0_n12_NSt3__113basic_istreamIwNS_11char_traitsIwEEED1Ev($this){
$this=($this)|0;
var $1=0,$2=0,$3=0,$4=0,$5=0,$6=0,$_sum=0,$7=0,$8=0,label=0;
$1=$this;
$2=$this;
$3=((HEAP32[(($2)>>2)])|0);
$4=((($3)-(12))|0);
$5=$4;
$6=((HEAP32[(($5)>>2)])|0);
$_sum=((($6)+(8))|0);
$7=(($1+$_sum)|0);
$8=$7;
__ZNSt3__18ios_baseD2Ev($8);
return;
}
Traceback (most recent call last):
File "/usr/bin/emcc", line 1864, in <module>
final = shared.Building.emscripten(final, append_ext=False, extra_args=extra_args)
File "/usr/share/emscripten/tools/shared.py", line 1276, in emscripten
assert os.path.exists(filename + '.o.js') and len(open(filename + '.o.js', 'r').read()) > 0, 'Emscripten failed to generate .js: ' + str(compiler_output)
AssertionError: Emscripten failed to generate .js:
I was under the impression that Emscripten has come a long way, and is capable of compiling entire C++ games for the browser! Is there some kind of flag or configuration I missed in order to sucessfully compile portions of the C++ standard library? I know that clang/gcc compilers will link against the C++ standard shared library by default. Does the issue have something to do with that you think?
I have also tried using the command em++ in place of emcc and recieved the same error message.
If relevant, here is the default configuration that was built when running emscripten for the first time:
$ cat ~/.emscripten
# Note: If you put paths relative to the home directory, do not forget os.path.expanduser
import os
# this helps projects using emscripten find it
EMSCRIPTEN_ROOT = os.path.expanduser(os.getenv('EMSCRIPTEN') or '/usr/share/emscripten') # directory
LLVM_ROOT = os.path.expanduser(os.getenv('LLVM') or '/usr/bin') # directory
PYTHON = os.path.expanduser(os.getenv('PYTHON') or '/usr/bin/python2') # executable
# See below for notes on which JS engine(s) you need
NODE_JS = os.path.expanduser(os.getenv('NODE') or '/usr/bin/node') # executable
SPIDERMONKEY_ENGINE = [os.path.expanduser(os.getenv('SPIDERMONKEY') or 'js')] # executable
V8_ENGINE = os.path.expanduser(os.getenv('V8') or 'd8') # executable
JAVA = 'java' # executable
TEMP_DIR = '/tmp'
CRUNCH = os.path.expanduser(os.getenv('CRUNCH') or 'crunch') # executable
#CLOSURE_COMPILER = '..' # define this to not use the bundled version
########################################################################################################
# Pick the JS engine to use for running the compiler. This engine must exist, or
# nothing can be compiled.
#
# Recommendation: If you already have node installed, use that. Otherwise, build v8 or
# spidermonkey from source. Any of these three is fine, as long as it's
# a recent version (especially for v8 and spidermonkey).
COMPILER_ENGINE = NODE_JS
#COMPILER_ENGINE = V8_ENGINE
#COMPILER_ENGINE = SPIDERMONKEY_ENGINE
# All JS engines to use when running the automatic tests. Not all the engines in this list
# must exist (if they don't, they will be skipped in the test runner).
#
# Recommendation: If you already have node installed, use that. If you can, also build
# spidermonkey from source as well to get more test coverage (node can't
# run all the tests due to node issue 1669). v8 is currently not recommended
# here because of v8 issue 1822.
JS_ENGINES = [NODE_JS] # add this if you have spidermonkey installed too, SPIDERMONKEY_ENGINE]
I can't seem to find a way to get the basic C++ program above to successfully compile.
First, your program compiles fine for me with emcc. Your original program (with printf) causes emcc to assume it is compiling C code and as such it will auto-include stdio.h as C does. Your second program is having more trouble, probably due to an install error (for me I had an issue like this because my version of LLVM doesn't line up with the exact version Emscripten needed.)
Unfortunately, my understanding is that this is a common problem with emscripten and auto installers like apt-get -- I had the problem with both port and brew on my Mac.
The solution is to get Emscripten through the SDK, which bundles all of the sensitive pieces together: https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html
Follow the instructions there carefully. The two problems I ran into were that it expects Python 2 to be called python2 on your system and the script to adjust your default path assumes you're using bash (if you are, it should work fine.)

Logging with grunt and qunit

I am running javascript unittests with grunt/qunit. Sometimes the tests fails because of e.g syntax errors in the source files (works fine with file info if syntax errors are introduced in the test files). When that happens grunt simply prints the line number and not the file where the problem is.
Running "qunit:all" (qunit) task
Warning: Line 99: Unexpected identifier Use --force to continue.
Aborted due to warnings.
This does not help much since I have 100 of js files. I have looked into:
https://github.com/gruntjs/grunt-contrib-qunit
and tried to add the following to my Gruntfile.js (grunt.event.on):
module.exports = function(grunt) {
"use:strict";
var reportDir = "output/reports/"+(new Date()).getTime().toString();
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
qunit: {
options: {
'--web-security': 'no',
coverage: {
src: ['../src/**/*.js'],
instrumentedFiles: 'output/instrument/',
htmlReport: 'output/coverage',
coberturaReport: 'output/',
linesTresholdPct: 85
}
},
all: ["testsSuites.html"]
}
});
// Has no effect
grunt.event.on('qunit.error.onError', function (msg, stack) {
grunt.util._.each(stack, function (entry) {
grunt.log.writeln(entry.file + ':' + entry.line);
});
grunt.warn(msg);
});
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.loadNpmTasks('grunt-qunit-istanbul');
grunt.registerTask('test', ['qunit']);
Where testsSuites.html contains:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="qunit/qunit.css">
<script src="qunit/qunit.js"></script>
<script src="sinonjs/sinon-1.7.3.js"></script>
<script src="sinonjs/sinon-qunit-1.0.0.js"></script>
<!-- Sources -->
<script src="../src/sample.js"></script>
<!-- Test-->
<script src="test/sample-test.js"></script>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script>
</script>
</body>
</html>
But the source file where the problem is located is still not printed. Is is out of Grunts hands to verify source code/show line number/file where e.g a syntax error is located?
I have also tried running:
grunt test --debug 9
It prints some debug info but not any information regarding syntax errors in the javascript sources.
I have tried to install JSHint and call it on all my javascript source files:
for i in $(find ../src -iname "*.js"); do jshint $i; done
Now I get tons of errors but Grunt is still happy. If I introduce a simple syntax error e.g:
(function(){
var sampleVar 32;
}
to provoke an error in Grunt:
Running "qunit:all" (qunit) task
Warning: Line 2: Unexpected number Use --force to continue.
Aborted due to warnings.
it simply disappears in the stream of errors generated by JSHint. How do I filter JSHint "warnings" from critical errors that will actually make Grunt fail?
Or is it qunit that should be configured for more verbose output?
grunt-contrib-qunit will display filenames when encountering a syntax error. Take this simplified version of your Gruntfile.js:
module.exports = function(grunt) {
"use:strict";
grunt.initConfig({
qunit: {
options: { '--web-security': 'no' },
all: ["testsSuites.html"]
}
});
grunt.loadNpmTasks('grunt-contrib-qunit');
};
Running it gives the error you're looking for:
$ grunt qunit
Running "qunit:all" (qunit) task
Testing testsSuites.html F.
>> global failure
>> Message: SyntaxError: Parse error
>> file:///tmp/src/sample.js:2
Warning: 1/2 assertions failed (17ms) Use --force to continue.
Aborted due to warnings.
The issue you're having looks to be a bug(?) in grunt-qunit-istanbul. The warning you're getting:
Warning: Line 99: Unexpected identifier Use --force to continue.
is Grunt handling an uncaught exception. The exception is being raised by the grunt-qunit-istanbul task. You can prove it by modifying this line in your original Gruntfile.js from:
src: ['../src/**/*.js'],
to:
src: ['../src/**/*.js.nomatch'],
This will prevent grunt-qunit-istanbul from finding and parsing any Javascript files before Qunit is run. If you let Qunit run, its error handler prints out the filenames with syntax errors like you want.
The only fix is the workaround I've described, or to patch grunt-qunit-istanbul to add an error handler for parse errors like Qunit does.
Patching grunt-qunit-istanbul
The function that is throwing the exception is Instrumenter.instrumentSync, which it is supposed to do:
instrumentSync ( code, filename )
Defined in lib/instrumenter.js:380
synchronous instrumentation method. Throws when illegal code is passed to it
You can fix it by wrapping the function call:
diff -r 14008db115ff node_modules/grunt-qunit-istanbul/tasks/qunit.js
--- a/node_modules/grunt-qunit-istanbul/tasks/qunit.js Tue Feb 25 12:14:48 2014 -0500
+++ b/node_modules/grunt-qunit-istanbul/tasks/qunit.js Tue Feb 25 12:19:58 2014 -0500
## -209,7 +209,11 ##
// instrument the files that should be processed by istanbul
if (options.coverage && options.coverage.instrumentedFiles) {
- instrumentedFiles[fileStorage] = instrumenter.instrumentSync(String(fs.readFileSync(filepath)), filepath);
+ try {
+ instrumentedFiles[fileStorage] = instrumenter.instrumentSync(String(fs.readFileSync(filepath)), filepath);
+ } catch (e) {
+ grunt.log.error(filepath + ': ' + e);
+ }
}
cb();
Then the test will keep running (and inform you of the syntax error):
$ grunt qunit
Running "qunit:all" (qunit) task
>> /tmp/src/sample.js: Error: Line 2: Unexpected number
Testing testsSuites.html F.
>> global failure
>> Message: SyntaxError: Parse error
>> file:///tmp/src/sample.js:2
Warning: 1/2 assertions failed (19ms) Use --force to continue.
Aborted due to warnings.
I have used grunt-contrib-qunit in the past but I have never attempted something like this. The problem you are facing is fairly interesting because the docs mention that the event qunit.error.onError should be emitted by grunt but it is not happening for you.
I created a new project using a jquery template and changed the code so that my test would fail. After that I wrote the following code:
grunt.event.on('qunit.error.onError', function(message, stackTrace) {
grunt.file.write('log/qunit-error.log', message);
});
When I ran the command grunt, I received no output in the file. To check this, I made a change to the event:
grunt.event.on('qunit.log', function(result, actual, expected, message, source) {
grunt.file.write('log/qunit-error.log', message);
});
Now, this piece of code did give me the error message in my file but it was useless because I could not get the stacktrace or the exact error message.
After this, I though of reading up the source and this is what I found:
phantomjs.on('error.onError', function (msg, stackTrace) {
grunt.event.emit('qunit.error.onError', msg, stackTrace);
});
The grunt event is only emitted when phantomjs throws an error.
At the moment I am not sure how I can get a phantomjs error while testing a simple JavaScript file without any browser related testing. This is my analysis so far and I hope this helps you in someway.

Categories

Resources