How to unit test a non AMD JavaScript file using Intern? - intern

I have a non AMD JavaScript file with a class Snake like so:
// ./www/js/Snake.js
function Snake(initPos) {
this.pos = initPos;
}
// I want to unit test this method.
Snake.proptotype.move = function(dir) {
// Do things.
};
I wrote an Intern module to test it:
// ./test/Snake.js
define([
'intern!object',
'intern/chai!assert',
"../www/js/Snake"
], function (registerSuite, assert, Snake) {
registerSuite({
name: 'Snake',
move: function () {
// Intern complains that this object is not a function.
var snake = new Snake([
{x: 0, y: 0},
{x: 1, y: 0},
{x: 2, y: 0}
]);
snake.move("right");
...
How to make Intern recognize the Snake class?

I found what the problem is. In the intern configuration file I need to set the loader packages option as follows:
// ./tests/intern.js
define({
...
loader: {
packages: [ { name: 'app', location: 'www/js' } ]
},
...
Then in my test module I need to import the Snake.js file:
// ./tests/Snake.js
define([
'intern!object',
'intern/chai!assert',
"intern/order!app/Snake.js"
], function (registerSuite, assert) {
registerSuite({
name: 'Snake',
move: function () {
var snake = new Snake([
{x: 0, y: 0},
{x: 1, y: 0},
{x: 2, y: 0}
]);
...
Now it doesn't complain that Snake is undefined.

Related

Text Ellipsis in bubble chart

i'm using bubble chart from Highcharts, the label text inside of the bubbles is dynamic and sometimes can be bigger than the bubble itself,
I wonder if there's a way to make the text ellipsis according to the size of the bubble that contain it?
containerOptions = {
chart: {
type: 'bubble',
renderTo: $(container)[0],
events: {
drilldown: function (e) {
if (!e.seriesOptions) {
var chart = this,
drilldowns = {
'Animals': {
name: 'Animals',
data: [
{name: 'Dogs', y:2, x:10, z: 7, drilldown: true},
{name: 'Cats', y:4, x:12, z: 7}
]
},
'Dogs': {
name:"Dogs",
data: [
{name: 'Pitbull', y:3.7, x:7.6, z: 5, drilldown: false},
{name: 'German shepherd', y:6.7, x:6.9, z: 5, drilldown: false}
]
}
},
series = drilldowns[e.point.name];
chart.showLoading('Loading..');
setTimeout(function () {
chart.hideLoading();
chart.addSeriesAsDrilldown(e.point, series);
}, 1000);
}
}
}
},
plotOptions: {
series: {
borderWidth: 0,
dataLabels: {
enabled: true,
style: { color: 'red' },
format: '{point.name}'
}
}
},
series: [{
name: 'Things',
colorByPoint: true,
data: [{
name: 'Animals',
y: 5,
x: 1,
z: 9,
drilldown: true
}, {
name: 'Fruits',
y: 2,
x: 9,
z: 9,
drilldown: false
}
]
}],
drilldown: {
series: [],
drillUpButton: {
relativeTo: 'spacingBox',
position: {
y: 0,
x: 0
}
}
}
}
}
You can loop through the data labels on load/redraw event and add/remove ellipsis according to the bubble's width and text's width.
function applyEllipsis() {
var series = this.series[0];
var options = series.options.dataLabels;
series.points.forEach(p => {
var r = p.marker.radius;
var label = p.dataLabel;
var text = label.text.textStr;
var bbox = label.getBBox(true);
while (bbox.width > 2 * r && text.length !== 1) {
text = text.slice(0, -1);
p.dataLabel.attr({
text: text + '\u2026'
});
bbox = label.getBBox(true);
}
p.dataLabel.align({
width: bbox.width,
height: bbox.height,
align: options.align,
verticalAlign: options.verticalAlign
}, null, p.dlBox);
});
}
Attach the function on load/redraw
Highcharts.chart('container', {
chart: {
type: 'bubble',
events: {
load: applyEllipsis,
redraw: applyEllipsis
}
},
example: http://jsfiddle.net/12d997o4/

How to scan through objects that are inside object. [JavaScript]

I am making a barcode scanner for my school project but i am stuck. I dont know how to scan through this object. I have this object with objects inside, and I need to scan through each object inside storage variable to check its barcode.
var storage = {
bolts: {
barcode: 57263144,
price: 0.5,
name: 'Plain Brackets',
stock: 25,
},
brackets: {
barcode: 13245627,
price: 0.2,
name: '100mm Bolts',
stock: 2,
},
}
I have a variable called barcode, and I need to test this variable if its the same like one of these. I tried using
for (var key in storage){
if (storage[key].barcode === barcode){
}
}
I would like the most simple way to do that.
Use Object.keys:
Object.keys(obj).forEach(function(key) {
console.log(key, obj[key]);
});
Below is the example:
var storage = {
"bolts": {
barcode: 57263144,
price: 0.5,
name: 'Plain Brackets',
stock: 25,
},
"brackets": {
barcode: 13245627,
price: 0.2,
name: '100mm Bolts',
stock: 2,
}
}
var barcode = 57263144;
Object.keys(storage).forEach(function(key) {
if(storage[key].barcode === barcode) { console.log("do something")}
});
A Fiddle:
https://jsfiddle.net/spechackers/34bhthza/
Use the recursive function to verify if exist more nodes in the objects, example:
const complexObj = {
name: "nobody",
address: { number: 22, moreNumbers: [1,2,3,4,5] },
colors: ["green", "red"],
numbersAgain: { first: 1, second: 4 }
};
function scanObj(obj){
for (let i in obj) {
/*
*Do some verificatio, example:
*I'd like to verify all numbers and if the numbers is greater than 3:
*/
if(typeof obj[i] == "number" && obj[i] > 3){ console.log(obj[i]); }
if (typeof obj[i] === "object") {
scanObj(obj[i])
}
}
}
//call the method
scanObj(complexObj);
Output: 22 4 5 4

Mongoose .find() with conditions returns no result

I am working on a MEAN Stack app with a pre-existing MongoDB collection and if I define conditions for .find() no results were returned while it works without conditions.
Here is the code from my model file:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var mainSchema = new Schema({
id: Number,
x: Number,
y: Number,
prio: Number,
type0: String,
type1: String,
type2: String,
width: Number,
height: Number,
text1: String,
text2: String,
size1: Number,
font: String,
color1: String,
color2: String,
links: String,
peers: String
}, { collection: 'main' });
mainSchema.statics = {
load: function(l, t, r, b, cb){
console.log(l, t, r, b);
return this.find({
x: { $gt: l, $lt: r },
y: { $gt: t, $lt: b }
}).exec(cb);
}
};
module.exports = mongoose.model('main', mainSchema);
This is one object from the output without conditions:
[
{
"_id": "577faf952a7c33f2fe44b282",
"id": 4,
"x": 50944,
"y": 54995,
"prio": 1,
"type0": "a",
"type1": "a",
"type2": "a",
"width": 100,
"height": 100,
"text1": "Chemie",
"text2": "",
"size1": 48,
"font": "f1_a ",
"color1": "#000000",
"color2": "#bfdeff",
"links": "14,53445,57328,12,#ff3d3d,k&13,54744,53904,12,#8c8c86,k&12,52557,51870,12,#f2ff12,k&11,51172,49743,12,#2312ff,k&10,48270,47335,12,#49fe6e,k&",
"peers": "1"
}
]
Here is the code that calls the load methode:
var mongoose = require('mongoose');
var main = require('../models/main');
exports.load = function(req, res){
main.load(parseInt(req.query.l), parseInt(req.query.t), parseInt(req.query.r), parseInt(req.query.b), function(err, data) {
res.jsonp(data);
});
};
Problem solved!
Despite the output all data were stored as strings instead of int within MongoDB.
I just copied the JSON output (where the types are correct) to a file and imported it to MongoDB, now the code works fine.

Adding color through a function in flot graph

Can i add color dynamically by calling through a function passed by the user.
I already have the options variable defined by default, the color which the user passes should sit in the option variable. Is this possible? please help
var options = {
series: {
lines: {
show: true
},
points: {
show: true
},
color: '#00c7ce'--> user should pass dynamically
},
xaxis: {
mode: "time",
tickSize: [1, "month"],
tickLength: 0,
},
yaxis: {
show: false
}
}
};
You should be able to pass a color to the options. Setup your input then use that variable as your color.
<input id="userInput"></input>
var usrColor = $("#userInput").val();
var options = {
series: {
lines: { show: true},
points: {show: true, radius: 4},
color: usrColor
}
};
fiddle - http://jsfiddle.net/Rnusy/4/

Ext JS 4: Custom object property value based on condition

I'm trying to create custom property values (based on a condition of a function) for my Ext objects, instead of specifying just a value.
Example 1:
old code (working)
this.buttons = [
{
text: 'Save',
new code (not working)
this.buttons = [
{
text: function() {
return 'Save X';
},
Example 2:
old code (working)
}, {
width: 270,
labelAlign: 'right',
xtype: 'textfield',
name: 'user_id',
fieldLabel: 'User ID',
hidden: true
}]
new code (not working)
}, {
width: 270,
labelAlign: 'right',
xtype: 'textfield',
name: 'user_id',
fieldLabel: 'User ID',
hidden: function() { return true; }
}]
Example 3:
Ignore entire textfield object (lazy instance) completely based on a condition:
}, {
width: 270,
labelAlign: 'right',
xtype: 'textfield',
name: 'employee_number',
fieldLabel: 'Employee Number'
}]
You simply can't do it this way. It is not possible to replace a type with a function. In your case you assign a function reference to a variable which is expected to be boolean, same for the string.
Solution A.
You should consider to write yourself a field factory. Within that factory you can then execute any function before assigning configs. (Sort of same then B but can be used to reduce function calls)
Solution B.
Use a function reference itself. This one should then get executed. (spare the requirement of class extension and is over that reuseable)
// The data store containing the list of states
var states = Ext.create('Ext.data.Store', {
fields: ['abbr', 'name'],
data : [
{"abbr":"AL", "name":"Alabama"},
{"abbr":"AK", "name":"Alaska"},
{"abbr":"AZ", "name":"Arizona"}
//...
]
});
Ext.namespace('my.util.helper');
my.util.helper.decideHide = function() { return true; }
// Create the combo box, attached to the states data store
Ext.create('Ext.container.Container', {
renderTo: Ext.getBody(),
items: [{
xtype: 'combo',
fieldLabel: 'Choose State',
store: states,
queryMode: 'local',
displayField: 'name',
valueField: 'abbr',
test: my.util.helper.decideHide(),
listeners: {
afterrender: function(n) {
alert(n.test);
}
}
}]
});
Solution C.
And the solution I use most in such cases are simplified if else statements
// ... // more code
{
    text: myCondition ? 'Text A' : 'Text B',
// more code
}
// ... // more code
Yeah that is not going to work, some Ext configs take a function that will be evaluated but most of them don't. Instead of creating anonymous functions and not invoking them I would do something like this:
Ext.define('UserPanel', {
extend : 'Ext.panel.Panel',
initComponent : function() {
this.items = [{
xtype : 'button',
text : this._getSaveButtonText()
}, {
width : 270,
labelAlign : 'right',
xtype : 'textfield',
name : 'user_id',
fieldLabel : 'User ID',
hidden : this._isUserIdHidden()
}]
this.callParent();
},
_getSaveButtonText : function() {
return 'Save';
},
_isUserIdHidden : function() {
return true;
}
});

Resources