Is there a way to count the number of objects created and destroyed in mootools?
Suppose this case:
var Animal = new Class({
initialize: function(){},
create: function() {
alert('created!');
},
destroy: function() {
alert('destroyed');
}
});
var AnimalFactory = new Class({
initialize: function() {
for(i=0;i<10;i++) {
this.add(new Animal());
}
},
add: function(animal) {
this.animalsContainer.push(animal);
},
delete: function(animal) {
this.animalsContainer.remove(animal);
}
});
var animalFactory = new AnimalFactory();
I know how many animals I have created at the beginning but, imagine that somewhere in the code the animal destroy function from a concrete animal instance is called (code not shown here). how can i make the animalContainer array update correctly with one less?
Any help will be much appreciated.
Thanks!!
You can use the Events Class as a mix-in so that it notifies the factory of the animal's demise...
var Animal = new Class({
Implements: [Events,Options], // mixin
initialize: function(options){
this.setOptions(options);
},
create: function() {
alert('created!');
this.fireEvent("create");
},
destroy: function() {
alert('destroyed');
this.fireEvent("destroy", this); // notify the instance
}
});
var AnimalFactory = new Class({
animalsContainer: [],
initialize: function() {
var self = this;
for(i=0;i<10;i++) {
this.add(new Animal({
onDestroy: this.deleteA.bind(this)
}));
}
},
add: function(animal) {
this.animalsContainer.push(animal);
},
deleteA: function(animal) {
this.animalsContainer[this.animalsContainer.indexOf(animal)] = null;
animal = null; // gc
}
});
var foo = new AnimalFactory();
console.log(foo.animalsContainer[0]);
foo.animalsContainer[0].destroy();
console.log(foo.animalsContainer[0]);
watch it run: http://jsfiddle.net/dimitar/57SRR/
this is trying to keep the indexes/length of the array intact in case you save them
Related
spec.js
describe('Testing an animal adoption flow using page object', function() {
beforeEach(function() {
browser.get('http://www.thetestroom.com/jswebapp/index.html');
});
var home_page = require('./pages/home_page.js');
it ('Should be able to adopt an animal by page object', function() {
home_page.enterName('Blabla');
expect(home_page.getDynamicText()).toBe('Blabla');
var animal_page = home_page.clickContinue();
animal_page.selectAnimal(1);
var confirm_page = animal_page.clickContinue();
expect(confirm_page.getTitle()).toContain('Thank');
});
});
home_page.js
require('./animal_page.js');
var home_page = function() {
this.nameTextBox = element(by.model('person.name'));
this.dynamicText = element(by.binding('person.name'));
this.continueButton = element(by.buttonText('CONTINUE'));
this.enterName = function(name) {
this.nameTextBox.sendKeys(name);
};
this.getDynamicText = function() {
return this.dynamicText.getText();
};
this.clickContinue = function() {
this.continueButton.click();
return require('./animal_page.js');
};
};
Failures:
Testing an animal adoption flow using page object Should be able to adopt an animal by page object
Message:
[31m Failed: home_page.enterName is not a function[0m
Stack:
TypeError: home_page.enterName is not a function
You don't create an instance of your constructor function with new keyword. It should have been
var home_page = new (require('./pages/home_page.js'));
and you need to instruct js what you are exporting, so your home page should be
require('./animal_page.js');
var home_page = function() {
this.nameTextBox = element(by.model('person.name'));
this.dynamicText = element(by.binding('person.name'));
this.continueButton = element(by.buttonText('CONTINUE'));
this.enterName = function(name) {
this.nameTextBox.sendKeys(name);
};
this.getDynamicText = function() {
return this.dynamicText.getText();
};
this.clickContinue = function() {
this.continueButton.click();
return require('./animal_page.js');
};
}
module.exports = home_page; // <------ this line
but make sure you do the same with animal_page
I got the answer, we need to include
spec.js
const { browser } = require('protractor');
home_page.js
module.exports = new home_page();
I'm new to qunit + sinon.js, I want to write a unit test for function onMultiSelectPress, so I need to mock:
this.myController._oList
this.myController.getResourceBundle()
this.myController.getModel("masterView")
Right?
I'm stuck at get a stub for getModel("masterView"), any suggestion?
onInit : function () {
var oList = this.byId("list"),
oViewModel = this._createViewModel();
this._oList = oList;
this.setModel(oViewModel, "masterView");
},
_createViewModel : function() {
return new JSONModel({
isFilterBarVisible: false,
filterBarLabel: "",
delay: 0,
title: this.getResourceBundle().getText("masterTitleCount", [0]),
noDataText: this.getResourceBundle().getText("masterListNoDataText"),
sortBy: "Name",
groupBy: "None",
listMode: "SingleSelectMaster",
showDeleteButton: false
});
},
getModel : function (sName) {
return this.getView().getModel(sName);
},
onMultiSelectPress : function () {
var oMasterViewModel = this.getModel("masterView");
switch(this._oList.getMode()) {
case "MultiSelect":
oMasterViewModel.setProperty("/listMode", "SingleSelectMaster");
oMasterViewModel.setProperty("/showDeleteButton", false);
break;
case "SingleSelectMaster":
oMasterViewModel.setProperty("/listMode", "MultiSelect");
oMasterViewModel.setProperty("/showDeleteButton", true);
break;
}
},
Add a oViewStub in beforeEach, and set an empty JSON model using for testing.
QUnit.module("MasterController", {
beforeEach: function() {
this.oMasterController = new MasterController();
this.models = {};
var oViewStub = {
setModel: function(model, name) {
this.models[name] = model;
}.bind(this),
getModel: function(name) {
return this.models[name];
}.bind(this)
};
sinon.stub(Controller.prototype, "getView").returns(oViewStub);
},
afterEach: function() {
this.oMasterController.destroy();
jQuery.each(this.models, function(i, model) {
model.destroy();
});
Controller.prototype.getView.restore();
}
});
QUnit.test("test onMultiSelectPress() ", function(assert) {
var oMasterController = this.oMasterController;
var oModel = new JSONModel();
oMasterController.setModel(oModel, "masterView");
var oMasterViewModel = oMasterController.getModel("masterView");
oMasterController._oList = new sap.m.List();
sinon.stub(oMasterController._oList, "getMode").returns("MultiSelect");
oMasterController.onMultiSelectPress();
assert.strictEqual(oMasterViewModel.getProperty("/listMode"), "SingleSelectMaster", "Did change list mode to SingleSelectMaster");
assert.strictEqual(oMasterViewModel.getProperty("/showDeleteButton"), false, "Did hide the delete button");
oMasterController._oList.getMode.restore();
sinon.stub(oMasterController._oList, "getMode").returns("SingleSelectMaster");
oMasterController.onMultiSelectPress();
assert.strictEqual(oMasterViewModel.getProperty("/listMode"), "MultiSelect", "Did change list mode to MultiSelect");
assert.strictEqual(oMasterViewModel.getProperty("/showDeleteButton"), true, "Did show the delete button");
oMasterController._oList.destroy();
});
//This is my AngularPage.cs page object file
var AngularPage= function()
{
var nameInput= element(by.model('yourName'));
var greeting = element(by.binding('yourName'));
this.get=function()
{
browser.get('http://www.angularjs.org');
};
this.setName= function(name)
{
nameInput.sendKeys(name);
};
this.getGreeting= function()
{
return greeting.getText();`
};
};
module.exports = new AngularPage();
//This is my AngularHome_spec.js file
var angularPage = require('./AngularPage.js');
describe('angularjs homepage',function()
{
var angular_page;
beforeEach(function()
{
angular_page= new AngularPage();
});
it('greetings for new user', function()
{
// var angular_page= new AngularPage();
angular_page.get();
angular_page.setName('Rahul');
expect(angular_page.getGreeting()).toEqual('Hello Rahul!');
}
);
}
);
//I am unable to use page objects in my spec file as it is throwing an error
:AngularPage is not defined
In your code, object has been created twice. First time on page "AngularPage.js" and second time on spec "AngularHome_spec.js" level.
Do following on page "AngularHome_spec.js"
module.exports = AngularPage;
Change the
var AngularPage = require('./AngularPage.js');//Capital the 'A'
I have created view model
var catalog = ko.observableArray();
$.ajax({
type: "GET",
url: "http://localhost:8080/ticket-service/rest/ticket/list",
success: function(msg) {
catalog.push.apply(catalog, $.map(msg, function(data) {
return new Ticket(data)
}));
return catalog;
},
error: function(msg) {
console.log(msg)
}
});
and the model
function Ticket(data) {
this.ticketId = ko.observable(data.ticketId);
this.ticketNo = ko.observable(data.ticketNo);
this.ticketTitle = ko.observable(data.ticketTitle);
this.longDescription = ko.observable(data.longDescription);
this.createdBy = ko.observable(data.createdBy);
this.createdOn= ko.observable(data.createdOn);
this.assignTo = ko.observable(data.assignTo);
this.priority = ko.observable(data.priority);
this.dueDate = ko.observable(data.dueDate);
this.status = ko.observable(data.status);
this.projectId = ko.observable(data.projectId);
}
with at the end viewmodel like this
return {
ticket: newTicket,
searchTerm: searchTerm,
catalog: filteredCatalog,
newTicket: newTicket,
addTicket: addTicket,
delTicket: delTicket
};
})();
console.log(vm);
ko.applyBindings(vm);
produce list,add, and delete form.The question is how can i use knockout mapping that can list from get methode.
you need to do something like this
Demonstrated taking a single entity from your code .
view:
Output Preview :
<pre data-bind="text:ko.toJSON($data,null,2)"></pre>
viewModel:
function Ticket(data) {
this.ticketId = ko.observable(data.ticketId);
}
var mapping = {
create: function (options) {
return new Ticket(options.data);
}
};
var ViewModel = function () {
var self = this;
self.catalog = ko.observableArray();
var data = [{
'ticketId': 1
}, {
'ticketId': 2
}]
//under ajax call do the same but pass 'msg' in place of data
self.catalog(ko.mapping.fromJS(data, mapping)())
console.log(self.catalog()); // check console for output
};
ko.applyBindings(new ViewModel());
sample working fiddle here
I have a list of dogs in a table that have an underlying dog model and dog collection. When I update the dogName of a dog document in the mongo collection I want the table list item to update and show the new dog name without having to refresh the page.
I thought this was supposed to happen when you this.listenTo(this.model, 'change', this.render);
How can I get the table row item to update when the model changes??
window.Dog = Backbone.Model.extend({
urlRoot: "/dogs",
idAttribute:"_id",
initialize: function() {
}
defaults:{
_id: null,
dogName: "",
}
});
window.DogCollection = Backbone.Collection.extend({
model: Dog,
url: "/dogs/user/",
});
window.DogListView = Backbone.View.extend({
initialize: function () {
this.listenTo(this.model, 'change', this.render);
this.render();
},
render: function () {
var dogs = this.model.models;
$(this.el).html(this.template());
for (var i = 0; i < dogs.length; i++) {
this.$('#dogsTable tbody').append(
new DogListItemView({model: dogs[i], no: i+1}).render().el
);
}
this.$('#dogsTable').dataTable({
"bAutoWidth": false,"iDisplayLength": 50
});
return this;
}
});
window.DogListItemView = Backbone.View.extend({
tagName: "tr",
initialize: function (options) {
this.listenTo(this.model, 'change', this.render);
this.model.bind("change", this.render, this);
this.model.bind("destroy", this.close, this);
this.no = options.no;
this.render();
},
render: function () {
$(this.el).html(this.template({
no: this.no,
id: this.model.get("_id"),
dogName: this.model.get("dogName"),
}));
return this;
},
events: {
"click .delete": "deleteDog",
}
});
And finally in backbone controller I use this to load the view:
var dogList = new DogCollection();
dogList.url = "/dogs/user/" + this.user.get("_id");
dogList.fetch({
success: function() {
$('#content').html(new DogListView({model: dogList}).el);
}
});
What you're doing right now is:
Create some views (item- and collectionViews)
Define a collection
Set an url for this collection
Fetch the collection and on succes
Display the fetched data in these views
This is totally fine and these views will (probably, did not test your code) update once a change occurs in any of your models in the collection.
However, your application has no way of knowing that something is changed in your mongo database once it has fetched the data. If you would like to obtain this functionality, you could do for example one of the following;
Make the collection poll (and thus refetch) once in a while.
Inform your application that something has changed on the server using websockets. If you'd like to do this, you can use a library like http://socket.io