Code:
for (var i in RESTCalls_GET) {
describe('Retrieve all Product Component names and their IDs', function() {
var restCalls;
beforeEach(function() {
RESTCalls_GET.setClient(mockClient);
restCalls = new Rest_calls(mockClient);
});
describe(i + '()', function() {
it('should return data if response code is 200', function(done) {
mockClient.mockURLForSucceed(eval('restCalls.' + i + "_RESTCall"), eval('RESTCalls_GET_ExampleData.' + i + "_ExampleData"), 200);
eval('RESTCalls_GET.' + i)(function(result) {
result.should.equal(eval('RESTCalls_GET_ExampleData.' + i + "_ExampleData"));
done();
});
}),
it('should return error if response code is NOT 200', function(done) {
mockClient.mockURLForError(eval('restCalls.' + i + "_RESTCall"), null, TestData.RESTCallResponseError_Test);
eval('RESTCalls_GET.' + i)(function(errorObj) {
errorObj.should.have.property('errorCode');
done();
});
});
});
});
}
I am looping though functions in RESTCalls_GET. Say, for example, i = getComponent, a function called getComponent_RESTCall will be in module restCalls
I have been told that one way to accomplish this is by using eval() (even though it is not recommended). This way is not working and when I debug, the parameters which use eval() in mockURLForSucceed are undefined.
This obviously causes all my tests to fail.
Any suggestions appreciated.
EDIT: (additional information)
var mockClient = function() {
var urlMap = {};
return {
get: function(url, callback) {
var entry = urlMap[url];
if (entry) {
callback(entry[0], entry[1]);
} else {
console.error("Unable to match URL " + url);
}
return {
on: function() {
//Ignore
}
};
},
mockURLForSucceed: function(URLofRESTCall, succeedData, succeedRes) {
urlMap[URLofRESTCall] = [succeedData, {statusCode: succeedRes}];
},
mockURLForError: function(URLofRESTCall, errorData, errorRes) {
urlMap[URLofRESTCall] = [errorData, errorRes];
}
}
}();
EDIT: (half way there)
I've resorted back to eval() an got the function/variable name required in format file.functionName by this:
var RESTCallURL = eval('"restCalls." + i + "_RESTCall"');
var RESTCallData = eval('"RESTCalls_GET_ExampleData." + i + "_ExampleData"');
The problem I'm having now if that these are strings. So when I pass them into a function, it gets that string value and not the one it equals in it's own function, does that make sense?
What I mean is that if I passed in RESTCallURL into a function now, then the value of that parameter would be restCalls.whatever_RESTCall whereas before it got the URL of the REST Call I am calling (http://whatever). Since I now have the name of the function, am I able to search for functions in my project by that name?
This task seems so simple to do and I think I am over thinking it.
I don't think you need eval there, what about using
RESTCalls_GET[i](function(result) {
result.should.equal(RESTCalls_GET_ExampleData[i + '_ExampleData']));
done();
});
You could easily test this behaviour by defining the following in your browser console
var test = {
'some-function': function() { console.log('works'); }
};
test['some-function']();
Related
exports.getDefiniton = function (text) {
var definition = "";
wn.definitions(text, {
useCanonical: true
, includeRelated: true
, limit: 3
}, function (e, defs) {
definition = defs[0].word + ': 1.' + defs[0].text;
definition += '\n2.' + defs[1].text;
definition += '\n3.' + defs[2].text;
console.log(definition)
});
return definition;
};
Console.log inside function(e, defs) works.
but the return statement doesn't seem to return the value.
How to properly return 'definition' variable?
since wn.definition is an Asynchronous call you should use promise or async/await or callback features.
Using callback your code would be like something like this (for example lets say you store this in a def.js file):
exports.getDefiniton = function (text, callback) {
var definition = "";
wn.definitions(text, {
useCanonical: true
, includeRelated: true
, limit: 3
}, function (e, defs) {
definition = defs[0].word + ': 1.' + defs[0].text;
definition += '\n2.' + defs[1].text;
definition += '\n3.' + defs[2].text;
console.log(definition);
callback(definition);
});
};
and you can use def.js module like this:
var defModule = require("./def");
defModule.getDefiniton("Hello", function (defintion) {
console.log(defintion);
});
UPDATE:
#Xuva in that case check the code below:
var defModule = require("./def");
defModule.getDefiniton("Hello", function (definition) {
displayMessage(text, definition);
//rest of the code ...
});
I have the following function which selects a category from a list of available categories. This function works fine in my first test. But the same function with a different valid category name in my second test fails with the following error.
Error: Index out of bound. Trying to access element at index: 0, but there are only 0 elements that match locator By.cssSelector(".grid-view-builder__category")
this.categoryElements = element.all(by.css('.grid-view-builder__category'));
this.selectCategory = function (categoryName) {
var filteredCategories = this.categoryElements.filter(function (category) {
return category.getText().then(function (text) {
log.info(text);
return text === categoryName;
})
})
filteredCategories.first().click().then(function () {
log.info("Select Category: " + categoryName);
}).then(null, function (err) {
log.error("Category: " + categoryName + " Not Found !!" + err);
});
}
Spec File
var columnSelect = require('pages/grid/columns/columnselector-page')()
it('Add Publisher ID Column to the Grid & Verify', function () {
var columnCountBefore = columnSelect.getColumnCount();
columnSelect.openColumnSelector();
columnSelect.selectCategory('Advanced');
columnSelect.selectColumn('Publisher ID');
columnSelect.apply();
var columnCountAfter = columnSelect.getColumnCount();
expect(columnCountAfter).toBeGreaterThan(columnCountBefore);
});
The problem might be in the way you are defining and using Page Objects. Here is a quick solution to try - if this would help, we'll discuss on why that is happening.
Make the categoryElements a function instead of being a property:
this.getCategoryElements = function () {
return element.all(by.css('.grid-view-builder__category'));
};
this.selectCategory = function (categoryName) {
var filteredCategories = this.getCategoryElements().filter(function (category) {
return category.getText().then(function (text) {
log.info(text);
return text === categoryName;
})
})
filteredCategories.first().click().then(function () {
log.info("Select Category: " + categoryName);
}).then(null, function (err) {
log.error("Category: " + categoryName + " Not Found !!" + err);
});
}
Or, this could be a "timing issue" - let's add an Explicit Wait via browser.wait() to wait for at least a single category to be present:
var EC = protractor.ExpectedConditions;
var category = element(by.css('.grid-view-builder__category'));
browser.wait(EC.presenceOf(category), 5000);
It looks like this has nothing to do with the code posted here, only that the css selector you're using is not finding any elements
I want to call a method within a method for clientside but I don't know how to handle it, i've tried by calling like myFunction()and this.myFunction() but it is not working... This is my code
Template.decision.rendered = function () {
if ($(".active").length == 0) {
var random = Math.floor(Math.random() * 1000);
var $items = $(".item");
$items.eq(random % $items.length).addClass("active");
}
$.each($(".item"), function (index, value) {
if (Session.get($(this).attr('id'))) {
this.showResults(value.option);
}
});
};
Template.decision.showResults = function($option) {
$('#result').html('Option ' + $option + ' is voted');
};
As you can see I want to call showResults for each item inside rendered callback...
Found it using Template.decision.showResults(); silly me.
I think that a better way depending on what you are trying to do would be either to use a Session variable or a Meteor Method:
Session Variable.
Template.decision.created = function() {
Session.setDefault('showResults', false);
}
Template.decision.rendered = function() {
// [...]
$.each($(".item"), function (index, value) {
if (Session.get($(this).attr('id'))) {
Session.set('showResults', true);
}
});
}
Template.decision.showResults = function() {
return Session.get('showResults');
}
// in your template
<template name="decision">
{{#if showResults}}
<p>Here is the results.</p>
{{/if}}
</template>
Meteor Method.
// On the client.
Template.decision.rendered = function() {
// [...]
$.each($(".item"), function (index, value) {
if (Session.get($(this).attr('id'))) {
Meteor.call('showResults', function(error, result) {
if (!error and result === true) {
$('.class').hide() // It is here that you modify the DOM element according to the server response and your needs.
}
});
}
});
}
// Server-side method
// But, if you want it to react like a stub, put it inside your lib folder.
Meteor.methods({
showResults: function() {
// do your thing
result = true; // let's say everything works as expected on server-side, we return true
return result;
}
});
When I run this code in Chrome DevTool,
require(['common'], function (common) { common.getProfilPic(123); })
It always print the whole chunk of requirejs code,
function localRequire(deps, callback, errback) {
var id, map, requireMod;
if (options.enableBuildCallback && callback && isFunction(callback)) {
callback.__requireJsBuild = true;
}
if (typeof deps === 'string') {
if (isFunction(callback)) {
//Invalid call
return onError(makeError('requireargs', 'Invalid require call'), errback);
}
//If require|exports|module are requested, get the
//value for them from the special handlers. Caveat:
//this only works while module is being defined.
if (relMap && hasProp(handlers, deps)) {
return handlers[deps](registry[relMap.id]);
}
//Synchronous access to one module. If require.get is
//available (as in the Node adapter), prefer that.
if (req.get) {
return req.get(context, deps, relMap, localRequire);
}
//Normalize module name, if it contains . or ..
map = makeModuleMap(deps, relMap, false, true);
id = map.id;
if (!hasProp(defined, id)) {
return onError(makeError('notloaded', 'Module name "' +
id +
'" has not been loaded yet for context: ' +
contextName +
(relMap ? '' : '. Use require([])')));
}
return defined[id];
}
//Grab defines waiting in the global queue.
intakeDefines();
//Mark all the dependencies as needing to be loaded.
context.nextTick(function () {
//Some defines could have been added since the
//require call, collect them.
intakeDefines();
requireMod = getModule(makeModuleMap(null, relMap));
//Store if map config should be applied to this require
//call for dependencies.
requireMod.skipMap = options.skipMap;
requireMod.init(deps, callback, errback, {
enabled: true
});
checkLoaded();
});
return localRequire;
} require.js:1361
require(['common'], function (common) { console.log(common.getProfilPic(123)); })
function localRequire(deps, callback, errback) {
var id, map, requireMod;
if (options.enableBuildCallback && callback && isFunction(callback)) {
callback.__requireJsBuild = true;
}
if (typeof deps === 'string') {
if (isFunction(callback)) {
//Invalid call
return onError(makeError('requireargs', 'Invalid require call'), errback);
}
//If require|exports|module are requested, get the
//value for them from the special handlers. Caveat:
//this only works while module is being defined.
if (relMap && hasProp(handlers, deps)) {
return handlers[deps](registry[relMap.id]);
}
//Synchronous access to one module. If require.get is
//available (as in the Node adapter), prefer that.
if (req.get) {
return req.get(context, deps, relMap, localRequire);
}
//Normalize module name, if it contains . or ..
map = makeModuleMap(deps, relMap, false, true);
id = map.id;
if (!hasProp(defined, id)) {
return onError(makeError('notloaded', 'Module name "' +
id +
'" has not been loaded yet for context: ' +
contextName +
(relMap ? '' : '. Use require([])')));
}
return defined[id];
}
//Grab defines waiting in the global queue.
intakeDefines();
//Mark all the dependencies as needing to be loaded.
context.nextTick(function () {
//Some defines could have been added since the
//require call, collect them.
intakeDefines();
requireMod = getModule(makeModuleMap(null, relMap));
//Store if map config should be applied to this require
//call for dependencies.
requireMod.skipMap = options.skipMap;
requireMod.init(deps, callback, errback, {
enabled: true
});
checkLoaded();
});
return localRequire;
}
and and me from seeing the log result, and idea how to stop requirejs to print itself?
Run this instead:
(function(){ require(['common'], function (common) { common.getProfilPic(123); }) })()
What happens is that the console is printing out the value of the expression. The value of a function call is what the call returns. You can easily work around it with something like:
require(['common'], function (common) { common.getProfilPic(123); }); 1
Adding ; 1 will make the expression evaluate to 1. So you'll get 1 on the console but at least it won't push diagnostic messages off the screen.
I'm making an AJAX call from within an Anonymous function. When the success callback takes place I'm then able to set my custom JS objects ids and other important info that has arrived from the data server.
After I set the a.target.id to the returned data.id everything looks fine.
On the step where I'm calling a function to do some work with the newly updated custom JS object, that I just updated with the response data from the server. I am passing the parent of that object to the method to do some work on all the children of that object.
However, as you can see on the last example in the snap shot photos the a.target.parent.children[0].id is not in the collection and/or it's ids where never set.
I must be losing a reference to that object during the AJAX call when using an Anonymous function.
Here is all of the code. How am I losing the reference? Or how can I maintain a reference to that parent's children when the AJAX call returns?
I've never had this happen before, makes me believe that it has something to do with the Anonymous function.
var horizontalPositioner = function (horizontals) {
var hpa = ['?horPositions='];
for (var i = 0; i < horizontals.children.length; i += 1) {
hpa.push(horizontals.children[i].id + ':' + horizontals.children[i].position + ',');
};
hpa[i] = hpa[i].replace(',', '');
dataBase.update(dbPart('horizontal' + hpa.join('')));
};
this.subscribe.call(this, e.horizontaladded, function (a, fn) {
//
if (!a.extra.owner.id) {
return;
};
(function (a) {
dataBase.insert(
dbPart(
['horizontal?a=', a.extra.owner.instanceName, '&id=', a.extra.owner.id].join(''),
a.target
),
dbCB(
function (data, status) {
if (status === 'error') { return; };
a.target.id = data.id,
a.target.HTML().addClass('alum_' + data.id),
a.target.finish.id = data.finishID,
a.target.size.id = data.sizeID,
a.target.siteLine.id = data.sitelineID;
//
//reposition horizontals
// setTimeout(function () { horizontalPositioner(a.target.parent); }, 1000);
debugger
horizontalPositioner(a.target.parent);
if (fn) { processCallbacks(data, status, fn); };
//very last
events.publishDatabaseCallbacks(e.horizontaladded,
eArgs(a.bay, { data: data, instanceName: 'horizontal', ownerid: a.extra.owner.id, id: data.id }));
},
function (xhr, status, errorThrown) { console.log('ERROR adding horizontal'); })
);
}(a));
}, true);
I've added an anonymous function with a nested setTimeout to give everything time to build. I've got many events taking place at once, so for now this works.
var horizontalPositioner = function (horizontals) {
(function (hors) {
setTimeout(function () {
var hpa = ['?horPositions='];
for (var i = 0; i < hors.children.length; i += 1) {
hpa.push(hors.children[i].id + ':' + (hors.children[i].position ? hors.children[i].position : 1) + ',');
};
hpa[i] = hpa[i].replace(',', '');
dataBase.update(dbPart('horizontal' + hpa.join('')));
}, 1000);
}(horizontals));
};