I am trying to write the following Protractor test in CoffeeScript:
describe "tests", ->
browser.get "/"
it "should display Login page", ->
expect(element(by.css("h1")).getText()).toBe "Login"
However, CoffeeScript spits out this error:
SyntaxError: unexpected by
Solutions?
Like #meagar said it is reserved, you can alias it in your protractor config in the onPrepare block:
require('coffee-script/register');
exports.config = {
....
// by is reserved in coffee script
onPrepare: function() {
global.By = global.by;
}
}
then
expect(element(By.css("h1")).getText()).toBe "Login"
by is a reserved word in CoffeeScript, used in specifying loop increments:
evens = (x for x in [0..10] by 2)
Use a different variable name.
Related
I am trying out Stitch, a serverless/hosted JavaScript environment from MongoDB. My main purpose is to help me learn modern JavaScript, but I am trying to write a useful app as well.
I have written the following function, and saved it in my Stitch app. I believe this follows the documented way to write functions in Stitch, and I have tested it from the Stitch administration console:
exports = function(query){
const http = context.services.get("HTTP");
const urlBase = context.values.get("stackOverflowApiUrl");
const options = [
'order=desc',
'sort=activity',
'site=stackoverflow',
'q=' + encodeURIComponent(query),
'user=472495',
'filter=!--uPQ.wqQ0zW'
];
return http
.get({ url: urlBase + '?' + options.join('&') })
.then(response => {
// The response body is encoded as raw BSON.Binary. Parse it to JSON.
const ejson_body = EJSON.parse(response.body.text());
return ejson_body.total;
});
};
This code is pretty simple - it obtains an http object for making external API fetches, and obtains a configuration value for a URL urlBase to contact (resolving to https://api.stackexchange.com/2.2/search/excerpts) and then makes a call to the Stack Overflow Data API. This runs a search query against my user and returns the number of results.
So far so good. Now, I want to call this function locally, in Jest. To do this, I have installed Node and Jest in a local Docker container, and have written the following test function:
const callApi = require('./source');
test('Simple fetch with no user', () => {
expect(callApi('hello')).toBe(123);
});
This fails, with the following error:
~ # jest
FAIL functions/callApi/source.test.js
✕ Simple fetch with no user (3ms)
● Simple fetch with no user
TypeError: callApi is not a function
2 |
3 | test('Simple fetch with no user', () => {
> 4 | expect(callApi('hello')).toBe(123);
| ^
5 | });
6 |
at Object.<anonymous>.test (functions/callApi/source.test.js:4:12)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 1.418s
Ran all test suites.
(In fact I was expecting it to fail, since it contains a global object context that Jest does not have access to. I will work out how to mock that later, but for now Jest cannot even see the function at all).
I suspect I can see the reason - in the Jest introduction docs, one has to do this for the SUT:
module.exports = function() { ... }
However the Stitch docs seem to require functions to be defined as:
exports = function() { ... }
I do not have a background in JavaScript to understand the difference. I could try module.exports in Stitch, but I would rather not, since this would either not work now, or cause a breakage in the future. Can Jest be instructed to "see" bare exports without the module prefix?
Incidentally, I have picked Jest because it is popular, and because some of my JavaScript colleagues vouch for it. However, I am not wedded to it, and would be happy to use something else if it is known to be better for Stitch development.
Update
Following the useful answer from jperl below, I find that the following construction is not possible in Stitch:
module.exports = exports = function() {}
I also cannot do this:
exports = function() {}
module.exports = exports
If I try either, I get the following error:
runtime error during function validation
So it looks like I have to get Jest to work without module.exports, or create a glue file that imports the exports version into module.exports, with the main file being used by Stitch, and the glue importer being used by Jest.
I suggest you to read this thread. And you're right in thinking it has to do with modules.exports vs exports. The thing is that module.exports and exports first point to the same thing. So something like this works:
//modify the same object that modules.exports is pointing to
exports.a = {}
exports.b = {}
but this won't:
exports = {}
Why? Because now exports points to something else than module.exports so what you're doing has no effect at all.
Update
Following some updates in the comments, we came to the view that Stitch does not seem to support the export format that Jest requires.
This is an addendum to jperl's answer, to show how I got Jest working while respecting Stitch's limitations.
Firstly, it is worth noting how a Stitch application is laid out. This is determined by the import/export format.
auth_providers/
functions/
function_name_1/
config.json
source.js
function_name_2/
config.json
source.js
...
services/
values/
The config.json file is created by Stitch remotely, and is obtained through a export. This contains ID information to uniquely identify the function in the same folder.
I believe it is common JavaScript practice to mix tests with source code, so I am following that style (I am new to modern JS, and I confess I find this style untidy, but I am running with it nevertheless). Thus I add a source.test.js file in each function folder.
Finally, since there is a discrepancy between what Stitch requires and what Jest requires, I have written a script to create a source code file under _source.js in each function folder.
So, each folder will contain these files (the underscore files will probably be ignored by Git, as they will always be generated):
_source.js
config.json
source.js
source.test.js
In order to create the underscored copies, I am using this shell script:
#!/bin/bash
# Copy all source.js files as _source.js
for f in $(find functions/ -name source.js); do cp -- "$f" "$(dirname $f)/_$(basename $f)"; done
# Search and replace in all _source.js files
for f in $(find functions/ -name _source.js); do sed -i -e 's/exports =/module.exports =/g' $f; done
A bit hacky perhaps, but it works!
I have the following piece of code that works well:
require.ensure(['./core/sample-form.js'], require => {
require('./core/sample-form.js');
});
Now if I put that string into a variable:
const ajaxJs = './core/sample-form.js';
require.ensure([ajaxJs], require => {
require(ajaxJs); // eslint-disable-line import/no-dynamic-require
});
It throws the following error:
Uncaught (in promise) Error: Cannot find module "." at webpackMissingModule
Is there any way I can use a variable for that require?
Take a look at Webpack's Context Module.
Apparently, when you attempt to dynamicly require a module, Webpack will try to parse the input expression to a context.
Try the following code (haven't tested this):
const ajaxJs = './sample-form.js';
core = require.context('./core', true, /^\.\/.*\.js$/);
require.ensure([], () => {
core(ajaxJs);
});
Webpack can't figure out which modules to bundle when the name is dynamic variable. You can't use variable name in require. You'll have to do something like :
require.ensure(['./core/sample-form.js'], require => {
require('./core/sample-form.js'); // eslint-disable-line import/no-dynamic-require
});
This answer can help.
Running mocha tests in node I'm getting the following syntax errors.
String Template: this one worked on 4.4, but is failing on 6.2.
/home/ubuntu/workspace/lib/admin.js:18
ROOT: `${homeDir}/.config`,
^
SyntaxError: Unexpected token ILLEGAL
full code:
var homeDir = os.homedir(),
configLocations = {
ROOT: `${homeDir}/.config`,
BASE: `${homeDir}/.config/nobjs`,
FILE: `${homeDir}/.config/nobjs/nobjs_config.json`
};
Default Parameter:
/home/ubuntu/workspace/lib/nobutil.js:4
function splitStringToArray(str, seperator = ','){
^
SyntaxError: Unexpected token =
These fail when I try to run mocha tests.
These seem to be supported.
All simple contrived examples seem to be working in the console. Is mocha the problem?
Thanks to #robertklep 's tip, it is a path problem, global mocha running the tests using system installed node on cloud9.
by installing mocha locally and prefixing my path so that mocha is resolved first, mocha calls my default nvm installed node.
export PATH=/home/ubuntu/workspace/node_modules/mocha/bin:$PATH
I have a Node.js web application where I use Backbone.js and jQuery. My main js file is app.js where I include all the necessary scripts, including jQuery. So, this is the beginning of my app.js code:
'use strict';
var _ = require('lodash');
var $ = require('jquery');
var B = require('backbone');
B.$ = $;
Now if I run grunt on my project, it raises errors at the line where jQuery is loaded to $. It shows me this:
Linting public/js/app.js ...ERROR
[L4:C5] W079: Redefinition of '$'.
var $ = require('jquery');
I can still get everything running with grunt --force, but I would like to eliminate this error anyway. Can somebody explain why it raises the error and how to fix it?
My .jshintrc file:
{
"laxcomma": true
,"laxbreak": true
,"curly": true
,"eqeqeq": true
,"immed": true
,"latedef": true
,"newcap": true
,"noarg": true
,"sub": true
,"undef": true
,"unused": false
,"asi": true
,"boss": true
,"eqnull": true
,"node": true
,"browser": true
,"jquery": true
,"predef":
[
"suite"
,"test"
,"setup"
,"teardown"
,"suiteSetup"
,"suiteTeardown"
,"requestAnimationFrame"
]
}
In jshint docs: http://www.jshint.com/docs/options/
jquery = true
This option defines globals exposed by the jQuery JavaScript library.
You are telling jshint that jquery exists, thus he assumes that $ is defined. Remove the "jquery" : true" and your issue should go away.
Add this at the top of the file to make that error go away:
/* jshint -W079 */
What's happening here is that JQuery defines the $ variable, so JSHint views this as a piece of "potentially dangerous code"
A better solution would be to require jquery directly which should give you access to the $ variable globally.
Random guess: do you include jquery somewhere else? For example in some html file as a script. Or some other script might be defining global jquery variable.
Make sure that in your .jshintrc you don't have '$' set as predefined.
// Predefined Globals
"predef" : ["$"]
If it is, remove.
I'm making my first attempt at Javascript testing, with Buster.js
I've followed the instructions at the Buster site to run "states the obvious" test. However, I haven't been able to import any of my existing .js files into the tests.
For instance, I have a file js/testLibrary.js, containing:
function addTwo(inp) {
return inp+2;
}
and a file test/first-test.js, containing:
// Node.js tests
var buster = require("buster");
var testLibrary = require("../js/testLibrary.js");
var assert = buster.referee.assert;
buster.testCase("A module", {
"Test The Library": function() {
result = addTwo(3);
console.log(result);
assert(true, 'a message for you');
}
});
Running buster-test gives:
Error: A module Test The Library
ReferenceError: addTwo is not defined
[...]
Replacing result = addTwo(3); with result = testLibrary.addTwo(3); gives:
Error: A module Test The Library
TypeError: Object #<Object> has no method 'addTwo'
[...]
I'm probably missing something really basic, but at present, I'm completely stumped. Can someone point me in the right direction?
That is because you are not exporting this function from the module.
Take a look at that:
http://nodejs.org/api/modules.html#modules_module_exports