Polyemer unit testing - polymer-1.0

I have problems testing the next component:
<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../bower_components/paper-input/paper-input.html">
<link rel="import" href="../maps/maps-api.html">
<dom-module id="address-input">
<template>
<maps-api on-api-load="_onApiLoad"></maps-api>
<paper-input
id="address"
name$="[[name]]"
label$="[[label]]"
placeholder="[[placeholder]]"
required$="[[required]]"
value="{{value}}"
disabled="{{disabled}}"
always-float-label
on-keydown="_onKeyDown"></paper-input>
</template>
<script>
(function () {
'use strict';
Polymer({
is: 'address-input',
properties: {
value: {
type: String,
notify: true
},
name: {
type: Object
},
label: {
type: Object
},
lastAutoCompleteResult: {
type: Object,
notify: true,
observer: '_onLastAutoCompleteResultChange'
},
disabled: {
type: Boolean,
value: false
},
required: {
type: Boolean,
value: false
},
map: {
type: Object
}
},
attached: function () {
if (!this._autocomplete && window.google && window.google.maps) this._onApiLoad();
},
_onApiLoad: function () {
//DOES SOMETHING
}
_onLastAutoCompleteResultChange: function () {
//DOES SOMETHING
}
});
})();
</script>
</dom-module>
and that module includes maps-api
<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="stylesheet" href="../../bower_components/google-apis/google-maps-api.html">
<!--
Wrapper for the google maps api component in order to avoid copying the
API key everywhere just import this component instead.
-->
<dom-module id="maps-api">
<template>
<google-maps-api api-key="[[apiKey]]" version="3"></google-maps-api>
</template>
<script>
(function () {
'use strict';
Polymer({
is: 'maps-api',
properties: {
apiKey: {
type: String,
value: APP_CONFIG.gmapsApiKey
},
}
})
})();
</script>
</dom-module>
this is the test:
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>my-greeting-basic</title>
<script src="../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="../bower_components/web-component-tester/browser.js"></script>
<!-- Import the element to test -->
<link rel="import" href="../elements/common/address-input.html">
</head>
<maps-api on-api-load="_onApiLoad"></maps-api>
<body>
<test-fixture id="address-input">
<template>
<address-input
id="address"
value="430 W Erie St"
></address-input>
</template>
</test-fixture>
<script>
describe('address-input', function (done) {
var addressInput, id, value;
beforeEach(function () {
APP_CONFIG = {};
APP_CONFIG = {gmapsApiKey:"someKey"};
addressInput = fixture('address-input');
});
test('should enable when disable is false', function () {
addressInput.disabled = false;
var element = document.getElementById('address');
var isDisabled = element.disabled;
assert.equal(isDisabled, false);
});
});
</script>
</body>
</html>
The problem is the global variable APP_CONFIG is undefined forthe component map-api
I get this error:
Error: APP_CONFIG is not defined
at /components/elements/maps/maps-api.html:23
at /components/elements/maps/maps-api.html:27
(I'm using Mocha,Chai and Sinon)
what's the correct way to set global variables in polymer testing?

Related

How to map an array of objects [duplicate]

I am new to React JS The question is that I need to display all the fields from my database in this piece of code. I have been able to obtain all the data as objects in the browser console and I am able to view the last piece of data in the array in the browser but have not been able to view them. Please forgive me for the wrong format in the code as I am new to this.Thanks in advance.....
Output and Codes
Browser View:
Land of Toys Inc. is the name 131 is the ID
The JSON data :
{"posts":[
{"id":"103","name":"Atelier graphique"},
{"id":"112","name":"Signal Gift Stores"},
{"id":"114","name":"Australian Collectors, Co."},
{"id":"119","name":"La Rochelle Gifts"},
{"id":"121","name":"Baane Mini Imports"},
{"id":"124","name":"Mini Gifts Distributors Ltd."},
{"id":"125","name":"Havel & Zbyszek Co"},
{"id":"128","name":"Blauer See Auto, Co."},
{"id":"129","name":"Mini Wheels Co."},
{"id":"131","name":"Land of Toys Inc."}
]}
This data is obtained through a PHP code written as a plugin which is in the form of a url which is given in the JS code
http://localhost/Akshay/REACT/testDataAPI.php?user=2&num=10&format=json
My Code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>React Tutorial</title>
<!-- Not present in the tutorial. Just for basic styling. -->
<link rel="stylesheet" href="css/base.css" />
<script src="https://npmcdn.com/react#15.3.0/dist/react.js"></script>
<script src="https://npmcdn.com/react-dom#15.3.0/dist/react-dom.js"></script>
<script src="https://npmcdn.com/babel-core#5.8.38/browser.min.js"></script>
<script src="https://npmcdn.com/jquery#3.1.0/dist/jquery.min.js"></script>
<script src="https://npmcdn.com/remarkable#1.6.2/dist/remarkable.min.js"></script>
</head>
<body>
<div id="content"></div>
<script type="text/babel">
var UserGist = React.createClass({
getInitialState: function() {
return {
username:[],
companyID:[]
};
},
componentDidMount: function()
{
var rows = [];
this.serverRequest = $.get(this.props.source, function (result) {
for (var i=0; i < 10; i++)
{
var lastGist = result.posts[i];
//console.log(result.posts[i]);
this.setState({
username: lastGist.id,
companyID: lastGist.name
});
}
}.bind(this));
},
componentWillUnmount: function() {
this.serverRequest.abort();
},
render: function() {
return (
<li>{this.state.companyID} is the name {this.state.username} is the ID</li>
);
}
});
ReactDOM.render(
<UserGist source="http://localhost/Akshay/REACT/testDataAPI.php?user=2&num=10&format=json" />,
document.getElementById('content')
);
</script>
</body>
</html>
Use map to render your data. and store the json as a javascript object in the state itself instead of two seperate arrays.
<!-- Not present in the tutorial. Just for basic styling. -->
<link rel="stylesheet" href="css/base.css" />
<script src="https://npmcdn.com/react#15.3.0/dist/react.js"></script>
<script src="https://npmcdn.com/react-dom#15.3.0/dist/react-dom.js"></script>
<script src="https://npmcdn.com/babel-core#5.8.38/browser.min.js"></script>
<script src="https://npmcdn.com/jquery#3.1.0/dist/jquery.min.js"></script>
<script src="https://npmcdn.com/remarkable#1.6.2/dist/remarkable.min.js"></script>
<div id="content"></div>
<script type="text/babel">
var UserGist = React.createClass({
getInitialState: function() {
return {
data: [{"id":"103","name":"Atelier graphique"},
{"id":"112","name":"Signal Gift Stores"},
{"id":"114","name":"Australian Collectors, Co."},
{"id":"119","name":"La Rochelle Gifts"},
{"id":"121","name":"Baane Mini Imports"},
{"id":"124","name":"Mini Gifts Distributors Ltd."},
{"id":"125","name":"Havel & Zbyszek Co"},
{"id":"128","name":"Blauer See Auto, Co."},
{"id":"129","name":"Mini Wheels Co."},
{"id":"131","name":"Land of Toys Inc."}]
};
},
componentDidMount: function()
{
},
componentWillUnmount: function() {
this.serverRequest.abort();
},
render: function() {
return (
<div>
{this.state.data.map(function(item, index){
return <li>{item.name} is the company name, {item.id} is the ID</li>
})}</div>
);
}
});
ReactDOM.render(
<UserGist source="http://localhost/Akshay/REACT/testDataAPI.php?user=2&num=10&format=json" />,
document.getElementById('content')
);
</script>
</html>
JSFIDDLE
For the fiddle example I have deleted your $.get() code in componentDidMount.
P.S. Create the state array data as an array of object as shown in the
fiddle example
It will help you i think.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>React Tutorial</title>
<!-- Not present in the tutorial. Just for basic styling. -->
<link rel="stylesheet" href="css/base.css" />
<script src="https://npmcdn.com/react#15.3.0/dist/react.js"></script>
<script src="https://npmcdn.com/react-dom#15.3.0/dist/react-dom.js"></script>
<script src="https://npmcdn.com/babel-core#5.8.38/browser.min.js"></script>
<script src="https://npmcdn.com/jquery#3.1.0/dist/jquery.min.js"></script>
<script src="https://npmcdn.com/remarkable#1.6.2/dist/remarkable.min.js"></script>
</head>
<body>
<div id="content"></div>
<script type="text/babel">
var UserGist = React.createClass({
getInitialState: function() {
return {
username:[],
companyID:[]
};
},
componentDidMount: function()
{
var rows = [];
this.serverRequest = $.get(this.props.source, function (result) {
var username = [];
var companyID = [];
for (var i=0; i < 10; i++)
{
var lastGist = result.posts[i];
//console.log(result.posts[i]);
username.push(lastGist.id);
companyID.push(lastGist.name);
}
this.setState({
username: username,
companyID: companyID,
});
}.bind(this));
},
componentWillUnmount: function() {
this.serverRequest.abort();
},
render: function() {
return (
<div>
{this.state.companyID.map(function(item, index){
return <li>{item} is the company name, {this.state.username[index]} is the ID</li>
})}</div>
);
}
});
ReactDOM.render(
<UserGist source="http://localhost/Akshay/REACT/testDataAPI.php?user=2&num=10&format=json" />,
document.getElementById('content')
);
</script>
</body>
</html>

i18next - strings don't update when the language is changed

I am integrating the i18next library with my Angular 1.5.3 project.
https://github.com/i18next/ng-i18next
When I use the changeLanguage feature the strings on my page don't update to the correct language.
Here's my html:
<!DOCTYPE html>
<html lang="en">
<head>
<script data-require="angular.js#1.5.3" data-semver="1.5.3" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.3/angular-sanitize.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/i18next/8.4.1/i18next.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ng-i18next/1.0.4/ng-i18next.min.js"></script>
<script src="app.js"></script>
<meta charset="utf-8" />
</head>
<body ng-app="myApp">
<div ng-controller="MyCtrl">
Hello, {{name}}!
<div ng-i18next="HELLO"></div>
<button ng-click="change()">change lng</button>
</div>
</body>
</html>
Here's my app.js
if (window.i18next) {
window.i18next.init({
debug: true,
lng: 'en', // If not given, i18n will detect the browser language.
fallbackLng: 'en', // Default is dev
resources: {},
useCookie: false,
useLocalStorage: false,
joinArrays: '<br />'
});
}
var myApp = angular.module('myApp', ['ngSanitize', 'jm.i18next']);
myApp.controller('MyCtrl', MyCtrl);
function MyCtrl($scope, $i18next) {
$scope.name = 'Superhero';
$scope.change = function() {
$i18next.i18n.changeLanguage('fr', function(err, t) {
console.log(t('HELLO')); //prints out bonjour
});
console.log($i18next.t('HELLO')); //prints out hiya
};
$i18next.i18n.addResourceBundle('en', 'translation', {
'HELLO': 'hiya'
});
$i18next.i18n.addResourceBundle('fr', 'translation', {
'HELLO': 'bonjour'
});
console.log($i18next.t('HELLO')); //prints out hiya
}
Plunkr: https://plnkr.co/edit/7oI13bNJVqVgTEFOT6bk
I don't know how I can 'refresh' my page to get the correct translations.
Working plunker
Use this to change the language $i18next.changeLanguage('fr');
Replace:
$i18next.i18n.changeLanguage('fr', function(err, t) {
console.log(t('HELLO')); //prints out bonjour
});
with this:
$i18next.changeLanguage('fr');
Translations in the controller
For translations to be performed in the controller after a language change happens, listen for the i18nextLanguageChange event and then perform translations like below.
// Listen for the language change event and perform $scope bindings
$scope.$on('i18nextLanguageChange', function () {
// Inside a timeout to allow the language change to complete
$timeout(function () {
console.log($i18next.t('HELLO'));}
);
});

Error: ng:areq Bad Argument Argument 'msgController' is not a function, got undefined

I am new to angularJS and I couldn't understand why this error is coming. Please help find where I have done mistake.
index.html
<!DOCTYPE html>
<html ng-app="MyApp">
<head>
<title>Angular JS Web-Socket</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
<script src="js/chat.js"></script>
<script src="lib/ngDialog.js"></script>
<link rel="stylesheet" type="text/css" href="css/ngDialog-theme-default.css">
<link rel="stylesheet" type="text/css" href="css/ngDialog.css">
<body>
<button ng-controller="MainCtrl" ng-click="openChatBox()">Open</button>
</body>
</html>
chatBox.html
<script src="lib/ngDialog.js"></script>
<script src="lib/angular-websocket.js"></script>
<script src="js/socket.js"></script>
<link rel="stylesheet" type="text/css" href="css/ngDialog.css">
<link rel="stylesheet" type="text/css" href="css/chat.css">
<!-- The Modal -->
<div id="myModal" class="modal" ng-app="chatSocket">
<!-- Modal content -->
<div class="modal-content">
<div class="modal-header">
<div class="menu">
<div class="name">Bot</div>
<div class="close">Close</div>
</div>
</div>
<div class="modal-body" ng-controller="msgController">
<h2>Modal body</h2>
<label ng-repeat="item in socket.msg">
Name : {{item.name}} <br>
Msg : {{item.msg}}
</label>
</div>
<div class="modal-footer">
<h3>Modal Footer</h3>
<form ng-submit="submit()">
<input type="text" ng-model="msgbox">
<button id="sendMsg" type="submit" >Send Message</button>
</form>
</div>
chat.js
var app = angular.module('MyApp', ['ngDialog']);
app.controller('MainCtrl', function ($scope, ngDialog) {
$scope.openChatBox = function() {
ngDialog.openConfirm({template: 'chatBox.html',
scope: $scope //Pass the scope object if you need to access in the template
}).then(
function(value) {
//You need to implement the saveForm() method which should return a promise object
$scope.closeChat().then(
);
},
function(value) {
//Cancel or do nothing
}
);
};
});
socket.js
angular.module('chatSocket', ['ngWebSocket'])
.factory('socket', function ($websocket) {
// Open a WebSocket connection
var ws = $websocket("ws://" + document.location.host + document.location.pathname);
var msg = [];
ws.onMessage(function (event) {
console.log('message: ', event.data);
var response;
try {
response = event.data;
} catch (e) {
console.log('error: ', e);
}
msg.push({
name: "Bot",
msg: response,
});
});
ws.onError(function (event) {
console.log('connection Error', event);
});
ws.onClose(function (event) {
console.log('connection closed', event);
});
ws.onOpen(function () {
console.log('connection open');
ws.send('HELLO SERVER');
});
return {
msg: msg,
status: function () {
return ws.readyState;
},
send: function (message) {
console.log(message);
msg.push({
name: "User",
msg: message,
});
ws.send(message);
}
};
})
.controller('msgController', function ($scope, socket) {
$scope.socket = socket;
$scope.submit = function () {
socket.send($scope.msgbox);
};
});
If I didn't use msgController, the dialog box is opening. when I include this, the error is shown and couldn't open the dialog box.
Because you are referencing the msgController in openConfirm method of ngDialog and you didn't define it.
ngDialog.openConfirm({
template: 'chatBox.html',
controller: 'msgController',
scope: $scope //Pass the scope object if you need to access in the template
})
In addition to that you have specified msgController in chatSocket module and you are using it in MyApp module which is why you are getting the error.
You need to specify the chatSocket as dependency to MyApp module and define the msgController on MyApp module like blow:
var app = angular.module('MyApp', ['ngDialog','chatSocket']);
app.controller('msgController', function ($scope, socket) {
$scope.socket = socket;
$scope.submit = function () {
socket.send($scope.msgbox);
};
});

Polymer neon-animation : Can I animate multiple nodes with one animation?

Regarding Neon Animations ( https://elements.polymer-project.org/guides/using-neon-animations )
Is it possible to specify the same animation to run simultaneously on multiple nodes?
For example:
animationConfig: {
value: function() {
return {
'entry': {
name: 'bounce-in-animation',
node: Polymer.dom(this.root).querySelectorAll("div"), // here
timing: {duration: 1000}
},
'exit': {
name: 'fade-out-animation',
node: this
}
}
}
}
In the above code sample (specifically in "//here"), I’m attempting to run ‘bounce-in-animation’ on multiple div instances instead of just one.
Is this presently possible?
I tried the code above, and got a 'Cannot execute' type of error. So I'm really asking if there is a way to achieve what the code above intends. Thanks
You have to import cascaded-animation and in your entry definition use:
{
name: 'cascaded-animation',
animation: 'bounce-in-animation',
nodes: Polymer.dom(this.root).querySelectorAll("div"),
nodeDelay: 0, // You can use this to delay animation between each node
timing: {duration: 1000}
}
Here you have a quick demo:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Polymer cascaded animation</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/0.7.22/webcomponents.min.js"></script>
<link href="https://polygit.org/components/polymer/polymer.html" rel="import">
<link href="https://polygit.org/components/neon-animation/neon-animation-runner-behavior.html" rel="import">
<link href="https://polygit.org/components/neon-animation/animations/fade-in-animation.html" rel="import">
<link href="https://polygit.org/components/neon-animation/animations/cascaded-animation.html" rel="import">
</head>
<body>
<dom-module id="x-foo">
<template>
<div>
Hi! I'm a div!
</div>
<div>
Hello! I'm another div!
</div>
<div>
And I'm the last div!
</div>
<button on-tap="runAnimation">Click me!</button>
</template>
<script>
HTMLImports.whenReady(function () {
Polymer({
is: 'x-foo',
behaviors: [
Polymer.NeonAnimationRunnerBehavior
],
properties: {
animationConfig: {
value: function() { return {
'entry': {
name: 'cascaded-animation',
animation: 'fade-in-animation',
nodes: Polymer.dom(this.root).querySelectorAll("div"),
nodeDelay: 0, // You can use this to delay animation between each node
timing: {duration: 1000}
}
} }
}
},
runAnimation: function() {
this.playAnimation('entry')
}
});
});
</script>
</dom-module>
<x-foo></x-foo>
</body>
</html>
EDIT: If you are confused about imports - import from bower_components, I had to import from those sources to make the demo work.
EDIT2: After reading your comment I have another idea: you can tell Polymer that every time the elements is initialized you want it to check all of the divs in it and register animation for this one. I'm not best at describing but maybe the demo will help you understand it better:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Polymer cascaded animation</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/0.7.22/webcomponents.min.js"></script>
<link href="https://polygit.org/components/polymer/polymer.html" rel="import">
<link href="https://polygit.org/components/neon-animation/neon-animation-runner-behavior.html" rel="import">
<link href="https://polygit.org/components/neon-animation/animations/fade-in-animation.html" rel="import">
<link href="https://polygit.org/components/neon-animation/animations/cascaded-animation.html" rel="import">
</head>
<body>
<dom-module id="x-foo">
<template>
<div>
Hi! I'm a div!
</div>
<div>
Hello! I'm another div!
</div>
<div>
And I'm the last div!
</div>
<button on-tap="runAnimation">Click me!</button>
</template>
<script>
HTMLImports.whenReady(function () {
Polymer({
is: 'x-foo',
behaviors: [
Polymer.NeonAnimationRunnerBehavior
],
properties: {
animationConfig: {
value: function() { return {
'entry': {
// Leave empty
}
} }
}
},
ready: function() {
var divsNL = Polymer.dom(this.root).querySelectorAll('div');
var divs = Array.prototype.slice.call(divsNL);
var output = [];
divs.forEach(function(item) {
output.push({
name: 'fade-in-animation',
node: item,
timing: { duration: 1000 }
});
});
this.set('animationConfig.entry', output);
},
runAnimation: function() {
this.playAnimation('entry')
}
});
});
</script>
</dom-module>
<x-foo></x-foo>
</body>
</html>

passing object to angularjs directive from the controller

Trying to get my head around AngularJS directives. I need to pass a full object from my main controller to the directive. See the code below and jsfiddle: http://jsfiddle.net/graphicsxp/Z5MBf/4/
<body ng-app="myApp">
<div ng-controller="MandatCtrl">
<div person myPerson="mandat.person"></div>
<span>{{mandat.rum}}</span>
<span>{{mandat.person.firstname}}</span>
</div>
and the script:
var myApp = angular.module("myApp", []);
myApp.controller("MandatCtrl", function ($scope) {
$scope.mandat = { rum: "15000", person: { id: 1408, firstname: "sam" } };
});
myApp.directive("person", function () {
return {
scope: {
myPerson: "="
},
template: 'test: <div ng-model="myPerson"><input type="text" ng-model="firstname" /></div>'
}
});
Ok, the binding is working fine for mandat.rum and mandat.person.firstname.
However, I'm trying to pass mandat.person to the directive, and it does not work. I know I must be doing something wrong, the question is what ? :)
Pls see below working copy
<!doctype html>
<html ng-app="plunker" >
<head>
<meta charset="utf-8">
<title>AngularJS Plunker</title>
<link rel="stylesheet" href="style.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<span>{{mandat.rum}}</span>
<span>{{mandat.person.firstname}}</span>
<input type="text" ng-model="mandat.person.firstname" />
<my-directive mandateperson="mandat.person" >
</my-directive>
<script type="text/javascript">
var app = angular.module('plunker', []);
app.controller('MainCtrl', function ($scope) {
$scope.mandat = { name: "John", surname: "Doe", person: { id: 1408, firstname: "sam" } };
});
app.directive('myDirective', function () {
return {
restrict: 'E',
template: "<div><span>{{mandateperson.id}}<span><input type='text' ng-model='mandateperson.firstname' /></div>",
replace: true,
scope: { mandateperson: '=' }
}
}
)
</script>
</body>
</html>

Resources